// Init
        //------------------------------------------------------------------------
        public void Init(apEditor editor, object loadKey, apAnimClip targetAnimGroup, FUNC_ADD_TIMELINE funcResult)
        {
            _editor         = editor;
            _loadKey        = loadKey;
            _funcResult     = funcResult;
            _targetAnimClip = targetAnimGroup;

            _selectedLinkData = null;
            _linkDataList.Clear();

            //타임라인을 검색해보자

            //리스트에 들어가는건 한글로 바꾸기 힘들 수 있다.

            //_linkDataList.Add(new LinkableData(apAnimClip.LINK_TYPE.ControlParam, "Control Parameters", -1, _editor.ImageSet.Get(apImageSet.PRESET.Anim_WithControlParam)));
            AddLinkableData(apAnimClip.LINK_TYPE.ControlParam, "Control Parameters", -1);            //"Control Parameters"
            //AddLinkableData(apAnimClip.LINK_TYPE.Bone, "Bones", -1);

            List <apModifierBase> modifiers = _targetAnimClip._targetMeshGroup._modifierStack._modifiers;

            for (int i = 0; i < modifiers.Count; i++)
            {
                apModifierBase curMod = modifiers[i];

                if (!curMod.IsAnimated)
                {
                    continue;
                }

                //"Modifier : "
                AddLinkableData(apAnimClip.LINK_TYPE.AnimatedModifier, "Modifier : " + curMod.DisplayName, curMod._uniqueID);
            }
        }
        // Init
        //------------------------------------------------------------------------
        public void Init(FUNC_RETARGET_SINGLE_POSE_IMPORT_ANIM funcResult_Anim, FUNC_RETARGET_SINGLE_POSE_IMPORT_MOD funcResult_Mod,
                         apEditor editor, object loadKey, apMeshGroup targetMeshGroup,
                         apModifierBase targetModifier, apModifierParamSet targetParamSet,                                //<<일반 Modifier에서 작업하는 경우
                         apAnimClip targetAnimClip, apAnimTimeline targetAnimTimeline, int targetFrame)
        {
            _editor          = editor;
            _loadKey         = loadKey;
            _targetMeshGroup = targetMeshGroup;

            _funcResult_Anim = funcResult_Anim;
            _funcResult_Mod  = funcResult_Mod;

            _targetModifier     = targetModifier;
            _targetParamSet     = targetParamSet;
            _targetAnimClip     = targetAnimClip;
            _targetAnimTimeline = targetAnimTimeline;
            _targetFrame        = targetFrame;

            //_imgIcon_Bone = _editor.ImageSet.Get(apImageSet.PRESET.Hierarchy_Bone);

            _category = CATEGORY.SameMeshGroup;

            _retarget.LoadSinglePoseFileList(editor);
            _selectedBonePoseFile = null;
            _isValidPose          = false;

            _meshGroupUniqueID = _targetMeshGroup._uniqueID;
            _portraitName      = _targetMeshGroup._parentPortrait.name;
        }
예제 #3
0
 //추가 5.19
 //유효하지 않은 데이터를 삭제하는 기능
 public void CheckAndRemoveInvalidData(apModifierBase parentModifier)
 {
     //유효하지 않은 데이터가 있다면 삭제한다.
     if ((int)(_modValueType & MOD_VALUE_TYPE.VertexPosList) == 0)
     {
         //1. Vertex 정보가 있는 경우 삭제
         if (_vertices != null && _vertices.Count > 0)
         {
             //Debug.LogError("Invalid Data [" + parentModifier.DisplayName + "] : 잘못된 Vertex 리스트");
             _vertices.Clear();
         }
     }
     if ((int)(_modValueType & MOD_VALUE_TYPE.VertexWeightList_Physics) == 0 &&
         (int)(_modValueType & MOD_VALUE_TYPE.VertexWeightList_Volume) == 0)
     {
         //2. VertexWeight 정보가 있는 경우 삭제
         if (_vertWeights != null && _vertWeights.Count > 0)
         {
             //Debug.LogError("Invalid Data [" + parentModifier.DisplayName + "] : 잘못된 VertexWeight 리스트");
             _vertWeights.Clear();
         }
     }
     if ((int)(_modValueType & MOD_VALUE_TYPE.BoneVertexWeightList) == 0)
     {
         //3. VertRig 정보가 있는 경우 삭제
         if (_vertRigs != null && _vertRigs.Count > 0)
         {
             //Debug.LogError("Invalid Data [" + parentModifier.DisplayName + "] : 잘못된 VertexRig 리스트");
             _vertRigs.Clear();
         }
     }
 }
예제 #4
0
        // Init
        //--------------------------------------------------------------
        public apModifierParamSetGroupAnimPack(apModifierBase modifier, apAnimClip animClip)
        {
            _parentModifier = modifier;
            _linkedAnimClip = animClip;

            _paramSetGroups.Clear();
        }
예제 #5
0
        //------------------------------------------------------------------------------------------
        // Bone - TransformChanged (Default / Rigging Test / Modifier / AnimClip Modifier)
        // Scale 값 직접 수정 (Scale Lock 체크)
        //------------------------------------------------------------------------------------------
        public void TransformChanged_Scale__Modifier_Rigging(Vector2 scale)
        {
            if (Editor.Select.MeshGroup == null ||
                Editor.Select.Bone == null ||
                Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render ||
                Editor.Select.Modifier == null                    //<<Modifier가 null이면 안된다.
                )
            {
                return;
            }

            if (!Editor.Select.IsRigEditTestPosing)
            {
                //TestPosing이 허용되지 않았다면 패스
                return;
            }

            apBone         bone                = Editor.Select.Bone;
            apMeshGroup    meshGroup           = Editor.Select.MeshGroup;
            apMeshGroup    boneParentMeshGroup = bone._meshGroup;        //Bone이 속한 MeshGroup. 다를 수 있다.
            apModifierBase modifier            = Editor.Select.Modifier; //선택한 Modifier

            if (modifier.ModifierType != apModifierBase.MODIFIER_TYPE.Rigging)
            {
                //리깅 Modifier가 아니라면 패스
                return;
            }

            //직접 대입한다.
            bone._rigTestMatrix.SetScale(scale);
            bone.MakeWorldMatrix(true);
            bone.GUIUpdate(true);

            //apMatrix dummyWorldMatrix = new apMatrix(bone._worldMatrix);
            //dummyWorldMatrix.SetScale(scale);

            ////Parent - (Local) - (RigTest) 순으로 matrix 역 연산 후 남는 Scale 값으로 대입
            //apMatrix parentMatrix = null;
            //if(bone._parentBone != null)
            //{
            //	parentMatrix = bone._parentBone._worldMatrix;
            //}
            //else if(bone._renderUnit != null)
            //{
            //	parentMatrix = bone._renderUnit.WorldMatrixWrap;
            //}

            //if (parentMatrix != null)
            //{
            //	dummyWorldMatrix.RInverse(parentMatrix);
            //}
            //dummyWorldMatrix.Subtract(bone._localMatrix);
            //dummyWorldMatrix.Subtract(bone._defaultMatrix);//<<Default를 빼자
            //dummyWorldMatrix.MakeMatrix();

            //bone._rigTestMatrix.SetScale(dummyWorldMatrix.Scale2);
            //bone.MakeWorldMatrix(true);
            //bone.GUIUpdate(true);
        }
