Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

443 рядки
15 KiB

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