示例#1
0
        public void FillTempBone(int generalBoneID, int lastActiveID)
        {
            int           id            = tempPreviewBones.Count;
            CharacterBone characterBone = characterBones[generalBoneID];

            if (characterBone.selected)
            {
                PreviewBone parentBone = null;
                if (lastActiveID != -1)
                {
                    parentBone = tempPreviewBones[lastActiveID];
                    if (parentBone.childIDs == null)
                    {
                        parentBone.childIDs = new List <int>();
                    }
                    parentBone.childIDs.Add(id);
                }
                tempPreviewBones.Add(new PreviewBone(characterBone.tr, generalBoneID, lastActiveID));
                lastActiveID = id;
            }

            if (characterBone.childIDs != null)
            {
                for (int i = 0; i < characterBone.childIDs.Count; i++)
                {
                    int childId = characterBone.childIDs[i];
                    FillTempBone(childId, lastActiveID);
                }
            }
        }
示例#2
0
        public void CalculateRotationAndBoundsSingleChild(PreviewBone bone, int id)
        {
            Vector3 childPos = tempPreviewBones[bone.childIDs[id]].tr.position;

            bone.direction = childPos - bone.tr.position;

            bone.rotation = Quaternion.Inverse(transform.rotation) * Quaternion.LookRotation(bone.direction, transform.forward);

            bone.bounds.center = new Vector3(bone.bounds.center.x, bone.bounds.center.y, bone.direction.magnitude / 2);
            bone.bounds.size   = new Vector3(bone.bounds.size.x, bone.bounds.size.y, bone.direction.magnitude);
            bone.capsuleBounds.SetSize(bone.bounds.size);
        }
示例#3
0
        private void ColliderSettings()
        {
            tgt.showColliderSettings = EditorGUILayout.Foldout(tgt.showColliderSettings, "Collider");
            tgt.showJointSettings    = !tgt.showColliderSettings;
            if (!tgt.showColliderSettings)
            {
                return;
            }

            PreviewBone bone = tgt.previewBones[tgt.selectedBoneID];

            bone.ColliderType  = (ColliderType)EditorGUILayout.EnumPopup("Collider Type", bone.ColliderType);
            bone.bounds.center = EditorGUILayout.Vector3Field("Center", bone.bounds.center);
            switch (bone.colliderType)
            {
            case ColliderType.Box:
                bone.bounds.size = EditorGUILayout.Vector3Field("Size", bone.bounds.size);
                break;

            case ColliderType.Capsule:
                bone.capsuleBounds.height    = EditorGUILayout.FloatField("Height", bone.capsuleBounds.height);
                bone.capsuleBounds.radius    = EditorGUILayout.FloatField("Radius", bone.capsuleBounds.radius);
                bone.capsuleBounds.direction = (CapsuleDirection)EditorGUILayout.EnumPopup("Direction", bone.capsuleBounds.direction);
                bone.bounds.size             = bone.capsuleBounds.GetSize();
                break;

            case ColliderType.Sphere:
                bone.capsuleBounds.radius = EditorGUILayout.FloatField("Radius", bone.capsuleBounds.radius);
                bone.capsuleBounds.height = bone.capsuleBounds.radius * 2;
                bone.bounds.size          = bone.capsuleBounds.GetSize();
                break;
            }

            EditorGUILayout.Space();

            tgt.rotationHandle = EditorGUILayout.Toggle("Edit Bone Rotation", tgt.rotationHandle);
            EditorGUI.BeginDisabledGroup(!tgt.rotationHandle);
            EditorGUI.BeginChangeCheck();
            Vector3 rot = bone.rotation.eulerAngles;

            rot = EditorGUILayout.Vector3Field("Rotation", rot);
            if (EditorGUI.EndChangeCheck())
            {
                bone.rotation = Quaternion.Euler(rot);
            }
            EditorGUI.EndDisabledGroup();
        }
示例#4
0
 private bool CheckAndBeginLineDrag()
 {
     //click on bone
     if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
     {
         foreach (PreviewBone bone in tgt.avatar.previewBones)
         {
             if (bone.rect.Contains(Event.current.mousePosition))
             {
                 lineStartBone = bone;
                 lineDrag      = true;
                 return(true);
             }
         }
     }
     return(false);
 }
