Sfoglia il codice sorgente

Add highly experimental SceneGraph, Unit and World classes

Daniele Bartolini 12 anni fa
parent
commit
747a087fc9

+ 192 - 0
engine/SceneGraph.cpp

@@ -0,0 +1,192 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "SceneGraph.h"
+#include "Device.h"
+#include "DebugRenderer.h"
+#include "Quat.h"
+
+namespace crown
+{
+
+//-----------------------------------------------------------------------------
+SceneGraph::SceneGraph() :
+	m_nodes(m_allocator, MAX_NODES),
+	m_world_poses(m_allocator),
+	m_local_poses(m_allocator),
+	m_parents(m_allocator)
+{
+}
+
+//-----------------------------------------------------------------------------
+NodeId SceneGraph::create_node(const Vec3& pos, const Quat& rot)
+{
+	const NodeId node = m_nodes.create();
+
+	Mat4 pose(rot, pos);
+
+	if (m_world_poses.size() <= node.index)
+	{
+		m_world_poses.push_back(pose);
+		m_local_poses.push_back(pose);
+		m_parents.push_back(-1);
+		m_sparse_to_packed[node.index] = m_world_poses.size() - 1;
+	}
+	else
+	{
+		m_world_poses[node.index] = pose;
+		m_local_poses[node.index] = pose;
+		m_parents[node.index] = -1;
+		m_sparse_to_packed[node.index] = node.index;
+	}
+
+	return node;
+}
+
+//-----------------------------------------------------------------------------
+void SceneGraph::destroy_node(NodeId id)
+{
+	(void)id;
+}
+
+//-----------------------------------------------------------------------------
+void SceneGraph::link(NodeId child, NodeId parent)
+{
+	CE_ASSERT(m_nodes.has(child), "Child node does not exist");
+	CE_ASSERT(m_nodes.has(parent), "Parent node does not exist");
+
+	m_parents[m_sparse_to_packed[child.index]] = m_sparse_to_packed[parent.index];
+}
+
+//-----------------------------------------------------------------------------
+void SceneGraph::unlink(NodeId child)
+{
+	CE_ASSERT(m_nodes.has(child), "Node does not exist");
+
+	m_local_poses[m_sparse_to_packed[child.index]] = m_world_poses[m_sparse_to_packed[child.index]];
+	m_parents[m_sparse_to_packed[child.index]] = -1;
+}
+
+//-----------------------------------------------------------------------------
+void SceneGraph::set_local_position(NodeId node, const Vec3& pos)
+{
+	CE_ASSERT(m_nodes.has(node), "Node does not exist");
+
+	Mat4& local_pose = m_local_poses[m_sparse_to_packed[node.index]];
+	local_pose.set_translation(pos);
+}
+
+//-----------------------------------------------------------------------------
+void SceneGraph::set_local_rotation(NodeId node, const Quat& rot)
+{
+	CE_ASSERT(m_nodes.has(node), "Node does not exist");
+
+	Mat4& local_pose = m_local_poses[m_sparse_to_packed[node.index]];
+
+	Vec3 local_translation = local_pose.translation();
+	local_pose = rot.to_mat4();
+	local_pose.set_translation(local_translation);
+}
+
+//-----------------------------------------------------------------------------
+void SceneGraph::set_local_pose(NodeId node, const Mat4& pose)
+{
+	CE_ASSERT(m_nodes.has(node), "Node does not exist");
+
+	m_local_poses[m_sparse_to_packed[node.index]] = pose;
+}
+
+//-----------------------------------------------------------------------------
+Vec3 SceneGraph::local_position(NodeId node) const
+{
+	CE_ASSERT(m_nodes.has(node), "Node does not exist");
+
+	return m_local_poses[m_sparse_to_packed[node.index]].translation();
+}
+
+//-----------------------------------------------------------------------------
+Quat SceneGraph::local_rotation(NodeId node) const
+{
+	CE_ASSERT(m_nodes.has(node), "Node does not exist");
+
+	return Quat(Vec3(1, 0, 0), 0.0f);
+}
+
+//-----------------------------------------------------------------------------
+Mat4 SceneGraph::local_pose(NodeId node) const
+{
+	CE_ASSERT(m_nodes.has(node), "Node does not exist");
+
+	return m_local_poses[m_sparse_to_packed[node.index]];
+}
+
+//-----------------------------------------------------------------------------
+Vec3 SceneGraph::world_position(NodeId node) const
+{
+	CE_ASSERT(m_nodes.has(node), "Node does not exist");
+
+	return m_world_poses[m_sparse_to_packed[node.index]].translation();
+}
+
+//-----------------------------------------------------------------------------
+Quat SceneGraph::world_rotation(NodeId node) const
+{
+	CE_ASSERT(m_nodes.has(node), "Node does not exist");
+
+	return Quat(Vec3(1, 0, 0), 0.0f);
+}
+
+//-----------------------------------------------------------------------------
+Mat4 SceneGraph::world_pose(NodeId node) const
+{
+	CE_ASSERT(m_nodes.has(node), "Node does not exist");
+
+	return m_world_poses[m_sparse_to_packed[node.index]];
+}
+
+//-----------------------------------------------------------------------------
+void SceneGraph::update()
+{
+	for (uint32_t i = 0; i < m_world_poses.size(); i++)
+	{
+		if (m_parents[i] == -1)
+		{
+			m_world_poses[i] = m_local_poses[i];
+		}
+		else
+		{
+			m_world_poses[i] = m_local_poses[m_parents[i]] * m_local_poses[i];
+		}
+	}
+
+	// Draw debug
+	for (uint32_t i = 0; i < m_world_poses.size(); i++)
+	{
+		device()->debug_renderer()->add_pose(m_world_poses[i], true);
+	}
+}
+
+} // namespace crown

