/// <summary>
 /// Setups the Avatar Loader.
 /// </summary>
 protected void Start()
 {
     _loaderOptions = AssetLoaderOptions.CreateInstance();
     _loaderOptions.UseLegacyAnimations = false;
     _loaderOptions.AnimatorController  = RuntimeAnimatorController;
 }
        public override void OnInspectorGUI()
        {
            if (!_isAssimpAsset)
            {
                base.OnInspectorGUI();
                return;
            }
            GUI.enabled = true;
#pragma warning disable 618
            EditorGUIUtility.LookLikeInspector();
#pragma warning restore 618
            EditorGUILayout.BeginVertical();
            EditorGUILayout.BeginHorizontal();
            _currentTab = GUILayout.Toggle(_currentTab == 0, "General", "Button") ? 0 : _currentTab;
            _currentTab = GUILayout.Toggle(_currentTab == 1, "Meshes", "Button") ? 1 : _currentTab;
            _currentTab = GUILayout.Toggle(_currentTab == 2, "Materials", "Button") ? 2 : _currentTab;
            _currentTab = GUILayout.Toggle(_currentTab == 3, "Animations", "Button") ? 3 : _currentTab;
            _currentTab = GUILayout.Toggle(_currentTab == 4, "Misc", "Button") ? 4 : _currentTab;
            _currentTab = GUILayout.Toggle(_currentTab == 5, "Metadata", "Button") ? 5 : _currentTab;
            _currentTab = GUILayout.Toggle(_currentTab == 6, "Advanced", "Button") ? 6 : _currentTab;
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();
            EditorGUI.BeginChangeCheck();
            switch (_currentTab)
            {
            case 0:
                EditorGUILayout.LabelField("General", EditorStyles.boldLabel);
#if UNITY_2017_3_OR_NEWER
                _tempAssetLoaderOptions.PostProcessSteps = (AssimpPostProcessSteps)EditorGUILayout.EnumFlagsField("Post Processor Options", _tempAssetLoaderOptions.PostProcessSteps);
#else
                _tempAssetLoaderOptions.PostProcessSteps = (AssimpPostProcessSteps)EditorGUILayout.EnumMaskField("Post Processor Options", _tempAssetLoaderOptions.PostProcessSteps);
#endif
                break;

            case 1:
            {
                EditorGUILayout.LabelField("Meshes", EditorStyles.boldLabel);
                var dontLoadMeshesProperty = _tempSerializedObject.FindProperty("DontLoadMeshes");
                EditorGUILayout.PropertyField(dontLoadMeshesProperty);
                if (!dontLoadMeshesProperty.boolValue)
                {
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("CombineMeshes"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("Scale"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("RotationAngles"));
#if UNITY_2017_3_OR_NEWER
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("Use32BitsIndexFormat"));
#endif
                    var generateMeshCollidersProperty = _tempSerializedObject.FindProperty("GenerateMeshColliders");
                    EditorGUILayout.PropertyField(generateMeshCollidersProperty);
                    if (generateMeshCollidersProperty.boolValue)
                    {
                        EditorGUI.indentLevel = 1;
                        EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("ConvexMeshColliders"));
                        EditorGUI.indentLevel = 0;
                    }
                }
                EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("DontLoadSkinning"));
                EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("DontLoadBlendShapes"));
            }
            break;

            case 2:
            {
                EditorGUILayout.LabelField("Materials", EditorStyles.boldLabel);
                var dontLoadMaterialsProperty = _tempSerializedObject.FindProperty("DontLoadMaterials");
                EditorGUILayout.PropertyField(dontLoadMaterialsProperty);
                if (!dontLoadMaterialsProperty.boolValue)
                {
                    var disableAlphaMaterials = _tempSerializedObject.FindProperty("DisableAlphaMaterials");
                    EditorGUILayout.PropertyField(disableAlphaMaterials);
                    if (!disableAlphaMaterials.boolValue)
                    {
                        EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("ApplyColorAlpha"));
                    }
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("ApplyDiffuseColor"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("ApplyEmissionColor"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("ApplySpecularColor"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("ApplyDiffuseTexture"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("ApplyEmissionTexture"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("ApplySpecularTexture"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("ApplyNormalTexture"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("ApplyDisplacementTexture"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("ApplyNormalScale"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("ApplyGlossiness"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("ApplyGlossinessScale"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("GenerateMipMaps"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("UseStandardSpecularMaterial"));
                    if (!disableAlphaMaterials.boolValue)
                    {
                        EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("ScanForAlphaMaterials"));
                        EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("UseCutoutMaterials"));
                    }
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("TextureCompression"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("TextureFilterMode"));
                }
            }
            break;

            case 3:
            {
                EditorGUILayout.LabelField("Animations", EditorStyles.boldLabel);
                var dontLoadAnimationsProperty = _tempSerializedObject.FindProperty("DontLoadAnimations");
                EditorGUILayout.PropertyField(dontLoadAnimationsProperty);
                if (!dontLoadAnimationsProperty.boolValue)
                {
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("AutoPlayAnimations"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("AnimationWrapMode"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("EnsureQuaternionContinuity"));
                    var legacyAnimationProperty = _tempSerializedObject.FindProperty("UseLegacyAnimations");
                    EditorGUILayout.PropertyField(legacyAnimationProperty);
                    if (!legacyAnimationProperty.boolValue)
                    {
                        EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("AnimatorController"));
                        var avatar = _tempSerializedObject.FindProperty("Avatar");
                        EditorGUILayout.PropertyField(avatar);
                        if (avatar.objectReferenceValue == null)
                        {
                            EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("DontGenerateAvatar"));
                        }
                    }
                }
            }
            break;

            case 4:
            {
                EditorGUILayout.LabelField("Misc", EditorStyles.boldLabel);
                EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("AddAssetUnloader"));
                EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("DontLoadCameras"));
                EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("DontLoadLights"));
            }
            break;

            case 5:
            {
                EditorGUILayout.LabelField("Metadata", EditorStyles.boldLabel);
                EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("DontLoadMetadata"));
            }
            break;

            default:
            {
                EditorGUILayout.LabelField("Advanced", EditorStyles.boldLabel);
                var advancedConfigs = _tempSerializedObject.FindProperty("AdvancedConfigs");
                var lastGroup       = string.Empty;
                var groupIndex      = 0;
                foreach (var configKey in AssetAdvancedPropertyMetadata.ConfigKeys)
                {
                    AssetAdvancedConfigType assetAdvancedConfigType;
                    string className;
                    string description;
                    string group;
                    bool   hasDefaultValue;
                    bool   hasMinValue;
                    bool   hasMaxValue;
                    object defaultValue;
                    object minValue;
                    object maxValue;
                    AssetAdvancedPropertyMetadata.GetOptionMetadata(configKey, out assetAdvancedConfigType, out className, out description, out group, out defaultValue, out minValue, out maxValue, out hasDefaultValue, out hasMinValue, out hasMaxValue);
                    SerializedProperty elementSerializedProperty = null;
                    var serializedElementIndex = 0;
                    var recentlyCreated        = false;
                    for (var i = 0; i < _tempAssetLoaderOptions.AdvancedConfigs.Count; i++)
                    {
                        var advancedProperty = _tempAssetLoaderOptions.AdvancedConfigs[i];
                        if (advancedProperty.Key == configKey)
                        {
                            serializedElementIndex    = i;
                            elementSerializedProperty = advancedConfigs.GetArrayElementAtIndex(i);
                            break;
                        }
                    }
                    if (group != lastGroup)
                    {
                        lastGroup = group;
                        _groupUnfolded[groupIndex] = EditorGUILayout.Foldout(_groupUnfolded[groupIndex], lastGroup);
                        groupIndex++;
                    }
                    if (_groupUnfolded[groupIndex - 1])
                    {
                        EditorGUILayout.BeginHorizontal();
                        var enableProperty = EditorGUILayout.BeginToggleGroup(new GUIContent(className, description), elementSerializedProperty != null);
                        if (elementSerializedProperty == null && enableProperty)
                        {
                            advancedConfigs.InsertArrayElementAtIndex(advancedConfigs.arraySize);
                            _tempSerializedObject.ApplyModifiedProperties();
                            var elementIndex = Mathf.Max(0, advancedConfigs.arraySize - 1);
                            elementSerializedProperty = advancedConfigs.GetArrayElementAtIndex(elementIndex);
                            elementSerializedProperty.FindPropertyRelative("Key").stringValue = configKey;
                            _tempSerializedObject.ApplyModifiedProperties();
                            recentlyCreated = true;
                        }
                        else if (elementSerializedProperty != null && !enableProperty)
                        {
                            advancedConfigs.DeleteArrayElementAtIndex(serializedElementIndex);
                            _tempSerializedObject.ApplyModifiedProperties();
                            return;
                        }
                        SerializedProperty valueSerializedProperty;
                        switch (assetAdvancedConfigType)
                        {
                        case AssetAdvancedConfigType.Bool:
                            var boolDefaultValue = hasDefaultValue && (bool)defaultValue;
                            if (elementSerializedProperty == null)
                            {
                                GUI.enabled = false;
                                EditorGUILayout.Toggle(boolDefaultValue ? "Enabled" : "Disabled", boolDefaultValue);
                            }
                            else
                            {
                                GUI.enabled             = true;
                                valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("BoolValue");
                                if (recentlyCreated)
                                {
                                    valueSerializedProperty.boolValue = boolDefaultValue;
                                }
                                EditorGUILayout.PropertyField(valueSerializedProperty, new GUIContent(valueSerializedProperty.boolValue ? "Enabled" : "Disabled"));
                            }
                            break;

                        case AssetAdvancedConfigType.Integer:
                            var intDefaultValue = hasDefaultValue ? (int)defaultValue : 0;
                            if (hasMinValue && hasMaxValue)
                            {
                                if (elementSerializedProperty == null)
                                {
                                    GUI.enabled = false;
                                    EditorGUILayout.IntSlider(intDefaultValue, (int)minValue, (int)maxValue);
                                }
                                else
                                {
                                    GUI.enabled             = true;
                                    valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("IntValue");
                                    if (recentlyCreated)
                                    {
                                        valueSerializedProperty.intValue = intDefaultValue;
                                    }
                                    EditorGUILayout.IntSlider(valueSerializedProperty, (int)minValue, (int)maxValue, GUIContent.none);
                                }
                            }
                            else
                            {
                                if (elementSerializedProperty == null)
                                {
                                    GUI.enabled = false;
                                    EditorGUILayout.IntField(intDefaultValue);
                                }
                                else
                                {
                                    GUI.enabled             = true;
                                    valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("IntValue");
                                    if (recentlyCreated)
                                    {
                                        valueSerializedProperty.intValue = intDefaultValue;
                                    }
                                    EditorGUILayout.PropertyField(valueSerializedProperty, GUIContent.none);
                                }
                            }
                            break;

                        case AssetAdvancedConfigType.Float:
                            var floatDefaultValue = hasDefaultValue ? (float)defaultValue : 0f;
                            if (hasMinValue && hasMaxValue)
                            {
                                if (elementSerializedProperty == null)
                                {
                                    GUI.enabled = false;
                                    EditorGUILayout.Slider(floatDefaultValue, (float)minValue, (float)maxValue);
                                }
                                else
                                {
                                    GUI.enabled             = true;
                                    valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("FloatValue");
                                    if (recentlyCreated)
                                    {
                                        valueSerializedProperty.floatValue = floatDefaultValue;
                                    }
                                    EditorGUILayout.Slider(valueSerializedProperty, (float)minValue, (float)maxValue, GUIContent.none);
                                }
                            }
                            else
                            {
                                if (elementSerializedProperty == null)
                                {
                                    GUI.enabled = false;
                                    EditorGUILayout.FloatField(floatDefaultValue);
                                }
                                else
                                {
                                    GUI.enabled             = true;
                                    valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("FloatValue");
                                    if (recentlyCreated)
                                    {
                                        valueSerializedProperty.floatValue = floatDefaultValue;
                                    }
                                    EditorGUILayout.PropertyField(valueSerializedProperty, GUIContent.none);
                                }
                            }
                            break;

                        case AssetAdvancedConfigType.String:
                            var stringDefaultValue = hasDefaultValue ? (string)defaultValue : string.Empty;
                            if (elementSerializedProperty == null)
                            {
                                GUI.enabled = false;
                                EditorGUILayout.TextField(stringDefaultValue);
                            }
                            else
                            {
                                GUI.enabled             = true;
                                valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("StringValue");
                                if (recentlyCreated)
                                {
                                    valueSerializedProperty.stringValue = stringDefaultValue;
                                }
                                EditorGUILayout.PropertyField(valueSerializedProperty, GUIContent.none);
                            }
                            break;

                        case AssetAdvancedConfigType.AiComponent:
                            var aiComponentDefaultValue = hasDefaultValue ? (AiComponent)defaultValue : AiComponent.Animations;
                            if (elementSerializedProperty == null)
                            {
                                GUI.enabled = false;
#if UNITY_2017_3_OR_NEWER
                                EditorGUILayout.EnumFlagsField(aiComponentDefaultValue);
#else
                                EditorGUILayout.EnumMaskField(aiComponentDefaultValue);
#endif
                            }
                            else
                            {
                                GUI.enabled             = true;
                                valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("IntValue");
                                if (recentlyCreated)
                                {
                                    valueSerializedProperty.intValue = (int)aiComponentDefaultValue;
                                }
                                PropertyEnumMaskField(valueSerializedProperty, assetAdvancedConfigType, GUIContent.none);
                            }
                            break;

                        case AssetAdvancedConfigType.AiPrimitiveType:
                            var aiPrimitiveTypeDefaultValue = hasDefaultValue ? (AiPrimitiveType)defaultValue : AiPrimitiveType.Line;
                            if (elementSerializedProperty == null)
                            {
                                GUI.enabled = false;
#if UNITY_2017_3_OR_NEWER
                                EditorGUILayout.EnumFlagsField(aiPrimitiveTypeDefaultValue);
#else
                                EditorGUILayout.EnumMaskField(aiPrimitiveTypeDefaultValue);
#endif
                            }
                            else
                            {
                                GUI.enabled             = true;
                                valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("IntValue");
                                if (recentlyCreated)
                                {
                                    valueSerializedProperty.intValue = (int)aiPrimitiveTypeDefaultValue;
                                }
                                PropertyEnumMaskField(valueSerializedProperty, assetAdvancedConfigType, GUIContent.none);
                            }
                            break;

                        case AssetAdvancedConfigType.AiUVTransform:
                            var aiUvTransformDefaultValue = hasDefaultValue ? (AiUVTransform)defaultValue : AiUVTransform.Rotation;
                            if (elementSerializedProperty == null)
                            {
                                GUI.enabled = false;
#if UNITY_2017_3_OR_NEWER
                                EditorGUILayout.EnumFlagsField(aiUvTransformDefaultValue);
#else
                                EditorGUILayout.EnumMaskField(aiUvTransformDefaultValue);
#endif
                            }
                            else
                            {
                                GUI.enabled             = true;
                                valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("IntValue");
                                if (recentlyCreated)
                                {
                                    valueSerializedProperty.intValue = (int)aiUvTransformDefaultValue;
                                }
                                PropertyEnumMaskField(valueSerializedProperty, assetAdvancedConfigType, GUIContent.none);
                            }
                            break;

                        case AssetAdvancedConfigType.AiMatrix:
                            if (elementSerializedProperty == null)
                            {
                                GUI.enabled = false;
                                GUILayout.BeginVertical();
                                GUILayout.BeginHorizontal();
                                GUILayout.Label("Translation", GUILayout.Width(75));
                                GUILayout.FlexibleSpace();
                                EditorGUILayout.Vector3Field(GUIContent.none, Vector3.zero);
                                GUILayout.EndHorizontal();
                                GUILayout.BeginHorizontal();
                                GUILayout.Label("Rotation", GUILayout.Width(75));
                                GUILayout.FlexibleSpace();
                                EditorGUILayout.Vector3Field(GUIContent.none, Vector3.zero);
                                GUILayout.EndHorizontal();
                                GUILayout.BeginHorizontal();
                                GUILayout.Label("Scale", GUILayout.Width(75));
                                GUILayout.FlexibleSpace();
                                EditorGUILayout.Vector3Field(GUIContent.none, Vector3.one);
                                GUILayout.EndHorizontal();
                                GUILayout.EndVertical();
                            }
                            else
                            {
                                GUI.enabled = true;
                                var valueSerializedProperty1 = elementSerializedProperty.FindPropertyRelative("TranslationValue");
                                var valueSerializedProperty2 = elementSerializedProperty.FindPropertyRelative("RotationValue");
                                var valueSerializedProperty3 = elementSerializedProperty.FindPropertyRelative("ScaleValue");
                                if (recentlyCreated)
                                {
                                    valueSerializedProperty1.vector3Value = Vector3.zero;
                                    valueSerializedProperty2.vector3Value = Vector3.zero;
                                    valueSerializedProperty3.vector3Value = Vector3.one;
                                }
                                GUILayout.BeginVertical();
                                GUILayout.BeginHorizontal();
                                GUILayout.Label("Translation", GUILayout.Width(75));
                                GUILayout.FlexibleSpace();
                                EditorGUILayout.PropertyField(valueSerializedProperty1, GUIContent.none, true, GUILayout.MinWidth(100));
                                GUILayout.EndHorizontal();
                                GUILayout.BeginHorizontal();
                                GUILayout.Label("Rotation", GUILayout.Width(75));
                                GUILayout.FlexibleSpace();
                                EditorGUILayout.PropertyField(valueSerializedProperty2, GUIContent.none, true, GUILayout.MinWidth(100));
                                GUILayout.EndHorizontal();
                                GUILayout.BeginHorizontal();
                                GUILayout.Label("Scale", GUILayout.Width(75));
                                GUILayout.FlexibleSpace();
                                EditorGUILayout.PropertyField(valueSerializedProperty3, GUIContent.none, true, GUILayout.MinWidth(100));
                                GUILayout.EndHorizontal();
                                GUILayout.EndVertical();
                            }
                            break;
                        }
                        GUI.enabled = true;
                        EditorGUILayout.EndToggleGroup();
                        EditorGUILayout.EndHorizontal();
                    }
                }
            }
            break;
            }
            if (EditorGUI.EndChangeCheck())
            {
                _hasChanged = true;
            }
            EditorGUILayout.Space();
            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUI.enabled = _hasChanged;
            if (GUILayout.Button("Revert"))
            {
                DestroyTempObject();
                _tempAssetLoaderOptions = AssetLoaderOptions.CreateInstance();
                SaveChanges();
            }
            if (GUILayout.Button("Apply"))
            {
                _tempSerializedObject.ApplyModifiedProperties();
                SaveChanges();
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndVertical();
        }
        public override void OnInspectorGUI()
        {
            if (!_isAssimpAsset)
            {
                base.OnInspectorGUI();
                return;
            }
            GUI.enabled = true;
#pragma warning disable 618
            EditorGUIUtility.LookLikeInspector();
#pragma warning restore 618
            EditorGUILayout.BeginVertical();
            EditorGUILayout.BeginHorizontal();
            _currentTab = GUILayout.Toggle(_currentTab == 0, "General", "Button") ? 0 : _currentTab;
            _currentTab = GUILayout.Toggle(_currentTab == 1, "Meshes", "Button") ? 1 : _currentTab;
            _currentTab = GUILayout.Toggle(_currentTab == 2, "Materials", "Button") ? 2 : _currentTab;
            _currentTab = GUILayout.Toggle(_currentTab == 3, "Animations", "Button") ? 3 : _currentTab;
            _currentTab = GUILayout.Toggle(_currentTab == 4, "Advanced", "Button") ? 4 : _currentTab;
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();
            EditorGUI.BeginChangeCheck();
            switch (_currentTab)
            {
            case 0:
                EditorGUILayout.LabelField("General", EditorStyles.boldLabel);
                _tempAssetLoaderOptions.PostProcessSteps = (AssimpPostProcessSteps)EditorGUILayout.EnumMaskField("Post Processor Options", _tempAssetLoaderOptions.PostProcessSteps);
                break;

            case 1:
            {
                EditorGUILayout.LabelField("Meshes", EditorStyles.boldLabel);
                EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("Scale"));
                EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("RotationAngles"));
                var generateMeshCollidersProperty = _tempSerializedObject.FindProperty("GenerateMeshColliders");
                EditorGUILayout.PropertyField(generateMeshCollidersProperty);
                if (generateMeshCollidersProperty.boolValue)
                {
                    EditorGUI.indentLevel = 1;
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("ConvexMeshColliders"));
                    EditorGUI.indentLevel = 0;
                }
            }
            break;

            case 2:
            {
                EditorGUILayout.LabelField("Materials", EditorStyles.boldLabel);
                var dontLoadMaterialsProperty = _tempSerializedObject.FindProperty("DontLoadMaterials");
                EditorGUILayout.PropertyField(dontLoadMaterialsProperty);
                if (!dontLoadMaterialsProperty.boolValue)
                {
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("TexturesPathOverride"));
                    EditorGUILayout.Space();
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("MaterialsOverride"), new GUIContent("Material Override"), true);
                }
            }
            break;

            case 3:
            {
                EditorGUILayout.LabelField("Animations", EditorStyles.boldLabel);

                var dontLoadAnimationsProperty = _tempSerializedObject.FindProperty("DontLoadAnimations");
                EditorGUILayout.PropertyField(dontLoadAnimationsProperty);
                if (!dontLoadAnimationsProperty.boolValue)
                {
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("AutoPlayAnimations"));
                    EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("AnimationWrapMode"));
                    var legacyAnimationProperty = _tempSerializedObject.FindProperty("UseLegacyAnimations");
                    EditorGUILayout.PropertyField(legacyAnimationProperty);
                    if (!legacyAnimationProperty.boolValue)
                    {
                        EditorGUILayout.PropertyField(_tempSerializedObject.FindProperty("AnimatorController"));
                    }
                }
            }
            break;

            default:
            {
                EditorGUILayout.LabelField("Advanced", EditorStyles.boldLabel);
                var advancedConfigs = _tempSerializedObject.FindProperty("AdvancedConfigs");
                var lastGroup       = string.Empty;
                var groupIndex      = 0;
                foreach (var configKey in AssetAdvancedPropertyMetadata.ConfigKeys)
                {
                    AssetAdvancedConfigType assetAdvancedConfigType;
                    string className;
                    string description;
                    string @group;
                    bool   hasDefaultValue;
                    bool   hasMinValue;
                    bool   hasMaxValue;
                    object defaultValue;
                    object minValue;
                    object maxValue;
                    AssetAdvancedPropertyMetadata.GetOptionMetadata(configKey, out assetAdvancedConfigType, out className, out description, out @group, out defaultValue, out minValue, out maxValue, out hasDefaultValue, out hasMinValue, out hasMaxValue);
                    SerializedProperty elementSerializedProperty = null;
                    var serializedElementIndex = 0;
                    var recentlyCreated        = false;
                    for (var i = 0; i < _tempAssetLoaderOptions.AdvancedConfigs.Count; i++)
                    {
                        var advancedProperty = _tempAssetLoaderOptions.AdvancedConfigs[i];
                        if (advancedProperty.Key == configKey)
                        {
                            serializedElementIndex    = i;
                            elementSerializedProperty = advancedConfigs.GetArrayElementAtIndex(i);
                            break;
                        }
                    }
                    if (@group != lastGroup)
                    {
                        lastGroup = @group;
                        _groupUnfolded[groupIndex] = EditorGUILayout.Foldout(_groupUnfolded[groupIndex], lastGroup);
                        groupIndex++;
                    }
                    if (_groupUnfolded[groupIndex - 1])
                    {
                        EditorGUILayout.BeginHorizontal();
                        var enableProperty = EditorGUILayout.BeginToggleGroup(new GUIContent(className, description), elementSerializedProperty != null);
                        if (elementSerializedProperty == null && enableProperty)
                        {
                            advancedConfigs.InsertArrayElementAtIndex(advancedConfigs.arraySize);
                            _tempSerializedObject.ApplyModifiedProperties();
                            var elementIndex = Mathf.Max(0, advancedConfigs.arraySize - 1);
                            elementSerializedProperty = advancedConfigs.GetArrayElementAtIndex(elementIndex);
                            elementSerializedProperty.FindPropertyRelative("Key").stringValue = configKey;
                            _tempSerializedObject.ApplyModifiedProperties();
                            recentlyCreated = true;
                        }
                        else if (elementSerializedProperty != null && !enableProperty)
                        {
                            advancedConfigs.DeleteArrayElementAtIndex(serializedElementIndex);
                            _tempSerializedObject.ApplyModifiedProperties();
                            return;
                        }
                        SerializedProperty valueSerializedProperty;
                        switch (assetAdvancedConfigType)
                        {
                        case AssetAdvancedConfigType.Bool:
                            var boolDefaultValue = hasDefaultValue && (bool)defaultValue;
                            if (elementSerializedProperty == null)
                            {
                                GUI.enabled = false;
                                EditorGUILayout.Toggle(boolDefaultValue ? "Enabled" : "Disabled", boolDefaultValue);
                            }
                            else
                            {
                                GUI.enabled             = true;
                                valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("BoolValue");
                                if (recentlyCreated)
                                {
                                    valueSerializedProperty.boolValue = boolDefaultValue;
                                }
                                EditorGUILayout.PropertyField(valueSerializedProperty, new GUIContent(valueSerializedProperty.boolValue ? "Enabled" : "Disabled"));
                            }
                            break;

                        case AssetAdvancedConfigType.Integer:
                            var intDefaultValue = hasDefaultValue ? (int)defaultValue : 0;
                            if (hasMinValue && hasMaxValue)
                            {
                                if (elementSerializedProperty == null)
                                {
                                    GUI.enabled = false;
                                    EditorGUILayout.IntSlider(intDefaultValue, (int)minValue, (int)maxValue);
                                }
                                else
                                {
                                    GUI.enabled             = true;
                                    valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("IntValue");
                                    if (recentlyCreated)
                                    {
                                        valueSerializedProperty.intValue = intDefaultValue;
                                    }
                                    EditorGUILayout.IntSlider(valueSerializedProperty, (int)minValue, (int)maxValue, GUIContent.none);
                                }
                            }
                            else
                            {
                                if (elementSerializedProperty == null)
                                {
                                    GUI.enabled = false;
                                    EditorGUILayout.IntField(intDefaultValue);
                                }
                                else
                                {
                                    GUI.enabled             = true;
                                    valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("IntValue");
                                    if (recentlyCreated)
                                    {
                                        valueSerializedProperty.intValue = intDefaultValue;
                                    }
                                    EditorGUILayout.PropertyField(valueSerializedProperty, GUIContent.none);
                                }
                            }
                            break;

                        case AssetAdvancedConfigType.Float:
                            var floatDefaultValue = hasDefaultValue ? (float)defaultValue : 0f;
                            if (hasMinValue && hasMaxValue)
                            {
                                if (elementSerializedProperty == null)
                                {
                                    GUI.enabled = false;
                                    EditorGUILayout.Slider(floatDefaultValue, (float)minValue, (float)maxValue);
                                }
                                else
                                {
                                    GUI.enabled             = true;
                                    valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("FloatValue");
                                    if (recentlyCreated)
                                    {
                                        valueSerializedProperty.floatValue = floatDefaultValue;
                                    }
                                    EditorGUILayout.Slider(valueSerializedProperty, (float)minValue, (float)maxValue, GUIContent.none);
                                }
                            }
                            else
                            {
                                if (elementSerializedProperty == null)
                                {
                                    GUI.enabled = false;
                                    EditorGUILayout.FloatField(floatDefaultValue);
                                }
                                else
                                {
                                    GUI.enabled             = true;
                                    valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("FloatValue");
                                    if (recentlyCreated)
                                    {
                                        valueSerializedProperty.floatValue = floatDefaultValue;
                                    }
                                    EditorGUILayout.PropertyField(valueSerializedProperty, GUIContent.none);
                                }
                            }
                            break;

                        case AssetAdvancedConfigType.String:
                            var stringDefaultValue = hasDefaultValue ? (string)defaultValue : string.Empty;
                            if (elementSerializedProperty == null)
                            {
                                GUI.enabled = false;
                                EditorGUILayout.TextField(stringDefaultValue);
                            }
                            else
                            {
                                GUI.enabled             = true;
                                valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("StringValue");
                                if (recentlyCreated)
                                {
                                    valueSerializedProperty.stringValue = stringDefaultValue;
                                }
                                EditorGUILayout.PropertyField(valueSerializedProperty, GUIContent.none);
                            }
                            break;

                        case AssetAdvancedConfigType.AiComponent:
                            var aiComponentDefaultValue = hasDefaultValue ? (AiComponent)defaultValue : AiComponent.Animations;
                            if (elementSerializedProperty == null)
                            {
                                GUI.enabled = false;
                                EditorGUILayout.EnumMaskField(aiComponentDefaultValue);
                            }
                            else
                            {
                                GUI.enabled             = true;
                                valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("IntValue");
                                if (recentlyCreated)
                                {
                                    valueSerializedProperty.intValue = (int)aiComponentDefaultValue;
                                }
                                PropertyEnumMaskField(valueSerializedProperty, assetAdvancedConfigType, GUIContent.none);
                            }
                            break;

                        case AssetAdvancedConfigType.AiPrimitiveType:
                            var aiPrimitiveTypeDefaultValue = hasDefaultValue ? (AiPrimitiveType)defaultValue : AiPrimitiveType.Line;
                            if (elementSerializedProperty == null)
                            {
                                GUI.enabled = false;
                                EditorGUILayout.EnumMaskField(aiPrimitiveTypeDefaultValue);
                            }
                            else
                            {
                                GUI.enabled             = true;
                                valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("IntValue");
                                if (recentlyCreated)
                                {
                                    valueSerializedProperty.intValue = (int)aiPrimitiveTypeDefaultValue;
                                }
                                PropertyEnumMaskField(valueSerializedProperty, assetAdvancedConfigType, GUIContent.none);
                            }
                            break;

                        case AssetAdvancedConfigType.AiUVTransform:
                            var aiUvTransformDefaultValue = hasDefaultValue ? (AiUVTransform)defaultValue : AiUVTransform.Rotation;
                            if (elementSerializedProperty == null)
                            {
                                GUI.enabled = false;
                                EditorGUILayout.EnumMaskField(aiUvTransformDefaultValue);
                            }
                            else
                            {
                                GUI.enabled             = true;
                                valueSerializedProperty = elementSerializedProperty.FindPropertyRelative("IntValue");
                                if (recentlyCreated)
                                {
                                    valueSerializedProperty.intValue = (int)aiUvTransformDefaultValue;
                                }
                                PropertyEnumMaskField(valueSerializedProperty, assetAdvancedConfigType, GUIContent.none);
                            }
                            break;
                        }
                        GUI.enabled = true;
                        EditorGUILayout.EndToggleGroup();
                        EditorGUILayout.EndHorizontal();
                    }
                }
            }
            break;
            }
            if (EditorGUI.EndChangeCheck())
            {
                _hasChanged = true;
            }
            EditorGUILayout.Space();
            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUI.enabled = _hasChanged;
            if (GUILayout.Button("Revert"))
            {
                DestroyTempObject();
                _tempAssetLoaderOptions = AssetLoaderOptions.CreateInstance();
                SaveChanges();
            }
            if (GUILayout.Button("Apply"))
            {
                _tempSerializedObject.ApplyModifiedProperties();
                SaveChanges();
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndVertical();
        }
