Prechádzať zdrojové kódy

Refactor Camera and LuaCamera, add factory methods to World and temporaty accessor for camera in Unit and LuaUnit

Daniele Bartolini 12 rokov pred
rodič
commit
b7987f1a16

+ 1 - 0
engine/CMakeLists.txt

@@ -337,6 +337,7 @@ set (LUA_SRC
 	lua/LuaResourcePackage.cpp
 	lua/LuaWorld.cpp
 	lua/LuaUnit.cpp
+	lua/LuaCamera.cpp
 	lua/LuaSound.cpp
 )
 

+ 69 - 109
engine/Camera.cpp

@@ -27,83 +27,84 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Camera.h"
 #include "Types.h"
 #include "MathUtils.h"
+#include "Quat.h"
+#include "Unit.h"
+#include "Assert.h"
 
 namespace crown
 {
 
-//-----------------------------------------------------------------------------
-Camera::Camera(const Vec3& position, float fov, float aspect) :
-	m_position(position),
-	m_look_at(0, 0, -1),
-	m_up(0, 1, 0),
-
-	m_rot_factor(0.0f, 0.0f),
-	m_angle_x(0.0f),
-	m_angle_y(0.0f),
-
-	m_FOV(fov),
-	m_aspect(aspect),
-	m_near(0.1f),
-	m_far(1000.0f)
+//-----------------------------------------------------------------------
+void Camera::create(Unit& parent, int32_t node)
 {
-	update_projection_matrix();
-	update_view_matrix();
-	update_frustum();
+	m_parent = &parent;
+	m_node = node;
 }
 
-//-----------------------------------------------------------------------------
-const Vec3& Camera::position() const
+//-----------------------------------------------------------------------
+Vec3 Camera::local_position() const
 {
-	return m_position;
+	return m_parent->local_position(m_node);
 }
 
-//-----------------------------------------------------------------------------
-void Camera::set_position(const Vec3& position)
+//-----------------------------------------------------------------------
+Quat Camera::local_rotation() const
 {
-	m_position = position;
-
-	update_view_matrix();
+	return m_parent->local_rotation(m_node);
 }
 
-//-----------------------------------------------------------------------------
-const Vec3& Camera::look_at() const
+//-----------------------------------------------------------------------
+Mat4 Camera::local_pose() const
 {
-	return m_look_at;
+	return m_parent->local_pose(m_node);
 }
 
-//-----------------------------------------------------------------------------
-void Camera::set_look_at(const Vec3& lookat)
+//-----------------------------------------------------------------------
+Vec3 Camera::world_position() const
 {
-	m_look_at = lookat;
+	return m_parent->world_position(m_node);
+}
 
-	update_view_matrix();
+//-----------------------------------------------------------------------
+Quat Camera::world_rotation() const
+{
+	return m_parent->world_rotation(m_node);
 }
 
 //-----------------------------------------------------------------------
-void Camera::set_rotation(const float x, const float y)
+Mat4 Camera::world_pose() const
 {
-	Vec3 right(1, 0, 0);
-	Vec3 look;
+	return m_parent->world_pose(m_node);
+}
 
-	look.x = 0.0f;
-	look.y = math::sin(x);
-	look.z = -math::cos(x);
+//-----------------------------------------------------------------------
+void Camera::set_local_position(const Vec3& pos)
+{
+	m_parent->set_local_position(pos, m_node);
+}
 
-	Vec3 up = right.cross(look);
-	up.normalize();
+//-----------------------------------------------------------------------
+void Camera::set_local_rotation(const Quat& rot)
+{
+	m_parent->set_local_rotation(rot, m_node);
+}
 
-	Mat3 m;
-	m.build_rotation_y(y);
-	look = m * look;
-	m_up = m * up;
+//-----------------------------------------------------------------------
+void Camera::set_local_pose(const Mat4& pose)
+{
+	m_parent->set_local_pose(pose, m_node);
+}
 
-	set_look_at(look);
+//-----------------------------------------------------------------------
+void Camera::set_projection_type(ProjectionType::Enum type)
+{
+	m_projection_type = type;
 }
 
-//-----------------------------------------------------------------------------
-const Vec3& Camera::up() const
+//-----------------------------------------------------------------------
+ProjectionType::Enum Camera::projection_type() const
 {
-	return m_up;
+	return m_projection_type;
 }
 
 //-----------------------------------------------------------------------------
@@ -116,7 +117,6 @@ float Camera::fov() const
 void Camera::set_fov(float fov)
 {
 	m_FOV = fov;
-
 	update_projection_matrix();
 }
 
@@ -130,7 +130,6 @@ float Camera::aspect() const
 void Camera::set_aspect(float aspect)
 {
 	m_aspect = aspect;
-
 	update_projection_matrix();
 }
 
@@ -144,7 +143,6 @@ float Camera::near_clip_distance() const
 void Camera::set_near_clip_distance(float near)
 {
 	m_near = near;
-
 	update_projection_matrix();
 }
 
@@ -158,75 +156,37 @@ float Camera::far_clip_distance() const
 void Camera::set_far_clip_distance(float far)
 {
 	m_far = far;
-
 	update_projection_matrix();
 }
 
-//-----------------------------------------------------------------------------
-const Mat4& Camera::projection_matrix() const
-{
-	return m_projection;
-}
-
-//-----------------------------------------------------------------------------
-const Mat4& Camera::view_matrix() const
-{
-	return m_view;
-}
-
-//-----------------------------------------------------------------------------
-const Frustum& Camera::frustum() const
-{
-	return m_frustum;
-}
-
 //-----------------------------------------------------------------------------
 void Camera::update_projection_matrix()
 {
-	m_projection.build_projection_perspective_rh(m_FOV, m_aspect, m_near, m_far);
-}
-
-//-----------------------------------------------------------------------------
-void Camera::update_view_matrix()
-{
-	m_view.build_look_at_rh(m_position, m_position + m_look_at, m_up);
+	switch (m_projection_type)
+	{
+		case ProjectionType::ORTHOGRAPHIC:
+		{
+			CE_FATAL("TODO");
+			break;
+		}
+		case ProjectionType::PERSPECTIVE:
+		{
+			m_projection.build_projection_perspective_rh(m_FOV, m_aspect, m_near, m_far);
+			break;
+		}
+		default:
+		{
+			CE_FATAL("Oops, unknown projection type");
+			break;
+		}
+	}
 }
 
 //-----------------------------------------------------------------------------
 void Camera::update_frustum()
 {
-	m_frustum.from_matrix(m_projection * m_view);
-}
-
-//-----------------------------------------------------------------------------
-void Camera::move_forward(float meters)
-{
-	set_position(m_position + m_look_at * meters);
-}
-
-//-----------------------------------------------------------------------
-void Camera::move_backward(float meters)
-{
-	set_position(m_position + m_look_at * -meters);
-}
-
-//-----------------------------------------------------------------------
-void Camera::strafe_left(float meters)
-{
-	Vec3 left = m_up.cross(m_look_at);
-	left.normalize();
-
-	set_position(m_position + left * meters);
-}
-
-//-----------------------------------------------------------------------
-void Camera::strafe_right(float meters)
-{
-	Vec3 left = m_up.cross(m_look_at);
-	left.normalize();
-
-	set_position(m_position + left * -meters);
+	// TODO
+	//m_frustum.from_matrix(m_projection * m_view);
 }
 
 } // namespace crown
