示例#1
0
        private void DoTargetGUI(Solver2D solver, IKChain2D chain)
        {
            int controlId = GUIUtility.GetControlID(kTargetHashCode, FocusType.Passive);

            var color = FadeFromChain(Color.white, chain);

            if (!isDragging && (color.a == 0f || !IsVisible(chain.target.position)))
            {
                return;
            }

            EditorGUI.BeginChangeCheck();

            Handles.color = color;
            var newPosition = Handles.Slider2D(controlId, chain.target.position, chain.target.forward, chain.target.up, chain.target.right, HandleUtility.GetHandleSize(chain.effector.position) * kCircleHandleRadius, Handles.CircleHandleCap, Vector2.zero);

            if (EditorGUI.EndChangeCheck())
            {
                if (!isDragging)
                {
                    isDragging = true;
                    IKEditorManager.instance.RegisterUndo(solver, "Move Target");
                }

                Undo.RecordObject(chain.target, "Move Target");

                chain.target.position = newPosition;
            }
        }
示例#2
0
 private void SetSolverDirty(Solver2D solver)
 {
     if (solver && solver.isValid && solver.isActiveAndEnabled)
     {
         SetManagerDirty(FindManager(solver));
     }
 }
示例#3
0
        public IKManager2D FindManager(Solver2D solver)
        {
            foreach (IKManager2D manager in m_IKManagers)
            {
                if (manager == null)
                {
                    continue;
                }

                foreach (Solver2D s in manager.solvers)
                {
                    if (s == null)
                    {
                        continue;
                    }

                    if (s == solver)
                    {
                        return(manager);
                    }
                }
            }

            return(null);
        }
示例#4
0
        private void StoreSolverPositionOverrides(Solver2D solver)
        {
            Debug.Assert(solver.allChainsHaveTargets == false);

            m_ChainPositionOverrides.Clear();

            IKManager2D manager = IKEditorManager.instance.FindManager(solver);

            foreach (Solver2D l_solver in manager.solvers)
            {
                if (l_solver == null || l_solver.allChainsHaveTargets)
                {
                    continue;
                }

                for (int i = 0; i < l_solver.chainCount; ++i)
                {
                    var chain = l_solver.GetChain(i);
                    if (chain.effector != null)
                    {
                        m_ChainPositionOverrides[chain] = chain.effector.position;
                    }
                }
            }
        }
示例#5
0
        private void DoIkPoseGUI(Solver2D solver, IKChain2D chain)
        {
            int controlId = GUIUtility.GetControlID(kTargetHashCode, FocusType.Passive);

            var color = FadeFromChain(Color.white, chain);

            if (!isDragging && (color.a == 0f || !IsVisible(chain.effector.position)))
            {
                return;
            }

            if (HandleUtility.nearestControl == controlId && Event.current.type == EventType.MouseDown && Event.current.button == 0)
            {
                StoreSolverPositionOverrides(solver);
            }

            EditorGUI.BeginChangeCheck();

            Handles.color = color;
            Vector3 newPosition = Handles.Slider2D(controlId, chain.effector.position, chain.effector.forward, chain.effector.up, chain.effector.right, HandleUtility.GetHandleSize(chain.effector.position) * kCircleHandleRadius, Handles.CircleHandleCap, Vector2.zero);

            if (EditorGUI.EndChangeCheck())
            {
                if (!isDragging)
                {
                    isDragging = true;
                }

                IKEditorManager.instance.Record(solver, "IK Pose");

                SetSolverPositionOverrides();
                IKEditorManager.instance.SetChainPositionOverride(chain, newPosition);
                IKEditorManager.instance.UpdateSolverImmediate(solver, true);
            }
        }