示例#5
0
        public void CalculateRotationAndBounds(PreviewBone bone)
        {
            if (bone.childIDs == null || bone.childIDs.Count == 0)
            {
                //end bones without childs (for example: head, hand, foot)
                bone.direction = bone.IsRoot ? bone.tr.up : tempPreviewBones[bone.parentID].direction;
                bone.direction = bone.direction.AlignDirectionTo(bone.tr);

                if (bone.rotation == Quaternion.identity)
                {
                    bone.rotation = Quaternion.Inverse(transform.rotation) * Quaternion.LookRotation(bone.direction, transform.forward);
                }

                if (bone.bounds.center == Vector3.zero)
                {
                    bone.bounds.center = Vector3.forward * bone.bounds.size.z / 2;
                }
            }
            else if (bone.childIDs.Count == 1)
            {
                //intermediate bones with one child(upper/lower arm/leg, stomach)
                CalculateRotationAndBoundsSingleChild(bone, 0);
            }
            else if (bone.childIDs.Count > 1)
            {
                //bones with many childs (hip, chest)

                //main bone search
                float dot = -1;
                int   id  = 0;
                for (int i = 0; i < bone.childIDs.Count; i++)
                {
                    Vector3 childPos1   = tempPreviewBones[bone.childIDs[i]].tr.position;
                    Vector3 localAbsDir = bone.tr.InverseTransformDirection(childPos1 - bone.tr.position).Abs();
                    float   tempDot     = Mathf.Max(Vector3.Dot(Vector3.up, localAbsDir), Vector3.Dot(Vector3.right, localAbsDir), Vector3.Dot(Vector3.forward, localAbsDir));
                    if (tempDot > dot)
                    {
                        dot = tempDot;
                        id  = i;
                    }
                }

                CalculateRotationAndBoundsSingleChild(bone, id);
            }
        }
示例#6
0
        private void MassSettings()
        {
            PreviewBone bone = tgt.previewBones[tgt.selectedBoneID];
            float       fullMassInPercent = 0;

            for (int i = 0; i < tgt.previewBones.Count; i++)
            {
                if (tgt.selectedBoneID == i)
                {
                    continue;
                }
                fullMassInPercent += tgt.previewBones[i].massInPercent;
            }
            EditorGUI.BeginDisabledGroup(fullMassInPercent >= 1);
            bone.massInPercent = EditorGUILayout.Slider("Mass In Percent", bone.massInPercent, 0, 1 - fullMassInPercent);
            EditorGUILayout.LabelField("Mass " + (tgt.mass * bone.massInPercent).ToString("0.00") + " kg out of " + (tgt.mass * (fullMassInPercent + bone.massInPercent)).ToString("0.00"));
            EditorGUI.EndDisabledGroup();
        }
