Beispiel #1
0
        public void Bake(apOptBone parentBone,
                         int effectorBoneID, apBoneIKController.CONTROLLER_TYPE controllerType,
                         float defaultMixWeight, bool isWeightByControlParam, int weightControlParamID)
        {
            _parentBone     = parentBone;
            _effectorBoneID = effectorBoneID;

            switch (controllerType)
            {
            case apBoneIKController.CONTROLLER_TYPE.None:
                _controllerType = CONTROLLER_TYPE.None;
                break;

            case apBoneIKController.CONTROLLER_TYPE.Position:
                _controllerType = CONTROLLER_TYPE.Position;
                break;

            case apBoneIKController.CONTROLLER_TYPE.LookAt:
                _controllerType = CONTROLLER_TYPE.LookAt;
                break;
            }
            _defaultMixWeight = defaultMixWeight;

            _effectorBone = null;

            _isWeightByControlParam = isWeightByControlParam;
            _weightControlParamID   = weightControlParamID;
            _weightControlParam     = null;
        }
Beispiel #2
0
        /// <summary>
        /// 재활용을 위해 OptNode를 리턴한다.
        /// 용도는 Bone 소켓
        /// </summary>
        /// <param name="parentOptBone"></param>
        /// <returns></returns>
        public apOptNode FindOptBoneSocket(apOptBone parentOptBone)
        {
            //_stopwatches[TIMER_TYPE.OptNode].Start();

            apBakeLinkParam resultLinkParam = null;

            resultLinkParam = _totalParams_OptNode.Find(delegate(apBakeLinkParam a)
            {
                if (!a._isRecycled && a._isOptGameObject && a._optNode != null && a._parentLinkParam != null)
                {
                    if (a._parentLinkParam._optBone != null &&
                        a._parentLinkParam._optBone == parentOptBone)
                    {
                        return(true);
                    }
                }
                return(false);
            });

            //_stopwatches[TIMER_TYPE.OptNode].Stop();
            //_timerCalls[TIMER_TYPE.OptNode] = _timerCalls[TIMER_TYPE.OptNode] + 1;


            if (resultLinkParam == null)
            {
                return(null);
            }

            resultLinkParam._isRecycled = true;            //<<Recycle 된걸로 전환
            return(resultLinkParam._optNode);
        }
                public bool Link(apPortrait portrait, apCache <apOptTransform> cache)
                {
                    _bone = null;

                    //Cache를 통해서 일단 MeshGroup에 해당하는 optTransform을 찾자
                    apOptTransform meshGroup = null;

                    if (cache.IsContain(_meshGroupID))
                    {
                        meshGroup = cache.Get(_meshGroupID);
                    }
                    else
                    {
                        meshGroup = portrait.GetOptTransformAsMeshGroup(_meshGroupID);
                        if (meshGroup == null)
                        {
                            Debug.LogError("VertRig Bake 실패 : MeshGroup을 찾을 수 없다. [" + _meshGroupID + "]");
                            return(false);
                        }

                        //캐시에 담고
                        cache.Add(_meshGroupID, meshGroup);
                    }

                    //본을 찾자
                    _bone = meshGroup.GetBone(_boneID);
                    if (_bone == null)
                    {
                        Debug.LogError("VertRig Bake 실패 : Bone을 찾을 수 없다. [" + _boneID + "]");
                        return(false);
                    }

                    return(true);
                }
Beispiel #4
0
        public apOptBone GetBoneRecursive(int uniqueID)
        {
            if (_boneList_All != null)
            {
                for (int i = 0; i < _boneList_All.Length; i++)
                {
                    if (_boneList_All[i]._uniqueID == uniqueID)
                    {
                        return(_boneList_All[i]);
                    }
                }
            }


            apOptBone result = null;

            if (_childTransforms == null)
            {
                //Debug.LogError("Child가 없다. [Opt Transform : " + _name + "]");
                return(null);
            }
            for (int i = 0; i < _childTransforms.Length; i++)
            {
                result = _childTransforms[i].GetBoneRecursive(uniqueID);
                if (result != null)
                {
                    return(result);
                }
            }

            return(null);
        }
Beispiel #5
0
        // Functions
        //---------------------------------------------------------------



        // Get / Set
        //---------------------------------------------------------------
        /// <summary>
        /// boneID를 가지는 Bone을 자식 노드로 두고 있는가.
        /// 재귀적으로 찾는다.
        /// </summary>
        /// <param name="boneID"></param>
        /// <returns></returns>
        public apOptBone GetChildBoneRecursive(int boneID)
        {
            if (_childBones == null)
            {
                return(null);
            }
            //바로 아래의 자식 노드를 검색
            for (int i = 0; i < _childBones.Length; i++)
            {
                if (_childBones[i]._uniqueID == boneID)
                {
                    return(_childBones[i]);
                }
            }

            //못찾았다면..
            //재귀적으로 검색해보자

            for (int i = 0; i < _childBones.Length; i++)
            {
                apOptBone result = _childBones[i].GetChildBoneRecursive(boneID);
                if (result != null)
                {
                    return(result);
                }
            }

            return(null);
        }
Beispiel #6
0
        /// <summary>
        /// 자식 Bone 중에서 특정 Target Bone을 재귀적인 자식으로 가지는 시작 Bone을 찾는다.
        /// </summary>
        /// <param name="targetBoneID"></param>
        /// <returns></returns>
        public apOptBone FindNextChainedBone(int targetBoneID)
        {
            //바로 아래의 자식 노드를 검색
            if (_childBones == null)
            {
                return(null);
            }
            for (int i = 0; i < _childBones.Length; i++)
            {
                if (_childBones[i]._uniqueID == targetBoneID)
                {
                    return(_childBones[i]);
                }
            }

            //못찾았다면..
            //재귀적으로 검색해서, 그 중에 실제로 Target Bone을 포함하는 Child Bone을 리턴하자

            for (int i = 0; i < _childBones.Length; i++)
            {
                apOptBone result = _childBones[i].GetChildBoneRecursive(targetBoneID);
                if (result != null)
                {
                    //return result;
                    return(_childBones[i]);                   //<<Result가 아니라, ChildBone을 리턴
                }
            }
            return(null);
        }