示例#6
0
        public void DoSolverGUI(Solver2D solver)
        {
            if (solver == null || !solver.isValid)
            {
                return;
            }

            IKManager2D manager = IKEditorManager.instance.FindManager(solver);

            if (!solver.isActiveAndEnabled || manager == null || !manager.isActiveAndEnabled)
            {
                return;
            }

            var solverData = manager.GetSolverEditorData(solver);

            if (!solverData.showGizmo)
            {
                return;
            }
            DrawSolver(solver, solverData);

            var allChainsHaveTargets = solver.allChainsHaveTargets;

            for (int i = 0; i < solver.chainCount; ++i)
            {
                var chain = solver.GetChain(i);
                if (chain == null)
                {
                    continue;
                }

                if (allChainsHaveTargets)
                {
                    if (!IsTargetTransformSelected(chain))
                    {
                        DoTargetGUI(solver, chain);
                    }
                }
                else if (chain.target == null)
                {
                    DoIkPoseGUI(solver, chain);
                }
            }

            if (GUIUtility.hotControl == 0)
            {
                isDragging = false;
            }
        }
        public void Setup()
        {
            editorManager = IKEditorManager.instance;

            go = new GameObject();
            var child1GO = new GameObject();

            child1GO.transform.parent = go.transform;

            var child2GO = new GameObject();

            child2GO.transform.parent = child1GO.transform;

            var child3GO = new GameObject();

            child3GO.transform.parent = child2GO.transform;

            targetGO = new GameObject();
            targetGO.transform.parent = child3GO.transform;

            go.transform.position       = Vector3.zero;
            child1GO.transform.position = new Vector3(1.0f, 0.0f, 0.0f);
            child2GO.transform.position = new Vector3(3.0f, 0.0f, 0.0f);
            child3GO.transform.position = new Vector3(6.0f, 0.0f, 0.0f);
            targetGO.transform.position = new Vector3(10.0f, 0.0f, 0.0f);

            ikGO    = new GameObject();
            manager = ikGO.AddComponent <IKManager2D>();
            var lsGO = new GameObject();

            solver = lsGO.AddComponent <FabrikSolver2D>();
            lsGO.transform.parent = ikGO.transform;

            effectorGO = new GameObject();
            effectorGO.transform.parent   = solver.transform;
            effectorGO.transform.position = new Vector3(10.0f, 0.0f, 0.0f);

            chain                = solver.GetChain(0);
            chain.target         = targetGO.transform;
            chain.effector       = effectorGO.transform;
            chain.transformCount = 5;

            solver.Initialize();

            manager.AddSolver(solver);

            editorManager.Initialize();
        }
示例#8
0
        private void DrawSolver(Solver2D solver, IKManager2D.SolverEditorData editorData)
        {
            if (Event.current.type != EventType.Repaint)
            {
                return;
            }

            for (int i = 0; i < solver.chainCount; ++i)
            {
                var chain = solver.GetChain(i);
                if (chain != null)
                {
                    DrawChain(chain, editorData.color, solver.allChainsHaveTargets);
                }
            }
        }
        public void Setup()
        {
            go = new GameObject();
            var child1GO = new GameObject();

            child1GO.transform.parent = go.transform;

            var child2GO = new GameObject();

            child2GO.transform.parent = child1GO.transform;

            var child3GO = new GameObject();

            child3GO.transform.parent = child2GO.transform;

            targetGO = new GameObject();
            targetGO.transform.parent = child3GO.transform;

            go.transform.position       = Vector3.zero;
            child1GO.transform.position = new Vector3(1.0f, 0.0f, 0.0f);
            child2GO.transform.position = new Vector3(3.0f, 0.0f, 0.0f);
            child3GO.transform.position = new Vector3(6.0f, 0.0f, 0.0f);
            targetGO.transform.position = new Vector3(10.0f, 0.0f, 0.0f);

            ikGO    = new GameObject();
            manager = ikGO.AddComponent <IKManager2D>();
            var lsGO = new GameObject();

            // Using FABRIKSolver2D here, but tests are generalised for all Solver2Ds
            solver = lsGO.AddComponent <FabrikSolver2D>();
            lsGO.transform.parent = ikGO.transform;

            effectorGO = new GameObject();
            effectorGO.transform.parent = solver.transform;

            var chain = solver.GetChain(0);

            chain.target         = targetGO.transform;
            chain.effector       = effectorGO.transform;
            chain.transformCount = 5;
            chain.Initialize();

            manager.AddSolver(solver);
        }
示例#10
0
        private void DrawSolver(Solver2D solver)
        {
            if (Event.current.type != EventType.Repaint)
            {
                return;
            }

            IKManager2D manager           = IKEditorManager.instance.FindManager(solver);
            bool        isManagerDisabled = !solver.isActiveAndEnabled || manager == null || !manager.isActiveAndEnabled;

            for (int i = 0; i < solver.chainCount; ++i)
            {
                var chain = solver.GetChain(i);
                if (chain != null)
                {
                    DrawChain(chain, isManagerDisabled, solver.allChainsHaveTargets);
                }
            }
        }
