threeDGameExample.h 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  1. #pragma once
  2. #include <gl2d/gl2d.h>
  3. #include <gl3d.h>
  4. #include <imgui.h>
  5. #include <baseContainer.h>
  6. #include <shortcutApi/shortcutApi.h>
  7. #include <pikaSizes.h>
  8. #include <imgui_spinner.h>
  9. #include <imfilebrowser.h>
  10. #include <engineLibraresSupport/engineGL3DSupport.h>
  11. #include <containers/minecraftDungeons/mcDungeonsgameplay.h>
  12. #include <sushi/sushi.h>
  13. #include <engineLibraresSupport/sushi/engineSushiSupport.h>
  14. //todo engine: don't remove notifications untill the user can see them (the engine has focus)
  15. struct ThreeDGameExample: public Container
  16. {
  17. enum Animations
  18. {
  19. attack,
  20. idle,
  21. run,
  22. run2,
  23. zombieAttack,
  24. zombieIdle,
  25. zombieRun,
  26. };
  27. bool player2joined = 0;
  28. //todo user can request imgui ids; shortcut manager context; allocators
  29. static ContainerStaticInfo containerInfo()
  30. {
  31. ContainerStaticInfo info = {};
  32. info.defaultHeapMemorySize = pika::MB(1500); //todo option to use global allocator
  33. info.requestImguiFbo = true;
  34. info.requestImguiIds = 1;
  35. return info;
  36. }
  37. struct Enemy
  38. {
  39. McDungeonsGameplay::PhysicsComponent physics;
  40. gl3d::Entity entity;
  41. float life = 1;
  42. float attackCulldown = 0.f;
  43. Enemy() {};
  44. Enemy(int x, int z) { physics.position = {x,z}; physics.lastPos = {x,z}; };
  45. };
  46. struct PlayerModel
  47. {
  48. gl3d::Entity head;
  49. gl3d::Entity torso;
  50. gl3d::Entity hands[2];
  51. gl3d::Entity legs[2];
  52. float armAngle = 0;
  53. gl3d::PointLight pointLight;
  54. gl3d::SpotLight spotLight;
  55. McDungeonsGameplay::PhysicsComponent physics;
  56. };
  57. PlayerModel playerModel1;
  58. PlayerModel playerModel2;
  59. std::vector<Enemy> enemies;
  60. float enemySpawnTimer = 5;
  61. gl3d::Renderer3D renderer;
  62. gl3d::Model groundModel;
  63. gl3d::Entity groundEntity;
  64. bool first = 1;
  65. int killed = 0;
  66. sushi::SushyContext sushyContext;
  67. pika::gl3d::General3DEditor editor;
  68. gl2d::Renderer2D renderer2d;
  69. gl2d::Font font;
  70. pika::GL::PikaFramebuffer frameBuffers[2];
  71. //todo add this in the renderer
  72. //todo add a default material if material left blank or something
  73. gl3d::Model createCubeModel(gl3d::Renderer3D &renderer, glm::vec3 color, float metallic = 1)
  74. {
  75. static float uv = 1;
  76. static float cubePositionsNormals[] = {
  77. -1.0f, +1.0f, +1.0f, // 0
  78. +0.0f, +1.0f, +0.0f, // Normal
  79. 0, 0, //uv
  80. //0,0,0, //tangent
  81. //0,0,0, //btangent
  82. +1.0f, +1.0f, +1.0f, // 1
  83. +0.0f, +1.0f, +0.0f, // Normal
  84. 1 * uv, 0, //uv
  85. //0,0,0, //tangent
  86. //0,0,0, //btangent
  87. +1.0f, +1.0f, -1.0f, // 2
  88. +0.0f, +1.0f, +0.0f, // Normal
  89. 1 * uv, 1 * uv, //uv
  90. //0,0,0, //tangent
  91. //0,0,0, //btangent
  92. -1.0f, +1.0f, -1.0f, // 3
  93. +0.0f, +1.0f, +0.0f, // Normal
  94. 0, 1 * uv, //uv
  95. //0,0,0, //tangent
  96. //0,0,0, //btangent
  97. -1.0f, +1.0f, -1.0f, // 4
  98. 0.0f, +0.0f, -1.0f, // Normal
  99. 0, 1 * uv, //uv
  100. //0,0,0, //tangent
  101. //0,0,0, //btangent
  102. +1.0f, +1.0f, -1.0f, // 5
  103. 0.0f, +0.0f, -1.0f, // Normal
  104. 1 * uv, 1 * uv, //uv
  105. //0,0,0, //tangent
  106. //0,0,0, //btangent
  107. +1.0f, -1.0f, -1.0f, // 6
  108. 0.0f, +0.0f, -1.0f, // Normal
  109. 1 * uv, 0, //uv
  110. //0,0,0, //tangent
  111. //0,0,0, //btangent
  112. -1.0f, -1.0f, -1.0f, // 7
  113. 0.0f, +0.0f, -1.0f, // Normal
  114. 0, 0, //uv
  115. //0,0,0, //tangent
  116. //0,0,0, //btangent
  117. +1.0f, +1.0f, -1.0f, // 8
  118. +1.0f, +0.0f, +0.0f, // Normal
  119. 1 * uv, 0, //uv
  120. //0,0,0, //tangent
  121. //0,0,0, //btangent
  122. +1.0f, +1.0f, +1.0f, // 9
  123. +1.0f, +0.0f, +0.0f, // Normal
  124. 1 * uv, 1 * uv, //uv
  125. //0,0,0, //tangent
  126. //0,0,0, //btangent
  127. +1.0f, -1.0f, +1.0f, // 10
  128. +1.0f, +0.0f, +0.0f, // Normal
  129. 0, 1 * uv, //uv
  130. //0,0,0, //tangent
  131. //0,0,0, //btangent
  132. +1.0f, -1.0f, -1.0f, // 11
  133. +1.0f, +0.0f, +0.0f, // Normal
  134. 0, 0, //uv
  135. //0,0,0, //tangent
  136. //0,0,0, //btangent
  137. -1.0f, +1.0f, +1.0f, // 12
  138. -1.0f, +0.0f, +0.0f, // Normal
  139. 1 * uv, 1 * uv, //uv
  140. //0,0,0, //tangent
  141. //0,0,0, //btangent
  142. -1.0f, +1.0f, -1.0f, // 13
  143. -1.0f, +0.0f, +0.0f, // Normal
  144. 1 * uv, 0, //uv
  145. //0,0,0, //tangent
  146. //0,0,0, //btangent
  147. -1.0f, -1.0f, -1.0f, // 14
  148. -1.0f, +0.0f, +0.0f, // Normal
  149. 0, 0, //uv
  150. //0,0,0, //tangent
  151. //0,0,0, //btangent
  152. -1.0f, -1.0f, +1.0f, // 15
  153. -1.0f, +0.0f, +0.0f, // Normal
  154. 0, 1 * uv, //uv
  155. //0,0,0, //tangent
  156. //0,0,0, //btangent
  157. +1.0f, +1.0f, +1.0f, // 16
  158. +0.0f, +0.0f, +1.0f, // Normal
  159. 1 * uv, 1 * uv, //uv
  160. //0,0,0, //tangent
  161. //0,0,0, //btangent
  162. -1.0f, +1.0f, +1.0f, // 17
  163. +0.0f, +0.0f, +1.0f, // Normal
  164. 0, 1 * uv, //uv
  165. //0, 0, 0, //tangent
  166. //0, 0, 0, //btangent
  167. -1.0f, -1.0f, +1.0f, // 18
  168. +0.0f, +0.0f, +1.0f, // Normal
  169. 0, 0, //uv
  170. //0, 0, 0, //tangent
  171. //0, 0, 0, //btangent
  172. +1.0f, -1.0f, +1.0f, // 19
  173. +0.0f, +0.0f, +1.0f, // Normal
  174. 1 * uv, 0, //uv
  175. //0, 0, 0, //tangent
  176. //0, 0, 0, //btangent
  177. +1.0f, -1.0f, -1.0f, // 20
  178. +0.0f, -1.0f, +0.0f, // Normal
  179. 1 * uv, 0, //uv
  180. //0, 0, 0, //tangent
  181. //0, 0, 0, //btangent
  182. -1.0f, -1.0f, -1.0f, // 21
  183. +0.0f, -1.0f, +0.0f, // Normal
  184. 0, 0, //uv
  185. //0, 0, 0, //tangent
  186. //0, 0, 0, //btangent
  187. -1.0f, -1.0f, +1.0f, // 22
  188. +0.0f, -1.0f, +0.0f, // Normal
  189. 0, 1 * uv, //uv
  190. //0, 0, 0, //tangent
  191. //0, 0, 0, //btangent
  192. +1.0f, -1.0f, +1.0f, // 23
  193. +0.0f, -1.0f, +0.0f, // Normal
  194. 1 * uv, 1 * uv, //uv
  195. //0, 0, 0, //tangent
  196. //0, 0, 0, //btangent
  197. };
  198. static unsigned int cubeIndices[] = {
  199. 0, 1, 2, 0, 2, 3, // Top
  200. 4, 5, 6, 4, 6, 7, // Back
  201. 8, 9, 10, 8, 10, 11, // Right
  202. 12, 13, 14, 12, 14, 15, // Left
  203. 16, 17, 18, 16, 18, 19, // Front
  204. 20, 22, 21, 20, 23, 22, // Bottom
  205. };
  206. auto material = renderer.createMaterial(0, {color,1}, 0, metallic);
  207. return renderer.createModelFromData(material, "cube",
  208. sizeof(cubePositionsNormals)/sizeof(cubePositionsNormals[0]), cubePositionsNormals,
  209. sizeof(cubeIndices)/ sizeof(cubeIndices[0]), cubeIndices);
  210. }
  211. void createPlayerEntity(gl3d::Renderer3D &renderer, glm::vec3 color, PlayerModel& playerModel)
  212. {
  213. auto cube = createCubeModel(renderer, color, 0);
  214. playerModel.torso = renderer.createEntity(cube, {}, false, true, false);
  215. playerModel.legs[0] = renderer.createEntity(cube, {}, false, true, false);
  216. playerModel.legs[1] = renderer.createEntity(cube, {}, false, true, false);
  217. playerModel.hands[0] = renderer.createEntity(cube, {}, false, true, false);
  218. playerModel.hands[1] = renderer.createEntity(cube, {}, false, true, false);
  219. playerModel.head = renderer.createEntity(cube, {}, false, true, false);
  220. playerModel.pointLight = renderer.createPointLight({}, glm::vec3{1.f}, 20, 1);
  221. playerModel.spotLight = renderer.createSpotLight({}, glm::radians(50.f), {0,0}, 40, 10, glm::vec3(2.f));
  222. }
  223. gl3d::Model createPlane(gl3d::Renderer3D &renderer)
  224. {
  225. float uv = 10;
  226. float size = 200;
  227. std::vector<unsigned int> ind = {0, 1, 2, 0, 2, 3};
  228. std::vector<float> topVer = {
  229. -1.0f * size, +0.0f, +1.0f * size, // 0
  230. +0.0f, +1.0f, +0.0f, // Normal
  231. 0, 0, //uv
  232. +1.0f * size, +0.0f, +1.0f * size, // 1
  233. +0.0f, +1.0f, +0.0f, // Normal
  234. 1 * uv, 0, //uv
  235. +1.0f * size, +0.0f, -1.0f * size, // 2
  236. +0.0f, +1.0f, +0.0f, // Normal
  237. 1 * uv, 1 * uv, //uv
  238. -1.0f * size, +0.0f, -1.0f * size, // 3
  239. +0.0f, +1.0f, +0.0f, // Normal
  240. 0, 1 * uv, //uv
  241. };
  242. //auto material = renderer.createMaterial(0, {1,1,1,1}, 0, 1);
  243. auto material = renderer.loadMaterial(PIKA_RESOURCES_PATH "materials/rustedIron.mtl", gl3d::maxQuality);
  244. if (material.empty())
  245. {
  246. material.push_back(renderer.createMaterial(0, {1,1,1,1}, 0, 1));
  247. }
  248. return renderer.createModelFromData(material[0], "plane",
  249. topVer.size(), topVer.data(), ind.size(),
  250. ind.data());
  251. }
  252. void createStalpi()
  253. {
  254. auto cube = createCubeModel(renderer, {0.2,0.4,0.8}, 0);
  255. bool flip = 0;
  256. for (int x = -100; x <= 100; x += 25)
  257. {
  258. for (int z = -100; z <= 100; z+=50)
  259. {
  260. addStalp({x, z + 25 * flip}, cube);
  261. }
  262. flip = !flip;
  263. }
  264. }
  265. std::vector<gl3d::SpotLight> spotLights;
  266. void addStalp(glm::vec2 position, gl3d::Model cube)
  267. {
  268. renderer.createEntity(cube, {glm::vec3{position.x, 3.5, position.y}
  269. ,{},{0.25,5,0.25}
  270. });
  271. renderer.createEntity(cube, {glm::vec3{position.x, 8.5, position.y}
  272. ,{},{3,0.25,0.25}
  273. });
  274. spotLights.push_back(renderer.createSpotLight({position.x - 1.5, 8.1, position.y},
  275. glm::radians(55.f), glm::vec3(0, -1, 0), 20, 2, glm::vec3(1.f), 1.f, 0));
  276. spotLights.push_back
  277. (renderer.createSpotLight({position.x + 1.5, 8.1, position.y},
  278. glm::radians(55.f), glm::vec3(0, -1, 0), 20, 2, glm::vec3(1.f), 1.f, 0));
  279. }
  280. void addEnemy(glm::vec2 position, gl3d::Model playerM, gl3d::Material mat)
  281. {
  282. Enemy i = {};
  283. i.physics.position = position; i.physics.lastPos = position;
  284. i.entity = renderer.createEntity(playerM,
  285. gl3d::Transform{glm::vec3{i.physics.position.x, 0, i.physics.position.y}
  286. ,{},glm::vec3{0.5f}
  287. }, false);
  288. int count = renderer.getEntityMeshesCount(i.entity);
  289. //if (!count)return 0;
  290. for (int j = 0; j < count; j++)
  291. {
  292. renderer.setEntityMeshMaterial(i.entity, j, mat);
  293. auto m = renderer.getEntityMeshMaterialValues(i.entity, j);
  294. m.kd = {(rand()%255)/255.f,(rand() % 255) / 255.f,(rand() % 255) / 255.f,1};
  295. renderer.setEntityMeshMaterialValues(i.entity, j, m);
  296. }
  297. renderer.setEntityAnimationIndex(i.entity, 15); //idle
  298. renderer.setEntityAnimationSpeed(i.entity, 1);
  299. renderer.setEntityAnimate(i.entity, true);
  300. enemies.push_back(i);
  301. }
  302. gl3d::Model playerM;
  303. std::vector<gl3d::Material> zombieMat;
  304. bool create(RequestedContainerInfo &requestedInfo, pika::StaticString<256> commandLineArgument)
  305. {
  306. renderer2d.create(requestedInfo.requestedFBO.fbo, 50);
  307. //font = pika::gl2d::loadFont(PIKA_RESOURCES_PATH "arial.ttf", requestedInfo);
  308. frameBuffers[0].createFramebuffer(1, 1, false);
  309. frameBuffers[1].createFramebuffer(1, 1, false);
  310. renderer.setErrorCallback(&errorCallbackCustom, &requestedInfo);
  311. renderer.fileOpener.userData = &requestedInfo;
  312. renderer.fileOpener.readEntireFileBinaryCallback = readEntireFileBinaryCustom;
  313. renderer.fileOpener.readEntireFileCallback = readEntireFileCustom;
  314. renderer.fileOpener.fileExistsCallback = defaultFileExistsCustom;
  315. renderer.init(1, 1, PIKA_RESOURCES_PATH "BRDFintegrationMap.png", requestedInfo.requestedFBO.fbo);
  316. renderer.skyBox = renderer.loadSkyBox(PIKA_RESOURCES_PATH "/skyBoxes/forest.png");
  317. //pika::gl3d::loadSettingsFromFileName(renderer, PIKA_RESOURCES_PATH "/threedgame/settings.gl3d", requestedInfo);
  318. editor.loadFromFile(renderer, PIKA_RESOURCES_PATH "/threedgame/settings.gl3d", requestedInfo);
  319. //renderer.skyBox.color = glm::vec3(0.8f);
  320. zombieMat = renderer.loadMaterial(PIKA_RESOURCES_PATH "threedgame/zombie.mtl", 0);
  321. if (zombieMat.size() != 1) { return false; }
  322. playerM = renderer.loadModel(PIKA_RESOURCES_PATH "mcDungeons/steve.glb", 0, 1);
  323. renderer.getSSRdata().setLowQuality();
  324. renderer.getDirectionalShadowCascadesFrustumSplit(0) = 0.15;
  325. renderer.getDirectionalShadowCascadesFrustumSplit(1) = 0.28;
  326. renderer.getDirectionalShadowCascadesFrustumSplit(2) = 0.48;
  327. //renderer.
  328. createPlayerEntity(renderer, {1,1,0}, playerModel1);
  329. createStalpi();
  330. groundModel = createPlane(renderer);
  331. gl3d::Transform t;
  332. t.position = {0, -0.4, 0};
  333. //t.rotation = {1.5, 0 , 0};
  334. groundEntity = renderer.createEntity(groundModel, t);
  335. renderer.createDirectionalLight(glm::normalize(glm::vec3{-0.175,-0.577, -0.798}), glm::vec3{0.25f});
  336. {
  337. sushi::SushyBinaryFormat loader;
  338. requestedInfo.readEntireFileBinary(PIKA_RESOURCES_PATH "threedgame/ui.sushi", loader.data);
  339. sushyContext.load(loader);
  340. sushyContext.root.background.color = {0,0,0,0};
  341. }
  342. //if (0)
  343. {
  344. addEnemy({18,16}, playerM, zombieMat[0]);
  345. addEnemy({16,16}, playerM, zombieMat[0]);
  346. }
  347. return true;
  348. }
  349. float attackCulldown = 0;
  350. bool freeCamera = 0;
  351. bool update(pika::Input input, pika::WindowState windowState,
  352. RequestedContainerInfo &requestedInfo)
  353. {
  354. #pragma region init stuff
  355. renderer.setErrorCallback(&errorCallbackCustom, &requestedInfo);
  356. renderer.fileOpener.userData = &requestedInfo;
  357. renderer.fileOpener.readEntireFileBinaryCallback = readEntireFileBinaryCustom;
  358. renderer.fileOpener.readEntireFileCallback = readEntireFileCustom;
  359. renderer.fileOpener.fileExistsCallback = defaultFileExistsCustom;
  360. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  361. glEnable(GL_DEPTH_TEST);
  362. glDisable(GL_LINE_SMOOTH);
  363. glDisable(GL_MULTISAMPLE);
  364. //renderer.updateWindowMetrics(windowState.windowW, windowState.windowH);
  365. //renderer.camera.aspectRatio = (float)windowState.windowW / windowState.windowH; //todo do this in update
  366. renderer2d.updateWindowMetrics(windowState.windowW, windowState.windowH);
  367. #pragma endregion
  368. frameBuffers[0].clear();
  369. frameBuffers[0].resizeFramebuffer(windowState.windowW / 2, windowState.windowH);
  370. frameBuffers[1].clear();
  371. frameBuffers[1].resizeFramebuffer(windowState.windowW/2, windowState.windowH);
  372. if (!player2joined && input.buttons[pika::Button::Enter].pressed())
  373. {
  374. player2joined = true;
  375. createPlayerEntity(renderer, {1,0,0}, playerModel2);
  376. }
  377. if (enemySpawnTimer < 0)
  378. {
  379. if (enemies.size() < 15)
  380. {
  381. addEnemy({rand() % 100 - 50, rand() % 100 - 50}, playerM, zombieMat[0]);
  382. }
  383. }
  384. else
  385. {
  386. enemySpawnTimer -= input.deltaTime;
  387. }
  388. if (input.buttons[pika::Button::Escape].released())
  389. {
  390. ::pika::pikaImgui::removeFocusToCurrentWindow();
  391. requestedInfo.setNormalCursor();
  392. }
  393. if (input.buttons[pika::Button::F].released())
  394. {
  395. freeCamera = !freeCamera;
  396. }
  397. //editor.update(requestedInfo.requestedImguiIds, renderer, input, 4, requestedInfo, {windowState.windowW,windowState.windowH});
  398. #pragma region spot lights
  399. for (int i = 0; i < spotLights.size(); i++)
  400. {
  401. //auto t = renderer.getSpotLightDirection(spotLights[i]);
  402. renderer.setSpotLightDirection(spotLights[i], gl3d::fromAnglesToDirection(glm::radians(190.f),
  403. ((i%2)*2-1) * clock()*0.0003f + i));
  404. }
  405. #pragma endregion
  406. #pragma region player
  407. {
  408. #pragma region input
  409. {
  410. if (!freeCamera)
  411. {
  412. auto updatePlayer = [&](PlayerModel &p, bool differentInput = 0)
  413. {
  414. glm::vec2 dir = {};
  415. {
  416. if (
  417. (!differentInput && input.buttons[pika::Button::A].held()) ||
  418. (differentInput && input.buttons[pika::Button::Left].held()) )
  419. {
  420. dir -= glm::vec2(1, 1);
  421. }
  422. if (
  423. (!differentInput && input.buttons[pika::Button::D].held() )
  424. || (differentInput && input.buttons[pika::Button::Right].held()) )
  425. {
  426. dir += glm::vec2(1, 1);
  427. }
  428. if (
  429. (!differentInput && input.buttons[pika::Button::W].held() )
  430. || (differentInput && input.buttons[pika::Button::Up].held()))
  431. {
  432. dir += glm::vec2(1, -1);
  433. }
  434. if ((!differentInput && input.buttons[pika::Button::S].held() )
  435. || (differentInput && input.buttons[pika::Button::Down].held()))
  436. {
  437. dir -= glm::vec2(1, -1);
  438. }
  439. }
  440. if (dir.x != 0 || dir.y != 0)
  441. {
  442. dir = glm::normalize(dir);
  443. p.physics.lookDirection = dir;
  444. p.physics.desiredRotation = std::atan2(dir.x, dir.y);
  445. p.armAngle = sin(clock()/100.f);
  446. {
  447. //renderer.setEntityAnimationIndex(playerEntity, run); //run
  448. //renderer.setEntityAnimationSpeed(playerEntity, 1.5);
  449. }
  450. }
  451. else
  452. {
  453. if (p.armAngle > 0)
  454. {
  455. p.armAngle -= input.deltaTime;
  456. if (p.armAngle < 0) p.armAngle = 0;
  457. }
  458. else if(p.armAngle < 0)
  459. {
  460. p.armAngle += input.deltaTime;
  461. if (p.armAngle > 0) p.armAngle = 0;
  462. }
  463. {
  464. //renderer.setEntityAnimationIndex(playerEntity, idle); //idle
  465. //renderer.setEntityAnimationSpeed(playerEntity, 1);
  466. }
  467. }
  468. float speed = 3;
  469. p.physics.position += dir * input.deltaTime * speed;
  470. if ((!differentInput && input.buttons[pika::Button::Space].pressed()) ||
  471. (differentInput && input.buttons[pika::Button::Enter].pressed())
  472. )
  473. {
  474. //renderer.setEntityAnimationIndex(playerEntity, attack); //attack
  475. //renderer.setEntityAnimationSpeed(playerEntity, 1.3);
  476. attackCulldown = 0.2;
  477. for (int i = 0; i < enemies.size(); i++)
  478. {
  479. float d = glm::distance(p.physics.position
  480. + p.physics.lookDirection * 4.5f
  481. , enemies[i].physics.position);
  482. if (d < 4.5f)
  483. {
  484. enemies[i].life -= 0.4;
  485. if (enemies[i].life <= 0)
  486. {
  487. renderer.deleteEntity(enemies[i].entity);
  488. enemies.erase(enemies.begin() + i);
  489. killed++;
  490. i--;
  491. continue;
  492. }
  493. glm::vec2 dir(1, 0);
  494. if (d != 0)
  495. {
  496. dir = (enemies[i].physics.position - p.physics.position) / d;
  497. }
  498. enemies[i].physics.position += dir * 4.0f;
  499. }
  500. }
  501. }
  502. if (attackCulldown > 0)
  503. {
  504. attackCulldown -= input.deltaTime;
  505. }
  506. //set player's position
  507. {
  508. auto setPos = [&](PlayerModel &p)
  509. {
  510. float limbRotation = p.armAngle;
  511. renderer.setEntityTransform(p.torso,
  512. {{p.physics.position.x, 2.50, p.physics.position.y}, {0,
  513. p.physics.rotation, 0}, {0.5,1,0.25}});
  514. renderer.setEntityTransform(p.head,
  515. {{p.physics.position.x, 3.0, p.physics.position.y}, {0,
  516. p.physics.rotation, 0}, {0.5,0.5,0.5}});
  517. glm::mat4 legMatrix =
  518. glm::translate(glm::vec3{p.physics.position.x, 0.75, p.physics.position.y}) *
  519. glm::rotate(p.physics.rotation, glm::vec3{0,0.75,0}) *
  520. glm::translate(glm::vec3{0, 0.75 / 2.f, 0}) *
  521. glm::rotate(limbRotation, glm::vec3{1,0,0}) *
  522. glm::translate(glm::vec3{-0.25, -0.75 / 2.f, 0}) *
  523. glm::scale(glm::vec3{0.25,0.75,0.25});
  524. gl3d::Transform legTransform;
  525. legTransform.setFromMatrix(legMatrix);
  526. glm::mat4 legMatrix2 =
  527. glm::translate(glm::vec3{p.physics.position.x, 0.75, p.physics.position.y}) *
  528. glm::rotate(p.physics.rotation, glm::vec3{0,0.75,0}) *
  529. glm::translate(glm::vec3{0, 0.75 / 2.f, 0}) *
  530. glm::rotate(-limbRotation, glm::vec3{1,0,0}) *
  531. glm::translate(glm::vec3{0.25, -0.75 / 2.f, 0}) *
  532. glm::scale(glm::vec3{0.25,0.75,0.25});
  533. gl3d::Transform legTransform2;
  534. legTransform2.setFromMatrix(legMatrix2);
  535. renderer.setEntityTransform(p.legs[0], legTransform);
  536. renderer.setEntityTransform(p.legs[1], legTransform2);
  537. glm::mat4 armMatrix =
  538. glm::translate(glm::vec3{p.physics.position.x, 1.75, p.physics.position.y}) *
  539. glm::rotate(p.physics.rotation, glm::vec3{0,0.75,0}) *
  540. glm::translate(glm::vec3{0, 0.75 / 2.f, 0}) *
  541. glm::rotate(-limbRotation, glm::vec3{1,0,0}) *
  542. glm::translate(glm::vec3{-0.75, -0.75 / 2.f, 0}) *
  543. glm::scale(glm::vec3{0.25,0.75,0.25});
  544. gl3d::Transform armTransform;
  545. armTransform.setFromMatrix(armMatrix);
  546. glm::mat4 armMatrix2 =
  547. glm::translate(glm::vec3{p.physics.position.x, 1.75, p.physics.position.y}) *
  548. glm::rotate(p.physics.rotation, glm::vec3{0,0.75,0}) *
  549. glm::translate(glm::vec3{0, 0.75 / 2.f, 0}) *
  550. glm::rotate(limbRotation, glm::vec3{1,0,0}) *
  551. glm::translate(glm::vec3{0.75, -0.75 / 2.f, 0}) *
  552. glm::scale(glm::vec3{0.25,0.75,0.25});
  553. gl3d::Transform armTransform2;
  554. armTransform2.setFromMatrix(armMatrix2);
  555. renderer.setEntityTransform(p.hands[0], armTransform);
  556. renderer.setEntityTransform(p.hands[1], armTransform2);
  557. };
  558. setPos(p);
  559. }
  560. renderer.setPointLightPosition(p.pointLight, glm::vec3(p.physics.position.x,
  561. 1, p.physics.position.y));
  562. renderer.setSpotLightPosition(p.spotLight, glm::vec3(p.physics.position.x,
  563. 1, p.physics.position.y));
  564. renderer.setSpotLightDirection(p.spotLight,
  565. gl3d::fromAnglesToDirection(glm::radians(90.f), -p.physics.rotation
  566. + glm::radians(180.f)));
  567. };
  568. updatePlayer(playerModel1, false);
  569. if (player2joined)
  570. {
  571. updatePlayer(playerModel2, true);
  572. }
  573. }
  574. }
  575. #pragma endregion
  576. auto solveRotation = [deltaTime = input.deltaTime](McDungeonsGameplay::PhysicsComponent &p)
  577. {
  578. const float pi2 = 3.1415926f * 2.f;
  579. if (p.desiredRotation != p.rotation)
  580. {
  581. float pozDistance = 0;
  582. float negDistance = 0;
  583. if (p.desiredRotation > p.rotation)
  584. {
  585. pozDistance = p.desiredRotation - p.rotation;
  586. negDistance = p.rotation + pi2 - p.desiredRotation;
  587. }
  588. else
  589. {
  590. pozDistance = pi2 - p.rotation + p.desiredRotation;
  591. negDistance = p.rotation - p.desiredRotation;
  592. }
  593. float speed = deltaTime * 3.141592f * 2.f;
  594. float oldRot = p.rotation;
  595. if (pozDistance > negDistance)
  596. {
  597. if (negDistance < speed)
  598. {
  599. p.rotation = p.desiredRotation;
  600. }
  601. else
  602. {
  603. p.rotation -= speed;
  604. }
  605. }
  606. else
  607. {
  608. if (pozDistance < speed)
  609. {
  610. p.rotation = p.desiredRotation;
  611. }
  612. else
  613. {
  614. p.rotation += speed;
  615. }
  616. }
  617. if (p.rotation > pi2) { p.rotation -= pi2; }
  618. }
  619. };
  620. solveRotation(playerModel1.physics);
  621. playerModel1.physics.updateMove();
  622. if (player2joined)
  623. {
  624. solveRotation(playerModel2.physics);
  625. playerModel2.physics.updateMove();
  626. }
  627. auto setTransform = [&](McDungeonsGameplay::PhysicsComponent &p, gl3d::Entity &e)
  628. {
  629. gl3d::Transform t;
  630. t.rotation.y = p.rotation;
  631. t.position = glm::vec3(p.position.x, -0.5, p.position.y);
  632. t.scale = glm::vec3(1.f);
  633. renderer.setEntityTransform(e, t);
  634. return t;
  635. };
  636. #pragma region player position
  637. glm::vec3 playerPos = {playerModel1.physics.position.x, -0.5, playerModel1.physics.position.y};
  638. glm::vec3 cameraPos = {};
  639. {
  640. glm::vec3 cameraViewDir = glm::normalize(glm::vec3(-1, 0.8, 1));
  641. cameraPos = playerPos + cameraViewDir * 20.f;
  642. }
  643. #pragma endregion
  644. for (auto &e : enemies)
  645. {
  646. float d = glm::distance(e.physics.position, playerModel1.physics.position);
  647. float d2 = glm::distance(e.physics.position, playerModel2.physics.position);
  648. if (!player2joined) { d2 = 10000000000; }
  649. if (d < 16.f || d2 < 16.f)
  650. {
  651. auto attack = [&](PlayerModel &p, float d)
  652. {
  653. if (d > 1.f)
  654. {
  655. glm::vec2 dir = glm::normalize(p.physics.position - e.physics.position);
  656. float speed = 1.4;
  657. e.physics.position += dir * input.deltaTime * speed;
  658. e.physics.desiredRotation = std::atan2(dir.x, dir.y);
  659. renderer.setEntityAnimationIndex(e.entity, zombieRun); //run
  660. renderer.setEntityAnimationSpeed(e.entity, 1.5);
  661. }
  662. else
  663. {
  664. renderer.setEntityAnimationIndex(e.entity, zombieAttack); //attack
  665. renderer.setEntityAnimationSpeed(e.entity, 1.3);
  666. if (e.attackCulldown <= 0.f)
  667. {
  668. //health -= 0.1;
  669. e.attackCulldown = 1.f;
  670. }
  671. //attack
  672. }
  673. };
  674. if (d < d2)
  675. {
  676. attack(playerModel1, d);
  677. }
  678. else
  679. {
  680. attack(playerModel2, d2);
  681. }
  682. }
  683. else
  684. {
  685. renderer.setEntityAnimationIndex(e.entity, zombieIdle); //idle
  686. renderer.setEntityAnimationSpeed(e.entity, 1);
  687. }
  688. if (e.attackCulldown > 0)
  689. {
  690. e.attackCulldown -= input.deltaTime;
  691. }
  692. solveRotation(e.physics);
  693. //resolveConstrains(e.physics);
  694. e.physics.updateMove();
  695. setTransform(e.physics, e.entity);
  696. //requestedInfo.consoleWrite(std::to_string(e.physics.position.x) + " " +
  697. // std::to_string(e.physics.position.y) + "\n");
  698. }
  699. if (!freeCamera)
  700. {
  701. renderer.camera.position = cameraPos;
  702. renderer.camera.viewDirection = glm::normalize(playerPos - cameraPos);
  703. }
  704. else
  705. {
  706. editor.update(requestedInfo.requestedImguiIds, renderer, input,
  707. 4, requestedInfo, {windowState.windowW,windowState.windowH});
  708. }
  709. }
  710. #pragma endregion
  711. #pragma region render3d
  712. if (player2joined && !freeCamera)
  713. {
  714. renderer.frameBuffer = frameBuffers[0].fbo;
  715. renderer.updateWindowMetrics(windowState.windowW/2, windowState.windowH);
  716. renderer.camera.aspectRatio = (float)(windowState.windowW/2) / windowState.windowH;
  717. renderer.render(input.deltaTime);
  718. glm::vec3 playerPos = {playerModel2.physics.position.x, -0.5, playerModel2.physics.position.y};
  719. glm::vec3 cameraPos = {};
  720. {
  721. glm::vec3 cameraViewDir = glm::normalize(glm::vec3(-1, 0.8, 1));
  722. cameraPos = playerPos + cameraViewDir * 20.f;
  723. }
  724. renderer.camera.position = cameraPos;
  725. renderer.camera.viewDirection = glm::normalize(playerPos - cameraPos);
  726. renderer.frameBuffer = frameBuffers[1].fbo;
  727. //renderer.updateWindowMetrics(windowState.windowW / 2, windowState.windowH);
  728. renderer.camera.aspectRatio = (float)(windowState.windowW / 2) / windowState.windowH;
  729. renderer.render(0);
  730. gl2d::Texture t1; t1.id = frameBuffers[0].texture;
  731. gl2d::Texture t2; t2.id = frameBuffers[1].texture;
  732. renderer2d.renderRectangle({0,0, windowState.windowW / 2, windowState.windowH}, t1);
  733. renderer2d.renderRectangle({windowState.windowW / 2,0, windowState.windowW / 2, windowState.windowH}, t2);
  734. glDisable(GL_DEPTH_TEST);
  735. renderer2d.flush();
  736. //todo constructor (maybe explicit from uint)
  737. }
  738. else
  739. {
  740. renderer.updateWindowMetrics(windowState.windowW, windowState.windowH);
  741. renderer.frameBuffer = requestedInfo.requestedFBO.fbo;
  742. renderer.camera.aspectRatio = (float)(windowState.windowW) / windowState.windowH;
  743. renderer.render(input.deltaTime);
  744. }
  745. glDisable(GL_DEPTH_TEST);
  746. #pragma endregion
  747. return true;
  748. }
  749. void destruct(RequestedContainerInfo &requestedInfo) override
  750. {
  751. renderer.clearAllRendererResources();
  752. frameBuffers[0].deleteFramebuffer();
  753. frameBuffers[1].deleteFramebuffer();
  754. renderer2d.cleanup();
  755. font.texture.cleanup();
  756. }
  757. };
  758. //todo flag to clear screen from engine
  759. //todo error popup
  760. //todo error popup disable in release
  761. //todo reset container button (keep same imgui id)