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.
 
 
 

447 lines
15 KiB

  1. //
  2. // Lol Engine — Bullet physics test
  3. //
  4. // Copyright © 2009—2013 Cédric Lecacheur <jordx@free.fr>
  5. // © 2009—2013 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
  6. // © 2012—2018 Sam Hocevar <sam@hocevar.net>
  7. //
  8. // Lol Engine is free software. It comes without any warranty, to
  9. // the extent permitted by applicable law. You can redistribute it
  10. // and/or modify it under the terms of the Do What the Fuck You Want
  11. // to Public License, Version 2, as published by the WTFPL Task Force.
  12. // See http://www.wtfpl.net/ for more details.
  13. //
  14. #pragma once
  15. /* FIXME: this file is pure crap; it's only a test. */
  16. #include <lol/engine.h>
  17. #include "easymesh/easymesh.h"
  18. #include "physics/easyphysics.h"
  19. #include "physics/easycharactercontroller.h"
  20. #include "physics/easyconstraint.h"
  21. using namespace lol;
  22. using namespace lol::phys;
  23. #if CAT_MODE
  24. #define USE_SPHERE 1
  25. #else
  26. #define USE_BOX 1
  27. #define USE_SPHERE 1
  28. #define USE_CONE 1
  29. #define USE_CYLINDER 1
  30. #define USE_CAPSULE 1
  31. #endif
  32. class PhysicsObject : public WorldEntity
  33. {
  34. public:
  35. PhysicsObject(Simulation* new_sim, const vec3 &base_location, const quat &base_rotation)
  36. : m_custom_shader(0),
  37. m_ready(false),
  38. m_should_render(true),
  39. m_is_character(false),
  40. m_is_phys(false)
  41. {
  42. m_physics = new EasyPhysic(this);
  43. //m_mesh.Compile("[sc#ddd afcb 60 1 60 -.1]");
  44. m_mesh.SetCurColor(Color::white);
  45. m_mesh.AppendFlatChamfBox(vec3(60.f, 1.f, 60.f), -.1f);
  46. vec3 BoxSize = vec3(60.f, 1.f, 60.f);
  47. m_physics->SetCollisionChannel(0, 0xFF);
  48. m_physics->SetShapeToBox(BoxSize);
  49. m_physics->SetMass(.0f);
  50. m_physics->SetTransform(base_location, base_rotation);
  51. m_physics->InitBodyToRigid(true);
  52. m_physics->AddToSimulation(new_sim);
  53. }
  54. PhysicsObject(Simulation* new_sim, const vec3 &base_location, const quat &base_rotation, int dummy)
  55. : m_custom_shader(0),
  56. m_ready(false),
  57. m_should_render(true),
  58. m_is_character(false),
  59. m_is_phys(false)
  60. {
  61. if (dummy == 1) //for platform purpose
  62. {
  63. m_physics = new EasyPhysic(this);
  64. m_mesh.Compile("[sc#ddd afcb 20 1 20 -.1]");
  65. vec3 BoxSize = vec3(20.f, 1.f, 20.f);
  66. m_physics->SetCollisionChannel(0, 0xFF);
  67. m_physics->SetShapeToBox(BoxSize);
  68. m_physics->SetMass(.0f);
  69. m_physics->SetTransform(base_location, base_rotation);
  70. m_physics->InitBodyToRigid(true);
  71. m_physics->AddToSimulation(new_sim);
  72. }
  73. else if (dummy == 2) //for character purpose
  74. {
  75. m_character = new EasyCharacterController(this);
  76. m_is_character = true;
  77. //m_mesh.Compile("[sc#f00 afcb10 10 10 -.1]");
  78. m_mesh.Compile(
  79. "[sc#000 scb#000"
  80. //"[sc#aaa scb#aaa"
  81. "[ad8 2 0 rx180 ty-1]"
  82. "[asph8 .5 ty1]"
  83. "[ac32 2 .5 .5 0 0]"
  84. "[asph6 .1 ty.9 tx.5 tz.15]"
  85. "[asph6 .1 ty.9 tx.5 tz-.15]"
  86. "[asph8 .05 sy10 ty.6 tz.5]"
  87. "[asph8 .05 sy10 ty.6 tz-.5]"
  88. "]"
  89. "[sc#fd0 scb#fd0"
  90. "[ac8 .4 .1 0 0 0 ty.25 rz-90 ty.7 tx.5]"
  91. "]"
  92. "["
  93. "[sc#fff scb#fff"
  94. "[ad8 2 0 rx180 ty-1]"
  95. "[asph8 .5 ty1]"
  96. "[ac32 1.9 .5 .5 0 0]"
  97. "]"
  98. " ty-.1 tx.05]"
  99. );
  100. vec3 BoxSize = vec3(1.f, 2.f, 1.f);
  101. m_character->SetCollisionChannel(0, 0xFF);
  102. m_character->SetShapeToCapsule(BoxSize.x, BoxSize.y);
  103. m_character->SetMass(.0f);
  104. //m_character->SetStepHeight(1.f);
  105. m_character->SetTransform(base_location, base_rotation);
  106. m_character->InitBodyToGhost();
  107. m_character->AddToSimulation(new_sim);
  108. }
  109. else if (dummy == 3) //for Stairs purpose
  110. {
  111. m_physics = new EasyPhysic(this);
  112. m_mesh.Compile("[sc#aae afcb4 .25 4 -.01]");
  113. vec3 BoxSize = vec3(4.f, .25f, 4.f);
  114. m_physics->SetCollisionChannel(0, 0xFF);
  115. m_physics->SetShapeToBox(BoxSize);
  116. m_physics->SetMass(.0f);
  117. m_physics->SetTransform(base_location, base_rotation);
  118. m_physics->InitBodyToRigid(true);
  119. m_physics->AddToSimulation(new_sim);
  120. }
  121. }
  122. PhysicsObject(Simulation* new_sim, float base_mass, const vec3 &base_location, int RandValue = -1)
  123. : m_custom_shader(0),
  124. m_ready(false),
  125. m_should_render(true),
  126. m_is_character(false),
  127. m_is_phys(false)
  128. {
  129. static array<EasyMesh> MeshRand;
  130. static array<int> MeshLimit;
  131. static array<int> MeshType;
  132. if (!MeshRand.count())
  133. {
  134. array<std::string> colors_base = { "#add", "#dad", "#dda", "#daa", "#ada", "#aad" };
  135. MeshLimit << 0;
  136. #if USE_BOX
  137. {
  138. array<std::string> colors = colors_base;
  139. while (colors.count())
  140. {
  141. EasyMesh m;
  142. vec4 color = Color::C8BppHexString(colors.pop());
  143. m.SetCurColor(color);
  144. m.AppendFlatChamfBox(vec3(1.7f), .4f);
  145. m.OpenBrace();
  146. {
  147. m.SetCurColor(Color::black);
  148. m.ToggleScaleWinding();
  149. m.AppendFlatChamfBox(vec3(1.9f), .4f);
  150. m.ScaleX(-1.f);
  151. m.ScaleY(-1.f);
  152. m.ScaleZ(-1.f);
  153. }
  154. m.CloseBrace();
  155. MeshRand << m;
  156. }
  157. }
  158. //MeshRand << "[sc#add afcb1.7 1.7 1.7 0.4][sc#000 tsw afcb1.9 1.9 1.9 0.4 sx-1 sy-1 sz-1]";
  159. //MeshRand << "[sc#dad afcb1.7 1.7 1.7 0.4][sc#000 tsw afcb1.9 1.9 1.9 0.4 sx-1 sy-1 sz-1]";
  160. //MeshRand << "[sc#dda afcb1.7 1.7 1.7 0.4][sc#000 tsw afcb1.9 1.9 1.9 0.4 sx-1 sy-1 sz-1]";
  161. //MeshRand << "[sc#daa afcb1.7 1.7 1.7 0.4][sc#000 tsw afcb1.9 1.9 1.9 0.4 sx-1 sy-1 sz-1]";
  162. //MeshRand << "[sc#ada afcb1.7 1.7 1.7 0.4][sc#000 tsw afcb1.9 1.9 1.9 0.4 sx-1 sy-1 sz-1]";
  163. //MeshRand << "[sc#aad afcb1.7 1.7 1.7 0.4][sc#000 tsw afcb1.9 1.9 1.9 0.4 sx-1 sy-1 sz-1]";
  164. MeshLimit << MeshRand.count();
  165. MeshType << 0;
  166. #endif //USE_BOX
  167. #if USE_SPHERE
  168. #if CAT_MODE
  169. int nb_sprite = NB_SPRITE;
  170. //SPRITE
  171. vec2 start_point = vec2((float)rand(nb_sprite), (float)rand(nb_sprite)) / vec2((float)nb_sprite);
  172. //vec2(0.f, .0f) / vec2((float)nb_sprite);
  173. vec2 size = vec2(1.f) / vec2((float)nb_sprite);
  174. m_mesh.BD()->SetTexCoordCustomBuild(MeshType::Quad, MeshFaceType::QuadDefault,
  175. start_point, start_point + size);
  176. m_mesh.BD()->SetTexCoordCustomBuild2(MeshType::Quad, MeshFaceType::QuadDefault,
  177. vec2(-PARTICLE_SIZE), vec2(PARTICLE_SIZE));
  178. MeshRand << "[tpbn tvnc sc#ffff aq 0 0]";
  179. MeshRand << "[tpbn tvnc sc#faaf aq 0 0]";
  180. MeshRand << "[tpbn tvnc sc#afaf aq 0 0]";
  181. MeshRand << "[tpbn tvnc sc#aaff aq 0 0]";
  182. #else
  183. {
  184. array<std::string> colors = colors_base;
  185. while (colors.count())
  186. {
  187. EasyMesh m;
  188. vec4 color = Color::C8BppHexString(colors.pop());
  189. m.SetCurColor(color);
  190. m.AppendSphere(1, 2.f);
  191. MeshRand << m;
  192. }
  193. }
  194. //MeshRand << "[sc#add asph1 2]";
  195. //MeshRand << "[sc#dad asph1 2]";
  196. //MeshRand << "[sc#dda asph1 2]";
  197. //MeshRand << "[sc#daa asph1 2]";
  198. //MeshRand << "[sc#ada asph1 2]";
  199. //MeshRand << "[sc#aad asph1 2]";
  200. #endif
  201. MeshLimit << MeshRand.count();
  202. MeshType << 1;
  203. #endif //USE_SPHERE
  204. #if USE_CONE
  205. {
  206. array<std::string> colors = colors_base;
  207. while (colors.count())
  208. {
  209. EasyMesh m;
  210. vec4 color = Color::C8BppHexString(colors.pop());
  211. m.SetCurColor(color);
  212. m.SetCurColorB(color);
  213. m.AppendDisc(8, 2.f);
  214. m.RotateX(180.f);
  215. m.TranslateY(-1.f);
  216. m.AppendCylinder(8, 2.f, 2.f, 0.f);
  217. MeshRand << m;
  218. }
  219. }
  220. //MeshRand << "[sc#add scb#add ad8 2 0 rx180 ty-1 ac8 2 2 0 0 0]";
  221. //MeshRand << "[sc#dad scb#dad ad8 2 0 rx180 ty-1 ac8 2 2 0 0 0]";
  222. //MeshRand << "[sc#dda scb#dda ad8 2 0 rx180 ty-1 ac8 2 2 0 0 0]";
  223. //MeshRand << "[sc#daa scb#daa ad8 2 0 rx180 ty-1 ac8 2 2 0 0 0]";
  224. //MeshRand << "[sc#ada scb#ada ad8 2 0 rx180 ty-1 ac8 2 2 0 0 0]";
  225. //MeshRand << "[sc#aad scb#aad ad8 2 0 rx180 ty-1 ac8 2 2 0 0 0]";
  226. MeshLimit << MeshRand.count();
  227. MeshType << 2;
  228. #endif //USE_CONE
  229. #if USE_CYLINDER
  230. {
  231. array<std::string> colors = colors_base;
  232. while (colors.count())
  233. {
  234. EasyMesh m;
  235. vec4 color = Color::C8BppHexString(colors.pop());
  236. m.SetCurColor(color);
  237. m.SetCurColorB(color);
  238. m.AppendDisc(8, 2.f);
  239. m.RotateX(180.f);
  240. m.TranslateY(-1.f);
  241. m.MirrorY();
  242. m.AppendCylinder(8.f, 2.f, 2.f, 2.f);
  243. MeshRand << m;
  244. }
  245. }
  246. //MeshRand << "[sc#add scb#add ad8 2 0 rx180 ty-1 my ac8 2 2 2 0 0]";
  247. //MeshRand << "[sc#dad scb#dad ad8 2 0 rx180 ty-1 my ac8 2 2 2 0 0]";
  248. //MeshRand << "[sc#dda scb#dda ad8 2 0 rx180 ty-1 my ac8 2 2 2 0 0]";
  249. //MeshRand << "[sc#daa scb#daa ad8 2 0 rx180 ty-1 my ac8 2 2 2 0 0]";
  250. //MeshRand << "[sc#ada scb#ada ad8 2 0 rx180 ty-1 my ac8 2 2 2 0 0]";
  251. //MeshRand << "[sc#aad scb#aad ad8 2 0 rx180 ty-1 my ac8 2 2 2 0 0]";
  252. MeshLimit << MeshRand.count();
  253. MeshType << 3;
  254. #endif //USE_CYLINDER
  255. #if USE_CAPSULE
  256. {
  257. array<std::string> colors = colors_base;
  258. while (colors.count())
  259. {
  260. EasyMesh m;
  261. vec4 color = Color::C8BppHexString(colors.pop());
  262. m.SetCurColor(color);
  263. m.SetCurColorB(color);
  264. m.AppendCapsule(1, 2.f, 1.f);
  265. MeshRand << m;
  266. }
  267. }
  268. //MeshRand << "[sc#add scb#add acap1 2 1]";
  269. //MeshRand << "[sc#dad scb#dad acap1 2 1]";
  270. //MeshRand << "[sc#dda scb#dda acap1 2 1]";
  271. //MeshRand << "[sc#daa scb#daa acap1 2 1]";
  272. //MeshRand << "[sc#ada scb#ada acap1 2 1]";
  273. //MeshRand << "[sc#aad scb#aad acap1 2 1]";
  274. MeshLimit << MeshRand.count();
  275. MeshType << 4;
  276. #endif //USE_CAPSULE
  277. }
  278. int RandLimit = RandValue;
  279. if (MeshLimit.count() <= RandValue || RandValue < 0)
  280. RandLimit = rand((int)MeshLimit.count() - 1);
  281. RandValue = rand(MeshLimit[RandLimit], MeshLimit[RandLimit + 1]);
  282. m_physics = new EasyPhysic(this);
  283. //m_mesh.Compile(MeshRand[RandValue]);
  284. m_mesh = MeshRand[RandValue];
  285. m_mesh.Scale(vec3(OBJ_SIZE));
  286. vec3 BoxSize = vec3(2.0f) * OBJ_SIZE;
  287. int ColGroup = 1;
  288. switch (MeshType[RandLimit])
  289. {
  290. case 0:
  291. {
  292. m_physics->SetShapeToBox(BoxSize);
  293. ColGroup += 0;
  294. break;
  295. }
  296. case 1:
  297. {
  298. m_physics->SetShapeToSphere(BoxSize.x);
  299. ColGroup += 1;
  300. break;
  301. }
  302. case 2:
  303. {
  304. m_physics->SetShapeToCone(BoxSize.x, BoxSize.y);
  305. ColGroup += 2;
  306. break;
  307. }
  308. case 3:
  309. {
  310. m_physics->SetShapeToCylinder(BoxSize);
  311. ColGroup += 3;
  312. break;
  313. }
  314. case 4:
  315. {
  316. m_physics->SetShapeToCapsule(BoxSize.x, BoxSize.y);
  317. ColGroup += 4;
  318. break;
  319. }
  320. default:
  321. {
  322. }
  323. }
  324. m_physics->SetHitRestitution(1.0f);
  325. m_physics->SetCollisionChannel(0, 0xFF);
  326. //m_physics->SetCollisionChannel(ColGroup, (1 << ColGroup)|(1));
  327. m_physics->SetMass(base_mass);
  328. m_physics->SetTransform(base_location);
  329. m_physics->InitBodyToRigid();
  330. m_physics->AddToSimulation(new_sim);
  331. }
  332. void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation = lol::quat(lol::mat3(1.0f)))
  333. {
  334. if (m_is_character)
  335. m_character->SetTransform(base_location, base_rotation);
  336. else
  337. m_physics->SetTransform(base_location, base_rotation);
  338. }
  339. lol::mat4 GetTransform()
  340. {
  341. if (m_is_character)
  342. return m_character->GetTransform();
  343. else
  344. return m_physics->GetTransform();
  345. }
  346. void SetRender(bool should_render)
  347. {
  348. m_should_render = should_render;
  349. }
  350. void SetCustomShaderData(GpuShaderData* custom_shader)
  351. {
  352. m_custom_shader = custom_shader;
  353. }
  354. GpuShaderData* GetCustomShaderData()
  355. {
  356. return m_custom_shader;
  357. }
  358. EasyMesh *GetMesh() { return &m_mesh; }
  359. EasyPhysic *GetPhysic() { return m_physics; }
  360. EasyCharacterController *GetCharacter() { return m_character; }
  361. ~PhysicsObject()
  362. {
  363. }
  364. std::string GetName() const { return "<PhysicsObject>"; }
  365. protected:
  366. virtual void tick_game(float seconds)
  367. {
  368. WorldEntity::tick_game(seconds);
  369. }
  370. virtual void tick_draw(float seconds, Scene &scene)
  371. {
  372. WorldEntity::tick_draw(seconds, scene);
  373. #if CAT_MODE
  374. if (!m_is_phys || m_custom_shader)
  375. #endif //CAT_MODE
  376. {
  377. if (!m_ready)
  378. {
  379. m_mesh.MeshConvert();
  380. /* FIXME: m_custom_shader is ignored */
  381. m_ready = true;
  382. }
  383. else if (m_should_render)
  384. {
  385. if (m_is_character)
  386. m_mesh.Render(scene, m_character->GetTransform());
  387. else
  388. m_mesh.Render(scene, m_physics->GetTransform());
  389. }
  390. }
  391. }
  392. private:
  393. // Base data
  394. EasyMesh m_mesh;
  395. EasyPhysic* m_physics;
  396. EasyCharacterController* m_character;
  397. GpuShaderData* m_custom_shader;
  398. bool m_ready;
  399. bool m_should_render;
  400. bool m_is_character;
  401. bool m_is_phys; /* Only used in CAT_MODE */
  402. };