* Commit from Jed Zhu (DeepThink) - Initial implementation of mesh collision into BulletX plugin. Additional work to come in the next few days.

0.6.0-stable
Adam Frisby 2008-05-08 13:32:15 +00:00
parent 8bd1924aaa
commit cf7560d1aa
1 changed files with 172 additions and 3 deletions

View File

@ -259,6 +259,8 @@ namespace OpenSim.Region.Physics.BulletXPlugin
// else
// nameA = "null";
BulletXCharacter bxcB = null;
BulletXPrim bxpB = null;
t = bodyB.GetType();
@ -268,21 +270,178 @@ namespace OpenSim.Region.Physics.BulletXPlugin
relatedScene._characters.TryGetValue(rb, out bxcB);
relatedScene._prims.TryGetValue(rb, out bxpB);
}
// String nameB;
// if (bxcB != null)
// nameB = bxcB._name;
// else if (bxpB != null)
// nameB = bxpB._name;
// else
// nameB = "null";
// nameB = "null";
bool needsCollision;
////////////////////////////////////////////////////////
//BulletX Mesh Collisions
//added by Jed zhu
//data: May 07,2005
////////////////////////////////////////////////////////
#region BulletXMeshCollisions Fields
if (bxcA != null && bxpB != null)
needsCollision = Collision(bxcA, bxpB);
else if (bxpA != null && bxcB != null)
needsCollision = Collision(bxcB, bxpA);
else
needsCollision = base.NeedsCollision(bodyA, bodyB);
#endregion
bool needsCollision = base.NeedsCollision(bodyA, bodyB);
//m_log.DebugFormat("[BulletX]: A collision was detected between {0} and {1} --> {2}", nameA, nameB,
//needsCollision);
return needsCollision;
}
//added by jed zhu
//calculas the collision between the Prim and Actor
private bool Collision(BulletXCharacter actorA, BulletXPrim primB)
{
int[] indexBase;
Vector3[] vertexBase;
Vector3 vNormal, vP1, vP2, vP3;
IMesh mesh = primB.GetMesh();
float fdistance;
if (primB == null)
return false;
if (mesh == null)
return false;
if (actorA == null)
return false;
int iVertexCount = mesh.getVertexList().Count;
int iIndexCount = mesh.getIndexListAsInt().Length;
if (iVertexCount == 0)
return false;
if (iIndexCount == 0)
return false;
lock (BulletXScene.BulletXLock)
{
indexBase = mesh.getIndexListAsInt();
vertexBase = new Vector3[iVertexCount];
for (int i = 0; i < iVertexCount; i++)
{
PhysicsVector v = mesh.getVertexList()[i];
if (v != null) // Note, null has special meaning. See meshing code for details
vertexBase[i] = BulletXMaths.PhysicsVectorToXnaVector3(v);
else
vertexBase[i] = Vector3.Zero;
}
for (int ix = 0; ix < iIndexCount; ix += 3)
{
int ia = indexBase[ix + 0];
int ib = indexBase[ix + 1];
int ic = indexBase[ix + 2];
//
Vector3 v1 = vertexBase[ib] - vertexBase[ia];
Vector3 v2 = vertexBase[ic] - vertexBase[ia];
Vector3.Cross(ref v1, ref v2, out vNormal);
Vector3.Normalize(ref vNormal, out vNormal);
fdistance = Vector3.Dot(vNormal, vertexBase[ia]) + 5.0f;
if (preCheckCollision(actorA, vNormal, fdistance) == 1)
{
if (CheckCollision(actorA, ia, ib, ic, vNormal, vertexBase) == 1)
{
PhysicsVector v = actorA.Position;
Vector3 v3 = BulletXMaths.PhysicsVectorToXnaVector3(v);
Vector3 vp = vNormal * (fdistance - Vector3.Dot(vNormal, v3) + 0.2f);
actorA.Position += BulletXMaths.XnaVector3ToPhysicsVector(vp);
return false;
}
}
}
}
return true;
}
//added by jed zhu
//return value 1: need second check
//return value 0: no need check
private int preCheckCollision(BulletXActor actA, Vector3 vNormal, float fDist)
{
float fstartSide;
PhysicsVector v = actA.Position;
Vector3 v3 = BulletXMaths.PhysicsVectorToXnaVector3(v);
fstartSide = Vector3.Dot(vNormal, v3) - fDist;
if (fstartSide <= 0) return 0;
else return 1;
}
//added by jed zhu
private int CheckCollision(BulletXActor actA, int ia, int ib, int ic, Vector3 vNormal, Vector3[] vertBase)
{
Vector3 perPlaneNormal;
float fPerPlaneDist;
PhysicsVector v = actA.Position;
Vector3 v3 = BulletXMaths.PhysicsVectorToXnaVector3(v);
//check AB
Vector3 v1;
v1 = vertBase[ib] - vertBase[ia];
Vector3.Cross(ref vNormal, ref v1, out perPlaneNormal);
Vector3.Normalize(ref perPlaneNormal, out perPlaneNormal);
if (Vector3.Dot((vertBase[ic] - vertBase[ia]), perPlaneNormal) < 0)
perPlaneNormal = -perPlaneNormal;
fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ia]) - 5.0f;
if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) < 0)
return 0;
fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ic]) + 5.0f;
if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) > 0)
return 0;
//check BC
v1 = vertBase[ic] - vertBase[ib];
Vector3.Cross(ref vNormal, ref v1, out perPlaneNormal);
Vector3.Normalize(ref perPlaneNormal, out perPlaneNormal);
if (Vector3.Dot((vertBase[ia] - vertBase[ib]), perPlaneNormal) < 0)
perPlaneNormal = -perPlaneNormal;
fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ib]) - 5.0f;
if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) < 0)
return 0;
fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ia]) + 5.0f;
if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) > 0)
return 0;
//check CA
v1 = vertBase[ia] - vertBase[ic];
Vector3.Cross(ref vNormal, ref v1, out perPlaneNormal);
Vector3.Normalize(ref perPlaneNormal, out perPlaneNormal);
if (Vector3.Dot((vertBase[ib] - vertBase[ic]), perPlaneNormal) < 0)
perPlaneNormal = -perPlaneNormal;
fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ic]) - 5.0f;
if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) < 0)
return 0;
fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ib]) + 5.0f;
if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) > 0)
return 0;
return 1;
}
}
/// <summary>
@ -570,7 +729,9 @@ namespace OpenSim.Region.Physics.BulletXPlugin
public override bool IsThreaded
{
get { return (false); // for now we won't be multithreaded
get
{
return (false); // for now we won't be multithreaded
}
}
@ -1213,6 +1374,11 @@ namespace OpenSim.Region.Physics.BulletXPlugin
private BulletXScene _parent_scene;
private PhysicsVector m_prev_position = new PhysicsVector(0, 0, 0);
private bool m_lastUpdateSent = false;
//added by jed zhu
private IMesh _mesh;
public IMesh GetMesh() { return _mesh; }
public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector size,
AxiomQuaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
@ -1416,6 +1582,9 @@ namespace OpenSim.Region.Physics.BulletXPlugin
float _restitution = 0.0f;
Matrix _startTransform = Matrix.Identity;
Matrix _centerOfMassOffset = Matrix.Identity;
//added by jed zhu
//_mesh = mesh;
lock (BulletXScene.BulletXLock)
{
_startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos);