Exemplo n.º 1
0
        // 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));
            });
        }
Exemplo n.º 2
0
        // Functions
        //---------------------------------------------------
        /// <summary>
        /// 선택된 Bone들이 유효한 것들인지 체크한다.
        /// RefreshSubChainedBones()함수를 포함한다.
        /// </summary>
        public void CheckValidation()
        {
            if (_effectorBone != null)
            {
                //Effector 본이 존재할 때
                //Effector 본은
                //- 자기 자신 제외
                //- 자신의 IK Header가 있다면, IK Header의 모든 Child 제외
                //- Parent 제외
                //- 자신의 모든 Child 제외 (Chain 상관없이)
                //위 조건을 만족해야한다.

                List <apBone> exBones = new List <apBone>();
                exBones.Add(_parentBone);

                if (_parentBone._IKHeaderBone != null)
                {
                    List <apBone> childBonesOfIKHeader = _parentBone._IKHeaderBone.GetAllChildBones();
                    if (childBonesOfIKHeader != null)
                    {
                        for (int i = 0; i < childBonesOfIKHeader.Count; i++)
                        {
                            exBones.Add(childBonesOfIKHeader[i]);
                        }
                    }
                }

                if (_parentBone._parentBone != null)
                {
                    exBones.Add(_parentBone._parentBone);
                }

                List <apBone> childBones = _parentBone.GetAllChildBones();
                if (childBones != null)
                {
                    for (int i = 0; i < childBones.Count; i++)
                    {
                        exBones.Add(childBones[i]);
                    }
                }

                if (exBones.Contains(_effectorBone))
                {
                    //선택될 수 없는 EffectBone이다.
                    Debug.LogError("유효하지 않은 Position Controller Effector Bone이다.");
                    _effectorBoneID = -1;
                    _effectorBone   = null;
                }
            }

            #region [미사용 코드]
            //if(_startBone != null)
            //{
            //	//EndBone이 존재할 때
            //	//EndBone 조건
            //	//-자기 자신을 제외한 Chained의 모든 자식 본들만 선택가능

            //	//EndBone -> Start Bone으로 변경
            //	//Start Bone이 Parent Bone 중에 하나여야 하며, Chain으로 연결된 상태여야 한다.
            //	//

            //	List<apBone> parentBones = _parentBone.GetAllChainedParentBones();
            //	if(parentBones == null)
            //	{
            //		_startBoneID = -1;
            //		_startBone = null;
            //	}
            //	else if(!parentBones.Contains(_startBone))
            //	{
            //		_startBoneID = -1;
            //		_startBone = null;
            //	}
            //	//TODO
            //	//List<apBone> childChainedBones = _parentBone.GetAllChainedChildBones();
            //	//if(childChainedBones == null)
            //	//{
            //	//	//리스트가 사라졌다.
            //	//	_endBoneID = -1;
            //	//	_endBone = null;
            //	//}
            //	//else if(!childChainedBones.Contains(_endBone))
            //	//{
            //	//	//선택될 수 없는 EndBone이다.
            //	//	Debug.LogError("유효하지 않은 Position Controller End Bone ID이다.");
            //	//	_endBoneID = -1;
            //	//	_endBone = null;
            //	//}
            //}

            //RefreshSubChainedBones();
            #endregion
        }