aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/SphereBoxCollisionAlgorithm.cs
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/SphereBoxCollisionAlgorithm.cs')
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/SphereBoxCollisionAlgorithm.cs270
1 files changed, 0 insertions, 270 deletions
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/SphereBoxCollisionAlgorithm.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/SphereBoxCollisionAlgorithm.cs
deleted file mode 100644
index 2b4e801..0000000
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/SphereBoxCollisionAlgorithm.cs
+++ /dev/null
@@ -1,270 +0,0 @@
1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22using System;
23using System.Collections.Generic;
24using System.Text;
25using MonoXnaCompactMaths;
26
27namespace XnaDevRu.BulletX
28{
29 /// <summary>
30 /// SphereBoxCollisionAlgorithm provides sphere-box collision detection.
31 /// Other features are frame-coherency (persistent data) and collision response.
32 /// </summary>
33 public class SphereBoxCollisionAlgorithm : CollisionAlgorithm, IDisposable
34 {
35 private bool _ownManifold;
36 private PersistentManifold _manifold;
37 private bool _isSwapped;
38
39 public SphereBoxCollisionAlgorithm(PersistentManifold manifold, CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject collisionObjectA, CollisionObject collisionObjectB, bool isSwapped)
40 : base(collisionAlgorithmConstructionInfo)
41 {
42 _ownManifold = false;
43 _manifold = manifold;
44 _isSwapped = isSwapped;
45
46 CollisionObject sphereObject = _isSwapped ? collisionObjectB : collisionObjectA;
47 CollisionObject boxObject = _isSwapped ? collisionObjectA : collisionObjectB;
48
49 if (_manifold == null && Dispatcher.NeedsCollision(sphereObject, boxObject))
50 {
51 _manifold = Dispatcher.GetNewManifold(sphereObject, boxObject);
52 _ownManifold = true;
53 }
54 }
55
56 public float GetSphereDistance(CollisionObject boxObject, out Vector3 pointOnBox, out Vector3 pointOnSphere, Vector3 sphereCenter, float radius)
57 {
58 pointOnBox = new Vector3();
59 pointOnSphere = new Vector3();
60
61 float margins;
62 Vector3[] bounds = new Vector3[2];
63 BoxShape boxShape = boxObject.CollisionShape as BoxShape;
64
65 bounds[0] = -boxShape.HalfExtents;
66 bounds[1] = boxShape.HalfExtents;
67
68 margins = boxShape.Margin; //also add sphereShape margin?
69
70 Matrix m44T = boxObject.WorldTransform;
71
72 Vector3[] boundsVec = new Vector3[2];
73 float penetration;
74
75 boundsVec[0] = bounds[0];
76 boundsVec[1] = bounds[1];
77
78 Vector3 marginsVec = new Vector3(margins, margins, margins);
79
80 // add margins
81 bounds[0] += marginsVec;
82 bounds[1] -= marginsVec;
83
84 /////////////////////////////////////////////////
85
86 Vector3 tmp, prel, normal, v3P;
87 Vector3[] n = new Vector3[6];
88 float sep = 10000000.0f, sepThis;
89
90 n[0] = new Vector3(-1.0f, 0.0f, 0.0f);
91 n[1] = new Vector3(0.0f, -1.0f, 0.0f);
92 n[2] = new Vector3(0.0f, 0.0f, -1.0f);
93 n[3] = new Vector3(1.0f, 0.0f, 0.0f);
94 n[4] = new Vector3(0.0f, 1.0f, 0.0f);
95 n[5] = new Vector3(0.0f, 0.0f, 1.0f);
96
97 // convert point in local space
98 prel = MathHelper.InvXForm(m44T, sphereCenter);
99
100 bool found = false;
101
102 v3P = prel;
103
104 for (int i = 0; i < 6; i++)
105 {
106 int j = i < 3 ? 0 : 1;
107 if ((sepThis = (Vector3.Dot(v3P - bounds[j], n[i]))) > 0.0f)
108 {
109 v3P = v3P - n[i] * sepThis;
110 found = true;
111 }
112 }
113
114 //
115
116 if (found)
117 {
118 bounds[0] = boundsVec[0];
119 bounds[1] = boundsVec[1];
120
121 normal = Vector3.Normalize(prel - v3P);
122 pointOnBox = v3P + normal * margins;
123 pointOnSphere = prel - normal * radius;
124
125 if ((Vector3.Dot(pointOnSphere - pointOnBox, normal)) > 0.0f)
126 {
127 return 1.0f;
128 }
129
130 // transform back in world space
131 tmp = MathHelper.MatrixToVector(m44T, pointOnBox);
132 pointOnBox = tmp;
133 tmp = MathHelper.MatrixToVector(m44T, pointOnSphere);
134 pointOnSphere = tmp;
135 float seps2 = (pointOnBox - pointOnSphere).LengthSquared();
136
137 //if this fails, fallback into deeper penetration case, below
138 if (seps2 > MathHelper.Epsilon)
139 {
140 sep = -(float)Math.Sqrt(seps2);
141 normal = (pointOnBox - pointOnSphere);
142 normal *= 1f / sep;
143 }
144 return sep;
145 }
146
147 //////////////////////////////////////////////////
148 // Deep penetration case
149
150 penetration = GetSpherePenetration(boxObject, ref pointOnBox, ref pointOnSphere, sphereCenter, radius, bounds[0], bounds[1]);
151
152 bounds[0] = boundsVec[0];
153 bounds[1] = boundsVec[1];
154
155 if (penetration <= 0.0f)
156 return (penetration - margins);
157 else
158 return 1.0f;
159 }
160
161 public float GetSpherePenetration(CollisionObject boxObject, ref Vector3 pointOnBox, ref Vector3 pointOnSphere, Vector3 sphereCenter, float radius, Vector3 aabbMin, Vector3 aabbMax)
162 {
163 Vector3[] bounds = new Vector3[2];
164
165 bounds[0] = aabbMin;
166 bounds[1] = aabbMax;
167
168 Vector3 p0 = new Vector3(), tmp, prel, normal = new Vector3();
169 Vector3[] n = new Vector3[6];
170 float sep = -10000000.0f, sepThis;
171
172 n[0] = new Vector3(-1.0f, 0.0f, 0.0f);
173 n[1] = new Vector3(0.0f, -1.0f, 0.0f);
174 n[2] = new Vector3(0.0f, 0.0f, -1.0f);
175 n[3] = new Vector3(1.0f, 0.0f, 0.0f);
176 n[4] = new Vector3(0.0f, 1.0f, 0.0f);
177 n[5] = new Vector3(0.0f, 0.0f, 1.0f);
178
179 Matrix m44T = boxObject.WorldTransform;
180
181 // convert point in local space
182 prel = MathHelper.InvXForm(m44T, sphereCenter);
183
184 ///////////
185
186 for (int i = 0; i < 6; i++)
187 {
188 int j = i < 3 ? 0 : 1;
189 if ((sepThis = (Vector3.Dot(prel - bounds[j], n[i])) - radius) > 0.0f) return 1.0f;
190 if (sepThis > sep)
191 {
192 p0 = bounds[j];
193 normal = n[i];
194 sep = sepThis;
195 }
196 }
197
198 pointOnBox = prel - normal * (Vector3.Dot(normal, (prel - p0)));
199 pointOnSphere = pointOnBox + normal * sep;
200
201 // transform back in world space
202 tmp = MathHelper.MatrixToVector(m44T, pointOnBox);
203 pointOnBox = tmp;
204 tmp = MathHelper.MatrixToVector(m44T, pointOnSphere);
205 pointOnSphere = tmp;
206 normal = Vector3.Normalize(pointOnBox - pointOnSphere);
207
208 return sep;
209 }
210
211 public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
212 {
213 if (_manifold == null)
214 return;
215
216 CollisionObject sphereObject = _isSwapped ? bodyB : bodyA;
217 CollisionObject boxObject = _isSwapped ? bodyA : bodyB;
218
219 SphereShape sphereA = sphereObject.CollisionShape as SphereShape;
220
221 Vector3 pOnBox, pOnSphere;
222 Vector3 sphereCenter = sphereObject.WorldTransform.Translation;
223 float radius = sphereA.Radius;
224
225 float dist = GetSphereDistance(boxObject, out pOnBox, out pOnSphere, sphereCenter, radius);
226
227 if (dist < MathHelper.Epsilon)
228 {
229 Vector3 normalOnSurfaceB = Vector3.Normalize(pOnBox - pOnSphere);
230
231 // report a contact. internally this will be kept persistent, and contact reduction is done
232 resultOut.SetPersistentManifold(_manifold);
233 resultOut.AddContactPoint(normalOnSurfaceB, pOnBox, dist);
234 }
235 }
236
237 public override float CalculateTimeOfImpact(CollisionObject collisionObjectA, CollisionObject collisionObjectB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
238 {
239 //not yet
240 return 1;
241 }
242
243 public class CreateFunc : CollisionAlgorithmCreateFunction
244 {
245 public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
246 {
247 if (!IsSwapped)
248 return new SphereBoxCollisionAlgorithm(null, collisionAlgorithmConstructionInfo, bodyA, bodyB, false);
249 else
250 return new SphereBoxCollisionAlgorithm(null, collisionAlgorithmConstructionInfo, bodyA, bodyB, true);
251 }
252 }
253
254 #region IDisposable Members
255 public void Dispose()
256 {
257 Dispose(true);
258 }
259
260 public void Dispose(bool disposing)
261 {
262 if (disposing && _ownManifold)
263 {
264 if (_manifold != null)
265 Dispatcher.ReleaseManifold(_manifold);
266 }
267 }
268 #endregion
269 }
270}