Camera3D.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. #include "pch.h"
  2. #include "Camera3D.h"
  3. #include "CppUnitTest.h"
  4. #include "DX12GraphicsApi.h"
  5. #include "Globals.h"
  6. #include "Model3D.h"
  7. #include "RenderThread.h"
  8. #include "Screen.h"
  9. #include "Window.h"
  10. #include "World3D.h"
  11. using namespace Microsoft::VisualStudio::CppUnitTestFramework;
  12. namespace FrameworkTests
  13. {
  14. TEST_CLASS (Cam3Tests)
  15. {
  16. public:
  17. TEST_METHOD (TestProjection)
  18. {
  19. Framework::Cam3D cam;
  20. cam.setPosition(Framework::Vec3<float>(0, 0, 0));
  21. cam.setRotation(Framework::Vec3<float>(0, 0, 0));
  22. Framework::Vec3<float> target(0, 1000, 0);
  23. cam.setViewDirection(target);
  24. Framework::Mat4<float> projection = cam.getProjectionMatrix();
  25. Framework::Mat4<float> inverse = cam.getInverseProjectionMatrix();
  26. Framework::Mat4<float> view = cam.getViewMatrix();
  27. Framework::Mat4<float> iView = cam.getInverseViewMatrix();
  28. for (int i = 0; i < 10; i++)
  29. {
  30. for (int j = 0; j < 10; j++)
  31. {
  32. Framework::Vec4<float> origin(0, 0, 0, 1.f);
  33. Framework::Vec4<float> target(
  34. i / 5.f - 1.f, j / 5.f - 1.f, -1.f, 1.f);
  35. Framework::Vec4<float> transformedOrigin = iView * origin;
  36. Framework::Vec4<float> transformedTarget
  37. = iView * (inverse * target);
  38. Framework::Vec4<float> transformedDirection
  39. = transformedTarget - transformedOrigin;
  40. }
  41. }
  42. }
  43. TEST_METHOD (TestRaytracing)
  44. {
  45. Framework::initFramework();
  46. Framework::setDebugDX(1);
  47. Framework::NativeWindow window;
  48. WNDCLASS wc = Framework::F_Normal(GetModuleHandle(0));
  49. wc.lpszClassName = "Factory Craft";
  50. window.create(WS_POPUPWINDOW, wc);
  51. Framework::Monitor m = Framework::getMonitor(0);
  52. window.setBounds(Framework::Point(m.x, m.y),
  53. Framework::Point(m.width, m.height));
  54. window.setDisplayMode(SW_SHOWNORMAL);
  55. window.setPreCloseAction([&window](void* p, void* f) {
  56. Framework::StopMessageLoop(window.getWindowHandle());
  57. });
  58. window.setMouseAction(Framework::_ret1ME);
  59. window.setKeyboardAction(Framework::_ret1TE);
  60. Framework::DirectX12* api = new Framework::DirectX12();
  61. Framework::Screen3D screen(
  62. dynamic_cast<Framework::NativeWindow*>(window.getThis()), api);
  63. screen.setHandleUserInputsOnTick(0);
  64. window.setScreen(
  65. dynamic_cast<Framework::Screen*>(screen.getThis()));
  66. screen.setFillColor(0);
  67. screen.setTestRend(0);
  68. Framework::Cam3D cam;
  69. cam.setPosition({0.f, 0.f, 0.f});
  70. Framework::Vec3<float> target(0, 1000, 0);
  71. cam.setViewDirection(target);
  72. Framework::World3D world;
  73. Framework::Model3DData* data
  74. = screen.zGraphicsApi()->createModel("cube");
  75. data->setAmbientFactor(0.f);
  76. data->setDiffusFactor(1.f);
  77. data->setSpecularFactor(0.f);
  78. float size = 1;
  79. float left, right, top, bottom;
  80. // Calculate the screen coordinates of the left side of the bitmap.
  81. right = (float)((-size / 2.0));
  82. // Calculate the screen coordinates of the right side of the bitmap.
  83. left = right + (float)size;
  84. // Calculate the screen coordinates of the top of the bitmap.
  85. top = (float)(size / 2.0);
  86. // Calculate the screen coordinates of the bottom of the bitmap.
  87. bottom = top - (float)size;
  88. float front = -size / 2;
  89. float back = front + size;
  90. Framework::Vertex3D* vertecies = new Framework::Vertex3D[24];
  91. for (int i = 0; i < 24; i++)
  92. vertecies[i].knochenId = 0;
  93. // front side
  94. vertecies[0].pos = Framework::Vec3<float>(left, front, top);
  95. vertecies[0].tPos = Framework::Vec2<float>(0.f, 0.f);
  96. vertecies[1].pos = Framework::Vec3<float>(right, front, top);
  97. vertecies[1].tPos = Framework::Vec2<float>(1.f, 0.f);
  98. vertecies[2].pos = Framework::Vec3<float>(left, front, bottom);
  99. vertecies[2].tPos = Framework::Vec2<float>(0.f, 1.f);
  100. vertecies[3].pos = Framework::Vec3<float>(right, front, bottom);
  101. vertecies[3].tPos = Framework::Vec2<float>(1.f, 1.f);
  102. // back side
  103. vertecies[4].pos = Framework::Vec3<float>(right, back, top);
  104. vertecies[4].tPos = Framework::Vec2<float>(0.0f, 0.0f);
  105. vertecies[5].pos = Framework::Vec3<float>(left, back, top);
  106. vertecies[5].tPos = Framework::Vec2<float>(1.0f, 0.0f);
  107. vertecies[6].pos = Framework::Vec3<float>(right, back, bottom);
  108. vertecies[6].tPos = Framework::Vec2<float>(0.0f, 1.0f);
  109. vertecies[7].pos = Framework::Vec3<float>(left, back, bottom);
  110. vertecies[7].tPos = Framework::Vec2<float>(1.0f, 1.0f);
  111. // left side
  112. vertecies[8].pos = Framework::Vec3<float>(left, back, top);
  113. vertecies[8].tPos = Framework::Vec2<float>(0.f, 0.f);
  114. vertecies[9].pos = Framework::Vec3<float>(left, front, top);
  115. vertecies[9].tPos = Framework::Vec2<float>(1.f, 0.f);
  116. vertecies[10].pos = Framework::Vec3<float>(left, back, bottom);
  117. vertecies[10].tPos = Framework::Vec2<float>(0.f, 1.f);
  118. vertecies[11].pos = Framework::Vec3<float>(left, front, bottom);
  119. vertecies[11].tPos = Framework::Vec2<float>(1.f, 1.f);
  120. // right side
  121. vertecies[12].pos = Framework::Vec3<float>(right, front, top);
  122. vertecies[12].tPos = Framework::Vec2<float>(0.0f, 0.0f);
  123. vertecies[13].pos = Framework::Vec3<float>(right, back, top);
  124. vertecies[13].tPos = Framework::Vec2<float>(1.0f, 0.0f);
  125. vertecies[14].pos = Framework::Vec3<float>(right, front, bottom);
  126. vertecies[14].tPos = Framework::Vec2<float>(0.0f, 1.0f);
  127. vertecies[15].pos = Framework::Vec3<float>(right, back, bottom);
  128. vertecies[15].tPos = Framework::Vec2<float>(1.0f, 1.0f);
  129. // top side
  130. vertecies[16].pos = Framework::Vec3<float>(left, back, top);
  131. vertecies[16].tPos = Framework::Vec2<float>(0.f, 0.f);
  132. vertecies[17].pos = Framework::Vec3<float>(right, back, top);
  133. vertecies[17].tPos = Framework::Vec2<float>(1.f, 0.f);
  134. vertecies[18].pos = Framework::Vec3<float>(left, front, top);
  135. vertecies[18].tPos = Framework::Vec2<float>(0.f, 1.f);
  136. vertecies[19].pos = Framework::Vec3<float>(right, front, top);
  137. vertecies[19].tPos = Framework::Vec2<float>(1.f, 1.f);
  138. // botom side
  139. vertecies[20].pos = Framework::Vec3<float>(left, front, bottom);
  140. vertecies[20].tPos = Framework::Vec2<float>(0.0f, 0.0f);
  141. vertecies[21].pos = Framework::Vec3<float>(right, front, bottom);
  142. vertecies[21].tPos = Framework::Vec2<float>(1.0f, 0.0f);
  143. vertecies[22].pos = Framework::Vec3<float>(left, back, bottom);
  144. vertecies[22].tPos = Framework::Vec2<float>(0.0f, 1.0f);
  145. vertecies[23].pos = Framework::Vec3<float>(right, back, bottom);
  146. vertecies[23].tPos = Framework::Vec2<float>(1.0f, 1.0f);
  147. data->setVertecies(vertecies, 24);
  148. // the order of the polygons has to be NORTH (front), EAST (left),
  149. // SOUTH (back), WEST (right), TOP, BOTTOM according to the Area
  150. // definition front side
  151. Framework::Polygon3D* p
  152. = new Framework::Polygon3D(); // looking from (0,0,0) to (1,0,0)
  153. // to see this side
  154. p->indexAnz = 6;
  155. p->indexList = new int[p->indexAnz];
  156. p->indexList[0] = 0;
  157. p->indexList[1] = 1;
  158. p->indexList[2] = 2;
  159. p->indexList[3] = 1;
  160. p->indexList[4] = 3;
  161. p->indexList[5] = 2;
  162. data->addPolygon(p);
  163. // left side
  164. p = new Framework::Polygon3D(); // looking from (0,0,0) to (0,1,0)
  165. // to see this
  166. // side
  167. p->indexAnz = 6;
  168. p->indexList = new int[p->indexAnz];
  169. p->indexList[0] = 0 + 8;
  170. p->indexList[1] = 1 + 8;
  171. p->indexList[2] = 2 + 8;
  172. p->indexList[3] = 1 + 8;
  173. p->indexList[4] = 3 + 8;
  174. p->indexList[5] = 2 + 8;
  175. data->addPolygon(p);
  176. // back side
  177. p = new Framework::Polygon3D(); // looking from (0,0,0) to (-1,0,0)
  178. // to see this
  179. // side
  180. p->indexAnz = 6;
  181. p->indexList = new int[p->indexAnz];
  182. p->indexList[0] = 0 + 4;
  183. p->indexList[1] = 1 + 4;
  184. p->indexList[2] = 2 + 4;
  185. p->indexList[3] = 1 + 4;
  186. p->indexList[4] = 3 + 4;
  187. p->indexList[5] = 2 + 4;
  188. data->addPolygon(p);
  189. // right side
  190. p = new Framework::Polygon3D(); // looking from (0,0,0) to (0,-1,0)
  191. // to see this
  192. // side
  193. p->indexAnz = 6;
  194. p->indexList = new int[p->indexAnz];
  195. p->indexList[0] = 0 + 12;
  196. p->indexList[1] = 1 + 12;
  197. p->indexList[2] = 2 + 12;
  198. p->indexList[3] = 1 + 12;
  199. p->indexList[4] = 3 + 12;
  200. p->indexList[5] = 2 + 12;
  201. data->addPolygon(p);
  202. // top side
  203. p = new Framework::Polygon3D(); // looking from (0,0,0) to (0,0,-1)
  204. // to see this
  205. // side
  206. p->indexAnz = 6;
  207. p->indexList = new int[p->indexAnz];
  208. p->indexList[0] = 0 + 16;
  209. p->indexList[1] = 1 + 16;
  210. p->indexList[2] = 2 + 16;
  211. p->indexList[3] = 1 + 16;
  212. p->indexList[4] = 3 + 16;
  213. p->indexList[5] = 2 + 16;
  214. data->addPolygon(p);
  215. // botom side
  216. p = new Framework::Polygon3D(); // looking from (0,0,0) to (0,0,1)
  217. // to see this
  218. // side
  219. p->indexAnz = 6;
  220. p->indexList = new int[p->indexAnz];
  221. p->indexList[0] = 0 + 20;
  222. p->indexList[1] = 1 + 20;
  223. p->indexList[2] = 2 + 20;
  224. p->indexList[3] = 1 + 20;
  225. p->indexList[4] = 3 + 20;
  226. p->indexList[5] = 2 + 20;
  227. data->addPolygon(p);
  228. data->calculateNormals();
  229. Framework::Array<Framework::Model3D*> cubes;
  230. std::function<void(int, int, int)> addCube
  231. = [&cubes, &world, &data](int x, int y, int z) {
  232. Framework::Model3D* cube = new Framework::Model3D();
  233. cube->setModelData(dynamic_cast<Framework::Model3DData*>(
  234. data->getThis()));
  235. cube->setPosition(x, y, z);
  236. cube->setSize(5 + rand() % 5);
  237. cube->setRotation(
  238. rand() % 10 / 5, rand() % 10 / 5, rand() % 10 / 5);
  239. world.addDrawable(cube);
  240. cubes.add(cube);
  241. };
  242. for (int i = 0; i < 10000; i++)
  243. {
  244. addCube(rand() % 1000 - 500,
  245. rand() % 1000 - 500,
  246. rand() % 1000 - 500);
  247. }
  248. cam.setWorld(dynamic_cast<Framework::World3D*>(world.getThis()));
  249. cam.addStyle(Framework::Cam3D::Style::Movable
  250. | Framework::Cam3D::Style::Rotatable
  251. | Framework::Cam3D::Style::Zoomable
  252. | Framework::Cam3D::Style::Tick);
  253. cam.setMovementSpeed(0.1f);
  254. screen.addKamera(dynamic_cast<Framework::Cam3D*>(cam.getThis()));
  255. Framework::RenderTh rTh;
  256. rTh.setMaxFps(-1);
  257. rTh.setQuiet(0);
  258. rTh.setMaxFps(-1);
  259. rTh.setScreen(dynamic_cast<Framework::Screen*>(screen.getThis()));
  260. double sum = 0;
  261. rTh.setTickFunktion(
  262. [&cubes, &sum, &addCube](void* p, void* f, double tick) {
  263. for (Framework::Model3D* cube : cubes)
  264. {
  265. cube->setRotationX(cube->getXRotation() + tick * 2);
  266. cube->setRotationY(cube->getXRotation() + tick / 5);
  267. cube->setRotationZ(cube->getXRotation() + tick / 25);
  268. cube->setSize(
  269. cube->getSize() + tick * 5 * (sum > 2.5 ? 1 : -1));
  270. }
  271. sum += tick;
  272. if (sum > 5)
  273. {
  274. sum -= 5;
  275. /* addCube(rand() % 1000 - 500,
  276. rand() % 1000 - 500,
  277. rand() % 1000 - 500);*/
  278. }
  279. });
  280. rTh.beginn();
  281. Framework::StartMessageLoop();
  282. rTh.terminate();
  283. }
  284. };
  285. } // namespace FrameworkTests