Beispiel #7
0
        public bool Bake(apModifiedBone srcModBone, apPortrait portrait)
        {
            _portrait         = portrait;
            _meshGroupID_Bone = srcModBone._meshGropuUniqueID_Bone;
            apOptTransform meshGroupTransform = portrait.GetOptTransformAsMeshGroup(_meshGroupID_Bone);

            if (meshGroupTransform == null)
            {
                Debug.LogError("[ModBone] Bake 실패 : 찾을 수 없는 OptTransform [" + _meshGroupID_Bone + "]");
                return(false);
            }

            _transformUniqueID = meshGroupTransform._transformID;
            _meshGroup_Bone    = meshGroupTransform;

            _boneID = srcModBone._boneID;

            _bone = meshGroupTransform.GetBone(_boneID);
            if (_bone == null)
            {
                Debug.LogError("[ModBone] Bake 실패 : 찾을 수 없는 Bone [" + _boneID + "]");
                return(false);
            }
            _transformMatrix = new apMatrix(srcModBone._transformMatrix);
            return(true);
        }
Beispiel #8
0
        // Functions
        //-------------------------------------------------
        public apOptBoneIKChainUnit(apOptBone baseBone, apOptBone targetBone, apOptBone parentBone)
        {
            _baseBone   = baseBone;
            _targetBone = targetBone;
            _parentBone = parentBone;

            _parentChainUnit = null;
            _childChainUnit  = null;

            _isPreferredAngleAdapted = false;
        }
Beispiel #9
0
        //Link 함수의 내용은 Bake 시에 진행해야한다.
        public void Bake(apBone bone)
        {
            _uniqueID    = bone._uniqueID;
            _meshGroupID = bone._meshGroupID;
            _defaultMatrix.SetMatrix(bone._defaultMatrix);


            _deltaPos   = Vector2.zero;
            _deltaAngle = 0.0f;
            _deltaScale = Vector2.one;

            _localMatrix.SetIdentity();

            _worldMatrix.SetIdentity();

            _color       = bone._color;
            _shapeWidth  = bone._shapeWidth;
            _shapeLength = bone._shapeLength;
            _shapeTaper  = bone._shapeTaper;

            _optionLocalMove = bone._optionLocalMove;
            _optionIK        = bone._optionIK;

            _isIKTail = bone._isIKTail;

            _IKTargetBoneID = bone._IKTargetBoneID;
            _IKTargetBone   = null;          //<<나중에 링크

            _IKNextChainedBoneID = bone._IKNextChainedBoneID;
            _IKNextChainedBone   = null;          //<<나중에 링크


            _IKHeaderBoneID = bone._IKHeaderBoneID;
            _IKHeaderBone   = null;          //<<나중에 링크


            _isIKAngleRange     = bone._isIKAngleRange;
            _IKAngleRange_Lower = bone._IKAngleRange_Lower;
            _IKAngleRange_Upper = bone._IKAngleRange_Upper;
            _IKAnglePreferred   = bone._IKAnglePreferred;


            _isIKCalculated       = false;
            _IKRequestAngleResult = 0.0f;



            _transformLocalMatrix.SetIdentity();
        }
Beispiel #10
0
            public bool Link(apPortrait portrait)
            {
                _meshGroup = portrait.GetOptTransformAsMeshGroup(_meshGroupID);
                if (_meshGroup == null)
                {
                    Debug.LogError("VertRig Bake 실패 : MeshGroup을 찾을 수 없다. [" + _meshGroupID + "]");
                    return(false);
                }

                _bone = _meshGroup.GetBone(_boneID);
                if (_bone == null)
                {
                    Debug.LogError("VertRig Bake 실패 : Bone을 찾을 수 없다. [" + _boneID + "]");
                    return(false);
                }

                return(true);
            }
Beispiel #11
0
        // Init
        //--------------------------------------------
        public apOptCalculatedResultParam(apCalculatedResultParam.CALCULATED_VALUE_TYPE calculatedValueType,
                                          apCalculatedResultParam.CALCULATED_SPACE calculatedSpace,
                                          apOptModifierUnitBase linkedModifier,
                                          apOptTransform targetOptTranform,
                                          apOptMesh targetOptMesh,
                                          apOptBone targetBone,                                              //<<추가
                                          apOptParamSetGroupVertWeight weightedVertData)
        {
            _calculatedValueType = calculatedValueType;
            _calculatedSpace     = calculatedSpace;

            //TODO 여기서부터 작업하자
            _linkedModifier     = linkedModifier;
            _targetOptTransform = targetOptTranform;
            _targetOptMesh      = targetOptMesh;
            _targetBone         = targetBone;    //<<추가



            _weightedVertexData = weightedVertData;

            //Vertex 데이터가 들어간 경우 Vert 리스트를 만들어주자
            if ((int)(_calculatedValueType & apCalculatedResultParam.CALCULATED_VALUE_TYPE.VertexPos) != 0)
            {
                int nPos = 0;
                if (_targetOptMesh.LocalVertPositions != null)
                {
                    nPos = _targetOptMesh.LocalVertPositions.Length;
                }

                _result_Positions = new List <Vector2>();
                _tmp_Positions    = new List <Vector2>();
                for (int i = 0; i < nPos; i++)
                {
                    _result_Positions.Add(Vector2.zero);
                    _tmp_Positions.Add(Vector2.zero);
                }
            }
        }
Beispiel #12
0
        public void LinkEffector(apOptBone effectorBone)
        {
            //if(_controllerType != CONTROLLER_TYPE.None)
            //{
            //	Debug.Log("Link Effector : " + _parentBone.name + " : " + (effectorBone != null ? effectorBone.name : " <None>"));
            //}

            _effectorBone = effectorBone;

            if (_effectorBone == null)
            {
                _effectorBoneID = -1;
            }
            else
            {
                _effectorBoneID = _effectorBone._uniqueID;
            }
            if (_effectorBone == null)
            {
                //Effector Bone이 없으면 처리 무효
                _controllerType = CONTROLLER_TYPE.None;
            }
        }
        // Get / Set
        //------------------------------------------------
        public apOptBone GetBone(string name)
        {
            //일단 빠른 검색부터
            if (_optBonesMap.ContainsKey(name))
            {
                return(_optBonesMap[name]);
            }

            apOptBone resultBone = _optBones.Find(delegate(apOptBone a)
            {
                return(string.Equals(a._name, name));
            });

            if (resultBone == null)
            {
                return(null);
            }

            //빠른 검색 리스트에 넣고
            _optBonesMap.Add(name, resultBone);

            return(resultBone);
        }
Beispiel #14
0
        public void Link(apOptTransform targetOptTransform)
        {
            _parentOptTransform = targetOptTransform;
            if (_parentOptTransform == null)
            {
                //??
                Debug.LogError("[" + transform.name + "] OptBone의 ParentOptTransform이 Null이다. [" + _meshGroupID + "]");
                _IKTargetBone      = null;
                _IKNextChainedBone = null;
                _IKHeaderBone      = null;

                //LinkBoneChaining();


                return;
            }


            _IKTargetBone      = _parentOptTransform.GetBone(_IKTargetBoneID);
            _IKNextChainedBone = _parentOptTransform.GetBone(_IKNextChainedBoneID);
            _IKHeaderBone      = _parentOptTransform.GetBone(_IKHeaderBoneID);

            //LinkBoneChaining();
        }
