Ver Fonte

world: cleanup

Daniele Bartolini há 5 meses atrás
pai
commit
344472826d
4 ficheiros alterados com 184 adições e 189 exclusões
  1. 19 39
      src/world/level.cpp
  2. 12 10
      src/world/level.h
  3. 152 137
      src/world/world.cpp
  4. 1 3
      src/world/world.h

+ 19 - 39
src/world/level.cpp

@@ -3,25 +3,19 @@
  * SPDX-License-Identifier: MIT
  */
 
-#include "core/containers/array.inl"
 #include "core/list.inl"
 #include "core/math/constants.h"
+#include "core/memory/memory.inl"
 #include "core/strings/string_id.inl"
 #include "resource/level_resource.h"
-#include "resource/unit_resource.h"
 #include "world/level.h"
-#include "world/unit_manager.h"
-#include "world/world.h"
 
 namespace crown
 {
-Level::Level(Allocator &a, UnitManager &um, World &w, const LevelResource &lr)
+Level::Level(const LevelResource *level_resource, UnitId *unit_lookup)
 	: _marker(LEVEL_MARKER)
-	, _allocator(&a)
-	, _unit_manager(&um)
-	, _world(&w)
-	, _resource(&lr)
-	, _unit_lookup(a)
+	, _resource(level_resource)
+	, _unit_lookup(unit_lookup)
 {
 	list::init_head(_node);
 }
@@ -34,35 +28,6 @@ Level::~Level()
 	_node.prev = NULL;
 }
 
-void Level::load(const Vector3 &pos, const Quaternion &rot)
-{
-	// Spawn units
-	const UnitResource *ur = level_resource::unit_resource(_resource);
-
-	// Spawn units
-	array::resize(_unit_lookup, ur->num_units);
-	for (u32 i = 0; i < ur->num_units; ++i)
-		_unit_lookup[i] = _unit_manager->create();
-
-	spawn_units(*_world, ur, pos, rot, VECTOR3_ONE, array::begin(_unit_lookup));
-
-	// Spawn skydome.
-	_world->spawn_skydome(_resource->skydome_unit);
-
-	// Play sounds
-	const u32 num_sounds = level_resource::num_sounds(_resource);
-	for (u32 i = 0; i < num_sounds; ++i) {
-		const LevelSound *ls = level_resource::get_sound(_resource, i);
-		_world->play_sound(ls->name
-			, ls->loop
-			, ls->volume
-			, ls->position
-			, ls->range
-			, ls->group
-			);
-	}
-}
-
 UnitId Level::unit_by_name(StringId32 name)
 {
 	const StringId32 *unit_names = level_resource::unit_names(_resource);
@@ -74,4 +39,19 @@ UnitId Level::unit_by_name(StringId32 name)
 	return UNIT_INVALID;
 }
 
+namespace level
+{
+	Level *create(Allocator &a, const LevelResource *level_resource)
+	{
+		Level *l = (Level *)a.allocate(sizeof(*l) + level_resource->num_units*sizeof(UnitId));
+		return new (l) Level(level_resource, (UnitId *)&l[1]);
+	}
+
+	void destroy(Allocator &a, Level *level)
+	{
+		CE_DELETE(a, level);
+	}
+
+} // namespace level
+
 } // namespace crown

+ 12 - 10
src/world/level.h

@@ -5,9 +5,7 @@
 
 #pragma once
 
-#include "core/containers/types.h"
 #include "core/list.h"
-#include "core/math/types.h"
 #include "core/memory/types.h"
 #include "resource/types.h"
 #include "world/types.h"
@@ -20,24 +18,28 @@ namespace crown
 struct Level
 {
 	u32 _marker;
-	Allocator *_allocator;
-	UnitManager *_unit_manager;
-	World *_world;
 	const LevelResource *_resource;
-	Array<UnitId> _unit_lookup;
+	UnitId *_unit_lookup;
 	ListNode _node;
 
 	///
-	Level(Allocator &a, UnitManager &um, World &w, const LevelResource &lr);
+	Level(const LevelResource *level_resource, UnitId *unit_lookup);
 
 	///
 	~Level();
 
-	///
-	void load(const Vector3 &pos, const Quaternion &rot);
-
 	///
 	UnitId unit_by_name(StringId32 name);
 };
 
+namespace level
+{
+	///
+	Level *create(Allocator &a, const LevelResource *level_resource);
+
+	///
+	void destroy(Allocator &a, Level *level);
+
+} // namespace level
+
 } // namespace crown

+ 152 - 137
src/world/world.cpp

