Last active
April 22, 2024 09:51
-
-
Save MrChickenRocket/09050693faee256888313c04d93cbb08 to your computer and use it in GitHub Desktop.
Revisions
-
MrChickenRocket revised this gist
Feb 9, 2023 . 1 changed file with 36 additions and 72 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,91 +1,55 @@ local Frustum = {} local function planeFromPoints(p0, p1, p2) local normal = (p1 - p0):Cross(p2 - p1).Unit return { normal = normal, d = -normal:Dot(p0), } end function Frustum.sphereInFrustum(frustum, origin, radius) for _, plane in frustum do local distance = origin:Dot(plane.normal) + plane.d + radius if distance <= 0 then return false end end return true end function Frustum.fromCamera(camera, farPlaneZ) local aspectRatio = camera.ViewportSize.X / camera.ViewportSize.Y local halfFov = math.rad(camera.FieldOfView / 2) local halfFarPlaneHeight = 2 * math.tan(halfFov) * farPlaneZ / 2 local halfFarPlaneWidth = halfFarPlaneHeight * aspectRatio local halfNearPlaneHeight = 2 * math.tan(halfFov) * -camera.NearPlaneZ / 2 local halfNearPlaneWidth = halfNearPlaneHeight * aspectRatio local farTopLeft = camera.CFrame * Vector3.new(-halfFarPlaneWidth, halfFarPlaneHeight, -farPlaneZ) local farTopRight = camera.CFrame * Vector3.new(halfFarPlaneWidth, halfFarPlaneHeight, -farPlaneZ) local farBottomRight = camera.CFrame * Vector3.new(halfFarPlaneWidth, -halfFarPlaneHeight, -farPlaneZ) local nearTopLeft = camera.CFrame * Vector3.new(-halfNearPlaneWidth, halfNearPlaneHeight, camera.NearPlaneZ) local nearTopRight = camera.CFrame * Vector3.new(halfNearPlaneWidth, halfNearPlaneHeight, camera.NearPlaneZ) local nearBottomLeft = camera.CFrame * Vector3.new(-halfNearPlaneWidth, -halfNearPlaneHeight, camera.NearPlaneZ) local nearBottomRight = camera.CFrame * Vector3.new(halfNearPlaneWidth, -halfNearPlaneHeight, camera.NearPlaneZ) local frustum = {} frustum.near = planeFromPoints(nearTopRight, nearBottomRight, nearTopLeft) frustum.far = planeFromPoints(farTopRight, farTopLeft, farBottomRight) frustum.top = planeFromPoints(nearTopRight, nearTopLeft, farTopRight) frustum.bottom = planeFromPoints(nearBottomRight, farBottomRight, nearBottomLeft) frustum.left = planeFromPoints(nearTopLeft, nearBottomLeft, farTopLeft) frustum.right = planeFromPoints(nearTopRight, farTopRight, nearBottomRight) return frustum end return Frustum -
MrChickenRocket revised this gist
Feb 8, 2023 . 1 changed file with 25 additions and 16 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -30,21 +30,30 @@ function module:IsSphereVisible(planes, worldPoint, radius) end --Not really tested this, think its correct :D function module:IsAABBVisible(planes, aabbMin, aabbMax) local result = "INSIDE" for i = 1, #planes do local plane = planes[i] local nx = plane.normal.x > 0 local ny = plane.normal.y > 0 local nz = plane.normal.z > 0 local dot = plane.normal:Dot(Vector3:new{x = (nx == 1 and aabbMax.x or aabbMin.x), y = (ny == 1 and aabbMax.y or aabbMin.y), z = (nz == 1 and aabbMax.z or aabbMin.z)}) if dot < -plane.offset then return "OUTSIDE" end local dot2 = plane.normal:Dot(Vector3:new{x = (nx == 0 and aabbMax.x or aabbMin.x), y = (ny == 0 and aabbMax.y or aabbMin.y), z = (nz == 0 and aabbMax.z or aabbMin.z)}) if dot2 <= -plane.offset then result = "INTERSECTS" end end return result end function module:MakePlanes(camera, farDist) @@ -72,7 +81,7 @@ function module:MakePlanes(camera, farDist) planes[2] = PlaneFromPoints(rb1, rb2,rd1) --far - do we need a far plane? planes[3] = PlaneFromPoints(ra1,rb1,rc1) --top planes[4] = PlaneFromPoints(ra1,ra2,rb1) --left Is this correct?? planes[5] = PlaneFromPoints(ra2,rc2,rb2) --bot planes[6] = PlaneFromPoints(rc1,rd1,rd2) --right -
MrChickenRocket created this gist
Feb 8, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,82 @@ --Ultra simple module that lets you generate a camera frustum in roblox and test it for spheres and aabbs local module = {} local function PlaneFromPoints(v0,v1,v2) local xx = v1 - v0 local yy = v2 - v0 local normal = xx:Cross(yy) normal = normal.Unit local res = { n = normal, d = -v0:Dot(normal) } return res end function module:IsSphereVisible(planes, worldPoint, radius) for j = 1, 6 do local dist = worldPoint:Dot(planes[j].n) + planes[j].d + radius if(dist < 0) then return false end end return true end function module:IsAABBVisible(planes, min, max) for j = 1, 6 do local d = planes[j].n:Dot(min) + planes[j].d if (d < 0) then return false end d = planes[j].n:Dot(max) + planes[j].d if (d < 0) then return false end end return true end function module:MakePlanes(camera, farDist) local x = camera.ViewportSize.X local y = camera.ViewportSize.Y local a1 = camera:ViewportPointToRay(0, 0, 1) local c1 = camera:ViewportPointToRay(x, 0, 1) local a2 = camera:ViewportPointToRay(0, y, 1) local c2 = camera:ViewportPointToRay(x, y, 1) local ra1 = a1.Origin + a1.Direction local ra2 = a2.Origin + a2.Direction local rb1 = a1.Origin + a1.Direction * farDist local rb2 = a2.Origin + a2.Direction * farDist local rc1 = c1.Origin + c1.Direction local rc2 = c2.Origin + c2.Direction local rd1 = c1.Origin + c1.Direction * farDist local rd2 = c2.Origin + c2.Direction * farDist --build some planes local planes = {} planes[1] = PlaneFromPoints(ra1, rc1, ra2) --near planes[2] = PlaneFromPoints(rb1, rb2,rd1) --far - do we need a far plane? planes[3] = PlaneFromPoints(ra1,rb1,rc1) --top planes[4] = PlaneFromPoints(ra1,ra2,rb1) --left planes[5] = PlaneFromPoints(ra2,rc2,rb2) --bot planes[6] = PlaneFromPoints(rc1,rd1,rd2) --right return planes end return module