예제 #6
0
        // Init
        //-------------------------------------------------
        public apModifierParamSetGroup(apPortrait portrait, apModifierBase parentModifier, int layerIndex)
        {
            LinkPortrait(portrait, parentModifier);

            _layerIndex  = layerIndex;
            _layerWeight = 1.0f;
            _blendMethod = BLEND_METHOD.Interpolation;
        }
예제 #7
0
        //------------------------------------------------------------------------------------------
        // Bone - TransformChanged (Default / Rigging Test / Modifier / AnimClip Modifier)
        // Rotate 값 직접 수정 (IK Range 확인)
        //------------------------------------------------------------------------------------------
        public void TransformChanged_Rotate__Modifier_Rigging(float angle)
        {
            if (Editor.Select.MeshGroup == null ||
                Editor.Select.Bone == null ||
                Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render ||
                Editor.Select.Modifier == null                    //<<Modifier가 null이면 안된다.
                )
            {
                return;
            }

            if (!Editor.Select.IsRigEditTestPosing)
            {
                //TestPosing이 허용되지 않았다면 패스
                return;
            }

            apBone      bone      = Editor.Select.Bone;
            apMeshGroup meshGroup = Editor.Select.MeshGroup;
            //apMeshGroup boneParentMeshGroup = bone._meshGroup;//Bone이 속한 MeshGroup. 다를 수 있다.
            apModifierBase modifier = Editor.Select.Modifier;            //선택한 Modifier

            if (modifier.ModifierType != apModifierBase.MODIFIER_TYPE.Rigging)
            {
                //리깅 Modifier가 아니라면 패스
                return;
            }

            if (bone._isIKAngleRange)
            {
                if (angle < bone._defaultMatrix._angleDeg + bone._IKAngleRange_Lower)
                {
                    angle = bone._defaultMatrix._angleDeg + bone._IKAngleRange_Lower;
                }
                else if (angle > bone._defaultMatrix._angleDeg + bone._IKAngleRange_Upper)
                {
                    angle = bone._defaultMatrix._angleDeg + bone._IKAngleRange_Upper;
                }
            }

            //직접 대입한다.
            bone._rigTestMatrix.SetRotate(angle);
            //bone.MakeWorldMatrix(true);//<<이전

            //<BONE_EDIT>
            //if(bone._meshGroup != null)
            //{
            //	bone._meshGroup.UpdateBonesWorldMatrix();//<<변경 : 모든 본 동시에 갱신
            //}

            //>Root MeshGroup에서 변경
            if (meshGroup != null)
            {
                meshGroup.UpdateBonesWorldMatrix();
            }

            bone.GUIUpdate(true);
        }
예제 #8
0
        /// <summary>
        /// MeshGroup 메뉴 + Modifier 중 Rigging Modifier에서만 제어할 수 있다.
        /// Rigging 테스트를 위해 임시 WorldMatrix를 만들어서 움직인다.
        /// Rigging Modifier 활성할때마다 변수가 초기화됨.
        /// 자식 MeshGroup의 Bone도 제어 가능하다 (!)
        /// IK의 영향을 받지 않는다.
        /// </summary>
        /// <param name="deltaAngleW"></param>
        public void Rotate__Modifier_Rigging(float deltaAngleW, bool isFirstRotate)
        {
            if (Editor.Select.MeshGroup == null ||
                Editor.Select.Bone == null ||
                Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render ||
                Editor.Select.Modifier == null ||                 //<<Modifier가 null이면 안된다.
                deltaAngleW == 0.0f
                )
            {
                return;
            }

            if (!Editor.Select.IsRigEditTestPosing)
            {
                //TestPosing이 허용되지 않았다면 패스
                return;
            }

            apBone      bone      = Editor.Select.Bone;
            apMeshGroup meshGroup = Editor.Select.MeshGroup;
            //apMeshGroup boneParentMeshGroup = bone._meshGroup;//Bone이 속한 MeshGroup. 다를 수 있다.
            apModifierBase modifier = Editor.Select.Modifier;            //선택한 Modifier

            if (modifier.ModifierType != apModifierBase.MODIFIER_TYPE.Rigging)
            {
                //리깅 Modifier가 아니라면 패스
                return;
            }

            //Default Angle은 -180 ~ 180 범위 안에 들어간다.
            float nextAngle = bone._rigTestMatrix._angleDeg + deltaAngleW;

            if (nextAngle < -180.0f)
            {
                nextAngle += 360.0f;
            }
            if (nextAngle > 180.0f)
            {
                nextAngle -= 360.0f;
            }

            bone._rigTestMatrix.SetRotate(nextAngle);
            //bone.MakeWorldMatrix(true);//<<이전 : 단일 본 수정

            //<BONE_EDIT>
            //if(bone._meshGroup != null)
            //{
            //	bone._meshGroup.UpdateBonesWorldMatrix();//변경 : 전체 본 수정
            //}

            //>Root MeshGroup에서 변경
            if (meshGroup != null)
            {
                meshGroup.UpdateBonesWorldMatrix();
            }
            bone.GUIUpdate(true);
        }
