From 09fa1809ab285d41180a5767d8cf408855986129 Mon Sep 17 00:00:00 2001 From: sanine Date: Sun, 7 May 2023 22:12:00 -0500 Subject: implement basic third-person camera --- main.lua | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 4 deletions(-) (limited to 'main.lua') diff --git a/main.lua b/main.lua index c06b80c..4372a03 100644 --- a/main.lua +++ b/main.lua @@ -14,6 +14,7 @@ local nvg = honey.nvg -- initialize honey local window = honey.init() +window:setInputMode(glfw.CURSOR, glfw.CURSOR_DISABLED) -- setup vector graphics local vg = nvg.CreateContext() @@ -127,7 +128,7 @@ function setupEntities() local capsule = entities:createEntityWithComponents{ transform = { - matrix = Mat4():identity():translate(Vec3{0,10,0}) + matrix = Mat4():identity():translate(Vec3{0,10,0}):rotateX(0.5*math.pi) }, collision = { class = "capsule", @@ -142,6 +143,7 @@ function setupEntities() radius = 1, length = 2, }, + maxAngularSpeed = 0, }, renderMesh = { mesh = { filename="assets/capsule.obj", index=1 }, @@ -150,14 +152,85 @@ function setupEntities() } + local pivotPivot = entities:createEntityWithComponents{ + transform = { + parent = capsule, + matrix = Mat4():identity():rotateX(-0.5*math.pi), + }, + } + + + local capcamPivot = entities:createEntityWithComponents{ + transform = { + parent = pivotPivot, + matrix = Mat4():identity(), + }, + pitchyaw = { + pitch = 0, + yaw = 0, + }, + onCursorPos = { script = "cameraCursorPos" }, + } + package.loaded["cameraCursorPos"] = (function() + local prevx, prevy = 0, 0 + return function(entities, id, data) + local dx = data.xpos - prevx + local dy = data.ypos - prevy + prevx, prevy = data.xpos, data.ypos + + local transform = entities:getComponent(id, "transform") + local py = entities:getComponent(id, "pitchyaw") + py.pitch = py.pitch - dy + py.yaw = py.yaw - dx + if py.pitch > 89.9 then py.pitch = 89.9 end + if py.pitch < -89.9 then py.pitch = -89.9 end + + transform.matrix + :identity() + :rotateY(math.rad(py.yaw)) + :rotateX(math.rad(py.pitch)) + end + end)() + + + local capcam = entities:createEntityWithComponents{ + camera = { + projection = Mat4():perspective(math.rad(45), 640/480, 0.1, 1000), + render="screen", + }, + transform = { + parent = capcamPivot, + matrix = Mat4():identity():translate(Vec3{0,0,10}), + }, + onWindowResize = { script = "cameraHandleResize" }, + } + + + local skybox = entities:createEntityWithComponents{ + transform = { + parent = capsule, + matrix = Mat4():identity():scale(Vec3{2,2,2}), + }, + renderMesh = { + mesh = { filename="assets/skybox.obj", index=1 }, + shader = { vertex="vertex.glsl", fragment="fragment.glsl" }, + textures = { + ourTexture = { + filename = "assets/skyboxsun5deg2_tn.jpg" + } + }, + }, + } + + local camera = entities:createEntity() entities:addComponents(camera, { - camera={ - projection=Mat4():perspective(math.rad(45), 640/480, 0.1, 100), + ccamera={ + projection=Mat4():perspective(math.rad(45), 640/480, 0.1, 1000), render="screen", }, transform={ - matrix=Mat4():identity():rotateX(math.rad(-20)):translate(Vec3{0, 10, 30}), + matrix=Mat4():identity():rotateX(math.rad(-20)):translate(Vec3{0, 5, 30}), }, z = {value=-60}, onKey = { @@ -184,6 +257,11 @@ window:setKeyCallback(function(_, key, scancode, action) end end) + +window:setCursorPosCallback(function(_, xpos, ypos) + dispatch(entities, "onCursorPos", {xpos=xpos, ypos=ypos}) +end) + -- resize window correctly window:setFramebufferSizeCallback(function(_, width, height) gl.Viewport(0, 0, width, height) @@ -193,6 +271,7 @@ end) package.loaded["cameraHandleResize"] = function(entities, id, data) local camera = entities:getComponent(id, "camera") + if not camera then return end camera.projection:perspectiveResize(data.width/data.height) end -- cgit v1.2.1