Daniele Bartolini преди 9 години
родител
ревизия
59221cd9b7
променени са 6 файла, в които са добавени 192 реда и са изтрити 189 реда
  1. 1 1
      src/resource/level_resource.cpp
  2. 1 1
      src/resource/level_resource.h
  3. 18 2
      src/world/level.cpp
  4. 12 11
      src/world/level.h
  5. 105 114
      src/world/world.cpp
  6. 55 60
      src/world/world.h

+ 1 - 1
src/resource/level_resource.cpp

@@ -91,7 +91,7 @@ namespace level_resource
 		allocator.deallocate(resource);
 	}
 
-	const UnitResource* get_units(const LevelResource* lr)
+	const UnitResource* unit_resource(const LevelResource* lr)
 	{
 		return (const UnitResource*)((char*)lr + lr->units_offset);
 	}

+ 1 - 1
src/resource/level_resource.h

@@ -38,7 +38,7 @@ namespace level_resource
 	void* load(File& file, Allocator& a);
 	void unload(Allocator& allocator, void* resource);
 
-	const UnitResource* get_units(const LevelResource* lr);
+	const UnitResource* unit_resource(const LevelResource* lr);
 	u32 num_sounds(const LevelResource* lr);
 	const LevelSound* get_sound(const LevelResource* lr, u32 i);
 } // namespace level_resource

+ 18 - 2
src/world/level.cpp

@@ -5,15 +5,19 @@
 
 #include "level.h"
 #include "level_resource.h"
+#include "unit_manager.h"
+#include "unit_resource.h"
 #include "world.h"
 
 namespace crown
 {
-Level::Level(Allocator& a, World& w, const LevelResource& lr)
+Level::Level(Allocator& a, UnitManager& um, World& w, const LevelResource& lr)
 	: _marker(MARKER)
 	, _allocator(&a)
+	, _unit_manager(&um)
 	, _world(&w)
 	, _resource(&lr)
+	, _unit_lookup(a)
 {
 }
 
@@ -24,7 +28,19 @@ Level::~Level()
 
 void Level::load(const Vector3& pos, const Quaternion& rot)
 {
-	_world->spawn_unit(*level_resource::get_units(_resource), pos, rot);
+	const UnitResource* ur = level_resource::unit_resource(_resource);
+	const u32 num_units = ur->num_units;
+
+	array::resize(_unit_lookup, num_units);
+
+	for (u32 i = 0; i < num_units; ++i)
+		_unit_lookup[i] = _unit_manager->create();
+
+	spawn_units(*_world, *ur, pos, rot, array::begin(_unit_lookup));
+
+	// Post events
+	for (u32 i = 0; i < num_units; ++i)
+		_world->post_unit_spawned_event(_unit_lookup[i]);
 }
 
 } // namespace crown

+ 12 - 11
src/world/level.h

@@ -5,10 +5,11 @@
 
 #pragma once
 
-#include "world_types.h"
+#include "container_types.h"
+#include "math_types.h"
 #include "memory_types.h"
 #include "resource_types.h"
-#include "math_types.h"
+#include "world_types.h"
 
 namespace crown
 {
@@ -17,22 +18,22 @@ namespace crown
 /// @ingroup World
 class Level
 {
+	u32 _marker;
+
+	Allocator* _allocator;
+	UnitManager* _unit_manager;
+	World* _world;
+	const LevelResource* _resource;
+	Array<UnitId> _unit_lookup;
+
 public:
 
-	Level(Allocator& a, World& w, const LevelResource& lr);
+	Level(Allocator& a, UnitManager& um, World& w, const LevelResource& lr);
 	~Level();
 
 	void load(const Vector3& pos, const Quaternion& rot);
 
 	static const u32 MARKER = 0x1f2b43fe;
-
-private:
-
-	u32 _marker;
-
-	Allocator* _allocator;
-	World* _world;
-	const LevelResource* _resource;
 };
 
 } // namespace crown

+ 105 - 114
src/world/world.cpp

