void Camera_GetViewMat(Camera *camera) { mat4x4 R; mat4x4_Rot(R, camera->transform.quaternion); vec3 forward = { 0.0f, 0.0f, -1.0f }; vec3 cam_forward; mat3x3_MulVec3(cam_forward, R, forward); vec3 right = { 1.0f, 0.0f, 0.0f }; vec3 cam_right; mat3x3_MulVec3(cam_right, R, right); vec3 cam_up; vec3_CrossProd(cam_up, cam_right, cam_forward); vec3 target; vec3_Add(target, cam_forward, camera->transform.position); vec3 n; vec3_Sub(n, camera->transform.position, target); vec3_Norm(n, n); vec3 u; vec3_CrossProd(u, cam_up, n); vec3_Norm(u, u); vec3 v; vec3_CrossProd(v, n, u); int i = 0; for(i = 0; i < 3; ++i) camera->view_matrix[0][i] = u[i]; for(i = 0; i < 3; ++i) camera->view_matrix[1][i] = v[i]; for(i = 0; i < 3; ++i) camera->view_matrix[2][i] = n[i]; for(i = 0; i < 3; ++i) camera->view_matrix[3][i] = 0.0f; vec3_Negate(u, u); vec3_Negate(v, v); vec3_Negate(n, n); camera->view_matrix[0][3] = vec3_DotProd(u, camera->transform.position); camera->view_matrix[1][3] = vec3_DotProd(v, camera->transform.position); camera->view_matrix[2][3] = vec3_DotProd(n, camera->transform.position); camera->view_matrix[3][3] = 1.0f; }
Matrix4* mat4_FPSView( const Vector3* eyePos, float yaw, float pitch, Matrix4* out ) { assert( out != NULL ); while( yaw > 360.0f ) yaw -= 360.0f; while( yaw <= 0.0f ) yaw += 360.0f; pitch = ( pitch < -90.0f ) ? -90.0f : pitch; pitch = ( pitch > 90.0f ) ? 90.0f : pitch; float cosPitch = cosf( DEG_TO_RAD( pitch ) ); float sinPitch = sinf( DEG_TO_RAD( pitch ) ); float cosYaw = cosf( DEG_TO_RAD( yaw ) ); float sinYaw = sinf( DEG_TO_RAD( yaw ) ); Vector3 s; Vector3 u; Vector3 f; s.v[0] = cosYaw; s.v[1] = 0.0f; s.v[2] = -sinYaw; u.v[0] = sinYaw * sinPitch; u.v[1] = cosPitch; u.v[2] = cosYaw * sinPitch; f.v[0] = sinYaw * cosPitch; f.v[1] = -sinPitch; f.v[2] = cosPitch * cosYaw; memcpy( out, &IDENTITY_MATRIX, sizeof( Matrix4 ) ); out->m[0] = s.v[0]; out->m[1] = u.v[0]; out->m[2] = f.v[0]; out->m[4] = s.v[1]; out->m[5] = u.v[1]; out->m[6] = f.v[1]; out->m[8] = s.v[2]; out->m[9] = u.v[2]; out->m[10] = f.v[2]; out->m[12] = -vec3_DotProd( &s, eyePos ); out->m[13] = -vec3_DotProd( &u, eyePos ); out->m[14] = -vec3_DotProd( &f, eyePos ); return out; }
Matrix4* mat4_LookAtView( const Vector3* eyePos, const Vector3* lookPos, const Vector3* up, Matrix4* out ) { assert( out != NULL ); Vector3 u, f, s; memcpy( out, &IDENTITY_MATRIX, sizeof( Matrix4 ) ); vec3_Subtract( lookPos, eyePos, &f ); vec3_Normalize( &f ); memcpy( &u, up, sizeof( Vector3 ) ); vec3_Normalize( &u ); vec3_CrossProd( &f, &u, &s ); vec3_Normalize( &s ); vec3_CrossProd( &s, &f, &u ); out->m[0] = s.v[0]; out->m[4] = s.v[1]; out->m[8] = s.v[2]; out->m[1] = u.v[0]; out->m[5] = u.v[1]; out->m[9] = u.v[2]; out->m[2] = -f.v[0]; out->m[6] = -f.v[1]; out->m[10] = -f.v[2]; out->m[12] = -vec3_DotProd( &s, eyePos ); out->m[13] = -vec3_DotProd( &u, eyePos ); out->m[14] = vec3_DotProd( &f, eyePos ); return out; }