-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinit.lua
More file actions
75 lines (66 loc) · 2.94 KB
/
init.lua
File metadata and controls
75 lines (66 loc) · 2.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
-- Separating Axis Theorem (SAT) collision detection for Roblox
-- by @mattmarcin
-- Pass in 2 Models to ModelsCollide to test if they intersect. Supports rotation.
-- This gets the BoundingBox of the model which encompasses the model and all of its children.
-- A major benefit to this is being able to detect collisions between models that are not parented to the Workspace
local SATUtil = {}
-- Test if two Models intersect. Return true if they do.
function SATUtil.ModelsCollide(object1: Model, object2: Model)
local box1CFrame, box1Size = object1:GetBoundingBox()
local box2CFrame, box2Size = object2:GetBoundingBox()
local axes = {}
local eps = 1e-5 -- Small epsilon to deal with numerical precision issues
-- Get the box axes
axes[1], axes[2], axes[3] = box1CFrame.RightVector, box1CFrame.UpVector, box1CFrame.LookVector
axes[4], axes[5], axes[6] = box2CFrame.RightVector, box2CFrame.UpVector, box2CFrame.LookVector
-- Compute the cross product of the edge directions
for i = 1, 3 do
for j = 4, 6 do
axes[#axes + 1] = axes[i]:Cross(axes[j])
-- If the cross product is very small, it means the edges are almost parallel, so we don't need this axis
if axes[#axes].Magnitude < eps then
axes[#axes] = nil
end
end
end
-- Now we need to project both boxes onto these axes and see if the projections overlap
for _, axis in pairs(axes) do
if axis then -- Ensure the axis is not nil (in case of almost parallel edges)
local min1, max1 = math.huge, -math.huge
local min2, max2 = math.huge, -math.huge
-- Compute the projection of the first box onto the current axis
for _, corner in pairs(SATUtil.getBoxCorners(box1CFrame, box1Size)) do
local projection = corner:Dot(axis)
min1 = math.min(min1, projection)
max1 = math.max(max1, projection)
end
-- Compute the projection of the second box onto the current axis
for _, corner in pairs(SATUtil.getBoxCorners(box2CFrame, box2Size)) do
local projection = corner:Dot(axis)
min2 = math.min(min2, projection)
max2 = math.max(max2, projection)
end
-- If the projections do not overlap, then we have found a separating axis and the boxes do not intersect
if max1 < min2 or max2 < min1 then
return false
end
end
end
-- If we haven't found a separating axis, then the boxes intersect
return true
end
-- Helper function to get the corners of a box given its CFrame and size
function SATUtil.getBoxCorners(cframe, size)
local halfSize = size / 2
return {
cframe * Vector3.new(halfSize.X, halfSize.Y, halfSize.Z),
cframe * Vector3.new(-halfSize.X, halfSize.Y, halfSize.Z),
cframe * Vector3.new(halfSize.X, -halfSize.Y, halfSize.Z),
cframe * Vector3.new(halfSize.X, halfSize.Y, -halfSize.Z),
cframe * Vector3.new(-halfSize.X, -halfSize.Y, halfSize.Z),
cframe * Vector3.new(-halfSize.X, halfSize.Y, -halfSize.Z),
cframe * Vector3.new(halfSize.X, -halfSize.Y, -halfSize.Z),
cframe * Vector3.new(-halfSize.X, -halfSize.Y, -halfSize.Z),
}
end
return SATUtil