Browse Source

Finish lua camera controller implementation

master
Riyyi 3 years ago
parent
commit
77a6a9715e
  1. 131
      assets/lua/cameracontroller.lua
  2. 4
      inferno/src/inferno/scene/scene.cpp
  3. 1
      inferno/src/inferno/script/cameracontroller.cpp
  4. 3
      inferno/src/inferno/script/luascript.cpp
  5. 53
      inferno/src/inferno/script/registration.cpp
  6. 1
      inferno/src/inferno/script/registration.h

131
assets/lua/cameracontroller.lua

@ -1,3 +1,10 @@
TRANSLATE_SPEED = 2.5
ROTATE_SPEED = 90.0
ZOOM_SENSITIVITY = 2.5
MOUSE_SENSITIVITY = 0.25
NEAR_PLANE = 0.1
FAR_PLANE = 100.0
LuaScript = {
camera = nil,
@ -11,22 +18,128 @@ LuaScript = {
end,
update = function(self, deltaTime)
self.camera = GetComponent("CameraComponent")
LuaScript:updateOrthographic(deltaTime)
LuaScript:updatePerspective(deltaTime)
local tmp = self.camera.fov
self.camera.fov = 30.0
self.camera = getCameraComponent()
--
if self.camera.type == CameraType.Orthographic then
LuaScript:updateOrthographic(deltaTime)
elseif self.camera.type == CameraType.Perspective then
LuaScript:updatePerspective(deltaTime)
end
end,
updateOrthographic = function(self, deltaTime)
--
-- Update camera rotation
cameraRotateSpeed = ROTATE_SPEED * deltaTime
if Input.isKeyPressed(keyCode("GLFW_KEY_Q")) then
self.transform.rotate.z = self.transform.rotate.z - cameraRotateSpeed
end
if Input.isKeyPressed(keyCode("GLFW_KEY_E")) then
self.transform.rotate.z = self.transform.rotate.z + cameraRotateSpeed
end
if self.transform.rotate.z > 180.0 then
self.transform.rotate.z = self.transform.rotate.z - 360.0
elseif self.transform.rotate.z <= -180.0 then
self.transform.rotate.z = self.transform.rotate.z + 360.0
end
-- Update camera translation
cameraTranslateSpeed = TRANSLATE_SPEED * deltaTime
-- WASD movement
if Input.isKeyPressed(keyCode("GLFW_KEY_W")) then
self.transform.translate.x = self.transform.translate.x + -math.sin(glm.radians(self.transform.rotate.z)) * cameraTranslateSpeed;
self.transform.translate.y = self.transform.translate.y + math.cos(glm.radians(self.transform.rotate.z)) * cameraTranslateSpeed;
end
if Input.isKeyPressed(keyCode("GLFW_KEY_S")) then
self.transform.translate.x = self.transform.translate.x - -math.sin(glm.radians(self.transform.rotate.z)) * cameraTranslateSpeed;
self.transform.translate.y = self.transform.translate.y - math.cos(glm.radians(self.transform.rotate.z)) * cameraTranslateSpeed;
end
if Input.isKeyPressed(keyCode("GLFW_KEY_A")) then
self.transform.translate.x = self.transform.translate.x - math.cos(glm.radians(self.transform.rotate.z)) * cameraTranslateSpeed;
self.transform.translate.y = self.transform.translate.y - math.sin(glm.radians(self.transform.rotate.z)) * cameraTranslateSpeed;
end
if Input.isKeyPressed(keyCode("GLFW_KEY_D")) then
self.transform.translate.x = self.transform.translate.x + math.cos(glm.radians(self.transform.rotate.z)) * cameraTranslateSpeed;
self.transform.translate.y = self.transform.translate.y + math.sin(glm.radians(self.transform.rotate.z)) * cameraTranslateSpeed;
end
-- Update camera zoom
zoomSpeed = ZOOM_SENSITIVITY * deltaTime;
if Input.isKeyPressed(keyCode("GLFW_KEY_EQUAL")) then
self.camera.zoomLevel = self.camera.zoomLevel - zoomSpeed
end
if Input.isKeyPressed(keyCode("GLFW_KEY_MINUS")) then
self.camera.zoomLevel = self.camera.zoomLevel + zoomSpeed
end
self.camera.zoomLevel = math.max(self.camera.zoomLevel, 0.25);
self.camera.zoomLevel = math.min(self.camera.zoomLevel, 10.0);
end,
updatePerspective = function(self, deltaTime)
--
-- Get mouse movement offset compared to last frame
xOffset = Input.getXOffset() * MOUSE_SENSITIVITY;
yOffset = Input.getYOffset() * MOUSE_SENSITIVITY;
self.camera.yaw = self.camera.yaw + xOffset;
self.camera.pitch = self.camera.pitch + yOffset;
-- Prevent gimbal lock
if self.camera.pitch > 89.0 then self.camera.pitch = 89.0 end
if self.camera.pitch < -89.0 then self.camera.pitch = -89.0 end
-- Update camera rotation, by calculating direction vector via yaw and pitch
self.transform.rotate = glm.vec3(
math.cos(glm.radians(self.camera.pitch)) * math.cos(glm.radians(self.camera.yaw)),
math.sin(glm.radians(self.camera.pitch)),
math.cos(glm.radians(self.camera.pitch)) * math.sin(glm.radians(self.camera.yaw))
)
self.transform.rotate = glm.normalize(self.transform.rotate)
-- The direction vector is based on
-- Camera direction (z): normalize(position - target)
-- Right axis (x): normalize(cross(up, direction))
-- Up axis (y): cross(direction, right)
-- Source: https://learnopengl.com/img/getting-started/camera_axes.png
-- Cross = combination of two vectors in 3D space,
-- where result is always perpendicular to both of the vectors
-- Update camera translation
cameraSpeed = TRANSLATE_SPEED * deltaTime
-- WASD movement
if Input.isKeyPressed(keyCode("GLFW_KEY_W")) then
self.transform.translate = glm.vec3( self.transform.translate + cameraSpeed * self.transform.rotate )
end
if Input.isKeyPressed(keyCode("GLFW_KEY_S")) then
self.transform.translate = glm.vec3( self.transform.translate - cameraSpeed * self.transform.rotate )
end
if Input.isKeyPressed(keyCode("GLFW_KEY_A")) then
self.transform.translate = glm.vec3( self.transform.translate -
glm.normalize(glm.cross(self.transform.rotate, self.camera.up)) * cameraSpeed )
end
if Input.isKeyPressed(keyCode("GLFW_KEY_D")) then
self.transform.translate = glm.vec3( self.transform.translate +
glm.normalize(glm.cross(self.transform.rotate, self.camera.up)) * cameraSpeed )
end
-- Up / down movement
if Input.isKeyPressed(keyCode("GLFW_KEY_SPACE")) then
self.transform.translate = glm.vec3( self.transform.translate.x, self.transform.translate.y + cameraSpeed, self.transform.translate.z )
end
if Input.isKeyPressed(keyCode("GLFW_KEY_LEFT_SHIFT")) then
self.transform.translate = glm.vec3( self.transform.translate.x, self.transform.translate.y - cameraSpeed, self.transform.translate.z )
end
end,
}

4
inferno/src/inferno/scene/scene.cpp

@ -46,8 +46,8 @@ namespace Inferno {
cameraTransform.rotate.z = -1.0f;
cameraTransform.translate.z = 1.0f;
addComponent<CameraComponent>(camera, CameraType::Perspective);
addComponent<NativeScriptComponent>(camera).bind<CameraController>();
// addComponent<LuaScriptComponent>(camera, "assets/lua/cameracontroller.lua");
// addComponent<NativeScriptComponent>(camera).bind<CameraController>();
addComponent<LuaScriptComponent>(camera, "assets/lua/cameracontroller.lua");
uint32_t quad = createEntity("Quad");
addComponent<SpriteComponent>(quad, glm::vec4 { 1.0f, 1.0f, 1.0f, 1.0f }, m_texture);

1
inferno/src/inferno/script/cameracontroller.cpp

@ -95,6 +95,7 @@ namespace Inferno {
// Update camera translation
float cameraSpeed = TRANSLATE_SPEED * deltaTime;
// WASD movement
if (Input::isKeyPressed(KeyCode("GLFW_KEY_W"))) {
transform->translate = { transform->translate + cameraSpeed * transform->rotate };

3
inferno/src/inferno/script/luascript.cpp

@ -19,7 +19,7 @@ namespace Inferno {
// Load libraries
// ---------------------------------
m_state.open_libraries(sol::lib::base);
m_state.open_libraries(sol::lib::base, sol::lib::math);
// Component get functions
// ---------------------------------
@ -32,7 +32,6 @@ namespace Inferno {
return &m_scene->getComponent<TransformComponent>(m_entity);
});
// (*m_state).set_function("GetComponent", &LuaScript::getComponentSol);
m_state.set_function("getCameraComponent", [this]() -> CameraComponent* {
return &m_scene->getComponent<CameraComponent>(m_entity);
});

53
inferno/src/inferno/script/registration.cpp

@ -1,7 +1,10 @@
#include "glm/ext/vector_float2.hpp" // glm::vec2
#include "glm/ext/vector_float3.hpp" // glm::vec3
#include "glm/ext/vector_float4.hpp" // glm::vec4
#include "glm/ext/vector_float2.hpp" // glm::vec2
#include "glm/ext/vector_float3.hpp" // glm::vec3
#include "glm/ext/vector_float4.hpp" // glm::vec4
#include "glm/ext/matrix_transform.hpp" // glm::radians
#include "inferno/input.h"
#include "inferno/inputcodes.h"
#include "inferno/scene/components.h"
#include "inferno/script/registration.h"
@ -11,13 +14,16 @@ namespace Inferno {
{
glm(state);
component(state);
input(state);
}
void Registration::glm(sol::state_view& state)
{
auto vec2 = state.new_usertype<glm::vec2>(
auto glm = state["glm"].get_or_create<sol::table>();
auto vec2 = glm.new_usertype<glm::vec2>(
"vec2",
sol::call_constructor, sol::constructors<glm::vec2(), glm::vec2(float), glm::vec2(float, float)>(),
sol::call_constructor, sol::constructors<glm::vec2(), glm::vec2(glm::vec2), glm::vec2(float), glm::vec2(float, float)>(),
"x", &glm::vec2::x, "y", &glm::vec2::y,
"r", &glm::vec2::r, "g", &glm::vec2::g,
"s", &glm::vec2::s, "t", &glm::vec2::t,
@ -27,9 +33,9 @@ namespace Inferno {
"__div", division<glm::vec2, float>()
);
auto vec3 = state.new_usertype<glm::vec3>(
auto vec3 = glm.new_usertype<glm::vec3>(
"vec3",
sol::call_constructor, sol::constructors<glm::vec3(), glm::vec3(float), glm::vec3(float, float, float)>(),
sol::call_constructor, sol::constructors<glm::vec3(), glm::vec3(glm::vec3), glm::vec3(float), glm::vec3(float, float, float)>(),
"x", &glm::vec3::x, "y", &glm::vec3::y, "z", &glm::vec3::z,
"r", &glm::vec3::r, "g", &glm::vec3::g, "b", &glm::vec3::b,
"s", &glm::vec3::s, "t", &glm::vec3::t, "p", &glm::vec3::p,
@ -40,9 +46,9 @@ namespace Inferno {
// "__tostring", [](glm::vec3 self) { return self.x; } // Template!!! convert via logstream
);
auto vec4 = state.new_usertype<glm::vec4>(
auto vec4 = glm.new_usertype<glm::vec4>(
"vec4",
sol::call_constructor, sol::constructors<glm::vec4(), glm::vec4(float), glm::vec4(float, float, float, float)>(),
sol::call_constructor, sol::constructors<glm::vec4(), glm::vec4(glm::vec4), glm::vec4(float), glm::vec4(float, float, float, float)>(),
"x", &glm::vec4::x, "y", &glm::vec4::y, "z", &glm::vec4::z, "w", &glm::vec4::w,
"r", &glm::vec4::r, "g", &glm::vec4::g, "b", &glm::vec4::b, "a", &glm::vec4::a,
"s", &glm::vec4::s, "t", &glm::vec4::t, "p", &glm::vec4::p, "q", &glm::vec4::q,
@ -51,6 +57,21 @@ namespace Inferno {
"__mul", multiplication<glm::vec4, float>(),
"__div", division<glm::vec4, float>()
);
glm.set_function("radians", sol::overload(
[](float v) { return glm::radians(v); },
[](const glm::vec2& v) { return glm::radians(v); },
[](const glm::vec3& v) { return glm::radians(v); },
[](const glm::vec4& v) { return glm::radians(v); }
));
glm.set_function("normalize", sol::overload(
[](const glm::vec2& v) { return glm::normalize(v); },
[](const glm::vec3& v) { return glm::normalize(v); },
[](const glm::vec4& v) { return glm::normalize(v); }
));
glm.set_function("cross", [](const glm::vec3& x, const glm::vec3& y) { return glm::cross(x, y); });
}
void Registration::component(sol::state_view& state)
@ -64,6 +85,10 @@ namespace Inferno {
transformComponent["scale"] = &TransformComponent::scale;
transformComponent["transform"] = &TransformComponent::transform;
auto cameraType = state.new_enum("CameraType",
"Orthographic", CameraType::Orthographic,
"Perspective", CameraType::Perspective);
auto cameraComponent = state.new_usertype<CameraComponent>("CameraComponent", sol::no_constructor);
cameraComponent["type"] = &CameraComponent::type;
cameraComponent["zoomLevel"] = &CameraComponent::zoomLevel;
@ -79,4 +104,14 @@ namespace Inferno {
spriteComponent["texture"] = &SpriteComponent::texture;
}
void Registration::input(sol::state_view& state)
{
state.set_function("keyCode", &KeyCode);
// state["keyCode"] = &KeyCode;
auto input = state.new_usertype<Input>("Input", sol::no_constructor);
input["isKeyPressed"] = &Input::isKeyPressed;
input["getXOffset"] = &Input::getXOffset;
input["getYOffset"] = &Input::getYOffset;
}
}

1
inferno/src/inferno/script/registration.h

@ -13,6 +13,7 @@ namespace Inferno {
private:
static void glm(sol::state_view& state);
static void component(sol::state_view& state);
static void input(sol::state_view& state);
template<typename T, typename V>
static auto addition()

Loading…
Cancel
Save