Skip to content

Commit

Permalink
Initialized the buffer capacity in MergeBuffers() to fix OutOfMemory …
Browse files Browse the repository at this point in the history
…issues, and added a test covering this.
  • Loading branch information
MeltyPlayer committed Jan 15, 2023
1 parent 2d6a77c commit b952dbd
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/SharpGLTF.Core/Schema2/gltf.Buffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
5 changes: 3 additions & 2 deletions src/SharpGLTF.Core/Schema2/gltf.BufferView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<byte>(initialCapacity);
}

#endregion
Expand All @@ -360,7 +361,7 @@ public _StaticBufferBuilder(int bufferIndex)
private readonly int _BufferIndex;

// accumulated data
private readonly List<Byte> _Data = new List<byte>();
private readonly List<Byte> _Data;

#endregion

Expand Down
94 changes: 94 additions & 0 deletions tests/SharpGLTF.Toolkit.Tests/Scenes/SceneBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -991,5 +991,99 @@ public void TestSceneAddition()
gltf.AttachToCurrentTest("Three cubes.glb");
}

[Test]
public void TestHugeSceneViaBuilders()
{
// create a scene

var mesh = new MeshBuilder<VertexPositionNormal, VertexColor2Texture2, VertexJoints8>();

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<VertexPositionNormal, VertexColor2Texture1, VertexJoints8>
.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();
}
}
}
}
3 changes: 2 additions & 1 deletion tests/SharpGLTF.Toolkit.Tests/SharpGLTF.Toolkit.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
</ItemGroup>

</Project>

0 comments on commit b952dbd

Please sign in to comment.