コード例 #1
0
        public void Optimize_TwoTriangles_4VerticesAnd6IndicesCreated()
        {
            var builder = new IndexedMeshBuilder();

            builder.BeginBuffer();
            builder.BeginPrimitive(PrimitiveTopology.TriangleList);
            builder.Position(new Vector3(0, 0, 0));
            builder.Position(new Vector3(1, 0, 0));
            builder.Position(new Vector3(0, 1, 0));
            builder.Position(new Vector3(1, 0, 0));
            builder.Position(new Vector3(1, 1, 0));
            builder.Position(new Vector3(0, 1, 0));

            var mesh = IndexedMesh.Optimize(builder.Complete());

            Assert.AreEqual(1, mesh.Primitives.Count);
            Assert.AreEqual(6, mesh.Primitives[0].GetIndexReader(StreamKey.Position).Count);
            Assert.AreEqual(4, mesh.Primitives[0].BufferView.GetStreamReader <Vector3>(StreamKey.Position).Count);
        }
コード例 #2
0
        public static IReadOnlyCollection <BufferViewAndPrimitiveIndices <IndexMeshPrimitive> > GroupPrimitives(
            this IndexedMesh mesh)
        {
            var map =
                new Dictionary <IBufferView, BufferViewAndPrimitiveIndices <IndexMeshPrimitive> >(mesh.Primitives.Count);

            for (var index = 0; index < mesh.Primitives.Count; index++)
            {
                var meshPrimitive = mesh.Primitives[index];
                var bufferView    = meshPrimitive.BufferView;
                if (!map.TryGetValue(bufferView, out var indices))
                {
                    map.Add(bufferView,
                            indices = new BufferViewAndPrimitiveIndices <IndexMeshPrimitive> {
                        BufferView = bufferView
                    });
                }

                indices.Primitives.Add(new PrimitiveAndIndex <IndexMeshPrimitive>(meshPrimitive, index));
            }

            return(map.Values);
        }
コード例 #3
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);
        }
コード例 #4
0
        public void Optimize_EmptyMesh_DoesntThrow()
        {
            var index = new GpuMesh();

            Assert.DoesNotThrow(() => IndexedMesh.Optimize(index));
        }