Beispiel #4
0
    public static GameObject load(String assetLocation)
    {
        GameObject g = null;

        using (var assetLoader = new AssetLoader())
        {
            try
            {
                var assetLoaderOptions = AssetLoaderOptions.CreateInstance();
                assetLoaderOptions.RotationAngles = Vector3.zero;
                GameObject loadedGameObject = assetLoader.LoadFromFile(@"./" + assetLocation, assetLoaderOptions, null, null);

                g = loadedGameObject;

                // First lets find the size of the model
                SizeBoundingBox.CreateBox(g.transform);
                var box = g.GetComponent <BoxCollider>();
                if (Vector3.Scale(box.size, g.transform.localScale).x > maxSize)
                {
                    g.transform.localScale *= maxSize / Vector3.Scale(box.size, g.transform.localScale).x;
                }
                if (Vector3.Scale(box.size, g.transform.localScale).y > maxSize)
                {
                    g.transform.localScale *= maxSize / Vector3.Scale(box.size, g.transform.localScale).y;
                }
                if (Vector3.Scale(box.size, g.transform.localScale).z > maxSize)
                {
                    g.transform.localScale *= maxSize / Vector3.Scale(box.size, g.transform.localScale).z;
                }
                else
                {
                    if (Vector3.Scale(box.size, g.transform.localScale).x < minSize)
                    {
                        g.transform.localScale *= minSize / Vector3.Scale(box.size, g.transform.localScale).x;
                    }
                    if (Vector3.Scale(box.size, g.transform.localScale).y < minSize)
                    {
                        g.transform.localScale *= minSize / Vector3.Scale(box.size, g.transform.localScale).y;
                    }
                    if (Vector3.Scale(box.size, g.transform.localScale).z < minSize)
                    {
                        g.transform.localScale *= minSize / Vector3.Scale(box.size, g.transform.localScale).z;
                    }
                }
                g.transform.Rotate(90, 0, 0);

                var rs = g.transform.GetComponentsInChildren <Renderer>();
                foreach (Renderer r in rs)
                {
                    if (r?.materials?.Any() == true)
                    {
                        foreach (Material mat in r.materials)
                        {
                            mat.EnableKeyword("_GLOSSYREFLECTIONS_OFF");
                        }
                    }
                }
                box.enabled = false;
                g.SetActive(false);
            }
            catch (Exception e)
            {
                Debug.LogError(e.ToString());
            }
        }
        return(g);
    }
        /// <summary>Loads a Model from the given URI Asynchronously (Accepts zip files).</summary>
        /// <param name="unityWebRequest">The Unity Web Request used to load the Model. You can use the CreateWebRequest method to create a new Unity Web Request or pass your instance.</param>
        /// <param name="onLoad">The Method to call on the Main Thread when the Model is loaded but resources may still pending.</param>
        /// <param name="onMaterialsLoad">The Method to call on the Main Thread when the Model and resources are loaded.</param>
        /// <param name="onProgress">The Method to call when the Model loading progress changes.</param>
        /// <param name="onError">The Method to call on the Main Thread when any error occurs.</param>
        /// <param name="wrapperGameObject">The Game Object that will be the parent of the loaded Game Object. Can be null.</param>
        /// <param name="assetLoaderOptions">The options to use when loading the Model.</param>
        /// <param name="customContextData">The Custom Data that will be passed along the Context.</param>
        /// <param name="fileExtension">The extension of the URI Model or the Model inside the Zip file.</param>
        /// <param name="isZipFile">Pass <c>true</c> if your file is a Zip file.</param>
        /// <returns>The AssetLoaderContext used to load the model.</returns>
        public static Coroutine LoadModelFromUri(UnityWebRequest unityWebRequest, Action <AssetLoaderContext> onLoad, Action <AssetLoaderContext> onMaterialsLoad, Action <AssetLoaderContext, float> onProgress, Action <IContextualizedError> onError = null, GameObject wrapperGameObject = null, AssetLoaderOptions assetLoaderOptions = null, object customContextData = null, string fileExtension = null, bool?isZipFile = null)
        {
            var assetDownloader = new GameObject("Asset Downloader").AddComponent <AssetDownloaderBehaviour>();

            return(assetDownloader.StartCoroutine(assetDownloader.DownloadAsset(unityWebRequest, onLoad, onMaterialsLoad, onProgress, wrapperGameObject, onError, assetLoaderOptions, customContextData, fileExtension, isZipFile)));
        }