@@ -66,115 +66,14 @@ World::~World()
 	_marker = 0;
 }
 
-UnitId World::spawn_unit(const UnitResource& ur, const Vector3& pos, const Quaternion& rot)
-{
-	TempAllocator512 ta;
-	UnitId* unit_lookup = (UnitId*)ta.allocate(sizeof(UnitId) * ur.num_units);
-
-	for (u32 i = 0; i < ur.num_units; ++i)
-		unit_lookup[i] = _unit_manager->create();
-
-	// Start of components data
-	const char* components_begin = (const char*)(&ur + 1);
-	const ComponentData* component = NULL;
-
-	for (u32 cc = 0; cc < ur.num_component_types; ++cc, components_begin += component->size + sizeof(ComponentData))
-	{
-		component = (const ComponentData*)components_begin;
-		const u32* unit_index = (const u32*)(component + 1);
-		const char* data = (const char*)(unit_index + component->num_instances);
-
-		if (component->type == COMPONENT_TYPE_TRANSFORM)
-		{
-			const TransformDesc* td = (const TransformDesc*)data;
-			for (u32 i = 0; i < component->num_instances; ++i, ++td)
-			{
-				Matrix4x4 matrix = matrix4x4(rot, pos);
-				Matrix4x4 matrix_res = matrix4x4(td->rotation, td->position);
-				_scene_graph->create(unit_lookup[unit_index[i]], matrix_res*matrix);
-			}
-		}
-		else if (component->type == COMPONENT_TYPE_CAMERA)
-		{
-			const CameraDesc* cd = (const CameraDesc*)data;
-			for (u32 i = 0; i < component->num_instances; ++i, ++cd)
-			{
-				create_camera(unit_lookup[unit_index[i]], *cd);
-			}
-		}
-		else if (component->type == COMPONENT_TYPE_COLLIDER)
-		{
-			const ColliderDesc* cd = (const ColliderDesc*)data;
-			for (u32 i = 0; i < component->num_instances; ++i)
-			{
-				physics_world()->create_collider(unit_lookup[unit_index[i]], cd);
-				cd = (ColliderDesc*)((char*)(cd + 1) + cd->size);
-			}
-		}
-		else if (component->type == COMPONENT_TYPE_ACTOR)
-		{
-			const ActorResource* ar = (const ActorResource*)data;
-			for (u32 i = 0; i < component->num_instances; ++i, ++ar)
-			{
-				Matrix4x4 tm = _scene_graph->world_pose(_scene_graph->get(unit_lookup[unit_index[i]]));
-				physics_world()->create_actor(unit_lookup[unit_index[i]], ar, tm);
-			}
-		}
-		else if (component->type == COMPONENT_TYPE_CONTROLLER)
-		{
-			const ControllerDesc* cd = (const ControllerDesc*)data;
-			for (u32 i = 0; i < component->num_instances; ++i, ++cd)
-			{
-				Matrix4x4 tm = _scene_graph->world_pose(_scene_graph->get(unit_lookup[unit_index[i]]));
-				physics_world()->create_controller(unit_lookup[unit_index[i]], *cd, tm);
-			}
-		}
-		else if (component->type == COMPONENT_TYPE_MESH_RENDERER)
-		{
-			const MeshRendererDesc* mrd = (const MeshRendererDesc*)data;
-			for (u32 i = 0; i < component->num_instances; ++i, ++mrd)
-			{
-				Matrix4x4 tm = _scene_graph->world_pose(_scene_graph->get(unit_lookup[unit_index[i]]));
-				render_world()->create_mesh(unit_lookup[unit_index[i]], *mrd, tm);
-			}
-		}
-		else if (component->type == COMPONENT_TYPE_SPRITE_RENDERER)
-		{
-			const SpriteRendererDesc* srd = (const SpriteRendererDesc*)data;
-			for (u32 i = 0; i < component->num_instances; ++i, ++srd)
-			{
-				Matrix4x4 tm = _scene_graph->world_pose(_scene_graph->get(unit_lookup[unit_index[i]]));
-				render_world()->create_sprite(unit_lookup[unit_index[i]], *srd, tm);
-			}
-		}
-		else if (component->type == COMPONENT_TYPE_LIGHT)
-		{
-			const LightDesc* ld = (const LightDesc*)data;
-			for (u32 i = 0; i < component->num_instances; ++i, ++ld)
-			{
-				Matrix4x4 tm = _scene_graph->world_pose(_scene_graph->get(unit_lookup[unit_index[i]]));
-				render_world()->create_light(unit_lookup[unit_index[i]], *ld, tm);
-			}
-		}
-		else
-		{
-			CE_FATAL("Unknown component type");
-		}
-	}
-
-	array::push(_units, &unit_lookup[0], ur.num_units);
-
-	// Post events
-	for (u32 i = 0; i < ur.num_units; ++i)
-		post_unit_spawned_event(unit_lookup[i]);
-
-	return unit_lookup[0];
-}
-
 UnitId World::spawn_unit(StringId64 name, const Vector3& pos, const Quaternion& rot)
 {
 	const UnitResource* ur = (const UnitResource*)_resource_manager->get(RESOURCE_TYPE_UNIT, name);
-	return spawn_unit(*ur, pos, rot);
+	UnitId id = _unit_manager->create();
+	spawn_units(*this, *ur, pos, rot, &id);
+	array::push_back(_units, id);
+	post_unit_spawned_event(id);
+	return id;
 }
 
 UnitId World::spawn_empty_unit()