Beispiel #15
0
        public apOptBone GetBoneRecursive(int uniqueID)
        {
            for (int i = 0; i < _boneList_All.Length; i++)
            {
                if (_boneList_All[i]._uniqueID == uniqueID)
                {
                    return(_boneList_All[i]);
                }
            }


            apOptBone result = null;

            for (int i = 0; i < _childTransforms.Length; i++)
            {
                result = _childTransforms[i].GetBoneRecursive(uniqueID);
                if (result != null)
                {
                    return(result);
                }
            }

            return(null);
        }
 // Init
 //------------------------------------------------------------
 public apOptBoneIKChainSet(apOptBone bone)
 {
     _bone  = bone;
     _nLoop = 0;
 }
Beispiel #17
0
        //여기서는 LinkBoneChaining만 진행
        /// <summary>
        /// Bone Chaining 직후에 재귀적으로 호출한다.
        /// Tail이 가지는 -> Head로의 IK 리스트를 만든다.
        ///
        /// </summary>
        public void LinkBoneChaining()
        {
            if (_localMatrix == null)
            {
                _localMatrix = new apMatrix();
            }
            if (_worldMatrix == null)
            {
                _worldMatrix = new apMatrix();
            }
            if (_worldMatrix_NonModified == null)
            {
                _worldMatrix_NonModified = new apMatrix();
            }


            if (_isIKTail)
            {
                apOptBone curParentBone = _parentBone;
                apOptBone headBone      = _IKHeaderBone;

                bool isParentExist       = (curParentBone != null);
                bool isHeaderExist       = (headBone != null);
                bool isHeaderIsInParents = false;
                if (isParentExist && isHeaderExist)
                {
                    isHeaderIsInParents = (GetParentRecursive(headBone._uniqueID) != null);
                }


                if (isParentExist && isHeaderExist && isHeaderIsInParents)
                {
                    if (_IKChainSet == null)
                    {
                        _IKChainSet = new apOptBoneIKChainSet(this);
                    }
                    //Chain을 Refresh한다.
                    _IKChainSet.RefreshChain();
                }
                else
                {
                    _IKChainSet = null;

                    Debug.LogError("[" + transform.name + "] IK Chaining Error : Parent -> Chain List 연결시 데이터가 누락되었다. "
                                   + "[ Parent : " + isParentExist
                                   + " / Header : " + isHeaderExist
                                   + " / IsHeader Is In Parent : " + isHeaderIsInParents + " ]");
                }
            }
            else
            {
                _IKChainSet = null;
            }

            if (_childBones != null)
            {
                for (int i = 0; i < _childBones.Length; i++)
                {
                    _childBones[i].LinkBoneChaining();
                }
            }
        }
 public void AddChildBone(apOptBone bone)
 {
     _optBones.Add(bone);
 }
 public OptBoneAndModParamPair(apOptBone bone)
 {
     _keyBone = bone;
 }
 public RigBoneWeightPair(apOptTransform optTransform, apOptBone bone, float weight)
 {
     _optTransform = optTransform;
     _bone         = bone;
     _weight       = weight;
 }
        //Link 함수의 내용은 Bake 시에 진행해야한다.
        /// <summary>
        /// [Please do not use it]
        /// </summary>
        /// <param name="bone"></param>
        public void Bake(apBone bone)
        {
            _name        = bone._name;
            _uniqueID    = bone._uniqueID;
            _meshGroupID = bone._meshGroupID;
            _defaultMatrix.SetMatrix(bone._defaultMatrix);


            _deltaPos   = Vector2.zero;
            _deltaAngle = 0.0f;
            _deltaScale = Vector2.one;

            _localMatrix.SetIdentity();

            _worldMatrix.SetIdentity();

            _worldMatrix_NonModified.SetIdentity();
            _vertWorld2BoneModWorldMatrix.SetIdentity();

            _color       = bone._color;
            _shapeWidth  = bone._shapeWidth;
            _shapeLength = bone._shapeLength;
            _shapeTaper  = bone._shapeTaper;

            _optionLocalMove = bone._optionLocalMove;
            _optionIK        = bone._optionIK;

            _isIKTail = bone._isIKTail;

            _IKTargetBoneID = bone._IKTargetBoneID;
            _IKTargetBone   = null;          //<<나중에 링크

            _IKNextChainedBoneID = bone._IKNextChainedBoneID;
            _IKNextChainedBone   = null;          //<<나중에 링크


            _IKHeaderBoneID = bone._IKHeaderBoneID;
            _IKHeaderBone   = null;          //<<나중에 링크


            _isIKAngleRange = bone._isIKAngleRange;
            //이게 기존 코드
            //_IKAngleRange_Lower = bone._IKAngleRange_Lower;
            //_IKAngleRange_Upper = bone._IKAngleRange_Upper;
            //_IKAnglePreferred = bone._IKAnglePreferred;

            //이게 변경된 IK 코드
            _IKAngleRange_Lower = bone._defaultMatrix._angleDeg + bone._IKAngleRange_Lower;
            _IKAngleRange_Upper = bone._defaultMatrix._angleDeg + bone._IKAngleRange_Upper;
            _IKAnglePreferred   = bone._defaultMatrix._angleDeg + bone._IKAnglePreferred;


            _isIKCalculated       = false;
            _IKRequestAngleResult = 0.0f;
            _IKRequestWeight      = 0.0f;

            _socketTransform = null;

            _transformLocalMatrix.SetIdentity();

            _childBones = null;

            _isIKChainInit = false;
        }
        public void LinkOpt(apAnimClip animClip, apAnimTimeline timeline)
        {
            _parentAnimClip = animClip;
            _parentTimeline = timeline;

            _linkType = _parentTimeline._linkType;

            if (_parentAnimClip == null)
            {
                Debug.Log("Parent Anim Clip이 Null이다.");
            }
            else if (_parentAnimClip._targetOptTranform == null)
            {
                Debug.LogError("Parent Anim Clip TargetOptTranform이 Null이다.");
            }

            switch (_linkType)
            {
            case apAnimClip.LINK_TYPE.AnimatedModifier:
            {
                switch (_linkModType)
                {
                case LINK_MOD_TYPE.MeshTransform:
                    //수정 : 재귀적으로 링크를 수행한다.
                    _linkedOptTransform = _parentAnimClip._targetOptTranform.GetMeshTransformRecursive(_transformID);
                    if (_linkedOptTransform == null)
                    {
                        Debug.LogError("Opt TimelineLayer MeshTransform 연결 실패 : " + _transformID);
                        _transformID = -1;
                    }
                    break;

                case LINK_MOD_TYPE.MeshGroupTransform:
                    //수정 : 재귀적으로 링크를 수행한다.
                    _linkedOptTransform = _parentAnimClip._targetOptTranform.GetMeshGroupTransformRecursive(_transformID);
                    if (_linkedOptTransform == null)
                    {
                        Debug.LogError("Opt TimelineLayer MeshGroupTransform 연결 실패 : " + _transformID);
                        _transformID = -1;
                    }
                    break;

                case LINK_MOD_TYPE.Bone:
                    //TODO : Bone 타입 연결을 해야한다.
                    _linkedOptBone = _parentAnimClip._targetOptTranform.GetBoneRecursive(_boneID);
                    break;

                case LINK_MOD_TYPE.None:
                    _linkedOptTransform = null;
                    _transformID        = -1;
                    _boneID             = -1;
                    break;
                }
            }
            break;

            case apAnimClip.LINK_TYPE.ControlParam:
            {
                _linkedControlParam = _parentAnimClip._portrait.GetControlParam(_controlParamID);
                if (_linkedControlParam == null)
                {
                    _controlParamID = -1;
                }
            }
            break;

                //case apAnimClip.LINK_TYPE.Bone:
                //	{
                //		Debug.LogError("TODO : TimelineLayer의 Bone 타입 연동하기");
                //	}
                //	break;
            }


            for (int i = 0; i < _keyframes.Count; i++)
            {
                _keyframes[i].Link(this);
            }

            SortAndRefreshKeyframes();
        }
        // Functions
        //------------------------------------------------------------
        /// <summary>
        /// Bone Hierarchy에 맞추어서 다시 Chain을 만든다.
        /// </summary>
        public void RefreshChain()
        {
            _chainUnits.Clear();
            _headChainUnit = null;
            _tailChainUnit = null;

            if (!_bone._isIKTail)
            {
                return;
            }


            //Bone으로부터 Head가 나올때까지 Chain을 추가하자
            //[Parent] .... [Cur Bone] ----> [Target Bone < 이것 부터 시작]
            apOptBone parentBone = null;
            apOptBone curBone    = null;
            apOptBone targetBone = _bone;

            string strBoneNames = "";

            //int curLevel = 0;
            while (true)
            {
                curBone = targetBone._parentBone;
                if (curBone == null)
                {
                    //? 왜 여기서 끊기지..
                    break;
                }

                parentBone = curBone._parentBone;                //<<이건 Null 일 수 있다.

                //apBoneIKChainUnit newUnit = new apBoneIKChainUnit(curBone, targetBone, parentBone, curLevel);
                apOptBoneIKChainUnit newUnit = new apOptBoneIKChainUnit(curBone, targetBone, parentBone);

                _chainUnits.Add(newUnit);

                strBoneNames += curBone.transform.name + ", ";

                //끝났당
                if (curBone == _bone._IKHeaderBone)
                {
                    break;
                }

                //하나씩 위로 탐색하자
                targetBone = curBone;
                //curLevel++;
            }
            if (_chainUnits.Count == 0)
            {
                return;
            }
            ////전체 Unit 개수를 넣어주자
            //for (int i = 0; i < _chainUnits.Count; i++)
            //{
            //	_chainUnits[i].SetTotalChainLevel(_chainUnits.Count);
            //}

            //Debug.Log("Refresh Chain : [" + _bone._name + "] " + strBoneNames);

            //앞쪽이 Tail이다.
            _tailChainUnit = _chainUnits[0];
            _headChainUnit = _chainUnits[_chainUnits.Count - 1];

            //Chain Unit간의 연결을 한다.
            apOptBoneIKChainUnit curUnit = null;

            for (int i = 0; i < _chainUnits.Count; i++)
            {
                curUnit = _chainUnits[i];

                if (i > 0)
                {
                    curUnit.SetChild(_chainUnits[i - 1]);
                }

                if (i < _chainUnits.Count - 1)
                {
                    curUnit.SetParent(_chainUnits[i + 1]);
                }

                curUnit.SetTail(_tailChainUnit);
            }

            if (_chainUnits.Count == 0)
            {
                _nLoop = 0;
            }
            else
            {
                // 얼마나 연산을 반복할 것인지 결정 (연산 횟수는 루프 단위로 결정한다)
                _nLoop = MAX_CALCULATE_LOOP_EDITOR;
                if (_chainUnits.Count * _nLoop > MAX_TOTAL_UNIT_CALCULATE)
                {
                    //전체 계산 횟수 (Unit * Loop)가 제한을 넘겼을 때
                    _nLoop = MAX_TOTAL_UNIT_CALCULATE / _chainUnits.Count;
                    if (_nLoop < 2)
                    {
                        _nLoop = 2;
                    }
                }
            }

            _isContinuousPrevPos = false;
        }