+ 83 - 0
engine/SceneGraph.h

@@ -0,0 +1,83 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#pragma once
+
+#include "Types.h"
+#include "Mat4.h"
+#include "List.h"
+#include "IdTable.h"
+#include "HeapAllocator.h"
+
+namespace crown
+{
+
+#define MAX_NODES 1024
+typedef Id NodeId;
+
+class SceneGraph
+{
+public:
+
+					SceneGraph();
+
+	NodeId			create_node(const Vec3& pos, const Quat& rot);
+	void			destroy_node(NodeId id);
+
+	void			link(NodeId child, NodeId parent);
+	void			unlink(NodeId child);
+
+	void			set_local_position(NodeId node, const Vec3& pos);
+	void			set_local_rotation(NodeId node, const Quat& rot);
+	void			set_local_pose(NodeId node, const Mat4& pose);
+
+	Vec3			local_position(NodeId node) const;
+	Quat			local_rotation(NodeId node) const;
+	Mat4			local_pose(NodeId node) const;
+
+	Vec3			world_position(NodeId node) const;
+	Quat			world_rotation(NodeId node) const;
+	Mat4			world_pose(NodeId node) const;
+
+	void			update();
+
+private:
+
+	HeapAllocator	m_allocator;
+
+	// Sparse table of nodes
+	IdTable			m_nodes;
+
+	// Conversion from sparse table to packed array
+	uint32_t		m_sparse_to_packed[MAX_NODES];
+
+	// Packed arrays of transforms
+	List<Mat4>		m_world_poses;
+	List<Mat4>		m_local_poses;
+	List<int32_t>	m_parents;
+};
+
+} // namespace crown

+ 93 - 0
engine/Unit.cpp