예제 #9
0
        /// <summary>
        /// Modifier들의 계산 값들을 초기화한다.
        /// </summary>
        public void InitModifierCalculatedValues()
        {
            for (int iMod = 0; iMod < _modifiers.Count; iMod++)
            {
                //Modifier ->..
                apModifierBase modifier = _modifiers[iMod];

                List <apModifierParamSetGroup> paramSetGroups = modifier._paramSetGroup_controller;

                for (int iGroup = 0; iGroup < paramSetGroups.Count; iGroup++)
                {
                    //Modifier -> ParamSetGroup ->..
                    apModifierParamSetGroup paramSetGroup = paramSetGroups[iGroup];

                    List <apModifierParamSet> paramSets = paramSetGroup._paramSetList;

                    for (int iParam = 0; iParam < paramSets.Count; iParam++)
                    {
                        //Modifier -> ParamSetGroup -> ParamSet ->...
                        apModifierParamSet paramSet = paramSets[iParam];

                        List <apModifiedMesh> modMeshes = paramSet._meshData;
                        List <apModifiedBone> modBones  = paramSet._boneData;

                        for (int iModMesh = 0; iModMesh < modMeshes.Count; iModMesh++)
                        {
                            apModifiedMesh modMesh = modMeshes[iModMesh];
                            if (modMesh._vertices != null && modMesh._vertices.Count > 0)
                            {
                                //ModVert 초기화 => 현재는 초기화 할게 없다.
                            }
                            if (modMesh._vertRigs != null && modMesh._vertRigs.Count > 0)
                            {
                                //ModVertRig 초기화 => 현재는 초기화 할게 없다.
                            }
                            if (modMesh._vertWeights != null && modMesh._vertWeights.Count > 0)
                            {
                                apModifiedVertexWeight vertWeight = null;
                                for (int iVW = 0; iVW < modMesh._vertWeights.Count; iVW++)
                                {
                                    vertWeight = modMesh._vertWeights[iVW];
                                    vertWeight.InitCalculatedValue();                                    //<<초기화를 하자. (여기서는 물리값)
                                }
                            }
                        }

                        for (int iModBone = 0; iModBone < modBones.Count; iModBone++)
                        {
                            apModifiedBone modBone = modBones[iModBone];
                            //ModBone도 현재는 초기화 할게 없다.
                        }
                    }
                }
            }
        }
        public void LinkPortrait(apPortrait portrait, apModifierBase parentModifier)
        {
            _portrait       = portrait;
            _parentModifier = parentModifier;

            if (_tmpMatrix == null)
            {
                //변경 : apMatrix > apMatrixCal로 변경
                //_tmpMatrix = new apMatrix();
            }
        }
        // Init
        //--------------------------------------------------
        public apCalculatedResultParam(CALCULATED_VALUE_TYPE calculatedValueType,
                                       CALCULATED_SPACE calculatedSpace,
                                       apModifierBase linkedModifier,
                                       apRenderUnit targetRenderUnit,
                                       apRenderUnit ownerRenderUnit, //<<추가 10.2 : Modifier를 가지고 있었던 RenderUnit
                                       apBone targetBone
                                                                     //apModifierParamSetGroupVertWeight weightedVertData//삭제 19.5.20
                                       )
        {
            _calculatedValueType = calculatedValueType;
            _calculatedSpace     = calculatedSpace;

            _linkedModifier   = linkedModifier;
            _targetRenderUnit = targetRenderUnit;
            _ownerRenderUnit  = ownerRenderUnit;

            _targetBone = targetBone;

            //삭제 19.5.20 : _weightedVertexData 변수 삭제됨
            //_weightedVertexData = weightedVertData;

            //처리 타입이 Vertex 계열이면 Vertex List를 준비해야한다.
            if ((int)(_calculatedValueType & CALCULATED_VALUE_TYPE.VertexPos) != 0)
            {
                int nPos = 0;
                if (_targetRenderUnit._meshTransform != null && _targetRenderUnit._meshTransform._mesh != null)
                {
                    nPos = _targetRenderUnit._meshTransform._mesh._vertexData.Count;
                }

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

                //추가 : 만약 리깅타입이면 Vertex 개수만큼의 Matrix를 만들어야 한다.
                if (_linkedModifier.ModifierType == apModifierBase.MODIFIER_TYPE.Rigging)
                {
                    _result_VertMatrices = new apMatrix3x3[nPos];
                    for (int i = 0; i < nPos; i++)
                    {
                        _result_VertMatrices[i] = apMatrix3x3.zero;
                    }
                }
            }

            _debugID = UnityEngine.Random.Range(0, 10000);
        }
예제 #12
0
        // Show Window / Close Dialog
        //------------------------------------------------------------------------
        public static object ShowDialog(apEditor editor,
                                        apPortrait portrait,
                                        apMeshGroup meshGroup,
                                        apModifierBase modifier,
                                        apModifiedMesh modMesh,
                                        apRenderUnit renderUnit,
                                        bool isAnimEdit,
                                        apAnimClip animClip,
                                        apAnimKeyframe keyframe)
        {
            CloseDialog();

            if (editor == null ||
                editor._portrait == null ||
                meshGroup == null ||
                modifier == null ||
                modMesh == null)
            {
                return(null);
            }



            EditorWindow         curWindow = EditorWindow.GetWindow(typeof(apDialog_ExtraOption), true, "Extra Properties", true);
            apDialog_ExtraOption curTool   = curWindow as apDialog_ExtraOption;

            object loadKey = new object();

            if (curTool != null && curTool != s_window)
            {
                int width = 400;

                int height = 620;
                if (isAnimEdit)
                {
                    height = 715;
                }
                s_window          = curTool;
                s_window.position = new Rect((editor.position.xMin + editor.position.xMax) / 2 - (width / 2),
                                             (editor.position.yMin + editor.position.yMax) / 2 - (height / 2),
                                             width, height);
                s_window.Init(editor, portrait, meshGroup, modifier, modMesh, renderUnit, isAnimEdit, animClip, keyframe);

                return(loadKey);
            }
            else
            {
                return(null);
            }
        }
        public void Clear()
        {
            _action     = ACTION.None;
            _saveTarget = SAVE_TARGET.None;
            _portrait   = null;
            _mesh       = null;
            _meshGroup  = null;
            _modifier   = null;

            _keyObject        = null;
            _isCallContinuous = false;            //여러 항목을 동시에 처리하는 Batch 액션 중인가

            _lastUndoTime = DateTime.Now;
        }
예제 #14
0
        // Add / Remove
        //----------------------------------------------------
        public void AddModifier(apModifierBase modifier, apModifierBase.MODIFIER_TYPE modifierType)
        {
            switch (modifierType)
            {
            case apModifierBase.MODIFIER_TYPE.Base:

                break;

            case apModifierBase.MODIFIER_TYPE.Volume:
                _modifiers_Volume.Add((apModifier_Volume)modifier);
                break;

            case apModifierBase.MODIFIER_TYPE.Morph:
                _modifiers_Morph.Add((apModifier_Morph)modifier);
                break;

            case apModifierBase.MODIFIER_TYPE.AnimatedMorph:
                _modifiers_AnimatedMorph.Add((apModifier_AnimatedMorph)modifier);
                break;

            case apModifierBase.MODIFIER_TYPE.Rigging:
                _modifiers_Rigging.Add((apModifier_Rigging)modifier);
                break;

            case apModifierBase.MODIFIER_TYPE.Physic:
                _modifiers_Physic.Add((apModifier_Physic)modifier);
                break;

            case apModifierBase.MODIFIER_TYPE.TF:
                _modifiers_TF.Add((apModifier_TF)modifier);
                break;

            case apModifierBase.MODIFIER_TYPE.AnimatedTF:
                _modifiers_AnimatedTF.Add((apModifier_AnimatedTF)modifier);
                break;

            case apModifierBase.MODIFIER_TYPE.FFD:
                _modifiers_FFD.Add((apModifier_FFD)modifier);
                break;

            case apModifierBase.MODIFIER_TYPE.AnimatedFFD:
                _modifiers_AnimatedFFD.Add((apModifier_AnimatedFFD)modifier);
                break;

            default:
                Debug.LogError("TODO : 정의되지 않은 타입 [" + modifier + "]");
                break;
            }
        }
