Example #1
0
        public static IndexedMesh Optimize(IMesh mesh)
        {
            var result           = new IndexedMesh(mesh.Id);
            var resultPrimitives = new IndexMeshPrimitive[mesh.Primitives.Count];
            var primitiveGroups  = mesh.GroupPrimitives();

            foreach (var primitiveGroup in primitiveGroups)
            {
                var resultBufferView = new MeshBufferView();

                var bufferView        = primitiveGroup.BufferView;
                var streamKeys        = bufferView.GetStreams().ToList();
                var sourceStreams     = streamKeys.Select(x => bufferView.GetStream(x)).ToList();
                var dictionaryStreams = sourceStreams.Select(_ => _.CreateDictionaryMeshStreamOfTheSameType()).ToList();
                for (var index = 0; index < dictionaryStreams.Count; index++)
                {
                    resultBufferView.SetStream(streamKeys[index], dictionaryStreams[index]);
                }

                foreach (var primitiveAndIndex in primitiveGroup.Primitives)
                {
                    var meshPrimitive = new IndexMeshPrimitive(resultBufferView);
                    resultPrimitives[primitiveAndIndex.Index] = meshPrimitive;
                    var submesh = primitiveAndIndex.Primitive;
                    meshPrimitive.Topology = submesh.Topology;

                    for (var keyIndex = 0; keyIndex < streamKeys.Count; ++keyIndex)
                    {
                        var key           = streamKeys[keyIndex];
                        var sourceIndices = submesh.GetIndexReader(key);
                        var dataStream    = dictionaryStreams[keyIndex];
                        var sourceStream  = sourceStreams[keyIndex];
                        var stream        = new List <int>(sourceIndices.Count);
                        for (var i = 0; i < sourceIndices.Count; ++i)
                        {
                            stream.Add(dataStream.Add(sourceStream[sourceIndices[i]]));
                        }
                        meshPrimitive.SetIndexStream(key, stream);
                    }
                }

                for (var keyIndex = 0; keyIndex < streamKeys.Count; ++keyIndex)
                {
                    bufferView.SetStream(streamKeys[keyIndex], dictionaryStreams[keyIndex]);
                }
            }

            foreach (var indexMeshPrimitive in resultPrimitives)
            {
                result.Primitives.Add(indexMeshPrimitive);
            }
            return(result);
        }
Example #2
0
        public static GpuMesh Optimize(IMesh source)
        {
            var optimalIndexedMesh = IndexedMesh.Optimize(source);
            var resultPrimitives   = new GpuPrimitive[optimalIndexedMesh.Primitives.Count];
            var result             = new GpuMesh(source.Id);

            var indices = new List <int>();

            foreach (var primitiveGroup in optimalIndexedMesh.GroupPrimitives())
            {
                var sourceBuffer  = primitiveGroup.BufferView;
                var gpuBufferView = new MeshBufferView();
                var streamKeys    = sourceBuffer.GetStreams();
                var copiers       = streamKeys.Project((streamKey, streamIndex) =>
                {
                    var meshStream  = sourceBuffer.GetStream(streamKey);
                    var destination = meshStream.CreateListMeshStreamOfTheSameType();
                    gpuBufferView.SetStream(streamKey, destination);
                    return(new BoxingtMeshStreamCopier(meshStream, destination));
                });

                var expectedCapacityEsitmation =
                    primitiveGroup.Select(_ => _.GetIndexReader(StreamKey.Position).Count).Sum() * streamKeys.Count;
                indices.Clear();
                if (indices.Capacity < expectedCapacityEsitmation)
                {
                    indices.Capacity = expectedCapacityEsitmation;
                }
                var vertexMap = new Dictionary <IndexSet, int>();
                foreach (var primitiveAndIndex in primitiveGroup.Primitives)
                {
                    var primitive  = primitiveAndIndex.Primitive;
                    var setReader  = new IndexSetReader(indices, streamKeys, primitive);
                    var ints       = primitive.GetIndexReader(StreamKey.Position);
                    var gpuIndices = new List <int>();
                    for (var index = 0; index < ints.Count; index++)
                    {
                        var set = setReader.Read(index);
                        if (vertexMap.TryGetValue(set, out var vertexIndex))
                        {
                            setReader.Position = set.Offset;
                        }
                        else
                        {
                            for (var streamIndex = 0; streamIndex < streamKeys.Count; streamIndex++)
                            {
                                vertexIndex = copiers[streamIndex].Copy(set[streamIndex]);
                            }
                            vertexMap.Add(set, vertexIndex);
                        }

                        gpuIndices.Add(vertexIndex);
                    }

                    var gpuPrimitive = new GpuPrimitive(primitive.Topology, gpuIndices, gpuBufferView);
                    resultPrimitives[primitiveAndIndex.Index] = gpuPrimitive;
                }
            }

            foreach (var indexMeshPrimitive in resultPrimitives)
            {
                result.Primitives.Add(indexMeshPrimitive);
            }

            return(result);
        }