Kaynağa Gözat

Initial SceneGraph rewrite

Daniele Bartolini 10 yıl önce
ebeveyn
işleme
3574017bf1

+ 21 - 77
docs/lua_api.txt

@@ -327,49 +327,38 @@ World
 Unit
 ----
 
-	**node** (unit, name)
-		Returns the node *name*.
+	**local_position** (unit) : Vector3
+		Returns the local position of the unit.
 
-	**has_node** (unit, name) : int
-		Returns whether the unit has the node *name*.
+	**local_rotation** (unit) : Quaternion
+		Returns the local rotation of the unit.
 
-	**num_nodes** (unit) : int
-		Returns the number of nodes of the unit.
+	**local_scale** (unit) : Vector3
+		Returns the local scale of the unit.
 
-	**local_position** (unit, n) : Vector3
-		Returns the local position of the node with index n inside the unit.
+	**local_pose** (unit) : Matrix4x4
+		Returns the local pose of the unit.
 
-	**local_rotation** (unit, n) : Quaternion
-		Returns the local rotation of the node with index n inside the unit.
+	**world_position** (unit) : Vector3
+		Returns the world position of the unit.
 
-	**local_pose** (unit, n) : Matrix4x4
-		Returns the local pose of the node with index n inside the unit.
+	**world_rotation** (unit) : Quaternion
+		Returns the world rotation of the unit.
 
-	**world_position** (unit, n) : Vector3
-		Returns the world position of the node with index n inside the unit.
+	**world_pose** (unit) : Matrix4x4
+		Returns the world pose of the unit.
 
-	**world_rotation** (unit, n) : Quaternion
-		Returns the world rotation of the node with index n inside the unit.
+	**set_local_position** (unit, position)
+		Sets the local position of the unit.
 
-	**world_pose** (unit, n) : Matrix4x4
-		Returns the world pose of the node with index n inside the unit.
+	**set_local_rotation** (unit, rotation)
+		Sets the local rotation of the unit.
 
-	**set_local_position** (unit, n, position)
-		Sets the local position of the node with index n inside the unit.
-
-	**set_local_rotation** (unit, n, rotation)
-		Sets the local rotation of the node with index n inside the unit.
+	**set_local_scale** (unit, scale)
+		Sets the local scale of the unit.
 
 	**set_local_pose** (unit, n, pose)
-		Sets the local pose of the node with index n inside the unit.
-
-	**link_node** (unit)
-		Links the *child* node to the *parent* node.
-		After the linking the *child* pose is reset to identity.
-		Note that *parent* node must be either -1 (meaning no parent), or an index lesser than child.
-
-	**unlink_node** (unit, child)
-		Unlinks *child* from its parent, if any.
+		Sets the local pose of the unit.
 
 	**camera** (unit, name)
 		Returns the camera *name*.
@@ -401,33 +390,6 @@ Unit
 Camera
 ------
 
-	**local_position** (camera, position)
-		Returns the local position of the camera.
-
-	**local_rotation** (camera, rotation)
-		Returns the local rotation of the camera.
-
-	**local_pose** (camera, pose)
-		Returns the local pose of the camera.
-
-	**world_position** (camera) : Vector3
-		Returns the world position of the camera.
-
-	**world_rotation** (camera) : Quaternion
-		Returns the world rotation of the camera.
-
-	**world_pose** (camera) : Matrix4x4
-		Returns the world pose of the camera.
-
-	**set_local_position** (camera, unit, position)
-		Sets the local position of the camera.
-
-	**set_local_rotation** (camera, unit, rotation)
-		Sets the local rotation of the camera.
-
-	**set_local_pose** (camera, unit, pose)
-		Sets the local pose of the camera.
-
 	**set_projection_type** (camera, type)
 		Sets the projection type of the camera.
 
@@ -473,24 +435,6 @@ Camera
 Sprite
 ------
 
-	**local_position** (sprite) : Vector3
-		Returns the local position of the sprite.
-
-	**local_rotation** (sprite) : Quaternion
-		Returns the local rotation of the sprite.
-
-	**local_pose** (sprite) : Matrix4x4
-		Returns the local pose of the sprite.
-
-	**set_local_position** (sprite, unit, position)
-		Sets the local position of the sprite.
-
-	**set_local_rotation** (sprite, unit, rotation)
-		Sets the local rotation of the sprite.
-
-	**set_local_pose** (sprite, unit, pose)
-		Sets the local pose of the sprite.
-
 	**set_frame** (sprite, num)
 		Sets the frame of the sprite.
 

+ 0 - 72
engine/lua/lua_camera.cpp

