예제 #1
0
    void Update()
    {
        UpdateCoordinates();
        UpdateInterpolation();

        // Project the idle controller onto the headLook controller
        // each frame, since the headLook controller calculates a full
        // offset each frame from the base pose to the gazing pose
        headlookController.Decode(
            this.dummyController.Encode(
                this.NewTransformArray()));
        this.headlookController.ControlledUpdate();

        ShadowTransform[] dummy =
            dummyController.Encode(this.NewTransformArray());
        ShadowTransform[] headLook =
            this.headlookController.Encode(this.NewTransformArray());

        ShadowTransform[] blend = BlendSystem.Blend(
            this.NewTransformArray(),
            new BlendPair(headLook, interp),
            new BlendPair(dummy, 1.0f - interp));

        Shadow.ReadShadowData(blend, transform.GetChild(0), this);
    }
    public static void ChangeBlendSystem(BlendSystemUser component, int blendSystem)
    {
        Undo.RecordObject(component, "Change Blend System");

        // Unregister from existing system if one exists
        if (component.blendSystem != null)
        {
            // Remove existing editor if one exists
            if (blendSystemEditors.ContainsKey(component))
            {
                DestroyImmediate(blendSystemEditors[component]);
                blendSystemEditors.Remove(component);
            }

            component.blendSystem.Unregister(component);
        }

        // Only attempt to create new system if a new system was actually chosen
        if (blendSystem != 0)
        {
            // Attempt to find existing instance of new system
            BlendSystem system = (BlendSystem)component.GetComponent(blendSystems[blendSystem]);

            if (system == null)
            {
                // Blend System doesn't exist - must be created first
                system = (BlendSystem)Undo.AddComponent(component.gameObject, blendSystems[blendSystem]);
            }

            // Register with the new system
            system.Register(component);
        }

        CreateBlendSystemEditor(component);
    }
    void Init()
    {
        Type sysType = target.GetType();

        MemberInfo[] propInfo = sysType.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);

        myTarget         = (BlendSystem)target;
        serializedTarget = new SerializedObject(myTarget);

        List <SerializedProperty> propertiesList = new List <SerializedProperty>();

        for (int a = 0; a < propInfo.Length; a++)
        {
            SerializedProperty property = serializedTarget.FindProperty(propInfo[a].Name);
            if (property != null)
            {
                propertiesList.Add(property);
            }
        }

        properties = propertiesList.ToArray();

        sharedMessage = "The following components are using this BlendSystem:\n\n";
        for (int u = 0; u < myTarget.users.Length; u++)
        {
            sharedMessage += "• " + myTarget.users[u].GetType().Name + "\n";
        }
        sharedMessage += "\nThe BlendSystem and its settings will be shared.";
    }
예제 #4
0
    private ShadowTransform[] BlendController(
        ShadowController controller,
        ShadowTransform[] input,
        Slider weight,
        FilterList <string> filter = null)
    {
        if (weight.IsMin == true)
        {
            return(input);
        }

        // Update the target controller from that blend
        if (filter == null)
        {
            controller.Decode(input);
        }
        else
        {
            controller.Decode(input, filter);
        }
        controller.ControlledUpdate();
        ShadowTransform[] result
            = controller.Encode(this.NewTransformArray());

        return(BlendSystem.Blend(
                   this.NewTransformArray(),
                   new BlendPair(input, weight.Inverse),
                   new BlendPair(result, weight.Value)));
    }
