示例#1
0
        private void displayInputInfos()
        {
            GUILayout.Label("Import a glTF (*.gltf, *.glb, *.zip)", _ui.sketchfabModelName);

            _ui.displaySubContent("Source file:");
            GUILayout.BeginHorizontal();
            Color backup = GUI.color;

            if (_importFilePath == _sourceFileHint)
            {
                GUI.contentColor = Color.red;
            }

            GUILayout.TextField(_importFilePath, GUILayout.MinWidth(UI_SIZE.x), GUILayout.Height(UI_SIZE.y));
            GUI.contentColor = backup;
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Select file", GUILayout.Height(UI_SIZE.y), GUILayout.Width(minWidthButton)))
            {
                _importFilePath = EditorUtility.OpenFilePanel("Choose gltf or zip file", "", "zip,gltf,glb");

                string modelfileName = Path.GetFileNameWithoutExtension(_importFilePath);
                _importDirectory   = GLTFUtils.unifyPathSeparator(Path.Combine(_defaultImportDirectory, modelfileName));
                _currentSampleName = modelfileName;
            }

            GUILayout.EndHorizontal();
        }
示例#2
0
        /// <summary>
        /// Create a prefab from the imported hierarchy of game objects.
        /// This is the final output of an Editor glTF import.
        /// </summary>
        protected IEnumerator <GameObject> CreatePrefabEnum()
        {
            string basename = "scene.prefab";

            if (!String.IsNullOrEmpty(_imported.Scene.name))
            {
                basename = String.Format("{0}.prefab",
                                         GLTFUtils.cleanName(_imported.Scene.name));
            }

            string dir  = UnityPathUtil.GetProjectPath(_importPath);
            string path = Path.Combine(dir, basename);

            GameObject prefab =
                PrefabUtility.SaveAsPrefabAsset(_imported.Scene, path);

            // Make the prefab visible.
            //
            // Note: The model hierarchy is kept hidden during the glTF import
            // so that the user never sees the partially reconstructed
            // model.

            prefab.SetActive(true);

            // Note: base.Clear() removes imported game objects from
            // the scene and from memory, but does not remove imported
            // asset files from disk.

            base.Clear();

            yield return(prefab);
        }
    // UI FUNCTIONS
    private void showImportUI()
    {
        // Import file
        GUILayout.BeginHorizontal();
        GUILayout.FlexibleSpace();
        GUILayout.Label("Import or Drag'n drop glTF asset(gltf, glb, zip supported)", _header);
        GUILayout.FlexibleSpace();
        GUILayout.EndHorizontal();

        GUILayout.BeginVertical("Box");
        GUILayout.Label("Model to import: " + _gltfPath);
        GUILayout.Label("Import directory: " + stripProjectDirectory(_projectDirectory));

        GUILayout.EndVertical();
        GUILayout.BeginHorizontal();
        if (GUILayout.Button("Import file from disk"))
        {
            _gltfPath = EditorUtility.OpenFilePanel("Choose glTF to import", Application.dataPath, "glb,gltf,zip");
            string modelfileName = Path.GetFileNameWithoutExtension(_gltfPath);
            _projectDirectory  = GLTFUtils.unifyPathSeparator(Path.Combine(_defaultImportDirectory, modelfileName));
            _currentSampleName = modelfileName;
        }
        if (GUILayout.Button("Change import directory"))
        {
            changeDirectory();
        }
        GUILayout.EndHorizontal();
    }
    private void proceedToExportAndUpload()
    {
        if (System.IO.File.Exists(zipPath))
        {
            System.IO.File.Delete(zipPath);
        }

        // "Sketchfab Plugin (Unity " + Application.unityVersion + ")"
        var exporter = new GLTFSceneExporter(opt_exportSelection ? GLTFUtils.getSelectedTransforms() : GLTFUtils.getSceneTransforms());

        exporter.enableAnimation(opt_exportAnimation);
        exporter.SaveGLTFandBin(Path.GetDirectoryName(exportPath), Path.GetFileNameWithoutExtension(exportPath));

        GLTFUtils.buildZip(exporter.getExportedFilesList(), Path.Combine(Path.GetDirectoryName(exportPath), "Unity2Skfb.zip"), true);
        if (File.Exists(zipPath))
        {
            bool shouldUpload = checkFileSize(zipPath);

            if (!shouldUpload)
            {
                shouldUpload = EditorUtility.DisplayDialog("Error", "The export exceed the max file size allowed by your current account type", "Continue", "Cancel");
            }
            _api.publishModel(buildParameterDict(), zipPath);
        }
        else
        {
            Debug.Log("Zip file has not been generated. Aborting publish.");
        }
    }
        private void updateSettingsWithFile()
        {
            string modelfileName = Path.GetFileNameWithoutExtension(_importFilePath);

            _importDirectory   = GLTFUtils.unifyPathSeparator(Path.Combine(_defaultImportDirectory, modelfileName));
            _currentSampleName = modelfileName;
        }
