/// <summary> /// RenderUnit의 CalculateStack을 업데이트한다. /// 기본 단계의 업데이트이며, Rigging, VertWorld는 Post Update에서 처리한다. /// </summary> /// <param name="tDelta"></param> /// <param name="isMakeHashCode"></param> //public void Calculate_Pre(float tDelta, bool isMakeHashCode) public void Calculate_Pre(float tDelta) { float prevWeight = 0.0f; float curWeight = 0.0f; apCalculatedResultParam resultParam = null; //추가) 처음 실행되는 CalParam은 Additive로 작동하지 않도록 한다. int iCalculatedParam = 0; //-------------------------------------------------------------------- // 1. Local Morph if (_isAnyVertLocal) { prevWeight = 0.0f; curWeight = 0.0f; resultParam = null; List <Vector2> posVerts = null; iCalculatedParam = 0; for (int iParam = 0; iParam < _resultParams_VertLocal.Count; iParam++) { resultParam = _resultParams_VertLocal[iParam]; curWeight = resultParam.ModifierWeight; if (!resultParam.IsModifierAvailable || curWeight <= 0.001f) { continue; } posVerts = resultParam._result_Positions; if (posVerts.Count != _result_VertLocal.Length) { //결과가 잘못 들어왔다 갱신 필요 Debug.LogError("Wrong Vert Local Result (Cal : " + posVerts.Count + " / Verts : " + _result_VertLocal.Length + ")"); continue; } // Blend 방식에 맞게 Pos를 만들자 if (resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || iCalculatedParam == 0) { for (int i = 0; i < posVerts.Count; i++) { _result_VertLocal[i] = BlendPosition_ITP(_result_VertLocal[i], posVerts[i], curWeight); } prevWeight += curWeight; //>>>> Calculated Log - VertLog resultParam.CalculatedLog.Calculate_CalParamResult(curWeight, iCalculatedParam, apModifierBase.BLEND_METHOD.Interpolation, CalculateLog_2_VertLocal); } else { for (int i = 0; i < posVerts.Count; i++) { _result_VertLocal[i] = BlendPosition_Add(_result_VertLocal[i], posVerts[i], curWeight); } //>>>> Calculated Log - VertLog resultParam.CalculatedLog.Calculate_CalParamResult(curWeight, iCalculatedParam, apModifierBase.BLEND_METHOD.Additive, CalculateLog_2_VertLocal); } //Debug.Log("[" + resultParam._targetRenderUnit.Name + "] : " + resultParam._linkedModifier.DisplayName + " / " + resultParam._paramKeyValues.Count); iCalculatedParam++; } ////HashCode를 만들자. //if (isMakeHashCode) //{ // if (_result_VertLocal.Length > 0) // { // _hashCode_VertLocal = _result_VertLocal[(_result_VertLocal.Length - 1) / 2].GetHashCode(); // } //} } //-------------------------------------------------------------------- // 2. Mesh / MeshGroup Transformation if (_isAnyTransformation) { prevWeight = 0.0f; curWeight = 0.0f; resultParam = null; iCalculatedParam = 0; for (int iParam = 0; iParam < _resultParams_Transform.Count; iParam++) { resultParam = _resultParams_Transform[iParam]; curWeight = resultParam.ModifierWeight; if (!resultParam.IsModifierAvailable || curWeight <= 0.001f) { continue; } // Blend 방식에 맞게 Matrix를 만들자 하자 if (resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || iCalculatedParam == 0) { BlendMatrix_ITP(_result_MeshTransform, resultParam._result_Matrix, curWeight); prevWeight += curWeight; //>>>> Calculated Log - VertLog resultParam.CalculatedLog.Calculate_CalParamResult(curWeight, iCalculatedParam, apModifierBase.BLEND_METHOD.Interpolation, CalculateLog_3_MeshTransform); } else { BlendMatrix_Add(_result_MeshTransform, resultParam._result_Matrix, curWeight); //>>>> Calculated Log - VertLog resultParam.CalculatedLog.Calculate_CalParamResult(curWeight, iCalculatedParam, apModifierBase.BLEND_METHOD.Additive, CalculateLog_3_MeshTransform); } iCalculatedParam++; } _result_MeshTransform.MakeMatrix(); ////HashCode를 만들자. //if (isMakeHashCode) //{ // _hashCode_MeshTransform = _result_MeshTransform.GetHashCode(); //} } //-------------------------------------------------------------------- // 3. Mesh Color if (_isAnyMeshColor) { prevWeight = 0.0f; curWeight = 0.0f; resultParam = null; iCalculatedParam = 0; _result_IsVisible = false; _result_CalculatedColor = false; int nMeshColorCalculated = 0; for (int iParam = 0; iParam < _resultParams_MeshColor.Count; iParam++) { resultParam = _resultParams_MeshColor[iParam]; curWeight = resultParam.ModifierWeight; if (!resultParam.IsModifierAvailable || curWeight <= 0.001f || !resultParam.IsColorValueEnabled || !resultParam._isColorCalculated //<<추가 : Color로 등록했지만 아예 계산이 안되었을 수도 있다. ) { continue; } // Blend 방식에 맞게 Matrix를 만들자 하자 if (resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || iCalculatedParam == 0) { //_result_Color = BlendColor_ITP(_result_Color, resultParam._result_Color, prevWeight, curWeight); _result_Color = apUtil.BlendColor_ITP(_result_Color, resultParam._result_Color, Mathf.Clamp01(curWeight)); prevWeight += curWeight; } else { _result_Color = apUtil.BlendColor_Add(_result_Color, resultParam._result_Color, curWeight); } //Visible 여부도 결정 _result_IsVisible |= resultParam._result_IsVisible; nMeshColorCalculated++; _result_CalculatedColor = true; //<<"계산된 MeshColor" Result가 있음을 알린다. //Debug.Log("MeshColor Update < " + resultParam._result_Color + " [" + resultParam._linkedModifier.DisplayName + "] (" + curWeight + ") >> " + _result_Color); iCalculatedParam++; } if (nMeshColorCalculated == 0) { //색상 처리값이 없다면 자동으로 True _result_IsVisible = true; } } else { //색상 처리값이 없다면 자동으로 True _result_IsVisible = true; } //-------------------------------------------------------------------- //5. Bone을 업데이트 하자 //Bone은 값 저장만 할게 아니라 직접 업데이트를 해야한다. if (_isAnyBoneTransform) //if(false) { prevWeight = 0.0f; curWeight = 0.0f; resultParam = null; for (int iBonePair = 0; iBonePair < _resultParams_BoneTransform.Count; iBonePair++) { BoneAndModParamPair boneModPair = _resultParams_BoneTransform[iBonePair]; apBone targetBone = boneModPair._keyBone; List <ModifierAndResultParamListPair> modParamPairs = boneModPair._modParamPairs; if (targetBone == null || modParamPairs.Count == 0) { continue; } iCalculatedParam = 0; _result_BoneTransform.SetIdentity(); for (int iModParamPair = 0; iModParamPair < modParamPairs.Count; iModParamPair++) { ModifierAndResultParamListPair modParamPair = modParamPairs[iModParamPair]; for (int iParam = 0; iParam < modParamPair._resultParams.Count; iParam++) { resultParam = modParamPair._resultParams[iParam]; curWeight = resultParam.ModifierWeight; if (!resultParam.IsModifierAvailable || curWeight <= 0.001f) { continue; } // Blend 방식에 맞게 Matrix를 만들자 하자 if (resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || iCalculatedParam == 0) { BlendMatrix_ITP(_result_BoneTransform, resultParam._result_Matrix, curWeight); prevWeight += curWeight; } else { BlendMatrix_Add(_result_BoneTransform, resultParam._result_Matrix, curWeight); } iCalculatedParam++; } } //참조된 본에 직접 값을 넣어주자 targetBone.UpdateModifiedValue(_result_BoneTransform._pos, _result_BoneTransform._angleDeg, _result_BoneTransform._scale); } } }
// Add / Remove / Sort //--------------------------------------------------- public void AddCalculatedResultParam(apCalculatedResultParam resultParam) { //Debug.Log("[" + _tmpID + "] AddCalculatedResultParam >> " + resultParam._resultType + "[R " + _parentRenderUnit._tmpName + "]"); if ((int)(resultParam._calculatedValueType & apCalculatedResultParam.CALCULATED_VALUE_TYPE.VertexPos) != 0) { if (resultParam._targetBone == null) { if (resultParam._calculatedSpace == apCalculatedResultParam.CALCULATED_SPACE.Object) { if (!_resultParams_VertLocal.Contains(resultParam)) { _resultParams_VertLocal.Add(resultParam); } _isAnyVertLocal = true; } else if (resultParam._calculatedSpace == apCalculatedResultParam.CALCULATED_SPACE.World) { if (!_resultParams_VertWorld.Contains(resultParam)) { _resultParams_VertWorld.Add(resultParam); } _isAnyVertWorld = true; } else if (resultParam._calculatedSpace == apCalculatedResultParam.CALCULATED_SPACE.Rigging) //<<추가되었다. { if (!_resultParams_Rigging.Contains(resultParam)) { _resultParams_Rigging.Add(resultParam); } _isAnyRigging = true; } else { Debug.LogError("허용되지 않은 데이터 타입 [Calculate : Vertex + Loca]"); } } } if ((int)(resultParam._calculatedValueType & apCalculatedResultParam.CALCULATED_VALUE_TYPE.TransformMatrix) != 0) { //변경 : Bone타입과 일반 Transform타입으로 나뉜다. if (resultParam._targetBone != null) { //Bone 타입이다. //Modifier + ResultParam Pair로 저장해야한다. BoneAndModParamPair modParamPair = _resultParams_BoneTransform.Find(delegate(BoneAndModParamPair a) { return(a._keyBone == resultParam._targetBone); }); if (modParamPair == null) { modParamPair = new BoneAndModParamPair(resultParam._targetBone); _resultParams_BoneTransform.Add(modParamPair); } modParamPair.AddCalculatedResultParam(resultParam); _isAnyBoneTransform = true; //이전 코드 //if(!_resultParams_BoneTransform.Contains(resultParam)) //{ // _resultParams_BoneTransform.Add(resultParam); // _isAnyBoneTransform = true; //} } else { //Mesh/MeshGroup Transform 타입이다. if (!_resultParams_Transform.Contains(resultParam)) { _resultParams_Transform.Add(resultParam); _isAnyTransformation = true; } } } if ((int)(resultParam._calculatedValueType & apCalculatedResultParam.CALCULATED_VALUE_TYPE.Color) != 0) { //Bone 타입은 제외한다. if (resultParam._targetBone == null) { if (!_resultParams_MeshColor.Contains(resultParam)) { _resultParams_MeshColor.Add(resultParam); _isAnyMeshColor = true; } } } //else //{ // Debug.LogError("apCalculatedResultStack / AddCalculatedResultParam : 알수없는 Result Type : " + resultParam._calculatedValueType); //} #region [미사용 코드] 변경되기 전의 Caculated Value //switch (resultParam._calculatedValueType) //{ // case apCalculatedResultParam.CALCULATED_VALUE_TYPE.VertexPos: // { // } // break; // case apCalculatedResultParam.CALCULATED_VALUE_TYPE.TransformMatrix: // if(!_resultParams_Transform.Contains(resultParam)) // { // _resultParams_Transform.Add(resultParam); // _isAnyTransformation = true; // } // break; // case apCalculatedResultParam.CALCULATED_VALUE_TYPE.MeshGroup_Color: // if(!_resultParams_MeshColor.Contains(resultParam)) // { // _resultParams_MeshColor.Add(resultParam); // _isAnyMeshColor = true; // } // break; // case apCalculatedResultParam.CALCULATED_VALUE_TYPE.Vertex_World: // if(!_resultParams_VertWorld.Contains(resultParam)) // { // _resultParams_VertWorld.Add(resultParam); // _isAnyVertWorld = true; // } // break; // default: // Debug.LogError("apCalculatedResultStack / AddCalculatedResultParam : 알수없는 Result Type : " + resultParam._calculatedValueType); // break; //} #endregion }