예제 #5
0
    // Update is usually where we do the blending and fading
    void Update()
    {
        this.UpdateCoordinates();
        this.UpdateInterpolation();

        // Project the idle controller onto the reach controller
        // each frame, except for the hierarchy beginning with the
        // LeftArm joint, otherwise the reach control would be
        // overwritten each frame
        this.reachController.Decode(
            this.dummyController.Encode(
                this.NewTransformArray()),
            new Blacklist <string>("LeftArm"));
        this.reachController.ControlledUpdate();

        ShadowTransform[] dummy =
            this.dummyController.Encode(this.NewTransformArray());
        ShadowTransform[] reach =
            this.reachController.Encode(this.NewTransformArray());

        ShadowTransform[] blend =
            BlendSystem.Blend(
                this.NewTransformArray(),
                new BlendPair(reach, interp),
                new BlendPair(dummy, 1.0f - interp));

        Shadow.ReadShadowData(blend, transform.GetChild(0), this);
    }
    private ShadowTransform[] BlendRagdoll(ShadowTransform[] input)
    {
        if (this.dWeight.IsMin == true)
        {
            this.ragdoll.Decode(
                input,
                new Blacklist <string>("LeftUpLeg", "RightUpLeg"));
        }
        this.ragdoll.ControlledUpdate();
        ShadowTransform[] result
            = this.ragdoll.Encode(this.ragdollPose);

        return(BlendSystem.Blend(
                   this.NewTransformArray(),
                   new BlendPair(input, this.dWeight.Inverse),
                   new BlendPair(result, this.dWeight.Value)));
    }
예제 #7
0
    void Init()
    {
        Type sysType = target.GetType();

        MemberInfo[] propInfo = sysType.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);

        myTarget = (BlendSystem)target;

        serializedTarget = new SerializedObject(myTarget);
        properties       = new SerializedProperty[propInfo.Length];

        for (int a = 0; a < properties.Length; a++)
        {
            properties[a] = serializedTarget.FindProperty(propInfo[a].Name);
        }

        users = myTarget.GetComponents <BlendSystemUser>();
    }
예제 #8
0
    void Update()
    {
        this.weight.Tick(Time.deltaTime);

        // Move the root position of each shadow to match the display model
        this.UpdateCoordinates();

        // Update the lean controller and write its shadow into the buffer
        this.lean.ControlledUpdate();
        this.lean.Encode(this.buffer1);

        // Update the anim controller and write its shadow into the buffer
        this.anim.ControlledUpdate();
        this.anim.Encode(this.buffer2, new Whitelist <string>("Spine1"));

        // Optionally, uncomment this to see the weight value
        // Debug.Log(weight);

        // Play an animation when we press T
        if (Input.GetKeyDown(KeyCode.T) == true)
        {
            this.anim.AnimPlay("dismissing_gesture");
            this.weight.ToMin();
        }

        // Fade out the animation controller if we're finished
        if (anim.IsPlaying() == false)
        {
            this.weight.ToMax();
        }

        // Blend the two controllers using the weight value
        BlendSystem.Blend(
            this.buffer1,
            new BlendPair(this.buffer1, this.weight.Value),
            new BlendPair(this.buffer2, this.weight.Inverse));

        // Write the shadow buffer to the display model, starting at the hips
        Shadow.ReadShadowData(
            this.buffer1,
            this.transform.GetChild(0),
            this);
    }
예제 #9
0
    private ShadowTransform[] BlendLegsAndSitting()
    {
        // Update the leg controller
        this.locomotion.ControlledUpdate();
        ShadowTransform[] legs =
            this.locomotion.Encode(this.NewTransformArray());

        // If we don't need to blend the gesture controller, don't bother
        if (sWeight.IsMin == true)
        {
            return(legs);
        }

        this.sitting.ControlledUpdate();
        ShadowTransform[] sitBody =
            this.sitting.Encode(this.NewTransformArray());

        return(BlendSystem.Blend(
                   this.NewTransformArray(),
                   new BlendPair(legs, sWeight.Inverse),
                   new BlendPair(sitBody, sWeight.Value)));
    }
