예제 #1
0
        private static Intersection TestIntersectionSphereSphere(Hitbox caller, Hitbox collider, Vector3 offsetCaller)
        {
            Intersection i    = null;
            Vector3      diff = collider.GetCenter() - (caller.GetCenter() + offsetCaller);

            float diffLength     = diff.LengthFast;
            float radiusCaller   = caller.Owner.Scale.X / 2;
            float radiusCollider = collider.Owner.Scale.X / 2;

            float diffCollision = diffLength - (radiusCollider + radiusCaller);

            if (diffCollision < 0)
            {
                // collision detected!
                diff.NormalizeFast();

                Vector3 mtv   = diff * diffCollision;
                Vector3 mtvUp = new Vector3(0, (caller.GetCenter() + offsetCaller).Y >= collider.GetCenter().Y ? -diffCollision : diffCollision, 0); // approximated!
                Vector3 collisionSurfaceNormal = Vector3.NormalizeFast((caller.GetCenter() + offsetCaller) - collider.GetCenter());
                i = new Intersection(collider.Owner, caller, collider, mtv, mtvUp, "KWSphere", collisionSurfaceNormal);
                return(i);
            }

            return(i);
        }
예제 #2
0
        /// <summary>
        /// Berechnet das Volumen der Kollision (wie viel von Objekt B schneidet sich mit Objekt A?)
        /// </summary>
        /// <returns>IntersectionVolume-Instanz mit genaueren Angaben zum Volumen</returns>
        public IntersectionVolume CalculateVolume()
        {
            if (mHitboxCaller.Owner.IsSpherePerfect())
            {
                mHitboxCaller.UpdateSphereForClipping();
            }
            if (mHitboxCollider.Owner.IsSpherePerfect())
            {
                mHitboxCollider.UpdateSphereForClipping();
            }

            List <Vector3> volumeVertices = Hitbox.ClipFaces(mHitboxCaller, mHitboxCollider);

            volumeVertices.AddRange(Hitbox.ClipFaces(mHitboxCollider, mHitboxCaller));
            if (volumeVertices.Count > 0)
            {
                IntersectionVolume volume = new IntersectionVolume(volumeVertices, mHitboxCaller.GetCenter());
                return(volume);
            }
            else
            {
                IntersectionVolume volume = new IntersectionVolume();
                return(volume);
            }
        }
예제 #3
0
        private static Intersection TestIntersectionConvexHullSphere(Hitbox caller, Hitbox collider, Vector3 offsetCaller)
        {
            float mtvDistance    = float.MaxValue;
            float mtvDirection   = 1;
            float mtvDistanceUp  = float.MaxValue;
            float mtvDirectionUp = 1;

            MTVTemp   = Vector3.Zero;
            MTVTempUp = Vector3.Zero;
            bool useSphereNormal = false;

            float   sphereRadius = collider.Owner.Scale.X / 2;
            Vector3 collisionSurfaceNormal = new Vector3(0, 0, 0);
            float   shape1Min, shape1Max, shape2Min, shape2Max;

            for (int i = 0; i < caller.mNormals.Length; i++)
            {
                SatTest(ref caller.mNormals[i], ref caller.mVertices, out shape1Min, out shape1Max, ref ZeroVector);
                shape2Min = Vector3.Dot(collider.GetCenter() - caller.mNormals[i] * sphereRadius, caller.mNormals[i]);
                shape2Max = Vector3.Dot(collider.GetCenter() + caller.mNormals[i] * sphereRadius, caller.mNormals[i]);

                if (!Overlaps(shape1Min, shape1Max, shape2Min, shape2Max))
                {
                    return(null);
                }
                else
                {
                    bool m = CalculateOverlap(ref caller.mNormals[i], ref shape1Min, ref shape1Max, ref shape2Min, ref shape2Max,
                                              ref mtvDistance, ref mtvDistanceUp, ref MTVTemp, ref MTVTempUp, ref mtvDirection, ref mtvDirectionUp, ref caller.mCenter, ref collider.mCenter, ref offsetCaller);
                    if (m)
                    {
                        collisionSurfaceNormal = Vector3.NormalizeFast((caller.mCenter + offsetCaller) - collider.mCenter);
                    }
                }
            }
            //collider is sphere:
            Vector3 sphereToHullDirectionVector = Vector3.NormalizeFast((caller.GetCenter() + offsetCaller) - collider.GetCenter());

            SatTest(ref sphereToHullDirectionVector, ref caller.mVertices, out shape1Min, out shape1Max, ref offsetCaller);
            shape2Min = Vector3.Dot(collider.GetCenter() - sphereToHullDirectionVector * sphereRadius, sphereToHullDirectionVector);
            shape2Max = Vector3.Dot(collider.GetCenter() + sphereToHullDirectionVector * sphereRadius, sphereToHullDirectionVector);

            if (!Overlaps(shape1Min, shape1Max, shape2Min, shape2Max))
            {
                return(null);
            }
            else
            {
                bool m = CalculateOverlap(ref sphereToHullDirectionVector, ref shape1Min, ref shape1Max, ref shape2Min, ref shape2Max,
                                          ref mtvDistance, ref mtvDistanceUp, ref MTVTemp, ref MTVTempUp, ref mtvDirection, ref mtvDirectionUp, ref caller.mCenter, ref collider.mCenter, ref offsetCaller);
                if (m)
                {
                    useSphereNormal = true;
                }
            }

            if (MTVTemp == Vector3.Zero)
            {
                return(null);
            }

            Intersection o = new Intersection(collider.Owner, caller, collider, MTVTemp, MTVTempUp, collider.mMesh.Name, useSphereNormal ? sphereToHullDirectionVector : collisionSurfaceNormal);

            return(o);
        }
