Exemplo n.º 1
0
        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);
                }
            }
        }
Exemplo n.º 2
0
        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);
        }