unit.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. /*
  2. * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "unit.h"
  6. #include "world.h"
  7. #include "memory.h"
  8. #include "log.h"
  9. #include "unit_resource.h"
  10. #include "actor.h"
  11. #include "controller.h"
  12. #include "physics_resource.h"
  13. #include "device.h"
  14. #include "resource_manager.h"
  15. #include "sprite.h"
  16. #include "sprite_animation_player.h"
  17. namespace crown
  18. {
  19. using namespace unit_resource;
  20. Unit::Unit(World& w, UnitId unit_id, const UnitResource* ur, SceneGraph& sg, const Matrix4x4& pose)
  21. : m_world(w)
  22. , m_scene_graph(sg)
  23. , m_sprite_animation(NULL)
  24. , m_resource(ur)
  25. , m_id(unit_id)
  26. , m_num_cameras(0)
  27. , m_num_sprites(0)
  28. , m_num_actors(0)
  29. , m_num_materials(0)
  30. , m_values(NULL)
  31. {
  32. m_controller.component.id = INVALID_ID;
  33. create_objects(pose);
  34. }
  35. Unit::~Unit()
  36. {
  37. destroy_objects();
  38. }
  39. void Unit::set_id(const UnitId id)
  40. {
  41. m_id = id;
  42. }
  43. UnitId Unit::id()
  44. {
  45. return m_id;
  46. }
  47. const UnitResource* Unit::resource() const
  48. {
  49. return m_resource;
  50. }
  51. void Unit::create_objects(const Matrix4x4& pose)
  52. {
  53. using namespace unit_resource;
  54. m_scene_graph.create(pose, m_id);
  55. create_camera_objects();
  56. create_renderable_objects();
  57. create_physics_objects();
  58. set_default_material();
  59. m_values = (char*) default_allocator().allocate(values_size(m_resource));
  60. memcpy(m_values, values(m_resource), values_size(m_resource));
  61. StringId64 anim_id = sprite_animation(m_resource);
  62. if (anim_id.id() != 0)
  63. {
  64. m_sprite_animation = m_world.sprite_animation_player()->create_sprite_animation((SpriteAnimationResource*) device()->resource_manager()->get(SPRITE_ANIMATION_TYPE, anim_id));
  65. }
  66. }
  67. void Unit::destroy_objects()
  68. {
  69. if (m_sprite_animation)
  70. {
  71. m_world.sprite_animation_player()->destroy_sprite_animation(m_sprite_animation);
  72. }
  73. default_allocator().deallocate(m_values);
  74. // Destroy cameras
  75. for (uint32_t i = 0; i < m_num_cameras; i++)
  76. {
  77. m_world.destroy_camera(m_cameras[i].component);
  78. }
  79. m_num_cameras = 0;
  80. // Destroy sprites
  81. for (uint32_t i = 0; i < m_num_sprites; i++)
  82. {
  83. m_world.render_world()->destroy_sprite(m_sprites[i].component);
  84. }
  85. m_num_sprites = 0;
  86. // Destroy actors
  87. for (uint32_t i = 0; i < m_num_actors; i++)
  88. {
  89. m_world.physics_world()->destroy_actor(m_actors[i].component);
  90. }
  91. m_num_actors = 0;
  92. // Destroy controller
  93. if (m_controller.component.id != INVALID_ID)
  94. {
  95. m_world.physics_world()->destroy_controller(m_controller.component);
  96. m_controller.component.id = INVALID_ID;
  97. }
  98. // Destroy materials
  99. for (uint32_t i = 0; i < m_num_materials; i++)
  100. {
  101. material_manager::get()->destroy_material(m_materials[i].component);
  102. }
  103. m_num_materials = 0;
  104. // Destroy scene graph
  105. m_scene_graph.destroy(m_scene_graph.get(m_id));
  106. }
  107. void Unit::create_camera_objects()
  108. {
  109. for (uint32_t i = 0; i < num_cameras(m_resource); i++)
  110. {
  111. const UnitCamera* cam = get_camera(m_resource, i);
  112. const CameraId id = m_world.create_camera(m_scene_graph, m_id, (ProjectionType::Enum)cam->type, cam->near, cam->far);
  113. add_camera(cam->name, id);
  114. }
  115. }
  116. void Unit::create_renderable_objects()
  117. {
  118. for (uint32_t i = 0; i < num_materials(m_resource); i++)
  119. {
  120. const UnitMaterial* mat = get_material(m_resource, i);
  121. add_material(StringId32("default"), material_manager::get()->create_material(mat->id));
  122. }
  123. // Create renderables
  124. for (uint32_t i = 0; i < num_renderables(m_resource); i++)
  125. {
  126. const UnitRenderable* ur = get_renderable(m_resource, i);
  127. if (ur->type == UnitRenderable::MESH)
  128. {
  129. // MeshResource* mr = (MeshResource*) device()->resource_manager()->get(MESH_TYPE, ur->resource);
  130. // m_world.render_world()->create_mesh(mr, m_materials[0].component, m_scene_graph, ur->node);
  131. }
  132. else if (ur->type == UnitRenderable::SPRITE)
  133. {
  134. SpriteResource* sr = (SpriteResource*) device()->resource_manager()->get(SPRITE_TYPE, ur->resource);
  135. SpriteId sprite = m_world.render_world()->create_sprite(sr, m_scene_graph, m_id);
  136. add_sprite(ur->name, sprite);
  137. }
  138. else
  139. {
  140. CE_FATAL("Oops, bad renderable type");
  141. }
  142. }
  143. }
  144. void Unit::create_physics_objects()
  145. {
  146. using namespace unit_resource;
  147. using namespace physics_resource;
  148. if (unit_resource::physics_resource(m_resource).id() != 0)
  149. {
  150. const PhysicsResource* pr = (PhysicsResource*) device()->resource_manager()->get(PHYSICS_TYPE, unit_resource::physics_resource(m_resource));
  151. // Create controller if any
  152. if (has_controller(pr))
  153. {
  154. const ControllerResource* cr = physics_resource::controller(pr);
  155. set_controller(cr->name, m_world.physics_world()->create_controller(cr, m_scene_graph, m_id));
  156. }
  157. // Create actors if any
  158. for (uint32_t i = 0; i < num_actors(pr); i++)
  159. {
  160. const ActorResource* ar = physics_resource::actor(pr, i);
  161. ActorId id = m_world.physics_world()->create_actor(ar, m_scene_graph, m_id);
  162. add_actor(ar->name, id);
  163. }
  164. // Create joints if any
  165. for (uint32_t i = 0; i < num_joints(pr); i++)
  166. {
  167. const JointResource* jr = physics_resource::joint(pr, i);
  168. m_world.physics_world()->create_joint(jr, *actor_by_index(jr->actor_0), *actor_by_index(jr->actor_1));
  169. }
  170. }
  171. }
  172. void Unit::set_default_material()
  173. {
  174. if (m_num_materials == 0) return;
  175. for (uint32_t i = 0; i < m_num_sprites; i++)
  176. {
  177. Sprite* s = m_world.render_world()->get_sprite(m_sprites[i].component);
  178. s->set_material(m_materials[0].component);
  179. }
  180. }
  181. Vector3 Unit::local_position() const
  182. {
  183. TransformInstance ti = m_scene_graph.get(m_id);
  184. return m_scene_graph.local_position(ti);
  185. }
  186. Quaternion Unit::local_rotation() const
  187. {
  188. TransformInstance ti = m_scene_graph.get(m_id);
  189. return m_scene_graph.local_rotation(ti);
  190. }
  191. Vector3 Unit::local_scale() const
  192. {
  193. TransformInstance ti = m_scene_graph.get(m_id);
  194. return m_scene_graph.local_scale(ti);
  195. }
  196. Matrix4x4 Unit::local_pose() const
  197. {
  198. TransformInstance ti = m_scene_graph.get(m_id);
  199. return m_scene_graph.local_pose(ti);
  200. }
  201. Vector3 Unit::world_position() const
  202. {
  203. TransformInstance ti = m_scene_graph.get(m_id);
  204. return m_scene_graph.world_position(ti);
  205. }
  206. Quaternion Unit::world_rotation() const
  207. {
  208. TransformInstance ti = m_scene_graph.get(m_id);
  209. return m_scene_graph.world_rotation(ti);
  210. }
  211. Matrix4x4 Unit::world_pose() const
  212. {
  213. TransformInstance ti = m_scene_graph.get(m_id);
  214. return m_scene_graph.world_pose(ti);
  215. }
  216. void Unit::set_local_position(const Vector3& pos)
  217. {
  218. TransformInstance ti = m_scene_graph.get(m_id);
  219. m_scene_graph.set_local_position(ti, pos);
  220. }
  221. void Unit::set_local_rotation(const Quaternion& rot)
  222. {
  223. TransformInstance ti = m_scene_graph.get(m_id);
  224. m_scene_graph.set_local_rotation(ti, rot);
  225. }
  226. void Unit::set_local_scale(const Vector3& scale)
  227. {
  228. TransformInstance ti = m_scene_graph.get(m_id);
  229. m_scene_graph.set_local_scale(ti, scale);
  230. }
  231. void Unit::set_local_pose(const Matrix4x4& pose)
  232. {
  233. TransformInstance ti = m_scene_graph.get(m_id);
  234. m_scene_graph.set_local_pose(ti, pose);
  235. }
  236. void Unit::update()
  237. {
  238. if (m_sprite_animation)
  239. {
  240. sprite(0u)->set_frame(m_sprite_animation->m_cur_frame);
  241. }
  242. }
  243. void Unit::reload(UnitResource* new_ur)
  244. {
  245. TransformInstance ti = m_scene_graph.get(m_id);
  246. Matrix4x4 m = m_scene_graph.world_pose(ti);
  247. destroy_objects();
  248. m_resource = new_ur;
  249. create_objects(m);
  250. }
  251. void Unit::add_component(StringId32 name, Id component, uint32_t& size, Component* array)
  252. {
  253. Component comp;
  254. comp.name = name;
  255. comp.component = component;
  256. array[size] = comp;
  257. size++;
  258. }
  259. Id Unit::find_component(const char* name, uint32_t size, Component* array)
  260. {
  261. return find_component_by_name(StringId32(name), size, array);
  262. }
  263. Id Unit::find_component_by_index(uint32_t index, uint32_t size, Component* array)
  264. {
  265. Id comp;
  266. comp.id = INVALID_ID;
  267. if (index < size)
  268. {
  269. comp = array[index].component;
  270. }
  271. return comp;
  272. }
  273. Id Unit::find_component_by_name(StringId32 name, uint32_t size, Component* array)
  274. {
  275. Id comp;
  276. comp.id = INVALID_ID;
  277. for (uint32_t i = 0; i < size; i++)
  278. {
  279. if (name == array[i].name)
  280. {
  281. comp = array[i].component;
  282. }
  283. }
  284. return comp;
  285. }
  286. void Unit::add_camera(StringId32 name, CameraId camera)
  287. {
  288. CE_ASSERT(m_num_cameras < CE_MAX_CAMERA_COMPONENTS, "Max camera number reached");
  289. add_component(name, camera, m_num_cameras, m_cameras);
  290. }
  291. void Unit::add_sprite(StringId32 name, SpriteId sprite)
  292. {
  293. CE_ASSERT(m_num_sprites < CE_MAX_SPRITE_COMPONENTS, "Max sprite number reached");
  294. add_component(name, sprite, m_num_sprites, m_sprites);
  295. }
  296. void Unit::add_actor(StringId32 name, ActorId actor)
  297. {
  298. CE_ASSERT(m_num_actors < CE_MAX_ACTOR_COMPONENTS, "Max actor number reached");
  299. add_component(name, actor, m_num_actors, m_actors);
  300. }
  301. void Unit::add_material(StringId32 name, MaterialId material)
  302. {
  303. CE_ASSERT(m_num_materials < CE_MAX_MATERIAL_COMPONENTS, "Max material number reached");
  304. add_component(name, material, m_num_materials, m_materials);
  305. }
  306. void Unit::set_controller(StringId32 name, ControllerId controller)
  307. {
  308. m_controller.name = name;
  309. m_controller.component = controller;
  310. }
  311. Camera* Unit::camera(const char* name)
  312. {
  313. CameraId cam = find_component(name, m_num_cameras, m_cameras);
  314. CE_ASSERT(cam.id != INVALID_ID, "Unit does not have camera with name '%s'", name);
  315. return m_world.get_camera(cam);
  316. }
  317. Camera* Unit::camera(uint32_t i)
  318. {
  319. CameraId cam = find_component_by_index(i, m_num_cameras, m_cameras);
  320. CE_ASSERT(cam.id != INVALID_ID, "Unit does not have camera with index '%d'", i);
  321. return m_world.get_camera(cam);
  322. }
  323. Sprite* Unit::sprite(const char* name)
  324. {
  325. SpriteId sprite = find_component(name, m_num_sprites, m_sprites);
  326. CE_ASSERT(sprite.id != INVALID_ID, "Unit does not have sprite with name '%s'", name);
  327. return m_world.render_world()->get_sprite(sprite);
  328. }
  329. Sprite* Unit::sprite(uint32_t i)
  330. {
  331. SpriteId sprite = find_component_by_index(i, m_num_sprites, m_sprites);
  332. CE_ASSERT(sprite.id != INVALID_ID, "Unit does not have sprite with index '%d'", i);
  333. return m_world.render_world()->get_sprite(sprite);
  334. }
  335. Actor* Unit::actor(const char* name)
  336. {
  337. ActorId actor = find_component(name, m_num_actors, m_actors);
  338. CE_ASSERT(actor.id != INVALID_ID, "Unit does not have actor with name '%s'", name);
  339. return m_world.physics_world()->get_actor(actor);
  340. }
  341. Actor* Unit::actor(uint32_t i)
  342. {
  343. ActorId actor = find_component_by_index(i, m_num_actors, m_actors);
  344. CE_ASSERT(actor.id != INVALID_ID, "Unit does not have actor with index '%d'", i);
  345. return m_world.physics_world()->get_actor(actor);
  346. }
  347. Actor* Unit::actor_by_index(StringId32 name)
  348. {
  349. ActorId actor = find_component_by_name(name, m_num_actors, m_actors);
  350. CE_ASSERT(actor.id != INVALID_ID, "Unit does not have actor with name '%d'", name);
  351. return m_world.physics_world()->get_actor(actor);
  352. }
  353. Controller* Unit::controller()
  354. {
  355. if (m_controller.component.id != INVALID_ID)
  356. {
  357. return m_world.physics_world()->get_controller(m_controller.component);
  358. }
  359. return NULL;
  360. }
  361. Material* Unit::material(const char* name)
  362. {
  363. MaterialId material = find_component(name, m_num_materials, m_materials);
  364. CE_ASSERT(material.id != INVALID_ID, "Unit does not have material with name '%s'", name);
  365. return material_manager::get()->lookup_material(material);
  366. }
  367. Material* Unit::material(uint32_t i)
  368. {
  369. MaterialId material = find_component_by_index(i, m_num_materials, m_materials);
  370. CE_ASSERT(material.id != INVALID_ID, "Unit does not have material with name '%d'", i);
  371. return material_manager::get()->lookup_material(material);
  372. }
  373. bool Unit::is_a(StringId64 name)
  374. {
  375. return m_resource->name == name;
  376. }
  377. void Unit::play_sprite_animation(const char* name, bool loop)
  378. {
  379. if (m_sprite_animation)
  380. m_sprite_animation->play(StringId32(name), loop);
  381. }
  382. void Unit::stop_sprite_animation()
  383. {
  384. if (m_sprite_animation)
  385. m_sprite_animation->stop();
  386. }
  387. bool Unit::has_key(const char* k) const
  388. {
  389. using namespace unit_resource;
  390. return unit_resource::has_key(m_resource, k);
  391. }
  392. ValueType::Enum Unit::value_type(const char* k)
  393. {
  394. using namespace unit_resource;
  395. Key key;
  396. unit_resource::get_key(m_resource, k, key);
  397. return (ValueType::Enum) key.type;
  398. }
  399. bool Unit::get_key(const char* k, bool& v) const
  400. {
  401. using namespace unit_resource;
  402. Key key;
  403. bool has = unit_resource::get_key(m_resource, k, key);
  404. v = *(uint32_t*)(m_values + key.offset);
  405. return has;
  406. }
  407. bool Unit::get_key(const char* k, float& v) const
  408. {
  409. using namespace unit_resource;
  410. Key key;
  411. bool has = unit_resource::get_key(m_resource, k, key);
  412. v = *(float*)(m_values + key.offset);
  413. return has;
  414. }
  415. bool Unit::get_key(const char* k, StringId32& v) const
  416. {
  417. using namespace unit_resource;
  418. Key key;
  419. bool has = unit_resource::get_key(m_resource, k, key);
  420. v = *(StringId32*)(m_values + key.offset);
  421. return has;
  422. }
  423. bool Unit::get_key(const char* k, Vector3& v) const
  424. {
  425. using namespace unit_resource;
  426. Key key;
  427. bool has = unit_resource::get_key(m_resource, k, key);
  428. v = *(Vector3*)(m_values + key.offset);
  429. return has;
  430. }
  431. void Unit::set_key(const char* k, bool v)
  432. {
  433. using namespace unit_resource;
  434. Key key;
  435. unit_resource::get_key(m_resource, k, key);
  436. *(uint32_t*)(m_values + key.offset) = v;
  437. }
  438. void Unit::set_key(const char* k, float v)
  439. {
  440. using namespace unit_resource;
  441. Key key;
  442. unit_resource::get_key(m_resource, k, key);
  443. *(float*)(m_values + key.offset) = v;
  444. }
  445. void Unit::set_key(const char* k, const char* v)
  446. {
  447. using namespace unit_resource;
  448. Key key;
  449. unit_resource::get_key(m_resource, k, key);
  450. *(StringId32*)(m_values + key.offset) = StringId32(v);
  451. }
  452. void Unit::set_key(const char* k, const Vector3& v)
  453. {
  454. using namespace unit_resource;
  455. Key key;
  456. unit_resource::get_key(m_resource, k, key);
  457. *(Vector3*)(m_values + key.offset) = v;
  458. }
  459. } // namespace crown