Beispiel #1
0
        public static void CleanOrphanVertices(IList <Vector3> vertices, IList <Triangle3Indexed> triangles, out IList <Vector3> cleanVertices, out IList <Triangle3Indexed> cleanTriangles)
        {
            Vector3 minCoordinate = new Vector3(float.MaxValue);
            Vector3 maxCoordinate = new Vector3(float.MinValue);

            // First we build non-indexed triangles so we can re-index them after the cleanup
            IList <Triangle3> triangleList = new List <Triangle3>();

            for (var i = 0; i < triangles.Count; i++)
            {
                Triangle3Indexed indexed = triangles[i];
                if (!IsVertexValid(vertices[indexed.A]) || !IsVertexValid(vertices[indexed.B]) || !IsVertexValid(vertices[indexed.C]))
                {
                    // This triangle has invalid vertices, ignore
                    Logger.Warn("- Triangle Vertex out of safe range, skipping!");
                    continue;
                }

                Triangle3 nonIndexed = new Triangle3(vertices[indexed.A], vertices[indexed.B], vertices[indexed.C]);
                triangleList.Add(nonIndexed);

                BuildMinCoordinate(ref minCoordinate, nonIndexed.A);
                BuildMinCoordinate(ref minCoordinate, nonIndexed.B);
                BuildMinCoordinate(ref minCoordinate, nonIndexed.C);

                BuildMaxCoordinate(ref maxCoordinate, nonIndexed.A);
                BuildMaxCoordinate(ref maxCoordinate, nonIndexed.B);
                BuildMaxCoordinate(ref maxCoordinate, nonIndexed.C);
            }

            cleanVertices  = new List <Vector3>();
            cleanTriangles = new List <Triangle3Indexed>();

            //float size = Math.Abs((maxCoordinate - minCoordinate).Length());
            Octree <MeshSpatialInfo> cleanTree = new Octree <MeshSpatialInfo>(1, minCoordinate, 1);

            for (var i = 0; i < triangleList.Count; i++)
            {
                Triangle3 triangle = triangleList[i];
                uint      indexA;
                uint      indexB;
                uint      indexC;

                if (!IndexOfVertex(cleanTree, triangle.A, out indexA))
                {
                    indexA = AddNewVertex(cleanVertices, triangle.A, cleanTree);
                }

                if (!IndexOfVertex(cleanTree, triangle.B, out indexB))
                {
                    indexB = AddNewVertex(cleanVertices, triangle.B, cleanTree);
                }

                if (!IndexOfVertex(cleanTree, triangle.C, out indexC))
                {
                    indexC = AddNewVertex(cleanVertices, triangle.C, cleanTree);
                }

                cleanTriangles.Add(new Triangle3Indexed(indexA, indexB, indexC));
            }

            if (cleanVertices.Count != vertices.Count)
            {
                Logger.Info("- {0} orphan vertices", vertices.Count - cleanVertices.Count);
            }
        }
Beispiel #2
0
        // -------------------------------------------------------------------
        // Private
        // -------------------------------------------------------------------
        private void DoJoin(IList <Vector3> vertices, IList <Vector3> normals, IDictionary <uint, uint[]> normalMapping, IList <Triangle3Indexed> triangles, Vector3 offset)
        {
            bool[] vertexInvalidMap = new bool[vertices.Count];
            uint[] indexMap         = new uint[vertices.Count];
            uint[] normalMap        = new uint[normals.Count];

            Logger.Info("- {0} vertices", vertices.Count);
            bool check   = this.Vertices.Count > 0;
            int  skipped = 0;

            for (var i = 0; i < vertices.Count; i++)
            {
                Vector3 finalVertex = vertices[i] + offset;
                if (finalVertex.Length() > MathUtils.MaxFloat)
                {
                    // Create a zero vertex, we will skip the triangles anyway
                    indexMap[i]         = MeshUtils.AddNewVertex(this.Vertices, new Vector3(0), this.mergeTree);
                    vertexInvalidMap[i] = false;
                    Logger.Warn("- Vertex out of Safe Range: " + finalVertex);
                    skipped++;
                    continue;
                }

                if (!check)
                {
                    indexMap[i] = MeshUtils.AddNewVertex(this.Vertices, finalVertex, this.mergeTree);
                    continue;
                }

                uint index;
                if (MeshUtils.IndexOfVertex(this.mergeTree, finalVertex, out index))
                {
                    indexMap[i] = index;
                    skipped++;
                    continue;
                }

                indexMap[i] = MeshUtils.AddNewVertex(this.Vertices, finalVertex, this.mergeTree);
            }

            if (skipped > 0)
            {
                Logger.Info("  {0} duplicates", skipped);
            }

            Logger.Info("- {0} normals", normals.Count);
            bool checkNormals = this.Normals.Count > 0;

            skipped = 0;
            for (var i = 0; i < normals.Count; i++)
            {
                var normal = normals[i];

                if (!checkNormals)
                {
                    normalMap[i] = MeshUtils.AddNewNormal(this.Normals, normal, this.mergeTree);
                    continue;
                }

                uint index;
                if (MeshUtils.IndexOfNormal(this.mergeTree, normal, out index))
                {
                    normalMap[i] = index;
                    skipped++;
                    continue;
                }

                normalMap[i] = MeshUtils.AddNewNormal(this.Normals, normal, this.mergeTree);
            }

            if (skipped > 0)
            {
                Logger.Info("  {0} duplicates", skipped);
            }

            Logger.Info("- {0} triangles", triangles.Count);
            for (var i = 0; i < triangles.Count; i++)
            {
                Triangle3Indexed triangle = triangles[i];

                if (vertexInvalidMap[triangle.A] || vertexInvalidMap[triangle.B] || vertexInvalidMap[triangle.C])
                {
                    Logger.Warn("Triangle had invalid index mapping, possibly skipped vertices, skipping triangle");
                    continue;
                }

                if (check)
                {
                    // Re-index the triangle
                    this.Triangles.Add(new Triangle3Indexed(indexMap[triangle.A], indexMap[triangle.B], indexMap[triangle.C]));
                }
                else
                {
                    this.Triangles.Add(triangle);
                }

                // Remap the normals for this triangle and
                if (normalMapping.Count > 0)
                {
                    uint[] map = new uint[3];
                    for (var n = 0; n < 3; n++)
                    {
                        uint normalIndex = normalMapping[(uint)i][n];
                        map[n] = normalMap[normalIndex];
                    }

                    this.NormalMapping.Add((uint)this.Triangles.Count - 1, map);
                }
            }

            this.RecalculateBounds();
        }