Пример #1
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);
                            }
                        }
                    }
                }
            }
        }