Camera3D.cpp 14 KB

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