2 #include <kazmath/utility.h>
3 #include <kazmathxx/mat4.h>
4 #include <kazmathxx/vec3.h>
7 #include "scene/camera.h"
13 Camera::Camera(const string
& name
):
15 m_FrustumNeedsUpdating(true) {
17 kmQuaternionIdentity(&m_Orientation
);
20 Camera::Camera(const string
& name
, const Vec3
& vec
):
22 m_FrustumNeedsUpdating(true) {
25 kmQuaternionIdentity(&m_Orientation
);
28 Camera::Camera(const string
& name
, float x
, float y
, float z
):
30 m_FrustumNeedsUpdating(true) {
32 m_Position
= Vec3(x
, y
, z
);
33 kmQuaternionIdentity(&m_Orientation
);
36 void Camera::setPosition(const Vec3
& vec
) {
40 void Camera::lookAt(const Vec3
& vec
) {
42 newForward
= vec
- m_Position
;
43 setDirection(newForward
);
44 m_FrustumNeedsUpdating
= true;
47 void Camera::setNearClipDistance(float dist
) {
51 void Camera::setFarClipDistance(float dist
) {
55 void Camera::yaw(float angle
) {
59 // Rotate around fixed yaw axis
63 kmQuaternionMultiplyVec3(&yAxis
, &m_Orientation
, &UNIT_Y
);
67 m_FrustumNeedsUpdating
= true;
70 void Camera::pitch(float angle
) {
74 kmQuaternionMultiplyVec3(&xAxis
, &m_Orientation
, &UNIT_X
);
78 m_FrustumNeedsUpdating
= true;
81 void Camera::roll(float val
) {
85 void Camera::rotate(const Vec3
& axis
, float angle
) {
87 kmQuaternionRotationAxis(&q
, &axis
, kmDegreesToRadians(angle
));
92 void Camera::rotate(const kmQuaternion
& q
) {
95 kmQuaternionNormalize(&q2
, &q
);
96 kmQuaternionMultiply(&m_Orientation
, &q
, &m_Orientation
);
97 kmQuaternionNormalize(&m_Orientation
, &m_Orientation
);
98 m_FrustumNeedsUpdating
= true;
101 /* Vec3 Camera::getUp() const {
105 Vec3 Camera::getRight() const {
109 Vec3 Camera::getForward() const {
113 string
Camera::getName() {
117 void Camera::setFixedYawAxis(bool fixYaw
, const Vec3
& axis
) {
122 void Camera::setOrientation(const kmQuaternion
& q
) {
126 void Camera::setDirection(const Vec3
& vec
) {
127 //Do nothing if the vector passed has no length
132 //Get the normalized vector, negated to take into accoun the Z axis
135 kmVec3Normalize(&normDir
, &normDir
);
137 //If the yaw axis is fixed (i.e. first person camera)
140 kmVec3Cross(&right
, &yawFixedAxis
, &normDir
);
143 kmVec3Cross(&up
, &normDir
, &right
);
145 //Set the orientation
147 kmMat4Identity(&rotation
);
149 rotation
.m_Mat
[0] = right
.x
;
150 rotation
.m_Mat
[1] = right
.y
;
151 rotation
.m_Mat
[2] = right
.z
;
153 rotation
.m_Mat
[4] = up
.x
;
154 rotation
.m_Mat
[5] = up
.y
;
155 rotation
.m_Mat
[6] = up
.z
;
157 rotation
.m_Mat
[8] = normDir
.x
;
158 rotation
.m_Mat
[9] = normDir
.y
;
159 rotation
.m_Mat
[10] = normDir
.z
;
161 kmQuaternionRotationMatrix(&m_Orientation
, &rotation
);
166 kmMat4RotationQuaternion(&rotation
, &m_Orientation
);
167 axes
[0].x
= rotation
.m_Mat
[0];
168 axes
[0].y
= rotation
.m_Mat
[1];
169 axes
[0].z
= rotation
.m_Mat
[2];
171 axes
[1].x
= rotation
.m_Mat
[4];
172 axes
[1].y
= rotation
.m_Mat
[5];
173 axes
[1].z
= rotation
.m_Mat
[6];
175 axes
[2].x
= rotation
.m_Mat
[8];
176 axes
[2].y
= rotation
.m_Mat
[9];
177 axes
[2].z
= rotation
.m_Mat
[10];
180 kmQuaternion rotQuat
;
181 Vec3 temp
= axes
[2] + normDir
;
182 if (kmVec3LengthSq(&temp
) < 0.00005f
) {
183 kmQuaternionRotationAxis(&rotQuat
, &axes
[1], kmPI
);
186 kmQuaternionRotationBetweenVec3(&rotQuat
, &axes
[2], &normDir
, &fallback
);
189 kmQuaternionMultiply(&m_Orientation
, &rotQuat
, &m_Orientation
);
190 kmQuaternionNormalize(&m_Orientation
, &m_Orientation
);
193 m_FrustumNeedsUpdating
= true;
199 kmMat4RotationQuaternion(&transform
, &m_Orientation
);
200 glMultMatrixf(transform
.m_Mat
);
202 transform
.m_Mat
[12] = m_Position
.x
;
203 transform
.m_Mat
[13] = m_Position
.y
;
204 transform
.m_Mat
[14] = m_Position
.z
;
206 glTranslatef(m_Position
.x
, m_Position
.y
, m_Position
.z
);
208 if (m_FrustumNeedsUpdating
) {
209 float model
[16] = {0}; // Array to store the modelview matrix.
210 float proj
[16] = {0}; // Array to store the projection matrix.
212 glGetFloatv(GL_PROJECTION_MATRIX
, proj
);
213 glGetFloatv(GL_MODELVIEW_MATRIX
, model
);
214 m_Frustum
.update_frustum(model
, proj
);
218 void Camera::moveRelative(const Vec3
& vec
) {
219 // Transform the axes of the relative vector by camera's local axes
222 kmQuaternionMultiplyVec3(&trans
, &m_Orientation
, &vec
);
223 m_Position
= m_Position
+ trans
;
224 m_FrustumNeedsUpdating
= true;