|
|
@@ -1,13 +1,18 @@
|
|
|
using System;
|
|
|
-using System.Collections.Generic;
|
|
|
+using System.Drawing;
|
|
|
+using System.Drawing.Imaging;
|
|
|
+using System.IO;
|
|
|
using System.Linq;
|
|
|
using System.Numerics;
|
|
|
-using System.Text;
|
|
|
-using System.Threading.Tasks;
|
|
|
|
|
|
using NUnit.Framework;
|
|
|
-
|
|
|
+using SharpGLTF.Geometry;
|
|
|
+using SharpGLTF.Geometry.VertexTypes;
|
|
|
+using SharpGLTF.Materials;
|
|
|
+using SharpGLTF.Memory;
|
|
|
+using SharpGLTF.Scenes;
|
|
|
using SharpGLTF.Schema2;
|
|
|
+using SharpGLTF.Transforms;
|
|
|
|
|
|
namespace SharpGLTF.ThirdParty
|
|
|
{
|
|
|
@@ -76,5 +81,97 @@ namespace SharpGLTF.ThirdParty
|
|
|
|
|
|
Assert.AreEqual(4, satellites.Length);
|
|
|
}
|
|
|
+
|
|
|
+ [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();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|