Beispiel #24
0
        public void Parse(GameObject targetGameObject, apBakeLinkParam parentLinkParam)
        {
            _prevGameObject     = targetGameObject;
            _isRecycled         = false;
            _isReGroupCompleted = false;

            //Parent-Child를 서로 연결하자
            _parentLinkParam = parentLinkParam;
            if (parentLinkParam != null)
            {
                if (_parentLinkParam._childLinkParams == null)
                {
                    _parentLinkParam._childLinkParams = new List <apBakeLinkParam>();
                }
                _parentLinkParam._childLinkParams.Add(this);
            }


            //Component를 보고 이 객체의 성격을 정의하자
            _isOptGameObject = false;

            _optRoot      = null;
            _optNode      = null;
            _optBone      = null;
            _optTransform = null;
            _optMesh      = null;

            _meshRenderer = null;
            _meshFilter   = null;

            _isOtherComponentExist = false;


            MeshRenderer compMeshRenderer = null;
            MeshFilter   compMeshFilter   = null;

            Component[] components = _prevGameObject.GetComponents(typeof(Component));
            if (components != null)
            {
                Component curComp = null;
                for (int i = 0; i < components.Length; i++)
                {
                    curComp = components[i];
                    if (curComp is Transform)
                    {
                        //? 이건 필수로 들어가는 겁니더..
                        continue;
                    }


                    if (curComp is apOptRootUnit)
                    {
                        _optRoot = curComp as apOptRootUnit;
                    }
                    else if (curComp is apOptTransform)
                    {
                        _optTransform = curComp as apOptTransform;
                    }
                    else if (curComp is apOptNode)
                    {
                        _optNode = curComp as apOptNode;
                    }
                    else if (curComp is apOptBone)
                    {
                        _optBone = curComp as apOptBone;
                    }
                    else if (curComp is apOptMesh)
                    {
                        _optMesh = curComp as apOptMesh;
                    }
                    else if (curComp is MeshRenderer)
                    {
                        compMeshRenderer = curComp as MeshRenderer;
                    }
                    else if (curComp is MeshFilter)
                    {
                        compMeshFilter = curComp as MeshFilter;
                    }
                    else
                    {
                        //알 수 없는 컴포넌트가 있다.
                        _isOtherComponentExist = true;
                    }
                }
            }

            if (_optRoot != null ||
                _optNode != null ||
                _optBone != null ||
                _optTransform != null ||
                _optMesh != null)
            {
                // Opt 계열의 컴포넌트가 있다면
                _isOptGameObject = true;
            }

            //만약 MeshRenderer/MeshFilter가 있을때
            //_optMesh가 있다면 포함가능,
            //그 외에는 "알 수 없는 컴포넌트"로 지정한다.
            if (compMeshRenderer != null)
            {
                if (_optMesh != null)
                {
                    _meshRenderer = compMeshRenderer;
                }
                else
                {
                    _isOtherComponentExist = true;
                }
            }

            if (compMeshFilter != null)
            {
                if (_optMesh != null)
                {
                    _meshFilter = compMeshFilter;
                }
                else
                {
                    _isOtherComponentExist = true;
                }
            }
        }
        /// <summary>
        /// Calculate Result Statck의 업데이트 부분
        /// Pre-Update로서 VertWorld와 Rigging이 제외된다.
        /// </summary>
        public void Calculate_Pre()
        {
            //bool isFirstDebug = true;
            _cal_prevWeight  = 0.0f;
            _cal_curWeight   = 0.0f;
            _cal_resultParam = null;
            _cal_posVerts    = null;


            //Debug.Log("Is Any Vert Local : " + _isAnyVertLocal + " [" + _resultParams_VertLocal.Count +"]");
            // 1. Local Morph
            if (_isAnyVertLocal)
            {
//#if UNITY_EDITOR
//				Profiler.BeginSample("Calcuate Result Stack - 1. Vert Local");
//#endif
                _cal_prevWeight      = 0.0f;
                _cal_curWeight       = 0.0f;
                _cal_resultParam     = null;
                _cal_posVerts        = null;
                _cal_vertRequestList = null;
                _cal_vertRequest     = null;

                _iCalculatedParam = 0;                //<<추가 : 첫 모디파이어는 무조건 Interpolation으로 만들자


                #region [미사용 코드 : 최적화 전]
                //이전 코드
                //for (int iParam = 0; iParam < _resultParams_VertLocal.Count; iParam++)
                //{
                //	_cal_resultParam = _resultParams_VertLocal[iParam];
                //	_cal_curWeight = _cal_resultParam.ModifierWeight;

                //	if (!_cal_resultParam.IsModifierAvailable || _cal_curWeight <= 0.001f)
                //	{ continue; }


                //	_cal_posVerts = _cal_resultParam._result_Positions;
                //	if (_result_VertLocal == null)
                //	{
                //		Debug.LogError("Result Vert Local is Null");
                //	}
                //	if (_cal_posVerts == null)
                //	{
                //		Debug.LogError("Cal Pos Vert is Null");
                //	}
                //	if (_cal_posVerts.Length != _result_VertLocal.Length)
                //	{
                //		//결과가 잘못 들어왔다 갱신 필요
                //		Debug.LogError("Wrong Vert Local Result (Cal : " + _cal_posVerts.Length + " / Verts : " + _result_VertLocal.Length + ")");
                //		continue;
                //	}

                //	// Blend 방식에 맞게 Pos를 만들자
                //	if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0)
                //	{
                //		for (int i = 0; i < _cal_posVerts.Length; i++)
                //		{
                //			_result_VertLocal[i] = BlendPosition_ITP(_result_VertLocal[i], _cal_posVerts[i], _cal_curWeight);
                //		}

                //		_cal_prevWeight += _cal_curWeight;
                //	}
                //	else
                //	{
                //		for (int i = 0; i < _cal_posVerts.Length; i++)
                //		{
                //			_result_VertLocal[i] = BlendPosition_Add(_result_VertLocal[i], _cal_posVerts[i], _cal_curWeight);
                //		}
                //	}
                //	_iCalculatedParam++;
                //}
                #endregion

                //최적화된 코드.
                //Vertex Pos를 건드리지 않고 보간식을 중첩한다.
                for (int iParam = 0; iParam < _resultParams_VertLocal.Count; iParam++)
                {
                    _cal_resultParam = _resultParams_VertLocal[iParam];
                    _cal_resultParam._resultWeight = 0.0f;
                    _cal_curWeight = _cal_resultParam.ModifierWeight;

                    if (!_cal_resultParam.IsModifierAvailable || _cal_curWeight <= 0.001f)
                    {
                        continue;
                    }

                    _cal_resultParam._resultWeight = 1.0f;                    //<<일단 Weight를 1로 두고 계산 시작


                    // Blend 방식에 맞게 Pos를 만들자
                    if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0)
                    {
                        //Interpolation : Prev * (1-weight) + Next * weight
                        _cal_resultParam._resultWeight = _cal_curWeight;
                        for (int iPrev = 0; iPrev < iParam - 1; iPrev++)
                        {
                            _resultParams_VertLocal[iPrev]._resultWeight *= (1.0f - _cal_curWeight);
                        }
                    }
                    else
                    {
                        //Additive : Prev + Next * weight
                        _cal_resultParam._resultWeight = _cal_curWeight;
                    }
                    _iCalculatedParam++;
                }

                //이제 계산된 Weight를 모두 입력해주자
                for (int iParam = 0; iParam < _resultParams_VertLocal.Count; iParam++)
                {
                    _cal_resultParam     = _resultParams_VertLocal[iParam];
                    _cal_vertRequestList = _cal_resultParam._result_VertLocalPairs;
                    for (int iVR = 0; iVR < _cal_vertRequestList.Count; iVR++)
                    {
                        _cal_vertRequestList[iVR].MultiplyWeight(_cal_resultParam._resultWeight);
                    }
                }

//#if UNITY_EDITOR
//				Profiler.EndSample();
//#endif
            }

            // 2. Mesh / MeshGroup Transformation
            if (_isAnyTransformation)
            {
//#if UNITY_EDITOR
//				Profiler.BeginSample("Calcuate Result Stack - 2. MeshGroup Transformation");
//#endif
                _cal_prevWeight  = 0.0f;
                _cal_curWeight   = 0.0f;
                _cal_resultParam = null;

                _iCalculatedParam = 0;

                //Debug.Log("Update TF - OPT");
                for (int iParam = 0; iParam < _resultParams_Transform.Count; iParam++)
                {
                    _cal_resultParam = _resultParams_Transform[iParam];
                    _cal_curWeight   = _cal_resultParam.ModifierWeight;

                    if (!_cal_resultParam.IsModifierAvailable || _cal_curWeight <= 0.001f)
                    {
                        continue;
                    }



                    // Blend 방식에 맞게 Matrix를 만들자 하자
                    if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0)
                    {
                        //Debug.Log("Cal TF [ITP] : " + _cal_resultParam._result_Matrix.Pos3 + " (Weight : " + _cal_curWeight + ")");

                        BlendMatrix_ITP(_result_MeshTransform, _cal_resultParam._result_Matrix, _cal_curWeight);

                        //if (_cal_resultParam._result_Matrix.Scale2.magnitude < 0.5f || _cal_curWeight < 0.5f)
                        //{
                        //	Debug.Log("Cal TF [ITP] : " + _cal_resultParam._result_Matrix.Scale2 + " > " + _result_MeshTransform.Scale2 + " (Weight : " + _cal_curWeight + ")");
                        //}

                        _cal_prevWeight += _cal_curWeight;
                    }
                    else
                    {
                        BlendMatrix_Add(_result_MeshTransform, _cal_resultParam._result_Matrix, _cal_curWeight);
                    }

                    _iCalculatedParam++;
                }

                _result_MeshTransform.MakeMatrix();

                if (_result_MeshTransform._scale.magnitude < 0.5f)
                {
                    Debug.Log("Cal TF [ITP] : " + _result_MeshTransform._scale + " (Total Weight : " + _cal_prevWeight + ")");
                }