-

+ 35 - 70
engine/Camera.h

@@ -35,102 +35,67 @@ OTHER DEALINGS IN THE SOFTWARE.
 namespace crown
 {
 
-/// Represents the point of view into the game world.
-class Camera
+struct ProjectionType
 {
-public:
-
-	/// Construct the camera placed at the given world-space @a position
-	/// with the given @a fov field of view and @a aspect ratio.
-					Camera(const Vec3& position, float fov, float aspect);
+	enum Enum
+	{
+		ORTHOGRAPHIC,
+		PERSPECTIVE
+	};
+};
 
-	/// Returns the world-space position of the camera 
-	const Vec3&		position() const;
+class Quat;
+class Unit;
 
-	/// Sets the world-space @a position of the camera
-	void			set_position(const Vec3& position);
+/// Represents the point of view into the game world.
+struct Camera
+{
+	void			create(Unit& parent, int32_t node);
 
-	/// Returns the lookat-point of the camera
-	const Vec3&		look_at() const;
+	Vec3			local_position() const;
+	Quat			local_rotation() const;
+	Mat4			local_pose() const;
 
-	/// Sets the lookat-point of the camera
-	void			set_look_at(const Vec3& lookat);
+	Vec3			world_position() const;
+	Quat			world_rotation() const;
+	Mat4			world_pose() const;
 
-	/// Sets the rotation of the camera about the world's @a x axis and @a y axis
-	void			set_rotation(const float x, const float y);
+	void			set_local_position(const Vec3& pos);
+	void			set_local_rotation(const Quat& rot);
+	void			set_local_pose(const Mat4& pose);
 
-	/// Returns the up-vector of the camera
-	const Vec3&		up() const;
+	void			set_projection_type(ProjectionType::Enum type);
+	ProjectionType::Enum projection_type() const;
 
-	/// Returns the field of view of the camera in degrees
 	float			fov() const;
-
-	/// Sets the field of view of the camera
 	void			set_fov(float fov);
 
-	/// Returns the aspect ratio of the camera
 	float			aspect() const;
-
-	/// Sets the aspect ration of the camera
 	void			set_aspect(float aspect);
 
-	/// Returns the near clipping distance of the camera
 	float			near_clip_distance() const;
-
-	/// Sets the near clipping distance of the camera
 	void			set_near_clip_distance(float near);
-
-	/// Returns the far clipping distance of the camera
 	float			far_clip_distance() const;
-
-	/// Sets the far clipping distance of the camera
 	void			set_far_clip_distance(float far);
 
-	/// Returns the view-frustum of the camera
-	const Frustum&	frustum() const;
-
-	/// Returns the renderer-independent projection matrix used by the camera
-	const Mat4&		projection_matrix() const;
-
-	/// Returns the renderer-independent view matrix used by the camera
-	const Mat4&		view_matrix() const;
-
-	/// Moves the camera towards look direction by @a meters meters
-	void			move_forward(float meters);
-
-	/// Moves the camera towards the opposite look direction by @a meters meters
-	void			move_backward(float meters);
-
-	/// Moves the camera along the axis perpendicular to the look direction by @a meters meters
-	void			strafe_left(float meters);
-
-	/// Moves the camera along the axis perpendicular to the look direction by @a meters meters
-	void			strafe_right(float meters);
-
-protected:
+private:
 
 	void			update_projection_matrix();
-	void			update_view_matrix();
 	void			update_frustum();
 
-	Vec3			m_position;
-	Vec3			m_look_at;
-	Vec3			m_up;
-
-	Vec2			m_rot_factor;
-	float			m_angle_x;
-	float			m_angle_y;
-
-	Mat4			m_view;
-	Mat4			m_projection;
+private:
 
-	Frustum			m_frustum;
+	Unit*					m_parent;
+	int32_t					m_node;
 
-	float			m_FOV;
-	float			m_aspect;
+	ProjectionType::Enum	m_projection_type;
+	Mat4					m_projection;
 
-	float			m_near;
-	float			m_far;
+	Frustum					m_frustum;
+	float					m_FOV;
+	float					m_aspect;
+	float					m_near;
+	float					m_far;
 };
 
 } // namespace crown

