/// <summary> /// Calculate Result Statck의 업데이트 부분 /// Pre-Update로서 VertWorld와 Rigging이 제외된다. /// </summary> public void Calculate_Pre() { //bool isFirstDebug = true; _cal_prevWeight = 0.0f; _cal_curWeight = 0.0f; _cal_resultParam = null; _cal_posVerts = null; //Debug.Log("Is Any Vert Local : " + _isAnyVertLocal + " [" + _resultParams_VertLocal.Count +"]"); // 1. Local Morph if (_isAnyVertLocal) { #if UNITY_EDITOR Profiler.BeginSample("Calcuate Result Stack - 1. Vert Local"); #endif _cal_prevWeight = 0.0f; _cal_curWeight = 0.0f; _cal_resultParam = null; _cal_posVerts = null; _iCalculatedParam = 0; //<<추가 : 첫 모디파이어는 무조건 Interpolation으로 만들자 for (int iParam = 0; iParam < _resultParams_VertLocal.Count; iParam++) { _cal_resultParam = _resultParams_VertLocal[iParam]; _cal_curWeight = _cal_resultParam.ModifierWeight; if (!_cal_resultParam.IsModifierAvailable || _cal_curWeight <= 0.001f) { continue; } _cal_posVerts = _cal_resultParam._result_Positions; if (_result_VertLocal == null) { Debug.LogError("Result Vert Local is Null"); } if (_cal_posVerts == null) { Debug.LogError("Cal Pos Vert is Null"); } if (_cal_posVerts.Count != _result_VertLocal.Length) { //결과가 잘못 들어왔다 갱신 필요 Debug.LogError("Wrong Vert Local Result (Cal : " + _cal_posVerts.Count + " / Verts : " + _result_VertLocal.Length + ")"); continue; } // Blend 방식에 맞게 Pos를 만들자 if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0) { for (int i = 0; i < _cal_posVerts.Count; i++) { _result_VertLocal[i] = BlendPosition_ITP(_result_VertLocal[i], _cal_posVerts[i], _cal_curWeight); //if (isFirstDebug) //{ // if (_result_VertLocal[i].sqrMagnitude > 0.0f) // { // Debug.Log("Valid Result Local : " + _result_VertLocal[i]); // isFirstDebug = false; // } //} } _cal_prevWeight += _cal_curWeight; } else { for (int i = 0; i < _cal_posVerts.Count; i++) { _result_VertLocal[i] = BlendPosition_Add(_result_VertLocal[i], _cal_posVerts[i], _cal_curWeight); } } _iCalculatedParam++; } #if UNITY_EDITOR Profiler.EndSample(); #endif } // 2. Mesh / MeshGroup Transformation if (_isAnyTransformation) { #if UNITY_EDITOR Profiler.BeginSample("Calcuate Result Stack - 2. MeshGroup Transformation"); #endif _cal_prevWeight = 0.0f; _cal_curWeight = 0.0f; _cal_resultParam = null; _iCalculatedParam = 0; //Debug.Log("Update TF - OPT"); for (int iParam = 0; iParam < _resultParams_Transform.Count; iParam++) { _cal_resultParam = _resultParams_Transform[iParam]; _cal_curWeight = _cal_resultParam.ModifierWeight; if (!_cal_resultParam.IsModifierAvailable || _cal_curWeight <= 0.001f) { continue; } // Blend 방식에 맞게 Matrix를 만들자 하자 if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0) { //Debug.Log("Cal TF [ITP] : " + _cal_resultParam._result_Matrix.Pos3 + " (Weight : " + _cal_curWeight + ")"); BlendMatrix_ITP(_result_MeshTransform, _cal_resultParam._result_Matrix, _cal_curWeight); //if (_cal_resultParam._result_Matrix.Scale2.magnitude < 0.5f || _cal_curWeight < 0.5f) //{ // Debug.Log("Cal TF [ITP] : " + _cal_resultParam._result_Matrix.Scale2 + " > " + _result_MeshTransform.Scale2 + " (Weight : " + _cal_curWeight + ")"); //} _cal_prevWeight += _cal_curWeight; } else { BlendMatrix_Add(_result_MeshTransform, _cal_resultParam._result_Matrix, _cal_curWeight); } _iCalculatedParam++; } _result_MeshTransform.MakeMatrix(); if (_result_MeshTransform._scale.magnitude < 0.5f) { Debug.Log("Cal TF [ITP] : " + _result_MeshTransform._scale + " (Total Weight : " + _cal_prevWeight + ")"); } #if UNITY_EDITOR Profiler.EndSample(); #endif } // 3. Mesh Color if (_isAnyMeshColor) { #if UNITY_EDITOR Profiler.BeginSample("Calcuate Result Stack - 3. Mesh Color"); #endif _cal_prevWeight = 0.0f; _cal_curWeight = 0.0f; _cal_resultParam = null; _iCalculatedParam = 0; _result_IsVisible = false; _nMeshColorCalculated = 0; _result_CalculatedColor = false; for (int iParam = 0; iParam < _resultParams_MeshColor.Count; iParam++) { _cal_resultParam = _resultParams_MeshColor[iParam]; _cal_curWeight = Mathf.Clamp01(_cal_resultParam.ModifierWeight); if (!_cal_resultParam.IsModifierAvailable || _cal_curWeight <= 0.001f || !_cal_resultParam.IsColorValueEnabled || !_cal_resultParam._isColorCalculated //<<추가 : Color로 등록했지만 아예 계산이 안되었을 수도 있다. ) { continue; } //<<TODO // Blend 방식에 맞게 Matrix를 만들자 하자 if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0) { //_result_Color = BlendColor_ITP(_result_Color, _cal_resultParam._result_Color, _cal_prevWeight, _cal_curWeight); _result_Color = apUtil.BlendColor_ITP(_result_Color, _cal_resultParam._result_Color, _cal_curWeight); _cal_prevWeight += _cal_curWeight; } else { _result_Color = apUtil.BlendColor_Add(_result_Color, _cal_resultParam._result_Color, _cal_curWeight); } _result_IsVisible |= _cal_resultParam._result_IsVisible; _nMeshColorCalculated++; _result_CalculatedColor = true; //<<"계산된 MeshColor" Result가 있음을 알린다. _iCalculatedParam++; } if (_nMeshColorCalculated == 0) { _result_IsVisible = true; } #if UNITY_EDITOR Profiler.EndSample(); #endif } else { _result_IsVisible = true; } //AnyBoneTransform if (_isAnyBoneTransform) { _cal_prevWeight = 0.0f; _cal_curWeight = 0.0f; _cal_resultParam = null; for (int iBonePair = 0; iBonePair < _resultParams_BoneTransform.Count; iBonePair++) { OptBoneAndModParamPair boneModPair = _resultParams_BoneTransform[iBonePair]; apOptBone targetBone = boneModPair._keyBone; List <OptModifierAndResultParamListPair> modParamPairs = boneModPair._modParamPairs; if (targetBone == null || modParamPairs.Count == 0) { continue; } _iCalculatedParam = 0; _result_BoneTransform.SetIdentity(); apMatrix lastMatrix = new apMatrix(); for (int iModParamPair = 0; iModParamPair < modParamPairs.Count; iModParamPair++) { OptModifierAndResultParamListPair modParamPair = modParamPairs[iModParamPair]; for (int iParam = 0; iParam < modParamPair._resultParams.Count; iParam++) { _cal_resultParam = modParamPair._resultParams[iParam]; _cal_curWeight = _cal_resultParam.ModifierWeight; if (!_cal_resultParam.IsModifierAvailable || _cal_curWeight <= 0.001f) { continue; } // Blend 방식에 맞게 Matrix를 만들자 하자 if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0) { BlendMatrix_ITP(_result_BoneTransform, _cal_resultParam._result_Matrix, _cal_curWeight); _cal_prevWeight += _cal_curWeight; } else { BlendMatrix_Add(_result_BoneTransform, _cal_resultParam._result_Matrix, _cal_curWeight); } lastMatrix.SetMatrix(_cal_resultParam._result_Matrix); _iCalculatedParam++; } } //참조된 본에 직접 값을 넣어주자 targetBone.UpdateModifiedValue(_result_BoneTransform._pos, _result_BoneTransform._angleDeg, _result_BoneTransform._scale); if (_result_BoneTransform._scale.magnitude < 0.3f && targetBone.name.Contains("Pelvis")) { Debug.LogError("본 사이즈가 너무 작다 : " + targetBone.name + " / Num CalParam : " + _iCalculatedParam + " / 마지막 Weight : " + _cal_curWeight + " / 마지막 Matrix : " + lastMatrix.ToString()); } } } }