@@ -530,20 +429,17 @@ void World::destroy_gui(Gui& gui)
 	CE_DELETE(*_allocator, &gui);
 }
 
-Level* World::load_level(const LevelResource& lr, const Vector3& pos, const Quaternion& rot)
+Level* World::load_level(StringId64 name, const Vector3& pos, const Quaternion& rot)
 {
-	Level* level = CE_NEW(*_allocator, Level)(*_allocator, *this, lr);
+	const LevelResource* lr = (const LevelResource*)_resource_manager->get(RESOURCE_TYPE_LEVEL, name);
+
+	Level* level = CE_NEW(*_allocator, Level)(*_allocator, *_unit_manager, *this, *lr);
 	level->load(pos, rot);
 
 	array::push_back(_levels, level);
 	post_level_loaded_event();
-	return level;
-}
 
-Level* World::load_level(StringId64 name, const Vector3& pos, const Quaternion& rot)
-{
-	const LevelResource* lr = (LevelResource*)_resource_manager->get(RESOURCE_TYPE_LEVEL, name);
-	return load_level(*lr, pos, rot);
+	return level;
 }
 
 EventStream& World::events()
@@ -625,4 +521,99 @@ void World::Camera::update_projection_matrix()
 	}
 }
 
+void spawn_units(World& w, const UnitResource& ur, const Vector3& pos, const Quaternion& rot, const UnitId* unit_lookup)
+{
+	SceneGraph* scene_graph = w.scene_graph();
+	RenderWorld* render_world = w.render_world();
+	PhysicsWorld* physics_world = w.physics_world();
+
+	// Start of components data
+	const char* components_begin = (const char*)(&ur + 1);
+	const ComponentData* component = NULL;
+
+	for (u32 cc = 0; cc < ur.num_component_types; ++cc, components_begin += component->size + sizeof(ComponentData))
+	{
+		component = (const ComponentData*)components_begin;
+		const u32* unit_index = (const u32*)(component + 1);
+		const char* data = (const char*)(unit_index + component->num_instances);
+
+		if (component->type == COMPONENT_TYPE_TRANSFORM)
+		{
+			const TransformDesc* td = (const TransformDesc*)data;
+			for (u32 i = 0; i < component->num_instances; ++i, ++td)
+			{
+				Matrix4x4 matrix = matrix4x4(rot, pos);
+				Matrix4x4 matrix_res = matrix4x4(td->rotation, td->position);
+				scene_graph->create(unit_lookup[unit_index[i]], matrix_res*matrix);
+			}
+		}
+		else if (component->type == COMPONENT_TYPE_CAMERA)
+		{
+			const CameraDesc* cd = (const CameraDesc*)data;
+			for (u32 i = 0; i < component->num_instances; ++i, ++cd)
+			{
+				w.create_camera(unit_lookup[unit_index[i]], *cd);
+			}
+		}
+		else if (component->type == COMPONENT_TYPE_COLLIDER)
+		{
+			const ColliderDesc* cd = (const ColliderDesc*)data;
+			for (u32 i = 0; i < component->num_instances; ++i)
+			{
+				physics_world->create_collider(unit_lookup[unit_index[i]], cd);
+				cd = (ColliderDesc*)((char*)(cd + 1) + cd->size);
+			}
+		}
+		else if (component->type == COMPONENT_TYPE_ACTOR)
+		{
+			const ActorResource* ar = (const ActorResource*)data;
+			for (u32 i = 0; i < component->num_instances; ++i, ++ar)
+			{
+				Matrix4x4 tm = scene_graph->world_pose(scene_graph->get(unit_lookup[unit_index[i]]));
+				physics_world->create_actor(unit_lookup[unit_index[i]], ar, tm);
+			}
+		}
+		else if (component->type == COMPONENT_TYPE_CONTROLLER)
+		{
+			const ControllerDesc* cd = (const ControllerDesc*)data;
+			for (u32 i = 0; i < component->num_instances; ++i, ++cd)
+			{
+				Matrix4x4 tm = scene_graph->world_pose(scene_graph->get(unit_lookup[unit_index[i]]));
+				physics_world->create_controller(unit_lookup[unit_index[i]], *cd, tm);
+			}
+		}
+		else if (component->type == COMPONENT_TYPE_MESH_RENDERER)
+		{
+			const MeshRendererDesc* mrd = (const MeshRendererDesc*)data;
+			for (u32 i = 0; i < component->num_instances; ++i, ++mrd)
+			{
+				Matrix4x4 tm = scene_graph->world_pose(scene_graph->get(unit_lookup[unit_index[i]]));
+				render_world->create_mesh(unit_lookup[unit_index[i]], *mrd, tm);
+			}
+		}
+		else if (component->type == COMPONENT_TYPE_SPRITE_RENDERER)
+		{
+			const SpriteRendererDesc* srd = (const SpriteRendererDesc*)data;
+			for (u32 i = 0; i < component->num_instances; ++i, ++srd)
+			{
+				Matrix4x4 tm = scene_graph->world_pose(scene_graph->get(unit_lookup[unit_index[i]]));
+				render_world->create_sprite(unit_lookup[unit_index[i]], *srd, tm);
+			}
+		}
+		else if (component->type == COMPONENT_TYPE_LIGHT)
+		{
+			const LightDesc* ld = (const LightDesc*)data;
+			for (u32 i = 0; i < component->num_instances; ++i, ++ld)
+			{
+				Matrix4x4 tm = scene_graph->world_pose(scene_graph->get(unit_lookup[unit_index[i]]));
+				render_world->create_light(unit_lookup[unit_index[i]], *ld, tm);
+			}
+		}
+		else
+		{
+			CE_FATAL("Unknown component type");
+		}
+	}
+}
+
 } // namespace crown

