aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionWorld.cs
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionWorld.cs')
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionWorld.cs716
1 files changed, 358 insertions, 358 deletions
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionWorld.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionWorld.cs
index 968e219..cb520bb 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionWorld.cs
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionDispatch/CollisionWorld.cs
@@ -1,358 +1,358 @@
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 CollisionWorld 29 public class CollisionWorld
30 { 30 {
31 private List<CollisionObject> _collisionObjects = new List<CollisionObject>(); 31 private List<CollisionObject> _collisionObjects = new List<CollisionObject>();
32 private IDispatcher _dispatcher; 32 private IDispatcher _dispatcher;
33 private OverlappingPairCache _broadphasePairCache; 33 private OverlappingPairCache _broadphasePairCache;
34 private bool _ownsDispatcher; 34 private bool _ownsDispatcher;
35 private bool _ownsBroadphasePairCache; 35 private bool _ownsBroadphasePairCache;
36 private DispatcherInfo _dispatchInfo = new DispatcherInfo(); 36 private DispatcherInfo _dispatchInfo = new DispatcherInfo();
37 37
38 /// <summary> 38 /// <summary>
39 /// this constructor doesn't own the dispatcher and paircache/broadphase 39 /// this constructor doesn't own the dispatcher and paircache/broadphase
40 /// </summary> 40 /// </summary>
41 /// <param name="dispatcher"></param> 41 /// <param name="dispatcher"></param>
42 /// <param name="pairCache"></param> 42 /// <param name="pairCache"></param>
43 public CollisionWorld(IDispatcher dispatcher, OverlappingPairCache pairCache) 43 public CollisionWorld(IDispatcher dispatcher, OverlappingPairCache pairCache)
44 { 44 {
45 _dispatcher = dispatcher; 45 _dispatcher = dispatcher;
46 _broadphasePairCache = pairCache; 46 _broadphasePairCache = pairCache;
47 _ownsDispatcher = false; 47 _ownsDispatcher = false;
48 _ownsBroadphasePairCache = false; 48 _ownsBroadphasePairCache = false;
49 } 49 }
50 50
51 public DispatcherInfo DispatchInfo { get { return _dispatchInfo; } protected set { _dispatchInfo = value; } } 51 public DispatcherInfo DispatchInfo { get { return _dispatchInfo; } protected set { _dispatchInfo = value; } }
52 public List<CollisionObject> CollisionObjects { get { return _collisionObjects; } protected set { _collisionObjects = value; } } 52 public List<CollisionObject> CollisionObjects { get { return _collisionObjects; } protected set { _collisionObjects = value; } }
53 public IBroadphase Broadphase { get { return _broadphasePairCache; } } 53 public IBroadphase Broadphase { get { return _broadphasePairCache; } }
54 public OverlappingPairCache BroadphasePairCache { get { return _broadphasePairCache; } protected set { _broadphasePairCache = value; } } 54 public OverlappingPairCache BroadphasePairCache { get { return _broadphasePairCache; } protected set { _broadphasePairCache = value; } }
55 public IDispatcher Dispatcher { get { return _dispatcher; } protected set { _dispatcher = value; } } 55 public IDispatcher Dispatcher { get { return _dispatcher; } protected set { _dispatcher = value; } }
56 public int CollisionObjectsCount { get { return _collisionObjects.Count; } } 56 public int CollisionObjectsCount { get { return _collisionObjects.Count; } }
57 protected bool OwnsDispatcher { get { return _ownsDispatcher; } set { _ownsDispatcher = value; } } 57 protected bool OwnsDispatcher { get { return _ownsDispatcher; } set { _ownsDispatcher = value; } }
58 protected bool OwnsBroadphasePairCache { get { return _ownsBroadphasePairCache; } set { _ownsBroadphasePairCache = value; } } 58 protected bool OwnsBroadphasePairCache { get { return _ownsBroadphasePairCache; } set { _ownsBroadphasePairCache = value; } }
59 59
60 // rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback 60 // rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback
61 // This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback. 61 // This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
62 public void RayTest(Vector3 rayFromWorld, Vector3 rayToWorld, RayResultCallback resultCallback) 62 public void RayTest(Vector3 rayFromWorld, Vector3 rayToWorld, RayResultCallback resultCallback)
63 { 63 {
64 Matrix rayFromTrans, rayToTrans; 64 Matrix rayFromTrans, rayToTrans;
65 65
66 rayFromTrans = Matrix.Identity; 66 rayFromTrans = Matrix.Identity;
67 rayFromTrans.Translation = rayFromWorld; 67 rayFromTrans.Translation = rayFromWorld;
68 68
69 rayToTrans = Matrix.Identity; 69 rayToTrans = Matrix.Identity;
70 rayToTrans.Translation = rayToWorld; 70 rayToTrans.Translation = rayToWorld;
71 71
72 // brute force go over all objects. Once there is a broadphase, use that, or 72 // brute force go over all objects. Once there is a broadphase, use that, or
73 // add a raycast against aabb first. 73 // add a raycast against aabb first.
74 74
75 foreach (CollisionObject collisionObject in _collisionObjects) 75 foreach (CollisionObject collisionObject in _collisionObjects)
76 { 76 {
77 //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); 77 //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
78 Vector3 collisionObjectAabbMin, collisionObjectAabbMax; 78 Vector3 collisionObjectAabbMin, collisionObjectAabbMax;
79 collisionObject.CollisionShape.GetAabb(collisionObject.WorldTransform, out collisionObjectAabbMin, out collisionObjectAabbMax); 79 collisionObject.CollisionShape.GetAabb(collisionObject.WorldTransform, out collisionObjectAabbMin, out collisionObjectAabbMax);
80 80
81 float hitLambda = 1f; //could use resultCallback.m_closestHitFraction, but needs testing 81 float hitLambda = 1f; //could use resultCallback.m_closestHitFraction, but needs testing
82 Vector3 hitNormal = new Vector3(); 82 Vector3 hitNormal = new Vector3();
83 83
84 //if (MathHelper.TestAabbAgainstAabb2(rayAabbMin, rayAabbMax, collisionObjectAabbMin, collisionObjectAabbMax)) 84 //if (MathHelper.TestAabbAgainstAabb2(rayAabbMin, rayAabbMax, collisionObjectAabbMin, collisionObjectAabbMax))
85 if (MathHelper.RayAabb(rayFromWorld, rayToWorld, collisionObjectAabbMin, collisionObjectAabbMax, hitLambda, hitNormal)) 85 if (MathHelper.RayAabb(rayFromWorld, rayToWorld, collisionObjectAabbMin, collisionObjectAabbMax, hitLambda, hitNormal))
86 { 86 {
87 RayTestSingle(rayFromTrans, rayToTrans, 87 RayTestSingle(rayFromTrans, rayToTrans,
88 collisionObject, collisionObject.CollisionShape, 88 collisionObject, collisionObject.CollisionShape,
89 collisionObject.WorldTransform, resultCallback); 89 collisionObject.WorldTransform, resultCallback);
90 90
91 } 91 }
92 } 92 }
93 } 93 }
94 94
95 // rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest. 95 // rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
96 // In a future implementation, we consider moving the ray test as a virtual method in CollisionShape. 96 // In a future implementation, we consider moving the ray test as a virtual method in CollisionShape.
97 // This allows more customization. 97 // This allows more customization.
98 public static void RayTestSingle(Matrix rayFromTrans, Matrix rayToTrans, 98 public static void RayTestSingle(Matrix rayFromTrans, Matrix rayToTrans,
99 CollisionObject collisionObject, 99 CollisionObject collisionObject,
100 CollisionShape collisionShape, 100 CollisionShape collisionShape,
101 Matrix colObjWorldTransform, 101 Matrix colObjWorldTransform,
102 RayResultCallback resultCallback) 102 RayResultCallback resultCallback)
103 { 103 {
104 SphereShape pointShape=new SphereShape(0.0f); 104 SphereShape pointShape=new SphereShape(0.0f);
105 105
106 if (collisionShape.IsConvex) 106 if (collisionShape.IsConvex)
107 { 107 {
108 CastResult castResult = new CastResult(); 108 CastResult castResult = new CastResult();
109 castResult.Fraction = 1f;//?? 109 castResult.Fraction = 1f;//??
110 110
111 ConvexShape convexShape = collisionShape as ConvexShape; 111 ConvexShape convexShape = collisionShape as ConvexShape;
112 VoronoiSimplexSolver simplexSolver = new VoronoiSimplexSolver(); 112 VoronoiSimplexSolver simplexSolver = new VoronoiSimplexSolver();
113 SubsimplexConvexCast convexCaster = new SubsimplexConvexCast(pointShape, convexShape, simplexSolver); 113 SubsimplexConvexCast convexCaster = new SubsimplexConvexCast(pointShape, convexShape, simplexSolver);
114 //GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver); 114 //GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
115 //ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0); 115 //ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);
116 116
117 if (convexCaster.CalcTimeOfImpact(rayFromTrans, rayToTrans, colObjWorldTransform, colObjWorldTransform, castResult)) 117 if (convexCaster.CalcTimeOfImpact(rayFromTrans, rayToTrans, colObjWorldTransform, colObjWorldTransform, castResult))
118 { 118 {
119 //add hit 119 //add hit
120 if (castResult.Normal.LengthSquared() > 0.0001f) 120 if (castResult.Normal.LengthSquared() > 0.0001f)
121 { 121 {
122 castResult.Normal.Normalize(); 122 castResult.Normal.Normalize();
123 if (castResult.Fraction < resultCallback.ClosestHitFraction) 123 if (castResult.Fraction < resultCallback.ClosestHitFraction)
124 { 124 {
125 125
126 CollisionWorld.LocalRayResult localRayResult = new LocalRayResult 126 CollisionWorld.LocalRayResult localRayResult = new LocalRayResult
127 ( 127 (
128 collisionObject, 128 collisionObject,
129 new LocalShapeInfo(), 129 new LocalShapeInfo(),
130 castResult.Normal, 130 castResult.Normal,
131 castResult.Fraction 131 castResult.Fraction
132 ); 132 );
133 133
134 resultCallback.AddSingleResult(localRayResult); 134 resultCallback.AddSingleResult(localRayResult);
135 } 135 }
136 } 136 }
137 } 137 }
138 else 138 else
139 { 139 {
140 if (collisionShape.IsConcave) 140 if (collisionShape.IsConcave)
141 { 141 {
142 142
143 TriangleMeshShape triangleMesh = collisionShape as TriangleMeshShape; 143 TriangleMeshShape triangleMesh = collisionShape as TriangleMeshShape;
144 144
145 Matrix worldTocollisionObject = MathHelper.InvertMatrix(colObjWorldTransform); 145 Matrix worldTocollisionObject = MathHelper.InvertMatrix(colObjWorldTransform);
146 146
147 Vector3 rayFromLocal = Vector3.TransformNormal(rayFromTrans.Translation, worldTocollisionObject); 147 Vector3 rayFromLocal = Vector3.TransformNormal(rayFromTrans.Translation, worldTocollisionObject);
148 Vector3 rayToLocal = Vector3.TransformNormal(rayToTrans.Translation, worldTocollisionObject); 148 Vector3 rayToLocal = Vector3.TransformNormal(rayToTrans.Translation, worldTocollisionObject);
149 149
150 BridgeTriangleRaycastCallback rcb = new BridgeTriangleRaycastCallback(rayFromLocal, rayToLocal, resultCallback, collisionObject, triangleMesh); 150 BridgeTriangleRaycastCallback rcb = new BridgeTriangleRaycastCallback(rayFromLocal, rayToLocal, resultCallback, collisionObject, triangleMesh);
151 rcb.HitFraction = resultCallback.ClosestHitFraction; 151 rcb.HitFraction = resultCallback.ClosestHitFraction;
152 152
153 Vector3 rayAabbMinLocal = rayFromLocal; 153 Vector3 rayAabbMinLocal = rayFromLocal;
154 MathHelper.SetMin(ref rayAabbMinLocal, rayToLocal); 154 MathHelper.SetMin(ref rayAabbMinLocal, rayToLocal);
155 Vector3 rayAabbMaxLocal = rayFromLocal; 155 Vector3 rayAabbMaxLocal = rayFromLocal;
156 MathHelper.SetMax(ref rayAabbMaxLocal, rayToLocal); 156 MathHelper.SetMax(ref rayAabbMaxLocal, rayToLocal);
157 157
158 triangleMesh.ProcessAllTriangles(rcb, rayAabbMinLocal, rayAabbMaxLocal); 158 triangleMesh.ProcessAllTriangles(rcb, rayAabbMinLocal, rayAabbMaxLocal);
159 } 159 }
160 else 160 else
161 { 161 {
162 //todo: use AABB tree or other BVH acceleration structure! 162 //todo: use AABB tree or other BVH acceleration structure!
163 if (collisionShape.IsCompound) 163 if (collisionShape.IsCompound)
164 { 164 {
165 CompoundShape compoundShape = collisionShape as CompoundShape; 165 CompoundShape compoundShape = collisionShape as CompoundShape;
166 for (int i = 0; i < compoundShape.ChildShapeCount; i++) 166 for (int i = 0; i < compoundShape.ChildShapeCount; i++)
167 { 167 {
168 Matrix childTrans = compoundShape.GetChildTransform(i); 168 Matrix childTrans = compoundShape.GetChildTransform(i);
169 CollisionShape childCollisionShape = compoundShape.GetChildShape(i); 169 CollisionShape childCollisionShape = compoundShape.GetChildShape(i);
170 Matrix childWorldTrans = colObjWorldTransform * childTrans; 170 Matrix childWorldTrans = colObjWorldTransform * childTrans;
171 RayTestSingle(rayFromTrans, rayToTrans, 171 RayTestSingle(rayFromTrans, rayToTrans,
172 collisionObject, 172 collisionObject,
173 childCollisionShape, 173 childCollisionShape,
174 childWorldTrans, 174 childWorldTrans,
175 resultCallback); 175 resultCallback);
176 } 176 }
177 } 177 }
178 } 178 }
179 } 179 }
180 } 180 }
181 } 181 }
182 182
183 public void AddCollisionObject(CollisionObject collisionObject, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask) 183 public void AddCollisionObject(CollisionObject collisionObject, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask)
184 { 184 {
185 //check that the object isn't already added 185 //check that the object isn't already added
186 if (!_collisionObjects.Contains(collisionObject)) 186 if (!_collisionObjects.Contains(collisionObject))
187 { 187 {
188 _collisionObjects.Add(collisionObject); 188 _collisionObjects.Add(collisionObject);
189 189
190 //calculate new AABB 190 //calculate new AABB
191 Matrix trans = collisionObject.WorldTransform; 191 Matrix trans = collisionObject.WorldTransform;
192 192
193 Vector3 minAabb; 193 Vector3 minAabb;
194 Vector3 maxAabb; 194 Vector3 maxAabb;
195 collisionObject.CollisionShape.GetAabb(trans, out minAabb, out maxAabb); 195 collisionObject.CollisionShape.GetAabb(trans, out minAabb, out maxAabb);
196 196
197 BroadphaseNativeTypes type = collisionObject.CollisionShape.ShapeType; 197 BroadphaseNativeTypes type = collisionObject.CollisionShape.ShapeType;
198 collisionObject.Broadphase = Broadphase.CreateProxy( 198 collisionObject.Broadphase = Broadphase.CreateProxy(
199 minAabb, 199 minAabb,
200 maxAabb, 200 maxAabb,
201 type, 201 type,
202 collisionObject, 202 collisionObject,
203 collisionFilterGroup, 203 collisionFilterGroup,
204 collisionFilterMask 204 collisionFilterMask
205 ); 205 );
206 } 206 }
207 } 207 }
208 208
209 public void AddCollisionObject(CollisionObject collisionObject) 209 public void AddCollisionObject(CollisionObject collisionObject)
210 { 210 {
211 AddCollisionObject(collisionObject, BroadphaseProxy.CollisionFilterGroups.Default, BroadphaseProxy.CollisionFilterGroups.Default); 211 AddCollisionObject(collisionObject, BroadphaseProxy.CollisionFilterGroups.Default, BroadphaseProxy.CollisionFilterGroups.Default);
212 } 212 }
213 213
214 public void RemoveCollisionObject(CollisionObject collisionObject) 214 public void RemoveCollisionObject(CollisionObject collisionObject)
215 { 215 {
216 BroadphaseProxy bp = collisionObject.Broadphase; 216 BroadphaseProxy bp = collisionObject.Broadphase;
217 if (bp != null) 217 if (bp != null)
218 { 218 {
219 // 219 //
220 // only clear the cached algorithms 220 // only clear the cached algorithms
221 // 221 //
222 Broadphase.CleanProxyFromPairs(bp); 222 Broadphase.CleanProxyFromPairs(bp);
223 Broadphase.DestroyProxy(bp); 223 Broadphase.DestroyProxy(bp);
224 collisionObject.Broadphase = null; 224 collisionObject.Broadphase = null;
225 } 225 }
226 226
227 _collisionObjects.Remove(collisionObject); 227 _collisionObjects.Remove(collisionObject);
228 } 228 }
229 229
230 public virtual void PerformDiscreteCollisionDetection() 230 public virtual void PerformDiscreteCollisionDetection()
231 { 231 {
232 DispatcherInfo dispatchInfo = DispatchInfo; 232 DispatcherInfo dispatchInfo = DispatchInfo;
233 //update aabb (of all moved objects) 233 //update aabb (of all moved objects)
234 234
235 Vector3 aabbMin, aabbMax; 235 Vector3 aabbMin, aabbMax;
236 for (int i = 0; i < _collisionObjects.Count; i++) 236 for (int i = 0; i < _collisionObjects.Count; i++)
237 { 237 {
238 _collisionObjects[i].CollisionShape.GetAabb(_collisionObjects[i].WorldTransform, out aabbMin, out aabbMax); 238 _collisionObjects[i].CollisionShape.GetAabb(_collisionObjects[i].WorldTransform, out aabbMin, out aabbMax);
239 _broadphasePairCache.SetAabb(_collisionObjects[i].Broadphase, aabbMin, aabbMax); 239 _broadphasePairCache.SetAabb(_collisionObjects[i].Broadphase, aabbMin, aabbMax);
240 } 240 }
241 241
242 _broadphasePairCache.RefreshOverlappingPairs(); 242 _broadphasePairCache.RefreshOverlappingPairs();
243 243
244 IDispatcher dispatcher = Dispatcher; 244 IDispatcher dispatcher = Dispatcher;
245 if (dispatcher != null) 245 if (dispatcher != null)
246 dispatcher.DispatchAllCollisionPairs(_broadphasePairCache, dispatchInfo); 246 dispatcher.DispatchAllCollisionPairs(_broadphasePairCache, dispatchInfo);
247 } 247 }
248 248
249 public void Dispose(bool disposing) 249 public void Dispose(bool disposing)
250 { 250 {
251 if (disposing) 251 if (disposing)
252 { 252 {
253 //clean up remaining objects 253 //clean up remaining objects
254 foreach (CollisionObject collisionObject in _collisionObjects) 254 foreach (CollisionObject collisionObject in _collisionObjects)
255 { 255 {
256 BroadphaseProxy bp = collisionObject.Broadphase; 256 BroadphaseProxy bp = collisionObject.Broadphase;
257 if (bp != null) 257 if (bp != null)
258 { 258 {
259 // 259 //
260 // only clear the cached algorithms 260 // only clear the cached algorithms
261 // 261 //
262 Broadphase.CleanProxyFromPairs(bp); 262 Broadphase.CleanProxyFromPairs(bp);
263 Broadphase.DestroyProxy(bp); 263 Broadphase.DestroyProxy(bp);
264 } 264 }
265 } 265 }
266 } 266 }
267 } 267 }
268 268
269 /// <summary> 269 /// <summary>
270 /// LocalShapeInfo gives extra information for complex shapes 270 /// LocalShapeInfo gives extra information for complex shapes
271 /// Currently, only TriangleMeshShape is available, so it just contains triangleIndex and subpart 271 /// Currently, only TriangleMeshShape is available, so it just contains triangleIndex and subpart
272 /// </summary> 272 /// </summary>
273 public struct LocalShapeInfo 273 public struct LocalShapeInfo
274 { 274 {
275 private int _shapePart; 275 private int _shapePart;
276 private int _triangleIndex; 276 private int _triangleIndex;
277 277
278 public int ShapePart { get { return _shapePart; } set { _shapePart = value; } } 278 public int ShapePart { get { return _shapePart; } set { _shapePart = value; } }
279 public int TriangleIndex { get { return _triangleIndex; } set { _triangleIndex = value; } } 279 public int TriangleIndex { get { return _triangleIndex; } set { _triangleIndex = value; } }
280 } 280 }
281 281
282 public struct LocalRayResult 282 public struct LocalRayResult
283 { 283 {
284 private CollisionObject _collisionObject; 284 private CollisionObject _collisionObject;
285 private LocalShapeInfo _localShapeInfo; 285 private LocalShapeInfo _localShapeInfo;
286 private Vector3 _hitNormalLocal; 286 private Vector3 _hitNormalLocal;
287 private float _hitFraction; 287 private float _hitFraction;
288 288
289 public LocalRayResult(CollisionObject collisionObject, 289 public LocalRayResult(CollisionObject collisionObject,
290 LocalShapeInfo localShapeInfo, 290 LocalShapeInfo localShapeInfo,
291 Vector3 hitNormalLocal, 291 Vector3 hitNormalLocal,
292 float hitFraction) 292 float hitFraction)
293 { 293 {
294 _collisionObject = collisionObject; 294 _collisionObject = collisionObject;
295 _localShapeInfo = localShapeInfo; 295 _localShapeInfo = localShapeInfo;
296 _hitNormalLocal = hitNormalLocal; 296 _hitNormalLocal = hitNormalLocal;
297 _hitFraction = hitFraction; 297 _hitFraction = hitFraction;
298 } 298 }
299 299
300 public CollisionObject CollisionObject { get { return _collisionObject; } set { _collisionObject = value; } } 300 public CollisionObject CollisionObject { get { return _collisionObject; } set { _collisionObject = value; } }
301 public LocalShapeInfo LocalShapeInfo { get { return _localShapeInfo; } set { _localShapeInfo = value; } } 301 public LocalShapeInfo LocalShapeInfo { get { return _localShapeInfo; } set { _localShapeInfo = value; } }
302 public Vector3 HitNormalLocal { get { return _hitNormalLocal; } set { _hitNormalLocal = value; } } 302 public Vector3 HitNormalLocal { get { return _hitNormalLocal; } set { _hitNormalLocal = value; } }
303 public float HitFraction { get { return _hitFraction; } set { _hitFraction = value; } } 303 public float HitFraction { get { return _hitFraction; } set { _hitFraction = value; } }
304 } 304 }
305 305
306 /// <summary> 306 /// <summary>
307 /// RayResultCallback is used to report new raycast results 307 /// RayResultCallback is used to report new raycast results
308 /// </summary> 308 /// </summary>
309 public abstract class RayResultCallback 309 public abstract class RayResultCallback
310 { 310 {
311 private float _closestHitFraction; 311 private float _closestHitFraction;
312 312
313 public RayResultCallback() 313 public RayResultCallback()
314 { 314 {
315 _closestHitFraction = 1; 315 _closestHitFraction = 1;
316 } 316 }
317 317
318 public float ClosestHitFraction { get { return _closestHitFraction; } set { _closestHitFraction = value; } } 318 public float ClosestHitFraction { get { return _closestHitFraction; } set { _closestHitFraction = value; } }
319 public bool HasHit { get { return _closestHitFraction < 1; } } 319 public bool HasHit { get { return _closestHitFraction < 1; } }
320 320
321 public abstract float AddSingleResult(LocalRayResult rayResult); 321 public abstract float AddSingleResult(LocalRayResult rayResult);
322 } 322 }
323 323
324 public class ClosestRayResultCallback : RayResultCallback 324 public class ClosestRayResultCallback : RayResultCallback
325 { 325 {
326 private Vector3 _rayFromWorld;//used to calculate hitPointWorld from hitFraction 326 private Vector3 _rayFromWorld;//used to calculate hitPointWorld from hitFraction
327 private Vector3 _rayToWorld; 327 private Vector3 _rayToWorld;
328 328
329 private Vector3 _hitNormalWorld; 329 private Vector3 _hitNormalWorld;
330 private Vector3 _hitPointWorld; 330 private Vector3 _hitPointWorld;
331 private CollisionObject _collisionObject; 331 private CollisionObject _collisionObject;
332 332
333 public ClosestRayResultCallback(Vector3 rayFromWorld, Vector3 rayToWorld) 333 public ClosestRayResultCallback(Vector3 rayFromWorld, Vector3 rayToWorld)
334 { 334 {
335 _rayFromWorld = rayFromWorld; 335 _rayFromWorld = rayFromWorld;
336 _rayToWorld = rayToWorld; 336 _rayToWorld = rayToWorld;
337 _collisionObject = null; 337 _collisionObject = null;
338 } 338 }
339 339
340 public Vector3 RayFromWorld { get { return _rayFromWorld; } set { _rayFromWorld = value; } } 340 public Vector3 RayFromWorld { get { return _rayFromWorld; } set { _rayFromWorld = value; } }
341 public Vector3 RayToWorld { get { return _rayToWorld; } set { _rayToWorld = value; } } 341 public Vector3 RayToWorld { get { return _rayToWorld; } set { _rayToWorld = value; } }
342 public Vector3 HitNormalWorld { get { return _hitNormalWorld; } set { _hitNormalWorld = value; } } 342 public Vector3 HitNormalWorld { get { return _hitNormalWorld; } set { _hitNormalWorld = value; } }
343 public Vector3 HitPointWorld { get { return _hitPointWorld; } set { _hitPointWorld = value; } } 343 public Vector3 HitPointWorld { get { return _hitPointWorld; } set { _hitPointWorld = value; } }
344 public CollisionObject CollisionObject { get { return _collisionObject; } set { _collisionObject = value; } } 344 public CollisionObject CollisionObject { get { return _collisionObject; } set { _collisionObject = value; } }
345 345
346 public override float AddSingleResult(LocalRayResult rayResult) 346 public override float AddSingleResult(LocalRayResult rayResult)
347 { 347 {
348 //caller already does the filter on the m_closestHitFraction 348 //caller already does the filter on the m_closestHitFraction
349 //assert(rayResult.m_hitFraction <= m_closestHitFraction); 349 //assert(rayResult.m_hitFraction <= m_closestHitFraction);
350 ClosestHitFraction = rayResult.HitFraction; 350 ClosestHitFraction = rayResult.HitFraction;
351 _collisionObject = rayResult.CollisionObject; 351 _collisionObject = rayResult.CollisionObject;
352 _hitNormalWorld = Vector3.TransformNormal(rayResult.HitNormalLocal, _collisionObject.WorldTransform); 352 _hitNormalWorld = Vector3.TransformNormal(rayResult.HitNormalLocal, _collisionObject.WorldTransform);
353 MathHelper.SetInterpolate3(_rayFromWorld, _rayToWorld, rayResult.HitFraction, ref _hitPointWorld); 353 MathHelper.SetInterpolate3(_rayFromWorld, _rayToWorld, rayResult.HitFraction, ref _hitPointWorld);
354 return rayResult.HitFraction; 354 return rayResult.HitFraction;
355 } 355 }
356 } 356 }
357 } 357 }
358} 358}