@@ -0,0 +1,93 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "Unit.h"
+
+namespace crown
+{
+
+//-----------------------------------------------------------------------------
+Unit::Unit(SceneGraph& sg, const Vec3& pos, const Quat& rot) :
+	m_scene_graph(sg)
+{
+	m_root_node = m_scene_graph.create_node(pos, rot);
+}
+
+//-----------------------------------------------------------------------------
+Vec3 Unit::local_position() const
+{
+	return m_scene_graph.local_position(m_root_node);
+}
+
+//-----------------------------------------------------------------------------
+Quat Unit::local_rotation() const
+{
+	return m_scene_graph.local_rotation(m_root_node);
+}
+
+//-----------------------------------------------------------------------------
+Mat4 Unit::local_pose() const
+{
+	return m_scene_graph.local_pose(m_root_node);
+}
+
+//-----------------------------------------------------------------------------
+Vec3 Unit::world_position() const
+{
+	return m_scene_graph.world_position(m_root_node);
+}
+
+//-----------------------------------------------------------------------------
+Quat Unit::world_rotation() const
+{
+	return m_scene_graph.world_rotation(m_root_node);
+}
+
+//-----------------------------------------------------------------------------
+Mat4 Unit::world_pose() const
+{
+	return m_scene_graph.world_pose(m_root_node);
+}
+
+//-----------------------------------------------------------------------------
+void Unit::set_local_position(const Vec3& pos)
+{
+	m_scene_graph.set_local_position(m_root_node, pos);
+}
+
+//-----------------------------------------------------------------------------
+void Unit::set_local_rotation(const Quat& rot)
+{
+	m_scene_graph.set_local_rotation(m_root_node, rot);
+}
+
+//-----------------------------------------------------------------------------
+void Unit::set_local_pose(const Mat4& pose)
+{
+	m_scene_graph.set_local_pose(m_root_node, pose);
+}
+
+} // namespace crown

+ 70 - 0
engine/Unit.h

@@ -0,0 +1,70 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#pragma once
+
+#include "Vec3.h"
+#include "Quat.h"
+#include "Mat4.h"
+#include "SceneGraph.h"
+#include "IdTable.h"
+
+namespace crown
+{
+
+typedef Id UnitId;
+
+class Camera;
+
+class Unit
+{
+public:
+
+					Unit(SceneGraph& sg, const Vec3& pos, const Quat& rot);
+
+	Vec3			local_position() const;
+	Quat			local_rotation() const;
+	Mat4			local_pose() const;
+
+	Vec3			world_position() const;
+	Quat			world_rotation() const;
+	Mat4			world_pose() const;
+
+	void			set_local_position(const Vec3& pos);
+	void			set_local_rotation(const Quat& rot);
+	void			set_local_pose(const Mat4& pose);
+
+private:
+
+	SceneGraph&		m_scene_graph;
+	NodeId			m_root_node;
+
+private:
+
+	friend class	World;
+};
+
+} // namespace crown

+ 92 - 0
engine/World.cpp

@@ -0,0 +1,92 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "Assert.h"
+#include "World.h"
+
+namespace crown
+{
+
+//-----------------------------------------------------------------------------
+World::World() :
+	m_unit_table(m_allocator, MAX_UNITS)
+{
+}
+
+//-----------------------------------------------------------------------------
+UnitId World::spawn_unit(const char* /*name*/, const Vec3& pos, const Quat& rot)
+{
+	const UnitId unit = m_unit_table.create();
+
+	m_units[unit.index] = CE_NEW(m_allocator, Unit)(m_scene_graph, pos, rot);
+
+	return unit;
+}
+
+//-----------------------------------------------------------------------------
+void World::kill_unit(UnitId unit)
+{
+	CE_ASSERT(m_unit_table.has(unit), "Unit does not exist");
+	(void)unit;
+}
+
+//-----------------------------------------------------------------------------
+void World::link_unit(UnitId child, UnitId parent)
+{
+	CE_ASSERT(m_unit_table.has(child), "Child unit does not exist");
+	CE_ASSERT(m_unit_table.has(parent), "Parent unit does not exist");
+
+	Unit* child_unit = unit(child);
+	Unit* parent_unit = unit(parent);
+
+	m_scene_graph.link(child_unit->m_root_node, parent_unit->m_root_node);
+}
+
+//-----------------------------------------------------------------------------
+void World::unlink_unit(UnitId child)
+{
+	CE_ASSERT(m_unit_table.has(child), "Node does not exist");
+
+	Unit* child_unit = unit(child);
+
+	m_scene_graph.unlink(child_unit->m_root_node);
+}
+
+//-----------------------------------------------------------------------------
+Unit* World::unit(UnitId unit)
+{
+	CE_ASSERT(m_unit_table.has(unit), "Unit does not exist");
+
+	return m_units[unit.index];
+}
+
+//-----------------------------------------------------------------------------
+void World::update(float dt)
+{
+	m_scene_graph.update();
+}
+
+} // namespace crown

