aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision')
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ContinuousConvexCollision.cs398
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ConvexCast.cs146
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/DiscreteCollisionDetectorInterface.cs234
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkConvexCast.cs352
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkEpa.cs1266
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkEpaPenetrationDepthSolver.cs112
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkEpaSolver.cs202
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkPairDetector.cs684
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/IConvexPenetrationDepthSolver.cs84
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ISimplexSolver.cs94
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ManifoldPoint.cs156
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.cs492
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/PersistentManifold.cs544
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/PointCollector.cs128
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/SubsimplexConvexCast.cs284
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/TriangleRaycastCallback.cs230
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/VoronoiSimplexSolver.cs1286
17 files changed, 3346 insertions, 3346 deletions
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ContinuousConvexCollision.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ContinuousConvexCollision.cs
index 497f220..d011ef2 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ContinuousConvexCollision.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ContinuousConvexCollision.cs
@@ -1,199 +1,199 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 /// <summary> 29 /// <summary>
30 /// ContinuousConvexCollision implements angular and linear time of impact for convex objects. 30 /// ContinuousConvexCollision implements angular and linear time of impact for convex objects.
31 /// Based on Brian Mirtich's Conservative Advancement idea (PhD thesis). 31 /// Based on Brian Mirtich's Conservative Advancement idea (PhD thesis).
32 /// Algorithm operates in worldspace, in order to keep inbetween motion globally consistent. 32 /// Algorithm operates in worldspace, in order to keep inbetween motion globally consistent.
33 /// It uses GJK at the moment. Future improvement would use minkowski sum / supporting vertex, merging innerloops 33 /// It uses GJK at the moment. Future improvement would use minkowski sum / supporting vertex, merging innerloops
34 /// </summary> 34 /// </summary>
35 public class ContinuousConvexCollision : IConvexCast 35 public class ContinuousConvexCollision : IConvexCast
36 { 36 {
37 /// <summary> 37 /// <summary>
38 /// This maximum should not be necessary. It allows for untested/degenerate cases in production code. 38 /// This maximum should not be necessary. It allows for untested/degenerate cases in production code.
39 /// You don't want your game ever to lock-up. 39 /// You don't want your game ever to lock-up.
40 /// </summary> 40 /// </summary>
41 private const int MaxIterations = 1000; 41 private const int MaxIterations = 1000;
42 42
43 private ISimplexSolver _simplexSolver; 43 private ISimplexSolver _simplexSolver;
44 private IConvexPenetrationDepthSolver _penetrationDepthSolver; 44 private IConvexPenetrationDepthSolver _penetrationDepthSolver;
45 private ConvexShape _convexA; 45 private ConvexShape _convexA;
46 private ConvexShape _convexB; 46 private ConvexShape _convexB;
47 47
48 public ContinuousConvexCollision(ConvexShape convexA, ConvexShape convexB, 48 public ContinuousConvexCollision(ConvexShape convexA, ConvexShape convexB,
49 ISimplexSolver simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver) 49 ISimplexSolver simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
50 { 50 {
51 _simplexSolver = simplexSolver; 51 _simplexSolver = simplexSolver;
52 _penetrationDepthSolver = penetrationDepthSolver; 52 _penetrationDepthSolver = penetrationDepthSolver;
53 _convexA = convexA; 53 _convexA = convexA;
54 _convexB = convexB; 54 _convexB = convexB;
55 } 55 }
56 56
57 public bool CalcTimeOfImpact(Matrix fromA, Matrix toA, Matrix fromB, Matrix toB, CastResult result) 57 public bool CalcTimeOfImpact(Matrix fromA, Matrix toA, Matrix fromB, Matrix toB, CastResult result)
58 { 58 {
59 _simplexSolver.Reset(); 59 _simplexSolver.Reset();
60 60
61 // compute linear and angular velocity for this interval, to interpolate 61 // compute linear and angular velocity for this interval, to interpolate
62 Vector3 linVelA = new Vector3(), angVelA = new Vector3(), linVelB = new Vector3(), angVelB = new Vector3(); 62 Vector3 linVelA = new Vector3(), angVelA = new Vector3(), linVelB = new Vector3(), angVelB = new Vector3();
63 TransformUtil.CalculateVelocity(fromA, toA, 1f, ref linVelA, ref angVelA); 63 TransformUtil.CalculateVelocity(fromA, toA, 1f, ref linVelA, ref angVelA);
64 TransformUtil.CalculateVelocity(fromB, toB, 1f, ref linVelB, ref angVelB); 64 TransformUtil.CalculateVelocity(fromB, toB, 1f, ref linVelB, ref angVelB);
65 65
66 float boundingRadiusA = _convexA.GetAngularMotionDisc(); 66 float boundingRadiusA = _convexA.GetAngularMotionDisc();
67 float boundingRadiusB = _convexB.GetAngularMotionDisc(); 67 float boundingRadiusB = _convexB.GetAngularMotionDisc();
68 68
69 float maxAngularProjectedVelocity = angVelA.Length() * boundingRadiusA + 69 float maxAngularProjectedVelocity = angVelA.Length() * boundingRadiusA +
70 angVelB.Length() * boundingRadiusB; 70 angVelB.Length() * boundingRadiusB;
71 71
72 float radius = 0.001f; 72 float radius = 0.001f;
73 73
74 float lambda = 0f; 74 float lambda = 0f;
75 Vector3 v = new Vector3(1f, 0f, 0f); 75 Vector3 v = new Vector3(1f, 0f, 0f);
76 76
77 int maxIter = MaxIterations; 77 int maxIter = MaxIterations;
78 78
79 Vector3 n = new Vector3(); 79 Vector3 n = new Vector3();
80 bool hasResult = false; 80 bool hasResult = false;
81 Vector3 c; 81 Vector3 c;
82 82
83 float lastLambda = lambda; 83 float lastLambda = lambda;
84 //float epsilon = 0.001f; 84 //float epsilon = 0.001f;
85 85
86 int numIter = 0; 86 int numIter = 0;
87 //first solution, using GJK 87 //first solution, using GJK
88 88
89 89
90 Matrix identityTrans = Matrix.Identity; 90 Matrix identityTrans = Matrix.Identity;
91 91
92 SphereShape raySphere = new SphereShape(0f); 92 SphereShape raySphere = new SphereShape(0f);
93 raySphere.Margin=0f; 93 raySphere.Margin=0f;
94 94
95 95
96 //result.drawCoordSystem(sphereTr); 96 //result.drawCoordSystem(sphereTr);
97 97
98 PointCollector pointCollector1 = new PointCollector(); 98 PointCollector pointCollector1 = new PointCollector();
99 99
100 GjkPairDetector gjk = new GjkPairDetector(_convexA, _convexB, (VoronoiSimplexSolver)_simplexSolver, _penetrationDepthSolver); 100 GjkPairDetector gjk = new GjkPairDetector(_convexA, _convexB, (VoronoiSimplexSolver)_simplexSolver, _penetrationDepthSolver);
101 GjkPairDetector.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput(); 101 GjkPairDetector.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput();
102 102
103 //we don't use margins during CCD 103 //we don't use margins during CCD
104 gjk.setIgnoreMargin(true); 104 gjk.setIgnoreMargin(true);
105 105
106 input.TransformA = fromA; 106 input.TransformA = fromA;
107 input.TransformB = fromB; 107 input.TransformB = fromB;
108 108
109 DiscreteCollisionDetectorInterface.Result r = (DiscreteCollisionDetectorInterface.Result)pointCollector1; 109 DiscreteCollisionDetectorInterface.Result r = (DiscreteCollisionDetectorInterface.Result)pointCollector1;
110 gjk.GetClosestPoints(input, r, null); 110 gjk.GetClosestPoints(input, r, null);
111 111
112 hasResult = pointCollector1.HasResult; 112 hasResult = pointCollector1.HasResult;
113 c = pointCollector1.PointInWorld; 113 c = pointCollector1.PointInWorld;
114 114
115 if (hasResult) 115 if (hasResult)
116 { 116 {
117 float dist; 117 float dist;
118 dist = pointCollector1.Distance; 118 dist = pointCollector1.Distance;
119 n = pointCollector1.NormalOnBInWorld; 119 n = pointCollector1.NormalOnBInWorld;
120 120
121 //not close enough 121 //not close enough
122 while (dist > radius) 122 while (dist > radius)
123 { 123 {
124 numIter++; 124 numIter++;
125 if (numIter > maxIter) 125 if (numIter > maxIter)
126 return false; //todo: report a failure 126 return false; //todo: report a failure
127 127
128 float dLambda = 0f; 128 float dLambda = 0f;
129 129
130 //calculate safe moving fraction from distance / (linear+rotational velocity) 130 //calculate safe moving fraction from distance / (linear+rotational velocity)
131 131
132 //float clippedDist = GEN_min(angularConservativeRadius,dist); 132 //float clippedDist = GEN_min(angularConservativeRadius,dist);
133 //float clippedDist = dist; 133 //float clippedDist = dist;
134 134
135 float projectedLinearVelocity = Vector3.Dot(linVelB - linVelA, n); 135 float projectedLinearVelocity = Vector3.Dot(linVelB - linVelA, n);
136 136
137 dLambda = dist / (projectedLinearVelocity + maxAngularProjectedVelocity); 137 dLambda = dist / (projectedLinearVelocity + maxAngularProjectedVelocity);
138 138
139 lambda = lambda + dLambda; 139 lambda = lambda + dLambda;
140 140
141 if (lambda > 1f) return false; 141 if (lambda > 1f) return false;
142 if (lambda < 0f) return false; 142 if (lambda < 0f) return false;
143 143
144 //todo: next check with relative epsilon 144 //todo: next check with relative epsilon
145 if (lambda <= lastLambda) 145 if (lambda <= lastLambda)
146 break; 146 break;
147 lastLambda = lambda; 147 lastLambda = lambda;
148 148
149 149
150 //interpolate to next lambda 150 //interpolate to next lambda
151 Matrix interpolatedTransA = new Matrix(), interpolatedTransB = new Matrix(), relativeTrans; 151 Matrix interpolatedTransA = new Matrix(), interpolatedTransB = new Matrix(), relativeTrans;
152 152
153 TransformUtil.IntegrateTransform(fromA, linVelA, angVelA, lambda, ref interpolatedTransA); 153 TransformUtil.IntegrateTransform(fromA, linVelA, angVelA, lambda, ref interpolatedTransA);
154 TransformUtil.IntegrateTransform(fromB, linVelB, angVelB, lambda, ref interpolatedTransB); 154 TransformUtil.IntegrateTransform(fromB, linVelB, angVelB, lambda, ref interpolatedTransB);
155 155
156 relativeTrans = MathHelper.InverseTimes(interpolatedTransB, interpolatedTransA); 156 relativeTrans = MathHelper.InverseTimes(interpolatedTransB, interpolatedTransA);
157 157
158 result.DebugDraw(lambda); 158 result.DebugDraw(lambda);
159 159
160 PointCollector pointCollector = new PointCollector(); 160 PointCollector pointCollector = new PointCollector();
161 gjk = new GjkPairDetector(_convexA, _convexB, (VoronoiSimplexSolver)_simplexSolver, _penetrationDepthSolver); 161 gjk = new GjkPairDetector(_convexA, _convexB, (VoronoiSimplexSolver)_simplexSolver, _penetrationDepthSolver);
162 input = new DiscreteCollisionDetectorInterface.ClosestPointInput(); 162 input = new DiscreteCollisionDetectorInterface.ClosestPointInput();
163 input.TransformA = interpolatedTransA; 163 input.TransformA = interpolatedTransA;
164 input.TransformB = interpolatedTransB; 164 input.TransformB = interpolatedTransB;
165 165
166 // !!!!!!!!!! 166 // !!!!!!!!!!
167 r = (DiscreteCollisionDetectorInterface.Result)pointCollector1; 167 r = (DiscreteCollisionDetectorInterface.Result)pointCollector1;
168 gjk.GetClosestPoints(input, r, null); 168 gjk.GetClosestPoints(input, r, null);
169 169
170 if (pointCollector.HasResult) 170 if (pointCollector.HasResult)
171 { 171 {
172 if (pointCollector.Distance < 0f) 172 if (pointCollector.Distance < 0f)
173 { 173 {
174 //degenerate ?! 174 //degenerate ?!
175 result.Fraction = lastLambda; 175 result.Fraction = lastLambda;
176 result.Normal = n; 176 result.Normal = n;
177 return true; 177 return true;
178 } 178 }
179 c = pointCollector.PointInWorld; 179 c = pointCollector.PointInWorld;
180 180
181 dist = pointCollector.Distance; 181 dist = pointCollector.Distance;
182 } 182 }
183 else 183 else
184 { 184 {
185 //?? 185 //??
186 return false; 186 return false;
187 } 187 }
188 188
189 } 189 }
190 190
191 result.Fraction = lambda; 191 result.Fraction = lambda;
192 result.Normal = n; 192 result.Normal = n;
193 return true; 193 return true;
194 } 194 }
195 195
196 return false; 196 return false;
197 } 197 }
198 } 198 }
199} 199}
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ConvexCast.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ConvexCast.cs
index 9e88a7e..93501ed 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ConvexCast.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ConvexCast.cs
@@ -1,73 +1,73 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 29
30 /// <summary> 30 /// <summary>
31 /// CastResult stores the closest result 31 /// CastResult stores the closest result
32 /// alternatively, add a callback method to decide about closest/all results 32 /// alternatively, add a callback method to decide about closest/all results
33 /// </summary> 33 /// </summary>
34 public class CastResult 34 public class CastResult
35 { 35 {
36 private Vector3 _normal; 36 private Vector3 _normal;
37 private float _fraction; 37 private float _fraction;
38 private Matrix _hitTransformA; 38 private Matrix _hitTransformA;
39 private Matrix _hitTransformB; 39 private Matrix _hitTransformB;
40 private IDebugDraw _debugDrawer; 40 private IDebugDraw _debugDrawer;
41 41
42 public CastResult() 42 public CastResult()
43 { 43 {
44 _fraction = 1e30f; 44 _fraction = 1e30f;
45 } 45 }
46 46
47 public Vector3 Normal { get { return _normal; } set { _normal = value; } } 47 public Vector3 Normal { get { return _normal; } set { _normal = value; } }
48 public float Fraction { get { return _fraction; } set { _fraction = value; } } 48 public float Fraction { get { return _fraction; } set { _fraction = value; } }
49 public Matrix HitTransformA { get { return _hitTransformA; } set { _hitTransformA = value; } } 49 public Matrix HitTransformA { get { return _hitTransformA; } set { _hitTransformA = value; } }
50 public Matrix HitTransformB { get { return _hitTransformB; } set { _hitTransformB = value; } } 50 public Matrix HitTransformB { get { return _hitTransformB; } set { _hitTransformB = value; } }
51 public IDebugDraw DebugDrawer { get { return _debugDrawer; } set { _debugDrawer = value; } } 51 public IDebugDraw DebugDrawer { get { return _debugDrawer; } set { _debugDrawer = value; } }
52 52
53 public virtual void DebugDraw(float fraction) { } 53 public virtual void DebugDraw(float fraction) { }
54 public virtual void DrawCoordSystem(Matrix trans) { } 54 public virtual void DrawCoordSystem(Matrix trans) { }
55 } 55 }
56 56
57 /// <summary> 57 /// <summary>
58 /// ConvexCast is an interface for Casting 58 /// ConvexCast is an interface for Casting
59 /// </summary> 59 /// </summary>
60 public interface IConvexCast 60 public interface IConvexCast
61 { 61 {
62 /// <summary> 62 /// <summary>
63 /// cast a convex against another convex object 63 /// cast a convex against another convex object
64 /// </summary> 64 /// </summary>
65 /// <param name="fromA"></param> 65 /// <param name="fromA"></param>
66 /// <param name="toA"></param> 66 /// <param name="toA"></param>
67 /// <param name="fromB"></param> 67 /// <param name="fromB"></param>
68 /// <param name="toB"></param> 68 /// <param name="toB"></param>
69 /// <param name="result"></param> 69 /// <param name="result"></param>
70 /// <returns></returns> 70 /// <returns></returns>
71 bool CalcTimeOfImpact(Matrix fromA, Matrix toA, Matrix fromB, Matrix toB, CastResult result); 71 bool CalcTimeOfImpact(Matrix fromA, Matrix toA, Matrix fromB, Matrix toB, CastResult result);
72 } 72 }
73} 73}
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/DiscreteCollisionDetectorInterface.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/DiscreteCollisionDetectorInterface.cs
index fae2557..5b07d9b 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/DiscreteCollisionDetectorInterface.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/DiscreteCollisionDetectorInterface.cs
@@ -1,117 +1,117 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 public abstract class DiscreteCollisionDetectorInterface 29 public abstract class DiscreteCollisionDetectorInterface
30 { 30 {
31 public abstract class Result 31 public abstract class Result
32 { 32 {
33 public abstract void SetShapeIdentifiers(int partIdA, int indexA, int partIdB, int indexB); 33 public abstract void SetShapeIdentifiers(int partIdA, int indexA, int partIdB, int indexB);
34 public abstract void AddContactPoint(Vector3 normalOnBInWorld, Vector3 pointInWorld, float depth); 34 public abstract void AddContactPoint(Vector3 normalOnBInWorld, Vector3 pointInWorld, float depth);
35 } 35 }
36 36
37 public class ClosestPointInput 37 public class ClosestPointInput
38 { 38 {
39 private float _maximumDistanceSquared; 39 private float _maximumDistanceSquared;
40 private Matrix _transformA, _transformB; 40 private Matrix _transformA, _transformB;
41 41
42 #region Properties 42 #region Properties
43 public Matrix TransformB 43 public Matrix TransformB
44 { 44 {
45 get { return _transformB; } 45 get { return _transformB; }
46 set { _transformB = value; } 46 set { _transformB = value; }
47 } 47 }
48 48
49 public Matrix TransformA 49 public Matrix TransformA
50 { 50 {
51 get { return _transformA; } 51 get { return _transformA; }
52 set { _transformA = value; } 52 set { _transformA = value; }
53 } 53 }
54 54
55 public float MaximumDistanceSquared 55 public float MaximumDistanceSquared
56 { 56 {
57 get { return _maximumDistanceSquared; } 57 get { return _maximumDistanceSquared; }
58 set { _maximumDistanceSquared = value; } 58 set { _maximumDistanceSquared = value; }
59 } 59 }
60 #endregion 60 #endregion
61 61
62 public ClosestPointInput() 62 public ClosestPointInput()
63 { 63 {
64 _maximumDistanceSquared = 1e30f; 64 _maximumDistanceSquared = 1e30f;
65 } 65 }
66 } 66 }
67 67
68 public abstract void GetClosestPoints(ClosestPointInput input, Result output, IDebugDraw debugDraw); 68 public abstract void GetClosestPoints(ClosestPointInput input, Result output, IDebugDraw debugDraw);
69 } 69 }
70 70
71 public class StorageResult : DiscreteCollisionDetectorInterface.Result 71 public class StorageResult : DiscreteCollisionDetectorInterface.Result
72 { 72 {
73 private Vector3 _closestPointInB; 73 private Vector3 _closestPointInB;
74 private Vector3 _normalOnSurfaceB; 74 private Vector3 _normalOnSurfaceB;
75 private float _distance; //negative means penetration ! 75 private float _distance; //negative means penetration !
76 76
77 #region Properties 77 #region Properties
78 78
79 public float Distance 79 public float Distance
80 { 80 {
81 get { return _distance; } 81 get { return _distance; }
82 set { _distance = value; } 82 set { _distance = value; }
83 } 83 }
84 public Vector3 NormalOnSurfaceB 84 public Vector3 NormalOnSurfaceB
85 { 85 {
86 get { return _normalOnSurfaceB; } 86 get { return _normalOnSurfaceB; }
87 set { _normalOnSurfaceB = value; } 87 set { _normalOnSurfaceB = value; }
88 } 88 }
89 public Vector3 ClosestPointInB 89 public Vector3 ClosestPointInB
90 { 90 {
91 get { return _closestPointInB; } 91 get { return _closestPointInB; }
92 set { _closestPointInB = value; } 92 set { _closestPointInB = value; }
93 } 93 }
94 94
95 #endregion 95 #endregion
96 96
97 public StorageResult() 97 public StorageResult()
98 { 98 {
99 _distance = 1e30f; 99 _distance = 1e30f;
100 } 100 }
101 101
102 public override void AddContactPoint(Vector3 normalOnBInWorld, Vector3 pointInWorld, float depth) 102 public override void AddContactPoint(Vector3 normalOnBInWorld, Vector3 pointInWorld, float depth)
103 { 103 {
104 if (depth < _distance) 104 if (depth < _distance)
105 { 105 {
106 _normalOnSurfaceB = normalOnBInWorld; 106 _normalOnSurfaceB = normalOnBInWorld;
107 _closestPointInB = pointInWorld; 107 _closestPointInB = pointInWorld;
108 _distance = depth; 108 _distance = depth;
109 } 109 }
110 } 110 }
111 111
112 public override void SetShapeIdentifiers(int partId0, int index0, int partId1, int index1) 112 public override void SetShapeIdentifiers(int partId0, int index0, int partId1, int index1)
113 { 113 {
114 throw new Exception("The method or operation is not implemented."); 114 throw new Exception("The method or operation is not implemented.");
115 } 115 }
116 } 116 }
117} 117}
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkConvexCast.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkConvexCast.cs
index 4ee9599..ea7d335 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkConvexCast.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkConvexCast.cs
@@ -1,176 +1,176 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 /// <summary> 29 /// <summary>
30 /// GjkConvexCast performs a raycast on a convex object using support mapping. 30 /// GjkConvexCast performs a raycast on a convex object using support mapping.
31 /// </summary> 31 /// </summary>
32 public class GjkConvexCast : IConvexCast 32 public class GjkConvexCast : IConvexCast
33 { 33 {
34 private VoronoiSimplexSolver _simplexSolver; 34 private VoronoiSimplexSolver _simplexSolver;
35 private ConvexShape _convexA, _convexB; 35 private ConvexShape _convexA, _convexB;
36 36
37 public GjkConvexCast(ConvexShape convexShapeA, ConvexShape convexShapeB, VoronoiSimplexSolver solver) 37 public GjkConvexCast(ConvexShape convexShapeA, ConvexShape convexShapeB, VoronoiSimplexSolver solver)
38 { 38 {
39 _simplexSolver = solver; 39 _simplexSolver = solver;
40 40
41 _convexA = convexShapeA; 41 _convexA = convexShapeA;
42 _convexB = convexShapeB; 42 _convexB = convexShapeB;
43 } 43 }
44 44
45 #region IConvexCast Members 45 #region IConvexCast Members
46 46
47 /// <summary> 47 /// <summary>
48 /// cast a convex against another convex object 48 /// cast a convex against another convex object
49 /// </summary> 49 /// </summary>
50 /// <param name="fromA"></param> 50 /// <param name="fromA"></param>
51 /// <param name="toA"></param> 51 /// <param name="toA"></param>
52 /// <param name="fromB"></param> 52 /// <param name="fromB"></param>
53 /// <param name="toB"></param> 53 /// <param name="toB"></param>
54 /// <param name="result"></param> 54 /// <param name="result"></param>
55 /// <returns></returns> 55 /// <returns></returns>
56 public bool CalcTimeOfImpact(Matrix fromA, Matrix toA, Matrix fromB, Matrix toB, CastResult result) 56 public bool CalcTimeOfImpact(Matrix fromA, Matrix toA, Matrix fromB, Matrix toB, CastResult result)
57 { 57 {
58 MinkowskiSumShape combined = new MinkowskiSumShape(_convexA, _convexB); 58 MinkowskiSumShape combined = new MinkowskiSumShape(_convexA, _convexB);
59 59
60 Matrix rayFromLocalA = MathHelper.InvertMatrix(fromA) * fromB; 60 Matrix rayFromLocalA = MathHelper.InvertMatrix(fromA) * fromB;
61 Matrix rayToLocalA = MathHelper.InvertMatrix(toA) * toB; 61 Matrix rayToLocalA = MathHelper.InvertMatrix(toA) * toB;
62 62
63 Matrix transformA = fromA; 63 Matrix transformA = fromA;
64 Matrix transformB = fromB; 64 Matrix transformB = fromB;
65 65
66 transformA.Translation = new Vector3(0, 0, 0); 66 transformA.Translation = new Vector3(0, 0, 0);
67 transformB.Translation = new Vector3(0, 0, 0); 67 transformB.Translation = new Vector3(0, 0, 0);
68 68
69 combined.TransformA = transformA; 69 combined.TransformA = transformA;
70 combined.TransformB = transformB; 70 combined.TransformB = transformB;
71 71
72 float radius = 0.01f; 72 float radius = 0.01f;
73 float lambda = 0; 73 float lambda = 0;
74 74
75 Vector3 s = rayFromLocalA.Translation; 75 Vector3 s = rayFromLocalA.Translation;
76 Vector3 r = rayToLocalA.Translation - rayFromLocalA.Translation; 76 Vector3 r = rayToLocalA.Translation - rayFromLocalA.Translation;
77 Vector3 x = s; 77 Vector3 x = s;
78 Vector3 n = new Vector3(); 78 Vector3 n = new Vector3();
79 Vector3 c = new Vector3(); 79 Vector3 c = new Vector3();
80 80
81 bool hasResult = false; 81 bool hasResult = false;
82 float lastLambda = lambda; 82 float lastLambda = lambda;
83 83
84 IConvexPenetrationDepthSolver penSolver = null; 84 IConvexPenetrationDepthSolver penSolver = null;
85 Matrix identityTransform = Matrix.Identity; 85 Matrix identityTransform = Matrix.Identity;
86 86
87 SphereShape raySphere = new SphereShape(0.0f); 87 SphereShape raySphere = new SphereShape(0.0f);
88 raySphere.Margin=0.0f; 88 raySphere.Margin=0.0f;
89 89
90 Matrix sphereTransform = Matrix.Identity; 90 Matrix sphereTransform = Matrix.Identity;
91 sphereTransform.Translation = rayFromLocalA.Translation; 91 sphereTransform.Translation = rayFromLocalA.Translation;
92 92
93 result.DrawCoordSystem(sphereTransform); 93 result.DrawCoordSystem(sphereTransform);
94 94
95 { 95 {
96 PointCollector pointCollector = new PointCollector(); 96 PointCollector pointCollector = new PointCollector();
97 GjkPairDetector gjk = new GjkPairDetector(raySphere, combined, _simplexSolver, penSolver); 97 GjkPairDetector gjk = new GjkPairDetector(raySphere, combined, _simplexSolver, penSolver);
98 98
99 GjkPairDetector.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput(); 99 GjkPairDetector.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput();
100 input.TransformA = sphereTransform; 100 input.TransformA = sphereTransform;
101 input.TransformB = identityTransform; 101 input.TransformB = identityTransform;
102 102
103 gjk.GetClosestPoints(input, pointCollector, null); 103 gjk.GetClosestPoints(input, pointCollector, null);
104 104
105 hasResult = pointCollector.HasResult; 105 hasResult = pointCollector.HasResult;
106 106
107 c = pointCollector.PointInWorld; 107 c = pointCollector.PointInWorld;
108 n = pointCollector.NormalOnBInWorld; 108 n = pointCollector.NormalOnBInWorld;
109 } 109 }
110 110
111 if (hasResult) 111 if (hasResult)
112 { 112 {
113 float dist = (c - x).Length(); 113 float dist = (c - x).Length();
114 114
115 if (dist < radius) 115 if (dist < radius)
116 { 116 {
117 lastLambda = 1.0f; 117 lastLambda = 1.0f;
118 } 118 }
119 119
120 while (dist > radius) 120 while (dist > radius)
121 { 121 {
122 n = x - c; 122 n = x - c;
123 float dot = Vector3.Dot(n, r); 123 float dot = Vector3.Dot(n, r);
124 124
125 if (dot >= -(MathHelper.Epsilon * MathHelper.Epsilon)) return false; 125 if (dot >= -(MathHelper.Epsilon * MathHelper.Epsilon)) return false;
126 126
127 lambda = lambda - Vector3.Distance(n, n) / dot; 127 lambda = lambda - Vector3.Distance(n, n) / dot;
128 if (lambda <= lastLambda) break; 128 if (lambda <= lastLambda) break;
129 129
130 lastLambda = lambda; 130 lastLambda = lambda;
131 131
132 x = s + lambda * r; 132 x = s + lambda * r;
133 133
134 sphereTransform.Translation = x; 134 sphereTransform.Translation = x;
135 result.DrawCoordSystem(sphereTransform); 135 result.DrawCoordSystem(sphereTransform);
136 PointCollector pointCollector = new PointCollector(); 136 PointCollector pointCollector = new PointCollector();
137 137
138 GjkPairDetector gjk = new GjkPairDetector(raySphere, combined, _simplexSolver, penSolver); 138 GjkPairDetector gjk = new GjkPairDetector(raySphere, combined, _simplexSolver, penSolver);
139 GjkPairDetector.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput(); 139 GjkPairDetector.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput();
140 input.TransformA = sphereTransform; 140 input.TransformA = sphereTransform;
141 input.TransformB = identityTransform; 141 input.TransformB = identityTransform;
142 142
143 gjk.GetClosestPoints(input, pointCollector, null); 143 gjk.GetClosestPoints(input, pointCollector, null);
144 144
145 if (pointCollector.HasResult) 145 if (pointCollector.HasResult)
146 { 146 {
147 if (pointCollector.Distance < 0.0f) 147 if (pointCollector.Distance < 0.0f)
148 { 148 {
149 result.Fraction = lastLambda; 149 result.Fraction = lastLambda;
150 result.Normal = n; 150 result.Normal = n;
151 return true; 151 return true;
152 } 152 }
153 153
154 c = pointCollector.PointInWorld; 154 c = pointCollector.PointInWorld;
155 dist = (c - x).Length(); 155 dist = (c - x).Length();
156 } 156 }
157 else 157 else
158 { 158 {
159 return false; 159 return false;
160 } 160 }
161 } 161 }
162 162
163 if (lastLambda < 1.0f) 163 if (lastLambda < 1.0f)
164 { 164 {
165 result.Fraction = lastLambda; 165 result.Fraction = lastLambda;
166 result.Normal = n; 166 result.Normal = n;
167 return true; 167 return true;
168 } 168 }
169 } 169 }
170 170
171 return false; 171 return false;
172 } 172 }
173 173
174 #endregion 174 #endregion
175 } 175 }
176} 176}
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkEpa.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkEpa.cs
index 50ae7ab..a3064db 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkEpa.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkEpa.cs
@@ -1,633 +1,633 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 /// <summary> 29 /// <summary>
30 /// GJK-EPA collision solver by Nathanael Presson 30 /// GJK-EPA collision solver by Nathanael Presson
31 /// Nov.2006 31 /// Nov.2006
32 /// </summary> 32 /// </summary>
33 public class GjkEpa 33 public class GjkEpa
34 { 34 {
35 //private static readonly int _precision = 1 /* U(sizeof(F) == 4)*/; 35 //private static readonly int _precision = 1 /* U(sizeof(F) == 4)*/;
36 36
37 private static readonly float _infinity = MathHelper.Infinity; 37 private static readonly float _infinity = MathHelper.Infinity;
38 //private static readonly float _pi = (float)Math.PI; 38 //private static readonly float _pi = (float)Math.PI;
39 private static readonly float _twoPi = (float)(Math.PI * 2); 39 private static readonly float _twoPi = (float)(Math.PI * 2);
40 40
41 private static readonly int _gjkMaxIterations = 128; 41 private static readonly int _gjkMaxIterations = 128;
42 private static readonly int _gjkHashSize = 1 << 6; 42 private static readonly int _gjkHashSize = 1 << 6;
43 private static readonly int _gjkHashMask = _gjkHashSize - 1; 43 private static readonly int _gjkHashMask = _gjkHashSize - 1;
44 private static readonly float _gjkInSimplexEpsilon = 0.0001f; 44 private static readonly float _gjkInSimplexEpsilon = 0.0001f;
45 private static readonly float _gjkSquareInSimplexEpsilon = _gjkInSimplexEpsilon * _gjkInSimplexEpsilon; 45 private static readonly float _gjkSquareInSimplexEpsilon = _gjkInSimplexEpsilon * _gjkInSimplexEpsilon;
46 46
47 private static readonly int _epaMaxIterations = 256; 47 private static readonly int _epaMaxIterations = 256;
48 private static readonly float _epaInFaceEpsilon = 0.01f; 48 private static readonly float _epaInFaceEpsilon = 0.01f;
49 private static readonly float _epaAccuracy = 0.001f; 49 private static readonly float _epaAccuracy = 0.001f;
50 50
51 public static float EpaAccuracy { get { return _epaAccuracy; } } 51 public static float EpaAccuracy { get { return _epaAccuracy; } }
52 52
53 private static float Abs(float v) { return (v < 0 ? -v : v); } 53 private static float Abs(float v) { return (v < 0 ? -v : v); }
54 private static float Sign(float v) { return (v < 0 ? -1 : 1); } 54 private static float Sign(float v) { return (v < 0 ? -1 : 1); }
55 55
56 static void Swap<T>(ref T a, ref T b) 56 static void Swap<T>(ref T a, ref T b)
57 { 57 {
58 T t = a; 58 T t = a;
59 a = b; 59 a = b;
60 b = t; 60 b = t;
61 } 61 }
62 62
63 public class Gjk 63 public class Gjk
64 { 64 {
65 public class MinkowskiVertice 65 public class MinkowskiVertice
66 { 66 {
67 private Vector3 _vertice; /* Minkowski vertice */ 67 private Vector3 _vertice; /* Minkowski vertice */
68 private Vector3 _ray; /* Ray */ 68 private Vector3 _ray; /* Ray */
69 69
70 public Vector3 Vertice { get { return _vertice; } set { _vertice = value; } } 70 public Vector3 Vertice { get { return _vertice; } set { _vertice = value; } }
71 public Vector3 Ray { get { return _ray; } set { _ray = value; } } 71 public Vector3 Ray { get { return _ray; } set { _ray = value; } }
72 } 72 }
73 public class He 73 public class He
74 { 74 {
75 private Vector3 _ray; 75 private Vector3 _ray;
76 private He _next; 76 private He _next;
77 77
78 public He Next { get { return _next; } set { _next = value; } } 78 public He Next { get { return _next; } set { _next = value; } }
79 public Vector3 Ray { get { return _ray; } set { _ray = value; } } 79 public Vector3 Ray { get { return _ray; } set { _ray = value; } }
80 } 80 }
81 81
82 private He[] _table = new He[_gjkHashSize]; 82 private He[] _table = new He[_gjkHashSize];
83 private Matrix[] _wrotations = new Matrix[2]; 83 private Matrix[] _wrotations = new Matrix[2];
84 private Vector3[] _positions = new Vector3[2]; 84 private Vector3[] _positions = new Vector3[2];
85 private ConvexShape[] _shapes = new ConvexShape[2]; 85 private ConvexShape[] _shapes = new ConvexShape[2];
86 private MinkowskiVertice[] _simplex = new MinkowskiVertice[5]; 86 private MinkowskiVertice[] _simplex = new MinkowskiVertice[5];
87 private Vector3 _ray; 87 private Vector3 _ray;
88 private int _order; 88 private int _order;
89 private int _iterations; 89 private int _iterations;
90 private float _margin; 90 private float _margin;
91 private bool _failed; 91 private bool _failed;
92 92
93 public Gjk(Matrix wrotationA, Vector3 positionA, ConvexShape shapeA, 93 public Gjk(Matrix wrotationA, Vector3 positionA, ConvexShape shapeA,
94 Matrix wrotationB, Vector3 positionB, ConvexShape shapeB) 94 Matrix wrotationB, Vector3 positionB, ConvexShape shapeB)
95 : this(wrotationA, positionA, shapeA, wrotationB, positionB, shapeB, 0) { } 95 : this(wrotationA, positionA, shapeA, wrotationB, positionB, shapeB, 0) { }
96 96
97 public Gjk(Matrix wrotationA, Vector3 positionA, ConvexShape shapeA, 97 public Gjk(Matrix wrotationA, Vector3 positionA, ConvexShape shapeA,
98 Matrix wrotationB, Vector3 positionB, ConvexShape shapeB, 98 Matrix wrotationB, Vector3 positionB, ConvexShape shapeB,
99 float pmargin) 99 float pmargin)
100 { 100 {
101 for (int i = 0; i < _simplex.Length; i++) 101 for (int i = 0; i < _simplex.Length; i++)
102 _simplex[i] = new MinkowskiVertice(); 102 _simplex[i] = new MinkowskiVertice();
103 103
104 for (int i = 0; i < _wrotations.Length; i++) 104 for (int i = 0; i < _wrotations.Length; i++)
105 _wrotations[i] = new Matrix(); 105 _wrotations[i] = new Matrix();
106 106
107 for (int i = 0; i < _positions.Length; i++) 107 for (int i = 0; i < _positions.Length; i++)
108 _positions[i] = new Vector3(); 108 _positions[i] = new Vector3();
109 109
110 _wrotations[0] = wrotationA; _positions[0] = positionA; 110 _wrotations[0] = wrotationA; _positions[0] = positionA;
111 _shapes[0] = shapeA; 111 _shapes[0] = shapeA;
112 _wrotations[0].Translation = Vector3.Zero; 112 _wrotations[0].Translation = Vector3.Zero;
113 _wrotations[1] = wrotationB; _positions[1] = positionB; 113 _wrotations[1] = wrotationB; _positions[1] = positionB;
114 _shapes[1] = shapeB; 114 _shapes[1] = shapeB;
115 _wrotations[1].Translation = Vector3.Zero; 115 _wrotations[1].Translation = Vector3.Zero;
116 //sablock = sa->BeginBlock(); 116 //sablock = sa->BeginBlock();
117 _margin = pmargin; 117 _margin = pmargin;
118 _failed = false; 118 _failed = false;
119 } 119 }
120 120
121 public bool Failed { get { return _failed; } } 121 public bool Failed { get { return _failed; } }
122 public int Iterations { get { return _iterations; } } 122 public int Iterations { get { return _iterations; } }
123 public int Order { get { return _order; } } 123 public int Order { get { return _order; } }
124 public MinkowskiVertice[] Simplex { get { return _simplex; } } 124 public MinkowskiVertice[] Simplex { get { return _simplex; } }
125 125
126 public int Hash(Vector3 v) 126 public int Hash(Vector3 v)
127 { 127 {
128 int h = ((int)(v.X * 15461) ^ (int)(v.Y * 83003) ^ (int)(v.Z * 15473)); 128 int h = ((int)(v.X * 15461) ^ (int)(v.Y * 83003) ^ (int)(v.Z * 15473));
129 return (h * 169639) & _gjkHashMask; 129 return (h * 169639) & _gjkHashMask;
130 } 130 }
131 131
132 public bool FetchSupport() 132 public bool FetchSupport()
133 { 133 {
134 int h = Hash(_ray); 134 int h = Hash(_ray);
135 He e = _table[h]; 135 He e = _table[h];
136 while (e != null) 136 while (e != null)
137 { 137 {
138 if (e.Ray == _ray) 138 if (e.Ray == _ray)
139 { 139 {
140 --_order; 140 --_order;
141 return (false); 141 return (false);
142 } 142 }
143 else e = e.Next; 143 else e = e.Next;
144 } 144 }
145 e = new He(); 145 e = new He();
146 e.Ray = _ray; 146 e.Ray = _ray;
147 e.Next = _table[h]; 147 e.Next = _table[h];
148 _table[h] = e; 148 _table[h] = e;
149 Support(_ray, ref _simplex[++_order]); 149 Support(_ray, ref _simplex[++_order]);
150 return (Vector3.Dot(_ray, _simplex[_order].Vertice) > 0); 150 return (Vector3.Dot(_ray, _simplex[_order].Vertice) > 0);
151 } 151 }
152 152
153 public Vector3 LocalSupport(Vector3 d, int i) 153 public Vector3 LocalSupport(Vector3 d, int i)
154 { 154 {
155 Matrix m = _wrotations[i]; 155 Matrix m = _wrotations[i];
156 m.Translation = Vector3.Zero; 156 m.Translation = Vector3.Zero;
157 Vector3 vtx = Vector3.TransformNormal(d, m); 157 Vector3 vtx = Vector3.TransformNormal(d, m);
158 Vector3 result = MathHelper.MatrixToVector(_wrotations[i], _shapes[i].LocalGetSupportingVertex(vtx)); 158 Vector3 result = MathHelper.MatrixToVector(_wrotations[i], _shapes[i].LocalGetSupportingVertex(vtx));
159 return (result + _positions[i]); 159 return (result + _positions[i]);
160 } 160 }
161 161
162 public void Support(Vector3 d, ref MinkowskiVertice v) 162 public void Support(Vector3 d, ref MinkowskiVertice v)
163 { 163 {
164 v.Ray = d; 164 v.Ray = d;
165 v.Vertice = LocalSupport(d, 0) - LocalSupport(-d, 1) + d * _margin; 165 v.Vertice = LocalSupport(d, 0) - LocalSupport(-d, 1) + d * _margin;
166 } 166 }
167 167
168 public bool SolveSimplex2(Vector3 ao, Vector3 ab) 168 public bool SolveSimplex2(Vector3 ao, Vector3 ab)
169 { 169 {
170 if (Vector3.Dot(ab, ao) >= 0) 170 if (Vector3.Dot(ab, ao) >= 0)
171 { 171 {
172 Vector3 cabo = Vector3.Cross(ab, ao); 172 Vector3 cabo = Vector3.Cross(ab, ao);
173 if (cabo.LengthSquared() > _gjkSquareInSimplexEpsilon) 173 if (cabo.LengthSquared() > _gjkSquareInSimplexEpsilon)
174 { _ray = Vector3.Cross(cabo, ab); } 174 { _ray = Vector3.Cross(cabo, ab); }
175 else 175 else
176 { return true; } 176 { return true; }
177 } 177 }
178 else 178 else
179 { 179 {
180 _order = 0; 180 _order = 0;
181 _simplex[0].Ray = _simplex[1].Ray; 181 _simplex[0].Ray = _simplex[1].Ray;
182 _simplex[0].Vertice = _simplex[1].Vertice; 182 _simplex[0].Vertice = _simplex[1].Vertice;
183 183
184 _ray = ao; 184 _ray = ao;
185 } 185 }
186 return false; 186 return false;
187 } 187 }
188 188
189 public bool SolveSimplex3(Vector3 ao, Vector3 ab, Vector3 ac) 189 public bool SolveSimplex3(Vector3 ao, Vector3 ab, Vector3 ac)
190 { 190 {
191 return (SolveSimplex3a(ao, ab, ac, Vector3.Cross(ab, ac))); 191 return (SolveSimplex3a(ao, ab, ac, Vector3.Cross(ab, ac)));
192 } 192 }
193 193
194 public bool SolveSimplex3a(Vector3 ao, Vector3 ab, Vector3 ac, Vector3 cabc) 194 public bool SolveSimplex3a(Vector3 ao, Vector3 ab, Vector3 ac, Vector3 cabc)
195 { 195 {
196 if ((Vector3.Dot(Vector3.Cross(cabc, ab), ao)) < -_gjkInSimplexEpsilon) 196 if ((Vector3.Dot(Vector3.Cross(cabc, ab), ao)) < -_gjkInSimplexEpsilon)
197 { 197 {
198 _order = 1; 198 _order = 1;
199 _simplex[0].Vertice = _simplex[1].Vertice; 199 _simplex[0].Vertice = _simplex[1].Vertice;
200 _simplex[0].Ray = _simplex[1].Ray; 200 _simplex[0].Ray = _simplex[1].Ray;
201 201
202 _simplex[1].Vertice = _simplex[2].Vertice; 202 _simplex[1].Vertice = _simplex[2].Vertice;
203 _simplex[1].Ray = _simplex[2].Ray; 203 _simplex[1].Ray = _simplex[2].Ray;
204 204
205 return (SolveSimplex2(ao, ab)); 205 return (SolveSimplex2(ao, ab));
206 } 206 }
207 else if (Vector3.Dot(Vector3.Cross(cabc, ac), ao) > +_gjkInSimplexEpsilon) 207 else if (Vector3.Dot(Vector3.Cross(cabc, ac), ao) > +_gjkInSimplexEpsilon)
208 { 208 {
209 _order = 1; 209 _order = 1;
210 _simplex[1].Vertice = _simplex[2].Vertice; 210 _simplex[1].Vertice = _simplex[2].Vertice;
211 _simplex[1].Ray = _simplex[2].Ray; 211 _simplex[1].Ray = _simplex[2].Ray;
212 212
213 return (SolveSimplex2(ao, ac)); 213 return (SolveSimplex2(ao, ac));
214 } 214 }
215 else 215 else
216 { 216 {
217 float d = Vector3.Dot(cabc, ao); 217 float d = Vector3.Dot(cabc, ao);
218 if (Abs(d) > _gjkInSimplexEpsilon) 218 if (Abs(d) > _gjkInSimplexEpsilon)
219 { 219 {
220 if (d > 0) 220 if (d > 0)
221 { _ray = cabc; } 221 { _ray = cabc; }
222 else 222 else
223 { _ray = -cabc; Swap<MinkowskiVertice>(ref _simplex[0], ref _simplex[1]); } 223 { _ray = -cabc; Swap<MinkowskiVertice>(ref _simplex[0], ref _simplex[1]); }
224 return (false); 224 return (false);
225 } 225 }
226 else return (true); 226 else return (true);
227 } 227 }
228 } 228 }
229 229
230 public bool SolveSimplex4(Vector3 ao, Vector3 ab, Vector3 ac, Vector3 ad) 230 public bool SolveSimplex4(Vector3 ao, Vector3 ab, Vector3 ac, Vector3 ad)
231 { 231 {
232 Vector3 crs; 232 Vector3 crs;
233 if (Vector3.Dot((crs = Vector3.Cross(ab, ac)), ao) > _gjkInSimplexEpsilon) 233 if (Vector3.Dot((crs = Vector3.Cross(ab, ac)), ao) > _gjkInSimplexEpsilon)
234 { 234 {
235 _order = 2; 235 _order = 2;
236 _simplex[0].Vertice = _simplex[1].Vertice; 236 _simplex[0].Vertice = _simplex[1].Vertice;
237 _simplex[0].Ray = _simplex[1].Ray; 237 _simplex[0].Ray = _simplex[1].Ray;
238 238
239 _simplex[1].Vertice = _simplex[2].Vertice; 239 _simplex[1].Vertice = _simplex[2].Vertice;
240 _simplex[1].Ray = _simplex[2].Ray; 240 _simplex[1].Ray = _simplex[2].Ray;
241 241
242 _simplex[2].Vertice = _simplex[3].Vertice; 242 _simplex[2].Vertice = _simplex[3].Vertice;
243 _simplex[2].Ray = _simplex[3].Ray; 243 _simplex[2].Ray = _simplex[3].Ray;
244 244
245 return (SolveSimplex3a(ao, ab, ac, crs)); 245 return (SolveSimplex3a(ao, ab, ac, crs));
246 } 246 }
247 else if (Vector3.Dot((crs = Vector3.Cross(ac, ad)), ao) > _gjkInSimplexEpsilon) 247 else if (Vector3.Dot((crs = Vector3.Cross(ac, ad)), ao) > _gjkInSimplexEpsilon)
248 { 248 {
249 _order = 2; 249 _order = 2;
250 _simplex[2].Vertice = _simplex[3].Vertice; 250 _simplex[2].Vertice = _simplex[3].Vertice;
251 _simplex[2].Ray = _simplex[3].Ray; 251 _simplex[2].Ray = _simplex[3].Ray;
252 252
253 return (SolveSimplex3a(ao, ac, ad, crs)); 253 return (SolveSimplex3a(ao, ac, ad, crs));
254 } 254 }
255 else if (Vector3.Dot((crs = Vector3.Cross(ad, ab)), ao) > _gjkInSimplexEpsilon) 255 else if (Vector3.Dot((crs = Vector3.Cross(ad, ab)), ao) > _gjkInSimplexEpsilon)
256 { 256 {
257 _order = 2; 257 _order = 2;
258 258
259 _simplex[1].Vertice = _simplex[0].Vertice; 259 _simplex[1].Vertice = _simplex[0].Vertice;
260 _simplex[1].Ray = _simplex[0].Ray; 260 _simplex[1].Ray = _simplex[0].Ray;
261 261
262 _simplex[0].Vertice = _simplex[2].Vertice; 262 _simplex[0].Vertice = _simplex[2].Vertice;
263 _simplex[0].Ray = _simplex[2].Ray; 263 _simplex[0].Ray = _simplex[2].Ray;
264 264
265 _simplex[2].Vertice = _simplex[3].Vertice; 265 _simplex[2].Vertice = _simplex[3].Vertice;
266 _simplex[2].Ray = _simplex[3].Ray; 266 _simplex[2].Ray = _simplex[3].Ray;
267 267
268 return (SolveSimplex3a(ao, ad, ab, crs)); 268 return (SolveSimplex3a(ao, ad, ab, crs));
269 } 269 }
270 else return (true); 270 else return (true);
271 } 271 }
272 272
273 public bool SearchOrigin() 273 public bool SearchOrigin()
274 { 274 {
275 return SearchOrigin(new Vector3(1, 0, 0)); 275 return SearchOrigin(new Vector3(1, 0, 0));
276 } 276 }
277 277
278 public bool SearchOrigin(Vector3 initray) 278 public bool SearchOrigin(Vector3 initray)
279 { 279 {
280 _iterations = 0; 280 _iterations = 0;
281 unchecked 281 unchecked
282 { 282 {
283 _order = (int)(-1); 283 _order = (int)(-1);
284 } 284 }
285 _failed = false; 285 _failed = false;
286 _ray = Vector3.Normalize(initray); 286 _ray = Vector3.Normalize(initray);
287 287
288 //ClearMemory(table, sizeof(void*) * GJK_hashsize); 288 //ClearMemory(table, sizeof(void*) * GJK_hashsize);
289 for (int i = 0; i < _table.Length; i++) 289 for (int i = 0; i < _table.Length; i++)
290 _table[i] = null; 290 _table[i] = null;
291 FetchSupport(); 291 FetchSupport();
292 _ray = -_simplex[0].Vertice; 292 _ray = -_simplex[0].Vertice;
293 for (; _iterations < _gjkMaxIterations; ++_iterations) 293 for (; _iterations < _gjkMaxIterations; ++_iterations)
294 { 294 {
295 float rl = _ray.Length(); 295 float rl = _ray.Length();
296 _ray /= rl > 0 ? rl : 1; 296 _ray /= rl > 0 ? rl : 1;
297 if (FetchSupport()) 297 if (FetchSupport())
298 { 298 {
299 bool found = (false); 299 bool found = (false);
300 switch (_order) 300 switch (_order)
301 { 301 {
302 case 1: found = SolveSimplex2(-_simplex[1].Vertice, _simplex[0].Vertice - _simplex[1].Vertice); break; 302 case 1: found = SolveSimplex2(-_simplex[1].Vertice, _simplex[0].Vertice - _simplex[1].Vertice); break;
303 case 2: found = SolveSimplex3(-_simplex[2].Vertice, _simplex[1].Vertice - _simplex[2].Vertice, _simplex[0].Vertice - _simplex[2].Vertice); break; 303 case 2: found = SolveSimplex3(-_simplex[2].Vertice, _simplex[1].Vertice - _simplex[2].Vertice, _simplex[0].Vertice - _simplex[2].Vertice); break;
304 case 3: found = SolveSimplex4(-_simplex[3].Vertice, _simplex[2].Vertice - _simplex[3].Vertice, _simplex[1].Vertice - _simplex[3].Vertice, _simplex[0].Vertice - _simplex[3].Vertice); break; 304 case 3: found = SolveSimplex4(-_simplex[3].Vertice, _simplex[2].Vertice - _simplex[3].Vertice, _simplex[1].Vertice - _simplex[3].Vertice, _simplex[0].Vertice - _simplex[3].Vertice); break;
305 } 305 }
306 if (found) return (true); 306 if (found) return (true);
307 } 307 }
308 else return (false); 308 else return (false);
309 } 309 }
310 _failed = true; 310 _failed = true;
311 return (false); 311 return (false);
312 } 312 }
313 313
314 public bool EncloseOrigin() 314 public bool EncloseOrigin()
315 { 315 {
316 switch (_order) 316 switch (_order)
317 { 317 {
318 /* Point */ 318 /* Point */
319 case 0: break; 319 case 0: break;
320 /* Line */ 320 /* Line */
321 case 1: 321 case 1:
322 Vector3 ab = _simplex[1].Vertice - _simplex[0].Vertice; 322 Vector3 ab = _simplex[1].Vertice - _simplex[0].Vertice;
323 Vector3[] b ={ Vector3.Cross(ab, new Vector3(1, 0, 0)), 323 Vector3[] b ={ Vector3.Cross(ab, new Vector3(1, 0, 0)),
324 Vector3.Cross(ab, new Vector3(0, 1, 0)), 324 Vector3.Cross(ab, new Vector3(0, 1, 0)),
325 Vector3.Cross(ab, new Vector3(0, 0, 1)) }; 325 Vector3.Cross(ab, new Vector3(0, 0, 1)) };
326 float[] m ={ b[0].LengthSquared(), b[1].LengthSquared(), b[2].LengthSquared() }; 326 float[] m ={ b[0].LengthSquared(), b[1].LengthSquared(), b[2].LengthSquared() };
327 Matrix r = Matrix.CreateFromQuaternion(new Quaternion(Vector3.Normalize(ab), _twoPi / 3)); 327 Matrix r = Matrix.CreateFromQuaternion(new Quaternion(Vector3.Normalize(ab), _twoPi / 3));
328 Vector3 w = b[m[0] > m[1] ? m[0] > m[2] ? 0 : 2 : m[1] > m[2] ? 1 : 2]; 328 Vector3 w = b[m[0] > m[1] ? m[0] > m[2] ? 0 : 2 : m[1] > m[2] ? 1 : 2];
329 Support(Vector3.Normalize(w), ref _simplex[4]); w = Vector3.TransformNormal(w, r); 329 Support(Vector3.Normalize(w), ref _simplex[4]); w = Vector3.TransformNormal(w, r);
330 Support(Vector3.Normalize(w), ref _simplex[2]); w = Vector3.TransformNormal(w, r); 330 Support(Vector3.Normalize(w), ref _simplex[2]); w = Vector3.TransformNormal(w, r);
331 Support(Vector3.Normalize(w), ref _simplex[3]); w = Vector3.TransformNormal(w, r); 331 Support(Vector3.Normalize(w), ref _simplex[3]); w = Vector3.TransformNormal(w, r);
332 _order = 4; 332 _order = 4;
333 return true; 333 return true;
334 /* Triangle */ 334 /* Triangle */
335 case 2: 335 case 2:
336 Vector3 n = Vector3.Normalize(Vector3.Cross(_simplex[1].Vertice - _simplex[0].Vertice, _simplex[2].Vertice - _simplex[0].Vertice)); 336 Vector3 n = Vector3.Normalize(Vector3.Cross(_simplex[1].Vertice - _simplex[0].Vertice, _simplex[2].Vertice - _simplex[0].Vertice));
337 Support(n, ref _simplex[3]); 337 Support(n, ref _simplex[3]);
338 Support(-n, ref _simplex[4]); 338 Support(-n, ref _simplex[4]);
339 _order = 4; 339 _order = 4;
340 return true; 340 return true;
341 /* Tetrahedron */ 341 /* Tetrahedron */
342 case 3: return (true); 342 case 3: return (true);
343 /* Hexahedron */ 343 /* Hexahedron */
344 case 4: return (true); 344 case 4: return (true);
345 } 345 }
346 return (false); 346 return (false);
347 } 347 }
348 } 348 }
349 349
350 public class Epa 350 public class Epa
351 { 351 {
352 public class Face 352 public class Face
353 { 353 {
354 public Gjk.MinkowskiVertice[] _vertices = new Gjk.MinkowskiVertice[3]; 354 public Gjk.MinkowskiVertice[] _vertices = new Gjk.MinkowskiVertice[3];
355 public Face[] _faces = new Face[3]; 355 public Face[] _faces = new Face[3];
356 public int[] _e = new int[3]; 356 public int[] _e = new int[3];
357 public Vector3 _n; 357 public Vector3 _n;
358 public float _d; 358 public float _d;
359 public int _mark; 359 public int _mark;
360 public Face _prev; 360 public Face _prev;
361 public Face _next; 361 public Face _next;
362 } 362 }
363 363
364 private Gjk _gjk; 364 private Gjk _gjk;
365 private Face _root; 365 private Face _root;
366 private int _nfaces; 366 private int _nfaces;
367 private int _iterations; 367 private int _iterations;
368 private Vector3[,] _features = new Vector3[2, 3]; 368 private Vector3[,] _features = new Vector3[2, 3];
369 private Vector3[] _nearest = new Vector3[2]; 369 private Vector3[] _nearest = new Vector3[2];
370 private Vector3 _normal; 370 private Vector3 _normal;
371 private float _depth; 371 private float _depth;
372 private bool _failed; 372 private bool _failed;
373 373
374 public Epa(Gjk gjk) 374 public Epa(Gjk gjk)
375 { 375 {
376 this._gjk = gjk; 376 this._gjk = gjk;
377 } 377 }
378 378
379 public bool Failed { get { return _failed; } } 379 public bool Failed { get { return _failed; } }
380 public int Iterations { get { return _iterations; } } 380 public int Iterations { get { return _iterations; } }
381 public Vector3 Normal { get { return _normal; } } 381 public Vector3 Normal { get { return _normal; } }
382 public Vector3[] Nearest { get { return _nearest; } } 382 public Vector3[] Nearest { get { return _nearest; } }
383 383
384 public Vector3 GetCoordinates(Face face) 384 public Vector3 GetCoordinates(Face face)
385 { 385 {
386 Vector3 o = face._n * -face._d; 386 Vector3 o = face._n * -face._d;
387 float[] a ={ Vector3.Cross(face._vertices[0].Vertice - o, face._vertices[1].Vertice - o).Length(), 387 float[] a ={ Vector3.Cross(face._vertices[0].Vertice - o, face._vertices[1].Vertice - o).Length(),
388 Vector3.Cross(face._vertices[1].Vertice - o, face._vertices[2].Vertice - o).Length(), 388 Vector3.Cross(face._vertices[1].Vertice - o, face._vertices[2].Vertice - o).Length(),
389 Vector3.Cross(face._vertices[2].Vertice - o, face._vertices[0].Vertice - o).Length()}; 389 Vector3.Cross(face._vertices[2].Vertice - o, face._vertices[0].Vertice - o).Length()};
390 float sm = a[0] + a[1] + a[2]; 390 float sm = a[0] + a[1] + a[2];
391 return (new Vector3(a[1], a[2], a[0]) / (sm > 0 ? sm : 1)); 391 return (new Vector3(a[1], a[2], a[0]) / (sm > 0 ? sm : 1));
392 } 392 }
393 393
394 public Face FindBest() 394 public Face FindBest()
395 { 395 {
396 Face bf = null; 396 Face bf = null;
397 if (_root != null) 397 if (_root != null)
398 { 398 {
399 Face cf = _root; 399 Face cf = _root;
400 float bd = _infinity; 400 float bd = _infinity;
401 do 401 do
402 { 402 {
403 if (cf._d < bd) { bd = cf._d; bf = cf; } 403 if (cf._d < bd) { bd = cf._d; bf = cf; }
404 } while (null != (cf = cf._next)); 404 } while (null != (cf = cf._next));
405 } 405 }
406 return bf; 406 return bf;
407 } 407 }
408 408
409 public bool Set(ref Face f, Gjk.MinkowskiVertice a, Gjk.MinkowskiVertice b, Gjk.MinkowskiVertice c) 409 public bool Set(ref Face f, Gjk.MinkowskiVertice a, Gjk.MinkowskiVertice b, Gjk.MinkowskiVertice c)
410 { 410 {
411 Vector3 nrm = Vector3.Cross(b.Vertice - a.Vertice, c.Vertice - a.Vertice); 411 Vector3 nrm = Vector3.Cross(b.Vertice - a.Vertice, c.Vertice - a.Vertice);
412 float len = nrm.Length(); 412 float len = nrm.Length();
413 bool valid = (Vector3.Dot(Vector3.Cross(a.Vertice, b.Vertice), nrm) >= -_epaInFaceEpsilon && 413 bool valid = (Vector3.Dot(Vector3.Cross(a.Vertice, b.Vertice), nrm) >= -_epaInFaceEpsilon &&
414 Vector3.Dot(Vector3.Cross(b.Vertice, c.Vertice), nrm) >= -_epaInFaceEpsilon && 414 Vector3.Dot(Vector3.Cross(b.Vertice, c.Vertice), nrm) >= -_epaInFaceEpsilon &&
415 Vector3.Dot(Vector3.Cross(c.Vertice, a.Vertice), nrm) >= -_epaInFaceEpsilon); 415 Vector3.Dot(Vector3.Cross(c.Vertice, a.Vertice), nrm) >= -_epaInFaceEpsilon);
416 f._vertices[0] = a; 416 f._vertices[0] = a;
417 f._vertices[1] = b; 417 f._vertices[1] = b;
418 f._vertices[2] = c; 418 f._vertices[2] = c;
419 f._mark = 0; 419 f._mark = 0;
420 f._n = nrm / (len > 0 ? len : _infinity); 420 f._n = nrm / (len > 0 ? len : _infinity);
421 f._d = Max(0, -Vector3.Dot(f._n, a.Vertice)); 421 f._d = Max(0, -Vector3.Dot(f._n, a.Vertice));
422 return valid; 422 return valid;
423 } 423 }
424 424
425 public Face NewFace(Gjk.MinkowskiVertice a, Gjk.MinkowskiVertice b, Gjk.MinkowskiVertice c) 425 public Face NewFace(Gjk.MinkowskiVertice a, Gjk.MinkowskiVertice b, Gjk.MinkowskiVertice c)
426 { 426 {
427 Face pf = new Face(); 427 Face pf = new Face();
428 if (Set(ref pf, a, b, c)) 428 if (Set(ref pf, a, b, c))
429 { 429 {
430 if (_root != null) _root._prev = pf; 430 if (_root != null) _root._prev = pf;
431 pf._prev = null; 431 pf._prev = null;
432 pf._next = _root; 432 pf._next = _root;
433 _root = pf; 433 _root = pf;
434 ++_nfaces; 434 ++_nfaces;
435 } 435 }
436 else 436 else
437 { 437 {
438 pf._prev = pf._next = null; 438 pf._prev = pf._next = null;
439 } 439 }
440 return (pf); 440 return (pf);
441 } 441 }
442 442
443 public void Detach(ref Face face) 443 public void Detach(ref Face face)
444 { 444 {
445 if (face._prev != null || face._next != null) 445 if (face._prev != null || face._next != null)
446 { 446 {
447 --_nfaces; 447 --_nfaces;
448 if (face == _root) 448 if (face == _root)
449 { 449 {
450 _root = face._next; 450 _root = face._next;
451 _root._prev = null; 451 _root._prev = null;
452 } 452 }
453 else 453 else
454 { 454 {
455 if (face._next == null) 455 if (face._next == null)
456 { 456 {
457 face._prev._next = null; 457 face._prev._next = null;
458 } 458 }
459 else 459 else
460 { 460 {
461 face._prev._next = face._next; 461 face._prev._next = face._next;
462 face._next._prev = face._prev; 462 face._next._prev = face._prev;
463 } 463 }
464 } 464 }
465 face._prev = face._next = null; 465 face._prev = face._next = null;
466 } 466 }
467 } 467 }
468 468
469 public void Link(ref Face f0, int e0, ref Face f1, int e1) 469 public void Link(ref Face f0, int e0, ref Face f1, int e1)
470 { 470 {
471 f0._faces[e0] = f1; f1._e[e1] = e0; 471 f0._faces[e0] = f1; f1._e[e1] = e0;
472 f1._faces[e1] = f0; f0._e[e0] = e1; 472 f1._faces[e1] = f0; f0._e[e0] = e1;
473 } 473 }
474 474
475 public Gjk.MinkowskiVertice Support(Vector3 w) 475 public Gjk.MinkowskiVertice Support(Vector3 w)
476 { 476 {
477 Gjk.MinkowskiVertice v = new Gjk.MinkowskiVertice(); 477 Gjk.MinkowskiVertice v = new Gjk.MinkowskiVertice();
478 _gjk.Support(w, ref v); 478 _gjk.Support(w, ref v);
479 return v; 479 return v;
480 } 480 }
481 481
482 private static int[] mod3 ={ 0, 1, 2, 0, 1 }; 482 private static int[] mod3 ={ 0, 1, 2, 0, 1 };
483 483
484 public int BuildHorizon(int markid, Gjk.MinkowskiVertice w, ref Face f, int e, ref Face cf, ref Face ff) 484 public int BuildHorizon(int markid, Gjk.MinkowskiVertice w, ref Face f, int e, ref Face cf, ref Face ff)
485 { 485 {
486 int ne = (0); 486 int ne = (0);
487 if (f._mark != markid) 487 if (f._mark != markid)
488 { 488 {
489 int e1 = (mod3[e + 1]); 489 int e1 = (mod3[e + 1]);
490 if ((Vector3.Dot(f._n, w.Vertice) + f._d) > 0) 490 if ((Vector3.Dot(f._n, w.Vertice) + f._d) > 0)
491 { 491 {
492 Face nf = NewFace(f._vertices[e1], f._vertices[e], w); 492 Face nf = NewFace(f._vertices[e1], f._vertices[e], w);
493 Link(ref nf, 0, ref f, e); 493 Link(ref nf, 0, ref f, e);
494 if (cf != null) Link(ref cf, 1, ref nf, 2); else ff = nf; 494 if (cf != null) Link(ref cf, 1, ref nf, 2); else ff = nf;
495 cf = nf; ne = 1; 495 cf = nf; ne = 1;
496 } 496 }
497 else 497 else
498 { 498 {
499 int e2 = (mod3[e + 2]); 499 int e2 = (mod3[e + 2]);
500 Detach(ref f); 500 Detach(ref f);
501 f._mark = markid; 501 f._mark = markid;
502 ne += BuildHorizon(markid, w, ref f._faces[e1], f._e[e1], ref cf, ref ff); 502 ne += BuildHorizon(markid, w, ref f._faces[e1], f._e[e1], ref cf, ref ff);
503 ne += BuildHorizon(markid, w, ref f._faces[e2], f._e[e2], ref cf, ref ff); 503 ne += BuildHorizon(markid, w, ref f._faces[e2], f._e[e2], ref cf, ref ff);
504 } 504 }
505 } 505 }
506 return (ne); 506 return (ne);
507 } 507 }
508 508
509 public float EvaluatePD() 509 public float EvaluatePD()
510 { 510 {
511 return EvaluatePD(_epaAccuracy); 511 return EvaluatePD(_epaAccuracy);
512 } 512 }
513 513
514 private int[,] fidx; 514 private int[,] fidx;
515 private int[,] eidx; 515 private int[,] eidx;
516 516
517 public float EvaluatePD(float accuracy) 517 public float EvaluatePD(float accuracy)
518 { 518 {
519 //Block* sablock = sa->BeginBlock(); 519 //Block* sablock = sa->BeginBlock();
520 Face bestface = null; 520 Face bestface = null;
521 int markid = 1; 521 int markid = 1;
522 _depth = -_infinity; 522 _depth = -_infinity;
523 _normal = new Vector3(); 523 _normal = new Vector3();
524 _root = null; 524 _root = null;
525 _nfaces = 0; 525 _nfaces = 0;
526 _iterations = 0; 526 _iterations = 0;
527 _failed = false; 527 _failed = false;
528 /* Prepare hull */ 528 /* Prepare hull */
529 if (_gjk.EncloseOrigin()) 529 if (_gjk.EncloseOrigin())
530 { 530 {
531 int nfidx = 0; 531 int nfidx = 0;
532 int neidx = 0; 532 int neidx = 0;
533 Gjk.MinkowskiVertice[] basemkv = new Gjk.MinkowskiVertice[5]; 533 Gjk.MinkowskiVertice[] basemkv = new Gjk.MinkowskiVertice[5];
534 Face[] basefaces = new Face[6]; 534 Face[] basefaces = new Face[6];
535 switch (_gjk.Order) 535 switch (_gjk.Order)
536 { 536 {
537 /* Tetrahedron */ 537 /* Tetrahedron */
538 case 3: 538 case 3:
539 { 539 {
540 fidx = new int[,] { { 2, 1, 0 }, { 3, 0, 1 }, { 3, 1, 2 }, { 3, 2, 0 } }; 540 fidx = new int[,] { { 2, 1, 0 }, { 3, 0, 1 }, { 3, 1, 2 }, { 3, 2, 0 } };
541 eidx = new int[,] { { 0, 0, 2, 1 }, { 0, 1, 1, 1 }, { 0, 2, 3, 1 }, { 1, 0, 3, 2 }, { 2, 0, 1, 2 }, { 3, 0, 2, 2 } }; 541 eidx = new int[,] { { 0, 0, 2, 1 }, { 0, 1, 1, 1 }, { 0, 2, 3, 1 }, { 1, 0, 3, 2 }, { 2, 0, 1, 2 }, { 3, 0, 2, 2 } };
542 nfidx = 4; neidx = 6; 542 nfidx = 4; neidx = 6;
543 } break; 543 } break;
544 /* Hexahedron */ 544 /* Hexahedron */
545 case 4: 545 case 4:
546 { 546 {
547 fidx = new int[,] { { 2, 0, 4 }, { 4, 1, 2 }, { 1, 4, 0 }, { 0, 3, 1 }, { 0, 2, 3 }, { 1, 3, 2 } }; 547 fidx = new int[,] { { 2, 0, 4 }, { 4, 1, 2 }, { 1, 4, 0 }, { 0, 3, 1 }, { 0, 2, 3 }, { 1, 3, 2 } };
548 eidx = new int[,] { { 0, 0, 4, 0 }, { 0, 1, 2, 1 }, { 0, 2, 1, 2 }, { 1, 1, 5, 2 }, { 1, 0, 2, 0 }, { 2, 2, 3, 2 }, { 3, 1, 5, 0 }, { 3, 0, 4, 2 }, { 5, 1, 4, 1 } }; 548 eidx = new int[,] { { 0, 0, 4, 0 }, { 0, 1, 2, 1 }, { 0, 2, 1, 2 }, { 1, 1, 5, 2 }, { 1, 0, 2, 0 }, { 2, 2, 3, 2 }, { 3, 1, 5, 0 }, { 3, 0, 4, 2 }, { 5, 1, 4, 1 } };
549 nfidx = 6; neidx = 9; 549 nfidx = 6; neidx = 9;
550 } break; 550 } break;
551 } 551 }
552 int i; 552 int i;
553 553
554 for (i = 0; i <= _gjk.Order; ++i) 554 for (i = 0; i <= _gjk.Order; ++i)
555 { 555 {
556 //basemkv[i] = (GJK::Mkv*)sa->Allocate(sizeof(GJK::Mkv)); 556 //basemkv[i] = (GJK::Mkv*)sa->Allocate(sizeof(GJK::Mkv));
557 basemkv[i] = new Gjk.MinkowskiVertice(); 557 basemkv[i] = new Gjk.MinkowskiVertice();
558 basemkv[i].Vertice = _gjk.Simplex[i].Vertice; 558 basemkv[i].Vertice = _gjk.Simplex[i].Vertice;
559 basemkv[i].Ray = _gjk.Simplex[i].Ray; 559 basemkv[i].Ray = _gjk.Simplex[i].Ray;
560 } 560 }
561 for (i = 0; i < nfidx; ++i) 561 for (i = 0; i < nfidx; ++i)
562 { 562 {
563 basefaces[i] = NewFace(basemkv[fidx[i, 0]], basemkv[fidx[i, 1]], basemkv[fidx[i, 2]]); 563 basefaces[i] = NewFace(basemkv[fidx[i, 0]], basemkv[fidx[i, 1]], basemkv[fidx[i, 2]]);
564 } 564 }
565 for (i = 0; i < neidx; ++i) 565 for (i = 0; i < neidx; ++i)
566 { 566 {
567 Link(ref basefaces[eidx[i, 0]], eidx[i, 1], ref basefaces[eidx[i, 2]], eidx[i, 3]); 567 Link(ref basefaces[eidx[i, 0]], eidx[i, 1], ref basefaces[eidx[i, 2]], eidx[i, 3]);
568 } 568 }
569 } 569 }
570 if (0 == _nfaces) 570 if (0 == _nfaces)
571 { 571 {
572 return _depth; 572 return _depth;
573 } 573 }
574 /* Expand hull */ 574 /* Expand hull */
575 for (; _iterations < _epaMaxIterations; ++_iterations) 575 for (; _iterations < _epaMaxIterations; ++_iterations)
576 { 576 {
577 Face bf = FindBest(); 577 Face bf = FindBest();
578 if (bf != null) 578 if (bf != null)
579 { 579 {
580 Gjk.MinkowskiVertice w = Support(-bf._n); 580 Gjk.MinkowskiVertice w = Support(-bf._n);
581 float d = Vector3.Dot(bf._n, w.Vertice) + bf._d; 581 float d = Vector3.Dot(bf._n, w.Vertice) + bf._d;
582 bestface = bf; 582 bestface = bf;
583 if (d < -accuracy) 583 if (d < -accuracy)
584 { 584 {
585 Face cf = null; 585 Face cf = null;
586 Face ff = null; 586 Face ff = null;
587 int nf = 0; 587 int nf = 0;
588 Detach(ref bf); 588 Detach(ref bf);
589 bf._mark = ++markid; 589 bf._mark = ++markid;
590 for (int i = 0; i < 3; ++i) 590 for (int i = 0; i < 3; ++i)
591 { 591 {
592 nf += BuildHorizon(markid, w, ref bf._faces[i], bf._e[i], ref cf, ref ff); 592 nf += BuildHorizon(markid, w, ref bf._faces[i], bf._e[i], ref cf, ref ff);
593 } 593 }
594 if (nf <= 2) { break; } 594 if (nf <= 2) { break; }
595 Link(ref cf, 1, ref ff, 2); 595 Link(ref cf, 1, ref ff, 2);
596 } 596 }
597 else break; 597 else break;
598 } 598 }
599 else break; 599 else break;
600 } 600 }
601 /* Extract contact */ 601 /* Extract contact */
602 if (bestface != null) 602 if (bestface != null)
603 { 603 {
604 Vector3 b = GetCoordinates(bestface); 604 Vector3 b = GetCoordinates(bestface);
605 _normal = bestface._n; 605 _normal = bestface._n;
606 _depth = Max(0, bestface._d); 606 _depth = Max(0, bestface._d);
607 for (int i = 0; i < 2; ++i) 607 for (int i = 0; i < 2; ++i)
608 { 608 {
609 float s = i != 0 ? -1 : 1; 609 float s = i != 0 ? -1 : 1;
610 for (int j = 0; j < 3; ++j) 610 for (int j = 0; j < 3; ++j)
611 { 611 {
612 _features[i, j] = _gjk.LocalSupport(s * bestface._vertices[j].Ray, i); 612 _features[i, j] = _gjk.LocalSupport(s * bestface._vertices[j].Ray, i);
613 } 613 }
614 } 614 }
615 _nearest[0] = _features[0, 0] * b.X + _features[0, 1] * b.Y + _features[0, 2] * b.Z; 615 _nearest[0] = _features[0, 0] * b.X + _features[0, 1] * b.Y + _features[0, 2] * b.Z;
616 _nearest[1] = _features[1, 0] * b.X + _features[1, 1] * b.Y + _features[1, 2] * b.Z; 616 _nearest[1] = _features[1, 0] * b.X + _features[1, 1] * b.Y + _features[1, 2] * b.Z;
617 } 617 }
618 else _failed = true; 618 else _failed = true;
619 return _depth; 619 return _depth;
620 } 620 }
621 621
622 private float Max(float a, float b) 622 private float Max(float a, float b)
623 { 623 {
624 return (a > b ? a : b); 624 return (a > b ? a : b);
625 } 625 }
626 626
627 private float Min(float a, float b) 627 private float Min(float a, float b)
628 { 628 {
629 return (a < b ? a : b); 629 return (a < b ? a : b);
630 } 630 }
631 } 631 }
632 } 632 }
633} 633}
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkEpaPenetrationDepthSolver.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkEpaPenetrationDepthSolver.cs
index 739b4fc..551449f 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkEpaPenetrationDepthSolver.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkEpaPenetrationDepthSolver.cs
@@ -1,56 +1,56 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 /// <summary> 29 /// <summary>
30 /// EpaPenetrationDepthSolver uses the Expanding Polytope Algorithm to 30 /// EpaPenetrationDepthSolver uses the Expanding Polytope Algorithm to
31 /// calculate the penetration depth between two convex shapes. 31 /// calculate the penetration depth between two convex shapes.
32 /// </summary> 32 /// </summary>
33 public class GjkEpaPenetrationDepthSolver : IConvexPenetrationDepthSolver 33 public class GjkEpaPenetrationDepthSolver : IConvexPenetrationDepthSolver
34 { 34 {
35 public bool CalculatePenetrationDepth(ISimplexSolver simplexSolver, ConvexShape convexA, ConvexShape convexB, Matrix transformA, Matrix transformB, Vector3 vector, out Vector3 ptrA, out Vector3 ptrB, IDebugDraw debugDraw) 35 public bool CalculatePenetrationDepth(ISimplexSolver simplexSolver, ConvexShape convexA, ConvexShape convexB, Matrix transformA, Matrix transformB, Vector3 vector, out Vector3 ptrA, out Vector3 ptrB, IDebugDraw debugDraw)
36 { 36 {
37 float radialmargin = 0; 37 float radialmargin = 0;
38 38
39 GjkEpaSolver.Results results; 39 GjkEpaSolver.Results results;
40 if (GjkEpaSolver.Collide(convexA, transformA, 40 if (GjkEpaSolver.Collide(convexA, transformA,
41 convexB, transformB, 41 convexB, transformB,
42 radialmargin, out results)) 42 radialmargin, out results))
43 { 43 {
44 // debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0)); 44 // debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0));
45 //resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth); 45 //resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth);
46 ptrA = results.Witnesses[0]; 46 ptrA = results.Witnesses[0];
47 ptrB = results.Witnesses[1]; 47 ptrB = results.Witnesses[1];
48 return true; 48 return true;
49 } 49 }
50 ptrA = new Vector3(); 50 ptrA = new Vector3();
51 ptrB = new Vector3(); 51 ptrB = new Vector3();
52 52
53 return false; 53 return false;
54 } 54 }
55 } 55 }
56} 56}
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkEpaSolver.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkEpaSolver.cs
index aa9d61e..20af192 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkEpaSolver.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkEpaSolver.cs
@@ -1,101 +1,101 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 /// <summary> 29 /// <summary>
30 /// GjkEpaSolver contributed under zlib by Nathanael Presson 30 /// GjkEpaSolver contributed under zlib by Nathanael Presson
31 /// </summary> 31 /// </summary>
32 public class GjkEpaSolver 32 public class GjkEpaSolver
33 { 33 {
34 public struct Results 34 public struct Results
35 { 35 {
36 public enum Status 36 public enum Status
37 { 37 {
38 Separated, /* Shapes doesnt penetrate */ 38 Separated, /* Shapes doesnt penetrate */
39 Penetrating, /* Shapes are penetrating */ 39 Penetrating, /* Shapes are penetrating */
40 GjkFailed, /* GJK phase fail, no big issue, shapes are probably just 'touching' */ 40 GjkFailed, /* GJK phase fail, no big issue, shapes are probably just 'touching' */
41 EpaFailed, /* EPA phase fail, bigger problem, need to save parameters, and debug */ 41 EpaFailed, /* EPA phase fail, bigger problem, need to save parameters, and debug */
42 } 42 }
43 43
44 private Vector3[] _witnesses; 44 private Vector3[] _witnesses;
45 private Vector3 _normal; 45 private Vector3 _normal;
46 private float _depth; 46 private float _depth;
47 private int _epaIterations; 47 private int _epaIterations;
48 private int _gjkIterations; 48 private int _gjkIterations;
49 private Status _status; 49 private Status _status;
50 50
51 public Vector3[] Witnesses { get { return _witnesses; } set { _witnesses = value; } } 51 public Vector3[] Witnesses { get { return _witnesses; } set { _witnesses = value; } }
52 public Vector3 Normal { get { return _normal; } set { _normal = value; } } 52 public Vector3 Normal { get { return _normal; } set { _normal = value; } }
53 public float Depth { get { return _depth; } set { _depth = value; } } 53 public float Depth { get { return _depth; } set { _depth = value; } }
54 public int EpaIterations { get { return _epaIterations; } set { _epaIterations = value; } } 54 public int EpaIterations { get { return _epaIterations; } set { _epaIterations = value; } }
55 public int GjkIterations { get { return _gjkIterations; } set { _gjkIterations = value; } } 55 public int GjkIterations { get { return _gjkIterations; } set { _gjkIterations = value; } }
56 public Status ResultStatus { get { return _status; } set { _status = value; } } 56 public Status ResultStatus { get { return _status; } set { _status = value; } }
57 } 57 }
58 58
59 public static bool Collide(ConvexShape shapeA, Matrix wtrsA, 59 public static bool Collide(ConvexShape shapeA, Matrix wtrsA,
60 ConvexShape shapeB, Matrix wtrsB, 60 ConvexShape shapeB, Matrix wtrsB,
61 float radialmargin, 61 float radialmargin,
62 out Results results) 62 out Results results)
63 { 63 {
64 /* Initialize */ 64 /* Initialize */
65 results = new Results(); 65 results = new Results();
66 results.Witnesses = new Vector3[2]; 66 results.Witnesses = new Vector3[2];
67 results.Witnesses[0] = 67 results.Witnesses[0] =
68 results.Witnesses[1] = 68 results.Witnesses[1] =
69 results.Normal = new Vector3(); 69 results.Normal = new Vector3();
70 results.Depth = 0; 70 results.Depth = 0;
71 results.ResultStatus = Results.Status.Separated; 71 results.ResultStatus = Results.Status.Separated;
72 results.EpaIterations = 0; 72 results.EpaIterations = 0;
73 results.GjkIterations = 0; 73 results.GjkIterations = 0;
74 /* Use GJK to locate origin */ 74 /* Use GJK to locate origin */
75 GjkEpa.Gjk gjk = new GjkEpa.Gjk(wtrsA, wtrsA.Translation, shapeA, 75 GjkEpa.Gjk gjk = new GjkEpa.Gjk(wtrsA, wtrsA.Translation, shapeA,
76 wtrsB, wtrsB.Translation, shapeB, 76 wtrsB, wtrsB.Translation, shapeB,
77 radialmargin + GjkEpa.EpaAccuracy); 77 radialmargin + GjkEpa.EpaAccuracy);
78 bool collide = gjk.SearchOrigin(); 78 bool collide = gjk.SearchOrigin();
79 results.GjkIterations = gjk.Iterations + 1; 79 results.GjkIterations = gjk.Iterations + 1;
80 if (collide) 80 if (collide)
81 { 81 {
82 /* Then EPA for penetration depth */ 82 /* Then EPA for penetration depth */
83 GjkEpa.Epa epa = new GjkEpa.Epa(gjk); 83 GjkEpa.Epa epa = new GjkEpa.Epa(gjk);
84 float pd = epa.EvaluatePD(); 84 float pd = epa.EvaluatePD();
85 results.EpaIterations = epa.Iterations + 1; 85 results.EpaIterations = epa.Iterations + 1;
86 if (pd > 0) 86 if (pd > 0)
87 { 87 {
88 results.ResultStatus = Results.Status.Penetrating; 88 results.ResultStatus = Results.Status.Penetrating;
89 results.Normal = epa.Normal; 89 results.Normal = epa.Normal;
90 results.Depth = pd; 90 results.Depth = pd;
91 results.Witnesses[0] = epa.Nearest[0]; 91 results.Witnesses[0] = epa.Nearest[0];
92 results.Witnesses[1] = epa.Nearest[1]; 92 results.Witnesses[1] = epa.Nearest[1];
93 return true; 93 return true;
94 } 94 }
95 else { if (epa.Failed) results.ResultStatus = Results.Status.EpaFailed; } 95 else { if (epa.Failed) results.ResultStatus = Results.Status.EpaFailed; }
96 } 96 }
97 else { if (gjk.Failed) results.ResultStatus = Results.Status.GjkFailed; } 97 else { if (gjk.Failed) results.ResultStatus = Results.Status.GjkFailed; }
98 return false; 98 return false;
99 } 99 }
100 } 100 }
101} 101}
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkPairDetector.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkPairDetector.cs
index 0831ff5..7557ed9 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkPairDetector.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/GjkPairDetector.cs
@@ -1,343 +1,343 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 public class GjkPairDetector : DiscreteCollisionDetectorInterface 29 public class GjkPairDetector : DiscreteCollisionDetectorInterface
30 { 30 {
31 private Vector3 _cachedSeparatingAxis; 31 private Vector3 _cachedSeparatingAxis;
32 private IConvexPenetrationDepthSolver _penetrationDepthSolver; 32 private IConvexPenetrationDepthSolver _penetrationDepthSolver;
33 private ISimplexSolver _simplexSolver; 33 private ISimplexSolver _simplexSolver;
34 private ConvexShape _minkowskiA, _minkowskiB; 34 private ConvexShape _minkowskiA, _minkowskiB;
35 private bool _ignoreMargin; 35 private bool _ignoreMargin;
36 36
37 private int _lastUsedMethod; 37 private int _lastUsedMethod;
38 private int _currentIteration; 38 private int _currentIteration;
39 private int _degenerateSimplex; 39 private int _degenerateSimplex;
40 private int _catchDegeneracies; 40 private int _catchDegeneracies;
41 41
42 private static int _numDeepPenetrationChecks = 0; 42 private static int _numDeepPenetrationChecks = 0;
43 private static int _numGjkChecks = 0; 43 private static int _numGjkChecks = 0;
44 44
45 private const float RelativeError2 = 1.0e-6f; 45 private const float RelativeError2 = 1.0e-6f;
46 46
47 #region Properties 47 #region Properties
48 public int LastUsedMethod 48 public int LastUsedMethod
49 { 49 {
50 get { return _lastUsedMethod; } 50 get { return _lastUsedMethod; }
51 set { _lastUsedMethod = value; } 51 set { _lastUsedMethod = value; }
52 } 52 }
53 53
54 public int CurrentIteration 54 public int CurrentIteration
55 { 55 {
56 get { return _currentIteration; } 56 get { return _currentIteration; }
57 set { _currentIteration = value; } 57 set { _currentIteration = value; }
58 } 58 }
59 59
60 public int DegenerateSimplex 60 public int DegenerateSimplex
61 { 61 {
62 get { return _degenerateSimplex; } 62 get { return _degenerateSimplex; }
63 set { _degenerateSimplex = value; } 63 set { _degenerateSimplex = value; }
64 } 64 }
65 65
66 public int CatchDegeneracies 66 public int CatchDegeneracies
67 { 67 {
68 get { return _catchDegeneracies; } 68 get { return _catchDegeneracies; }
69 set { _catchDegeneracies = value; } 69 set { _catchDegeneracies = value; }
70 } 70 }
71 71
72 public static int DeepPenetrationChecksCount { get { return _numDeepPenetrationChecks; } } 72 public static int DeepPenetrationChecksCount { get { return _numDeepPenetrationChecks; } }
73 public static int GjkChecksCount { get { return _numGjkChecks; } } 73 public static int GjkChecksCount { get { return _numGjkChecks; } }
74 #endregion 74 #endregion
75 75
76 public GjkPairDetector(ConvexShape objectA, ConvexShape objectB, 76 public GjkPairDetector(ConvexShape objectA, ConvexShape objectB,
77 ISimplexSolver simplexSolver, 77 ISimplexSolver simplexSolver,
78 IConvexPenetrationDepthSolver penetrationDepthSolver) 78 IConvexPenetrationDepthSolver penetrationDepthSolver)
79 { 79 {
80 _cachedSeparatingAxis = new Vector3(0, 0, 1); 80 _cachedSeparatingAxis = new Vector3(0, 0, 1);
81 81
82 _penetrationDepthSolver = penetrationDepthSolver; 82 _penetrationDepthSolver = penetrationDepthSolver;
83 _simplexSolver = simplexSolver; 83 _simplexSolver = simplexSolver;
84 _minkowskiA = objectA; 84 _minkowskiA = objectA;
85 _minkowskiB = objectB; 85 _minkowskiB = objectB;
86 _ignoreMargin = false; 86 _ignoreMargin = false;
87 _lastUsedMethod = -1; 87 _lastUsedMethod = -1;
88 _catchDegeneracies = 1; 88 _catchDegeneracies = 1;
89 } 89 }
90 90
91 public void setMinkowskiA(ConvexShape minkA) 91 public void setMinkowskiA(ConvexShape minkA)
92 { 92 {
93 _minkowskiA = minkA; 93 _minkowskiA = minkA;
94 } 94 }
95 95
96 public void setMinkowskiB(ConvexShape minkB) 96 public void setMinkowskiB(ConvexShape minkB)
97 { 97 {
98 _minkowskiB = minkB; 98 _minkowskiB = minkB;
99 } 99 }
100 public void setCachedSeperatingAxis(Vector3 seperatingAxis) 100 public void setCachedSeperatingAxis(Vector3 seperatingAxis)
101 { 101 {
102 _cachedSeparatingAxis = seperatingAxis; 102 _cachedSeparatingAxis = seperatingAxis;
103 } 103 }
104 104
105 public void setPenetrationDepthSolver(IConvexPenetrationDepthSolver penetrationDepthSolver) 105 public void setPenetrationDepthSolver(IConvexPenetrationDepthSolver penetrationDepthSolver)
106 { 106 {
107 this._penetrationDepthSolver = penetrationDepthSolver; 107 this._penetrationDepthSolver = penetrationDepthSolver;
108 } 108 }
109 109
110 public void setIgnoreMargin(bool ignoreMargin) 110 public void setIgnoreMargin(bool ignoreMargin)
111 { 111 {
112 this._ignoreMargin = ignoreMargin; 112 this._ignoreMargin = ignoreMargin;
113 } 113 }
114 114
115 public override void GetClosestPoints(DiscreteCollisionDetectorInterface.ClosestPointInput input, DiscreteCollisionDetectorInterface.Result output, IDebugDraw debugDraw) 115 public override void GetClosestPoints(DiscreteCollisionDetectorInterface.ClosestPointInput input, DiscreteCollisionDetectorInterface.Result output, IDebugDraw debugDraw)
116 { 116 {
117 float distance = 0; 117 float distance = 0;
118 118
119 Vector3 normalInB = new Vector3(); 119 Vector3 normalInB = new Vector3();
120 Vector3 pointOnA = new Vector3(), pointOnB = new Vector3(); 120 Vector3 pointOnA = new Vector3(), pointOnB = new Vector3();
121 121
122 Matrix localTransA = input.TransformA; 122 Matrix localTransA = input.TransformA;
123 Matrix localTransB = input.TransformB; 123 Matrix localTransB = input.TransformB;
124 124
125 Vector3 positionOffset = (localTransA.Translation + localTransB.Translation) * 0.5f; 125 Vector3 positionOffset = (localTransA.Translation + localTransB.Translation) * 0.5f;
126 localTransA.Translation -= positionOffset; 126 localTransA.Translation -= positionOffset;
127 localTransB.Translation -= positionOffset; 127 localTransB.Translation -= positionOffset;
128 128
129 float marginA = _minkowskiA.Margin; 129 float marginA = _minkowskiA.Margin;
130 float marginB = _minkowskiB.Margin; 130 float marginB = _minkowskiB.Margin;
131 131
132 _numGjkChecks++; 132 _numGjkChecks++;
133 133
134 if (_ignoreMargin) 134 if (_ignoreMargin)
135 { 135 {
136 marginA = 0; 136 marginA = 0;
137 marginB = 0; 137 marginB = 0;
138 } 138 }
139 139
140 _currentIteration = 0; 140 _currentIteration = 0;
141 141
142 int gjkMaxIter = 1000; 142 int gjkMaxIter = 1000;
143 _cachedSeparatingAxis = new Vector3(0, 1, 0); 143 _cachedSeparatingAxis = new Vector3(0, 1, 0);
144 144
145 bool isValid = false; 145 bool isValid = false;
146 bool checkSimplex = false; 146 bool checkSimplex = false;
147 bool checkPenetration = true; 147 bool checkPenetration = true;
148 _degenerateSimplex = 0; 148 _degenerateSimplex = 0;
149 149
150 _lastUsedMethod = -1; 150 _lastUsedMethod = -1;
151 151
152 { 152 {
153 float squaredDistance = MathHelper.Infinity; 153 float squaredDistance = MathHelper.Infinity;
154 float delta = 0; 154 float delta = 0;
155 155
156 float margin = marginA + marginB; 156 float margin = marginA + marginB;
157 157
158 _simplexSolver.Reset(); 158 _simplexSolver.Reset();
159 159
160 while (true) 160 while (true)
161 { 161 {
162 Matrix transABasis = input.TransformA; 162 Matrix transABasis = input.TransformA;
163 transABasis.Translation = Vector3.Zero; 163 transABasis.Translation = Vector3.Zero;
164 164
165 Matrix transBBasis = input.TransformB; 165 Matrix transBBasis = input.TransformB;
166 transBBasis.Translation = Vector3.Zero; 166 transBBasis.Translation = Vector3.Zero;
167 167
168 Vector3 seperatingAxisInA = Vector3.TransformNormal(-_cachedSeparatingAxis, transABasis); 168 Vector3 seperatingAxisInA = Vector3.TransformNormal(-_cachedSeparatingAxis, transABasis);
169 Vector3 seperatingAxisInB = Vector3.TransformNormal(_cachedSeparatingAxis, transBBasis); 169 Vector3 seperatingAxisInB = Vector3.TransformNormal(_cachedSeparatingAxis, transBBasis);
170 170
171 Vector3 pInA = _minkowskiA.LocalGetSupportingVertexWithoutMargin(seperatingAxisInA); 171 Vector3 pInA = _minkowskiA.LocalGetSupportingVertexWithoutMargin(seperatingAxisInA);
172 Vector3 qInB = _minkowskiB.LocalGetSupportingVertexWithoutMargin(seperatingAxisInB); 172 Vector3 qInB = _minkowskiB.LocalGetSupportingVertexWithoutMargin(seperatingAxisInB);
173 Vector3 pWorld = MathHelper.MatrixToVector(localTransA, pInA); 173 Vector3 pWorld = MathHelper.MatrixToVector(localTransA, pInA);
174 Vector3 qWorld = MathHelper.MatrixToVector(localTransB, qInB); 174 Vector3 qWorld = MathHelper.MatrixToVector(localTransB, qInB);
175 175
176 Vector3 w = pWorld - qWorld; 176 Vector3 w = pWorld - qWorld;
177 delta = Vector3.Dot(_cachedSeparatingAxis, w); 177 delta = Vector3.Dot(_cachedSeparatingAxis, w);
178 178
179 if ((delta > 0.0) && (delta * delta > squaredDistance * input.MaximumDistanceSquared)) 179 if ((delta > 0.0) && (delta * delta > squaredDistance * input.MaximumDistanceSquared))
180 { 180 {
181 checkPenetration = false; 181 checkPenetration = false;
182 break; 182 break;
183 } 183 }
184 184
185 if (_simplexSolver.InSimplex(w)) 185 if (_simplexSolver.InSimplex(w))
186 { 186 {
187 _degenerateSimplex = 1; 187 _degenerateSimplex = 1;
188 checkSimplex = true; 188 checkSimplex = true;
189 break; 189 break;
190 } 190 }
191 191
192 float f0 = squaredDistance - delta; 192 float f0 = squaredDistance - delta;
193 float f1 = squaredDistance * RelativeError2; 193 float f1 = squaredDistance * RelativeError2;
194 194
195 if (f0 <= f1) 195 if (f0 <= f1)
196 { 196 {
197 if (f0 <= 0.0f) 197 if (f0 <= 0.0f)
198 { 198 {
199 _degenerateSimplex = 2; 199 _degenerateSimplex = 2;
200 } 200 }
201 201
202 checkSimplex = true; 202 checkSimplex = true;
203 break; 203 break;
204 } 204 }
205 205
206 _simplexSolver.AddVertex(w, pWorld, qWorld); 206 _simplexSolver.AddVertex(w, pWorld, qWorld);
207 207
208 if (!_simplexSolver.Closest(out _cachedSeparatingAxis)) 208 if (!_simplexSolver.Closest(out _cachedSeparatingAxis))
209 { 209 {
210 _degenerateSimplex = 3; 210 _degenerateSimplex = 3;
211 checkSimplex = true; 211 checkSimplex = true;
212 break; 212 break;
213 } 213 }
214 214
215 float previouseSquaredDistance = squaredDistance; 215 float previouseSquaredDistance = squaredDistance;
216 squaredDistance = _cachedSeparatingAxis.LengthSquared(); 216 squaredDistance = _cachedSeparatingAxis.LengthSquared();
217 217
218 if (previouseSquaredDistance - squaredDistance <= MathHelper.Epsilon * previouseSquaredDistance) 218 if (previouseSquaredDistance - squaredDistance <= MathHelper.Epsilon * previouseSquaredDistance)
219 { 219 {
220 _simplexSolver.BackupClosest(out _cachedSeparatingAxis); 220 _simplexSolver.BackupClosest(out _cachedSeparatingAxis);
221 checkSimplex = true; 221 checkSimplex = true;
222 break; 222 break;
223 } 223 }
224 224
225 if (_currentIteration++ > gjkMaxIter) 225 if (_currentIteration++ > gjkMaxIter)
226 { 226 {
227#if DEBUG 227#if DEBUG
228 Console.WriteLine("GjkPairDetector maxIter exceeded: {0}", _currentIteration); 228 Console.WriteLine("GjkPairDetector maxIter exceeded: {0}", _currentIteration);
229 Console.WriteLine("sepAxis=({0},{1},{2}), squaredDistance = {3}, shapeTypeA={4}, shapeTypeB={5}", 229 Console.WriteLine("sepAxis=({0},{1},{2}), squaredDistance = {3}, shapeTypeA={4}, shapeTypeB={5}",
230 _cachedSeparatingAxis.X, 230 _cachedSeparatingAxis.X,
231 _cachedSeparatingAxis.Y, 231 _cachedSeparatingAxis.Y,
232 _cachedSeparatingAxis.Z, 232 _cachedSeparatingAxis.Z,
233 squaredDistance, 233 squaredDistance,
234 _minkowskiA.ShapeType, 234 _minkowskiA.ShapeType,
235 _minkowskiB.ShapeType 235 _minkowskiB.ShapeType
236 ); 236 );
237#endif 237#endif
238 break; 238 break;
239 } 239 }
240 240
241 bool check = (!_simplexSolver.FullSimplex); 241 bool check = (!_simplexSolver.FullSimplex);
242 242
243 if (!check) 243 if (!check)
244 { 244 {
245 _simplexSolver.BackupClosest(out _cachedSeparatingAxis); 245 _simplexSolver.BackupClosest(out _cachedSeparatingAxis);
246 break; 246 break;
247 } 247 }
248 } 248 }
249 249
250 if (checkSimplex) 250 if (checkSimplex)
251 { 251 {
252 _simplexSolver.ComputePoints(out pointOnA, out pointOnB); 252 _simplexSolver.ComputePoints(out pointOnA, out pointOnB);
253 normalInB = pointOnA - pointOnB; 253 normalInB = pointOnA - pointOnB;
254 float lenSqr = _cachedSeparatingAxis.LengthSquared(); 254 float lenSqr = _cachedSeparatingAxis.LengthSquared();
255 255
256 if (lenSqr < 0.0001f) 256 if (lenSqr < 0.0001f)
257 { 257 {
258 _degenerateSimplex = 5; 258 _degenerateSimplex = 5;
259 } 259 }
260 260
261 if (lenSqr > MathHelper.Epsilon * MathHelper.Epsilon) 261 if (lenSqr > MathHelper.Epsilon * MathHelper.Epsilon)
262 { 262 {
263 float rlen = 1.0f / (float)Math.Sqrt((float)lenSqr); 263 float rlen = 1.0f / (float)Math.Sqrt((float)lenSqr);
264 normalInB *= rlen; 264 normalInB *= rlen;
265 float s = (float)Math.Sqrt((float)squaredDistance); 265 float s = (float)Math.Sqrt((float)squaredDistance);
266 266
267 BulletDebug.Assert(s > 0); 267 BulletDebug.Assert(s > 0);
268 pointOnA -= _cachedSeparatingAxis * (marginA / s); 268 pointOnA -= _cachedSeparatingAxis * (marginA / s);
269 pointOnB += _cachedSeparatingAxis * (marginB / s); 269 pointOnB += _cachedSeparatingAxis * (marginB / s);
270 distance = ((1 / rlen) - margin); 270 distance = ((1 / rlen) - margin);
271 271
272 isValid = true; 272 isValid = true;
273 273
274 _lastUsedMethod = 1; 274 _lastUsedMethod = 1;
275 } 275 }
276 else 276 else
277 { 277 {
278 _lastUsedMethod = 2; 278 _lastUsedMethod = 2;
279 } 279 }
280 } 280 }
281 281
282 bool catchDegeneratePenetrationCase = 282 bool catchDegeneratePenetrationCase =
283 (_catchDegeneracies != 0 && _penetrationDepthSolver != null && _degenerateSimplex != 0 && ((distance + margin) < 0.01f)); 283 (_catchDegeneracies != 0 && _penetrationDepthSolver != null && _degenerateSimplex != 0 && ((distance + margin) < 0.01f));
284 284
285 if (checkPenetration && (!isValid || catchDegeneratePenetrationCase)) 285 if (checkPenetration && (!isValid || catchDegeneratePenetrationCase))
286 { 286 {
287#warning Check this 287#warning Check this
288 if (_penetrationDepthSolver != null) 288 if (_penetrationDepthSolver != null)
289 { 289 {
290 Vector3 tmpPointOnA, tmpPointOnB; 290 Vector3 tmpPointOnA, tmpPointOnB;
291 291
292 _numDeepPenetrationChecks++; 292 _numDeepPenetrationChecks++;
293 293
294 bool isValid2 = _penetrationDepthSolver.CalculatePenetrationDepth( 294 bool isValid2 = _penetrationDepthSolver.CalculatePenetrationDepth(
295 _simplexSolver, _minkowskiA, _minkowskiB, localTransA, localTransB, 295 _simplexSolver, _minkowskiA, _minkowskiB, localTransA, localTransB,
296 _cachedSeparatingAxis, out tmpPointOnA, out tmpPointOnB, 296 _cachedSeparatingAxis, out tmpPointOnA, out tmpPointOnB,
297 debugDraw 297 debugDraw
298 ); 298 );
299 299
300 if (isValid2) 300 if (isValid2)
301 { 301 {
302 Vector3 tmpNormalInB = tmpPointOnB - tmpPointOnA; 302 Vector3 tmpNormalInB = tmpPointOnB - tmpPointOnA;
303 float lengSqr = tmpNormalInB.LengthSquared(); 303 float lengSqr = tmpNormalInB.LengthSquared();
304 304
305 if (lengSqr > (MathHelper.Epsilon * MathHelper.Epsilon)) 305 if (lengSqr > (MathHelper.Epsilon * MathHelper.Epsilon))
306 { 306 {
307 tmpNormalInB /= (float)Math.Sqrt((float)lengSqr); 307 tmpNormalInB /= (float)Math.Sqrt((float)lengSqr);
308 float distance2 = -(tmpPointOnA - tmpPointOnB).Length(); 308 float distance2 = -(tmpPointOnA - tmpPointOnB).Length();
309 309
310 if (!isValid || (distance2 < distance)) 310 if (!isValid || (distance2 < distance))
311 { 311 {
312 distance = distance2; 312 distance = distance2;
313 pointOnA = tmpPointOnA; 313 pointOnA = tmpPointOnA;
314 pointOnB = tmpPointOnB; 314 pointOnB = tmpPointOnB;
315 normalInB = tmpNormalInB; 315 normalInB = tmpNormalInB;
316 isValid = true; 316 isValid = true;
317 _lastUsedMethod = 3; 317 _lastUsedMethod = 3;
318 } 318 }
319 else 319 else
320 { 320 {
321 321
322 } 322 }
323 } 323 }
324 else 324 else
325 { 325 {
326 _lastUsedMethod = 4; 326 _lastUsedMethod = 4;
327 } 327 }
328 } 328 }
329 else 329 else
330 { 330 {
331 _lastUsedMethod = 5; 331 _lastUsedMethod = 5;
332 } 332 }
333 } 333 }
334 } 334 }
335 335
336 if (isValid) 336 if (isValid)
337 { 337 {
338 output.AddContactPoint(normalInB, pointOnB + positionOffset, distance); 338 output.AddContactPoint(normalInB, pointOnB + positionOffset, distance);
339 } 339 }
340 } 340 }
341 } 341 }
342 } 342 }
343} \ No newline at end of file 343} \ No newline at end of file
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/IConvexPenetrationDepthSolver.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/IConvexPenetrationDepthSolver.cs
index 59fd486..08206c8 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/IConvexPenetrationDepthSolver.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/IConvexPenetrationDepthSolver.cs
@@ -1,42 +1,42 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 /// <summary> 29 /// <summary>
30 /// IConvexPenetrationDepthSolver provides an interface for penetration depth calculation. 30 /// IConvexPenetrationDepthSolver provides an interface for penetration depth calculation.
31 /// </summary> 31 /// </summary>
32 public interface IConvexPenetrationDepthSolver 32 public interface IConvexPenetrationDepthSolver
33 { 33 {
34 bool CalculatePenetrationDepth( 34 bool CalculatePenetrationDepth(
35 ISimplexSolver simplexSolver, 35 ISimplexSolver simplexSolver,
36 ConvexShape convexA, ConvexShape convexB, 36 ConvexShape convexA, ConvexShape convexB,
37 Matrix transformA, Matrix transformB, 37 Matrix transformA, Matrix transformB,
38 Vector3 vector, out Vector3 ptrA, out Vector3 ptrB, 38 Vector3 vector, out Vector3 ptrA, out Vector3 ptrB,
39 IDebugDraw debugDraw//, StackAlloc stackAlloc 39 IDebugDraw debugDraw//, StackAlloc stackAlloc
40 ); 40 );
41 } 41 }
42} 42}
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ISimplexSolver.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ISimplexSolver.cs
index 71b1eaa..f1b1807 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ISimplexSolver.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ISimplexSolver.cs
@@ -1,48 +1,48 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 /// ISimplexSolver can incrementally calculate distance between origin and up to 4 vertices 29 /// ISimplexSolver can incrementally calculate distance between origin and up to 4 vertices
30 /// Used by GJK or Linear Casting. Can be implemented by the Johnson-algorithm or alternative approaches based on 30 /// Used by GJK or Linear Casting. Can be implemented by the Johnson-algorithm or alternative approaches based on
31 /// voronoi regions or barycentric coordinates 31 /// voronoi regions or barycentric coordinates
32 public interface ISimplexSolver 32 public interface ISimplexSolver
33 { 33 {
34 void Reset(); 34 void Reset();
35 void AddVertex(Vector3 w, Vector3 p, Vector3 q); 35 void AddVertex(Vector3 w, Vector3 p, Vector3 q);
36 bool Closest(out Vector3 v); 36 bool Closest(out Vector3 v);
37 37
38 int GetSimplex(out Vector3[] pBuf, out Vector3[] qBuf, out Vector3[] yBuf); 38 int GetSimplex(out Vector3[] pBuf, out Vector3[] qBuf, out Vector3[] yBuf);
39 bool InSimplex(Vector3 w); 39 bool InSimplex(Vector3 w);
40 void BackupClosest(out Vector3 v); 40 void BackupClosest(out Vector3 v);
41 void ComputePoints(out Vector3 pA, out Vector3 pB); 41 void ComputePoints(out Vector3 pA, out Vector3 pB);
42 42
43 int NumVertices { get;} 43 int NumVertices { get;}
44 bool EmptySimplex { get;} 44 bool EmptySimplex { get;}
45 float MaxVertex { get;} 45 float MaxVertex { get;}
46 bool FullSimplex { get;} 46 bool FullSimplex { get;}
47 } 47 }
48} \ No newline at end of file 48} \ No newline at end of file
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ManifoldPoint.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ManifoldPoint.cs
index 751a9df..f5bcedc 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ManifoldPoint.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/ManifoldPoint.cs
@@ -1,78 +1,78 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 public class ManifoldPoint 29 public class ManifoldPoint
30 { 30 {
31 private Vector3 _localPointA; 31 private Vector3 _localPointA;
32 private Vector3 _localPointB; 32 private Vector3 _localPointB;
33 private Vector3 _positionWorldOnB; 33 private Vector3 _positionWorldOnB;
34 private Vector3 _positionWorldOnA; 34 private Vector3 _positionWorldOnA;
35 private Vector3 _normalWorldOnB; 35 private Vector3 _normalWorldOnB;
36 36
37 private float _distance; 37 private float _distance;
38 private float _combinedFriction; 38 private float _combinedFriction;
39 private float _combinedRestitution; 39 private float _combinedRestitution;
40 40
41 private object _userPersistentData; 41 private object _userPersistentData;
42 42
43 private int _lifeTime;//lifetime of the contactpoint in frames 43 private int _lifeTime;//lifetime of the contactpoint in frames
44 44
45 public ManifoldPoint() 45 public ManifoldPoint()
46 : this(new Vector3(), new Vector3(), new Vector3(), 0f) 46 : this(new Vector3(), new Vector3(), new Vector3(), 0f)
47 { 47 {
48 } 48 }
49 49
50 public ManifoldPoint(Vector3 pointA, Vector3 pointB, 50 public ManifoldPoint(Vector3 pointA, Vector3 pointB,
51 Vector3 normal, 51 Vector3 normal,
52 float distance) 52 float distance)
53 { 53 {
54 _localPointA = pointA; 54 _localPointA = pointA;
55 _localPointB = pointB; 55 _localPointB = pointB;
56 _normalWorldOnB = normal; 56 _normalWorldOnB = normal;
57 _distance = distance; 57 _distance = distance;
58 _positionWorldOnA = new Vector3(); 58 _positionWorldOnA = new Vector3();
59 _positionWorldOnB = new Vector3(); 59 _positionWorldOnB = new Vector3();
60 } 60 }
61 61
62 public float Distance { get { return _distance; } set { _distance = value; } } 62 public float Distance { get { return _distance; } set { _distance = value; } }
63 public int LifeTime { get { return _lifeTime; } set { _lifeTime = value; } } 63 public int LifeTime { get { return _lifeTime; } set { _lifeTime = value; } }
64 64
65 public Vector3 PositionWorldOnA { get { return _positionWorldOnA; } set { _positionWorldOnA = value; } } 65 public Vector3 PositionWorldOnA { get { return _positionWorldOnA; } set { _positionWorldOnA = value; } }
66 public Vector3 PositionWorldOnB { get { return _positionWorldOnB; } set { _positionWorldOnB = value; } } 66 public Vector3 PositionWorldOnB { get { return _positionWorldOnB; } set { _positionWorldOnB = value; } }
67 67
68 public Vector3 LocalPointA { get { return _localPointA; } set { _localPointA = value; } } 68 public Vector3 LocalPointA { get { return _localPointA; } set { _localPointA = value; } }
69 public Vector3 LocalPointB { get { return _localPointB; } set { _localPointB = value; } } 69 public Vector3 LocalPointB { get { return _localPointB; } set { _localPointB = value; } }
70 70
71 public Vector3 NormalWorldOnB { get { return _normalWorldOnB; } } 71 public Vector3 NormalWorldOnB { get { return _normalWorldOnB; } }
72 72
73 public float CombinedFriction { get { return _combinedFriction; } set { _combinedFriction = value; } } 73 public float CombinedFriction { get { return _combinedFriction; } set { _combinedFriction = value; } }
74 public float CombinedRestitution { get { return _combinedRestitution; } set { _combinedRestitution = value; } } 74 public float CombinedRestitution { get { return _combinedRestitution; } set { _combinedRestitution = value; } }
75 75
76 public object UserPersistentData { get { return _userPersistentData; } set { _userPersistentData = value; } } 76 public object UserPersistentData { get { return _userPersistentData; } set { _userPersistentData = value; } }
77 } 77 }
78} 78}
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.cs
index 81b05b8..7363e28 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/MinkowskiPenetrationDepthSolver.cs
@@ -1,246 +1,246 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 /// <summary> 29 /// <summary>
30 /// MinkowskiPenetrationDepthSolver implements bruteforce penetration depth estimation. 30 /// MinkowskiPenetrationDepthSolver implements bruteforce penetration depth estimation.
31 /// Implementation is based on sampling the depth using support mapping, and using GJK step to get the witness points. 31 /// Implementation is based on sampling the depth using support mapping, and using GJK step to get the witness points.
32 /// </summary> 32 /// </summary>
33 public class MinkowskiPenetrationDepthSolver : IConvexPenetrationDepthSolver 33 public class MinkowskiPenetrationDepthSolver : IConvexPenetrationDepthSolver
34 { 34 {
35 private const int UnitSpherePointsCount = 42; 35 private const int UnitSpherePointsCount = 42;
36 36
37 private static Vector3[] penetrationDirections = 37 private static Vector3[] penetrationDirections =
38 { 38 {
39 new Vector3(0.000000f , -0.000000f,-1.000000f), 39 new Vector3(0.000000f , -0.000000f,-1.000000f),
40 new Vector3(0.723608f , -0.525725f,-0.447219f), 40 new Vector3(0.723608f , -0.525725f,-0.447219f),
41 new Vector3(-0.276388f , -0.850649f,-0.447219f), 41 new Vector3(-0.276388f , -0.850649f,-0.447219f),
42 new Vector3(-0.894426f , -0.000000f,-0.447216f), 42 new Vector3(-0.894426f , -0.000000f,-0.447216f),
43 new Vector3(-0.276388f , 0.850649f,-0.447220f), 43 new Vector3(-0.276388f , 0.850649f,-0.447220f),
44 new Vector3(0.723608f , 0.525725f,-0.447219f), 44 new Vector3(0.723608f , 0.525725f,-0.447219f),
45 new Vector3(0.276388f , -0.850649f,0.447220f), 45 new Vector3(0.276388f , -0.850649f,0.447220f),
46 new Vector3(-0.723608f , -0.525725f,0.447219f), 46 new Vector3(-0.723608f , -0.525725f,0.447219f),
47 new Vector3(-0.723608f , 0.525725f,0.447219f), 47 new Vector3(-0.723608f , 0.525725f,0.447219f),
48 new Vector3(0.276388f , 0.850649f,0.447219f), 48 new Vector3(0.276388f , 0.850649f,0.447219f),
49 new Vector3(0.894426f , 0.000000f,0.447216f), 49 new Vector3(0.894426f , 0.000000f,0.447216f),
50 new Vector3(-0.000000f , 0.000000f,1.000000f), 50 new Vector3(-0.000000f , 0.000000f,1.000000f),
51 new Vector3(0.425323f , -0.309011f,-0.850654f), 51 new Vector3(0.425323f , -0.309011f,-0.850654f),
52 new Vector3(-0.162456f , -0.499995f,-0.850654f), 52 new Vector3(-0.162456f , -0.499995f,-0.850654f),
53 new Vector3(0.262869f , -0.809012f,-0.525738f), 53 new Vector3(0.262869f , -0.809012f,-0.525738f),
54 new Vector3(0.425323f , 0.309011f,-0.850654f), 54 new Vector3(0.425323f , 0.309011f,-0.850654f),
55 new Vector3(0.850648f , -0.000000f,-0.525736f), 55 new Vector3(0.850648f , -0.000000f,-0.525736f),
56 new Vector3(-0.525730f , -0.000000f,-0.850652f), 56 new Vector3(-0.525730f , -0.000000f,-0.850652f),
57 new Vector3(-0.688190f , -0.499997f,-0.525736f), 57 new Vector3(-0.688190f , -0.499997f,-0.525736f),
58 new Vector3(-0.162456f , 0.499995f,-0.850654f), 58 new Vector3(-0.162456f , 0.499995f,-0.850654f),
59 new Vector3(-0.688190f , 0.499997f,-0.525736f), 59 new Vector3(-0.688190f , 0.499997f,-0.525736f),
60 new Vector3(0.262869f , 0.809012f,-0.525738f), 60 new Vector3(0.262869f , 0.809012f,-0.525738f),
61 new Vector3(0.951058f , 0.309013f,0.000000f), 61 new Vector3(0.951058f , 0.309013f,0.000000f),
62 new Vector3(0.951058f , -0.309013f,0.000000f), 62 new Vector3(0.951058f , -0.309013f,0.000000f),
63 new Vector3(0.587786f , -0.809017f,0.000000f), 63 new Vector3(0.587786f , -0.809017f,0.000000f),
64 new Vector3(0.000000f , -1.000000f,0.000000f), 64 new Vector3(0.000000f , -1.000000f,0.000000f),
65 new Vector3(-0.587786f , -0.809017f,0.000000f), 65 new Vector3(-0.587786f , -0.809017f,0.000000f),
66 new Vector3(-0.951058f , -0.309013f,-0.000000f), 66 new Vector3(-0.951058f , -0.309013f,-0.000000f),
67 new Vector3(-0.951058f , 0.309013f,-0.000000f), 67 new Vector3(-0.951058f , 0.309013f,-0.000000f),
68 new Vector3(-0.587786f , 0.809017f,-0.000000f), 68 new Vector3(-0.587786f , 0.809017f,-0.000000f),
69 new Vector3(-0.000000f , 1.000000f,-0.000000f), 69 new Vector3(-0.000000f , 1.000000f,-0.000000f),
70 new Vector3(0.587786f , 0.809017f,-0.000000f), 70 new Vector3(0.587786f , 0.809017f,-0.000000f),
71 new Vector3(0.688190f , -0.499997f,0.525736f), 71 new Vector3(0.688190f , -0.499997f,0.525736f),
72 new Vector3(-0.262869f , -0.809012f,0.525738f), 72 new Vector3(-0.262869f , -0.809012f,0.525738f),
73 new Vector3(-0.850648f , 0.000000f,0.525736f), 73 new Vector3(-0.850648f , 0.000000f,0.525736f),
74 new Vector3(-0.262869f , 0.809012f,0.525738f), 74 new Vector3(-0.262869f , 0.809012f,0.525738f),
75 new Vector3(0.688190f , 0.499997f,0.525736f), 75 new Vector3(0.688190f , 0.499997f,0.525736f),
76 new Vector3(0.525730f , 0.000000f,0.850652f), 76 new Vector3(0.525730f , 0.000000f,0.850652f),
77 new Vector3(0.162456f , -0.499995f,0.850654f), 77 new Vector3(0.162456f , -0.499995f,0.850654f),
78 new Vector3(-0.425323f , -0.309011f,0.850654f), 78 new Vector3(-0.425323f , -0.309011f,0.850654f),
79 new Vector3(-0.425323f , 0.309011f,0.850654f), 79 new Vector3(-0.425323f , 0.309011f,0.850654f),
80 new Vector3(0.162456f , 0.499995f,0.850654f) 80 new Vector3(0.162456f , 0.499995f,0.850654f)
81 }; 81 };
82 82
83 private class IntermediateResult : DiscreteCollisionDetectorInterface.Result 83 private class IntermediateResult : DiscreteCollisionDetectorInterface.Result
84 { 84 {
85 private Vector3 _normalOnBInWorld; 85 private Vector3 _normalOnBInWorld;
86 private Vector3 _pointInWorld; 86 private Vector3 _pointInWorld;
87 private float _depth; 87 private float _depth;
88 private bool _hasResult; 88 private bool _hasResult;
89 89
90 public IntermediateResult() 90 public IntermediateResult()
91 { 91 {
92 _hasResult = false; 92 _hasResult = false;
93 } 93 }
94 94
95 public bool HasResult { get { return _hasResult; } } 95 public bool HasResult { get { return _hasResult; } }
96 public float Depth { get { return _depth; } } 96 public float Depth { get { return _depth; } }
97 public Vector3 PointInWorld { get { return _pointInWorld; } } 97 public Vector3 PointInWorld { get { return _pointInWorld; } }
98 98
99 public override void SetShapeIdentifiers(int partId0, int index0, int partId1, int index1) 99 public override void SetShapeIdentifiers(int partId0, int index0, int partId1, int index1)
100 { 100 {
101 } 101 }
102 102
103 public override void AddContactPoint(Vector3 normalOnBInWorld, Vector3 pointInWorld, float depth) 103 public override void AddContactPoint(Vector3 normalOnBInWorld, Vector3 pointInWorld, float depth)
104 { 104 {
105 _normalOnBInWorld = normalOnBInWorld; 105 _normalOnBInWorld = normalOnBInWorld;
106 _pointInWorld = pointInWorld; 106 _pointInWorld = pointInWorld;
107 _depth = depth; 107 _depth = depth;
108 _hasResult = true; 108 _hasResult = true;
109 } 109 }
110 } 110 }
111 111
112 #region IConvexPenetrationDepthSolver Members 112 #region IConvexPenetrationDepthSolver Members
113 public bool CalculatePenetrationDepth(ISimplexSolver simplexSolver, 113 public bool CalculatePenetrationDepth(ISimplexSolver simplexSolver,
114 ConvexShape convexA, ConvexShape convexB, 114 ConvexShape convexA, ConvexShape convexB,
115 Matrix transformA, Matrix transformB, 115 Matrix transformA, Matrix transformB,
116 Vector3 v, out Vector3 pa, out Vector3 pb, IDebugDraw debugDraw) 116 Vector3 v, out Vector3 pa, out Vector3 pb, IDebugDraw debugDraw)
117 { 117 {
118 pa = new Vector3(); 118 pa = new Vector3();
119 pb = new Vector3(); 119 pb = new Vector3();
120 //just take fixed number of orientation, and sample the penetration depth in that direction 120 //just take fixed number of orientation, and sample the penetration depth in that direction
121 float minProj = 1e30f; 121 float minProj = 1e30f;
122 Vector3 minNorm = new Vector3(); 122 Vector3 minNorm = new Vector3();
123 Vector3 minA = new Vector3(), minB = new Vector3(); 123 Vector3 minA = new Vector3(), minB = new Vector3();
124 Vector3 seperatingAxisInA, seperatingAxisInB; 124 Vector3 seperatingAxisInA, seperatingAxisInB;
125 Vector3 pInA, qInB, pWorld, qWorld, w; 125 Vector3 pInA, qInB, pWorld, qWorld, w;
126 126
127 Vector3[] supportVerticesABatch = new Vector3[UnitSpherePointsCount + ConvexShape.MaxPreferredPenetrationDirections * 2]; 127 Vector3[] supportVerticesABatch = new Vector3[UnitSpherePointsCount + ConvexShape.MaxPreferredPenetrationDirections * 2];
128 Vector3[] supportVerticesBBatch = new Vector3[UnitSpherePointsCount + ConvexShape.MaxPreferredPenetrationDirections * 2]; 128 Vector3[] supportVerticesBBatch = new Vector3[UnitSpherePointsCount + ConvexShape.MaxPreferredPenetrationDirections * 2];
129 Vector3[] seperatingAxisInABatch = new Vector3[UnitSpherePointsCount + ConvexShape.MaxPreferredPenetrationDirections * 2]; 129 Vector3[] seperatingAxisInABatch = new Vector3[UnitSpherePointsCount + ConvexShape.MaxPreferredPenetrationDirections * 2];
130 Vector3[] seperatingAxisInBBatch = new Vector3[UnitSpherePointsCount + ConvexShape.MaxPreferredPenetrationDirections * 2]; 130 Vector3[] seperatingAxisInBBatch = new Vector3[UnitSpherePointsCount + ConvexShape.MaxPreferredPenetrationDirections * 2];
131 131
132 int numSampleDirections = UnitSpherePointsCount; 132 int numSampleDirections = UnitSpherePointsCount;
133 133
134 for (int i = 0; i < numSampleDirections; i++) 134 for (int i = 0; i < numSampleDirections; i++)
135 { 135 {
136 Vector3 norm = penetrationDirections[i]; 136 Vector3 norm = penetrationDirections[i];
137 seperatingAxisInABatch[i] = Vector3.TransformNormal((-norm), transformA); 137 seperatingAxisInABatch[i] = Vector3.TransformNormal((-norm), transformA);
138 seperatingAxisInBBatch[i] = Vector3.TransformNormal(norm, transformB); 138 seperatingAxisInBBatch[i] = Vector3.TransformNormal(norm, transformB);
139 } 139 }
140 140
141 { 141 {
142 int numPDA = convexA.PreferredPenetrationDirectionsCount; 142 int numPDA = convexA.PreferredPenetrationDirectionsCount;
143 if (numPDA != 0) 143 if (numPDA != 0)
144 { 144 {
145 for (int i = 0; i < numPDA; i++) 145 for (int i = 0; i < numPDA; i++)
146 { 146 {
147 Vector3 norm; 147 Vector3 norm;
148 convexA.GetPreferredPenetrationDirection(i, out norm); 148 convexA.GetPreferredPenetrationDirection(i, out norm);
149 norm = Vector3.TransformNormal(norm, transformA); 149 norm = Vector3.TransformNormal(norm, transformA);
150 penetrationDirections[numSampleDirections] = norm; 150 penetrationDirections[numSampleDirections] = norm;
151 seperatingAxisInABatch[numSampleDirections] = Vector3.TransformNormal((-norm), transformA); 151 seperatingAxisInABatch[numSampleDirections] = Vector3.TransformNormal((-norm), transformA);
152 seperatingAxisInBBatch[numSampleDirections] = Vector3.TransformNormal(norm, transformB); 152 seperatingAxisInBBatch[numSampleDirections] = Vector3.TransformNormal(norm, transformB);
153 numSampleDirections++; 153 numSampleDirections++;
154 } 154 }
155 } 155 }
156 } 156 }
157 157
158 { 158 {
159 int numPDB = convexB.PreferredPenetrationDirectionsCount; 159 int numPDB = convexB.PreferredPenetrationDirectionsCount;
160 if (numPDB != 0) 160 if (numPDB != 0)
161 { 161 {
162 for (int i = 0; i < numPDB; i++) 162 for (int i = 0; i < numPDB; i++)
163 { 163 {
164 Vector3 norm; 164 Vector3 norm;
165 convexB.GetPreferredPenetrationDirection(i, out norm); 165 convexB.GetPreferredPenetrationDirection(i, out norm);
166 norm = Vector3.TransformNormal(norm, transformB); 166 norm = Vector3.TransformNormal(norm, transformB);
167 penetrationDirections[numSampleDirections] = norm; 167 penetrationDirections[numSampleDirections] = norm;
168 seperatingAxisInABatch[numSampleDirections] = Vector3.TransformNormal((-norm), transformA); 168 seperatingAxisInABatch[numSampleDirections] = Vector3.TransformNormal((-norm), transformA);
169 seperatingAxisInBBatch[numSampleDirections] = Vector3.TransformNormal(norm, transformB); 169 seperatingAxisInBBatch[numSampleDirections] = Vector3.TransformNormal(norm, transformB);
170 numSampleDirections++; 170 numSampleDirections++;
171 } 171 }
172 } 172 }
173 } 173 }
174 174
175 convexA.BatchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInABatch, supportVerticesABatch); //, numSampleDirections); 175 convexA.BatchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInABatch, supportVerticesABatch); //, numSampleDirections);
176 convexB.BatchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInBBatch, supportVerticesBBatch); //, numSampleDirections); 176 convexB.BatchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInBBatch, supportVerticesBBatch); //, numSampleDirections);
177 177
178 for (int i = 0; i < numSampleDirections; i++) 178 for (int i = 0; i < numSampleDirections; i++)
179 { 179 {
180 Vector3 norm = penetrationDirections[i]; 180 Vector3 norm = penetrationDirections[i];
181 seperatingAxisInA = seperatingAxisInABatch[i]; 181 seperatingAxisInA = seperatingAxisInABatch[i];
182 seperatingAxisInB = seperatingAxisInBBatch[i]; 182 seperatingAxisInB = seperatingAxisInBBatch[i];
183 183
184 pInA = supportVerticesABatch[i]; 184 pInA = supportVerticesABatch[i];
185 qInB = supportVerticesBBatch[i]; 185 qInB = supportVerticesBBatch[i];
186 186
187 pWorld = MathHelper.MatrixToVector(transformA, pInA); 187 pWorld = MathHelper.MatrixToVector(transformA, pInA);
188 qWorld = MathHelper.MatrixToVector(transformB, qInB); 188 qWorld = MathHelper.MatrixToVector(transformB, qInB);
189 w = qWorld - pWorld; 189 w = qWorld - pWorld;
190 float delta = Vector3.Dot(norm, w); 190 float delta = Vector3.Dot(norm, w);
191 //find smallest delta 191 //find smallest delta
192 if (delta < minProj) 192 if (delta < minProj)
193 { 193 {
194 minProj = delta; 194 minProj = delta;
195 minNorm = norm; 195 minNorm = norm;
196 minA = pWorld; 196 minA = pWorld;
197 minB = qWorld; 197 minB = qWorld;
198 } 198 }
199 } 199 }
200 200
201 //add the margins 201 //add the margins
202 minA += minNorm * convexA.Margin; 202 minA += minNorm * convexA.Margin;
203 minB -= minNorm * convexB.Margin; 203 minB -= minNorm * convexB.Margin;
204 //no penetration 204 //no penetration
205 if (minProj < 0) 205 if (minProj < 0)
206 return false; 206 return false;
207 207
208 minProj += (convexA.Margin + convexB.Margin); 208 minProj += (convexA.Margin + convexB.Margin);
209 209
210 GjkPairDetector gjkdet = new GjkPairDetector(convexA, convexB, simplexSolver, null); 210 GjkPairDetector gjkdet = new GjkPairDetector(convexA, convexB, simplexSolver, null);
211 211
212 float offsetDist = minProj; 212 float offsetDist = minProj;
213 Vector3 offset = minNorm * offsetDist; 213 Vector3 offset = minNorm * offsetDist;
214 214
215 GjkPairDetector.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput(); 215 GjkPairDetector.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput();
216 216
217 Vector3 newOrg = transformA.Translation + offset; 217 Vector3 newOrg = transformA.Translation + offset;
218 218
219 Matrix displacedTrans = transformA; 219 Matrix displacedTrans = transformA;
220 displacedTrans.Translation = newOrg; 220 displacedTrans.Translation = newOrg;
221 221
222 input.TransformA = displacedTrans; 222 input.TransformA = displacedTrans;
223 input.TransformB = transformB; 223 input.TransformB = transformB;
224 input.MaximumDistanceSquared = 1e30f;//minProj; 224 input.MaximumDistanceSquared = 1e30f;//minProj;
225 225
226 IntermediateResult res = new IntermediateResult(); 226 IntermediateResult res = new IntermediateResult();
227 gjkdet.GetClosestPoints(input, res, debugDraw); 227 gjkdet.GetClosestPoints(input, res, debugDraw);
228 228
229 float correctedMinNorm = minProj - res.Depth; 229 float correctedMinNorm = minProj - res.Depth;
230 230
231 //the penetration depth is over-estimated, relax it 231 //the penetration depth is over-estimated, relax it
232 float penetration_relaxation = 1; 232 float penetration_relaxation = 1;
233 minNorm *= penetration_relaxation; 233 minNorm *= penetration_relaxation;
234 234
235 if (res.HasResult) 235 if (res.HasResult)
236 { 236 {
237 237
238 pa = res.PointInWorld - minNorm * correctedMinNorm; 238 pa = res.PointInWorld - minNorm * correctedMinNorm;
239 pb = res.PointInWorld; 239 pb = res.PointInWorld;
240 } 240 }
241 241
242 return res.HasResult; 242 return res.HasResult;
243 } 243 }
244 #endregion 244 #endregion
245 } 245 }
246} 246}
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/PersistentManifold.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/PersistentManifold.cs
index 47cfe9a..04a533d 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/PersistentManifold.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/PersistentManifold.cs
@@ -1,272 +1,272 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 public delegate bool ContactDestroyedCallback(object userPersistentData); 29 public delegate bool ContactDestroyedCallback(object userPersistentData);
30 30
31 public class PersistentManifold 31 public class PersistentManifold
32 { 32 {
33 private static ContactDestroyedCallback _contactDestroyedCallback = null; 33 private static ContactDestroyedCallback _contactDestroyedCallback = null;
34 private static float _contactBreakingThreshold = 0.02f; 34 private static float _contactBreakingThreshold = 0.02f;
35 35
36 private ManifoldPoint[] _pointCache = new ManifoldPoint[4]; 36 private ManifoldPoint[] _pointCache = new ManifoldPoint[4];
37 37
38 // this two body pointers can point to the physics rigidbody class. 38 // this two body pointers can point to the physics rigidbody class.
39 // object will allow any rigidbody class 39 // object will allow any rigidbody class
40 private object _bodyA; 40 private object _bodyA;
41 private object _bodyB; 41 private object _bodyB;
42 private int _cachedPoints; 42 private int _cachedPoints;
43 43
44 public PersistentManifold(object bodyA, object bodyB) 44 public PersistentManifold(object bodyA, object bodyB)
45 { 45 {
46 _bodyA = bodyA; 46 _bodyA = bodyA;
47 _bodyB = bodyB; 47 _bodyB = bodyB;
48 _cachedPoints = 0; 48 _cachedPoints = 0;
49 } 49 }
50 50
51 public object BodyA { get { return _bodyA; } } 51 public object BodyA { get { return _bodyA; } }
52 public object BodyB { get { return _bodyB; } } 52 public object BodyB { get { return _bodyB; } }
53 53
54 public int ContactsCount { get { return _cachedPoints; } } 54 public int ContactsCount { get { return _cachedPoints; } }
55 55
56 public static ContactDestroyedCallback ContactDestroyedCallback { get { return _contactDestroyedCallback; } set { _contactDestroyedCallback = value; } } 56 public static ContactDestroyedCallback ContactDestroyedCallback { get { return _contactDestroyedCallback; } set { _contactDestroyedCallback = value; } }
57 public static float ContactBreakingThreshold { get { return _contactBreakingThreshold; } } 57 public static float ContactBreakingThreshold { get { return _contactBreakingThreshold; } }
58 58
59 public void SetBodies(object bodyA, object bodyB) 59 public void SetBodies(object bodyA, object bodyB)
60 { 60 {
61 _bodyA = bodyA; 61 _bodyA = bodyA;
62 _bodyB = bodyB; 62 _bodyB = bodyB;
63 } 63 }
64 64
65 public ManifoldPoint GetContactPoint(int index) 65 public ManifoldPoint GetContactPoint(int index)
66 { 66 {
67 if (index >= _cachedPoints) 67 if (index >= _cachedPoints)
68 throw new ArgumentOutOfRangeException("index", "index must be smaller than cachedPoints"); 68 throw new ArgumentOutOfRangeException("index", "index must be smaller than cachedPoints");
69 69
70 return _pointCache[index]; 70 return _pointCache[index];
71 } 71 }
72 72
73 public int GetCacheEntry(ManifoldPoint newPoint) 73 public int GetCacheEntry(ManifoldPoint newPoint)
74 { 74 {
75 float shortestDist = ContactBreakingThreshold * ContactBreakingThreshold; 75 float shortestDist = ContactBreakingThreshold * ContactBreakingThreshold;
76 int size = ContactsCount; 76 int size = ContactsCount;
77 int nearestPoint = -1; 77 int nearestPoint = -1;
78 for (int i = 0; i < size; i++) 78 for (int i = 0; i < size; i++)
79 { 79 {
80 ManifoldPoint mp = _pointCache[i]; 80 ManifoldPoint mp = _pointCache[i];
81 81
82 Vector3 diffA = mp.LocalPointA - newPoint.LocalPointA; 82 Vector3 diffA = mp.LocalPointA - newPoint.LocalPointA;
83 float distToManiPoint = Vector3.Dot(diffA, diffA); 83 float distToManiPoint = Vector3.Dot(diffA, diffA);
84 if (distToManiPoint < shortestDist) 84 if (distToManiPoint < shortestDist)
85 { 85 {
86 shortestDist = distToManiPoint; 86 shortestDist = distToManiPoint;
87 nearestPoint = i; 87 nearestPoint = i;
88 } 88 }
89 } 89 }
90 return nearestPoint; 90 return nearestPoint;
91 } 91 }
92 92
93 public void AddManifoldPoint(ManifoldPoint newPoint) 93 public void AddManifoldPoint(ManifoldPoint newPoint)
94 { 94 {
95 if (!ValidContactDistance(newPoint)) 95 if (!ValidContactDistance(newPoint))
96 throw new BulletException(); 96 throw new BulletException();
97 97
98 int insertIndex = ContactsCount; 98 int insertIndex = ContactsCount;
99 if (insertIndex == 4) 99 if (insertIndex == 4)
100 { 100 {
101 //sort cache so best points come first, based on area 101 //sort cache so best points come first, based on area
102 insertIndex = SortCachedPoints(newPoint); 102 insertIndex = SortCachedPoints(newPoint);
103 } 103 }
104 else 104 else
105 { 105 {
106 _cachedPoints++; 106 _cachedPoints++;
107 } 107 }
108 ReplaceContactPoint(newPoint, insertIndex); 108 ReplaceContactPoint(newPoint, insertIndex);
109 } 109 }
110 110
111 public void RemoveContactPoint(int index) 111 public void RemoveContactPoint(int index)
112 { 112 {
113 ClearUserCache(_pointCache[index]); 113 ClearUserCache(_pointCache[index]);
114 114
115 int lastUsedIndex = ContactsCount - 1; 115 int lastUsedIndex = ContactsCount - 1;
116 _pointCache[index] = _pointCache[lastUsedIndex]; 116 _pointCache[index] = _pointCache[lastUsedIndex];
117 //get rid of duplicated userPersistentData pointer 117 //get rid of duplicated userPersistentData pointer
118 _pointCache[lastUsedIndex].UserPersistentData = null; 118 _pointCache[lastUsedIndex].UserPersistentData = null;
119 _cachedPoints--; 119 _cachedPoints--;
120 } 120 }
121 121
122 public void ReplaceContactPoint(ManifoldPoint newPoint, int insertIndex) 122 public void ReplaceContactPoint(ManifoldPoint newPoint, int insertIndex)
123 { 123 {
124 BulletDebug.Assert(ValidContactDistance(newPoint)); 124 BulletDebug.Assert(ValidContactDistance(newPoint));
125 125
126 if (_pointCache[insertIndex] != null) 126 if (_pointCache[insertIndex] != null)
127 { 127 {
128 int lifeTime = _pointCache[insertIndex].LifeTime; 128 int lifeTime = _pointCache[insertIndex].LifeTime;
129 BulletDebug.Assert(lifeTime >= 0); 129 BulletDebug.Assert(lifeTime >= 0);
130 object cache = _pointCache[insertIndex].UserPersistentData; 130 object cache = _pointCache[insertIndex].UserPersistentData;
131 131
132 _pointCache[insertIndex] = newPoint; 132 _pointCache[insertIndex] = newPoint;
133 133
134 _pointCache[insertIndex].UserPersistentData = cache; 134 _pointCache[insertIndex].UserPersistentData = cache;
135 _pointCache[insertIndex].LifeTime = lifeTime; 135 _pointCache[insertIndex].LifeTime = lifeTime;
136 } 136 }
137 else 137 else
138 { 138 {
139 _pointCache[insertIndex] = newPoint; 139 _pointCache[insertIndex] = newPoint;
140 } 140 }
141 141
142 //ClearUserCache(_pointCache[insertIndex]); 142 //ClearUserCache(_pointCache[insertIndex]);
143 //_pointCache[insertIndex] = newPoint; 143 //_pointCache[insertIndex] = newPoint;
144 } 144 }
145 145
146 public bool ValidContactDistance(ManifoldPoint pt) 146 public bool ValidContactDistance(ManifoldPoint pt)
147 { 147 {
148 return pt.Distance <= ContactBreakingThreshold; 148 return pt.Distance <= ContactBreakingThreshold;
149 } 149 }
150 150
151 // calculated new worldspace coordinates and depth, and reject points that exceed the collision margin 151 // calculated new worldspace coordinates and depth, and reject points that exceed the collision margin
152 public void RefreshContactPoints(Matrix trA, Matrix trB) 152 public void RefreshContactPoints(Matrix trA, Matrix trB)
153 { 153 {
154 // first refresh worldspace positions and distance 154 // first refresh worldspace positions and distance
155 for (int i = ContactsCount - 1; i >= 0; i--) 155 for (int i = ContactsCount - 1; i >= 0; i--)
156 { 156 {
157 ManifoldPoint manifoldPoint = _pointCache[i]; 157 ManifoldPoint manifoldPoint = _pointCache[i];
158 manifoldPoint.PositionWorldOnA = MathHelper.MatrixToVector(trA,manifoldPoint.LocalPointA); 158 manifoldPoint.PositionWorldOnA = MathHelper.MatrixToVector(trA,manifoldPoint.LocalPointA);
159 manifoldPoint.PositionWorldOnB = MathHelper.MatrixToVector(trB, manifoldPoint.LocalPointB); 159 manifoldPoint.PositionWorldOnB = MathHelper.MatrixToVector(trB, manifoldPoint.LocalPointB);
160 manifoldPoint.Distance = Vector3.Dot(manifoldPoint.PositionWorldOnA - manifoldPoint.PositionWorldOnB, manifoldPoint.NormalWorldOnB); 160 manifoldPoint.Distance = Vector3.Dot(manifoldPoint.PositionWorldOnA - manifoldPoint.PositionWorldOnB, manifoldPoint.NormalWorldOnB);
161 manifoldPoint.LifeTime++; 161 manifoldPoint.LifeTime++;
162 } 162 }
163 163
164 // then 164 // then
165 float distance2d; 165 float distance2d;
166 Vector3 projectedDifference, projectedPoint; 166 Vector3 projectedDifference, projectedPoint;
167 for (int i = ContactsCount - 1; i >= 0; i--) 167 for (int i = ContactsCount - 1; i >= 0; i--)
168 { 168 {
169 169
170 ManifoldPoint manifoldPoint = _pointCache[i]; 170 ManifoldPoint manifoldPoint = _pointCache[i];
171 //contact becomes invalid when signed distance exceeds margin (projected on contactnormal direction) 171 //contact becomes invalid when signed distance exceeds margin (projected on contactnormal direction)
172 if (!ValidContactDistance(manifoldPoint)) 172 if (!ValidContactDistance(manifoldPoint))
173 { 173 {
174 RemoveContactPoint(i); 174 RemoveContactPoint(i);
175 } 175 }
176 else 176 else
177 { 177 {
178 //contact also becomes invalid when relative movement orthogonal to normal exceeds margin 178 //contact also becomes invalid when relative movement orthogonal to normal exceeds margin
179 projectedPoint = manifoldPoint.PositionWorldOnA - manifoldPoint.NormalWorldOnB * manifoldPoint.Distance; 179 projectedPoint = manifoldPoint.PositionWorldOnA - manifoldPoint.NormalWorldOnB * manifoldPoint.Distance;
180 projectedDifference = manifoldPoint.PositionWorldOnB - projectedPoint; 180 projectedDifference = manifoldPoint.PositionWorldOnB - projectedPoint;
181 distance2d = Vector3.Dot(projectedDifference, projectedDifference); 181 distance2d = Vector3.Dot(projectedDifference, projectedDifference);
182 if (distance2d > ContactBreakingThreshold * ContactBreakingThreshold) 182 if (distance2d > ContactBreakingThreshold * ContactBreakingThreshold)
183 { 183 {
184 RemoveContactPoint(i); 184 RemoveContactPoint(i);
185 } 185 }
186 } 186 }
187 } 187 }
188 } 188 }
189 189
190 public void ClearManifold() 190 public void ClearManifold()
191 { 191 {
192 for (int i = 0; i < _cachedPoints; i++) 192 for (int i = 0; i < _cachedPoints; i++)
193 { 193 {
194 ClearUserCache(_pointCache[i]); 194 ClearUserCache(_pointCache[i]);
195 } 195 }
196 _cachedPoints = 0; 196 _cachedPoints = 0;
197 } 197 }
198 198
199 private void ClearUserCache(ManifoldPoint pt) 199 private void ClearUserCache(ManifoldPoint pt)
200 { 200 {
201 if (pt != null) 201 if (pt != null)
202 { 202 {
203 object oldPtr = pt.UserPersistentData; 203 object oldPtr = pt.UserPersistentData;
204 204
205 if (oldPtr != null) 205 if (oldPtr != null)
206 { 206 {
207 if (pt.UserPersistentData != null && _contactDestroyedCallback != null) 207 if (pt.UserPersistentData != null && _contactDestroyedCallback != null)
208 { 208 {
209 _contactDestroyedCallback(pt.UserPersistentData); 209 _contactDestroyedCallback(pt.UserPersistentData);
210 pt.UserPersistentData = null; 210 pt.UserPersistentData = null;
211 } 211 }
212 } 212 }
213 } 213 }
214 } 214 }
215 215
216 // sort cached points so most isolated points come first 216 // sort cached points so most isolated points come first
217 private int SortCachedPoints(ManifoldPoint pt) 217 private int SortCachedPoints(ManifoldPoint pt)
218 { 218 {
219 //calculate 4 possible cases areas, and take biggest area 219 //calculate 4 possible cases areas, and take biggest area
220 //also need to keep 'deepest' 220 //also need to keep 'deepest'
221 221
222 int maxPenetrationIndex = -1; 222 int maxPenetrationIndex = -1;
223 float maxPenetration = pt.Distance; 223 float maxPenetration = pt.Distance;
224 for (int i = 0; i < 4; i++) 224 for (int i = 0; i < 4; i++)
225 { 225 {
226 if (_pointCache[i].Distance < maxPenetration) 226 if (_pointCache[i].Distance < maxPenetration)
227 { 227 {
228 maxPenetrationIndex = i; 228 maxPenetrationIndex = i;
229 maxPenetration = _pointCache[i].Distance; 229 maxPenetration = _pointCache[i].Distance;
230 } 230 }
231 } 231 }
232 232
233 float res0 = 0, res1 = 0, res2 = 0, res3 = 0; 233 float res0 = 0, res1 = 0, res2 = 0, res3 = 0;
234 if (maxPenetrationIndex != 0) 234 if (maxPenetrationIndex != 0)
235 { 235 {
236 Vector3 a0 = pt.LocalPointA - _pointCache[1].LocalPointA; 236 Vector3 a0 = pt.LocalPointA - _pointCache[1].LocalPointA;
237 Vector3 b0 = _pointCache[3].LocalPointA - _pointCache[2].LocalPointA; 237 Vector3 b0 = _pointCache[3].LocalPointA - _pointCache[2].LocalPointA;
238 Vector3 cross = Vector3.Cross(a0, b0); 238 Vector3 cross = Vector3.Cross(a0, b0);
239 res0 = cross.LengthSquared(); 239 res0 = cross.LengthSquared();
240 } 240 }
241 if (maxPenetrationIndex != 1) 241 if (maxPenetrationIndex != 1)
242 { 242 {
243 Vector3 a1 = pt.LocalPointA - _pointCache[0].LocalPointA; 243 Vector3 a1 = pt.LocalPointA - _pointCache[0].LocalPointA;
244 Vector3 b1 = _pointCache[3].LocalPointA - _pointCache[2].LocalPointA; 244 Vector3 b1 = _pointCache[3].LocalPointA - _pointCache[2].LocalPointA;
245 Vector3 cross = Vector3.Cross(a1, b1); 245 Vector3 cross = Vector3.Cross(a1, b1);
246 res1 = cross.LengthSquared(); 246 res1 = cross.LengthSquared();
247 } 247 }
248 248
249 if (maxPenetrationIndex != 2) 249 if (maxPenetrationIndex != 2)
250 { 250 {
251 Vector3 a2 = pt.LocalPointA - _pointCache[0].LocalPointA; 251 Vector3 a2 = pt.LocalPointA - _pointCache[0].LocalPointA;
252 Vector3 b2 = _pointCache[3].LocalPointA - _pointCache[1].LocalPointA; 252 Vector3 b2 = _pointCache[3].LocalPointA - _pointCache[1].LocalPointA;
253 Vector3 cross = Vector3.Cross(a2, b2); 253 Vector3 cross = Vector3.Cross(a2, b2);
254 res2 = cross.LengthSquared(); 254 res2 = cross.LengthSquared();
255 } 255 }
256 256
257 if (maxPenetrationIndex != 3) 257 if (maxPenetrationIndex != 3)
258 { 258 {
259 Vector3 a3 = pt.LocalPointA - _pointCache[0].LocalPointA; 259 Vector3 a3 = pt.LocalPointA - _pointCache[0].LocalPointA;
260 Vector3 b3 = _pointCache[2].LocalPointA - _pointCache[1].LocalPointA; 260 Vector3 b3 = _pointCache[2].LocalPointA - _pointCache[1].LocalPointA;
261 Vector3 cross = Vector3.Cross(a3, b3); 261 Vector3 cross = Vector3.Cross(a3, b3);
262 res3 = cross.LengthSquared(); 262 res3 = cross.LengthSquared();
263 } 263 }
264 264
265 Vector4 maxvec = new Vector4(res0, res1, res2, res3); 265 Vector4 maxvec = new Vector4(res0, res1, res2, res3);
266 int biggestarea = MathHelper.ClosestAxis(maxvec); 266 int biggestarea = MathHelper.ClosestAxis(maxvec);
267 return biggestarea; 267 return biggestarea;
268 } 268 }
269 269
270 private int FindContactPoint(ManifoldPoint unUsed, int numUnused, ManifoldPoint pt) { return 0; } 270 private int FindContactPoint(ManifoldPoint unUsed, int numUnused, ManifoldPoint pt) { return 0; }
271 } 271 }
272} 272}
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/PointCollector.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/PointCollector.cs
index 4e0b0a0..c70741e 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/PointCollector.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/PointCollector.cs
@@ -1,64 +1,64 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 public class PointCollector : DiscreteCollisionDetectorInterface.Result 29 public class PointCollector : DiscreteCollisionDetectorInterface.Result
30 { 30 {
31 private Vector3 _normalOnBInWorld; 31 private Vector3 _normalOnBInWorld;
32 private Vector3 _pointInWorld; 32 private Vector3 _pointInWorld;
33 private float _distance; //negative means penetration 33 private float _distance; //negative means penetration
34 private bool _hasResult; 34 private bool _hasResult;
35 35
36 public PointCollector() 36 public PointCollector()
37 { 37 {
38 _distance = 1e30f; 38 _distance = 1e30f;
39 _hasResult = false; 39 _hasResult = false;
40 } 40 }
41 41
42 public Vector3 NormalOnBInWorld { get { return _normalOnBInWorld; } } 42 public Vector3 NormalOnBInWorld { get { return _normalOnBInWorld; } }
43 public Vector3 PointInWorld { get { return _pointInWorld; } } 43 public Vector3 PointInWorld { get { return _pointInWorld; } }
44 public float Distance { get { return _distance; } } 44 public float Distance { get { return _distance; } }
45 public bool HasResult { get { return _hasResult; } } 45 public bool HasResult { get { return _hasResult; } }
46 46
47 public override void SetShapeIdentifiers(int partIdA, int indexA, int partIdB, int indexB) 47 public override void SetShapeIdentifiers(int partIdA, int indexA, int partIdB, int indexB)
48 { 48 {
49 //?? 49 //??
50 } 50 }
51 51
52 public override void AddContactPoint(Vector3 normalOnBInWorld, Vector3 pointInWorld, float depth) 52 public override void AddContactPoint(Vector3 normalOnBInWorld, Vector3 pointInWorld, float depth)
53 { 53 {
54 if (depth < _distance) 54 if (depth < _distance)
55 { 55 {
56 _hasResult = true; 56 _hasResult = true;
57 _normalOnBInWorld = normalOnBInWorld; 57 _normalOnBInWorld = normalOnBInWorld;
58 _pointInWorld = pointInWorld; 58 _pointInWorld = pointInWorld;
59 //negative means penetration 59 //negative means penetration
60 _distance = depth; 60 _distance = depth;
61 } 61 }
62 } 62 }
63 } 63 }
64} 64}
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/SubsimplexConvexCast.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/SubsimplexConvexCast.cs
index 6d320c4..5c92a0c 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/SubsimplexConvexCast.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/SubsimplexConvexCast.cs
@@ -1,142 +1,142 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 /// <summary> 29 /// <summary>
30 /// SubsimplexConvexCast implements Gino van den Bergens' paper 30 /// SubsimplexConvexCast implements Gino van den Bergens' paper
31 /// "Ray Casting against bteral Convex Objects with Application to Continuous Collision Detection" 31 /// "Ray Casting against bteral Convex Objects with Application to Continuous Collision Detection"
32 /// GJK based Ray Cast, optimized version 32 /// GJK based Ray Cast, optimized version
33 /// Objects should not start in overlap, otherwise results are not defined. 33 /// Objects should not start in overlap, otherwise results are not defined.
34 /// </summary> 34 /// </summary>
35 public class SubsimplexConvexCast : IConvexCast 35 public class SubsimplexConvexCast : IConvexCast
36 { 36 {
37 private ISimplexSolver _simplexSolver; 37 private ISimplexSolver _simplexSolver;
38 private ConvexShape _convexA; 38 private ConvexShape _convexA;
39 private ConvexShape _convexB; 39 private ConvexShape _convexB;
40 40
41 /// <summary> 41 /// <summary>
42 /// Typically the conservative advancement reaches solution in a few iterations, clip it to 32 for degenerate cases. 42 /// Typically the conservative advancement reaches solution in a few iterations, clip it to 32 for degenerate cases.
43 /// See discussion about this here http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=565 43 /// See discussion about this here http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=565
44 /// </summary> 44 /// </summary>
45 private const int MaxIterations = 32; 45 private const int MaxIterations = 32;
46 46
47 public SubsimplexConvexCast(ConvexShape shapeA, ConvexShape shapeB, ISimplexSolver simplexSolver) 47 public SubsimplexConvexCast(ConvexShape shapeA, ConvexShape shapeB, ISimplexSolver simplexSolver)
48 { 48 {
49 _simplexSolver = simplexSolver; 49 _simplexSolver = simplexSolver;
50 _convexA = shapeA; 50 _convexA = shapeA;
51 _convexB = shapeB; 51 _convexB = shapeB;
52 } 52 }
53 53
54 #region IConvexCast Members 54 #region IConvexCast Members
55 /// <summary> 55 /// <summary>
56 /// SimsimplexConvexCast calculateTimeOfImpact calculates the time of impact+normal for the linear cast (sweep) between two moving objects. 56 /// SimsimplexConvexCast calculateTimeOfImpact calculates the time of impact+normal for the linear cast (sweep) between two moving objects.
57 /// Precondition is that objects should not penetration/overlap at the start from the interval. Overlap can be tested using GjkPairDetector. 57 /// Precondition is that objects should not penetration/overlap at the start from the interval. Overlap can be tested using GjkPairDetector.
58 /// </summary> 58 /// </summary>
59 /// <param name="fromA"></param> 59 /// <param name="fromA"></param>
60 /// <param name="toA"></param> 60 /// <param name="toA"></param>
61 /// <param name="fromB"></param> 61 /// <param name="fromB"></param>
62 /// <param name="toB"></param> 62 /// <param name="toB"></param>
63 /// <param name="result"></param> 63 /// <param name="result"></param>
64 /// <returns></returns> 64 /// <returns></returns>
65 public bool CalcTimeOfImpact(Matrix fromA, Matrix toA, Matrix fromB, Matrix toB, CastResult result) 65 public bool CalcTimeOfImpact(Matrix fromA, Matrix toA, Matrix fromB, Matrix toB, CastResult result)
66 { 66 {
67 MinkowskiSumShape convex = new MinkowskiSumShape(_convexA, _convexB); 67 MinkowskiSumShape convex = new MinkowskiSumShape(_convexA, _convexB);
68 68
69 Matrix rayFromLocalA; 69 Matrix rayFromLocalA;
70 Matrix rayToLocalA; 70 Matrix rayToLocalA;
71 71
72 rayFromLocalA = MathHelper.InvertMatrix(fromA) * fromB; 72 rayFromLocalA = MathHelper.InvertMatrix(fromA) * fromB;
73 rayToLocalA = MathHelper.InvertMatrix(toA) * toB; 73 rayToLocalA = MathHelper.InvertMatrix(toA) * toB;
74 74
75 _simplexSolver.Reset(); 75 _simplexSolver.Reset();
76 76
77 convex.TransformB = rayFromLocalA; 77 convex.TransformB = rayFromLocalA;
78 78
79 float lambda = 0; 79 float lambda = 0;
80 //todo: need to verify this: 80 //todo: need to verify this:
81 //because of minkowski difference, we need the inverse direction 81 //because of minkowski difference, we need the inverse direction
82 82
83 Vector3 s = -rayFromLocalA.Translation; 83 Vector3 s = -rayFromLocalA.Translation;
84 Vector3 r = -(rayToLocalA.Translation - rayFromLocalA.Translation); 84 Vector3 r = -(rayToLocalA.Translation - rayFromLocalA.Translation);
85 Vector3 x = s; 85 Vector3 x = s;
86 Vector3 v; 86 Vector3 v;
87 Vector3 arbitraryPoint = convex.LocalGetSupportingVertex(r); 87 Vector3 arbitraryPoint = convex.LocalGetSupportingVertex(r);
88 88
89 v = x - arbitraryPoint; 89 v = x - arbitraryPoint;
90 90
91 int maxIter = MaxIterations; 91 int maxIter = MaxIterations;
92 92
93 Vector3 n = new Vector3(); 93 Vector3 n = new Vector3();
94 float lastLambda = lambda; 94 float lastLambda = lambda;
95 95
96 float dist2 = v.LengthSquared(); 96 float dist2 = v.LengthSquared();
97 float epsilon = 0.0001f; 97 float epsilon = 0.0001f;
98 98
99 Vector3 w, p; 99 Vector3 w, p;
100 float VdotR; 100 float VdotR;
101 101
102 while ((dist2 > epsilon) && (maxIter-- != 0)) 102 while ((dist2 > epsilon) && (maxIter-- != 0))
103 { 103 {
104 p = convex.LocalGetSupportingVertex(v); 104 p = convex.LocalGetSupportingVertex(v);
105 w = x - p; 105 w = x - p;
106 106
107 float VdotW = Vector3.Dot(v, w); 107 float VdotW = Vector3.Dot(v, w);
108 108
109 if (VdotW > 0) 109 if (VdotW > 0)
110 { 110 {
111 VdotR = Vector3.Dot(v, r); 111 VdotR = Vector3.Dot(v, r);
112 112
113 if (VdotR >= -(MathHelper.Epsilon * MathHelper.Epsilon)) 113 if (VdotR >= -(MathHelper.Epsilon * MathHelper.Epsilon))
114 return false; 114 return false;
115 else 115 else
116 { 116 {
117 lambda = lambda - VdotW / VdotR; 117 lambda = lambda - VdotW / VdotR;
118 x = s + lambda * r; 118 x = s + lambda * r;
119 _simplexSolver.Reset(); 119 _simplexSolver.Reset();
120 //check next line 120 //check next line
121 w = x - p; 121 w = x - p;
122 lastLambda = lambda; 122 lastLambda = lambda;
123 n = v; 123 n = v;
124 } 124 }
125 } 125 }
126 _simplexSolver.AddVertex(w, x, p); 126 _simplexSolver.AddVertex(w, x, p);
127 if (_simplexSolver.Closest(out v)) 127 if (_simplexSolver.Closest(out v))
128 { 128 {
129 dist2 = v.LengthSquared(); 129 dist2 = v.LengthSquared();
130 } 130 }
131 else 131 else
132 { 132 {
133 dist2 = 0f; 133 dist2 = 0f;
134 } 134 }
135 } 135 }
136 result.Fraction = lambda; 136 result.Fraction = lambda;
137 result.Normal = n; 137 result.Normal = n;
138 return true; 138 return true;
139 } 139 }
140 #endregion 140 #endregion
141 } 141 }
142} 142}
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/TriangleRaycastCallback.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/TriangleRaycastCallback.cs
index c127460..1e0fb3b 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/TriangleRaycastCallback.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/TriangleRaycastCallback.cs
@@ -1,115 +1,115 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 public abstract class TriangleRaycastCallback : ITriangleCallback 29 public abstract class TriangleRaycastCallback : ITriangleCallback
30 { 30 {
31 private Vector3 _from; 31 private Vector3 _from;
32 private Vector3 _to; 32 private Vector3 _to;
33 private float _hitFraction; 33 private float _hitFraction;
34 34
35 public TriangleRaycastCallback(Vector3 from, Vector3 to) 35 public TriangleRaycastCallback(Vector3 from, Vector3 to)
36 { 36 {
37 _from = from; 37 _from = from;
38 _to = to; 38 _to = to;
39 _hitFraction = 1; 39 _hitFraction = 1;
40 } 40 }
41 41
42 public Vector3 From { get { return _from; } set { _from = value; } } 42 public Vector3 From { get { return _from; } set { _from = value; } }
43 public Vector3 To { get { return _to; } set { _to = value; } } 43 public Vector3 To { get { return _to; } set { _to = value; } }
44 public float HitFraction { get { return _hitFraction; } set { _hitFraction = value; } } 44 public float HitFraction { get { return _hitFraction; } set { _hitFraction = value; } }
45 45
46 public abstract float ReportHit(Vector3 hitNormalLocal, float hitFraction, int partId, int triangleIndex); 46 public abstract float ReportHit(Vector3 hitNormalLocal, float hitFraction, int partId, int triangleIndex);
47 47
48 #region ITriangleCallback Members 48 #region ITriangleCallback Members
49 49
50 public void ProcessTriangle(Vector3[] triangle, int partID, int triangleIndex) 50 public void ProcessTriangle(Vector3[] triangle, int partID, int triangleIndex)
51 { 51 {
52 Vector3 vertA = triangle[0]; 52 Vector3 vertA = triangle[0];
53 Vector3 vertB = triangle[1]; 53 Vector3 vertB = triangle[1];
54 Vector3 vertC = triangle[2]; 54 Vector3 vertC = triangle[2];
55 55
56 Vector3 vBA = vertB - vertA; 56 Vector3 vBA = vertB - vertA;
57 Vector3 vCA = vertC - vertA; 57 Vector3 vCA = vertC - vertA;
58 58
59 Vector3 triangleNormal = Vector3.Cross(vBA, vCA); 59 Vector3 triangleNormal = Vector3.Cross(vBA, vCA);
60 60
61 float dist = Vector3.Dot(vertA, triangleNormal); 61 float dist = Vector3.Dot(vertA, triangleNormal);
62 float distA = Vector3.Dot(triangleNormal, _from); 62 float distA = Vector3.Dot(triangleNormal, _from);
63 distA -= dist; 63 distA -= dist;
64 float distB = Vector3.Dot(triangleNormal, _to); 64 float distB = Vector3.Dot(triangleNormal, _to);
65 distB -= dist; 65 distB -= dist;
66 66
67 if (distA * distB >= 0.0f) 67 if (distA * distB >= 0.0f)
68 { 68 {
69 return; // same sign 69 return; // same sign
70 } 70 }
71 71
72 float projLength = distA - distB; 72 float projLength = distA - distB;
73 float distance = (distA) / (projLength); 73 float distance = (distA) / (projLength);
74 // Now we have the intersection point on the plane, we'll see if it's inside the triangle 74 // Now we have the intersection point on the plane, we'll see if it's inside the triangle
75 // Add an epsilon as a tolerance for the raycast, 75 // Add an epsilon as a tolerance for the raycast,
76 // in case the ray hits exacly on the edge of the triangle. 76 // in case the ray hits exacly on the edge of the triangle.
77 // It must be scaled for the triangle size. 77 // It must be scaled for the triangle size.
78 78
79 if (distance < _hitFraction) 79 if (distance < _hitFraction)
80 { 80 {
81 float edgeTolerance = triangleNormal.LengthSquared(); 81 float edgeTolerance = triangleNormal.LengthSquared();
82 edgeTolerance *= -0.0001f; 82 edgeTolerance *= -0.0001f;
83 Vector3 point = new Vector3(); 83 Vector3 point = new Vector3();
84 MathHelper.SetInterpolate3(_from, _to, distance, ref point); 84 MathHelper.SetInterpolate3(_from, _to, distance, ref point);
85 85
86 Vector3 vertexAPoint = vertA - point; 86 Vector3 vertexAPoint = vertA - point;
87 Vector3 vertexBPoint = vertB - point; 87 Vector3 vertexBPoint = vertB - point;
88 Vector3 contactPointA = Vector3.Cross(vertexAPoint, vertexBPoint); 88 Vector3 contactPointA = Vector3.Cross(vertexAPoint, vertexBPoint);
89 89
90 if (Vector3.Dot(contactPointA, triangleNormal) >= edgeTolerance) 90 if (Vector3.Dot(contactPointA, triangleNormal) >= edgeTolerance)
91 { 91 {
92 Vector3 vertexCPoint = vertC - point; 92 Vector3 vertexCPoint = vertC - point;
93 Vector3 contactPointB = Vector3.Cross(vertexBPoint, vertexCPoint); 93 Vector3 contactPointB = Vector3.Cross(vertexBPoint, vertexCPoint);
94 if (Vector3.Dot(contactPointB, triangleNormal) >= edgeTolerance) 94 if (Vector3.Dot(contactPointB, triangleNormal) >= edgeTolerance)
95 { 95 {
96 Vector3 contactPointC = Vector3.Cross(vertexCPoint, vertexAPoint); 96 Vector3 contactPointC = Vector3.Cross(vertexCPoint, vertexAPoint);
97 97
98 if (Vector3.Dot(contactPointC, triangleNormal) >= edgeTolerance) 98 if (Vector3.Dot(contactPointC, triangleNormal) >= edgeTolerance)
99 { 99 {
100 if (distA > 0) 100 if (distA > 0)
101 { 101 {
102 _hitFraction = ReportHit(triangleNormal, distance, partID, triangleIndex); 102 _hitFraction = ReportHit(triangleNormal, distance, partID, triangleIndex);
103 } 103 }
104 else 104 else
105 { 105 {
106 _hitFraction = ReportHit(-triangleNormal, distance, partID, triangleIndex); 106 _hitFraction = ReportHit(-triangleNormal, distance, partID, triangleIndex);
107 } 107 }
108 } 108 }
109 } 109 }
110 } 110 }
111 } 111 }
112 } 112 }
113 #endregion 113 #endregion
114 } 114 }
115} 115}
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/VoronoiSimplexSolver.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/VoronoiSimplexSolver.cs
index 16f3dab..1bc94d3 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/VoronoiSimplexSolver.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/NarrowPhaseCollision/VoronoiSimplexSolver.cs
@@ -1,643 +1,643 @@
1/* 1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru 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 3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4 4
5 This software is provided 'as-is', without any express or implied 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 6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software. 7 arising from the use of this software.
8 8
9 Permission is granted to anyone to use this software for any purpose, 9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it 10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions: 11 freely, subject to the following restrictions:
12 12
13 1. The origin of this software must not be misrepresented; you must not 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 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 15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required. 16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be 17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software. 18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution. 19 3. This notice may not be removed or altered from any source distribution.
20*/ 20*/
21 21
22using System; 22using System;
23using System.Collections.Generic; 23using System.Collections.Generic;
24using System.Text; 24using System.Text;
25using MonoXnaCompactMaths; 25using MonoXnaCompactMaths;
26 26
27namespace XnaDevRu.BulletX 27namespace XnaDevRu.BulletX
28{ 28{
29 public class UsageBitfield 29 public class UsageBitfield
30 { 30 {
31 private bool _usedVertexA, _usedVertexB, _usedVertexC, _usedVertexD; 31 private bool _usedVertexA, _usedVertexB, _usedVertexC, _usedVertexD;
32 32
33 public bool UsedVertexA { get { return _usedVertexA; } set { _usedVertexA = value; } } 33 public bool UsedVertexA { get { return _usedVertexA; } set { _usedVertexA = value; } }
34 public bool UsedVertexB { get { return _usedVertexB; } set { _usedVertexB = value; } } 34 public bool UsedVertexB { get { return _usedVertexB; } set { _usedVertexB = value; } }
35 public bool UsedVertexC { get { return _usedVertexC; } set { _usedVertexC = value; } } 35 public bool UsedVertexC { get { return _usedVertexC; } set { _usedVertexC = value; } }
36 public bool UsedVertexD { get { return _usedVertexD; } set { _usedVertexD = value; } } 36 public bool UsedVertexD { get { return _usedVertexD; } set { _usedVertexD = value; } }
37 37
38 public void Reset() 38 public void Reset()
39 { 39 {
40 _usedVertexA = _usedVertexB = _usedVertexC = _usedVertexD = false; 40 _usedVertexA = _usedVertexB = _usedVertexC = _usedVertexD = false;
41 } 41 }
42 } 42 }
43 43
44 public class SubSimplexClosestResult 44 public class SubSimplexClosestResult
45 { 45 {
46 private Vector3 _closestPointOnSimplex; 46 private Vector3 _closestPointOnSimplex;
47 47
48 //MASK for m_usedVertices 48 //MASK for m_usedVertices
49 //stores the simplex vertex-usage, using the MASK, 49 //stores the simplex vertex-usage, using the MASK,
50 // if m_usedVertices & MASK then the related vertex is used 50 // if m_usedVertices & MASK then the related vertex is used
51 private UsageBitfield _usedVertices = new UsageBitfield(); 51 private UsageBitfield _usedVertices = new UsageBitfield();
52 private float[] _barycentricCoords = new float[4]; 52 private float[] _barycentricCoords = new float[4];
53 private bool _degenerate; 53 private bool _degenerate;
54 54
55 public Vector3 ClosestPointOnSimplex { get { return _closestPointOnSimplex; } set { _closestPointOnSimplex = value; } } 55 public Vector3 ClosestPointOnSimplex { get { return _closestPointOnSimplex; } set { _closestPointOnSimplex = value; } }
56 public UsageBitfield UsedVertices { get { return _usedVertices; } set { _usedVertices = value; } } 56 public UsageBitfield UsedVertices { get { return _usedVertices; } set { _usedVertices = value; } }
57 public float[] BarycentricCoords { get { return _barycentricCoords; } set { _barycentricCoords = value; } } 57 public float[] BarycentricCoords { get { return _barycentricCoords; } set { _barycentricCoords = value; } }
58 public bool Degenerate { get { return _degenerate; } set { _degenerate = value; } } 58 public bool Degenerate { get { return _degenerate; } set { _degenerate = value; } }
59 59
60 public void Reset() 60 public void Reset()
61 { 61 {
62 _degenerate = false; 62 _degenerate = false;
63 SetBarycentricCoordinates(); 63 SetBarycentricCoordinates();
64 _usedVertices.Reset(); 64 _usedVertices.Reset();
65 } 65 }
66 66
67 public bool IsValid 67 public bool IsValid
68 { 68 {
69 get 69 get
70 { 70 {
71 return (_barycentricCoords[0] >= 0f) && 71 return (_barycentricCoords[0] >= 0f) &&
72 (_barycentricCoords[1] >= 0f) && 72 (_barycentricCoords[1] >= 0f) &&
73 (_barycentricCoords[2] >= 0f) && 73 (_barycentricCoords[2] >= 0f) &&
74 (_barycentricCoords[3] >= 0f); 74 (_barycentricCoords[3] >= 0f);
75 } 75 }
76 } 76 }
77 77
78 public void SetBarycentricCoordinates() 78 public void SetBarycentricCoordinates()
79 { 79 {
80 SetBarycentricCoordinates(0f, 0f, 0f, 0f); 80 SetBarycentricCoordinates(0f, 0f, 0f, 0f);
81 } 81 }
82 82
83 public void SetBarycentricCoordinates(float a, float b, float c, float d) 83 public void SetBarycentricCoordinates(float a, float b, float c, float d)
84 { 84 {
85 _barycentricCoords[0] = a; 85 _barycentricCoords[0] = a;
86 _barycentricCoords[1] = b; 86 _barycentricCoords[1] = b;
87 _barycentricCoords[2] = c; 87 _barycentricCoords[2] = c;
88 _barycentricCoords[3] = d; 88 _barycentricCoords[3] = d;
89 } 89 }
90 } 90 }
91 91
92 /// VoronoiSimplexSolver is an implementation of the closest point distance 92 /// VoronoiSimplexSolver is an implementation of the closest point distance
93 /// algorithm from a 1-4 points simplex to the origin. 93 /// algorithm from a 1-4 points simplex to the origin.
94 /// Can be used with GJK, as an alternative to Johnson distance algorithm. 94 /// Can be used with GJK, as an alternative to Johnson distance algorithm.
95 public class VoronoiSimplexSolver : ISimplexSolver 95 public class VoronoiSimplexSolver : ISimplexSolver
96 { 96 {
97 private const int VertexA = 0, VertexB = 1, VertexC = 2, VertexD = 3; 97 private const int VertexA = 0, VertexB = 1, VertexC = 2, VertexD = 3;
98 98
99 private const int VoronoiSimplexMaxVerts = 5; 99 private const int VoronoiSimplexMaxVerts = 5;
100 private const bool CatchDegenerateTetrahedron = true; 100 private const bool CatchDegenerateTetrahedron = true;
101 101
102 private int _numVertices; 102 private int _numVertices;
103 103
104 private Vector3[] _simplexVectorW = new Vector3[VoronoiSimplexMaxVerts]; 104 private Vector3[] _simplexVectorW = new Vector3[VoronoiSimplexMaxVerts];
105 private Vector3[] _simplexPointsP = new Vector3[VoronoiSimplexMaxVerts]; 105 private Vector3[] _simplexPointsP = new Vector3[VoronoiSimplexMaxVerts];
106 private Vector3[] _simplexPointsQ = new Vector3[VoronoiSimplexMaxVerts]; 106 private Vector3[] _simplexPointsQ = new Vector3[VoronoiSimplexMaxVerts];
107 107
108 private Vector3 _cachedPA; 108 private Vector3 _cachedPA;
109 private Vector3 _cachedPB; 109 private Vector3 _cachedPB;
110 private Vector3 _cachedV; 110 private Vector3 _cachedV;
111 private Vector3 _lastW; 111 private Vector3 _lastW;
112 private bool _cachedValidClosest; 112 private bool _cachedValidClosest;
113 113
114 private SubSimplexClosestResult _cachedBC = new SubSimplexClosestResult(); 114 private SubSimplexClosestResult _cachedBC = new SubSimplexClosestResult();
115 115
116 private bool _needsUpdate; 116 private bool _needsUpdate;
117 117
118 #region ISimplexSolver Members 118 #region ISimplexSolver Members
119 119
120 public bool FullSimplex 120 public bool FullSimplex
121 { 121 {
122 get 122 get
123 { 123 {
124 return _numVertices == 4; 124 return _numVertices == 4;
125 } 125 }
126 } 126 }
127 127
128 public int NumVertices 128 public int NumVertices
129 { 129 {
130 get 130 get
131 { 131 {
132 return _numVertices; 132 return _numVertices;
133 } 133 }
134 } 134 }
135 135
136 public void Reset() 136 public void Reset()
137 { 137 {
138 _cachedValidClosest = false; 138 _cachedValidClosest = false;
139 _numVertices = 0; 139 _numVertices = 0;
140 _needsUpdate = true; 140 _needsUpdate = true;
141 _lastW = new Vector3(1e30f, 1e30f, 1e30f); 141 _lastW = new Vector3(1e30f, 1e30f, 1e30f);
142 _cachedBC.Reset(); 142 _cachedBC.Reset();
143 } 143 }
144 144
145 public void AddVertex(Vector3 w, Vector3 p, Vector3 q) 145 public void AddVertex(Vector3 w, Vector3 p, Vector3 q)
146 { 146 {
147 _lastW = w; 147 _lastW = w;
148 _needsUpdate = true; 148 _needsUpdate = true;
149 149
150 _simplexVectorW[_numVertices] = w; 150 _simplexVectorW[_numVertices] = w;
151 _simplexPointsP[_numVertices] = p; 151 _simplexPointsP[_numVertices] = p;
152 _simplexPointsQ[_numVertices] = q; 152 _simplexPointsQ[_numVertices] = q;
153 153
154 _numVertices++; 154 _numVertices++;
155 } 155 }
156 156
157 //return/calculate the closest vertex 157 //return/calculate the closest vertex
158 public bool Closest(out Vector3 v) 158 public bool Closest(out Vector3 v)
159 { 159 {
160 bool succes = UpdateClosestVectorAndPoints(); 160 bool succes = UpdateClosestVectorAndPoints();
161 v = _cachedV; 161 v = _cachedV;
162 return succes; 162 return succes;
163 } 163 }
164 164
165 public float MaxVertex 165 public float MaxVertex
166 { 166 {
167 get 167 get
168 { 168 {
169 int numverts = NumVertices; 169 int numverts = NumVertices;
170 float maxV = 0f, curLen2; 170 float maxV = 0f, curLen2;
171 for (int i = 0; i < numverts; i++) 171 for (int i = 0; i < numverts; i++)
172 { 172 {
173 curLen2 = _simplexVectorW[i].LengthSquared(); 173 curLen2 = _simplexVectorW[i].LengthSquared();
174 if (maxV < curLen2) maxV = curLen2; 174 if (maxV < curLen2) maxV = curLen2;
175 } 175 }
176 return maxV; 176 return maxV;
177 } 177 }
178 } 178 }
179 179
180 //return the current simplex 180 //return the current simplex
181 public int GetSimplex(out Vector3[] pBuf, out Vector3[] qBuf, out Vector3[] yBuf) 181 public int GetSimplex(out Vector3[] pBuf, out Vector3[] qBuf, out Vector3[] yBuf)
182 { 182 {
183 int numverts = NumVertices; 183 int numverts = NumVertices;
184 pBuf = new Vector3[numverts]; 184 pBuf = new Vector3[numverts];
185 qBuf = new Vector3[numverts]; 185 qBuf = new Vector3[numverts];
186 yBuf = new Vector3[numverts]; 186 yBuf = new Vector3[numverts];
187 for (int i = 0; i < numverts; i++) 187 for (int i = 0; i < numverts; i++)
188 { 188 {
189 yBuf[i] = _simplexVectorW[i]; 189 yBuf[i] = _simplexVectorW[i];
190 pBuf[i] = _simplexPointsP[i]; 190 pBuf[i] = _simplexPointsP[i];
191 qBuf[i] = _simplexPointsQ[i]; 191 qBuf[i] = _simplexPointsQ[i];
192 } 192 }
193 return numverts; 193 return numverts;
194 } 194 }
195 195
196 public bool InSimplex(Vector3 w) 196 public bool InSimplex(Vector3 w)
197 { 197 {
198 //check in case lastW is already removed 198 //check in case lastW is already removed
199 if (w == _lastW) return true; 199 if (w == _lastW) return true;
200 200
201 //w is in the current (reduced) simplex 201 //w is in the current (reduced) simplex
202 int numverts = NumVertices; 202 int numverts = NumVertices;
203 for (int i = 0; i < numverts; i++) 203 for (int i = 0; i < numverts; i++)
204 if (_simplexVectorW[i] == w) return true; 204 if (_simplexVectorW[i] == w) return true;
205 205
206 return false; 206 return false;
207 } 207 }
208 208
209 public void BackupClosest(out Vector3 v) 209 public void BackupClosest(out Vector3 v)
210 { 210 {
211 v = _cachedV; 211 v = _cachedV;
212 } 212 }
213 213
214 public bool EmptySimplex 214 public bool EmptySimplex
215 { 215 {
216 get 216 get
217 { 217 {
218 return NumVertices == 0; 218 return NumVertices == 0;
219 } 219 }
220 } 220 }
221 221
222 public void ComputePoints(out Vector3 p1, out Vector3 p2) 222 public void ComputePoints(out Vector3 p1, out Vector3 p2)
223 { 223 {
224 UpdateClosestVectorAndPoints(); 224 UpdateClosestVectorAndPoints();
225 p1 = _cachedPA; 225 p1 = _cachedPA;
226 p2 = _cachedPB; 226 p2 = _cachedPB;
227 } 227 }
228 228
229 #endregion 229 #endregion
230 230
231 public void RemoveVertex(int index) 231 public void RemoveVertex(int index)
232 { 232 {
233 BulletDebug.Assert(_numVertices > 0); 233 BulletDebug.Assert(_numVertices > 0);
234 _numVertices--; 234 _numVertices--;
235 _simplexVectorW[index] = _simplexVectorW[_numVertices]; 235 _simplexVectorW[index] = _simplexVectorW[_numVertices];
236 _simplexPointsP[index] = _simplexPointsP[_numVertices]; 236 _simplexPointsP[index] = _simplexPointsP[_numVertices];
237 _simplexPointsQ[index] = _simplexPointsQ[_numVertices]; 237 _simplexPointsQ[index] = _simplexPointsQ[_numVertices];
238 } 238 }
239 239
240 public void ReduceVertices(UsageBitfield usedVerts) 240 public void ReduceVertices(UsageBitfield usedVerts)
241 { 241 {
242 if ((NumVertices >= 4) && (!usedVerts.UsedVertexD)) RemoveVertex(3); 242 if ((NumVertices >= 4) && (!usedVerts.UsedVertexD)) RemoveVertex(3);
243 if ((NumVertices >= 3) && (!usedVerts.UsedVertexC)) RemoveVertex(2); 243 if ((NumVertices >= 3) && (!usedVerts.UsedVertexC)) RemoveVertex(2);
244 if ((NumVertices >= 2) && (!usedVerts.UsedVertexB)) RemoveVertex(1); 244 if ((NumVertices >= 2) && (!usedVerts.UsedVertexB)) RemoveVertex(1);
245 if ((NumVertices >= 1) && (!usedVerts.UsedVertexA)) RemoveVertex(0); 245 if ((NumVertices >= 1) && (!usedVerts.UsedVertexA)) RemoveVertex(0);
246 } 246 }
247 247
248 public bool UpdateClosestVectorAndPoints() 248 public bool UpdateClosestVectorAndPoints()
249 { 249 {
250 if (_needsUpdate) 250 if (_needsUpdate)
251 { 251 {
252 _cachedBC.Reset(); 252 _cachedBC.Reset();
253 _needsUpdate = false; 253 _needsUpdate = false;
254 254
255 Vector3 p, a, b, c, d; 255 Vector3 p, a, b, c, d;
256 switch (NumVertices) 256 switch (NumVertices)
257 { 257 {
258 case 0: 258 case 0:
259 _cachedValidClosest = false; 259 _cachedValidClosest = false;
260 break; 260 break;
261 case 1: 261 case 1:
262 _cachedPA = _simplexPointsP[0]; 262 _cachedPA = _simplexPointsP[0];
263 _cachedPB = _simplexPointsQ[0]; 263 _cachedPB = _simplexPointsQ[0];
264 _cachedV = _cachedPA - _cachedPB; 264 _cachedV = _cachedPA - _cachedPB;
265 _cachedBC.Reset(); 265 _cachedBC.Reset();
266 _cachedBC.SetBarycentricCoordinates(1f, 0f, 0f, 0f); 266 _cachedBC.SetBarycentricCoordinates(1f, 0f, 0f, 0f);
267 _cachedValidClosest = _cachedBC.IsValid; 267 _cachedValidClosest = _cachedBC.IsValid;
268 break; 268 break;
269 case 2: 269 case 2:
270 //closest point origin from line segment 270 //closest point origin from line segment
271 Vector3 from = _simplexVectorW[0]; 271 Vector3 from = _simplexVectorW[0];
272 Vector3 to = _simplexVectorW[1]; 272 Vector3 to = _simplexVectorW[1];
273 Vector3 nearest; 273 Vector3 nearest;
274 274
275 Vector3 diff = -from; 275 Vector3 diff = -from;
276 Vector3 v = to - from; 276 Vector3 v = to - from;
277 float t = Vector3.Dot(v, diff); 277 float t = Vector3.Dot(v, diff);
278 278
279 if (t > 0) 279 if (t > 0)
280 { 280 {
281 float dotVV = v.LengthSquared(); 281 float dotVV = v.LengthSquared();
282 if (t < dotVV) 282 if (t < dotVV)
283 { 283 {
284 t /= dotVV; 284 t /= dotVV;
285 diff -= t * v; 285 diff -= t * v;
286 _cachedBC.UsedVertices.UsedVertexA = true; 286 _cachedBC.UsedVertices.UsedVertexA = true;
287 _cachedBC.UsedVertices.UsedVertexB = true; 287 _cachedBC.UsedVertices.UsedVertexB = true;
288 } 288 }
289 else 289 else
290 { 290 {
291 t = 1; 291 t = 1;
292 diff -= v; 292 diff -= v;
293 //reduce to 1 point 293 //reduce to 1 point
294 _cachedBC.UsedVertices.UsedVertexB = true; 294 _cachedBC.UsedVertices.UsedVertexB = true;
295 } 295 }
296 } 296 }
297 else 297 else
298 { 298 {
299 t = 0; 299 t = 0;
300 //reduce to 1 point 300 //reduce to 1 point
301 _cachedBC.UsedVertices.UsedVertexA = true; 301 _cachedBC.UsedVertices.UsedVertexA = true;
302 } 302 }
303 303
304 _cachedBC.SetBarycentricCoordinates(1 - t, t, 0, 0); 304 _cachedBC.SetBarycentricCoordinates(1 - t, t, 0, 0);
305 nearest = from + t * v; 305 nearest = from + t * v;
306 306
307 _cachedPA = _simplexPointsP[0] + t * (_simplexPointsP[1] - _simplexPointsP[0]); 307 _cachedPA = _simplexPointsP[0] + t * (_simplexPointsP[1] - _simplexPointsP[0]);
308 _cachedPB = _simplexPointsQ[0] + t * (_simplexPointsQ[1] - _simplexPointsQ[0]); 308 _cachedPB = _simplexPointsQ[0] + t * (_simplexPointsQ[1] - _simplexPointsQ[0]);
309 _cachedV = _cachedPA - _cachedPB; 309 _cachedV = _cachedPA - _cachedPB;
310 310
311 ReduceVertices(_cachedBC.UsedVertices); 311 ReduceVertices(_cachedBC.UsedVertices);
312 312
313 _cachedValidClosest = _cachedBC.IsValid; 313 _cachedValidClosest = _cachedBC.IsValid;
314 break; 314 break;
315 case 3: 315 case 3:
316 //closest point origin from triangle 316 //closest point origin from triangle
317 p = new Vector3(); 317 p = new Vector3();
318 a = _simplexVectorW[0]; 318 a = _simplexVectorW[0];
319 b = _simplexVectorW[1]; 319 b = _simplexVectorW[1];
320 c = _simplexVectorW[2]; 320 c = _simplexVectorW[2];
321 321
322 ClosestPtPointTriangle(p, a, b, c, ref _cachedBC); 322 ClosestPtPointTriangle(p, a, b, c, ref _cachedBC);
323 _cachedPA = _simplexPointsP[0] * _cachedBC.BarycentricCoords[0] + 323 _cachedPA = _simplexPointsP[0] * _cachedBC.BarycentricCoords[0] +
324 _simplexPointsP[1] * _cachedBC.BarycentricCoords[1] + 324 _simplexPointsP[1] * _cachedBC.BarycentricCoords[1] +
325 _simplexPointsP[2] * _cachedBC.BarycentricCoords[2] + 325 _simplexPointsP[2] * _cachedBC.BarycentricCoords[2] +
326 _simplexPointsP[3] * _cachedBC.BarycentricCoords[3]; 326 _simplexPointsP[3] * _cachedBC.BarycentricCoords[3];
327 327
328 _cachedPB = _simplexPointsQ[0] * _cachedBC.BarycentricCoords[0] + 328 _cachedPB = _simplexPointsQ[0] * _cachedBC.BarycentricCoords[0] +
329 _simplexPointsQ[1] * _cachedBC.BarycentricCoords[1] + 329 _simplexPointsQ[1] * _cachedBC.BarycentricCoords[1] +
330 _simplexPointsQ[2] * _cachedBC.BarycentricCoords[2] + 330 _simplexPointsQ[2] * _cachedBC.BarycentricCoords[2] +
331 _simplexPointsQ[3] * _cachedBC.BarycentricCoords[3]; 331 _simplexPointsQ[3] * _cachedBC.BarycentricCoords[3];
332 332
333 _cachedV = _cachedPA - _cachedPB; 333 _cachedV = _cachedPA - _cachedPB;
334 334
335 ReduceVertices(_cachedBC.UsedVertices); 335 ReduceVertices(_cachedBC.UsedVertices);
336 _cachedValidClosest = _cachedBC.IsValid; 336 _cachedValidClosest = _cachedBC.IsValid;
337 break; 337 break;
338 case 4: 338 case 4:
339 p = new Vector3(); 339 p = new Vector3();
340 a = _simplexVectorW[0]; 340 a = _simplexVectorW[0];
341 b = _simplexVectorW[1]; 341 b = _simplexVectorW[1];
342 c = _simplexVectorW[2]; 342 c = _simplexVectorW[2];
343 d = _simplexVectorW[3]; 343 d = _simplexVectorW[3];
344 344
345 bool hasSeperation = ClosestPtPointTetrahedron(p, a, b, c, d, ref _cachedBC); 345 bool hasSeperation = ClosestPtPointTetrahedron(p, a, b, c, d, ref _cachedBC);
346 346
347 if (hasSeperation) 347 if (hasSeperation)
348 { 348 {
349 _cachedPA = _simplexPointsP[0] * _cachedBC.BarycentricCoords[0] + 349 _cachedPA = _simplexPointsP[0] * _cachedBC.BarycentricCoords[0] +
350 _simplexPointsP[1] * _cachedBC.BarycentricCoords[1] + 350 _simplexPointsP[1] * _cachedBC.BarycentricCoords[1] +
351 _simplexPointsP[2] * _cachedBC.BarycentricCoords[2] + 351 _simplexPointsP[2] * _cachedBC.BarycentricCoords[2] +
352 _simplexPointsP[3] * _cachedBC.BarycentricCoords[3]; 352 _simplexPointsP[3] * _cachedBC.BarycentricCoords[3];
353 353
354 _cachedPB = _simplexPointsQ[0] * _cachedBC.BarycentricCoords[0] + 354 _cachedPB = _simplexPointsQ[0] * _cachedBC.BarycentricCoords[0] +
355 _simplexPointsQ[1] * _cachedBC.BarycentricCoords[1] + 355 _simplexPointsQ[1] * _cachedBC.BarycentricCoords[1] +
356 _simplexPointsQ[2] * _cachedBC.BarycentricCoords[2] + 356 _simplexPointsQ[2] * _cachedBC.BarycentricCoords[2] +
357 _simplexPointsQ[3] * _cachedBC.BarycentricCoords[3]; 357 _simplexPointsQ[3] * _cachedBC.BarycentricCoords[3];
358 358
359 _cachedV = _cachedPA - _cachedPB; 359 _cachedV = _cachedPA - _cachedPB;
360 ReduceVertices(_cachedBC.UsedVertices); 360 ReduceVertices(_cachedBC.UsedVertices);
361 } 361 }
362 else 362 else
363 { 363 {
364 if (_cachedBC.Degenerate) 364 if (_cachedBC.Degenerate)
365 { 365 {
366 _cachedValidClosest = false; 366 _cachedValidClosest = false;
367 } 367 }
368 else 368 else
369 { 369 {
370 _cachedValidClosest = true; 370 _cachedValidClosest = true;
371 //degenerate case == false, penetration = true + zero 371 //degenerate case == false, penetration = true + zero
372 _cachedV.X = _cachedV.Y = _cachedV.Z = 0f; 372 _cachedV.X = _cachedV.Y = _cachedV.Z = 0f;
373 } 373 }
374 break; // !!!!!!!!!!!! proverit na vsakiy sluchai 374 break; // !!!!!!!!!!!! proverit na vsakiy sluchai
375 } 375 }
376 376
377 _cachedValidClosest = _cachedBC.IsValid; 377 _cachedValidClosest = _cachedBC.IsValid;
378 378
379 //closest point origin from tetrahedron 379 //closest point origin from tetrahedron
380 break; 380 break;
381 default: 381 default:
382 _cachedValidClosest = false; 382 _cachedValidClosest = false;
383 break; 383 break;
384 } 384 }
385 } 385 }
386 386
387 return _cachedValidClosest; 387 return _cachedValidClosest;
388 } 388 }
389 389
390 public bool ClosestPtPointTriangle(Vector3 p, Vector3 a, Vector3 b, Vector3 c, 390 public bool ClosestPtPointTriangle(Vector3 p, Vector3 a, Vector3 b, Vector3 c,
391 ref SubSimplexClosestResult result) 391 ref SubSimplexClosestResult result)
392 { 392 {
393 result.UsedVertices.Reset(); 393 result.UsedVertices.Reset();
394 394
395 float v, w; 395 float v, w;
396 396
397 // Check if P in vertex region outside A 397 // Check if P in vertex region outside A
398 Vector3 ab = b - a; 398 Vector3 ab = b - a;
399 Vector3 ac = c - a; 399 Vector3 ac = c - a;
400 Vector3 ap = p - a; 400 Vector3 ap = p - a;
401 float d1 = Vector3.Dot(ab, ap); 401 float d1 = Vector3.Dot(ab, ap);
402 float d2 = Vector3.Dot(ac, ap); 402 float d2 = Vector3.Dot(ac, ap);
403 if (d1 <= 0f && d2 <= 0f) 403 if (d1 <= 0f && d2 <= 0f)
404 { 404 {
405 result.ClosestPointOnSimplex = a; 405 result.ClosestPointOnSimplex = a;
406 result.UsedVertices.UsedVertexA = true; 406 result.UsedVertices.UsedVertexA = true;
407 result.SetBarycentricCoordinates(1, 0, 0, 0); 407 result.SetBarycentricCoordinates(1, 0, 0, 0);
408 return true; // a; // barycentric coordinates (1,0,0) 408 return true; // a; // barycentric coordinates (1,0,0)
409 } 409 }
410 410
411 // Check if P in vertex region outside B 411 // Check if P in vertex region outside B
412 Vector3 bp = p - b; 412 Vector3 bp = p - b;
413 float d3 = Vector3.Dot(ab, bp); 413 float d3 = Vector3.Dot(ab, bp);
414 float d4 = Vector3.Dot(ac, bp); 414 float d4 = Vector3.Dot(ac, bp);
415 if (d3 >= 0f && d4 <= d3) 415 if (d3 >= 0f && d4 <= d3)
416 { 416 {
417 result.ClosestPointOnSimplex = b; 417 result.ClosestPointOnSimplex = b;
418 result.UsedVertices.UsedVertexB = true; 418 result.UsedVertices.UsedVertexB = true;
419 result.SetBarycentricCoordinates(0, 1, 0, 0); 419 result.SetBarycentricCoordinates(0, 1, 0, 0);
420 420
421 return true; // b; // barycentric coordinates (0,1,0) 421 return true; // b; // barycentric coordinates (0,1,0)
422 } 422 }
423 // Check if P in edge region of AB, if so return projection of P onto AB 423 // Check if P in edge region of AB, if so return projection of P onto AB
424 float vc = d1 * d4 - d3 * d2; 424 float vc = d1 * d4 - d3 * d2;
425 if (vc <= 0f && d1 >= 0f && d3 <= 0f) 425 if (vc <= 0f && d1 >= 0f && d3 <= 0f)
426 { 426 {
427 v = d1 / (d1 - d3); 427 v = d1 / (d1 - d3);
428 result.ClosestPointOnSimplex = a + v * ab; 428 result.ClosestPointOnSimplex = a + v * ab;
429 result.UsedVertices.UsedVertexA = true; 429 result.UsedVertices.UsedVertexA = true;
430 result.UsedVertices.UsedVertexB = true; 430 result.UsedVertices.UsedVertexB = true;
431 result.SetBarycentricCoordinates(1 - v, v, 0, 0); 431 result.SetBarycentricCoordinates(1 - v, v, 0, 0);
432 return true; 432 return true;
433 //return a + v * ab; // barycentric coordinates (1-v,v,0) 433 //return a + v * ab; // barycentric coordinates (1-v,v,0)
434 } 434 }
435 435
436 // Check if P in vertex region outside C 436 // Check if P in vertex region outside C
437 Vector3 cp = p - c; 437 Vector3 cp = p - c;
438 float d5 = Vector3.Dot(ab, cp); 438 float d5 = Vector3.Dot(ab, cp);
439 float d6 = Vector3.Dot(ac, cp); 439 float d6 = Vector3.Dot(ac, cp);
440 if (d6 >= 0f && d5 <= d6) 440 if (d6 >= 0f && d5 <= d6)
441 { 441 {
442 result.ClosestPointOnSimplex = c; 442 result.ClosestPointOnSimplex = c;
443 result.UsedVertices.UsedVertexC = true; 443 result.UsedVertices.UsedVertexC = true;
444 result.SetBarycentricCoordinates(0, 0, 1, 0); 444 result.SetBarycentricCoordinates(0, 0, 1, 0);
445 return true;//c; // barycentric coordinates (0,0,1) 445 return true;//c; // barycentric coordinates (0,0,1)
446 } 446 }
447 447
448 // Check if P in edge region of AC, if so return projection of P onto AC 448 // Check if P in edge region of AC, if so return projection of P onto AC
449 float vb = d5 * d2 - d1 * d6; 449 float vb = d5 * d2 - d1 * d6;
450 if (vb <= 0f && d2 >= 0f && d6 <= 0f) 450 if (vb <= 0f && d2 >= 0f && d6 <= 0f)
451 { 451 {
452 w = d2 / (d2 - d6); 452 w = d2 / (d2 - d6);
453 result.ClosestPointOnSimplex = a + w * ac; 453 result.ClosestPointOnSimplex = a + w * ac;
454 result.UsedVertices.UsedVertexA = true; 454 result.UsedVertices.UsedVertexA = true;
455 result.UsedVertices.UsedVertexC = true; 455 result.UsedVertices.UsedVertexC = true;
456 result.SetBarycentricCoordinates(1 - w, 0, w, 0); 456 result.SetBarycentricCoordinates(1 - w, 0, w, 0);
457 return true; 457 return true;
458 //return a + w * ac; // barycentric coordinates (1-w,0,w) 458 //return a + w * ac; // barycentric coordinates (1-w,0,w)
459 } 459 }
460 460
461 // Check if P in edge region of BC, if so return projection of P onto BC 461 // Check if P in edge region of BC, if so return projection of P onto BC
462 float va = d3 * d6 - d5 * d4; 462 float va = d3 * d6 - d5 * d4;
463 if (va <= 0f && (d4 - d3) >= 0f && (d5 - d6) >= 0f) 463 if (va <= 0f && (d4 - d3) >= 0f && (d5 - d6) >= 0f)
464 { 464 {
465 w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); 465 w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
466 466
467 result.ClosestPointOnSimplex = b + w * (c - b); 467 result.ClosestPointOnSimplex = b + w * (c - b);
468 result.UsedVertices.UsedVertexB = true; 468 result.UsedVertices.UsedVertexB = true;
469 result.UsedVertices.UsedVertexC = true; 469 result.UsedVertices.UsedVertexC = true;
470 result.SetBarycentricCoordinates(0, 1 - w, w, 0); 470 result.SetBarycentricCoordinates(0, 1 - w, w, 0);
471 return true; 471 return true;
472 // return b + w * (c - b); // barycentric coordinates (0,1-w,w) 472 // return b + w * (c - b); // barycentric coordinates (0,1-w,w)
473 } 473 }
474 474
475 // P inside face region. Compute Q through its barycentric coordinates (u,v,w) 475 // P inside face region. Compute Q through its barycentric coordinates (u,v,w)
476 float denom = 1.0f / (va + vb + vc); 476 float denom = 1.0f / (va + vb + vc);
477 v = vb * denom; 477 v = vb * denom;
478 w = vc * denom; 478 w = vc * denom;
479 479
480 result.ClosestPointOnSimplex = a + ab * v + ac * w; 480 result.ClosestPointOnSimplex = a + ab * v + ac * w;
481 result.UsedVertices.UsedVertexA = true; 481 result.UsedVertices.UsedVertexA = true;
482 result.UsedVertices.UsedVertexB = true; 482 result.UsedVertices.UsedVertexB = true;
483 result.UsedVertices.UsedVertexC = true; 483 result.UsedVertices.UsedVertexC = true;
484 result.SetBarycentricCoordinates(1 - v - w, v, w, 0); 484 result.SetBarycentricCoordinates(1 - v - w, v, w, 0);
485 485
486 return true; 486 return true;
487 } 487 }
488 488
489 /// Test if point p and d lie on opposite sides of plane through abc 489 /// Test if point p and d lie on opposite sides of plane through abc
490 public int PointOutsideOfPlane(Vector3 p, Vector3 a, Vector3 b, Vector3 c, Vector3 d) 490 public int PointOutsideOfPlane(Vector3 p, Vector3 a, Vector3 b, Vector3 c, Vector3 d)
491 { 491 {
492 Vector3 normal = Vector3.Cross(b - a, c - a); 492 Vector3 normal = Vector3.Cross(b - a, c - a);
493 493
494 float signp = Vector3.Dot(p - a, normal); // [AP AB AC] 494 float signp = Vector3.Dot(p - a, normal); // [AP AB AC]
495 float signd = Vector3.Dot(d - a, normal); // [AD AB AC] 495 float signd = Vector3.Dot(d - a, normal); // [AD AB AC]
496 496
497 if (CatchDegenerateTetrahedron) 497 if (CatchDegenerateTetrahedron)
498 if (signd * signd < (1e-4f * 1e-4f)) return -1; 498 if (signd * signd < (1e-4f * 1e-4f)) return -1;
499 499
500 // Points on opposite sides if expression signs are opposite 500 // Points on opposite sides if expression signs are opposite
501 return signp * signd < 0f ? 1 : 0; 501 return signp * signd < 0f ? 1 : 0;
502 } 502 }
503 503
504 public bool ClosestPtPointTetrahedron(Vector3 p, Vector3 a, Vector3 b, Vector3 c, Vector3 d, 504 public bool ClosestPtPointTetrahedron(Vector3 p, Vector3 a, Vector3 b, Vector3 c, Vector3 d,
505 ref SubSimplexClosestResult finalResult) 505 ref SubSimplexClosestResult finalResult)
506 { 506 {
507 SubSimplexClosestResult tempResult = new SubSimplexClosestResult(); 507 SubSimplexClosestResult tempResult = new SubSimplexClosestResult();
508 508
509 // Start out assuming point inside all halfspaces, so closest to itself 509 // Start out assuming point inside all halfspaces, so closest to itself
510 finalResult.ClosestPointOnSimplex = p; 510 finalResult.ClosestPointOnSimplex = p;
511 finalResult.UsedVertices.Reset(); 511 finalResult.UsedVertices.Reset();
512 finalResult.UsedVertices.UsedVertexA = true; 512 finalResult.UsedVertices.UsedVertexA = true;
513 finalResult.UsedVertices.UsedVertexB = true; 513 finalResult.UsedVertices.UsedVertexB = true;
514 finalResult.UsedVertices.UsedVertexC = true; 514 finalResult.UsedVertices.UsedVertexC = true;
515 finalResult.UsedVertices.UsedVertexD = true; 515 finalResult.UsedVertices.UsedVertexD = true;
516 516
517 int pointOutsideABC = PointOutsideOfPlane(p, a, b, c, d); 517 int pointOutsideABC = PointOutsideOfPlane(p, a, b, c, d);
518 int pointOutsideACD = PointOutsideOfPlane(p, a, c, d, b); 518 int pointOutsideACD = PointOutsideOfPlane(p, a, c, d, b);
519 int pointOutsideADB = PointOutsideOfPlane(p, a, d, b, c); 519 int pointOutsideADB = PointOutsideOfPlane(p, a, d, b, c);
520 int pointOutsideBDC = PointOutsideOfPlane(p, b, d, c, a); 520 int pointOutsideBDC = PointOutsideOfPlane(p, b, d, c, a);
521 521
522 if (pointOutsideABC < 0 || pointOutsideACD < 0 || pointOutsideADB < 0 || pointOutsideBDC < 0) 522 if (pointOutsideABC < 0 || pointOutsideACD < 0 || pointOutsideADB < 0 || pointOutsideBDC < 0)
523 { 523 {
524 finalResult.Degenerate = true; 524 finalResult.Degenerate = true;
525 return false; 525 return false;
526 } 526 }
527 527
528 if (pointOutsideABC == 0 && pointOutsideACD == 0 && pointOutsideADB == 0 && pointOutsideBDC == 0) 528 if (pointOutsideABC == 0 && pointOutsideACD == 0 && pointOutsideADB == 0 && pointOutsideBDC == 0)
529 return false; 529 return false;
530 530
531 float bestSqDist = float.MaxValue; 531 float bestSqDist = float.MaxValue;
532 // If point outside face abc then compute closest point on abc 532 // If point outside face abc then compute closest point on abc
533 if (pointOutsideABC != 0) 533 if (pointOutsideABC != 0)
534 { 534 {
535 ClosestPtPointTriangle(p, a, b, c, ref tempResult); 535 ClosestPtPointTriangle(p, a, b, c, ref tempResult);
536 Vector3 q = tempResult.ClosestPointOnSimplex; 536 Vector3 q = tempResult.ClosestPointOnSimplex;
537 537
538 float sqDist = ((Vector3)(q - p)).LengthSquared(); 538 float sqDist = ((Vector3)(q - p)).LengthSquared();
539 // Update best closest point if (squared) distance is less than current best 539 // Update best closest point if (squared) distance is less than current best
540 if (sqDist < bestSqDist) 540 if (sqDist < bestSqDist)
541 { 541 {
542 bestSqDist = sqDist; 542 bestSqDist = sqDist;
543 finalResult.ClosestPointOnSimplex = q; 543 finalResult.ClosestPointOnSimplex = q;
544 //convert result bitmask! 544 //convert result bitmask!
545 finalResult.UsedVertices.Reset(); 545 finalResult.UsedVertices.Reset();
546 finalResult.UsedVertices.UsedVertexA = tempResult.UsedVertices.UsedVertexA; 546 finalResult.UsedVertices.UsedVertexA = tempResult.UsedVertices.UsedVertexA;
547 finalResult.UsedVertices.UsedVertexB = tempResult.UsedVertices.UsedVertexB; 547 finalResult.UsedVertices.UsedVertexB = tempResult.UsedVertices.UsedVertexB;
548 finalResult.UsedVertices.UsedVertexC = tempResult.UsedVertices.UsedVertexC; 548 finalResult.UsedVertices.UsedVertexC = tempResult.UsedVertices.UsedVertexC;
549 finalResult.SetBarycentricCoordinates( 549 finalResult.SetBarycentricCoordinates(
550 tempResult.BarycentricCoords[VertexA], 550 tempResult.BarycentricCoords[VertexA],
551 tempResult.BarycentricCoords[VertexB], 551 tempResult.BarycentricCoords[VertexB],
552 tempResult.BarycentricCoords[VertexC], 552 tempResult.BarycentricCoords[VertexC],
553 0); 553 0);
554 } 554 }
555 } 555 }
556 556
557 // Repeat test for face acd 557 // Repeat test for face acd
558 if (pointOutsideACD != 0) 558 if (pointOutsideACD != 0)
559 { 559 {
560 ClosestPtPointTriangle(p, a, c, d, ref tempResult); 560 ClosestPtPointTriangle(p, a, c, d, ref tempResult);
561 Vector3 q = tempResult.ClosestPointOnSimplex; 561 Vector3 q = tempResult.ClosestPointOnSimplex;
562 //convert result bitmask! 562 //convert result bitmask!
563 563
564 float sqDist = ((Vector3)(q - p)).LengthSquared(); 564 float sqDist = ((Vector3)(q - p)).LengthSquared();
565 if (sqDist < bestSqDist) 565 if (sqDist < bestSqDist)
566 { 566 {
567 bestSqDist = sqDist; 567 bestSqDist = sqDist;
568 finalResult.ClosestPointOnSimplex = q; 568 finalResult.ClosestPointOnSimplex = q;
569 finalResult.UsedVertices.Reset(); 569 finalResult.UsedVertices.Reset();
570 finalResult.UsedVertices.UsedVertexA = tempResult.UsedVertices.UsedVertexA; 570 finalResult.UsedVertices.UsedVertexA = tempResult.UsedVertices.UsedVertexA;
571 finalResult.UsedVertices.UsedVertexC = tempResult.UsedVertices.UsedVertexB; 571 finalResult.UsedVertices.UsedVertexC = tempResult.UsedVertices.UsedVertexB;
572 finalResult.UsedVertices.UsedVertexD = tempResult.UsedVertices.UsedVertexC; 572 finalResult.UsedVertices.UsedVertexD = tempResult.UsedVertices.UsedVertexC;
573 finalResult.SetBarycentricCoordinates( 573 finalResult.SetBarycentricCoordinates(
574 tempResult.BarycentricCoords[VertexA], 574 tempResult.BarycentricCoords[VertexA],
575 0, 575 0,
576 tempResult.BarycentricCoords[VertexB], 576 tempResult.BarycentricCoords[VertexB],
577 tempResult.BarycentricCoords[VertexC]); 577 tempResult.BarycentricCoords[VertexC]);
578 } 578 }
579 } 579 }
580 // Repeat test for face adb 580 // Repeat test for face adb
581 581
582 if (pointOutsideADB != 0) 582 if (pointOutsideADB != 0)
583 { 583 {
584 ClosestPtPointTriangle(p, a, d, b, ref tempResult); 584 ClosestPtPointTriangle(p, a, d, b, ref tempResult);
585 Vector3 q = tempResult.ClosestPointOnSimplex; 585 Vector3 q = tempResult.ClosestPointOnSimplex;
586 //convert result bitmask! 586 //convert result bitmask!
587 587
588 float sqDist = ((Vector3)(q - p)).LengthSquared(); 588 float sqDist = ((Vector3)(q - p)).LengthSquared();
589 if (sqDist < bestSqDist) 589 if (sqDist < bestSqDist)
590 { 590 {
591 bestSqDist = sqDist; 591 bestSqDist = sqDist;
592 finalResult.ClosestPointOnSimplex = q; 592 finalResult.ClosestPointOnSimplex = q;
593 finalResult.UsedVertices.Reset(); 593 finalResult.UsedVertices.Reset();
594 finalResult.UsedVertices.UsedVertexA = tempResult.UsedVertices.UsedVertexA; 594 finalResult.UsedVertices.UsedVertexA = tempResult.UsedVertices.UsedVertexA;
595 finalResult.UsedVertices.UsedVertexD = tempResult.UsedVertices.UsedVertexB; 595 finalResult.UsedVertices.UsedVertexD = tempResult.UsedVertices.UsedVertexB;
596 finalResult.UsedVertices.UsedVertexB = tempResult.UsedVertices.UsedVertexC; 596 finalResult.UsedVertices.UsedVertexB = tempResult.UsedVertices.UsedVertexC;
597 finalResult.SetBarycentricCoordinates( 597 finalResult.SetBarycentricCoordinates(
598 tempResult.BarycentricCoords[VertexA], 598 tempResult.BarycentricCoords[VertexA],
599 tempResult.BarycentricCoords[VertexC], 599 tempResult.BarycentricCoords[VertexC],
600 0, 600 0,
601 tempResult.BarycentricCoords[VertexB]); 601 tempResult.BarycentricCoords[VertexB]);
602 602
603 } 603 }
604 } 604 }
605 // Repeat test for face bdc 605 // Repeat test for face bdc
606 606
607 if (pointOutsideBDC != 0) 607 if (pointOutsideBDC != 0)
608 { 608 {
609 ClosestPtPointTriangle(p, b, d, c, ref tempResult); 609 ClosestPtPointTriangle(p, b, d, c, ref tempResult);
610 Vector3 q = tempResult.ClosestPointOnSimplex; 610 Vector3 q = tempResult.ClosestPointOnSimplex;
611 //convert result bitmask! 611 //convert result bitmask!
612 float sqDist = ((Vector3)(q - p)).LengthSquared(); 612 float sqDist = ((Vector3)(q - p)).LengthSquared();
613 if (sqDist < bestSqDist) 613 if (sqDist < bestSqDist)
614 { 614 {
615 bestSqDist = sqDist; 615 bestSqDist = sqDist;
616 finalResult.ClosestPointOnSimplex = q; 616 finalResult.ClosestPointOnSimplex = q;
617 finalResult.UsedVertices.Reset(); 617 finalResult.UsedVertices.Reset();
618 finalResult.UsedVertices.UsedVertexB = tempResult.UsedVertices.UsedVertexA; 618 finalResult.UsedVertices.UsedVertexB = tempResult.UsedVertices.UsedVertexA;
619 finalResult.UsedVertices.UsedVertexD = tempResult.UsedVertices.UsedVertexB; 619 finalResult.UsedVertices.UsedVertexD = tempResult.UsedVertices.UsedVertexB;
620 finalResult.UsedVertices.UsedVertexC = tempResult.UsedVertices.UsedVertexC; 620 finalResult.UsedVertices.UsedVertexC = tempResult.UsedVertices.UsedVertexC;
621 621
622 finalResult.SetBarycentricCoordinates( 622 finalResult.SetBarycentricCoordinates(
623 0, 623 0,
624 tempResult.BarycentricCoords[VertexA], 624 tempResult.BarycentricCoords[VertexA],
625 tempResult.BarycentricCoords[VertexC], 625 tempResult.BarycentricCoords[VertexC],
626 tempResult.BarycentricCoords[VertexB]); 626 tempResult.BarycentricCoords[VertexB]);
627 } 627 }
628 } 628 }
629 629
630 //help! we ended up full ! 630 //help! we ended up full !
631 631
632 if (finalResult.UsedVertices.UsedVertexA && 632 if (finalResult.UsedVertices.UsedVertexA &&
633 finalResult.UsedVertices.UsedVertexB && 633 finalResult.UsedVertices.UsedVertexB &&
634 finalResult.UsedVertices.UsedVertexC && 634 finalResult.UsedVertices.UsedVertexC &&
635 finalResult.UsedVertices.UsedVertexD) 635 finalResult.UsedVertices.UsedVertexD)
636 { 636 {
637 return true; 637 return true;
638 } 638 }
639 639
640 return true; 640 return true;
641 } 641 }
642 } 642 }
643} 643}