Пример #1
0
        public void AddParamKeyValueSet(apOptCalculatedResultParam.OptParamKeyValueSet paramKeyValue)
        {
            if (_subParamKeyValues.Contains(paramKeyValue))
            {
                return;
            }
            _subParamKeyValues.Add(paramKeyValue);
            _nSubParamKeyValues = _subParamKeyValues.Count;



            if (_isVertexLocalMorph || _isVertexRigging)
            {
                if (_vertexRequest == null)
                {
                    _vertexRequest = new apOptVertexRequest(_isVertexLocalMorph ? apOptVertexRequest.REQUEST_TYPE.VertLocal :  apOptVertexRequest.REQUEST_TYPE.Rigging);
                }
                //변경 19.5.24 : ModifiedMeshSet을 이용할지 여부
                if (paramKeyValue._modifiedMesh != null)
                {
                    _vertexRequest.AddModMesh(paramKeyValue._modifiedMesh);
                }
                else if (paramKeyValue._modifiedMeshSet != null)
                {
                    _vertexRequest.AddModMeshSet(paramKeyValue._modifiedMeshSet);
                }
            }
        }
        public apMatrix3x3 GetDeferredRiggingMatrix(int vertexIndex)
        {
            _tmpMatrix.SetZero3x2();

            for (int iParam = 0; iParam < _resultParams_Rigging.Count; iParam++)
            {
                _cal_resultParam = _resultParams_Rigging[iParam];
                for (int iVR = 0; iVR < _cal_resultParam._result_VertLocalPairs.Count; iVR++)
                {
                    _cal_vertRequest = _cal_resultParam._result_VertLocalPairs[iVR];
                    if (!_cal_vertRequest._isCalculated || _cal_vertRequest._totalWeight == 0.0f)
                    {
                        continue;
                    }

                    _tmpVertRigWeightTable = _cal_vertRequest._rigBoneWeightTables[vertexIndex];
                    if (_tmpVertRigWeightTable._nRigTable == 0)
                    {
                        continue;
                    }

                    for (int iRig = 0; iRig < _tmpVertRigWeightTable._nRigTable; iRig++)
                    {
                        _tmpVertRigWeightTable._rigTable[iRig].CalculateMatrix();
                        _tmpMatrix.AddMatrixWithWeight(_tmpVertRigWeightTable._rigTable[iRig]._boneMatrix, _tmpVertRigWeightTable._rigTable[iRig]._weight);
                    }
                }
            }

            return(_tmpMatrix);
        }
        public Vector2 GetDeferredLocalPos(int vertexIndex)
        {
            _tmpPos = Vector2.zero;

            for (int iParam = 0; iParam < _resultParams_VertLocal.Count; iParam++)
            {
                _cal_resultParam = _resultParams_VertLocal[iParam];
                for (int iVR = 0; iVR < _cal_resultParam._result_VertLocalPairs.Count; iVR++)
                {
                    _cal_vertRequest = _cal_resultParam._result_VertLocalPairs[iVR];
                    if (!_cal_vertRequest._isCalculated || _cal_vertRequest._totalWeight == 0.0f)
                    {
                        continue;
                    }

                    for (int iModPair = 0; iModPair < _cal_vertRequest._nModWeightPairs; iModPair++)
                    {
                        _cal_vertRequestModWeightPair = _cal_vertRequest._modWeightPairs[iModPair];
                        if (!_cal_vertRequestModWeightPair._isCalculated)
                        {
                            continue;
                        }
                        _tmpPos += _cal_vertRequestModWeightPair._modMesh._vertices[vertexIndex]._deltaPos * _cal_vertRequestModWeightPair._weight;
                    }
                }
            }

            return(_tmpPos);
        }
