Example #1
0
 public MeshElement(VertexDeclaration vertexDeclaration, float[] vertexBuffer, ushort[] indexBuffer)
 {
     _vertexDeclaration = vertexDeclaration;
     _vertexBuffer = vertexBuffer;
     _indexBuffer = indexBuffer;
     _vertexCount = _vertexBuffer.Length / _vertexDeclaration.Stride;
 }
Example #2
0
        void IMeshOptimiser.Apply(float[] originalVertexBuffer, ushort[] originalIndexBuffer, MeshElement meshElement)
        {
            _vertexDeclaration = meshElement.VertexDeclaration;
            _meshElement = meshElement;
            _originalIndexBuffer = originalIndexBuffer;
            unsmoothedChannels = new List<VertexChannel>();
            Dictionary<int, List<int>> smoothingCandidates = new Dictionary<int, List<int>>();

            foreach (VertexChannel channel in _vertexDeclaration.channels)
            {
                if (channel.Name != "NORMAL" && channel.Name != "TANGENT" && channel.Name != "BITANGENT")
                    unsmoothedChannels.Add(channel);
            }

            List<int> uniqueVertices = new List<int>(meshElement.VertexCount);

            for (int i = 0; i < meshElement.VertexCount; ++i)
            {
                int matching = -1;
                foreach (int j in uniqueVertices)
                {
                    if (ChannelsMatch(i, j))
                    {
                        matching = j;
                        break;
                    }
                }
                if (matching >= 0)
                {
                    if (smoothingCandidates.ContainsKey(matching))
                    {
                        smoothingCandidates[matching].Add(i);
                    }
                    else
                    {
                        smoothingCandidates.Add(matching, new List<int>());
                        smoothingCandidates[matching].Add(i);
                    }
                }
                else
                {
                    uniqueVertices.Add(i);
                }
            }

            _optimisedVertexBuffer = new float[uniqueVertices.Count * _vertexDeclaration.Stride];
            _optimisedIndexBuffer = new ushort[originalIndexBuffer.Length];

            for (int i = 0; i < uniqueVertices.Count; ++i)
            {
                MeshHelper.CopyFloatArray(originalVertexBuffer, uniqueVertices[i] * _vertexDeclaration.Stride, _optimisedVertexBuffer, i * _vertexDeclaration.Stride, _vertexDeclaration.Stride);
                ChangeIndices(uniqueVertices[i], i);

                if (smoothingCandidates.ContainsKey(uniqueVertices[i]))
                {
                    foreach (int j in smoothingCandidates[uniqueVertices[i]])
                    {
                        if (meshElement.VertexDeclaration.ContainsChannel("TANGENT"))
                        {
                            float[] tangent = meshElement.ReadAttribute("TANGENT", j);
                            MeshHelper.AddFloatArray(tangent, 0, _optimisedVertexBuffer, i * _vertexDeclaration.Stride + _vertexDeclaration.GetChannel("TANGENT").Offset, 3);
                            float[] bitangent = meshElement.ReadAttribute("BITANGENT", j);
                            MeshHelper.AddFloatArray(bitangent, 0, _optimisedVertexBuffer, i * _vertexDeclaration.Stride + _vertexDeclaration.GetChannel("BITANGENT").Offset, 3);
                        }
                        float[] normal = meshElement.ReadAttribute("NORMAL", j);
                        MeshHelper.AddFloatArray(normal, 0, _optimisedVertexBuffer, i * _vertexDeclaration.Stride + _vertexDeclaration.GetChannel("NORMAL").Offset, 3);
                        ChangeIndices(j, i);
                    }
                }
                MeshHelper.Normalize(_optimisedVertexBuffer, i * _vertexDeclaration.Stride + _vertexDeclaration.GetChannel("NORMAL").Offset, 3);
                if (meshElement.VertexDeclaration.ContainsChannel("TANGENT"))
                {
                    MeshHelper.Normalize(_optimisedVertexBuffer, i * _vertexDeclaration.Stride + _vertexDeclaration.GetChannel("TANGENT").Offset, 3);
                    MeshHelper.Normalize(_optimisedVertexBuffer, i * _vertexDeclaration.Stride + _vertexDeclaration.GetChannel("BITANGENT").Offset, 3);
                }
            }
        }
Example #3
0
 public Vertex(VertexDeclaration declaration)
 {
     _vertexDeclaration = declaration;
     _data = new float[_vertexDeclaration.Stride];
 }
