本文整理汇总了C#中JigLibX.Collision.CollisionFunctor类的典型用法代码示例。如果您正苦于以下问题:C# CollisionFunctor类的具体用法?C# CollisionFunctor怎么用?C# CollisionFunctor使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
CollisionFunctor类属于JigLibX.Collision命名空间,在下文中一共展示了CollisionFunctor类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: CollDetect
public override void CollDetect(CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
{
Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;
// todo - proper swept test
Capsule oldCapsule0 = (Capsule)info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0);
Capsule newCapsule0 = (Capsule)info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0);
Segment oldSeg0 = new Segment(oldCapsule0.Position, oldCapsule0.Length * oldCapsule0.Orientation.Backward);
Segment newSeg0 = new Segment(newCapsule0.Position, newCapsule0.Length * newCapsule0.Orientation.Backward);
Capsule oldCapsule1 = (Capsule)info.Skin1.GetPrimitiveOldWorld(info.IndexPrim1);
Capsule newCapsule1 = (Capsule)info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1);
Segment oldSeg1 = new Segment(oldCapsule1.Position, oldCapsule1.Length * oldCapsule1.Orientation.Backward);
Segment newSeg1 = new Segment(newCapsule1.Position, newCapsule1.Length * newCapsule1.Orientation.Backward);
float radSum = newCapsule0.Radius + newCapsule1.Radius;
float oldt0, oldt1;
float newt0, newt1;
float oldDistSq = Distance.SegmentSegmentDistanceSq(out oldt0, out oldt1, oldSeg0, oldSeg1);
float newDistSq = Distance.SegmentSegmentDistanceSq(out newt0, out newt1, newSeg0, newSeg1);
if (System.Math.Min(oldDistSq, newDistSq) < ((radSum + collTolerance) * (radSum + collTolerance)))
{
Vector3 pos0 = oldSeg0.GetPoint(oldt0);
Vector3 pos1 = oldSeg1.GetPoint(oldt1);
Vector3 delta = pos0 - pos1;
float dist = (float)System.Math.Sqrt((float)oldDistSq);
float depth = radSum - dist;
if (dist > JiggleMath.Epsilon)
{
delta /= dist;
}
else
{
// todo - make this not random
delta = Vector3.Transform(Vector3.Backward, Matrix.CreateFromAxisAngle(Vector3.Up, MathHelper.ToRadians(random.Next(360))));
}
Vector3 worldPos = pos1 +
(oldCapsule1.Radius - 0.5f * depth) * delta;
unsafe
{
SmallCollPointInfo collInfo = new SmallCollPointInfo(worldPos - body0Pos, worldPos - body1Pos, depth);
collisionFunctor.CollisionNotify(ref info, ref delta, &collInfo, 1);
}
}
}
示例2: CollDetect
/// <summary>
///
/// </summary>
/// <param name="info"></param>
/// <param name="collTolerance"></param>
/// <param name="collisionFunctor"></param>
public override void CollDetect(CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
{
if (info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0).Type == this.Type1)
{
CollisionSkin skinSwap = info.Skin0;
info.Skin0 = info.Skin1;
info.Skin1 = skinSwap;
int primSwap = info.IndexPrim0;
info.IndexPrim0 = info.IndexPrim1;
info.IndexPrim1 = primSwap;
}
Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;
// todo - proper swept test
Sphere oldSphere = (Sphere)info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0);
Sphere newSphere = (Sphere)info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0);
JigLibX.Geometry.Plane oldPlane = (JigLibX.Geometry.Plane)info.Skin1.GetPrimitiveOldWorld(info.IndexPrim1);
JigLibX.Geometry.Plane newPlane = (JigLibX.Geometry.Plane)info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1);
Matrix newPlaneInvTransform = newPlane.InverseTransformMatrix;
Matrix oldPlaneInvTransform = oldPlane.InverseTransformMatrix;
Vector3 oldSpherePos = Vector3.Transform(oldSphere.Position, oldPlaneInvTransform);
Vector3 newSpherePos = Vector3.Transform(newSphere.Position, newPlaneInvTransform);
// consider it a contact if either old or new are touching
float oldDist = Distance.PointPlaneDistance(oldSpherePos, oldPlane);
float newDist = Distance.PointPlaneDistance(newSpherePos, newPlane);
if (System.Math.Min(newDist, oldDist) > collTolerance + newSphere.Radius)
return;
// collision - record depth using the old values
float oldDepth = oldSphere.Radius - oldDist;
// calc the world position based on the old position(s)
Vector3 worldPos = oldSphere.Position - oldSphere.Radius * oldPlane.Normal;
unsafe
{
SmallCollPointInfo collInfo = new SmallCollPointInfo(worldPos - body0Pos, worldPos - body1Pos, oldDepth);
collisionFunctor.CollisionNotify(ref info, ref oldPlane.normal, &collInfo, 1);
}
}
示例3: CollDetect
/// <summary>
/// Detect BoxStaticMesh Collisions.
/// </summary>
/// <param name="info"></param>
/// <param name="collTolerance"></param>
/// <param name="collisionFunctor"></param>
public override void CollDetect(CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
{
if (info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0).Type == Type1)
{
CollisionSkin skinSwap = info.Skin0;
info.Skin0 = info.Skin1;
info.Skin1 = skinSwap;
int primSwap = info.IndexPrim0;
info.IndexPrim0 = info.IndexPrim1;
info.IndexPrim1 = primSwap;
}
if (info.Skin0.CollisionSystem != null && info.Skin0.CollisionSystem.UseSweepTests)
CollDetectSweep(ref info, collTolerance, collisionFunctor);
else
CollDetectOverlap(ref info, collTolerance, collisionFunctor);
}
示例4: CollDetect
/// <summary>
/// CollDetect
/// </summary>
/// <param name="info"></param>
/// <param name="collTolerance"></param>
/// <param name="collisionFunctor"></param>
public override void CollDetect(CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
{
Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;
// todo - proper swept test
Sphere oldSphere0 = (Sphere) info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0);
Sphere newSphere0 = (Sphere)info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0);
Sphere oldSphere1 = (Sphere)info.Skin1.GetPrimitiveOldWorld(info.IndexPrim1);
Sphere newSphere1 = (Sphere)info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1);
Vector3 oldDelta = oldSphere0.Position - oldSphere1.Position;
Vector3 newDelta = newSphere0.Position - oldSphere1.Position;
float oldDistSq = oldDelta.LengthSquared;
float newDistSq = newDelta.LengthSquared;
float radSum = newSphere0.Radius + newSphere1.Radius;
if (System.Math.Min(oldDistSq, newDistSq) < ((radSum + collTolerance) * (radSum + collTolerance)))
{
float oldDist = (float)System.Math.Sqrt((float)oldDistSq);
float depth = radSum - oldDist;
if (oldDist > JiggleMath.Epsilon)
{
oldDelta /= oldDist;
}
else
{
// TODO - make this not random...!
oldDelta = Vector3Extensions.TransformNormal(Vector3Extensions.Backward, Matrix4.CreateFromAxisAngle(Vector3Extensions.Up, OpenTKHelper.ToRadians(random.Next(360))));
}
Vector3 worldPos = oldSphere1.Position +
(oldSphere1.Radius - 0.5f * depth) * oldDelta;
unsafe
{
SmallCollPointInfo collInfo = new SmallCollPointInfo(worldPos - body0Pos, worldPos - body1Pos, depth);
collisionFunctor.CollisionNotify(ref info, ref oldDelta, &collInfo, 1);
}
}
}
示例5: CollDetect
/// <summary>
/// CollDetect
/// </summary>
/// <param name="info"></param>
/// <param name="collTolerance"></param>
/// <param name="collisionFunctor"></param>
public override void CollDetect(CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
{
// get the skins in the order that we're expecting
if (info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0).Type == this.Type1)
{
CollisionSkin skinSwap = info.Skin0;
info.Skin0 = info.Skin1;
info.Skin1 = skinSwap;
int primSwap = info.IndexPrim0;
info.IndexPrim0 = info.IndexPrim1;
info.IndexPrim1 = primSwap;
}
if((info.Skin0.CollisionSystem != null) && info.Skin0.CollisionSystem.UseSweepTests)
CollDetectSweep(info, collTolerance, collisionFunctor);
else
CollDetectOverlap(info, collTolerance, collisionFunctor);
}
示例6: CollDetect
/// <summary>
///
/// </summary>
/// <param name="infoOrig"></param>
/// <param name="collTolerance"></param>
/// <param name="collisionFunctor"></param>
public override void CollDetect(CollDetectInfo infoOrig, float collTolerance, CollisionFunctor collisionFunctor)
{
CollDetectInfo info = infoOrig;
if (info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0).Type == this.Type1)
{
CollisionSkin skinSwap = info.Skin0;
info.Skin0 = info.Skin1;
info.Skin1 = skinSwap;
int primSwap = info.IndexPrim0;
info.IndexPrim0 = info.IndexPrim1;
info.IndexPrim1 = primSwap;
}
Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;
// todo - proper swept test
Sphere oldSphere = (Sphere)info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0);
Sphere newSphere = (Sphere)info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0);
Heightmap oldHeightmap = (Heightmap)info.Skin1.GetPrimitiveOldWorld(info.IndexPrim1);
Heightmap newHeightmap = (Heightmap)info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1);
float newDist;
Vector3 normal;
newHeightmap.GetHeightAndNormal(out newDist, out normal,newSphere.Position);
if (newDist < collTolerance + newSphere.Radius)
{
float oldDist = oldHeightmap.GetHeight(oldSphere.Position);
float depth = oldSphere.Radius - oldDist;
// calc the world position when it just hit
Vector3 oldPt = oldSphere.Position - oldSphere.Radius * normal;
unsafe
{
SmallCollPointInfo ptInfo = new SmallCollPointInfo(oldPt - body0Pos, oldPt - body1Pos, depth);
collisionFunctor.CollisionNotify(ref info, ref normal, &ptInfo, 1);
}
}
}
示例7: CollDetect
/// <summary>
/// CollDetect
/// </summary>
/// <param name="infoOrig"></param>
/// <param name="collTolerance"></param>
/// <param name="collisionFunctor"></param>
public override void CollDetect(CollDetectInfo infoOrig, float collTolerance, CollisionFunctor collisionFunctor)
{
// get the skins in the order that we're expecting
CollDetectInfo info = infoOrig;
if (info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0).Type == this.Type1)
{
CollisionSkin skinSwap = info.Skin0;
info.Skin0 = info.Skin1;
info.Skin1 = skinSwap;
int primSwap = info.IndexPrim0;
info.IndexPrim0 = info.IndexPrim1;
info.IndexPrim1 = primSwap;
}
Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;
// todo - proper sweep test
Sphere oldSphere = info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0) as Sphere;
Sphere newSphere = info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0) as Sphere;
Box oldBox = info.Skin1.GetPrimitiveOldWorld(info.IndexPrim1) as Box;
Box newBox = info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1) as Box;
Vector3 oldBoxPoint;
Vector3 newBoxPoint;
float oldDist = oldBox.GetDistanceToPoint(out oldBoxPoint, oldSphere.Position);
float newDist = newBox.GetDistanceToPoint(out newBoxPoint, newSphere.Position);
// normally point will be outside
float oldDepth = oldSphere.Radius - oldDist;
float newDepth = newSphere.Radius - newDist;
if (System.Math.Max(oldDepth, newDepth) > -collTolerance)
{
Vector3 dir;
if (oldDist < -JiggleMath.Epsilon)
{
dir = oldBoxPoint - oldSphere.Position - oldBoxPoint;
JiggleMath.NormalizeSafe(ref dir);
}
else if (oldDist > JiggleMath.Epsilon)
{
dir = oldSphere.Position - oldBoxPoint;
JiggleMath.NormalizeSafe(ref dir);
}
else
{
dir = oldSphere.Position - oldBox.GetCentre();
JiggleMath.NormalizeSafe(ref dir);
}
unsafe
{
SmallCollPointInfo collInfo = new SmallCollPointInfo(oldBoxPoint - body0Pos,
oldBoxPoint - body1Pos, oldDepth);
collisionFunctor.CollisionNotify(ref info, ref dir, &collInfo, 1);
}
}
#endregion
}
示例8: CollDetect
/// <summary>
///
/// </summary>
/// <param name="info"></param>
/// <param name="collTolerance"></param>
/// <param name="collisionFunctor"></param>
public abstract void CollDetect(CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor);
示例9: CollDetectSweep
/// <summary>
/// CollDetectSweep
/// </summary>
/// <param name="info"></param>
/// <param name="collTolerance"></param>
/// <param name="collisionFunctor"></param>
private void CollDetectSweep(ref CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
{
// todo - proper swept test
// note - mesh is static and its triangles are in world space
TriangleMesh mesh = info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1) as TriangleMesh;
Box oldBox = info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0) as Box;
Box newBox = info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0) as Box;
Vector3 oldCentre;
oldBox.GetCentre(out oldCentre);
Vector3 newCentre;
newBox.GetCentre(out newCentre);
Vector3 delta;
Vector3.Subtract(ref newCentre, ref oldCentre, out delta);
float boxMinLen = 0.5f * System.Math.Min(newBox.SideLengths.X, System.Math.Min(newBox.SideLengths.Y, newBox.SideLengths.Z));
int nPositions = 1 + (int)(delta.Length / boxMinLen);
// limit the max positions...
if (nPositions > 50)
{
System.Diagnostics.Debug.WriteLine("Warning - clamping max positions in swept box test");
nPositions = 50;
}
if (nPositions == 1)
{
CollDetectBoxStaticMeshOverlap(oldBox, newBox, mesh,ref info, collTolerance, collisionFunctor);
}
else
{
BoundingBox bb = BoundingBoxHelper.InitialBox;
BoundingBoxHelper.AddBox(oldBox, ref bb);
BoundingBoxHelper.AddBox(newBox, ref bb);
unsafe
{
#if USE_STACKALLOC
int* potentialTriangles = stackalloc int[MaxLocalStackTris];
{
#else
int[] potTriArray = IntStackAlloc();
fixed( int* potentialTriangles = potTriArray)
{
#endif
int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);
if (numTriangles > 0)
{
for (int i = 0; i <= nPositions; ++i)
{
float frac = ((float)i) / nPositions;
Vector3 centre;
Vector3.Multiply(ref delta, frac, out centre);
Vector3.Add(ref centre, ref oldCentre, out centre);
Matrix4 orient = Matrix4Extensions.Add(Matrix4Extensions.Multiply(oldBox.Orientation, 1.0f - frac), Matrix4Extensions.Multiply(newBox.Orientation, frac));
Box box = new Box(centre - 0.5f * Vector3Extensions.TransformNormal(newBox.SideLengths, orient), orient, newBox.SideLengths);
// ideally we'd break if we get one collision... but that stops us getting multiple collisions
// when we enter a corner (two walls meeting) - can let us pass through
CollDetectBoxStaticMeshOverlap(oldBox, box, mesh, ref info, collTolerance, collisionFunctor);
}
}
#if USE_STACKALLOC
}
#else
}
FreeStackAlloc(potTriArray);
#endif
}
}
}
示例10: CollDetect
/// <summary>
/// Detect BoxHeightmap Collisions.
/// </summary>
/// <param name="infoOrig"></param>
/// <param name="collTolerance"></param>
/// <param name="collisionFunctor"></param>
public override void CollDetect(CollDetectInfo infoOrig, float collTolerance, CollisionFunctor collisionFunctor)
{
CollDetectInfo info = infoOrig;
if (info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0).Type == this.Type1)
{
CollisionSkin skinSwap = info.Skin0;
info.Skin0 = info.Skin1;
info.Skin1 = skinSwap;
int primSwap = info.IndexPrim0;
info.IndexPrim0 = info.IndexPrim1;
info.IndexPrim1 = primSwap;
}
Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;
// todo - proper swept test
Box oldBox = info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0) as Box;
Box newBox = info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0) as Box;
Heightmap oldHeightmap = info.Skin1.GetPrimitiveOldWorld(info.IndexPrim1) as Heightmap;
Heightmap newHeightmap = info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1) as Heightmap;
Vector3[] oldPts, newPts;
oldBox.GetCornerPoints(out oldPts);
newBox.GetCornerPoints(out newPts);
unsafe
{
#if USE_STACKALLOC
SmallCollPointInfo* collPts = stackalloc SmallCollPointInfo[MaxLocalStackSCPI];
#else
SmallCollPointInfo[] collPtArray = SCPIStackAlloc();
fixed (SmallCollPointInfo* collPts = collPtArray)
#endif
{
int numCollPts = 0;
Vector3 collNormal = Vector3.Zero;
for (int i = 0; i < 8; ++i)
{
Vector3 newPt = newPts[i];
float newDist;
Vector3 normal;
newHeightmap.GetHeightAndNormal(out newDist, out normal, newPt);
if (newDist < collTolerance)
{
Vector3 oldPt = oldPts[i];
float oldDist = oldHeightmap.GetHeight(oldPt);
#region REFERENCE: collPts.Add(new CollPointInfo(oldPt - body0Pos, oldPt - body1Pos, -oldDist));
Vector3 pt0;
Vector3 pt1;
Vector3.Subtract(ref oldPt, ref body0Pos, out pt0);
Vector3.Subtract(ref oldPt, ref body1Pos, out pt1);
if (numCollPts < MaxLocalStackSCPI)
{
collPts[numCollPts++] = new SmallCollPointInfo(ref pt0, ref pt1, -oldDist);
}
#endregion
#region REFERENCE: collNormal += normal;
Vector3.Add(ref collNormal, ref normal, out collNormal);
#endregion
}
}
if (numCollPts > 0)
{
JiggleMath.NormalizeSafe(ref collNormal);
collisionFunctor.CollisionNotify(ref info, ref collNormal, collPts, numCollPts);
}
}
#if !USE_STACKALLOC
FreeStackAlloc(collPtArray);
#endif
}
}
示例11: DetectAllCollisions
/// <summary>
/// As DetectCollisions but detects for all bodies, testing each pair
/// only once
/// </summary>
/// <param name="bodies"></param>
/// <param name="collisionFunctor"></param>
/// <param name="collisionPredicate"></param>
/// <param name="collTolerance"></param>
public abstract void DetectAllCollisions(List<Body> bodies, CollisionFunctor collisionFunctor,
CollisionSkinPredicate2 collisionPredicate, float collTolerance);
示例12: CollDetectSphereStaticMeshSweep
internal static void CollDetectSphereStaticMeshSweep(BoundingSphere oldSphere, BoundingSphere newSphere, TriangleMesh mesh,
CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
{
// really use a swept test - or overlap?
Vector3 delta = newSphere.Center - oldSphere.Center;
if (delta.LengthSquared() < (0.25f * newSphere.Radius * newSphere.Radius))
{
CollDetectSphereStaticMeshOverlap(oldSphere, newSphere, mesh, info, collTolerance, collisionFunctor);
}
else
{
Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;
float sphereTolR = collTolerance + oldSphere.Radius;
float sphereToR2 = sphereTolR * sphereTolR;
Vector3 collNormal = Vector3.Zero;
BoundingBox bb = BoundingBoxHelper.InitialBox;
BoundingBoxHelper.AddSphere(oldSphere, ref bb);
BoundingBoxHelper.AddSphere(newSphere, ref bb);
// get the spheres centers in triangle mesh space
Vector3 newSphereCen = Vector3.Transform(newSphere.Center, mesh.InverseTransformMatrix);
Vector3 oldSphereCen = Vector3.Transform(oldSphere.Center, mesh.InverseTransformMatrix);
unsafe
{
#if USE_STACKALLOC
SmallCollPointInfo* collPts = stackalloc SmallCollPointInfo[MaxLocalStackSCPI];
int* potentialTriangles = stackalloc int[MaxLocalStackTris];
{
{
#else
SmallCollPointInfo[] collPtArray = SCPIStackAlloc();
fixed (SmallCollPointInfo* collPts = collPtArray)
{
int[] potTriArray = IntStackAlloc();
fixed( int* potentialTriangles = potTriArray)
{
#endif
int numCollPts = 0;
int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);
for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
{
// first test the old sphere for being on the wrong side
IndexedTriangle meshTriangle = mesh.GetTriangle(potentialTriangles[iTriangle]);
float distToCentreOld = meshTriangle.Plane.DotCoordinate(oldSphereCen);
if (distToCentreOld <= 0.0f)
continue;
// now test the new sphere for being clear
float distToCentreNew = meshTriangle.Plane.DotCoordinate(newSphereCen);
if (distToCentreNew > sphereTolR)
continue;
int i0, i1, i2;
meshTriangle.GetVertexIndices(out i0, out i1, out i2);
Triangle triangle = new Triangle(mesh.GetVertex(i0), mesh.GetVertex(i1), mesh.GetVertex(i2));
// If the old sphere is intersecting, just use that result
float s, t;
float d2 = Distance.PointTriangleDistanceSq(out s, out t, oldSphereCen, triangle);
if (d2 < sphereToR2)
{
float dist = (float)System.Math.Sqrt(d2);
float depth = oldSphere.Radius - dist;
Vector3 triangleN = triangle.Normal;
Vector3 normSafe = oldSphereCen - triangle.GetPoint(s, t);
JiggleMath.NormalizeSafe(ref normSafe);
Vector3 collisionN = (dist > float.Epsilon) ? normSafe : triangleN;
// since impulse gets applied at the old position
Vector3 pt = oldSphere.Center - oldSphere.Radius * collisionN;
if (numCollPts < MaxLocalStackSCPI)
{
collPts[numCollPts++] = new SmallCollPointInfo(pt - body0Pos, pt - body1Pos, depth);
}
collNormal += collisionN;
}
else if (distToCentreNew < distToCentreOld)
{
// old sphere is not intersecting - do a sweep, but only if the sphere is moving into the
// triangle
Vector3 pt, N; // CHECK THIS
float depth;
if (Intersection.SweptSphereTriangleIntersection(out pt, out N, out depth, oldSphere, newSphere, triangle,
distToCentreOld, distToCentreNew, Intersection.EdgesToTest.EdgeAll, Intersection.CornersToTest.CornerAll))
{
// collision point etc must be relative to the old position because that's
//where the impulses are applied
float dist = (float)System.Math.Sqrt(d2);
float depth2 = oldSphere.Radius - dist;
//.........这里部分代码省略.........
示例13: CollDetectCapsuleStaticMeshOverlap
/// <summary>
/// CollDetectCapsuleStaticMeshOverlap
/// </summary>
/// <param name="oldCapsule"></param>
/// <param name="newCapsule"></param>
/// <param name="mesh"></param>
/// <param name="info"></param>
/// <param name="collTolerance"></param>
/// <param name="collisionFunctor"></param>
private void CollDetectCapsuleStaticMeshOverlap(Capsule oldCapsule, Capsule newCapsule,
TriangleMesh mesh, CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
{
Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;
float capsuleTolR = collTolerance + newCapsule.Radius;
float capsuleTolR2 = capsuleTolR * capsuleTolR;
Vector3 collNormal = Vector3.Zero;
BoundingBox bb = BoundingBoxHelper.InitialBox;
BoundingBoxHelper.AddCapsule(newCapsule, ref bb);
unsafe
{
#if USE_STACKALLOC
SmallCollPointInfo* collPts = stackalloc SmallCollPointInfo[MaxLocalStackSCPI];
int* potentialTriangles = stackalloc int[MaxLocalStackTris];
{
{
#else
SmallCollPointInfo[] collPtArray = SCPIStackAlloc();
fixed (SmallCollPointInfo* collPts = collPtArray)
{
int[] potTriArray = IntStackAlloc();
fixed (int* potentialTriangles = potTriArray)
{
#endif
int numCollPts = 0;
int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);
Vector3 capsuleStart = newCapsule.Position;
Vector3 capsuleEnd = newCapsule.GetEnd();
Matrix4 meshInvTransform = mesh.InverseTransformMatrix;
Vector3 meshSpaceCapsuleStart = Vector3.Transform(capsuleStart, meshInvTransform);
Vector3 meshSpaceCapsuleEnd = Vector3.Transform(capsuleEnd, meshInvTransform);
for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
{
IndexedTriangle meshTriangle = mesh.GetTriangle(potentialTriangles[iTriangle]);
// we do the plane test using the capsule in mesh space
float distToStart = meshTriangle.Plane.DotCoordinate(meshSpaceCapsuleStart);
float distToEnd = meshTriangle.Plane.DotCoordinate(meshSpaceCapsuleEnd);
// BEN-BUG-FIX: Fixed by replacing 0.0F with -capsuleTolR.
if ((distToStart > capsuleTolR && distToEnd > capsuleTolR)
|| (distToStart < -capsuleTolR && distToEnd < -capsuleTolR))
continue;
// we now transform the triangle into world space (we could keep leave the mesh alone
// but at this point 3 vector transforms is probably not a major slow down)
int i0, i1, i2;
meshTriangle.GetVertexIndices(out i0, out i1, out i2);
Vector3 triVec0;
Vector3 triVec1;
Vector3 triVec2;
mesh.GetVertex(i0, out triVec0);
mesh.GetVertex(i1, out triVec1);
mesh.GetVertex(i2, out triVec2);
// Deano move tri into world space
Matrix4 transformMatrix = mesh.TransformMatrix;
Vector3.Transform(ref triVec0, ref transformMatrix, out triVec0);
Vector3.Transform(ref triVec1, ref transformMatrix, out triVec1);
Vector3.Transform(ref triVec2, ref transformMatrix, out triVec2);
Triangle triangle = new Triangle(ref triVec0, ref triVec1, ref triVec2);
Segment seg = new Segment(capsuleStart, capsuleEnd - capsuleStart);
float tS, tT0, tT1;
float d2 = Distance.SegmentTriangleDistanceSq(out tS, out tT0, out tT1, seg, triangle);
if (d2 < capsuleTolR2)
{
Vector3 oldCapsuleStart = oldCapsule.Position;
Vector3 oldCapsuleEnd = oldCapsule.GetEnd();
Segment oldSeg = new Segment(oldCapsuleStart, oldCapsuleEnd - oldCapsuleStart);
d2 = Distance.SegmentTriangleDistanceSq(out tS, out tT0, out tT1, oldSeg, triangle);
// report result from old position
float dist = (float)System.Math.Sqrt(d2);
float depth = oldCapsule.Radius - dist;
Vector3 pt = triangle.GetPoint(tT0, tT1);
Vector3 collisionN = (d2 > JiggleMath.Epsilon) ? JiggleMath.NormalizeSafe(oldSeg.GetPoint(tS) - pt) :
meshTriangle.Plane.Normal;
if (numCollPts < MaxLocalStackSCPI)
{
//.........这里部分代码省略.........
示例14: CollDetectSweep
/// <summary>
/// CollDetectSweep
/// </summary>
/// <param name="info"></param>
/// <param name="collTolerance"></param>
/// <param name="collisionFunctor"></param>
private void CollDetectSweep(CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
{
Capsule oldCapsule = info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0) as Capsule;
Capsule newCapsule = info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0) as Capsule;
// todo - proper swept test
// note - mesh is static and its triangles are in world space
TriangleMesh mesh = info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1) as TriangleMesh;
CollDetectCapsulseStaticMeshSweep(oldCapsule, newCapsule, mesh, info, collTolerance, collisionFunctor);
}
示例15: CollDetectCapsulseStaticMeshSweep
/// <summary>
/// CollDetectCapsulseStaticMeshSweep
/// </summary>
/// <param name="oldCapsule"></param>
/// <param name="newCapsule"></param>
/// <param name="mesh"></param>
/// <param name="info"></param>
/// <param name="collTolerance"></param>
/// <param name="collisionFunctor"></param>
private void CollDetectCapsulseStaticMeshSweep(Capsule oldCapsule, Capsule newCapsule,
TriangleMesh mesh, CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
{
// really use a swept test - or overlap?
Vector3 delta = newCapsule.Position - oldCapsule.Position;
if (delta.LengthSquared < (0.25f * newCapsule.Radius * newCapsule.Radius))
{
CollDetectCapsuleStaticMeshOverlap(oldCapsule, newCapsule, mesh, info, collTolerance, collisionFunctor);
}
else
{
float capsuleLen = oldCapsule.Length;
float capsuleRadius = oldCapsule.Radius;
int nSpheres = 2 + (int)(capsuleLen / (2.0f * oldCapsule.Radius));
for (int iSphere = 0; iSphere < nSpheres; ++iSphere)
{
float offset = ((float)iSphere) * capsuleLen / ((float)nSpheres - 1.0f);
BoundingSphere oldSphere = new BoundingSphere(oldCapsule.Position + oldCapsule.Orientation.Backward() * offset, capsuleRadius);
BoundingSphere newSphere = new BoundingSphere(newCapsule.Position + newCapsule.Orientation.Backward() * offset, capsuleRadius);
CollDetectSphereStaticMesh.CollDetectSphereStaticMeshSweep(oldSphere, newSphere, mesh, info, collTolerance, collisionFunctor);
}
}
}