Exemple #1
0
        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);
        }
Exemple #2
0
        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));
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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();
        }
Exemple #5
0
        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);
            }
        }
Exemple #6
0
        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();
        }