Beispiel #6
0
        /// <summary>Loads a Model from the OS file picker asynchronously, or synchronously when the OS doesn't support Threads.</summary>
        /// <param name="title">The dialog title.</param>
        /// <param name="onLoad">The Method to call on the Main Thread when the Model is loaded but resources may still pending.</param>
        /// <param name="onMaterialsLoad">The Method to call on the Main Thread when the Model and resources are loaded.</param>
        /// <param name="onProgress">The Method to call when the Model loading progress changes.</param>
        /// <param name="onBeginLoad">The Method to call when the model begins to load.</param>
        /// <param name="onError">The Method to call on the Main Thread when any error occurs.</param>
        /// <param name="wrapperGameObject">The Game Object that will be the parent of the loaded Game Object. Can be null.</param>
        /// <param name="assetLoaderOptions">The options to use when loading the Model.</param>
        public void LoadModelFromFilePickerAsync(string title, Action <AssetLoaderContext> onLoad, Action <AssetLoaderContext> onMaterialsLoad, Action <AssetLoaderContext, float> onProgress, Action <bool> onBeginLoad, Action <IContextualizedError> onError, GameObject wrapperGameObject, AssetLoaderOptions assetLoaderOptions)
        {
            _onLoad             = onLoad;
            _onMaterialsLoad    = onMaterialsLoad;
            _onProgress         = onProgress;
            _onError            = onError;
            _onBeginLoad        = onBeginLoad;
            _wrapperGameObject  = wrapperGameObject;
            _assetLoaderOptions = assetLoaderOptions;
            try
            {
                StandaloneFileBrowser.OpenFilePanelAsync(title, null, GetExtensions(), true, OnItemsWithStreamSelected);
            }
            catch (Exception)
            {
#if (UNITY_WSA || UNITY_ANDROID) && !UNITY_EDITOR
                Dispatcher.InvokeAsync(new ContextualizedAction(DestroyMe));
#else
                DestroyMe();
#endif
                throw;
            }
        }
    // Modified version of ImportTrainFile for importing nn file
    void ImportClassifyFile(string directory, string fileName, int fileIndex, string modelName, List <string> recordingLabels, string[] jointNames)
    //void ImportFile(string directory, string fileName, int fileIndex, string[] jointNames)
    {
        string filePath           = directory + "/" + fileName;
        var    assetLoader        = new AssetLoader();
        var    assetLoaderOptions = AssetLoaderOptions.CreateInstance();

        assetLoaderOptions.AutoPlayAnimations = true;
        assetLoaderOptions.AnimationWrapMode  = WrapMode.Loop;
        assetLoaderOptions.UseOriginalPositionRotationAndScale = true;

        //Debug.Log("filename: " + fileName);
        string recordingName = fileName.Replace(".fbx", "");

        //Debug.Log("recordingName: " + recordingName);

        _rootGameObject      = assetLoader.LoadFromFileWithTextures(filePath, assetLoaderOptions);
        _rootGameObject.name = recordingName;
        _rootGameObject.transform.localScale = new Vector3(0.005f, 0.005f, 0.005f);
        _rootGameObject.transform.parent     = transform;


        _rootGameObject.AddComponent <JointVisualizer>();

        _rootGameObject.AddComponent <BehaviorParameters>();
        // all the behavior parameters has to be here and not in the Agent Init in order for it to work for some reason. i haven't been able to figure out why that might be, but who cares?
        _rootGameObject.GetComponent <BehaviorParameters>().BehaviorName = "MotionCaptureRNN";
        _rootGameObject.GetComponent <BehaviorParameters>().BrainParameters.VectorObservationSize = jointNames.Length * 4 + 3; // number of joints times 4 quaternion values per joint, plus 3 position values for the hips
        _rootGameObject.GetComponent <BehaviorParameters>().BrainParameters.VectorActionSpaceType = SpaceType.Discrete;

        // Add nn file
        NNModel model = new NNModel();

        model.modelData       = new NNModelData();
        model.modelData.Value = File.ReadAllBytes(Application.streamingAssetsPath + "/results/testName/MotionCaptureRNN.nn");
        _rootGameObject.GetComponent <BehaviorParameters>().Model = model;


        // The commented out line will work when we have a data structure for features working
        List <string> modelLabels      = dataManager.GetLabelsFromModel(modelName);
        int           numLabelsInModel = modelLabels.Count;

        _rootGameObject.GetComponent <BehaviorParameters>().BrainParameters.VectorActionSize = new int[numLabelsInModel];
        //_rootGameObject.GetComponent<BehaviorParameters>().BrainParameters.VectorActionSize = new int[2]; // this will need to be changed to match the features list

        // For now, we're using a vectoractionsize value of 2 for each vector action.
        // Because we're using binary labels that are either true or false.  Ie.It either is labeled "twisting" or it's not.
        for (int i = 0; i < _rootGameObject.GetComponent <BehaviorParameters>().BrainParameters.VectorActionSize.Length; i++)
        {
            _rootGameObject.GetComponent <BehaviorParameters>().BrainParameters.VectorActionSize[i] = 2;
        }

        int[] recordingVectorActionValues = new int[numLabelsInModel];
        for (int i = 0; i < recordingVectorActionValues.Length; i++)
        {
            // We need to make the list of labels for this recording conform to array of all the possible labels for the model
            // where the value at each index corresponds to whether that label is present for this model.
            // For example, if the possible labels are:  Arc, Twist, Bend
            // and this recording has the labels: Arc, Bend
            // then we need an array like {1, 0, 1}
            if (recordingLabels.Contains(modelLabels[i])) // it should be safe to use i here because the size of the recordingVectorActionValues arary should be the same length as the modelFeatures array, because it was set above
            {
                recordingVectorActionValues[i] = 1;
                //_rootGameObject.GetComponent<BehaviorParameters>().BrainParameters.VectorActionSize[i] = 1;
            }
            else
            {
                recordingVectorActionValues[i] = 0;
                // _rootGameObject.GetComponent<BehaviorParameters>().BrainParameters.VectorActionSize[i] = 0;
            }
        }



        //Debug.Log("adding agent component");
        _rootGameObject.AddComponent <MocapTrainerAgent_TimedEpisode_RuntimeVersion>();
        //Debug.Log("calling init on agent component");
        _rootGameObject.GetComponent <MocapTrainerAgent_TimedEpisode_RuntimeVersion>().Init(
            recordingName,
            jointNames,
            behaviorName,
            recordingVectorActionValues
            );
    }