+ 55 - 60
src/world/world.h

@@ -20,15 +20,64 @@ namespace crown
 /// @ingroup World
 class World
 {
+	struct Camera
+	{
+		UnitId unit;
+
+		ProjectionType::Enum projection_type;
+		Matrix4x4 projection;
+
+		Frustum frustum;
+		f32 fov;
+		f32 aspect;
+		f32 near;
+		f32 far;
+
+		// Orthographic projection only
+		f32 left;
+		f32 right;
+		f32 bottom;
+		f32 top;
+
+		u16 view_x;
+		u16 view_y;
+		u16 view_width;
+		u16 view_height;
+
+		void update_projection_matrix();
+	};
+
+	u32 _marker;
+
+	Allocator* _allocator;
+	ResourceManager* _resource_manager;
+	ShaderManager* _shader_manager;
+	MaterialManager* _material_manager;
+	LuaEnvironment* _lua_environment;
+	UnitManager* _unit_manager;
+
+	DebugLine* _lines;
+	SceneGraph* _scene_graph;
+	RenderWorld* _render_world;
+	PhysicsWorld* _physics_world;
+	SoundWorld* _sound_world;
+
+	Array<UnitId> _units;
+	Array<Level*> _levels;
+	Array<Camera> _camera;
+	Hash<u32> _camera_map;
+
+	EventStream _events;
+
+	CameraInstance make_camera_instance(u32 i) { CameraInstance inst = { i }; return inst; }
+
 public:
 
 	World(Allocator& a, ResourceManager& rm, ShaderManager& sm, MaterialManager& mm, UnitManager& um, LuaEnvironment& env);
 	~World();
 
-	UnitId spawn_unit(const UnitResource& ur, const Vector3& position = VECTOR3_ZERO, const Quaternion& rotation = QUATERNION_IDENTITY);
-
 	/// Spawns a new instance of the unit @a name at the given @a position and @a rotation.
-	UnitId spawn_unit(StringId64 name, const Vector3& pos, const Quaternion& rot);
+	UnitId spawn_unit(StringId64 name, const Vector3& pos = VECTOR3_ZERO, const Quaternion& rot = QUATERNION_IDENTITY);
 
 	/// Spawns a new empty unit and returns its id.
 	UnitId spawn_empty_unit();
@@ -150,7 +199,6 @@ public:
 	void destroy_gui(Gui& gui);
 
 	/// Loads the level @a name into the world.
-	Level* load_level(const LevelResource& lr, const Vector3& pos, const Quaternion& rot);
 	Level* load_level(StringId64 name, const Vector3& pos, const Quaternion& rot);
 
 	/// Returns the events.
@@ -168,66 +216,13 @@ public:
 	/// Returns the sound sub-world.
 	SoundWorld* sound_world();
 
-	static const u32 MARKER = 0xfb6ce2d3;
-
-private:
-
-	CameraInstance make_camera_instance(u32 i) { CameraInstance inst = { i }; return inst; }
-
 	void post_unit_spawned_event(UnitId id);
 	void post_unit_destroyed_event(UnitId id);
 	void post_level_loaded_event();
 
-private:
-
-	struct Camera
-	{
-		UnitId unit;
-
-		ProjectionType::Enum projection_type;
-		Matrix4x4 projection;
-
-		Frustum frustum;
-		f32 fov;
-		f32 aspect;
-		f32 near;
-		f32 far;
-
-		// Orthographic projection only
-		f32 left;
-		f32 right;
-		f32 bottom;
-		f32 top;
-
-		u16 view_x;
-		u16 view_y;
-		u16 view_width;
-		u16 view_height;
-
-		void update_projection_matrix();
-	};
-
-	u32 _marker;
-
-	Allocator* _allocator;
-	ResourceManager* _resource_manager;
-	ShaderManager* _shader_manager;
-	MaterialManager* _material_manager;
-	LuaEnvironment* _lua_environment;
-	UnitManager* _unit_manager;
-
-	DebugLine* _lines;
-	SceneGraph* _scene_graph;
-	RenderWorld* _render_world;
-	PhysicsWorld* _physics_world;
-	SoundWorld* _sound_world;
-
-	Array<UnitId> _units;
-	Array<Level*> _levels;
-	Array<Camera> _camera;
-	Hash<u32> _camera_map;
-
-	EventStream _events;
+	static const u32 MARKER = 0xfb6ce2d3;
 };
 
+void spawn_units(World& w, const UnitResource& ur, const Vector3& pos, const Quaternion& rot, const UnitId* unit_lookup);
+
 } // namespace crown