diff --git a/README.md b/README.md index ef69431..7fe1c22 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ groverburger's 3D engine (g3d) simplifies [LÖVE](http://love2d.org)'s 3d capabi - .obj file loading - Basic first person movement and camera controls - Perspective and orthographic projections -- Functions for simple collision handling - Simple, commented, and organized ## Installation @@ -60,3 +59,9 @@ end - Use basic first person movement with `FirstPersonCameraMovement(dt)` and `FirstPersonCameraLook(dx,dy)` For more information, check out the `model.lua` and `camera.lua` files. + +## Collision Detection + +Please use the [CPML](https://github.com/excessive/cpml) library or refer to [3DreamEngine](https://github.com/3dreamengine/3DreamEngine) for their 3D collision code. +Mozilla also has a [nice article](https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_collision_detection) on basic 3D collision detection. +g3d no longer offers collision detection, instead focusing only on making 3D rendering as simple as possible. diff --git a/g3d/matrices.lua b/g3d/matrices.lua index 3e5d73b..98969a6 100644 --- a/g3d/matrices.lua +++ b/g3d/matrices.lua @@ -62,6 +62,7 @@ function GetProjectionMatrix(fov, near, far, aspectRatio) local bottom = -1*top local right = top * aspectRatio local left = -1*right + return { 2*near/(right-left), 0, (right+left)/(right-left), 0, 0, 2*near/(top-bottom), (top+bottom)/(top-bottom), 0, @@ -79,6 +80,7 @@ function GetOrthoMatrix(fov, size, near, far, aspectRatio) local bottom = -1*top local right = top * aspectRatio local left = -1*right + return { 2/(right-left), 0, 0, -1*(right+left)/(right-left), 0, 2/(top-bottom), 0, -1*(top+bottom)/(top-bottom), @@ -175,62 +177,3 @@ function TransposeMatrix(m) GetMatrixXY(m, 4,1), GetMatrixXY(m, 4,2), GetMatrixXY(m, 4,3), GetMatrixXY(m, 4,4), } end - ----------------------------------------------------------------------------------------------------- --- detect collisions between a model and a vector ----------------------------------------------------------------------------------------------------- --- these functions are used for the Model:vectorIntersection function - -local function subtractVector(v1,v2,v3, v4,v5,v6) - return v1-v4, v2-v5, v3-v6 -end -local function crossProd(a1,a2,a3, b1,b2,b3) - return a2*b3 - a3*b2, a3*b1 - a1*b3, a1*b2 - a2*b1 -end -local function dotProd(a1,a2,a3, b1,b2,b3) - return a1*b1 + a2*b2 + a3*b3 -end -local DBL_EPSILON = 2.2204460492503131e-16 - --- taken and modified for efficiency from Cirno's Perfect Math Library --- using just numbers and not vector tables for efficiency -function FastRayTriangle(p1,p2,p3, d1,d2,d3, t11,t12,t13,t21,t22,t23,t31,t32,t33) - local e11,e12,e13 = subtractVector(t21,t22,t23, t11,t12,t13) - local e21,e22,e23 = subtractVector(t31,t32,t33, t11,t12,t13) - local h1,h2,h3 = crossProd(d1,d2,d3, e21,e22,e23) - local a = dotProd(h1,h2,h3, e11,e12,e13) - - -- if a is too close to 0, ray does not intersect triangle - if math.abs(a) <= DBL_EPSILON then - return false - end - - local f = 1 / a - local s1,s2,s3 = subtractVector(p1,p2,p3, t11,t12,t13) - local u = dotProd(s1,s2,s3, h1,h2,h3) * f - - -- ray does not intersect triangle - if u < 0 or u > 1 then - return false - end - - local q1,q2,q3 = crossProd(s1,s2,s3, e11,e12,e13) - local v = dotProd(d1,d2,d3, q1,q2,q3) * f - - -- ray does not intersect triangle - if v < 0 or u + v > 1 then - return false - end - - -- at this stage we can compute t to find out where - -- the intersection point is on the line - local t = dotProd(q1,q2,q3, e21,e22,e23) * f - - -- return position of intersection and distance from ray origin - if t >= DBL_EPSILON then - return t, p1 + d1*t,p2 + d2*t,p3 + d3*t - end - - -- ray does not intersect triangle - return false -end diff --git a/g3d/model.lua b/g3d/model.lua index c4ee07e..48d0e00 100644 --- a/g3d/model.lua +++ b/g3d/model.lua @@ -107,45 +107,3 @@ function Model:draw() love.graphics.draw(self.mesh) love.graphics.setShader() end - -local function dotProd(a1,a2,a3, b1,b2,b3) - return a1*b1 + a2*b2 + a3*b3 -end - --- check if a vector has collided with this model --- takes two 3d vectors as arguments, sourcePoint and directionVector --- returns length of vector from sourcePoint to collisionPoint --- and returns the collisionPoint --- length will be nil if no collision was found --- this function is useful for building game physics -function Model:vectorIntersection(sourcePoint, directionVector) - local length = nil - local where = {} - - for v=1, #self.verts, 3 do - if dotProd(self.verts[v][6],self.verts[v][7],self.verts[v][8], directionVector[1],directionVector[2],directionVector[3]) < 0 then - - local this, w1,w2,w3 = FastRayTriangle(sourcePoint[1],sourcePoint[2],sourcePoint[3], - directionVector[1],directionVector[2],directionVector[3], - self.verts[v][1] + self.translation[1], - self.verts[v][2] + self.translation[2], - self.verts[v][3] + self.translation[3], - self.verts[v+1][1] + self.translation[1], - self.verts[v+1][2] + self.translation[2], - self.verts[v+1][3] + self.translation[3], - self.verts[v+2][1] + self.translation[1], - self.verts[v+2][2] + self.translation[2], - self.verts[v+2][3] + self.translation[3] - ) - - if this then - if not length or length > this then - length = this - where = {w1,w2,w3} - end - end - end - end - - return length, where -end