Fix BVH
ray intersections with it seem to be working now in testing
This commit is contained in:
parent
654089031d
commit
a1f7f7d3fc
163
modules/bvh.lua
163
modules/bvh.lua
@ -48,14 +48,20 @@ local function new(triangles, maxTrianglesPerNode)
|
||||
|
||||
-- create the root node, add all the triangles to it
|
||||
local triangleCount = #triangles
|
||||
local extents = tree:calcExtents(0, triangleCount, EPSILON)
|
||||
tree._rootNode = Node(extents[1], extents[2], 0, triangleCount, 0)
|
||||
local extents = tree:calcExtents(1, triangleCount, EPSILON)
|
||||
tree._rootNode = Node(extents[1], extents[2], 1, triangleCount, 1)
|
||||
|
||||
tree._nodesToSplit = { tree._rootNode }
|
||||
for _, node in ipairs(tree._nodesToSplit) do
|
||||
tree:splitNode(node)
|
||||
local function split_r(node)
|
||||
local left, right = tree:splitNode(tree._rootNode)
|
||||
if left then
|
||||
split_r(left)
|
||||
end
|
||||
if right then
|
||||
split_r(right)
|
||||
end
|
||||
end
|
||||
tree._nodesToSplit = {}
|
||||
|
||||
split_r(tree._rootNode)
|
||||
|
||||
return tree
|
||||
end
|
||||
@ -66,9 +72,9 @@ function BVH:intersectRay(rayOrigin, rayDirection, backfaceCulling)
|
||||
local intersectingTriangles = {}
|
||||
|
||||
local invRayDirection = vec3(
|
||||
1.0 / rayDirection.x,
|
||||
1.0 / rayDirection.y,
|
||||
1.0 / rayDirection.z
|
||||
1 / rayDirection.x,
|
||||
1 / rayDirection.y,
|
||||
1 / rayDirection.z
|
||||
)
|
||||
|
||||
-- go over the BVH tree, and extract the list of triangles that lie in nodes that intersect the ray.
|
||||
@ -86,7 +92,7 @@ function BVH:intersectRay(rayOrigin, rayDirection, backfaceCulling)
|
||||
end
|
||||
|
||||
for i=node._startIndex, node._endIndex do
|
||||
table.insert(trianglesInIntersectingNodes, self._bboxArray[i*7])
|
||||
table.insert(trianglesInIntersectingNodes, self._bboxArray[1+(i-1)*7])
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -101,15 +107,16 @@ function BVH:intersectRay(rayOrigin, rayDirection, backfaceCulling)
|
||||
for i=1, #trianglesInIntersectingNodes do
|
||||
local triIndex = trianglesInIntersectingNodes[i]
|
||||
|
||||
triangle[1].x = self._trianglesArray[triIndex*9]
|
||||
triangle[1].y = self._trianglesArray[triIndex*9+1]
|
||||
triangle[1].z = self._trianglesArray[triIndex*9+2]
|
||||
triangle[2].x = self._trianglesArray[triIndex*9+3]
|
||||
triangle[2].y = self._trianglesArray[triIndex*9+4]
|
||||
triangle[2].z = self._trianglesArray[triIndex*9+5]
|
||||
triangle[3].x = self._trianglesArray[triIndex*9+6]
|
||||
triangle[3].y = self._trianglesArray[triIndex*9+7]
|
||||
triangle[3].z = self._trianglesArray[triIndex*9+8]
|
||||
-- print(triIndex, #self._trianglesArray)
|
||||
triangle[1].x = self._trianglesArray[1+(triIndex-1)*9]
|
||||
triangle[1].y = self._trianglesArray[1+(triIndex-1)*9+1]
|
||||
triangle[1].z = self._trianglesArray[1+(triIndex-1)*9+2]
|
||||
triangle[2].x = self._trianglesArray[1+(triIndex-1)*9+3]
|
||||
triangle[2].y = self._trianglesArray[1+(triIndex-1)*9+4]
|
||||
triangle[2].z = self._trianglesArray[1+(triIndex-1)*9+5]
|
||||
triangle[3].x = self._trianglesArray[1+(triIndex-1)*9+6]
|
||||
triangle[3].y = self._trianglesArray[1+(triIndex-1)*9+7]
|
||||
triangle[3].z = self._trianglesArray[1+(triIndex-1)*9+8]
|
||||
|
||||
local intersectionPoint, intersectionDistance = intersect.ray_triangle(ray, triangle, backfaceCulling)
|
||||
|
||||
@ -127,31 +134,31 @@ function BVH:intersectRay(rayOrigin, rayDirection, backfaceCulling)
|
||||
end
|
||||
|
||||
function BVH.calcBoundingBoxes(trianglesArray)
|
||||
local p0x, p0y, p0z
|
||||
local p1x, p1y, p1z
|
||||
local p2x, p2y, p2z
|
||||
local p3x, p3y, p3z
|
||||
local minX, minY, minZ
|
||||
local maxX, maxY, maxZ
|
||||
|
||||
local bboxArray = {}
|
||||
|
||||
for i=1, #trianglesArray / 9 do
|
||||
p0x = trianglesArray[i*9]
|
||||
p0y = trianglesArray[i*9+1]
|
||||
p0z = trianglesArray[i*9+2]
|
||||
p1x = trianglesArray[i*9+3]
|
||||
p1y = trianglesArray[i*9+4]
|
||||
p1z = trianglesArray[i*9+5]
|
||||
p2x = trianglesArray[i*9+6]
|
||||
p2y = trianglesArray[i*9+7]
|
||||
p2z = trianglesArray[i*9+8]
|
||||
p1x = trianglesArray[1+(i-1)*9]
|
||||
p1y = trianglesArray[1+(i-1)*9+1]
|
||||
p1z = trianglesArray[1+(i-1)*9+2]
|
||||
p2x = trianglesArray[1+(i-1)*9+3]
|
||||
p2y = trianglesArray[1+(i-1)*9+4]
|
||||
p2z = trianglesArray[1+(i-1)*9+5]
|
||||
p3x = trianglesArray[1+(i-1)*9+6]
|
||||
p3y = trianglesArray[1+(i-1)*9+7]
|
||||
p3z = trianglesArray[1+(i-1)*9+8]
|
||||
|
||||
minX = math.min(p0x, p1x, p2x)
|
||||
minY = math.min(p0y, p1y, p2y)
|
||||
minZ = math.min(p0z, p1z, p2z)
|
||||
maxX = math.max(p0x, p1x, p2x)
|
||||
maxY = math.max(p0y, p1y, p2y)
|
||||
maxZ = math.max(p0z, p1z, p2z)
|
||||
minX = math.min(p1x, p2x, p3x)
|
||||
minY = math.min(p1y, p2y, p3y)
|
||||
minZ = math.min(p1z, p2z, p3z)
|
||||
maxX = math.max(p1x, p2x, p3x)
|
||||
maxY = math.max(p1y, p2y, p3y)
|
||||
maxZ = math.max(p1z, p2z, p3z)
|
||||
|
||||
BVH.setBox(bboxArray, i, i, minX, minY, minZ, maxX, maxY, maxZ)
|
||||
end
|
||||
@ -174,12 +181,12 @@ function BVH:calcExtents(startIndex, endIndex, expandBy)
|
||||
local maxZ = -math.huge
|
||||
|
||||
for i=startIndex, endIndex do
|
||||
minX = math.min(self._bboxArray[i*7+1], minX)
|
||||
minY = math.min(self._bboxArray[i*7+2], minY)
|
||||
minZ = math.min(self._bboxArray[i*7+3], minZ)
|
||||
maxX = math.max(self._bboxArray[i*7+4], maxX)
|
||||
maxY = math.max(self._bboxArray[i*7+5], maxY)
|
||||
maxZ = math.max(self._bboxArray[i*7+6], maxZ)
|
||||
minX = math.min(self._bboxArray[1+(i-1)*7+1], minX)
|
||||
minY = math.min(self._bboxArray[1+(i-1)*7+2], minY)
|
||||
minZ = math.min(self._bboxArray[1+(i-1)*7+3], minZ)
|
||||
maxX = math.max(self._bboxArray[1+(i-1)*7+4], maxX)
|
||||
maxY = math.max(self._bboxArray[1+(i-1)*7+5], maxY)
|
||||
maxZ = math.max(self._bboxArray[1+(i-1)*7+6], maxZ)
|
||||
end
|
||||
|
||||
return {
|
||||
@ -195,9 +202,9 @@ function BVH:splitNode(node)
|
||||
end
|
||||
|
||||
local startIndex = node._startIndex
|
||||
local endIndex = node._endIndex
|
||||
local endIndex = node._endIndex
|
||||
|
||||
local leftNode = { {},{},{} }
|
||||
local leftNode = { {},{},{} }
|
||||
local rightNode = { {},{},{} }
|
||||
local extentCenters = { node:centerX(), node:centerY(), node:centerZ() }
|
||||
|
||||
@ -207,12 +214,11 @@ function BVH:splitNode(node)
|
||||
node._extentsMax.z - node._extentsMin.z
|
||||
}
|
||||
|
||||
-- NOTE: Indices might be off by 1?
|
||||
local objectCenter = {}
|
||||
for i=startIndex, endIndex do
|
||||
objectCenter[1] = (self._bboxArray[i * 7 + 1] + self._bboxArray[i * 7 + 4]) * 0.5 -- center = (min + max) / 2
|
||||
objectCenter[2] = (self._bboxArray[i * 7 + 2] + self._bboxArray[i * 7 + 5]) * 0.5 -- center = (min + max) / 2
|
||||
objectCenter[3] = (self._bboxArray[i * 7 + 3] + self._bboxArray[i * 7 + 6]) * 0.5 -- center = (min + max) / 2
|
||||
objectCenter[1] = (self._bboxArray[1+(i-1)*7+1] + self._bboxArray[1+(i-1)*7+4]) * 0.5 -- center = (min + max) / 2
|
||||
objectCenter[2] = (self._bboxArray[1+(i-1)*7+2] + self._bboxArray[1+(i-1)*7+5]) * 0.5 -- center = (min + max) / 2
|
||||
objectCenter[3] = (self._bboxArray[1+(i-1)*7+3] + self._bboxArray[1+(i-1)*7+6]) * 0.5 -- center = (min + max) / 2
|
||||
|
||||
for j=1, 3 do
|
||||
if objectCenter[j] < extentCenters[j] then
|
||||
@ -227,9 +233,9 @@ function BVH:splitNode(node)
|
||||
-- here, dont try to split any more (cause it will always fail, and we'll
|
||||
-- enter an infinite loop
|
||||
local splitFailed = {
|
||||
(#leftNode[1] == 0) or (#rightNode[1] == 0),
|
||||
(#leftNode[2] == 0) or (#rightNode[2] == 0),
|
||||
(#leftNode[3] == 0) or (#rightNode[3] == 0)
|
||||
#leftNode[1] == 0 or #rightNode[1] == 0,
|
||||
#leftNode[2] == 0 or #rightNode[2] == 0,
|
||||
#leftNode[3] == 0 or #rightNode[3] == 0
|
||||
}
|
||||
|
||||
if splitFailed[1] and splitFailed[2] and splitFailed[3] then
|
||||
@ -239,7 +245,7 @@ function BVH:splitNode(node)
|
||||
-- choose the longest split axis. if we can't split by it, choose next best one.
|
||||
local splitOrder = { 1, 2, 3 }
|
||||
table.sort(splitOrder, function(a, b)
|
||||
return (extentsLength[b] - extentsLength[a])
|
||||
return extentsLength[b] - extentsLength[a]
|
||||
end)
|
||||
|
||||
local leftElements
|
||||
@ -247,7 +253,6 @@ function BVH:splitNode(node)
|
||||
|
||||
for i=1, 3 do
|
||||
local candidateIndex = splitOrder[i]
|
||||
|
||||
if not splitFailed[candidateIndex] then
|
||||
leftElements = leftNode[candidateIndex]
|
||||
rightElements = rightNode[candidateIndex]
|
||||
@ -273,15 +278,16 @@ function BVH:splitNode(node)
|
||||
table.insert(concatenatedElements, element)
|
||||
end
|
||||
|
||||
-- print(#leftElements, #rightElements, #concatenatedElements)
|
||||
|
||||
for i=1, #concatenatedElements do
|
||||
currElement = concatenatedElements[i]
|
||||
BVH.copyBox(self._bboxArray, currElement, self._bboxHelper, helperPos)
|
||||
helperPos = helperPos + 1
|
||||
end
|
||||
|
||||
-- NOTE: Maybe off by 1
|
||||
-- copy results back to main array
|
||||
for i=node._startIndex * 7, node._endIndex * 7 do
|
||||
for i=1+(node._startIndex-1)*7, 1+(node._endIndex-1)*7 do
|
||||
self._bboxArray[i] = self._bboxHelper[i]
|
||||
end
|
||||
|
||||
@ -297,8 +303,7 @@ function BVH:splitNode(node)
|
||||
node:clearShapes()
|
||||
|
||||
-- add new nodes to the split queue
|
||||
table.insert(self._nodesToSplit, node0)
|
||||
table.insert(self._nodesToSplit, node1)
|
||||
return node0, node1
|
||||
end
|
||||
|
||||
function BVH._calcTValues(minVal, maxVal, rayOriginCoord, invdir)
|
||||
@ -356,37 +361,37 @@ function BVH.intersectNodeBox(rayOrigin, invRayDirection, node)
|
||||
end
|
||||
|
||||
function BVH.setBox(bboxArray, pos, triangleId, minX, minY, minZ, maxX, maxY, maxZ)
|
||||
bboxArray[pos*7] = triangleId
|
||||
bboxArray[pos*7+1] = minX
|
||||
bboxArray[pos*7+2] = minY
|
||||
bboxArray[pos*7+3] = minZ
|
||||
bboxArray[pos*7+4] = maxX
|
||||
bboxArray[pos*7+5] = maxY
|
||||
bboxArray[pos*7+6] = maxZ
|
||||
bboxArray[1+(pos-1)*7] = triangleId
|
||||
bboxArray[1+(pos-1)*7+1] = minX
|
||||
bboxArray[1+(pos-1)*7+2] = minY
|
||||
bboxArray[1+(pos-1)*7+3] = minZ
|
||||
bboxArray[1+(pos-1)*7+4] = maxX
|
||||
bboxArray[1+(pos-1)*7+5] = maxY
|
||||
bboxArray[1+(pos-1)*7+6] = maxZ
|
||||
end
|
||||
|
||||
function BVH.copyBox(sourceArray, sourcePos, destArray, destPos)
|
||||
destArray[destPos*7] = sourceArray[sourcePos*7]
|
||||
destArray[destPos*7+1] = sourceArray[sourcePos*7+1]
|
||||
destArray[destPos*7+2] = sourceArray[sourcePos*7+2]
|
||||
destArray[destPos*7+3] = sourceArray[sourcePos*7+3]
|
||||
destArray[destPos*7+4] = sourceArray[sourcePos*7+4]
|
||||
destArray[destPos*7+5] = sourceArray[sourcePos*7+5]
|
||||
destArray[destPos*7+6] = sourceArray[sourcePos*7+6]
|
||||
destArray[1+(destPos-1)*7] = sourceArray[1+(sourcePos-1)*7]
|
||||
destArray[1+(destPos-1)*7+1] = sourceArray[1+(sourcePos-1)*7+1]
|
||||
destArray[1+(destPos-1)*7+2] = sourceArray[1+(sourcePos-1)*7+2]
|
||||
destArray[1+(destPos-1)*7+3] = sourceArray[1+(sourcePos-1)*7+3]
|
||||
destArray[1+(destPos-1)*7+4] = sourceArray[1+(sourcePos-1)*7+4]
|
||||
destArray[1+(destPos-1)*7+5] = sourceArray[1+(sourcePos-1)*7+5]
|
||||
destArray[1+(destPos-1)*7+6] = sourceArray[1+(sourcePos-1)*7+6]
|
||||
end
|
||||
|
||||
function BVH.getBox(bboxArray, pos, outputBox)
|
||||
outputBox.triangleId = bboxArray[pos*7]
|
||||
outputBox.minX = bboxArray[pos*7+1]
|
||||
outputBox.minY = bboxArray[pos*7+2]
|
||||
outputBox.minZ = bboxArray[pos*7+3]
|
||||
outputBox.maxX = bboxArray[pos*7+4]
|
||||
outputBox.maxY = bboxArray[pos*7+5]
|
||||
outputBox.maxZ = bboxArray[pos*7+6]
|
||||
outputBox.triangleId = bboxArray[1+(pos-1)*7]
|
||||
outputBox.minX = bboxArray[1+(pos-1)*7+1]
|
||||
outputBox.minY = bboxArray[1+(pos-1)*7+2]
|
||||
outputBox.minZ = bboxArray[1+(pos-1)*7+3]
|
||||
outputBox.maxX = bboxArray[1+(pos-1)*7+4]
|
||||
outputBox.maxY = bboxArray[1+(pos-1)*7+5]
|
||||
outputBox.maxZ = bboxArray[1+(pos-1)*7+6]
|
||||
end
|
||||
|
||||
local function new_node(extentsMin, extentsMax, startIndex, endIndex, level)
|
||||
return {
|
||||
return setmetatable({
|
||||
_extentsMin = extentsMin,
|
||||
_extentsMax = extentsMax,
|
||||
_startIndex = startIndex,
|
||||
@ -394,7 +399,7 @@ local function new_node(extentsMin, extentsMax, startIndex, endIndex, level)
|
||||
_level = level
|
||||
--_node0 = nil
|
||||
--_node1 = nil
|
||||
}
|
||||
}, BVHNode)
|
||||
end
|
||||
|
||||
function BVHNode:elementCount()
|
||||
|
Loading…
x
Reference in New Issue
Block a user