예제 #15
0
        public void LinkPortrait(apPortrait portrait, apModifierBase parentModifier)
        {
            _portrait       = portrait;
            _parentModifier = parentModifier;

            if (_tmpMatrix == null)
            {
                _tmpMatrix = new apMatrix();
            }

            if (_tmpPositions == null)
            {
                _tmpPositions = new List <Vector2>();
            }
        }
예제 #16
0
        public void RemoveModifier(apModifierBase modifier)
        {
            apModifierBase.MODIFIER_TYPE modType = modifier.ModifierType;

            switch (modType)
            {
            case apModifierBase.MODIFIER_TYPE.Base:

                break;

            case apModifierBase.MODIFIER_TYPE.Volume:
                _modifiers_Volume.Remove((apModifier_Volume)modifier);
                break;

            case apModifierBase.MODIFIER_TYPE.Morph:
                _modifiers_Morph.Remove((apModifier_Morph)modifier);
                break;

            case apModifierBase.MODIFIER_TYPE.AnimatedMorph:
                _modifiers_AnimatedMorph.Remove((apModifier_AnimatedMorph)modifier);
                break;

            case apModifierBase.MODIFIER_TYPE.Rigging:
                _modifiers_Rigging.Remove((apModifier_Rigging)modifier);
                break;

            case apModifierBase.MODIFIER_TYPE.Physic:
                _modifiers_Physic.Remove((apModifier_Physic)modifier);
                break;

            case apModifierBase.MODIFIER_TYPE.TF:
                _modifiers_TF.Remove((apModifier_TF)modifier);
                break;

            case apModifierBase.MODIFIER_TYPE.AnimatedTF:
                _modifiers_AnimatedTF.Remove((apModifier_AnimatedTF)modifier);
                break;

            case apModifierBase.MODIFIER_TYPE.FFD:
                _modifiers_FFD.Remove((apModifier_FFD)modifier);
                break;

            case apModifierBase.MODIFIER_TYPE.AnimatedFFD:
                _modifiers_AnimatedFFD.Remove((apModifier_AnimatedFFD)modifier);
                break;
            }
        }
예제 #17
0
        /// <summary>
        /// MeshGroup 메뉴 + Modifier 중 Rigging Modifier에서만 제어할 수 있다.
        /// Rigging 테스트를 위해 임시 WorldMatrix를 만들어서 움직인다.
        /// Rigging Modifier 활성할때마다 변수가 초기화됨.
        /// 자식 MeshGroup의 Bone도 제어 가능하다 (!)
        /// IK의 영향을 받지 않는다.
        /// </summary>
        /// <param name="deltaScaleW"></param>
        public void Scale__Modifier_Rigging(Vector2 deltaScaleW, bool isFirstScale)
        {
            if (Editor.Select.MeshGroup == null ||
                Editor.Select.Bone == null ||
                Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render ||
                Editor.Select.Modifier == null ||                 //<<Modifier가 null이면 안된다.
                deltaScaleW.sqrMagnitude == 0.0f
                )
            {
                return;
            }

            if (!Editor.Select.IsRigEditTestPosing)
            {
                //TestPosing이 허용되지 않았다면 패스
                return;
            }

            apBone      bone      = Editor.Select.Bone;
            apMeshGroup meshGroup = Editor.Select.MeshGroup;
            //apMeshGroup boneParentMeshGroup = bone._meshGroup;//Bone이 속한 MeshGroup. 다를 수 있다.
            apModifierBase modifier = Editor.Select.Modifier;            //선택한 Modifier

            if (modifier.ModifierType != apModifierBase.MODIFIER_TYPE.Rigging)
            {
                //리깅 Modifier가 아니라면 패스
                return;
            }

            Vector3 prevScale = bone._rigTestMatrix._scale;
            Vector2 nextScale = new Vector2(prevScale.x + deltaScaleW.x, prevScale.y + deltaScaleW.y);

            bone._rigTestMatrix.SetScale(nextScale);
            //bone.MakeWorldMatrix(true);//<<이전 : 단일 본 갱신
            //<BONE_EDIT>
            //if(bone._meshGroup != null)
            //{
            //	bone._meshGroup.UpdateBonesWorldMatrix();//<<변경 : 전체 본 갱신
            //}

            //>Root MeshGroup에서 변경
            if (meshGroup != null)
            {
                meshGroup.UpdateBonesWorldMatrix();
            }
            bone.GUIUpdate(true);
        }
예제 #18
0
        //------------------------------------------------------------------------------------------
        // Bone - TransformChanged (Default / Rigging Test / Modifier / AnimClip Modifier)
        // Move 값 직접 수정. IK, Local Move 옵션에 따라 무시될 수 있다.
        // World 값이 아니라 Local 값을 수정한다. Local Move가 Lock이 걸린 경우엔 값이 적용되지 않는다.
        //------------------------------------------------------------------------------------------
        public void TransformChanged_Position__Modifier_Rigging(Vector2 pos)
        {
            if (Editor.Select.MeshGroup == null ||
                Editor.Select.Bone == null ||
                Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render ||
                Editor.Select.Modifier == null                    //<<Modifier가 null이면 안된다.
                )
            {
                return;
            }

            apBone      bone      = Editor.Select.Bone;
            apMeshGroup meshGroup = Editor.Select.MeshGroup;
            //apMeshGroup boneParentMeshGroup = bone._meshGroup;//Bone이 속한 MeshGroup. 다를 수 있다.
            apModifierBase modifier = Editor.Select.Modifier;            //선택한 Modifier

            if (modifier.ModifierType != apModifierBase.MODIFIER_TYPE.Rigging)
            {
                //리깅 Modifier가 아니라면 패스
                return;
            }
            if (!Editor.Select.IsRigEditTestPosing)
            {
                //TestPosing이 허용되지 않았다면 패스
                return;
            }

            //직접 대입하고 끝
            bone._rigTestMatrix.SetPos(pos);
            //bone.MakeWorldMatrix(true);//<<이전 : 단일 본 변경
            //<BONE_EDIT>
            //if(bone._meshGroup != null)
            //{
            //	bone._meshGroup.UpdateBonesWorldMatrix();//변경 : 전체 본 갱신
            //}

            //>Root MeshGroup에서 변경
            if (meshGroup != null)
            {
                meshGroup.UpdateBonesWorldMatrix();
            }
            bone.GUIUpdate(true);
        }
