Game Programming
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Building a Flexible Camera Class
September 01, 2005
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
DirectX SDK & Sample Codes
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
File New
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Copy Sample Files
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Project Add To Project
Files
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
FileView
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Project Settings
Link
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Tool Options
Directories
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Sample: Camera
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Control Keys
W / S – walk forward / backward
A / D – Strafe left / right
R / F – Fly up / down
Up / Down arrow keys – Pitch
Left / Right arrow keys – Yaw
N / M – Roll
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Analysis of Sample: Camera
cameraApp.cpp
d3dUtility.cpp
d3dUtility.h
InitD3D();
Setup();
EnterMsgLoop();
Cleanup();
WndProc();
Display();
WinMain();
WndProc();
Setup();
Cleanup();
Display();
camera.h
camera.cpp
InitD3D();EnterMsgLoop();DrawBasicScene();
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Analysis of Sample: Camera
cameraApp.cpp
d3dUtility.cpp
d3dUtility.h
InitD3D();
Setup();
EnterMsgLoop();
Cleanup();
WndProc();
Display();
WinMain();
WndProc();
Setup();
Cleanup();
Display();
camera.h
camera.cpp
InitD3D();EnterMsgLoop();DrawBasicScene();
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
WinMain( )
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Analysis of Sample: Camera
cameraApp.cpp
d3dUtility.cpp
d3dUtility.h
InitD3D();
Setup();
EnterMsgLoop();
Cleanup();
WndProc();
Display();
WinMain();
WndProc();
Setup();
Cleanup();
Display();
camera.h
camera.cpp
InitD3D();EnterMsgLoop();DrawBasicScene();
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Creating the Main Window
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Initializing Direct3D (Step 1)
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Initializing Direct3D (Step 2,3)
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Initializing Direct3D (Step 4)
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Analysis of Sample: Camera
cameraApp.cpp
d3dUtility.cpp
d3dUtility.h
InitD3D();
Setup();
EnterMsgLoop();
Cleanup();
WndProc();
Display();
WinMain();
WndProc();
Setup();
Cleanup();
Display();
camera.h
camera.cpp
InitD3D();EnterMsgLoop();DrawBasicScene();
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Setup ( ) – Projection
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Analysis of Sample: Camera
cameraApp.cpp
d3dUtility.cpp
d3dUtility.h
InitD3D();
Setup();
EnterMsgLoop();
Cleanup();
WndProc();
Display();
WinMain();
WndProc();
Setup();
Cleanup();
Display();
camera.h
camera.cpp
InitD3D();EnterMsgLoop();DrawBasicScene();
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Creating the Buffers
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Accessing the Buffers
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Setting Rendering States
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Rendering Background
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Analysis of Sample: Camera
cameraApp.cpp
d3dUtility.cpp
d3dUtility.h
InitD3D();
Setup();
EnterMsgLoop();
Cleanup();
WndProc();
Display();
WinMain();
WndProc();
Setup();
Cleanup();
Display();
camera.h
camera.cpp
InitD3D();EnterMsgLoop();DrawBasicScene();
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
EnterMsgLoop ( )
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Analysis of Sample: Camera
cameraApp.cpp
d3dUtility.cpp
d3dUtility.h
InitD3D();
Setup();
EnterMsgLoop();
Cleanup();
WndProc();
Display();
WinMain();
WndProc();
Setup();
Cleanup();
Display();
camera.h
camera.cpp
InitD3D();EnterMsgLoop();DrawBasicScene();
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
WndProc ( )
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Analysis of Sample: Camera
cameraApp.cpp
d3dUtility.cpp
d3dUtility.h
InitD3D();
Setup();
EnterMsgLoop();
Cleanup();
WndProc();
Display();
WinMain();
WndProc();
Setup();
Cleanup();
Display();
camera.h
camera.cpp
InitD3D();EnterMsgLoop();DrawBasicScene();
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Handling Keyboard Events
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Camera & Rendering Scene
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Analysis of Sample: Camera
cameraApp.cpp
d3dUtility.cpp
d3dUtility.h
InitD3D();
Setup();
EnterMsgLoop();
Cleanup();
WndProc();
Display();
WinMain();
WndProc();
Setup();
Cleanup();
Display();
camera.h
camera.cpp
InitD3D();EnterMsgLoop();DrawBasicScene();
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Cleanup ( )
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Analysis of Sample: Camera
cameraApp.cpp
d3dUtility.cpp
d3dUtility.h
InitD3D();
Setup();
EnterMsgLoop();
Cleanup();
WndProc();
Display();
WinMain();
WndProc();
Setup();
Cleanup();
Display();
camera.h
camera.cpp
InitD3D();EnterMsgLoop();DrawBasicScene();
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Objective
To learn how to implement a flexible Cameraclass
suitable for light simulators games played from first-person perspective
D3DXMatrixLookAtLH( ) function
[+] positioning and aiming a camera in a fixed position
[−] moving camera that reacts to user input
Motivation
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Camera Design (1)
Four camera vectorsposition and orientation of the camera
right, up, look, and position vectors
(R, U, L): orientation vectors
orthonormal vectors
orthogonal matrix
inverse == transpose
World Space
PR
UL
P = Position vectorR = Right vectorU = Up vectorL = Look vector
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Camera Design (2)
Six operations – six degrees of freedomrotate around the right vector (pitch)
rotate around the up vector (yaw)
rotate around the look vector (roll)
strafe along the right vector
fly along the up vector
move along look vector
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Camera Design (3)
class Camera{public:
enum CameraType { LANDOBJECT, AIRCRAFT };
Camera();Camera(CameraType cameraType);~Camera();
void strafe(float units); // left/rightvoid fly(float units); // up/downvoid walk(float units); // forward/backward
void pitch(float angle); // rotate on right vectorvoid yaw(float angle); // rotate on up vectorvoid roll(float angle); // rotate on look vector
void getViewMatrix(D3DXMATRIX* V); void setCameraType(CameraType cameraType); void getPosition(D3DXVECTOR3* pos); void setPosition(D3DXVECTOR3* pos);
void getRight(D3DXVECTOR3* right);void getUp(D3DXVECTOR3* up);void getLook(D3DXVECTOR3* look);
private:CameraType _cameraType;D3DXVECTOR3 _right;D3DXVECTOR3 _up;D3DXVECTOR3 _look;D3DXVECTOR3 _pos;
};
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Implementation Details (1)
Computing the view matrix
p = (px, py, pz) : position vectorr = (rx, ry, rz) : right vectoru = (ux, uy, uz) : up vectord = (dx, dy, dz) : look vector
+x
+z
O
AB
C
D
+x
+z
O
AB
C
D
+x
+z
O
AD
B
C
< View Space Transformation >
pV = (0, 0, 0) : originrV = (1, 0, 0) : x-axisuV = (0, 1, 0) : y-axisdV = (0, 0, 1) : z-axis
pV = (0, 0, 0) : originrV = (1, 0, 0) : x-axisuV = (0, 1, 0) : y-axisdV = (0, 0, 1) : z-axis
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Part 1: Translation
Taking p to the origin
0px =−
⎥⎥⎥⎥⎥
⎦
⎤
⎢⎢⎢⎢⎢
⎣
⎡
−−−
=
1
0100
0010
0001
zyx ppp
T
( ) ( ) ( )000=− zyx pppzyx
[ ]
[ ]11
0100
0010
0001
1
zyx
zyx
pzpypx
ppp
zyx
−−−=⎥⎥⎥⎥⎥
⎦
⎤
⎢⎢⎢⎢⎢
⎣
⎡
−−−
=xT
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Part 2: Rotation (1)
Aligning r, u, d camera vectors with world’s axes
[ ] [ ]001
222120
121110
020100
=⎥⎥⎥
⎦
⎤
⎢⎢⎢
⎣
⎡=
aaa
aaa
aaa
rrr zyxrA
[ ] [ ]010
222120
121110
020100
=⎥⎥⎥
⎦
⎤
⎢⎢⎢
⎣
⎡=
aaa
aaa
aaa
uuu zyxuA
[ ] [ ]100
222120
121110
020100
=⎥⎥⎥
⎦
⎤
⎢⎢⎢
⎣
⎡=
aaa
aaa
aaa
ddd zyxdA
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Part 2: Rotation (2)
Aligning r, u, d camera vectors with world’s axes
⎥⎥⎥
⎦
⎤
⎢⎢⎢
⎣
⎡=
⎥⎥⎥
⎦
⎤
⎢⎢⎢
⎣
⎡
⎥⎥⎥
⎦
⎤
⎢⎢⎢
⎣
⎡
100
010
001
222120
121110
020100
aaa
aaa
aaa
ddd
uuu
rrr
zyx
zyx
zyx
[ ] [ ]001
222120
121110
020100
=⎥⎥⎥
⎦
⎤
⎢⎢⎢
⎣
⎡=
aaa
aaa
aaa
rrr zyxrA
[ ] [ ]010
222120
121110
020100
=⎥⎥⎥
⎦
⎤
⎢⎢⎢
⎣
⎡=
aaa
aaa
aaa
uuu zyxuA
[ ] [ ]100
222120
121110
020100
=⎥⎥⎥
⎦
⎤
⎢⎢⎢
⎣
⎡=
aaa
aaa
aaa
ddd zyxdA
⎥⎥⎥
⎦
⎤
⎢⎢⎢
⎣
⎡===−
zzz
yyy
xxxT
dur
dur
dur
ABB 1
1
1
−
−
=∴
==
BA
IBBBA
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Combining Both Parts
View transformation matrix V:
⎥⎥⎥⎥⎥
⎦
⎤
⎢⎢⎢⎢⎢
⎣
⎡
⋅−⋅−⋅−
=
⎥⎥⎥⎥
⎦
⎤
⎢⎢⎢⎢
⎣
⎡
⎥⎥⎥⎥⎥
⎦
⎤
⎢⎢⎢⎢⎢
⎣
⎡
−−−
==
1
0
0
0
1000
0
0
0
1
0100
0010
0001
dur
TAV
zyx
zzz
yyy
xxx
zzz
yyy
xxx
zyx
ppp
dur
dur
dur
dur
dur
dur
ppp
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Camera :: getViewMatrix ( )
void Camera::getViewMatrix(D3DXMATRIX* V){
// Keep camera's axes orthogonal to each otherD3DXVec3Normalize(&_look, &_look);
D3DXVec3Cross(&_up, &_look, &_right);D3DXVec3Normalize(&_up, &_up);
D3DXVec3Cross(&_right, &_up, &_look);D3DXVec3Normalize(&_right, &_right);
// Build the view matrix:float x = -D3DXVec3Dot(&_right, &_pos);float y = -D3DXVec3Dot(&_up, &_pos);float z = -D3DXVec3Dot(&_look, &_pos);
(*V)(0, 0) = _right.x; (*V)(0, 1) = _up.x; (*V)(0, 2) = _look.x; (*V)(0, 3) = 0.0f;
(*V)(1, 0) = _right.y; (*V)(1, 1) = _up.y; (*V)(1, 2) = _look.y; (*V)(1, 3) = 0.0f;
(*V)(2, 0) = _right.z; (*V)(2, 1) = _up.z; (*V)(2, 2) = _look.z; (*V)(2, 3) = 0.0f;
(*V)(3, 0) = x; (*V)(3, 1) = y; (*V)(3, 2) = z; (*V)(3, 3) = 1.0f;
}
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Implementation Details (2)
Rotation about an arbitrary axis
ex)
D3DXMATRIX &D3DXMatrixRotationAxis (D3DXMATRIX *pOut,CONST D3DXVECTOR *pV,FLOAT Angle
);
D3DXMATRIX &D3DXMatrixRotationAxis (D3DXMATRIX *pOut,CONST D3DXVECTOR *pV,FLOAT Angle
);
A
Y
Z
X
D3DXMATRIX R;D3DXVECTOR3 axis(0.707f, 0.707f, 0.0f);D3DXMatrixRotationAxis(&R, &axis, D3DX_PI/2.0f);
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Implementation Details (3)
Pitch, yaw, and roll
PR
UL
PR
L
U
Pitch
PR
UL
PL
U
R
Yaw
PR
UL
PU
RL
Roll
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Camera :: pitch ( ) and yaw ( )
void Camera::pitch(float angle){
D3DXMATRIX T;D3DXMatrixRotationAxis(&T, &_right, angle);
// rotate _up and _look around _right vectorD3DXVec3TransformCoord(&_up,&_up, &T);D3DXVec3TransformCoord(&_look,&_look, &T);
}
void Camera::yaw(float angle){
D3DXMATRIX T;
// rotate around world y (0, 1, 0) always for land objectif( _cameraType == LANDOBJECT )
D3DXMatrixRotationY(&T, angle);
// rotate around own up vector for aircraftif( _cameraType == AIRCRAFT )
D3DXMatrixRotationAxis(&T, &_up, angle);
// rotate _right and _look around _up or y-axisD3DXVec3TransformCoord(&_right,&_right, &T);D3DXVec3TransformCoord(&_look,&_look, &T);
}
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Camera :: roll ( )
void Camera::roll(float angle){
// only roll for aircraft typeif( _cameraType == AIRCRAFT ){
D3DXMATRIX T;D3DXMatrixRotationAxis(&T, &_look, angle);
// rotate _up and _right around _look vectorD3DXVec3TransformCoord(&_right,&_right, &T);D3DXVec3TransformCoord(&_up,&_up, &T);
}}
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Implementation Details (4)
Walking, strafing, and flying
P
sL
P’=P+sL
tR P’=P+tR
rU
P’=P+rU
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Camera :: walk, strafe, fly ( )
void Camera::walk(float units){
// move only on xz plane for land objectif( _cameraType == LANDOBJECT )
_pos += D3DXVECTOR3(_look.x, 0.0f, _look.z) * units;
if( _cameraType == AIRCRAFT )_pos += _look * units;
}
void Camera::strafe(float units){
// move only on xz plane for land objectif( _cameraType == LANDOBJECT )
_pos += D3DXVECTOR3(_right.x, 0.0f, _right.z) * units;
if( _cameraType == AIRCRAFT )_pos += _right * units;
}
void Camera::fly(float units){
// move only on y-axis for land objectif( _cameraType == LANDOBJECT )
_pos.y += units;
if( _cameraType == AIRCRAFT )_pos += _up * units;
}
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Sample: Camera
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Control Keys
W / S – walk forward / backward
A / D – Strafe left / right
R / F – Fly up / down
Up / Down arrow keys – Pitch
Left / Right arrow keys – Yaw
N / M – Roll
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Creation of a Camera Object
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Moving of a Camera
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Getting of a View Matrix
Sun-Jeong Kim http://www.hallym.ac.kr/~sunkim/teach/2005/gp1http://www.hallym.ac.kr/~sunkim/teach/2005/gp2
Exercise
Create a Camera object for an airplane
Change the view: airplane whole view
whole view airplane