SimpleCamera.cpp 9.8 KB

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