private GltfMesh[] ExtractMeshes(Gltf model, GltfAccessor[] accessors, GltfBucketContainer materials) { var noOfItems = model.Meshes != null ? model.Meshes.Length : 0; var output = new GltfMesh[noOfItems]; for (var i = 0; i < noOfItems; i += 1) { var result = new GltfMesh(model.Meshes[i], accessors); output[i] = result; } return(output); }
static Mesh FromGltf(GltfSerialization.GltfStorage storage, GltfMesh x, GltfPrimitive primitive, bool isShared) { var mesh = new Mesh((TopologyType)primitive.mode) { VertexBuffer = primitive.attributes.FromGltf(storage) }; if (isShared) { // create joined index buffer mesh.IndexBuffer = storage.IndexBufferFromGltf(x.primitives.Select(y => y.indices).ToArray()); } else { mesh.IndexBuffer = storage.AccessorFromGltf(primitive.indices); } if (primitive.targets != null) { for (int i = 0; i < primitive.targets.Count; ++i) { var gltfTarget = primitive.targets[i]; string targetName = null; if (primitive.extras != null && primitive.extras.targetNames != null && i < primitive.extras.targetNames.Count ) { targetName = primitive.extras.targetNames[i]; } var target = new MorphTarget(targetName) { VertexBuffer = gltfTarget.FromGltf(storage) }; // validate count foreach (var kv in target.VertexBuffer) { if (kv.Value.Count != mesh.VertexBuffer.Count) { throw new Exception(); } } mesh.MorphTargets.Add(target); } } return(mesh); }
public static MeshGroup FromGltf(this GltfMesh x, GltfSerialization.GltfStorage storage, List <Material> materials) { var group = new MeshGroup(x.name); if (x.primitives.Count == 1) { var primitive = x.primitives[0]; var mesh = primitive.FromGltf(storage, x); mesh.Submeshes.Add( new Submesh(0, mesh.IndexBuffer.Count, materials[primitive.material])); group.Meshes.Add(mesh); } else if (!x.AllPrimitivesHasSameVertexBuffer()) { int offset = 0; foreach (var primitive in x.primitives) { var mesh = primitive.FromGltf(storage, x); mesh.Submeshes.Add( new Submesh(offset, mesh.IndexBuffer.Count, materials[primitive.material])); offset += mesh.IndexBuffer.Count; group.Meshes.Add(mesh); } } else { // for VRM var mesh = x.SharedBufferFromGltf(storage); int offset = 0; foreach (var primitive in x.primitives) { var count = storage.Gltf.accessors[primitive.indices].count; mesh.Submeshes.Add( new Submesh(offset, count, materials[primitive.material])); offset += count; } group.Meshes.Add(mesh); } return(group); }
protected List <Mesh> readPrimitivesInMesh(int index, Node parent) { GltfMesh gltfMesh = this._root.Meshes[index]; List <Mesh> meshes = new List <Mesh>(); foreach (GltfMeshPrimitive p in gltfMesh.Primitives) { Mesh mesh = readPrimitive(p, out Material material); mesh.Name = gltfMesh.Name; meshes.Add(mesh); parent.Children.Add(material); //TODO: fix the material reference } return(meshes); }
private static async Task ConstructMeshAsync(GltfObject gltfObject, GameObject parent, int meshId) { GltfMesh gltfMesh = gltfObject.meshes[meshId]; var renderer = parent.gameObject.AddComponent <MeshRenderer>(); var filter = parent.gameObject.AddComponent <MeshFilter>(); if (gltfMesh.primitives.Length == 1) { gltfMesh.Mesh = await ConstructMeshPrimitiveAsync(gltfObject, gltfMesh.primitives[0]); gltfMesh.Mesh.name = gltfMesh.name; filter.sharedMesh = gltfMesh.Mesh; renderer.sharedMaterial = gltfObject.materials[gltfMesh.primitives[0].material].Material; return; } var materials = new List <Material>(); var meshCombines = new CombineInstance[gltfMesh.primitives.Length]; for (int i = 0; i < gltfMesh.primitives.Length; i++) { meshCombines[i].mesh = await ConstructMeshPrimitiveAsync(gltfObject, gltfMesh.primitives[i]); var meshMaterial = gltfObject.materials[gltfMesh.primitives[i].material].Material; if (!materials.Contains(meshMaterial)) { materials.Add(meshMaterial); } } var newMesh = new Mesh(); newMesh.CombineMeshes(meshCombines); gltfMesh.Mesh = filter.sharedMesh = newMesh; gltfMesh.Mesh.name = gltfMesh.name; renderer.sharedMaterials = materials.ToArray(); }
/// <summary> /// IndexBuffer毎に異なるVertexBufferを参照する /// /// VertexBuffer /// +--------+ +--------+ +--------+ /// |0 | |1 | |2 | /// +--------+ +--------+ +--------+ /// A A A /// | | | /// +---------+--------+--------+ /// | submesh0|submesh1|submesh2| /// +---------+--------+--------+ /// IndexBuffer /// </summary> public static Mesh FromGltf(this GltfPrimitive primitive, GltfSerialization.GltfStorage storage, GltfMesh x) { return(FromGltf(storage, x, primitive, false)); }
/// <summary> /// VertexBufferはひとつでIndexBufferの参照が異なる /// /// VertexBuffer /// +----------------------------------+ /// | | /// +----------------------------------+ /// A A A /// | | | /// +---------+--------+--------+ /// | submesh0|submesh1|submesh2| /// +---------+--------+--------+ /// IndexBuffer /// </summary> public static Mesh SharedBufferFromGltf(this GltfMesh x, GltfSerialization.GltfStorage storage) { // 先頭を使う return(FromGltf(storage, x, x.primitives[0], true)); }
public static async void OnImportGltfAsset(AssetImportContext context) { var importedObject = await GltfUtility.ImportGltfObjectFromPathAsync(context.assetPath); if (importedObject == null || importedObject.GameObjectReference == null) { Debug.LogError("Failed to import glTF object"); return; } var gltfAsset = (GltfAsset)ScriptableObject.CreateInstance(typeof(GltfAsset)); gltfAsset.GltfObject = importedObject; gltfAsset.name = $"{gltfAsset.GltfObject.Name}{Path.GetExtension(context.assetPath)}"; gltfAsset.Model = importedObject.GameObjectReference; context.AddObjectToAsset("main", gltfAsset.Model); context.SetMainObject(importedObject.GameObjectReference); context.AddObjectToAsset("glTF data", gltfAsset); bool reImport = false; for (var i = 0; i < gltfAsset.GltfObject.textures?.Length; i++) { GltfTexture gltfTexture = gltfAsset.GltfObject.textures[i]; if (gltfTexture == null) { continue; } var path = AssetDatabase.GetAssetPath(gltfTexture.Texture); if (string.IsNullOrWhiteSpace(path)) { var textureName = gltfTexture.name; if (string.IsNullOrWhiteSpace(textureName)) { textureName = $"Texture_{i}"; gltfTexture.Texture.name = textureName; } context.AddObjectToAsset(textureName, gltfTexture.Texture); } else { if (!gltfTexture.Texture.isReadable) { var textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; if (textureImporter != null) { textureImporter.isReadable = true; textureImporter.SetPlatformTextureSettings(new TextureImporterPlatformSettings { format = TextureImporterFormat.RGBA32 }); textureImporter.SaveAndReimport(); reImport = true; } } } } if (reImport) { var importer = AssetImporter.GetAtPath(context.assetPath); importer.SaveAndReimport(); return; } for (var i = 0; i < gltfAsset.GltfObject.meshes?.Length; i++) { GltfMesh gltfMesh = gltfAsset.GltfObject.meshes[i]; string meshName = string.IsNullOrWhiteSpace(gltfMesh.name) ? $"Mesh_{i}" : gltfMesh.name; gltfMesh.Mesh.name = meshName; context.AddObjectToAsset($"{meshName}", gltfMesh.Mesh); } if (gltfAsset.GltfObject.materials != null) { foreach (GltfMaterial gltfMaterial in gltfAsset.GltfObject.materials) { context.AddObjectToAsset(gltfMaterial.name, gltfMaterial.Material); } } }
public static async void OnImportGltfAsset(AssetImportContext context) { var gltfAsset = (GltfAsset)ScriptableObject.CreateInstance(typeof(GltfAsset)); var importedObject = await GltfUtility.ImportGltfObjectFromPathAsync(context.assetPath); gltfAsset.GltfObject = importedObject; gltfAsset.name = $"{gltfAsset.GltfObject.Name}{Path.GetExtension(context.assetPath)}"; gltfAsset.Model = importedObject.GameObjectReference; context.AddObjectToAsset("main", gltfAsset.Model); context.SetMainObject(importedObject.GameObjectReference); context.AddObjectToAsset("glTF data", gltfAsset); bool reImport = false; for (var i = 0; i < gltfAsset.GltfObject.textures.Length; i++) { GltfTexture gltfTexture = gltfAsset.GltfObject.textures[i]; var path = AssetDatabase.GetAssetPath(gltfTexture.Texture); if (string.IsNullOrWhiteSpace(path)) { var textureName = gltfTexture.name; if (string.IsNullOrWhiteSpace(textureName)) { textureName = $"Texture_{i}"; gltfTexture.Texture.name = textureName; } context.AddObjectToAsset(textureName, gltfTexture.Texture); } else { if (!gltfTexture.Texture.isReadable) { var textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; textureImporter.isReadable = true; textureImporter.SetPlatformTextureSettings(new TextureImporterPlatformSettings { format = TextureImporterFormat.RGBA32 }); textureImporter.SaveAndReimport(); reImport = true; } } } if (reImport) { var importer = AssetImporter.GetAtPath(context.assetPath); importer.SaveAndReimport(); return; } for (var i = 0; i < gltfAsset.GltfObject.meshes.Length; i++) { GltfMesh gltfMesh = gltfAsset.GltfObject.meshes[i]; string meshName = string.IsNullOrWhiteSpace(gltfMesh.name) ? $"Mesh_{i}" : gltfMesh.name; gltfMesh.Mesh.name = meshName; context.AddObjectToAsset($"{meshName}", gltfMesh.Mesh); } foreach (GltfMaterial gltfMaterial in gltfAsset.GltfObject.materials) { if (context.assetPath.EndsWith(".glb")) { context.AddObjectToAsset(gltfMaterial.name, gltfMaterial.Material); } else { var path = Path.GetFullPath(Path.GetDirectoryName(context.assetPath)); path = path.Replace("\\", "/").Replace(Application.dataPath, "Assets"); path = $"{path}/{gltfMaterial.name}.mat"; AssetDatabase.CreateAsset(gltfMaterial.Material, path); gltfMaterial.Material = AssetDatabase.LoadAssetAtPath <Material>(path); } } }