Ejemplo n.º 1
0
        internal static Vector3ex.Information GetInformation(IList <Vector3> points, float epsilon)
        {
            if (points == null)
            {
                return(null);
            }
            int count = points.Count;

            if (count == 0 || epsilon < 0f)
            {
                return(null);
            }
            Vector3ex.Information information = new Vector3ex.Information();
            information.ExtremeCCW = false;
            float num2;
            float num  = num2 = points[0].x;
            int   num3 = 0;
            int   num4 = 0;
            float num6;
            float num5 = num6 = points[0].y;
            int   num7 = 0;
            int   num8 = 0;
            float num10;
            float num9  = num10 = points[0].z;
            int   num11 = 0;
            int   num12 = 0;

            for (int i = 1; i < count; i++)
            {
                float num13 = points[i].x;
                if (num13 < num2)
                {
                    num2 = num13;
                    num3 = i;
                }
                else if (num13 > num)
                {
                    num  = num13;
                    num4 = i;
                }
                num13 = points[i].y;
                if (num13 < num6)
                {
                    num6 = num13;
                    num7 = i;
                }
                else if (num13 > num5)
                {
                    num5 = num13;
                    num8 = i;
                }
                num13 = points[i].z;
                if (num13 < num10)
                {
                    num10 = num13;
                    num11 = i;
                }
                else if (num13 > num9)
                {
                    num9  = num13;
                    num12 = i;
                }
            }
            information.Min.x      = num2;
            information.Min.y      = num6;
            information.Min.z      = num10;
            information.Max.x      = num;
            information.Max.y      = num5;
            information.Max.z      = num9;
            information.MaxRange   = num - num2;
            information.Extreme[0] = num3;
            information.Extreme[1] = num4;
            float num14 = num5 - num6;

            if (num14 > information.MaxRange)
            {
                information.MaxRange   = num14;
                information.Extreme[0] = num7;
                information.Extreme[1] = num8;
            }
            num14 = num9 - num10;
            if (num14 > information.MaxRange)
            {
                information.MaxRange   = num14;
                information.Extreme[0] = num11;
                information.Extreme[1] = num12;
            }
            information.Origin = points[information.Extreme[0]];
            if (information.MaxRange < epsilon)
            {
                information.Dimension    = 0;
                information.Extreme[1]   = information.Extreme[0];
                information.Extreme[2]   = information.Extreme[0];
                information.Extreme[3]   = information.Extreme[0];
                information.Direction[0] = Vector3ex.Zero;
                information.Direction[1] = Vector3ex.Zero;
                information.Direction[2] = Vector3ex.Zero;
                return(information);
            }
            information.Direction[0] = points[information.Extreme[1]] - information.Origin;
            information.Direction[0].Normalize();
            float num15 = 0f;

            information.Extreme[2] = information.Extreme[0];
            float d;

            for (int j = 0; j < count; j++)
            {
                Vector3 vector = points[j] - information.Origin;
                d = information.Direction[0].Dot(vector);
                float num16 = (vector - d * information.Direction[0]).magnitude;
                if (num16 > num15)
                {
                    num15 = num16;
                    information.Extreme[2] = j;
                }
            }
            if (num15 < epsilon * information.MaxRange)
            {
                information.Dimension  = 1;
                information.Extreme[2] = information.Extreme[1];
                information.Extreme[3] = information.Extreme[1];
                return(information);
            }
            information.Direction[1] = points[information.Extreme[2]] - information.Origin;
            d = information.Direction[0].Dot(information.Direction[1]);
            information.Direction[1] -= d * information.Direction[0];
            information.Direction[1].Normalize();
            information.Direction[2] = information.Direction[0].Cross(information.Direction[1]);
            num15 = 0f;
            float num17 = 0f;

            information.Extreme[3] = information.Extreme[0];
            for (int k = 0; k < count; k++)
            {
                Vector3 value = points[k] - information.Origin;
                float   num16 = information.Direction[2].Dot(value);
                float   num18 = Mathf.Sign(num16);
                num16 = Mathf.Abs(num16);
                if (num16 > num15)
                {
                    num15 = num16;
                    num17 = num18;
                    information.Extreme[3] = k;
                }
            }
            if (num15 < epsilon * information.MaxRange)
            {
                information.Dimension  = 2;
                information.Extreme[3] = information.Extreme[2];
                return(information);
            }
            information.Dimension  = 3;
            information.ExtremeCCW = (num17 > 0f);
            return(information);
        }
        public static bool Create(IList <Vector3> vertices, float epsilon, out int dimension, out int[] indices)
        {
            Vector3ex.Information information = Vector3ex.GetInformation(vertices, epsilon);
            if (information == null)
            {
                dimension = -1;
                indices   = null;
                return(false);
            }
            int count = vertices.Count;

            if (information.Dimension == 0)
            {
                dimension = 0;
                int[] array = new int[1];
                indices = array;
                return(true);
            }
            if (information.Dimension == 1)
            {
                float[] array2 = new float[count];
                Vector3 origin = information.Origin;
                Vector3 vector = information.Direction[0];
                for (int i = 0; i < count; i++)
                {
                    Vector3 value = vertices[i] - origin;
                    array2[i] = vector.Dot(value);
                }
                ConvexHull1.Create(array2, epsilon, out dimension, out indices);
                return(true);
            }
            if (information.Dimension == 2)
            {
                Vector2[] array3  = new Vector2[count];
                Vector3   origin2 = information.Origin;
                Vector3   vector2 = information.Direction[0];
                Vector3   vector3 = information.Direction[1];
                for (int j = 0; j < count; j++)
                {
                    Vector3 value2 = vertices[j] - origin2;
                    array3[j] = new Vector2(vector2.Dot(value2), vector3.Dot(value2));
                }
                return(ConvexHull2.Create(array3, epsilon, out dimension, out indices));
            }
            dimension = 3;
            Vector3[] array4 = new Vector3[count];
            Vector3   min    = information.Min;
            float     d      = 1f / information.MaxRange;

            for (int k = 0; k < count; k++)
            {
                array4[k] = (vertices[k] - min) * d;
            }
            Query3 query = new Query3(array4);
            int    v     = information.Extreme[0];
            int    num   = information.Extreme[1];
            int    num2  = information.Extreme[2];
            int    num3  = information.Extreme[3];

            ConvexHull3.Triangle triangle;
            ConvexHull3.Triangle triangle2;
            ConvexHull3.Triangle triangle3;
            ConvexHull3.Triangle triangle4;
            if (information.ExtremeCCW)
            {
                triangle  = new ConvexHull3.Triangle(v, num, num3);
                triangle2 = new ConvexHull3.Triangle(v, num2, num);
                triangle3 = new ConvexHull3.Triangle(v, num3, num2);
                triangle4 = new ConvexHull3.Triangle(num, num2, num3);
                triangle.AttachTo(triangle2, triangle4, triangle3);
                triangle2.AttachTo(triangle3, triangle4, triangle);
                triangle3.AttachTo(triangle, triangle4, triangle2);
                triangle4.AttachTo(triangle2, triangle3, triangle);
            }
            else
            {
                triangle  = new ConvexHull3.Triangle(v, num3, num);
                triangle2 = new ConvexHull3.Triangle(v, num, num2);
                triangle3 = new ConvexHull3.Triangle(v, num2, num3);
                triangle4 = new ConvexHull3.Triangle(num, num3, num2);
                triangle.AttachTo(triangle3, triangle4, triangle2);
                triangle2.AttachTo(triangle, triangle4, triangle3);
                triangle3.AttachTo(triangle2, triangle4, triangle);
                triangle4.AttachTo(triangle, triangle3, triangle2);
            }
            HashSet <ConvexHull3.Triangle> hashSet = new HashSet <ConvexHull3.Triangle>();

            hashSet.Add(triangle);
            hashSet.Add(triangle2);
            hashSet.Add(triangle3);
            hashSet.Add(triangle4);
            for (int l = 0; l < count; l++)
            {
                if (!ConvexHull3.Update(hashSet, l, query))
                {
                    dimension = -1;
                    indices   = null;
                    return(false);
                }
            }
            ConvexHull3.ExtractIndices(hashSet, out indices);
            return(true);
        }