예제 #10
0
 // Update is called once per frame
 void Update()
 {
     this.weight.Tick(Time.deltaTime);
     this.UpdateCoordinates();
     this.lean.ControlledUpdate();
     this.lean.Encode(this.buffer1);
     this.anim.ControlledUpdate();
     this.anim.Encode(this.buffer2, new Whitelist <string>("Spine1"));
     if (Input.GetKeyDown(KeyCode.T) == true)
     {
         this.anim.AnimPlay("dismissing_gesture");
         this.weight.ToMax();
     }
     if (anim.IsPlaying() == false)
     {
         this.weight.ToMin();
     }
     BlendSystem.Blend(this.buffer1,
                       new BlendPair(this.buffer1, this.weight.Value),
                       new BlendPair(this.buffer2, this.weight.Inverse));
     Shadow.ReadShadowData(this.buffer1, this.transform.GetChild(0), this);
 }
 public static void DrawBlendSystemButtons(BlendSystem blendSystem)
 {
     if (blendSystemButtons.ContainsKey(blendSystem))
     {
         if (blendSystemButtons[blendSystem].Length > 0 && blendSystemButtons[blendSystem].Length < 3)
         {
             Rect buttonPanel = EditorGUILayout.BeginHorizontal();
             EditorGUI.HelpBox(new Rect(buttonPanel.x, buttonPanel.y - 4, buttonPanel.width, buttonPanel.height + 8), "BlendSystem Commands:", MessageType.Info);
             GUILayout.FlexibleSpace();
             foreach (BlendSystemButton.Reference button in blendSystemButtons[blendSystem])
             {
                 if (GUILayout.Button(button.displayName, GUILayout.Height(20), GUILayout.MinWidth(120)))
                 {
                     button.method.Invoke(blendSystem, null);
                 }
             }
             GUILayout.FlexibleSpace();
             EditorGUILayout.EndHorizontal();
             EditorGUILayout.Space();
         }
         else if (blendSystemButtons[blendSystem].Length >= 3)
         {
             Rect buttonPanel = EditorGUILayout.BeginHorizontal();
             EditorGUI.HelpBox(new Rect(buttonPanel.x, buttonPanel.y - 4, buttonPanel.width, buttonPanel.height + 8), "BlendSystem Commands:", MessageType.Info);
             GUILayout.FlexibleSpace();
             foreach (BlendSystemButton.Reference button in blendSystemButtons[blendSystem])
             {
                 if (GUILayout.Button(button.displayName, GUILayout.Height(20), GUILayout.MinWidth(120)))
                 {
                     button.method.Invoke(blendSystem, null);
                 }
             }
             GUILayout.Space(5);
             EditorGUILayout.EndHorizontal();
             EditorGUILayout.Space();
         }
     }
 }
    public static void GetBlendSystemButtons(BlendSystem blendSystem)
    {
        if (blendSystemButtons.ContainsKey(blendSystem))
        {
            blendSystemButtons.Remove(blendSystem);
        }

        MethodInfo[] methods = blendSystem.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance);
        BlendSystemButton.Reference[] buttons = new BlendSystemButton.Reference[0];

        int buttonLength = 0;

        for (int m = 0; m < methods.Length; m++)
        {
            BlendSystemButton[] button = (BlendSystemButton[])methods[m].GetCustomAttributes(typeof(BlendSystemButton), false);
            if (button.Length > 0)
            {
                buttonLength++;
            }
        }

        if (buttonLength > 0)
        {
            buttons = new BlendSystemButton.Reference[buttonLength];
            int b = 0;
            for (int m = 0; m < methods.Length; m++)
            {
                BlendSystemButton[] button = (BlendSystemButton[])methods[m].GetCustomAttributes(typeof(BlendSystemButton), false);
                if (button.Length > 0)
                {
                    buttons[b] = new BlendSystemButton.Reference(button[0].displayName, methods[m]);
                    b++;
                }
            }
        }

        blendSystemButtons.Add(blendSystem, buttons);
    }
    public override void OnInspectorGUI()
    {
        BlendSystem bsTarget = (BlendSystem)target;

        if (properties == null)
        {
            Init();
        }

        if (serializedTarget != null && target != null)
        {
            serializedTarget.Update();

            if (bsTarget.users != null)
            {
                if (bsTarget.users.Length > 1)
                {
                    EditorGUILayout.HelpBox(sharedMessage, MessageType.Info);
                }
            }

            EditorGUI.BeginChangeCheck();
            foreach (SerializedProperty property in properties)
            {
                if (property != null)
                {
                    EditorGUILayout.PropertyField(property, true);
                }
            }
            if (EditorGUI.EndChangeCheck())
            {
                myTarget.SendMessage("OnVariableChanged", SendMessageOptions.DontRequireReceiver);
            }
            serializedTarget.ApplyModifiedProperties();
        }
    }
