public override void ProcessCollision(
            CollisionObject bodyA,
            CollisionObject bodyB,
            DispatcherInfo dispatchInfo, ManifoldResult resultOut)
        {
            //Begin

            CollisionObject collisionObject = _isSwapped ? bodyB : bodyB;
            CollisionObject otherObject     = _isSwapped ? bodyA : bodyB;

            //Debug.Assert(collisionObject.getCollisionShape().isCompound());
            BulletDebug.Assert(collisionObject.CollisionShape.IsCompound);

            CompoundShape compoundShape = (CompoundShape)collisionObject.CollisionShape;

            int childrenNumber = _childCollisionAlgorithms.Count;

            for (int i = 0; i < childrenNumber; i++)
            {
                CompoundShape childShape = compoundShape.GetChildShape(i) as CompoundShape;

                Matrix         orgTransform = collisionObject.WorldTransform;
                CollisionShape orgShape     = collisionObject.CollisionShape;

                Matrix childTransform = compoundShape.GetChildTransform(i);
                Matrix newChildWorld  = orgTransform * childTransform;

                collisionObject.WorldTransform = newChildWorld;
                collisionObject.CollisionShape = childShape;
                _childCollisionAlgorithms[i].ProcessCollision(collisionObject, otherObject, dispatchInfo, resultOut);

                collisionObject.CollisionShape = orgShape;
                collisionObject.WorldTransform = orgTransform;
            }
        }
        public override float CalculateTimeOfImpact(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
        {
            CollisionObject collisionObject = _isSwapped ? bodyB : bodyA;
            CollisionObject otherObject     = _isSwapped ? bodyA : bodyB;

            BulletDebug.Assert(collisionObject.CollisionShape.IsCompound);

            CompoundShape compoundShape = (CompoundShape)collisionObject.CollisionShape;

            float hitFraction = 1.0f;

            for (int i = 0; i < _childCollisionAlgorithms.Count; i++)
            {
                CollisionShape childShape = compoundShape.GetChildShape(i);

                Matrix         orgTransform = collisionObject.WorldTransform;
                CollisionShape orgShape     = collisionObject.CollisionShape;

                Matrix childTransform = compoundShape.GetChildTransform(i);
                Matrix newChildWorld  = orgTransform * childTransform;
                collisionObject.WorldTransform = newChildWorld;

                collisionObject.CollisionShape = childShape;
                float frac = _childCollisionAlgorithms[i].CalculateTimeOfImpact(
                    collisionObject, otherObject, dispatchInfo, resultOut
                    );

                if (frac < hitFraction)
                {
                    hitFraction = frac;
                }

                collisionObject.CollisionShape = orgShape;
                collisionObject.WorldTransform = orgTransform;
            }

            return(hitFraction);
        }
Exemple #3
0
        // rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
        // In a future implementation, we consider moving the ray test as a virtual method in CollisionShape.
        // This allows more customization.
        public static void RayTestSingle(Matrix rayFromTrans, Matrix rayToTrans,
                                         CollisionObject collisionObject,
                                         CollisionShape collisionShape,
                                         Matrix colObjWorldTransform,
                                         RayResultCallback resultCallback)
        {
            SphereShape pointShape = new SphereShape(0.0f);

            if (collisionShape.IsConvex)
            {
                CastResult castResult = new CastResult();
                castResult.Fraction = 1f;                //??

                ConvexShape          convexShape   = collisionShape as ConvexShape;
                VoronoiSimplexSolver simplexSolver = new VoronoiSimplexSolver();
                SubsimplexConvexCast convexCaster  = new SubsimplexConvexCast(pointShape, convexShape, simplexSolver);
                //GjkConvexCast	convexCaster(&pointShape,convexShape,&simplexSolver);
                //ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);

                if (convexCaster.CalcTimeOfImpact(rayFromTrans, rayToTrans, colObjWorldTransform, colObjWorldTransform, castResult))
                {
                    //add hit
                    if (castResult.Normal.LengthSquared() > 0.0001f)
                    {
                        castResult.Normal.Normalize();
                        if (castResult.Fraction < resultCallback.ClosestHitFraction)
                        {
                            CollisionWorld.LocalRayResult localRayResult = new LocalRayResult
                                                                           (
                                collisionObject,
                                new LocalShapeInfo(),
                                castResult.Normal,
                                castResult.Fraction
                                                                           );

                            resultCallback.AddSingleResult(localRayResult);
                        }
                    }
                }
                else
                {
                    if (collisionShape.IsConcave)
                    {
                        TriangleMeshShape triangleMesh = collisionShape as TriangleMeshShape;

                        Matrix worldTocollisionObject = MathHelper.InvertMatrix(colObjWorldTransform);

                        Vector3 rayFromLocal = Vector3.TransformNormal(rayFromTrans.Translation, worldTocollisionObject);
                        Vector3 rayToLocal   = Vector3.TransformNormal(rayToTrans.Translation, worldTocollisionObject);

                        BridgeTriangleRaycastCallback rcb = new BridgeTriangleRaycastCallback(rayFromLocal, rayToLocal, resultCallback, collisionObject, triangleMesh);
                        rcb.HitFraction = resultCallback.ClosestHitFraction;

                        Vector3 rayAabbMinLocal = rayFromLocal;
                        MathHelper.SetMin(ref rayAabbMinLocal, rayToLocal);
                        Vector3 rayAabbMaxLocal = rayFromLocal;
                        MathHelper.SetMax(ref rayAabbMaxLocal, rayToLocal);

                        triangleMesh.ProcessAllTriangles(rcb, rayAabbMinLocal, rayAabbMaxLocal);
                    }
                    else
                    {
                        //todo: use AABB tree or other BVH acceleration structure!
                        if (collisionShape.IsCompound)
                        {
                            CompoundShape compoundShape = collisionShape as CompoundShape;
                            for (int i = 0; i < compoundShape.ChildShapeCount; i++)
                            {
                                Matrix         childTrans          = compoundShape.GetChildTransform(i);
                                CollisionShape childCollisionShape = compoundShape.GetChildShape(i);
                                Matrix         childWorldTrans     = colObjWorldTransform * childTrans;
                                RayTestSingle(rayFromTrans, rayToTrans,
                                              collisionObject,
                                              childCollisionShape,
                                              childWorldTrans,
                                              resultCallback);
                            }
                        }
                    }
                }
            }
        }