//#if UNITY_EDITOR
//				Profiler.EndSample();
//#endif
            }

            // 3. Mesh Color
            if (_isAnyMeshColor)
            {
//#if UNITY_EDITOR
//				Profiler.BeginSample("Calcuate Result Stack - 3. Mesh Color");
//#endif
                _cal_prevWeight  = 0.0f;
                _cal_curWeight   = 0.0f;
                _cal_resultParam = null;

                _iCalculatedParam = 0;

                _result_IsVisible       = false;
                _nMeshColorCalculated   = 0;
                _result_CalculatedColor = false;

                for (int iParam = 0; iParam < _resultParams_MeshColor.Count; iParam++)
                {
                    _cal_resultParam = _resultParams_MeshColor[iParam];
                    _cal_curWeight   = Mathf.Clamp01(_cal_resultParam.ModifierWeight);

                    if (!_cal_resultParam.IsModifierAvailable ||
                        _cal_curWeight <= 0.001f ||
                        !_cal_resultParam.IsColorValueEnabled ||
                        !_cal_resultParam._isColorCalculated                           //<<추가 : Color로 등록했지만 아예 계산이 안되었을 수도 있다.
                        )
                    {
                        continue;
                    }                    //<<TODO


                    // Blend 방식에 맞게 Matrix를 만들자 하자
                    if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0)
                    {
                        //_result_Color = BlendColor_ITP(_result_Color, _cal_resultParam._result_Color, _cal_prevWeight, _cal_curWeight);
                        _result_Color    = apUtil.BlendColor_ITP(_result_Color, _cal_resultParam._result_Color, _cal_curWeight);
                        _cal_prevWeight += _cal_curWeight;
                    }
                    else
                    {
                        _result_Color = apUtil.BlendColor_Add(_result_Color, _cal_resultParam._result_Color, _cal_curWeight);
                    }

                    _result_IsVisible |= _cal_resultParam._result_IsVisible;
                    _nMeshColorCalculated++;

                    _result_CalculatedColor = true;                    //<<"계산된 MeshColor" Result가 있음을 알린다.

                    _iCalculatedParam++;
                }

                if (_nMeshColorCalculated == 0)
                {
                    _result_IsVisible = true;
                }


