world.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. /*
  2. * Copyright (c) 2012-2025 Daniele Bartolini et al.
  3. * SPDX-License-Identifier: MIT
  4. */
  5. #include "core/containers/hash_map.inl"
  6. #include "core/error/error.h"
  7. #include "core/list.inl"
  8. #include "core/math/matrix4x4.inl"
  9. #include "core/math/vector3.inl"
  10. #include "core/math/vector4.inl"
  11. #include "core/memory/temp_allocator.inl"
  12. #include "core/strings/string_id.inl"
  13. #include "device/device.h"
  14. #include "lua/lua_environment.h"
  15. #include "resource/resource_manager.h"
  16. #include "resource/unit_resource.h"
  17. #include "world/animation_state_machine.h"
  18. #include "world/debug_line.h"
  19. #include "world/event_stream.inl"
  20. #include "world/gui.h"
  21. #include "world/level.h"
  22. #include "world/physics_world.h"
  23. #include "world/render_world.h"
  24. #include "world/scene_graph.h"
  25. #include "world/script_world.h"
  26. #include "world/sound_world.h"
  27. #include "world/unit_manager.h"
  28. #include "world/world.h"
  29. #include <bgfx/bgfx.h>
  30. #include <bx/math.h>
  31. namespace crown
  32. {
  33. World::World(Allocator &a
  34. , ResourceManager &rm
  35. , ShaderManager &sm
  36. , MaterialManager &mm
  37. , UnitManager &um
  38. , LuaEnvironment &env
  39. , Pipeline &pl
  40. )
  41. : _marker(WORLD_MARKER)
  42. , _allocator(&a)
  43. , _resource_manager(&rm)
  44. , _shader_manager(&sm)
  45. , _material_manager(&mm)
  46. , _lua_environment(&env)
  47. , _pipeline(&pl)
  48. , _unit_manager(&um)
  49. , _lines(NULL)
  50. , _scene_graph(NULL)
  51. , _render_world(NULL)
  52. , _physics_world(NULL)
  53. , _sound_world(NULL)
  54. , _animation_state_machine(NULL)
  55. , _units(a)
  56. , _camera(a)
  57. , _camera_map(a)
  58. , _events(a)
  59. , _changed_units(a)
  60. , _changed_world(a)
  61. , _gui_buffer(sm)
  62. {
  63. _lines = create_debug_line(true);
  64. _scene_graph = CE_NEW(*_allocator, SceneGraph)(*_allocator, um);
  65. _render_world = CE_NEW(*_allocator, RenderWorld)(*_allocator, rm, sm, mm, um, pl);
  66. _physics_world = CE_NEW(*_allocator, PhysicsWorld)(*_allocator, rm, um, *_lines);
  67. _sound_world = CE_NEW(*_allocator, SoundWorld)(*_allocator);
  68. _script_world = CE_NEW(*_allocator, ScriptWorld)(*_allocator, um, rm, env, *this);
  69. _sprite_animation_player = CE_NEW(*_allocator, SpriteAnimationPlayer)(*_allocator);
  70. _mesh_animation_player = CE_NEW(*_allocator, MeshAnimationPlayer)(*_allocator);
  71. _animation_state_machine = CE_NEW(*_allocator, AnimationStateMachine)(*_allocator, rm, um, *_sprite_animation_player, *_mesh_animation_player);
  72. _gui_buffer.create();
  73. list::init_head(_guis);
  74. list::init_head(_levels);
  75. _node.next = NULL;
  76. _node.prev = NULL;
  77. }
  78. World::~World()
  79. {
  80. // Destroy loaded levels
  81. ListNode *cur;
  82. ListNode *tmp;
  83. list_for_each_safe(cur, tmp, &_levels)
  84. {
  85. Level *level = (Level *)container_of(cur, Level, _node);
  86. CE_DELETE(*_allocator, level);
  87. }
  88. // Destroy units
  89. for (u32 i = 0; i < array::size(_units); ++i)
  90. _unit_manager->destroy(_units[i]);
  91. // Destroy subsystems
  92. CE_DELETE(*_allocator, _animation_state_machine);
  93. CE_DELETE(*_allocator, _mesh_animation_player);
  94. CE_DELETE(*_allocator, _sprite_animation_player);
  95. CE_DELETE(*_allocator, _script_world);
  96. CE_DELETE(*_allocator, _sound_world);
  97. CE_DELETE(*_allocator, _physics_world);
  98. CE_DELETE(*_allocator, _render_world);
  99. CE_DELETE(*_allocator, _scene_graph);
  100. destroy_debug_line(*_lines);
  101. _marker = 0;
  102. }
  103. UnitId World::spawn_unit(StringId64 name, const Vector3 &pos, const Quaternion &rot, const Vector3 &scl)
  104. {
  105. const UnitResource *ur = (const UnitResource *)_resource_manager->get(RESOURCE_TYPE_UNIT, name);
  106. UnitId *unit_lookup = (UnitId *)default_scratch_allocator().allocate(sizeof(*unit_lookup) * ur->num_units);
  107. for (u32 i = 0; i < ur->num_units; ++i)
  108. unit_lookup[i] = _unit_manager->create();
  109. spawn_units(*this, ur, pos, rot, scl, unit_lookup);
  110. UnitId root_unit = unit_lookup[0];
  111. default_scratch_allocator().deallocate(unit_lookup);
  112. return root_unit;
  113. }
  114. UnitId World::spawn_empty_unit()
  115. {
  116. UnitId unit = _unit_manager->create();
  117. array::push_back(_units, unit);
  118. post_unit_spawned_event(unit);
  119. return unit;
  120. }
  121. void World::destroy_unit(UnitId unit)
  122. {
  123. _unit_manager->destroy(unit);
  124. for (u32 i = 0, n = array::size(_units); i < n; ++i) {
  125. if (_units[i] == unit) {
  126. _units[i] = _units[n - 1];
  127. array::pop_back(_units);
  128. break;
  129. }
  130. }
  131. post_unit_destroyed_event(unit);
  132. }
  133. u32 World::num_units() const
  134. {
  135. return array::size(_units);
  136. }
  137. void World::units(Array<UnitId> &units) const
  138. {
  139. array::reserve(units, array::size(_units));
  140. array::push(units, array::begin(_units), array::size(_units));
  141. }
  142. UnitId World::unit_by_name(StringId32 name)
  143. {
  144. ListNode *cur;
  145. list_for_each(cur, &_levels)
  146. {
  147. Level *level = (Level *)container_of(cur, Level, _node);
  148. UnitId unit = level->unit_by_name(name);
  149. if (unit != UNIT_INVALID)
  150. return unit;
  151. }
  152. return UNIT_INVALID;
  153. }
  154. void World::update_animations(f32 dt)
  155. {
  156. _animation_state_machine->update(dt);
  157. }
  158. void World::update_scene(f32 dt)
  159. {
  160. // Process animation events
  161. {
  162. EventStream &events = _animation_state_machine->_events;
  163. const u32 size = array::size(events);
  164. u32 read = 0;
  165. while (read < size) {
  166. const EventHeader *eh = (EventHeader *)&events[read];
  167. const char *data = (char *)&eh[1];
  168. read += sizeof(*eh) + eh->size;
  169. switch (eh->type) {
  170. case 0: {
  171. const SpriteFrameChangeEvent &ptev = *(SpriteFrameChangeEvent *)data;
  172. const SpriteInstance si = _render_world->sprite_instance(ptev.unit);
  173. _render_world->sprite_set_frame(si, ptev.frame_num);
  174. break;
  175. }
  176. default:
  177. CE_FATAL("Unknown event type");
  178. break;
  179. }
  180. }
  181. array::clear(events);
  182. }
  183. _scene_graph->get_changed(_changed_units, _changed_world);
  184. _physics_world->update_actor_world_poses(array::begin(_changed_units)
  185. , array::end(_changed_units)
  186. , array::begin(_changed_world)
  187. );
  188. _physics_world->update(dt);
  189. // Process physics events
  190. {
  191. EventStream &events = _physics_world->events();
  192. const u32 size = array::size(events);
  193. u32 read = 0;
  194. while (read < size) {
  195. const EventHeader *eh = (EventHeader *)&events[read];
  196. const char *data = (char *)&eh[1];
  197. read += sizeof(*eh) + eh->size;
  198. switch (eh->type) {
  199. case EventType::PHYSICS_TRANSFORM: {
  200. const PhysicsTransformEvent &ptev = *(PhysicsTransformEvent *)data;
  201. const TransformInstance ti = _scene_graph->instance(ptev.unit_id);
  202. if (is_valid(ti)) // User code may have destroyed the actor
  203. _scene_graph->set_world_pose_and_rescale(ti, ptev.world);
  204. break;
  205. }
  206. case EventType::PHYSICS_COLLISION: {
  207. const PhysicsCollisionEvent &pcev = *(PhysicsCollisionEvent *)data;
  208. script_world::collision(*_script_world, pcev);
  209. break;
  210. }
  211. case EventType::PHYSICS_TRIGGER:
  212. break;
  213. default:
  214. CE_FATAL("Unknown event type");
  215. break;
  216. }
  217. }
  218. array::clear(events);
  219. }
  220. array::clear(_changed_units);
  221. array::clear(_changed_world);
  222. _scene_graph->get_changed(_changed_units, _changed_world);
  223. _scene_graph->clear_changed();
  224. _render_world->update_transforms(array::begin(_changed_units)
  225. , array::end(_changed_units)
  226. , array::begin(_changed_world)
  227. );
  228. _sound_world->update();
  229. _gui_buffer.reset();
  230. array::clear(_events);
  231. script_world::update(*_script_world, dt);
  232. }
  233. void World::update(f32 dt)
  234. {
  235. update_animations(dt);
  236. update_scene(dt);
  237. }
  238. void World::render(const Matrix4x4 &view)
  239. {
  240. _render_world->render(view);
  241. _physics_world->debug_draw();
  242. _render_world->debug_draw(*_lines);
  243. _lines->submit();
  244. _lines->reset();
  245. }
  246. CameraInstance World::camera_create(UnitId unit, const CameraDesc &cd, const Matrix4x4 & /*tr*/)
  247. {
  248. CE_ASSERT(!hash_map::has(_camera_map, unit), "Unit already has a camera component");
  249. Camera camera;
  250. camera.unit = unit;
  251. camera.projection_type = (ProjectionType::Enum)cd.type;
  252. camera.fov = cd.fov;
  253. camera.near_range = cd.near_range;
  254. camera.far_range = cd.far_range;
  255. const u32 last = array::size(_camera);
  256. array::push_back(_camera, camera);
  257. hash_map::set(_camera_map, unit, last);
  258. return camera_make_instance(last);
  259. }
  260. void World::camera_destroy(CameraInstance camera)
  261. {
  262. const u32 last = array::size(_camera) - 1;
  263. const UnitId u = _camera[camera.i].unit;
  264. const UnitId last_u = _camera[last].unit;
  265. _camera[camera.i] = _camera[last];
  266. hash_map::set(_camera_map, last_u, camera.i);
  267. hash_map::remove(_camera_map, u);
  268. }
  269. CameraInstance World::camera_instance(UnitId unit)
  270. {
  271. return camera_make_instance(hash_map::get(_camera_map, unit, UINT32_MAX));
  272. }
  273. void World::camera_set_projection_type(CameraInstance camera, ProjectionType::Enum type)
  274. {
  275. _camera[camera.i].projection_type = type;
  276. }
  277. ProjectionType::Enum World::camera_projection_type(CameraInstance camera)
  278. {
  279. return _camera[camera.i].projection_type;
  280. }
  281. Matrix4x4 World::camera_projection_matrix(CameraInstance camera, f32 aspect_ratio)
  282. {
  283. Camera &cam = _camera[camera.i];
  284. const bgfx::Caps *caps = bgfx::getCaps();
  285. f32 bx_proj[16];
  286. switch (cam.projection_type) {
  287. case ProjectionType::ORTHOGRAPHIC:
  288. bx::mtxOrtho(bx_proj
  289. , -cam.half_size * aspect_ratio
  290. , cam.half_size * aspect_ratio
  291. , -cam.half_size
  292. , cam.half_size
  293. , cam.near_range
  294. , cam.far_range
  295. , 0.0f
  296. , caps->homogeneousDepth
  297. , bx::Handedness::Right
  298. );
  299. break;
  300. case ProjectionType::PERSPECTIVE:
  301. bx::mtxProj(bx_proj
  302. , fdeg(cam.fov)
  303. , aspect_ratio
  304. , cam.near_range
  305. , cam.far_range
  306. , caps->homogeneousDepth
  307. , bx::Handedness::Right
  308. );
  309. break;
  310. default:
  311. CE_FATAL("Unknown projection type");
  312. break;
  313. }
  314. return from_array(bx_proj);
  315. }
  316. Matrix4x4 World::camera_view_matrix(CameraInstance camera)
  317. {
  318. TransformInstance ti = _scene_graph->instance(_camera[camera.i].unit);
  319. Matrix4x4 view = _scene_graph->world_pose(ti);
  320. Matrix4x4 rotate_x_90 = from_matrix3x3(from_x_axis_angle(frad(90.0f)));
  321. view = rotate_x_90 * view;
  322. invert(view);
  323. return view;
  324. }
  325. f32 World::camera_fov(CameraInstance camera)
  326. {
  327. return _camera[camera.i].fov;
  328. }
  329. void World::camera_set_fov(CameraInstance camera, f32 fov)
  330. {
  331. _camera[camera.i].fov = fov;
  332. }
  333. f32 World::camera_near_clip_distance(CameraInstance camera)
  334. {
  335. return _camera[camera.i].near_range;
  336. }
  337. void World::camera_set_near_clip_distance(CameraInstance camera, f32 near)
  338. {
  339. _camera[camera.i].near_range = near;
  340. }
  341. f32 World::camera_far_clip_distance(CameraInstance camera)
  342. {
  343. return _camera[camera.i].far_range;
  344. }
  345. void World::camera_set_far_clip_distance(CameraInstance camera, f32 far)
  346. {
  347. _camera[camera.i].far_range = far;
  348. }
  349. void World::camera_set_orthographic_size(CameraInstance camera, f32 half_size)
  350. {
  351. _camera[camera.i].half_size = half_size;
  352. }
  353. Vector3 World::camera_screen_to_world(CameraInstance camera, const Vector3 &pos)
  354. {
  355. u16 view_width;
  356. u16 view_height;
  357. device()->resolution(view_width, view_height);
  358. const f32 w = (f32)view_width;
  359. const f32 h = (f32)view_height;
  360. Matrix4x4 camera_proj = camera_projection_matrix(camera, w/h);
  361. Matrix4x4 camera_view = camera_view_matrix(camera);
  362. Matrix4x4 camera_view_proj = camera_view * camera_proj;
  363. invert(camera_view_proj);
  364. const bgfx::Caps *caps = bgfx::getCaps();
  365. Vector4 ndc;
  366. ndc.x = (2.0f * pos.x) / w - 1.0f;
  367. ndc.y = (2.0f * pos.y) / h - 1.0f;
  368. ndc.z = caps->homogeneousDepth ? (2.0f * pos.z) - 1.0f : pos.z;
  369. ndc.w = 1.0f;
  370. Vector4 tmp = ndc * camera_view_proj;
  371. tmp *= 1.0f / tmp.w;
  372. return vector3(tmp.x, tmp.y, tmp.z);
  373. }
  374. Vector3 World::camera_world_to_screen(CameraInstance camera, const Vector3 &pos)
  375. {
  376. u16 view_width;
  377. u16 view_height;
  378. device()->resolution(view_width, view_height);
  379. const f32 x = 0.0f;
  380. const f32 y = 0.0f;
  381. const f32 w = (f32)view_width;
  382. const f32 h = (f32)view_height;
  383. Matrix4x4 camera_proj = camera_projection_matrix(camera, w/h);
  384. Matrix4x4 camera_view = camera_view_matrix(camera);
  385. Matrix4x4 camera_view_proj = camera_view * camera_proj;
  386. Vector4 pos4 = vector4(pos.x, pos.y, pos.z, 1.0f);
  387. Vector4 ndc = pos4 * camera_view_proj;
  388. ndc.x *= 1.0 / ndc.w;
  389. ndc.y *= 1.0 / ndc.w;
  390. Vector3 screen;
  391. screen.x = (x + w * (ndc.x + 1.0f)) / 2.0f;
  392. screen.y = h - (y + h * (1.0f - ndc.y)) / 2.0f;
  393. screen.z = ndc.z;
  394. return screen;
  395. }
  396. SoundInstanceId World::play_sound(const SoundResource &sr, const bool loop, const f32 volume, const Vector3 &pos, const f32 range)
  397. {
  398. return _sound_world->play(sr, loop, volume, range, pos);
  399. }
  400. SoundInstanceId World::play_sound(StringId64 name, const bool loop, const f32 volume, const Vector3 &pos, const f32 range)
  401. {
  402. const SoundResource *sr = (const SoundResource *)_resource_manager->get(RESOURCE_TYPE_SOUND, name);
  403. return play_sound(*sr, loop, volume, pos, range);
  404. }
  405. void World::stop_sound(SoundInstanceId id)
  406. {
  407. _sound_world->stop(id);
  408. }
  409. void World::link_sound(SoundInstanceId /*id*/, UnitId /*unit*/, s32 /*node*/)
  410. {
  411. CE_FATAL("Not implemented yet");
  412. }
  413. void World::set_listener_pose(const Matrix4x4 &pose)
  414. {
  415. _sound_world->set_listener_pose(pose);
  416. }
  417. void World::set_sound_position(SoundInstanceId id, const Vector3 &pos)
  418. {
  419. _sound_world->set_sound_positions(1, &id, &pos);
  420. }
  421. void World::set_sound_range(SoundInstanceId id, f32 range)
  422. {
  423. _sound_world->set_sound_ranges(1, &id, &range);
  424. }
  425. void World::set_sound_volume(SoundInstanceId id, f32 vol)
  426. {
  427. _sound_world->set_sound_volumes(1, &id, &vol);
  428. }
  429. DebugLine *World::create_debug_line(bool depth_test)
  430. {
  431. return debug_line::create(*_allocator, *_pipeline, depth_test);
  432. }
  433. void World::destroy_debug_line(DebugLine &line)
  434. {
  435. CE_DELETE(*_allocator, &line);
  436. }
  437. Gui *World::create_screen_gui()
  438. {
  439. Gui *gui = gui::create_screen_gui(*_allocator
  440. , _gui_buffer
  441. , *_resource_manager
  442. , *_shader_manager
  443. , *_material_manager
  444. , &_pipeline->_gui_shader
  445. );
  446. list::add(gui->_node, _guis);
  447. return gui;
  448. }
  449. Gui *World::create_world_gui()
  450. {
  451. Gui *gui = gui::create_world_gui(*_allocator
  452. , _gui_buffer
  453. , *_resource_manager
  454. , *_shader_manager
  455. , *_material_manager
  456. , &_pipeline->_gui_3d_shader
  457. );
  458. list::add(gui->_node, _guis);
  459. return gui;
  460. }
  461. void World::destroy_gui(Gui &gui)
  462. {
  463. list::remove(gui._node);
  464. CE_DELETE(*_allocator, &gui);
  465. }
  466. Level *World::load_level(StringId64 name, const Vector3 &pos, const Quaternion &rot)
  467. {
  468. const LevelResource *lr = (const LevelResource *)_resource_manager->get(RESOURCE_TYPE_LEVEL, name);
  469. Level *level = CE_NEW(*_allocator, Level)(*_allocator, *_unit_manager, *this, *lr);
  470. level->load(pos, rot);
  471. list::add(level->_node, _levels);
  472. post_level_loaded_event();
  473. return level;
  474. }
  475. void World::post_unit_spawned_event(UnitId unit)
  476. {
  477. UnitSpawnedEvent ev;
  478. ev.unit = unit;
  479. event_stream::write(_events, EventType::UNIT_SPAWNED, ev);
  480. }
  481. void World::post_unit_destroyed_event(UnitId unit)
  482. {
  483. UnitDestroyedEvent ev;
  484. ev.unit = unit;
  485. event_stream::write(_events, EventType::UNIT_DESTROYED, ev);
  486. }
  487. void World::post_level_loaded_event()
  488. {
  489. LevelLoadedEvent ev;
  490. event_stream::write(_events, EventType::LEVEL_LOADED, ev);
  491. }
  492. void World::disable_unit_callbacks()
  493. {
  494. #if CROWN_DEBUG
  495. _script_world->_disable_callbacks = true;
  496. #endif
  497. }
  498. void World::reload_materials(const MaterialResource *old_resource, const MaterialResource *new_resource)
  499. {
  500. #if CROWN_CAN_RELOAD
  501. _render_world->reload_materials(old_resource, new_resource);
  502. #else
  503. CE_UNUSED_2(old_resource, new_resource);
  504. CE_NOOP();
  505. #endif
  506. }
  507. void spawn_units(World &w, const UnitResource *ur, const Vector3 &pos, const Quaternion &rot, const Vector3 &scl, const UnitId *unit_lookup)
  508. {
  509. SceneGraph *scene_graph = w._scene_graph;
  510. RenderWorld *render_world = w._render_world;
  511. PhysicsWorld *physics_world = w._physics_world;
  512. ScriptWorld *script_world = w._script_world;
  513. AnimationStateMachine *animation_state_machine = w._animation_state_machine;
  514. const u32 *unit_parents = unit_resource::parents(ur);
  515. // Create components
  516. const ComponentData *component = unit_resource::component_type_data(ur, NULL);
  517. for (u32 cc = 0; cc < ur->num_component_types; ++cc) {
  518. const u32 *unit_index = unit_resource::component_unit_index(component);
  519. const char *data = unit_resource::component_payload(component);
  520. if (component->type == STRING_ID_32("transform", UINT32_C(0xad9b5315))) {
  521. const TransformDesc *td = (const TransformDesc *)data;
  522. for (u32 i = 0, n = component->num_instances; i < n; ++i, ++td) {
  523. // FIXME: add SceneGraph::allocate() to reserve an instance
  524. // without initializing it.
  525. const TransformInstance ti = scene_graph->create(unit_lookup[unit_index[i]]
  526. , td->position
  527. , td->rotation
  528. , td->scale
  529. );
  530. if (unit_parents[unit_index[i]] != UINT32_MAX) {
  531. TransformInstance parent_ti = scene_graph->instance(unit_lookup[unit_parents[unit_index[i]]]);
  532. scene_graph->link(parent_ti, ti, td->position, td->rotation, td->scale);
  533. } else {
  534. const Vector3 scale = vector3(td->scale.x * scl.x
  535. , td->scale.y * scl.y
  536. , td->scale.z * scl.z
  537. );
  538. Matrix4x4 tr = from_quaternion_translation(rot, pos);
  539. scene_graph->set_local_pose(ti, scene_graph->local_pose(ti) * tr);
  540. scene_graph->set_local_scale(ti, scale);
  541. }
  542. }
  543. } else if (component->type == STRING_ID_32("camera", UINT32_C(0x31822dc7))) {
  544. const CameraDesc *cd = (const CameraDesc *)data;
  545. for (u32 i = 0, n = component->num_instances; i < n; ++i, ++cd) {
  546. w.camera_create(unit_lookup[unit_index[i]], *cd, MATRIX4X4_IDENTITY);
  547. }
  548. } else if (component->type == STRING_ID_32("collider", UINT32_C(0x2129d74e))) {
  549. const ColliderDesc *cd = (const ColliderDesc *)data;
  550. for (u32 i = 0, n = component->num_instances; i < n; ++i) {
  551. TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
  552. Matrix4x4 tm = scene_graph->world_pose(ti);
  553. physics_world->collider_create(unit_lookup[unit_index[i]], cd, scale(tm));
  554. cd = (ColliderDesc *)((char *)(cd + 1) + cd->size);
  555. }
  556. } else if (component->type == STRING_ID_32("actor", UINT32_C(0x374cf583))) {
  557. const ActorResource *ar = (const ActorResource *)data;
  558. for (u32 i = 0, n = component->num_instances; i < n; ++i, ++ar) {
  559. TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
  560. Matrix4x4 tm = scene_graph->world_pose(ti);
  561. physics_world->actor_create(unit_lookup[unit_index[i]], ar, from_quaternion_translation(rotation(tm), translation(tm)));
  562. }
  563. } else if (component->type == STRING_ID_32("mesh_renderer", UINT32_C(0xdf017893))) {
  564. const MeshRendererDesc *mrd = (const MeshRendererDesc *)data;
  565. for (u32 i = 0, n = component->num_instances; i < n; ++i, ++mrd) {
  566. TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
  567. Matrix4x4 tm = scene_graph->world_pose(ti);
  568. render_world->mesh_create(unit_lookup[unit_index[i]], *mrd, tm);
  569. }
  570. } else if (component->type == STRING_ID_32("sprite_renderer", UINT32_C(0x6a1c2a3b))) {
  571. const SpriteRendererDesc *srd = (const SpriteRendererDesc *)data;
  572. for (u32 i = 0, n = component->num_instances; i < n; ++i, ++srd) {
  573. TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
  574. Matrix4x4 tm = scene_graph->world_pose(ti);
  575. render_world->sprite_create(unit_lookup[unit_index[i]], *srd, tm);
  576. }
  577. } else if (component->type == STRING_ID_32("light", UINT32_C(0xbb9f08c2))) {
  578. const LightDesc *ld = (const LightDesc *)data;
  579. for (u32 i = 0, n = component->num_instances; i < n; ++i, ++ld) {
  580. TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
  581. Matrix4x4 tm = scene_graph->world_pose(ti);
  582. render_world->light_create(unit_lookup[unit_index[i]], *ld, tm);
  583. }
  584. } else if (component->type == STRING_ID_32("script", UINT32_C(0xd18f8ad6))) {
  585. const ScriptDesc *sd = (const ScriptDesc *)data;
  586. for (u32 i = 0, n = component->num_instances; i < n; ++i, ++sd) {
  587. script_world::create(*script_world, unit_lookup[unit_index[i]], *sd);
  588. }
  589. } else if (component->type == STRING_ID_32("animation_state_machine", UINT32_C(0xe87992ac))) {
  590. const AnimationStateMachineDesc *asmd = (const AnimationStateMachineDesc *)data;
  591. for (u32 i = 0, n = component->num_instances; i < n; ++i, ++asmd) {
  592. animation_state_machine->create(unit_lookup[unit_index[i]], *asmd);
  593. }
  594. } else {
  595. CE_FATAL("Unknown component type");
  596. }
  597. component = unit_resource::component_type_data(ur, component);
  598. }
  599. for (u32 i = 0; i < ur->num_units; ++i)
  600. array::push_back(w._units, unit_lookup[i]);
  601. // Post events
  602. for (u32 i = 0; i < ur->num_units; ++i)
  603. w.post_unit_spawned_event(unit_lookup[i]);
  604. }
  605. } // namespace crown