示例#7
0
        private void DrawJointHandles()
        {
            if (tgt.previewBones[tgt.selectedBoneID].IsRoot || !tgt.showJointSettings)
            {
                return;
            }

            PreviewBone bone      = tgt.previewBones[tgt.selectedBoneID];
            Quaternion  globalRot = tgt.transform.rotation * bone.rotation;

            if (tgt.rotationHandle)
            {
                Quaternion rot = globalRot * Quaternion.LookRotation(Vector3.Cross(bone.axis, bone.swingAxis), bone.swingAxis);
                EditorGUI.BeginChangeCheck();
                rot = Quaternion.Inverse(globalRot) * Handles.RotationHandle(rot, bone.tr.position);
                if (EditorGUI.EndChangeCheck())
                {
                    bone.axis      = -Vector3.Cross(rot * Vector3.forward, bone.swingAxis).Round(2);
                    bone.swingAxis = (rot * Vector3.up).Round(2);
                }
            }

            Matrix4x4 jointMatrix = Matrix4x4.TRS(bone.tr.position, globalRot * Quaternion.LookRotation(Vector3.Cross(bone.axis, bone.swingAxis), bone.swingAxis), Vector3.one);

            using (new Handles.DrawingScope(jointMatrix)) {
                jointAngularLimitHandle.xMin = bone.lowTwistLimit;
                jointAngularLimitHandle.xMax = bone.highTwistLimit;
                jointAngularLimitHandle.yMin = -bone.swing1Limit;
                jointAngularLimitHandle.yMax = bone.swing1Limit;
                jointAngularLimitHandle.zMin = -bone.swing2Limit;
                jointAngularLimitHandle.zMax = bone.swing2Limit;
                EditorGUI.BeginChangeCheck();
                jointAngularLimitHandle.DrawHandle();
                if (EditorGUI.EndChangeCheck())
                {
                    bone.lowTwistLimit  = jointAngularLimitHandle.xMin;
                    bone.highTwistLimit = jointAngularLimitHandle.xMax;
                    bone.swing1Limit    = jointAngularLimitHandle.yMax == bone.swing1Limit ? -jointAngularLimitHandle.yMin : jointAngularLimitHandle.yMax;
                    bone.swing2Limit    = jointAngularLimitHandle.zMax == bone.swing2Limit ? -jointAngularLimitHandle.zMin : jointAngularLimitHandle.zMax;
                }
            }
        }
        public void CopyTo(PreviewBone bone, bool mirror)
        {
            bone.massInPercent = massInPercent;

            if (!mirror)
            {
                bone.rotation = rotation;
            }

            bone.colliderType  = colliderType;
            bone.bounds        = bounds;
            bone.capsuleBounds = capsuleBounds;

            bone.axis           = axis;
            bone.swingAxis      = swingAxis;
            bone.lowTwistLimit  = lowTwistLimit;
            bone.highTwistLimit = highTwistLimit;
            bone.swing1Limit    = swing1Limit;
            bone.swing2Limit    = swing2Limit;
        }
        public PreviewBone(PreviewBone avatarBone)
        {
            characterBoneId = -1;
            parentID        = avatarBone.parentID;
            childIDs        = avatarBone.childIDs;

            name = avatarBone.name;

            massInPercent = avatarBone.massInPercent;

            rotation = avatarBone.rotation;

            colliderType  = avatarBone.colliderType;
            bounds        = avatarBone.bounds;
            capsuleBounds = avatarBone.capsuleBounds;

            axis           = avatarBone.axis;
            swingAxis      = avatarBone.swingAxis;
            lowTwistLimit  = avatarBone.lowTwistLimit;
            highTwistLimit = avatarBone.highTwistLimit;
            swing1Limit    = avatarBone.swing1Limit;
            swing2Limit    = avatarBone.swing2Limit;
        }
示例#10
0
        private void JointSettings()
        {
            tgt.showJointSettings    = EditorGUILayout.Foldout(tgt.showJointSettings, "Joint");
            tgt.showColliderSettings = !tgt.showJointSettings;
            if (!tgt.showJointSettings)
            {
                return;
            }

            PreviewBone bone = tgt.previewBones[tgt.selectedBoneID];

            bone.lowTwistLimit  = Mathf.Clamp(EditorGUILayout.FloatField("Low Twist Limit", bone.lowTwistLimit), -180, 180);
            bone.highTwistLimit = Mathf.Clamp(EditorGUILayout.FloatField("High Twist Limit", bone.highTwistLimit), -180, 180);
            bone.swing1Limit    = Mathf.Clamp(EditorGUILayout.FloatField("Swing 1 Limit", bone.swing1Limit), 0, 180);
            bone.swing2Limit    = Mathf.Clamp(EditorGUILayout.FloatField("Swing 2 Limit", bone.swing2Limit), 0, 180);

            EditorGUILayout.Space();

            tgt.rotationHandle = EditorGUILayout.Toggle("Edit Axis Rotation", tgt.rotationHandle);
            EditorGUI.BeginDisabledGroup(!tgt.rotationHandle);
            bone.axis      = EditorGUILayout.Vector3Field("Axis", bone.axis);
            bone.swingAxis = EditorGUILayout.Vector3Field("Swing Axis", bone.swingAxis);
            EditorGUI.EndDisabledGroup();
        }
