// 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; }
//추가 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(); } } }
// Init //-------------------------------------------------------------- public apModifierParamSetGroupAnimPack(apModifierBase modifier, apAnimClip animClip) { _parentModifier = modifier; _linkedAnimClip = animClip; _paramSetGroups.Clear(); }
//------------------------------------------------------------------------------------------ // 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); }
// Init //------------------------------------------------- public apModifierParamSetGroup(apPortrait portrait, apModifierBase parentModifier, int layerIndex) { LinkPortrait(portrait, parentModifier); _layerIndex = layerIndex; _layerWeight = 1.0f; _blendMethod = BLEND_METHOD.Interpolation; }
//------------------------------------------------------------------------------------------ // 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); }
/// <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); }
/// <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); }
// 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; }
// 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; } }
public void LinkPortrait(apPortrait portrait, apModifierBase parentModifier) { _portrait = portrait; _parentModifier = parentModifier; if (_tmpMatrix == null) { _tmpMatrix = new apMatrix(); } if (_tmpPositions == null) { _tmpPositions = new List <Vector2>(); } }
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; } }
/// <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); }
//------------------------------------------------------------------------------------------ // 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); }
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); } }
//------------------------------------------------------------------------------------------ // 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)); }
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); }
// 에디터 관련 코드 //---------------------------------------------------- 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(); } } } } }
// 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); }
/// <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); } } } } }
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; }
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(); } } }