SimpleCamera.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. #include "SimpleCamera.h"
  2. #include "Bullet3Common/b3Vector3.h"
  3. #include "Bullet3Common/b3Quaternion.h"
  4. #include "Bullet3Common/b3Matrix3x3.h"
  5. #include "Bullet3Common/b3Transform.h"
  6. B3_ATTRIBUTE_ALIGNED16(struct) SimpleCameraInternalData
  7. {
  8. SimpleCameraInternalData()
  9. :m_cameraTargetPosition(b3MakeVector3(0,0,0)),
  10. m_cameraDistance(20),
  11. m_cameraUp(b3MakeVector3(0,1,0)),
  12. m_cameraForward(b3MakeVector3(1,0,0)),
  13. m_cameraUpAxis(1),
  14. m_yaw(20),
  15. m_pitch(0),
  16. m_aspect(1),
  17. m_frustumZNear(0.01),
  18. m_frustumZFar(1000),
  19. m_enableVR(false)
  20. {
  21. b3Transform tr;
  22. tr.setIdentity();
  23. tr.getOpenGLMatrix(m_offsetTransformVR);
  24. }
  25. B3_DECLARE_ALIGNED_ALLOCATOR();
  26. B3_ATTRIBUTE_ALIGNED16(float) m_offsetTransformVR[16];
  27. b3Vector3 m_cameraTargetPosition;
  28. float m_cameraDistance;
  29. b3Vector3 m_cameraUp;
  30. b3Vector3 m_cameraForward;
  31. int m_cameraUpAxis;
  32. //the m_cameraPosition is a cached value, recomputed from other values
  33. b3Vector3 m_cameraPosition;
  34. float m_yaw;
  35. float m_pitch;
  36. float m_aspect;
  37. float m_frustumZNear;
  38. float m_frustumZFar;
  39. bool m_enableVR;
  40. float m_viewMatrixVR[16];
  41. float m_projectionMatrixVR[16];
  42. };
  43. SimpleCamera::SimpleCamera()
  44. {
  45. m_data = new SimpleCameraInternalData;
  46. }
  47. SimpleCamera::~SimpleCamera()
  48. {
  49. delete m_data;
  50. }
  51. void SimpleCamera::setVRCamera(const float viewMat[16], const float projectionMatrix[16])
  52. {
  53. m_data->m_enableVR = true;
  54. for (int i=0;i<16;i++)
  55. {
  56. m_data->m_viewMatrixVR[i] = viewMat[i];
  57. m_data->m_projectionMatrixVR[i] = projectionMatrix[i];
  58. }
  59. }
  60. void SimpleCamera::disableVRCamera()
  61. {
  62. m_data->m_enableVR = false;
  63. }
  64. bool SimpleCamera::isVRCamera() const
  65. {
  66. return m_data->m_enableVR ;
  67. }
  68. static void b3CreateFrustum(
  69. float left,
  70. float right,
  71. float bottom,
  72. float top,
  73. float nearVal,
  74. float farVal,
  75. float frustum[16])
  76. {
  77. frustum[0*4+0] = (float(2) * nearVal) / (right - left);
  78. frustum[0*4+1] = float(0);
  79. frustum[0*4+2] = float(0);
  80. frustum[0*4+3] = float(0);
  81. frustum[1*4+0] = float(0);
  82. frustum[1*4+1] = (float(2) * nearVal) / (top - bottom);
  83. frustum[1*4+2] = float(0);
  84. frustum[1*4+3] = float(0);
  85. frustum[2*4+0] = (right + left) / (right - left);
  86. frustum[2*4+1] = (top + bottom) / (top - bottom);
  87. frustum[2*4+2] = -(farVal + nearVal) / (farVal - nearVal);
  88. frustum[2*4+3] = float(-1);
  89. frustum[3*4+0] = float(0);
  90. frustum[3*4+1] = float(0);
  91. frustum[3*4+2] = -(float(2) * farVal * nearVal) / (farVal - nearVal);
  92. frustum[3*4+3] = float(0);
  93. }
  94. #if 0
  95. static void b3CreateDiagonalMatrix(float value, float result[4][4])
  96. {
  97. for (int i=0;i<4;i++)
  98. {
  99. for (int j=0;j<4;j++)
  100. {
  101. if (i==j)
  102. {
  103. result[i][j] = value;
  104. } else
  105. {
  106. result[i][j] = 0.f;
  107. }
  108. }
  109. }
  110. }
  111. static void b3CreateOrtho(float left, float right, float bottom, float top, float zNear, float zFar, float result[4][4])
  112. {
  113. b3CreateDiagonalMatrix(1.f,result);
  114. result[0][0] = 2.f / (right - left);
  115. result[1][1] = 2.f / (top - bottom);
  116. result[2][2] = - 2.f / (zFar - zNear);
  117. result[3][0] = - (right + left) / (right - left);
  118. result[3][1] = - (top + bottom) / (top - bottom);
  119. result[3][2] = - (zFar + zNear) / (zFar - zNear);
  120. }
  121. #endif
  122. static void b3CreateLookAt(const b3Vector3& eye, const b3Vector3& center,const b3Vector3& up, float result[16])
  123. {
  124. b3Vector3 f = (center - eye).normalized();
  125. b3Vector3 u = up.normalized();
  126. b3Vector3 s = (f.cross(u)).normalized();
  127. u = s.cross(f);
  128. result[0*4+0] = s.x;
  129. result[1*4+0] = s.y;
  130. result[2*4+0] = s.z;
  131. result[0*4+1] = u.x;
  132. result[1*4+1] = u.y;
  133. result[2*4+1] = u.z;
  134. result[0*4+2] =-f.x;
  135. result[1*4+2] =-f.y;
  136. result[2*4+2] =-f.z;
  137. result[0*4+3] = 0.f;
  138. result[1*4+3] = 0.f;
  139. result[2*4+3] = 0.f;
  140. result[3*4+0] = -s.dot(eye);
  141. result[3*4+1] = -u.dot(eye);
  142. result[3*4+2] = f.dot(eye);
  143. result[3*4+3] = 1.f;
  144. }
  145. void SimpleCamera::setCameraUpAxis(int upAxis)
  146. {
  147. m_data->m_cameraUpAxis = upAxis;
  148. update();
  149. }
  150. int SimpleCamera::getCameraUpAxis() const
  151. {
  152. return m_data->m_cameraUpAxis;
  153. }
  154. void SimpleCamera::update()
  155. {
  156. int forwardAxis(-1);
  157. switch (m_data->m_cameraUpAxis)
  158. {
  159. case 1:
  160. forwardAxis = 2;
  161. m_data->m_cameraUp = b3MakeVector3(0,1,0);
  162. //gLightPos = b3MakeVector3(-50.f,100,30);
  163. break;
  164. case 2:
  165. forwardAxis = 1;
  166. m_data->m_cameraUp = b3MakeVector3(0,0,1);
  167. //gLightPos = b3MakeVector3(-50.f,30,100);
  168. break;
  169. default:
  170. {
  171. //b3Assert(0);
  172. return;
  173. }
  174. };
  175. b3Vector3 eyePos = b3MakeVector3(0,0,0);
  176. eyePos[forwardAxis] = -m_data->m_cameraDistance;
  177. m_data->m_cameraForward = b3MakeVector3(eyePos[0],eyePos[1],eyePos[2]);
  178. if (m_data->m_cameraForward.length2() < B3_EPSILON)
  179. {
  180. m_data->m_cameraForward.setValue(1.f,0.f,0.f);
  181. } else
  182. {
  183. m_data->m_cameraForward.normalize();
  184. }
  185. // m_azi=m_azi+0.01;
  186. b3Scalar rele = m_data->m_yaw * b3Scalar(0.01745329251994329547);// rads per deg
  187. b3Scalar razi = m_data->m_pitch * b3Scalar(0.01745329251994329547);// rads per deg
  188. b3Quaternion rot(m_data->m_cameraUp,razi);
  189. b3Vector3 right = m_data->m_cameraUp.cross(m_data->m_cameraForward);
  190. b3Quaternion roll(right,-rele);
  191. eyePos = b3Matrix3x3(rot) * b3Matrix3x3(roll) * eyePos;
  192. m_data->m_cameraPosition = eyePos;
  193. m_data->m_cameraPosition+= m_data->m_cameraTargetPosition;
  194. }
  195. void SimpleCamera::getCameraProjectionMatrix(float projectionMatrix[16]) const
  196. {
  197. if (m_data->m_enableVR)
  198. {
  199. for (int i=0;i<16;i++)
  200. {
  201. projectionMatrix[i] = m_data->m_projectionMatrixVR[i];
  202. }
  203. } else
  204. {
  205. b3CreateFrustum(-m_data->m_aspect * m_data->m_frustumZNear, m_data->m_aspect * m_data->m_frustumZNear, -m_data->m_frustumZNear,m_data->m_frustumZNear, m_data->m_frustumZNear, m_data->m_frustumZFar,projectionMatrix);
  206. }
  207. }
  208. void SimpleCamera::setVRCameraOffsetTransform(const float offset[16])
  209. {
  210. for (int i=0;i<16;i++)
  211. {
  212. m_data->m_offsetTransformVR[i] = offset[i];
  213. }
  214. }
  215. void SimpleCamera::getCameraViewMatrix(float viewMatrix[16]) const
  216. {
  217. if (m_data->m_enableVR)
  218. {
  219. for (int i=0;i<16;i++)
  220. {
  221. b3Transform tr;
  222. tr.setFromOpenGLMatrix(m_data->m_viewMatrixVR);
  223. b3Transform shift=b3Transform::getIdentity();
  224. shift.setFromOpenGLMatrix(m_data->m_offsetTransformVR);
  225. tr = tr*shift;
  226. tr.getOpenGLMatrix(viewMatrix);
  227. //viewMatrix[i] = m_data->m_viewMatrixVR[i];
  228. }
  229. } else
  230. {
  231. b3CreateLookAt(m_data->m_cameraPosition,m_data->m_cameraTargetPosition,m_data->m_cameraUp,viewMatrix);
  232. }
  233. }
  234. void SimpleCamera::getCameraTargetPosition(double pos[3]) const
  235. {
  236. pos[0] =m_data->m_cameraTargetPosition[0];
  237. pos[1] =m_data->m_cameraTargetPosition[1];
  238. pos[2] =m_data->m_cameraTargetPosition[2];
  239. }
  240. void SimpleCamera::getCameraPosition(double pos[3]) const
  241. {
  242. pos[0] =m_data->m_cameraPosition[0];
  243. pos[1] =m_data->m_cameraPosition[1];
  244. pos[2] =m_data->m_cameraPosition[2];
  245. }
  246. void SimpleCamera::getCameraTargetPosition(float pos[3]) const
  247. {
  248. pos[0] =m_data->m_cameraTargetPosition[0];
  249. pos[1] =m_data->m_cameraTargetPosition[1];
  250. pos[2] =m_data->m_cameraTargetPosition[2];
  251. }
  252. void SimpleCamera::getCameraPosition(float pos[3]) const
  253. {
  254. pos[0] =m_data->m_cameraPosition[0];
  255. pos[1] =m_data->m_cameraPosition[1];
  256. pos[2] =m_data->m_cameraPosition[2];
  257. }
  258. void SimpleCamera::setCameraTargetPosition(float x,float y,float z)
  259. {
  260. m_data->m_cameraTargetPosition.setValue(x,y,z);
  261. update();
  262. }
  263. float SimpleCamera::getCameraDistance() const
  264. {
  265. return m_data->m_cameraDistance;
  266. }
  267. void SimpleCamera::setCameraDistance(float dist)
  268. {
  269. m_data->m_cameraDistance = dist;
  270. update();
  271. }
  272. void SimpleCamera::setCameraUpVector(float x,float y ,float z)
  273. {
  274. m_data->m_cameraUp.setValue(x,y,z);
  275. update();
  276. }
  277. void SimpleCamera::getCameraUpVector(float up[3]) const
  278. {
  279. up[0] = float(m_data->m_cameraUp[0]);
  280. up[1] = float(m_data->m_cameraUp[1]);
  281. up[2] = float(m_data->m_cameraUp[2]);
  282. }
  283. void SimpleCamera::setCameraYaw(float yaw)
  284. {
  285. m_data->m_yaw = yaw;
  286. update();
  287. }
  288. float SimpleCamera::getCameraYaw() const
  289. {
  290. return m_data->m_yaw;
  291. }
  292. void SimpleCamera::setCameraPitch(float pitch)
  293. {
  294. m_data->m_pitch = pitch;
  295. update();
  296. }
  297. void SimpleCamera::setAspectRatio(float ratio)
  298. {
  299. m_data->m_aspect = ratio;
  300. update();
  301. }
  302. float SimpleCamera::getCameraPitch() const
  303. {
  304. return m_data->m_pitch;
  305. }
  306. float SimpleCamera::getAspectRatio() const
  307. {
  308. return m_data->m_aspect;
  309. }