示例#11
0
        private bool PrepareEffectorOverrides(Solver2D solver)
        {
            m_EffectorPositions.Clear();

            for (int i = 0; i < solver.chainCount; ++i)
            {
                var chain = solver.GetChain(i);

                Vector3 positionOverride;
                if (!m_ChainPositionOverrides.TryGetValue(chain, out positionOverride))
                {
                    m_EffectorPositions.Clear();
                    return(false);
                }

                m_EffectorPositions.Add(positionOverride);
            }

            return(true);
        }
示例#12
0
        private void OnSelectMenu(object param)
        {
            Type solverType = param as Type;

            GameObject solverGO = new GameObject(GameObjectUtility.GetUniqueNameForSibling(m_Manager.transform, "New " + solverType.Name));

            solverGO.transform.SetParent(m_Manager.transform);
            solverGO.transform.localPosition = Vector3.zero;
            solverGO.transform.rotation      = Quaternion.identity;
            solverGO.transform.localScale    = Vector3.one;

            Solver2D solver = solverGO.AddComponent(solverType) as Solver2D;

            Undo.RegisterCreatedObjectUndo(solverGO, Contents.createSolverString);
            Undo.RegisterCompleteObjectUndo(m_Manager, Contents.createSolverString);
            m_Manager.AddSolver(solver);
            EditorUtility.SetDirty(m_Manager);

            Selection.activeGameObject = solverGO;
        }
示例#13
0
        public void DoSolverGUI(Solver2D solver)
        {
            if (solver == null || !solver.isValid)
            {
                return;
            }

            DrawSolver(solver);

            var allChainsHaveTargets = solver.allChainsHaveTargets;

            for (int i = 0; i < solver.chainCount; ++i)
            {
                var chain = solver.GetChain(i);
                if (chain == null)
                {
                    continue;
                }

                if (allChainsHaveTargets)
                {
                    if (!IsTargetTransformSelected(chain))
                    {
                        DoTargetGUI(solver, chain);
                    }
                }
                else if (chain.target == null)
                {
                    DoIkPoseGUI(solver, chain);
                }
            }

            if (GUIUtility.hotControl == 0)
            {
                isDragging = false;
            }
        }
        public void SetupReordeableList()
        {
            m_ReorderableList = new ReorderableList(serializedObject, m_SolversProperty, true, true, true, true);
            m_ReorderableList.drawHeaderCallback = (Rect rect) =>
            {
                GUI.Label(rect, Contents.listHeaderLabel);
            };
            m_ReorderableList.elementHeightCallback = (int index) =>
            {
                return(EditorGUIUtility.singleLineHeight + 6);
            };
            m_ReorderableList.drawElementCallback = (Rect rect, int index, bool isactive, bool isfocused) =>
            {
                rect.y     += 2f;
                rect.height = EditorGUIUtility.singleLineHeight;
                SerializedProperty element = m_SolversProperty.GetArrayElementAtIndex(index);
                EditorGUI.PropertyField(rect, element, GUIContent.none);
            };
            m_ReorderableList.onAddCallback = (ReorderableList list) =>
            {
                var menu = new GenericMenu();

                foreach (Type type in m_SolverTypes)
                {
                    Solver2DMenuAttribute attribute = Attribute.GetCustomAttribute(type, typeof(Solver2DMenuAttribute)) as Solver2DMenuAttribute;

                    if (attribute != null)
                    {
                        menu.AddItem(new GUIContent(attribute.menuPath), false, OnSelectMenu, type);
                    }
                    else
                    {
                        menu.AddItem(new GUIContent(type.Name), false, OnSelectMenu, type);
                    }
                }

                menu.ShowAsContext();
            };
            m_ReorderableList.onRemoveCallback = (ReorderableList list) =>
            {
                Solver2D solver = m_Manager.solvers[list.index];
                if (solver)
                {
                    Undo.RegisterCompleteObjectUndo(m_Manager, Undo.GetCurrentGroupName());

                    m_Manager.RemoveSolver(solver);

                    GameObject solverGO = solver.gameObject;

                    if (solverGO.transform.childCount == 0)
                    {
                        Undo.DestroyObjectImmediate(solverGO);
                    }
                    else
                    {
                        Undo.DestroyObjectImmediate(solver);
                    }

                    EditorUtility.SetDirty(m_Manager);
                }
                else
                {
                    ReorderableList.defaultBehaviours.DoRemoveButton(list);
                }
            };
        }