@@ -13,6 +13,7 @@
 #include "core/strings/string_id.inl"
 #include "device/device.h"
 #include "lua/lua_environment.h"
+#include "resource/level_resource.h"
 #include "resource/resource_manager.h"
 #include "resource/unit_resource.h"
 #include "world/animation_state_machine.h"
@@ -32,6 +33,128 @@
 
 namespace crown
 {
+static void create_components(World &w, const UnitResource *ur, const Vector3 &pos, const Quaternion &rot, const Vector3 &scl, const UnitId *unit_lookup)
+{
+	SceneGraph *scene_graph = w._scene_graph;
+	RenderWorld *render_world = w._render_world;
+	PhysicsWorld *physics_world = w._physics_world;
+	ScriptWorld *script_world = w._script_world;
+	AnimationStateMachine *animation_state_machine = w._animation_state_machine;
+
+	const u32 *unit_parents = unit_resource::parents(ur);
+
+	// Create components
+	const ComponentData *component = unit_resource::component_type_data(ur, NULL);
+	for (u32 cc = 0; cc < ur->num_component_types; ++cc) {
+		const u32 *unit_index = unit_resource::component_unit_index(component);
+		const char *data = unit_resource::component_payload(component);
+
+		if (component->type == STRING_ID_32("transform", UINT32_C(0xad9b5315))) {
+			const TransformDesc *td = (TransformDesc *)data;
+			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++td) {
+				// FIXME: add SceneGraph::allocate() to reserve an instance
+				// without initializing it.
+				const TransformInstance ti = scene_graph->create(unit_lookup[unit_index[i]]
+					, td->position
+					, td->rotation
+					, td->scale
+					);
+				if (unit_parents[unit_index[i]] != UINT32_MAX) {
+					TransformInstance parent_ti = scene_graph->instance(unit_lookup[unit_parents[unit_index[i]]]);
+					scene_graph->link(parent_ti, ti, td->position, td->rotation, td->scale);
+				} else {
+					const Vector3 scale = { td->scale.x * scl.x, td->scale.y * scl.y, td->scale.z * scl.z };
+					Matrix4x4 tr = from_quaternion_translation(rot, pos);
+					scene_graph->set_local_pose(ti, scene_graph->local_pose(ti) * tr);
+					scene_graph->set_local_scale(ti, scale);
+				}
+			}
+		} else if (component->type == STRING_ID_32("camera", UINT32_C(0x31822dc7))) {
+			const CameraDesc *cd = (CameraDesc *)data;
+			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++cd) {
+				w.camera_create(unit_lookup[unit_index[i]], *cd, MATRIX4X4_IDENTITY);
+			}
+		} else if (component->type == STRING_ID_32("collider", UINT32_C(0x2129d74e))) {
+			const ColliderDesc *cd = (ColliderDesc *)data;
+			for (u32 i = 0, n = component->num_instances; i < n; ++i) {
+				TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
+				Matrix4x4 tm = scene_graph->world_pose(ti);
+				physics_world->collider_create(unit_lookup[unit_index[i]], cd, scale(tm));
+				cd = (ColliderDesc *)((char *)(cd + 1) + cd->size);
+			}
+		} else if (component->type == STRING_ID_32("actor", UINT32_C(0x374cf583))) {
+			const ActorResource *ar = (ActorResource *)data;
+			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++ar) {
+				TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
+				Matrix4x4 tm = scene_graph->world_pose(ti);
+				physics_world->actor_create(unit_lookup[unit_index[i]], ar, from_quaternion_translation(rotation(tm), translation(tm)));
+			}
+		} else if (component->type == STRING_ID_32("mover", UINT32_C(0xac07d371))) {
+			const MoverDesc *md = (MoverDesc *)data;
+			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++md) {
+				TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
+				Matrix4x4 tm = scene_graph->world_pose(ti);
+				physics_world->mover_create(unit_lookup[unit_index[i]], md, tm);
+			}
+		} else if (component->type == STRING_ID_32("mesh_renderer", UINT32_C(0xdf017893))) {
+			const MeshRendererDesc *mrd = (MeshRendererDesc *)data;
+			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++mrd) {
+				TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
+				Matrix4x4 tm = scene_graph->world_pose(ti);
+				render_world->mesh_create(unit_lookup[unit_index[i]], *mrd, tm);
+			}
+		} else if (component->type == STRING_ID_32("sprite_renderer", UINT32_C(0x6a1c2a3b))) {
+			const SpriteRendererDesc *srd = (SpriteRendererDesc *)data;
+			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++srd) {
+				TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
+				Matrix4x4 tm = scene_graph->world_pose(ti);
+				render_world->sprite_create(unit_lookup[unit_index[i]], *srd, tm);
+			}
+		} else if (component->type == STRING_ID_32("light", UINT32_C(0xbb9f08c2))) {
+			const LightDesc *ld = (LightDesc *)data;
+			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++ld) {
+				TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
+				Matrix4x4 tm = scene_graph->world_pose(ti);
+				render_world->light_create(unit_lookup[unit_index[i]], *ld, tm);
+			}
+		} else if (component->type == STRING_ID_32("fog", UINT32_C(0xf007ef0d))) {
+			const FogDesc *fd = (FogDesc *)data;
+			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++fd) {
+				render_world->fog_create(unit_lookup[unit_index[i]], *fd);
+			}
+		} else if (component->type == STRING_ID_32("global_lighting", UINT32_C(0x718af7fe))) {
+			const GlobalLightingDesc *desc = (GlobalLightingDesc *)data;
+			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++desc) {
+				render_world->global_lighting_create(unit_lookup[unit_index[i]], *desc);
+			}
+		} else if (component->type == STRING_ID_32("bloom", UINT32_C(0x995dd31c))) {
+			const BloomDesc *desc = (BloomDesc *)data;
+			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++desc) {
+				render_world->bloom_create(unit_lookup[unit_index[i]], *desc);
+			}
+		} else if (component->type == STRING_ID_32("tonemap", UINT32_C(0x7089b06b))) {
+			const TonemapDesc *desc = (TonemapDesc *)data;
+			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++desc) {
+				render_world->tonemap_create(unit_lookup[unit_index[i]], *desc);
+			}
+		} else if (component->type == STRING_ID_32("script", UINT32_C(0xd18f8ad6))) {
+			const ScriptDesc *sd = (ScriptDesc *)data;
+			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++sd) {
+				script_world::create(*script_world, unit_lookup[unit_index[i]], *sd);
+			}
+		} else if (component->type == STRING_ID_32("animation_state_machine", UINT32_C(0xe87992ac))) {
+			const AnimationStateMachineDesc *asmd = (AnimationStateMachineDesc *)data;
+			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++asmd) {
+				animation_state_machine->create(unit_lookup[unit_index[i]], *asmd, w);
+			}
+		} else {
+			CE_FATAL("Unknown component type");
+		}
+
+		component = unit_resource::component_type_data(ur, component);
+	}
+}
+
 World::World(Allocator &a
 	, ResourceManager &rm
 	, ShaderManager &sm
@@ -119,7 +242,10 @@ UnitId World::spawn_unit(StringId64 name, const Vector3 &pos, const Quaternion &
 	for (u32 i = 0; i < ur->num_units; ++i)
 		unit_lookup[i] = _unit_manager->create();
 
-	spawn_units(*this, ur, pos, rot, scl, unit_lookup);
+	create_components(*this, ur, pos, rot, scl, unit_lookup);
+
+	array::push(_units, unit_lookup, ur->num_units);
+	post_unit_spawned_events(unit_lookup, ur->num_units);
 
 	UnitId root_unit = unit_lookup[0];
 	default_scratch_allocator().deallocate(unit_lookup);
@@ -130,7 +256,7 @@ UnitId World::spawn_empty_unit()
 {
 	UnitId unit = _unit_manager->create();
 	array::push_back(_units, unit);
-	post_unit_spawned_event(unit);
+	post_unit_spawned_events(&unit, 1);
 	return unit;
 }
 
@@ -572,9 +698,25 @@ void World::destroy_gui(Gui &gui)
 Level *World::load_level(StringId64 name, const Vector3 &pos, const Quaternion &rot)
 {
 	const LevelResource *lr = (LevelResource *)_resource_manager->get(RESOURCE_TYPE_LEVEL, name);
+	const UnitResource *ur = level_resource::unit_resource(lr);
+
+	Level *level = level::create(*_allocator, lr);
+
+	// Create IDs for units.
+	for (u32 i = 0; i < ur->num_units; ++i)
+		level->_unit_lookup[i] = _unit_manager->create();
+
+	create_components(*this, ur, pos, rot, VECTOR3_ONE, level->_unit_lookup);
+
+	spawn_skydome(lr->skydome_unit);
+
+	for (u32 i = 0; i < lr->num_sounds; ++i) {
+		const LevelSound *ls = level_resource::get_sound(lr, i);
+		play_sound(ls->name, ls->loop, ls->volume, ls->position, ls->range, ls->group);
+	}
 
-	Level *level = CE_NEW(*_allocator, Level)(*_allocator, *_unit_manager, *this, *lr);
-	level->load(pos, rot);
+	array::push(_units, level->_unit_lookup, ur->num_units);
+	post_unit_spawned_events(level->_unit_lookup, ur->num_units);
 
 	list::add(level->_node, _levels);
 
@@ -582,11 +724,13 @@ Level *World::load_level(StringId64 name, const Vector3 &pos, const Quaternion &
 	return level;
 }
 
-void World::post_unit_spawned_event(UnitId unit)
+void World::post_unit_spawned_events(UnitId *units, u32 num_units)
 {
-	UnitSpawnedEvent ev;
-	ev.unit = unit;
-	event_stream::write(_events, EventType::UNIT_SPAWNED, ev);
+	for (u32 i = 0; i < num_units; ++i) {
+		UnitSpawnedEvent ev;
+		ev.unit = units[i];
+		event_stream::write(_events, EventType::UNIT_SPAWNED, ev);
+	}
 }
 
 void World::post_unit_destroyed_event(UnitId unit)
@@ -619,133 +763,4 @@ void World::reload_materials(const MaterialResource *old_resource, const Materia
 #endif
 }
 
-void spawn_units(World &w, const UnitResource *ur, const Vector3 &pos, const Quaternion &rot, const Vector3 &scl, const UnitId *unit_lookup)
-{
-	SceneGraph *scene_graph = w._scene_graph;
-	RenderWorld *render_world = w._render_world;
-	PhysicsWorld *physics_world = w._physics_world;
-	ScriptWorld *script_world = w._script_world;
-	AnimationStateMachine *animation_state_machine = w._animation_state_machine;
-
-	const u32 *unit_parents = unit_resource::parents(ur);
-
-	// Create components
-	const ComponentData *component = unit_resource::component_type_data(ur, NULL);
-	for (u32 cc = 0; cc < ur->num_component_types; ++cc) {
-		const u32 *unit_index = unit_resource::component_unit_index(component);
-		const char *data = unit_resource::component_payload(component);
-
-		if (component->type == STRING_ID_32("transform", UINT32_C(0xad9b5315))) {
-			const TransformDesc *td = (TransformDesc *)data;
-			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++td) {
-				// FIXME: add SceneGraph::allocate() to reserve an instance
-				// without initializing it.
-				const TransformInstance ti = scene_graph->create(unit_lookup[unit_index[i]]
-					, td->position
-					, td->rotation
-					, td->scale
-					);
-				if (unit_parents[unit_index[i]] != UINT32_MAX) {
-					TransformInstance parent_ti = scene_graph->instance(unit_lookup[unit_parents[unit_index[i]]]);
-					scene_graph->link(parent_ti, ti, td->position, td->rotation, td->scale);
-				} else {
-					const Vector3 scale = { td->scale.x * scl.x, td->scale.y * scl.y, td->scale.z * scl.z };
-					Matrix4x4 tr = from_quaternion_translation(rot, pos);
-					scene_graph->set_local_pose(ti, scene_graph->local_pose(ti) * tr);
-					scene_graph->set_local_scale(ti, scale);
-				}
-			}
-		} else if (component->type == STRING_ID_32("camera", UINT32_C(0x31822dc7))) {
-			const CameraDesc *cd = (CameraDesc *)data;
-			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++cd) {
-				w.camera_create(unit_lookup[unit_index[i]], *cd, MATRIX4X4_IDENTITY);
-			}
-		} else if (component->type == STRING_ID_32("collider", UINT32_C(0x2129d74e))) {
-			const ColliderDesc *cd = (ColliderDesc *)data;
-			for (u32 i = 0, n = component->num_instances; i < n; ++i) {
-				TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
-				Matrix4x4 tm = scene_graph->world_pose(ti);
-				physics_world->collider_create(unit_lookup[unit_index[i]], cd, scale(tm));
-				cd = (ColliderDesc *)((char *)(cd + 1) + cd->size);
-			}
-		} else if (component->type == STRING_ID_32("actor", UINT32_C(0x374cf583))) {
-			const ActorResource *ar = (ActorResource *)data;
-			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++ar) {
-				TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
-				Matrix4x4 tm = scene_graph->world_pose(ti);
-				physics_world->actor_create(unit_lookup[unit_index[i]], ar, from_quaternion_translation(rotation(tm), translation(tm)));
-			}
-		} else if (component->type == STRING_ID_32("mover", UINT32_C(0xac07d371))) {
-			const MoverDesc *md = (MoverDesc *)data;
-			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++md) {
-				TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
-				Matrix4x4 tm = scene_graph->world_pose(ti);
-				physics_world->mover_create(unit_lookup[unit_index[i]], md, tm);
-			}
-		} else if (component->type == STRING_ID_32("mesh_renderer", UINT32_C(0xdf017893))) {
-			const MeshRendererDesc *mrd = (MeshRendererDesc *)data;
-			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++mrd) {
-				TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
-				Matrix4x4 tm = scene_graph->world_pose(ti);
-				render_world->mesh_create(unit_lookup[unit_index[i]], *mrd, tm);
-			}
-		} else if (component->type == STRING_ID_32("sprite_renderer", UINT32_C(0x6a1c2a3b))) {
-			const SpriteRendererDesc *srd = (SpriteRendererDesc *)data;
-			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++srd) {
-				TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
-				Matrix4x4 tm = scene_graph->world_pose(ti);
-				render_world->sprite_create(unit_lookup[unit_index[i]], *srd, tm);
-			}
-		} else if (component->type == STRING_ID_32("light", UINT32_C(0xbb9f08c2))) {
-			const LightDesc *ld = (LightDesc *)data;
-			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++ld) {
-				TransformInstance ti = scene_graph->instance(unit_lookup[unit_index[i]]);
-				Matrix4x4 tm = scene_graph->world_pose(ti);
-				render_world->light_create(unit_lookup[unit_index[i]], *ld, tm);
-			}
-		} else if (component->type == STRING_ID_32("fog", UINT32_C(0xf007ef0d))) {
-			const FogDesc *fd = (FogDesc *)data;
-			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++fd) {
-				render_world->fog_create(unit_lookup[unit_index[i]], *fd);
-			}
-		} else if (component->type == STRING_ID_32("global_lighting", UINT32_C(0x718af7fe))) {
-			const GlobalLightingDesc *desc = (GlobalLightingDesc *)data;
-			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++desc) {
-				render_world->global_lighting_create(unit_lookup[unit_index[i]], *desc);
-			}
-		} else if (component->type == STRING_ID_32("bloom", UINT32_C(0x995dd31c))) {
-			const BloomDesc *desc = (BloomDesc *)data;
-			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++desc) {
-				render_world->bloom_create(unit_lookup[unit_index[i]], *desc);
-			}
-		} else if (component->type == STRING_ID_32("tonemap", UINT32_C(0x7089b06b))) {
-			const TonemapDesc *desc = (TonemapDesc *)data;
-			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++desc) {
-				render_world->tonemap_create(unit_lookup[unit_index[i]], *desc);
-			}
-		} else if (component->type == STRING_ID_32("script", UINT32_C(0xd18f8ad6))) {
-			const ScriptDesc *sd = (ScriptDesc *)data;
-			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++sd) {
-				script_world::create(*script_world, unit_lookup[unit_index[i]], *sd);
-			}
-		} else if (component->type == STRING_ID_32("animation_state_machine", UINT32_C(0xe87992ac))) {
-			const AnimationStateMachineDesc *asmd = (AnimationStateMachineDesc *)data;
-			for (u32 i = 0, n = component->num_instances; i < n; ++i, ++asmd) {
-				animation_state_machine->create(unit_lookup[unit_index[i]], *asmd, w);
-			}
-		} else {
-			CE_FATAL("Unknown component type");
-		}
-
-		component = unit_resource::component_type_data(ur, component);
-	}
-
-	for (u32 i = 0; i < ur->num_units; ++i)
-		array::push_back(w._units, unit_lookup[i]);
-
-	// Post events
-	for (u32 i = 0; i < ur->num_units; ++i)
-		w.post_unit_spawned_event(unit_lookup[i]);
-}
-
 } // namespace crown

+ 1 - 3
src/world/world.h

@@ -214,7 +214,7 @@ struct World
 	Level *load_level(StringId64 name, const Vector3 &pos, const Quaternion &rot);
 
 	///
-	void post_unit_spawned_event(UnitId unit);
+	void post_unit_spawned_events(UnitId *units, u32 num);
 
 	///
 	void post_unit_destroyed_event(UnitId unit);
@@ -231,6 +231,4 @@ struct World
 	void reload_materials(const MaterialResource *old_resource, const MaterialResource *new_resource);
 };
 
-void spawn_units(World &w, const UnitResource *ur, const Vector3 &pos, const Quaternion &rot, const Vector3 &scl, const UnitId *unit_lookup);
-
 } // namespace crown