public Gltf(string name, CSkelMeshLod lod, List <CSkelMeshBone> bones, List <MaterialExporter>?materialExports) { var mesh = new MeshBuilder <VERTEX, VertexColorXTextureX, VertexJoints4>(name); for (var i = 0; i < lod.Sections.Value.Length; i++) { ExportSkelMeshSections(i, lod, lod.Sections.Value[i], materialExports, mesh); } var sceneBuilder = new SceneBuilder(); var armatureNodeBuilder = new NodeBuilder(name + ".ao"); var armature = CreateGltfSkeleton(bones, armatureNodeBuilder); sceneBuilder.AddSkinnedMesh(mesh, Matrix4x4.Identity, armature); Model = sceneBuilder.ToGltf2(); }
public void SaveToGltf2(string path, string texturePath) { var textures = new List <(string, Texture)>(); var converter = new ImageConverter(texturePath); var scene = new SceneBuilder(); // var materials = new DictionaryEntry(); var materials = new MaterialBuilder[Materials.Length]; var skin = CreateSkin(); int meshId = 0; foreach (var mesh in Meshes) { // Console.WriteLine("Process mesh " + meshId); int counter = 0; foreach (var submesh in mesh.Submeshes) { var mat = materials[submesh.Material.Id] ?? InitializeMaterial(submesh.Material, materials, converter); materials[submesh.Material.Id] = mat; if (submesh.Vertices.FirstOrDefault().BoneIndices != null) { var glbMesh = new MeshBuilder <VertexPositionNormal, VertexTexture1, VertexJoints4>($"{submesh.Name}"); var primitive = glbMesh.UsePrimitive(mat); var vertices = submesh.Vertices .Select(v => new VertexBuilder <VertexPositionNormal, VertexTexture1, VertexJoints4>( new VertexPositionNormal(v.Position, v.Normal), new VertexTexture1(new Vector2(v.Uv0.X, 1 - v.Uv0.Y)), new VertexJoints4( (v.BoneIndices[0], v.BoneWeights[0]), (v.BoneIndices[1], v.BoneWeights[1]), (v.BoneIndices[2], v.BoneWeights[2]), (v.BoneIndices[3], v.BoneWeights[3]) ) )).ToArray(); var t = submesh.Triangles; for (int i = 0; i < t.GetLength(0); i++) { primitive.AddTriangle(vertices[t[i, 0]], vertices[t[i, 1]], vertices[t[i, 2]]); } scene.AddSkinnedMesh(glbMesh, null, Matrix4x4.Identity, skin); } else { var glbMesh = new MeshBuilder <VertexPositionNormal, VertexTexture1, VertexEmpty>($"{submesh.Name}"); var primitive = glbMesh.UsePrimitive(mat); var vertices = submesh.Vertices .Select(v => new VertexBuilder <VertexPositionNormal, VertexTexture1, VertexEmpty>( new VertexPositionNormal(v.Position, v.Normal), new VertexTexture1(new Vector2(v.Uv0.X, 1 - v.Uv0.Y)) )).ToArray(); var t = submesh.Triangles; for (int i = 0; i < t.GetLength(0); i++) { primitive.AddTriangle(vertices[t[i, 0]], vertices[t[i, 1]], vertices[t[i, 2]]); } scene.AddRigidMesh(glbMesh, null, submesh.Transform); } } meshId++; } // Console.WriteLine("Save..."); var gltf2 = scene.ToGltf2(); // Fix skin var firstSkin = gltf2.LogicalSkins.FirstOrDefault(); foreach (var node in gltf2.LogicalNodes) { if (node.Skin != null) { node.Skin = firstSkin; } } // Fix texture naming (sadl, very inefficient...) foreach (var tex in gltf2.LogicalTextures) { var name = converter.GetName(tex.PrimaryImage.Content.Content.ToArray()); if (name != null) { tex.Name = name; tex.PrimaryImage.Name = name; } else { Console.WriteLine("Texture not found."); } } gltf2.Save(Path.GetFullPath(path), new WriteSettings() { ImageWriting = ResourceWriteMode.Default, Validation = ValidationMode.Strict }); }