http://hi.baidu.com/zyb_debug/blog/item/a5cd0251412e196b84352488.html龙书上的camera,可重用,直接看代码和注释吧。
zybCamera.h
1#ifndef ZYB_CAMERAL_H
2#define ZYB_CAMERAL_H
3
4namespace zyb
5{
6
7
8class zybCamera
9{
10public:
11 enum CameraType {LANDOBJECT,AIRCRAFT};
12
13 zybCamera();
14 zybCamera(CameraType cameraType);
15 ~zybCamera();
16
17 void strafe(float units); //横移 左右
18 void fly(float units); //上下
19 void walk(float units); //前后
20
21
22 void pitch(float angle); //俯仰,沿x轴,也就是右向量的旋转
23 //实际效果是飞机机头的升降
24
25 void yaw(float angle); //偏航,沿y轴,也就是上向量的旋转
26
27 void roll(float angle); //左右倒,沿周,也就是前向量的旋转
28 //实际效果是飞机的机翼左右倒
29
30 void getViewMatrix(D3DXMATRIX* V); //获取摄像机矩阵
31 void setCameraType(CameraType cameraType); //设置摄像机的类型
32 void getPosition(D3DXVECTOR3* pos); //得到摄像机的位置
33 void setPosition(D3DXVECTOR3* pos); //设置摄像机的位置
34
35 void getRight(D3DXVECTOR3* right); //得到摄像机的右向量,在世界坐标系
36 void getUp(D3DXVECTOR3* up); //得到摄像机的上向量,在世界坐标系
37 void getLook(D3DXVECTOR3* look); //得到摄像机的前向量,在世界坐标系
38
39private:
40 CameraType _cameraType; //摄像机类型
41 D3DXVECTOR3 _right; //右向量
42 D3DXVECTOR3 _up; //上向量
43 D3DXVECTOR3 _look; //前向量
44 D3DXVECTOR3 _pos; //摄像机在世界坐标系中的位置
45
46};
47
48}
49
50
51#endif
52
53
zybCamera.cpp
1 #include "DXUT.h"
2 #include "zybCamera.h"
3
4 namespace zyb
5 {
6
7 //=========================================
8 /**
9 @brief 初始化位置为坐标原点(世界坐标系)
10 右向量为x轴正向单位向量
11 上向量为y轴正向单位向量
12 前向量为z轴正向单位向量
13 @param
14 @return
15 */
16 //=========================================
17 zybCamera::zybCamera()
18 {
19
20 _cameraType = AIRCRAFT;
21
22 _pos = D3DXVECTOR3(0.0f,0.0f,0.0f);
23 _right = D3DXVECTOR3(1.0f,0.0f,0.0f);
24 _up = D3DXVECTOR3(0.0f,1.0f,0.0f);
25 _look = D3DXVECTOR3(0.0f,0.0f,1.0f);
26
27 }
28
29 zybCamera::zybCamera(zyb::zybCamera::CameraType cameraType)
30 {
31 _cameraType = cameraType;
32
33 _pos = D3DXVECTOR3(0.0f,0.0f,0.0f);
34 _right = D3DXVECTOR3(1.0f,0.0f,0.0f);
35 _up = D3DXVECTOR3(0.0f,1.0f,0.0f);
36 _look = D3DXVECTOR3(0.0f,0.0f,1.0f);
37
38
39 }
40
41 zybCamera::~zybCamera()
42 {
43
44 }
45
46 //=========================================
47 /**
48 @brief 如果是飞机类型的相机,那么横移只是
49 摄像机右向量方向上的移动(世界坐标系)
50 如果陆地类型的相机,那么横移方向不包括右方向
51 y项分量的移动
52 @param
53 @return
54 */
55 //=========================================
56 void zybCamera::strafe(float units)
57 {
58 if( _cameraType == LANDOBJECT )
59 _pos += D3DXVECTOR3(_right.x, 0.0f, _right.z) * units;
60
61 if( _cameraType == AIRCRAFT )
62 _pos += _right * units;
63
64 }
65
66
67 //=========================================
68 /**
69 @brief 如果是飞机类型的相机,那么摄像机随着摄像机上
70 向量的方向移动
71
72 如果陆地类型的相机,那么只增加摄像机的位置的y分量
73
74 @param
75 @return
76 */
77 //=========================================
78
79 void zybCamera::fly(float units)
80 {
81 if( _cameraType == LANDOBJECT )
82 _pos.y += units;
83
84 if( _cameraType == AIRCRAFT )
85 _pos += _up * units;
86
87 }
88
89 //=========================================
90 /**
91 如果是飞机类型的相机,那么前行只是
92 摄像机前向量方向上的移动(世界坐标系)
93 如果陆地类型的相机,那么前行方向不包括look方向
94 y项的移动
95 */
96 //=========================================
97 void zybCamera::walk(float units)
98 {
99 if (_cameraType == LANDOBJECT)
100 {
101 _pos += D3DXVECTOR3(_look.x, 0.0f , _look.z) * units;
102 }
103 else
104 {
105 _pos += _look * units;
106 }
107
108 }
109
110
111 //=========================================
112 /**
113 @brief 计算绕右向量旋转的矩阵,然后
114 上向量和前向量乘以这个矩阵得到现在
115 的上向量和前向量,为什么右向量不变?
116 因为上向量和前向量同时旋转一个角度,那么
117 它们形成的平面还是和右向量是垂直的
118 @param
119 @return
120 */
121 //=========================================
122 void zybCamera::pitch(float angle)
123 {
124 D3DXMATRIX T;
125 D3DXMatrixRotationAxis(&T, &_right, angle);
126
127
128 D3DXVec3TransformCoord(&_up,&_up, &T);
129 D3DXVec3TransformCoord(&_look,&_look, &T);
130
131 }
132
133 //=========================================
134 /**
135 @brief 如果是陆地型摄像机,直接绕世界坐标y轴旋转
136 @param 如果是飞机型摄像机,绕摄像机的y轴转动
137 @return
138 */
139 //=========================================
140 void zybCamera::yaw(float angle)
141 {
142
143
144 D3DXMATRIX T;
145
146 // rotate around world y (0, 1, 0) always for land object
147 if( _cameraType == LANDOBJECT )
148 D3DXMatrixRotationY(&T, angle);
149
150 // rotate around own up vector for aircraft
151 if( _cameraType == AIRCRAFT )
152 D3DXMatrixRotationAxis(&T, &_up, angle);
153
154 // rotate _right and _look around _up or y-axis
155 D3DXVec3TransformCoord(&_right,&_right, &T);
156 D3DXVec3TransformCoord(&_look,&_look, &T);
157
158 }
159
160 //=========================================
161 /**
162 @brief 只针对飞机型摄像机才有绕前向量的旋转,也就是左右晃
163 @param
164 @return
165 */
166 //=========================================
167 void zybCamera::roll(float angle)
168 {
169 // only roll for aircraft type
170 if( _cameraType == AIRCRAFT )
171 {
172 D3DXMATRIX T;
173 D3DXMatrixRotationAxis(&T, &_look, angle);
174
175 // rotate _up and _right around _look vector
176 D3DXVec3TransformCoord(&_right,&_right, &T);
177 D3DXVec3TransformCoord(&_up,&_up, &T);
178 }
179
180
181 }
182
183
184 //=========================================
185 /**
186 @brief 计算摄像机矩阵,这个可以去看有关的数学知识
187 摄像机变换
188 就是根据3个向量来进行摄像机变换
189
190 思路:点世界变幻的逆运算就是摄像机变换
191 @param
192 @return
193 */
194 //=========================================
195
196 void zybCamera::getViewMatrix(D3DXMATRIX* V)
197 {
198 // Keep camera's axes orthogonal to eachother
199 D3DXVec3Normalize(&_look, &_look);
200
201 D3DXVec3Cross(&_up, &_look, &_right);
202 D3DXVec3Normalize(&_up, &_up);
203
204 D3DXVec3Cross(&_right, &_up, &_look);
205 D3DXVec3Normalize(&_right, &_right);
206
207 // Build the view matrix:
208 float x = -D3DXVec3Dot(&_right, &_pos);
209 float y = -D3DXVec3Dot(&_up, &_pos);
210 float z = -D3DXVec3Dot(&_look, &_pos);
211
212 (*V)(0,0) = _right.x; (*V)(0, 1) = _up.x; (*V)(0, 2) = _look.x; (*V)(0, 3) = 0.0f;
213 (*V)(1,0) = _right.y; (*V)(1, 1) = _up.y; (*V)(1, 2) = _look.y; (*V)(1, 3) = 0.0f;
214 (*V)(2,0) = _right.z; (*V)(2, 1) = _up.z; (*V)(2, 2) = _look.z; (*V)(2, 3) = 0.0f;
215 (*V)(3,0) = x; (*V)(3, 1) = y; (*V)(3, 2) = z; (*V)(3, 3) = 1.0f;
216
217 }
218
219 void zybCamera::setCameraType(CameraType cameraType)
220 {
221 _cameraType = cameraType;
222
223
224 }
225 //=========================================
226 /**
227 @brief 简单的getSet
228 @param
229 @return
230 */
231 //=========================================
232
233 void zybCamera::getPosition(D3DXVECTOR3* pos)
234 {
235 *pos = _pos;
236
237 }
238
239 void zybCamera::setPosition(D3DXVECTOR3* pos)
240 {
241 _pos = *pos;
242
243 }
244
245 void zybCamera::getRight(D3DXVECTOR3* right)
246 {
247 *right = _right;
248 }
249
250 void zybCamera::getUp(D3DXVECTOR3* up)
251 {
252 *up = _up;
253 }
254
255 void zybCamera::getLook(D3DXVECTOR3 *look)
256 {
257 *look = _look;
258 }
259
260
261
262
263
264 }
265