annotate semiconginev2/contrib/algorithms/collision.nim @ 1226:c8e3037aca66 compiletime-tests

add: contrib stuff
author sam <sam@basx.dev>
date Wed, 17 Jul 2024 23:41:51 +0700
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1226
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
1 const MAX_COLLISON_DETECTION_ITERATIONS = 20
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
2 const MAX_COLLISON_POINT_CALCULATION_ITERATIONS = 20
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
3
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
4 type
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
5 ColliderType* = enum
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
6 Box, Sphere, Points
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
7 Collider* = object
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
8 transform*: Mat4 = Unit4F32
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
9 case theType*: ColliderType
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
10 of Box: discard
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
11 of Sphere: radius*: float32
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
12 of Points: points*: seq[Vec3f]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
13
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
14 func between(value, b1, b2: float32): bool =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
15 min(b1, b2) <= value and value <= max(b1, b2)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
16
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
17 func Contains*(collider: Collider, x: Vec3f): bool =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
18 # from https://math.stackexchange.com/questions/1472049/check-if-a-point-is-inside-a-rectangular-shaped-area-3d
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
19 case collider.theType:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
20 of Box:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
21 let
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
22 P1 = collider.transform * NewVec3f(0, 0, 0) # origin
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
23 P2 = collider.transform * Z
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
24 P4 = collider.transform * X
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
25 P5 = collider.transform * Y
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
26 u = (P1 - P4).Cross(P1 - P5)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
27 v = (P1 - P2).Cross(P1 - P5)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
28 w = (P1 - P2).Cross(P1 - P4)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
29 uP1 = u.Dot(P1)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
30 uP2 = u.Dot(P2)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
31 vP1 = v.Dot(P1)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
32 vP4 = v.Dot(P4)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
33 wP1 = w.Dot(P1)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
34 wP5 = w.Dot(P5)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
35 ux = u.Dot(x)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
36 vx = v.Dot(x)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
37 wx = w.Dot(x)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
38 ux.between(uP1, uP2) and vx.between(vP1, vP4) and wx.between(wP1, wP5)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
39 of Sphere:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
40 (collider.transform * x).Length < (collider.transform * NewVec3f()).Length
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
41 of Points:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
42 raise newException(Exception, "Points are not supported yet for 'contains'")
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
43
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
44 # implementation of GJK, based on https://blog.winter.dev/2020/gjk-algorithm/
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
45
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
46 # most generic implementation of findFurthestPoint
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
47 # add other implementations of findFurthestPoint for other kind of geometry or optimization
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
48 # (will be selected depening on type of the first parameter)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
49 func findFurthestPoint(points: openArray[Vec3f], direction: Vec3f): Vec3f =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
50 var maxDist = low(float32)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
51 for p in points:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
52 let dist = direction.Dot(p)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
53 if dist > maxDist:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
54 maxDist = dist
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
55 result = p
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
56
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
57 func findFurthestPoint(transform: Mat4, direction: Vec3f): Vec3f =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
58 return findFurthestPoint(
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
59 [
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
60 transform * NewVec3f(0, 0, 0),
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
61 transform * X,
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
62 transform * Y,
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
63 transform * Z,
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
64 transform * (X + Y),
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
65 transform * (X + Z),
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
66 transform * (Y + Z),
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
67 transform * (X + Y + Z),
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
68 ],
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
69 direction
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
70 )
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
71 func findFurthestPoint(collider: Collider, direction: Vec3f): Vec3f =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
72 case collider.theType
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
73 of Sphere:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
74 let directionNormalizedToSphere = ((direction / direction.Length) * collider.radius)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
75 collider.transform * directionNormalizedToSphere
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
76 of Box:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
77 findFurthestPoint(collider.transform, direction)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
78 of Points:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
79 findFurthestPoint(collider.points, direction)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
80
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
81 func supportPoint(a, b: Collider, direction: Vec3f): Vec3f =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
82 a.findFurthestPoint(direction) - b.findFurthestPoint(-direction)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
83
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
84 func sameDirection(direction: Vec3f, ao: Vec3f): bool =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
85 direction.Dot(ao) > 0
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
86
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
87 func line(simplex: var seq[Vec3f], direction: var Vec3f): bool =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
88 let
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
89 a = simplex[0]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
90 b = simplex[1]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
91 ab = b - a
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
92 ao = - a
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
93
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
94 if sameDirection(ab, ao):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
95 direction = Cross(Cross(ab, ao), ab)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
96 else:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
97 simplex = @[a]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
98 direction = ao
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
99
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
100 return false
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
101
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
102 func triangle(simplex: var seq[Vec3f], direction: var Vec3f, twoDimensional = false): bool =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
103 let
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
104 a = simplex[0]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
105 b = simplex[1]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
106 c = simplex[2]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
107 ab = b - a
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
108 ac = c - a
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
109 ao = - a
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
110 abc = ab.Cross(ac)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
111
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
112 if sameDirection(abc.Cross(ac), ao):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
113 if sameDirection(ac, ao):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
114 simplex = @[a, c]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
115 direction = ac.Cross(ao).Cross(ac)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
116 else:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
117 simplex = @[a, b]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
118 return line(simplex, direction)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
119 else:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
120 if (sameDirection(ab.Cross(abc), ao)):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
121 simplex = @[a, b]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
122 return line(simplex, direction)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
123 else:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
124 if twoDimensional:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
125 return true
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
126 if (sameDirection(abc, ao)):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
127 direction = abc
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
128 else:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
129 simplex = @[a, c, b]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
130 direction = -abc
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
131
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
132 return false
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
133
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
134 func tetrahedron(simplex: var seq[Vec3f], direction: var Vec3f): bool =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
135 let
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
136 a = simplex[0]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
137 b = simplex[1]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
138 c = simplex[2]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
139 d = simplex[3]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
140 ab = b - a
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
141 ac = c - a
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
142 ad = d - a
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
143 ao = - a
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
144 abc = ab.Cross(ac)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
145 acd = ac.Cross(ad)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
146 adb = ad.Cross(ab)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
147
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
148 if sameDirection(abc, ao):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
149 simplex = @[a, b, c]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
150 return triangle(simplex, direction)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
151 if sameDirection(acd, ao):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
152 simplex = @[a, c, d]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
153 return triangle(simplex, direction)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
154 if sameDirection(adb, ao):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
155 simplex = @[a, d, b]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
156 return triangle(simplex, direction)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
157
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
158 return true
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
159
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
160 func getFaceNormals(polytope: seq[Vec3f], faces: seq[int]): (seq[Vec4f], int) =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
161 var
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
162 normals: seq[Vec4f]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
163 minTriangle = 0
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
164 minDistance = high(float32)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
165
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
166 for i in countup(0, faces.len - 1, 3):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
167 let
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
168 a = polytope[faces[i + 0]]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
169 b = polytope[faces[i + 1]]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
170 c = polytope[faces[i + 2]]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
171
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
172 var normal = (b - a).Cross(c - a).Normalized()
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
173 var distance = normal.Dot(a)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
174
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
175 if distance < 0:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
176 normal = normal * -1'f32
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
177 distance = distance * -1'f32
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
178
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
179 normals.add normal.ToVec4(distance)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
180
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
181 if distance < minDistance:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
182 minTriangle = i div 3
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
183 minDistance = distance
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
184
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
185 return (normals, minTriangle)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
186
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
187 func addIfUniqueEdge(edges: var seq[(int, int)], faces: seq[int], a: int, b: int) =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
188 let reverse = edges.find((faces[b], faces[a]))
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
189 if (reverse >= 0):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
190 edges.delete(reverse)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
191 else:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
192 edges.add (faces[a], faces[b])
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
193
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
194 func nextSimplex(simplex: var seq[Vec3f], direction: var Vec3f, twoDimensional = false): bool =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
195 case simplex.len
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
196 of 2: simplex.line(direction)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
197 of 3: simplex.triangle(direction, twoDimensional)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
198 of 4: simplex.tetrahedron(direction)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
199 else: raise newException(Exception, "Error in simplex")
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
200
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
201 func collisionPoint3D(simplex: var seq[Vec3f], a, b: Collider): tuple[normal: Vec3f, penetrationDepth: float32] =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
202 var
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
203 polytope = simplex
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
204 faces = @[
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
205 0, 1, 2,
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
206 0, 3, 1,
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
207 0, 2, 3,
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
208 1, 3, 2
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
209 ]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
210 (normals, minFace) = getFaceNormals(polytope, faces)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
211 minNormal: Vec3f
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
212 minDistance = high(float32)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
213 iterCount = 0
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
214
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
215 while minDistance == high(float32) and iterCount < MAX_COLLISON_POINT_CALCULATION_ITERATIONS:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
216 minNormal = normals[minFace].xyz
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
217 minDistance = normals[minFace].w
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
218 var
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
219 support = supportPoint(a, b, minNormal)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
220 sDistance = minNormal.Dot(support)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
221
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
222 if abs(sDistance - minDistance) > 0.001'f32:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
223 minDistance = high(float32)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
224 var uniqueEdges: seq[(int, int)]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
225 var i = 0
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
226 while i < normals.len:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
227 if sameDirection(normals[i], support):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
228 var f = i * 3
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
229
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
230 addIfUniqueEdge(uniqueEdges, faces, f + 0, f + 1)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
231 addIfUniqueEdge(uniqueEdges, faces, f + 1, f + 2)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
232 addIfUniqueEdge(uniqueEdges, faces, f + 2, f + 0)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
233
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
234 faces[f + 2] = faces.pop()
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
235 faces[f + 1] = faces.pop()
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
236 faces[f + 0] = faces.pop()
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
237
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
238 normals[i] = normals.pop()
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
239
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
240 dec i
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
241 inc i
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
242
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
243 var newFaces: seq[int]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
244 for (edgeIndex1, edgeIndex2) in uniqueEdges:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
245 newFaces.add edgeIndex1
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
246 newFaces.add edgeIndex2
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
247 newFaces.add polytope.len
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
248
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
249 polytope.add support
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
250
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
251 var (newNormals, newMinFace) = getFaceNormals(polytope, newFaces)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
252 if newNormals.len == 0:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
253 break
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
254
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
255 var oldMinDistance = high(float32)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
256 for j in 0 ..< normals.len:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
257 if normals[j].w < oldMinDistance:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
258 oldMinDistance = normals[j].w
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
259 minFace = j
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
260
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
261 if (newNormals[newMinFace].w < oldMinDistance):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
262 minFace = newMinFace + normals.len
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
263
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
264 for f in newFaces:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
265 faces.add f
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
266 for n in newNormals:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
267 normals.add n
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
268 inc iterCount
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
269
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
270 result = (normal: minNormal, penetrationDepth: minDistance + 0.001'f32)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
271
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
272
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
273 func collisionPoint2D(polytopeIn: seq[Vec3f], a, b: Collider): tuple[normal: Vec3f, penetrationDepth: float32] =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
274 var
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
275 polytope = polytopeIn
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
276 minIndex = 0
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
277 minDistance = high(float32)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
278 iterCount = 0
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
279 minNormal: Vec2f
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
280
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
281 while minDistance == high(float32) and iterCount < MAX_COLLISON_POINT_CALCULATION_ITERATIONS:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
282 for i in 0 ..< polytope.len:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
283 let
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
284 j = (i + 1) mod polytope.len
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
285 vertexI = polytope[i]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
286 vertexJ = polytope[j]
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
287 ij = vertexJ - vertexI
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
288 var
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
289 normal = NewVec2f(ij.y, -ij.x).Normalized()
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
290 distance = normal.Dot(vertexI)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
291
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
292 if (distance < 0):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
293 distance *= -1'f32
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
294 normal = normal * -1'f32
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
295
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
296 if distance < minDistance:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
297 minDistance = distance
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
298 minNormal = normal
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
299 minIndex = j
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
300
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
301 let
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
302 support = supportPoint(a, b, minNormal.ToVec3)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
303 sDistance = minNormal.Dot(support)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
304
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
305 if(abs(sDistance - minDistance) > 0.001):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
306 minDistance = high(float32)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
307 polytope.insert(support, minIndex)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
308 inc iterCount
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
309
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
310 result = (normal: NewVec3f(minNormal.x, minNormal.y), penetrationDepth: minDistance + 0.001'f32)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
311
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
312 func Intersects*(a, b: Collider, as2D = false): bool =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
313 var
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
314 support = supportPoint(a, b, NewVec3f(0.8153, -0.4239, if as2D: 0.0 else: 0.5786)) # just random initial vector
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
315 simplex = newSeq[Vec3f]()
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
316 direction = -support
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
317 n = 0
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
318 simplex.insert(support, 0)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
319 while n < MAX_COLLISON_DETECTION_ITERATIONS:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
320 support = supportPoint(a, b, direction)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
321 if support.Dot(direction) <= 0:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
322 return false
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
323 simplex.insert(support, 0)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
324 if nextSimplex(simplex, direction, twoDimensional = as2D):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
325 return true
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
326 # prevent numeric instability
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
327 if direction == NewVec3f(0, 0, 0):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
328 direction[0] = 0.0001
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
329 inc n
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
330
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
331 func Collision*(a, b: Collider, as2D = false): tuple[hasCollision: bool, normal: Vec3f, penetrationDepth: float32] =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
332 var
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
333 support = supportPoint(a, b, NewVec3f(0.8153, -0.4239, if as2D: 0.0 else: 0.5786)) # just random initial vector
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
334 simplex = newSeq[Vec3f]()
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
335 direction = -support
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
336 n = 0
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
337 simplex.insert(support, 0)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
338 while n < MAX_COLLISON_DETECTION_ITERATIONS:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
339 support = supportPoint(a, b, direction)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
340 if support.Dot(direction) <= 0:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
341 return result
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
342 simplex.insert(support, 0)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
343 if nextSimplex(simplex, direction, twoDimensional = as2D):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
344 let (normal, depth) = if as2D: collisionPoint2D(simplex, a, b) else: collisionPoint3D(simplex, a, b)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
345 return (true, normal, depth)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
346 # prevent numeric instability
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
347 if direction == NewVec3f(0, 0, 0):
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
348 direction[0] = 0.0001
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
349 inc n
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
350
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
351 func CalculateCollider*(points: openArray[Vec3f], theType: ColliderType): Collider =
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
352 var
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
353 minX = high(float32)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
354 maxX = low(float32)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
355 minY = high(float32)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
356 maxY = low(float32)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
357 minZ = high(float32)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
358 maxZ = low(float32)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
359 center: Vec3f
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
360
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
361 for p in points:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
362 minX = min(minX, p.x)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
363 maxX = max(maxX, p.x)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
364 minY = min(minY, p.y)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
365 maxY = max(maxY, p.y)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
366 minZ = min(minZ, p.z)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
367 maxZ = max(maxz, p.z)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
368 center = center + p
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
369 center = center / float32(points.len)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
370
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
371 let
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
372 scaleX = (maxX - minX)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
373 scaleY = (maxY - minY)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
374 scaleZ = (maxZ - minZ)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
375
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
376 if theType == Points:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
377 result = Collider(theType: Points, points: @points)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
378 else:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
379 result = Collider(theType: theType, transform: Translate(minX, minY, minZ) * Scale(scaleX, scaleY, scaleZ))
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
380
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
381 if theType == Sphere:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
382 result.transform = Translate(center)
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
383 for p in points:
c8e3037aca66 add: contrib stuff
sam <sam@basx.dev>
parents:
diff changeset
384 result.radius = max(result.radius, (p - center).Length)