public void MakeTransformMatrix() { //[R] _matrix_TFResult_World.RMultiply(_matrix_TF_ToParent); _matrix_TFResult_World.RMultiply(_matrix_TF_LocalModified); _matrix_TFResult_World.RMultiply(_matrix_TF_ParentWorld); _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ToParent); _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ParentWorld); //Inverse는 반대로 계산한다. _invMatrix_TFResult_World.SetMatrix(_matrix_TF_ParentWorld); _invMatrix_TFResult_World.RInverse(_matrix_TF_LocalModified); _invMatrix_TFResult_World.RInverse(_matrix_TF_ToParent); _invMatrix_TFResult_WorldWithoutMod.SetMatrix(_matrix_TF_ParentWorldWithoutMod); _invMatrix_TFResult_WorldWithoutMod.RInverse(_matrix_TF_ToParent); }
public void MakeTransformMatrix() { //1) SR Multiply로 만드는 경우 //[SR] //_matrix_TFResult_World.SRMultiply(_matrix_TF_LocalModified, true); //_matrix_TFResult_World.SRMultiply(_matrix_TF_ToParent, true); //_matrix_TFResult_World.SRMultiply(_matrix_TF_ParentWorld, true); //_matrix_TFResult_WorldWithoutMod.SRMultiply(_matrix_TF_ToParent, true); //_matrix_TFResult_WorldWithoutMod.SRMultiply(_matrix_TF_ParentWorld, true); //[R] _matrix_TFResult_World.RMultiply(_matrix_TF_ToParent); _matrix_TFResult_World.RMultiply(_matrix_TF_LocalModified); _matrix_TFResult_World.RMultiply(_matrix_TF_ParentWorld); _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ToParent); _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ParentWorld); }
/// <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 apGizmos.TransformParam PivotReturn__MeshGroup_Setting() { if (Editor.Select.MeshGroup == null) { return(null); } if (Editor.Select.SubMeshInGroup == null && Editor.Select.SubMeshGroupInGroup == null) { return(null); } apRenderUnit curRenderUnit = null; apMatrix curMatrixParam = null; apMatrix resultMatrix = null; Color meshColor2X = Color.gray; bool isVisible = true; if (Editor.Select.SubMeshInGroup != null) { curRenderUnit = Editor.Select.MeshGroup.GetRenderUnit(Editor.Select.SubMeshInGroup); curMatrixParam = Editor.Select.SubMeshInGroup._matrix; meshColor2X = Editor.Select.SubMeshInGroup._meshColor2X_Default; isVisible = Editor.Select.SubMeshInGroup._isVisible_Default; } else if (Editor.Select.SubMeshGroupInGroup != null) { curRenderUnit = Editor.Select.MeshGroup.GetRenderUnit(Editor.Select.SubMeshGroupInGroup); curMatrixParam = Editor.Select.SubMeshGroupInGroup._matrix; meshColor2X = Editor.Select.SubMeshGroupInGroup._meshColor2X_Default; isVisible = Editor.Select.SubMeshGroupInGroup._isVisible_Default; } if (curRenderUnit == null) { return(null); } if (curRenderUnit._meshTransform != null) { resultMatrix = curRenderUnit._meshTransform._matrix_TFResult_World; } else if (curRenderUnit._meshGroupTransform != null) { resultMatrix = curRenderUnit._meshGroupTransform._matrix_TFResult_World; } else { return(null); } //Root의 MeshGroupTransform을 추가 apMatrix curMatrixParam_Result = new apMatrix(curMatrixParam); curMatrixParam_Result.RMultiply(Editor.Select.MeshGroup._rootMeshGroupTransform._matrix); //TODO : Pivot 수정중엔 Calculated 데이터가 제외되어야 한다. //Vector3 posW3 = curRenderUnit.WorldMatrixOfNode.GetPosition(); Vector2 posW2 = resultMatrix._pos; if (!Editor.Select.IsMeshGroupSettingChangePivot) { return(apGizmos.TransformParam.Make( posW2, //<<Calculate를 포함한다. //curMatrixParam._pos, //curMatrixParam_Result._angleDeg, //curMatrixParam_Result._scale, resultMatrix._angleDeg, resultMatrix._scale, curRenderUnit.GetDepth(), //curRenderUnit.GetColor(), meshColor2X, isVisible, curRenderUnit.WorldMatrix, false, apGizmos.TRANSFORM_UI.Color, //색상만 설정 가능 curMatrixParam._pos, curMatrixParam._angleDeg, curMatrixParam._scale)); } else { return(apGizmos.TransformParam.Make( //curMatrixParam_Result._pos,//<<Calculate를 포함한다. posW2, //<<Calculate를 포함한다. //curMatrixParam._pos, //curMatrixParam_Result._angleDeg, //curMatrixParam_Result._scale, resultMatrix._angleDeg, resultMatrix._scale, curRenderUnit.GetDepth(), //curRenderUnit.GetColor(), meshColor2X, isVisible, //curMatrixParam_Result.MtrxToSpace, curRenderUnit.WorldMatrix, false, //apGizmos.TRANSFORM_UI.TRS, apGizmos.TRANSFORM_UI.TRS_WithDepth //Depth 포함한 TRS | apGizmos.TRANSFORM_UI.Color, //색상도 포함시킨다. curMatrixParam._pos, curMatrixParam._angleDeg, curMatrixParam._scale )); } }
/// <summary> /// Bake를 위해서 BoneMatrix를 초기화한다. /// </summary> /// <param name="isRecursive"></param> public void ResetBoneMatrixForBake(bool isRecursive) { _deltaPos = Vector2.zero; _deltaAngle = 0.0f; _deltaScale = Vector2.one; _localMatrix.SetIdentity(); _worldMatrix.SetIdentity(); _worldMatrix_NonModified.SetIdentity(); _vertWorld2BoneModWorldMatrix.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_WorldWithoutMod); //RenderUnit의 WorldMatrixWrap의 Opt 버전 _worldMatrix_NonModified.RMultiply(_parentOptTransform._matrix_TFResult_WorldWithoutMod); } } else { _worldMatrix.SetMatrix(_defaultMatrix); _worldMatrix.Add(_localMatrix); _worldMatrix.RMultiply(_parentBone._worldMatrix_NonModified); _worldMatrix_NonModified.SetMatrix(_defaultMatrix); //Local Matrix 없이 Default만 지정 _worldMatrix_NonModified.RMultiply(_parentBone._worldMatrix_NonModified); } _worldMatrix.SetMatrix(_worldMatrix_NonModified); _vertWorld2BoneModWorldMatrix = _worldMatrix_NonModified.MtrxToSpace; _vertWorld2BoneModWorldMatrix *= _worldMatrix_NonModified.MtrxToLowerSpace; //Debug.Log("Reset Bone Matrix [" + this.name + "]"); //Debug.Log("World Matrix [ " + _worldMatrix.ToString() + "]"); if (isRecursive) { if (_childBones != null && _childBones.Length > 0) { for (int i = 0; i < _childBones.Length; i++) { _childBones[i].ResetBoneMatrixForBake(true); } } } }
/// <summary> /// CalculateStack을 업데이트 한다. /// Pre-Update이다. Rigging, VertWorld는 제외된다. /// </summary> public void UpdateCalculate_Pre() { #if UNITY_EDITOR Profiler.BeginSample("Transform - 1. Stack Calculate"); #endif //1. Calculated Stack 업데이트 if (_calculatedStack != null) { _calculatedStack.Calculate_Pre(); } #if UNITY_EDITOR Profiler.EndSample(); #endif #if UNITY_EDITOR Profiler.BeginSample("Transform - 2. Matrix / Color"); #endif //2. Calculated의 값 적용 + 계층적 Matrix 적용 if (_calculatedStack.MeshWorldMatrixWrap != null) { //변경전 //_calclateTmpMatrix.SRMultiply(_calculatedStack.MeshWorldMatrixWrap, true); //_matrix_TF_Cal_ToWorld = _calculateTmpMatrix.MtrxToSpace; //변경후 _matrix_TF_LocalModified.SetMatrix(_calculatedStack.MeshWorldMatrixWrap); //if(_calculatedStack.MeshWorldMatrixWrap.Scale2.magnitude < 0.8f) //{ // Debug.Log(name + " : Low Scale : " + _calculatedStack.MeshWorldMatrixWrap.Scale2); //} } if (CalculatedStack.IsAnyColorCalculated) { _meshColor2X = CalculatedStack.MeshColor; _isVisible = CalculatedStack.IsMeshVisible; } else { _meshColor2X = _meshColor2X_Default; _isVisible = _isVisible_Default; } if (!_isVisible) { _meshColor2X.a = 0.0f; } if (_parentTransform != null) { //변경 전 //_calculateTmpMatrix.SRMultiply(_parentTransform.CalculatedTmpMatrix, true); //_matrix_TF_Cal_ToWorld = _calculateTmpMatrix.MtrxToSpace; //변경 후 _matrix_TF_ParentWorld.SetMatrix(_parentTransform._matrix_TFResult_World); _matrix_TF_ParentWorld_NonModified.SetMatrix(_parentTransform._matrix_TFResult_WorldWithoutMod); //색상은 2X 방식의 Add _meshColor2X.r = Mathf.Clamp01(((float)(_meshColor2X.r) - 0.5f) + ((float)(_parentTransform._meshColor2X.r) - 0.5f) + 0.5f); _meshColor2X.g = Mathf.Clamp01(((float)(_meshColor2X.g) - 0.5f) + ((float)(_parentTransform._meshColor2X.g) - 0.5f) + 0.5f); _meshColor2X.b = Mathf.Clamp01(((float)(_meshColor2X.b) - 0.5f) + ((float)(_parentTransform._meshColor2X.b) - 0.5f) + 0.5f); _meshColor2X.a *= _parentTransform._meshColor2X.a; } if (_meshColor2X.a < VISIBLE_ALPHA //|| !CalculatedStack.IsMeshVisible ) { _isVisible = false; _meshColor2X.a = 0.0f; } //MakeTransformMatrix(); < 이 함수 부분 //World Matrix를 만든다. _matrix_TFResult_World.RMultiply(_matrix_TF_ToParent); //변경 : ToParent -> LocalModified -> ParentWorld 순으로 바꾼다. _matrix_TFResult_World.RMultiply(_matrix_TF_LocalModified); //<<[R] //_matrix_TFResult_World.RMultiply(_matrix_TF_ToParent);//<<[R] _matrix_TFResult_World.RMultiply(_matrix_TF_ParentWorld); //<<[R] //_matrix_TFResult_WorldWithoutMod.SRMultiply(_matrix_TF_ToParent, true);//ToParent는 넣지 않는다. //_matrix_TFResult_WorldWithoutMod.SRMultiply(_matrix_TF_ParentWorld, true);//<<[SR] _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ToParent); //<<[R] _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ParentWorld_NonModified); //<<[R] #if UNITY_EDITOR Profiler.EndSample(); #endif //[MeshUpdate]는 Post Update로 전달 //3. 자식 호출 //자식 객체도 업데이트를 한다. if (_childTransforms != null) { for (int i = 0; i < _childTransforms.Length; i++) { _childTransforms[i].UpdateCalculate_Pre(); } } }
///// <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); } } }
/// <summary> /// CalculateStack을 업데이트 한다. /// Pre-Update이다. Rigging, VertWorld는 제외된다. /// </summary> public void UpdateCalculate_Pre() { //#if UNITY_EDITOR // Profiler.BeginSample("Transform - 1. Stack Calculate"); //#endif //1. Calculated Stack 업데이트 if (_calculatedStack != null) { _calculatedStack.Calculate_Pre(); } //#if UNITY_EDITOR // Profiler.EndSample(); //#endif //#if UNITY_EDITOR // Profiler.BeginSample("Transform - 2. Matrix / Color"); //#endif //2. Calculated의 값 적용 + 계층적 Matrix 적용 if (CalculatedStack.MeshWorldMatrixWrap != null) { //변경전 //_calclateTmpMatrix.SRMultiply(_calculatedStack.MeshWorldMatrixWrap, true); //_matrix_TF_Cal_ToWorld = _calculateTmpMatrix.MtrxToSpace; //변경후 _matrix_TF_LocalModified.SetMatrix(_calculatedStack.MeshWorldMatrixWrap); //if(_calculatedStack.MeshWorldMatrixWrap.Scale2.magnitude < 0.8f) //{ // Debug.Log(name + " : Low Scale : " + _calculatedStack.MeshWorldMatrixWrap.Scale2); //} } if (CalculatedStack.IsAnyColorCalculated) { _meshColor2X = CalculatedStack.MeshColor; _isVisible = CalculatedStack.IsMeshVisible; _isAnyColorCalculated = true; } else { _meshColor2X = _meshColor2X_Default; _isVisible = _isVisible_Default; } if (!_isVisible) { _meshColor2X.a = 0.0f; _isAnyColorCalculated = true; } if (_parentTransform != null) { //변경 전 //_calculateTmpMatrix.SRMultiply(_parentTransform.CalculatedTmpMatrix, true); //_matrix_TF_Cal_ToWorld = _calculateTmpMatrix.MtrxToSpace; //변경 후 _matrix_TF_ParentWorld.SetMatrix(_parentTransform._matrix_TFResult_World); _matrix_TF_ParentWorld_NonModified.SetMatrix(_parentTransform._matrix_TFResult_WorldWithoutMod); //색상은 2X 방식의 Add _meshColor2X.r = Mathf.Clamp01(((float)(_meshColor2X.r) - 0.5f) + ((float)(_parentTransform._meshColor2X.r) - 0.5f) + 0.5f); _meshColor2X.g = Mathf.Clamp01(((float)(_meshColor2X.g) - 0.5f) + ((float)(_parentTransform._meshColor2X.g) - 0.5f) + 0.5f); _meshColor2X.b = Mathf.Clamp01(((float)(_meshColor2X.b) - 0.5f) + ((float)(_parentTransform._meshColor2X.b) - 0.5f) + 0.5f); _meshColor2X.a *= _parentTransform._meshColor2X.a; if (_parentTransform._isAnyColorCalculated) { _isAnyColorCalculated = true; } } if (_meshColor2X.a < VISIBLE_ALPHA //|| !CalculatedStack.IsMeshVisible ) { _isVisible = false; _meshColor2X.a = 0.0f; _isAnyColorCalculated = true; } //MakeTransformMatrix(); < 이 함수 부분 //World Matrix를 만든다. _matrix_TFResult_World.RMultiply(_matrix_TF_ToParent); //변경 : ToParent -> LocalModified -> ParentWorld 순으로 바꾼다. _matrix_TFResult_World.RMultiply(_matrix_TF_LocalModified); //<<[R] //_matrix_TFResult_World.RMultiply(_matrix_TF_ToParent);//<<[R] _matrix_TFResult_World.RMultiply(_matrix_TF_ParentWorld); //<<[R] //_matrix_TFResult_WorldWithoutMod.SRMultiply(_matrix_TF_ToParent, true);//ToParent는 넣지 않는다. //_matrix_TFResult_WorldWithoutMod.SRMultiply(_matrix_TF_ParentWorld, true);//<<[SR] //Without Mod는 계산하지 않았을 경우에만 계산한다. //바뀌지 않으므로 if (!_isCalculateWithoutMod) { _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ToParent); //<<[R] _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ParentWorld_NonModified); //<<[R] //리깅용 단축식을 추가한다. if (_childMesh != null) { _vertLocal2MeshWorldMatrix = _matrix_TFResult_WorldWithoutMod.MtrxToSpace; _vertLocal2MeshWorldMatrix *= _childMesh._matrix_Vert2Mesh; _vertWorld2MeshLocalMatrix = _childMesh._matrix_Vert2Mesh_Inverse; _vertWorld2MeshLocalMatrix *= _matrix_TFResult_WorldWithoutMod.MtrxToLowerSpace; _vertMeshWorldNoModMatrix = _matrix_TFResult_WorldWithoutMod.MtrxToSpace; _vertMeshWorldNoModInverseMatrix = _matrix_TFResult_WorldWithoutMod.MtrxToLowerSpace; } _isCalculateWithoutMod = true; } //처리된 TRS _updatedWorldPos_NoRequest.x = _matrix_TFResult_World._pos.x; _updatedWorldPos_NoRequest.y = _matrix_TFResult_World._pos.y; _updatedWorldAngle_NoRequest = _matrix_TFResult_World._angleDeg; _updatedWorldScale_NoRequest.x = _matrix_TFResult_World._scale.x; _updatedWorldScale_NoRequest.y = _matrix_TFResult_World._scale.y; _updatedWorldPos = _updatedWorldPos_NoRequest; _updatedWorldAngle = _updatedWorldAngle_NoRequest; _updatedWorldScale = _updatedWorldScale_NoRequest; //스크립트로 외부에서 제어한 경우 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 (_isExternalUpdate_Position || _isExternalUpdate_Rotation || _isExternalUpdate_Scaling) { //WorldMatrix를 갱신해주자 _matrix_TFResult_World.SetTRS(_updatedWorldPos.x, _updatedWorldPos.y, _updatedWorldAngle, _updatedWorldScale.x, _updatedWorldScale.y); _isExternalUpdate_Position = false; _isExternalUpdate_Rotation = false; _isExternalUpdate_Scaling = false; } //추가 : 소켓도 만들어준다. //Vert World를 아직 계산하지 않았지만 Socket 처리에는 문제가 없다. if (_socketTransform != null) { _socketTransform.localPosition = new Vector3(_matrix_TFResult_World._pos.x, _matrix_TFResult_World._pos.y, 0); _socketTransform.localRotation = Quaternion.Euler(0.0f, 0.0f, _matrix_TFResult_World._angleDeg); _socketTransform.localScale = new Vector3(_matrix_TFResult_World._scale.x, _matrix_TFResult_World._scale.y, 1.0f); } //#if UNITY_EDITOR // Profiler.EndSample(); //#endif //[MeshUpdate]는 Post Update로 전달 //3. 자식 호출 //자식 객체도 업데이트를 한다. if (_childTransforms != null) { for (int i = 0; i < _childTransforms.Length; i++) { _childTransforms[i].UpdateCalculate_Pre(); } } }
/// <summary> /// CalculateStack을 업데이트 한다. /// Pre-Update이다. Rigging, VertWorld는 제외된다. /// </summary> public void UpdateCalculate_Pre() { //#if UNITY_EDITOR // Profiler.BeginSample("Transform - 1. Stack Calculate"); //#endif //1. Calculated Stack 업데이트 if (_calculatedStack != null) { _calculatedStack.Calculate_Pre(); } //#if UNITY_EDITOR // Profiler.EndSample(); //#endif //#if UNITY_EDITOR // Profiler.BeginSample("Transform - 2. Matrix / Color"); //#endif //2. Calculated의 값 적용 + 계층적 Matrix 적용 if (CalculatedStack.MeshWorldMatrixWrap != null) { //변경전 //_calclateTmpMatrix.SRMultiply(_calculatedStack.MeshWorldMatrixWrap, true); //_matrix_TF_Cal_ToWorld = _calculateTmpMatrix.MtrxToSpace; //변경후 _matrix_TF_LocalModified.SetMatrix(_calculatedStack.MeshWorldMatrixWrap); //if(_calculatedStack.MeshWorldMatrixWrap.Scale2.magnitude < 0.8f) //{ // Debug.Log(name + " : Low Scale : " + _calculatedStack.MeshWorldMatrixWrap.Scale2); //} } if (CalculatedStack.IsAnyColorCalculated) { _meshColor2X = CalculatedStack.MeshColor; _isVisible = CalculatedStack.IsMeshVisible; _isAnyColorCalculated = true; } else { _meshColor2X = _meshColor2X_Default; _isVisible = _isVisible_Default; } if (!_isVisible) { _meshColor2X.a = 0.0f; _isAnyColorCalculated = true; } //추가 11.30 : Extra Option if (_calculatedStack.IsExtraDepthChanged) { if (_func_ExtraDepthChanged != null) { _func_ExtraDepthChanged(this, _calculatedStack.ExtraDeltaDepth); } } if (_calculatedStack.IsExtraTextureChanged) { _isExtraTextureChanged = true; _extraTextureData = _calculatedStack.ExtraTextureData; if (_extraTextureData == null) { _isExtraTextureChanged = false; } } if (_isExtraTextureChanged_Prev != _isExtraTextureChanged || _extraTextureData_Prev != _extraTextureData) { #if UNITY_EDITOR if (Application.isPlaying) { #endif //Extra-Texture 이벤트가 발생하거나 해지되어서 상태가 바뀌었을 경우 //또는 새로운 텍스쳐가 발생했을 경우 if (_childMesh != null) { if (_isExtraTextureChanged) { //> 텍스쳐 교체 이벤트가 발생했다. //현재 처리중인 텍스쳐를 먼저 저장한 뒤, 교체 _extraDefaultTexture = _childMesh.GetCurrentProcessedTexture(); _childMesh.SetExtraChangedTexture(_extraTextureData._texture); } else { //>텍스쳐를 해지해야한다. 저장했던 값으로 되돌린다. _childMesh.SetExtraChangedTexture(_extraDefaultTexture); } } #if UNITY_EDITOR } #endif _isExtraTextureChanged_Prev = _isExtraTextureChanged; if (_isExtraTextureChanged) { _extraTextureData_Prev = _extraTextureData; } else { _extraTextureData_Prev = null; } } if (_parentTransform != null) { //변경 전 //_calculateTmpMatrix.SRMultiply(_parentTransform.CalculatedTmpMatrix, true); //_matrix_TF_Cal_ToWorld = _calculateTmpMatrix.MtrxToSpace; //변경 후 _matrix_TF_ParentWorld.SetMatrix(_parentTransform._matrix_TFResult_World); _matrix_TF_ParentWorld_NonModified.SetMatrix(_parentTransform._matrix_TFResult_WorldWithoutMod); //색상은 2X 방식의 Add _meshColor2X.r = Mathf.Clamp01(((float)(_meshColor2X.r) - 0.5f) + ((float)(_parentTransform._meshColor2X.r) - 0.5f) + 0.5f); _meshColor2X.g = Mathf.Clamp01(((float)(_meshColor2X.g) - 0.5f) + ((float)(_parentTransform._meshColor2X.g) - 0.5f) + 0.5f); _meshColor2X.b = Mathf.Clamp01(((float)(_meshColor2X.b) - 0.5f) + ((float)(_parentTransform._meshColor2X.b) - 0.5f) + 0.5f); _meshColor2X.a *= _parentTransform._meshColor2X.a; if (_parentTransform._isAnyColorCalculated) { _isAnyColorCalculated = true; } } if (_meshColor2X.a < VISIBLE_ALPHA //|| !CalculatedStack.IsMeshVisible ) { _isVisible = false; _meshColor2X.a = 0.0f; _isAnyColorCalculated = true; } //MakeTransformMatrix(); < 이 함수 부분 //World Matrix를 만든다. _matrix_TFResult_World.RMultiply(_matrix_TF_ToParent); //변경 : ToParent -> LocalModified -> ParentWorld 순으로 바꾼다. _matrix_TFResult_World.RMultiply(_matrix_TF_LocalModified); //<<[R] //_matrix_TFResult_World.RMultiply(_matrix_TF_ToParent);//<<[R] _matrix_TFResult_World.RMultiply(_matrix_TF_ParentWorld); //<<[R] //_matrix_TFResult_WorldWithoutMod.SRMultiply(_matrix_TF_ToParent, true);//ToParent는 넣지 않는다. //_matrix_TFResult_WorldWithoutMod.SRMultiply(_matrix_TF_ParentWorld, true);//<<[SR] //Without Mod는 계산하지 않았을 경우에만 계산한다. //바뀌지 않으므로 if (!_isCalculateWithoutMod) { _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ToParent); //<<[R] _matrix_TFResult_WorldWithoutMod.RMultiply(_matrix_TF_ParentWorld_NonModified); //<<[R] //리깅용 단축식을 추가한다. if (_childMesh != null) { _vertLocal2MeshWorldMatrix = _matrix_TFResult_WorldWithoutMod.MtrxToSpace; _vertLocal2MeshWorldMatrix *= _childMesh._matrix_Vert2Mesh; _vertWorld2MeshLocalMatrix = _childMesh._matrix_Vert2Mesh_Inverse; _vertWorld2MeshLocalMatrix *= _matrix_TFResult_WorldWithoutMod.MtrxToLowerSpace; _vertMeshWorldNoModMatrix = _matrix_TFResult_WorldWithoutMod.MtrxToSpace; _vertMeshWorldNoModInverseMatrix = _matrix_TFResult_WorldWithoutMod.MtrxToLowerSpace; } _isCalculateWithoutMod = true; } //_convert2TargetMatrix4x4 = Matrix4x4.identity; //_convert2TargetMatrix3x3 = apMatrix3x3.identity; _isCamOrthoCorrection = false; if (_portrait._billboardType != apPortrait.BILLBOARD_TYPE.None && _childMesh != null) { Camera curCamera = _portrait.GetCamera(); if (curCamera != null && !curCamera.orthographic) { //Perspective 카메라라면 Vector3 pos_Cam = curCamera.worldToCameraMatrix.MultiplyPoint3x4(_childMesh.transform.position); //Vector3 pos_Cam = (curCamera.worldToCameraMatrix * transform.localToWorldMatrix).MultiplyPoint3x4(new Vector3(_matrix_TFResult_World._pos.x, _matrix_TFResult_World._pos.y, 0)); float zDepth = pos_Cam.z; float zRatio = zDepth / _portrait.GetZDepth(); //Debug.Log("pos_Cam : " + pos_Cam + " / " + zRatio); //transform.tr//>>TODO _isCamOrthoCorrection = true; Matrix4x4 orthoConvertMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(zRatio, zRatio, 1)); _convert2TargetMatrix4x4 = _childMesh.transform.worldToLocalMatrix * curCamera.cameraToWorldMatrix * orthoConvertMatrix * curCamera.worldToCameraMatrix * _childMesh.transform.localToWorldMatrix; _convert2TargetMatrix3x3 = apMatrix3x3.identity; _convert2TargetMatrix3x3._m00 = _convert2TargetMatrix4x4.m00; _convert2TargetMatrix3x3._m01 = _convert2TargetMatrix4x4.m01; _convert2TargetMatrix3x3._m02 = _convert2TargetMatrix4x4.m03; _convert2TargetMatrix3x3._m10 = _convert2TargetMatrix4x4.m10; _convert2TargetMatrix3x3._m11 = _convert2TargetMatrix4x4.m11; _convert2TargetMatrix3x3._m12 = _convert2TargetMatrix4x4.m13; _convert2TargetMatrix3x3._m20 = _convert2TargetMatrix4x4.m30; _convert2TargetMatrix3x3._m21 = _convert2TargetMatrix4x4.m31; _convert2TargetMatrix3x3._m22 = _convert2TargetMatrix4x4.m23; //Debug.Log("_convert2TargetMatrix4x4 : \n " + _convert2TargetMatrix4x4.ToString() + "\n" + "_convert2TargetMatrix3x3 : \n " + _convert2TargetMatrix3x3.ToString()); } } //처리된 TRS _updatedWorldPos_NoRequest.x = _matrix_TFResult_World._pos.x; _updatedWorldPos_NoRequest.y = _matrix_TFResult_World._pos.y; _updatedWorldAngle_NoRequest = _matrix_TFResult_World._angleDeg; _updatedWorldScale_NoRequest.x = _matrix_TFResult_World._scale.x; _updatedWorldScale_NoRequest.y = _matrix_TFResult_World._scale.y; _updatedWorldPos = _updatedWorldPos_NoRequest; _updatedWorldAngle = _updatedWorldAngle_NoRequest; _updatedWorldScale = _updatedWorldScale_NoRequest; //스크립트로 외부에서 제어한 경우 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 (_isExternalUpdate_Position || _isExternalUpdate_Rotation || _isExternalUpdate_Scaling) { //WorldMatrix를 갱신해주자 _matrix_TFResult_World.SetTRS(_updatedWorldPos.x, _updatedWorldPos.y, _updatedWorldAngle, _updatedWorldScale.x, _updatedWorldScale.y); _isExternalUpdate_Position = false; _isExternalUpdate_Rotation = false; _isExternalUpdate_Scaling = false; } //추가 : 소켓도 만들어준다. //Vert World를 아직 계산하지 않았지만 Socket 처리에는 문제가 없다. if (_socketTransform != null) { _socketTransform.localPosition = new Vector3(_matrix_TFResult_World._pos.x, _matrix_TFResult_World._pos.y, 0); _socketTransform.localRotation = Quaternion.Euler(0.0f, 0.0f, _matrix_TFResult_World._angleDeg); _socketTransform.localScale = new Vector3(_matrix_TFResult_World._scale.x, _matrix_TFResult_World._scale.y, 1.0f); } //#if UNITY_EDITOR // Profiler.EndSample(); //#endif //[MeshUpdate]는 Post Update로 전달 //3. 자식 호출 //자식 객체도 업데이트를 한다. if (_childTransforms != null) { for (int i = 0; i < _childTransforms.Length; i++) { _childTransforms[i].UpdateCalculate_Pre(); } } }
public InverseResult World2ModLocalPos_TransformRotationScaling(float deltaRotateAngle, Vector2 deltaScale) { if (_modMesh == null) { Debug.LogError("World2ModLocalPos_Transform 실패 : ModMesh에서 호출하지 않았다."); return(null); } if (_modMesh._transform_Mesh == null) { Debug.LogError("World2ModLocalPos_Transform 실패 : ModMesh의 MeshTransform이 Null이다."); return(null); } //현재 위치를 받자 //이제 위로 하나씩 계산하면서 어떤 CalculateLog가 기록되었는지 확인하자 //StatckLResultLayer까지 올라가면 된다. (거기는 값이 고정이므로) apCalculatedLog modified = this; apCalculatedLog layer_ParamSetGroup = modified._parentLayerLog; apCalculatedLog layer_CalParamResult = layer_ParamSetGroup._parentLayerLog; apCalculatedLog stackLayer_MeshTransform = layer_CalParamResult._parentCalResultStackLayer; apCalculatedLog transform_Modified = stackLayer_MeshTransform._parentTF_Modified; //현재 posW 를 저장하자 Vector2 posW_prev = _modMesh._transform_Mesh._matrix_TFResult_World._pos; //일단 회전값/스케일을 추가하자 apMatrix RSModMatrix = new apMatrix(_modMesh._transform_Mesh._matrix_TF_LocalModified); RSModMatrix.SetRotate(RSModMatrix._angleDeg + deltaRotateAngle); RSModMatrix.SetScale(RSModMatrix._scale + deltaScale); apMatrix RSWorldMatrix = new apMatrix(_modMesh._transform_Mesh._matrix_TF_ToParent); RSWorldMatrix.RMultiply(RSModMatrix); RSWorldMatrix.RMultiply(_modMesh._transform_Mesh._matrix_TF_ParentWorld); //이 WorldMatrix의 계산 후 Position을 확인하자 Vector2 posW_rs = RSWorldMatrix._pos; //posW_rotated가 아닌 posW_prev로 돌려야 한다. 고치자. Vector2 deltaPosW = posW_prev - posW_rs; _inverseResult.Request(posW_rs, deltaPosW); //이제 역으로 내려오자 // ParentWorld <- Modified <- ToParent = World // [Modified <- ToParent] = [ParentWorld-1 <- World] // Modified = [ParentWorld-1 <- World <- ToParent-1] apMatrix worldMatrix_next = new apMatrix(RSWorldMatrix); worldMatrix_next.SetPos(worldMatrix_next._pos + deltaPosW); apMatrix modMatrix_next = transform_Modified._meshTransform._matrix_TF_ToParent.RInverseMatrix; modMatrix_next.RMultiply(worldMatrix_next); modMatrix_next.RInverse(transform_Modified._meshTransform._matrix_TF_ParentWorld); //위 수식은 "StackLayer-MeshTF" 레벨에서 계산된 것이다. //StackLayer -> CalParam -> ParamSetGroup으로 이동하자. apMatrix modMatrix_paramSet = GetInverseInterpolatedMatrix(layer_ParamSetGroup, layer_CalParamResult, stackLayer_MeshTransform, modMatrix_next); if (modMatrix_paramSet == null) { Debug.LogError("StackLayer -> CalParam -> ParamSetGroup 전환에 실패했다."); return(null); } //_inverseResult.SetResult(transform_Modified._meshTransform._matrix_TF_LocalModified._pos, // modMatrix_next._pos); _inverseResult.SetResult(transform_Modified._meshTransform._matrix_TF_LocalModified._pos, modMatrix_paramSet._pos); return(_inverseResult); }
/// <summary> /// Modified 단계에서 위로 검색하여 현재 World Position으로부터 다시 Local로 내려온다. /// 결과값은 ModMesh(TF)의 TransformMatrix에 사용될 값으로 변환된다. /// ModMesh에서 호출해야한다. /// </summary> /// <param name="deltaPosW"></param> /// <returns></returns> //public InverseResult World2ModLocalPos_TransformMove(Vector2 nextPosW) public InverseResult World2ModLocalPos_TransformMove(Vector2 nextPosW, Vector2 deltaPosW) { if (_modMesh == null) { Debug.LogError("World2ModLocalPos_Transform 실패 : ModMesh에서 호출하지 않았다."); return(null); } if (_modMesh._transform_Mesh == null) { Debug.LogError("World2ModLocalPos_Transform 실패 : ModMesh의 MeshTransform이 Null이다."); return(null); } //현재 위치를 받자 Vector2 posW_prev = _modMesh._transform_Mesh._matrix_TFResult_World._pos; //Vector2 deltaPosW = nextPosW - posW_prev; nextPosW = posW_prev + deltaPosW; _inverseResult.Request(posW_prev, deltaPosW); //이제 위로 하나씩 계산하면서 어떤 CalculateLog가 기록되었는지 확인하자 //StatckLResultLayer까지 올라가면 된다. (거기는 값이 고정이므로) apCalculatedLog modified = this; apCalculatedLog layer_ParamSetGroup = modified._parentLayerLog; apCalculatedLog layer_CalParamResult = layer_ParamSetGroup._parentLayerLog; apCalculatedLog stackLayer_MeshTransform = layer_CalParamResult._parentCalResultStackLayer; apCalculatedLog transform_Modified = stackLayer_MeshTransform._parentTF_Modified; //Debug.Log("Calculate Log"); //이제 역으로 내려오자 Vector2 posW_next = nextPosW; apMatrix worldMatrix = transform_Modified._meshTransform._matrix_TFResult_World; // ParentWorld <- Modified <- ToParent = World // [Modified <- ToParent] = [ParentWorld-1 <- World] // Modified = [ParentWorld-1 <- World <- ToParent-1] apMatrix worldMatrix_next = new apMatrix(worldMatrix); worldMatrix_next.SetPos(worldMatrix_next._pos + deltaPosW); apMatrix modMatrix_next = transform_Modified._meshTransform._matrix_TF_ToParent.RInverseMatrix; modMatrix_next.RMultiply(worldMatrix_next); modMatrix_next.RInverse(transform_Modified._meshTransform._matrix_TF_ParentWorld); //위 수식은 "StackLayer-MeshTF" 레벨에서 계산된 것이다. //StackLayer -> CalParam -> ParamSetGroup으로 이동하자. apMatrix modMatrix_paramSet = GetInverseInterpolatedMatrix(layer_ParamSetGroup, layer_CalParamResult, stackLayer_MeshTransform, modMatrix_next); if (modMatrix_paramSet == null) { Debug.LogError("StackLayer -> CalParam -> ParamSetGroup 전환에 실패했다."); return(null); } //_inverseResult.SetResult(transform_Modified._meshTransform._matrix_TF_LocalModified._pos, // modMatrix_next._pos); _inverseResult.SetResult(transform_Modified._meshTransform._matrix_TF_LocalModified._pos, modMatrix_paramSet._pos); return(_inverseResult); }