+ 35 - 20
engine/Unit.cpp

@@ -25,14 +25,23 @@ OTHER DEALINGS IN THE SOFTWARE.
 */
 
 #include "Unit.h"
+#include "IdTable.h"
+#include "World.h"
 
 namespace crown
 {
 
+typedef Id CameraId;
+
 //-----------------------------------------------------------------------------
-void Unit::create(const Vec3& pos, const Quat& rot)
+void Unit::create(World& creator, const Vec3& pos, const Quat& rot)
 {
-	m_root_node = m_scene_graph.create_node(pos, rot);
+	m_creator = &creator;
+	m_root_node = m_scene_graph.create_node(-1, pos, rot);
+
+	int32_t camera_node = m_scene_graph.create_node(m_root_node, Vec3::ZERO, Quat::IDENTITY);
+	CameraId camera = m_creator->create_camera(*this, camera_node);
+	m_camera = m_creator->lookup_camera(camera);
 }
 
 //-----------------------------------------------------------------------------
@@ -59,57 +68,63 @@ void Unit::reload(UnitResource* new_ur)
 }
 
 //-----------------------------------------------------------------------------
-Vec3 Unit::local_position() const
+Vec3 Unit::local_position(int32_t node) const
+{
+	return m_scene_graph.local_position(node);
+}
+
+//-----------------------------------------------------------------------------
+Quat Unit::local_rotation(int32_t node) const
 {
-	return m_scene_graph.local_position(m_root_node);
+	return m_scene_graph.local_rotation(node);
 }
 
 //-----------------------------------------------------------------------------
