* Commit from Jed Zhu (DeepThink) - Initial implementation of mesh collision into BulletX plugin. Additional work to come in the next few days.
parent
8bd1924aaa
commit
cf7560d1aa
|
@ -259,6 +259,8 @@ namespace OpenSim.Region.Physics.BulletXPlugin
|
||||||
// else
|
// else
|
||||||
// nameA = "null";
|
// nameA = "null";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BulletXCharacter bxcB = null;
|
BulletXCharacter bxcB = null;
|
||||||
BulletXPrim bxpB = null;
|
BulletXPrim bxpB = null;
|
||||||
t = bodyB.GetType();
|
t = bodyB.GetType();
|
||||||
|
@ -268,21 +270,178 @@ namespace OpenSim.Region.Physics.BulletXPlugin
|
||||||
relatedScene._characters.TryGetValue(rb, out bxcB);
|
relatedScene._characters.TryGetValue(rb, out bxcB);
|
||||||
relatedScene._prims.TryGetValue(rb, out bxpB);
|
relatedScene._prims.TryGetValue(rb, out bxpB);
|
||||||
}
|
}
|
||||||
|
|
||||||
// String nameB;
|
// String nameB;
|
||||||
// if (bxcB != null)
|
// if (bxcB != null)
|
||||||
// nameB = bxcB._name;
|
// nameB = bxcB._name;
|
||||||
// else if (bxpB != null)
|
// else if (bxpB != null)
|
||||||
// nameB = bxpB._name;
|
// nameB = bxpB._name;
|
||||||
// else
|
// 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,
|
//m_log.DebugFormat("[BulletX]: A collision was detected between {0} and {1} --> {2}", nameA, nameB,
|
||||||
//needsCollision);
|
//needsCollision);
|
||||||
|
|
||||||
return 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>
|
/// <summary>
|
||||||
|
@ -570,7 +729,9 @@ namespace OpenSim.Region.Physics.BulletXPlugin
|
||||||
|
|
||||||
public override bool IsThreaded
|
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 BulletXScene _parent_scene;
|
||||||
private PhysicsVector m_prev_position = new PhysicsVector(0, 0, 0);
|
private PhysicsVector m_prev_position = new PhysicsVector(0, 0, 0);
|
||||||
private bool m_lastUpdateSent = false;
|
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,
|
public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector size,
|
||||||
AxiomQuaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
|
AxiomQuaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
|
||||||
|
@ -1416,6 +1582,9 @@ namespace OpenSim.Region.Physics.BulletXPlugin
|
||||||
float _restitution = 0.0f;
|
float _restitution = 0.0f;
|
||||||
Matrix _startTransform = Matrix.Identity;
|
Matrix _startTransform = Matrix.Identity;
|
||||||
Matrix _centerOfMassOffset = Matrix.Identity;
|
Matrix _centerOfMassOffset = Matrix.Identity;
|
||||||
|
//added by jed zhu
|
||||||
|
//_mesh = mesh;
|
||||||
|
|
||||||
lock (BulletXScene.BulletXLock)
|
lock (BulletXScene.BulletXLock)
|
||||||
{
|
{
|
||||||
_startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos);
|
_startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos);
|
||||||
|
|
Loading…
Reference in New Issue