//#if UNITY_EDITOR
//				Profiler.EndSample();
//#endif
            }
            else
            {
                _result_IsVisible = true;
            }

            //AnyBoneTransform
            if (_isAnyBoneTransform)
            {
//#if UNITY_EDITOR
//				Profiler.BeginSample("Calcuate Result Stack - 5. Bone Transform");
//#endif
                _cal_prevWeight  = 0.0f;
                _cal_curWeight   = 0.0f;
                _cal_resultParam = null;


                OptBoneAndModParamPair boneModPair = null;
                apOptBone targetBone = null;
                List <OptModifierAndResultParamListPair> modParamPairs = null;


                for (int iBonePair = 0; iBonePair < _resultParams_BoneTransform.Count; iBonePair++)
                {
                    boneModPair   = _resultParams_BoneTransform[iBonePair];
                    targetBone    = boneModPair._keyBone;
                    modParamPairs = boneModPair._modParamPairs;

                    if (targetBone == null || modParamPairs.Count == 0)
                    {
                        continue;
                    }


                    _iCalculatedParam = 0;
                    _result_BoneTransform.SetIdentity();

                    for (int iModParamPair = 0; iModParamPair < modParamPairs.Count; iModParamPair++)
                    {
                        OptModifierAndResultParamListPair modParamPair = modParamPairs[iModParamPair];

                        for (int iParam = 0; iParam < modParamPair._resultParams.Count; iParam++)
                        {
                            _cal_resultParam = modParamPair._resultParams[iParam];

                            _cal_curWeight = _cal_resultParam.ModifierWeight;

                            if (!_cal_resultParam.IsModifierAvailable || _cal_curWeight <= 0.001f)
                            {
                                continue;
                            }

                            //if(_cal_resultParam._result_Matrix._scale.magnitude < 0.3f)
                            //{
                            //	Debug.LogError("[" + targetBone.name + "] 너무 작은 Cal Matrix : " + _cal_resultParam._linkedModifier._name);
                            //}
                            // Blend 방식에 맞게 Matrix를 만들자 하자
                            if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0)
                            {
                                BlendMatrix_ITP(_result_BoneTransform, _cal_resultParam._result_Matrix, _cal_curWeight);
                                _cal_prevWeight += _cal_curWeight;
                            }
                            else
                            {
                                BlendMatrix_Add(_result_BoneTransform, _cal_resultParam._result_Matrix, _cal_curWeight);
                            }

                            _iCalculatedParam++;
                        }
                    }

                    //참조된 본에 직접 값을 넣어주자
                    targetBone.UpdateModifiedValue(_result_BoneTransform._pos, _result_BoneTransform._angleDeg, _result_BoneTransform._scale);
                }

//#if UNITY_EDITOR
//				Profiler.EndSample();
//#endif
            }
        }
