public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut) { CollisionObject convexBody = _isSwapped ? bodyB : bodyA; CollisionObject triBody = _isSwapped ? bodyA : bodyB; if (triBody.CollisionShape.IsConcave) { CollisionObject triOb = triBody; ConcaveShape concaveShape = triOb.CollisionShape as ConcaveShape; if (convexBody.CollisionShape.IsConvex) { float collisionMarginTriangle = concaveShape.Margin; resultOut.SetPersistentManifold(_convexTriangleCallback.Manifold); _convexTriangleCallback.SetTimeStepAndCounters(collisionMarginTriangle, dispatchInfo, resultOut); //Disable persistency. previously, some older algorithm calculated all contacts in one go, so you can clear it here. //m_dispatcher->clearManifold(m_btConvexTriangleCallback.m_manifoldPtr); _convexTriangleCallback.Manifold.SetBodies(convexBody, triBody); concaveShape.ProcessAllTriangles(_convexTriangleCallback, _convexTriangleCallback.AabbMin, _convexTriangleCallback.AabbMax); } } }
public override float CalculateTimeOfImpact(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut) { CollisionObject convexbody = _isSwapped ? bodyB : bodyA; CollisionObject triBody = _isSwapped ? bodyA : bodyB; //quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast) //only perform CCD above a certain threshold, this prevents blocking on the long run //because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame... float squareMot0 = (convexbody.InterpolationWorldTransform.Translation - convexbody.WorldTransform.Translation).LengthSquared(); if (squareMot0 < convexbody.CcdSquareMotionThreshold) { return(1); } Matrix triInv = MathHelper.InvertMatrix(triBody.WorldTransform); Matrix convexFromLocal = triInv * convexbody.WorldTransform; Matrix convexToLocal = triInv * convexbody.InterpolationWorldTransform; if (triBody.CollisionShape.IsConcave) { Vector3 rayAabbMin = convexFromLocal.Translation; MathHelper.SetMin(ref rayAabbMin, convexToLocal.Translation); Vector3 rayAabbMax = convexFromLocal.Translation; MathHelper.SetMax(ref rayAabbMax, convexToLocal.Translation); float ccdRadius0 = convexbody.CcdSweptSphereRadius; rayAabbMin -= new Vector3(ccdRadius0, ccdRadius0, ccdRadius0); rayAabbMax += new Vector3(ccdRadius0, ccdRadius0, ccdRadius0); float curHitFraction = 1f; //is this available? LocalTriangleSphereCastCallback raycastCallback = new LocalTriangleSphereCastCallback(convexFromLocal, convexToLocal, convexbody.CcdSweptSphereRadius, curHitFraction); raycastCallback.HitFraction = convexbody.HitFraction; CollisionObject concavebody = triBody; ConcaveShape triangleMesh = concavebody.CollisionShape as ConcaveShape; if (triangleMesh != null) { triangleMesh.ProcessAllTriangles(raycastCallback, rayAabbMin, rayAabbMax); } if (raycastCallback.HitFraction < convexbody.HitFraction) { convexbody.HitFraction = raycastCallback.HitFraction; return(raycastCallback.HitFraction); } } return(1); }