Пример #1
0
        public RayCollisionInfo getRayCollisionInfo(Vector rayStart, Vector rayDir)
        {
            VectorSet set      = calculateTrans();
            Vector?   pClosest = null;
            Edge      eClosest = null;

            if (rayDir.Length > 0)
            {
                float distance = float.MaxValue;

                set.forEachEdge(edge =>
                {
                    float x = rayStart.X * edge.Unit.Y - rayStart.Y * edge.Unit.X - edge.V1.X * edge.Unit.Y + edge.V1.Y * edge.Unit.X;
                    x      /= rayDir.Y * edge.Unit.X - rayDir.X * edge.Unit.Y;

                    float y = rayStart.X * rayDir.Y - rayStart.Y * rayDir.X + rayDir.X * edge.V1.Y - rayDir.Y * edge.V1.X;
                    y      /= rayDir.Y * edge.Unit.X - rayDir.X * edge.Unit.Y;

                    if (x > 0 && y > 0 && y < edge.Length)
                    {
                        Vector p           = edge.V1 + y * edge.Unit;
                        float testDistance = (p - rayStart).Length;

                        if (testDistance < distance)
                        {
                            distance = testDistance;
                            pClosest = p;
                            eClosest = edge;
                        }
                    }
                });
            }

            if (pClosest.HasValue)
            {
                return(new RayCollisionInfo(rayStart, rayDir, eClosest.Normal, pClosest.Value));
            }
            else
            {
                return(null);
            }
        }
Пример #2
0
        /// <summary>
        /// Run an SAT test against the other convex object
        /// </summary>
        /// <param name="conv"></param>
        /// <returns></returns>
        public CollisionInfo getCollisionInfo(Convex conv)
        {
            List <Vector> axisSet   = new List <Vector>();
            VectorSet     aSet      = calculateTrans();
            VectorSet     bSet      = conv.calculateTrans();
            Vector        mtv       = Vector.One * 10000;
            bool          colliding = true;

            aSet.forEachEdge(e => axisSet.Add(e.Normal));
            bSet.forEachEdge(e => axisSet.Add(e.Normal));

            foreach (Vector a in axisSet)
            {
                //create the axis
                Vector axis = a.Unit;

                float aMin = float.MaxValue, aMax = float.MinValue;
                float bMin = float.MaxValue, bMax = float.MinValue;

                //project conv, a, onto axis
                aSet.forEachVector(v =>
                {
                    float p = (v).dot(axis);
                    if (p < aMin)
                    {
                        aMin = p;
                    }
                    if (p > aMax)
                    {
                        aMax = p;
                    }
                });

                //project conv, b, onto axis
                bSet.forEachVector(v =>
                {
                    float p = (v).dot(axis);
                    if (p < bMin)
                    {
                        bMin = p;
                    }
                    if (p > bMax)
                    {
                        bMax = p;
                    }
                });

                //are a and b overlapping?
                if ((aMin > bMin && aMin < bMax) ||
                    (aMax > bMin && aMax < bMax) ||
                    (bMin > aMin && bMin < aMax) ||
                    (bMax > aMin && bMax < aMax)
                    )
                {
                    //they are overlapping
                    //calculate overlap vector
                    float overlap = Math.Min(aMax, bMax) - Math.Max(aMin, bMin);
                    if (aMax < bMax)
                    {
                        overlap *= -1;
                    }


                    if (Math.Abs(overlap) < mtv.Length)
                    {
                        mtv = axis * overlap;
                    }
                }
                else
                {
                    //they are not overlapping. no collision can be occuring.
                    colliding = false;
                    break;
                }
            }



            CollisionInfo collInfo = new CollisionInfo(mtv);

            if (!colliding)
            {
                return(null);
            }
            else
            {
                return(collInfo);
            }
        }