LOD地形根据视点的变化决定是否进行网格分割,因此系统应设计一个视点类,来管理视点相关的数据。这节介绍的视点类是通用的,在很多网站都可下到这个类的代码,它可以用在OPENGL编程的各个场合,当然朋友也可根据需要自己增加相应功能! /*********************************************************************** * Copyrights Reserved by QinGeSoftware * Author : Qinge * Filename : Camera.h 1.0 * Date: 2008-1-10 ************************************************************************/ #pragma once #include "Vector3.h" class Camera { public: Camera(void); virtual ~Camera(void); public: CVector3 GetPosition(){return m_vPosition;} //获得摄像机位置 CVector3 GetView(){return m_vView;} //获得视线目标点 CVector3 GetUpVector() {return m_vUpVector;} //获得向上方向 CVector3 GetStrafe() {return m_vStrafe;} //获得平移方向的单位向量 void PosotionCamera(float positionX, float positionY, float positionZ, float viewX, float viewY, float viewZ, float upVectorX, float upVectorY, float upVectorZ); //初始化摄像机 void RotateView(float angle, float X, float Y, float Z); //绕(x,y,z)旋转angle void SetViewByMouse(); //通过鼠标旋转场景 void RotateAroundPoint(CVector3 vCenter, float X, float Y, float Z); //绕点旋转 void StrafeCamera(float speed); //平移摄像机 void MoveCamera(float speed); //沿视线方向移动摄像机 void Look(); //设置视点相当于glLookAt() void Update(); //更新视点位置。 void CheckForMovement(); //检查是否有视点变量更新 private: CVector3 m_vPosition; //摄像机视点 CVector3 m_vView; //摄像机视线 CVector3 m_vUpVector; //摄像机向上方向 CVector3 m_vStrafe; //摄像机平移 const float fSpeed; //摄像机移动速度 }; /*********************************************************************** * Copyrights Reserved by QinGeSoftware * Author : Qinge * Filename : Camera.cpp 1.0 * Date: 2008-1-10 ************************************************************************/ #include "StdAfx.h" #include "Camera.h" Camera::Camera(void):fSpeed(5.0f) { m_vPosition = CVector3(0,0,0); m_vView = CVector3(0.0,1.0,0.5); m_vUpVector = CVector3(0.0,0.0,1.0); } Camera::~Camera(void) { } void Camera::PosotionCamera(float positionX, float positionY, float positionZ, float viewX, float viewY, float viewZ, float upVectorX, float upVectorY, float upVectorZ) { m_vPosition = CVector3(positionX, positionY+200, positionZ); m_vView = CVector3(viewX, viewY, viewZ); m_vUpVector = CVector3(upVectorX, upVectorY, upVectorZ); } void Camera::SetViewByMouse() { CPoint m_CurPt,m_PrePt; HDC hDC = ::GetDC(NULL); float angleY, angleZ; CVector3 m_uAixs, m_vViewDire; unsigned long WIDTH, HEIGHT; WIDTH =::GetDeviceCaps(hDC,HORZRES); //获得屏幕分辨率 HEIGHT =::GetDeviceCaps(hDC,VERTRES); // ::GetCursorPos(&m_CurPt); m_PrePt.x = WIDTH >>1; //分辨率/2 m_PrePt.y = HEIGHT >> 1; ::SetCursorPos(m_PrePt.x, m_PrePt.y); //固定光标在屏幕中心 angleY = (m_CurPt.x - m_PrePt.x )/1000.0; //根据鼠标移动距离确定旋转角度 angleZ = (m_CurPt.y - m_PrePt.y )/1000.0; // m_vViewDire = m_vView - m_vPosition; m_uAixs = m_vViewDire.CrossProduct(m_vViewDire,m_vUpVector); //得到平移向量 m_uAixs = m_uAixs.Normalize(m_uAixs); RotateView(angleZ, m_uAixs.x, m_uAixs.y, m_uAixs.z); //绕任意轴旋转 RotateView(angleY,0,1,0); //绕y轴旋转 } void Camera::RotateView(float angle, float x, float y, float z) { CVector3 vNewView; CVector3 vView = m_vView - m_vPosition; //视线方向 float cosTheta = (float)cos(angle); float sinTheta = (float)sin(angle); //下面就是一个数学公式 vNewView.x = (cosTheta + (1 - cosTheta) * x * x) * vView.x; vNewView.x += ((1 - cosTheta) * x * y - z * sinTheta) * vView.y; vNewView.x += ((1 - cosTheta) * x * z + y * sinTheta) * vView.z; vNewView.y = ((1 - cosTheta) * x * y + z * sinTheta) * vView.x; vNewView.y += (cosTheta + (1 - cosTheta) * y * y) * vView.y; vNewView.y += ((1 - cosTheta) * y * z - x * sinTheta) * vView.z; vNewView.z = ((1 - cosTheta) * x * z - y * sinTheta) * vView.x; vNewView.z += ((1 - cosTheta) * y * z + x * sinTheta) * vView.y; vNewView.z += (cosTheta + (1 - cosTheta) * z * z) * vView.z; m_vView = m_vPosition + vNewView; //视点+新向量=新视线目标点 } void Camera::StrafeCamera(float speed) { //给视线目标点,视点增加一个增量 m_vPosition.x += m_vStrafe.x * speed; m_vPosition.z += m_vStrafe.z * speed; m_vView.x += m_vStrafe.x * speed; m_vView.z += m_vStrafe.z * speed; } void Camera::MoveCamera(float speed) { CVector3 vVector = m_vView - m_vPosition; vVector = vVector.Normalize(vVector); m_vPosition.x += vVector.x * speed; //沿视线方向移动 m_vPosition.z += vVector.z * speed; // m_vView.x += vVector.x * speed; // m_vView.z += vVector.z * speed; // } void Camera::Update() { CVector3 vCross =m_vView.CrossProduct(m_vView - m_vPosition, m_vUpVector); m_vStrafe = vCross.Normalize(vCross); SetViewByMouse(); CheckForMovement(); } void Camera::CheckForMovement() // 上下左右移动视点 { if(GetKeyState(VK_UP) & 0x80 || GetKeyState('W') & 0x80) { MoveCamera(fSpeed); } if(GetKeyState(VK_DOWN) & 0x80 || GetKeyState('S') & 0x80) { MoveCamera(-fSpeed); } if(GetKeyState(VK_LEFT) & 0x80 || GetKeyState('A') & 0x80) { StrafeCamera(-fSpeed); } if(GetKeyState(VK_RIGHT) & 0x80 || GetKeyState('D') & 0x80) { StrafeCamera(fSpeed); } } void Camera::Look() //等于gluLookAt() { gluLookAt(m_vPosition.x, m_vPosition.y, m_vPosition.z, m_vView.x, m_vView.y, m_vView.z, m_vUpVector.x, m_vUpVector.y, m_vUpVector.z); }
LOD地形设计(三)
最新推荐文章于 2024-05-07 10:44:28 发布