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); } } }
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; } } } }