示例#6
0
        private void displayInputInfos()
        {
            GUILayout.Label("Import a glTF (*.gltf, *.glb, *.zip)", _ui.sketchfabModelName);

            _ui.displaySubContent("Source file:");
            GUILayout.BeginHorizontal();
            Color backup = GUI.color;

            if (_importFilePath == _sourceFileHint)
            {
                GUI.contentColor = Color.red;
            }

            GUILayout.TextField(_importFilePath, GUILayout.MinWidth(UI_SIZE.x), GUILayout.Height(UI_SIZE.y));
            GUI.contentColor = backup;
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Select file", GUILayout.Height(UI_SIZE.y), GUILayout.Width(minWidthButton)))
            {
                string newImportDir = EditorUtility.OpenFolderPanel("Choose import directory", GLTFUtils.getPathAbsoluteFromProject(_importDirectory), GLTFUtils.getPathAbsoluteFromProject(_importDirectory));
                if (GLTFUtils.isFolderInProjectDirectory(newImportDir))
                {
                    _importDirectory = newImportDir;
                }
                else if (newImportDir != "")
                {
                    EditorUtility.DisplayDialog("Error", "Please select a path within your current Unity project (with Assets/)", "Ok");
                }
            }

            GUILayout.EndHorizontal();
        }
示例#7
0
    // File serialization
    public Mesh saveMesh(Mesh mesh, string objectName = "Scene")
    {
        string baseName        = GLTFUtils.cleanName(objectName + ".asset");
        string fullPath        = Path.Combine(_importMeshesDirectory, baseName);
        string meshProjectPath = GLTFUtils.getPathProjectFromAbsolute(fullPath);

        serializeAsset(mesh, meshProjectPath, fullPath, true);
        return(AssetDatabase.LoadAssetAtPath(meshProjectPath, typeof(Mesh)) as Mesh);
    }
示例#8
0
        private void CopyLicenseFile()
        {
            String licensePath     = Path.Combine(_gltfDirectoryPath, "license.txt");
            String destLicensePath = GLTFUtils.SystemToUnityPath(GLTFUtils.getPathAbsoluteFromProject(Path.Combine(_projectDirectoryPath, "license.txt")));

            if (File.Exists(licensePath))
            {
                File.Copy(licensePath, destLicensePath);
            }
        }
示例#9
0
        // Model archive download and import
        public void importArchive(byte[] data, string unzipDirectory, string importDirectory, string prefabName, bool addToCurrentScene = false)
        {
            if (!GLTFUtils.isFolderInProjectDirectory(importDirectory))
            {
                EditorUtility.DisplayDialog("Error", "Please select a path within your Asset directory", "OK");
                return;
            }

            _importer.configure(importDirectory, prefabName, addToCurrentScene);
            _importer.loadFromBuffer(data);
        }
示例#10
0
    // https://docs.unity3d.com/ScriptReference/Animations.AnimatorController.html
    private void createAnimatorAsset(AnimationClip clip)
    {
        string animatorname = getPrefabName(_prefabName);
        string animatorPath = GLTFUtils.getPathProjectFromAbsolute(_importAnimationDirectory + "/" + animatorname + ".controller");

        AnimatorController.CreateAnimatorControllerAtPathWithClip(animatorPath, clip);
        if (_animator == null)
        {
            _animator = AssetDatabase.LoadAssetAtPath <Animator>(animatorPath);
        }
    }
示例#11
0
    public Material saveMaterial(Material material, int index)
    {
        string baseName            = generateName(material.name.Length > 0 ? material.name.Trim() : "material", index) + ".mat";
        string materialAssetPath   = Path.Combine(_importMaterialsDirectory, baseName);
        string materialProjectPath = GLTFUtils.getPathProjectFromAbsolute(materialAssetPath);

        serializeAsset(material, materialProjectPath, materialAssetPath, true);

        // Reload as asset
        return((Material)AssetDatabase.LoadAssetAtPath(materialProjectPath, typeof(Material)));
    }
        void onChangImportDirectoryClick()
        {
            string newImportDir = EditorUtility.OpenFolderPanel("Choose import directory", Application.dataPath, "");

            if (GLTFUtils.isFolderInProjectDirectory(newImportDir))
            {
                _importDirectory = newImportDir;
            }
            else if (newImportDir != "")
            {
                EditorUtility.DisplayDialog("Error", "Please select a path within your current Unity project (with Assets/)", "Ok");
            }
        }
示例#13
0
    public Texture2D saveTexture(Texture2D texture, int index = -1, string imageName = "")
    {
        string basename = GLTFUtils.cleanName(texture.name + (index >= 0 ? "_" + index.ToString() : "") + ".png");         // Extension will be overridden
        string fullPath = Path.Combine(_importTexturesDirectory, basename);

        // Write texture
        string newAssetPath = GLTFTextureUtils.writeTextureOnDisk(texture, fullPath, true);

        // Reload as asset
        string    projectPath = GLTFUtils.getPathProjectFromAbsolute(newAssetPath);
        Texture2D tex         = (Texture2D)AssetDatabase.LoadAssetAtPath(projectPath, typeof(Texture2D));

        _parsedImages.Add(tex);
        return(tex);
    }
示例#14
0
        private void handleDragNDrop()
        {
            DragAndDrop.visualMode = DragAndDropVisualMode.Generic;

            if (Event.current.type == EventType.DragExited)
            {
                if (DragAndDrop.paths.Length > 0)
                {
                    _importFilePath = DragAndDrop.paths[0];
                    string modelfileName = Path.GetFileNameWithoutExtension(_importFilePath);
                    _importDirectory   = GLTFUtils.unifyPathSeparator(Path.Combine(_defaultImportDirectory, modelfileName));
                    _currentSampleName = modelfileName;
                }
            }
        }
示例#15
0
    public GameObject savePrefab(GameObject sceneObject, string _importDirectory, bool instanciateInScene = false)
    {
        string baseName            = getPrefabName(sceneObject.name) + ".prefab";
        string fullPath            = Path.Combine(_importDirectory, baseName);
        string prefabPathInProject = GLTFUtils.getPathProjectFromAbsolute(fullPath);

        if (File.Exists(fullPath))
        {
            File.Delete(fullPath);
            File.Delete(fullPath + ".meta");
            AssetDatabase.Refresh();
        }

        _generatedFiles.Add(fullPath);
        return(PrefabUtility.CreatePrefab(prefabPathInProject, sceneObject));
    }
示例#16
0
        private void displayImportButton()
        {
            GUILayout.BeginHorizontal();
            Color old = GUI.color;

            GUI.color        = GlTFUI.SKFB_BLUE;
            GUI.contentColor = Color.white;
            GUI.enabled      = GLTFUtils.isFolderInProjectDirectory(_importDirectory) && File.Exists(_importFilePath);
            if (GUILayout.Button("IMPORT", _ui.GlTFButton))
            {
                processImportButton();
            }
            GUI.color   = old;
            GUI.enabled = true;
            GUILayout.EndHorizontal();
        }
示例#17
0
        public void loadFromBuffer(byte[] data)
        {
            if (!GLTFUtils.isFolderInProjectDirectory(_importDirectory))
            {
                Debug.LogError("Import directory is outside of project directory. Please select path in Assets/");
                return;
            }

            if (!Directory.Exists(_importDirectory))
            {
                Directory.CreateDirectory(_importDirectory);
            }

            _gltfInput = unzipGLTFArchiveData(data);
            _importer.setupForPath(_gltfInput, _importDirectory, _currentSampleName, _addToCurrentScene);
            _importer.Load();
        }
        public void displayModelPage(SketchfabModel model, SketchfabBrowser browser)
        {
            _window = browser;
            if (_currentModel == null || model.uid != _currentModel.uid)
            {
                _currentModel    = model;
                _prefabName      = GLTFUtils.cleanName(_currentModel.name).Replace(" ", "_");
                _importDirectory = Application.dataPath + "/Import/" + _prefabName.Replace(" ", "_");
            }
            else
            {
                _currentModel = model;
            }

            _ui  = SketchfabPlugin.getUI();
            show = true;
        }
