world.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. * Copyright (c) 2012-2014 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include <new>
  6. #include "assert.h"
  7. #include "world.h"
  8. #include "device.h"
  9. #include "resource_manager.h"
  10. #include "debug_line.h"
  11. #include "actor.h"
  12. #include "lua_environment.h"
  13. #include "level_resource.h"
  14. #include "memory.h"
  15. #include "matrix4x4.h"
  16. #include "int_setting.h"
  17. namespace crown
  18. {
  19. static IntSetting g_physics_debug("physics.debug", "Enable physics debug rendering.", 0, 0, 1);
  20. World::World()
  21. : m_unit_pool(default_allocator(), CE_MAX_UNITS, sizeof(Unit), CE_ALIGNOF(Unit))
  22. , m_camera_pool(default_allocator(), CE_MAX_CAMERAS, sizeof(Camera), CE_ALIGNOF(Camera))
  23. , m_physics_world(*this)
  24. , m_events(default_allocator())
  25. , _lines(NULL)
  26. {
  27. m_id.id = INVALID_ID;
  28. m_sound_world = SoundWorld::create(default_allocator());
  29. _lines = create_debug_line(false);
  30. }
  31. World::~World()
  32. {
  33. destroy_debug_line(_lines);
  34. // Destroy all units
  35. for (uint32_t i = 0; i < id_array::size(m_units); i++)
  36. {
  37. CE_DELETE(m_unit_pool, m_units[i]);
  38. }
  39. SoundWorld::destroy(default_allocator(), m_sound_world);
  40. }
  41. WorldId World::id() const
  42. {
  43. return m_id;
  44. }
  45. void World::set_id(WorldId id)
  46. {
  47. m_id = id;
  48. }
  49. UnitId World::spawn_unit(const char* name, const Vector3& pos, const Quaternion& rot)
  50. {
  51. const ResourceId id(UNIT_EXTENSION, name);
  52. return spawn_unit(id.name, pos, rot);
  53. }
  54. UnitId World::spawn_unit(StringId64 name, const Vector3& pos, const Quaternion& rot)
  55. {
  56. UnitResource* ur = (UnitResource*)device()->resource_manager()->get(UNIT_TYPE, name);
  57. Unit* u = (Unit*) m_unit_pool.allocate(sizeof(Unit), CE_ALIGNOF(Unit));
  58. const UnitId unit_id = id_array::create(m_units, u);
  59. new (u) Unit(*this, unit_id, name, ur, Matrix4x4(rot, pos));
  60. post_unit_spawned_event(unit_id);
  61. return unit_id;
  62. }
  63. void World::destroy_unit(UnitId id)
  64. {
  65. CE_DELETE(m_unit_pool, id_array::get(m_units, id));
  66. id_array::destroy(m_units, id);
  67. post_unit_destroyed_event(id);
  68. }
  69. void World::reload_units(UnitResource* old_ur, UnitResource* new_ur)
  70. {
  71. for (uint32_t i = 0; i < id_array::size(m_units); i++)
  72. {
  73. if (m_units[i]->resource() == old_ur)
  74. {
  75. m_units[i]->reload(new_ur);
  76. }
  77. }
  78. }
  79. uint32_t World::num_units() const
  80. {
  81. return id_array::size(m_units);
  82. }
  83. void World::units(Array<UnitId>& units) const
  84. {
  85. for (uint32_t i = 0; i < id_array::size(m_units); i++)
  86. {
  87. array::push_back(units, m_units[i]->id());
  88. }
  89. }
  90. void World::link_unit(UnitId child, UnitId parent, int32_t node)
  91. {
  92. Unit* parent_unit = get_unit(parent);
  93. parent_unit->link_node(0, node);
  94. }
  95. void World::unlink_unit(UnitId /*child*/)
  96. {
  97. }
  98. Unit* World::get_unit(UnitId id)
  99. {
  100. return id_array::get(m_units, id);
  101. }
  102. Camera* World::get_camera(CameraId id)
  103. {
  104. return id_array::get(m_cameras, id);
  105. }
  106. void World::update_animations(float dt)
  107. {
  108. m_sprite_animation_player.update(dt);
  109. }
  110. void World::update_scene(float dt)
  111. {
  112. m_physics_world.update(dt);
  113. m_scenegraph_manager.update();
  114. for (uint32_t i = 0; i < id_array::size(m_units); i++)
  115. {
  116. m_units[i]->update();
  117. }
  118. m_sound_world->update();
  119. process_physics_events();
  120. }
  121. void World::update(float dt)
  122. {
  123. update_animations(dt);
  124. update_scene(dt);
  125. }
  126. void World::render(Camera* camera)
  127. {
  128. m_render_world.update(camera->view_matrix(), camera->projection_matrix(), camera->_view_x, camera->_view_y,
  129. camera->_view_width, camera->_view_height, device()->last_delta_time());
  130. if (g_physics_debug == 1)
  131. m_physics_world.draw_debug(*_lines);
  132. }
  133. CameraId World::create_camera(SceneGraph& sg, int32_t node, ProjectionType::Enum type, float near, float far)
  134. {
  135. Camera* camera = CE_NEW(m_camera_pool, Camera)(sg, node, type, near, far);
  136. return id_array::create(m_cameras, camera);
  137. }
  138. void World::destroy_camera(CameraId id)
  139. {
  140. CE_DELETE(m_camera_pool, id_array::get(m_cameras, id));
  141. id_array::destroy(m_cameras, id);
  142. }
  143. SoundInstanceId World::play_sound(const char* name, const bool loop, const float volume, const Vector3& pos, const float range)
  144. {
  145. ResourceId id(SOUND_EXTENSION, name);
  146. return play_sound(id.name, loop, volume, pos, range);
  147. }
  148. SoundInstanceId World::play_sound(StringId64 name, const bool loop, const float volume, const Vector3& pos, const float range)
  149. {
  150. SoundResource* sr = (SoundResource*)device()->resource_manager()->get(SOUND_TYPE, name);
  151. return m_sound_world->play(sr, loop, volume, pos);
  152. }
  153. void World::stop_sound(SoundInstanceId id)
  154. {
  155. m_sound_world->stop(id);
  156. }
  157. void World::link_sound(SoundInstanceId id, Unit* unit, int32_t node)
  158. {
  159. }
  160. void World::set_listener_pose(const Matrix4x4& pose)
  161. {
  162. m_sound_world->set_listener_pose(pose);
  163. }
  164. void World::set_sound_position(SoundInstanceId id, const Vector3& pos)
  165. {
  166. m_sound_world->set_sound_positions(1, &id, &pos);
  167. }
  168. void World::set_sound_range(SoundInstanceId id, float range)
  169. {
  170. m_sound_world->set_sound_ranges(1, &id, &range);
  171. }
  172. void World::set_sound_volume(SoundInstanceId id, float vol)
  173. {
  174. m_sound_world->set_sound_volumes(1, &id, &vol);
  175. }
  176. GuiId World::create_window_gui(uint16_t width, uint16_t height, const char* material)
  177. {
  178. return m_render_world.create_gui(width, height, material);
  179. }
  180. void World::destroy_gui(GuiId id)
  181. {
  182. m_render_world.destroy_gui(id);
  183. }
  184. Gui* World::get_gui(GuiId id)
  185. {
  186. return m_render_world.get_gui(id);
  187. }
  188. DebugLine* World::create_debug_line(bool depth_test)
  189. {
  190. return CE_NEW(default_allocator(), DebugLine)(depth_test);
  191. }
  192. void World::destroy_debug_line(DebugLine* line)
  193. {
  194. CE_DELETE(default_allocator(), line);
  195. }
  196. void World::load_level(const char* name)
  197. {
  198. const LevelResource* lr = (LevelResource*) device()->resource_manager()->get(LEVEL_EXTENSION, name);
  199. load_level(lr);
  200. }
  201. void World::load_level(const LevelResource* lr)
  202. {
  203. using namespace level_resource;
  204. uint32_t num = level_resource::num_units(lr);
  205. for (uint32_t i = 0; i < num; i++)
  206. {
  207. const LevelUnit* lu = level_resource::get_unit(lr, i);
  208. spawn_unit(lu->name, lu->position, lu->rotation);
  209. }
  210. num = level_resource::num_sounds(lr);
  211. for (uint32_t i = 0; i < num; i++)
  212. {
  213. const LevelSound* ls = level_resource::get_sound(lr, i);
  214. play_sound(ls->name, ls->loop, ls->volume, ls->position, ls->range);
  215. }
  216. post_level_loaded_event();
  217. }
  218. SceneGraphManager* World::scene_graph_manager()
  219. {
  220. return &m_scenegraph_manager;
  221. }
  222. SpriteAnimationPlayer* World::sprite_animation_player()
  223. {
  224. return &m_sprite_animation_player;
  225. }
  226. RenderWorld* World::render_world()
  227. {
  228. return &m_render_world;
  229. }
  230. PhysicsWorld* World::physics_world()
  231. {
  232. return &m_physics_world;
  233. }
  234. SoundWorld* World::sound_world()
  235. {
  236. return m_sound_world;
  237. }
  238. void World::post_unit_spawned_event(UnitId id)
  239. {
  240. UnitSpawnedEvent ev;
  241. ev.unit = id;
  242. event_stream::write(m_events, EventType::UNIT_SPAWNED, ev);
  243. }
  244. void World::post_unit_destroyed_event(UnitId id)
  245. {
  246. UnitDestroyedEvent ev;
  247. ev.unit = id;
  248. event_stream::write(m_events, EventType::UNIT_DESTROYED, ev);
  249. }
  250. void World::post_level_loaded_event()
  251. {
  252. LevelLoadedEvent ev;
  253. event_stream::write(m_events, EventType::LEVEL_LOADED, ev);
  254. }
  255. void World::process_physics_events()
  256. {
  257. EventStream& events = m_physics_world.events();
  258. // Read all events
  259. const char* ee = array::begin(events);
  260. while (ee != array::end(events))
  261. {
  262. event_stream::Header h = *(event_stream::Header*) ee;
  263. // CE_LOGD("=== PHYSICS EVENT ===");
  264. // CE_LOGD("type = %d", h.type);
  265. // CE_LOGD("size = %d", h.size);
  266. const char* event = ee + sizeof(event_stream::Header);
  267. switch (h.type)
  268. {
  269. case physics_world::EventType::COLLISION:
  270. {
  271. physics_world::CollisionEvent coll_ev = *(physics_world::CollisionEvent*) event;
  272. // CE_LOGD("type = %s", coll_ev.type == physics_world::CollisionEvent::BEGIN_TOUCH ? "begin" : "end");
  273. // CE_LOGD("actor_0 = (%p)", coll_ev.actors[0]);
  274. // CE_LOGD("actor_1 = (%p)", coll_ev.actors[1]);
  275. // CE_LOGD("unit_0 = (%p)", coll_ev.actors[0]->unit());
  276. // CE_LOGD("unit_1 = (%p)", coll_ev.actors[1]->unit());
  277. // CE_LOGD("where = (%f %f %f)", coll_ev.where.x, coll_ev.where.y, coll_ev.where.z);
  278. // CE_LOGD("normal = (%f %f %f)", coll_ev.normal.x, coll_ev.normal.y, coll_ev.normal.z);
  279. device()->lua_environment()->call_physics_callback(
  280. coll_ev.actors[0],
  281. coll_ev.actors[1],
  282. (id_array::has(m_units, coll_ev.actors[0]->unit_id())) ? coll_ev.actors[0]->unit() : NULL,
  283. (id_array::has(m_units, coll_ev.actors[1]->unit_id())) ? coll_ev.actors[1]->unit() : NULL,
  284. coll_ev.where,
  285. coll_ev.normal,
  286. (coll_ev.type == physics_world::CollisionEvent::BEGIN_TOUCH) ? "begin" : "end");
  287. break;
  288. }
  289. case physics_world::EventType::TRIGGER:
  290. {
  291. physics_world::TriggerEvent trigg_ev = *(physics_world::TriggerEvent*) event;
  292. // CE_LOGD("type = %s", trigg_ev.type == physics_world::TriggerEvent::BEGIN_TOUCH ? "begin" : "end");
  293. // CE_LOGD("trigger = (%p)", trigg_ev.trigger);
  294. // CE_LOGD("other = (%p)", trigg_ev.other);
  295. device()->lua_environment()->call_trigger_callback(
  296. trigg_ev.trigger,
  297. trigg_ev.other,
  298. (trigg_ev.type == physics_world::TriggerEvent::BEGIN_TOUCH ? "begin" : "end"));
  299. break;
  300. }
  301. default:
  302. {
  303. CE_FATAL("Unknown Physics event");
  304. break;
  305. }
  306. }
  307. // CE_LOGD("=====================");
  308. // Next event
  309. ee += sizeof(event_stream::Header) + h.size;
  310. }
  311. array::clear(events);
  312. }
  313. } // namespace crown