Пример #1
0
        // Split this Face with given Plane
        public bool Split(Plane inPlane, out Face outFront, out Face outBack)
        {
            outFront = new Face();
            outBack  = new Face();

            float[]      distance = new float[vertices.Length + 1];
            EPlaneSide[] side     = new EPlaneSide[vertices.Length + 1];


            for (int i = 0; i < vertices.Length; ++i)
            {
                distance[i] = inPlane.GetDistanceToPoint(vertices[i]);
                side[i]     = Side(inPlane, vertices[i]);
            }

            distance[vertices.Length] = distance[0];
            side[vertices.Length]     = side[0];

            for (int i = 0; i < vertices.Length; ++i)
            {
                // if we lie on plane, add them to both
                if (side[i] == EPlaneSide.Side_Planar)
                {
                    outFront.AddVertex(vertices[i], uv[i]);
                    outBack.AddVertex(vertices[i], uv[i]);
                    // nothing todo with this vertex
                    continue;
                }

                // if we are on the front, add it to front face
                if (side[i] == EPlaneSide.Side_Front)
                {
                    outFront.AddVertex(vertices[i], uv[i]);
                }
                // if we are on the back, add it to the back side
                else if (side[i] == EPlaneSide.Side_Back)
                {
                    outBack.AddVertex(vertices[i], uv[i]);
                }

                // check if the next vertex is planar or on the same side, then we do not split
                if (side[i + 1] == EPlaneSide.Side_Planar || side[i] == side[i + 1])
                {
                    continue;
                }

                // create split point
                Vector3 nextVector = vertices[(i + 1) % vertices.Length];
                Vector2 nextUV = uv[(i + 1) % uv.Length];
                Vector3 newVector, newUV;

                // if we were on the front
                if (side[i] == EPlaneSide.Side_Front)
                {
                    float t = distance[i] / (distance[i] - distance[i + 1]);

                    newVector = vertices[i] + t * (nextVector - vertices[i]);
                    newUV     = uv[i] + t * (nextUV - uv[i]);
                }
                else // back side...
                {
                    float t = distance[i + 1] / (distance[i + 1] - distance[i]);

                    newVector = nextVector + t * (vertices[i] - nextVector);
                    newUV     = nextUV + t * (uv[i] - nextUV);
                }

                // split points are added

                // add to front
                outFront.AddVertex(newVector, newUV);

                // add to back
                outBack.AddVertex(newVector, newUV);
            }

            // Debugging checks
            if (outFront.vertices.Length < 3 || outBack.vertices.Length < 3)
            {
                Debug.Log("Degenerate Faces");
            }


            // todo...
            outFront.material = material;

            //
            outBack.material = material;

            return(true);
        }
Пример #2
0
        public bool Merge(Face inOther, out Face outFace)
        {
            outFace = null;


            // do not share same material
            if (material != inOther.material || vertices.Length < 1)
            {
                return(false);
            }

            Vector3 p1, p2;
            Vector3 p3, p4;
            int     i = 0, j = 0;

            // just to fix compiler error
            p1 = vertices[0];
            p2 = vertices[1 % vertices.Length];

            // check if we share an edge
            for (i = 0; i < vertices.Length; ++i)
            {
                // get edge
                p1 = vertices[i];
                p2 = vertices[(i + 1) % vertices.Length];


                // go through all edges of other face
                for (j = 0; j < inOther.vertices.Length; ++j)
                {
                    // get other edge
                    p3 = inOther.vertices[j];
                    p4 = inOther.vertices[(j + 1) % inOther.vertices.Length];

                    // check if we are sharing an edge
                    if (p1.Equals(p4) && p2.Equals(p3))
                    {
                        break;
                    }
                }

                // found edge
                if (j < inOther.vertices.Length)
                {
                    break;
                }
            }

            // no edge found
            if (i == vertices.Length)
            {
                return(false);
            }

            //  ...
            Vector3 back  = vertices[(i + vertices.Length - 1) % vertices.Length];
            Vector3 delta = p1 - back;

            Vector3 normal = Vector3.Cross(GetPlane().normal, delta);

            normal.Normalize();

            back  = inOther.vertices[(j + 2) % inOther.vertices.Length];
            delta = back - p1;

            float dot = Vector3.Dot(delta, normal);

            // not a convex polygon
            if (dot > BooleanSettings.Epsilonf)
            {
                return(false);
            }

            // if they are co linear
            bool keep1 = (dot < -BooleanSettings.Epsilonf);

            // ...
            back   = vertices[(i + 2) % vertices.Length];
            delta  = back - p2;
            normal = Vector3.Cross(GetPlane().normal, delta);
            normal.Normalize();

            back  = inOther.vertices[(j + inOther.vertices.Length - 1) % inOther.vertices.Length];
            delta = back - p2;
            dot   = Vector3.Dot(delta, normal);

            // not convex
            if (dot > BooleanSettings.Epsilonf)
            {
                return(false);
            }

            bool keep2 = (dot < -BooleanSettings.Epsilonf);

            bool keep = false;

            // create out face
            outFace = new Face();

            outFace.flags    = flags;
            outFace.material = material;

            // copy vertices from this
            for (int k = (i + 1) % vertices.Length; k != i; k = (k + 1) % vertices.Length)
            {
                if (!keep && k == (i + 1) % vertices.Length && !keep2)
                {
                    continue;
                }

                // copy vector
                outFace.AddVertex(vertices[k], uv[k]);
            }

            // copy vertices from other
            for (int k = (j + 1) % inOther.vertices.Length; k != j; k = (k + 1) % inOther.vertices.Length)
            {
                if (!keep && k == (j + 1) % inOther.vertices.Length && !keep1)
                {
                    continue;
                }

                outFace.AddVertex(inOther.vertices[k], inOther.uv[k]);
            }

            return(true);
        }