The camera's for Box Bunny and for Deepspace are very similar. The C++ interface only exposes SetAt, SetUp, SetEye, VewToWorld and World To View. Box Bunny exposed a few more, but they complicated both the C++ and Lua code. In Deepspace I decided to limit the C++ to storing the data needed to create and cache the world to view transform.
Using this simple lua interface it's very easy to throw together new cameras. Interesting code from Camera Lua Interface local function SetCamera(self, name) if(name == "Spherical") then self.update_function = SphericalCamera elseif(name == "Scroll") then self.update_function = ScrollCamera end local lcam = self function camera_update() lcam:update_function() end end function InitCameraComponent(cam_table, component) local l_camera = cam_table.camera game_camera = component component.first_persion = false component.radius = 5.0 component.azimuth = 0.0 component.inclination = 0.0 component.scroll_offset = { x = 0; y = 0; z = 20; } component.SetCamera = SetCamera function component:SetAt( pos) l_camera:SetAt( pos) end function component:SetEye(pos) l_camera:SetEye(pos) end function component:SetUp( pos) l_camera:SetUp( pos) end function component:GetAt() return l_camera:GetAt() end function component:GetEye() return l_camera:GetEye() end function component:GetUp() return l_camera:GetUp() end function component:ViewToWorld(pos) return l_camera:ViewToWorld(pos) end function component:WorldToView(pos) return l_camera:WorldToView(pos) end -- camera_update is only called from C++ component.camera_update = _G[cam_table.init_name] end Sample Lua Camera This camera is a simple example for a side scrolling game and can easily be extened to allow the player to move within a bounding box in screenspace without moving the camera -- This is a camera used side scrolling that puts the lookat location -- at the entity and the eye at the entity location + self.scroll_offset local function ScrollCamera(self) local parent = self:GetParent() local transform = parent.Transform local offset = self.scroll_offset; local at = transform:GetPosition() local eye = { x = at.x + offset.x; y = at.y + offset.y; z = at.z + offset.z; } local up = { x = 0; y = 1; z = 0; } self:SetAt(at) self:SetEye(eye) self:SetUp(up) end Interesting Code from Camera.cpp Most of the code on the C++ is basic get/setters for lua and only one get/set pair is shown here. namespace Graphics{ LUA_CLASS_BEGIN(Camera) LUA_CLASS_METHOD(Camera, SetAt), LUA_CLASS_METHOD(Camera, SetEye), LUA_CLASS_METHOD(Camera, SetUp), LUA_CLASS_METHOD(Camera, GetAt), LUA_CLASS_METHOD(Camera, GetEye), LUA_CLASS_METHOD(Camera, GetUp), LUA_CLASS_METHOD(Camera, ViewToWorld), LUA_CLASS_METHOD(Camera, WorldToView), LUA_CLASS_END(); Camera::Camera(const UT::ComponentInit com_init, const std::string& init_type) : UT::Component(com_init, true), m_init_type(init_type), m_dirty(true), m_at(0, 0, 0), m_eye(0, 0, 10), m_up(0, 1, 0) { } int Camera::SetUp(lua_State* state) { Lua::State L(state); float3 up; if(L.Get(1, up)){ m_up = up; m_dirty = true; } return 0; } int Camera::GetUp(lua_State* state) { Lua::State L(state); L.Push(m_up); return 1; } int Camera::ViewToWorld(lua_State* state) { Lua::State L(state); float3 init_pos; if(L.Get(1, init_pos)){ float3 out_pos; float4x4 inv_view_mat; Math::Inverse(inv_view_mat, GetLookAt()); Math::TransformPoint(out_pos, init_pos, inv_view_mat); L.Push(out_pos); return 1; } return 0; } int Camera::WorldToView(lua_State* state) { Lua::State L(state); float3 init_pos; if(L.Get(1, init_pos)){ float3 out_pos; Math::TransformPoint(out_pos, init_pos, GetLookAt()); L.Push(out_pos); return 1; } return 0; } const float4x4& Camera::GetLookAt() const { if(m_lua_state){ m_lua_state->GetGlobal("camera_update"); m_lua_state->Call(0, 0, "camera_update"); } if(m_dirty){ Math::LookAt(m_look_at, m_eye, m_at, m_up); m_dirty = false; } return m_look_at; } void Camera::PushLua(Lua::State& L) { lua_createtable(L, 0, 2); L.Push(this); L.SetField(-2, "camera"); L.Push(m_init_type); L.SetField(-2, "init_name"); L.GetGlobal("InitCameraComponent"); m_lua_state = &L; } |