physics_resource.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809
  1. /*
  2. * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "physics_resource.h"
  6. #include "physics_types.h"
  7. #include "filesystem.h"
  8. #include "json_parser.h"
  9. #include "string_utils.h"
  10. #include "dynamic_string.h"
  11. #include "map.h"
  12. #include "quaternion.h"
  13. #include "compile_options.h"
  14. #include <algorithm>
  15. namespace crown
  16. {
  17. namespace physics_resource
  18. {
  19. struct Shape
  20. {
  21. const char* name;
  22. ShapeType::Enum type;
  23. };
  24. static const Shape s_shape[ShapeType::COUNT] =
  25. {
  26. { "sphere", ShapeType::SPHERE },
  27. { "capsule", ShapeType::CAPSULE },
  28. { "box", ShapeType::BOX },
  29. { "plane", ShapeType::PLANE },
  30. { "convex_mesh", ShapeType::CONVEX_MESH }
  31. };
  32. struct Joint
  33. {
  34. const char* name;
  35. JointType::Enum type;
  36. };
  37. static const Joint s_joint[JointType::COUNT] =
  38. {
  39. { "fixed", JointType::FIXED },
  40. { "spherical", JointType::SPHERICAL },
  41. { "revolute", JointType::REVOLUTE },
  42. { "prismatic", JointType::PRISMATIC },
  43. { "distance", JointType::DISTANCE }
  44. };
  45. static uint32_t shape_type_to_enum(const char* type)
  46. {
  47. for (uint32_t i = 0; i < ShapeType::COUNT; i++)
  48. {
  49. if (strcmp(type, s_shape[i].name) == 0)
  50. return s_shape[i].type;
  51. }
  52. CE_FATAL("Bad shape type");
  53. return 0;
  54. }
  55. static uint32_t joint_type_to_enum(const char* type)
  56. {
  57. for (uint32_t i = 0; i < JointType::COUNT; i++)
  58. {
  59. if (strcmp(type, s_joint[i].name) == 0)
  60. return s_joint[i].type;
  61. }
  62. CE_FATAL("Bad joint type");
  63. return 0;
  64. }
  65. void parse_controller(JSONElement e, ControllerResource& controller)
  66. {
  67. controller.name = e.key("name").to_string_id();
  68. controller.height = e.key("height").to_float();
  69. controller.radius = e.key("radius").to_float();
  70. controller.slope_limit = e.key("slope_limit").to_float();
  71. controller.step_offset = e.key("step_offset").to_float();
  72. controller.contact_offset = e.key("contact_offset").to_float();
  73. controller.collision_filter = e.key("collision_filter").to_string_id();
  74. }
  75. void parse_shapes(JSONElement e, Array<ShapeResource>& shapes)
  76. {
  77. Vector<DynamicString> keys(default_allocator());
  78. e.to_keys(keys);
  79. for (uint32_t k = 0; k < vector::size(keys); k++)
  80. {
  81. JSONElement shape = e.key(keys[k].c_str());
  82. ShapeResource sr;
  83. sr.name = keys[k].to_string_id();
  84. sr.shape_class = shape.key("class").to_string_id();
  85. sr.material = shape.key("material").to_string_id();
  86. sr.position = shape.key("position").to_vector3();
  87. sr.rotation = shape.key("rotation").to_quaternion();
  88. DynamicString stype; shape.key("type").to_string(stype);
  89. sr.type = shape_type_to_enum(stype.c_str());
  90. switch (sr.type)
  91. {
  92. case ShapeType::SPHERE:
  93. {
  94. sr.data_0 = shape.key("radius").to_float();
  95. break;
  96. }
  97. case ShapeType::CAPSULE:
  98. {
  99. sr.data_0 = shape.key("radius").to_float();
  100. sr.data_1 = shape.key("half_height").to_float();
  101. break;
  102. }
  103. case ShapeType::BOX:
  104. {
  105. sr.data_0 = shape.key("half_x").to_float();
  106. sr.data_1 = shape.key("half_y").to_float();
  107. sr.data_2 = shape.key("half_z").to_float();
  108. break;
  109. }
  110. case ShapeType::PLANE:
  111. {
  112. sr.data_0 = shape.key("n_x").to_float();
  113. sr.data_1 = shape.key("n_y").to_float();
  114. sr.data_2 = shape.key("n_z").to_float();
  115. sr.data_3 = shape.key("distance").to_float();
  116. break;
  117. }
  118. }
  119. array::push_back(shapes, sr);
  120. }
  121. }
  122. void parse_actors(JSONElement e, Array<ActorResource>& actors)
  123. {
  124. Vector<DynamicString> keys(default_allocator());
  125. e.to_keys(keys);
  126. for (uint32_t k = 0; k < vector::size(keys); k++)
  127. {
  128. JSONElement actor = e.key(keys[k].c_str());
  129. ActorResource pa;
  130. pa.name = keys[k].to_string_id();
  131. pa.node = actor.key("node").to_string_id();
  132. pa.actor_class = actor.key("class").to_string_id();
  133. pa.mass = actor.key("mass").to_float();
  134. pa.flags = 0;
  135. pa.flags |= actor.key_or_nil("lock_translation_x").to_bool(false) ? ActorFlags::LOCK_TRANSLATION_X : 0;
  136. pa.flags |= actor.key_or_nil("lock_translation_y").to_bool(false) ? ActorFlags::LOCK_TRANSLATION_Y : 0;
  137. pa.flags |= actor.key_or_nil("lock_translation_z").to_bool(false) ? ActorFlags::LOCK_TRANSLATION_Z : 0;
  138. pa.flags |= actor.key_or_nil("lock_rotation_x").to_bool(false) ? ActorFlags::LOCK_ROTATION_X : 0;
  139. pa.flags |= actor.key_or_nil("lock_rotation_y").to_bool(false) ? ActorFlags::LOCK_ROTATION_Y : 0;
  140. pa.flags |= actor.key_or_nil("lock_rotation_z").to_bool(false) ? ActorFlags::LOCK_ROTATION_Z : 0;
  141. array::push_back(actors, pa);
  142. }
  143. }
  144. void parse_joints(JSONElement e, Array<JointResource>& joints)
  145. {
  146. Vector<DynamicString> keys(default_allocator());
  147. e.to_keys(keys);
  148. for (uint32_t k = 0; k < vector::size(keys); k++)
  149. {
  150. JSONElement joint = e.key(keys[k].c_str());
  151. JSONElement type = joint.key("type");
  152. JointResource pj;
  153. pj.name = keys[k].to_string_id();
  154. DynamicString jtype; type.to_string(jtype);
  155. pj.type = joint_type_to_enum(jtype.c_str());
  156. pj.actor_0 = joint.key("actor_0").to_string_id();
  157. pj.actor_1 = joint.key("actor_1").to_string_id();
  158. pj.anchor_0 = joint.key_or_nil("anchor_0").to_vector3(vector3::ZERO);
  159. pj.anchor_1 = joint.key_or_nil("anchor_1").to_vector3(vector3::ZERO);
  160. pj.restitution = joint.key_or_nil("restitution").to_float(0.5f);
  161. pj.spring = joint.key_or_nil("spring").to_float(100.0f);
  162. pj.damping = joint.key_or_nil("damping").to_float(0.0f);
  163. pj.distance = joint.key_or_nil("distance").to_float(1.0f);
  164. pj.breakable = joint.key_or_nil("breakable").to_bool(false);
  165. pj.break_force = joint.key_or_nil("break_force").to_float(3000.0f);
  166. pj.break_torque = joint.key_or_nil("break_torque").to_float(1000.0f);
  167. switch (pj.type)
  168. {
  169. case JointType::FIXED:
  170. {
  171. return;
  172. }
  173. case JointType::SPHERICAL:
  174. {
  175. pj.y_limit_angle = joint.key_or_nil("y_limit_angle").to_float(HALF_PI);
  176. pj.z_limit_angle = joint.key_or_nil("z_limit_angle").to_float(HALF_PI);
  177. pj.contact_dist = joint.key_or_nil("contact_dist").to_float(0.0f);
  178. break;
  179. }
  180. case JointType::REVOLUTE:
  181. case JointType::PRISMATIC:
  182. {
  183. pj.lower_limit = joint.key_or_nil("lower_limit").to_float(0.0f);
  184. pj.upper_limit = joint.key_or_nil("upper_limit").to_float(0.0f);
  185. pj.contact_dist = joint.key_or_nil("contact_dist").to_float(0.0f);
  186. break;
  187. }
  188. case JointType::DISTANCE:
  189. {
  190. pj.max_distance = joint.key_or_nil("max_distance").to_float(0.0f);
  191. break;
  192. }
  193. }
  194. array::push_back(joints, pj);
  195. }
  196. }
  197. void compile(const char* path, CompileOptions& opts)
  198. {
  199. static const uint32_t VERSION = 1;
  200. Buffer buf = opts.read(path);
  201. JSONParser json(array::begin(buf));
  202. JSONElement root = json.root();
  203. bool m_has_controller = false;
  204. ControllerResource m_controller;
  205. // Read controller
  206. JSONElement controller = root.key_or_nil("controller");
  207. if (controller.is_nil())
  208. {
  209. m_has_controller = false;
  210. }
  211. else
  212. {
  213. parse_controller(controller, m_controller);
  214. m_has_controller = true;
  215. }
  216. Array<ActorResource> m_actors(default_allocator());
  217. Array<ShapeResource> m_shapes(default_allocator());
  218. Array<JointResource> m_joints(default_allocator());
  219. if (root.has_key("colliders")) parse_shapes(root.key("colliders"), m_shapes);
  220. if (root.has_key("actors")) parse_actors(root.key("actors"), m_actors);
  221. if (root.has_key("joints")) parse_joints(root.key("joints"), m_joints);
  222. PhysicsResource pr;
  223. pr.version = VERSION;
  224. pr.num_controllers = m_has_controller ? 1 : 0;
  225. pr.num_colliders = array::size(m_shapes);
  226. pr.num_actors = array::size(m_actors);
  227. pr.num_joints = array::size(m_joints);
  228. uint32_t offt = sizeof(PhysicsResource);
  229. pr.controller_offset = offt; offt += sizeof(ControllerResource) * pr.num_controllers;
  230. pr.colliders_offset = offt; offt += sizeof(ShapeResource) * pr.num_colliders;
  231. pr.actors_offset = offt; offt += sizeof(ActorResource) * pr.num_actors;
  232. pr.joints_offset = offt;
  233. // Write all
  234. opts.write(pr.version);
  235. opts.write(pr.num_controllers);
  236. opts.write(pr.controller_offset);
  237. opts.write(pr.num_colliders);
  238. opts.write(pr.colliders_offset);
  239. opts.write(pr.num_actors);
  240. opts.write(pr.actors_offset);
  241. opts.write(pr.num_joints);
  242. opts.write(pr.joints_offset);
  243. if (m_has_controller)
  244. {
  245. opts.write(m_controller.name);
  246. opts.write(m_controller.height);
  247. opts.write(m_controller.radius);
  248. opts.write(m_controller.slope_limit);
  249. opts.write(m_controller.step_offset);
  250. opts.write(m_controller.contact_offset);
  251. opts.write(m_controller.collision_filter);
  252. }
  253. for (uint32_t i = 0; i < array::size(m_shapes); ++i)
  254. {
  255. opts.write(m_shapes[i].name);
  256. opts.write(m_shapes[i].shape_class);
  257. opts.write(m_shapes[i].type);
  258. opts.write(m_shapes[i].material);
  259. opts.write(m_shapes[i].position);
  260. opts.write(m_shapes[i].rotation);
  261. opts.write(m_shapes[i].data_0);
  262. opts.write(m_shapes[i].data_1);
  263. opts.write(m_shapes[i].data_2);
  264. opts.write(m_shapes[i].data_3);
  265. }
  266. for (uint32_t i = 0; i < array::size(m_actors); i++)
  267. {
  268. opts.write(m_actors[i].name);
  269. opts.write(m_actors[i].node);
  270. opts.write(m_actors[i].actor_class);
  271. opts.write(m_actors[i].mass);
  272. opts.write(m_actors[i].flags);
  273. }
  274. for (uint32_t i = 0; i < array::size(m_joints); i++)
  275. {
  276. opts.write(m_joints[i].name);
  277. opts.write(m_joints[i].type);
  278. opts.write(m_joints[i].actor_0);
  279. opts.write(m_joints[i].actor_1);
  280. opts.write(m_joints[i].anchor_0);
  281. opts.write(m_joints[i].anchor_1);
  282. opts.write(m_joints[i].breakable);
  283. opts.write(m_joints[i]._pad[0]);
  284. opts.write(m_joints[i]._pad[1]);
  285. opts.write(m_joints[i]._pad[2]);
  286. opts.write(m_joints[i].break_force);
  287. opts.write(m_joints[i].break_torque);
  288. opts.write(m_joints[i].lower_limit);
  289. opts.write(m_joints[i].upper_limit);
  290. opts.write(m_joints[i].y_limit_angle);
  291. opts.write(m_joints[i].z_limit_angle);
  292. opts.write(m_joints[i].max_distance);
  293. opts.write(m_joints[i].contact_dist);
  294. opts.write(m_joints[i].restitution);
  295. opts.write(m_joints[i].spring);
  296. opts.write(m_joints[i].damping);
  297. opts.write(m_joints[i].distance);
  298. }
  299. }
  300. void* load(File& file, Allocator& a)
  301. {
  302. const size_t file_size = file.size();
  303. void* res = a.allocate(file_size);
  304. file.read(res, file_size);
  305. return res;
  306. }
  307. void online(StringId64 /*id*/, ResourceManager& /*rm*/)
  308. {
  309. }
  310. void offline(StringId64 /*id*/, ResourceManager& /*rm*/)
  311. {
  312. }
  313. void unload(Allocator& allocator, void* resource)
  314. {
  315. allocator.deallocate(resource);
  316. }
  317. bool has_controller(const PhysicsResource* pr)
  318. {
  319. return pr->num_controllers == 1;
  320. }
  321. const ControllerResource* controller(const PhysicsResource* pr)
  322. {
  323. CE_ASSERT(has_controller(pr), "Controller does not exist");
  324. ControllerResource* controller = (ControllerResource*) ((char*)pr + pr->controller_offset);
  325. return controller;
  326. }
  327. uint32_t num_colliders(const PhysicsResource* pr)
  328. {
  329. return pr->num_colliders;
  330. }
  331. const ShapeResource* collider(const PhysicsResource* pr, uint32_t i)
  332. {
  333. CE_ASSERT(i < num_colliders(pr), "Index out of bounds");
  334. ShapeResource* collider = (ShapeResource*) ((char*)pr + pr->colliders_offset);
  335. return &collider[i];
  336. }
  337. uint32_t num_actors(const PhysicsResource* pr)
  338. {
  339. return pr->num_actors;
  340. }
  341. const ActorResource* actor(const PhysicsResource* pr, uint32_t i)
  342. {
  343. CE_ASSERT(i < num_actors(pr), "Index out of bounds");
  344. ActorResource* actor = (ActorResource*) ((char*)pr + pr->actors_offset);
  345. return &actor[i];
  346. }
  347. uint32_t num_joints(const PhysicsResource* pr)
  348. {
  349. return pr->num_joints;
  350. }
  351. const JointResource* joint(const PhysicsResource* pr, uint32_t i)
  352. {
  353. CE_ASSERT(i < num_joints(pr), "Index out of bounds");
  354. JointResource* joint = (JointResource*) ((char*)pr + pr->joints_offset);
  355. return &joint[i];
  356. }
  357. } // namespace physics_resource
  358. namespace physics_config_resource
  359. {
  360. static Map<DynamicString, uint32_t>* s_ftm = NULL;
  361. struct ObjectName
  362. {
  363. StringId32 name;
  364. uint32_t index;
  365. bool operator()(const ObjectName& a, const ObjectName& b)
  366. {
  367. return a.name < b.name;
  368. }
  369. };
  370. void parse_materials(JSONElement e, Array<ObjectName>& names, Array<PhysicsConfigMaterial>& objects)
  371. {
  372. Vector<DynamicString> keys(default_allocator());
  373. e.to_keys(keys);
  374. for (uint32_t i = 0; i < vector::size(keys); i++)
  375. {
  376. JSONElement material = e.key(keys[i].c_str());
  377. // Read material name
  378. ObjectName mat_name;
  379. mat_name.name = keys[i].to_string_id();
  380. mat_name.index = i;
  381. // Read material object
  382. PhysicsConfigMaterial mat;
  383. mat.static_friction = material.key("static_friction").to_float();
  384. mat.dynamic_friction = material.key("dynamic_friction").to_float();
  385. mat.restitution = material.key("restitution").to_float();
  386. array::push_back(names, mat_name);
  387. array::push_back(objects, mat);
  388. }
  389. }
  390. void parse_shapes(JSONElement e, Array<ObjectName>& names, Array<PhysicsConfigShape>& objects)
  391. {
  392. Vector<DynamicString> keys(default_allocator());
  393. e.to_keys(keys);
  394. for (uint32_t i = 0; i < vector::size(keys); i++)
  395. {
  396. JSONElement shape = e.key(keys[i].c_str());
  397. // Read shape name
  398. ObjectName shape_name;
  399. shape_name.name = keys[i].to_string_id();
  400. shape_name.index = i;
  401. // Read shape object
  402. PhysicsConfigShape ps2;
  403. ps2.trigger = shape.key("trigger").to_bool();
  404. ps2.collision_filter = shape.key("collision_filter").to_string_id();
  405. array::push_back(names, shape_name);
  406. array::push_back(objects, ps2);
  407. }
  408. }
  409. void parse_actors(JSONElement e, Array<ObjectName>& names, Array<PhysicsConfigActor>& objects)
  410. {
  411. Vector<DynamicString> keys(default_allocator());
  412. e.to_keys(keys);
  413. for (uint32_t i = 0; i < vector::size(keys); i++)
  414. {
  415. JSONElement actor = e.key(keys[i].c_str());
  416. // Read actor name
  417. ObjectName actor_name;
  418. actor_name.name = keys[i].to_string_id();
  419. actor_name.index = i;
  420. // Read actor object
  421. PhysicsConfigActor pa2;
  422. pa2.linear_damping = actor.key_or_nil("linear_damping").to_float(0.0f);
  423. pa2.angular_damping = actor.key_or_nil("angular_damping").to_float(0.05f);
  424. JSONElement dynamic = actor.key_or_nil("dynamic");
  425. JSONElement kinematic = actor.key_or_nil("kinematic");
  426. JSONElement disable_gravity = actor.key_or_nil("disable_gravity");
  427. pa2.flags = 0;
  428. if (!dynamic.is_nil())
  429. {
  430. pa2.flags |= dynamic.to_bool() ? 1 : 0;
  431. }
  432. if (!kinematic.is_nil())
  433. {
  434. pa2.flags |= kinematic.to_bool() ? PhysicsConfigActor::KINEMATIC : 0;
  435. }
  436. if (!disable_gravity.is_nil())
  437. {
  438. pa2.flags |= disable_gravity.to_bool() ? PhysicsConfigActor::DISABLE_GRAVITY : 0;
  439. }
  440. array::push_back(names, actor_name);
  441. array::push_back(objects, pa2);
  442. }
  443. }
  444. uint32_t new_filter_mask()
  445. {
  446. static uint32_t mask = 1;
  447. CE_ASSERT(mask != 0x80000000u, "Too many collision filters");
  448. uint32_t tmp = mask;
  449. mask = mask << 1;
  450. return tmp;
  451. }
  452. uint32_t filter_to_mask(const char* f)
  453. {
  454. if (map::has(*s_ftm, DynamicString(f)))
  455. return map::get(*s_ftm, DynamicString(f), 0u);
  456. uint32_t new_filter = new_filter_mask();
  457. map::set(*s_ftm, DynamicString(f), new_filter);
  458. return new_filter;
  459. }
  460. uint32_t collides_with_to_mask(const Vector<DynamicString>& coll_with)
  461. {
  462. uint32_t mask = 0;
  463. for (uint32_t i = 0; i < vector::size(coll_with); i++)
  464. {
  465. mask |= filter_to_mask(coll_with[i].c_str());
  466. }
  467. return mask;
  468. }
  469. void parse_collision_filters(JSONElement e, Array<ObjectName>& names, Array<PhysicsCollisionFilter>& objects)
  470. {
  471. Vector<DynamicString> keys(default_allocator());
  472. e.to_keys(keys);
  473. for (uint32_t i = 0; i < vector::size(keys); i++)
  474. {
  475. JSONElement filter = e.key(keys[i].c_str());
  476. JSONElement collides_with = filter.key("collides_with");
  477. // Read filter name
  478. ObjectName filter_name;
  479. filter_name.name = keys[i].to_string_id();
  480. filter_name.index = i;
  481. // Build mask
  482. Vector<DynamicString> collides_with_vector(default_allocator());
  483. collides_with.to_array(collides_with_vector);
  484. PhysicsCollisionFilter pcf;
  485. pcf.me = filter_to_mask(keys[i].c_str());
  486. pcf.mask = collides_with_to_mask(collides_with_vector);
  487. // printf("FILTER: %s (me = %X, mask = %X\n", keys[i].c_str(), pcf.me, pcf.mask);
  488. array::push_back(names, filter_name);
  489. array::push_back(objects, pcf);
  490. }
  491. }
  492. void compile(const char* path, CompileOptions& opts)
  493. {
  494. static const uint32_t VERSION = 1;
  495. Buffer buf = opts.read(path);
  496. JSONParser json(array::begin(buf));
  497. JSONElement root = json.root();
  498. typedef Map<DynamicString, uint32_t> FilterMap;
  499. s_ftm = CE_NEW(default_allocator(), FilterMap)(default_allocator());
  500. Array<ObjectName> material_names(default_allocator());
  501. Array<PhysicsConfigMaterial> material_objects(default_allocator());
  502. Array<ObjectName> shape_names(default_allocator());
  503. Array<PhysicsConfigShape> shape_objects(default_allocator());
  504. Array<ObjectName> actor_names(default_allocator());
  505. Array<PhysicsConfigActor> actor_objects(default_allocator());
  506. Array<ObjectName> filter_names(default_allocator());
  507. Array<PhysicsCollisionFilter> filter_objects(default_allocator());
  508. // Parse materials
  509. if (root.has_key("collision_filters")) parse_collision_filters(root.key("collision_filters"), filter_names, filter_objects);
  510. if (root.has_key("materials")) parse_materials(root.key("materials"), material_names, material_objects);
  511. if (root.has_key("shapes")) parse_shapes(root.key("shapes"), shape_names, shape_objects);
  512. if (root.has_key("actors")) parse_actors(root.key("actors"), actor_names, actor_objects);
  513. // Sort objects by name
  514. std::sort(array::begin(material_names), array::end(material_names), ObjectName());
  515. std::sort(array::begin(shape_names), array::end(shape_names), ObjectName());
  516. std::sort(array::begin(actor_names), array::end(actor_names), ObjectName());
  517. std::sort(array::begin(filter_names), array::end(filter_names), ObjectName());
  518. // Setup struct for writing
  519. PhysicsConfigResource pcr;
  520. pcr.version = VERSION;
  521. pcr.num_materials = array::size(material_names);
  522. pcr.num_shapes = array::size(shape_names);
  523. pcr.num_actors = array::size(actor_names);
  524. pcr.num_filters = array::size(filter_names);
  525. uint32_t offt = sizeof(PhysicsConfigResource);
  526. pcr.materials_offset = offt;
  527. offt += sizeof(StringId32) * pcr.num_materials;
  528. offt += sizeof(PhysicsConfigMaterial) * pcr.num_materials;
  529. pcr.shapes_offset = offt;
  530. offt += sizeof(StringId32) * pcr.num_shapes;
  531. offt += sizeof(PhysicsConfigShape) * pcr.num_shapes;
  532. pcr.actors_offset = offt;
  533. offt += sizeof(StringId32) * pcr.num_actors;
  534. offt += sizeof(PhysicsConfigActor) * pcr.num_actors;
  535. pcr.filters_offset = offt;
  536. offt += sizeof(StringId32) * pcr.num_filters;
  537. offt += sizeof(PhysicsCollisionFilter) * pcr.num_filters;
  538. // Write all
  539. opts.write(pcr.version);
  540. opts.write(pcr.num_materials);
  541. opts.write(pcr.materials_offset);
  542. opts.write(pcr.num_shapes);
  543. opts.write(pcr.shapes_offset);
  544. opts.write(pcr.num_actors);
  545. opts.write(pcr.actors_offset);
  546. opts.write(pcr.num_filters);
  547. opts.write(pcr.filters_offset);
  548. // Write material names
  549. for (uint32_t i = 0; i < pcr.num_materials; i++)
  550. {
  551. opts.write(material_names[i].name);
  552. }
  553. // Write material objects
  554. for (uint32_t i = 0; i < pcr.num_materials; i++)
  555. {
  556. opts.write(material_objects[material_names[i].index].static_friction);
  557. opts.write(material_objects[material_names[i].index].dynamic_friction);
  558. opts.write(material_objects[material_names[i].index].restitution);
  559. }
  560. // Write shape names
  561. for (uint32_t i = 0; i < pcr.num_shapes; i++)
  562. {
  563. opts.write(shape_names[i].name);
  564. }
  565. // Write material objects
  566. for (uint32_t i = 0; i < pcr.num_shapes; i++)
  567. {
  568. opts.write(shape_objects[shape_names[i].index].collision_filter);
  569. opts.write(shape_objects[shape_names[i].index].trigger);
  570. opts.write(shape_objects[shape_names[i].index]._pad[0]);
  571. opts.write(shape_objects[shape_names[i].index]._pad[1]);
  572. opts.write(shape_objects[shape_names[i].index]._pad[2]);
  573. }
  574. // Write actor names
  575. for (uint32_t i = 0; i < pcr.num_actors; i++)
  576. {
  577. opts.write(actor_names[i].name);
  578. }
  579. // Write actor objects
  580. for (uint32_t i = 0; i < pcr.num_actors; i++)
  581. {
  582. opts.write(actor_objects[actor_names[i].index].linear_damping);
  583. opts.write(actor_objects[actor_names[i].index].angular_damping);
  584. opts.write(actor_objects[actor_names[i].index].flags);
  585. }
  586. // Write filter names
  587. for (uint32_t i = 0; i < pcr.num_filters; i++)
  588. {
  589. opts.write(filter_names[i].name);
  590. }
  591. // Write filter objects
  592. for (uint32_t i = 0; i < pcr.num_filters; i++)
  593. {
  594. opts.write(filter_objects[filter_names[i].index].me);
  595. opts.write(filter_objects[filter_names[i].index].mask);
  596. }
  597. CE_DELETE(default_allocator(), s_ftm);
  598. }
  599. void* load(File& file, Allocator& a)
  600. {
  601. const size_t file_size = file.size();
  602. void* res = a.allocate(file_size);
  603. file.read(res, file_size);
  604. return res;
  605. }
  606. void online(StringId64 /*id*/, ResourceManager& /*rm*/)
  607. {
  608. }
  609. void offline(StringId64 /*id*/, ResourceManager& /*rm*/)
  610. {
  611. }
  612. void unload(Allocator& allocator, void* resource)
  613. {
  614. allocator.deallocate(resource);
  615. }
  616. uint32_t num_materials(const PhysicsConfigResource* pcr)
  617. {
  618. return pcr->num_materials;
  619. }
  620. /// Returns the material with the given @a name
  621. const PhysicsConfigMaterial* material(const PhysicsConfigResource* pcr, StringId32 name)
  622. {
  623. StringId32* begin = (StringId32*) ((char*)pcr + pcr->materials_offset);
  624. StringId32* end = begin + num_materials(pcr);
  625. StringId32* id = std::find(begin, end, name);
  626. CE_ASSERT(id != end, "Material not found");
  627. return material_by_index(pcr, id - begin);
  628. }
  629. const PhysicsConfigMaterial* material_by_index(const PhysicsConfigResource* pcr, uint32_t i)
  630. {
  631. CE_ASSERT(i < num_materials(pcr), "Index out of bounds");
  632. const PhysicsConfigMaterial* base = (PhysicsConfigMaterial*) ((char*)pcr + pcr->materials_offset + sizeof(StringId32) * num_materials(pcr));
  633. return &base[i];
  634. }
  635. uint32_t num_shapes(const PhysicsConfigResource* pcr)
  636. {
  637. return pcr->num_shapes;
  638. }
  639. const PhysicsConfigShape* shape(const PhysicsConfigResource* pcr, StringId32 name)
  640. {
  641. StringId32* begin = (StringId32*) ((char*)pcr + pcr->shapes_offset);
  642. StringId32* end = begin + num_shapes(pcr);
  643. StringId32* id = std::find(begin, end, name);
  644. CE_ASSERT(id != end, "Shape not found");
  645. return shape_by_index(pcr, id - begin);
  646. }
  647. const PhysicsConfigShape* shape_by_index(const PhysicsConfigResource* pcr, uint32_t i)
  648. {
  649. CE_ASSERT(i < num_shapes(pcr), "Index out of bounds");
  650. const PhysicsConfigShape* base = (PhysicsConfigShape*) ((char*)pcr + pcr->shapes_offset + sizeof(StringId32) * num_shapes(pcr));
  651. return &base[i];
  652. }
  653. uint32_t num_actors(const PhysicsConfigResource* pcr)
  654. {
  655. return pcr->num_actors;
  656. }
  657. /// Returns the actor with the given @a name
  658. const PhysicsConfigActor* actor(const PhysicsConfigResource* pcr, StringId32 name)
  659. {
  660. StringId32* begin = (StringId32*) ((char*)pcr + pcr->actors_offset);
  661. StringId32* end = begin + num_actors(pcr);
  662. StringId32* id = std::find(begin, end, name);
  663. CE_ASSERT(id != end, "Actor not found");
  664. return actor_by_index(pcr, id - begin);
  665. }
  666. const PhysicsConfigActor* actor_by_index(const PhysicsConfigResource* pcr, uint32_t i)
  667. {
  668. CE_ASSERT(i < num_actors(pcr), "Index out of bounds");
  669. const PhysicsConfigActor* base = (PhysicsConfigActor*) ((char*)pcr + pcr->actors_offset + sizeof(StringId32) * num_actors(pcr));
  670. return &base[i];
  671. }
  672. uint32_t num_filters(const PhysicsConfigResource* pcr)
  673. {
  674. return pcr->num_filters;
  675. }
  676. const PhysicsCollisionFilter* filter(const PhysicsConfigResource* pcr, StringId32 name)
  677. {
  678. StringId32* begin = (StringId32*) ((char*)pcr + pcr->filters_offset);
  679. StringId32* end = begin + num_filters(pcr);
  680. StringId32* id = std::find(begin, end, name);
  681. CE_ASSERT(id != end, "Filter not found");
  682. return filter_by_index(pcr, id - begin);
  683. }
  684. const PhysicsCollisionFilter* filter_by_index(const PhysicsConfigResource* pcr, uint32_t i)
  685. {
  686. CE_ASSERT(i < num_filters(pcr), "Index out of bounds");
  687. const PhysicsCollisionFilter* base = (PhysicsCollisionFilter*) ((char*)pcr + pcr->filters_offset + sizeof(StringId32) * num_filters(pcr));
  688. return &base[i];
  689. }
  690. } // namespace physics_config_resource
  691. } // namespace crown