コード例 #1
0
        public NativeMeshSOA(NativeMeshSOA other, Allocator allocator)
        {
            vertexPositions = new NativeArray <Vector3>(other.vertexPositions, allocator);
            vertexTexCoords = new NativeArray <Vector2>(other.vertexTexCoords, allocator);
            vertexNormals   = new NativeArray <Vector3>(other.vertexNormals, allocator);
            vertexCount     = other.vertexCount;

            faceIndices      = new NativeArray <int>(other.faceIndices, allocator);
            faceIndicesCount = other.faceIndicesCount;
        }
コード例 #2
0
        public void CopyTo(NativeMeshSOA other)
        {
            Debug.Assert(other.vertexCount == this.vertexCount);
            Debug.Assert(other.faceIndicesCount == this.faceIndicesCount);

            other.vertexPositions.CopyFrom(this.vertexPositions);
            other.vertexTexCoords.CopyFrom(this.vertexTexCoords);
            other.vertexNormals.CopyFrom(this.vertexNormals);
            other.vertexCount = this.vertexCount;

            other.faceIndices.CopyFrom(this.faceIndices);
            other.faceIndicesCount = this.faceIndicesCount;
        }
コード例 #3
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);
        }