Example #4
0
        private void ParseMesh(XPathNavigator nav)
        {
            var sourceIterator = nav.Select("c:source", nsManager);
            while (sourceIterator.MoveNext())
            {
                ParseSource(sourceIterator.Current);
            }

            var vertices = nav.SelectSingleNode("c:vertices", nsManager);
            string sourceNewName = vertices.GetAttribute("id", nsName);
            var input = nav.SelectSingleNode("c:vertices/c:input", nsManager);
            string sourceOldName = input.GetAttribute("source", nsName);
            sourceOldName = sourceOldName.Substring(1);

            float[] tmpData = sources[sourceOldName].data;
            int tmpStride = sources[sourceOldName].stride;

            sources.Remove(sourceOldName);
            sources.Add(sourceNewName, new Source(tmpData));
            sources[sourceNewName].stride = tmpStride;

            var polylist = nav.SelectSingleNode("c:polylist", nsManager);
            int polyCount;
            if (!int.TryParse(polylist.GetAttribute("count", nsName), out polyCount))
                throw new GeometryParserException("could not parse poly count!");

            polyVertexCount = new int[polyCount];

            var vcount = polylist.SelectSingleNode("c:vcount", nsManager);
            string[] parts = vcount.InnerXml.Split(' ');

            for (int i = 0; i < polyCount; ++i)
            {
                if (!int.TryParse(parts[i], out polyVertexCount[i]))
                    throw new GeometryParserException("could not parse poly vertex count at element: " + i);

                if (polyVertexCount[i] == 3)
                    ++triCount;
                else if (polyVertexCount[i] == 4)
                    triCount += 2;
                else
                    throw new GeometryParserException("can only parse tris and quads!");
            }

            var inputIterator = polylist.Select("c:input", nsManager);
            int inputCount = 0;
            while (inputIterator.MoveNext())
            {
                string inputSemantic = inputIterator.Current.GetAttribute("semantic", nsName);
                string inputSource = inputIterator.Current.GetAttribute("source", nsName).Substring(1);
                int inputOffset;
                if (!int.TryParse(inputIterator.Current.GetAttribute("offset", nsName), out inputOffset))
                    throw new GeometryParserException("could not parse input offset, (semantic " + inputSemantic + ")");
                semantics.Add(inputSemantic, new Semantic(inputSource, inputOffset));
                ++inputCount;
            }

            var indicesNode = polylist.SelectSingleNode("c:p", nsManager);
            parts = indicesNode.InnerXml.Split(' ');

            int indexCount = 0;

            foreach (int v in polyVertexCount)
                indexCount += v;

            indexCount *= inputCount;
            indices = new int[indexCount];

            for (int i = 0; i < indexCount; ++i)
            {
                int.TryParse(parts[i], out indices[i]);
            }

            _vertexDeclaration = new VertexDeclaration(GetChannels());
            PopulateMesh();

            Console.WriteLine("Finished Parsing Mesh");
        }
Example #5
0
        private void CreateArrays(bool generateTangents)
        {
            if (generateTangents && _vertexDeclaration.ContainsChannel("TEXCOORD"))
            {
                Console.WriteLine("generating tangent frames....");
                List<VertexChannel> originalChannels = new List<VertexChannel>();
                foreach (VertexChannel channel in _vertexDeclaration.channels)
                {
                    originalChannels.Add(channel);
                }
                originalChannels.Add(new VertexChannel("TANGENT", _vertexDeclaration.Stride, 3));
                originalChannels.Add(new VertexChannel("BITANGENT", _vertexDeclaration.Stride + 3, 3));
                _vertexDeclaration = new VertexDeclaration(originalChannels);
                vertexData = new float[_vertexDeclaration.Stride * tris.Length * 3];
                indexData = new ushort[tris.Length * 3];
                int offset = 0;
                for (int i = 0; i < tris.Length; ++i)
                {
                    for (int j = 0; j < 3; ++j)
                    {
                        tris[i][j].ToArray().CopyTo(vertexData, offset * _vertexDeclaration.Stride);
                        indexData[i * 3 + j] = (ushort)offset;
                        int tangentOffset = _vertexDeclaration.GetChannel("TANGENT").Offset;
                        GenerateTangents(tris[i], j).CopyTo(vertexData, (offset * _vertexDeclaration.Stride) + tangentOffset);
                        ++offset;
                    }
                }
            }
            else
            {
                vertexData = new float[_vertexDeclaration.Stride * tris.Length * 3];
                indexData = new ushort[tris.Length * 3];
                int offset = 0;

                for (int i = 0; i < tris.Length; ++i)
                {
                    for (int j = 0; j < 3; ++j)
                    {
                        tris[i][j].ToArray().CopyTo(vertexData, offset * _vertexDeclaration.Stride);
                        indexData[i * 3 + j] = (ushort)offset;
                        ++offset;
                    }
                }
            }
        }