예제 #19
0
        public void LinkPortrait(apPortrait portrait, apModifierBase parentModifier)
        {
            _portrait       = portrait;
            _parentModifier = parentModifier;

            if (_tmpMatrix == null)
            {
                _tmpMatrix = new apMatrix();
            }

            //if (_tmpPositions == null)
            //{
            //	_tmpPositions = new List<Vector2>();
            //}

            //if(_tmpVertMatrices == null)
            //{
            //	_tmpVertMatrices = new List<apMatrix3x3>();
            //}
        }
		public void Link(apAnimClip animClip)
		{
			_parentAnimClip = animClip;

			animClip._portrait.RegistUniqueID(apIDManager.TARGET.AnimTimeline, _uniqueID);

			_linkedModifier = null;
			//TODO : linkedBone 연결하자

			switch (_linkType)
			{
				case apAnimClip.LINK_TYPE.AnimatedModifier:
					{
						//_boneUniqueID = -1;

						if (_parentAnimClip._targetMeshGroup != null)
						{
							_linkedModifier = _parentAnimClip._targetMeshGroup.GetModifier(_modifierUniqueID);
							if (_linkedModifier == null)
							{
								//Debug.LogError("Timeline Link : Error - No Mod [" + _modifierUniqueID + "]");//<<디버그용
								_modifierUniqueID = -1;

							}
						}
					}

					break;

				//case apAnimClip.LINK_TYPE.Bone:
				case apAnimClip.LINK_TYPE.ControlParam:
					_modifierUniqueID = -1;
					break;
			}


			for (int i = 0; i < _layers.Count; i++)
			{
				_layers[i].Link(animClip, this);
			}
		}
        private static object ShowDialog(FUNC_RETARGET_SINGLE_POSE_IMPORT_ANIM funcResult_Anim, FUNC_RETARGET_SINGLE_POSE_IMPORT_MOD funcResult_Mod, apEditor editor, apMeshGroup targetMeshGroup,
                                         apModifierBase targetModifier, apModifierParamSet targetParamSet,             //<<일반 Modifier에서 작업하는 경우
                                         apAnimClip targetAnimClip, apAnimTimeline targetAnimTimeline, int targetFrame //<<애니메이션에서 Pose를 여는 경우
                                         )
        {
            CloseDialog();

            if (editor == null || editor._portrait == null || editor._portrait._controller == null)
            {
                return(null);
            }



            EditorWindow curWindow = EditorWindow.GetWindow(typeof(apDialog_RetargetSinglePoseImport), true, "Import Pose", true);
            apDialog_RetargetSinglePoseImport curTool = curWindow as apDialog_RetargetSinglePoseImport;

            object loadKey = new object();

            if (curTool != null && curTool != s_window)
            {
                int width  = 500;
                int height = 700;
                s_window          = curTool;
                s_window.position = new Rect((editor.position.xMin + editor.position.xMax) / 2 - (width / 2),
                                             (editor.position.yMin + editor.position.yMax) / 2 - (height / 2),
                                             width, height);

                s_window.Init(funcResult_Anim, funcResult_Mod, editor, loadKey, targetMeshGroup,
                              targetModifier, targetParamSet,
                              targetAnimClip, targetAnimTimeline, targetFrame);

                return(loadKey);
            }
            else
            {
                return(null);
            }
        }
예제 #22
0
        //------------------------------------------------------------------------------------------
        // Bone - Pivot Return (Default / Rigging Test / Modifier / AnimClip Modifier)
        //------------------------------------------------------------------------------------------
        public apGizmos.TransformParam PivotReturn__Modifier_Rigging()
        {
            if (Editor.Select.MeshGroup == null ||
                Editor.Select.Bone == null ||
                Editor._boneGUIRenderMode != apEditor.BONE_RENDER_MODE.Render ||
                Editor.Select.Modifier == null
                )
            {
                return(null);
            }

            apBone         bone                = Editor.Select.Bone;
            apMeshGroup    meshGroup           = Editor.Select.MeshGroup;
            apMeshGroup    boneParentMeshGroup = bone._meshGroup;        //Bone이 속한 MeshGroup. 다를 수 있다.
            apModifierBase modifier            = Editor.Select.Modifier; //선택한 Modifier

            if (modifier.ModifierType != apModifierBase.MODIFIER_TYPE.Rigging)
            {
                //리깅 Modifier가 아니라면 패스
                return(null);
            }
            if (!Editor.Select.IsRigEditTestPosing)
            {
                //TestPosing이 허용되지 않았다면 패스
                return(null);
            }

            return(apGizmos.TransformParam.Make(
                       bone._worldMatrix._pos,
                       bone._worldMatrix._angleDeg,
                       bone._worldMatrix._scale,
                       0, bone._color,
                       true,
                       bone._worldMatrix.MtrxToSpace,
                       false, apGizmos.TRANSFORM_UI.TRS,
                       bone._rigTestMatrix._pos,
                       bone._rigTestMatrix._angleDeg,
                       bone._rigTestMatrix._scale));
        }
예제 #23
0
            public void AddCalculatedResultParam(apCalculatedResultParam calculatedResultParam)
            {
                apModifierBase modifier = calculatedResultParam._linkedModifier;

                if (modifier == null)
                {
                    return;
                }

                ModifierAndResultParamListPair modParamPair = null;

                if (!_modParamPairs_ModKey.ContainsKey(modifier))
                {
                    modParamPair = new ModifierAndResultParamListPair(modifier);
                    _modParamPairs_ModKey.Add(modifier, modParamPair);
                    _modParamPairs.Add(modParamPair);
                }
                else
                {
                    modParamPair = _modParamPairs_ModKey[modifier];
                }
                modParamPair.AddCalculatedResultParam(calculatedResultParam);
            }
예제 #24
0
        // 에디터 관련 코드
        //----------------------------------------------------
        public void ActiveAllModifierFromExclusiveEditing()
        {
            apModifierBase modifier = null;

            for (int i = 0; i < _modifiers.Count; i++)
            {
                modifier = _modifiers[i];
                modifier._editorExclusiveActiveMod = apModifierBase.MOD_EDITOR_ACTIVE.Enabled;

                for (int iP = 0; iP < modifier._paramSetGroup_controller.Count; iP++)
                {
                    modifier._paramSetGroup_controller[iP]._isEnabledExclusive = true;
                }

                //List<apCalculatedResultParam> calParamList = modifier._calculatedResultParams;
                //for (int iCal = 0; iCal < calParamList.Count; iCal++)
                //{
                //	calParamList[iCal].ActiveAllParamList();
                //}
            }

            //Child MeshGroup에도 모두 적용하자
            if (_parentMeshGroup != null)
            {
                if (_parentMeshGroup._childMeshGroupTransforms != null)
                {
                    for (int i = 0; i < _parentMeshGroup._childMeshGroupTransforms.Count; i++)
                    {
                        apTransform_MeshGroup meshGroupTransform = _parentMeshGroup._childMeshGroupTransforms[i];
                        if (meshGroupTransform._meshGroup != null && meshGroupTransform._meshGroup != _parentMeshGroup)
                        {
                            meshGroupTransform._meshGroup._modifierStack.ActiveAllModifierFromExclusiveEditing();
                        }
                    }
                }
            }
        }
