Exemplo n.º 1
0
        public static CSGPlane CalcPolygonPlane(ControlMesh controlMesh, short polygonIndex)
        {
            if (controlMesh == null ||
                controlMesh.Polygons == null ||
                polygonIndex >= controlMesh.Polygons.Length)
            {
                return(new CSGPlane(Vector3.up, 0));
            }
            var edgeIndices = controlMesh.Polygons[polygonIndex].EdgeIndices;

            if (edgeIndices.Length == 3)
            {
                var v0 = controlMesh.GetVertex(edgeIndices[0]);
                var v1 = controlMesh.GetVertex(edgeIndices[1]);
                var v2 = controlMesh.GetVertex(edgeIndices[2]);

                return(new CSGPlane(v0, v1, v2));
            }

            // newell's method to calculate a normal for a concave polygon
            var normal    = MathConstants.zeroVector3;
            var prevIndex = edgeIndices.Length - 1;

            if (prevIndex < 0)
            {
                return(new CSGPlane(MathConstants.upVector3, MathConstants.zeroVector3));
            }

            var prevVertex = controlMesh.GetVertex(edgeIndices[prevIndex]);

            for (var e = 0; e < edgeIndices.Length; e++)
            {
                var currVertex = controlMesh.GetVertex(edgeIndices[e]);
                normal.x = normal.x + ((prevVertex.y - currVertex.y) * (prevVertex.z + currVertex.z));
                normal.y = normal.y + ((prevVertex.z - currVertex.z) * (prevVertex.x + currVertex.x));
                normal.z = normal.z + ((prevVertex.x - currVertex.x) * (prevVertex.y + currVertex.y));

                prevVertex = currVertex;
            }
            normal = normal.normalized;

            var d     = 0.0f;
            var count = 0;

            for (var e = 0; e < edgeIndices.Length; e++)
            {
                var currVertex = controlMesh.GetVertex(edgeIndices[e]);
                d += Vector3.Dot(normal, currVertex);
                count++;
            }
            d /= count;

            return(new CSGPlane(normal, d));
        }