예제 #14
0
        public static bool DrawShapeEditor(this Editor target, BlendSystem blendSystem, string[] blendables, bool useBones, bool allowCreationFromAnimClip, Shape shape, string name, int id, string invalidError = "")
        {
            bool markedForDeletion = false;

            // Add names if missing
            if (shape.blendableNames == null || shape.blendableNames.Count < shape.blendShapes.Count)
            {
                shape.blendableNames = new List <string>();
                for (int i = 0; i < shape.blendShapes.Count; i++)
                {
                    shape.blendableNames.Add(blendables[shape.blendShapes[i]]);
                }
            }

            // Create AnimBool if not defined
            if (!showBoneOptions.ContainsKey(target))
            {
                showBoneOptions.Add(target, new AnimBool(useBones, target.Repaint));
            }
            showBoneOptions[target].target = useBones;

            // Create styles if not defined
            if (lightToolbar == null)
            {
                lightToolbar = new GUIStyle(EditorStyles.toolbarDropDown);
                lightToolbar.normal.background = lightToolbarTexture;

                miniLabelDark = new GUIStyle(EditorStyles.miniLabel);
                miniLabelDark.normal.textColor = Color.black;
            }

            if (currentToggle == id && currentTarget == target.target)
            {
                Undo.RecordObject(target.target, "Change " + name + " Pose");
                Rect box = EditorGUILayout.BeginHorizontal();

                if (shape.verified)
                {
                    GUI.backgroundColor = new Color(1f, 0.77f, 0f);
                }
                else
                {
                    GUI.backgroundColor = new Color(0.4f, 0.4f, 0.4f);
                }

                if (GUI.Button(box, "", lightToolbar))
                {
                    currentSearchBlendable = -1;
                    searchString           = "";
                    currentToggle          = -1;
                }
                GUI.backgroundColor = Color.white;

                GUILayout.Box(name, miniLabelDark, GUILayout.Width(250));
                if (shape.weights.Count == 1)
                {
                    GUILayout.Box("1 " + blendSystem.blendableDisplayName, miniLabelDark);
                }
                else if (shape.weights.Count > 1)
                {
                    GUILayout.Box(shape.weights.Count.ToString() + " " + blendSystem.blendableDisplayNamePlural, miniLabelDark);
                }

                if (shape.bones.Count == 1 && useBones)
                {
                    GUILayout.Box("1 Bone Transform", miniLabelDark);
                }
                else if (shape.bones.Count > 1 && useBones)
                {
                    GUILayout.Box(shape.bones.Count.ToString() + " Bone Transforms", miniLabelDark);
                }
                if (!shape.verified)
                {
                    GUILayout.FlexibleSpace();
                    GUILayout.Box("Missing", miniLabelDark);
                    GUILayout.FlexibleSpace();
                }

                EditorGUILayout.EndHorizontal();

                if (!shape.verified)
                {
                    if (invalidError != "")
                    {
                        EditorGUILayout.HelpBox(invalidError, MessageType.Warning);
                    }
                    else
                    {
                        EditorGUILayout.HelpBox("There is no matching " + shape.GetType().Name + " in the project settings. It will still function correctly, but it is advised you add it to the project settings for compatibility. Alternatively, you can delete it from here.", MessageType.Warning);
                    }
                    if (GUILayout.Button("Delete Pose"))
                    {
                        markedForDeletion = true;
                    }
                }

                box = EditorGUILayout.BeginVertical();
                GUI.Box(new Rect(box.x + 4, box.y, box.width - 7, box.height), "", EditorStyles.helpBox);
                GUILayout.Space(20);
                for (int b = 0; b < shape.weights.Count; b++)
                {
                    Rect newBox = EditorGUILayout.BeginHorizontal();
                    GUI.Box(new Rect(newBox.x + 5, newBox.y, newBox.width - 11, newBox.height), "", EditorStyles.toolbar);
                    GUILayout.Space(5);


                    // Check if blendables have become out-of-sync
                    // (blend system started reporting different blendables)
                    if (blendables[shape.blendShapes[b]] != shape.blendableNames[b] && blendSystem.allowResyncing)
                    {
                        bool matched = false;
                        for (int i = 0; i < blendables.Length; i++)
                        {
                            if (blendables[i] == shape.blendableNames[b])
                            {
                                shape.blendShapes[b] = i;
                                matched = true;
                            }
                            else if (blendables[i].Remove(blendables[i].Length - 5).Contains(shape.blendableNames[b].Remove(shape.blendableNames[b].Length - 5)))
                            {
                                shape.blendShapes[b]    = i;
                                shape.blendableNames[b] = blendables[i];
                                matched = true;
                            }
                        }
                        if (!matched)
                        {
                            shape.blendableNames[b] = blendables[shape.blendShapes[b]];
                        }
                    }

                    int oldShape = shape.blendShapes[b];

                    if (currentSearchBlendable == b)
                    {
                        EditorGUI.BeginChangeCheck();
                        searchString = EditorGUILayout.TextField(bestSearchMatch == -1 ? "No Match" : blendables[bestSearchMatch], searchString, EditorStyles.toolbarTextField, GUILayout.ExpandWidth(true));
                        if (EditorGUI.EndChangeCheck())
                        {
                            bestSearchMatch = -1;
                            if (searchString != "")
                            {
                                for (int i = 0; i < blendables.Length; i++)
                                {
                                    if (Match(searchString.ToLowerInvariant(), blendables[i].ToLowerInvariant()))
                                    {
                                        bestSearchMatch = i;
                                    }
                                }
                            }
                        }
                        EditorGUI.BeginDisabledGroup(bestSearchMatch == -1);
                        if (GUILayout.Button("Set", EditorStyles.toolbarButton, GUILayout.MaxWidth(45)))
                        {
                            blendSystem.OnBlendableRemovedFromPose(shape.blendShapes[b]);
                            shape.blendShapes[b] = bestSearchMatch;
                            blendSystem.OnBlendableAddedToPose(bestSearchMatch);
                            currentSearchBlendable = -1;
                            bestSearchMatch        = -1;
                            searchString           = "";
                        }
                        EditorGUI.EndDisabledGroup();
                    }
                    else
                    {
                        int oldBlendable = shape.blendShapes[b];
                        shape.blendShapes[b] = EditorGUILayout.Popup(blendSystem.blendableDisplayName + " " + b.ToString(), shape.blendShapes[b], blendables, EditorStyles.toolbarPopup);
                        if (oldBlendable != shape.blendShapes[b])
                        {
                            blendSystem.OnBlendableRemovedFromPose(oldBlendable);
                            blendSystem.OnBlendableAddedToPose(shape.blendShapes[b]);
                        }
                    }

                    if (shape.blendShapes[b] != oldShape)
                    {
                        shape.blendableNames[b] = blendables[b];
                        blendSystem.SetBlendableValue(oldShape, 0);
                    }

                    if (GUILayout.Button(search, EditorStyles.toolbarButton, GUILayout.MaxWidth(30)))
                    {
                        currentSearchBlendable = currentSearchBlendable == b ? -1 : b;
                    }

                    GUI.backgroundColor = new Color(0.8f, 0.3f, 0.3f);
                    if (GUILayout.Button(delete, EditorStyles.toolbarButton, GUILayout.MaxWidth(50)))
                    {
                        Undo.RecordObject(target.target, "Delete " + blendSystem.blendableDisplayName);

                        shape.blendShapes.RemoveAt(b);
                        blendSystem.SetBlendableValue(oldShape, 0);
                        blendSystem.OnBlendableRemovedFromPose(oldShape);
                        selectedBone = 0;
                        shape.weights.RemoveAt(b);
                        shape.blendableNames.RemoveAt(b);
                        EditorUtility.SetDirty(target.target);
                        break;
                    }

                    GUILayout.Space(4);
                    GUI.backgroundColor = Color.white;
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    GUILayout.Space(15);
                    shape.weights[b] = EditorGUILayout.Slider(shape.weights[b], blendSystem.blendRangeLow, blendSystem.blendRangeHigh);
                    GUILayout.Space(10);
                    EditorGUILayout.EndHorizontal();
                    GUILayout.Space(10);
                }

                if (EditorGUILayout.BeginFadeGroup(showBoneOptions[target].faded))
                {
                    for (int b = 0; b < shape.bones.Count; b++)
                    {
                        Rect newBox = EditorGUILayout.BeginHorizontal();
                        GUI.Box(new Rect(newBox.x + 5, newBox.y, newBox.width - 11, newBox.height), "", EditorStyles.toolbar);
                        GUILayout.Space(10);
                        bool selected = EditorGUILayout.ToggleLeft(new GUIContent("Bone Transform " + b.ToString(), EditorGUIUtility.FindTexture("Transform Icon"), "Show Transform Handles"), selectedBone == b, GUILayout.Width(170));
                        selectedBone = selected ? b : selectedBone;

                        Transform oldBone = shape.bones[b].bone;
                        shape.bones[b].bone = (Transform)EditorGUILayout.ObjectField("", shape.bones[b].bone, typeof(Transform), true);

                        if (oldBone != shape.bones[b].bone)
                        {
                            if (shape.bones[b].bone != null)
                            {
                                Transform newbone = shape.bones[b].bone;
                                shape.bones[b].bone = oldBone;
                                if (shape.bones[b].bone != null)
                                {
                                    shape.bones[b].bone.localPosition    = shape.bones[b].neutralPosition;
                                    shape.bones[b].bone.localScale       = shape.bones[b].neutralScale;
                                    shape.bones[b].bone.localEulerAngles = shape.bones[b].neutralRotation;
                                }

                                shape.bones[b].bone = newbone;

                                shape.bones[b].SetNeutral();

                                shape.bones[b].endRotation = shape.bones[b].bone.localEulerAngles;
                                shape.bones[b].endPosition = shape.bones[b].bone.localPosition;
                                shape.bones[b].endScale    = shape.bones[b].bone.localScale;

                                shape.bones[b].bone.localPosition    = shape.bones[b].endPosition;
                                shape.bones[b].bone.localEulerAngles = shape.bones[b].endRotation;
                                shape.bones[b].bone.localScale       = shape.bones[b].endScale;
                            }
                        }

                        GUI.backgroundColor = new Color(0.8f, 0.3f, 0.3f);
                        if (GUILayout.Button(delete, EditorStyles.toolbarButton, GUILayout.MaxWidth(50)))
                        {
                            Undo.RecordObject(target.target, "Delete Bone Transform");
                            if (shape.bones[b].bone != null)
                            {
                                shape.bones[b].bone.localPosition    = shape.bones[b].neutralPosition;
                                shape.bones[b].bone.localEulerAngles = shape.bones[b].neutralRotation;
                                shape.bones[b].bone.localScale       = shape.bones[b].neutralScale;
                            }
                            shape.bones.RemoveAt(b);
                            if (selectedBone >= shape.bones.Count)
                            {
                                selectedBone -= 1;
                            }
                            EditorUtility.SetDirty(target.target);
                            break;
                        }
                        GUILayout.Space(4);
                        GUI.backgroundColor = Color.white;
                        EditorGUILayout.EndHorizontal();
                        GUILayout.Space(5);
                        EditorGUILayout.BeginHorizontal();
                        GUILayout.Space(10);
                        GUILayout.Box("Position", EditorStyles.label, GUILayout.MaxWidth(80));

                        EditorGUI.BeginDisabledGroup(shape.bones[b].bone == null);
                        EditorGUI.BeginDisabledGroup(shape.bones[b].lockPosition);
                        Vector3 newBonePosition = EditorGUILayout.Vector3Field("", shape.bones[b].endPosition);
                        EditorGUI.EndDisabledGroup();
                        GUILayout.Space(10);
                        if (GUILayout.Button(shape.bones[b].lockPosition ? locked : unlocked, GUILayout.Width(30), GUILayout.Height(16)))
                        {
                            shape.bones[b].lockPosition = !shape.bones[b].lockPosition;
                        }
                        EditorGUI.EndDisabledGroup();

                        if (shape.bones[b].bone != null)
                        {
                            if (newBonePosition != shape.bones[b].endPosition)
                            {
                                Undo.RecordObject(shape.bones[b].bone, "Move");
                                shape.bones[b].endPosition        = newBonePosition;
                                shape.bones[b].bone.localPosition = shape.bones[b].endPosition;
                            }
                            else if (shape.bones[b].bone.localPosition != shape.bones[b].endPosition)
                            {
                                shape.bones[b].endPosition = shape.bones[b].bone.localPosition;
                            }
                        }

                        GUILayout.Space(10);
                        EditorGUILayout.EndHorizontal();
                        EditorGUILayout.BeginHorizontal();
                        GUILayout.Space(10);
                        GUILayout.Box("Rotation", EditorStyles.label, GUILayout.MaxWidth(80));

                        EditorGUI.BeginDisabledGroup(shape.bones[b].bone == null);
                        EditorGUI.BeginDisabledGroup(shape.bones[b].lockRotation);
                        Vector3 newBoneRotation = EditorGUILayout.Vector3Field("", shape.bones[b].endRotation);
                        EditorGUI.EndDisabledGroup();
                        GUILayout.Space(10);
                        if (GUILayout.Button(shape.bones[b].lockRotation ? locked : unlocked, GUILayout.Width(30), GUILayout.Height(16)))
                        {
                            shape.bones[b].lockRotation = !shape.bones[b].lockRotation;
                        }
                        EditorGUI.EndDisabledGroup();
                        if (shape.bones[b].bone != null)
                        {
                            if (newBoneRotation != shape.bones[b].endRotation)
                            {
                                Undo.RecordObject(shape.bones[b].bone, "Rotate");
                                shape.bones[b].endRotation           = newBoneRotation;
                                shape.bones[b].bone.localEulerAngles = shape.bones[b].endRotation;
                            }
                            else if (shape.bones[b].bone.localEulerAngles != shape.bones[b].endRotation)
                            {
                                shape.bones[b].endRotation = shape.bones[b].bone.localEulerAngles;
                            }
                        }

                        GUILayout.Space(10);
                        EditorGUILayout.EndHorizontal();
                        EditorGUILayout.BeginHorizontal();
                        GUILayout.Space(10);
                        GUILayout.Box("Scale", EditorStyles.label, GUILayout.MaxWidth(80));

                        EditorGUI.BeginDisabledGroup(shape.bones[b].bone == null);
                        Vector3 newBoneScale = EditorGUILayout.Vector3Field("", shape.bones[b].endScale);
                        EditorGUI.EndDisabledGroup();
                        GUILayout.Space(10);
                        GUILayout.Button(unlocked, GUILayout.Width(30), GUILayout.Height(16));

                        if (shape.bones[b].bone != null)
                        {
                            if (newBonePosition != shape.bones[b].endScale)
                            {
                                Undo.RecordObject(shape.bones[b].bone, "Scale");
                                shape.bones[b].endScale        = newBoneScale;
                                shape.bones[b].bone.localScale = shape.bones[b].endScale;
                            }
                            else if (shape.bones[b].bone.localScale != shape.bones[b].endScale)
                            {
                                shape.bones[b].endScale = shape.bones[b].bone.localScale;
                            }
                        }

                        GUILayout.Space(10);
                        EditorGUILayout.EndHorizontal();
                        GUILayout.Space(10);
                    }
                }
                FixedEndFadeGroup(showBoneOptions[target].faded);

                EditorGUILayout.Space();

                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                if (blendSystem.blendableCount > 0)
                {
                    if (GUILayout.Button("Add " + blendSystem.blendableDisplayName, GUILayout.MaxWidth(200)))
                    {
                        Undo.RecordObject(target.target, "Add " + blendSystem.blendableDisplayName);
                        shape.blendShapes.Add(0);
                        shape.weights.Add(0);
                        shape.blendableNames.Add(blendables[0]);
                        blendSystem.OnBlendableAddedToPose(0);
                        EditorUtility.SetDirty(target.target);
                    }
                    if (useBones)
                    {
                        EditorGUILayout.Space();
                    }
                }

                if (useBones)
                {
                    if (GUILayout.Button("Add Bone Transform", GUILayout.MaxWidth(240)))
                    {
                        Undo.RecordObject(target.target, "Add Bone Shape");
                        shape.bones.Add(new BoneShape());
                        selectedBone = shape.bones.Count - 1;
                        EditorUtility.SetDirty(target.target);
                    }
                    GUILayout.FlexibleSpace();
                    GUILayout.EndHorizontal();
                    if (allowCreationFromAnimClip)
                    {
                        GUILayout.Space(5);
                        GUILayout.BeginHorizontal();
                        GUILayout.FlexibleSpace();
                        if (GUILayout.Button("Create Pose from AnimationClip", GUILayout.MaxWidth(240)))
                        {
                            PoseExtractorWizard.ShowWindow(blendSystem.transform, shape, name);
                        }
                        GUILayout.FlexibleSpace();
                        GUILayout.EndHorizontal();
                    }
                }
                else
                {
                    GUILayout.FlexibleSpace();
                    GUILayout.EndHorizontal();
                }

                if (blendSystem.blendableCount == 0 && !useBones)
                {
                    GUILayout.BeginHorizontal();
                    GUILayout.Space(10);
                    EditorGUILayout.HelpBox(blendSystem.noBlendablesMessage, MessageType.Warning);
                    GUILayout.Space(10);
                    GUILayout.EndHorizontal();
                }
                GUILayout.Space(14);
                EditorGUILayout.EndVertical();
            }
            else
            {
                Rect box = EditorGUILayout.BeginHorizontal();
                if (shape.verified)
                {
                    GUI.backgroundColor = Color.white;
                }
                else
                {
                    GUI.backgroundColor = new Color(0.7f, 0.7f, 0.7f);
                }

                if (GUI.Button(box, "", EditorStyles.toolbarDropDown))
                {
                    currentToggle = id;
                    currentTarget = target.target;
                    selectedBone  = 0;

                    searchString           = "";
                    currentSearchBlendable = -1;
                }

                GUILayout.Box(name, EditorStyles.miniLabel, GUILayout.Width(250));
                if (shape.weights.Count == 1)
                {
                    GUILayout.Box("1 " + blendSystem.blendableDisplayName, EditorStyles.miniLabel);
                }
                else if (shape.weights.Count > 1)
                {
                    GUILayout.Box(shape.weights.Count.ToString() + " " + blendSystem.blendableDisplayNamePlural, EditorStyles.miniLabel);
                }
                if (shape.bones.Count == 1 && useBones)
                {
                    GUILayout.Box("1 Bone Transform", EditorStyles.miniLabel);
                }
                else if (shape.bones.Count > 1 && useBones)
                {
                    GUILayout.Box(shape.bones.Count.ToString() + " Bone Transforms", EditorStyles.miniLabel);
                }

                if (!shape.verified)
                {
                    GUILayout.FlexibleSpace();
                    GUILayout.Box("Missing", EditorStyles.miniLabel);
                    GUILayout.FlexibleSpace();
                }

                EditorGUILayout.EndHorizontal();
            }

            return(markedForDeletion);
        }