// Functions //----------------------------------------------------- public void SetPose(apMeshGroup targetMeshGroup, apBone selectedBone, string sceneName) { Clear(); _poseName = "<No Name Pose>"; _description = "<No Description>"; _sceneName = sceneName; _portraitName = targetMeshGroup._parentPortrait.name; _meshGroupName = targetMeshGroup._name; _meshGroupUniqueID = targetMeshGroup._uniqueID; List <apBone> rootBones = new List <apBone>(); //<BONE_EDIT> //for (int i = 0; i < targetMeshGroup._boneList_Root.Count; i++) //{ // rootBones.Add(targetMeshGroup._boneList_Root[i]); //} //>>Bone Set으로 변경 apMeshGroup.BoneListSet boneSet = null; for (int iSet = 0; iSet < targetMeshGroup._boneListSets.Count; iSet++) { boneSet = targetMeshGroup._boneListSets[iSet]; for (int iRoot = 0; iRoot < boneSet._bones_Root.Count; iRoot++) { rootBones.Add(boneSet._bones_Root[iRoot]); } } rootBones.Sort(delegate(apBone a, apBone b) { return(b._depth - a._depth); }); int curUnitID = 0; for (int i = 0; i < rootBones.Count; i++) { curUnitID = SetBonesRecursive(rootBones[i], selectedBone, curUnitID); } //for (int i = 0; i < targetMeshGroup._boneList_All.Count; i++) //{ // apBone srcBone = targetMeshGroup._boneList_All[i]; // apRetargetBonePoseUnit dstPoseBone = new apRetargetBonePoseUnit(); // dstPoseBone.SetBone(i, srcBone); // if(selectedBone == srcBone) // { // //이건 일단 Export를 건다 // dstPoseBone._isExported = true; // } // _bones.Add(dstPoseBone); //} //Sort를 하자 //_bones.Sort(delegate (apRetargetBonePoseUnit a, apRetargetBonePoseUnit b) //{ // if (a._targetBone._level == b._targetBone._level) // { // return b._targetBone._depth - a._targetBone._depth; // } // return a._targetBone._level * 1000 - b._targetBone._level * 1000; // //return b._targetBone._depth - a._targetBone._depth; //}); }
private static void MakeSubUnits(apMeshGroup targetMeshGroup, List <apRetargetSubUnit> transforms_All, List <apRetargetSubUnit> transforms_Root, List <apRetargetSubUnit> bones_All, List <apRetargetSubUnit> bones_Root) { int unitID = 0; if (targetMeshGroup._childMeshTransforms != null) { for (int i = 0; i < targetMeshGroup._childMeshTransforms.Count; i++) { apTransform_Mesh meshTransform = targetMeshGroup._childMeshTransforms[i]; apRetargetSubUnit newSubUnit = new apRetargetSubUnit(); newSubUnit.SetSubData(unitID, meshTransform, null, null, null); unitID++; transforms_All.Add(newSubUnit); transforms_Root.Add(newSubUnit); } } if (targetMeshGroup._childMeshGroupTransforms != null) { for (int i = 0; i < targetMeshGroup._childMeshGroupTransforms.Count; i++) { apTransform_MeshGroup meshGroupTransform = targetMeshGroup._childMeshGroupTransforms[i]; //재귀 호출로 ChildMeshGroup의 SubUnit을 만들어주자 unitID = MakeSubUnitsFromMeshGroupTransformRecursive(targetMeshGroup, meshGroupTransform, unitID, transforms_All, transforms_Root, null); } } //Sort를 다시 하자 for (int i = 0; i < transforms_All.Count; i++) { apRetargetSubUnit subUnit = transforms_All[i]; int sortIndex = -1; if (subUnit._type == apRetargetSubUnit.TYPE.MeshTransform) { sortIndex = targetMeshGroup._renderUnits_All.FindIndex(delegate(apRenderUnit a) { if (a._meshTransform == null) { return(false); } return(a._meshTransform._transformUniqueID == subUnit._uniqueID); }); } else if (subUnit._type == apRetargetSubUnit.TYPE.MeshGroupTransform) { sortIndex = targetMeshGroup._renderUnits_All.FindIndex(delegate(apRenderUnit a) { if (a._meshGroupTransform == null) { return(false); } return(a._meshGroupTransform._transformUniqueID == subUnit._uniqueID); }); } subUnit._sortIndex = sortIndex; } transforms_All.Sort(delegate(apRetargetSubUnit a, apRetargetSubUnit b) { return(b._sortIndex - a._sortIndex); }); //Bone도 넣자 //<BONE_EDIT> //if(targetMeshGroup._boneList_Root.Count > 0) //{ // for (int i = 0; i < targetMeshGroup._boneList_Root.Count; i++) // { // unitID = MakeSubUnitsFromBonesRecursive(targetMeshGroup, // targetMeshGroup._boneList_Root[i], // unitID, bones_All, bones_Root, null); // } //} //>> Bone Set으로 변경 if (targetMeshGroup._boneListSets.Count > 0) { apMeshGroup.BoneListSet boneSet = null; for (int iSet = 0; iSet < targetMeshGroup._boneListSets.Count; iSet++) { boneSet = targetMeshGroup._boneListSets[iSet]; for (int iRoot = 0; iRoot < boneSet._bones_Root.Count; iRoot++) { unitID = MakeSubUnitsFromBonesRecursive( boneSet._bones_Root[iRoot], unitID, bones_All, bones_Root, null); } } } //Sort를 다시 하자 for (int i = 0; i < bones_All.Count; i++) { apRetargetSubUnit subUnit = bones_All[i]; //<BONE_EDIT> //subUnit._sortIndex = targetMeshGroup._boneList_All.FindIndex(delegate (apBone a) //{ // return a._uniqueID == subUnit._uniqueID; //}); //>>Bone Set을 이용 subUnit._sortIndex = -1; apMeshGroup.BoneListSet boneSet = null; int startIndex = 0; for (int iSet = 0; iSet < targetMeshGroup._boneListSets.Count; iSet++) { boneSet = targetMeshGroup._boneListSets[iSet]; //현재의 Bone List에 있는지 확인 int resultIndex = boneSet._bones_All.FindIndex(delegate(apBone a) { return(a._uniqueID == subUnit._uniqueID); }); if (resultIndex >= 0 && resultIndex < boneSet._bones_All.Count) { //찾았다. subUnit._sortIndex = startIndex + resultIndex; break; } else { //업다면 기본 인덱스 증가 startIndex += boneSet._bones_All.Count; } } } bones_All.Sort(delegate(apRetargetSubUnit a, apRetargetSubUnit b) { return(a._sortIndex - b._sortIndex); }); }
/// <summary> /// Rigging Modifier 내에서의 Gizmo 이벤트 : Vertex 선택 또는 Bone 선택 [단일 선택] /// </summary> /// <param name="mousePosGL"></param> /// <param name="mousePosW"></param> /// <param name="btnIndex"></param> /// <param name="selectType"></param> /// <returns></returns> public apGizmos.SelectResult Select__Modifier_Rigging(Vector2 mousePosGL, Vector2 mousePosW, int btnIndex, apGizmos.SELECT_TYPE selectType) { if (Editor.Select.MeshGroup == null || Editor.Select.Modifier == null) { return(null); } // 선택은 Test Posing 상관없이 수행한다. // - Vertex > (선택 못했어도 일단 이전에 선택한 Vertex를 해제하지 않는다.) // - Bone > (선택 못했으면 이전에 선택한 Bone 해제) // Vertex나 Bone 선택이 되지 않았다면, 이전에 선택했던 Vertex, Bone을 모두 해제한다. // - Mesh Transform 선택 (Lock이 안걸린 경우. 이건 리턴하지 않는다) // (아무것도 선택하지 않은 경우) -> Vertex, Bone, Mesh Transform 해제 bool isAnySelected = false; if (Editor.Select.ModRenderVertListOfMod == null) { return(null); } if (!Editor.Controller.IsMouseInGUI(mousePosGL)) { if (Editor.Select.ModRenderVertListOfMod.Count > 0) { return(apGizmos.SelectResult.Main.SetMultiple <apSelection.ModRenderVert>(Editor.Select.ModRenderVertListOfMod)); } if (Editor.Select.Bone != null) { return(apGizmos.SelectResult.Main.SetSingle(Editor.Select.Bone)); } return(null); } int prevSelectedVertex = Editor.Select.ModRenderVertListOfMod.Count; //bool isAnyVertexSelected = false; //bool isAnyBoneSelected = false; List <apSelection.ModRenderVert> prevSelectedVertices = new List <apSelection.ModRenderVert>(); for (int i = 0; i < Editor.Select.ModRenderVertListOfMod.Count; i++) { prevSelectedVertices.Add(Editor.Select.ModRenderVertListOfMod[i]); } //1. 버텍스 선택을 먼저 bool isChildMeshTransformSelectable = Editor.Select.Modifier.IsTarget_ChildMeshTransform; if (Editor.Select.ExKey_ModMesh != null && Editor.Select.MeshGroup != null) { //bool selectVertex = false; //일단 선택한 Vertex가 클릭 가능한지 체크 if (Editor.Select.ModRenderVertOfMod != null) { if (Editor.Select.ModRenderVertListOfMod.Count == 1) { if (Editor.Controller.IsVertexClickable(apGL.World2GL(Editor.Select.ModRenderVertOfMod._renderVert._pos_World), mousePosGL)) { if (selectType == apGizmos.SELECT_TYPE.Subtract) { //삭제인 경우 //ModVert가 아니라 ModVertRig인 점 주의 Editor.Select.RemoveModVertexOfModifier(null, Editor.Select.ModRenderVertOfMod._modVertRig, null, Editor.Select.ModRenderVertOfMod._renderVert); //return apGizmos.SELECT_RESULT.None; } else { //그 외에는 => 그대로 갑시다. isAnySelected = true; //return apGizmos.SELECT_RESULT.SameSelected; } //return Editor.Select.ModRenderVertListOfMod.Count; return(apGizmos.SelectResult.Main.SetMultiple <apSelection.ModRenderVert>(Editor.Select.ModRenderVertListOfMod)); } } else { //여러개라고 하네요. List <apSelection.ModRenderVert> modRenderVerts = Editor.Select.ModRenderVertListOfMod; for (int iModRenderVert = 0; iModRenderVert < modRenderVerts.Count; iModRenderVert++) { apSelection.ModRenderVert modRenderVert = modRenderVerts[iModRenderVert]; if (Editor.Controller.IsVertexClickable(apGL.World2GL(modRenderVert._renderVert._pos_World), mousePosGL)) { if (selectType == apGizmos.SELECT_TYPE.Subtract) { //삭제인 경우 //하나 지우고 끝 //결과는 List의 개수 Editor.Select.RemoveModVertexOfModifier(null, modRenderVert._modVertRig, null, modRenderVert._renderVert); } else if (selectType == apGizmos.SELECT_TYPE.Add) { //Add 상태에서 원래 선택된걸 누른다면 //추가인 경우 => 그대로 isAnySelected = true; } else { //만약... new 라면? //다른건 초기화하고 //얘만 선택해야함 apRenderVertex selectedRenderVert = modRenderVert._renderVert; apModifiedVertexRig selectedModVertRig = modRenderVert._modVertRig; Editor.Select.SetModVertexOfModifier(null, null, null, null); Editor.Select.SetModVertexOfModifier(null, selectedModVertRig, null, selectedRenderVert); //return apGizmos.SELECT_RESULT.NewSelected; //return Editor.Select.ModRenderVertOfModList.Count; } //return Editor.Select.ModRenderVertListOfMod.Count; return(apGizmos.SelectResult.Main.SetMultiple <apSelection.ModRenderVert>(Editor.Select.ModRenderVertListOfMod)); } } } } //이부분 주의 //일단 날리되, "Bone을 선택했다면 이전에 선택한 vertex를 유지한다"를 지켜야한다. if (selectType == apGizmos.SELECT_TYPE.New) { //Add나 Subtract가 아닐땐, 잘못 클릭하면 선택을 해제하자 (전부) Editor.Select.SetModVertexOfModifier(null, null, null, null); } if (selectType != apGizmos.SELECT_TYPE.Subtract) { if (Editor.Select.ExKey_ModMesh._transform_Mesh != null && Editor.Select.ExKey_ModMesh._vertRigs != null) { //선택된 RenderUnit을 고르자 apRenderUnit targetRenderUnit = Editor.Select.MeshGroup.GetRenderUnit(Editor.Select.ExKey_ModMesh._transform_Mesh); if (targetRenderUnit != null) { for (int iVert = 0; iVert < targetRenderUnit._renderVerts.Count; iVert++) { apRenderVertex renderVert = targetRenderUnit._renderVerts[iVert]; bool isClick = Editor.Controller.IsVertexClickable(apGL.World2GL(renderVert._pos_World), mousePosGL); if (isClick) { apModifiedVertexRig selectedModVertRig = Editor.Select.ExKey_ModMesh._vertRigs.Find(delegate(apModifiedVertexRig a) { return(renderVert._vertex._uniqueID == a._vertexUniqueID); }); if (selectedModVertRig != null) { if (selectType == apGizmos.SELECT_TYPE.New) { Editor.Select.SetModVertexOfModifier(null, selectedModVertRig, null, renderVert); } else if (selectType == apGizmos.SELECT_TYPE.Add) { Editor.Select.AddModVertexOfModifier(null, selectedModVertRig, null, renderVert); } isAnySelected = true; //isAnyVertexSelected = true; //result = apGizmos.SELECT_RESULT.NewSelected; break; } } } Editor.RefreshControllerAndHierarchy(); //Editor.Repaint(); Editor.SetRepaint(); } } } if (isAnySelected) { Editor.Select.AutoSelectModMeshOrModBone(); } } //if (!Editor.Select.IsLockExEditKey) //{ //기존 << Selection Lock이 안걸려 있을때로 한정 //} //변경 : Selection Lock에 상관없이 Bone을 선택할 수 있다. if (!isAnySelected) { //2. Bone을 선택하자 //Bone은 Select Mode가 Subtract가 아닌 이상 무조건 작동을 한다. //만약, 잠금 버튼이 눌렸다면 -> Bone 선택하지 않았어도 해제를 하지 않는다. apMeshGroup meshGroup = Editor.Select.MeshGroup; apBone prevBone = Editor.Select.Bone; apBone bone = null; apBone resultBone = null; //<BONE_EDIT> //List<apBone> boneList = meshGroup._boneList_All; //for (int i = 0; i < boneList.Count; i++) //{ // bone = boneList[i]; // if (IsBoneClick(bone, mousePosW, mousePosGL, Editor._boneGUIRenderMode, Editor.Select.IsBoneIKRenderable)) // { // if (resultBone == null || resultBone._depth < bone._depth) // { // resultBone = bone; // } // } //} //>>Bone Set으로 변경 apMeshGroup.BoneListSet boneSet = null; for (int iSet = 0; iSet < meshGroup._boneListSets.Count; iSet++) { boneSet = meshGroup._boneListSets[iSet]; for (int iRoot = 0; iRoot < boneSet._bones_Root.Count; iRoot++) { bone = CheckBoneClick(boneSet._bones_Root[iRoot], mousePosW, mousePosGL, Editor._boneGUIRenderMode, -1, Editor.Select.IsBoneIKRenderable); if (bone != null) { resultBone = bone; } } if (resultBone != null) { //이 Set에서 선택이 완료되었다. break; } } if (resultBone != null) { bone = resultBone; if (selectType != apGizmos.SELECT_TYPE.Subtract) { Editor.Select.SetBone(bone); isAnySelected = true; } else { Editor.Select.SetBone(null); } //isAnyBoneSelected = true; } else { bone = null; //isAnyBoneSelected = false; } if (!isAnySelected) { //기존 : 선택한게 없으면 Bone을 Null로 만든다. 단, SelectionLock이 켜져 있으면 유지하도록 한다. //Editor.Select.SetBone(null); //if (Editor.Select.IsLockExEditKey) //{ // Editor.Select.SetBone(prevBone);//복구 //} //변경 : Bone은 해제되지 않는다. if (Editor.Select.IsLockExEditKey) { Editor.Select.SetBone(prevBone); //복구 } } else { //Bone을 선택했다면 //Vertex를 복구해주자 for (int i = 0; i < prevSelectedVertices.Count; i++) { apSelection.ModRenderVert modRenderVert = prevSelectedVertices[i]; Editor.Select.AddModVertexOfModifier(modRenderVert._modVert, modRenderVert._modVertRig, null, modRenderVert._renderVert); } } if (prevBone != Editor.Select.Bone) { _isBoneSelect_MovePosReset = true; Editor.RefreshControllerAndHierarchy(); } } if (!Editor.Select.IsLockExEditKey) { if (!isAnySelected && selectType == apGizmos.SELECT_TYPE.New) { //3. Mesh Transform을 선택하자 //이건 선택 영역에 포함되지 않는다. apTransform_Mesh selectedMeshTransform = null; //정렬된 Render Unit //List<apRenderUnit> renderUnits = Editor.Select.MeshGroup._renderUnits_All;//<<이전 : RenderUnits All 이용 List <apRenderUnit> renderUnits = Editor.Select.MeshGroup.SortedRenderUnits; //<<변경 : Sorted 리스트 사용 for (int iUnit = 0; iUnit < renderUnits.Count; iUnit++) { apRenderUnit renderUnit = renderUnits[iUnit]; if (renderUnit._meshTransform != null && renderUnit._meshTransform._mesh != null) { if (renderUnit._meshTransform._isVisible_Default && renderUnit._meshColor2X.a > 0.1f) //Alpha 옵션 추가 { //Debug.LogError("TODO : Mouse Picking 바꿀것"); bool isPick = apEditorUtil.IsMouseInRenderUnitMesh( mousePosGL, renderUnit); if (isPick) { selectedMeshTransform = renderUnit._meshTransform; //찾았어도 계속 찾는다. //뒤의 아이템이 "앞쪽"에 있는 것이기 때문 } } } } if (selectedMeshTransform != null) { //만약 ChildMeshGroup에 속한 거라면, //Mesh Group 자체를 선택해야 한다. <- 추가 : Child Mesh Transform이 허용되는 경우 그럴 필요가 없다. apMeshGroup parentMeshGroup = Editor.Select.MeshGroup.FindParentMeshGroupOfMeshTransform(selectedMeshTransform); if (parentMeshGroup == null || parentMeshGroup == Editor.Select.MeshGroup || isChildMeshTransformSelectable) { Editor.Select.SetSubMeshInGroup(selectedMeshTransform); } else { apTransform_MeshGroup childMeshGroupTransform = Editor.Select.MeshGroup.FindChildMeshGroupTransform(parentMeshGroup); if (childMeshGroupTransform != null) { Editor.Select.SetSubMeshGroupInGroup(childMeshGroupTransform); } else { Editor.Select.SetSubMeshInGroup(selectedMeshTransform); } } } else { Editor.Select.SetSubMeshInGroup(null); } Editor.RefreshControllerAndHierarchy(); //Editor.Repaint(); Editor.SetRepaint(); } } if (isAnySelected) { if (Editor.Select.ModRenderVertListOfMod != null && Editor.Select.ModRenderVertListOfMod.Count > 0) { //return Editor.Select.ModRenderVertListOfMod.Count; return(apGizmos.SelectResult.Main.SetMultiple <apSelection.ModRenderVert>(Editor.Select.ModRenderVertListOfMod)); } if (Editor.Select.Bone != null) { return(apGizmos.SelectResult.Main.SetSingle(Editor.Select.Bone)); } } return(null); }