示例#15
0
 public void UpdateSolverImmediate(Solver2D solver, bool recordRootLoops)
 {
     SetSolverDirty(solver);
     UpdateDirtyManagers(recordRootLoops);
 }
示例#16
0
        public void RegisterUndo(Solver2D solver, string undoName)
        {
            var manager = FindManager(solver);

            DoUndo(manager, undoName, false);
        }
示例#17
0
        public void Record(Solver2D solver, string undoName)
        {
            var manager = FindManager(solver);

            DoUndo(manager, undoName, true);
        }
示例#18
0
        void SetupReordeableList()
        {
            m_ReorderableList = new ReorderableList(serializedObject, m_SolversProperty, true, true, true, true);
            m_ReorderableList.drawHeaderCallback = (Rect rect) =>
            {
                GUI.Label(rect, Contents.listHeaderLabel);
            };
            m_ReorderableList.elementHeightCallback = (int index) =>
            {
                return(EditorGUIUtility.singleLineHeight + 6);
            };
            m_ReorderableList.drawElementCallback = (Rect rect, int index, bool isactive, bool isfocused) =>
            {
                rect.y     += 2f;
                rect.height = EditorGUIUtility.singleLineHeight;
                SerializedProperty element     = m_SolversProperty.GetArrayElementAtIndex(index);
                SerializedProperty elementData = m_SolverEditorDataProperty.GetArrayElementAtIndex(index);
                var width = rect.width;
                rect.width = width > Contents.showGizmoPropertyWidth ? Contents.showGizmoPropertyWidth : width;
                var showGizmoProperty = elementData.FindPropertyRelative("showGizmo");
                showGizmoProperty.boolValue = GUI.Toggle(rect, showGizmoProperty.boolValue, Contents.gizmoVisibilityToolTip, k_Contents.visibilityToggleStyle);
                rect.x    += rect.width;
                width     -= rect.width;
                rect.width = width > Contents.solverPropertyWidth ? width - Contents.solverColorPropertyWidth  : Contents.solverPropertyWidth;
                EditorGUI.PropertyField(rect, element, GUIContent.none);
                rect.x    += rect.width;
                width     -= 100;
                rect.width = width > Contents.solverColorPropertyWidth ? Contents.solverColorPropertyWidth : width;
                EditorGUI.PropertyField(rect, elementData.FindPropertyRelative("color"), Contents.gizmoColorTooltip);
            };
            m_ReorderableList.onAddCallback = (ReorderableList list) =>
            {
                var menu = new GenericMenu();

                foreach (Type type in m_SolverTypes)
                {
                    Solver2DMenuAttribute attribute = Attribute.GetCustomAttribute(type, typeof(Solver2DMenuAttribute)) as Solver2DMenuAttribute;

                    if (attribute != null)
                    {
                        menu.AddItem(new GUIContent(attribute.menuPath), false, OnSelectMenu, type);
                    }
                    else
                    {
                        menu.AddItem(new GUIContent(type.Name), false, OnSelectMenu, type);
                    }
                }

                menu.ShowAsContext();
            };
            m_ReorderableList.onRemoveCallback = (ReorderableList list) =>
            {
                Solver2D solver = m_Manager.solvers[list.index];
                if (solver)
                {
                    Undo.RegisterCompleteObjectUndo(m_Manager, Undo.GetCurrentGroupName());

                    m_Manager.RemoveSolver(solver);

                    GameObject solverGO = solver.gameObject;

                    if (solverGO.transform.childCount == 0)
                    {
                        Undo.DestroyObjectImmediate(solverGO);
                    }
                    else
                    {
                        Undo.DestroyObjectImmediate(solver);
                    }

                    EditorUtility.SetDirty(m_Manager);
                }
                else
                {
                    ReorderableList.defaultBehaviours.DoRemoveButton(list);
                }
            };
        }
示例#19
0
 public static Transform Target(this Solver2D solver, int chainIndex = 0)
 {
     return(solver.GetChain(chainIndex).target);
 }