예제 #4
0
        private static Intersection TestIntersectionSphereConvexHull(Hitbox caller, Hitbox collider, Vector3 offsetCaller)
        {
            float mtvDistance    = float.MaxValue;
            float mtvDirection   = 1;
            float mtvDistanceUp  = float.MaxValue;
            float mtvDirectionUp = 1;

            MTVTemp   = Vector3.Zero;
            MTVTempUp = Vector3.Zero;

            float sphereRadius = caller.Owner.Scale.X / 2;
            int   bestCollisionIndex = 0;
            float shape1Min, shape1Max, shape2Min, shape2Max;

            for (int i = 0; i < collider.mNormals.Length; i++)
            {
                shape1Min = Vector3.Dot((caller.GetCenter() + offsetCaller) - collider.mNormals[i] * sphereRadius, collider.mNormals[i]);
                shape1Max = Vector3.Dot((caller.GetCenter() + offsetCaller) + collider.mNormals[i] * sphereRadius, collider.mNormals[i]);
                SatTest(ref collider.mNormals[i], ref collider.mVertices, out shape2Min, out shape2Max, ref ZeroVector);

                if (!Overlaps(shape1Min, shape1Max, shape2Min, shape2Max))
                {
                    return(null);
                }
                else
                {
                    bool m = CalculateOverlap(ref collider.mNormals[i], ref shape1Min, ref shape1Max, ref shape2Min, ref shape2Max,
                                              ref mtvDistance, ref mtvDistanceUp, ref MTVTemp, ref MTVTempUp, ref mtvDirection, ref mtvDirectionUp, ref caller.mCenter, ref collider.mCenter, ref offsetCaller);
                    if (m)
                    {
                        bestCollisionIndex = i;
                    }
                }
            }
            Vector3 hullToSphereDirectionVector = Vector3.NormalizeFast((caller.GetCenter() + offsetCaller) - collider.GetCenter());

            shape1Min = Vector3.Dot((caller.GetCenter() + offsetCaller) - hullToSphereDirectionVector * sphereRadius, hullToSphereDirectionVector);
            shape1Max = Vector3.Dot((caller.GetCenter() + offsetCaller) + hullToSphereDirectionVector * sphereRadius, hullToSphereDirectionVector);
            SatTest(ref hullToSphereDirectionVector, ref collider.mVertices, out shape2Min, out shape2Max, ref ZeroVector);
            if (!Overlaps(shape1Min, shape1Max, shape2Min, shape2Max))
            {
                return(null);
            }
            else
            {
                bool m = CalculateOverlap(ref hullToSphereDirectionVector, ref shape1Min, ref shape1Max, ref shape2Min, ref shape2Max,
                                          ref mtvDistance, ref mtvDistanceUp, ref MTVTemp, ref MTVTempUp, ref mtvDirection, ref mtvDirectionUp, ref caller.mCenter, ref collider.mCenter, ref offsetCaller);
                if (m)
                {
                    bestCollisionIndex = -100;
                }
            }

            if (MTVTemp == Vector3.Zero)
            {
                return(null);
            }

            Intersection o = new Intersection(collider.Owner, caller, collider, MTVTemp, MTVTempUp, collider.mMesh.Name, bestCollisionIndex == -100 ? hullToSphereDirectionVector : collider.mNormals[bestCollisionIndex]);

            return(o);
        }