Beispiel #26
0
        // Init
        //--------------------------------------------
        public apOptCalculatedResultParam(apCalculatedResultParam.CALCULATED_VALUE_TYPE calculatedValueType,
                                          apCalculatedResultParam.CALCULATED_SPACE calculatedSpace,
                                          apOptModifierUnitBase linkedModifier,
                                          apOptTransform targetOptTranform,
                                          apOptTransform ownerOptTranform,
                                          apOptMesh targetOptMesh,
                                          apOptBone targetBone,                                              //<<추가
                                          apOptParamSetGroupVertWeight weightedVertData)
        {
            _calculatedValueType = calculatedValueType;
            _calculatedSpace     = calculatedSpace;

            //TODO 여기서부터 작업하자
            _linkedModifier     = linkedModifier;
            _targetOptTransform = targetOptTranform;
            _ownerOptTransform  = ownerOptTranform;
            _targetOptMesh      = targetOptMesh;
            _targetBone         = targetBone;    //<<추가

            _paramKeyValues.Clear();
            _subParamKeyValueList.Clear();

            _weightedVertexData = weightedVertData;

            _isVertexLocalMorph = false;
            _isVertexRigging    = false;

            //Vertex 데이터가 들어간 경우 Vert 리스트를 만들어주자
            if ((int)(_calculatedValueType & apCalculatedResultParam.CALCULATED_VALUE_TYPE.VertexPos) != 0)
            {
                int nPos = 0;
                if (_targetOptMesh.LocalVertPositions != null)
                {
                    nPos = _targetOptMesh.LocalVertPositions.Length;
                }

                _result_Positions = new Vector2[nPos];
                _tmp_Positions    = new Vector2[nPos];

                for (int i = 0; i < nPos; i++)
                {
                    _result_Positions[i] = Vector2.zero;
                    _tmp_Positions[i]    = Vector2.zero;
                }

                if (_linkedModifier._modifierType == apModifierBase.MODIFIER_TYPE.Rigging)
                {
                    _result_VertMatrices = new apMatrix3x3[nPos];
                    _tmp_VertMatrices    = new apMatrix3x3[nPos];

                    for (int i = 0; i < nPos; i++)
                    {
                        _result_VertMatrices[i].SetIdentity();
                        _tmp_VertMatrices[i].SetIdentity();
                    }
                }

                //if(_linkedModifier._modifierType == apModifierBase.MODIFIER_TYPE.Morph ||
                //	_linkedModifier._modifierType == apModifierBase.MODIFIER_TYPE.AnimatedMorph)
                //{
                //	//최적화를 위한 VertLocalPair를 만든다. 개수는 ParamSetGroup 만큼
                //	_result_VertLocalPairs = new apOptVertexRequest[_linkedModifier._paramSetGroupList.Count];
                //	for (int iVLP = 0; iVLP < _result_VertLocalPairs.Length; iVLP++)
                //	{
                //		apOptVertexRequest newRequest = new apOptVertexRequest();
                //		newRequest.InitVertLocalPair(_linkedModifier._paramSetGroupList[iVLP]);

                //		_result_VertLocalPairs[iVLP] = newRequest;
                //	}
                //}

                if (_linkedModifier._modifierType == apModifierBase.MODIFIER_TYPE.AnimatedMorph ||
                    _linkedModifier._modifierType == apModifierBase.MODIFIER_TYPE.Morph)
                {
                    _isVertexLocalMorph = true;
                }
                else if (_linkedModifier._modifierType == apModifierBase.MODIFIER_TYPE.Rigging)
                {
                    _isVertexRigging = true;
                }
            }
        }
        /// <summary>
        /// Calculate Result Statck의 업데이트 부분
        /// Pre-Update로서 VertWorld와 Rigging이 제외된다.
        /// </summary>
        public void Calculate_Pre()
        {
            //bool isFirstDebug = true;
            _cal_prevWeight  = 0.0f;
            _cal_curWeight   = 0.0f;
            _cal_resultParam = null;
            _cal_posVerts    = null;


            //Debug.Log("Is Any Vert Local : " + _isAnyVertLocal + " [" + _resultParams_VertLocal.Count +"]");
            // 1. Local Morph
            if (_isAnyVertLocal)
            {
#if UNITY_EDITOR
                Profiler.BeginSample("Calcuate Result Stack - 1. Vert Local");
#endif
                _cal_prevWeight  = 0.0f;
                _cal_curWeight   = 0.0f;
                _cal_resultParam = null;
                _cal_posVerts    = null;

                _iCalculatedParam = 0;                //<<추가 : 첫 모디파이어는 무조건 Interpolation으로 만들자

                for (int iParam = 0; iParam < _resultParams_VertLocal.Count; iParam++)
                {
                    _cal_resultParam = _resultParams_VertLocal[iParam];
                    _cal_curWeight   = _cal_resultParam.ModifierWeight;

                    if (!_cal_resultParam.IsModifierAvailable || _cal_curWeight <= 0.001f)
                    {
                        continue;
                    }

                    _cal_posVerts = _cal_resultParam._result_Positions;
                    if (_result_VertLocal == null)
                    {
                        Debug.LogError("Result Vert Local is Null");
                    }
                    if (_cal_posVerts == null)
                    {
                        Debug.LogError("Cal Pos Vert is Null");
                    }
                    if (_cal_posVerts.Count != _result_VertLocal.Length)
                    {
                        //결과가 잘못 들어왔다 갱신 필요
                        Debug.LogError("Wrong Vert Local Result (Cal : " + _cal_posVerts.Count + " / Verts : " + _result_VertLocal.Length + ")");
                        continue;
                    }

                    // Blend 방식에 맞게 Pos를 만들자
                    if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0)
                    {
                        for (int i = 0; i < _cal_posVerts.Count; i++)
                        {
                            _result_VertLocal[i] = BlendPosition_ITP(_result_VertLocal[i], _cal_posVerts[i], _cal_curWeight);

                            //if (isFirstDebug)
                            //{
                            //	if (_result_VertLocal[i].sqrMagnitude > 0.0f)
                            //	{
                            //		Debug.Log("Valid Result Local : " + _result_VertLocal[i]);
                            //		isFirstDebug = false;
                            //	}
                            //}
                        }

                        _cal_prevWeight += _cal_curWeight;
                    }
                    else
                    {
                        for (int i = 0; i < _cal_posVerts.Count; i++)
                        {
                            _result_VertLocal[i] = BlendPosition_Add(_result_VertLocal[i], _cal_posVerts[i], _cal_curWeight);
                        }
                    }

                    _iCalculatedParam++;
                }

#if UNITY_EDITOR
                Profiler.EndSample();
#endif
            }

            // 2. Mesh / MeshGroup Transformation
            if (_isAnyTransformation)
            {
#if UNITY_EDITOR
                Profiler.BeginSample("Calcuate Result Stack - 2. MeshGroup Transformation");
#endif
                _cal_prevWeight  = 0.0f;
                _cal_curWeight   = 0.0f;
                _cal_resultParam = null;

                _iCalculatedParam = 0;

                //Debug.Log("Update TF - OPT");
                for (int iParam = 0; iParam < _resultParams_Transform.Count; iParam++)
                {
                    _cal_resultParam = _resultParams_Transform[iParam];
                    _cal_curWeight   = _cal_resultParam.ModifierWeight;

                    if (!_cal_resultParam.IsModifierAvailable || _cal_curWeight <= 0.001f)
                    {
                        continue;
                    }



                    // Blend 방식에 맞게 Matrix를 만들자 하자
                    if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0)
                    {
                        //Debug.Log("Cal TF [ITP] : " + _cal_resultParam._result_Matrix.Pos3 + " (Weight : " + _cal_curWeight + ")");

                        BlendMatrix_ITP(_result_MeshTransform, _cal_resultParam._result_Matrix, _cal_curWeight);

                        //if (_cal_resultParam._result_Matrix.Scale2.magnitude < 0.5f || _cal_curWeight < 0.5f)
                        //{
                        //	Debug.Log("Cal TF [ITP] : " + _cal_resultParam._result_Matrix.Scale2 + " > " + _result_MeshTransform.Scale2 + " (Weight : " + _cal_curWeight + ")");
                        //}

                        _cal_prevWeight += _cal_curWeight;
                    }
                    else
                    {
                        BlendMatrix_Add(_result_MeshTransform, _cal_resultParam._result_Matrix, _cal_curWeight);
                    }

                    _iCalculatedParam++;
                }

                _result_MeshTransform.MakeMatrix();

                if (_result_MeshTransform._scale.magnitude < 0.5f)
                {
                    Debug.Log("Cal TF [ITP] : " + _result_MeshTransform._scale + " (Total Weight : " + _cal_prevWeight + ")");
                }