示例#19
0
    public void saveAnimationClip(AnimationClip clip)
    {
        if (_importAnimationDirectory == null)
        {
            createAnimationDirectory();
        }

        string directory = GLTFUtils.getPathProjectFromAbsolute(_importAnimationDirectory);
        string path      = directory + "/" + clip.name + ".anim";

        AssetDatabase.CreateAsset(clip, path);
        AssetDatabase.Refresh();

        // Add animation to animator
        AnimationClip loadedClip = AssetDatabase.LoadAssetAtPath <AnimationClip>(path);

        loadedClip.wrapMode = WrapMode.Loop;
        createAnimatorAsset(loadedClip);
    }
    private void OnGUI()
    {
        if (!_isInitialized)
        {
            Initialize();
        }

        checkValidity();

        SketchfabPlugin.showHeader();
        displayVersionInfo();

        DragAndDrop.visualMode = DragAndDropVisualMode.Generic;

        if (Event.current.type == EventType.DragExited)
        {
            if (DragAndDrop.paths.Length > 0)
            {
                _gltfPath = DragAndDrop.paths[0];
                string modelfileName = Path.GetFileNameWithoutExtension(_gltfPath);
                _projectDirectory  = GLTFUtils.unifyPathSeparator(Path.Combine(_defaultImportDirectory, modelfileName));
                _currentSampleName = modelfileName;
            }
        }

        showImportUI();

        // Options
        emptyLines(1);
        showOptions();
        emptyLines(1);

        // Disable import if nothing valid to import
        GUI.enabled = _gltfPath.Length > 0 && File.Exists(_gltfPath);

        // Import button
        if (GUILayout.Button("IMPORT"))
        {
            processImportButton();
        }

        showStatus();
    }
示例#21
0
        public void configure(string importDirectory, string prefabName, bool addToScene = false)
        {
            if (importDirectory.Length > 0)
            {
                if (!GLTFUtils.isFolderInProjectDirectory(importDirectory))
                {
                    Debug.LogError("Import directory in not in Assets");
                }
                else
                {
                    _importDirectory = importDirectory;
                }
            }

            if (prefabName.Length > 0)
            {
                _currentSampleName = prefabName;
            }

            _addToCurrentScene = addToScene;
        }
示例#22
0
        /// <summary>
        /// Create a prefab from the imported hierarchy of game objects.
        /// This is the final output of an Editor glTF import.
        /// </summary>
        protected IEnumerator <GameObject> CreatePrefabEnum()
        {
            string basename = "scene.prefab";

            if (!String.IsNullOrEmpty(_imported.Scene.name))
            {
                basename = String.Format("{0}.prefab",
                                         GLTFUtils.cleanName(_imported.Scene.name));
            }

            string dir  = UnityPathUtil.GetProjectPath(_importPath);
            string path = Path.Combine(dir, basename);

            GameObject prefab =
                PrefabUtility.SaveAsPrefabAsset(_imported.Scene, path);

            // Note: base.Clear() removes imported game objects from
            // the scene and from memory, but does not remove imported
            // asset files from disk.
            base.Clear();

            yield return(prefab);
        }
示例#23
0
        private string unzipGltfArchive(string zipPath)
        {
            if (!Directory.Exists(_unzipDirectory))
            {
                Directory.CreateDirectory(_unzipDirectory);
            }

            // Clean previously unzipped files
            GLTFUtils.removeFileList(_unzippedFiles.ToArray());
            string gltfFile = findGltfFile();

            if (gltfFile != "")
            {
                File.Delete(gltfFile);
            }

            // Extract archive
            ZipFile zipfile = ZipFile.Read(zipPath);

            zipfile.ExtractAll(_unzipDirectory, ExtractExistingFileAction.OverwriteSilently);

            return(findGltfFile());
        }
示例#24
0
    public void hardClean()
    {
        softClean();

        for (int i = 0; i < _createdGameObjects.Count; ++i)
        {
            Object.DestroyImmediate(_createdGameObjects[i]);
        }

        GLTFUtils.removeFileList(_generatedFiles.ToArray());
        AssetDatabase.Refresh();         // also triggers Resources.UnloadUnusedAssets()

        // Remove directories if empty
        GLTFUtils.removeEmptyDirectory(_importMeshesDirectory);
        GLTFUtils.removeEmptyDirectory(_importTexturesDirectory);
        GLTFUtils.removeEmptyDirectory(_importMaterialsDirectory);
        GLTFUtils.removeEmptyDirectory(_importAnimationDirectory);
        _createdGameObjects.Clear();

        AssetDatabase.Refresh();         // also triggers Resources.UnloadUnusedAssets()
        GLTFUtils.removeEmptyDirectory(_importDirectory);
        AssetDatabase.Refresh();         // also triggers Resources.UnloadUnusedAssets()
    }
