public static async Task <Texture2D> LoadTextureAsync(IAwaitCaller awaitCaller, glTF gltf, IStorage storage, int textureIndex) { var imageBytes = await awaitCaller.Run(() => { var imageIndex = gltf.textures[textureIndex].source; var segments = gltf.GetImageBytes(storage, imageIndex); return(ToArray(segments)); }); // // texture from image(png etc) bytes // var colorSpace = gltf.GetColorSpace(textureIndex); var texture = new Texture2D(2, 2, TextureFormat.ARGB32, false, colorSpace == RenderTextureReadWrite.Linear); texture.name = gltf.textures[textureIndex].name; if (imageBytes != null) { texture.LoadImage(imageBytes); } var sampler = gltf.GetSamplerFromTextureIndex(textureIndex); if (sampler != null) { TextureSamplerUtil.SetSampler(texture, sampler); } return(texture); }
private static async Task <Vrm10Instance> TryLoadingAsVrm10Async( GltfData gltfData, bool normalizeTransform, bool showMeshes, IAwaitCaller awaitCaller, IMaterialDescriptorGenerator materialGenerator, VrmMetaInformationCallback vrmMetaInformationCallback, CancellationToken ct) { ct.ThrowIfCancellationRequested(); if (awaitCaller == null) { throw new ArgumentNullException(); } var vrm10Data = await awaitCaller.Run(() => Vrm10Data.Parse(gltfData)); ct.ThrowIfCancellationRequested(); if (vrm10Data == null) { // NOTE: Failed to parse as VRM 1.0. return(null); } return(await LoadVrm10DataAsync( vrm10Data, null, normalizeTransform, showMeshes, awaitCaller, materialGenerator, vrmMetaInformationCallback, ct)); }
public static async Task <Mesh> CreateErasedMeshAsync(Mesh src, int[] eraseBoneIndices, IAwaitCaller awaitCaller) { if (awaitCaller == null) { throw new ArgumentNullException(); } var mesh = new Mesh(); mesh.name = src.name + "(erased)"; #if UNITY_2017_3_OR_NEWER mesh.indexFormat = src.indexFormat; #endif mesh.vertices = src.vertices; mesh.normals = src.normals; mesh.uv = src.uv; mesh.tangents = src.tangents; mesh.boneWeights = src.boneWeights; mesh.bindposes = src.bindposes; mesh.subMeshCount = src.subMeshCount; var boneWeights = mesh.boneWeights; for (int i = 0; i < src.subMeshCount; ++i) { var srcIndices = src.GetIndices(i); var dst = await awaitCaller.Run(() => GetExcludedIndices(srcIndices, boneWeights, eraseBoneIndices)); mesh.SetIndices(dst, MeshTopology.Triangles, i); } return(mesh); }
private static async Task BuildBlendShapeAsync(IAwaitCaller awaitCaller, Mesh mesh, BlendShape blendShape, Vector3[] emptyVertices) { Vector3[] positions = null; Vector3[] normals = null; await awaitCaller.Run(() => { positions = blendShape.Positions.ToArray(); if (blendShape.Normals != null) { normals = blendShape.Normals.ToArray(); } }); Profiler.BeginSample("MeshUploader.BuildBlendShapeAsync"); if (blendShape.Positions.Count > 0) { if (blendShape.Positions.Count == mesh.vertexCount) { mesh.AddBlendShapeFrame(blendShape.Name, FrameWeight, blendShape.Positions.ToArray(), normals.Length == mesh.vertexCount && normals.Length == positions.Length ? normals : null, null ); } else { Debug.LogWarningFormat( "May be partial primitive has blendShape. Require separate mesh or extend blend shape, but not implemented: {0}", blendShape.Name); } } else { // Debug.LogFormat("empty blendshape: {0}.{1}", mesh.name, blendShape.Name); // add empty blend shape for keep blend shape index mesh.AddBlendShapeFrame(blendShape.Name, FrameWeight, emptyVertices, null, null ); } Profiler.EndSample(); }
private static async Task <Vrm10Instance> TryMigratingFromVrm0XAsync( GltfData gltfData, bool normalizeTransform, bool showMeshes, IAwaitCaller awaitCaller, IMaterialDescriptorGenerator materialGenerator, VrmMetaInformationCallback vrmMetaInformationCallback, CancellationToken ct) { ct.ThrowIfCancellationRequested(); if (awaitCaller == null) { throw new ArgumentNullException(); } Vrm10Data migratedVrm10Data = default; MigrationData migrationData = default; using (var migratedGltfData = await awaitCaller.Run(() => Vrm10Data.Migrate(gltfData, out migratedVrm10Data, out migrationData))) { ct.ThrowIfCancellationRequested(); if (migratedVrm10Data == null) { throw new Exception(migrationData?.Message ?? "Failed to migrate."); } var migratedVrm10Instance = await LoadVrm10DataAsync( migratedVrm10Data, migrationData, normalizeTransform, showMeshes, awaitCaller, materialGenerator, vrmMetaInformationCallback, ct); if (migratedVrm10Instance == null) { throw new Exception(migrationData?.Message ?? "Failed to load migrated."); } return(migratedVrm10Instance); } }
protected virtual async Task LoadGeometryAsync(IAwaitCaller awaitCaller, Func <string, IDisposable> MeasureTime) { var inverter = InvertAxis.Create(); if (GLTF.meshes.Count > 0) { var maxVertexCapacity = 0; var maxIndexCapacity = 0; foreach (var gltfMesh in GLTF.meshes) { var(vertexCapacity, indexCapacity) = MeshData.GetCapacity(Data, gltfMesh); maxVertexCapacity = Math.Max(maxVertexCapacity, vertexCapacity); maxIndexCapacity = Math.Max(maxIndexCapacity, indexCapacity); } // 一番長い VertexBuffer, IndexBuffer の長さでNativeArray を確保し、 // 最後に Dispose する using (var meshData = new MeshData(maxVertexCapacity, maxIndexCapacity)) { for (var i = 0; i < GLTF.meshes.Count; ++i) { var index = i; var gltfMesh = Data.GLTF.meshes[index]; using (MeasureTime("ReadMesh")) await awaitCaller.Run(() => meshData.LoadFromGltf(Data, index, inverter)); var meshWithMaterials = await BuildMeshAsync(awaitCaller, MeasureTime, meshData, index); Meshes.Add(meshWithMaterials); } } await awaitCaller.NextFrame(); } if (GLTF.nodes.Count > 0) { using (MeasureTime("LoadNodes")) { Profiler.BeginSample("ImporterContext.LoadNodes"); for (var i = 0; i < GLTF.nodes.Count; i++) { Nodes.Add(NodeImporter.ImportNode(GLTF.nodes[i], i).transform); } Profiler.EndSample(); } await awaitCaller.NextFrame(); } using (MeasureTime("BuildHierarchy")) { var nodes = new List <NodeImporter.TransformWithSkin>(); if (Nodes.Count > 0) { Profiler.BeginSample("NodeImporter.BuildHierarchy"); for (var i = 0; i < Nodes.Count; ++i) { nodes.Add(NodeImporter.BuildHierarchy(GLTF, i, Nodes, Meshes)); } Profiler.EndSample(); await awaitCaller.NextFrame(); } NodeImporter.FixCoordinate(GLTF, nodes, inverter); // skinning if (nodes.Count > 0) { Profiler.BeginSample("NodeImporter.SetupSkinning"); for (var i = 0; i < nodes.Count; ++i) { NodeImporter.SetupSkinning(Data, nodes, i, inverter); } Profiler.EndSample(); await awaitCaller.NextFrame(); } if (Root == null) { Root = new GameObject("GLTF"); } if (GLTF.rootnodes != null) { // connect root foreach (var x in GLTF.rootnodes) { var t = nodes[x].Transform; t.SetParent(Root.transform, false); } } } await awaitCaller.NextFrame(); }
protected virtual async Task LoadGeometryAsync(IAwaitCaller awaitCaller, Func <string, IDisposable> MeasureTime) { var inverter = InvertAxis.Create(); var meshImporter = new MeshImporter(); if (GLTF.meshes.Count > 0) { for (var i = 0; i < GLTF.meshes.Count; ++i) { var index = i; using (MeasureTime("ReadMesh")) { var x = await awaitCaller.Run(() => meshImporter.ReadMesh(Data, index, inverter)); var y = await BuildMeshAsync(awaitCaller, MeasureTime, x, index); Meshes.Add(y); } } await awaitCaller.NextFrame(); } if (GLTF.nodes.Count > 0) { using (MeasureTime("LoadNodes")) { Profiler.BeginSample("ImporterContext.LoadNodes"); for (var i = 0; i < GLTF.nodes.Count; i++) { Nodes.Add(NodeImporter.ImportNode(GLTF.nodes[i], i).transform); } Profiler.EndSample(); } await awaitCaller.NextFrame(); } using (MeasureTime("BuildHierarchy")) { var nodes = new List <NodeImporter.TransformWithSkin>(); if (Nodes.Count > 0) { Profiler.BeginSample("NodeImporter.BuildHierarchy"); for (var i = 0; i < Nodes.Count; ++i) { nodes.Add(NodeImporter.BuildHierarchy(GLTF, i, Nodes, Meshes)); } Profiler.EndSample(); await awaitCaller.NextFrame(); } NodeImporter.FixCoordinate(GLTF, nodes, inverter); // skinning if (nodes.Count > 0) { Profiler.BeginSample("NodeImporter.SetupSkinning"); for (var i = 0; i < nodes.Count; ++i) { NodeImporter.SetupSkinning(Data, nodes, i, inverter); } Profiler.EndSample(); await awaitCaller.NextFrame(); } if (Root == null) { Root = new GameObject("GLTF"); } if (GLTF.rootnodes != null) { // connect root foreach (var x in GLTF.rootnodes) { var t = nodes[x].Transform; t.SetParent(Root.transform, false); } } } await awaitCaller.NextFrame(); }