I am developing a game, but, for performance reasons, need to dynamically generate a 2D table that acts like a virtual 3D container filled with virtual nodes, with each node (virtual basepart) being the table within that 2D table. Each subtable contains the virtual part’s CFrame and Vector3 size information respectively. I want to develop a way to check if a pair of given virtual parts are intersecting in that virtual space using each of their corresponding CFrame and size information alone and no basepart instances whatsoever. I tried using the function below, courtesy of ChatGPT (Exhibit A), but, for some reason, it will sometimes misidentify some virtual parts as touching/intersecting the other part that happen do be in the vicinity of the other part but are not necessarily touching spacially. I know this because I developed a 2nd function (Exhibit B) that renders basepart representations of each virtual part based on its CFrame and size information, to verify what should be going on spacially. Can anyone give me any pointers as to what is going on?
Exhibit A:
local function areVirtualPartsTouching(cframe1, size1, cframe2, size2) --checks if two virtual parts, based each of their CFrame and size values, are touching. Returns true or false accordingly.
-- Calculate half sizes (extents) for each part
local halfSize1 = size1 / 2
local halfSize2 = size2 / 2
-- Get the corners of the bounding boxes for both parts
local min1 = cframe1.Position - halfSize1
local max1 = cframe1.Position + halfSize1
local min2 = cframe2.Position - halfSize2
local max2 = cframe2.Position + halfSize2
-- Check if the bounding boxes intersect in all three axes
local xOverlap = max1.X >= min2.X and min1.X <= max2.X
local yOverlap = max1.Y >= min2.Y and min1.Y <= max2.Y
local zOverlap = max1.Z >= min2.Z and min1.Z <= max2.Z
-- If all axes overlap, the parts are touching or intersecting
return xOverlap and yOverlap and zOverlap
end
Exhibit B:
function visualizeNodes(nodesTable) --this function is designed for diagnostic purposes, and just draws node parts on-screen in the corresponding CFrames, names, and sizes of the nodes from a given nodes table.
print("Starting node visualizer. Warning: This is for diagnostic purposes only, and should not run during production due to performance reasons.")
local nodePartConstructor = Instance.new("Part")
nodePartConstructor.Anchored = true
nodePartConstructor.CanQuery = false
nodePartConstructor.CanCollide = false
nodePartConstructor.CanTouch = false
nodePartConstructor.Transparency = 1
nodePartConstructor.Locked = false
local processThrottleCount = 0 --designed to force the process to wait after a certain amount of processes have occurred in the loop for efficiency purposes.
local nodeCount = 0
local disconnectedNodesCount = 0
for _, node in nodesTable do
nodeCount = nodeCount + 1
local newNode = nodePartConstructor:Clone()
newNode.Name = node[1]
newNode.CFrame = node[2]
newNode.Size = Vector3.new(node[3], node[3], node[3])
newNode.Parent = visualizedNodesFolder
newNode:SetAttribute("PointsTo", node[4])
if node[4] == -1 then
newNode.Color = Color3.fromRGB(255, 0, 0)
newNode.Material = Enum.Material.Neon
newNode.Transparency = 0
disconnectedNodesCount = disconnectedNodesCount + 1
local surroundingNodes, detectionRegions = getNeighborNodePresences(node, grid, cellSize, true)
if #surroundingNodes <= 0 then
print("Warning! " .. tostring(node[1]) .. " doesn't have any surrounding nodes!")
else
local surroundingNodePartColor = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))
for _, surroundingNode in surroundingNodes do
local surroundingNodePart = newNode:Clone()
surroundingNodePart.Name = tostring(node[1] .. "_Surrounding_Node")
surroundingNodePart.Color = surroundingNodePartColor
surroundingNodePart.Transparency = 0.75
surroundingNodePart.CFrame = surroundingNode[2]
surroundingNode.Size = Vector3.new(surroundingNode[3], surroundingNode[3], surroundingNode[3])
surroundingNodePart.Parent = visualizedNodesFolder
end
end
local detectionRegionColor = Color3.fromRGB(0, 0, 0)
for _, detectionRegion in detectionRegions do
local detectionRegionPart = newNode:Clone()
detectionRegionPart.Name = tostring(node[1] .. "_Detection_Region")
detectionRegionPart.Color = detectionRegionColor
detectionRegionPart.Transparency = 0.7
detectionRegionPart.CFrame = detectionRegion[1]
detectionRegionPart.Size = Vector3.new(detectionRegion[2].X, detectionRegion[2].Y, detectionRegion[2].Z)
detectionRegionPart.Parent = visualizedNodesFolder
end
end
processThrottleCount = processThrottleCount + 1
if processThrottleCount > 200 then
task.wait()
processThrottleCount = 0
end
end
print("Visualizer completed.")
print("Total Waypoints/Nodes after Map Generation: " .. tostring(nodeCount))
print("Total number of nodes that do not point to anything: " .. tostring(disconnectedNodesCount))
end