private void AddBoneUnitRecursive(apBone bone, List <apBone> exclusiveBones, apBone targetBone, BoneUnit parentBoneUnit) { int nextLevel = 0; if (parentBoneUnit != null) { nextLevel = parentBoneUnit._level + 1; } BoneUnit boneUnit = new BoneUnit(bone, !exclusiveBones.Contains(bone), bone == targetBone, parentBoneUnit, nextLevel); _boneUnits.Add(boneUnit); if (parentBoneUnit != null) { parentBoneUnit.AddBoneUnit(boneUnit); } if (parentBoneUnit == null) { _boneUnits_Root.Add(boneUnit); } for (int i = 0; i < bone._childBones.Count; i++) { AddBoneUnitRecursive(bone._childBones[i], exclusiveBones, targetBone, boneUnit); } //다 넣었으면 _boneUnit별로 Sort를 하자 if (boneUnit._childUnits.Count > 0) { boneUnit._childUnits.Sort(delegate(BoneUnit a, BoneUnit b) { return(string.Compare(a._bone._name, b._bone._name)); }); } }
public void AddBoneUnit(BoneUnit childUnit) { _childUnits.Add(childUnit); _isFoldable = true; _isFolded = false; }
private void AddBoneUnit(apBone bone) { BoneUnit boneUnit = new BoneUnit(bone, true, false, null, 0); _boneUnits.Add(boneUnit); _boneUnits_Root.Add(boneUnit); }
public BoneUnit(apBone bone, bool isSelectable, bool isTarget, BoneUnit parentUnit, int level) { _bone = bone; if (_bone != null) { _name = " " + _bone._name; } else { _name = " None"; } _isSelectable = isSelectable; _isTarget = isTarget; _parentUnit = parentUnit; _level = level; _childUnits.Clear(); _isFoldable = false; _isFolded = false; //if (_bone != null) //{ // if (_bone._childBones.Count > 0) // { // _isFoldable = true; // _isFolded = false; // } // else // { // _isFoldable = false; // _isFolded = false; // } //} //else //{ // _isFoldable = false; // _isFolded = false; //} }
private void DrawBoneUnit(BoneUnit boneUnit, int level, int width, Texture2D imgIcon_FoldDown, Texture2D imgIcon_FoldRight, GUIContent guiContent_Bone, GUIStyle guiStyle_None, GUIStyle guiStyle_Selected, GUIStyle guiStyle_NotSelectable, float scrollX) { //Search 옵션에 따라 다르다. bool isRenderable = true; if (_isSearched) { if (boneUnit._bone != null) { if (boneUnit._name.Contains(_strSearchKeyword)) { isRenderable = true; } else { isRenderable = false; } } } if (isRenderable) { bool isNotSelectable = !boneUnit._isSelectable || boneUnit._isTarget; if (boneUnit == _selectedBoneUnit) { Rect lastRect = GUILayoutUtility.GetLastRect(); Color prevColor = GUI.backgroundColor; if (EditorGUIUtility.isProSkin) { GUI.backgroundColor = new Color(0.0f, 1.0f, 1.0f, 1.0f); } else { GUI.backgroundColor = new Color(0.4f, 0.8f, 1.0f, 1.0f); } //GUI.Box(new Rect(lastRect.x, lastRect.y + 20, width, 20), ""); GUI.Box(new Rect(lastRect.x + scrollX, lastRect.y + 20, width, 20), ""); GUI.backgroundColor = prevColor; } if (_isSearched) { if (boneUnit._parentUnit != null) { if (boneUnit._parentUnit._bone != null && !boneUnit._parentUnit._name.Contains(_strSearchKeyword)) { //Parent Unit이 검색에 포함되지 않는 경우 //realLevel -= boneUnit._parentUnit._parentUnit._level; level = 0; } } } EditorGUILayout.BeginHorizontal(GUILayout.Width((width - 50) + level * 10)); GUILayout.Space(15 + (level * 10)); //Fold 관련 if (boneUnit._isFoldable) { Texture2D foldIcon = imgIcon_FoldDown; if (boneUnit._isFolded) { foldIcon = imgIcon_FoldRight; } if (GUILayout.Button(foldIcon, guiStyle_None, GUILayout.Width(20), GUILayout.Height(20))) { boneUnit._isFolded = !boneUnit._isFolded; } } else { if (boneUnit._bone != null) { EditorGUILayout.LabelField(guiContent_Bone, guiStyle_None, GUILayout.Width(20), GUILayout.Height(20)); } else { EditorGUILayout.LabelField("", guiStyle_None, GUILayout.Width(20), GUILayout.Height(20)); } } GUIStyle guiStyleLabel = guiStyle_None; if (isNotSelectable) { guiStyleLabel = guiStyle_NotSelectable; } else if (boneUnit == _selectedBoneUnit) { guiStyleLabel = guiStyle_Selected; } if (GUILayout.Button(boneUnit._name, guiStyleLabel, GUILayout.Width((width - 35) - 22), GUILayout.Height(20))) { //if(boneUnit._isSelectable && !boneUnit._isTarget) if (!isNotSelectable) { _selectedBoneUnit = boneUnit; } } EditorGUILayout.EndHorizontal(); } if (!boneUnit._isFolded //|| _isSearched ) { for (int i = 0; i < boneUnit._childUnits.Count; i++) { DrawBoneUnit(boneUnit._childUnits[i], level + 1, width, imgIcon_FoldDown, imgIcon_FoldRight, guiContent_Bone, guiStyle_None, guiStyle_Selected, guiStyle_NotSelectable, scrollX); } } // EditorGUILayout.BeginHorizontal(GUILayout.Width(width - 50)); // GUILayout.Space(15); // if(GUILayout.Button(new GUIContent(" " + _selectableMeshGroups[i]._name, iconMeshGroup), guiStyle, GUILayout.Width(width - 35), GUILayout.Height(20))) // { // _selectedMeshGroup = _selectableMeshGroups[i]; // } // EditorGUILayout.EndHorizontal(); //} }
// Init //------------------------------------------------------------------------ public void Init(apEditor editor, object loadKey, apBone targetBone, apMeshGroup targetMeshGroup, REQUEST_TYPE requestType, FUNC_SELECT_LINKED_BONE funcResult) { _editor = editor; _loadKey = loadKey; _funcResult = funcResult; _targetBone = targetBone; _targetMeshGroup = targetMeshGroup; _requestType = requestType; _selectedBoneUnit = null; _boneUnits.Clear(); _boneUnits_Root.Clear(); List <apBone> exclusiveBones = new List <apBone>(); //None 유닛 선택 //Parent에서만 가능 //추가 : IKController에서도 가능 if (_requestType == REQUEST_TYPE.ChangeParent || _requestType == REQUEST_TYPE.SelectIKLookAtControllerEffector || _requestType == REQUEST_TYPE.SelectIKLookAtControllerStartBone || _requestType == REQUEST_TYPE.SelectIKPositionControllerEffector || _requestType == REQUEST_TYPE.Mirror) { BoneUnit nullUnit = new BoneUnit(null, true, false, null, 0); _boneUnits.Add(nullUnit); _boneUnits_Root.Add(nullUnit); } //기존 Rootqnxj 순회하는 방식으로 리스트를 만들되, //"제외"되는 것들을 음영처리하자 //별도의 Unit 필요 //모두 None Unit이 있다. switch (_requestType) { case REQUEST_TYPE.AttachChild: //Parent 중 하나를 Child로 둬선 안된다. (Loop 발생) case REQUEST_TYPE.ChangeParent: { //전체 Bone 중에서 //- 자기 자신 제외 //- Parent 제외 exclusiveBones.Add(_targetBone); if (_targetBone._parentBone != null) { exclusiveBones.Add(_targetBone._parentBone); if (_requestType == REQUEST_TYPE.AttachChild) { //재귀적인 Parent 제외 AddExclusiveBoneRecursive(exclusiveBones, _targetBone._parentBone, false); } } for (int iChild = 0; iChild < _targetBone._childBones.Count; iChild++) { apBone childBone = _targetBone._childBones[iChild]; if (childBone != null) { exclusiveBones.Add(childBone); } if (_requestType == REQUEST_TYPE.ChangeParent) { //재귀적인 Child 제외 AddExclusiveBoneRecursive(exclusiveBones, childBone, true); } } //BoneUnit을 넣자 for (int i = 0; i < _targetMeshGroup._boneList_Root.Count; i++) { AddBoneUnitRecursive(_targetMeshGroup._boneList_Root[i], exclusiveBones, _targetBone, null); } } break; case REQUEST_TYPE.SelectIKTarget: { //<재귀적인 Child 중에서> //-자기 자신 제외 exclusiveBones.Add(_targetBone); for (int iChild = 0; iChild < _targetBone._childBones.Count; iChild++) { apBone childBone = _targetBone._childBones[iChild]; if (childBone != null) { AddBoneUnitRecursive(childBone, exclusiveBones, _targetBone, null); } } } break; case REQUEST_TYPE.SelectIKLookAtControllerEffector: case REQUEST_TYPE.SelectIKPositionControllerEffector: { //IK Controller의 Effector를 결정할때 //-자기 자신 제외 //-자신의 IK Header가 있다면, IK Header의 모든 Child 제외 (무한 움직임을 보일 것이므로) //-자기 바로 위의 Parent 제외 //-자신의 모든 Child 제외 (chain 상관없이) exclusiveBones.Add(_targetBone); if (_targetBone._parentBone != null) { exclusiveBones.Add(_targetBone._parentBone); } if (_targetBone._IKHeaderBone != null) { //IKHeader로부터 모든 Chained은 삭제 exclusiveBones.Add(_targetBone._IKHeaderBone); List <apBone> chainedChildBonesFromIKHeader = _targetBone._IKHeaderBone.GetAllChildBones(); if (chainedChildBonesFromIKHeader != null) { for (int i = 0; i < chainedChildBonesFromIKHeader.Count; i++) { exclusiveBones.Add(chainedChildBonesFromIKHeader[i]); } } } List <apBone> childBones = _targetBone.GetAllChildBones(); if (childBones != null) { for (int i = 0; i < childBones.Count; i++) { if (!exclusiveBones.Contains(childBones[i])) { exclusiveBones.Add(childBones[i]); } } } //그외 모든 본을 추가한다. //BoneUnit을 넣자 for (int i = 0; i < _targetMeshGroup._boneList_Root.Count; i++) { AddBoneUnitRecursive(_targetMeshGroup._boneList_Root[i], exclusiveBones, _targetBone, null); } } break; case REQUEST_TYPE.SelectIKLookAtControllerStartBone: { //IK LookAt Controller의 EndBone을 결정할 때 //-자기 자신을 제외한 Chained의 모든 자식 본들만 선택가능 //List<apBone> childChainedBones = _targetBone.GetAllChainedChildBones(); //if(childChainedBones.Contains(_targetBone)) //{ // childChainedBones.Remove(_targetBone); //} //for (int iChild = 0; iChild < _targetBone._childBones.Count; iChild++) //{ // apBone childBone = _targetBone._childBones[iChild]; // if (childBone != null) // { // AddBoneUnitRecursive(childBone, exclusiveBones, childChainedBones, _targetBone, null); // } //} //수정 : StartBone을 결정한다. //-자기 자신을 제외한 Chained의 모든 부모 본들만 선택 가능 List <apBone> parentChainedBones = _targetBone.GetAllChainedParentBones(); if (parentChainedBones != null) { if (parentChainedBones.Contains(_targetBone)) { parentChainedBones.Remove(_targetBone); } //가장 첫 루트 본에서 BoneUnit을 만들자 apBone parentRootBone = parentChainedBones[parentChainedBones.Count - 1]; //<<리스트 마지막이 가장 Parent이다. if (parentRootBone != null) { AddBoneUnitRecursive(parentRootBone, exclusiveBones, parentChainedBones, _targetBone, null); } } //for (int iChild = 0; iChild < _targetBone._childBones.Count; iChild++) //{ // apBone childBone = _targetBone._childBones[iChild]; // if (childBone != null) // { // AddBoneUnitRecursive(childBone, exclusiveBones, childChainedBones, _targetBone, null); // } //} } break; case REQUEST_TYPE.Mirror: { //Mirror Bone 선택 //자신의 Parent 본들과 자식 본들은 선택 불가. 그 외에는 모두 가능 exclusiveBones.Add(_targetBone); AddExclusiveBoneRecursive(exclusiveBones, _targetBone, true); AddExclusiveBoneRecursive(exclusiveBones, _targetBone, false); //그외 모든 본을 추가한다. //BoneUnit을 넣자 for (int i = 0; i < _targetMeshGroup._boneList_Root.Count; i++) { AddBoneUnitRecursive(_targetMeshGroup._boneList_Root[i], exclusiveBones, _targetBone, null); } } break; } _isSearched = false; _strSearchKeyword = ""; _boneUnits_Root.Sort(delegate(BoneUnit a, BoneUnit b) { if (a._bone == null && b._bone == null) { return(0); } if (a._bone == null) { return(-1); } else if (b._bone == null) { return(1); } return(string.Compare(a._name, b._name)); }); }
// Init //------------------------------------------------------------------------ public void Init(apEditor editor, object loadKey, apBone targetBone, apMeshGroup targetMeshGroup, REQUEST_TYPE requestType, FUNC_SELECT_LINKED_BONE funcResult) { _editor = editor; _loadKey = loadKey; _funcResult = funcResult; _targetBone = targetBone; _targetMeshGroup = targetMeshGroup; _requestType = requestType; _selectedBoneUnit = null; _boneUnits.Clear(); _boneUnits_Root.Clear(); List <apBone> exclusiveBones = new List <apBone>(); //None 유닛 선택 //Parent에서만 가능 if (_requestType == REQUEST_TYPE.ChangeParent) { BoneUnit nullUnit = new BoneUnit(null, true, false, null, 0); _boneUnits.Add(nullUnit); _boneUnits_Root.Add(nullUnit); } //기존 Rootqnxj 순회하는 방식으로 리스트를 만들되, //"제외"되는 것들을 음영처리하자 //별도의 Unit 필요 //모두 None Unit이 있다. switch (_requestType) { case REQUEST_TYPE.AttachChild: //Parent 중 하나를 Child로 둬선 안된다. (Loop 발생) case REQUEST_TYPE.ChangeParent: { //전체 Bone 중에서 //- 자기 자신 제외 //- Parent 제외 exclusiveBones.Add(_targetBone); if (_targetBone._parentBone != null) { exclusiveBones.Add(_targetBone._parentBone); if (_requestType == REQUEST_TYPE.AttachChild) { //재귀적인 Parent 제외 AddExclusiveBoneRecursive(exclusiveBones, _targetBone._parentBone, false); } } for (int iChild = 0; iChild < _targetBone._childBones.Count; iChild++) { apBone childBone = _targetBone._childBones[iChild]; if (childBone != null) { exclusiveBones.Add(childBone); } if (_requestType == REQUEST_TYPE.ChangeParent) { //재귀적인 Child 제외 AddExclusiveBoneRecursive(exclusiveBones, childBone, true); } } //BoneUnit을 넣자 for (int i = 0; i < _targetMeshGroup._boneList_Root.Count; i++) { AddBoneUnitRecursive(_targetMeshGroup._boneList_Root[i], exclusiveBones, _targetBone, null); } } break; case REQUEST_TYPE.SelectIKTarget: { //<재귀적인 Child 중에서> //-자기 자신 제외 exclusiveBones.Add(_targetBone); for (int iChild = 0; iChild < _targetBone._childBones.Count; iChild++) { apBone childBone = _targetBone._childBones[iChild]; if (childBone != null) { AddBoneUnitRecursive(childBone, exclusiveBones, _targetBone, null); } } } break; } _isSearched = false; _strSearchKeyword = ""; _boneUnits_Root.Sort(delegate(BoneUnit a, BoneUnit b) { if (a._bone == null && b._bone == null) { return(0); } if (a._bone == null) { return(-1); } else if (b._bone == null) { return(1); } return(string.Compare(a._name, b._name)); }); }