-Quat Unit::local_rotation() const
+Mat4 Unit::local_pose(int32_t node) const
 {
-	return m_scene_graph.local_rotation(m_root_node);
+	return m_scene_graph.local_pose(node);
 }
 
 //-----------------------------------------------------------------------------
-Mat4 Unit::local_pose() const
+Vec3 Unit::world_position(int32_t node) const
 {
-	return m_scene_graph.local_pose(m_root_node);
+	return m_scene_graph.world_position(node);
 }
 
 //-----------------------------------------------------------------------------
-Vec3 Unit::world_position() const
+Quat Unit::world_rotation(int32_t node) const
 {
-	return m_scene_graph.world_position(m_root_node);
+	return m_scene_graph.world_rotation(node);
 }
 
 //-----------------------------------------------------------------------------
-Quat Unit::world_rotation() const
+Mat4 Unit::world_pose(int32_t node) const
 {
-	return m_scene_graph.world_rotation(m_root_node);
+	return m_scene_graph.world_pose(node);
 }
 
 //-----------------------------------------------------------------------------
-Mat4 Unit::world_pose() const
+void Unit::set_local_position(const Vec3& pos, int32_t node)
 {
-	return m_scene_graph.world_pose(m_root_node);
+	m_scene_graph.set_local_position(node, pos);
 }
 
 //-----------------------------------------------------------------------------
-void Unit::set_local_position(const Vec3& pos)
+void Unit::set_local_rotation(const Quat& rot, int32_t node)
 {
-	m_scene_graph.set_local_position(m_root_node, pos);
+	m_scene_graph.set_local_rotation(node, rot);
 }
 
 //-----------------------------------------------------------------------------
-void Unit::set_local_rotation(const Quat& rot)
+void Unit::set_local_pose(const Mat4& pose, int32_t node)
 {
-	m_scene_graph.set_local_rotation(m_root_node, rot);
+	m_scene_graph.set_local_pose(node, pose);
 }
 
 //-----------------------------------------------------------------------------
-void Unit::set_local_pose(const Mat4& pose)
+Camera* Unit::camera(const char* /*name*/)
 {
-	m_scene_graph.set_local_pose(m_root_node, pose);
+	return m_camera;
 }
 
 } // namespace crown

+ 17 - 14
engine/Unit.h

@@ -30,7 +30,6 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Quat.h"
 #include "Mat4.h"
 #include "SceneGraph.h"
-#include "IdTable.h"
 
 namespace crown
 {
@@ -39,35 +38,39 @@ struct UnitResource
 {
 };
 
-typedef Id UnitId;
-
 class Camera;
+class World;
 
 struct Unit
 {
-	void			create(const Vec3& pos, const Quat& rot);
+	void			create(World& creator, const Vec3& pos, const Quat& rot);
 	void			destroy();
 
 	void			load(UnitResource* ur);
 	void			unload();
 	void			reload(UnitResource* new_ur);
 
-	Vec3			local_position() const;
-	Quat			local_rotation() const;
-	Mat4			local_pose() const;
+	Vec3			local_position(int32_t node = 0) const;
+	Quat			local_rotation(int32_t node = 0) const;
+	Mat4			local_pose(int32_t node = 0) const;
+
+	Vec3			world_position(int32_t node = 0) const;
+	Quat			world_rotation(int32_t node = 0) const;
+	Mat4			world_pose(int32_t node = 0) const;
 
-	Vec3			world_position() const;
-	Quat			world_rotation() const;
-	Mat4			world_pose() const;
+	void			set_local_position(const Vec3& pos, int32_t node = 0);
+	void			set_local_rotation(const Quat& rot, int32_t node = 0);
+	void			set_local_pose(const Mat4& pose, int32_t node = 0);
 
-	void			set_local_position(const Vec3& pos);
-	void			set_local_rotation(const Quat& rot);
-	void			set_local_pose(const Mat4& pose);
+	Camera*			camera(const char* name);
 
 public:
 
+	World*			m_creator;
 	SceneGraph		m_scene_graph;
-	NodeId			m_root_node;
+	int32_t			m_root_node;
+
+	Camera*			m_camera;
 
 	UnitResource*	m_resource;
 };

+ 25 - 2
engine/World.cpp

@@ -54,7 +54,7 @@ UnitId World::spawn_unit(const char* /*name*/, const Vec3& pos, const Quat& rot)
 {
 	const UnitId unit = m_unit_table.create();
 
-	m_units[unit.index].create(pos, rot);
+	m_units[unit.index].create(*this, pos, rot);
 
 	// m_units[unit.index].load(ur);
 
@@ -93,13 +93,21 @@ void World::unlink_unit(UnitId child, UnitId parent)
 }
 
 //-----------------------------------------------------------------------------
-Unit* World::unit(UnitId unit)
+Unit* World::lookup_unit(UnitId unit)
 {
 	CE_ASSERT(m_unit_table.has(unit), "Unit does not exist");
 
 	return &m_units[unit.index];
 }
 
+//-----------------------------------------------------------------------------
+Camera* World::lookup_camera(CameraId camera)
+{
+	CE_ASSERT(m_camera_table.has(camera), "Camera does not exist");
+
+	return &m_camera[camera.index];
+}
+
 //-----------------------------------------------------------------------------
 void World::update(float /*dt*/)
 {
@@ -111,5 +119,20 @@ SoundWorld&	World::sound_world()
 	return m_sound_world;
 }
 
+//-----------------------------------------------------------------------------
+CameraId World::create_camera(Unit& parent, int32_t node)
+{
+	CameraId camera = m_camera_table.create();
+
+	m_camera[camera.index].create(parent, node);
+	return camera;
+}
+
+//-----------------------------------------------------------------------------
+void World::destroy_camera(CameraId camera)
+{
+	m_camera_table.destroy(camera);
+}
+
 
 } // namespace crown