@@ -13,69 +13,6 @@
 namespace crown
 {
 
-static int camera_local_position(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.push_vector3(stack.get_camera(1)->local_position());
-	return 1;
-}
-
-static int camera_local_rotation(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.push_quaternion(stack.get_camera(1)->local_rotation());
-	return 1;
-}
-
-static int camera_local_pose(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.push_matrix4x4(stack.get_camera(1)->local_pose());
-	return 1;
-}
-
-static int camera_world_position(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.push_vector3(stack.get_camera(1)->world_position());
-	return 1;
-}
-
-static int camera_world_rotation(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.push_quaternion(stack.get_camera(1)->world_rotation());
-	return 1;
-}
-
-static int camera_world_pose(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.push_matrix4x4(stack.get_camera(1)->world_pose());
-	return 1;
-}
-
-static int camera_set_local_position(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.get_camera(1)->set_local_position(stack.get_unit(2), stack.get_vector3(3));
-	return 0;
-}
-
-static int camera_set_local_rotation(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.get_camera(1)->set_local_rotation(stack.get_unit(2), stack.get_quaternion(3));
-	return 0;
-}
-
-static int camera_set_local_pose(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.get_camera(1)->set_local_pose(stack.get_unit(2), stack.get_matrix4x4(3));
-	return 0;
-}
-
 static int camera_set_projection_type(lua_State* L)
 {
 	LuaStack stack(L);
@@ -178,15 +115,6 @@ static int camera_world_to_screen(lua_State* L)
 
 void load_camera(LuaEnvironment& env)
 {
-	env.load_module_function("Camera", "local_position",           camera_local_position);
-	env.load_module_function("Camera", "local_rotation",           camera_local_rotation);
-	env.load_module_function("Camera", "local_pose",               camera_local_pose);
-	env.load_module_function("Camera", "world_position",           camera_world_position);
-	env.load_module_function("Camera", "world_rotation",           camera_world_rotation);
-	env.load_module_function("Camera", "world_pose",               camera_world_pose);
-	env.load_module_function("Camera", "set_local_position",       camera_set_local_position);
-	env.load_module_function("Camera", "set_local_rotation",       camera_set_local_rotation);
-	env.load_module_function("Camera", "set_local_pose",           camera_set_local_pose);
 	env.load_module_function("Camera", "set_projection_type",      camera_set_projection_type);
 	env.load_module_function("Camera", "projection_type",          camera_projection_type);
 	env.load_module_function("Camera", "fov",                      camera_fov);

+ 0 - 48
engine/lua/lua_sprite.cpp

@@ -11,48 +11,6 @@
 namespace crown
 {
 
-static int sprite_local_position(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.push_vector3(stack.get_sprite(1)->local_position());
-	return 1;
-}
-
-static int sprite_local_rotation(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.push_quaternion(stack.get_sprite(1)->local_rotation());
-	return 1;
-}
-
-static int sprite_local_pose(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.push_matrix4x4(stack.get_sprite(1)->local_pose());
-	return 1;
-}
-
-static int sprite_set_local_position(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.get_sprite(1)->set_local_position(stack.get_unit(2), stack.get_vector3(3));
-	return 0;
-}
-
-static int sprite_set_local_rotation(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.get_sprite(1)->set_local_rotation(stack.get_unit(2), stack.get_quaternion(3));
-	return 0;
-}
-
-static int sprite_set_local_pose(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.get_sprite(1)->set_local_pose(stack.get_unit(2), stack.get_matrix4x4(3));
-	return 0;
-}
-
 static int sprite_set_frame(lua_State* L)
 {
 	LuaStack stack(L);
@@ -69,12 +27,6 @@ static int sprite_set_depth(lua_State* L)
 
 void load_sprite(LuaEnvironment& env)
 {
-	env.load_module_function("Sprite", "local_position",     sprite_local_position);
-	env.load_module_function("Sprite", "local_rotation",     sprite_local_rotation);
-	env.load_module_function("Sprite", "local_pose",         sprite_local_pose);
-	env.load_module_function("Sprite", "set_local_position", sprite_set_local_position);
-	env.load_module_function("Sprite", "set_local_rotation", sprite_set_local_rotation);
-	env.load_module_function("Sprite", "set_local_pose",     sprite_set_local_pose);
 	env.load_module_function("Sprite", "set_frame",          sprite_set_frame);
 	env.load_module_function("Sprite", "set_depth",          sprite_set_depth);
 }

+ 18 - 42
engine/lua/lua_unit.cpp

@@ -10,101 +10,80 @@
 namespace crown
 {
 
-static int unit_node(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.push_int32(stack.get_unit(1)->node(stack.get_string(2)));
-	return 1;
-}
-
-static int unit_has_node(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.push_bool(stack.get_unit(1)->has_node(stack.get_string(2)));
-	return 1;
-}
-
-static int unit_num_nodes(lua_State* L)
+static int unit_local_position(lua_State* L)
 {
 	LuaStack stack(L);
-	stack.push_int32(stack.get_unit(1)->num_nodes());
+	stack.push_vector3(stack.get_unit(1)->local_position());
 	return 1;
 }
 
-static int unit_local_position(lua_State* L)
+static int unit_local_rotation(lua_State* L)
 {
 	LuaStack stack(L);
-	stack.push_vector3(stack.get_unit(1)->local_position(stack.get_int(2)));
+	stack.push_quaternion(stack.get_unit(1)->local_rotation());
 	return 1;
 }
 
-static int unit_local_rotation(lua_State* L)
+static int unit_local_scale(lua_State* L)
 {
 	LuaStack stack(L);
-	stack.push_quaternion(stack.get_unit(1)->local_rotation(stack.get_int(2)));
+	stack.push_vector3(stack.get_unit(1)->local_scale());
 	return 1;
 }
 
 static int unit_local_pose(lua_State* L)
 {
 	LuaStack stack(L);
-	stack.push_matrix4x4(stack.get_unit(1)->local_pose(stack.get_int(2)));
+	stack.push_matrix4x4(stack.get_unit(1)->local_pose());
 	return 1;
 }
 
 static int unit_world_position(lua_State* L)
 {
 	LuaStack stack(L);
-	stack.push_vector3(stack.get_unit(1)->world_position(stack.get_int(2)));
+	stack.push_vector3(stack.get_unit(1)->world_position());
 	return 1;
 }
 
 static int unit_world_rotation(lua_State* L)
 {
 	LuaStack stack(L);
-	stack.push_quaternion(stack.get_unit(1)->world_rotation(stack.get_int(2)));
+	stack.push_quaternion(stack.get_unit(1)->world_rotation());
 	return 1;
 }
 
 static int unit_world_pose(lua_State* L)
 {
 	LuaStack stack(L);
-	stack.push_matrix4x4(stack.get_unit(1)->world_pose(stack.get_int(2)));
+	stack.push_matrix4x4(stack.get_unit(1)->world_pose());
 	return 1;
 }
 
 static int unit_set_local_position(lua_State* L)
 {
 	LuaStack stack(L);
-	stack.get_unit(1)->set_local_position(stack.get_int(2), stack.get_vector3(3));
+	stack.get_unit(1)->set_local_position(stack.get_vector3(2));
 	return 0;
 }
 
 static int unit_set_local_rotation(lua_State* L)
 {
 	LuaStack stack(L);
-	stack.get_unit(1)->set_local_rotation(stack.get_int(2), stack.get_quaternion(3));
-	return 0;
-}
-
-static int unit_set_local_pose(lua_State* L)
-{
-	LuaStack stack(L);
-	stack.get_unit(1)->set_local_pose(stack.get_int(2), stack.get_matrix4x4(3));
+	stack.get_unit(1)->set_local_rotation(stack.get_quaternion(2));
 	return 0;
 }
 
-static int unit_link_node(lua_State* L)
+static int unit_set_local_scale(lua_State* L)
 {
 	LuaStack stack(L);
-	stack.get_unit(1)->link_node(stack.get_int(2), stack.get_int(3));
+	stack.get_unit(1)->set_local_scale(stack.get_vector3(2));
 	return 0;
 }
 
-static int unit_unlink_node(lua_State* L)
+static int unit_set_local_pose(lua_State* L)
 {
 	LuaStack stack(L);
-	stack.get_unit(1)->unlink_node(stack.get_int(2));
+	stack.get_unit(1)->set_local_pose(stack.get_matrix4x4(2));
 	return 0;
 }
 
@@ -272,20 +251,17 @@ static int unit_set_key(lua_State* L)
 
 void load_unit(LuaEnvironment& env)
 {
-	env.load_module_function("Unit", "node",                  unit_node);
-	env.load_module_function("Unit", "has_node",              unit_has_node);
-	env.load_module_function("Unit", "num_nodes",             unit_num_nodes);
 	env.load_module_function("Unit", "local_position",        unit_local_position);
 	env.load_module_function("Unit", "local_rotation",        unit_local_rotation);
+	env.load_module_function("Unit", "local_scale",           unit_local_scale);
 	env.load_module_function("Unit", "local_pose",            unit_local_pose);
 	env.load_module_function("Unit", "world_position",        unit_world_position);
 	env.load_module_function("Unit", "world_rotation",        unit_world_rotation);
 	env.load_module_function("Unit", "world_pose",            unit_world_pose);
 	env.load_module_function("Unit", "set_local_position",    unit_set_local_position);
 	env.load_module_function("Unit", "set_local_rotation",    unit_set_local_rotation);
+	env.load_module_function("Unit", "set_local_scale",       unit_set_local_scale);
 	env.load_module_function("Unit", "set_local_pose",        unit_set_local_pose);
-	env.load_module_function("Unit", "link_node",             unit_link_node);
-	env.load_module_function("Unit", "unlink_node",           unit_unlink_node);
 	env.load_module_function("Unit", "camera",                unit_camera);
 	env.load_module_function("Unit", "material",              unit_material);
 	env.load_module_function("Unit", "sprite",                unit_sprite);

+ 16 - 0
engine/lua/lua_world.cpp

@@ -65,6 +65,20 @@ static int world_units(lua_State* L)
 	return 1;
 }
 
+static int world_link_unit(lua_State* L)
+{
+	LuaStack stack(L);
+	stack.get_world(1)->link_unit(stack.get_unit(2)->id(), stack.get_unit(3)->id());
+	return 0;
+}
+
+static int world_unlink_unit(lua_State* L)
+{
+	LuaStack stack(L);
+	stack.get_world(1)->unlink_unit(stack.get_unit(2)->id());
+	return 0;
+}
+
 static int world_update_animations(lua_State* L)
 {
 	LuaStack stack(L);
@@ -217,6 +231,8 @@ void load_world(LuaEnvironment& env)
 	env.load_module_function("World", "destroy_unit",       world_destroy_unit);
 	env.load_module_function("World", "num_units",          world_num_units);
 	env.load_module_function("World", "units",              world_units);
+	env.load_module_function("World", "link_unit",          world_link_unit);
+	env.load_module_function("World", "unlink_unit",        world_unlink_unit);
 	env.load_module_function("World", "update_animations",  world_update_animations);
 	env.load_module_function("World", "update_scene",       world_update_scene);
 	env.load_module_function("World", "update",             world_update);

+ 6 - 4
engine/physics/actor.cpp

@@ -23,11 +23,10 @@ using namespace physx;
 namespace crown
 {
 
-Actor::Actor(PhysicsWorld& pw, const ActorResource* ar, SceneGraph& sg, int32_t node, UnitId unit_id)
+Actor::Actor(PhysicsWorld& pw, const ActorResource* ar, SceneGraph& sg, UnitId unit_id)
 	: m_world(pw)
 	, m_resource(ar)
 	, m_scene_graph(sg)
-	, m_node(node)
 	, m_unit(unit_id)
 {
 	create_objects();
@@ -48,7 +47,9 @@ void Actor::create_objects()
 	const PhysicsActor2* actor_class = physics_config_resource::actor(config, actor->actor_class);
 
 	// Create rigid body
-	const PxMat44 pose((PxReal*) matrix4x4::to_float_ptr(m_scene_graph.world_pose(m_node)));
+	TransformInstance ti = m_scene_graph.get(m_unit);
+	const Matrix4x4 tr = m_scene_graph.world_pose(ti);
+	const PxMat44 pose((PxReal*) matrix4x4::to_float_ptr(tr));
 
 	if (actor_class->flags & PhysicsActor2::DYNAMIC)
 	{
@@ -473,7 +474,8 @@ Unit* Actor::unit()
 
 void Actor::update(const Matrix4x4& pose)
 {
-	m_scene_graph.set_world_pose(m_node, pose);
+	TransformInstance ti = m_scene_graph.get(m_unit);
+	m_scene_graph.set_local_pose(ti, pose);
 }
 
 } // namespace crown

+ 1 - 3
engine/physics/actor.h

@@ -32,7 +32,7 @@ struct SceneGraph;
 /// @ingroup Physics
 struct Actor
 {
-	Actor(PhysicsWorld& pw, const ActorResource* ar, SceneGraph& sg, int32_t node, UnitId unit_id);
+	Actor(PhysicsWorld& pw, const ActorResource* ar, SceneGraph& sg, UnitId unit_id);
 	~Actor();
 
 	/// Returns the world position of the actor.
@@ -166,8 +166,6 @@ public:
 	PxRigidActor* m_actor;
 
 	SceneGraph& m_scene_graph;
-	int32_t m_node;
-
 	UnitId m_unit;
 
 private:

+ 6 - 4
engine/physics/controller.cpp

@@ -24,14 +24,15 @@ using physx::PxVec3;
 namespace crown
 {
 
-Controller::Controller(const ControllerResource* cr, SceneGraph& sg, int32_t node, PxPhysics* physics, PxControllerManager* manager)
+Controller::Controller(const ControllerResource* cr, SceneGraph& sg, UnitId id, PxPhysics* physics, PxControllerManager* manager)
 	: m_resource(cr)
 	, m_scene_graph(sg)
-	, m_node(node)
+	, _unit_id(id)
 	, m_manager(manager)
 	, m_controller(NULL)
 {
-	const Vector3 pos = sg.world_position(m_node);
+	TransformInstance ti = sg.get(id);
+	const Vector3 pos = sg.world_position(ti);
 
 	PxCapsuleControllerDesc desc;
 	desc.climbingMode = PxCapsuleClimbingMode::eCONSTRAINED;
@@ -90,7 +91,8 @@ bool Controller::collides_sides() const
 
 void Controller::update()
 {
-	m_scene_graph.set_world_position(m_node, position());
+	TransformInstance ti = m_scene_graph.get(_unit_id);
+	m_scene_graph.set_local_position(ti, position());
 }
 
 } // namespace crown

+ 3 - 2
engine/physics/controller.h

@@ -6,6 +6,7 @@
 #pragma once
 
 #include "physics_callback.h"
+#include "world_types.h"
 #include "resource_types.h"
 #include "math_types.h"
 #include "PxController.h"
@@ -26,7 +27,7 @@ struct SceneGraph;
 /// @ingroup Physics
 struct Controller
 {
-	Controller(const ControllerResource* cr, SceneGraph& sg, int32_t node, PxPhysics* physics, PxControllerManager* manager);
+	Controller(const ControllerResource* cr, SceneGraph& sg, UnitId id, PxPhysics* physics, PxControllerManager* manager);
 	~Controller();
 
 	/// Moves the controller to @a pos.
@@ -54,7 +55,7 @@ private:
 	const ControllerResource* m_resource;
 
 	SceneGraph& m_scene_graph;
-	int32_t m_node;
+	UnitId _unit_id;
 	PxControllerManager* m_manager;
 	PxController* m_controller;
 	PxU32 m_flags;

+ 4 - 4
engine/physics/physics_world.cpp

@@ -251,9 +251,9 @@ PhysicsWorld::~PhysicsWorld()
 	m_scene->release();
 }
 
-ActorId	PhysicsWorld::create_actor(const ActorResource* ar, SceneGraph& sg, int32_t node, UnitId unit_id)
+ActorId	PhysicsWorld::create_actor(const ActorResource* ar, SceneGraph& sg, UnitId unit_id)
 {
-	Actor* actor = CE_NEW(m_actors_pool, Actor)(*this, ar, sg, node, unit_id);
+	Actor* actor = CE_NEW(m_actors_pool, Actor)(*this, ar, sg, unit_id);
 	return id_array::create(m_actors, actor);
 }
 
@@ -263,9 +263,9 @@ void PhysicsWorld::destroy_actor(ActorId id)
 	id_array::destroy(m_actors, id);
 }
 
-ControllerId PhysicsWorld::create_controller(const ControllerResource* cr, SceneGraph& sg, int32_t node)
+ControllerId PhysicsWorld::create_controller(const ControllerResource* cr, SceneGraph& sg, UnitId id)
 {
-	Controller* controller = CE_NEW(m_controllers_pool, Controller)(cr, sg, node, physics_globals::s_physics, m_controller_manager);
+	Controller* controller = CE_NEW(m_controllers_pool, Controller)(cr, sg, id, physics_globals::s_physics, m_controller_manager);
 	return id_array::create(m_controllers, controller);
 }
 

+ 2 - 2
engine/physics/physics_world.h

@@ -48,10 +48,10 @@ public:
 	PhysicsWorld(World& world);
 	~PhysicsWorld();
 
-	ActorId create_actor(const ActorResource* ar, SceneGraph& sg, int32_t node, UnitId unit_id);
+	ActorId create_actor(const ActorResource* ar, SceneGraph& sg, UnitId unit_id);
 	void destroy_actor(ActorId id);
 
-	ControllerId create_controller(const ControllerResource* cr, SceneGraph& sg, int32_t node);
+	ControllerId create_controller(const ControllerResource* cr, SceneGraph& sg, UnitId id);
 	void destroy_controller(ControllerId id);
 
 	JointId create_joint(const JointResource* jr, const Actor& actor_0, const Actor& actor_1);

+ 2 - 2
engine/renderers/render_world.cpp

@@ -29,9 +29,9 @@ RenderWorld::~RenderWorld()
 {
 }
 
-SpriteId RenderWorld::create_sprite(SpriteResource* sr, SceneGraph& sg, int32_t node)
+SpriteId RenderWorld::create_sprite(SpriteResource* sr, SceneGraph& sg, UnitId id)
 {
-	Sprite* sprite = CE_NEW(m_sprite_pool, Sprite)(*this, sg, node, sr);
+	Sprite* sprite = CE_NEW(m_sprite_pool, Sprite)(*this, sg, id, sr);
 	return id_array::create(m_sprite, sprite);
 }
 

+ 2 - 1
engine/renderers/render_world.h

@@ -25,6 +25,7 @@ struct SceneGraph;
 struct Sprite;
 struct Mesh;
 struct Gui;
+typedef Id UnitId;
 
 /// @defgroup Graphics Graphics
 
@@ -38,7 +39,7 @@ public:
 	RenderWorld();
 	~RenderWorld();
 
-	SpriteId create_sprite(SpriteResource* sr, SceneGraph& sg, int32_t node);
+	SpriteId create_sprite(SpriteResource* sr, SceneGraph& sg, UnitId id);
 
 	/// Destroys the sprite @a id.
 	void destroy_sprite(SpriteId id);

+ 3 - 0
engine/renderers/render_world_types.h

@@ -13,5 +13,8 @@ namespace crown
 typedef Id MeshId;
 typedef Id SpriteId;
 typedef Id GuiId;
+typedef Id MaterialId;
+
+class RenderWorld;
 
 } // namespace crown

+ 4 - 48
engine/renderers/sprite.cpp

@@ -18,61 +18,16 @@
 namespace crown
 {
 
-Sprite::Sprite(RenderWorld& render_world, SceneGraph& sg, int32_t node, const SpriteResource* sr)
+Sprite::Sprite(RenderWorld& render_world, SceneGraph& sg, UnitId id, const SpriteResource* sr)
 	: m_render_world(render_world)
 	, m_scene_graph(sg)
-	, m_node(node)
 	, m_resource(sr)
 	, m_frame(0)
 	, _depth(0)
+	, _unit_id(id)
 {
 }
 
-Vector3 Sprite::local_position() const
-{
-	return m_scene_graph.local_position(m_node);
-}
-
-Quaternion Sprite::local_rotation() const
-{
-	return m_scene_graph.local_rotation(m_node);
-}
-
-Matrix4x4 Sprite::local_pose() const
-{
-	return m_scene_graph.local_pose(m_node);
-}
-
-Vector3 Sprite::world_position() const
-{
-	return m_scene_graph.world_position(m_node);
-}
-
-Quaternion Sprite::world_rotation() const
-{
-	return m_scene_graph.world_rotation(m_node);
-}
-
-Matrix4x4 Sprite::world_pose() const
-{
-	return m_scene_graph.world_pose(m_node);
-}
-
-void Sprite::set_local_position(Unit* unit, const Vector3& pos)
-{
-	unit->set_local_position(m_node, pos);
-}
-
-void Sprite::set_local_rotation(Unit* unit, const Quaternion& rot)
-{
-	unit->set_local_rotation(m_node, rot);
-}
-
-void Sprite::set_local_pose(Unit* unit, const Matrix4x4& pose)
-{
-	unit->set_local_pose(m_node, pose);
-}
-
 void Sprite::set_material(MaterialId id)
 {
 	m_material = id;
@@ -102,7 +57,8 @@ void Sprite::render()
 		| BGFX_STATE_BLEND_ALPHA);
 	bgfx::setVertexBuffer(m_resource->vb);
 	bgfx::setIndexBuffer(m_resource->ib, m_frame * 6, 6);
-	bgfx::setTransform(matrix4x4::to_float_ptr(world_pose()));
+	TransformInstance ti = m_scene_graph.get(_unit_id);
+	bgfx::setTransform(matrix4x4::to_float_ptr(m_scene_graph.world_pose(ti)));
 	bgfx::submit(0, _depth);
 }
 

+ 3 - 35
engine/renderers/sprite.h

@@ -11,47 +11,15 @@
 #include "quaternion.h"
 #include "sprite_resource.h"
 #include "material.h"
+#include "world_types.h"
 #include <bgfx.h>
 
 namespace crown
 {
 
-class Renderer;
-class RenderWorld;
-struct SceneGraph;
-struct Unit;
-typedef Id MaterialId;
-
 struct Sprite
 {
-	Sprite(RenderWorld& render_world, SceneGraph& sg, int32_t node, const SpriteResource* sr);
-
-	/// Returns the local position of the sprite.
-	Vector3 local_position() const;
-
-	/// Returns the local rotation of the sprite.
-	Quaternion local_rotation() const;
-
-	/// Returns the local pose of the sprite.
-	Matrix4x4 local_pose() const;
-
-	/// Returns the world position of the sprite.
-	Vector3 world_position() const;
-
-	/// Returns the world rotation of the sprite.
-	Quaternion world_rotation() const;
-
-	/// Returns the world pose of the sprite.
-	Matrix4x4 world_pose() const;
-
-	/// Sets the local position of the sprite.
-	void set_local_position(Unit* unit, const Vector3& pos);
-
-	/// Sets the local rotation of the sprite.
-	void set_local_rotation(Unit* unit, const Quaternion& rot);
-
-	/// Sets the local pose of the sprite.
-	void set_local_pose(Unit* unit, const Matrix4x4& pose);
+	Sprite(RenderWorld& render_world, SceneGraph& sg, UnitId id, const SpriteResource* sr);
 
 	void set_material(MaterialId id);
 
@@ -65,11 +33,11 @@ public:
 
 	RenderWorld& m_render_world;
 	SceneGraph& m_scene_graph;
-	int32_t m_node;
 	const SpriteResource* m_resource;
 	MaterialId m_material;
 	uint32_t m_frame;
 	int32_t _depth;
+	UnitId _unit_id;
 };
 
 } // namespace crown

+ 5 - 55
engine/world/camera.cpp

@@ -16,9 +16,9 @@
 namespace crown
 {
 
-Camera::Camera(SceneGraph& sg, int32_t node, ProjectionType::Enum type, float near, float far)
+Camera::Camera(SceneGraph& sg, UnitId id, ProjectionType::Enum type, float near, float far)
 	: _scene_graph(sg)
-	, _node(node)
+	, _unit_id(id)
 	, _projection_type(type)
 	, _near(near)
 	, _far(far)
@@ -26,51 +26,6 @@ Camera::Camera(SceneGraph& sg, int32_t node, ProjectionType::Enum type, float ne
 	update_projection_matrix();
 }
 
-Vector3 Camera::local_position() const
-{
-	return _scene_graph.local_position(_node);
-}
-
-Quaternion Camera::local_rotation() const
-{
-	return _scene_graph.local_rotation(_node);
-}
-
-Matrix4x4 Camera::local_pose() const
-{
-	return _scene_graph.local_pose(_node);
-}
-
-Vector3 Camera::world_position() const
-{
-	return _scene_graph.world_position(_node);
-}
-
-Quaternion Camera::world_rotation() const
-{
-	return _scene_graph.world_rotation(_node);
-}
-
-Matrix4x4 Camera::world_pose() const
-{
-	return _scene_graph.world_pose(_node);
-}
-
-void Camera::set_local_position(Unit* unit, const Vector3& pos)
-{
-	unit->set_local_position(_node, pos);
-}
-
-void Camera::set_local_rotation(Unit* unit, const Quaternion& rot)
-{
-	unit->set_local_rotation(_node, rot);
-}
-
-void Camera::set_local_pose(Unit* unit, const Matrix4x4& pose)
-{
-	unit->set_local_pose(_node, pose);
-}
-
 void Camera::set_projection_type(ProjectionType::Enum type)
 {
 	_projection_type = type;
@@ -89,7 +44,7 @@ const Matrix4x4& Camera::projection_matrix() const
 
 Matrix4x4 Camera::view_matrix() const
 {
-	Matrix4x4 view = world_pose();
+	Matrix4x4 view = _scene_graph.world_pose(_scene_graph.get(_unit_id));
 	matrix4x4::invert(view);
 	return view;
 }
@@ -160,9 +115,7 @@ Vector3 Camera::screen_to_world(const Vector3& pos)
 {
 	using namespace matrix4x4;
 
-	Matrix4x4 world_inv = world_pose();
-	invert(world_inv);
-	Matrix4x4 mvp = world_inv * _projection;
+	Matrix4x4 mvp = view_matrix() * _projection;
 	invert(mvp);
 
 	Vector4 ndc( (2 * (pos.x - 0)) / _view_width - 1,
@@ -179,10 +132,7 @@ Vector3 Camera::world_to_screen(const Vector3& pos)
 {
 	using namespace matrix4x4;
 
-	Matrix4x4 world_inv = world_pose();
-	invert(world_inv);
-
-	Vector3 ndc = pos * (world_inv * _projection);
+	Vector3 ndc = pos * (view_matrix() * _projection);
 
 	return Vector3( (_view_x + _view_width * (ndc.x + 1.0f)) / 2.0f,
 					(_view_y + _view_height * (ndc.y + 1.0f)) / 2.0f,

+ 2 - 29
engine/world/camera.h

@@ -28,34 +28,7 @@ struct ProjectionType
 /// @ingroup World
 struct Camera
 {
-	Camera(SceneGraph& sg, int32_t node, ProjectionType::Enum type, float near, float far);
-
-	/// Returns the local position of the camera.
-	Vector3 local_position() const;
-
-	/// Returns the local rotation of the camera.
-	Quaternion local_rotation() const;
-
-	/// Returns the local pose of the camera.
-	Matrix4x4 local_pose() const;
-
-	/// Returns the world position of the camera.
-	Vector3 world_position() const;
-
-	/// Returns the world rotation of the camera.
-	Quaternion world_rotation() const;
-
-	/// Returns the world pose of the camera.
-	Matrix4x4 world_pose() const;
-
-	/// Sets the local position of the camera.
-	void set_local_position(Unit* unit, const Vector3& pos);
-
-	/// Sets the local rotation of the camera.
-	void set_local_rotation(Unit* unit, const Quaternion& rot);
-
-	/// Sets the local pose of the camera.
-	void set_local_pose(Unit* unit, const Matrix4x4& pose);
+	Camera(SceneGraph& sg, UnitId id, ProjectionType::Enum type, float near, float far);
 
 	/// Sets the projection type of the camera.
 	void set_projection_type(ProjectionType::Enum type);
@@ -113,7 +86,7 @@ public:
 public:
 
 	SceneGraph& _scene_graph;
-	int32_t _node;
+	UnitId _unit_id;
 
 	ProjectionType::Enum _projection_type;
 	Matrix4x4 _projection;

+ 198 - 161
engine/world/scene_graph.cpp

@@ -6,249 +6,286 @@
 #include "scene_graph.h"
 #include "quaternion.h"
 #include "vector3.h"
+#include "matrix3x3.h"
 #include "matrix4x4.h"
 #include "allocator.h"
-#include "string_utils.h"
-#include <string.h>
-
-#define CLEAN		0
-#define LOCAL_DIRTY	1
-#define WORLD_DIRTY	1 << 2
+#include "array.h"
+#include <string.h> // memcpy
+#include <stdint.h> // UINT_MAX
 
 namespace crown
 {
 
+using namespace vector3;
+using namespace matrix3x3;
 using namespace matrix4x4;
 
-SceneGraph::SceneGraph(Allocator& a, uint32_t index)
-	: m_allocator(&a)
-	, m_index(index)
-	, m_num_nodes(0)
-	, m_flags(NULL)
-	, m_world_poses(NULL)
-	, m_local_poses(NULL)
-	, m_parents(NULL)
-	, m_names(NULL)
+SceneGraph::SceneGraph(Allocator& a)
+	: _allocator(a)
+	, _map(a)
 {
 }
 
-void SceneGraph::create(const Matrix4x4& root, uint32_t count, const UnitNode* nodes)
+SceneGraph::~SceneGraph()
 {
-	m_num_nodes = count;
-
-	m_flags = (uint8_t*) m_allocator->allocate(sizeof(uint8_t) * count);
-	m_world_poses = (Matrix4x4*) m_allocator->allocate(sizeof(Matrix4x4) * count);
-	m_local_poses = (Matrix4x4*) m_allocator->allocate(sizeof(Matrix4x4) * count);
-	m_parents = (int32_t*) m_allocator->allocate(sizeof(int32_t) * count);
-	m_names = (StringId32*) m_allocator->allocate(sizeof(StringId32) * count);
-
-	for (uint32_t i = 0; i < count; i++)
-	{
-		m_flags[i] = (int) CLEAN;
-		m_local_poses[i] = nodes[i].pose;
-		m_parents[i] = -1;
-		m_names[i] = nodes[i].name;
-	}
-
-	// Compute initial world poses
-	for (uint32_t i = 1; i < m_num_nodes; i++)
-	{
-		m_world_poses[i] = root * m_local_poses[i];
-	}
-
-	m_world_poses[0] = root;
-	m_flags[0] = WORLD_DIRTY;
-
-	update();
+	_allocator.deallocate(_data.buffer);
 }
 
-void SceneGraph::destroy()
+TransformInstance SceneGraph::make_instance(uint32_t i)
 {
-	m_allocator->deallocate(m_flags);
-	m_allocator->deallocate(m_world_poses);
-	m_allocator->deallocate(m_local_poses);
-	m_allocator->deallocate(m_parents);
-	m_allocator->deallocate(m_names);
+	TransformInstance inst = { i };
+	return inst;
 }
 
-int32_t SceneGraph::node(const char* name) const
+void SceneGraph::allocate(uint32_t num)
 {
-	return node(StringId32(name));
+	CE_ASSERT(num > _data.size, "num > _data.size");
+
+	const uint32_t bytes = num * (0
+		+ sizeof(UnitId)
+		+ sizeof(Matrix4x4)
+		+ sizeof(Pose)
+		+ sizeof(TransformInstance) * 4);
+
+	InstanceData new_data;
+	new_data.size = _data.size;
+	new_data.capacity = num;
+	new_data.buffer = _allocator.allocate(bytes);
+
+	new_data.unit = (UnitId*)(new_data.buffer);
+	new_data.world = (Matrix4x4*)(new_data.unit + num);
+	new_data.local = (Pose*)(new_data.world + num);
+	new_data.parent = (TransformInstance*)(new_data.local + num);
+	new_data.first_child = (TransformInstance*)(new_data.parent + num);
+	new_data.next_sibling = (TransformInstance*)(new_data.first_child + num);
+	new_data.prev_sibling = (TransformInstance*)(new_data.next_sibling + num);
+
+	memcpy(new_data.unit, _data.unit, _data.size * sizeof(UnitId));
+	memcpy(new_data.world, _data.world, _data.size * sizeof(Matrix4x4));
+	memcpy(new_data.local, _data.local, _data.size * sizeof(Pose));
+	memcpy(new_data.parent, _data.parent, _data.size * sizeof(TransformInstance));
+	memcpy(new_data.first_child, _data.first_child, _data.size * sizeof(TransformInstance));
+	memcpy(new_data.next_sibling, _data.next_sibling, _data.size * sizeof(TransformInstance));
+	memcpy(new_data.prev_sibling, _data.prev_sibling, _data.size * sizeof(TransformInstance));
+
+	_allocator.deallocate(_data.buffer);
+	_data = new_data;
 }
 
-int32_t SceneGraph::node(StringId32 name) const
+void SceneGraph::create(const Matrix4x4& m, UnitId id)
 {
-	for (uint32_t i = 0; i < m_num_nodes; i++)
-	{
-		if (m_names[i] == name)
-		{
-			return i;
-		}
-	}
+	if (_data.capacity == _data.size)
+		grow();
 
-	CE_FATAL("Node not found");
-	return 0;
-}
+	const uint32_t last = _data.size;
 
-bool SceneGraph::has_node(const char* name) const
-{
-	const StringId32 name_hash(name);
+	_data.unit[last] = id;
+	_data.world[last] = m;
+	_data.local[last] = m;
+	_data.parent[last].i = UINT32_MAX;
+	_data.first_child[last].i = UINT32_MAX;
+	_data.next_sibling[last].i = UINT32_MAX;
+	_data.prev_sibling[last].i = UINT32_MAX;
 
-	for (uint32_t i = 0; i < m_num_nodes; i++)
-	{
-		if (m_names[i] == name_hash)
-		{
-			return true;
-		}
-	}
+	// FIXME
+	if (array::size(_map) <= id.index)
+		array::resize(_map, array::size(_map) + id.index + 1);
 
-	return false;
+	_map[id.index] = last;
+
+	++_data.size;
 }
 
-uint32_t SceneGraph::num_nodes() const
+void SceneGraph::destroy(TransformInstance i)
 {
-	return m_num_nodes;
+	const uint32_t last = _data.size - 1;
+	const UnitId u = _data.unit[i.i];
+	const UnitId last_u = _data.unit[last];
+
+	_data.unit[i.i] = _data.unit[last];
+	_data.world[i.i] = _data.world[last];
+	_data.local[i.i] = _data.local[last];
+	_data.parent[i.i] = _data.parent[last];
+	_data.first_child[i.i] = _data.first_child[last];
+	_data.next_sibling[i.i] = _data.next_sibling[last];
+	_data.prev_sibling[i.i] = _data.prev_sibling[last];
+
+	_map[last_u.index] = i.i;
+	_map[u.index] = UINT32_MAX;
+
+	--_data.size;
 }
 
-bool SceneGraph::can_link(int32_t child, int32_t parent) const
+TransformInstance SceneGraph::get(UnitId id)
 {
-	return parent < child;
+	return make_instance(_map[id.index]);
 }
 
-void SceneGraph::link(int32_t child, int32_t parent)
+void SceneGraph::set_local_position(TransformInstance i, const Vector3& pos)
 {
-	CE_ASSERT(child < (int32_t) m_num_nodes, "Child node does not exist");
-	CE_ASSERT(parent < (int32_t) m_num_nodes, "Parent node does not exist");
-	CE_ASSERT(can_link(child, parent), "Parent must be < child");
-
-	m_world_poses[child] = matrix4x4::IDENTITY;
-	m_local_poses[child] = matrix4x4::IDENTITY;
-	m_parents[child] = parent;
+	_data.local[i.i].position = pos;
+	set_local(i);
 }
 
-void SceneGraph::unlink(int32_t child)
+void SceneGraph::set_local_rotation(TransformInstance i, const Quaternion& rot)
 {
-	CE_ASSERT(child < (int32_t) m_num_nodes, "Child node does not exist");
-
-	if (m_parents[child] != -1)
-	{
-		// Copy world pose before unlinking from parent
-		m_local_poses[child] = m_world_poses[child];
-		m_parents[child] = -1;
-	}
+	_data.local[i.i].rotation = Matrix3x3(rot);
+	set_local(i);
 }
 
-void SceneGraph::set_local_position(int32_t node, const Vector3& pos)
+void SceneGraph::set_local_scale(TransformInstance i, const Vector3& scale)
 {
-	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
-
-	m_flags[node] |= LOCAL_DIRTY;
-	set_translation(m_local_poses[node], pos);
+	_data.local[i.i].scale = scale;
+	set_local(i);
 }
 
-void SceneGraph::set_local_rotation(int32_t node, const Quaternion& rot)
+void SceneGraph::set_local_pose(TransformInstance i, const Matrix4x4& pose)
 {
-	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
-
-	m_flags[node] |= LOCAL_DIRTY;
-	set_rotation(m_local_poses[node], rot);
+	_data.local[i.i] = pose;
+	set_local(i);
 }
 
-void SceneGraph::set_local_pose(int32_t node, const Matrix4x4& pose)
+Vector3 SceneGraph::local_position(TransformInstance i) const
 {
-	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
-
-	m_flags[node] |= LOCAL_DIRTY;
-	m_local_poses[node] = pose;
+	return _data.local[i.i].position;
 }
 
-Vector3 SceneGraph::local_position(int32_t node) const
+Quaternion SceneGraph::local_rotation(TransformInstance i) const
 {
-	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
-
-	return translation(m_local_poses[node]);
+	return rotation(_data.local[i.i].rotation);
 }
 
-Quaternion SceneGraph::local_rotation(int32_t node) const
+Vector3 SceneGraph::local_scale(TransformInstance i) const
 {
-	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
-
-	return rotation(m_local_poses[node]);
+	return _data.local[i.i].scale;
 }
 
-Matrix4x4 SceneGraph::local_pose(int32_t node) const
+Matrix4x4 SceneGraph::local_pose(TransformInstance i) const
 {
-	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
-
-	return m_local_poses[node];
+	Matrix4x4 tr(rotation(_data.local[i.i].rotation), _data.local[i.i].position);
+	set_scale(tr, _data.local[i.i].scale);
+	return tr;
 }
 
-void SceneGraph::set_world_position(int32_t node, const Vector3& pos)
+Vector3 SceneGraph::world_position(TransformInstance i) const
 {
-	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
-
-	m_flags[node] |= WORLD_DIRTY;
-	set_translation(m_world_poses[node], pos);
+	return translation(_data.world[i.i]);
 }
 
-void SceneGraph::set_world_rotation(int32_t node, const Quaternion& rot)
+Quaternion SceneGraph::world_rotation(TransformInstance i) const
 {
-	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
-
-	m_flags[node] |= WORLD_DIRTY;
-	set_rotation(m_world_poses[node], rot);
+	return rotation(_data.world[i.i]);
 }
 
-void SceneGraph::set_world_pose(int32_t node, const Matrix4x4& pose)
+Matrix4x4 SceneGraph::world_pose(TransformInstance i) const
 {
-	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
+	return _data.world[i.i];
+}
 
-	m_flags[node] |= WORLD_DIRTY;
-	m_world_poses[node] = pose;
+uint32_t SceneGraph::num_nodes() const
+{
+	return _data.size;
 }
 
-Vector3 SceneGraph::world_position(int32_t node) const
+void SceneGraph::link(TransformInstance child, TransformInstance parent)
 {
-	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
+	unlink(child);
+
+	if (!is_valid(_data.first_child[parent.i]))
+	{
+		_data.first_child[parent.i] = child;
+		_data.parent[child.i] = parent;
+	}
+	else
+	{
+		TransformInstance prev = { UINT32_MAX };
+		TransformInstance node = _data.first_child[parent.i];
+		while (is_valid(node))
+		{
+			prev = node;
+			node = _data.next_sibling[node.i];
+		}
+
+		_data.next_sibling[prev.i] = child;
+
+		_data.first_child[child.i].i = UINT32_MAX;
+		_data.next_sibling[child.i].i = UINT32_MAX;
+		_data.prev_sibling[child.i] = prev;
+	}
+
+	Matrix4x4 parent_tr = _data.world[parent.i];
+	Matrix4x4 child_tr = _data.world[child.i];
+	const Vector3 cs = scale(child_tr);
 
-	return translation(m_world_poses[node]);
+	Vector3 px = x(parent_tr);
+	Vector3 py = y(parent_tr);
+	Vector3 pz = z(parent_tr);
+	Vector3 cx = x(child_tr);
+	Vector3 cy = y(child_tr);
+	Vector3 cz = z(child_tr);
+
+	set_x(parent_tr, normalize(px));
+	set_y(parent_tr, normalize(py));
+	set_z(parent_tr, normalize(pz));
+	set_x(child_tr, normalize(cx));
+	set_y(child_tr, normalize(cy));
+	set_z(child_tr, normalize(cz));
+
+	const Matrix4x4 rel_tr = child_tr * get_inverted(parent_tr);
+
+	_data.local[child.i].position = translation(rel_tr);
+	_data.local[child.i].rotation = rotation(rel_tr);
+	_data.local[child.i].scale = cs;
+	_data.parent[child.i] = parent;
+
+	transform(parent_tr, child);
 }
 
-Quaternion SceneGraph::world_rotation(int32_t node) const
+void SceneGraph::unlink(TransformInstance child)
 {
-	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
+	if (!is_valid(_data.parent[child.i]))
+		return;
 
-	return rotation(m_world_poses[node]);
+	if (!is_valid(_data.prev_sibling[child.i]))
+		_data.first_child[_data.parent[child.i].i] = _data.next_sibling[child.i];
+	else
+		_data.next_sibling[_data.prev_sibling[child.i].i] = _data.next_sibling[child.i];
+
+	if (is_valid(_data.next_sibling[child.i]))
+		_data.prev_sibling[_data.next_sibling[child.i].i] = _data.prev_sibling[child.i];
+
+	_data.parent[child.i].i = UINT32_MAX;
+	_data.next_sibling[child.i].i = UINT32_MAX;
+	_data.prev_sibling[child.i].i = UINT32_MAX;
 }
 
-Matrix4x4 SceneGraph::world_pose(int32_t node) const
+bool SceneGraph::is_valid(TransformInstance i)
 {
-	CE_ASSERT(node < (int32_t) m_num_nodes, "Node does not exist");
+	return i.i != UINT32_MAX;
+}
 
-	return m_world_poses[node];
+void SceneGraph::set_local(TransformInstance i)
+{
+	TransformInstance parent = _data.parent[i.i];
+	Matrix4x4 parent_tm = is_valid(parent) ? _data.world[parent.i] : matrix4x4::IDENTITY;
+	transform(parent_tm, i);
 }
 
-void SceneGraph::update()
+void SceneGraph::transform(const Matrix4x4& parent, TransformInstance i)
 {
-	for (uint32_t i = 0; i < m_num_nodes; i++)
-	{
-		const uint8_t my_flags = m_flags[i];
-		const uint8_t parent_flags = m_flags[m_parents[i]];
+	_data.world[i.i] = local_pose(i) * parent;
 
-		if (my_flags & LOCAL_DIRTY || parent_flags & WORLD_DIRTY)
-		{
-			if (m_parents[i] == -1)
-			{
-				m_world_poses[i] = m_local_poses[i];
-			}
-			else
-			{
-				m_world_poses[i] = m_world_poses[m_parents[i]] * m_local_poses[i];
-			}
-
-			m_flags[i] = CLEAN;
-		}
+	TransformInstance child = _data.first_child[i.i];
+	while (is_valid(child))
+	{
+		transform(_data.world[i.i], child);
+		child = _data.next_sibling[child.i];
 	}
 }
 
+void SceneGraph::grow()
+{
+	allocate(_data.capacity * 2 + 1);
+}
+
 } // namespace crown

+ 108 - 63
engine/world/scene_graph.h

@@ -7,104 +7,149 @@
 
 #include "types.h"
 #include "math_types.h"
+#include "matrix4x4.h"
 #include "memory_types.h"
-#include "unit_resource.h"
+#include "world_types.h"
+#include "container_types.h"
+#include "matrix3x3.h"
+#include "matrix4x4.h"
+#include "vector3.h"
 
 namespace crown
 {
 
+struct TransformInstance
+{
+	uint32_t i;
+};
+
 /// Represents a collection of nodes, possibly linked together to form a tree.
 ///
 /// @ingroup World
 struct SceneGraph
 {
-	SceneGraph(Allocator& a, uint32_t index);
-
-	/// Creates the graph with @a count items.
-	/// @a name, @a local and @parent are the array containing the name of the nodes,
-	/// the local poses of the nodes and the links between the nodes respectively.
-	/// A parent of -1 means "no parent".
-	void create(const Matrix4x4& root, uint32_t count, const UnitNode* nodes);
-
-	/// Destroys the graph deallocating memory if necessary.
-	void destroy();
-
-	/// Returns the index of the node with the given @a name
-	int32_t node(const char* name) const;
-
-	/// @copydoc SceneGraph::node()
-	int32_t node(StringId32 name) const;
-
-	/// Returns whether the graph has the node with the given @a name.
-	bool has_node(const char* name) const;
+	SceneGraph(Allocator& a);
+	~SceneGraph();
 
-	/// Returns the number of nodes in the graph.
-	uint32_t num_nodes() const;
+	/// Creates a new transform instance for unit @a id.
+	void create(const Matrix4x4& m, UnitId id);
+	void destroy(TransformInstance i);
 
-	/// Returns whether the node @a child can be linked to @a parent.
-	bool can_link(int32_t child, int32_t parent) const;
-
-	/// Links the @a child node to the @a parent node.
-	/// After the linking the @a child pose is reset to identity.
-	/// @note The @a parent node must be either -1 (meaning no parent), or an index lesser than child.
-	void link(int32_t child, int32_t parent);
+	/// Returns the transform instance of unit @a id.
+	TransformInstance get(UnitId id);
 
-	/// Unlinks the @a child node from its parent if it has any.
-	/// After unlinking, the @child local pose is set to its previous world pose.
-	void unlink(int32_t child);
+	/// Sets the local position, rotation, scale or pose of the given @a node.
+	void set_local_position(TransformInstance i, const Vector3& pos);
 
-	/// Sets the local position, rotation or pose of the given @a node.
-	void set_local_position(int32_t node, const Vector3& pos);
+	/// @copydoc SceneGraph::set_local_position()
+	void set_local_rotation(TransformInstance i, const Quaternion& rot);
 
 	/// @copydoc SceneGraph::set_local_position()
-	void set_local_rotation(int32_t node, const Quaternion& rot);
+	void set_local_scale(TransformInstance i, const Vector3& scale);
 
 	/// @copydoc SceneGraph::set_local_position()
-	void set_local_pose(int32_t node, const Matrix4x4& pose);
+	void set_local_pose(TransformInstance i, const Matrix4x4& pose);
 
 	/// Returns the local position, rotation or pose of the given @a node.
-	Vector3 local_position(int32_t node) const;
+	Vector3 local_position(TransformInstance i) const;
 
 	/// @copydoc SceneGraph::local_position()
-	Quaternion local_rotation(int32_t node) const;
+	Quaternion local_rotation(TransformInstance i) const;
 
 	/// @copydoc SceneGraph::local_position()
-	Matrix4x4 local_pose(int32_t node) const;
-
-	/// Sets the world position, rotation or pose of the given @a node.
-	/// @note This should never be called by user code.
-	void set_world_position(int32_t node, const Vector3& pos);
+	Vector3 local_scale(TransformInstance i) const;
 
-	/// @copydoc SceneGraph::set_world_position()
-	void set_world_rotation(int32_t node, const Quaternion& rot);
-
-	/// @copydoc SceneGraph::set_world_position()
-	void set_world_pose(int32_t node, const Matrix4x4& pose);
+	/// @copydoc SceneGraph::local_position()
+	Matrix4x4 local_pose(TransformInstance i) const;
 
 	/// Returns the world position, rotation or pose of the given @a node.
-	Vector3 world_position(int32_t node) const;
+	Vector3 world_position(TransformInstance i) const;
 
 	/// @copydoc SceneGraph::world_position()
-	Quaternion world_rotation(int32_t node) const;
+	Quaternion world_rotation(TransformInstance i) const;
 
 	/// @copydoc SceneGraph::world_position()
-	Matrix4x4 world_pose(int32_t node) const;
+	Matrix4x4 world_pose(TransformInstance i) const;
+
+	/// Returns the number of nodes in the graph.
+	uint32_t num_nodes() const;
 
-	/// Transforms local poses to world poses.
-	void update();
+	/// Links the @a child node to the @a parent node.
+	void link(TransformInstance child, TransformInstance paren);
 
-public:
+	/// Unlinks the @a child node from its parent if it has any.
+	/// After unlinking, the @child local pose is set to its previous world pose.
+	void unlink(TransformInstance child);
+
+	bool is_valid(TransformInstance i);
+
+	void set_local(TransformInstance i);
+
+	void transform(const Matrix4x4& parent, TransformInstance i);
 
-	/// Index into SceneGraphManager
-	Allocator* m_allocator;
-	uint32_t m_index;
+	void grow();
+
+	void allocate(uint32_t num);
+
+	TransformInstance make_instance(uint32_t i);
+
+public:
 
-	uint32_t m_num_nodes;
-	uint8_t* m_flags;
-	Matrix4x4* m_world_poses;
-	Matrix4x4* m_local_poses;
-	int32_t* m_parents;
-	StringId32* m_names;
+	struct Pose
+	{
+		Pose& operator=(const Matrix4x4& m)
+		{
+			using namespace matrix3x3;
+			using namespace matrix4x4;
+			using namespace vector3;
+			Matrix3x3 rotm = to_matrix3x3(m);
+			normalize(rotm.x);
+			normalize(rotm.y);
+			normalize(rotm.z);
+
+			position = translation(m);
+			rotation = rotm;
+			scale = matrix4x4::scale(m);
+			return *this;
+		}
+
+		Vector3 position;
+		Matrix3x3 rotation;
+		Vector3 scale;
+	};
+
+	struct InstanceData
+	{
+		InstanceData()
+			: size(0)
+			, capacity(0)
+			, buffer(NULL)
+			, unit(NULL)
+			, world(NULL)
+			, local(NULL)
+			, parent(NULL)
+			, first_child(NULL)
+			, next_sibling(NULL)
+			, prev_sibling(NULL)
+		{
+		}
+
+		uint32_t size;
+		uint32_t capacity;
+		void* buffer;
+
+		UnitId* unit;
+		Matrix4x4* world;
+		Pose* local;
+		TransformInstance* parent;
+		TransformInstance* first_child;
+		TransformInstance* next_sibling;
+		TransformInstance* prev_sibling;
+	};
+
+	Allocator& _allocator;
+	InstanceData _data;
+	Array<uint32_t> _map;
 };
 
 } // namespace crown

+ 0 - 50
engine/world/scene_graph_manager.cpp

@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
- * License: https://github.com/taylor001/crown/blob/master/LICENSE
- */
-
-#include "scene_graph_manager.h"
-#include "scene_graph.h"
-#include "array.h"
-#include "memory.h"
-
-namespace crown
-{
-
-SceneGraphManager::SceneGraphManager()
-	: m_graphs(default_allocator())
-{
-}
-
-SceneGraphManager::~SceneGraphManager()
-{
-}
-
-SceneGraph* SceneGraphManager::create_scene_graph()
-{
-	uint32_t index = array::size(m_graphs);
-	SceneGraph* sg = CE_NEW(default_allocator(), SceneGraph)(default_allocator(), index);
-	array::push_back(m_graphs, sg);
-	return sg;
-}
-
-void SceneGraphManager::destroy_scene_graph(SceneGraph* sg)
-{
-	CE_ASSERT_NOT_NULL(sg);
-
-	m_graphs[sg->m_index] = m_graphs[array::size(m_graphs) - 1];
-	m_graphs[sg->m_index]->m_index = sg->m_index;
-	array::pop_back(m_graphs);
-
-	CE_DELETE(default_allocator(), sg);
-}
-
-void SceneGraphManager::update()
-{
-	for (uint32_t i = 0; i < array::size(m_graphs); i++)
-	{
-		m_graphs[i]->update();
-	}
-}
-
-} // namespace crown

+ 0 - 39
engine/world/scene_graph_manager.h

@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
- * License: https://github.com/taylor001/crown/blob/master/LICENSE
- */
-
-#pragma once
-
-#include "container_types.h"
-
-namespace crown
-{
-
-struct SceneGraph;
-
-/// Manages a collection of scene graphs.
-///
-/// @ingroup World
-class SceneGraphManager
-{
-public:
-
-	SceneGraphManager();
-	~SceneGraphManager();
-
-	/// Creates a new scene graph
-	SceneGraph* create_scene_graph();
-
-	/// Destroys the @a sg scene graph
-	void destroy_scene_graph(SceneGraph* sg);
-
-	/// Updates all the scene graphs
-	void update();
-
-private:
-
-	Array<SceneGraph*> m_graphs;
-};
-
-} // namespace crown

+ 43 - 49
engine/world/unit.cpp

@@ -8,7 +8,6 @@
 #include "memory.h"
 #include "log.h"
 #include "unit_resource.h"
-#include "scene_graph_manager.h"
 #include "actor.h"
 #include "controller.h"
 #include "physics_resource.h"
@@ -22,9 +21,9 @@ namespace crown
 
 using namespace unit_resource;
 
-Unit::Unit(World& w, UnitId unit_id, const UnitResource* ur, const Matrix4x4& pose)
+Unit::Unit(World& w, UnitId unit_id, const UnitResource* ur, SceneGraph& sg, const Matrix4x4& pose)
 	: m_world(w)
-	, m_scene_graph(*w.scene_graph_manager()->create_scene_graph())
+	, m_scene_graph(sg)
 	, m_sprite_animation(NULL)
 	, m_resource(ur)
 	, m_id(unit_id)
@@ -41,7 +40,6 @@ Unit::Unit(World& w, UnitId unit_id, const UnitResource* ur, const Matrix4x4& po
 Unit::~Unit()
 {
 	destroy_objects();
-	m_world.scene_graph_manager()->destroy_scene_graph(&m_scene_graph);
 }
 
 void Unit::set_id(const UnitId id)
@@ -62,7 +60,7 @@ const UnitResource*	Unit::resource() const
 void Unit::create_objects(const Matrix4x4& pose)
 {
 	using namespace unit_resource;
-	m_scene_graph.create(pose, num_scene_graph_nodes(m_resource), scene_graph_nodes(m_resource));
+	m_scene_graph.create(pose, m_id);
 
 	create_camera_objects();
 	create_renderable_objects();
@@ -125,7 +123,7 @@ void Unit::destroy_objects()
 	m_num_materials = 0;
 
 	// Destroy scene graph
-	m_scene_graph.destroy();
+	m_scene_graph.destroy(m_scene_graph.get(m_id));
 }
 
 void Unit::create_camera_objects()
@@ -133,7 +131,7 @@ void Unit::create_camera_objects()
 	for (uint32_t i = 0; i < num_cameras(m_resource); i++)
 	{
 		const UnitCamera* cam = get_camera(m_resource, i);
-		const CameraId id = m_world.create_camera(m_scene_graph, cam->node, (ProjectionType::Enum)cam->type, cam->near, cam->far);
+		const CameraId id = m_world.create_camera(m_scene_graph, m_id, (ProjectionType::Enum)cam->type, cam->near, cam->far);
 		add_camera(cam->name, id);
 	}
 }
@@ -159,7 +157,7 @@ void Unit::create_renderable_objects()
 		else if (ur->type == UnitRenderable::SPRITE)
 		{
 			SpriteResource* sr = (SpriteResource*) device()->resource_manager()->get(SPRITE_TYPE, ur->resource);
-			SpriteId sprite = m_world.render_world()->create_sprite(sr, m_scene_graph, ur->node);
+			SpriteId sprite = m_world.render_world()->create_sprite(sr, m_scene_graph, m_id);
 			add_sprite(ur->name, sprite);
 		}
 		else
@@ -181,8 +179,7 @@ void Unit::create_physics_objects()
 		if (has_controller(pr))
 		{
 			const ControllerResource* cr = physics_resource::controller(pr);
-
-			set_controller(cr->name, m_world.physics_world()->create_controller(cr, m_scene_graph, 0));
+			set_controller(cr->name, m_world.physics_world()->create_controller(cr, m_scene_graph, m_id));
 		}
 
 		// Create actors if any
@@ -190,7 +187,7 @@ void Unit::create_physics_objects()
 		{
 			const ActorResource* ar = physics_resource::actor(pr, i);
 
-			ActorId id = m_world.physics_world()->create_actor(ar, m_scene_graph, m_scene_graph.node(ar->node), m_id);
+			ActorId id = m_world.physics_world()->create_actor(ar, m_scene_graph, m_id);
 			add_actor(ar->name, id);
 		}
 
@@ -214,74 +211,70 @@ void Unit::set_default_material()
 	}
 }
 
-int32_t Unit::node(const char* name) const
-{
-	return m_scene_graph.node(name);
-}
-
-bool Unit::has_node(const char* name) const
-{
-	return m_scene_graph.has_node(name);
-}
-
-uint32_t Unit::num_nodes() const
-{
-	return m_scene_graph.num_nodes();
-}
-
-Vector3 Unit::local_position(int32_t node) const
+Vector3 Unit::local_position() const
 {
-	return m_scene_graph.local_position(node);
+	TransformInstance ti = m_scene_graph.get(m_id);
+	return m_scene_graph.local_position(ti);
 }
 
-Quaternion Unit::local_rotation(int32_t node) const
+Quaternion Unit::local_rotation() const
 {
-	return m_scene_graph.local_rotation(node);
+	TransformInstance ti = m_scene_graph.get(m_id);
+	return m_scene_graph.local_rotation(ti);
 }
 
-Matrix4x4 Unit::local_pose(int32_t node) const
+Vector3 Unit::local_scale() const
 {
-	return m_scene_graph.local_pose(node);
+	TransformInstance ti = m_scene_graph.get(m_id);
+	return m_scene_graph.local_scale(ti);
 }
 
-Vector3 Unit::world_position(int32_t node) const
+Matrix4x4 Unit::local_pose() const
 {
-	return m_scene_graph.world_position(node);
+	TransformInstance ti = m_scene_graph.get(m_id);
+	return m_scene_graph.local_pose(ti);
 }
 
-Quaternion Unit::world_rotation(int32_t node) const
+Vector3 Unit::world_position() const
 {
-	return m_scene_graph.world_rotation(node);
+	TransformInstance ti = m_scene_graph.get(m_id);
+	return m_scene_graph.world_position(ti);
 }
 
-Matrix4x4 Unit::world_pose(int32_t node) const
+Quaternion Unit::world_rotation() const
 {
-	return m_scene_graph.world_pose(node);
+	TransformInstance ti = m_scene_graph.get(m_id);
+	return m_scene_graph.world_rotation(ti);
 }
 
-void Unit::set_local_position(int32_t node, const Vector3& pos)
+Matrix4x4 Unit::world_pose() const
 {
-	m_scene_graph.set_local_position(node, pos);
+	TransformInstance ti = m_scene_graph.get(m_id);
+	return m_scene_graph.world_pose(ti);
 }
 
-void Unit::set_local_rotation(int32_t node, const Quaternion& rot)
+void Unit::set_local_position(const Vector3& pos)
 {
-	m_scene_graph.set_local_rotation(node, rot);
+	TransformInstance ti = m_scene_graph.get(m_id);
+	m_scene_graph.set_local_position(ti, pos);
 }
 
-void Unit::set_local_pose(int32_t node, const Matrix4x4& pose)
+void Unit::set_local_rotation(const Quaternion& rot)
 {
-	m_scene_graph.set_local_pose(node, pose);
+	TransformInstance ti = m_scene_graph.get(m_id);
+	m_scene_graph.set_local_rotation(ti, rot);
 }
 
-void Unit::link_node(int32_t child, int32_t parent)
+void Unit::set_local_scale(const Vector3& scale)
 {
-	m_scene_graph.link(child, parent);
+	TransformInstance ti = m_scene_graph.get(m_id);
+	m_scene_graph.set_local_scale(ti, scale);
 }
 
-void Unit::unlink_node(int32_t child)
+void Unit::set_local_pose(const Matrix4x4& pose)
 {
-	m_scene_graph.unlink(child);
+	TransformInstance ti = m_scene_graph.get(m_id);
+	m_scene_graph.set_local_pose(ti, pose);
 }
 
 void Unit::update()
@@ -294,7 +287,8 @@ void Unit::update()
 
 void Unit::reload(UnitResource* new_ur)
 {
-	Matrix4x4 m = m_scene_graph.world_pose(0);
+	TransformInstance ti = m_scene_graph.get(m_id);
+	Matrix4x4 m = m_scene_graph.world_pose(ti);
 	destroy_objects();
 	m_resource = new_ur;
 	create_objects(m);

+ 17 - 27
engine/world/unit.h

@@ -16,6 +16,7 @@
 #include "config.h"
 #include "sprite_animation.h"
 #include "resource_types.h"
+#include "unit_resource.h"
 
 namespace crown
 {
@@ -55,7 +56,7 @@ struct Material;
 /// @ingroup World
 struct Unit
 {
-	Unit(World& w, UnitId unit_id, const UnitResource* ur, const Matrix4x4& pose);
+	Unit(World& w, UnitId unit_id, const UnitResource* ur, SceneGraph& sg, const Matrix4x4& pose);
 	~Unit();
 
 	void set_id(const UnitId id);
@@ -63,49 +64,38 @@ struct Unit
 
 	const UnitResource*	resource() const;
 
-	/// Returns the node @a name.
-	int32_t node(const char* name) const;
-
-	/// Returns whether the unit has the node @a name.
-	bool has_node(const char* name) const;
-
-	/// Returns the number of nodes of the unit.
-	uint32_t num_nodes() const;
-
 	/// Returns the local position of the unit.
-	Vector3 local_position(int32_t node) const;
+	Vector3 local_position() const;
 
 	/// Returns the local rotation of the unit.
-	Quaternion local_rotation(int32_t node) const;
+	Quaternion local_rotation() const;
+
+	/// Returns the local scale of the unit.
+	Vector3 local_scale() const;
 
 	/// Returns the local pose of the unit.
-	Matrix4x4 local_pose(int32_t node) const;
+	Matrix4x4 local_pose() const;
 
 	/// Returns the world position of the unit.
-	Vector3 world_position(int32_t node) const;
+	Vector3 world_position() const;
 
 	/// Returns the world rotation of the unit.
-	Quaternion world_rotation(int32_t node) const;
+	Quaternion world_rotation() const;
 
 	/// Returns the world pose of the unit.
-	Matrix4x4 world_pose(int32_t node) const;
+	Matrix4x4 world_pose() const;
 
 	/// Sets the local position of the unit.
-	void set_local_position(int32_t node, const Vector3& pos);
+	void set_local_position(const Vector3& pos);
 
 	/// Sets the local rotation of the unit.
-	void set_local_rotation(int32_t node, const Quaternion& rot);
+	void set_local_rotation(const Quaternion& rot);
 
-	/// Sets the local pose of the unit.
-	void set_local_pose(int32_t node, const Matrix4x4& pose);
-
-	/// Links the @a child node to the @a parent node.
-	/// After the linking the @a child pose is reset to identity.
-	/// @note The @a parent node must be either -1 (meaning no parent), or an index lesser than child.
-	void link_node(int32_t child, int32_t parent);
+	/// Sets the local scale of the unit.
+	void set_local_scale(const Vector3& scale);
 
-	/// Unlinks @a child from its parent, if any.
-	void unlink_node(int32_t child);
+	/// Sets the local pose of the unit.
+	void set_local_pose(const Matrix4x4& pose);
 
 	void update();
 	void reload(UnitResource* new_ur);

+ 12 - 16
engine/world/world.cpp

@@ -25,7 +25,7 @@ World::World(ResourceManager& rm, LuaEnvironment& env)
 	, _lua_environment(&env)
 	, m_unit_pool(default_allocator(), CE_MAX_UNITS, sizeof(Unit), CE_ALIGNOF(Unit))
 	, m_camera_pool(default_allocator(), CE_MAX_CAMERAS, sizeof(Camera), CE_ALIGNOF(Camera))
-	, _scenegraph_manager(NULL)
+	, _scene_graph(NULL)
 	, _sprite_animation_player(NULL)
 	, _render_world(NULL)
 	, _physics_world(NULL)
@@ -33,7 +33,7 @@ World::World(ResourceManager& rm, LuaEnvironment& env)
 	, _events(default_allocator())
 	, _lines(NULL)
 {
-	_scenegraph_manager = CE_NEW(default_allocator(), SceneGraphManager);
+	_scene_graph = CE_NEW(default_allocator(), SceneGraph)(default_allocator());
 	_sprite_animation_player = CE_NEW(default_allocator(), SpriteAnimationPlayer);
 	_render_world = CE_NEW(default_allocator(), RenderWorld);
 	_physics_world = CE_NEW(default_allocator(), PhysicsWorld)(*this);
@@ -54,14 +54,14 @@ World::~World()
 	CE_DELETE(default_allocator(), _physics_world);
 	CE_DELETE(default_allocator(), _render_world);
 	CE_DELETE(default_allocator(), _sprite_animation_player);
-	CE_DELETE(default_allocator(), _scenegraph_manager);
+	CE_DELETE(default_allocator(), _scene_graph);
 }
 
 UnitId World::spawn_unit(const UnitResource* ur, const Vector3& pos, const Quaternion& rot)
 {
 	Unit* u = (Unit*) m_unit_pool.allocate(sizeof(Unit), CE_ALIGNOF(Unit));
 	const UnitId unit_id = id_array::create(m_units, u);
-	new (u) Unit(*this, unit_id, ur, Matrix4x4(rot, pos));
+	new (u) Unit(*this, unit_id, ur, *_scene_graph, Matrix4x4(rot, pos));
 
 	post_unit_spawned_event(unit_id);
 	return unit_id;
@@ -104,14 +104,16 @@ void World::units(Array<UnitId>& units) const
 	}
 }
 
-void World::link_unit(UnitId child, UnitId parent, int32_t node)
+void World::link_unit(UnitId child, UnitId parent)
 {
-	Unit* parent_unit = get_unit(parent);
-	parent_unit->link_node(0, node);
+	TransformInstance child_ti = _scene_graph->get(child);
+	TransformInstance parent_ti = _scene_graph->get(parent);
+	_scene_graph->link(child_ti, parent_ti);
 }
 
-void World::unlink_unit(UnitId /*child*/)
+void World::unlink_unit(UnitId child)
 {
+	_scene_graph->unlink(_scene_graph->get(child));
 }
 
 Unit* World::get_unit(UnitId id)
@@ -132,7 +134,6 @@ void World::update_animations(float dt)
 void World::update_scene(float dt)
 {
 	_physics_world->update(dt);
-	_scenegraph_manager->update();
 
 	for (uint32_t i = 0; i < id_array::size(m_units); i++)
 	{
@@ -159,9 +160,9 @@ void World::render(Camera* camera)
 		_physics_world->draw_debug(*_lines);
 }
 
-CameraId World::create_camera(SceneGraph& sg, int32_t node, ProjectionType::Enum type, float near, float far)
+CameraId World::create_camera(SceneGraph& sg, UnitId id, ProjectionType::Enum type, float near, float far)
 {
-	Camera* camera = CE_NEW(m_camera_pool, Camera)(sg, node, type, near, far);
+	Camera* camera = CE_NEW(m_camera_pool, Camera)(sg, id, type, near, far);
 
 	return id_array::create(m_cameras, camera);
 }
@@ -264,11 +265,6 @@ void World::load_level(StringId64 name)
 	load_level(lr);
 }
 
-SceneGraphManager* World::scene_graph_manager()
-{
-	return _scenegraph_manager;
-}
-
 SpriteAnimationPlayer* World::sprite_animation_player()
 {
 	return _sprite_animation_player;

+ 3 - 5
engine/world/world.h

@@ -13,7 +13,6 @@
 #include "pool_allocator.h"
 #include "render_world.h"
 #include "render_world_types.h"
-#include "scene_graph_manager.h"
 #include "types.h"
 #include "unit.h"
 #include "vector.h"
@@ -58,7 +57,7 @@ public:
 
 	/// Links the unit @a child to the @a node of the unit @a parent.
 	/// After this call, @a child will follow the @a parent unit.
-	void link_unit(UnitId child, UnitId parent, int32_t node);
+	void link_unit(UnitId child, UnitId parent);
 
 	/// Unlinks the unit @a id from its parent if it has any.
 	void unlink_unit(UnitId id);
@@ -81,7 +80,7 @@ public:
 	/// Renders the world form the point of view of the given @a camera.
 	void render(Camera* camera);
 
-	CameraId create_camera(SceneGraph& sg, int32_t node, ProjectionType::Enum type, float near, float far);
+	CameraId create_camera(SceneGraph& sg, UnitId id, ProjectionType::Enum type, float near, float far);
 
 	/// Destroys the camera @a id.
 	void destroy_camera(CameraId id);
@@ -130,7 +129,6 @@ public:
 	void load_level(const LevelResource* lr);
 	void load_level(StringId64 name);
 
-	SceneGraphManager* scene_graph_manager();
 	SpriteAnimationPlayer* sprite_animation_player();
 
 	/// Returns the rendering sub-world.
@@ -160,7 +158,7 @@ private:
 	IdArray<CE_MAX_UNITS, Unit*> m_units;
 	IdArray<CE_MAX_CAMERAS, Camera*> m_cameras;
 
-	SceneGraphManager* _scenegraph_manager;
+	SceneGraph* _scene_graph;
 	SpriteAnimationPlayer* _sprite_animation_player;
 	RenderWorld* _render_world;
 	PhysicsWorld* _physics_world;