예제 #1
0
        public override bool ConvexCast(ConvexShape castShape, ref RigidTransform startingTransform, ref Vector3f sweep, out RayHit hit)
        {
            hit = new RayHit();
            BoundingBox boundingBox;

            castShape.GetSweptBoundingBox(ref startingTransform, ref sweep, out boundingBox);
            var tri         = PhysicsThreadResources.GetTriangle();
            var hitElements = CommonResources.GetIntList();

            if (triangleMesh.Tree.GetOverlaps(boundingBox, hitElements))
            {
                hit.T = float.MaxValue;
                for (int i = 0; i < hitElements.Count; i++)
                {
                    triangleMesh.Data.GetTriangle(hitElements[i], out tri.vA, out tri.vB, out tri.vC);
                    Vector3f center;
                    Vector3f.Add(ref tri.vA, ref tri.vB, out center);
                    Vector3f.Add(ref center, ref tri.vC, out center);
                    Vector3f.Multiply(ref center, 1f / 3f, out center);
                    Vector3f.Subtract(ref tri.vA, ref center, out tri.vA);
                    Vector3f.Subtract(ref tri.vB, ref center, out tri.vB);
                    Vector3f.Subtract(ref tri.vC, ref center, out tri.vC);
                    tri.MaximumRadius = tri.vA.LengthSquared;
                    float radius = tri.vB.LengthSquared;
                    if (tri.MaximumRadius < radius)
                    {
                        tri.MaximumRadius = radius;
                    }
                    radius = tri.vC.LengthSquared;
                    if (tri.MaximumRadius < radius)
                    {
                        tri.MaximumRadius = radius;
                    }
                    tri.MaximumRadius   = (float)Math.Sqrt(tri.MaximumRadius);
                    tri.collisionMargin = 0;
                    var triangleTransform = new RigidTransform {
                        Orientation = Quaternion.Identity, Position = center
                    };
                    RayHit tempHit;
                    if (MPRToolbox.Sweep(castShape, tri, ref sweep, ref Toolbox.ZeroVector, ref startingTransform, ref triangleTransform, out tempHit) && tempHit.T < hit.T)
                    {
                        hit = tempHit;
                    }
                }
                tri.MaximumRadius = 0;
                PhysicsThreadResources.GiveBack(tri);
                CommonResources.GiveBack(hitElements);
                return(hit.T != float.MaxValue);
            }
            PhysicsThreadResources.GiveBack(tri);
            CommonResources.GiveBack(hitElements);
            return(false);
        }
예제 #2
0
        /// <summary>
        /// <para>Casts a convex shape against the space.</para>
        /// <para>Convex casts are sensitive to length; avoid extremely long convex casts for better stability and performance.</para>
        /// </summary>
        /// <param name="castShape">Shape to cast.</param>
        /// <param name="startingTransform">Initial transform of the shape.</param>
        /// <param name="sweep">Sweep to apply to the shape. Avoid extremely long convex casts for better stability and performance.</param>
        /// <param name="filter">Delegate to prune out hit candidates before performing a cast against them. Return true from the filter to process an entry or false to ignore the entry.</param>
        /// <param name="outputCastResults">Hit data, if any.</param>
        /// <returns>Whether or not the cast hit anything.</returns>
        public bool ConvexCast(ConvexShape castShape, ref RigidTransform startingTransform, ref Vector3 sweep, Func <BroadPhaseEntry, bool> filter, IList <RayCastResult> outputCastResults)
        {
            var         overlappedElements = PhysicsResources.GetBroadPhaseEntryList();
            BoundingBox boundingBox;

            castShape.GetSweptBoundingBox(ref startingTransform, ref sweep, out boundingBox);

            BroadPhase.QueryAccelerator.GetEntries(boundingBox, overlappedElements);
            for (int i = 0; i < overlappedElements.Count; ++i)
            {
                RayHit hit;
                if (overlappedElements.Elements[i].ConvexCast(castShape, ref startingTransform, ref sweep, filter, out hit))
                {
                    outputCastResults.Add(new RayCastResult {
                        HitData = hit, HitObject = overlappedElements.Elements[i]
                    });
                }
            }
            PhysicsResources.GiveBack(overlappedElements);
            return(outputCastResults.Count > 0);
        }