#if UNITY_EDITOR
                Profiler.EndSample();
#endif
            }

            // 3. Mesh Color
            if (_isAnyMeshColor)
            {
#if UNITY_EDITOR
                Profiler.BeginSample("Calcuate Result Stack - 3. Mesh Color");
#endif
                _cal_prevWeight  = 0.0f;
                _cal_curWeight   = 0.0f;
                _cal_resultParam = null;

                _iCalculatedParam = 0;

                _result_IsVisible       = false;
                _nMeshColorCalculated   = 0;
                _result_CalculatedColor = false;

                for (int iParam = 0; iParam < _resultParams_MeshColor.Count; iParam++)
                {
                    _cal_resultParam = _resultParams_MeshColor[iParam];
                    _cal_curWeight   = Mathf.Clamp01(_cal_resultParam.ModifierWeight);

                    if (!_cal_resultParam.IsModifierAvailable ||
                        _cal_curWeight <= 0.001f ||
                        !_cal_resultParam.IsColorValueEnabled ||
                        !_cal_resultParam._isColorCalculated                           //<<추가 : Color로 등록했지만 아예 계산이 안되었을 수도 있다.
                        )
                    {
                        continue;
                    }                    //<<TODO


                    // Blend 방식에 맞게 Matrix를 만들자 하자
                    if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0)
                    {
                        //_result_Color = BlendColor_ITP(_result_Color, _cal_resultParam._result_Color, _cal_prevWeight, _cal_curWeight);
                        _result_Color    = apUtil.BlendColor_ITP(_result_Color, _cal_resultParam._result_Color, _cal_curWeight);
                        _cal_prevWeight += _cal_curWeight;
                    }
                    else
                    {
                        _result_Color = apUtil.BlendColor_Add(_result_Color, _cal_resultParam._result_Color, _cal_curWeight);
                    }

                    _result_IsVisible |= _cal_resultParam._result_IsVisible;
                    _nMeshColorCalculated++;

                    _result_CalculatedColor = true;                    //<<"계산된 MeshColor" Result가 있음을 알린다.

                    _iCalculatedParam++;
                }

                if (_nMeshColorCalculated == 0)
                {
                    _result_IsVisible = true;
                }


#if UNITY_EDITOR
                Profiler.EndSample();
#endif
            }
            else
            {
                _result_IsVisible = true;
            }

            //AnyBoneTransform
            if (_isAnyBoneTransform)
            {
                _cal_prevWeight  = 0.0f;
                _cal_curWeight   = 0.0f;
                _cal_resultParam = null;

                for (int iBonePair = 0; iBonePair < _resultParams_BoneTransform.Count; iBonePair++)
                {
                    OptBoneAndModParamPair boneModPair = _resultParams_BoneTransform[iBonePair];
                    apOptBone targetBone = boneModPair._keyBone;
                    List <OptModifierAndResultParamListPair> modParamPairs = boneModPair._modParamPairs;
                    if (targetBone == null || modParamPairs.Count == 0)
                    {
                        continue;
                    }

                    _iCalculatedParam = 0;
                    _result_BoneTransform.SetIdentity();

                    apMatrix lastMatrix = new apMatrix();
                    for (int iModParamPair = 0; iModParamPair < modParamPairs.Count; iModParamPair++)
                    {
                        OptModifierAndResultParamListPair modParamPair = modParamPairs[iModParamPair];

                        for (int iParam = 0; iParam < modParamPair._resultParams.Count; iParam++)
                        {
                            _cal_resultParam = modParamPair._resultParams[iParam];

                            _cal_curWeight = _cal_resultParam.ModifierWeight;

                            if (!_cal_resultParam.IsModifierAvailable || _cal_curWeight <= 0.001f)
                            {
                                continue;
                            }



                            // Blend 방식에 맞게 Matrix를 만들자 하자
                            if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0)
                            {
                                BlendMatrix_ITP(_result_BoneTransform, _cal_resultParam._result_Matrix, _cal_curWeight);
                                _cal_prevWeight += _cal_curWeight;
                            }
                            else
                            {
                                BlendMatrix_Add(_result_BoneTransform, _cal_resultParam._result_Matrix, _cal_curWeight);
                            }
                            lastMatrix.SetMatrix(_cal_resultParam._result_Matrix);

                            _iCalculatedParam++;
                        }
                    }

                    //참조된 본에 직접 값을 넣어주자
                    targetBone.UpdateModifiedValue(_result_BoneTransform._pos, _result_BoneTransform._angleDeg, _result_BoneTransform._scale);

                    if (_result_BoneTransform._scale.magnitude < 0.3f && targetBone.name.Contains("Pelvis"))
                    {
                        Debug.LogError("본 사이즈가 너무 작다 : " + targetBone.name + " / Num CalParam : " + _iCalculatedParam + " / 마지막 Weight : " + _cal_curWeight + " / 마지막 Matrix : " + lastMatrix.ToString());
                    }
                }
            }
        }