示例#25
0
        private void ImportGLTF(CreateObjectModel fileModel)
        {
            try
            {
                if (_importer != null)
                {
                    _importer.cleanArtifacts();
                    _importer = null;
                }

                _importer = new SketchfabImporter(UpdateProgress, OnFinishImport);

                _importer.configure(GLTFUtils.getPathAbsoluteFromProject(fileModel.ModelFolder),
                                    Path.GetFileNameWithoutExtension(fileModel.Path), false);
                _importer.loadFromFile(fileModel.Path);
                fileModel.Extras = ParseAssetForLicense(_importer.GetGLTFInput());
            }
            catch (Exception e)
            {
                EditorUtility.DisplayDialog("Error!", $"Problem when importing a model for \"{fileModel.ObjectName}\" ({fileModel.Path}):\nNot valid model structure ({e.Message})", "OK");
                Debug.LogException(e);

                CleanUp();

                fileModel.Skip = true;

                if (_gltfQueue.Contains(fileModel))
                {
                    _gltfQueue.Remove(fileModel);
                }

                if (Directory.Exists("Assets/Objects/" + fileModel.ObjectName))
                {
                    Directory.Delete("Assets/Objects/" + fileModel.ObjectName, true);
                }
            }
        }
示例#26
0
 private void displayImportDirectory()
 {
     _ui.displaySubContent("Import into");
     GUILayout.BeginHorizontal();
     GUILayout.TextField(GLTFUtils.getPathProjectFromAbsolute(_importDirectory), GUILayout.MinWidth(UI_SIZE.x), GUILayout.Height(UI_SIZE.y));
     GUILayout.FlexibleSpace();
     if (GUILayout.Button("Change destination", GUILayout.Height(UI_SIZE.y), GUILayout.Width(minWidthButton)))
     {
         string newImportDir = EditorUtility.OpenFolderPanel("Choose import directory", GLTFUtils.getPathAbsoluteFromProject(_importDirectory), GLTFUtils.getPathAbsoluteFromProject(_importDirectory));
         if (GLTFUtils.isFolderInProjectDirectory(newImportDir))
         {
             _importDirectory = newImportDir;
         }
         else if (newImportDir != "")
         {
             EditorUtility.DisplayDialog("Error", "Please select a path within your current Unity project (with Assets/)", "Ok");
         }
         else
         {
             // Path is empty, user canceled. Do nothing
         }
     }
     GUILayout.EndHorizontal();
 }
示例#27
0
        void displayImportSettings()
        {
            GUILayout.BeginVertical("Box");
            _ui.displayContent("Import into");
            GUILayout.BeginHorizontal();
            GUILayout.Label(GLTFUtils.getPathProjectFromAbsolute(_importDirectory), GUILayout.Height(18));
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Change", GUILayout.Width(80), GUILayout.Height(18)))
            {
                string newImportDir = EditorUtility.OpenFolderPanel("Choose import directory", Application.dataPath, "");
                if (GLTFUtils.isFolderInProjectDirectory(newImportDir))
                {
                    _importDirectory = newImportDir;
                }
                else if (newImportDir != "")
                {
                    EditorUtility.DisplayDialog("Error", "Please select a path within your current Unity project (with Assets/)", "Ok");
                }
                else
                {
                    // Path is empty, user canceled. Do nothing
                }
            }
            GUILayout.EndHorizontal();
            _ui.displayContent("Options");
            GUILayout.BeginHorizontal();
            GUILayout.Label("Prefab name");
            _prefabName = GUILayout.TextField(_prefabName, GUILayout.Width(200));
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            _addToCurrentScene = GUILayout.Toggle(_addToCurrentScene, "Add to current scene");

            GUILayout.BeginHorizontal();
            Color old = GUI.color;

            GUI.color        = SketchfabUI.SKFB_BLUE;
            GUI.contentColor = Color.white;
            string buttonCaption = "";

            if (!_window._logger.isUserLogged())
            {
                buttonCaption = "You need to be logged in to download and import assets";
                GUI.enabled   = false;
            }
            else if (_isFeching)
            {
                buttonCaption = "Looking for model download url";
                GUI.enabled   = false;
            }
            else if (_archiveUrl != "")
            {
                buttonCaption = "Download model (" + Utils.humanifyFileSize(_size) + ")";
            }
            else
            {
                buttonCaption = "Model is not available in glTF";
                GUI.enabled   = false;
            }
            if (GUILayout.Button(buttonCaption))
            {
                if (!assetAlreadyExists() || EditorUtility.DisplayDialog("Override asset", "The asset " + _prefabName + " already exists in project. Do you want to override it ?", "Override", "Cancel"))
                {
                    requestArchive();
                }
            }
            GUI.color   = old;
            GUI.enabled = true;
            GUILayout.EndHorizontal();
            GUILayout.EndVertical();
        }
