internal static void _AddCameraTo(CameraTransform3D?_Camera, GLTFWriteSettings?settings, SharpGLTF.Scenes.SceneBuilder scene) { if (!_Camera.HasValue) { return; } var vcam = _Camera.Value; var camNode = new SharpGLTF.Scenes.NodeBuilder("CameraNode"); camNode.WorldMatrix = vcam.WorldMatrix; var cam = vcam; cam.WorldMatrix = Matrix4x4.Identity; vcam = cam; if (vcam.TryGetPerspectiveFieldOfView(out var vfov)) { var persp = new SharpGLTF.Scenes.CameraBuilder.Perspective(null, vfov, 0.1f); scene.AddCamera(persp, camNode); } else if (vcam.TryGetOrthographicScale(out var oscale)) { var ortho = new SharpGLTF.Scenes.CameraBuilder.Orthographic(oscale, oscale, 0.1f, 1000); scene.AddCamera(ortho, camNode); } if ((settings?.CameraSize ?? 0) > 0) { var camMesh = new GltfMeshScene3D(); vcam.DrawCameraTo(camMesh, settings.Value.CameraSize.Value); vcam.DrawFustrumTo(camMesh, settings.Value.CameraSize.Value * 0.05f, System.Drawing.Color.Yellow); scene.AddRigidMesh(camMesh.Mesh, camNode); } if (Matrix4x4.Invert(_Camera.Value.AxisMatrix, out var invMatrix)) { // scene.ApplyBasisTransform(invMatrix); } }
private static void _AddMeshInstances(SceneBuilder dstScene, IReadOnlyDictionary <Node, NodeBuilder> dstNodes, IReadOnlyList <Node> srcInstances) { var dstMeshes = srcInstances .Select(item => item.Mesh) .Distinct() .ToDictionary(item => item, item => item.ToMeshBuilder()); foreach (var srcInstance in srcInstances) { var dstMesh = dstMeshes[srcInstance.Mesh]; if (srcInstance.Skin == null) { var dstNode = dstNodes[srcInstance]; var dstInst = dstScene.AddRigidMesh(dstMesh, dstNode); _CopyMorphingAnimation(dstInst, srcInstance); } else { var joints = new (NodeBuilder, Matrix4x4)[srcInstance.Skin.JointsCount];
public void CreateNonConvexQuadsScene() { TestContext.CurrentContext.AttachShowDirLink(); TestContext.CurrentContext.AttachGltfValidatorLinks(); var mesh = new MeshBuilder <VertexPosition>(); var prim = mesh.UsePrimitive(MaterialBuilder.CreateDefault()); var idx = prim.AddQuadrangle(new VertexPosition(0, -1, 0), new VertexPosition(1, 0, 0), new VertexPosition(0, 1, 0), new VertexPosition(-1, 0, 0)); Assert.AreEqual((0, 1, 2, 3), idx); idx = prim.AddQuadrangle(new VertexPosition(0, -1, 1), new VertexPosition(1, 0, 1), new VertexPosition(0, 1, 1), new VertexPosition(0.5f, 0, 1)); Assert.AreEqual((4, 5, 6, 7), idx); idx = prim.AddQuadrangle(new VertexPosition(0, 0.5f, 2), new VertexPosition(1, 0, 2), new VertexPosition(0, 1, 2), new VertexPosition(-1, 0, 2)); Assert.AreEqual((8, 9, 10, 11), idx); idx = prim.AddQuadrangle(new VertexPosition(1, 0, 3), new VertexPosition(0, 1, 3), new VertexPosition(0.5f, 0, 3), new VertexPosition(0, -1, 3)); Assert.AreEqual((12, 13, 14, 15), idx); idx = prim.AddQuadrangle(new VertexPosition(1, 0, 4), new VertexPosition(1, 0, 4), new VertexPosition(0, 1, 4), new VertexPosition(-1, 0, 4)); Assert.AreEqual((-1, 16, 17, 18), idx); idx = prim.AddQuadrangle(new VertexPosition(1, 0, 4), new VertexPosition(1, 0, 4), new VertexPosition(0, 1, 4), new VertexPosition(0, 1, 4)); Assert.AreEqual((-1, -1, -1, -1), idx); idx = prim.AddQuadrangle(new VertexPosition(0, 0, 5), new VertexPosition(10, -1, 5), new VertexPosition(9, 0, 5), new VertexPosition(10, 1, 5)); Assert.AreEqual((19, 20, 21, 22), idx); idx = prim.AddQuadrangle(new VertexPosition(10, -1, 6), new VertexPosition(9, 0, 6), new VertexPosition(10, 1, 6), new VertexPosition(0, 0, 6)); Assert.AreEqual((23, 24, 25, 26), idx); var scene = new SceneBuilder(); scene.AddRigidMesh(mesh, Matrix4x4.Identity); scene.AttachToCurrentTest("NonConvexQuads.glb"); scene.AttachToCurrentTest("NonConvexQuads.gltf"); }
public void CreateCubeSceneWithExtras() { TestContext.CurrentContext.AttachGltfValidatorLinks(); var material = MaterialBuilder.CreateDefault(); material.Name = "hello name"; material.Extras = IO.JsonContent.Serialize(new KeyValuePair <string, int>("hello", 16)); var mesh = new Cube <MaterialBuilder>(material).ToMesh(Matrix4x4.Identity); mesh.Name = "world name"; mesh.Extras = "world extras"; var scene = new SceneBuilder(); scene.AddRigidMesh(mesh, Matrix4x4.Identity) .WithName("Cube") .WithExtras(17); scene.AttachToCurrentTest("cube.glb"); scene.AttachToCurrentTest("cube.gltf"); scene.AttachToCurrentTest("cube.plotly"); }
public void CreateAllAnimationTypesScene() { // 3D View 7.1908.9012.0 has an issue displaying off-center meshes with animated morph targets. TestContext.CurrentContext.AttachGltfValidatorLinks(); // create two materials var pink = new MaterialBuilder("material1") .WithChannelParam(KnownChannel.BaseColor, KnownProperty.RGBA, new Vector4(1, 0, 1, 1)); var yellow = new MaterialBuilder("material2") .WithChannelParam(KnownChannel.BaseColor, KnownProperty.RGBA, new Vector4(1, 1, 0, 1)); var mesh1 = VPOSNRM.CreateCompatibleMesh("shape1"); mesh1.AddCube(pink, Matrix4x4.Identity); var mesh2 = VPOSNRM.CreateCompatibleMesh("shape2"); mesh2.AddCube(yellow, Matrix4x4.Identity); var scene = new SceneBuilder(); var inst1 = scene.AddRigidMesh(mesh1, Matrix4x4.Identity); // meshes intended to support animation must be created using an armature var armature = new NodeBuilder(); armature.LocalTransform = Matrix4x4.CreateTranslation(2, 0, 0); var inst2 = scene.AddRigidMesh(mesh2, armature); scene.AttachToCurrentTest("static.glb"); scene.AttachToCurrentTest("static.gltf"); // up to this point, the scene has two plain unanimated cubes. var morphBuilder = mesh2.UseMorphTarget(0); morphBuilder.SetVertexDelta(morphBuilder.Positions.ElementAt(0), (Vector3.UnitY, Vector3.Zero)); morphBuilder.SetVertexDelta(morphBuilder.Positions.ElementAt(1), (Vector3.UnitY, Vector3.Zero)); morphBuilder.SetVertexDelta(morphBuilder.Positions.ElementAt(2), (Vector3.UnitY, Vector3.Zero)); morphBuilder.SetVertexDelta(morphBuilder.Positions.ElementAt(3), (Vector3.UnitY, Vector3.Zero)); // set default value. inst2.Content.UseMorphing().SetValue(1); // ser animation curve. var curve = inst2.Content.UseMorphing().UseTrackBuilder("Default"); curve.SetPoint(0, true, 0); curve.SetPoint(1, true, 1); curve.SetPoint(2, true, 0); var gltf = scene.ToGltf2(); TestContext.WriteLine(gltf.GetJsonPreview()); var meshIdx = 1; Assert.AreEqual(1, gltf.LogicalMeshes[meshIdx].Primitives[0].MorphTargetsCount); Assert.AreEqual(1, gltf.LogicalMeshes[meshIdx].MorphWeights[0]); Assert.AreEqual(1, gltf.LogicalAnimations.Count); scene.AttachToCurrentTest("mopth.glb"); scene.AttachToCurrentTest("mopth.gltf"); }
public void CreateSceneWithRandomShapes(bool useGpuInstancing) { TestContext.CurrentContext.AttachGltfValidatorLinks(); var rnd = new Random(177); // create materials var materials = Enumerable .Range(0, 10) .Select(idx => new MaterialBuilder() .WithChannelParam(KnownChannel.BaseColor, KnownProperty.RGBA, new Vector4(rnd.NextVector3(), 1))) .ToList(); // create meshes var sphereMeshes = Enumerable .Range(0, 10) .Select(idx => materials[idx]) .Select(mat => { var mesh = VPOSNRM.CreateCompatibleMesh("shape"); #if DEBUG mesh.VertexPreprocessor.SetValidationPreprocessors(); #else mesh.VertexPreprocessor.SetSanitizerPreprocessors(); #endif mesh.AddSphere(mat, 0.5f, Matrix4x4.Identity); mesh.Validate(); return(mesh); }); var cubeMeshes = Enumerable .Range(0, 10) .Select(idx => materials[idx]) .Select(mat => { var mesh = VPOSNRM.CreateCompatibleMesh("shape"); #if DEBUG mesh.VertexPreprocessor.SetValidationPreprocessors(); #else mesh.VertexPreprocessor.SetSanitizerPreprocessors(); #endif mesh.AddCube(mat, Matrix4x4.Identity); mesh.Validate(); return(mesh); }); var meshes = sphereMeshes.Concat(cubeMeshes).ToArray(); // create scene var scene = new SceneBuilder(); for (int i = 0; i < 100; ++i) { var mesh = meshes[rnd.Next(0, 20)]; // create random transform var r = rnd.NextQuaternion(); var t = rnd.NextVector3() * 25; scene.AddRigidMesh(mesh, (r, t)); } // collapse to glTF var gltf = scene.ToGltf2(useGpuInstancing ? SceneBuilderSchema2Settings.WithGpuInstancing : SceneBuilderSchema2Settings.Default); var bounds = Runtime.MeshDecoder.EvaluateBoundingBox(gltf.DefaultScene); // Assert.AreEqual(defaultBounds,instancedBounds); // save the model as GLB gltf.AttachToCurrentTest("shapes.glb"); scene.AttachToCurrentTest("shapes.plotly"); }