示例#1
0
        //-----------------------------------------------------------------------------------
        // 중요
        //-----------------------------------------------------------------------------------

        /// <summary>
        /// ParamSet간의 Weight를 계산한다. [ControlParam이 입력값인 경우]
        /// </summary>
        private void CalculateWeight_ControlParam()
        {
            //if(_controlParam == null)
            if (_keyParamSetGroup == null || _keyParamSetGroup._keyControlParam == null)
            {
                Debug.LogError("Key ParamSet Group is Null / Key Control Param Is null");
                return;
            }

            apControlParam controlParam = _keyParamSetGroup._keyControlParam;

            //1. 현재 값에 따라서 Dist 값을 넣자
            float minDist = float.MaxValue;
            float maxDist = 0.0f;
            float dist    = 0.0f;

            apCalculatedResultParam.ParamKeyValueSet curParamKeyValue  = null;
            apCalculatedResultParam.ParamKeyValueSet nextParamKeyValue = null;

            //int nSubParamKeyValues = _subParamKeyValues.Count;
            _totalWeight = 0.0f;

            for (int i = 0; i < _subParamKeyValues.Count; i++)
            {
                curParamKeyValue = _subParamKeyValues[i];
                dist             = -10.0f;
                curParamKeyValue._isCalculated = false;

#if UNITY_EDITOR
                //if (!curParamKeyValue._isActive_InEditorExclusive)
                if (!curParamKeyValue.IsActive)
                {
                    //에디터에서 제한한 Paramkey면
                    curParamKeyValue._dist         = -10.0f;
                    curParamKeyValue._isCalculated = false;

                    bool isKeyNull             = false;
                    bool isCalculateNotEnabled = false;
                    if (curParamKeyValue._keyParamSetGroup == null)
                    {
                        isKeyNull = true;
                    }
                    else if (!curParamKeyValue._keyParamSetGroup.IsCalculateEnabled)
                    {
                        isCalculateNotEnabled = true;
                    }
                    //Debug.LogError("CalResultParamSubList Weight Failed : " + _parentResultParam._targetRenderUnit + " / "
                    //	+ "ParamSetGroup Is Null : " + (isKeyNull) + " / Calculate Enabled : " + isCalculateNotEnabled);
                    continue;
                }
#endif

                //수식 1 : IDW 방식 (Inverse Distance Weighting)
                //-----------------------------------------------
                #region 수식 1 적용
                switch (controlParam._valueType)
                {
                //case apControlParam.TYPE.Bool:
                //	if (curParamKeyValue._paramSet._conSyncValue_Bool == controlParam._bool_Cur)
                //	{
                //		curParamKeyValue._dist = 0.0f;
                //		curParamKeyValue._isCalculated = true;
                //	}
                //	else
                //	{
                //		curParamKeyValue._dist = -10.0f;
                //		curParamKeyValue._isCalculated = false;
                //	}
                //	break;

                case apControlParam.TYPE.Int:
                    dist = controlParam.GetNormalizedDistance_Int(curParamKeyValue._paramSet._conSyncValue_Int);
                    break;

                case apControlParam.TYPE.Float:
                    dist = controlParam.GetNormalizedDistance_Float(curParamKeyValue._paramSet._conSyncValue_Float);
                    break;

                case apControlParam.TYPE.Vector2:
                    dist = controlParam.GetNormalizedDistance_Vector2(curParamKeyValue._paramSet._conSyncValue_Vector2);
                    break;

                    //case apControlParam.TYPE.Vector3:
                    //	dist = controlParam.GetNormalizedDistance_Vector3(curParamKeyValue._paramSet._conSyncValue_Vector3);
                    //	break;

                    //case apControlParam.TYPE.Color:
                    //	break;
                }


                if (dist < -1.0f)
                {
                    //계산 안함
                    continue;
                }

                curParamKeyValue._dist         = dist;
                curParamKeyValue._isCalculated = true;

                if (dist < minDist)
                {
                    minDist = dist;                    //<<최소 값
                }
                if (dist > maxDist)
                {
                    maxDist = dist;                    //최대값 (가장 Weight가 적게 걸리는 값)
                }


                #endregion
                //-----------------------------------------------
            }

            if (maxDist - minDist < 0.0001f)
            {
                maxDist = minDist + 0.0001f;
            }


            _totalWeight = 0.0f;
            // 여러개의 키값을 사용할 거라면


            #region [미사용 코드] 수식이 중복된다.
            //List<float> keepWeightRatios = new List<float>();


            //for (int i = 0; i < _subParamKeyValues.Count; i++)
            //{
            //	curParamKeyValue = _subParamKeyValues[i];
            //	if(curParamKeyValue._dist < -1.0f)
            //	{
            //		continue;
            //	}
            //	float keepWeightRatio = Mathf.Clamp01((curParamKeyValue._dist - minDist) / (maxDist - minDist));

            //	keepWeightRatios.Add(keepWeightRatio);
            //}

            //keepWeightRatios.Sort(delegate (float a, float b)
            //	{
            //		return (int)((a * 1000.0f) - (b * 1000.0f));
            //	});

            //bool isLimitedWeight = false;
            //float keepWeightRatio_Min = 0.0f;
            //float keepWeightRatio_Min2 = 0.0f;
            //float limitWeight = 1.0f;
            //if(keepWeightRatios.Count >= 2)
            //{
            //	isLimitedWeight = true;
            //	keepWeightRatio_Min = keepWeightRatios[0];
            //	keepWeightRatio_Min2 = keepWeightRatios[1];

            //	if(keepWeightRatio_Min2 - keepWeightRatio_Min < 0.0001f)
            //	{
            //		keepWeightRatio_Min2 = keepWeightRatio_Min + 0.0001f;
            //	}
            //	limitWeight = Mathf.Clamp01(0.5f - keepWeightRatio_Min) * 2;
            //}
            #endregion

            #region [미사용 코드] 역 선형 수식이지만 오류가 있다.
            //for (int i = 0; i < _subParamKeyValues.Count; i++)
            //{
            //	curParamKeyValue = _subParamKeyValues[i];

            //	if (curParamKeyValue._dist < -1.0f)
            //	{
            //		curParamKeyValue._weight = 0.0f;
            //		curParamKeyValue._isCalculated = false;
            //		continue;
            //	}

            //	//ITP 계산
            //	//1 - Dist로 역 선형 보간을 사용한다.
            //	//가장 가까운 포인트에서 MinDist를 구한다.
            //	//Min Dist가 0일때 = 어느 점에 도달했을때
            //	//> 다른 Weight가 0이 되어야 하며, Min Point인 부분은 Weight가 보전되어야 한다.
            //	//"보전률" = deltaMinDist가 작을수록 크다 (max를 구해야겠네)
            //	//"Mul-Weight" : 보전률에 비례한다. 보전률이 0일땐 MinDist (Normalize)의 값을 가지고, 최대일땐 1의 값을 가진다.

            //	float keepWeightRatio = 1.0f - Mathf.Clamp01((curParamKeyValue._dist - minDist) / (maxDist - minDist));

            //	// 가까우면 = 1 (감소 없음) / 멀면 minDist (포인트에 근접할 수록 0에 수렴)

            //	float multiplyWeight = (1.0f * keepWeightRatio) + minDist * (1.0f - keepWeightRatio);

            //	//만약, minDist가 일정 값 이하로 떨어지면 0으로 multiplyWeight가 아예 수렴해야한다.



            //	//float revWeight = (maxDist - curParamKeyValue._dist) * multiplyWeight;
            //	float revWeight = (2.0f - curParamKeyValue._dist) * multiplyWeight;//<<수정 : MaxDist가 아니라 Normalize 영역 크기(-1 ~ 1 = 2)로 빼야 적절하게 나온다.


            //	_totalWeight += revWeight;
            //	curParamKeyValue._weight = revWeight;
            //	curParamKeyValue._isCalculated = true;
            //}
            #endregion

            for (int i = 0; i < _subParamKeyValues.Count; i++)
            {
                curParamKeyValue = _subParamKeyValues[i];

                if (curParamKeyValue._dist < -1.0f)
                {
                    curParamKeyValue._weight       = 0.0f;
                    curParamKeyValue._weightBase   = 0.0f;
                    curParamKeyValue._isCalculated = false;
                    continue;
                }

                //변경
                //Weight 시작값이 기본 1이 아니라, 거리에 따른 가중치로 바뀐다.
                curParamKeyValue._weight = 1.0f;

                if (_subParamKeyValues.Count <= 2)
                //if(true)
                {
                    curParamKeyValue._weightBase = 1.0f;
                }
                else
                {
                    curParamKeyValue._weightBase = controlParam.GetInterpolationWeight(curParamKeyValue._dist);
                }
                curParamKeyValue._isCalculated = true;
                //_totalWeight += 1.0f;
                _totalWeight += curParamKeyValue._weight;                //변경!
            }

            if (_subParamKeyValues.Count >= 2)
            {
                _totalWeight = 0.0f;

                for (int i = 0; i < _subParamKeyValues.Count - 1; i++)
                {
                    curParamKeyValue = _subParamKeyValues[i];
                    if (!curParamKeyValue._isCalculated)
                    {
                        continue;
                    }
                    if (curParamKeyValue._weight < 0.00001f)
                    {
                        continue;
                    }
                    for (int j = i + 1; j < _subParamKeyValues.Count; j++)
                    {
                        nextParamKeyValue = _subParamKeyValues[j];
                        if (!nextParamKeyValue._isCalculated)
                        {
                            continue;
                        }

                        float sumDist = curParamKeyValue._dist + nextParamKeyValue._dist;
                        if (sumDist < 0.0001f)
                        {
                            curParamKeyValue._weight  *= 1.0f;
                            nextParamKeyValue._weight *= 1.0f;
                        }
                        else
                        {
                            float itp = Mathf.Clamp01((sumDist - curParamKeyValue._dist) / sumDist);
                            //float baseWeight = (curParamKeyValue._weightBase + nextParamKeyValue._weightBase) * 0.5f;
                            float baseWeight = Mathf.Clamp01(curParamKeyValue._weightBase + nextParamKeyValue._weightBase);
                            //float baseWeight = curParamKeyValue._weightBase * nextParamKeyValue._weightBase;

                            //float itp = apAnimCurve.GetSmoothInterpolation((sumDist - curParamKeyValue._dist) / sumDist);
                            //curParamKeyValue._weight *= itp;
                            //nextParamKeyValue._weight *= (1.0f - itp);
                            curParamKeyValue._weight  = curParamKeyValue._weight * ((1.0f - baseWeight) + itp * baseWeight);
                            nextParamKeyValue._weight = nextParamKeyValue._weight * ((1.0f - baseWeight) + (1.0f - itp) * baseWeight);


                            if (itp < 0.00001f)
                            {
                                break;
                            }
                        }
                    }
                }

                for (int i = 0; i < _subParamKeyValues.Count; i++)
                {
                    curParamKeyValue = _subParamKeyValues[i];
                    if (curParamKeyValue._isCalculated)
                    {
                        _totalWeight += curParamKeyValue._weight;
                    }
                }
            }

            //공통 부분
            if (_totalWeight > 0.0f)
            {
                for (int i = 0; i < _subParamKeyValues.Count; i++)
                {
                    curParamKeyValue = _subParamKeyValues[i];

                    if (curParamKeyValue._isCalculated)
                    {
                        curParamKeyValue._weight /= _totalWeight;
                    }
                    else
                    {
                        curParamKeyValue._weight = 0.0f;
                    }
                }
            }
        }
