コード例 #1
0
        public unsafe static NativeMeshSOA Parse(string path, Allocator outputAllocator = Allocator.Persistent, VertexAttribs vertexAttribs = VertexAttribs.Position, VertexOrder vertexOrder = VertexOrder.ByDefinition)
        {
#if VERBOSE
            Debug.LogFormat("trying {0}", path);
#endif

            var text     = File.ReadAllText(path);        //TODO replace with native variant
            var textSize = text.Length;

            // measure the data
            int numPositions = 0;
            int numTexCoords = 0;
            int numNormals   = 0;
            int numFaces     = 0;

            for (int i = 0; i < text.Length; i++)
            {
                if (ReadChar(text, ref i, 'v'))
                {
                    if (ReadBlank(text, ref i))
                    {
                        numPositions++;
                    }
                    else if (ReadChar(text, ref i, 't') && ReadBlank(text, ref i))
                    {
                        numTexCoords++;
                    }
                    else if (ReadChar(text, ref i, 'n') && ReadBlank(text, ref i))
                    {
                        numNormals++;
                    }
                }
                else if (ReadChar(text, ref i, 'f') && ReadBlankGreedy(text, ref i))
                {
                    int readVerts = 0;
                    while (ReadDigit(text, ref i))
                    {
                        ReadUntilNewlineOrBlank(text, ref i);
                        ReadBlankGreedy(text, ref i);
                        readVerts++;
                    }
                    if (readVerts > 2)
                    {
                        numFaces += readVerts - 2;
                    }
                }

                ReadUntilNewline(text, ref i);
            }

#if VERBOSE
            Debug.LogFormat("-- numPositions = {0}", numPositions);
            Debug.LogFormat("-- numTexCoords = {0}", numTexCoords);
            Debug.LogFormat("-- numNormals = {0}", numNormals);
            Debug.LogFormat("-- numFaces = {0}", numFaces);
#endif

            // allocate buffers
            var inputPositions = new NativeArray <Vector3>(numPositions, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
            var inputTexCoords = new NativeArray <Vector2>(numTexCoords, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
            var inputNormals   = new NativeArray <Vector3>(numNormals, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
            var inputFaces     = new NativeArray <InputFace>(numFaces, Allocator.Temp, NativeArrayOptions.UninitializedMemory);

            var outputIndicesMax = numFaces * 3;
            var outputIndicesLUT = new NativeHashMap <Hash128, int>(outputIndicesMax, Allocator.Temp);
            var outputPositions  = new NativeArray <Vector3>(outputIndicesMax, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
            var outputTexCoords  = new NativeArray <Vector2>(outputIndicesMax, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
            var outputNormals    = new NativeArray <Vector3>(outputIndicesMax, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
            var outputIndices    = new NativeArray <int>(outputIndicesMax, Allocator.Temp, NativeArrayOptions.UninitializedMemory);

            // read the data
            numPositions = 0;
            numTexCoords = 0;
            numNormals   = 0;
            numFaces     = 0;

            for (int i = 0; i < text.Length; i++)
            {
                if (ReadChar(text, ref i, 'v'))
                {
                    if (ReadBlank(text, ref i))
                    {
                        Vector3 position;
                        ReadFloat(text, ref i, out position.x);
                        position.x *= -1.0f;                        //TODO remove this hack
                        ReadBlankGreedy(text, ref i);
                        ReadFloat(text, ref i, out position.y);
                        ReadBlankGreedy(text, ref i);
                        ReadFloat(text, ref i, out position.z);
                        inputPositions[numPositions++] = position;
                    }
                    else if (ReadChar(text, ref i, 't') && ReadBlank(text, ref i))
                    {
                        Vector2 texCoord;
                        ReadFloat(text, ref i, out texCoord.x);
                        ReadBlankGreedy(text, ref i);
                        ReadFloat(text, ref i, out texCoord.y);
                        inputTexCoords[numTexCoords++] = texCoord;
                    }
                    else if (ReadChar(text, ref i, 'n') && ReadBlank(text, ref i))
                    {
                        Vector3 normal;
                        ReadFloat(text, ref i, out normal.x);
                        normal.x *= -1.0f;                        //TODO remove this hack
                        ReadBlankGreedy(text, ref i);
                        ReadFloat(text, ref i, out normal.y);
                        ReadBlankGreedy(text, ref i);
                        ReadFloat(text, ref i, out normal.z);
                        inputNormals[numNormals++] = normal;
                    }
                }
                else if (ReadChar(text, ref i, 'f') && ReadBlankGreedy(text, ref i))
                {
                    InputFace face = new InputFace();
                    if (ReadUInt(text, ref i, out face.v0.idxPosition))
                    {
                        ReadChar(text, ref i, '/');
                        ReadUInt(text, ref i, out face.v0.idxTexCoord);
                        ReadChar(text, ref i, '/');
                        ReadUInt(text, ref i, out face.v0.idxNormal);

                        int readVerts = 1;
                        while (ReadBlankGreedy(text, ref i))
                        {
                            face.v1 = face.v2;
                            if (ReadUInt(text, ref i, out face.v2.idxPosition))
                            {
                                ReadChar(text, ref i, '/');
                                ReadUInt(text, ref i, out face.v2.idxTexCoord);
                                ReadChar(text, ref i, '/');
                                ReadUInt(text, ref i, out face.v2.idxNormal);
                                if (++readVerts > 2)
                                {
                                    inputFaces[numFaces++] = face;
                                }
                            }
                        }
                    }
                }

                ReadUntilNewline(text, ref i);
            }

            // process the data
            int numOutputVertices = 0;
            int numOutputIndices  = 0;

            if (vertexOrder == VertexOrder.ByReference)
            {
                for (int i = 0; i != numFaces; i++)
                {
                    InputFace face = inputFaces[i];

                    var key0 = Hash(in face.v0);
                    var key1 = Hash(in face.v1);
                    var key2 = Hash(in face.v2);
                    int idx0, idx1, idx2;

                    if (outputIndicesLUT.TryGetValue(key0, out idx0) == false)
                    {
                        outputIndicesLUT[key0] = idx0 = numOutputVertices++;
                    }
                    if (outputIndicesLUT.TryGetValue(key1, out idx1) == false)
                    {
                        outputIndicesLUT[key1] = idx1 = numOutputVertices++;
                    }
                    if (outputIndicesLUT.TryGetValue(key2, out idx2) == false)
                    {
                        outputIndicesLUT[key2] = idx2 = numOutputVertices++;
                    }

                    outputPositions[idx0] = inputPositions[(int)face.v0.idxPosition - 1];
                    outputPositions[idx1] = inputPositions[(int)face.v1.idxPosition - 1];
                    outputPositions[idx2] = inputPositions[(int)face.v2.idxPosition - 1];

                    outputTexCoords[idx0] = inputTexCoords[(int)face.v0.idxTexCoord - 1];
                    outputTexCoords[idx1] = inputTexCoords[(int)face.v1.idxTexCoord - 1];
                    outputTexCoords[idx2] = inputTexCoords[(int)face.v2.idxTexCoord - 1];

                    outputNormals[idx0] = inputNormals[(int)face.v0.idxNormal - 1];
                    outputNormals[idx1] = inputNormals[(int)face.v1.idxNormal - 1];
                    outputNormals[idx2] = inputNormals[(int)face.v2.idxNormal - 1];

                    outputIndices[numOutputIndices++] = idx0;
                    outputIndices[numOutputIndices++] = idx1;
                    outputIndices[numOutputIndices++] = idx2;
                }
            }
            else if (vertexOrder == VertexOrder.ByDefinition)
            {
                numOutputVertices = numPositions;

                var indexVisited = new NativeArray <bool>(numPositions, Allocator.Temp, NativeArrayOptions.ClearMemory);

                for (int i = 0; i != numFaces; i++)
                {
                    InputFace face = inputFaces[i];

                    var key0 = Hash(in face.v0);
                    var key1 = Hash(in face.v1);
                    var key2 = Hash(in face.v2);
                    int idx0, idx1, idx2;

                    if (outputIndicesLUT.TryGetValue(key0, out idx0) == false)
                    {
                        if (indexVisited[idx0 = (int)face.v0.idxPosition - 1])
                        {
                            outputIndicesLUT[key0] = idx0 = numOutputVertices++;
                        }
                        else
                        {
                            outputIndicesLUT[key0] = idx0;
                        }
                    }

                    if (outputIndicesLUT.TryGetValue(key1, out idx1) == false)
                    {
                        if (indexVisited[idx1 = (int)face.v1.idxPosition - 1])
                        {
                            outputIndicesLUT[key1] = idx1 = numOutputVertices++;
                        }
                        else
                        {
                            outputIndicesLUT[key1] = idx1;
                        }
                    }

                    if (outputIndicesLUT.TryGetValue(key2, out idx2) == false)
                    {
                        if (indexVisited[idx2 = (int)face.v2.idxPosition - 1])
                        {
                            outputIndicesLUT[key2] = idx2 = numOutputVertices++;
                        }
                        else
                        {
                            outputIndicesLUT[key2] = idx2;
                        }
                    }

                    indexVisited[(int)face.v0.idxPosition - 1] = true;
                    indexVisited[(int)face.v1.idxPosition - 1] = true;
                    indexVisited[(int)face.v2.idxPosition - 1] = true;

                    outputPositions[idx0] = inputPositions[(int)face.v0.idxPosition - 1];
                    outputPositions[idx1] = inputPositions[(int)face.v1.idxPosition - 1];
                    outputPositions[idx2] = inputPositions[(int)face.v2.idxPosition - 1];

                    outputTexCoords[idx0] = inputTexCoords[(int)face.v0.idxTexCoord - 1];
                    outputTexCoords[idx1] = inputTexCoords[(int)face.v1.idxTexCoord - 1];
                    outputTexCoords[idx2] = inputTexCoords[(int)face.v2.idxTexCoord - 1];

                    outputNormals[idx0] = inputNormals[(int)face.v0.idxNormal - 1];
                    outputNormals[idx1] = inputNormals[(int)face.v1.idxNormal - 1];
                    outputNormals[idx2] = inputNormals[(int)face.v2.idxNormal - 1];

                    outputIndices[numOutputIndices++] = idx0;
                    outputIndices[numOutputIndices++] = idx1;
                    outputIndices[numOutputIndices++] = idx2;
                }

                indexVisited.Dispose();
            }

#if VERBOSE
            Debug.LogFormat("output vertex count = {0}", numOutputVertices);
            Debug.LogFormat("output index count = {0}", numOutputIndices);
#endif

            // copy to container
            NativeMeshSOA mesh = new NativeMeshSOA()
            {
                vertexPositions = new NativeArray <Vector3>(numOutputVertices, outputAllocator, NativeArrayOptions.UninitializedMemory),
                vertexTexCoords = new NativeArray <Vector2>(numOutputVertices, outputAllocator, NativeArrayOptions.UninitializedMemory),
                vertexNormals   = new NativeArray <Vector3>(numOutputVertices, outputAllocator, NativeArrayOptions.UninitializedMemory),
                vertexCount     = numOutputVertices,

                faceIndices      = new NativeArray <int>(numOutputIndices, outputAllocator, NativeArrayOptions.UninitializedMemory),
                faceIndicesCount = numOutputIndices,
            };

            NativeArray <Vector3> .Copy(outputPositions, mesh.vertexPositions, numOutputVertices);

            NativeArray <Vector2> .Copy(outputTexCoords, mesh.vertexTexCoords, numOutputVertices);

            NativeArray <Vector3> .Copy(outputNormals, mesh.vertexNormals, numOutputVertices);

            NativeArray <int> .Copy(outputIndices, mesh.faceIndices, numOutputIndices);

            // free buffers
            inputPositions.Dispose();
            inputTexCoords.Dispose();
            inputNormals.Dispose();
            inputFaces.Dispose();

            outputIndicesLUT.Dispose();
            outputPositions.Dispose();
            outputTexCoords.Dispose();
            outputNormals.Dispose();
            outputIndices.Dispose();

            // done
            return(mesh);
        }
コード例 #2
0
 public IPrimitive SetVertexOrder(VertexOrder vertexOrder)
 {
     this.VertexOrder = vertexOrder;
     return(this);
 }
コード例 #3
0
        public List <GeometricObject> ExtractObjectMesh(LoadMode loadMode)
        {
            List <GeometricObject> objectMesh = new List <GeometricObject>();

            FileHandler fileHandler = new FileHandler(_filePath);

            fileHandler.ExtractData();
            StringReader scanner = new StringReader(fileHandler.GetSourceData());

            List <Coordinate> vertexCoords = new List <Coordinate>();
            VertexOrder       vertexOrder;
            string            meshCommandDelimeter = " ";
            int    meshCommandIndex;
            string currLine = scanner.ReadLine();

            while (currLine != null)
            {
                meshCommandIndex = currLine.IndexOf(meshCommandDelimeter);
                if (meshCommandIndex != -1)
                {
                    string meshCommand = currLine.Substring(0, meshCommandIndex).ToUpper();
                    if (meshCommand.Equals(MeshCommand.V.ToString()))
                    {
                        vertexCoords.Add(new Coordinate());
                        currLine = currLine.Substring(meshCommandIndex + 1);
                        if (currLine.Substring(0, 1).Equals(meshCommandDelimeter))
                        {
                            currLine = currLine.Substring(1);
                        }

                        meshCommandIndex = currLine.IndexOf(meshCommandDelimeter);
                        vertexCoords.Last().XCoord = Convert.ToSingle(currLine.Substring(0, meshCommandIndex), CultureInfo.InvariantCulture);
                        currLine = currLine.Substring(meshCommandIndex + 1);

                        meshCommandIndex = currLine.IndexOf(meshCommandDelimeter);
                        vertexCoords.Last().YCoord = Convert.ToSingle(currLine.Substring(0, meshCommandIndex), CultureInfo.InvariantCulture);
                        currLine = currLine.Substring(meshCommandIndex + 1);

                        vertexCoords.Last().ZCoord = Convert.ToSingle(currLine, CultureInfo.InvariantCulture);
                    }
                    else if (meshCommand.Equals(MeshCommand.VT.ToString()))
                    {
                        currLine = currLine.Substring(meshCommandIndex + 1);

                        //meshCommandIndex = currLine.IndexOf(meshCommandDelimeter);
                        ///////////////////////// Handle Texture Meshing ///////////////////////
                        //currLine = currLine.Substring(meshCommandIndex + 1);

                        //meshCommandIndex = currLine.IndexOf(meshCommandDelimeter);
                        ///////////////////////// Handle Texture Meshing ///////////////////////
                        //currLine = currLine.Substring(meshCommandIndex + 1);
                    }
                    else if (meshCommand.Equals(MeshCommand.F.ToString()))
                    {
                        vertexOrder = new VertexOrder();
                        currLine    = currLine.Substring(meshCommandIndex + 1);

                        meshCommandIndex = currLine.IndexOf(meshCommandDelimeter);
                        while (meshCommandIndex != -1)
                        {
                            vertexOrder.InsertIndex(Convert.ToInt32(currLine.Substring(0, meshCommandIndex).Split('/').First()) - 1);
                            currLine         = currLine.Substring(meshCommandIndex + 1);
                            meshCommandIndex = currLine.IndexOf(meshCommandDelimeter);
                        }
                        if (currLine.Length > 0)
                        {
                            vertexOrder.InsertIndex(Convert.ToInt32(currLine.Split('/').First()) - 1);
                        }
                        objectMesh.Last().InsertPolygon(vertexOrder.ConstructPolygon(vertexCoords));
                    }
                    else if (currLine.Contains(MeshCommand.OBJECT.ToString() + " " + MeshCommand.MESH.ToString(), StringComparison.CurrentCultureIgnoreCase) ||
                             meshCommand.Equals(MeshCommand.O.ToString()))
                    {
                        objectMesh.Add(new GeometricObject());
                    }
                }
                currLine = scanner.ReadLine();
            }

            if (loadMode == LoadMode.Translated)
            {
                throw new NotImplementedException();
            }

            return(objectMesh);
        }