예제 #25
0
        // Init
        //--------------------------------------------------
        public apCalculatedResultParam(CALCULATED_VALUE_TYPE calculatedValueType,
                                       CALCULATED_SPACE calculatedSpace,
                                       apModifierBase linkedModifier,
                                       apRenderUnit targetRenderUnit,
                                       apBone targetBone,                                         //<<추가
                                       apModifierParamSetGroupVertWeight weightedVertData)
        {
            _calculatedValueType = calculatedValueType;
            _calculatedSpace     = calculatedSpace;

            _linkedModifier   = linkedModifier;
            _targetRenderUnit = targetRenderUnit;
            _targetBone       = targetBone;      //<추가

            _weightedVertexData = weightedVertData;

            //처리 타입이 Vertex 계열이면 Vertex List를 준비해야한다.
            if ((int)(_calculatedValueType & CALCULATED_VALUE_TYPE.VertexPos) != 0)
            {
                int nPos = 0;
                if (_targetRenderUnit._meshTransform != null && _targetRenderUnit._meshTransform._mesh != null)
                {
                    nPos = _targetRenderUnit._meshTransform._mesh._vertexData.Count;
                }

                _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);
                }
            }

            _debugID = UnityEngine.Random.Range(0, 10000);
        }
        // Functions
        //--------------------------------------------------
        /// <summary>
        /// Undo 전에 중복을 체크하기 위해 Action을 등록한다.
        /// 리턴값이 True이면 "새로운 Action"이므로 Undo 등록을 해야한다.
        /// 만약 Action 타입이 Add, New.. 계열이면 targetObject가 null일 수 있다. (parent는 null이 되어선 안된다)
        /// </summary>
        public bool SetAction(ACTION action, apPortrait portrait, apMesh mesh, apMeshGroup meshGroup, apModifierBase modifier, object keyObject, bool isCallContinuous, SAVE_TARGET saveTarget)
        {
            bool isTimeOver = false;

            if (DateTime.Now.Subtract(_lastUndoTime).TotalSeconds > 1.0f || _isFirstAction)
            {
                //1초가 넘었다면 강제 Undo ID 증가
                isTimeOver     = true;
                _lastUndoTime  = DateTime.Now;
                _isFirstAction = false;
            }

            //특정 조건에서는 UndoID가 증가하지 않는다.
            //유효한 Action이고 시간이 지나지 않았다면
            if (_action != ACTION.None && !isTimeOver)
            {
                //이전과 값이 같을 때에만 Multiple 처리가 된다.
                if (action == _action &&
                    saveTarget == _saveTarget &&
                    portrait == _portrait &&
                    mesh == _mesh &&
                    meshGroup == _meshGroup &&
                    modifier == _modifier &&
                    isCallContinuous == _isCallContinuous
                    )
                {
                    if (isCallContinuous)
                    {
                        //연속 호출이면 KeyObject가 달라도 Undo를 묶는다.
                        return(false);
                    }
                    else if (keyObject == _keyObject && keyObject != null)
                    {
                        //연속 호출이 아니더라도 KeyObject가 같으면 Undo를 묶는다.
                        return(false);
                    }
                }
            }
            #region [미사용 코드]
            //if (_action != ACTION.None && _parentMonoObject != null)
            //{
            //	if (_action == action && _parentMonoObject == parentMonoObject && isMultiple == _isMultiple)
            //	{
            //		if (_isMultiple)
            //		{
            //			//다중 처리 타입이면 -> targetObject가 달라도 연속된 액션이다.
            //			return false;
            //		}
            //		else
            //		{
            //			//Multiple 타입이 아니라면 targetObject도 동일해야한다.
            //			//단, 둘다 Null이라면 연속된 타입일 수 없다.
            //			if (targtObject == _keyObject && targtObject != null && _keyObject != null)
            //			{
            //				if (targetObject2 != null)
            //				{
            //					if(targetObject2 == _targetObject2)
            //					{
            //						return false;//연속된 Action이다.
            //					}
            //				}
            //				else
            //				{
            //					return false;//연속된 Action이다.
            //				}
            //			}
            //		}
            //	}
            //}
            #endregion
            _action = action;

            _saveTarget = saveTarget;
            _portrait   = portrait;
            _mesh       = mesh;
            _meshGroup  = meshGroup;
            _modifier   = modifier;

            _keyObject        = keyObject;
            _isCallContinuous = isCallContinuous;            //여러 항목을 동시에 처리하는 Batch 액션 중인가

            //_parentMonoObject = parentMonoObject;
            //_keyObject = targtObject;
            //_targetObject2 = targetObject2;
            //_isMultiple = isMultiple;

            //Debug.Log("Undo Regist [" + action + "]");
            return(true);
        }
예제 #27
0
        /// <summary>
        /// AnimTimeline을 선택하고, 그 안의 AnimTimeLayer를 모두 활성화한다.
        /// 일반적으로 [선택하지 않은 AnimTimeline]들을 모두 해제하는 반면에,
        /// 여기서는 해당 ParamSetGroup에 연동된 AnimTimeline이 AnimClip에 포함된다면 모두 포함시킨다.
        /// </summary>
        /// <param name="modifier"></param>
        /// <param name="paramSetGroups"></param>
        public void SetExclusiveModifierInEditing_MultipleParamSetGroup_General(apModifierBase modifier, apAnimClip targetAnimClip)
        {
            //apCalculatedResultParam.RESULT_TYPE targetResultType = modifier.CalculatedResultType;
            //추가
            //요청한 Modifier가 BoneTransform을 지원하는 경우
            //Rigging은 비활성화 되어서는 안된다.
            apModifierBase.MODIFIER_TYPE[] exGeneralTypes = modifier.GetGeneralExEditableModTypes();
            if (exGeneralTypes == null)
            {
                exGeneralTypes = new apModifierBase.MODIFIER_TYPE[] { modifier.ModifierType };
            }

            for (int i = 0; i < _modifiers.Count; i++)
            {
                bool isValidType = false;
                for (int iGT = 0; iGT < exGeneralTypes.Length; iGT++)
                {
                    if (exGeneralTypes[iGT] == _modifiers[i].ModifierType)
                    {
                        isValidType = true;
                        break;
                    }
                }

                if (isValidType)
                {
                    //AnimClip을 포함하는 ParamSetGroup에 한해서
                    _modifiers[i]._editorExclusiveActiveMod = apModifierBase.MOD_EDITOR_ACTIVE.ExclusiveEnabled;

                    for (int iP = 0; iP < _modifiers[i]._paramSetGroup_controller.Count; iP++)
                    {
                        apModifierParamSetGroup paramSetGroup = _modifiers[i]._paramSetGroup_controller[iP];
                        if (paramSetGroup._keyAnimClip == targetAnimClip)
                        {
                            paramSetGroup._isEnabledExclusive = true;
                        }
                        else
                        {
                            paramSetGroup._isEnabledExclusive = false;
                        }
                    }
                }
                else
                {
                    //지원하는 타입이 아니다.
                    //모두 Disabled한다.
                    _modifiers[i]._editorExclusiveActiveMod = apModifierBase.MOD_EDITOR_ACTIVE.Disabled;

                    for (int iP = 0; iP < _modifiers[i]._paramSetGroup_controller.Count; iP++)
                    {
                        apModifierParamSetGroup paramSetGroup = _modifiers[i]._paramSetGroup_controller[iP];
                        paramSetGroup._isEnabledExclusive = false;
                    }
                }
            }

            //Child MeshGroup에도 모두 적용하자
            if (_parentMeshGroup != null)
            {
                if (_parentMeshGroup._childMeshGroupTransforms != null)
                {
                    for (int i = 0; i < _parentMeshGroup._childMeshGroupTransforms.Count; i++)
                    {
                        apTransform_MeshGroup meshGroupTransform = _parentMeshGroup._childMeshGroupTransforms[i];
                        if (meshGroupTransform._meshGroup != null && meshGroupTransform._meshGroup != _parentMeshGroup)
                        {
                            meshGroupTransform._meshGroup._modifierStack.SetExclusiveModifierInEditing_MultipleParamSetGroup_General(modifier, targetAnimClip);
                        }
                    }
                }
            }
        }
