aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
authorAdam Frisby2008-05-08 13:32:15 +0000
committerAdam Frisby2008-05-08 13:32:15 +0000
commitcf7560d1aaa12d9f705efd08a9a36498f332afd9 (patch)
tree8ab9c7957dd720351c6c65e0832d2bba01c2f1c1 /OpenSim/Region/Physics
parentFrom: Michael Osias <mosias@us.ibm.com> (diff)
downloadopensim-SC-cf7560d1aaa12d9f705efd08a9a36498f332afd9.zip
opensim-SC-cf7560d1aaa12d9f705efd08a9a36498f332afd9.tar.gz
opensim-SC-cf7560d1aaa12d9f705efd08a9a36498f332afd9.tar.bz2
opensim-SC-cf7560d1aaa12d9f705efd08a9a36498f332afd9.tar.xz
* Commit from Jed Zhu (DeepThink) - Initial implementation of mesh collision into BulletX plugin. Additional work to come in the next few days.
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs175
1 files changed, 172 insertions, 3 deletions
diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
index 8a79dd6..69db337 100644
--- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
+++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
@@ -259,6 +259,8 @@ namespace OpenSim.Region.Physics.BulletXPlugin
259// else 259// else
260// nameA = "null"; 260// nameA = "null";
261 261
262
263
262 BulletXCharacter bxcB = null; 264 BulletXCharacter bxcB = null;
263 BulletXPrim bxpB = null; 265 BulletXPrim bxpB = null;
264 t = bodyB.GetType(); 266 t = bodyB.GetType();
@@ -268,21 +270,178 @@ namespace OpenSim.Region.Physics.BulletXPlugin
268 relatedScene._characters.TryGetValue(rb, out bxcB); 270 relatedScene._characters.TryGetValue(rb, out bxcB);
269 relatedScene._prims.TryGetValue(rb, out bxpB); 271 relatedScene._prims.TryGetValue(rb, out bxpB);
270 } 272 }
273
271// String nameB; 274// String nameB;
272// if (bxcB != null) 275// if (bxcB != null)
273// nameB = bxcB._name; 276// nameB = bxcB._name;
274// else if (bxpB != null) 277// else if (bxpB != null)
275// nameB = bxpB._name; 278// nameB = bxpB._name;
276// else 279// else
277// nameB = "null"; 280 // nameB = "null";
281 bool needsCollision;
282 ////////////////////////////////////////////////////////
283 //BulletX Mesh Collisions
284 //added by Jed zhu
285 //data: May 07,2005
286 ////////////////////////////////////////////////////////
287 #region BulletXMeshCollisions Fields
288 if (bxcA != null && bxpB != null)
289 needsCollision = Collision(bxcA, bxpB);
290 else if (bxpA != null && bxcB != null)
291 needsCollision = Collision(bxcB, bxpA);
292 else
293 needsCollision = base.NeedsCollision(bodyA, bodyB);
278 294
279 bool needsCollision = base.NeedsCollision(bodyA, bodyB); 295 #endregion
296
280 297
281 //m_log.DebugFormat("[BulletX]: A collision was detected between {0} and {1} --> {2}", nameA, nameB, 298 //m_log.DebugFormat("[BulletX]: A collision was detected between {0} and {1} --> {2}", nameA, nameB,
282 //needsCollision); 299 //needsCollision);
283 300
284 return needsCollision; 301 return needsCollision;
285 } 302 }
303 //added by jed zhu
304 //calculas the collision between the Prim and Actor
305 private bool Collision(BulletXCharacter actorA, BulletXPrim primB)
306 {
307 int[] indexBase;
308 Vector3[] vertexBase;
309 Vector3 vNormal, vP1, vP2, vP3;
310 IMesh mesh = primB.GetMesh();
311
312 float fdistance;
313 if (primB == null)
314 return false;
315 if (mesh == null)
316 return false;
317 if (actorA == null)
318 return false;
319
320 int iVertexCount = mesh.getVertexList().Count;
321 int iIndexCount = mesh.getIndexListAsInt().Length;
322 if (iVertexCount == 0)
323 return false;
324 if (iIndexCount == 0)
325 return false;
326 lock (BulletXScene.BulletXLock)
327 {
328 indexBase = mesh.getIndexListAsInt();
329 vertexBase = new Vector3[iVertexCount];
330 for (int i = 0; i < iVertexCount; i++)
331 {
332 PhysicsVector v = mesh.getVertexList()[i];
333 if (v != null) // Note, null has special meaning. See meshing code for details
334 vertexBase[i] = BulletXMaths.PhysicsVectorToXnaVector3(v);
335 else
336 vertexBase[i] = Vector3.Zero;
337 }
338 for (int ix = 0; ix < iIndexCount; ix += 3)
339 {
340 int ia = indexBase[ix + 0];
341 int ib = indexBase[ix + 1];
342 int ic = indexBase[ix + 2];
343 //
344 Vector3 v1 = vertexBase[ib] - vertexBase[ia];
345 Vector3 v2 = vertexBase[ic] - vertexBase[ia];
346
347 Vector3.Cross(ref v1, ref v2, out vNormal);
348 Vector3.Normalize(ref vNormal, out vNormal);
349
350 fdistance = Vector3.Dot(vNormal, vertexBase[ia]) + 5.0f;
351 if (preCheckCollision(actorA, vNormal, fdistance) == 1)
352 {
353 if (CheckCollision(actorA, ia, ib, ic, vNormal, vertexBase) == 1)
354 {
355 PhysicsVector v = actorA.Position;
356 Vector3 v3 = BulletXMaths.PhysicsVectorToXnaVector3(v);
357 Vector3 vp = vNormal * (fdistance - Vector3.Dot(vNormal, v3) + 0.2f);
358 actorA.Position += BulletXMaths.XnaVector3ToPhysicsVector(vp);
359 return false;
360
361 }
362 }
363
364
365 }
366 }
367
368
369 return true;
370 }
371 //added by jed zhu
372 //return value 1: need second check
373 //return value 0: no need check
374
375 private int preCheckCollision(BulletXActor actA, Vector3 vNormal, float fDist)
376 {
377 float fstartSide;
378 PhysicsVector v = actA.Position;
379 Vector3 v3 = BulletXMaths.PhysicsVectorToXnaVector3(v);
380
381 fstartSide = Vector3.Dot(vNormal, v3) - fDist;
382 if (fstartSide <= 0) return 0;
383 else return 1;
384 }
385 //added by jed zhu
386 private int CheckCollision(BulletXActor actA, int ia, int ib, int ic, Vector3 vNormal, Vector3[] vertBase)
387 {
388 Vector3 perPlaneNormal;
389 float fPerPlaneDist;
390 PhysicsVector v = actA.Position;
391 Vector3 v3 = BulletXMaths.PhysicsVectorToXnaVector3(v);
392 //check AB
393 Vector3 v1;
394 v1 = vertBase[ib] - vertBase[ia];
395 Vector3.Cross(ref vNormal, ref v1, out perPlaneNormal);
396 Vector3.Normalize(ref perPlaneNormal, out perPlaneNormal);
397
398 if (Vector3.Dot((vertBase[ic] - vertBase[ia]), perPlaneNormal) < 0)
399 perPlaneNormal = -perPlaneNormal;
400 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ia]) - 5.0f;
401
402
403
404 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) < 0)
405 return 0;
406 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ic]) + 5.0f;
407 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) > 0)
408 return 0;
409
410 //check BC
411
412 v1 = vertBase[ic] - vertBase[ib];
413 Vector3.Cross(ref vNormal, ref v1, out perPlaneNormal);
414 Vector3.Normalize(ref perPlaneNormal, out perPlaneNormal);
415
416 if (Vector3.Dot((vertBase[ia] - vertBase[ib]), perPlaneNormal) < 0)
417 perPlaneNormal = -perPlaneNormal;
418 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ib]) - 5.0f;
419
420
421 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) < 0)
422 return 0;
423 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ia]) + 5.0f;
424 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) > 0)
425 return 0;
426 //check CA
427 v1 = vertBase[ia] - vertBase[ic];
428 Vector3.Cross(ref vNormal, ref v1, out perPlaneNormal);
429 Vector3.Normalize(ref perPlaneNormal, out perPlaneNormal);
430
431 if (Vector3.Dot((vertBase[ib] - vertBase[ic]), perPlaneNormal) < 0)
432 perPlaneNormal = -perPlaneNormal;
433 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ic]) - 5.0f;
434
435
436 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) < 0)
437 return 0;
438 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ib]) + 5.0f;
439 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) > 0)
440 return 0;
441
442 return 1;
443
444 }
286 } 445 }
287 446
288 /// <summary> 447 /// <summary>
@@ -570,7 +729,9 @@ namespace OpenSim.Region.Physics.BulletXPlugin
570 729
571 public override bool IsThreaded 730 public override bool IsThreaded
572 { 731 {
573 get { return (false); // for now we won't be multithreaded 732 get
733 {
734 return (false); // for now we won't be multithreaded
574 } 735 }
575 } 736 }
576 737
@@ -1213,6 +1374,11 @@ namespace OpenSim.Region.Physics.BulletXPlugin
1213 private BulletXScene _parent_scene; 1374 private BulletXScene _parent_scene;
1214 private PhysicsVector m_prev_position = new PhysicsVector(0, 0, 0); 1375 private PhysicsVector m_prev_position = new PhysicsVector(0, 0, 0);
1215 private bool m_lastUpdateSent = false; 1376 private bool m_lastUpdateSent = false;
1377 //added by jed zhu
1378 private IMesh _mesh;
1379 public IMesh GetMesh() { return _mesh; }
1380
1381
1216 1382
1217 public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector size, 1383 public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector size,
1218 AxiomQuaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical) 1384 AxiomQuaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
@@ -1416,6 +1582,9 @@ namespace OpenSim.Region.Physics.BulletXPlugin
1416 float _restitution = 0.0f; 1582 float _restitution = 0.0f;
1417 Matrix _startTransform = Matrix.Identity; 1583 Matrix _startTransform = Matrix.Identity;
1418 Matrix _centerOfMassOffset = Matrix.Identity; 1584 Matrix _centerOfMassOffset = Matrix.Identity;
1585 //added by jed zhu
1586 //_mesh = mesh;
1587
1419 lock (BulletXScene.BulletXLock) 1588 lock (BulletXScene.BulletXLock)
1420 { 1589 {
1421 _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos); 1590 _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos);