/// <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(); } } }