+ 19 - 7
engine/World.h

@@ -30,13 +30,18 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "HeapAllocator.h"
 #include "IdTable.h"
 #include "Unit.h"
+#include "Camera.h"
 #include "SoundWorld.h"
 #include "LinearAllocator.h"
 
 namespace crown
 {
 
-#define MAX_UNITS 10
+#define MAX_UNITS 65000
+#define MAX_CAMERAS 16
+
+typedef Id UnitId;
+typedef Id CameraId;
 
 class Vec3;
 class Quat;
@@ -55,22 +60,29 @@ public:
 	void				link_unit(UnitId child, UnitId parent);
 	void				unlink_unit(UnitId child, UnitId parent);
 
-	Unit*				unit(UnitId unit);
+	Unit*				lookup_unit(UnitId unit);
+	Camera*				lookup_camera(CameraId camera);
 
 	void				update(float dt);
 
 	SoundWorld&			sound_world();
 
+	CameraId			create_camera(Unit& parent, int32_t node);
+	void				destroy_camera(CameraId camera);
+
 private:
 
-	LinearAllocator		m_allocator;
+	LinearAllocator			m_allocator;
+
+	bool					m_is_init :1;
 
-	bool				m_is_init :1;
+	IdTable<MAX_UNITS> 		m_unit_table;
+	Unit					m_units[MAX_UNITS];
 
-	IdTable<MAX_UNITS> 	m_unit_table;
-	Unit				m_units[MAX_UNITS];
+	IdTable<MAX_CAMERAS>	m_camera_table;
+	Camera					m_camera[MAX_CAMERAS];
 
-	SoundWorld			m_sound_world;
+	SoundWorld				m_sound_world;
 };
 
 } // namespace crown

+ 165 - 46
engine/lua/LuaCamera.cpp

@@ -25,7 +25,9 @@ OTHER DEALINGS IN THE SOFTWARE.
 */
 
 #include "Camera.h"
-#include "Vec2.h"
+#include "Vec3.h"
+#include "Quat.h"
+#include "Mat4.h"
 #include "LuaStack.h"
 #include "LuaEnvironment.h"
 