示例#11
0
        private void DrawAvatarBonesHierarchy(int boneID, bool singleBranch)
        {
            if (boneID >= tgt.avatar.previewBones.Count)
            {
                Debug.LogError("Ragdoll avatar is damaged. Some bones are lost.");
                return;
            }
            PreviewBone bone = tgt.avatar.previewBones[boneID];

            if (!singleBranch && bone.childIDs != null)
            {
                GUILayout.BeginVertical();
            }

            //change color if connected
            bool isConnected     = false;
            int  characterBoneID = -1;

            for (int i = 0; i < tgt.characterBones.Count; i++)
            {
                if (bone.name.Equals(tgt.characterBones[i].avatarConnection))
                {
                    characterBoneID = i;
                    isConnected     = true;
                    break;
                }
            }

            DrawBoneBox(bone.name, out bone.rect, Color.red, !isConnected);

            if (bone.childIDs != null)
            {
                if (bone.childIDs.Count > 1)
                {
                    GUILayout.BeginHorizontal();
                }

                for (int i = 0; i < bone.childIDs.Count; i++)
                {
                    int id = bone.childIDs[i];
                    DrawAvatarBonesHierarchy(id, bone.childIDs.Count == 1);
                }

                if (bone.childIDs.Count > 1)
                {
                    GUILayout.EndHorizontal();
                }
            }

            if (!singleBranch && bone.childIDs != null)
            {
                GUILayout.EndVertical();
            }

            //bottom line to childs
            if (!bone.IsRoot)
            {
                DrawBottomLineToChilds(bone.rect);
            }

            Handles.BeginGUI();
            if (isConnected)
            {
                DrawConnector(bone.rect, tgt.characterBones[characterBoneID].rect, Color.gray, true);
            }
            Handles.EndGUI();
        }
示例#12
0
        public override void OnInspectorGUI()
        {
            Undo.RecordObject(target, "RagdollConstructor");

            if (!tgt.configureBonesMode)
            {
                //BEGIN SELECT ACTIVE BONES MODE
                //BEGIN CHARACTER BONES HIERARCHY
                EditorGUILayout.BeginVertical(GUILayout.MinHeight(240));
                EditorGUILayout.LabelField("Character bones hierarchy.");
                scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
                DrawBonesHierarchy(tgt.characterBones[0], true, false, true);
                EditorGUILayout.EndScrollView();
                scrollRect = GUILayoutUtility.GetLastRect();
                foreach (CharacterBone bone in tgt.characterBones)
                {
                    bone.rect.position += scrollRect.position - scrollPosition;
                }
                EditorGUILayout.EndVertical();

                if (ClickCharacterBone())
                {
                    tgt.FillTempBones();
                    Repaint();
                    return;
                }
                //END CHARACTER BONES HIERARCHY
                EditorGUILayout.Space();

                EditorGUILayout.BeginVertical("HelpBox");
                //BEGIN AVATAR BONES HIERARCHY
                if (tgt.avatar != null && tgt.avatar.previewBones != null && tgt.avatar.previewBones.Count > 0)
                {
                    DrawAvatarBonesHierarchy(0, true);
                    EditorGUILayout.LabelField("Connect corresponding bones.");
                    if (CheckAndBeginLineDrag())
                    {
                        EditorGUILayout.EndVertical();
                        Repaint();
                        return;
                    }
                }
                //END AVATAR BONES HIERARCHY

                //BEGIN AVATAR
                EditorGUI.BeginChangeCheck();
                tgt.avatar = (RagdollAvatar)EditorGUILayout.ObjectField("Avatar", tgt.avatar, typeof(RagdollAvatar), false);
                if (EditorGUI.EndChangeCheck())
                {
                    tgt.FindConnectionsWithAvatar();
                    tgt.FillTempBones();
                }
                //END AVATAR
                EditorGUILayout.EndVertical();

                if (tgt.avatar == null)
                {
                    return;
                }
                if (UpdateLineDrag())
                {
                    tgt.FillTempBones();
                    Repaint();
                    return;
                }

                if (tgt.tempPreviewBones == null || tgt.tempPreviewBones.Count == 0)
                {
                    return;
                }
                EditorGUI.BeginDisabledGroup(tgt.previewBones == null || tgt.previewBones.Count == 0);
                tgt.restorePreviousConfiguration = EditorGUILayout.ToggleLeft("Restore Previous Configuration", tgt.restorePreviousConfiguration);
                EditorGUI.EndDisabledGroup();

                if (GUILayout.Button("Configure Selected Bones"))
                {
                    tgt.FillTempBones();
                    if (tgt.CheckRoot())
                    {
                        tgt.CompareAndChangePreviewBones();
                        if (tgt.selectedBoneID < tgt.previewBones.Count)
                        {
                            tgt.previewBones[tgt.selectedBoneID].selected = true;
                        }

                        tgt.configureBonesMode = true;
                    }
                    else
                    {
                        Debug.LogError("The root bone must be single.");
                    }
                }
                //END SELECT ACTIVE BONES MODE
            }
            else
            {
                if (GUILayout.Button("Change Active Bones"))
                {
                    tgt.FindConnectionsWithAvatar();
                    tgt.FillTempBones();
                    tgt.configureBonesMode = false;
                }

                DrawBonesHierarchy(tgt.previewBones[0], true, true, false);
                if (ClickPreviewBone())
                {
                    Repaint();
                    //move camera to bone
                    PreviewBone bone   = tgt.previewBones[tgt.selectedBoneID];
                    Bounds      bounds = bone.bounds;
                    bounds.center = bone.tr.position + bone.rotation * bounds.center;
                    if (bone.colliderType != ColliderType.Box)
                    {
                        bounds.size = bone.capsuleBounds.GetSize();
                    }
                    if (SceneView.lastActiveSceneView != null)
                    {
                        SceneView.lastActiveSceneView.Frame(bounds, false);
                    }
                    return;
                }
                ConfigureBonesGUI();

                if (tgt.avatar != null && GUILayout.Button("Save Avatar '" + tgt.avatar.name + "'"))
                {
                    tgt.SaveBonesToAvatar();
                    EditorUtility.SetDirty(tgt.avatar);
                }
                if (GUILayout.Button("Create Ragdoll"))
                {
                    tgt.CreateRagdoll();
                }
            }

            if (GUI.changed)
            {
                EditorUtility.SetDirty(tgt);
                EditorSceneManager.MarkSceneDirty(tgt.gameObject.scene);
            }
        }
 public bool IsSame(PreviewBone bone)
 {
     return(characterBoneId == bone.characterBoneId);
 }