예제 #28
0
 public ModifierAndResultParamListPair(apModifierBase modifier)
 {
     _keyModifier = modifier;
 }
        public void Bake(apModifierStack modStack, apPortrait portrait, bool isUseModMesh)
        {
            _portrait = portrait;
            _modifiers.Clear();

            _parentTransformID = -1;
            _parentTransform   = null;

            if (modStack._parentMeshGroup != null)
            {
                //MeshGroup 타입의 OptTransform을 찾자
                apOptTransform optTransform = _portrait.GetOptTransformAsMeshGroup(modStack._parentMeshGroup._uniqueID);
                if (optTransform != null)
                {
                    _parentTransformID = optTransform._transformID;
                    _parentTransform   = optTransform;
                }
            }
            if (_parentTransform == null)
            {
                Debug.LogError("Opt Modifier Stack -> Null Opt Transform");
            }

            //Modifier를 Bake해주자
            for (int i = 0; i < modStack._modifiers.Count; i++)
            {
                apModifierBase modifier = modStack._modifiers[i];

                apOptModifierUnitBase optMod = new apOptModifierUnitBase();

                ////ModifierType에 맞게 상속된 클래스로 생성한다.
                //switch (modifier.ModifierType)
                //{
                //	case apModifierBase.MODIFIER_TYPE.Base:
                //		optMod = new apOptModifierUnitBase();
                //		break;

                //	case apModifierBase.MODIFIER_TYPE.AnimatedMorph:
                //		break;

                //	case apModifierBase.MODIFIER_TYPE.Morph:
                //		optMod = new apOptModifierUnit_Morph();//Morph
                //		break;

                //	case apModifierBase.MODIFIER_TYPE.Physic:
                //		break;

                //	case apModifierBase.MODIFIER_TYPE.Rigging:
                //		break;

                //	case apModifierBase.MODIFIER_TYPE.Volume:
                //		break;

                //	default:
                //		Debug.LogError("apOptModifierSubStack Bake : 알 수 없는 Mod 타입 : " + modifier.ModifierType);
                //		break;

                //}

                if (optMod != null)
                {
                    optMod.Bake(modifier, _portrait, isUseModMesh);
                    optMod.Link(_portrait, _parentTransform);

                    _modifiers.Add(optMod);
                }
            }

            _nModifiers = _modifiers.Count;
        }