示例#2
0
        private void CalculateWeight_ControlParam()
        {
            if (_keyParamSetGroup._keyControlParam == null)
            {
                Debug.LogError("Null Key Control Param");
                return;
            }


            //Debug.Log("Update Control Param : " + _keyParamSetGroup._keyControlParam._keyName);

            _cal_controlParam = _keyParamSetGroup._keyControlParam;

            //_cal_minDist = float.MaxValue;
            //_cal_maxDist = 0.0f;
            _cal_dist             = 0.0f;
            _cal_curParamKeyValue = null;
            _totalWeight          = 0.0f;

            //Debug.Log(_cal_controlParam._keyName + " : " + _cal_controlParam._vec2_Cur);

            for (int i = 0; i < _nSubParamKeyValues; i++)
            {
                _cal_curParamKeyValue = _subParamKeyValues[i];
                _cal_dist             = -10.0f;
                _cal_curParamKeyValue._isCalculated = false;

                switch (_cal_controlParam._valueType)
                {
                //case apControlParam.TYPE.Bool:
                //	if(_cal_curParamKeyValue._paramSet._conSyncValue_Bool == _cal_controlParam._bool_Cur)
                //	{
                //		_cal_curParamKeyValue._dist = 0.0f;
                //		_cal_curParamKeyValue._isCalculated = true;
                //	}
                //	else
                //	{
                //		_cal_curParamKeyValue._dist = -10.0f;
                //		_cal_curParamKeyValue._isCalculated = false;
                //	}
                //	break;

                case apControlParam.TYPE.Int:
                    _cal_dist = _cal_controlParam.GetNormalizedDistance_Int(_cal_curParamKeyValue._paramSet._conSyncValue_Int);
                    break;

                case apControlParam.TYPE.Float:
                    _cal_dist = _cal_controlParam.GetNormalizedDistance_Float(_cal_curParamKeyValue._paramSet._conSyncValue_Float);
                    break;

                case apControlParam.TYPE.Vector2:
                    _cal_dist = _cal_controlParam.GetNormalizedDistance_Vector2(_cal_curParamKeyValue._paramSet._conSyncValue_Vector2);
                    break;

                    //case apControlParam.TYPE.Vector3:
                    //	_cal_dist = _cal_controlParam.GetNormalizedDistance_Vector3(_cal_curParamKeyValue._paramSet._conSyncValue_Vector3);
                    //	break;
                }
                if (_cal_dist < -1.0f)
                {
                    _cal_curParamKeyValue._dist         = -10.0f;
                    _cal_curParamKeyValue._isCalculated = false;
                    _cal_curParamKeyValue._weight       = 0.0f;
                    continue;
                }

                //주의 : Runtime에서는 Matched가 없다.

                _cal_curParamKeyValue._dist         = _cal_dist;
                _cal_curParamKeyValue._isCalculated = true;
                _cal_curParamKeyValue._weight       = 1.0f;
                _totalWeight += 1.0f;
            }

            //-----------------------------------------------
            // Weight 계산



            //선형 IDW 방식으로 계산한다.
            #region [미사용 코드] 역선형 보간 방식은 오류가 있다;
            //for (int i = 0; i < _nSubParamKeyvalues; i++)
            //{
            //	_cal_curParamKeyValue = _subParamKeyValues[i];
            //	if(!_cal_curParamKeyValue._isCalculated)
            //	{
            //		_cal_curParamKeyValue._weight = 0.0f;
            //		continue;
            //	}

            //	_cal_keepWeightRatio = Mathf.Clamp01((_cal_curParamKeyValue._dist - _cal_minDist) / (_cal_maxDist - _cal_minDist));
            //	_cal_mulWeight = (_cal_minDist * _cal_keepWeightRatio) + (1.0f - _cal_keepWeightRatio);
            //	//_cal_revWeight = (_cal_maxDist - _cal_curParamKeyValue._dist) * _cal_mulWeight;
            //	_cal_revWeight = (2.0f - _cal_curParamKeyValue._dist) * _cal_mulWeight;

            //	//_cal_revWeight = (1.0f / (_cal_curParamKeyValue._dist)) * _cal_mulWeight;

            //	_totalWeight += _cal_revWeight;
            //	_cal_curParamKeyValue._weight = _cal_revWeight;
            //}
            #endregion

            if (_nSubParamKeyValues >= 2)
            {
                _totalWeight = 0.0f;
                for (int i = 0; i < _nSubParamKeyValues; i++)
                {
                    _cal_curParamKeyValue = _subParamKeyValues[i];
                    if (!_cal_curParamKeyValue._isCalculated || _cal_curParamKeyValue._weight < _zeroBias)
                    {
                        continue;
                    }

                    //다른 SubParam과의 Dist를 비교하여 내분 Weight를 하자
                    if (i + 1 < _nSubParamKeyValues)
                    {
                        for (int j = i + 1; j < _nSubParamKeyValues; j++)
                        {
                            _cal_nextParamKeyValue = _subParamKeyValues[j];
                            if (!_cal_nextParamKeyValue._isCalculated)
                            {
                                continue;
                            }

                            _cal_sumDist = _cal_curParamKeyValue._dist + _cal_nextParamKeyValue._dist;
                            if (_cal_sumDist > _zeroBias)
                            {
                                _cal_itp = Mathf.Clamp01((_cal_sumDist - _cal_curParamKeyValue._dist) / _cal_sumDist);
                                _cal_curParamKeyValue._weight  *= _cal_itp;
                                _cal_nextParamKeyValue._weight *= (1.0f - _cal_itp);
                            }
                        }
                    }

                    _totalWeight += _cal_curParamKeyValue._weight;
                }
            }



            if (_totalWeight > 0.0f)
            {
                for (int i = 0; i < _nSubParamKeyValues; i++)
                {
                    _cal_curParamKeyValue = _subParamKeyValues[i];
                    if (_cal_curParamKeyValue._isCalculated)
                    {
                        _cal_curParamKeyValue._weight /= _totalWeight;
                    }
                }
            }
        }