+ 69 - 0
engine/World.h

@@ -0,0 +1,69 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#pragma once
+
+#include "SceneGraph.h"
+#include "HeapAllocator.h"
+#include "IdTable.h"
+#include "Unit.h"
+
+namespace crown
+{
+
+#define MAX_CAMERAS 32
+#define MAX_UNITS 1024
+
+class Vec3;
+class Quat;
+
+class World
+{
+public:
+	
+					World();
+
+	UnitId			spawn_unit(const char* name, const Vec3& pos = Vec3::ZERO, const Quat& rot = Quat(Vec3(0, 1, 0), 0.0f));
+	void			kill_unit(UnitId unit);
+
+	void			link_unit(UnitId child, UnitId parent);
+	void			unlink_unit(UnitId child);
+
+	Unit*			unit(UnitId unit);
+
+	void			update(float dt);
+
+private:
+
+	HeapAllocator	m_allocator;
+
+	SceneGraph		m_scene_graph;
+
+	IdTable			m_unit_table;
+	Unit*			m_units[MAX_UNITS];
+};
+
+} // namespace crown

+ 3 - 0
engine/lua/LuaEnvironment.cpp

@@ -248,6 +248,9 @@ CE_EXPORT int32_t luaopen_libcrown(lua_State* /*L*/)
 
 	load_window(*env);
 
+	load_unit(*env);
+	load_world(*env);
+
 	return 1;
 }
 

+ 4 - 1
engine/lua/LuaEnvironment.h

@@ -130,10 +130,13 @@ void load_mouse(LuaEnvironment& env);
 void load_keyboard(LuaEnvironment& env);
 void load_touch(LuaEnvironment& env);
 void load_accelerometer(LuaEnvironment& env);
-void load_camera(LuaEnvironment& env);
 void load_device(LuaEnvironment& env);
 void load_window(LuaEnvironment& env);
 
+void load_unit(LuaEnvironment& env);
+void load_camera(LuaEnvironment& env);
+void load_world(LuaEnvironment& env);
+
 CE_EXPORT int32_t luaopen_libcrown(lua_State* L);
 
 } // namespace crown

+ 15 - 0
engine/lua/LuaStack.cpp

@@ -30,6 +30,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Vec3.h"
 #include "Mat4.h"
 #include "Quat.h"
+#include "Unit.h"
 
 namespace crown
 {
@@ -172,6 +173,12 @@ void LuaStack::push_quat(const Quat& q)
 	lua_pushlightuserdata(m_state, next_quat(q));
 }
 
+//-----------------------------------------------------------------------------
+void LuaStack::push_unit(Unit* unit)
+{
+	lua_pushlightuserdata(m_state, unit);
+}
+
 //-----------------------------------------------------------------------------
 bool LuaStack::get_bool(int32_t index)
 {
@@ -266,4 +273,12 @@ Quat& LuaStack::get_quat(int32_t index)
 	return *q;
 }
 
+//-----------------------------------------------------------------------------
+Unit* LuaStack::get_unit(int32_t index)
+{
+	Unit* u = (Unit*)lua_touserdata(m_state, index);
+
+	return u;
+}
+
 } // namespace crown

+ 5 - 14
engine/lua/LuaStack.h

@@ -36,6 +36,7 @@ class Vec2;
 class Vec3;
 class Mat4;
 class Quat;
+class Unit;
 
 class LuaStack
 {
@@ -51,37 +52,25 @@ public:
 	int32_t					num_args();
 
 	void					push_bool(bool value);
-
 	void					push_int32(int32_t value);
-
 	void					push_uint32(uint32_t value);
-
 	void					push_int64(int64_t value);
-
 	void					push_uint64(uint64_t value);
-
 	void 					push_float(float value);
-
 	void 					push_string(const char* str, size_t len);
-
 	void					push_lightdata(void* data);
 
 	void					push_vec2(const Vec2& v);
-
 	void					push_vec3(const Vec3& v);
-
 	void					push_mat4(const Mat4& m);
-
 	void					push_quat(const Quat& q);
 
-	bool 					get_bool(int32_t index);
+	void					push_unit(Unit* unit);
 
+	bool 					get_bool(int32_t index);
 	int32_t					get_int(int32_t index);
-
 	float 					get_float(int32_t index);
-
 	const char*				get_string(int32_t index);
-
 	void*					get_lightdata(int32_t index);
 
 	Vec2&					get_vec2(int32_t index);
@@ -89,6 +78,8 @@ public:
 	Mat4&					get_mat4(int32_t index);
 	Quat&					get_quat(int32_t index);
 
+	Unit*					get_unit(int32_t index);
+
 private:
 
 	lua_State* 				m_state;

+ 159 - 0
engine/lua/LuaUnit.cpp

@@ -0,0 +1,159 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "LuaStack.h"
+#include "LuaEnvironment.h"
+#include "Unit.h"
+
+namespace crown
+{
+
+//-----------------------------------------------------------------------------
+CE_EXPORT int32_t unit_local_position(lua_State* L)
+{
+	LuaStack stack(L);
+
+	Unit* unit = stack.get_unit(1);
+
+	stack.push_vec3(unit->local_position());
+
+	return 1;
+}
+
+//-----------------------------------------------------------------------------
+CE_EXPORT int32_t unit_local_rotation(lua_State* L)
+{
+	LuaStack stack(L);
+
+	Unit* unit = stack.get_unit(1);
+
+	stack.push_quat(unit->local_rotation());
+
+	return 1;
+}
+
+//-----------------------------------------------------------------------------
+CE_EXPORT int32_t unit_local_pose(lua_State* L)
+{
+	LuaStack stack(L);
+
+	Unit* unit = stack.get_unit(1);
+
+	stack.push_mat4(unit->local_pose());
+
+	return 1;
+}
+
+//-----------------------------------------------------------------------------
+CE_EXPORT int32_t unit_world_position(lua_State* L)
+{
+	LuaStack stack(L);
+
+	Unit* unit = stack.get_unit(1);
+
+	stack.push_vec3(unit->world_position());
+
+	return 1;
+}
+
+//-----------------------------------------------------------------------------
+CE_EXPORT int32_t unit_world_rotation(lua_State* L)
+{
+	LuaStack stack(L);
+
+	Unit* unit = stack.get_unit(1);
+
+	stack.push_quat(unit->world_rotation());
+
+	return 1;
+}
+
+//-----------------------------------------------------------------------------
+CE_EXPORT int32_t unit_world_pose(lua_State* L)
+{
+	LuaStack stack(L);
+
+	Unit* unit = stack.get_unit(1);
+
+	stack.push_mat4(unit->world_pose());
+
+	return 1;
+}
+
+//-----------------------------------------------------------------------------
+CE_EXPORT int32_t unit_set_local_position(lua_State* L)
+{
+	LuaStack stack(L);
+
+	Unit* unit = stack.get_unit(1);
+	Vec3& pos = stack.get_vec3(2);
+
+	unit->set_local_position(pos);
+
+	return 0;
+}
+
+//-----------------------------------------------------------------------------
+CE_EXPORT int32_t unit_set_local_rotation(lua_State* L)
+{
+	LuaStack stack(L);
+
+	Unit* unit = stack.get_unit(1);
+	Quat& rot = stack.get_quat(2);
+
+	unit->set_local_rotation(rot);
+
+	return 0;
+}
+
+//-----------------------------------------------------------------------------
+CE_EXPORT int32_t unit_set_local_pose(lua_State* L)
+{
+	LuaStack stack(L);
+
+	Unit* unit = stack.get_unit(1);
+	Mat4& pose = stack.get_mat4(2);
+
+	unit->set_local_pose(pose);
+
+	return 0;
+}
+
+//-----------------------------------------------------------------------------
+void load_unit(LuaEnvironment& env)
+{
+	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_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_local_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_pose",			unit_set_local_pose);
+}
+
+} // namespace crown