///// <summary> ///// Rigging Modifier를 제외한 Modifier에서 실제 Mod값을 변경한다. ///// 회전값을 수정한다. ///// IK의 영향을 받지 않는다. ///// </summary> ///// <param name="deltaAngleW"></param> //public void Rotate__Bone_Modifier(float deltaAngleW) //{ // if(Editor.Select.MeshGroup == null // || Editor.Select.Bone == null // || !Editor._isBoneGUIVisible // || Editor.Select.Modifier == null //<<Modifier가 null이면 안된다. // || deltaAngleW == 0.0f // ) // { // return; // } // apBone bone = Editor.Select.Bone; // apMeshGroup meshGroup = Editor.Select.MeshGroup; // apMeshGroup boneParentMeshGroup = bone._meshGroup;//Bone이 속한 MeshGroup. 다를 수 있다. // apModifierBase modifier = Editor.Select.Modifier;//선택한 Modifier // if(modifier.ModifierType != apModifierBase.MODIFIER_TYPE.Rigging) // { // //리깅 Modifier가 아니라면 패스 // return; // } // //Editing 상태가 아니면 패스 + ModMesh가 없다면 패스 // if (Editor.Select.ExEditingMode == apSelection.EX_EDIT.None || Editor.Select.ExValue_ModMesh == null || Editor.Select.ExKey_ModParamSet == null) // { // return; // } // apModifiedMesh targetModMesh = Editor.Select.ExValue_ModMesh; // //TODO.. //} ///// <summary> ///// AnimClip 수정 중에 현재 AnimKeyFrame의 ModMesh값을 수정한다. ///// 회전값을 수정한다. ///// IK의 영향을 받지 않는다. ///// </summary> ///// <param name="deltaAngleW"></param> //public void Rotate__Bone_Animation(float deltaAngleW) //{ // if (Editor.Select.AnimClip == null // || Editor.Select.AnimClip._targetMeshGroup == null // || deltaAngleW == 0.0f) // { // return; // } // apModifierBase linkedModifier = Editor.Select.AnimTimeline._linkedModifier; // apAnimKeyframe workKeyframe = Editor.Select.AnimWorkKeyframe; // apModifiedMesh targetModMesh = Editor.Select.ModMeshOfAnim; // apRenderUnit targetRenderUnit = Editor.Select.RenderUnitOfAnim; // if (linkedModifier == null || workKeyframe == null || targetModMesh == null || targetRenderUnit == null) // { // //수정할 타겟이 없다. // return; // } // if (targetModMesh._transform_Mesh == null && targetModMesh._transform_MeshGroup == null) // { // //대상이 되는 Mesh/MeshGroup이 없다? // return; // } // if (!Editor.Select.IsAnimEditing || Editor.Select.IsAnimPlaying) // { // //에디팅 중이 아니다. // return; // } // //보이는게 없는데 수정하려고 한다; // if(!Editor._isBoneGUIVisible || Editor.Select.Bone == null) // { // return; // } // apBone bone = Editor.Select.Bone; // apMeshGroup meshGroup = Editor.Select.MeshGroup; // apMeshGroup boneParentMeshGroup = bone._meshGroup;//Bone이 속한 MeshGroup. 다를 수 있다. // apModifierBase modifier = Editor.Select.Modifier;//선택한 Modifier // //TODO.. //} #endregion //------------------------------------------------------------------------------------------------------------ // Bone - Scale (Default / Rigging Test / Modifier / AnimClip Modifier) // Scale은 IK와 관계가 없다. 값을 수정하자! // Scale은 옵션을 On으로 둔 Bone만 가능하다. 옵션 확인할 것 //------------------------------------------------------------------------------------------------------------ /// <summary> /// MeshGroup 메뉴에서 Bone의 Default 편집 중의 스케일 /// Edit Mode가 Select로 활성화되어있어야 한다. /// 선택한 Bone이 현재 선택한 MeshGroup에 속해있어야 한다. /// IK의 영향을 받지 않는다. /// </summary> /// <param name="deltaScaleW"></param> public void Scale__Bone_Default(Vector2 deltaScaleW) { if (Editor.Select.MeshGroup == null || Editor.Select.Bone == null || Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render || Editor.Select.BoneEditMode != apSelection.BONE_EDIT_MODE.SelectAndTRS || deltaScaleW.sqrMagnitude == 0.0f ) { return; } apBone bone = Editor.Select.Bone; apMeshGroup meshGroup = Editor.Select.MeshGroup; if (bone._meshGroup != meshGroup) { //직접 속하지 않고 자식 MeshGroup의 Transform인 경우 제어할 수 없다. return; } apEditorUtil.SetRecord(apUndoGroupData.ACTION.MeshGroup_BoneDefaultEdit, bone._meshGroup, null, false, Editor); Vector3 prevScale = bone._defaultMatrix._scale; Vector2 nextScale = new Vector2(prevScale.x + deltaScaleW.x, prevScale.y + deltaScaleW.y); bone._defaultMatrix.SetScale(nextScale); bone.MakeWorldMatrix(true); bone.GUIUpdate(true); }
//------------------------------------------------------------------------------------------ // Bone - TransformChanged (Default / Rigging Test / Modifier / AnimClip Modifier) // Scale 값 직접 수정 (Scale Lock 체크) //------------------------------------------------------------------------------------------ public void TransformChanged_Scale__Modifier_Rigging(Vector2 scale) { if (Editor.Select.MeshGroup == null || Editor.Select.Bone == null || Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render || Editor.Select.Modifier == null //<<Modifier가 null이면 안된다. ) { return; } if (!Editor.Select.IsRigEditTestPosing) { //TestPosing이 허용되지 않았다면 패스 return; } apBone bone = Editor.Select.Bone; apMeshGroup meshGroup = Editor.Select.MeshGroup; apMeshGroup boneParentMeshGroup = bone._meshGroup; //Bone이 속한 MeshGroup. 다를 수 있다. apModifierBase modifier = Editor.Select.Modifier; //선택한 Modifier if (modifier.ModifierType != apModifierBase.MODIFIER_TYPE.Rigging) { //리깅 Modifier가 아니라면 패스 return; } //직접 대입한다. bone._rigTestMatrix.SetScale(scale); bone.MakeWorldMatrix(true); bone.GUIUpdate(true); //apMatrix dummyWorldMatrix = new apMatrix(bone._worldMatrix); //dummyWorldMatrix.SetScale(scale); ////Parent - (Local) - (RigTest) 순으로 matrix 역 연산 후 남는 Scale 값으로 대입 //apMatrix parentMatrix = null; //if(bone._parentBone != null) //{ // parentMatrix = bone._parentBone._worldMatrix; //} //else if(bone._renderUnit != null) //{ // parentMatrix = bone._renderUnit.WorldMatrixWrap; //} //if (parentMatrix != null) //{ // dummyWorldMatrix.RInverse(parentMatrix); //} //dummyWorldMatrix.Subtract(bone._localMatrix); //dummyWorldMatrix.Subtract(bone._defaultMatrix);//<<Default를 빼자 //dummyWorldMatrix.MakeMatrix(); //bone._rigTestMatrix.SetScale(dummyWorldMatrix.Scale2); //bone.MakeWorldMatrix(true); //bone.GUIUpdate(true); }
/// <summary> /// MeshGroup 메뉴 + Modifier 중 Rigging Modifier에서만 제어할 수 있다. /// Rigging 테스트를 위해 임시 WorldMatrix를 만들어서 움직인다. /// Rigging Modifier 활성할때마다 변수가 초기화됨. /// 자식 MeshGroup의 Bone도 제어 가능하다 (!) /// IK의 영향을 받지 않는다. /// </summary> /// <param name="deltaAngleW"></param> public void Rotate__Modifier_Rigging(float deltaAngleW) { if (Editor.Select.MeshGroup == null || Editor.Select.Bone == null || Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render || Editor.Select.Modifier == null || //<<Modifier가 null이면 안된다. deltaAngleW == 0.0f ) { return; } if (!Editor.Select.IsRigEditTestPosing) { //TestPosing이 허용되지 않았다면 패스 return; } apBone bone = Editor.Select.Bone; apMeshGroup meshGroup = Editor.Select.MeshGroup; apMeshGroup boneParentMeshGroup = bone._meshGroup; //Bone이 속한 MeshGroup. 다를 수 있다. apModifierBase modifier = Editor.Select.Modifier; //선택한 Modifier if (modifier.ModifierType != apModifierBase.MODIFIER_TYPE.Rigging) { //리깅 Modifier가 아니라면 패스 return; } //Default Angle은 -180 ~ 180 범위 안에 들어간다. float nextAngle = bone._rigTestMatrix._angleDeg + deltaAngleW; if (nextAngle < -180.0f) { nextAngle += 360.0f; } if (nextAngle > 180.0f) { nextAngle -= 360.0f; } bone._rigTestMatrix.SetRotate(nextAngle); bone.MakeWorldMatrix(true); bone.GUIUpdate(true); }
///// <summary> ///// Rigging Modifier를 제외한 Modifier에서 실제 Mod 값을 변경한다. ///// 이동값을 수정하며, IK 옵션이 있다면 Parent 또는 그 이상의 Parent부터 계산을 한다. ///// IK Lock이 걸려있으므로 IK 계산을 해야한다. ///// </summary> ///// <param name="curMouseGL"></param> ///// <param name="curMousePosW"></param> ///// <param name="deltaMoveW"></param> ///// <param name="btnIndex"></param> ///// <param name="isFirstMove"></param> //public void Move__Bone_Modifier(Vector2 curMouseGL, Vector2 curMousePosW, Vector2 deltaMoveW, int btnIndex, bool isFirstMove) //{ // if(Editor.Select.MeshGroup == null // || Editor.Select.Bone == null // || !Editor._isBoneGUIVisible // || Editor.Select.Modifier == null //<<Modifier가 null이면 안된다. // || !Editor.Controller.IsMouseInGUI(curMouseGL) // || deltaMoveW.sqrMagnitude == 0.0f // ) // { // return; // } // apBone bone = Editor.Select.Bone; // apMeshGroup meshGroup = Editor.Select.MeshGroup; // apMeshGroup boneParentMeshGroup = bone._meshGroup;//Bone이 속한 MeshGroup. 다를 수 있다. // apModifierBase modifier = Editor.Select.Modifier;//선택한 Modifier // if(modifier.ModifierType != apModifierBase.MODIFIER_TYPE.Rigging) // { // //리깅 Modifier가 아니라면 패스 // return; // } // //Editing 상태가 아니면 패스 + ModMesh가 없다면 패스 // if (Editor.Select.ExEditingMode == apSelection.EX_EDIT.None || Editor.Select.ExValue_ModMesh == null || Editor.Select.ExKey_ModParamSet == null) // { // return; // } // apModifiedMesh targetModMesh = Editor.Select.ExValue_ModMesh; // //TODO.. //} ///// <summary> ///// AnimClip 수정 중에 현재 AnimKeyFrame의 ModMesh값을 수정한다. ///// 이동값을 수정하며, IK 옵션이 있다면 Parent 또는 그 이상의 Parent부터 계산을 한다. ///// IK Lock이 걸려있으므로 IK 계산을 해야한다. ///// </summary> ///// <param name="curMouseGL"></param> ///// <param name="curMousePosW"></param> ///// <param name="deltaMoveW"></param> ///// <param name="btnIndex"></param> ///// <param name="isFirstMove"></param> //public void Move__Bone_Animation(Vector2 curMouseGL, Vector2 curMousePosW, Vector2 deltaMoveW, int btnIndex, bool isFirstMove) //{ // if (Editor.Select.AnimClip == null // || Editor.Select.AnimClip._targetMeshGroup == null // || deltaMoveW.sqrMagnitude == 0.0f) // { // return; // } // apModifierBase linkedModifier = Editor.Select.AnimTimeline._linkedModifier; // apAnimKeyframe workKeyframe = Editor.Select.AnimWorkKeyframe; // apModifiedMesh targetModMesh = Editor.Select.ModMeshOfAnim; // apRenderUnit targetRenderUnit = Editor.Select.RenderUnitOfAnim; // if (linkedModifier == null || workKeyframe == null || targetModMesh == null || targetRenderUnit == null) // { // //수정할 타겟이 없다. // return; // } // if (targetModMesh._transform_Mesh == null && targetModMesh._transform_MeshGroup == null) // { // //대상이 되는 Mesh/MeshGroup이 없다? // return; // } // if (!Editor.Select.IsAnimEditing || Editor.Select.IsAnimPlaying) // { // //에디팅 중이 아니다. // return; // } // //마우스가 안에 없다. // if (!Editor.Controller.IsMouseInGUI(curMouseGL)) // { // return; // } // //보이는게 없는데 수정하려고 한다; // if(!Editor._isBoneGUIVisible || Editor.Select.Bone == null) // { // return; // } // apBone bone = Editor.Select.Bone; // apMeshGroup meshGroup = Editor.Select.MeshGroup; // apMeshGroup boneParentMeshGroup = bone._meshGroup;//Bone이 속한 MeshGroup. 다를 수 있다. // apModifierBase modifier = Editor.Select.Modifier;//선택한 Modifier // //TODO.. //} #endregion //------------------------------------------------------------------------------------------------------------ // Bone - Rotate (Default / Rigging Test / Modifier / AnimClip Modifier) // Rotate는 IK와 관계가 없다. 값을 수정하자! //------------------------------------------------------------------------------------------------------------ /// <summary> /// MeshGroup 메뉴에서 Bone의 Default 편집 중의 회전 /// Edit Mode가 Select로 활성화되어있어야 한다. /// 선택한 Bone이 현재 선택한 MeshGroup에 속해있어야 한다. /// IK의 영향을 받지 않는다. /// </summary> /// <param name="deltaAngleW"></param> public void Rotate__Bone_Default(float deltaAngleW, bool isFirstRotate) { if (Editor.Select.MeshGroup == null || Editor.Select.Bone == null || Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render || Editor.Select.BoneEditMode != apSelection.BONE_EDIT_MODE.SelectAndTRS ) { return; } if (deltaAngleW == 0.0f && !isFirstRotate) { return; } apBone bone = Editor.Select.Bone; apMeshGroup meshGroup = Editor.Select.MeshGroup; if (bone._meshGroup != meshGroup) { //직접 속하지 않고 자식 MeshGroup의 Transform인 경우 제어할 수 없다. return; } if (isFirstRotate) { apEditorUtil.SetRecord_MeshGroup(apUndoGroupData.ACTION.MeshGroup_BoneDefaultEdit, Editor, bone._meshGroup, null, false, false); } //Default Angle은 -180 ~ 180 범위 안에 들어간다. float nextAngle = bone._defaultMatrix._angleDeg + deltaAngleW; nextAngle = apUtil.AngleTo180(nextAngle); bone._defaultMatrix.SetRotate(nextAngle); bone.MakeWorldMatrix(true); bone.GUIUpdate(true); }
/// <summary> /// MeshGroup 메뉴 + Modifier 중 Rigging Modifier에서만 제어할 수 있다. /// Rigging 테스트를 위해 임시 WorldMatrix를 만들어서 움직인다. /// Rigging Modifier 활성할때마다 변수가 초기화됨. /// 자식 MeshGroup의 Bone도 제어 가능하다 (!) /// IK의 영향을 받지 않는다. /// </summary> /// <param name="deltaScaleW"></param> public void Scale__Modifier_Rigging(Vector2 deltaScaleW) { if (Editor.Select.MeshGroup == null || Editor.Select.Bone == null || Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render || Editor.Select.Modifier == null || //<<Modifier가 null이면 안된다. deltaScaleW.sqrMagnitude == 0.0f ) { return; } if (!Editor.Select.IsRigEditTestPosing) { //TestPosing이 허용되지 않았다면 패스 return; } apBone bone = Editor.Select.Bone; apMeshGroup meshGroup = Editor.Select.MeshGroup; apMeshGroup boneParentMeshGroup = bone._meshGroup; //Bone이 속한 MeshGroup. 다를 수 있다. apModifierBase modifier = Editor.Select.Modifier; //선택한 Modifier if (modifier.ModifierType != apModifierBase.MODIFIER_TYPE.Rigging) { //리깅 Modifier가 아니라면 패스 return; } Vector3 prevScale = bone._rigTestMatrix._scale; Vector2 nextScale = new Vector2(prevScale.x + deltaScaleW.x, prevScale.y + deltaScaleW.y); bone._rigTestMatrix.SetScale(nextScale); bone.MakeWorldMatrix(true); bone.GUIUpdate(true); }
//------------------------------------------------------------------------------------------ // Bone - TransformChanged (Default / Rigging Test / Modifier / AnimClip Modifier) // Move 값 직접 수정. IK, Local Move 옵션에 따라 무시될 수 있다. // World 값이 아니라 Local 값을 수정한다. Local Move가 Lock이 걸린 경우엔 값이 적용되지 않는다. //------------------------------------------------------------------------------------------ public void TransformChanged_Position__Modifier_Rigging(Vector2 pos, int depth) { if (Editor.Select.MeshGroup == null || Editor.Select.Bone == null || Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render || Editor.Select.Modifier == null //<<Modifier가 null이면 안된다. ) { return; } apBone bone = Editor.Select.Bone; apMeshGroup meshGroup = Editor.Select.MeshGroup; apMeshGroup boneParentMeshGroup = bone._meshGroup; //Bone이 속한 MeshGroup. 다를 수 있다. apModifierBase modifier = Editor.Select.Modifier; //선택한 Modifier if (modifier.ModifierType != apModifierBase.MODIFIER_TYPE.Rigging) { //리깅 Modifier가 아니라면 패스 return; } if (!Editor.Select.IsRigEditTestPosing) { //TestPosing이 허용되지 않았다면 패스 return; } //직접 대입하고 끝 bone._rigTestMatrix.SetPos(pos); bone.MakeWorldMatrix(true); bone.GUIUpdate(true); //_boneSelectPosW = pos; ////Move로 제어 가능한 경우는 ////1. IK Tail일 때 ////2. Root Bone일때 (절대값) //if (bone._isIKTail) //{ // //Debug.Log("Request IK : " + _boneSelectPosW); // float weight = 1.0f; // //bool successIK = bone.RequestIK(_boneSelectPosW, weight, !isFirstSelectBone); // bool successIK = bone.RequestIK(_boneSelectPosW, weight, true); // if (!successIK) // { // return; // } // apBone headBone = bone._IKHeaderBone; // if (headBone != null) // { // apBone curBone = bone; // //위로 올라가면서 IK 결과값을 Default에 적용하자 // while (true) // { // float deltaAngle = curBone._IKRequestAngleResult; // //float nextAngle = curBone._defaultMatrix._angleDeg + deltaAngle; // float nextAngle = curBone._rigTestMatrix._angleDeg + deltaAngle;//Rig Test로 할 것 // if (nextAngle < -180.0f) { nextAngle += 360.0f; } // if (nextAngle > 180.0f) { nextAngle -= 360.0f; } // //curBone._defaultMatrix.SetRotate(nextAngle); // curBone._rigTestMatrix.SetRotate(nextAngle); // curBone._isIKCalculated = false; // curBone._IKRequestAngleResult = 0.0f; // if (curBone == headBone) // { // break; // } // if (curBone._parentBone == null) // { // break; // } // curBone = curBone._parentBone; // } // //마지막으론 World Matrix 갱신 // headBone.MakeWorldMatrix(true); // headBone.GUIUpdate(true); // } //} //else if(bone._parentBone == null) //{ // apMatrix renderUnitMatrix = null; // if(bone._renderUnit != null) // { // //Render Unit의 World Matrix를 참조하여 // //로컬 값을 Default로 적용하자 // renderUnitMatrix = bone._renderUnit.WorldMatrixWrap; // } // apMatrix localMatrix = bone._localMatrix; // apMatrix newWorldMatrix = new apMatrix(bone._worldMatrix); // newWorldMatrix.SetPos(pos); // if(renderUnitMatrix != null) // { // newWorldMatrix.RInverse(renderUnitMatrix); // } // newWorldMatrix.Subtract(localMatrix);//이건 Add로 연산된거라 Subtract해야한다. // //bone._defaultMatrix.SetPos(newWorldMatrix._pos); // bone._rigTestMatrix.SetPos(newWorldMatrix._pos - bone._defaultMatrix._pos); // bone.MakeWorldMatrix(true); // bone.GUIUpdate(true); //} }
/// <summary> /// MeshGroup 메뉴 + Modifier 중 Rigging Modifier에서만 제어할 수 있다. /// Rigging 테스트를 위해 임시 WorldMatrix를 만들어서 움직인다. /// Rigging Modifier 활성할때마다 변수가 초기화됨. /// 자식 MeshGroup의 Bone도 제어 가능하다 (!) /// Default와 달리 IK Lock이 걸려있으므로 IK 계산을 해야한다. /// </summary> /// <param name="curMouseGL"></param> /// <param name="curMousePosW"></param> /// <param name="deltaMoveW"></param> /// <param name="btnIndex"></param> /// <param name="isFirstMove"></param> public void Move__Modifier_Rigging(Vector2 curMouseGL, Vector2 curMousePosW, Vector2 deltaMoveW, int btnIndex, bool isFirstMove) { if (Editor.Select.MeshGroup == null || Editor.Select.Bone == null || Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render || Editor.Select.Modifier == null || //<<Modifier가 null이면 안된다. !Editor.Controller.IsMouseInGUI(curMouseGL) || deltaMoveW.sqrMagnitude == 0.0f ) { return; } apBone bone = Editor.Select.Bone; apMeshGroup meshGroup = Editor.Select.MeshGroup; apMeshGroup boneParentMeshGroup = bone._meshGroup; //Bone이 속한 MeshGroup. 다를 수 있다. apModifierBase modifier = Editor.Select.Modifier; //선택한 Modifier if (modifier.ModifierType != apModifierBase.MODIFIER_TYPE.Rigging) { //리깅 Modifier가 아니라면 패스 return; } if (!Editor.Select.IsRigEditTestPosing) { //TestPosing이 허용되지 않았다면 패스 return; } _boneSelectPosW = curMousePosW; //Move로 제어 가능한 경우는 //1. IK Tail일 때 //2. Root Bone일때 (절대값) if (bone._isIKTail) { //Debug.Log("Request IK : " + _boneSelectPosW); float weight = 1.0f; if (deltaMoveW.sqrMagnitude < 5.0f) { //weight = 0.2f; } //bool successIK = bone.RequestIK(_boneSelectPosW, weight, !isFirstSelectBone); bool successIK = bone.RequestIK(_boneSelectPosW, weight, true); if (!successIK) { return; } apBone headBone = bone._IKHeaderBone; if (headBone != null) { apBone curBone = bone; //위로 올라가면서 IK 결과값을 Default에 적용하자 while (true) { float deltaAngle = curBone._IKRequestAngleResult; //float nextAngle = curBone._defaultMatrix._angleDeg + deltaAngle; float nextAngle = curBone._rigTestMatrix._angleDeg + deltaAngle; //Rig Test로 할 것 if (nextAngle < -180.0f) { nextAngle += 360.0f; } if (nextAngle > 180.0f) { nextAngle -= 360.0f; } //curBone._defaultMatrix.SetRotate(nextAngle); curBone._rigTestMatrix.SetRotate(nextAngle); curBone._isIKCalculated = false; curBone._IKRequestAngleResult = 0.0f; if (curBone == headBone) { break; } if (curBone._parentBone == null) { break; } curBone = curBone._parentBone; } //마지막으론 World Matrix 갱신 headBone.MakeWorldMatrix(true); headBone.GUIUpdate(true); } } else if (bone._parentBone == null) { apMatrix renderUnitMatrix = null; if (bone._renderUnit != null) { //Render Unit의 World Matrix를 참조하여 //로컬 값을 Default로 적용하자 renderUnitMatrix = bone._renderUnit.WorldMatrixWrap; } apMatrix localMatrix = bone._localMatrix; apMatrix newWorldMatrix = new apMatrix(bone._worldMatrix); newWorldMatrix.SetPos(newWorldMatrix._pos + deltaMoveW); if (renderUnitMatrix != null) { newWorldMatrix.RInverse(renderUnitMatrix); } newWorldMatrix.Subtract(localMatrix); //이건 Add로 연산된거라 Subtract해야한다. //bone._defaultMatrix.SetPos(newWorldMatrix._pos); bone._rigTestMatrix.SetPos(newWorldMatrix._pos - bone._defaultMatrix._pos); bone.MakeWorldMatrix(true); bone.GUIUpdate(true); } }
///// <summary> ///// Rigging Modifier를 제외한 Modifier에서 실제 Mod값을 변경한다. ///// 크기를 수정한다. ///// IK의 영향을 받지 않는다. ///// </summary> ///// <param name="deltaScaleW"></param> //public void Scale__Bone_Modifier(Vector2 deltaScaleW) //{ // if(Editor.Select.MeshGroup == null // || Editor.Select.Bone == null // || !Editor._isBoneGUIVisible // || Editor.Select.Modifier == null //<<Modifier가 null이면 안된다. // || deltaScaleW.sqrMagnitude == 0.0f // ) // { // return; // } // apBone bone = Editor.Select.Bone; // apMeshGroup meshGroup = Editor.Select.MeshGroup; // apMeshGroup boneParentMeshGroup = bone._meshGroup;//Bone이 속한 MeshGroup. 다를 수 있다. // apModifierBase modifier = Editor.Select.Modifier;//선택한 Modifier // if(modifier.ModifierType != apModifierBase.MODIFIER_TYPE.Rigging) // { // //리깅 Modifier가 아니라면 패스 // return; // } // //Editing 상태가 아니면 패스 + ModMesh가 없다면 패스 // if (Editor.Select.ExEditingMode == apSelection.EX_EDIT.None || Editor.Select.ExValue_ModMesh == null || Editor.Select.ExKey_ModParamSet == null) // { // return; // } // apModifiedMesh targetModMesh = Editor.Select.ExValue_ModMesh; // //TODO.. //} ///// <summary> ///// AnimClip 수정 중에 현재 AnimKeyFrame의 ModMesh값을 수정한다. ///// 크기값을 수정한다. ///// IK의 영향을 받지 않는다. ///// </summary> ///// <param name="deltaScaleW"></param> //public void Scale__Bone_Animation(Vector2 deltaScaleW) //{ // if (Editor.Select.AnimClip == null // || Editor.Select.AnimClip._targetMeshGroup == null // || deltaScaleW.sqrMagnitude == 0.0f) // { // return; // } // apModifierBase linkedModifier = Editor.Select.AnimTimeline._linkedModifier; // apAnimKeyframe workKeyframe = Editor.Select.AnimWorkKeyframe; // apModifiedMesh targetModMesh = Editor.Select.ModMeshOfAnim; // apRenderUnit targetRenderUnit = Editor.Select.RenderUnitOfAnim; // if (linkedModifier == null || workKeyframe == null || targetModMesh == null || targetRenderUnit == null) // { // //수정할 타겟이 없다. // return; // } // if (targetModMesh._transform_Mesh == null && targetModMesh._transform_MeshGroup == null) // { // //대상이 되는 Mesh/MeshGroup이 없다? // return; // } // if (!Editor.Select.IsAnimEditing || Editor.Select.IsAnimPlaying) // { // //에디팅 중이 아니다. // return; // } // //보이는게 없는데 수정하려고 한다; // if(!Editor._isBoneGUIVisible || Editor.Select.Bone == null) // { // return; // } // apBone bone = Editor.Select.Bone; // apMeshGroup meshGroup = Editor.Select.MeshGroup; // apMeshGroup boneParentMeshGroup = bone._meshGroup;//Bone이 속한 MeshGroup. 다를 수 있다. // apModifierBase modifier = Editor.Select.Modifier;//선택한 Modifier // //TODO.. //} #endregion //------------------------------------------------------------------------------------------ // Bone - TransformChanged (Default / Rigging Test / Modifier / AnimClip Modifier) // Move 값 직접 수정. IK, Local Move 옵션에 따라 무시될 수 있다. // World 값이 아니라 Local 값을 수정한다. Local Move가 Lock이 걸린 경우엔 값이 적용되지 않는다. //------------------------------------------------------------------------------------------ public void TransformChanged_Position__Bone_Default(Vector2 pos, int depth) { if (Editor.Select.MeshGroup == null || Editor.Select.Bone == null || Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render || Editor.Select.BoneEditMode != apSelection.BONE_EDIT_MODE.SelectAndTRS ) { return; } //Pos는 World 좌표계이다. apBone bone = Editor.Select.Bone; apMeshGroup meshGroup = Editor.Select.MeshGroup; if (bone._meshGroup != meshGroup) { //직접 속하지 않고 자식 MeshGroup의 Transform인 경우 제어할 수 없다. return; } apEditorUtil.SetRecord_MeshGroup(apUndoGroupData.ACTION.MeshGroup_BoneDefaultEdit, Editor, bone._meshGroup, null, false, false); _boneSelectPosW = pos; //수정 : 걍 직접 넣자 bone._defaultMatrix._pos = pos; bone.MakeWorldMatrix(true); bone.GUIUpdate(true); //Depth가 추가되었다. if (bone._depth != depth) { //Depth를 바꾸면 전체적으로 다시 정렬한다. //bone._depth = depth; bone._meshGroup.ChangeBoneDepth(bone, depth); Editor.RefreshControllerAndHierarchy(); } #region [미사용 코드] ////Move로 제어 가능한 경우는 ////1. IK Tail일 때 ////2. Root Bone일때 (절대값) //if (bone._isIKTail) //{ // //Debug.Log("Request IK : " + _boneSelectPosW); // bool successIK = bone.RequestIK(_boneSelectPosW, 1.0f, false);//Continuous가 아니다 // if (!successIK) // { // return; // } // apBone headBone = bone._IKHeaderBone; // if (headBone != null) // { // apBone curBone = bone; // //위로 올라가면서 IK 결과값을 Default에 적용하자 // while (true) // { // float deltaAngle = curBone._IKRequestAngleResult; // float nextAngle = curBone._defaultMatrix._angleDeg + deltaAngle; // if (nextAngle < -180.0f) // { // nextAngle += 360.0f; // } // if (nextAngle > 180.0f) // { // nextAngle -= 360.0f; // } // curBone._defaultMatrix.SetRotate(nextAngle); // curBone._isIKCalculated = false; // curBone._IKRequestAngleResult = 0.0f; // if (curBone == headBone) // { // break; // } // if (curBone._parentBone == null) // { // break; // } // curBone = curBone._parentBone; // } // //마지막으론 World Matrix 갱신 // headBone.MakeWorldMatrix(true); // headBone.GUIUpdate(true); // } //} //else if(bone._parentBone == null) //{ // apMatrix renderUnitMatrix = null; // if(bone._renderUnit != null) // { // //Render Unit의 World Matrix를 참조하여 // //로컬 값을 Default로 적용하자 // renderUnitMatrix = bone._renderUnit.WorldMatrixWrap; // } // apMatrix localMatrix = bone._localMatrix; // apMatrix newWorldMatrix = new apMatrix(bone._worldMatrix); // newWorldMatrix.SetPos(pos);//< 직접 입력 // if(renderUnitMatrix != null) // { // newWorldMatrix.RInverse(renderUnitMatrix); // } // newWorldMatrix.RInverse(localMatrix); // bone._defaultMatrix.SetPos(newWorldMatrix._pos); // bone.MakeWorldMatrix(true); // bone.GUIUpdate(true); //} #endregion }
//------------------------------------------------------------------------------------------------------------ // Bone - Move (Default / Rigging Test / Modifier / AnimClip Modifier) // Local Move / IK 처리 옵션에 따라 변경 값이 다르다 // Local Move / IK는 "허용하는 경우" 서로 배타적으로 수정한다. (토글 버튼을 두자) // (1) Local Move : Parent에 상관없이 Local Position을 바꾼다. RootNode를 제외하고는 모두 Off. // (2) IK : 제어한 마우스 위치에 맞게 Parent들을 회전한다. 실제로 Local Postion이 바뀌진 않다. // IK가 설정되어있다면 다중 IK 처리를 하며, 그렇지 않다면 바로 위의 Parent만 IK를 적용한다. (Root 제외) //------------------------------------------------------------------------------------------------------------ /// <summary> /// MeshGroup 메뉴에서 Bone의 Default 편집 중의 이동 /// Edit Mode가 Select로 활성화되어있어야 한다. /// 선택한 Bone이 현재 선택한 MeshGroup에 속해있어야 한다. /// IK Lock 여부에 따라 값이 바뀐다. /// IK Lock이 걸려있을 때) Parent 본의 Default Rotate가 바뀐다. (해당 Bone의 World를 만들어주기 위해서) /// IK Lock이 걸려있지않을 때) 해당 Bone의 Default Pos가 바뀐다. /// </summary> /// <param name="curMouseGL"></param> /// <param name="curMousePosW"></param> /// <param name="deltaMoveW"></param> /// <param name="btnIndex"></param> /// <param name="isFirstMove"></param> public void Move__Bone_Default(Vector2 curMouseGL, Vector2 curMousePosW, Vector2 deltaMoveW, int btnIndex, bool isFirstMove) { if (Editor.Select.MeshGroup == null || Editor.Select.Bone == null || Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render || Editor.Select.BoneEditMode != apSelection.BONE_EDIT_MODE.SelectAndTRS || !Editor.Controller.IsMouseInGUI(curMouseGL) ) { return; } if (deltaMoveW.sqrMagnitude == 0.0f && !isFirstMove) { return; } apBone bone = Editor.Select.Bone; apMeshGroup meshGroup = Editor.Select.MeshGroup; if (bone._meshGroup != meshGroup) { //직접 속하지 않고 자식 MeshGroup의 Transform인 경우 제어할 수 없다. return; } if (isFirstMove) { apEditorUtil.SetRecord_MeshGroup(apUndoGroupData.ACTION.MeshGroup_BoneDefaultEdit, Editor, bone._meshGroup, null, false, false); } //bool isFirstSelectBone = false; //TODO.. if (_isBoneSelect_MovePosReset) { _boneSelectPosW = bone._worldMatrix._pos; _isBoneSelect_MovePosReset = false; //isFirstSelectBone = true; } else { _boneSelectPosW += deltaMoveW; //<<여기에 IK를 걸어주자 } _boneSelectPosW = curMousePosW; //Move로 제어 가능한 경우는 //1. IK Tail일 때 //2. Root Bone일때 (절대값) if (bone._isIKTail) { //Debug.Log("Request IK : " + _boneSelectPosW); float weight = 1.0f; if (deltaMoveW.sqrMagnitude < 5.0f) { //weight = 0.2f; } //bool successIK = bone.RequestIK(_boneSelectPosW, weight, !isFirstSelectBone); bool successIK = bone.RequestIK(_boneSelectPosW, weight, true); if (!successIK) { return; } apBone headBone = bone._IKHeaderBone; if (headBone != null) { apBone curBone = bone; //위로 올라가면서 IK 결과값을 Default에 적용하자 while (true) { float deltaAngle = curBone._IKRequestAngleResult; //if(Mathf.Abs(deltaAngle) > 30.0f) //{ // deltaAngle *= deltaAngle * 0.1f; //} float nextAngle = curBone._defaultMatrix._angleDeg + deltaAngle; nextAngle = apUtil.AngleTo180(nextAngle); curBone._defaultMatrix.SetRotate(nextAngle); curBone._isIKCalculated = false; curBone._IKRequestAngleResult = 0.0f; if (curBone == headBone) { break; } if (curBone._parentBone == null) { break; } curBone = curBone._parentBone; } //마지막으론 World Matrix 갱신 headBone.MakeWorldMatrix(true); headBone.GUIUpdate(true); } } else if (bone._parentBone == null || (bone._parentBone._IKNextChainedBone != bone)) { //수정 : Parent가 있지만 IK로 연결 안된 경우 / Parent가 없는 경우 2가지 모두 처리한다. apMatrix parentMatrix = null; if (bone._parentBone == null) { if (bone._renderUnit != null) { //Render Unit의 World Matrix를 참조하여 //로컬 값을 Default로 적용하자 parentMatrix = bone._renderUnit.WorldMatrixWrap; } } else { parentMatrix = bone._parentBone._worldMatrix; } apMatrix localMatrix = bone._localMatrix; apMatrix newWorldMatrix = new apMatrix(bone._worldMatrix); newWorldMatrix.SetPos(newWorldMatrix._pos + deltaMoveW); if (parentMatrix != null) { newWorldMatrix.RInverse(parentMatrix); } newWorldMatrix.Subtract(localMatrix); //이건 Add로 연산된거라 Subtract해야한다. bone._defaultMatrix.SetPos(newWorldMatrix._pos); bone.MakeWorldMatrix(true); bone.GUIUpdate(true); } }
//public void TransformChanged_Rotate__Bone_Modifier(float angle) //{ //} //public void TransformChanged_Rotate__Bone_Animation(float angle) //{ //} #endregion //------------------------------------------------------------------------------------------ // Bone - TransformChanged (Default / Rigging Test / Modifier / AnimClip Modifier) // Scale 값 직접 수정 (Scale Lock 체크) //------------------------------------------------------------------------------------------ public void TransformChanged_Scale__Bone_Default(Vector2 scale) { if (Editor.Select.MeshGroup == null || Editor.Select.Bone == null || Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render || Editor.Select.BoneEditMode != apSelection.BONE_EDIT_MODE.SelectAndTRS ) { return; } apBone bone = Editor.Select.Bone; apMeshGroup meshGroup = Editor.Select.MeshGroup; if (bone._meshGroup != meshGroup) { //직접 속하지 않고 자식 MeshGroup의 Transform인 경우 제어할 수 없다. return; } apEditorUtil.SetRecord_MeshGroup(apUndoGroupData.ACTION.MeshGroup_BoneDefaultEdit, Editor, bone._meshGroup, null, false, false); //직접 넣자 bone._defaultMatrix.SetScale(scale); //<<변경된 값 bone.MakeWorldMatrix(true); bone.GUIUpdate(true); #region [미사용 코드] ////Scale 값이 World Matrix이다. //apMatrix dummyWorldMatrix = new apMatrix(bone._worldMatrix); //dummyWorldMatrix.SetScale(scale); ////Parent - (Local) - (RigTest) 순으로 matrix 역 연산 후 남는 Scale 값으로 대입 //apMatrix parentMatrix = null; //if(bone._parentBone != null) //{ // parentMatrix = bone._parentBone._worldMatrix; //} //else if(bone._renderUnit != null) //{ // parentMatrix = bone._renderUnit.WorldMatrixWrap; //} //if (parentMatrix != null) //{ // dummyWorldMatrix.RInverse(parentMatrix); //} //dummyWorldMatrix.Subtract(bone._localMatrix); //if(bone._isRigTestPosing) //{ // dummyWorldMatrix.Subtract(bone._rigTestMatrix); //} //dummyWorldMatrix.MakeMatrix(); ////bone._defaultMatrix.SetScale(scale); //bone._defaultMatrix.SetScale(dummyWorldMatrix.Scale2);//<<변경된 값 //bone.MakeWorldMatrix(true); //bone.GUIUpdate(true); #endregion }
//public void TransformChanged_Position__Bone_Modifier(Vector2 pos, int depth) //{ //} //public void TransformChanged_Position__Bone_Animation(Vector2 pos, int depth) //{ //} #endregion //------------------------------------------------------------------------------------------ // Bone - TransformChanged (Default / Rigging Test / Modifier / AnimClip Modifier) // Rotate 값 직접 수정 (IK Range 확인) //------------------------------------------------------------------------------------------ public void TransformChanged_Rotate__Bone_Default(float angle) { if (Editor.Select.MeshGroup == null || Editor.Select.Bone == null || Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render || Editor.Select.BoneEditMode != apSelection.BONE_EDIT_MODE.SelectAndTRS ) { return; } apBone bone = Editor.Select.Bone; apMeshGroup meshGroup = Editor.Select.MeshGroup; if (bone._meshGroup != meshGroup) { //직접 속하지 않고 자식 MeshGroup의 Transform인 경우 제어할 수 없다. return; } apEditorUtil.SetRecord_MeshGroup(apUndoGroupData.ACTION.MeshGroup_BoneDefaultEdit, Editor, bone._meshGroup, null, false, false); //직접 넣어주자 angle = apUtil.AngleTo180(angle); bone._defaultMatrix.SetRotate(angle); //World -> Default로 수정된 값 bone.MakeWorldMatrix(true); bone.GUIUpdate(true); #region [미사용 코드] ////Default Angle은 -180 ~ 180 범위 안에 들어간다. ////일단 값을 넣어주자. 나중에 Link시에 자동으로 -180 ~ 180 영역으로 돌아감 //apMatrix dummyWorldMatrix = new apMatrix(bone._worldMatrix); //dummyWorldMatrix.SetRotate(angle); ////Parent - (Local) - (RigTest) 순으로 matrix 역 연산 후 남는 Scale 값으로 대입 //apMatrix parentMatrix = null; //if(bone._parentBone != null) //{ // parentMatrix = bone._parentBone._worldMatrix; //} //else if(bone._renderUnit != null) //{ // parentMatrix = bone._renderUnit.WorldMatrixWrap; //} //if (parentMatrix != null) //{ // dummyWorldMatrix.RInverse(parentMatrix); //} //dummyWorldMatrix.Subtract(bone._localMatrix); //if(bone._isRigTestPosing) //{ // dummyWorldMatrix.Subtract(bone._rigTestMatrix); //} //dummyWorldMatrix.MakeMatrix(); ////bone._defaultMatrix.SetRotate(angle); //bone._defaultMatrix.SetRotate(dummyWorldMatrix._angleDeg);//World -> Default로 수정된 값 //bone.MakeWorldMatrix(true); //bone.GUIUpdate(true); #endregion }