From a8044b7df422d0d2b225ae71d0d64bba554a28ec Mon Sep 17 00:00:00 2001 From: groverburger Date: Sat, 16 Jan 2021 17:40:40 -0800 Subject: [PATCH 01/18] rewrite as module --- Thumbs.db | Bin 0 -> 27648 bytes g3d/camera.lua | 106 +++++++++++++++++++++++++++++----------------- g3d/init.lua | 63 +++------------------------ g3d/matrices.lua | 98 ++++++++++++++---------------------------- g3d/model.lua | 64 ++++++++++++++++------------ g3d/objloader.lua | 37 ++++++++-------- g3d/shader.lua | 35 +++++++++++++++ g3d/vectors.lua | 33 +++++++++++++++ main.lua | 14 +++--- 9 files changed, 235 insertions(+), 215 deletions(-) create mode 100644 Thumbs.db create mode 100644 g3d/shader.lua create mode 100644 g3d/vectors.lua diff --git a/Thumbs.db b/Thumbs.db new file mode 100644 index 0000000000000000000000000000000000000000..11cc24f1fbf0e48b08e125704a813fab2b511b14 GIT binary patch literal 27648 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 AzW@LL literal 0 HcmV?d00001 diff --git a/g3d/camera.lua b/g3d/camera.lua index 94b14ae..0161fee 100644 --- a/g3d/camera.lua +++ b/g3d/camera.lua @@ -1,17 +1,56 @@ -- written by groverbuger for g3d --- august 2020 +-- january 2021 -- MIT license +local shader = require(G3D_PATH .. "/shader") +local matrices = require(G3D_PATH .. "/matrices") + +---------------------------------------------------------------------------------------------------- +-- define the camera singleton +---------------------------------------------------------------------------------------------------- + +local camera = { + fov = math.pi/2, + nearClip = 0.01, + farClip = 1000, + aspectRatio = love.graphics.getWidth()/love.graphics.getHeight(), + position = {0,0,0}, + target = {0,0,1}, + down = {0,-1,0}, +} + +-- private variables used only for the first person camera functions +local direction = 0 +local pitch = 0 + +-- create the projection matrix from the camera and send it to the shader +shader:send("projectionMatrix", matrices.getProjectionMatrix(camera.fov, camera.nearClip, camera.farClip, camera.aspectRatio)) + +-- give the camera a point to look from and a point to look towards +function camera.lookAt(x,y,z, xAt,yAt,zAt) + camera.position[1] = x + camera.position[2] = y + camera.position[3] = z + camera.target[1] = xAt + camera.target[2] = yAt + camera.target[3] = zAt + + -- TODO: update direction and pitch here + + -- update the camera in the shader + shader:send("viewMatrix", matrices.getViewMatrix(camera.position, camera.target, camera.down)) +end + -- move and rotate the camera, given a point and a direction and a pitch (vertical direction) -function SetCamera(x,y,z, direction,pitch) - Camera.position[1] = x - Camera.position[2] = y - Camera.position[3] = z - Camera.direction = direction or Camera.direction - Camera.pitch = pitch or Camera.pitch +function camera.lookTowards(x,y,z, directionTowards,pitchTowards) + camera.position[1] = x + camera.position[2] = y + camera.position[3] = z + direction = directionTowards or direction + pitch = pitchTowards or pitch -- convert the direction and pitch into a target point - local sign = math.cos(Camera.pitch) + local sign = math.cos(pitch) if sign > 0 then sign = 1 elseif sign < 0 then @@ -19,31 +58,18 @@ function SetCamera(x,y,z, direction,pitch) else sign = 0 end - local cosPitch = sign*math.max(math.abs(math.cos(Camera.pitch)), 0.001) - Camera.target[1] = Camera.position[1]+math.sin(Camera.direction)*cosPitch - Camera.target[2] = Camera.position[2]-math.sin(Camera.pitch) - Camera.target[3] = Camera.position[3]+math.cos(Camera.direction)*cosPitch - - -- update the camera in the shader - G3DShader:send("viewMatrix", GetViewMatrix(Camera.position, Camera.target, Camera.down)) -end - --- give the camera a point to look from and a point to look towards -function SetCameraAndLookAt(x,y,z, xAt,yAt,zAt) - Camera.position[1] = x - Camera.position[2] = y - Camera.position[3] = z - Camera.target[1] = xAt - Camera.target[2] = yAt - Camera.target[3] = zAt + local cosPitch = sign*math.max(math.abs(math.cos(pitch)), 0.001) + camera.target[1] = camera.position[1]+math.sin(direction)*cosPitch + camera.target[2] = camera.position[2]-math.sin(pitch) + camera.target[3] = camera.position[3]+math.cos(direction)*cosPitch -- update the camera in the shader - G3DShader:send("viewMatrix", GetViewMatrix(Camera.position, Camera.target, Camera.down)) + shader:send("viewMatrix", matrices.getViewMatrix(camera.position, camera.target, camera.down)) end -- simple first person camera movement with WASD --- put this function in your love.update to use, passing in dt -function FirstPersonCameraMovement(dt) +-- put this local function in your love.update to use, passing in dt +function camera.firstPersonMovement(dt) -- collect inputs local mx,my = 0,0 local cameraMoved = false @@ -60,11 +86,11 @@ function FirstPersonCameraMovement(dt) mx = mx + 1 end if love.keyboard.isDown("space") then - Camera.position[2] = Camera.position[2] - 0.15*dt*60 + camera.position[2] = camera.position[2] - 0.15*dt*60 cameraMoved = true end if love.keyboard.isDown("lshift") then - Camera.position[2] = Camera.position[2] + 0.15*dt*60 + camera.position[2] = camera.position[2] + 0.15*dt*60 cameraMoved = true end @@ -73,25 +99,27 @@ function FirstPersonCameraMovement(dt) if mx ~= 0 or my ~= 0 then local angle = math.atan2(my,mx) local speed = 0.15 - local dx,dz = math.cos(Camera.direction + angle)*speed*dt*60, math.sin(Camera.direction + angle + math.pi)*speed*dt*60 + local dx,dz = math.cos(direction + angle)*speed*dt*60, math.sin(direction + angle + math.pi)*speed*dt*60 - Camera.position[1] = Camera.position[1] + dx - Camera.position[3] = Camera.position[3] + dz + camera.position[1] = camera.position[1] + dx + camera.position[3] = camera.position[3] + dz cameraMoved = true end if cameraMoved then - SetCamera(Camera.position[1],Camera.position[2],Camera.position[3], Camera.direction,Camera.pitch) + camera.lookTowards(camera.position[1],camera.position[2],camera.position[3], direction,pitch) end end --- best served with FirstPersonCameraMovement() +-- best served with firstPersoncameraMovement() -- use this in your love.mousemoved function, passing in the movements -function FirstPersonCameraLook(dx,dy) +function camera.firstPersonLook(dx,dy) love.mouse.setRelativeMode(true) local sensitivity = 1/300 - Camera.direction = Camera.direction + dx*sensitivity - Camera.pitch = math.max(math.min(Camera.pitch - dy*sensitivity, math.pi*0.5), math.pi*-0.5) + direction = direction + dx*sensitivity + pitch = math.max(math.min(pitch - dy*sensitivity, math.pi*0.5), math.pi*-0.5) - SetCamera(Camera.position[1],Camera.position[2],Camera.position[3], Camera.direction,Camera.pitch) + camera.lookTowards(camera.position[1],camera.position[2],camera.position[3], direction,pitch) end + +return camera diff --git a/g3d/init.lua b/g3d/init.lua index d85c0c6..b0e1cd9 100644 --- a/g3d/init.lua +++ b/g3d/init.lua @@ -1,5 +1,5 @@ -- written by groverbuger for g3d --- august 2020 +-- january 2021 -- MIT license --[[ @@ -14,63 +14,14 @@ \_/__/ --]] ----------------------------------------------------------------------------------------------------- --- set up the basic 3D shader ----------------------------------------------------------------------------------------------------- --- the shader that projects 3D meshes onto the screen +G3D_PATH = ... -G3DShader = love.graphics.newShader [[ - uniform mat4 projectionMatrix; - uniform mat4 modelMatrix; - uniform mat4 viewMatrix; +local g3d = {} - varying vec4 vertexColor; - - #ifdef VERTEX - vec4 position(mat4 transform_projection, vec4 vertex_position) - { - vertexColor = VertexColor; - return projectionMatrix * viewMatrix * modelMatrix * vertex_position; - } - #endif - - #ifdef PIXEL - vec4 effect(vec4 color, Image tex, vec2 texcoord, vec2 pixcoord) - { - vec4 texcolor = Texel(tex, texcoord); - if (texcolor.a == 0.0) { discard; } - return vec4(texcolor)*color*vertexColor; - } - #endif -]] - ----------------------------------------------------------------------------------------------------- --- load in all the required files ----------------------------------------------------------------------------------------------------- - -require(... .. "/matrices") -require(... .. "/objloader") -require(... .. "/model") -require(... .. "/camera") - ----------------------------------------------------------------------------------------------------- --- set up the basic camera ----------------------------------------------------------------------------------------------------- - -Camera = { - fov = math.pi/2, - nearClip = 0.01, - farClip = 1000, - aspectRatio = love.graphics.getWidth()/love.graphics.getHeight(), - position = {0,0,0}, - target = {0,0,1}, - direction = 0, - pitch = 0, - down = {0,-1,0}, -} - --- create the projection matrix from the camera and send it to the shader -G3DShader:send("projectionMatrix", GetProjectionMatrix(Camera.fov, Camera.nearClip, Camera.farClip, Camera.aspectRatio)) +g3d.model = require(G3D_PATH .. "/model") +g3d.camera = require(G3D_PATH .. "/camera") -- so that far polygons don't overlap near polygons love.graphics.setDepthMode("lequal", true) + +return g3d diff --git a/g3d/matrices.lua b/g3d/matrices.lua index 98969a6..75ec711 100644 --- a/g3d/matrices.lua +++ b/g3d/matrices.lua @@ -1,17 +1,21 @@ -- written by groverbuger for g3d --- august 2020 +-- january 2021 -- MIT license +local vectors = require(G3D_PATH .. "/vectors") + ---------------------------------------------------------------------------------------------------- -- transformation, projection, and rotation matrices ---------------------------------------------------------------------------------------------------- -- the three most important matrices for 3d graphics -- these three matrices are all you need to write a simple 3d shader +local matrices = {} + -- returns a transformation matrix -- translation and rotation are 3d vectors -function GetTransformationMatrix(translation, rotation, scale) - local ret = IdentityMatrix() +function matrices.getTransformationMatrix(translation, rotation, scale) + local ret = matrices.identityMatrix() -- translations ret[4] = translation[1] @@ -20,35 +24,35 @@ function GetTransformationMatrix(translation, rotation, scale) -- rotations -- x - local rx = IdentityMatrix() + local rx = matrices.identityMatrix() rx[6] = math.cos(rotation[1]) rx[7] = -1*math.sin(rotation[1]) rx[10] = math.sin(rotation[1]) rx[11] = math.cos(rotation[1]) - ret = MatrixMult(ret, rx) + ret = matrices.matrixMultiply(ret, rx) -- y - local ry = IdentityMatrix() + local ry = matrices.identityMatrix() ry[1] = math.cos(rotation[2]) ry[3] = math.sin(rotation[2]) ry[9] = -math.sin(rotation[2]) ry[11] = math.cos(rotation[2]) - ret = MatrixMult(ret, ry) + ret = matrices.matrixMultiply(ret, ry) -- z - local rz = IdentityMatrix() + local rz = matrices.identityMatrix() rz[1] = math.cos(rotation[3]) rz[2] = -math.sin(rotation[3]) rz[5] = math.sin(rotation[3]) rz[6] = math.cos(rotation[3]) - ret = MatrixMult(ret, rz) + ret = matrices.matrixMultiply(ret, rz) -- scale - local sm = IdentityMatrix() + local sm = matrices.identityMatrix() sm[1] = scale[1] sm[6] = scale[2] sm[11] = scale[3] - ret = MatrixMult(ret, sm) + ret = matrices.matrixMultiply(ret, sm) return ret end @@ -57,7 +61,7 @@ end -- (things farther away appear smaller) -- all arguments are scalars aka normal numbers -- aspectRatio is defined as window width divided by window height -function GetProjectionMatrix(fov, near, far, aspectRatio) +function matrices.getProjectionMatrix(fov, near, far, aspectRatio) local top = near * math.tan(fov/2) local bottom = -1*top local right = top * aspectRatio @@ -75,7 +79,7 @@ end -- (things farther away are the same size as things closer) -- all arguments are scalars aka normal numbers -- aspectRatio is defined as window width divided by window height -function GetOrthoMatrix(fov, size, near, far, aspectRatio) +function matrices.getOrthographicMatrix(fov, size, near, far, aspectRatio) local top = size * math.tan(fov/2) local bottom = -1*top local right = top * aspectRatio @@ -91,76 +95,46 @@ end -- returns a view matrix -- eye, target, and down are all 3d vectors -function GetViewMatrix(eye, target, down) - local z = NormalizeVector({eye[1] - target[1], eye[2] - target[2], eye[3] - target[3]}) - local x = NormalizeVector(CrossProduct(down, z)) - local y = CrossProduct(z, x) +function matrices.getViewMatrix(eye, target, down) + local z = vectors.normalizeVector({eye[1] - target[1], eye[2] - target[2], eye[3] - target[3]}) + local x = vectors.normalizeVector(vectors.crossProduct(down, z)) + local y = vectors.crossProduct(z, x) return { - x[1], x[2], x[3], -1*DotProduct(x, eye), - y[1], y[2], y[3], -1*DotProduct(y, eye), - z[1], z[2], z[3], -1*DotProduct(z, eye), + x[1], x[2], x[3], -1*vectors.dotProduct(x, eye), + y[1], y[2], y[3], -1*vectors.dotProduct(y, eye), + z[1], z[2], z[3], -1*vectors.dotProduct(z, eye), 0, 0, 0, 1, } end ----------------------------------------------------------------------------------------------------- --- basic vector functions ----------------------------------------------------------------------------------------------------- --- vectors are just 3 numbers in table, defined like {1,0,0} - -function NormalizeVector(vector) - local dist = math.sqrt(vector[1]^2 + vector[2]^2 + vector[3]^2) - return { - vector[1]/dist, - vector[2]/dist, - vector[3]/dist, - } -end - -function SubtractVector(v1, v2) - return {v1[1] - v2[1], v1[2] - v2[2], v1[3] - v2[3]} -end - -function DotProduct(a,b) - return a[1]*b[1] + a[2]*b[2] + a[3]*b[3] -end - -function CrossProduct(a,b) - return { - a[2]*b[3] - a[3]*b[2], - a[3]*b[1] - a[1]*b[3], - a[1]*b[2] - a[2]*b[1], - } -end - ---------------------------------------------------------------------------------------------------- -- basic matrix functions ---------------------------------------------------------------------------------------------------- -- matrices are just 16 numbers in table, representing a 4x4 matrix -- an identity matrix is defined as {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1} -function IdentityMatrix() +function matrices.identityMatrix() return {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1} end -- i find rows and columns confusing, so i use coordinate pairs instead -- this returns a value of a matrix at a specific coordinate -function GetMatrixXY(matrix, x,y) +function matrices.getMatrixXY(matrix, x,y) return matrix[x + (y-1)*4] end -- return the matrix that results from the two given matrices multiplied together -function MatrixMult(a,b) +function matrices.matrixMultiply(a,b) local ret = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0} local i = 1 for y=1, 4 do for x=1, 4 do - ret[i] = ret[i] + GetMatrixXY(a,1,y)*GetMatrixXY(b,x,1) - ret[i] = ret[i] + GetMatrixXY(a,2,y)*GetMatrixXY(b,x,2) - ret[i] = ret[i] + GetMatrixXY(a,3,y)*GetMatrixXY(b,x,3) - ret[i] = ret[i] + GetMatrixXY(a,4,y)*GetMatrixXY(b,x,4) + ret[i] = ret[i] + matrices.getMatrixXY(a,1,y)*matrices.getMatrixXY(b,x,1) + ret[i] = ret[i] + matrices.getMatrixXY(a,2,y)*matrices.getMatrixXY(b,x,2) + ret[i] = ret[i] + matrices.getMatrixXY(a,3,y)*matrices.getMatrixXY(b,x,3) + ret[i] = ret[i] + matrices.getMatrixXY(a,4,y)*matrices.getMatrixXY(b,x,4) i = i + 1 end end @@ -168,12 +142,4 @@ function MatrixMult(a,b) return ret end --- returns a transpose of the given matrix -function TransposeMatrix(m) - return { - GetMatrixXY(m, 1,1), GetMatrixXY(m, 1,2), GetMatrixXY(m, 1,3), GetMatrixXY(m, 1,4), - GetMatrixXY(m, 2,1), GetMatrixXY(m, 2,2), GetMatrixXY(m, 2,3), GetMatrixXY(m, 2,4), - GetMatrixXY(m, 3,1), GetMatrixXY(m, 3,2), GetMatrixXY(m, 3,3), GetMatrixXY(m, 3,4), - GetMatrixXY(m, 4,1), GetMatrixXY(m, 4,2), GetMatrixXY(m, 4,3), GetMatrixXY(m, 4,4), - } -end +return matrices diff --git a/g3d/model.lua b/g3d/model.lua index 48d0e00..b6404f8 100644 --- a/g3d/model.lua +++ b/g3d/model.lua @@ -1,31 +1,37 @@ -- written by groverbuger for g3d --- august 2020 +-- january 2021 -- MIT license +local vectors = require(G3D_PATH .. "/vectors") +local matrices = require(G3D_PATH .. "/matrices") +local loadObjFile = require(G3D_PATH .. "/objloader") + ---------------------------------------------------------------------------------------------------- -- define a model class ---------------------------------------------------------------------------------------------------- -Model = { +local model = { vertexFormat = { {"VertexPosition", "float", 3}, {"VertexTexCoord", "float", 2}, {"VertexNormal", "float", 3}, {"VertexColor", "byte", 4}, }, + + shader = require(G3D_PATH .. "/shader"), } -Model.__index = Model +model.__index = model --- this returns a new instance of the Model class +-- this returns a new instance of the model class -- a model must be given a .obj file or equivalent lua table, and a texture -- translation, rotation, and scale are all 3d vectors and are all optional -function Model:new(given, texture, translation, rotation, scale) - local self = setmetatable({}, Model) +function model.new(given, texture, translation, rotation, scale) + local self = setmetatable({}, model) -- if given is a string, use it as a path to a .obj file -- otherwise given is a table, use it as a model defintion if type(given) == "string" then - given = LoadObjFile(given) + given = loadObjFile(given) end -- if texture is a string, use it as a path to an image file @@ -35,7 +41,6 @@ function Model:new(given, texture, translation, rotation, scale) end -- initialize my variables - self.shader = G3DShader self.verts = given self.texture = texture self.mesh = love.graphics.newMesh(self.vertexFormat, self.verts, "triangles") @@ -46,7 +51,8 @@ function Model:new(given, texture, translation, rotation, scale) end -- populate model's normals in model's mesh automatically -function Model:makeNormals() +-- if true is passed in, then the normals are all flipped +function model:makeNormals(isFlipped) for i=1, #self.verts, 3 do local vp = self.verts[i] local v = self.verts[i+1] @@ -54,23 +60,23 @@ function Model:makeNormals() local vec1 = {v[1]-vp[1], v[2]-vp[2], v[3]-vp[3]} local vec2 = {vn[1]-v[1], vn[2]-v[2], vn[3]-v[3]} - local normal = NormalizeVector(CrossProduct(vec1,vec2)) - vp[6] = normal[1] - vp[7] = normal[2] - vp[8] = normal[3] - - v[6] = normal[1] - v[7] = normal[2] - v[8] = normal[3] - - vn[6] = normal[1] - vn[7] = normal[2] - vn[8] = normal[3] + local normal = vectors.normalizeVector(vectors.crossProduct(vec1,vec2)) + vp[6] = normal[1] * (isFlipped and -1 or 1) + vp[7] = normal[2] * (isFlipped and -1 or 1) + vp[8] = normal[3] * (isFlipped and -1 or 1) + + v[6] = normal[1] * (isFlipped and -1 or 1) + v[7] = normal[2] * (isFlipped and -1 or 1) + v[8] = normal[3] * (isFlipped and -1 or 1) + + vn[6] = normal[1] * (isFlipped and -1 or 1) + vn[7] = normal[2] * (isFlipped and -1 or 1) + vn[8] = normal[3] * (isFlipped and -1 or 1) end end -- move and rotate given two 3d vectors -function Model:setTransform(translation, rotation, scale) +function model:setTransform(translation, rotation, scale) self.translation = translation or {0,0,0} self.rotation = rotation or {0,0,0} self.scale = scale or {1,1,1} @@ -78,32 +84,34 @@ function Model:setTransform(translation, rotation, scale) end -- move given one 3d vector -function Model:setTranslation(tx,ty,tz) +function model:setTranslation(tx,ty,tz) self.translation = {tx,ty,tz} self:updateMatrix() end -- rotate given one 3d vector -function Model:setRotation(rx,ry,rz) +function model:setRotation(rx,ry,rz) self.rotation = {rx,ry,rz} self:updateMatrix() end -- resize model's matrix based on a given 3d vector -function Model:setScale(sx,sy,sz) +function model:setScale(sx,sy,sz) self.scale = {sx,sy,sz} self:updateMatrix() end -- update the model's transformation matrix -function Model:updateMatrix() - self.matrix = GetTransformationMatrix(self.translation, self.rotation, self.scale) +function model:updateMatrix() + self.matrix = matrices.getTransformationMatrix(self.translation, self.rotation, self.scale) end -- draw the model -function Model:draw() +function model:draw() love.graphics.setShader(self.shader) self.shader:send("modelMatrix", self.matrix) love.graphics.draw(self.mesh) love.graphics.setShader() end + +return model diff --git a/g3d/objloader.lua b/g3d/objloader.lua index 9da56c6..79528e7 100644 --- a/g3d/objloader.lua +++ b/g3d/objloader.lua @@ -1,32 +1,31 @@ -- written by groverbuger for g3d --- august 2020 +-- january 2021 -- MIT license ---------------------------------------------------------------------------------------------------- -- simple obj loader ---------------------------------------------------------------------------------------------------- --- stitch two tables together and return the result --- useful for use in the LoadObjFile function -local function concatTables(t1,t2,t3) - local ret = {} +-- give path of file +-- returns a lua table representation +return function (path) + -- stitch two tables together and return the result + local function concatTables(t1,t2,t3) + local ret = {} - for i,v in ipairs(t1) do - ret[#ret +1] = v - end - for i,v in ipairs(t2) do - ret[#ret +1] = v - end - for i,v in ipairs(t3) do - ret[#ret +1] = v - end + for i,v in ipairs(t1) do + ret[#ret +1] = v + end + for i,v in ipairs(t2) do + ret[#ret +1] = v + end + for i,v in ipairs(t3) do + ret[#ret +1] = v + end - return ret -end + return ret + end --- give path of file --- returns a lua table representation -function LoadObjFile(path) local verts = {} local faces = {} local uvs = {} diff --git a/g3d/shader.lua b/g3d/shader.lua new file mode 100644 index 0000000..a5f8b45 --- /dev/null +++ b/g3d/shader.lua @@ -0,0 +1,35 @@ +-- written by groverbuger for g3d +-- january 2021 +-- MIT license + +---------------------------------------------------------------------------------------------------- +-- define the 3d shader +---------------------------------------------------------------------------------------------------- +-- this is what projects 3d objects onto the 2d screen + +local shader = love.graphics.newShader [[ + uniform mat4 projectionMatrix; + uniform mat4 modelMatrix; + uniform mat4 viewMatrix; + + varying vec4 vertexColor; + + #ifdef VERTEX + vec4 position(mat4 transform_projection, vec4 vertex_position) + { + vertexColor = VertexColor; + return projectionMatrix * viewMatrix * modelMatrix * vertex_position; + } + #endif + + #ifdef PIXEL + vec4 effect(vec4 color, Image tex, vec2 texcoord, vec2 pixcoord) + { + vec4 texcolor = Texel(tex, texcoord); + if (texcolor.a == 0.0) { discard; } + return vec4(texcolor)*color*vertexColor; + } + #endif +]] + +return shader diff --git a/g3d/vectors.lua b/g3d/vectors.lua new file mode 100644 index 0000000..e668d84 --- /dev/null +++ b/g3d/vectors.lua @@ -0,0 +1,33 @@ +-- written by groverbuger for g3d +-- january 2021 +-- MIT license + +---------------------------------------------------------------------------------------------------- +-- basic vector functions +---------------------------------------------------------------------------------------------------- +-- vectors are just 3 numbers in table, defined like {1,0,0} + +local vectors = {} + +function vectors.normalizeVector(vector) + local dist = math.sqrt(vector[1]^2 + vector[2]^2 + vector[3]^2) + return { + vector[1]/dist, + vector[2]/dist, + vector[3]/dist, + } +end + +function vectors.dotProduct(a,b) + return a[1]*b[1] + a[2]*b[2] + a[3]*b[3] +end + +function vectors.crossProduct(a,b) + return { + a[2]*b[3] - a[3]*b[2], + a[3]*b[1] - a[1]*b[3], + a[1]*b[2] - a[2]*b[1], + } +end + +return vectors diff --git a/main.lua b/main.lua index fef1cd1..766c433 100644 --- a/main.lua +++ b/main.lua @@ -1,25 +1,25 @@ -- written by groverbuger for g3d --- october 2020 +-- january 2021 -- MIT license -require "g3d" +g3d = require "g3d" function love.load() - Earth = Model:new("assets/sphere.obj", "assets/earth.png", {0,0,4}, nil, {-1,1,1}) - Moon = Model:new("assets/sphere.obj", "assets/moon.png", {5,0,4}, nil, {-0.5,0.5,0.5}) - Background = Model:new("assets/sphere.obj", "assets/starfield.png", {0,0,0}, nil, {500,500,500}) + Earth = g3d.model.new("assets/sphere.obj", "assets/earth.png", {0,0,4}, nil, {-1,1,1}) + Moon = g3d.model.new("assets/sphere.obj", "assets/moon.png", {5,0,4}, nil, {-0.5,0.5,0.5}) + Background = g3d.model.new("assets/sphere.obj", "assets/starfield.png", {0,0,0}, nil, {500,500,500}) Timer = 0 end function love.mousemoved(x,y, dx,dy) - FirstPersonCameraLook(dx,dy) + g3d.camera.firstPersonLook(dx,dy) end function love.update(dt) Timer = Timer + dt Moon:setTranslation(math.cos(Timer)*5, 0, math.sin(Timer)*5 +4) Moon:setRotation(0,-1*Timer,0) - FirstPersonCameraMovement(dt) + g3d.camera.firstPersonMovement(dt) end function love.draw() From 30eec5784c4db2800854521b2054ad647dea4688 Mon Sep 17 00:00:00 2001 From: groverburger Date: Sat, 16 Jan 2021 17:46:28 -0800 Subject: [PATCH 02/18] nil out G3D_PATH when done, updated README --- README.md | 14 +++++++------- g3d/init.lua | 6 ++++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d86be27..ba19ef9 100644 --- a/README.md +++ b/README.md @@ -34,27 +34,27 @@ For more information, check out the [g3d wiki](https://github.com/groverburger/g The entire `main.lua` file for the Earth and Moon demo is under 30 lines, as shown here: ```lua -- written by groverbuger for g3d --- october 2020 +-- january 2021 -- MIT license -require "g3d" +g3d = require "g3d" function love.load() - Earth = Model:new("assets/sphere.obj", "assets/earth.png", {0,0,4}, nil, {-1,1,1}) - Moon = Model:new("assets/sphere.obj", "assets/moon.png", {5,0,4}, nil, {-0.5,0.5,0.5}) - Background = Model:new("assets/sphere.obj", "assets/starfield.png", {0,0,0}, nil, {500,500,500}) + Earth = g3d.model.new("assets/sphere.obj", "assets/earth.png", {0,0,4}, nil, {-1,1,1}) + Moon = g3d.model.new("assets/sphere.obj", "assets/moon.png", {5,0,4}, nil, {-0.5,0.5,0.5}) + Background = g3d.model.new("assets/sphere.obj", "assets/starfield.png", {0,0,0}, nil, {500,500,500}) Timer = 0 end function love.mousemoved(x,y, dx,dy) - FirstPersonCameraLook(dx,dy) + g3d.camera.firstPersonLook(dx,dy) end function love.update(dt) Timer = Timer + dt Moon:setTranslation(math.cos(Timer)*5, 0, math.sin(Timer)*5 +4) Moon:setRotation(0,-1*Timer,0) - FirstPersonCameraMovement(dt) + g3d.camera.firstPersonMovement(dt) end function love.draw() diff --git a/g3d/init.lua b/g3d/init.lua index b0e1cd9..0ea306e 100644 --- a/g3d/init.lua +++ b/g3d/init.lua @@ -14,6 +14,8 @@ \_/__/ --]] +-- add the path to g3d to the global namespace +-- so submodules can know how to load their dependencies G3D_PATH = ... local g3d = {} @@ -24,4 +26,8 @@ g3d.camera = require(G3D_PATH .. "/camera") -- so that far polygons don't overlap near polygons love.graphics.setDepthMode("lequal", true) +-- get rid of G3D_PATH from the global namespace +-- so the end user doesn't have to worry about any globals +G3D_PATH = nil + return g3d From 42e6c63ce8ba2ec23405bb369e80f124968c049e Mon Sep 17 00:00:00 2001 From: groverburger Date: Sat, 16 Jan 2021 22:08:52 -0800 Subject: [PATCH 03/18] more consistent matrix function names --- g3d/matrices.lua | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/g3d/matrices.lua b/g3d/matrices.lua index 75ec711..179f04f 100644 --- a/g3d/matrices.lua +++ b/g3d/matrices.lua @@ -15,7 +15,7 @@ local matrices = {} -- returns a transformation matrix -- translation and rotation are 3d vectors function matrices.getTransformationMatrix(translation, rotation, scale) - local ret = matrices.identityMatrix() + local ret = matrices.getIdentityMatrix() -- translations ret[4] = translation[1] @@ -24,35 +24,35 @@ function matrices.getTransformationMatrix(translation, rotation, scale) -- rotations -- x - local rx = matrices.identityMatrix() + local rx = matrices.getIdentityMatrix() rx[6] = math.cos(rotation[1]) rx[7] = -1*math.sin(rotation[1]) rx[10] = math.sin(rotation[1]) rx[11] = math.cos(rotation[1]) - ret = matrices.matrixMultiply(ret, rx) + ret = matrices.multiply(ret, rx) -- y - local ry = matrices.identityMatrix() + local ry = matrices.getIdentityMatrix() ry[1] = math.cos(rotation[2]) ry[3] = math.sin(rotation[2]) ry[9] = -math.sin(rotation[2]) ry[11] = math.cos(rotation[2]) - ret = matrices.matrixMultiply(ret, ry) + ret = matrices.multiply(ret, ry) -- z - local rz = matrices.identityMatrix() + local rz = matrices.getIdentityMatrix() rz[1] = math.cos(rotation[3]) rz[2] = -math.sin(rotation[3]) rz[5] = math.sin(rotation[3]) rz[6] = math.cos(rotation[3]) - ret = matrices.matrixMultiply(ret, rz) + ret = matrices.multiply(ret, rz) -- scale - local sm = matrices.identityMatrix() + local sm = matrices.getIdentityMatrix() sm[1] = scale[1] sm[6] = scale[2] sm[11] = scale[3] - ret = matrices.matrixMultiply(ret, sm) + ret = matrices.multiply(ret, sm) return ret end @@ -114,27 +114,27 @@ end -- matrices are just 16 numbers in table, representing a 4x4 matrix -- an identity matrix is defined as {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1} -function matrices.identityMatrix() +function matrices.getIdentityMatrix() return {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1} end -- i find rows and columns confusing, so i use coordinate pairs instead -- this returns a value of a matrix at a specific coordinate -function matrices.getMatrixXY(matrix, x,y) +function matrices.getMatrixValueAt(matrix, x,y) return matrix[x + (y-1)*4] end -- return the matrix that results from the two given matrices multiplied together -function matrices.matrixMultiply(a,b) +function matrices.multiply(a,b) local ret = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0} local i = 1 for y=1, 4 do for x=1, 4 do - ret[i] = ret[i] + matrices.getMatrixXY(a,1,y)*matrices.getMatrixXY(b,x,1) - ret[i] = ret[i] + matrices.getMatrixXY(a,2,y)*matrices.getMatrixXY(b,x,2) - ret[i] = ret[i] + matrices.getMatrixXY(a,3,y)*matrices.getMatrixXY(b,x,3) - ret[i] = ret[i] + matrices.getMatrixXY(a,4,y)*matrices.getMatrixXY(b,x,4) + ret[i] = ret[i] + matrices.getMatrixValueAt(a,1,y)*matrices.getMatrixValueAt(b,x,1) + ret[i] = ret[i] + matrices.getMatrixValueAt(a,2,y)*matrices.getMatrixValueAt(b,x,2) + ret[i] = ret[i] + matrices.getMatrixValueAt(a,3,y)*matrices.getMatrixValueAt(b,x,3) + ret[i] = ret[i] + matrices.getMatrixValueAt(a,4,y)*matrices.getMatrixValueAt(b,x,4) i = i + 1 end end From 7f9aa6e15bae938e5ce448f3121dea0eac75597a Mon Sep 17 00:00:00 2001 From: groverburger Date: Sun, 17 Jan 2021 01:38:18 -0800 Subject: [PATCH 04/18] added context to direction and pitch, encapsulated camera matrix functions --- g3d/camera.lua | 54 ++++++++++++++++++++++++++++++-------------------- g3d/init.lua | 1 + 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/g3d/camera.lua b/g3d/camera.lua index 0161fee..06950ab 100644 --- a/g3d/camera.lua +++ b/g3d/camera.lua @@ -15,16 +15,15 @@ local camera = { farClip = 1000, aspectRatio = love.graphics.getWidth()/love.graphics.getHeight(), position = {0,0,0}, - target = {0,0,1}, + target = {0,0,0}, down = {0,-1,0}, } -- private variables used only for the first person camera functions -local direction = 0 -local pitch = 0 - --- create the projection matrix from the camera and send it to the shader -shader:send("projectionMatrix", matrices.getProjectionMatrix(camera.fov, camera.nearClip, camera.farClip, camera.aspectRatio)) +local fpsController = { + direction = 0, + pitch = 0 +} -- give the camera a point to look from and a point to look towards function camera.lookAt(x,y,z, xAt,yAt,zAt) @@ -35,10 +34,10 @@ function camera.lookAt(x,y,z, xAt,yAt,zAt) camera.target[2] = yAt camera.target[3] = zAt - -- TODO: update direction and pitch here + -- TODO: update fpsController's direction and pitch here -- update the camera in the shader - shader:send("viewMatrix", matrices.getViewMatrix(camera.position, camera.target, camera.down)) + camera.updateViewMatrix() end -- move and rotate the camera, given a point and a direction and a pitch (vertical direction) @@ -46,11 +45,12 @@ function camera.lookTowards(x,y,z, directionTowards,pitchTowards) camera.position[1] = x camera.position[2] = y camera.position[3] = z - direction = directionTowards or direction - pitch = pitchTowards or pitch + + fpsController.direction = directionTowards or fpsController.direction + fpsController.pitch = pitchTowards or fpsController.pitch -- convert the direction and pitch into a target point - local sign = math.cos(pitch) + local sign = math.cos(fpsController.pitch) if sign > 0 then sign = 1 elseif sign < 0 then @@ -58,13 +58,25 @@ function camera.lookTowards(x,y,z, directionTowards,pitchTowards) else sign = 0 end - local cosPitch = sign*math.max(math.abs(math.cos(pitch)), 0.001) - camera.target[1] = camera.position[1]+math.sin(direction)*cosPitch - camera.target[2] = camera.position[2]-math.sin(pitch) - camera.target[3] = camera.position[3]+math.cos(direction)*cosPitch + local cosPitch = sign*math.max(math.abs(math.cos(fpsController.pitch)), 0.001) + camera.target[1] = camera.position[1]+math.sin(fpsController.direction)*cosPitch + camera.target[2] = camera.position[2]-math.sin(fpsController.pitch) + camera.target[3] = camera.position[3]+math.cos(fpsController.direction)*cosPitch -- update the camera in the shader - shader:send("viewMatrix", matrices.getViewMatrix(camera.position, camera.target, camera.down)) + camera.updateViewMatrix() +end + +-- recreate the camera's view matrix from its current values +-- and send the matrix to the shader specified, or the default shader +function camera.updateViewMatrix(shaderGiven) + (shaderGiven or shader):send("viewMatrix", matrices.getViewMatrix(camera.position, camera.target, camera.down)) +end + +-- recreate the camera's projection matrix from its current values +-- and send the matrix to the shader specified, or the default shader +function camera.updateProjectionMatrix(shaderGiven) + (shaderGiven or shader):send("projectionMatrix", matrices.getProjectionMatrix(camera.fov, camera.nearClip, camera.farClip, camera.aspectRatio)) end -- simple first person camera movement with WASD @@ -99,7 +111,7 @@ function camera.firstPersonMovement(dt) if mx ~= 0 or my ~= 0 then local angle = math.atan2(my,mx) local speed = 0.15 - local dx,dz = math.cos(direction + angle)*speed*dt*60, math.sin(direction + angle + math.pi)*speed*dt*60 + local dx,dz = math.cos(fpsController.direction + angle)*speed*dt*60, math.sin(fpsController.direction + angle + math.pi)*speed*dt*60 camera.position[1] = camera.position[1] + dx camera.position[3] = camera.position[3] + dz @@ -107,7 +119,7 @@ function camera.firstPersonMovement(dt) end if cameraMoved then - camera.lookTowards(camera.position[1],camera.position[2],camera.position[3], direction,pitch) + camera.lookTowards(camera.position[1],camera.position[2],camera.position[3], fpsController.direction,fpsController.pitch) end end @@ -116,10 +128,10 @@ end function camera.firstPersonLook(dx,dy) love.mouse.setRelativeMode(true) local sensitivity = 1/300 - direction = direction + dx*sensitivity - pitch = math.max(math.min(pitch - dy*sensitivity, math.pi*0.5), math.pi*-0.5) + fpsController.direction = fpsController.direction + dx*sensitivity + fpsController.pitch = math.max(math.min(fpsController.pitch - dy*sensitivity, math.pi*0.5), math.pi*-0.5) - camera.lookTowards(camera.position[1],camera.position[2],camera.position[3], direction,pitch) + camera.lookTowards(camera.position[1],camera.position[2],camera.position[3], fpsController.direction,fpsController.pitch) end return camera diff --git a/g3d/init.lua b/g3d/init.lua index 0ea306e..c1ee00f 100644 --- a/g3d/init.lua +++ b/g3d/init.lua @@ -22,6 +22,7 @@ local g3d = {} g3d.model = require(G3D_PATH .. "/model") g3d.camera = require(G3D_PATH .. "/camera") +g3d.camera.updateProjectionMatrix() -- so that far polygons don't overlap near polygons love.graphics.setDepthMode("lequal", true) From c0660e57a1c24dc158c7d289421954bf3b5eaf17 Mon Sep 17 00:00:00 2001 From: groverburger Date: Sun, 17 Jan 2021 01:43:57 -0800 Subject: [PATCH 05/18] objloader function now a singleton with added TODO --- g3d/objloader.lua | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/g3d/objloader.lua b/g3d/objloader.lua index 79528e7..fd76426 100644 --- a/g3d/objloader.lua +++ b/g3d/objloader.lua @@ -6,26 +6,26 @@ -- simple obj loader ---------------------------------------------------------------------------------------------------- --- give path of file --- returns a lua table representation -return function (path) - -- stitch two tables together and return the result - local function concatTables(t1,t2,t3) - local ret = {} - - for i,v in ipairs(t1) do - ret[#ret +1] = v - end - for i,v in ipairs(t2) do - ret[#ret +1] = v - end - for i,v in ipairs(t3) do - ret[#ret +1] = v - end +-- stitch two tables together and return the result +local function concatTables(t1,t2,t3) + local ret = {} - return ret + for i,v in ipairs(t1) do + ret[#ret +1] = v + end + for i,v in ipairs(t2) do + ret[#ret +1] = v + end + for i,v in ipairs(t3) do + ret[#ret +1] = v end + return ret +end + +-- give path of file +-- returns a lua table representation +local function objLoader(path) local verts = {} local faces = {} local uvs = {} @@ -60,7 +60,10 @@ return function (path) -- the arguments a point takes is v,vt,vn if words[1] == "f" then local store = {} + + -- TODO allow models with untriangulated faces assert(#words == 4, "Faces in "..path.." must be triangulated before they can be used in g3d!") + for i=2, #words do local num = "" local word = words[i] @@ -119,3 +122,5 @@ return function (path) return compiled end + +return objLoader From 854ffeec48a1512682a051349d7aa1e4d1fae238 Mon Sep 17 00:00:00 2001 From: groverburger Date: Sun, 17 Jan 2021 01:44:31 -0800 Subject: [PATCH 06/18] more consistent unary minus -> -1* --- g3d/matrices.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/g3d/matrices.lua b/g3d/matrices.lua index 179f04f..458ad3f 100644 --- a/g3d/matrices.lua +++ b/g3d/matrices.lua @@ -35,14 +35,14 @@ function matrices.getTransformationMatrix(translation, rotation, scale) local ry = matrices.getIdentityMatrix() ry[1] = math.cos(rotation[2]) ry[3] = math.sin(rotation[2]) - ry[9] = -math.sin(rotation[2]) + ry[9] = -1*math.sin(rotation[2]) ry[11] = math.cos(rotation[2]) ret = matrices.multiply(ret, ry) -- z local rz = matrices.getIdentityMatrix() rz[1] = math.cos(rotation[3]) - rz[2] = -math.sin(rotation[3]) + rz[2] = -1*math.sin(rotation[3]) rz[5] = math.sin(rotation[3]) rz[6] = math.cos(rotation[3]) ret = matrices.multiply(ret, rz) From dca8970cc3ef60924da7108c6e0fcca03d179866 Mon Sep 17 00:00:00 2001 From: groverburger Date: Sun, 17 Jan 2021 01:45:08 -0800 Subject: [PATCH 07/18] got rid of unnecessary table literals in model.lua to not create garbage --- g3d/model.lua | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/g3d/model.lua b/g3d/model.lua index b6404f8..c70ca7d 100644 --- a/g3d/model.lua +++ b/g3d/model.lua @@ -45,7 +45,7 @@ function model.new(given, texture, translation, rotation, scale) self.texture = texture self.mesh = love.graphics.newMesh(self.vertexFormat, self.verts, "triangles") self.mesh:setTexture(self.texture) - self:setTransform(translation or {0,0,0}, rotation or {0,0,0}, scale or {1,1,1}) + self:setTransform(translation, rotation, scale) return self end @@ -61,17 +61,19 @@ function model:makeNormals(isFlipped) local vec1 = {v[1]-vp[1], v[2]-vp[2], v[3]-vp[3]} local vec2 = {vn[1]-v[1], vn[2]-v[2], vn[3]-v[3]} local normal = vectors.normalizeVector(vectors.crossProduct(vec1,vec2)) - vp[6] = normal[1] * (isFlipped and -1 or 1) - vp[7] = normal[2] * (isFlipped and -1 or 1) - vp[8] = normal[3] * (isFlipped and -1 or 1) + local flippage = (isFlipped and -1 or 1) - v[6] = normal[1] * (isFlipped and -1 or 1) - v[7] = normal[2] * (isFlipped and -1 or 1) - v[8] = normal[3] * (isFlipped and -1 or 1) + vp[6] = normal[1] * flippage + vp[7] = normal[2] * flippage + vp[8] = normal[3] * flippage - vn[6] = normal[1] * (isFlipped and -1 or 1) - vn[7] = normal[2] * (isFlipped and -1 or 1) - vn[8] = normal[3] * (isFlipped and -1 or 1) + v[6] = normal[1] * flippage + v[7] = normal[2] * flippage + v[8] = normal[3] * flippage + + vn[6] = normal[1] * flippage + vn[7] = normal[2] * flippage + vn[8] = normal[3] * flippage end end @@ -85,19 +87,25 @@ end -- move given one 3d vector function model:setTranslation(tx,ty,tz) - self.translation = {tx,ty,tz} + self.translation[1] = tx + self.translation[2] = ty + self.translation[3] = tz self:updateMatrix() end -- rotate given one 3d vector function model:setRotation(rx,ry,rz) - self.rotation = {rx,ry,rz} + self.rotation[1] = rx + self.rotation[2] = ry + self.rotation[3] = rz self:updateMatrix() end -- resize model's matrix based on a given 3d vector function model:setScale(sx,sy,sz) - self.scale = {sx,sy,sz} + self.scale[1] = sx + self.scale[2] = sy + self.scale[3] = sz self:updateMatrix() end From 7844428eaec4548bfa9aea8ef770aaac8ddd6287 Mon Sep 17 00:00:00 2001 From: groverburger Date: Sun, 17 Jan 2021 01:50:21 -0800 Subject: [PATCH 08/18] better commenting and variable names in camera.lua --- g3d/camera.lua | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/g3d/camera.lua b/g3d/camera.lua index 06950ab..db878da 100644 --- a/g3d/camera.lua +++ b/g3d/camera.lua @@ -83,19 +83,19 @@ end -- put this local function in your love.update to use, passing in dt function camera.firstPersonMovement(dt) -- collect inputs - local mx,my = 0,0 + local moveX,moveY = 0,0 local cameraMoved = false if love.keyboard.isDown("w") then - my = my - 1 + moveY = moveY - 1 end if love.keyboard.isDown("a") then - mx = mx - 1 + moveX = moveX - 1 end if love.keyboard.isDown("s") then - my = my + 1 + moveY = moveY + 1 end if love.keyboard.isDown("d") then - mx = mx + 1 + moveX = moveX + 1 end if love.keyboard.isDown("space") then camera.position[2] = camera.position[2] - 0.15*dt*60 @@ -106,27 +106,30 @@ function camera.firstPersonMovement(dt) cameraMoved = true end - -- add camera's direction and movement direction - -- then move in the resulting direction - if mx ~= 0 or my ~= 0 then - local angle = math.atan2(my,mx) - local speed = 0.15 - local dx,dz = math.cos(fpsController.direction + angle)*speed*dt*60, math.sin(fpsController.direction + angle + math.pi)*speed*dt*60 + -- do some trigonometry on the inputs to make movement relative to camera's direction + -- also to make the player not move faster in diagonal directions + if moveX ~= 0 or moveY ~= 0 then + local angle = math.atan2(moveY,moveX) + local speed = 9 + local directionX,directionZ = math.cos(fpsController.direction + angle)*speed*dt, math.sin(fpsController.direction + angle + math.pi)*speed*dt - camera.position[1] = camera.position[1] + dx - camera.position[3] = camera.position[3] + dz + camera.position[1] = camera.position[1] + directionX + camera.position[3] = camera.position[3] + directionZ cameraMoved = true end + -- update the camera's in the shader + -- only if the camera moved, for a slight performance benefit if cameraMoved then camera.lookTowards(camera.position[1],camera.position[2],camera.position[3], fpsController.direction,fpsController.pitch) end end --- best served with firstPersoncameraMovement() -- use this in your love.mousemoved function, passing in the movements function camera.firstPersonLook(dx,dy) + -- capture the mouse love.mouse.setRelativeMode(true) + local sensitivity = 1/300 fpsController.direction = fpsController.direction + dx*sensitivity fpsController.pitch = math.max(math.min(fpsController.pitch - dy*sensitivity, math.pi*0.5), math.pi*-0.5) From efd96bb0d99a33b5ec3813225bcff70eaa3182ba Mon Sep 17 00:00:00 2001 From: groverburger Date: Sun, 17 Jan 2021 11:59:08 -0800 Subject: [PATCH 09/18] model.lua now only returns newModel function --- README.md | 6 +++--- g3d/init.lua | 2 +- g3d/model.lua | 4 ++-- main.lua | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index ba19ef9..53439ca 100644 --- a/README.md +++ b/README.md @@ -40,9 +40,9 @@ The entire `main.lua` file for the Earth and Moon demo is under 30 lines, as sho g3d = require "g3d" function love.load() - Earth = g3d.model.new("assets/sphere.obj", "assets/earth.png", {0,0,4}, nil, {-1,1,1}) - Moon = g3d.model.new("assets/sphere.obj", "assets/moon.png", {5,0,4}, nil, {-0.5,0.5,0.5}) - Background = g3d.model.new("assets/sphere.obj", "assets/starfield.png", {0,0,0}, nil, {500,500,500}) + Earth = g3d.newModel("assets/sphere.obj", "assets/earth.png", {0,0,4}, nil, {-1,1,1}) + Moon = g3d.newModel("assets/sphere.obj", "assets/moon.png", {5,0,4}, nil, {-0.5,0.5,0.5}) + Background = g3d.newModel("assets/sphere.obj", "assets/starfield.png", {0,0,0}, nil, {500,500,500}) Timer = 0 end diff --git a/g3d/init.lua b/g3d/init.lua index c1ee00f..3a44455 100644 --- a/g3d/init.lua +++ b/g3d/init.lua @@ -20,7 +20,7 @@ G3D_PATH = ... local g3d = {} -g3d.model = require(G3D_PATH .. "/model") +g3d.newModel = require(G3D_PATH .. "/model") g3d.camera = require(G3D_PATH .. "/camera") g3d.camera.updateProjectionMatrix() diff --git a/g3d/model.lua b/g3d/model.lua index c70ca7d..3b61e25 100644 --- a/g3d/model.lua +++ b/g3d/model.lua @@ -25,7 +25,7 @@ model.__index = model -- this returns a new instance of the model class -- a model must be given a .obj file or equivalent lua table, and a texture -- translation, rotation, and scale are all 3d vectors and are all optional -function model.new(given, texture, translation, rotation, scale) +function newModel(given, texture, translation, rotation, scale) local self = setmetatable({}, model) -- if given is a string, use it as a path to a .obj file @@ -122,4 +122,4 @@ function model:draw() love.graphics.setShader() end -return model +return newModel diff --git a/main.lua b/main.lua index 766c433..96005c8 100644 --- a/main.lua +++ b/main.lua @@ -5,9 +5,9 @@ g3d = require "g3d" function love.load() - Earth = g3d.model.new("assets/sphere.obj", "assets/earth.png", {0,0,4}, nil, {-1,1,1}) - Moon = g3d.model.new("assets/sphere.obj", "assets/moon.png", {5,0,4}, nil, {-0.5,0.5,0.5}) - Background = g3d.model.new("assets/sphere.obj", "assets/starfield.png", {0,0,0}, nil, {500,500,500}) + Earth = g3d.newModel("assets/sphere.obj", "assets/earth.png", {0,0,4}, nil, {-1,1,1}) + Moon = g3d.newModel("assets/sphere.obj", "assets/moon.png", {5,0,4}, nil, {-0.5,0.5,0.5}) + Background = g3d.newModel("assets/sphere.obj", "assets/starfield.png", {0,0,0}, nil, {500,500,500}) Timer = 0 end From 1eb62229c7baa15282ae0e82ee4ed5dacea65d11 Mon Sep 17 00:00:00 2001 From: groverburger Date: Sun, 17 Jan 2021 12:17:23 -0800 Subject: [PATCH 10/18] renamed lookTowards to lookInDirection --- g3d/camera.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/g3d/camera.lua b/g3d/camera.lua index db878da..9281b62 100644 --- a/g3d/camera.lua +++ b/g3d/camera.lua @@ -41,7 +41,7 @@ function camera.lookAt(x,y,z, xAt,yAt,zAt) end -- move and rotate the camera, given a point and a direction and a pitch (vertical direction) -function camera.lookTowards(x,y,z, directionTowards,pitchTowards) +function camera.lookInDirection(x,y,z, directionTowards,pitchTowards) camera.position[1] = x camera.position[2] = y camera.position[3] = z @@ -121,7 +121,7 @@ function camera.firstPersonMovement(dt) -- update the camera's in the shader -- only if the camera moved, for a slight performance benefit if cameraMoved then - camera.lookTowards(camera.position[1],camera.position[2],camera.position[3], fpsController.direction,fpsController.pitch) + camera.lookInDirection(camera.position[1],camera.position[2],camera.position[3], fpsController.direction,fpsController.pitch) end end @@ -134,7 +134,7 @@ function camera.firstPersonLook(dx,dy) fpsController.direction = fpsController.direction + dx*sensitivity fpsController.pitch = math.max(math.min(fpsController.pitch - dy*sensitivity, math.pi*0.5), math.pi*-0.5) - camera.lookTowards(camera.position[1],camera.position[2],camera.position[3], fpsController.direction,fpsController.pitch) + camera.lookInDirection(camera.position[1],camera.position[2],camera.position[3], fpsController.direction,fpsController.pitch) end return camera From f8f1ac05552334d616e7ea9ef13fff395bbc87c9 Mon Sep 17 00:00:00 2001 From: groverburger Date: Sun, 17 Jan 2021 12:22:52 -0800 Subject: [PATCH 11/18] added camera.updateOrthographicMatrix --- g3d/camera.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/g3d/camera.lua b/g3d/camera.lua index 9281b62..2a36612 100644 --- a/g3d/camera.lua +++ b/g3d/camera.lua @@ -79,6 +79,12 @@ function camera.updateProjectionMatrix(shaderGiven) (shaderGiven or shader):send("projectionMatrix", matrices.getProjectionMatrix(camera.fov, camera.nearClip, camera.farClip, camera.aspectRatio)) end +-- recreate the camera's orthographic projection matrix from its current values +-- and send the matrix to the shader specified, or the default shader +function camera.updateOrthographicMatrix(size, shaderGiven) + (shaderGiven or shader):send("projectionMatrix", matrices.getOrthographicMatrix(camera.fov, size or 5, camera.nearClip, camera.farClip, camera.aspectRatio)) +end + -- simple first person camera movement with WASD -- put this local function in your love.update to use, passing in dt function camera.firstPersonMovement(dt) From 63e74bfc8cd6bc67d752e237f35b04b657a611ae Mon Sep 17 00:00:00 2001 From: groverburger Date: Sun, 17 Jan 2021 12:59:22 -0800 Subject: [PATCH 12/18] model:setScale can now take only one scalar --- g3d/model.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/g3d/model.lua b/g3d/model.lua index 3b61e25..1f39076 100644 --- a/g3d/model.lua +++ b/g3d/model.lua @@ -104,8 +104,8 @@ end -- resize model's matrix based on a given 3d vector function model:setScale(sx,sy,sz) self.scale[1] = sx - self.scale[2] = sy - self.scale[3] = sz + self.scale[2] = sy or sx + self.scale[3] = sz or sx self:updateMatrix() end From 5b4e04994325637759a59d73c8546f4087d98626 Mon Sep 17 00:00:00 2001 From: groverburger Date: Sun, 17 Jan 2021 12:59:36 -0800 Subject: [PATCH 13/18] main.lua uses new model:setScale scalar --- README.md | 5 +++-- main.lua | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 53439ca..069a2d7 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,9 @@ g3d = require "g3d" function love.load() Earth = g3d.newModel("assets/sphere.obj", "assets/earth.png", {0,0,4}, nil, {-1,1,1}) - Moon = g3d.newModel("assets/sphere.obj", "assets/moon.png", {5,0,4}, nil, {-0.5,0.5,0.5}) - Background = g3d.newModel("assets/sphere.obj", "assets/starfield.png", {0,0,0}, nil, {500,500,500}) + Moon = g3d.newModel("assets/sphere.obj", "assets/moon.png", nil, nil, {-0.5,0.5,0.5}) + Background = g3d.newModel("assets/sphere.obj", "assets/starfield.png") + Background:setScale(500) Timer = 0 end diff --git a/main.lua b/main.lua index 96005c8..28f24f7 100644 --- a/main.lua +++ b/main.lua @@ -6,8 +6,9 @@ g3d = require "g3d" function love.load() Earth = g3d.newModel("assets/sphere.obj", "assets/earth.png", {0,0,4}, nil, {-1,1,1}) - Moon = g3d.newModel("assets/sphere.obj", "assets/moon.png", {5,0,4}, nil, {-0.5,0.5,0.5}) - Background = g3d.newModel("assets/sphere.obj", "assets/starfield.png", {0,0,0}, nil, {500,500,500}) + Moon = g3d.newModel("assets/sphere.obj", "assets/moon.png", nil, nil, {-0.5,0.5,0.5}) + Background = g3d.newModel("assets/sphere.obj", "assets/starfield.png") + Background:setScale(500) Timer = 0 end From 712f41ec68cba2c7e029081a8d37b0585b3b35d6 Mon Sep 17 00:00:00 2001 From: groverburger Date: Sun, 17 Jan 2021 13:00:24 -0800 Subject: [PATCH 14/18] Revert "main.lua uses new model:setScale scalar" This reverts commit 5b4e04994325637759a59d73c8546f4087d98626. --- README.md | 5 ++--- main.lua | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 069a2d7..53439ca 100644 --- a/README.md +++ b/README.md @@ -41,9 +41,8 @@ g3d = require "g3d" function love.load() Earth = g3d.newModel("assets/sphere.obj", "assets/earth.png", {0,0,4}, nil, {-1,1,1}) - Moon = g3d.newModel("assets/sphere.obj", "assets/moon.png", nil, nil, {-0.5,0.5,0.5}) - Background = g3d.newModel("assets/sphere.obj", "assets/starfield.png") - Background:setScale(500) + Moon = g3d.newModel("assets/sphere.obj", "assets/moon.png", {5,0,4}, nil, {-0.5,0.5,0.5}) + Background = g3d.newModel("assets/sphere.obj", "assets/starfield.png", {0,0,0}, nil, {500,500,500}) Timer = 0 end diff --git a/main.lua b/main.lua index 28f24f7..96005c8 100644 --- a/main.lua +++ b/main.lua @@ -6,9 +6,8 @@ g3d = require "g3d" function love.load() Earth = g3d.newModel("assets/sphere.obj", "assets/earth.png", {0,0,4}, nil, {-1,1,1}) - Moon = g3d.newModel("assets/sphere.obj", "assets/moon.png", nil, nil, {-0.5,0.5,0.5}) - Background = g3d.newModel("assets/sphere.obj", "assets/starfield.png") - Background:setScale(500) + Moon = g3d.newModel("assets/sphere.obj", "assets/moon.png", {5,0,4}, nil, {-0.5,0.5,0.5}) + Background = g3d.newModel("assets/sphere.obj", "assets/starfield.png", {0,0,0}, nil, {500,500,500}) Timer = 0 end From db5cd2823a955a6d0de8cfdd1706decea5434f0b Mon Sep 17 00:00:00 2001 From: groverburger Date: Sun, 17 Jan 2021 15:41:05 -0800 Subject: [PATCH 15/18] removed newModel from _G --- g3d/model.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g3d/model.lua b/g3d/model.lua index 1f39076..e74f985 100644 --- a/g3d/model.lua +++ b/g3d/model.lua @@ -25,7 +25,7 @@ model.__index = model -- this returns a new instance of the model class -- a model must be given a .obj file or equivalent lua table, and a texture -- translation, rotation, and scale are all 3d vectors and are all optional -function newModel(given, texture, translation, rotation, scale) +local function newModel(given, texture, translation, rotation, scale) local self = setmetatable({}, model) -- if given is a string, use it as a path to a .obj file From 9b6edf39d1b6e2a4d6373cf5f0f2d844dad4ab2b Mon Sep 17 00:00:00 2001 From: groverburger Date: Sun, 17 Jan 2021 15:42:44 -0800 Subject: [PATCH 16/18] removed ugly parenthesis for vertex normal flipping --- g3d/model.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g3d/model.lua b/g3d/model.lua index e74f985..3fa4d17 100644 --- a/g3d/model.lua +++ b/g3d/model.lua @@ -61,7 +61,7 @@ function model:makeNormals(isFlipped) local vec1 = {v[1]-vp[1], v[2]-vp[2], v[3]-vp[3]} local vec2 = {vn[1]-v[1], vn[2]-v[2], vn[3]-v[3]} local normal = vectors.normalizeVector(vectors.crossProduct(vec1,vec2)) - local flippage = (isFlipped and -1 or 1) + local flippage = isFlipped and -1 or 1 vp[6] = normal[1] * flippage vp[7] = normal[2] * flippage From a5ab5be63b8ba1bd4cef7fdf9665248ef56a679f Mon Sep 17 00:00:00 2001 From: groverburger Date: Wed, 20 Jan 2021 13:50:42 -0800 Subject: [PATCH 17/18] added some more comments --- g3d/matrices.lua | 1 + g3d/model.lua | 2 ++ 2 files changed, 3 insertions(+) diff --git a/g3d/matrices.lua b/g3d/matrices.lua index 458ad3f..172fafc 100644 --- a/g3d/matrices.lua +++ b/g3d/matrices.lua @@ -114,6 +114,7 @@ end -- matrices are just 16 numbers in table, representing a 4x4 matrix -- an identity matrix is defined as {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1} +-- creates and returns a new identity matrix function matrices.getIdentityMatrix() return {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1} end diff --git a/g3d/model.lua b/g3d/model.lua index 3fa4d17..fd67dec 100644 --- a/g3d/model.lua +++ b/g3d/model.lua @@ -10,6 +10,8 @@ local loadObjFile = require(G3D_PATH .. "/objloader") -- define a model class ---------------------------------------------------------------------------------------------------- +-- define some default properties that every model should inherit +-- that being the standard vertexFormat and basic 3D shader local model = { vertexFormat = { {"VertexPosition", "float", 3}, From fddd93691592ab62b1f0c86c72c91bf8b72834a2 Mon Sep 17 00:00:00 2001 From: groverburger Date: Wed, 20 Jan 2021 14:06:13 -0800 Subject: [PATCH 18/18] fixed sphere UVs --- assets/sphere.obj | 495 +++++++++++++++++++++++----------------------- main.lua | 4 +- 2 files changed, 250 insertions(+), 249 deletions(-) diff --git a/assets/sphere.obj b/assets/sphere.obj index 4dc7472..0e73931 100644 --- a/assets/sphere.obj +++ b/assets/sphere.obj @@ -1,155 +1,155 @@ -# Blender v2.82 (sub 7) OBJ File: '' +# Blender v2.91.2 OBJ File: '' # www.blender.org -mtllib skybox.mtl +mtllib sphere.mtl o Sphere v 0.000000 -0.900969 -0.433884 -v 0.000000 -1.000000 -0.000000 -v -0.000000 1.000000 -0.000000 -v 0.255030 0.900969 -0.351019 -v 0.459549 0.623490 -0.632515 -v 0.573048 0.222521 -0.788733 -v 0.573048 -0.222521 -0.788733 v 0.459549 -0.623490 -0.632515 v 0.255030 -0.900969 -0.351019 -v 0.412648 0.900969 -0.134078 -v 0.743566 0.623490 -0.241599 -v 0.927211 0.222521 -0.301269 +v 0.000000 0.222521 -0.974928 +v 0.573048 -0.222521 -0.788733 +v 0.000000 -0.222521 -0.974928 +v 0.000000 0.900969 -0.433884 +v 0.459549 0.623490 -0.632515 +v 0.000000 0.623490 -0.781832 +v 0.000000 -1.000000 -0.000000 +v 0.000000 -0.623490 -0.781832 +v 0.573048 0.222521 -0.788733 +v 0.000000 1.000000 0.000000 +v 0.255030 0.900969 -0.351019 +v 0.412648 -0.900969 -0.134078 v 0.927211 -0.222521 -0.301269 +v 0.743566 0.623490 -0.241599 v 0.743566 -0.623490 -0.241599 -v 0.412648 -0.900969 -0.134078 +v 0.927211 0.222521 -0.301269 +v 0.412648 0.900969 -0.134078 +v 0.412648 -0.900969 0.134077 +v 0.927211 -0.222521 0.301269 v 0.412648 0.900969 0.134077 v 0.743566 0.623490 0.241599 -v 0.927211 0.222521 0.301269 -v 0.927211 -0.222521 0.301269 v 0.743566 -0.623490 0.241599 -v 0.412648 -0.900969 0.134077 -v 0.255030 0.900969 0.351019 +v 0.927211 0.222521 0.301269 v 0.459549 0.623490 0.632515 +v 0.255030 -0.900969 0.351019 +v 0.459549 -0.623490 0.632515 v 0.573048 0.222521 0.788733 +v 0.255030 0.900969 0.351019 v 0.573048 -0.222521 0.788733 -v 0.459549 -0.623490 0.632515 -v 0.255030 -0.900969 0.351019 +v 0.000000 -0.900969 0.433883 +v 0.000000 -0.623490 0.781831 +v 0.000000 0.222521 0.974928 v 0.000000 0.900969 0.433883 +v 0.000000 -0.222521 0.974928 v 0.000000 0.623490 0.781831 -v -0.000000 0.222521 0.974928 -v -0.000000 -0.222521 0.974928 -v 0.000000 -0.623490 0.781831 -v 0.000000 -0.900969 0.433883 -v -0.255030 0.900969 0.351019 -v -0.459549 0.623490 0.632515 -v -0.573048 0.222521 0.788733 -v -0.573048 -0.222521 0.788733 v -0.459549 -0.623490 0.632515 +v -0.573048 0.222521 0.788733 +v -0.255030 0.900969 0.351019 v -0.255030 -0.900969 0.351019 +v -0.573048 -0.222521 0.788733 +v -0.459549 0.623490 0.632515 v -0.412648 0.900969 0.134077 -v -0.743566 0.623490 0.241599 -v -0.927212 0.222521 0.301269 -v -0.927212 -0.222521 0.301269 v -0.743566 -0.623490 0.241599 v -0.412648 -0.900969 0.134077 -v -0.412648 0.900969 -0.134078 -v -0.743566 0.623490 -0.241599 -v -0.927212 0.222521 -0.301269 +v -0.927212 -0.222521 0.301269 +v -0.743566 0.623490 0.241599 +v -0.927212 0.222521 0.301269 +v -0.412648 -0.900969 -0.134078 v -0.927212 -0.222521 -0.301269 +v -0.743566 0.623490 -0.241599 v -0.743566 -0.623490 -0.241599 -v -0.412648 -0.900969 -0.134078 -v -0.255030 0.900969 -0.351019 -v -0.459549 0.623490 -0.632515 -v -0.573048 0.222521 -0.788733 +v -0.927212 0.222521 -0.301269 +v -0.412648 0.900969 -0.134078 v -0.573048 -0.222521 -0.788733 -v -0.459549 -0.623490 -0.632515 +v -0.459549 0.623490 -0.632515 v -0.255030 -0.900969 -0.351019 -v 0.000000 0.900969 -0.433884 -v -0.000000 0.623490 -0.781832 -v -0.000000 0.222521 -0.974928 -v -0.000000 -0.222521 -0.974928 -v -0.000000 -0.623490 -0.781832 -vt 0.700000 0.142857 -vt 0.600000 0.285714 -vt 0.600000 0.142857 -vt 0.700000 0.571429 -vt 0.600000 0.428571 -vt 0.700000 0.428571 -vt 0.700000 0.857143 -vt 0.600000 0.714286 -vt 0.700000 0.714286 -vt 0.650000 0.000000 -vt 0.700000 0.285714 -vt 0.600000 0.571429 -vt 0.650000 1.000000 -vt 0.600000 0.857143 -vt 0.500000 0.142857 -vt 0.500000 0.428571 -vt 0.500000 0.714286 -vt 0.550000 0.000000 -vt 0.500000 0.285714 -vt 0.500000 0.571429 -vt 0.550000 1.000000 -vt 0.500000 0.857143 +v -0.459549 -0.623490 -0.632515 +v -0.573048 0.222521 -0.788733 +v -0.255030 0.900969 -0.351019 +vt 0.300000 0.142857 +vt 0.400000 0.285714 vt 0.400000 0.142857 +vt 0.300000 0.571429 vt 0.400000 0.428571 -vt 0.400000 0.857143 +vt 0.300000 0.428571 +vt 0.300000 0.857143 vt 0.400000 0.714286 -vt 0.450000 0.000000 -vt 0.400000 0.285714 -vt 0.400000 0.571429 -vt 0.450000 1.000000 vt 0.300000 0.714286 vt 0.350000 0.000000 -vt 0.300000 0.142857 vt 0.300000 0.285714 -vt 0.300000 0.571429 +vt 0.400000 0.571429 vt 0.350000 1.000000 -vt 0.300000 0.857143 -vt 0.300000 0.428571 -vt 0.250000 0.000000 -vt 0.200000 0.142857 -vt 0.200000 0.285714 -vt 0.200000 0.571429 -vt 0.250000 1.000000 -vt 0.200000 0.857143 -vt 0.200000 0.428571 -vt 0.200000 0.714286 -vt 0.100000 0.285714 -vt 0.100000 0.571429 -vt 0.150000 1.000000 -vt 0.100000 0.857143 -vt 0.100000 0.142857 -vt 0.100000 0.428571 -vt 0.100000 0.714286 -vt 0.150000 0.000000 -vt 0.050000 1.000000 -vt 0.000000 0.857143 -vt 0.000000 0.285714 -vt 0.000000 0.142857 -vt 0.000000 0.428571 -vt 0.000000 0.714286 -vt 0.050000 0.000000 -vt 0.000000 0.571429 -vt 1.000000 0.285714 +vt 0.400000 0.857143 +vt 0.500000 0.142857 +vt 0.500000 0.428571 +vt 0.500000 0.714286 +vt 0.450000 0.000000 +vt 0.500000 0.285714 +vt 0.500000 0.571429 +vt 0.450000 1.000000 +vt 0.500000 0.857143 +vt 0.600000 0.142857 +vt 0.600000 0.428571 +vt 0.600000 0.857143 +vt 0.600000 0.714286 +vt 0.550000 0.000000 +vt 0.600000 0.285714 +vt 0.600000 0.571429 +vt 0.550000 1.000000 +vt 0.700000 0.714286 +vt 0.650000 0.000000 +vt 0.700000 0.142857 +vt 0.700000 0.285714 +vt 0.700000 0.571429 +vt 0.650000 1.000000 +vt 0.700000 0.857143 +vt 0.700000 0.428571 +vt 0.750000 0.000000 +vt 0.800000 0.142857 +vt 0.800000 0.285714 +vt 0.800000 0.571429 +vt 0.750000 1.000000 +vt 0.800000 0.857143 +vt 0.800000 0.428571 +vt 0.800000 0.714286 +vt 0.900000 0.285714 +vt 0.900000 0.571429 +vt 0.850000 1.000000 +vt 0.900000 0.857143 vt 0.900000 0.142857 -vt 1.000000 0.142857 -vt 1.000000 0.571429 vt 0.900000 0.428571 -vt 1.000000 0.428571 -vt 1.000000 0.857143 vt 0.900000 0.714286 +vt 0.850000 0.000000 +vt 0.950000 1.000000 +vt 1.000000 0.857143 +vt 1.000000 0.285714 +vt 1.000000 0.142857 +vt 1.000000 0.428571 vt 1.000000 0.714286 vt 0.950000 0.000000 -vt 0.900000 0.285714 -vt 0.900000 0.571429 -vt 0.950000 1.000000 -vt 0.900000 0.857143 -vt 0.800000 0.428571 -vt 0.800000 0.714286 -vt 0.850000 0.000000 -vt 0.800000 0.142857 -vt 0.800000 0.285714 -vt 0.800000 0.571429 -vt 0.850000 1.000000 -vt 0.800000 0.857143 -vt 0.750000 0.000000 -vt 0.750000 1.000000 +vt 1.000000 0.571429 +vt 0.000000 0.285714 +vt 0.100000 0.142857 +vt 0.000000 0.142857 +vt 0.000000 0.571429 +vt 0.100000 0.428571 +vt 0.000000 0.428571 +vt 0.000000 0.857143 +vt 0.100000 0.714286 +vt 0.000000 0.714286 +vt 0.050000 0.000000 +vt 0.100000 0.285714 +vt 0.100000 0.571429 +vt 0.050000 1.000000 +vt 0.100000 0.857143 +vt 0.200000 0.428571 +vt 0.200000 0.714286 +vt 0.150000 0.000000 +vt 0.200000 0.142857 +vt 0.200000 0.285714 +vt 0.200000 0.571429 +vt 0.150000 1.000000 +vt 0.200000 0.857143 +vt 0.250000 0.000000 +vt 0.250000 1.000000 vn 0.1986 -0.7663 -0.6111 vn 0.3090 0.0000 -0.9511 vn 0.1986 0.7663 -0.6111 @@ -164,12 +164,12 @@ vn 0.1888 -0.9724 -0.1372 vn 0.7355 -0.4164 -0.5344 vn 0.7355 0.4164 -0.5344 vn 0.1888 0.9724 -0.1372 -vn 0.6425 -0.7663 0.0000 -vn 1.0000 0.0000 -0.0000 -vn 0.6425 0.7663 -0.0000 +vn 0.6425 -0.7663 -0.0000 +vn 1.0000 -0.0000 0.0000 +vn 0.6425 0.7663 0.0000 vn 0.2334 -0.9724 0.0000 vn 0.9092 -0.4164 -0.0000 -vn 0.9092 0.4164 -0.0000 +vn 0.9092 0.4164 0.0000 vn 0.2334 0.9724 0.0000 vn 0.5198 0.7663 0.3777 vn 0.1888 -0.9724 0.1372 @@ -177,33 +177,33 @@ vn 0.7355 -0.4164 0.5344 vn 0.7355 0.4164 0.5344 vn 0.1888 0.9724 0.1372 vn 0.5198 -0.7663 0.3777 -vn 0.8090 0.0000 0.5878 +vn 0.8090 -0.0000 0.5878 vn 0.0721 -0.9724 0.2219 vn 0.2810 -0.4164 0.8647 vn 0.2810 0.4164 0.8647 vn 0.0721 0.9724 0.2219 vn 0.1986 -0.7663 0.6111 -vn 0.3090 0.0000 0.9511 +vn 0.3090 -0.0000 0.9511 vn 0.1986 0.7663 0.6111 vn -0.2810 -0.4164 0.8647 vn -0.2810 0.4164 0.8647 vn -0.0721 0.9724 0.2219 vn -0.1986 -0.7663 0.6111 -vn -0.3090 0.0000 0.9511 +vn -0.3090 -0.0000 0.9511 vn -0.1986 0.7663 0.6111 vn -0.0721 -0.9724 0.2219 vn -0.1888 0.9724 0.1372 vn -0.5198 -0.7663 0.3777 -vn -0.8090 0.0000 0.5878 +vn -0.8090 -0.0000 0.5878 vn -0.5198 0.7663 0.3777 vn -0.1888 -0.9724 0.1372 vn -0.7355 -0.4164 0.5344 vn -0.7355 0.4164 0.5344 -vn -0.6425 -0.7663 0.0000 +vn -0.6425 -0.7663 -0.0000 vn -1.0000 0.0000 0.0000 vn -0.6425 0.7663 0.0000 vn -0.2334 -0.9724 0.0000 -vn -0.9092 -0.4164 0.0000 +vn -0.9092 -0.4164 -0.0000 vn -0.9092 0.4164 0.0000 vn -0.2334 0.9724 0.0000 vn -0.8090 0.0000 -0.5878 @@ -220,125 +220,126 @@ vn -0.0721 0.9724 -0.2219 vn -0.1986 -0.7663 -0.6111 vn -0.3090 0.0000 -0.9511 vn -0.1986 0.7663 -0.6111 +vn 0.1985 -0.7663 0.6111 usemtl Material.001 -s off -f 1/1/1 8/2/1 9/3/1 -f 60/4/2 7/5/2 61/6/2 -f 58/7/3 5/8/3 59/9/3 -f 2/10/4 1/1/4 9/3/4 -f 61/6/5 8/2/5 62/11/5 -f 59/9/6 6/12/6 60/4/6 -f 58/7/7 3/13/7 4/14/7 -f 8/2/8 15/15/8 9/3/8 -f 6/12/9 13/16/9 7/5/9 -f 4/14/10 11/17/10 5/8/10 -f 2/18/11 9/3/11 15/15/11 -f 7/5/12 14/19/12 8/2/12 -f 5/8/13 12/20/13 6/12/13 -f 4/14/14 3/21/14 10/22/14 -f 14/19/15 21/23/15 15/15/15 -f 12/20/16 19/24/16 13/16/16 -f 11/17/17 16/25/17 17/26/17 -f 2/27/18 15/15/18 21/23/18 -f 13/16/19 20/28/19 14/19/19 -f 11/17/20 18/29/20 12/20/20 -f 10/22/21 3/30/21 16/25/21 -f 16/25/22 23/31/22 17/26/22 -f 2/32/23 21/23/23 27/33/23 -f 19/24/24 26/34/24 20/28/24 -f 17/26/25 24/35/25 18/29/25 -f 16/25/26 3/36/26 22/37/26 -f 20/28/27 27/33/27 21/23/27 -f 18/29/28 25/38/28 19/24/28 -f 2/39/29 27/33/29 33/40/29 -f 25/38/30 32/41/30 26/34/30 -f 23/31/31 30/42/31 24/35/31 -f 22/37/32 3/43/32 28/44/32 -f 26/34/33 33/40/33 27/33/33 -f 24/35/34 31/45/34 25/38/34 -f 22/37/35 29/46/35 23/31/35 -f 31/45/36 38/47/36 32/41/36 -f 29/46/37 36/48/37 30/42/37 -f 28/44/38 3/49/38 34/50/38 -f 32/41/39 39/51/39 33/40/39 -f 30/42/40 37/52/40 31/45/40 -f 28/44/41 35/53/41 29/46/41 -f 2/54/42 33/40/42 39/51/42 -f 34/50/43 3/55/43 40/56/43 -f 39/51/44 44/57/44 45/58/44 -f 36/48/45 43/59/45 37/52/45 -f 34/50/46 41/60/46 35/53/46 -f 2/61/47 39/51/47 45/58/47 -f 37/52/48 44/57/48 38/47/48 -f 35/53/49 42/62/49 36/48/49 -f 44/63/50 51/64/50 45/65/50 -f 42/66/51 49/67/51 43/68/51 -f 40/69/52 47/70/52 41/71/52 -f 2/72/53 45/65/53 51/64/53 -f 43/68/54 50/73/54 44/63/54 -f 41/71/55 48/74/55 42/66/55 -f 40/69/56 3/75/56 46/76/56 -f 48/74/57 55/77/57 49/67/57 -f 46/76/58 53/78/58 47/70/58 -f 2/79/59 51/64/59 57/80/59 -f 49/67/60 56/81/60 50/73/60 -f 47/70/61 54/82/61 48/74/61 -f 46/76/62 3/83/62 52/84/62 -f 50/73/63 57/80/63 51/64/63 -f 2/85/64 57/80/64 1/1/64 -f 55/77/65 62/11/65 56/81/65 -f 53/78/66 60/4/66 54/82/66 -f 52/84/67 3/86/67 58/7/67 -f 56/81/68 1/1/68 57/80/68 -f 54/82/69 61/6/69 55/77/69 -f 52/84/70 59/9/70 53/78/70 -f 1/1/1 62/11/1 8/2/1 -f 60/4/2 6/12/2 7/5/2 -f 58/7/3 4/14/3 5/8/3 -f 61/6/5 7/5/5 8/2/5 -f 59/9/6 5/8/6 6/12/6 -f 8/2/8 14/19/8 15/15/8 -f 6/12/9 12/20/9 13/16/9 -f 4/14/10 10/22/10 11/17/10 -f 7/5/12 13/16/12 14/19/12 -f 5/8/13 11/17/13 12/20/13 -f 14/19/15 20/28/15 21/23/15 -f 12/20/16 18/29/16 19/24/16 -f 11/17/17 10/22/17 16/25/17 -f 13/16/19 19/24/19 20/28/19 -f 11/17/20 17/26/20 18/29/20 -f 16/25/22 22/37/22 23/31/22 -f 19/24/24 25/38/24 26/34/24 -f 17/26/25 23/31/25 24/35/25 -f 20/28/27 26/34/27 27/33/27 -f 18/29/28 24/35/28 25/38/28 -f 25/38/30 31/45/30 32/41/30 -f 23/31/31 29/46/31 30/42/31 -f 26/34/33 32/41/33 33/40/33 -f 24/35/34 30/42/34 31/45/34 -f 22/37/35 28/44/35 29/46/35 -f 31/45/36 37/52/36 38/47/36 -f 29/46/37 35/53/37 36/48/37 -f 32/41/39 38/47/39 39/51/39 -f 30/42/40 36/48/40 37/52/40 -f 28/44/41 34/50/41 35/53/41 -f 39/51/44 38/47/44 44/57/44 -f 36/48/45 42/62/45 43/59/45 -f 34/50/46 40/56/46 41/60/46 -f 37/52/48 43/59/48 44/57/48 -f 35/53/49 41/60/49 42/62/49 -f 44/63/50 50/73/50 51/64/50 -f 42/66/51 48/74/51 49/67/51 -f 40/69/52 46/76/52 47/70/52 -f 43/68/54 49/67/54 50/73/54 -f 41/71/55 47/70/55 48/74/55 -f 48/74/57 54/82/57 55/77/57 -f 46/76/58 52/84/58 53/78/58 -f 49/67/60 55/77/60 56/81/60 -f 47/70/61 53/78/61 54/82/61 -f 50/73/63 56/81/63 57/80/63 -f 55/77/65 61/6/65 62/11/65 -f 53/78/66 59/9/66 60/4/66 -f 56/81/68 62/11/68 1/1/68 -f 54/82/69 60/4/69 61/6/69 -f 52/84/70 58/7/70 59/9/70 +s 1 +f 1/1/1 2/2/1 3/3/1 +f 4/4/2 5/5/2 6/6/2 +f 7/7/3 8/8/3 9/9/3 +f 10/10/4 1/1/4 3/3/4 +f 6/6/5 2/2/5 11/11/5 +f 9/9/6 12/12/6 4/4/6 +f 7/7/7 13/13/7 14/14/7 +f 2/2/8 15/15/8 3/3/8 +f 12/12/9 16/16/9 5/5/9 +f 14/14/10 17/17/10 8/8/10 +f 10/18/11 3/3/11 15/15/11 +f 5/5/12 18/19/12 2/2/12 +f 8/8/13 19/20/13 12/12/13 +f 14/14/14 13/21/14 20/22/14 +f 18/19/15 21/23/15 15/15/15 +f 19/20/16 22/24/16 16/16/16 +f 17/17/17 23/25/17 24/26/17 +f 10/27/18 15/15/18 21/23/18 +f 16/16/19 25/28/19 18/19/19 +f 17/17/20 26/29/20 19/20/20 +f 20/22/21 13/30/21 23/25/21 +f 23/25/22 27/31/22 24/26/22 +f 10/32/23 21/23/23 28/33/23 +f 22/24/24 29/34/24 25/28/24 +f 24/26/25 30/35/25 26/29/25 +f 23/25/26 13/36/26 31/37/26 +f 25/28/27 28/33/27 21/23/27 +f 26/29/28 32/38/28 22/24/28 +f 10/39/29 28/33/29 33/40/29 +f 32/38/30 34/41/30 29/34/30 +f 27/31/31 35/42/31 30/35/31 +f 31/37/32 13/43/32 36/44/32 +f 29/34/33 33/40/33 28/33/33 +f 30/35/34 37/45/34 32/38/34 +f 31/37/35 38/46/35 27/31/35 +f 37/45/36 39/47/36 34/41/36 +f 38/46/37 40/48/37 35/42/37 +f 36/44/38 13/49/38 41/50/38 +f 34/41/39 42/51/39 33/40/39 +f 35/42/40 43/52/40 37/45/40 +f 36/44/41 44/53/41 38/46/41 +f 10/54/42 33/40/42 42/51/42 +f 41/50/43 13/55/43 45/56/43 +f 42/51/44 46/57/44 47/58/44 +f 40/48/45 48/59/45 43/52/45 +f 41/50/46 49/60/46 44/53/46 +f 10/61/47 42/51/47 47/58/47 +f 43/52/48 46/57/48 39/47/48 +f 44/53/49 50/62/49 40/48/49 +f 46/63/50 51/64/50 47/65/50 +f 50/66/51 52/67/51 48/68/51 +f 45/69/52 53/70/52 49/71/52 +f 10/72/53 47/65/53 51/64/53 +f 48/68/54 54/73/54 46/63/54 +f 49/71/55 55/74/55 50/66/55 +f 45/69/56 13/75/56 56/76/56 +f 55/74/57 57/77/57 52/67/57 +f 56/76/58 58/78/58 53/70/58 +f 10/79/59 51/64/59 59/80/59 +f 52/67/60 60/81/60 54/73/60 +f 53/70/61 61/82/61 55/74/61 +f 56/76/62 13/83/62 62/84/62 +f 54/73/63 59/80/63 51/64/63 +f 10/85/64 59/80/64 1/1/64 +f 57/77/65 11/11/65 60/81/65 +f 58/78/66 4/4/66 61/82/66 +f 62/84/67 13/86/67 7/7/67 +f 60/81/68 1/1/68 59/80/68 +f 61/82/69 6/6/69 57/77/69 +f 62/84/70 9/9/70 58/78/70 +f 1/1/1 11/11/1 2/2/1 +f 4/4/2 12/12/2 5/5/2 +f 7/7/3 14/14/3 8/8/3 +f 6/6/5 5/5/5 2/2/5 +f 9/9/6 8/8/6 12/12/6 +f 2/2/8 18/19/8 15/15/8 +f 12/12/9 19/20/9 16/16/9 +f 14/14/10 20/22/10 17/17/10 +f 5/5/12 16/16/12 18/19/12 +f 8/8/13 17/17/13 19/20/13 +f 18/19/15 25/28/15 21/23/15 +f 19/20/16 26/29/16 22/24/16 +f 17/17/17 20/22/17 23/25/17 +f 16/16/19 22/24/19 25/28/19 +f 17/17/20 24/26/20 26/29/20 +f 23/25/22 31/37/22 27/31/22 +f 22/24/24 32/38/24 29/34/24 +f 24/26/25 27/31/25 30/35/25 +f 25/28/27 29/34/27 28/33/27 +f 26/29/28 30/35/28 32/38/28 +f 32/38/30 37/45/30 34/41/30 +f 27/31/31 38/46/31 35/42/31 +f 29/34/33 34/41/71 33/40/33 +f 30/35/34 35/42/34 37/45/34 +f 31/37/35 36/44/35 38/46/35 +f 37/45/36 43/52/36 39/47/36 +f 38/46/37 44/53/37 40/48/37 +f 34/41/39 39/47/39 42/51/39 +f 35/42/40 40/48/40 43/52/40 +f 36/44/41 41/50/41 44/53/41 +f 42/51/44 39/47/44 46/57/44 +f 40/48/45 50/62/45 48/59/45 +f 41/50/46 45/56/46 49/60/46 +f 43/52/48 48/59/48 46/57/48 +f 44/53/49 49/60/49 50/62/49 +f 46/63/50 54/73/50 51/64/50 +f 50/66/51 55/74/51 52/67/51 +f 45/69/52 56/76/52 53/70/52 +f 48/68/54 52/67/54 54/73/54 +f 49/71/55 53/70/55 55/74/55 +f 55/74/57 61/82/57 57/77/57 +f 56/76/58 62/84/58 58/78/58 +f 52/67/60 57/77/60 60/81/60 +f 53/70/61 58/78/61 61/82/61 +f 54/73/63 60/81/63 59/80/63 +f 57/77/65 6/6/65 11/11/65 +f 58/78/66 9/9/66 4/4/66 +f 60/81/68 11/11/68 1/1/68 +f 61/82/69 4/4/69 6/6/69 +f 62/84/70 7/7/70 9/9/70 diff --git a/main.lua b/main.lua index 96005c8..8ca5b99 100644 --- a/main.lua +++ b/main.lua @@ -5,8 +5,8 @@ g3d = require "g3d" function love.load() - Earth = g3d.newModel("assets/sphere.obj", "assets/earth.png", {0,0,4}, nil, {-1,1,1}) - Moon = g3d.newModel("assets/sphere.obj", "assets/moon.png", {5,0,4}, nil, {-0.5,0.5,0.5}) + Earth = g3d.newModel("assets/sphere.obj", "assets/earth.png", {0,0,4}) + Moon = g3d.newModel("assets/sphere.obj", "assets/moon.png", {5,0,4}, nil, {0.5,0.5,0.5}) Background = g3d.newModel("assets/sphere.obj", "assets/starfield.png", {0,0,0}, nil, {500,500,500}) Timer = 0 end