camera.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #include "camera.h"
  2. #include "renderer.h"
  3. /*
  4. =======================================================================================================================================
  5. RenderDebug =
  6. =======================================================================================================================================
  7. */
  8. void camera_t::RenderDebug()
  9. {
  10. glPushMatrix();
  11. r::MultMatrix( world_transformation );
  12. const float cam_len = 1.0;
  13. float tmp0 = cam_len / tan( (PI - fovx)*0.5 ) + 0.001;
  14. float tmp1 = cam_len * tan(fovy*0.5) + 0.001;
  15. float points [][3] = {
  16. {0.0, 0.0, 0.0}, // 0: eye point
  17. {-tmp0, tmp1, -cam_len}, // 1: top left
  18. {-tmp0, -tmp1, -cam_len}, // 2: bottom left
  19. {tmp0, -tmp1, -cam_len}, // 3: bottom right
  20. {tmp0, tmp1, -cam_len}, // 4: top right
  21. };
  22. glLineWidth( 2.0 );
  23. r::SetGLState_Wireframe();
  24. glColor3fv( &vec3_t(1.0,0.0,1.0)[0] );
  25. glBegin( GL_LINES );
  26. glVertex3fv( &points[0][0] );
  27. glVertex3fv( &points[1][0] );
  28. glVertex3fv( &points[0][0] );
  29. glVertex3fv( &points[2][0] );
  30. glVertex3fv( &points[0][0] );
  31. glVertex3fv( &points[3][0] );
  32. glVertex3fv( &points[0][0] );
  33. glVertex3fv( &points[4][0] );
  34. glEnd();
  35. glBegin( GL_LINE_STRIP );
  36. glVertex3fv( &points[1][0] );
  37. glVertex3fv( &points[2][0] );
  38. glVertex3fv( &points[3][0] );
  39. glVertex3fv( &points[4][0] );
  40. glVertex3fv( &points[1][0] );
  41. glEnd();
  42. glPopMatrix();
  43. }
  44. /*
  45. =======================================================================================================================================
  46. Render =
  47. =======================================================================================================================================
  48. */
  49. void camera_t::Render()
  50. {
  51. if( !r::show_cameras ) return;
  52. RenderDebug();
  53. }
  54. /*
  55. =======================================================================================================================================
  56. LookAtPoint =
  57. =======================================================================================================================================
  58. */
  59. void camera_t::LookAtPoint( const vec3_t& point )
  60. {
  61. const vec3_t& j = vec3_t( 0.0, 1.0, 0.0 );
  62. vec3_t vdir = (point - local_translation).Normalized();
  63. vec3_t vup = j - vdir * j.Dot(vdir);
  64. vec3_t vside = vdir.Cross( vup );
  65. local_rotation.SetColumns( vside, vup, -vdir );
  66. }
  67. /*
  68. =======================================================================================================================================
  69. CalcLSpaceFrustumPlanes =
  70. =======================================================================================================================================
  71. */
  72. void camera_t::CalcLSpaceFrustumPlanes()
  73. {
  74. // right
  75. lspace_frustum_planes[RIGHT] = plane_t( vec3_t( cos(PI - fovx/2), 0.0f, sin(fovx - PI/2) ), 0.0f );
  76. // left
  77. lspace_frustum_planes[LEFT] = plane_t( vec3_t( -cos(PI - fovx/2), 0.0f, sin(fovx - PI/2) ), 0.0f );
  78. // top
  79. lspace_frustum_planes[TOP] = plane_t( vec3_t( 0.0f, sin( (3*PI-fovy)*0.5 ), cos( (3*PI-fovy)*0.5 ) ), 0.0f );
  80. // bottom
  81. lspace_frustum_planes[BOTTOM] = plane_t( vec3_t( 0.0f, -sin( (3*PI-fovy)*0.5 ), cos( (3*PI-fovy)*0.5 ) ), 0.0f );
  82. // near
  83. lspace_frustum_planes[NEAR] = plane_t( vec3_t( 0.0f, 0.0f, -1.0f ), znear );
  84. // far
  85. lspace_frustum_planes[FAR] = plane_t( vec3_t( 0.0f, 0.0f, 1.0f ), -zfar );
  86. }
  87. /*
  88. =======================================================================================================================================
  89. UpdateWSpaceFrustumPlanes =
  90. =======================================================================================================================================
  91. */
  92. void camera_t::UpdateWSpaceFrustumPlanes()
  93. {
  94. for( uint i=0; i<6; i++ )
  95. wspace_frustum_planes[i] = lspace_frustum_planes[i].Transformed( world_translation, world_rotation, world_scale );
  96. }
  97. /*
  98. =======================================================================================================================================
  99. InsideFrustum =
  100. check if the volume is inside the frustum cliping planes =
  101. =======================================================================================================================================
  102. */
  103. bool camera_t::InsideFrustum( const bvolume_t& bvol )
  104. {
  105. for( uint i=0; i<6; i++ )
  106. if( bvol.PlaneTest( wspace_frustum_planes[i] ) < 0.0 )
  107. return false;
  108. return true;
  109. }
  110. /*
  111. =======================================================================================================================================
  112. UpdateProjectionMatrix =
  113. =======================================================================================================================================
  114. */
  115. void camera_t::UpdateProjectionMatrix()
  116. {
  117. float f = 1.0f/tan( fovy*0.5f ); // f = cot(fovy/2)
  118. projection_mat(0,0) = f*fovy/fovx; // = f/aspect_ratio;
  119. projection_mat(0,1) = 0.0;
  120. projection_mat(0,2) = 0.0;
  121. projection_mat(0,3) = 0.0;
  122. projection_mat(1,0) = 0.0;
  123. projection_mat(1,1) = f;
  124. projection_mat(1,2) = 0.0;
  125. projection_mat(1,3) = 0.0;
  126. projection_mat(2,0) = 0.0;
  127. projection_mat(2,1) = 0.0;
  128. projection_mat(2,2) = (zfar+znear) / (znear-zfar);
  129. projection_mat(2,3) = (2.0f*zfar*znear) / (znear-zfar);
  130. projection_mat(3,0) = 0.0;
  131. projection_mat(3,1) = 0.0;
  132. projection_mat(3,2) = -1.0f;
  133. projection_mat(3,3) = 0.0;
  134. }
  135. /*
  136. =======================================================================================================================================
  137. UpdateViewMatrix =
  138. =======================================================================================================================================
  139. */
  140. void camera_t::UpdateViewMatrix()
  141. {
  142. /* The point at which the camera looks:
  143. vec3_t viewpoint = local_translation + z_axis;
  144. as we know the up vector, we can easily use gluLookAt:
  145. gluLookAt( local_translation.x, local_translation.x, local_translation.z, z_axis.x, z_axis.y, z_axis.z, y_axis.x, y_axis.y, y_axis.z );
  146. */
  147. // The view matrix is: Mview = camera.world_transform.Inverted(). Bus instead of inverting we do the following:
  148. mat3_t cam_inverted_rot = world_rotation.Transposed();
  149. vec3_t cam_inverted_tsl = -( cam_inverted_rot * world_translation );
  150. view_mat = mat4_t( cam_inverted_tsl, cam_inverted_rot );
  151. }
  152. /*
  153. =======================================================================================================================================
  154. Update =
  155. =======================================================================================================================================
  156. */
  157. void camera_t::Update()
  158. {
  159. UpdateViewMatrix();
  160. UpdateWSpaceFrustumPlanes();
  161. }