public bool Remove(apOptCalculatedResultParam calculatedResultParam)
            {
                bool isAnyClearedParam = false;

                for (int i = 0; i < _modParamPairs.Count; i++)
                {
                    _modParamPairs[i].Remove(calculatedResultParam);
                    if (_modParamPairs[i]._resultParams.Count == 0)
                    {
                        isAnyClearedParam = true;
                    }
                }
                if (isAnyClearedParam)
                {
                    //Param이 없는 Pair는 삭제하고, Dictionary를 다시 만들어주자
                    _modParamPairs_ModKey.Clear();
                    _modParamPairs.RemoveAll(delegate(OptModifierAndResultParamListPair a)
                    {
                        return(a._resultParams.Count == 0);
                    });

                    for (int i = 0; i < _modParamPairs.Count; i++)
                    {
                        OptModifierAndResultParamListPair modPair = _modParamPairs[i];

                        //빠른 참조를 위해 Dictionary도 세팅해주자
                        if (!_modParamPairs_ModKey.ContainsKey(modPair._keyModifier))
                        {
                            _modParamPairs_ModKey.Add(modPair._keyModifier, modPair);
                        }
                    }
                }

                return(isAnyClearedParam);
            }
            public void AddCalculatedResultParam(apOptCalculatedResultParam calculatedResultParam)
            {
                apOptModifierUnitBase modifier = calculatedResultParam._linkedModifier;

                if (modifier == null)
                {
                    return;
                }

                OptModifierAndResultParamListPair modParamPair = null;

                if (!_modParamPairs_ModKey.ContainsKey(modifier))
                {
                    modParamPair = new OptModifierAndResultParamListPair(modifier);
                    _modParamPairs_ModKey.Add(modifier, modParamPair);
                    _modParamPairs.Add(modParamPair);
                }
                else
                {
                    modParamPair = _modParamPairs_ModKey[modifier];
                }
                modParamPair.AddCalculatedResultParam(calculatedResultParam);
            }
        /// <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;
                _cal_vertRequestList = null;
                _cal_vertRequest     = null;

                _iCalculatedParam = 0;                //<<추가 : 첫 모디파이어는 무조건 Interpolation으로 만들자


                #region [미사용 코드 : 최적화 전]
                //이전 코드
                //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.Length != _result_VertLocal.Length)
                //	{
                //		//결과가 잘못 들어왔다 갱신 필요
                //		Debug.LogError("Wrong Vert Local Result (Cal : " + _cal_posVerts.Length + " / Verts : " + _result_VertLocal.Length + ")");
                //		continue;
                //	}

                //	// Blend 방식에 맞게 Pos를 만들자
                //	if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0)
                //	{
                //		for (int i = 0; i < _cal_posVerts.Length; i++)
                //		{
                //			_result_VertLocal[i] = BlendPosition_ITP(_result_VertLocal[i], _cal_posVerts[i], _cal_curWeight);
                //		}

                //		_cal_prevWeight += _cal_curWeight;
                //	}
                //	else
                //	{
                //		for (int i = 0; i < _cal_posVerts.Length; i++)
                //		{
                //			_result_VertLocal[i] = BlendPosition_Add(_result_VertLocal[i], _cal_posVerts[i], _cal_curWeight);
                //		}
                //	}
                //	_iCalculatedParam++;
                //}
                #endregion

                //최적화된 코드.
                //Vertex Pos를 건드리지 않고 보간식을 중첩한다.
                for (int iParam = 0; iParam < _resultParams_VertLocal.Count; iParam++)
                {
                    _cal_resultParam = _resultParams_VertLocal[iParam];
                    _cal_resultParam._resultWeight = 0.0f;
                    _cal_curWeight = _cal_resultParam.ModifierWeight;

                    if (!_cal_resultParam.IsModifierAvailable || _cal_curWeight <= 0.001f)
                    {
                        continue;
                    }

                    _cal_resultParam._resultWeight = 1.0f;                    //<<일단 Weight를 1로 두고 계산 시작


                    // Blend 방식에 맞게 Pos를 만들자
                    if (_cal_resultParam.ModifierBlendMethod == apModifierBase.BLEND_METHOD.Interpolation || _iCalculatedParam == 0)
                    {
                        //Interpolation : Prev * (1-weight) + Next * weight
                        _cal_resultParam._resultWeight = _cal_curWeight;
                        for (int iPrev = 0; iPrev < iParam - 1; iPrev++)
                        {
                            _resultParams_VertLocal[iPrev]._resultWeight *= (1.0f - _cal_curWeight);
                        }
                    }
                    else
                    {
                        //Additive : Prev + Next * weight
                        _cal_resultParam._resultWeight = _cal_curWeight;
                    }
                    _iCalculatedParam++;
                }

                //이제 계산된 Weight를 모두 입력해주자
                for (int iParam = 0; iParam < _resultParams_VertLocal.Count; iParam++)
                {
                    _cal_resultParam     = _resultParams_VertLocal[iParam];
                    _cal_vertRequestList = _cal_resultParam._result_VertLocalPairs;
                    for (int iVR = 0; iVR < _cal_vertRequestList.Count; iVR++)
                    {
                        _cal_vertRequestList[iVR].MultiplyWeight(_cal_resultParam._resultWeight);
                    }
                }

//#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)
            {
//#if UNITY_EDITOR
//				Profiler.BeginSample("Calcuate Result Stack - 5. Bone Transform");
//#endif
                _cal_prevWeight  = 0.0f;
                _cal_curWeight   = 0.0f;
                _cal_resultParam = null;


                OptBoneAndModParamPair boneModPair = null;
                apOptBone targetBone = null;
                List <OptModifierAndResultParamListPair> modParamPairs = null;


                for (int iBonePair = 0; iBonePair < _resultParams_BoneTransform.Count; iBonePair++)
                {
                    boneModPair   = _resultParams_BoneTransform[iBonePair];
                    targetBone    = boneModPair._keyBone;
                    modParamPairs = boneModPair._modParamPairs;

                    if (targetBone == null || modParamPairs.Count == 0)
                    {
                        continue;
                    }


                    _iCalculatedParam = 0;
                    _result_BoneTransform.SetIdentity();

                    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;
                            }

                            //if(_cal_resultParam._result_Matrix._scale.magnitude < 0.3f)
                            //{
                            //	Debug.LogError("[" + targetBone.name + "] 너무 작은 Cal Matrix : " + _cal_resultParam._linkedModifier._name);
                            //}
                            // 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);
                            }

                            _iCalculatedParam++;
                        }
                    }

                    //참조된 본에 직접 값을 넣어주자
                    targetBone.UpdateModifiedValue(_result_BoneTransform._pos, _result_BoneTransform._angleDeg, _result_BoneTransform._scale);
                }

//#if UNITY_EDITOR
//				Profiler.EndSample();
//#endif
            }
        }
コード例 #4
0
        /// <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());
                    }
                }
            }
        }