Example #1
0
        /// <summary>
        /// Load the VRM file from the binary.
        ///
        /// You should call this on Unity main thread.
        /// This will throw Exceptions (include OperationCanceledException).
        /// </summary>
        /// <param name="bytes">vrm file data</param>
        /// <param name="canLoadVrm0X">if true, this loader can load the vrm-0.x model as vrm-1.0 model with migration.</param>
        /// <param name="normalizeTransform">if true, vrm-1.0 models' transforms are normalized. (e.g. rotation, scaling)</param>
        /// <param name="showMeshes">if true, show meshes when loaded.</param>
        /// <param name="awaitCaller">this loader use specified await strategy.</param>
        /// <param name="materialGenerator">this loader use specified material generation strategy.</param>
        /// <param name="vrmMetaInformationCallback">return callback that notify meta information before loading.</param>
        /// <param name="ct">CancellationToken</param>
        /// <returns>vrm-1.0 instance. Maybe return null if unexpected error was raised.</returns>
        public static async Task <Vrm10Instance> LoadBytesAsync(
            byte[] bytes,
            bool canLoadVrm0X        = true,
            bool normalizeTransform  = true,
            bool showMeshes          = true,
            IAwaitCaller awaitCaller = null,
            IMaterialDescriptorGenerator materialGenerator        = null,
            VrmMetaInformationCallback vrmMetaInformationCallback = null,
            CancellationToken ct = default)
        {
            if (awaitCaller == null)
            {
                awaitCaller = Application.isPlaying
                    ? (IAwaitCaller) new RuntimeOnlyAwaitCaller()
                    : (IAwaitCaller) new ImmediateCaller();
            }

            return(await LoadAsync(
                       string.Empty,
                       bytes,
                       canLoadVrm0X,
                       normalizeTransform,
                       showMeshes,
                       awaitCaller,
                       materialGenerator,
                       vrmMetaInformationCallback,
                       ct));
        }
Example #2
0
        private static async Task <Vrm10Instance> LoadVrm10DataAsync(
            Vrm10Data vrm10Data,
            MigrationData migrationData,
            bool normalizeTransform,
            bool showMeshes,
            IAwaitCaller awaitCaller,
            IMaterialDescriptorGenerator materialGenerator,
            VrmMetaInformationCallback vrmMetaInformationCallback,
            CancellationToken ct)
        {
            ct.ThrowIfCancellationRequested();
            if (awaitCaller == null)
            {
                throw new ArgumentNullException();
            }

            if (vrm10Data == null)
            {
                throw new ArgumentNullException(nameof(vrm10Data));
            }

            using (var loader = new Vrm10Importer(vrm10Data, materialGenerator: materialGenerator, doNormalize: normalizeTransform))
            {
                // 1. Load meta information if callback was available.
                if (vrmMetaInformationCallback != null)
                {
                    var thumbnail = await loader.LoadVrmThumbnailAsync();

                    if (migrationData != null)
                    {
                        vrmMetaInformationCallback(thumbnail, default, migrationData.OriginalMetaBeforeMigration);
Example #3
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));
        }
Example #4
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);
            }
        }
Example #5
0
        private static async Task <Vrm10Instance> LoadAsync(
            string name,
            byte[] bytes,
            bool canLoadVrm0X,
            bool normalizeTransform,
            bool showMeshes,
            IAwaitCaller awaitCaller,
            IMaterialDescriptorGenerator materialGenerator,
            VrmMetaInformationCallback vrmMetaInformationCallback,
            CancellationToken ct)
        {
            ct.ThrowIfCancellationRequested();
            if (awaitCaller == null)
            {
                throw new ArgumentNullException();
            }

            using (var gltfData = new GlbLowLevelParser(name, bytes).Parse())
            {
                // 1. Try loading as vrm-1.0
                var instance = await TryLoadingAsVrm10Async(
                    gltfData,
                    normalizeTransform,
                    showMeshes,
                    awaitCaller,
                    materialGenerator,
                    vrmMetaInformationCallback,
                    ct);

                if (instance != null)
                {
                    if (ct.IsCancellationRequested)
                    {
                        UnityObjectDestoyer.DestroyRuntimeOrEditor(instance.gameObject);
                        ct.ThrowIfCancellationRequested();
                    }
                    return(instance);
                }

                // 2. Stop loading if not allowed migration.
                if (!canLoadVrm0X)
                {
                    throw new Exception($"Failed to load as VRM 1.0: {name}");
                }

                // 3. Try migration from vrm-0.x into vrm-1.0
                var migratedInstance = await TryMigratingFromVrm0XAsync(
                    gltfData,
                    normalizeTransform,
                    showMeshes,
                    awaitCaller,
                    materialGenerator,
                    vrmMetaInformationCallback,
                    ct);

                if (migratedInstance != null)
                {
                    if (ct.IsCancellationRequested)
                    {
                        UnityObjectDestoyer.DestroyRuntimeOrEditor(migratedInstance.gameObject);
                        ct.ThrowIfCancellationRequested();
                    }
                    return(migratedInstance);
                }

                // 4. Failed loading.
                throw new Exception($"Failed to load: {name}");
            }
        }