diff --git a/src/SharpGLTF.Core/Schema2/gltf.Buffer.cs b/src/SharpGLTF.Core/Schema2/gltf.Buffer.cs index 417cd2ef..a9b88683 100644 --- a/src/SharpGLTF.Core/Schema2/gltf.Buffer.cs +++ b/src/SharpGLTF.Core/Schema2/gltf.Buffer.cs @@ -220,7 +220,7 @@ public void MergeBuffers() // begin merge - var sbbuilder = new _StaticBufferBuilder(0); + var sbbuilder = new _StaticBufferBuilder(0, (int) totalLen); foreach (var bv in views) bv._IsolateBufferMemory(sbbuilder); diff --git a/src/SharpGLTF.Core/Schema2/gltf.BufferView.cs b/src/SharpGLTF.Core/Schema2/gltf.BufferView.cs index d09f86da..db3d1f55 100644 --- a/src/SharpGLTF.Core/Schema2/gltf.BufferView.cs +++ b/src/SharpGLTF.Core/Schema2/gltf.BufferView.cs @@ -347,9 +347,10 @@ sealed class _StaticBufferBuilder { #region lifecycle - public _StaticBufferBuilder(int bufferIndex) + public _StaticBufferBuilder(int bufferIndex, int initialCapacity = 0) { _BufferIndex = bufferIndex; + _Data = new List(initialCapacity); } #endregion @@ -360,7 +361,7 @@ public _StaticBufferBuilder(int bufferIndex) private readonly int _BufferIndex; // accumulated data - private readonly List _Data = new List(); + private readonly List _Data; #endregion diff --git a/tests/SharpGLTF.Toolkit.Tests/Scenes/SceneBuilderTests.cs b/tests/SharpGLTF.Toolkit.Tests/Scenes/SceneBuilderTests.cs index bab347d8..5affc1b4 100644 --- a/tests/SharpGLTF.Toolkit.Tests/Scenes/SceneBuilderTests.cs +++ b/tests/SharpGLTF.Toolkit.Tests/Scenes/SceneBuilderTests.cs @@ -991,5 +991,99 @@ public void TestSceneAddition() gltf.AttachToCurrentTest("Three cubes.glb"); } + [Test] + public void TestHugeSceneViaBuilders() + { + // create a scene + + var mesh = new MeshBuilder(); + + var gridSize = 1000; + + // generate texture + var diffuseImageSize = 2 * gridSize; + var occlusionImageSize = gridSize; + + MemoryImage diffuseImage, occlusionImage; + { + var img = new Bitmap(diffuseImageSize, diffuseImageSize, PixelFormat.Format32bppArgb); + + using var mem = new MemoryStream(); + img.Save(mem, ImageFormat.Png); + + mem.TryGetBuffer(out var bytes); + diffuseImage = new MemoryImage(bytes); + } + { + var img = new Bitmap(occlusionImageSize, occlusionImageSize, PixelFormat.Format32bppArgb); + + using var mem = new MemoryStream(); + img.Save(mem, ImageFormat.Png); + + mem.TryGetBuffer(out var bytes); + occlusionImage = new MemoryImage(bytes); + } + + var material = MaterialBuilder.CreateDefault().WithSpecularGlossinessShader(); + material.UseChannel(KnownChannel.Diffuse) + .UseTexture() + .WithPrimaryImage(ImageBuilder.From(diffuseImage)) + .WithCoordinateSet(0); + material.UseChannel(KnownChannel.Occlusion) + .UseTexture() + .WithPrimaryImage(ImageBuilder.From(occlusionImage)) + .WithCoordinateSet(0); + + // generate heightmap + + for (var y = 0; y < gridSize; ++y) + { + for (var x = 0; x < gridSize; ++x) + { + var vertices = new (float X, float Y)[] + { + (x, y), + (x + 1, y), + (x, y + 1), + (x + 1, y + 1) + }.Select(pos => VertexBuilder + .Create(new Vector3(pos.X, pos.Y, 0), new Vector3(x, y, 0)) + .WithMaterial(new Vector4(pos.X / gridSize, pos.Y / gridSize, 0, 1), + new Vector4(0, pos.X / gridSize, pos.Y / gridSize, 1), + new Vector2(pos.X / gridSize, pos.Y / gridSize), + new Vector2(pos.X / gridSize, pos.Y / gridSize)) + .WithSkinning(SparseWeight8.Create((0, 1)))) + .ToArray(); + + mesh.UsePrimitive(material).AddTriangle(vertices[0], vertices[1], vertices[2]); + mesh.UsePrimitive(material).AddTriangle(vertices[1], vertices[2], vertices[3]); + } + } + + var scene = new SceneBuilder(); + scene.AddSkinnedMesh(mesh, Matrix4x4.Identity, new NodeBuilder()); + + // convert to gltf + + var gltf = scene.ToGltf2(); + + Assert.AreEqual(1, gltf.LogicalMeshes.Count); + + var outFiles = new[] + { + "huge_scene.glb", + "huge_scene.gltf", + "huge_scene.obj", + }; + + foreach (var outFile in outFiles) + { + gltf.AttachToCurrentTest(outFile); + + GC.WaitForPendingFinalizers(); + GC.Collect(); + GC.WaitForFullGCComplete(); + } + } } } diff --git a/tests/SharpGLTF.Toolkit.Tests/SharpGLTF.Toolkit.Tests.csproj b/tests/SharpGLTF.Toolkit.Tests/SharpGLTF.Toolkit.Tests.csproj index cb396f65..1a542b3c 100644 --- a/tests/SharpGLTF.Toolkit.Tests/SharpGLTF.Toolkit.Tests.csproj +++ b/tests/SharpGLTF.Toolkit.Tests/SharpGLTF.Toolkit.Tests.csproj @@ -26,7 +26,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + + \ No newline at end of file