// Functions //-------------------------------------------- public void ReadyToCalculate() { _matrix.MakeMatrix(); //_matrix_TF_Cal_Parent = apMatrix3x3.identity; //_matrix_TF_Cal_Local = _matrix.MtrxToSpace; //if(_calculateTmpMatrix == null) //{ // _calculateTmpMatrix = new apMatrix(); //} //_calculateTmpMatrix.SetIdentity(); //_calculateTmpMatrix.SetMatrix(_matrix); //if(_calculateTmpMatrix_Local == null) //{ // _calculateTmpMatrix_Local = new apMatrix(); //} //_calculateTmpMatrix_Local.SetIdentity(); //_calculateTmpMatrix_Local.SetMatrix(_matrix); //변경 //[Parent World x To Parent x Local TF] 조합으로 변경 if (_matrix_TF_ParentWorld == null) { _matrix_TF_ParentWorld = new apMatrix(); } if (_matrix_TF_ToParent == null) { _matrix_TF_ToParent = new apMatrix(); } if (_matrix_TF_LocalModified == null) { _matrix_TF_LocalModified = new apMatrix(); } if (_matrix_TFResult_World == null) { _matrix_TFResult_World = new apMatrix(); } if (_matrix_TFResult_WorldWithoutMod == null) { _matrix_TFResult_WorldWithoutMod = new apMatrix(); } _matrix_TF_ParentWorld.SetIdentity(); _matrix_TF_ToParent.SetIdentity(); _matrix_TF_LocalModified.SetIdentity(); //ToParent는 Pivot이므로 고정 _matrix_TF_ToParent.SetMatrix(_matrix); _matrix_TFResult_World.SetIdentity(); _matrix_TFResult_WorldWithoutMod.SetIdentity(); }
public void TransformChanged_Position__MeshGroup_Setting(Vector2 pos, int depth) { if (Editor.Select.MeshGroup == null || !Editor.Select.IsMeshGroupSettingChangePivot) { return; } if (Editor.Select.SubMeshInGroup == null && Editor.Select.SubMeshGroupInGroup == null) { return; } apRenderUnit curRenderUnit = null; apMatrix curMatrixParam = null; object targetObj = null; if (Editor.Select.SubMeshInGroup != null) { curRenderUnit = Editor.Select.MeshGroup.GetRenderUnit(Editor.Select.SubMeshInGroup); curMatrixParam = Editor.Select.SubMeshInGroup._matrix; targetObj = Editor.Select.SubMeshInGroup; } else if (Editor.Select.SubMeshGroupInGroup != null) { curRenderUnit = Editor.Select.MeshGroup.GetRenderUnit(Editor.Select.SubMeshGroupInGroup); curMatrixParam = Editor.Select.SubMeshGroupInGroup._matrix; targetObj = Editor.Select.SubMeshGroupInGroup; } if (curRenderUnit == null) { return; } //Undo apEditorUtil.SetRecord_MeshGroup(apUndoGroupData.ACTION.MeshGroup_Gizmo_MoveTransform, Editor, Editor.Select.MeshGroup, targetObj, false, true); bool bSort = false; if (curRenderUnit.GetDepth() != depth) { //curRenderUnit.SetDepth(depth); Editor.Select.MeshGroup.ChangeRenderUnitDetph(curRenderUnit, depth); bSort = true; } curMatrixParam.SetPos(pos); curMatrixParam.MakeMatrix(); if (bSort) { Editor.Select.MeshGroup.SortRenderUnits(true); } Editor.SetRepaint(); }
public void Move__MeshGroup_Setting(Vector2 curMouseGL, Vector2 curMousePosW, Vector2 deltaMoveW, int btnIndex, bool isFirstMove) { if (Editor.Select.MeshGroup == null || !Editor.Select.IsMeshGroupSettingChangePivot) { return; } if (deltaMoveW.sqrMagnitude == 0.0f) { return; } apMatrix targetMatrix = null; object targetObj = null; apMatrix worldMatrix = null; apMatrix parentWorldMatrix = null; //Modifier가 적용이 안된 상태이므로 //World Matrix = ParentWorld x ToParent(Default) 가 성립한다. if (Editor.Select.SubMeshInGroup != null) { targetMatrix = Editor.Select.SubMeshInGroup._matrix; //=ToParent targetObj = Editor.Select.SubMeshInGroup; worldMatrix = new apMatrix(Editor.Select.SubMeshInGroup._matrix_TFResult_World); parentWorldMatrix = Editor.Select.SubMeshInGroup._matrix_TF_ParentWorld; } else if (Editor.Select.SubMeshGroupInGroup != null) { targetMatrix = Editor.Select.SubMeshGroupInGroup._matrix; //=ToParent targetObj = Editor.Select.SubMeshGroupInGroup; worldMatrix = new apMatrix(Editor.Select.SubMeshGroupInGroup._matrix_TFResult_World); parentWorldMatrix = Editor.Select.SubMeshGroupInGroup._matrix_TF_ParentWorld; } else { return; } worldMatrix._pos += deltaMoveW; worldMatrix.MakeMatrix(); worldMatrix.RInverse(parentWorldMatrix); //ParentWorld-1 x World = ToParent Vector2 newLocalPos = worldMatrix._pos; //Undo apEditorUtil.SetRecord(apUndoGroupData.ACTION.MeshGroup_Gizmo_MoveTransform, Editor.Select.MeshGroup, targetObj, false, Editor); //targetMatrix.SetPos(targetMatrix._pos.x + deltaMoveW.x, targetMatrix._pos.y + deltaMoveW.y); targetMatrix.SetPos(newLocalPos.x, newLocalPos.y); targetMatrix.MakeMatrix(); //Editor.RefreshControllerAndHierarchy(); }
public void Scale__MeshGroup_Setting(Vector2 deltaScaleW) { if (Editor.Select.MeshGroup == null || !Editor.Select.IsMeshGroupSettingChangePivot) { return; } if (deltaScaleW.sqrMagnitude == 0.0f) { return; } apMatrix targetMatrix = null; object targetObj = null; apMatrix worldMatrix = null; apMatrix parentWorldMatrix = null; //Modifier가 적용이 안된 상태이므로 //World Matrix = ParentWorld x ToParent(Default) 가 성립한다. if (Editor.Select.SubMeshInGroup != null) { targetMatrix = Editor.Select.SubMeshInGroup._matrix; targetObj = Editor.Select.SubMeshInGroup; worldMatrix = new apMatrix(Editor.Select.SubMeshInGroup._matrix_TFResult_World); parentWorldMatrix = Editor.Select.SubMeshInGroup._matrix_TF_ParentWorld; } else if (Editor.Select.SubMeshGroupInGroup != null) { targetMatrix = Editor.Select.SubMeshGroupInGroup._matrix; targetObj = Editor.Select.SubMeshGroupInGroup; worldMatrix = new apMatrix(Editor.Select.SubMeshGroupInGroup._matrix_TFResult_World); parentWorldMatrix = Editor.Select.SubMeshGroupInGroup._matrix_TF_ParentWorld; } else { return; } worldMatrix._scale += deltaScaleW; worldMatrix.MakeMatrix(); worldMatrix.RInverse(parentWorldMatrix); //ParentWorld-1 x World = ToParent //Undo apEditorUtil.SetRecord(apUndoGroupData.ACTION.MeshGroup_Gizmo_ScaleTransform, Editor.Select.MeshGroup, targetObj, false, Editor); //Vector2 scale2 = new Vector2(targetMatrix._scale.x, targetMatrix._scale.y); //targetMatrix.SetScale(deltaScaleW + scale2); targetMatrix.SetScale(worldMatrix._scale); targetMatrix.MakeMatrix(); }
//일단 파싱만 하고 계층 설정은 나중에 public bool DecodeData(string strSrc) { try { int nameLength = int.Parse(strSrc.Substring(0, 3)); _name = strSrc.Substring(3, nameLength); strSrc = strSrc.Substring(3 + nameLength); string[] strParse = strSrc.Split(new string[] { "/" }, StringSplitOptions.None); _unitID = int.Parse(strParse[0]); _type = (TYPE)int.Parse(strParse[1]); _uniqueID = int.Parse(strParse[2]); _defaultMatrix._pos.x = float.Parse(strParse[3]); _defaultMatrix._pos.y = float.Parse(strParse[4]); _defaultMatrix._angleDeg = float.Parse(strParse[5]); _defaultMatrix._scale.x = float.Parse(strParse[6]); _defaultMatrix._scale.y = float.Parse(strParse[7]); _defaultMatrix.MakeMatrix(); _defaultColor.r = float.Parse(strParse[8]); _defaultColor.g = float.Parse(strParse[9]); _defaultColor.b = float.Parse(strParse[10]); _defaultColor.a = float.Parse(strParse[11]); _isVisible = (int.Parse(strParse[12]) == 1 ? true : false); _parentUnitID = int.Parse(strParse[13]); int nChild = int.Parse(strParse[14]); _childUnitIDs.Clear(); for (int i = 0; i < nChild; i++) { _childUnitIDs.Add(int.Parse(strParse[15 + i])); } } catch (Exception ex) { Debug.LogError("DecodeData Exception : " + ex); return(false); } return(true); }
public bool DecodeData(string strSrc) { try { int nameLength = int.Parse(strSrc.Substring(0, 3)); _name = strSrc.Substring(3, nameLength); strSrc = strSrc.Substring(3 + nameLength); string[] strParse = strSrc.Split(new string[] { "/" }, StringSplitOptions.None); _unitID = int.Parse(strParse[0]); _uniqueID = int.Parse(strParse[1]); _defaultMatrix.SetIdentity(); _localMatrix.SetIdentity(); _worldMatrix.SetIdentity(); _defaultMatrix._pos.x = float.Parse(strParse[2]); _defaultMatrix._pos.y = float.Parse(strParse[3]); _defaultMatrix._angleDeg = float.Parse(strParse[4]); _defaultMatrix._scale.x = float.Parse(strParse[5]); _defaultMatrix._scale.y = float.Parse(strParse[6]); _defaultMatrix.MakeMatrix(); _localMatrix._pos.x = float.Parse(strParse[7]); _localMatrix._pos.y = float.Parse(strParse[8]); _localMatrix._angleDeg = float.Parse(strParse[9]); _localMatrix._scale.x = float.Parse(strParse[10]); _localMatrix._scale.y = float.Parse(strParse[11]); _localMatrix.MakeMatrix(); _worldMatrix._pos.x = float.Parse(strParse[12]); _worldMatrix._pos.y = float.Parse(strParse[13]); _worldMatrix._angleDeg = float.Parse(strParse[14]); _worldMatrix._scale.x = float.Parse(strParse[15]); _worldMatrix._scale.y = float.Parse(strParse[16]); _worldMatrix.MakeMatrix(); } catch (Exception ex) { Debug.LogError("DecodeData Exception : " + ex); return(false); } return(true); }
public void TransformChanged_Rotate__MeshGroup_Setting(float angle) { if (Editor.Select.MeshGroup == null || !Editor.Select.IsMeshGroupSettingChangePivot) { return; } if (Editor.Select.SubMeshInGroup == null && Editor.Select.SubMeshGroupInGroup == null) { return; } apRenderUnit curRenderUnit = null; apMatrix curMatrixParam = null; object targetObj = null; if (Editor.Select.SubMeshInGroup != null) { curRenderUnit = Editor.Select.MeshGroup.GetRenderUnit(Editor.Select.SubMeshInGroup); curMatrixParam = Editor.Select.SubMeshInGroup._matrix; targetObj = Editor.Select.SubMeshInGroup; } else if (Editor.Select.SubMeshGroupInGroup != null) { curRenderUnit = Editor.Select.MeshGroup.GetRenderUnit(Editor.Select.SubMeshGroupInGroup); curMatrixParam = Editor.Select.SubMeshGroupInGroup._matrix; targetObj = Editor.Select.SubMeshGroupInGroup; } if (curRenderUnit == null) { return; } //Undo apEditorUtil.SetRecord_MeshGroup(apUndoGroupData.ACTION.MeshGroup_Gizmo_RotateTransform, Editor, Editor.Select.MeshGroup, targetObj, false, true); curMatrixParam.SetRotate(angle); curMatrixParam.MakeMatrix(); Editor.SetRepaint(); }
// 데이터 리셋 //------------------------------------------------------------------ /// <summary> /// 저장되는 ModifiedValue의 데이터들을 처리 준비하게 해준다. /// 값 초기화는 Reset에서 한다. 주의주의 /// </summary> public void RefreshModifiedValues(apPortrait portrait) { if ((int)(_modValueType & MOD_VALUE_TYPE.VertexPosList) != 0) { RefreshVertices(); } else if ((int)(_modValueType & MOD_VALUE_TYPE.TransformMatrix) != 0) { _transformMatrix.MakeMatrix(); } else if ((int)(_modValueType & MOD_VALUE_TYPE.Color) != 0) { //_meshColor = new Color(0.5f, 0.5f, 0.5f, 1.0f);//2X 칼라 초기화 } else if ((int)(_modValueType & MOD_VALUE_TYPE.BoneVertexWeightList) != 0) { //Debug.LogError("TODO : ModMesh BoneVertexWeightList 타입 정의 필요"); //Debug.Log("ModMesh Link RenderUnit >> Bone Vertex Weight List"); RefreshVertexRigs(portrait); } else if ((int)(_modValueType & MOD_VALUE_TYPE.VertexWeightList_Physics) != 0) { //물리 타입의 Weight RefreshVertexWeights(portrait, true, false); } else if ((int)(_modValueType & MOD_VALUE_TYPE.VertexWeightList_Volume) != 0) { //물리 값을 사용하지 않는 Weight RefreshVertexWeights(portrait, false, true); } else if ((int)(_modValueType & MOD_VALUE_TYPE.FFD) != 0) { Debug.LogError("TODO : ModMesh FFD 타입 정의 필요"); } else { Debug.LogError("TODO : 알 수 없는 ModMesh Value Type : " + _modValueType); } }
/// <summary> /// BlendMatrix_ITP의 역연산 중 TargetLayer에서 최종 결과값을 만드는 과정. /// [ X = (inverseUpperLayer - (lowerLayer * (1 - weight))) / (weight) ] /// weight가 0이면 Null 리턴 /// </summary> /// <param name="curMatrix"></param> /// <param name="subtractedLayer"></param> /// <param name="weight"></param> public apMatrix InverseBlendMatrixTarget_ITP(apMatrix invUpperLayerResult, apMatrix lowerLayerResult, apMatrix targetLayer, float weight) { if (weight <= 0.0f) { return(null); } // ( InvUpperLayer - (lowerLayer * (1-weight)) ) / weight apMatrix result = new apMatrix(); result._pos.x = (invUpperLayerResult._pos.x - lowerLayerResult._pos.x * (1.0f - weight)) / weight; result._pos.y = (invUpperLayerResult._pos.y - lowerLayerResult._pos.y * (1.0f - weight)) / weight; result._angleDeg = (invUpperLayerResult._angleDeg - lowerLayerResult._angleDeg * (1.0f - weight)) / weight; result._scale.x = (invUpperLayerResult._scale.x - lowerLayerResult._scale.x * (1.0f - weight)) / weight; result._scale.y = (invUpperLayerResult._scale.y - lowerLayerResult._scale.y * (1.0f - weight)) / weight; //result._scale.z = (invUpperLayerResult._scale.z - lowerLayerResult._scale.z * (1.0f - weight)) / weight; result.MakeMatrix(); return(result); }
/// <summary> /// BlendMatrix_ITP의 역연산. [ (curMatrix - (subtractedLayer * weight)) / (1-weight) ] /// weight가 1이면 Identity로 만든다. /// </summary> /// <param name="curMatrix"></param> /// <param name="subtractedLayer"></param> /// <param name="weight"></param> public void InverseBlendMatrix_ITP(apMatrix curMatrix, apMatrix subtractedLayer, float weight) { if (weight >= 1.0f) { curMatrix.SetIdentity(); return; } if (weight <= 0.0f) { //처리하지 않는다. return; } curMatrix._pos.x = (curMatrix._pos.x - subtractedLayer._pos.x * weight) / (1.0f - weight); curMatrix._pos.y = (curMatrix._pos.y - subtractedLayer._pos.y * weight) / (1.0f - weight); curMatrix._angleDeg = (curMatrix._angleDeg - subtractedLayer._angleDeg * weight) / (1.0f - weight); curMatrix._scale.x = (curMatrix._scale.x - subtractedLayer._scale.x * weight) / (1.0f - weight); curMatrix._scale.y = (curMatrix._scale.y - subtractedLayer._scale.y * weight) / (1.0f - weight); //curMatrix._scale.z = (curMatrix._scale.z - subtractedLayer._scale.z * weight) / (1.0f - weight); curMatrix.MakeMatrix(); }
public apMatrix GetSubInverseLayeredMatrix(apCalculatedLog targetLog, apCalculatedLog parentLog, apMatrix parentMatrix) { apMatrix invUpperLayerMatrix = new apMatrix(parentMatrix); apMatrix lowerLayerMatrix = new apMatrix(); //타겟보다 낮은 레이어는 따로 합을 구한다. LOG_TYPE layerLogType = targetLog._logType; int nLayers = 0; int iLayer = -1; if (layerLogType == LOG_TYPE.Layer_CalParamResult) { nLayers = parentLog._childCalParamResultLogs.Count; iLayer = parentLog._childCalParamResultLogs.IndexOf(targetLog); } else if (layerLogType == LOG_TYPE.Layer_ParamSetGroup) { nLayers = parentLog._childLayerLogs.Count; iLayer = parentLog._childLayerLogs.IndexOf(targetLog); } else { Debug.LogError("Layer가 없는 LogType [" + layerLogType + "] 이다"); return(null); } if (iLayer < 0) { Debug.LogError("존재하지 않는 Log [" + layerLogType + "]"); return(null); } lowerLayerMatrix.SetIdentity(); //Debug.LogWarning(">> Lower To Layer [0 > " + iLayer + "]"); //낮은 레이어에서는 값을 더하자 if (iLayer > 0) { for (int i = 0; i < iLayer; i++) { apCalculatedLog calLog = null; apMatrix calMatrix = null; switch (layerLogType) { case LOG_TYPE.Layer_CalParamResult: calLog = parentLog._childCalParamResultLogs[i]; calMatrix = calLog._calResultParam._result_Matrix; break; case LOG_TYPE.Layer_ParamSetGroup: calLog = parentLog._childLayerLogs[i]; calMatrix = calLog._paramSetGroup._tmpMatrix; break; } float weight = calLog._weight; if (!calLog._isWeight) { weight = 1.0f; } //string prevMatrix = lowerLayerMatrix.ToString(); if (i == 0) { lowerLayerMatrix.SetPos(calMatrix._pos * weight); lowerLayerMatrix.SetRotate(calMatrix._angleDeg * weight); lowerLayerMatrix.SetScale(calMatrix._scale * weight + Vector2.one * (1.0f - weight)); lowerLayerMatrix.MakeMatrix(); } else { switch (calLog._layerBlendType) { case BLEND_METHOD.Interpolation: BlendMatrix_ITP(lowerLayerMatrix, calMatrix, weight); //Debug.Log("[" + i + "] ITP/" + weight + " : " + prevMatrix + " >> " + calMatrix + " => " + lowerLayerMatrix); break; case BLEND_METHOD.Additive: BlendMatrix_Add(lowerLayerMatrix, calMatrix, weight); //Debug.Log("[" + i + "] ADD/" + weight + " : " + prevMatrix + " >> " + calMatrix + " => " + lowerLayerMatrix); break; } } } } //Debug.LogWarning(">> Upper To Layer [" + (nLayers - 1) + " > " + iLayer + "]"); //위 레이어에서는 값을 빼자 if (iLayer < nLayers - 1) { for (int i = (nLayers - 1); i >= iLayer + 1; i--) { apCalculatedLog calLog = null; apMatrix calMatrix = null; switch (layerLogType) { case LOG_TYPE.Layer_CalParamResult: calLog = parentLog._childCalParamResultLogs[i]; calMatrix = calLog._calResultParam._result_Matrix; break; case LOG_TYPE.Layer_ParamSetGroup: calLog = parentLog._childLayerLogs[i]; calMatrix = calLog._paramSetGroup._tmpMatrix; break; } float weight = calLog._weight; if (!calLog._isWeight) { weight = 1.0f; } switch (calLog._layerBlendType) { case BLEND_METHOD.Interpolation: InverseBlendMatrix_ITP(invUpperLayerMatrix, calMatrix, weight); break; case BLEND_METHOD.Additive: InverseBlendMatrix_Add(invUpperLayerMatrix, calMatrix, weight); break; } } } apMatrix result = null; float weight_calParam = targetLog._weight; if (!targetLog._isWeight) { weight_calParam = 1.0f; } apMatrix calTargetMatrix = null; switch (layerLogType) { case LOG_TYPE.Layer_CalParamResult: calTargetMatrix = targetLog._calResultParam._result_Matrix; break; case LOG_TYPE.Layer_ParamSetGroup: calTargetMatrix = targetLog._paramSetGroup._tmpMatrix; break; } switch (targetLog._layerBlendType) { case BLEND_METHOD.Additive: result = InverseBlendMatrixTarget_Add(invUpperLayerMatrix, lowerLayerMatrix, calTargetMatrix, weight_calParam); break; case BLEND_METHOD.Interpolation: result = InverseBlendMatrixTarget_ITP(invUpperLayerMatrix, lowerLayerMatrix, calTargetMatrix, weight_calParam); break; } if (result == null) { return(null); } return(result); }
// Functions //--------------------------------------------------- public void ReadyToCalculate() { if (_isAnyVertLocal || _isAnyVertWorld || _isAnyRigging) { if (_result_VertLocal == null || _result_VertLocal.Length != _parentRenderUnit._renderVerts.Count) { //RenderUnit의 RenderVertex 개수 만큼 결과를 만들자 //_result_VertLocal = new List<Vector2>(); //_result_VertWorld = new List<Vector2>(); _result_VertLocal = new Vector2[_parentRenderUnit._renderVerts.Count]; _result_VertWorld = new Vector2[_parentRenderUnit._renderVerts.Count]; _result_Rigging = new Vector2[_parentRenderUnit._renderVerts.Count]; _result_RiggingWeight = 0.0f; //_result_VertLocal.Initialize(); //_result_VertWorld.Initialize(); for (int i = 0; i < _parentRenderUnit._renderVerts.Count; i++) { _result_VertLocal[i] = Vector2.zero; _result_VertWorld[i] = Vector2.zero; _result_Rigging[i] = Vector2.zero; } } else { //_result_VertLocal.Initialize(); //_result_VertWorld.Initialize(); //for (int i = 0; i < _result_VertLocal.Count; i++) //{ // _result_VertLocal[i] = Vector2.zero; // _result_VertWorld[i] = Vector2.zero; //} for (int i = 0; i < _result_VertLocal.Length; i++) { _result_VertLocal[i] = Vector2.zero; _result_VertWorld[i] = Vector2.zero; _result_Rigging[i] = Vector2.zero; } _result_RiggingWeight = 0.0f; } } _result_BoneTransform.SetIdentity(); _result_MeshTransform.SetIdentity(); _result_MeshTransform.MakeMatrix(); _result_Color = _color_Default; _result_IsVisible = true; _result_CalculatedColor = false; //>>> CalculateLog 초기화 CalculateLog_0_Rigging.ReadyToRecord(); CalculateLog_1_StaticMesh.ReadyToRecord(); CalculateLog_2_VertLocal.ReadyToRecord(); CalculateLog_3_MeshTransform.ReadyToRecord(); CalculateLog_4_VertWorld.ReadyToRecord(); CalculateLog_0_Rigging.LinkLog_CalResultStackLayer(CalculateLog_0_Rigging, CalculateLog_1_StaticMesh, CalculateLog_2_VertLocal, CalculateLog_3_MeshTransform, CalculateLog_4_VertWorld); CalculateLog_1_StaticMesh.LinkLog_CalResultStackLayer(CalculateLog_0_Rigging, CalculateLog_1_StaticMesh, CalculateLog_2_VertLocal, CalculateLog_3_MeshTransform, CalculateLog_4_VertWorld); CalculateLog_2_VertLocal.LinkLog_CalResultStackLayer(CalculateLog_0_Rigging, CalculateLog_1_StaticMesh, CalculateLog_2_VertLocal, CalculateLog_3_MeshTransform, CalculateLog_4_VertWorld); CalculateLog_3_MeshTransform.LinkLog_CalResultStackLayer(CalculateLog_0_Rigging, CalculateLog_1_StaticMesh, CalculateLog_2_VertLocal, CalculateLog_3_MeshTransform, CalculateLog_4_VertWorld); CalculateLog_4_VertWorld.LinkLog_CalResultStackLayer(CalculateLog_0_Rigging, CalculateLog_1_StaticMesh, CalculateLog_2_VertLocal, CalculateLog_3_MeshTransform, CalculateLog_4_VertWorld); }
/// <summary> /// 4) World Matrix를 만든다. /// 이 함수는 Parent의 MeshGroupTransform이 연산된 후 -> Vertex가 연산되기 전에 호출되어야 한다. /// </summary> public void MakeWorldMatrix(bool isRecursive) { _localMatrix.SetIdentity(); _localMatrix._pos = _deltaPos; _localMatrix._angleDeg = _deltaAngle; _localMatrix._scale.x = _deltaScale.x; _localMatrix._scale.y = _deltaScale.y; _localMatrix.MakeMatrix(); //World Matrix = ParentMatrix x LocalMatrix //Root인 경우에는 MeshGroup의 Matrix를 이용하자 //_invWorldMatrix_NonModified.SetIdentity(); if (_parentBone == null) { _worldMatrix.SetMatrix(_defaultMatrix); _worldMatrix.Add(_localMatrix); _worldMatrix_NonModified.SetMatrix(_defaultMatrix); //Local Matrix 없이 Default만 지정 if (_parentOptTransform != null) { //Debug.Log("SetParentOptTransform Matrix : [" + _parentOptTransform.transform.name + "] : " + _parentOptTransform._matrix_TFResult_World.Scale2); //Non Modified도 동일하게 적용 //렌더유닛의 WorldMatrix를 넣어주자 _worldMatrix.RMultiply(_parentOptTransform._matrix_TFResult_World); //RenderUnit의 WorldMatrixWrap의 Opt 버전 _worldMatrix_NonModified.RMultiply(_parentOptTransform._matrix_TFResult_WorldWithoutMod); } } else { _worldMatrix.SetMatrix(_defaultMatrix); _worldMatrix.Add(_localMatrix); _worldMatrix.RMultiply(_parentBone._worldMatrix); _worldMatrix_NonModified.SetMatrix(_defaultMatrix); //Local Matrix 없이 Default만 지정 _worldMatrix_NonModified.RMultiply(_parentBone._worldMatrix_NonModified); } //World Matrix는 MeshGroup과 동일한 Space의 값을 가진다. //그러나 실제로 Bone World Matrix는 //Root - MeshGroup...(Rec) - Bone Group - Bone.. (Rec <- 여기) //의 레벨을 가진다. //Root 밑으로는 모두 World에 대해서 동일한 Space를 가지므로 //Root를 찾아서 Scale을 제어하자...? //일단 Parent에서 빼두자 //_transformLocalMatrix.SetMatrix(_worldMatrix); #if UNITY_EDITOR _shapePoint_End = new Vector2(0.0f, _shapeLength); _shapePoint_Mid1 = new Vector2(-_shapeWidth * 0.5f, _shapeLength * 0.2f); _shapePoint_Mid2 = new Vector2(_shapeWidth * 0.5f, _shapeLength * 0.2f); float taperRatio = Mathf.Clamp01((float)(100 - _shapeTaper) / 100.0f); _shapePoint_End1 = new Vector2(-_shapeWidth * 0.5f * taperRatio, _shapeLength); _shapePoint_End2 = new Vector2(_shapeWidth * 0.5f * taperRatio, _shapeLength); _shapePoint_End = _worldMatrix.MtrxToSpace.MultiplyPoint(_shapePoint_End); _shapePoint_Mid1 = _worldMatrix.MtrxToSpace.MultiplyPoint(_shapePoint_Mid1); _shapePoint_Mid2 = _worldMatrix.MtrxToSpace.MultiplyPoint(_shapePoint_Mid2); _shapePoint_End1 = _worldMatrix.MtrxToSpace.MultiplyPoint(_shapePoint_End1); _shapePoint_End2 = _worldMatrix.MtrxToSpace.MultiplyPoint(_shapePoint_End2); #endif if (_socketTransform != null) { //소켓을 업데이트 하자 _socketTransform.localPosition = new Vector3(_worldMatrix._pos.x, _worldMatrix._pos.y, 0); _socketTransform.localRotation = Quaternion.Euler(0.0f, 0.0f, _worldMatrix._angleDeg); _socketTransform.localScale = _worldMatrix._scale; } //if (string.Equals(name, "Bone 2 Debug")) //{ // //디버그를 해보자 // Debug.Log("------- Bone Matrix [" + name + "] ------- (Runtime)"); // Debug.Log("Default Matrix [" + _defaultMatrix.ToString() + "]"); // Debug.Log("Local Matrix [" + _localMatrix.ToString() + "]"); // if (_parentBone != null) // { // Debug.Log("Parent(" + _parentBone.name + ")"); // Debug.Log(">> World Matrix [" + _parentBone._worldMatrix.ToString() + "]"); // Debug.Log(">> World Matrix No Mod [" + _parentBone._worldMatrix_NonModified.ToString() + "]"); // } // Debug.Log("World Matrix [" + _worldMatrix.ToString() + "]"); // Debug.Log("World Matrix No Mod [" + _worldMatrix_NonModified.ToString() + "]"); // Debug.Log("-----------------------------------------"); //} //Child도 호출해준다. if (isRecursive && _childBones != null) { for (int i = 0; i < _childBones.Length; i++) { _childBones[i].MakeWorldMatrix(true); } } }
public void ReadyToCalculate() { //TODO : 여기서부터 작성 if (_targetOptMesh == null) { if (_isAnyVertLocal) { Debug.LogError("AnyPortrait : Error No Mesh"); } return; } int nRenderVerts = _targetOptMesh.RenderVertices.Length; //수정 3.22 //따로 리셋하자. if (_isAnyVertLocal) { if (_result_VertLocal == null || _result_VertLocal.Length != nRenderVerts) { _result_VertLocal = new Vector2[nRenderVerts]; } for (int i = 0; i < nRenderVerts; i++) { _result_VertLocal[i] = Vector2.zero; } } if (_isAnyVertWorld) { if (_result_VertWorld == null || _result_VertWorld.Length != nRenderVerts) { _result_VertWorld = new Vector2[nRenderVerts]; } for (int i = 0; i < nRenderVerts; i++) { _result_VertWorld[i] = Vector2.zero; } } if (_isAnyRigging) { if (_result_RiggingMatrices == null || _result_RiggingMatrices.Length != nRenderVerts) { _result_RiggingMatrices = new apMatrix3x3[nRenderVerts]; } for (int i = 0; i < nRenderVerts; i++) { _result_RiggingMatrices[i].SetIdentity(); } _result_RiggingWeight = 0.0f; } #region [미사용 코드 : 모디파이어에 따라 다 분리시켰다] //if (_isAnyVertLocal || _isAnyVertWorld || _isAnyRigging) //{ // if (_result_VertLocal == null || _result_VertLocal.Length != _targetOptMesh.RenderVertices.Length) // { // //RenderUnit의 RenderVertex 개수 만큼 결과를 만들자 // _result_VertLocal = new Vector2[_targetOptMesh.RenderVertices.Length]; // _result_VertWorld = new Vector2[_targetOptMesh.RenderVertices.Length]; // //_result_Rigging = new Vector2[_targetOptMesh.RenderVertices.Length]; // _result_RiggingMatrices = new apMatrix3x3[_targetOptMesh.RenderVertices.Length]; // _result_RiggingWeight = 0.0f; // for (int i = 0; i < nRenderVerts; i++) // { // _result_VertLocal[i] = Vector2.zero; // _result_VertWorld[i] = Vector2.zero; // //_result_Rigging[i] = Vector2.zero; // _result_RiggingMatrices[i].SetIdentity(); // } // } // else // { // _result_RiggingWeight = 0.0f; // for (int i = 0; i < _result_VertLocal.Length; i++) // { // _result_VertLocal[i] = Vector2.zero; // _result_VertWorld[i] = Vector2.zero; // //_result_Rigging[i] = Vector2.zero; // _result_RiggingMatrices[i].SetIdentity(); // } // } //} //_result_BoneTransform.SetIdentity(); //_result_MeshTransform.SetIdentity(); //_result_MeshTransform.MakeMatrix(); ////_result_Color = _color_Default; //_result_Color = _parentOptTransform._meshColor2X_Default; //if (!_parentOptTransform._isVisible_Default) //{ // _result_Color.a = 0.0f; //} #endregion _result_MeshTransform.SetIdentity(); _result_MeshTransform.MakeMatrix(); _result_Color = _parentOptTransform._meshColor2X_Default; if (!_parentOptTransform._isVisible_Default) { _result_Color.a = 0.0f; } _result_BoneTransform.SetIdentity(); _result_IsVisible = true; _result_CalculatedColor = false; }
///// <summary> ///// 초기화/3) Parent Matrix를 넣는다. 바뀐게 없다면 더 호출하지 않아도 된다. ///// (에디터에서 메뉴에서 선택시, 처음 초기화시 호출해야함) ///// </summary> ///// <param name="parentMatrix"></param> //public void SetParentMatrix(apMatrix parentMatrix) //{ // _parentMatrix = parentMatrix; //} /// <summary> /// 4) World Matrix를 만든다. /// 이 함수는 Parent의 MeshGroupTransform이 연산된 후 -> Vertex가 연산되기 전에 호출되어야 한다. /// </summary> public void MakeWorldMatrix(bool isRecursive) { _localMatrix.SetIdentity(); _localMatrix._pos = _deltaPos; _localMatrix._angleDeg = _deltaAngle; _localMatrix._scale.x = _deltaScale.x; _localMatrix._scale.y = _deltaScale.y; _localMatrix.MakeMatrix(); //World Matrix = ParentMatrix x LocalMatrix //Root인 경우에는 MeshGroup의 Matrix를 이용하자 //_invWorldMatrix_NonModified.SetIdentity(); if (_parentBone == null) { _worldMatrix.SetMatrix(_defaultMatrix); _worldMatrix_NonModified.SetMatrix(_defaultMatrix); if (_isRigTestPosing) { _worldMatrix.Add(_rigTestMatrix); //Rig Test 추가 } _worldMatrix.Add(_localMatrix); if (_renderUnit != null) { //Non Modified도 동일하게 적용 //렌더유닛의 WorldMatrix를 넣어주자 //_worldMatrix.RMultiply(_renderUnit._meshGroup._rootMeshGroupTransform._matrix); _worldMatrix.RMultiply(_renderUnit.WorldMatrixWrap); _worldMatrix_NonModified.RMultiply(_renderUnit.WorldMatrixWrapWithoutModified); ////Inverse도 만들어주자 ////Inverse의 시작점부터 //if (_renderUnit._meshTransform != null)//TODO : 이거 고칠것 (MeshGroup Transform 포함하게) //{ // _invWorldMatrix.SetMatrix(_renderUnit._meshTransform._invMatrix_TFResult_World); // _invWorldMatrix_NonModified.SetMatrix(_renderUnit._meshTransform._invMatrix_TFResult_WorldWithoutMod); // //_invWorldMatrix_NonModified.SetIdentity(); // //_invWorldMatrix_NonModified.RInverse(_renderUnit._meshTransform._invMatrix_TFResult_WorldWithoutMod); //} } //else //{ // _invWorldMatrix.SetIdentity(); // _invWorldMatrix_NonModified.SetIdentity(); //} } else { _worldMatrix.SetMatrix(_defaultMatrix); _worldMatrix_NonModified.SetMatrix(_defaultMatrix); if (_isRigTestPosing) { _worldMatrix.Add(_rigTestMatrix); //Rig Test 추가 } _worldMatrix.Add(_localMatrix); _worldMatrix.RMultiply(_parentBone._worldMatrix); //주의, Parent의 NonModifiedMatrix를 적용할 것 _worldMatrix_NonModified.RMultiply(_parentBone._worldMatrix_NonModified); //Inverse를 적용하자 //_invWorldMatrix.SetMatrix(_parentBone._invWorldMatrix); //_invWorldMatrix_NonModified.SetMatrix(_parentBone._invWorldMatrix_NonModified); //_invWorldMatrix_NonModified.SetIdentity(); //_invWorldMatrix_NonModified.RInverse(_parentBone._invWorldMatrix_NonModified); } ////Inverse 이어서 작업 //_invWorldMatrix.RInverse(_localMatrix); //if(_isRigTestPosing) //{ // _invWorldMatrix.Subtract(_rigTestMatrix); //} //_invWorldMatrix.Subtract(_defaultMatrix); //_invWorldMatrix_NonModified.RInverse(_defaultMatrix); ////_invWorldMatrix_NonModified.Subtract(_defaultMatrix); //if (string.Equals(_name, "Bone 2 Debug")) //{ // //디버그를 해보자 // Debug.Log("------- Bone Matrix [" + _name + "] ------- (Editor)"); // Debug.Log("Default Matrix [" + _defaultMatrix.ToString() + "]"); // Debug.Log("Local Matrix [" + _localMatrix.ToString() + "]"); // if (_parentBone != null) // { // Debug.Log("Parent(" + _parentBone._name + ")"); // Debug.Log(">> World Matrix [" + _parentBone._worldMatrix.ToString() + "]"); // Debug.Log(">> World Matrix No Mod [" + _parentBone._worldMatrix_NonModified.ToString() + "]"); // } // Debug.Log("World Matrix [" + _worldMatrix.ToString() + "]"); // Debug.Log("World Matrix No Mod [" + _worldMatrix_NonModified.ToString() + "]"); // Debug.Log("-----------------------------------------"); //} //Child도 호출해준다. if (isRecursive) { for (int i = 0; i < _childBones.Count; i++) { _childBones[i].MakeWorldMatrix(true); } } }
public void Rotate__MeshGroup_Setting(float deltaAngleW, bool isFirstRotate) { if (Editor.Select.MeshGroup == null || !Editor.Select.IsMeshGroupSettingChangePivot) { return; } if (deltaAngleW == 0.0f && !isFirstRotate) { return; } apMatrix targetMatrix = null; object targetObj = null; apMatrix worldMatrix = null; apMatrix parentWorldMatrix = null; bool isRootMeshGroup = false; if (Editor.Select.SubMeshInGroup != null) { targetMatrix = Editor.Select.SubMeshInGroup._matrix; targetObj = Editor.Select.SubMeshInGroup; worldMatrix = new apMatrix(Editor.Select.SubMeshInGroup._matrix_TFResult_World); parentWorldMatrix = Editor.Select.SubMeshInGroup._matrix_TF_ParentWorld; isRootMeshGroup = Editor.Select.MeshGroup._childMeshTransforms.Contains(Editor.Select.SubMeshInGroup); } else if (Editor.Select.SubMeshGroupInGroup != null) { targetMatrix = Editor.Select.SubMeshGroupInGroup._matrix; targetObj = Editor.Select.SubMeshGroupInGroup; worldMatrix = new apMatrix(Editor.Select.SubMeshGroupInGroup._matrix_TFResult_World); parentWorldMatrix = Editor.Select.SubMeshGroupInGroup._matrix_TF_ParentWorld; isRootMeshGroup = false; } else { return; } float nextAngle = worldMatrix._angleDeg + deltaAngleW; while (nextAngle < -180.0f) { nextAngle += 360.0f; } while (nextAngle > 180.0f) { nextAngle -= 360.0f; } worldMatrix._angleDeg = nextAngle; worldMatrix.MakeMatrix(); worldMatrix.RInverse(parentWorldMatrix); //ParentWorld-1 x World = ToParent //Undo if (isFirstRotate) { apEditorUtil.SetRecord_MeshGroup(apUndoGroupData.ACTION.MeshGroup_Gizmo_RotateTransform, Editor, Editor.Select.MeshGroup, targetObj, false, !isRootMeshGroup); } //targetMatrix.SetRotate(deltaAngleW + targetMatrix._angleDeg); targetMatrix.SetRotate(worldMatrix._angleDeg); targetMatrix.MakeMatrix(); }
// 4) World Matrix를 만든다. // 이 함수는 Parent의 MeshGroupTransform이 연산된 후 -> Vertex가 연산되기 전에 호출되어야 한다. public void MakeWorldMatrix(bool isRecursive) { _localMatrix.SetIdentity(); _localMatrix._pos = _deltaPos; _localMatrix._angleDeg = _deltaAngle; _localMatrix._scale.x = _deltaScale.x; _localMatrix._scale.y = _deltaScale.y; _localMatrix.MakeMatrix(); //World Matrix = ParentMatrix x LocalMatrix //Root인 경우에는 MeshGroup의 Matrix를 이용하자 //_invWorldMatrix_NonModified.SetIdentity(); if (_parentBone == null) { _worldMatrix.SetMatrix(_defaultMatrix); _worldMatrix.Add(_localMatrix); _worldMatrix_NonModified.SetMatrix(_defaultMatrix); //Local Matrix 없이 Default만 지정 if (_parentOptTransform != null) { //Debug.Log("SetParentOptTransform Matrix : [" + _parentOptTransform.transform.name + "] : " + _parentOptTransform._matrix_TFResult_World.Scale2); //Non Modified도 동일하게 적용 //렌더유닛의 WorldMatrix를 넣어주자 _worldMatrix.RMultiply(_parentOptTransform._matrix_TFResult_World); //RenderUnit의 WorldMatrixWrap의 Opt 버전 _worldMatrix_NonModified.RMultiply(_parentOptTransform._matrix_TFResult_WorldWithoutMod); } } else { _worldMatrix.SetMatrix(_defaultMatrix); _worldMatrix.Add(_localMatrix); _worldMatrix.RMultiply(_parentBone._worldMatrix); _worldMatrix_NonModified.SetMatrix(_defaultMatrix); //Local Matrix 없이 Default만 지정 _worldMatrix_NonModified.RMultiply(_parentBone._worldMatrix_NonModified); } //처리된 TRS _updatedWorldPos_NoRequest.x = _worldMatrix._pos.x; _updatedWorldPos_NoRequest.y = _worldMatrix._pos.y; _updatedWorldAngle_NoRequest = _worldMatrix._angleDeg; _updatedWorldScale_NoRequest.x = _worldMatrix._scale.x; _updatedWorldScale_NoRequest.y = _worldMatrix._scale.y; _updatedWorldPos = _updatedWorldPos_NoRequest; _updatedWorldAngle = _updatedWorldAngle_NoRequest; _updatedWorldScale = _updatedWorldScale_NoRequest; if (_isIKCalculated) { _IKRequestAngleResult -= 90.0f; while (_IKRequestAngleResult > 180.0f) { _IKRequestAngleResult -= 360.0f; } while (_IKRequestAngleResult < -180.0f) { _IKRequestAngleResult += 360.0f; } //_updatedWorldAngle += _IKRequestAngleResult * _IKRequestWeight; _updatedWorldAngle = _updatedWorldAngle * (1.0f - _IKRequestWeight) + (_IKRequestAngleResult * _IKRequestWeight); //Debug.Log("Add IK [" + _name + "] : " + _IKRequestAngleResult); _IKRequestAngleResult = 0.0f; _IKRequestWeight = 0.0f; } //스크립트로 외부에서 제어한 경우 if (_isExternalUpdate_Position) { _updatedWorldPos.x = (_exUpdate_Pos.x * _externalUpdateWeight) + (_updatedWorldPos.x * (1.0f - _externalUpdateWeight)); _updatedWorldPos.y = (_exUpdate_Pos.y * _externalUpdateWeight) + (_updatedWorldPos.y * (1.0f - _externalUpdateWeight)); } if (_isExternalUpdate_Rotation) { _updatedWorldAngle = (_exUpdate_Angle * _externalUpdateWeight) + (_updatedWorldAngle * (1.0f - _externalUpdateWeight)); } if (_isExternalUpdate_Scaling) { _updatedWorldScale.x = (_exUpdate_Scale.x * _externalUpdateWeight) + (_updatedWorldScale.x * (1.0f - _externalUpdateWeight)); _updatedWorldScale.y = (_exUpdate_Scale.y * _externalUpdateWeight) + (_updatedWorldScale.y * (1.0f - _externalUpdateWeight)); } if (_isIKCalculated || _isExternalUpdate_Position || _isExternalUpdate_Rotation || _isExternalUpdate_Scaling) { //WorldMatrix를 갱신해주자 _worldMatrix.SetTRS(_updatedWorldPos.x, _updatedWorldPos.y, _updatedWorldAngle, _updatedWorldScale.x, _updatedWorldScale.y); _isIKCalculated = false; _isExternalUpdate_Position = false; _isExternalUpdate_Rotation = false; _isExternalUpdate_Scaling = false; } //World Matrix는 MeshGroup과 동일한 Space의 값을 가진다. //그러나 실제로 Bone World Matrix는 //Root - MeshGroup...(Rec) - Bone Group - Bone.. (Rec <- 여기) //의 레벨을 가진다. //Root 밑으로는 모두 World에 대해서 동일한 Space를 가지므로 //Root를 찾아서 Scale을 제어하자...? //일단 Parent에서 빼두자 //_transformLocalMatrix.SetMatrix(_worldMatrix); #if UNITY_EDITOR _shapePoint_End = new Vector2(0.0f, _shapeLength); _shapePoint_Mid1 = new Vector2(-_shapeWidth * 0.5f, _shapeLength * 0.2f); _shapePoint_Mid2 = new Vector2(_shapeWidth * 0.5f, _shapeLength * 0.2f); float taperRatio = Mathf.Clamp01((float)(100 - _shapeTaper) / 100.0f); _shapePoint_End1 = new Vector2(-_shapeWidth * 0.5f * taperRatio, _shapeLength); _shapePoint_End2 = new Vector2(_shapeWidth * 0.5f * taperRatio, _shapeLength); _shapePoint_End = _worldMatrix.MtrxToSpace.MultiplyPoint(_shapePoint_End); _shapePoint_Mid1 = _worldMatrix.MtrxToSpace.MultiplyPoint(_shapePoint_Mid1); _shapePoint_Mid2 = _worldMatrix.MtrxToSpace.MultiplyPoint(_shapePoint_Mid2); _shapePoint_End1 = _worldMatrix.MtrxToSpace.MultiplyPoint(_shapePoint_End1); _shapePoint_End2 = _worldMatrix.MtrxToSpace.MultiplyPoint(_shapePoint_End2); #endif //Rigging을 위해서 Matrix 통합 식을 만들자 //실제 식 // world * default_inv * VertPos W _vertWorld2BoneModWorldMatrix = _worldMatrix.MtrxToSpace; _vertWorld2BoneModWorldMatrix *= _worldMatrix_NonModified.MtrxToLowerSpace; if (_socketTransform != null) { //소켓을 업데이트 하자 _socketTransform.localPosition = new Vector3(_worldMatrix._pos.x, _worldMatrix._pos.y, 0); _socketTransform.localRotation = Quaternion.Euler(0.0f, 0.0f, _worldMatrix._angleDeg); _socketTransform.localScale = new Vector3(_worldMatrix._scale.x, _worldMatrix._scale.y, 1.0f); } //Child도 호출해준다. if (isRecursive && _childBones != null) { for (int i = 0; i < _childBones.Length; i++) { _childBones[i].MakeWorldMatrix(true); } } }