示例#28
0
 public void OnDestroy()
 {
     GLTFUtils.removeFileList(_unzippedFiles.ToArray());
     GLTFUtils.removeEmptyDirectory(_unzipDirectory);
 }
示例#29
0
 public void cleanArtifacts()
 {
     GLTFUtils.removeFileList(_unzippedFiles.ToArray());
 }
        private void addGLTFChannelDataToClip(GLTF.Schema.AnimationChannel channel, AnimationClip clip)
        {
            int animatedNodeIndex = channel.Target.Node.Id;

            if (!_importedObjects.ContainsKey(animatedNodeIndex))
            {
                Debug.Log("Node '" + animatedNodeIndex + "' found for animation, aborting.");
            }

            Transform animatedNode = _importedObjects[animatedNodeIndex].transform;
            string    nodePath     = AnimationUtility.CalculateTransformPath(animatedNode, _sceneObject.transform);

            bool isStepInterpolation = channel.Sampler.Value.Interpolation != InterpolationType.LINEAR;

            byte[]  timeBufferData = _assetCache.BufferCache[channel.Sampler.Value.Output.Value.BufferView.Value.Buffer.Id];
            float[] times          = GLTFHelpers.ParseKeyframeTimes(channel.Sampler.Value.Input.Value, timeBufferData);

            if (channel.Target.Path == GLTFAnimationChannelPath.translation || channel.Target.Path == GLTFAnimationChannelPath.scale)
            {
                byte[] bufferData             = _assetCache.BufferCache[channel.Sampler.Value.Output.Value.BufferView.Value.Buffer.Id];
                GLTF.Math.Vector3[] keyValues = GLTFHelpers.ParseVector3Keyframes(channel.Sampler.Value.Output.Value, bufferData);
                if (keyValues == null)
                {
                    return;
                }

                Vector3[]        values        = keyValues.ToUnityVector3();
                AnimationCurve[] vector3Curves = GLTFUtils.createCurvesFromArrays(times, values, isStepInterpolation, channel.Target.Path == GLTFAnimationChannelPath.translation);

                if (channel.Target.Path == GLTFAnimationChannelPath.translation)
                {
                    GLTFUtils.addTranslationCurvesToClip(vector3Curves, nodePath, ref clip);
                }
                else
                {
                    GLTFUtils.addScaleCurvesToClip(vector3Curves, nodePath, ref clip);
                }
            }
            else if (channel.Target.Path == GLTFAnimationChannelPath.rotation)
            {
                byte[]           bufferData     = _assetCache.BufferCache[channel.Sampler.Value.Output.Value.BufferView.Value.Buffer.Id];
                Vector4[]        values         = GLTFHelpers.ParseRotationKeyframes(channel.Sampler.Value.Output.Value, bufferData).ToUnityVector4();
                AnimationCurve[] rotationCurves = GLTFUtils.createCurvesFromArrays(times, values, isStepInterpolation);

                GLTFUtils.addRotationCurvesToClip(rotationCurves, nodePath, ref clip);
            }
            else if (channel.Target.Path == GLTFAnimationChannelPath.weights)
            {
                List <string> morphTargets = new List <string>();
                int           meshIndex    = _root.Nodes[animatedNodeIndex].Mesh.Id;
                for (int i = 0; i < _root.Meshes[meshIndex].Primitives[0].Targets.Count; ++i)
                {
                    morphTargets.Add(GLTFUtils.buildBlendShapeName(meshIndex, i));
                }

                byte[]           bufferData  = _assetCache.BufferCache[channel.Sampler.Value.Output.Value.BufferView.Value.Buffer.Id];
                float[]          values      = GLTFHelpers.ParseKeyframeTimes(channel.Sampler.Value.Output.Value, bufferData);
                AnimationCurve[] morphCurves = GLTFUtils.buildMorphAnimationCurves(times, values, morphTargets.Count);

                GLTFUtils.addMorphAnimationCurvesToClip(morphCurves, nodePath, morphTargets.ToArray(), ref clip);
            }
            else
            {
                Debug.Log("Unsupported animation channel target: " + channel.Target.Path);
            }
        }