diff options
author | Adam Frisby | 2008-05-08 13:32:15 +0000 |
---|---|---|
committer | Adam Frisby | 2008-05-08 13:32:15 +0000 |
commit | cf7560d1aaa12d9f705efd08a9a36498f332afd9 (patch) | |
tree | 8ab9c7957dd720351c6c65e0832d2bba01c2f1c1 /OpenSim/Region/Physics | |
parent | From: Michael Osias <mosias@us.ibm.com> (diff) | |
download | opensim-SC_OLD-cf7560d1aaa12d9f705efd08a9a36498f332afd9.zip opensim-SC_OLD-cf7560d1aaa12d9f705efd08a9a36498f332afd9.tar.gz opensim-SC_OLD-cf7560d1aaa12d9f705efd08a9a36498f332afd9.tar.bz2 opensim-SC_OLD-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.cs | 175 |
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); |