@@ -33,130 +35,247 @@ namespace crown
 {
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera(lua_State* L)
+CE_EXPORT int camera_local_position(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
 
-}
+	Camera* camera = stack.get_camera(1);
 
-//-----------------------------------------------------------------------------
-CE_EXPORT int camera_position(lua_State* L)
-{
-	LuaStack stack(L);	
+	stack.push_vec3(camera->local_position());
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_set_position(lua_State* L)
+CE_EXPORT int camera_local_rotation(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+
+	stack.push_quat(camera->local_rotation());
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_look_at(lua_State* L)
+CE_EXPORT int camera_local_pose(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+
+	stack.push_mat4(camera->local_pose());
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_set_look_at(lua_State* L)
+CE_EXPORT int camera_world_position(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+
+	stack.push_vec3(camera->world_position());
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_set_rotation(lua_State* L)
+CE_EXPORT int camera_world_rotation(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+
+	stack.push_quat(camera->world_rotation());
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_up(lua_State* L)
+CE_EXPORT int camera_world_pose(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+
+	stack.push_mat4(camera->world_pose());
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_fov(lua_State* L)
+CE_EXPORT int camera_set_local_position(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+	const Vec3 pos = stack.get_vec3(2);
+
+	camera->set_local_position(pos);
+	return 0;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_set_fov(lua_State* L)
+CE_EXPORT int camera_set_local_rotation(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+	const Quat rot = stack.get_quat(2);
+
+	camera->set_local_rotation(rot);
+	return 0;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_aspect(lua_State* L)
+CE_EXPORT int camera_set_local_pose(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+	const Mat4 pose = stack.get_mat4(2);
+
+	camera->set_local_pose(pose);
+	return 0;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_set_aspect(lua_State* L)
+CE_EXPORT int camera_set_projection_type(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+	ProjectionType::Enum proj_type = (ProjectionType::Enum) stack.get_int(2);
+
+	camera->set_projection_type(proj_type);
+	return 0;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_near_clip_distance(lua_State* L)
+CE_EXPORT int camera_projection_type(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+
+	stack.push_uint32(camera->projection_type());
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_set_near_clip_distance(lua_State* L)
+CE_EXPORT int camera_fov(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+
+	stack.push_float(camera->fov());
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_far_clip_distance(lua_State* L)
+CE_EXPORT int camera_set_fov(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+	const float fov = stack.get_float(2);
+
+	camera->set_fov(fov);
+	return 0;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_set_far_clip_distance(lua_State* L)
+CE_EXPORT int camera_aspect(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+
+	stack.push_float(camera->aspect());
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_projection_matrix(lua_State* L)
+CE_EXPORT int camera_set_aspect(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+	const float aspect = stack.get_float(2);
+
+	camera->set_aspect(aspect);
+	return 0;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_view_matrix(lua_State* L)
+CE_EXPORT int camera_near_clip_distance(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+
+	stack.push_float(camera->near_clip_distance());
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_move_forward(lua_State* L)
+CE_EXPORT int camera_set_near_clip_distance(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+	const float near = stack.get_float(2);
+
+	camera->set_near_clip_distance(near);
+	return 0;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_move_backward(lua_State* L)
+CE_EXPORT int camera_far_clip_distance(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+
+	stack.push_float(camera->far_clip_distance());
+	return 1;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_strafe_left(lua_State* L)
+CE_EXPORT int camera_set_far_clip_distance(lua_State* L)
 {
-	LuaStack stack(L);	
+	LuaStack stack(L);
+
+	Camera* camera = stack.get_camera(1);
+	const float far = stack.get_float(2);
+
+	camera->set_far_clip_distance(far);
+	return 0;
 }
 
 //-----------------------------------------------------------------------------
-CE_EXPORT int camera_strafe_right(lua_State* L)
+void load_camera(LuaEnvironment& env)
 {
-	LuaStack stack(L);	
+	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);
+	env.load_module_function("Camera", "set_fov",                camera_set_fov);
+	env.load_module_function("Camera", "aspect",                 camera_aspect);
+	env.load_module_function("Camera", "set_aspect",             camera_set_aspect);
+	env.load_module_function("Camera", "near_clip_distance",     camera_near_clip_distance);
+	env.load_module_function("Camera", "set_near_clip_distance", camera_set_near_clip_distance);
+	env.load_module_function("Camera", "far_clip_distance",      camera_far_clip_distance);
+	env.load_module_function("Camera", "set_far_clip_distance",  camera_set_far_clip_distance);
+
+	env.load_module_enum("Camera", "ORTHOGRAPHIC", ProjectionType::ORTHOGRAPHIC);
+	env.load_module_enum("Camera", "PERSPECTIVE", ProjectionType::PERSPECTIVE);
 }
 
 } // namespace crown

+ 1 - 0
engine/lua/LuaEnvironment.cpp

@@ -59,6 +59,7 @@ CE_EXPORT int luaopen_libcrown(lua_State* /*L*/)
 	load_resource_package(*env);
 
 	load_unit(*env);
+	load_camera(*env);
 	load_world(*env);
 	load_sound(*env);
 

+ 11 - 1
engine/lua/LuaStack.h

@@ -28,7 +28,6 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #include "lua.hpp"
 #include "Types.h"
-#include "Unit.h"
 
 namespace crown
 {
@@ -38,6 +37,7 @@ class Vec3;
 class Mat4;
 class Quat;
 class Unit;
+class Camera;
 
 class LuaStack
 {
@@ -159,6 +159,16 @@ public:
 		return (Unit*) lua_touserdata(m_state, index);
 	}
 
+	void push_camera(Camera* camera)
+	{
+		lua_pushlightuserdata(m_state, camera);
+	}
+
+	Camera* get_camera(int32_t index)
+	{
+		return (Camera*) lua_touserdata(m_state, index);
+	}
+
 	Vec2& get_vec2(int32_t index);
 	Vec3& get_vec3(int32_t index);
 	Mat4& get_mat4(int32_t index);

+ 12 - 9
engine/lua/LuaUnit.cpp

@@ -39,7 +39,6 @@ CE_EXPORT int32_t unit_local_position(lua_State* L)
 	Unit* unit = stack.get_unit(1);
 
 	stack.push_vec3(unit->local_position());
-
 	return 1;
 }
 
@@ -51,7 +50,6 @@ CE_EXPORT int32_t unit_local_rotation(lua_State* L)
 	Unit* unit = stack.get_unit(1);
 
 	stack.push_quat(unit->local_rotation());
-
 	return 1;
 }
 
@@ -63,7 +61,6 @@ CE_EXPORT int32_t unit_local_pose(lua_State* L)
 	Unit* unit = stack.get_unit(1);
 
 	stack.push_mat4(unit->local_pose());
-
 	return 1;
 }
 
@@ -75,7 +72,6 @@ CE_EXPORT int32_t unit_world_position(lua_State* L)
 	Unit* unit = stack.get_unit(1);
 
 	stack.push_vec3(unit->world_position());
-
 	return 1;
 }
 
@@ -87,7 +83,6 @@ CE_EXPORT int32_t unit_world_rotation(lua_State* L)
 	Unit* unit = stack.get_unit(1);
 
 	stack.push_quat(unit->world_rotation());
-
 	return 1;
 }
 
@@ -99,7 +94,6 @@ CE_EXPORT int32_t unit_world_pose(lua_State* L)
 	Unit* unit = stack.get_unit(1);
 
 	stack.push_mat4(unit->world_pose());
-
 	return 1;
 }
 
@@ -112,7 +106,6 @@ CE_EXPORT int32_t unit_set_local_position(lua_State* L)
 	Vec3& pos = stack.get_vec3(2);
 
 	unit->set_local_position(pos);
-
 	return 0;
 }
 
@@ -125,7 +118,6 @@ CE_EXPORT int32_t unit_set_local_rotation(lua_State* L)
 	Quat& rot = stack.get_quat(2);
 
 	unit->set_local_rotation(rot);
-
 	return 0;
 }
 
@@ -138,10 +130,19 @@ CE_EXPORT int32_t unit_set_local_pose(lua_State* L)
 	Mat4& pose = stack.get_mat4(2);
 
 	unit->set_local_pose(pose);
-
 	return 0;
 }
 
+CE_EXPORT int unit_camera(lua_State* L)
+{
+	LuaStack stack(L);
+
+	Unit* unit = stack.get_unit(1);
+
+	stack.push_camera(unit->camera("fixme"));
+	return 1;
+}
+
 //-----------------------------------------------------------------------------
 void load_unit(LuaEnvironment& env)
 {
@@ -154,6 +155,8 @@ void load_unit(LuaEnvironment& env)
 	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);
+
+	env.load_module_function("Unit", "camera", unit_camera);
 }
 
 } // namespace crown

+ 3 - 2
engine/lua/LuaWorld.cpp

@@ -43,9 +43,10 @@ CE_EXPORT int world_spawn_unit(lua_State* L)
 	const Vec3& pos = stack.num_args() > 2 ? stack.get_vec3(3) : Vec3::ZERO;
 	const Quat& rot = stack.num_args() > 3 ? stack.get_quat(4) : Quat::IDENTITY;
 
-	world->spawn_unit(name, pos, rot);
+	UnitId unit = world->spawn_unit(name, pos, rot);
 
-	return 0;
+	stack.push_unit(world->lookup_unit(unit));
+	return 1;
 }
 
 //-----------------------------------------------------------------------------