Пример #4
0
        // Init
        //--------------------------------------------
        public apOptCalculatedResultParamSubList(apOptCalculatedResultParam parentResultParam, bool isLocalMorph, bool isRigging)
        {
            _parentResultParam = parentResultParam;
            _subParamKeyValues.Clear();
            _nSubParamKeyValues = 0;

            _isVertexLocalMorph = isLocalMorph;
            _isVertexRigging    = isRigging;
            if (_isVertexLocalMorph)
            {
                _vertexRequest = new apOptVertexRequest(apOptVertexRequest.REQUEST_TYPE.VertLocal);
            }
            else if (_isVertexRigging)
            {
                _vertexRequest = new apOptVertexRequest(apOptVertexRequest.REQUEST_TYPE.Rigging);
            }
        }
        /// <summary>
        /// Calculate Result Statck의 업데이트 부분
        /// Pre-Update로서 VertWorld와 Rigging이 제외된다.
        /// </summary>
        public void Calculate_Post()
        {
            //bool isFirstDebug = true;
            _cal_prevWeight  = 0.0f;
            _cal_curWeight   = 0.0f;
            _cal_resultParam = null;
            _cal_posVerts    = null;


            // Rigging
            if (_isAnyRigging)
            {
//#if UNITY_EDITOR
//				Profiler.BeginSample("Calcuate Result Stack - 0. Rigging");
//#endif
                _cal_prevWeight  = 0.0f;
                _cal_curWeight   = 0.0f;
                _cal_resultParam = null;
                //_cal_posVerts = null;
                //_cal_vertMatrices = null;

                _iCalculatedParam = 0;


                _cal_vertRequestList = null;
                _cal_vertRequest     = null;

                _result_RiggingWeight = 0.0f;



                for (int iParam = 0; iParam < _resultParams_Rigging.Count; iParam++)
                {
                    _cal_resultParam = _resultParams_Rigging[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로 두고 계산 시작



                    _result_RiggingWeight += _cal_curWeight;

                    // 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_Rigging[iPrev]._resultWeight *= (1.0f - _cal_curWeight);
                        }
                    }
                    else
                    {
                        //Additive : Prev + Next * weight
                        _cal_resultParam._resultWeight = _cal_curWeight;
                    }

                    _iCalculatedParam++;
                }

                if (_result_RiggingWeight > 1.0f)
                {
                    _result_RiggingWeight = 1.0f;
                }

                //이제 계산된 Weight를 모두 입력해주자
                for (int iParam = 0; iParam < _resultParams_Rigging.Count; iParam++)
                {
                    _cal_resultParam     = _resultParams_Rigging[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
            }



            // 4. World Morph
            if (_isAnyVertWorld)
            {
//#if UNITY_EDITOR
//				Profiler.BeginSample("Calcuate Result Stack - 4. Vert World");
//#endif
                _cal_prevWeight  = 0.0f;
                _cal_curWeight   = 0.0f;
                _cal_resultParam = null;
                _cal_posVerts    = null;

                _iCalculatedParam = 0;

                for (int iParam = 0; iParam < _resultParams_VertWorld.Count; iParam++)
                {
                    _cal_resultParam = _resultParams_VertWorld[iParam];
                    _cal_curWeight   = _cal_resultParam.ModifierWeight;

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

                    //Debug.Log("Vert World [" + iParam + "] (" + _cal_curWeight + ")");

                    _cal_posVerts = _cal_resultParam._result_Positions;
                    if (_cal_posVerts.Length != _result_VertWorld.Length)
                    {
                        //결과가 잘못 들어왔다 갱신 필요
                        Debug.LogError("Wrong Vert World Result (Cal : " + _cal_posVerts.Length + " / Verts : " + _result_VertWorld.Length + ")");
                        continue;
                    }

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

                        _cal_prevWeight += _cal_curWeight;
                    }
                    else
                    {
                        for (int i = 0; i < _cal_posVerts.Length; i++)
                        {
                            _result_VertWorld[i] = BlendPosition_Add(_result_VertWorld[i], _cal_posVerts[i], _cal_curWeight);
                        }
                    }


                    _iCalculatedParam++;
                }

//#if UNITY_EDITOR
//				Profiler.EndSample();
//#endif
                //Debug.Log(" >> Vert World");
            }
        }
        /// <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
            }
        }