示例#14
0
 public void CopyBone()
 {
     RagdollConstructor.boneCopy = new PreviewBone(previewBones[selectedBoneID]);
 }
示例#15
0
        private void DrawColliderHandles()
        {
            if (!tgt.showColliderSettings)
            {
                return;
            }

            PreviewBone bone = tgt.previewBones[tgt.selectedBoneID];

            Quaternion globalRot = tgt.transform.rotation * bone.rotation;

            if (tgt.rotationHandle)
            {
                EditorGUI.BeginChangeCheck();
                Quaternion rot = Handles.RotationHandle(globalRot, bone.tr.position);
                if (EditorGUI.EndChangeCheck())
                {
                    bone.rotation = Quaternion.Inverse(tgt.transform.rotation) * rot;
                }
            }

            Matrix4x4 handleMatrix = Matrix4x4.TRS(bone.tr.position, globalRot, Vector3.one);

            using (new Handles.DrawingScope(handleMatrix)) {
                switch (bone.colliderType)
                {
                case ColliderType.Box:
                    boxBoundsHandle.center = bone.bounds.center;
                    boxBoundsHandle.size   = bone.bounds.size;
                    EditorGUI.BeginChangeCheck();
                    boxBoundsHandle.DrawHandle();
                    if (EditorGUI.EndChangeCheck())
                    {
                        bone.bounds.center = boxBoundsHandle.center;
                        bone.bounds.size   = boxBoundsHandle.size;
                    }
                    break;

                case ColliderType.Capsule:
                    capsuleBoundsHandle.center     = bone.bounds.center;
                    capsuleBoundsHandle.height     = bone.capsuleBounds.height;
                    capsuleBoundsHandle.radius     = bone.capsuleBounds.radius;
                    capsuleBoundsHandle.heightAxis = (CapsuleBoundsHandle.HeightAxis)bone.capsuleBounds.direction;
                    EditorGUI.BeginChangeCheck();
                    capsuleBoundsHandle.DrawHandle();
                    if (EditorGUI.EndChangeCheck())
                    {
                        bone.bounds.center           = capsuleBoundsHandle.center;
                        bone.capsuleBounds.height    = capsuleBoundsHandle.height;
                        bone.capsuleBounds.radius    = capsuleBoundsHandle.radius;
                        bone.capsuleBounds.direction = (CapsuleDirection)capsuleBoundsHandle.heightAxis;
                    }
                    break;

                case ColliderType.Sphere:
                    sphereBoundsHandle.center = bone.bounds.center;
                    sphereBoundsHandle.radius = bone.capsuleBounds.radius;
                    EditorGUI.BeginChangeCheck();
                    sphereBoundsHandle.DrawHandle();
                    if (EditorGUI.EndChangeCheck())
                    {
                        bone.bounds.center        = sphereBoundsHandle.center;
                        bone.capsuleBounds.radius = sphereBoundsHandle.radius;
                    }
                    break;
                }
            }
        }