You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

262 lines
7.1 KiB

5 years ago
  1. #pragma once
  2. #include "CELLMath.hpp"
  3. namespace CELL
  4. {
  5. class CELLCamera
  6. {
  7. public:
  8. float3 _eye;
  9. float3 _target;
  10. float3 _up;
  11. float3 _right;
  12. float3 _dir;
  13. matrix4 _matView;
  14. matrix4 _matProj;
  15. matrix4 _matWorld;
  16. float2 _viewSize;
  17. public:
  18. CELLCamera(const float3& target = float3(0,0,0),const float3& eye = float3(0,100,100),const float3& right = float3(1,0,0))
  19. {
  20. _viewSize = float2(256,256);
  21. _matView = CELL::matrix4(1);
  22. _matProj = CELL::matrix4(1);
  23. _matWorld = CELL::matrix4(1);
  24. _target = target;
  25. _eye = eye;
  26. _dir = normalize(_target - _eye);
  27. _right = right;
  28. _up = normalize(cross(_right,_dir));
  29. }
  30. ~CELLCamera()
  31. {}
  32. float3 getEye() const
  33. {
  34. return _eye;
  35. }
  36. /**
  37. * ۾λ
  38. */
  39. void setEye(CELL::float3 val)
  40. {
  41. _eye = val;
  42. }
  43. float3 getTarget() const
  44. {
  45. return _target;
  46. }
  47. void setTarget(CELL::float3 val)
  48. {
  49. _target = val;
  50. }
  51. void setRight(CELL::float3 val)
  52. {
  53. _right = val;
  54. }
  55. float3 getUp() const
  56. {
  57. return _up;
  58. }
  59. void setUp(CELL::float3 val)
  60. {
  61. _up = val;
  62. }
  63. float3 getDir() const
  64. {
  65. return _dir;
  66. }
  67. float3 getRight() const
  68. {
  69. return _right;
  70. }
  71. void setViewSize(const float2& viewSize)
  72. {
  73. _viewSize = viewSize;
  74. }
  75. void setViewSize(float x,float y)
  76. {
  77. _viewSize = float2(x,y);
  78. }
  79. float2 getViewSize()
  80. {
  81. return _viewSize;
  82. }
  83. void setProject(const matrix4& proj)
  84. {
  85. _matProj = proj;
  86. }
  87. const matrix4& getProject() const
  88. {
  89. return _matProj;
  90. }
  91. const matrix4& getView() const
  92. {
  93. return _matView;
  94. }
  95. /**
  96. * ͶӰ
  97. */
  98. void ortho( float left, float right, float bottom, float top, float zNear, float zFar )
  99. {
  100. _matProj = CELL::ortho(left,right,bottom,top,zNear,zFar);
  101. }
  102. /**
  103. * ͸ͶӰ
  104. */
  105. void perspective(float fovy, float aspect, float zNear, float zFar)
  106. {
  107. _matProj = CELL::perspective<float>(fovy,aspect,zNear,zFar);
  108. }
  109. /**
  110. * תΪ
  111. */
  112. bool project( const float4& world, float4& screen )
  113. {
  114. screen = (_matProj * _matView * _matWorld) * world;
  115. if (screen.w == 0.0f)
  116. {
  117. return false;
  118. }
  119. screen.x /= screen.w;
  120. screen.y /= screen.w;
  121. screen.z /= screen.w;
  122. // map to range 0 - 1
  123. screen.x = screen.x * 0.5f + 0.5f;
  124. screen.y = screen.y * 0.5f + 0.5f;
  125. screen.z = screen.z * 0.5f + 0.5f;
  126. // map to viewport
  127. screen.x = screen.x * _viewSize.x;
  128. screen.y = _viewSize.y - (screen.y * _viewSize.y);
  129. return true;
  130. }
  131. /**
  132. * תΪ
  133. */
  134. float2 worldToScreen( const float3& world)
  135. {
  136. float4 worlds(world.x,world.y,world.z,1);
  137. float4 screens;
  138. project(worlds,screens);
  139. return float2(screens.x,screens.y);
  140. }
  141. /**
  142. * תΪ
  143. */
  144. float3 screenToWorld(const float2& screen)
  145. {
  146. float4 screens(screen.x,screen.y,0,1);
  147. float4 world;
  148. unProject(screens,world);
  149. return float3(world.x,world.y,world.z);
  150. }
  151. float3 screenToWorld(float x,float y)
  152. {
  153. float4 screens(x,y,0,1);
  154. float4 world;
  155. unProject(screens,world);
  156. return float3(world.x,world.y,world.z);
  157. }
  158. /**
  159. * תΪ
  160. */
  161. bool unProject( const float4& screen, float4& world )
  162. {
  163. float4 v;
  164. v.x = screen.x;
  165. v.y = screen.y;
  166. v.z = screen.z;
  167. v.w = 1.0;
  168. // map from viewport to 0 - 1
  169. v.x = (v.x) /_viewSize.x;
  170. v.y = (_viewSize.y - v.y) /_viewSize.y;
  171. //v.y = (v.y - _viewPort.Y) / _viewPort.Height;
  172. // map to range -1 to 1
  173. v.x = v.x * 2.0f - 1.0f;
  174. v.y = v.y * 2.0f - 1.0f;
  175. v.z = v.z * 2.0f - 1.0f;
  176. CELL::matrix4 inverse = (_matProj * _matView * _matWorld).inverse();
  177. v = v * inverse;
  178. if (v.w == 0.0f)
  179. {
  180. return false;
  181. }
  182. world = v / v.w;
  183. return true;
  184. }
  185. Ray createRayFromScreen(int x,int y)
  186. {
  187. float4 minWorld;
  188. float4 maxWorld;
  189. float4 screen(float(x),float(y),0,1);
  190. float4 screen1(float(x),float(y),1,1);
  191. unProject(screen,minWorld);
  192. unProject(screen1,maxWorld);
  193. Ray ray;
  194. ray.setOrigin(float3(minWorld.x,minWorld.y,minWorld.z));
  195. float3 dir(maxWorld.x - minWorld.x,maxWorld.y - minWorld.y, maxWorld.z - minWorld.z);
  196. ray.setDirection(normalize(dir));
  197. return ray;
  198. }
  199. /**
  200. * ĺĹǽĹ۲ijתһĽǶ
  201. * ı۲ߵλãĿλò
  202. */
  203. virtual void rotateViewY(float angle)
  204. {
  205. _dir = rotateY<float>(_dir, angle);
  206. _up = rotateY<float>(_up, angle);
  207. _right = normalize(cross(_dir,_up));
  208. float len = length(_eye - _target);
  209. _eye = _target - _dir * len;
  210. _matView = CELL::lookAt(_eye,_target,_up);
  211. }
  212. virtual void rotateViewX(float angle)
  213. {
  214. matrix4 mat(1) ;
  215. mat.rotate(angle,_right);
  216. _dir = _dir * mat;
  217. _up = _up * mat;
  218. _right = normalize(cross(_dir,_up));
  219. float len = length(_eye - _target);
  220. _eye = _target - _dir * len;
  221. _matView = CELL::lookAt(_eye,_target,_up);
  222. }
  223. virtual void update()
  224. {
  225. _matView = CELL::lookAt(_eye,_target,_up);
  226. }
  227. };
  228. }