예제 #30
0
        public void LinkModifierStackToRenderUnitCalculateStack(bool isRoot = true, apMeshGroup rootMeshGroup = null)
        {
            //전체 Modifier중에서 RenderUnit을 포함한 Modifer를 찾는다.
            //그 중, RenderUnit에 대한것만 처리할 CalculateResultParam을 만들고 연동한다.
            //ResultParam을 RenderUnit의 CalculateStack에 넣는다.

            //Debug.Log("--------------------------------------------------------------");
            //Debug.Log("LinkModifierStackToRenderUnitCalculateStack [" + _parentMeshGroup._name + "]");
            //Debug.Log("--------------------------------------------------------------");

            //수정
            //각 ModMesh에서 계층적인 Link를 할 수 있도록
            //RenderUnit을 매번 바꾸어주자
            if (isRoot)
            {
                rootMeshGroup = _parentMeshGroup;

                //Modifier-ParamSetGroup-ParamSet + ModMesh가 "실제 RenderUnit"과 링크되지 않으므로
                //Calculate Param을 만들기 전에 이 링크를 먼저 해주어야 한다.
            }



            //Modifier를 돌면서 ParamSet 데이터를 Calculated 데이터로 변환해서 옮긴다.
            for (int iMod = 0; iMod < _modifiers.Count; iMod++)
            {
                //Modifier ->..
                apModifierBase modifier = _modifiers[iMod];

                List <apModifierParamSetGroup> paramSetGroups = modifier._paramSetGroup_controller;

                for (int iGroup = 0; iGroup < paramSetGroups.Count; iGroup++)
                {
                    //Modifier -> ParamSetGroup ->..
                    apModifierParamSetGroup paramSetGroup = paramSetGroups[iGroup];

                    List <apModifierParamSet> paramSets = paramSetGroup._paramSetList;

                    for (int iParam = 0; iParam < paramSets.Count; iParam++)
                    {
                        //Modifier -> ParamSetGroup -> ParamSet ->...
                        apModifierParamSet paramSet = paramSets[iParam];

                        List <apModifiedMesh> modMeshes = paramSet._meshData;
                        List <apModifiedBone> modBones  = paramSet._boneData;

                        //1. Mod Mesh => Calculate Param으로 연결한다.
                        for (int iModMesh = 0; iModMesh < modMeshes.Count; iModMesh++)
                        {
                            //[핵심]
                            //Modifier -> ParamSetGroup -> ParamSet -> ModMeh
                            //이제 이 ModMesh와 타겟 Transform을 연결하자.
                            //연결할땐 Calculated 오브젝트를 만들어서 연결
                            apModifiedMesh modMesh = modMeshes[iModMesh];

                            #region [미사용 코드]
                            //여기서 수정
                            //Root가 아닐때 > RenderUnit을 자체적으로 세팅할게 아니라, Root MeshGroup을 기준으로 RenderUnit을 찾자
                            //if(!isRoot)
                            //{
                            //	apRenderUnit recursiveRenderUnit = null;
                            //	if(modMesh._isMeshTransform)
                            //	{
                            //		recursiveRenderUnit = rootMeshGroup.GetRenderUnit(modMesh._transform_Mesh);
                            //	}
                            //	else
                            //	{
                            //		recursiveRenderUnit = rootMeshGroup.GetRenderUnit(modMesh._transform_MeshGroup);
                            //	}
                            //	if(recursiveRenderUnit != null)
                            //	{
                            //		//Debug.Log("Link ModStack -> Child Render Unit Changed [Modifier : " + modifier.DisplayName + "] / RenderUnit Name : " + recursiveRenderUnit.Name + " / is Changed : " + (modMesh._renderUnit != recursiveRenderUnit));
                            //		//if(modMesh._renderUnit == null)
                            //		//{
                            //		//	Debug.LogError("기존 RenderUnit이 Null이다.");
                            //		//}
                            //		//else if(modMesh._renderUnit._meshGroup == null)
                            //		//{
                            //		//	Debug.LogError("기존 RenderUnit의 MeshGroup이 Null이다.");
                            //		//}
                            //		//else
                            //		//{
                            //		//	Debug.Log("[" + modMesh._renderUnit._meshGroup._name + " > " + rootMeshGroup._name + "]");
                            //		//}

                            //		modMesh._renderUnit = recursiveRenderUnit;
                            //	}
                            //	else
                            //	{
                            //		Debug.LogError("Re Link Failed");
                            //	}
                            //}

                            #endregion

                            if (modMesh._renderUnit == null)
                            {
                                continue;
                            }
                            //이미 만든 Calculate Param이 있는지 확인
                            apCalculatedResultParam existParam = modifier.GetCalculatedResultParam(modMesh._renderUnit);

                            //추가 : 만약 Calculated Param을 찾지 못했다면..
                            //Parent의 누군가가 이미 만들었을 수 있다!
                            //Root Parent MeshGroup에 요청해서 한번 더 확인하자
                            //(Calculated Result Param을 공유할 수 있기 때문)
                            if (existParam == null && rootMeshGroup != null)
                            {
                                //rootMeshGroup._modifierStack
                                //?? 이거 해야하나
                            }

                            apModifierParamSetGroupVertWeight weightedVertexData = null;
                            if (modMesh._transform_Mesh != null)
                            {
                                weightedVertexData = paramSetGroup.GetWeightVertexData(modMesh._transform_Mesh);
                            }

                            if (existParam != null)
                            {
                                //Debug.Log("> ModMesh [" + iModMesh + "] : " + modMesh._transformUniqueID + "< Add >");
                                existParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, modMesh, null);
                                existParam.LinkWeightedVertexData(weightedVertexData);

                                //if(!isRoot)
                                //{
                                //	Debug.LogWarning("Child Modifier의 CalculateParam을 찾아서 적용 : "
                                //		+ modifier.DisplayName + " / " + existParam._debugID + " / " + existParam._targetRenderUnit.Name);
                                //}
                            }
                            else
                            {
                                //Debug.Log("> ModMesh [" + iModMesh + "] : " + modMesh._transformUniqueID + "< New >");
                                //새로 Calculate Param을 만들고..
                                apCalculatedResultParam newCalParam = new apCalculatedResultParam(
                                    modifier.CalculatedValueType,
                                    modifier.CalculatedSpace,
                                    modifier,
                                    modMesh._renderUnit,
                                    null,                                    //<Bone은 없으닝께..
                                    weightedVertexData
                                    );

                                newCalParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, modMesh, null);

                                // Modifier에 등록하고
                                modifier._calculatedResultParams.Add(newCalParam);

                                //RenderUnit에도 등록을 하자
                                modMesh._renderUnit._calculatedStack.AddCalculatedResultParam(newCalParam);


                                //if(!isRoot)
                                //{
                                //	Debug.LogWarning("Child Modifier의 CalculateParam을 찾아서 적용 : "
                                //		+ modifier.DisplayName + " / " + newCalParam._debugID + " / " + newCalParam._targetRenderUnit.Name);
                                //}
                            }
                            //else
                            //{
                            //	Debug.LogError("Link Modifier Stack Error : No Render Unit (isRoot : " + isRoot + ")");
                            //}
                        }

                        //2. Mod Bone => Calculate Param으로 연결한다.
                        for (int iModBone = 0; iModBone < modBones.Count; iModBone++)
                        {
                            apModifiedBone modBone = modBones[iModBone];

                            if (modBone._bone == null || modBone._renderUnit == null)
                            {
                                Debug.LogError("ModBone -> Calculate Link 실패 : [Bone : " + (modBone._bone != null) + ", RenderUnit : " + (modBone._renderUnit != null) + "]");
                                continue;
                            }

                            //이미 만든 Calculate Param이 있는지 확인
                            apCalculatedResultParam existParam = modifier.GetCalculatedResultParam_Bone(modBone._renderUnit, modBone._bone);

                            if (existParam != null)
                            {
                                //이미 있다면 ModBone만 추가해주자
                                existParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, null, modBone);
                            }
                            else
                            {
                                //Debug.Log("Mod Bone -> Calculate Param 등록");
                                //새로 CalculateParam을 만들고
                                apCalculatedResultParam newCalParam = new apCalculatedResultParam(
                                    modifier.CalculatedValueType,
                                    modifier.CalculatedSpace,
                                    modifier,
                                    modBone._renderUnit,
                                    modBone._bone,
                                    null                                    //WeightedVertex
                                    );

                                newCalParam.AddParamSetAndModifiedValue(paramSetGroup, paramSet, null, modBone);

                                // Modifier에 등록하고
                                modifier._calculatedResultParams.Add(newCalParam);

                                //RenderUnit에도 등록을 하자
                                modBone._renderUnit._calculatedStack.AddCalculatedResultParam(newCalParam);
                            }
                        }
                    }
                }


                //SubList를 한번 정렬하자
                for (int iCal = 0; iCal < modifier._calculatedResultParams.Count; iCal++)
                {
                    modifier._calculatedResultParams[iCal].SortSubList();
                }
            }

            //추가>>
            //하위 객체에 대해서도 Link를 자동으로 수행한다.
            //다 끝나고 Sort
            List <apTransform_MeshGroup> childMeshGroupTransforms = _parentMeshGroup._childMeshGroupTransforms;

            apTransform_MeshGroup childMeshGroup = null;

            if (childMeshGroupTransforms != null && childMeshGroupTransforms.Count > 0)
            {
                for (int i = 0; i < childMeshGroupTransforms.Count; i++)
                {
                    childMeshGroup = childMeshGroupTransforms[i];
                    if (childMeshGroup._meshGroup != null && childMeshGroup._meshGroup != _parentMeshGroup)
                    {
                        childMeshGroup._meshGroup._modifierStack.LinkModifierStackToRenderUnitCalculateStack(false, rootMeshGroup);                        //<<여기서도 같이 수행
                    }
                }
            }

            if (isRoot)
            {
                //Debug.Log("Start Sort : " + _parentMeshGroup._name);
                //Root인 경우
                //RenderUnit들을 검사하면서 Calculated Stack에 대해서 Sort를 해주자
                List <apRenderUnit> renderUnits = _parentMeshGroup._renderUnits_All;
                for (int i = 0; i < renderUnits.Count; i++)
                {
                    renderUnits[i]._calculatedStack.Sort();
                }
            }
        }