예제 #1
0
 public void AddParamKeyValueSet(apCalculatedResultParam.ParamKeyValueSet paramKeyValue)
 {
     if (_subParamKeyValues.Contains(paramKeyValue))
     {
         return;
     }
     //Debug.Log("AddParamKeyValueSet");
     _subParamKeyValues.Add(paramKeyValue);
 }
예제 #2
0
        private void CalculateWeight_Static()
        {
            ///계산할 필요가 없는데용...
            if (_keyParamSetGroup == null)
            {
                Debug.LogError("Key ParamSet Group is Null / Key Control Param Is null");
                return;
            }

            apCalculatedResultParam.ParamKeyValueSet curParamKeyValue = null;
            for (int i = 0; i < _subParamKeyValues.Count; i++)
            {
                curParamKeyValue               = _subParamKeyValues[i];
                curParamKeyValue._weight       = 1.0f;
                curParamKeyValue._isCalculated = true;                //<<나중에 이것도 true로 올리자
            }
        }
예제 #3
0
        /// <summary>
        /// ParamSet간의 Weight를 계산한다. [Keyframe이 입력값인 경우]
        /// </summary>
        private void CalculateWeight_Keyframe()
        {
            if (_keyParamSetGroup == null || _keyParamSetGroup._keyAnimTimelineLayer == null)
            {
                return;
            }

            if (_keyParamSetGroup._keyAnimClip._isSelectedInEditor)
            {
                _keyParamSetGroup._layerWeight = 1.0f;
            }
            else
            {
                _keyParamSetGroup._layerWeight = 0.0f;
            }

            apAnimTimelineLayer timlineLayer = _keyParamSetGroup._keyAnimTimelineLayer;

            apCalculatedResultParam.ParamKeyValueSet curParamKeyValue = null;
            int curFrame = timlineLayer._parentAnimClip.CurFrame;

            bool           isLoop        = timlineLayer._parentAnimClip.IsLoop;
            apAnimKeyframe firstKeyframe = timlineLayer._firstKeyFrame;
            apAnimKeyframe lastKeyframe  = timlineLayer._lastKeyFrame;

            //int firstFrame = -1;
            //int lastFrame = -1;
            //if(isLoop)
            //{
            //	if(firstKeyframe != null)
            //	{
            //		firstFrame = firstKeyframe._frameIndex;
            //	}

            //	if(lastKeyframe != null)
            //	{
            //		lastFrame = lastKeyframe._frameIndex;
            //	}
            //}

            _totalWeight = 0.0f;

            apAnimKeyframe curKeyframe  = null;
            apAnimKeyframe prevKeyframe = null;
            apAnimKeyframe nextKeyframe = null;

            //int indexOffsetA = 0;
            //int indexOffsetB = 0;
            int lengthFrames = timlineLayer._parentAnimClip.EndFrame - timlineLayer._parentAnimClip.StartFrame;
            int tmpCurFrame  = 0;

            //Debug.Log("Calculated--------------------------------");
            for (int i = 0; i < _subParamKeyValues.Count; i++)
            {
                curParamKeyValue               = _subParamKeyValues[i];
                curParamKeyValue._dist         = -10.0f;
                curParamKeyValue._isCalculated = false;

                //유효하지 않은 키프레임이면 처리하지 않는다.
                if (curParamKeyValue._paramSet.SyncKeyframe == null ||
                    !curParamKeyValue._paramSet.SyncKeyframe._isActive ||
                    //!curParamKeyValue._isActive_InEditorExclusive
                    !curParamKeyValue.IsActive
                    )
                {
                    //Debug.Log("[" + i + "] Not Active or Null Keyframe");
                    continue;
                }

                curKeyframe  = curParamKeyValue._paramSet.SyncKeyframe;
                prevKeyframe = curParamKeyValue._paramSet.SyncKeyframe._prevLinkedKeyframe;
                nextKeyframe = curParamKeyValue._paramSet.SyncKeyframe._nextLinkedKeyframe;


                //1. 프레임이 같다. => 100%
                if (curFrame == curKeyframe._frameIndex ||
                    ((curKeyframe._isLoopAsStart || curKeyframe._isLoopAsEnd) && curFrame == curKeyframe._loopFrameIndex))
                {
                    curParamKeyValue._dist         = 0.0f;
                    curParamKeyValue._isCalculated = true;
                    curParamKeyValue._weight       = 1.0f;
                    _totalWeight += 1.0f;

                    //Debug.Log("[" + i + "] <Exact Frame>");
                }
                //else if(curFrame >= curKeyframe._activeFrameIndexMin &&
                //		curFrame < curKeyframe._frameIndex)
                else if (curKeyframe.IsFrameIn(curFrame, true))
                {
                    //범위 안에 들었다. [Prev - Cur]
                    if (prevKeyframe != null)
                    {
                        //indexOffsetA = 0;
                        //indexOffsetB = 0;
                        //if(prevKeyframe._frameIndex > curKeyframe._frameIndex)
                        //{
                        //	//Loop인 경우 Prev가 더 클 수 있다.
                        //	indexOffsetA = -lengthFrames;
                        //}

                        tmpCurFrame = curFrame;
                        if (tmpCurFrame > curKeyframe._frameIndex)
                        {
                            tmpCurFrame -= lengthFrames;
                        }

                        //float itp = apAnimCurve.GetCurvedRelativeInterpolation(prevKeyframe._curveKey, curKeyframe._curveKey, curFrame, curKeyframe._curveKey._isPrevKeyUseDummyIndex, false);
                        //float itp = apAnimCurve.GetCurvedRelativeInterpolation(curKeyframe._curveKey, prevKeyframe._curveKey, tmpCurFrame, true);

                        //>> 변경
                        float itp = curKeyframe._curveKey.GetItp_Int(tmpCurFrame, true);

                        curParamKeyValue._dist         = 0.0f;
                        curParamKeyValue._isCalculated = true;
                        curParamKeyValue._weight       = itp;
                        _totalWeight += itp;

                        //Debug.Log("[" + i + "] [Prev ~ Cur] " + itp);
                        //Debug.Log("Prev ~ Next : " + itp);
                    }
                    else
                    {
                        //연결된게 없다면 이게 100% 가중치를 갖는다.
                        curParamKeyValue._dist         = 0.0f;
                        curParamKeyValue._isCalculated = true;
                        curParamKeyValue._weight       = 1.0f;
                        _totalWeight += 1.0f;
                        //Debug.Log("[" + i + "] [Prev ?? ~ Cur] 1.0");
                    }
                }
                //else if(curFrame > curKeyframe._frameIndex &&
                //		curFrame <= curKeyframe._activeFrameIndexMax)
                else if (curKeyframe.IsFrameIn(curFrame, false))
                {
                    //범위안에 들었다 [Cur - Next]
                    if (nextKeyframe != null)
                    {
                        //indexOffsetA = 0;
                        //indexOffsetB = 0;
                        //if(nextKeyframe._frameIndex < curKeyframe._frameIndex)
                        //{
                        //	//Loop인 경우 Next가 더 작을 수 있다.
                        //	indexOffsetB = lengthFrames;
                        //}

                        tmpCurFrame = curFrame;
                        if (tmpCurFrame < curKeyframe._frameIndex)
                        {
                            tmpCurFrame += lengthFrames;
                        }

                        //float itp = apAnimCurve.GetCurvedRelativeInterpolation(curKeyframe._curveKey, nextKeyframe._curveKey, curFrame, false, curKeyframe._curveKey._isNextKeyUseDummyIndex);
                        //float itp = apAnimCurve.GetCurvedRelativeInterpolation(curKeyframe._curveKey, nextKeyframe._curveKey, tmpCurFrame, false);

                        //>> 변경
                        float itp = curKeyframe._curveKey.GetItp_Int(tmpCurFrame, false);

                        //itp = 1.0f - itp;//결과가 B에 맞추어지므로 여기서는 Reverse

                        curParamKeyValue._dist         = 0.0f;
                        curParamKeyValue._isCalculated = true;
                        curParamKeyValue._weight       = itp;
                        _totalWeight += itp;

                        //Debug.Log("[" + i + "] [Cur ~ Next] " + itp);
                    }
                    else
                    {
                        //연결된게 없다면 이게 100% 가중치를 갖는다.
                        curParamKeyValue._dist         = 0.0f;
                        curParamKeyValue._isCalculated = true;
                        curParamKeyValue._weight       = 1.0f;
                        _totalWeight += 1.0f;

                        //Debug.Log("[" + i + "] [Cur ~ Next ??] 1.0");
                    }
                }
            }

            if (_totalWeight > 0.0f)
            {
                //Debug.Log("Result --------------------------------");
                float prevWeight = 0.0f;
                for (int i = 0; i < _subParamKeyValues.Count; i++)
                {
                    curParamKeyValue = _subParamKeyValues[i];

                    if (curParamKeyValue._isCalculated)
                    {
                        curParamKeyValue._weight /= _totalWeight;
                        //Debug.Log("[" + curParamKeyValue._weight + "]");
                    }
                    else
                    {
                        curParamKeyValue._weight = 0.0f;
                    }
                }
                //Debug.Log("-------------------------------------");
            }
        }
예제 #4
0
        private void CalculateWeight_ControlParam_2D()
        {
            if (_keyParamSetGroup == null || _keyParamSetGroup._keyControlParam == null)
            {
                Debug.LogError("Key ParamSet Group is Null / Key Control Param Is null");
                return;
            }

            apControlParam controlParam = _keyParamSetGroup._keyControlParam;


            //1. Param의 Weight를 모두 0으로 세팅 (+ 연산으로 Weight를 추가하는 방식)
            //2. 어느 RectArea에 있는지 결정한다.
            //3. Rect 안에서 itp를 계산한다.
            apCalculatedResultParam.ParamKeyValueSet curParamKeyValue = null;
            for (int i = 0; i < _subParamKeyValues.Count; i++)
            {
                curParamKeyValue               = _subParamKeyValues[i];
                curParamKeyValue._weight       = 0.0f;
                curParamKeyValue._isCalculated = false;                //<<나중에 이것도 true로 올리자
            }

            Vector2 curValue = controlParam._vec2_Cur;

            if (_cpLerpAreaLastSelected == null || !_cpLerpAreaLastSelected.IsInclude(curValue))
            {
                _cpLerpAreaLastSelected = _cpLerpAreas.Find(delegate(apCalculatedLerpArea a)
                {
                    return(a.IsInclude(curValue));
                });
            }
            if (_cpLerpAreaLastSelected == null)
            {
                //잠깐 끕시더
                //Debug.LogError("No Lerp Area");
                return;                //처리가 안되는데요;
            }

            _cpLerpAreaLastSelected.ReadyToCalculate();

            float itpX         = 0.0f;
            float itpY         = 0.0f;
            float rectPosX_Min = _cpLerpAreaLastSelected._posLT.x;
            float rectPosX_Max = _cpLerpAreaLastSelected._posRB.x;
            float rectPosY_Min = _cpLerpAreaLastSelected._posLT.y;
            float rectPosY_Max = _cpLerpAreaLastSelected._posRB.y;

            itpX = 1.0f - Mathf.Clamp01((curValue.x - rectPosX_Min) / (rectPosX_Max - rectPosX_Min));
            itpY = 1.0f - Mathf.Clamp01((curValue.y - rectPosY_Min) / (rectPosY_Max - rectPosY_Min));

            _cpLerpAreaLastSelected._pointLT._calculatedWeight = itpX * itpY;
            _cpLerpAreaLastSelected._pointRT._calculatedWeight = (1.0f - itpX) * itpY;
            _cpLerpAreaLastSelected._pointLB._calculatedWeight = itpX * (1.0f - itpY);
            _cpLerpAreaLastSelected._pointRB._calculatedWeight = (1.0f - itpX) * (1.0f - itpY);

            _cpLerpAreaLastSelected._pointLT.CalculateITPWeight();
            _cpLerpAreaLastSelected._pointRT.CalculateITPWeight();
            _cpLerpAreaLastSelected._pointLB.CalculateITPWeight();
            _cpLerpAreaLastSelected._pointRB.CalculateITPWeight();

            _totalWeight = 0.0f;

            // 여러개의 키값을 사용할 거라면
            for (int i = 0; i < _subParamKeyValues.Count; i++)
            {
                curParamKeyValue = _subParamKeyValues[i];

                if (!curParamKeyValue._isCalculated)
                {
                    curParamKeyValue._weight = 0.0f;
                    continue;
                }

                //변경
                //Weight 시작값이 기본 1이 아니라, 거리에 따른 가중치로 바뀐다.
                _totalWeight += curParamKeyValue._weight;
            }
            if (_totalWeight > 0.0f)
            {
                for (int i = 0; i < _subParamKeyValues.Count; i++)
                {
                    curParamKeyValue = _subParamKeyValues[i];
                    if (curParamKeyValue._isCalculated)
                    {
                        curParamKeyValue._weight /= _totalWeight;
                    }
                }
            }
        }
예제 #5
0
        private void CalculateWeight_ControlParam_1D()
        {
            if (_keyParamSetGroup == null || _keyParamSetGroup._keyControlParam == null)
            {
                Debug.LogError("Key ParamSet Group is Null / Key Control Param Is null");
                return;
            }

            apControlParam controlParam = _keyParamSetGroup._keyControlParam;

            apCalculatedResultParam.ParamKeyValueSet curParamKeyValue = null;
            for (int i = 0; i < _subParamKeyValues.Count; i++)
            {
                curParamKeyValue               = _subParamKeyValues[i];
                curParamKeyValue._weight       = 0.0f;
                curParamKeyValue._isCalculated = false;                //<<나중에 이것도 true로 올리자
            }
            if (_cpLerpPoints.Count == 0)
            {
                return;                //처리 불가;
            }

            if (_cpLerpPoints.Count == 1)
            {
                _cpLerpPoints[0]._calculatedWeight = 1.0f;
                _cpLerpPoints[0].CalculateITPWeight();
            }
            else
            {
                //1) ITP를 계산할 두개의 Point (A, B)를 잡는다.
                //2) 두개의 포인트를 기준으로 ITP를 계산한다.
                //3) Total Weight 계산 후 적용
                bool isRefreshLerpPointRange = false;
                if (_cpLerpPoint_A == null || _cpLerpPoint_B == null)
                {
                    isRefreshLerpPointRange = true;
                }
                else
                {
                    if (controlParam._valueType == apControlParam.TYPE.Int)
                    {
                        if (controlParam._int_Cur < _cpLerpPoint_A._iPos ||
                            controlParam._int_Cur > _cpLerpPoint_B._iPos)
                        {
                            isRefreshLerpPointRange = true;
                        }
                    }
                    else
                    {
                        if (controlParam._float_Cur < _cpLerpPoint_A._pos.x ||
                            controlParam._float_Cur > _cpLerpPoint_B._pos.x)
                        {
                            isRefreshLerpPointRange = true;
                        }
                    }
                }

                if (isRefreshLerpPointRange)
                {
                    //0..1..2.. [value]..3...4
                    int iB = -1;
                    if (controlParam._valueType == apControlParam.TYPE.Int)
                    {
                        for (int i = 0; i < _cpLerpPoints.Count; i++)
                        {
                            if (controlParam._int_Cur <= _cpLerpPoints[i]._iPos)
                            {
                                iB = i;
                                break;
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < _cpLerpPoints.Count; i++)
                        {
                            if (controlParam._float_Cur <= _cpLerpPoints[i]._pos.x)
                            {
                                iB = i;
                                break;
                            }
                        }
                    }
                    if (iB < 0)
                    {
                        iB = _cpLerpPoints.Count - 1;
                    }

                    _cpLerpPoint_B = _cpLerpPoints[iB];
                    if (iB == 0)
                    {
                        _cpLerpPoint_A = _cpLerpPoints[0];
                    }
                    else
                    {
                        _cpLerpPoint_A = _cpLerpPoints[iB - 1];
                    }
                }

                if (_cpLerpPoint_A == null || _cpLerpPoint_B == null)
                {
                    return;
                }

                if (_cpLerpPoint_A == _cpLerpPoint_B)
                {
                    _cpLerpPoint_A._calculatedWeight = 1.0f;
                    _cpLerpPoint_A.CalculateITPWeight();
                }
                else
                {
                    float itp = 0.0f;
                    if (controlParam._valueType == apControlParam.TYPE.Int)
                    {
                        itp = 1.0f - Mathf.Clamp01((float)(controlParam._int_Cur - _cpLerpPoint_A._iPos) / (float)(_cpLerpPoint_B._iPos - _cpLerpPoint_A._iPos));
                    }
                    else
                    {
                        itp = 1.0f - Mathf.Clamp01((float)(controlParam._float_Cur - _cpLerpPoint_A._pos.x) / (float)(_cpLerpPoint_B._pos.x - _cpLerpPoint_A._pos.x));
                    }

                    _cpLerpPoint_A._calculatedWeight = itp;
                    _cpLerpPoint_B._calculatedWeight = 1.0f - itp;

                    _cpLerpPoint_A.CalculateITPWeight();
                    _cpLerpPoint_B.CalculateITPWeight();
                }

                _totalWeight = 0.0f;

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

                    if (!curParamKeyValue._isCalculated)
                    {
                        curParamKeyValue._weight = 0.0f;
                        continue;
                    }

                    _totalWeight += curParamKeyValue._weight;
                }

                if (_totalWeight > 0.0f)
                {
                    for (int i = 0; i < _subParamKeyValues.Count; i++)
                    {
                        curParamKeyValue = _subParamKeyValues[i];
                        if (curParamKeyValue._isCalculated)
                        {
                            curParamKeyValue._weight /= _totalWeight;
                        }
                    }
                }
            }
        }
예제 #6
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;
                    }
                }
            }
        }
예제 #7
0
        //Control Param 보간 관련
        //--------------------------------------------------------------------------------------
        private void MakeControlParamLerpAreas()
        {
            //1. ParamSetKeyValue => Point를 만든다.

            _cpLerpAreas.Clear();
            _cpLerpPoints.Clear();

            apControlParam controlParam = _keyParamSetGroup._keyControlParam;

            if (controlParam == null)
            {
                return;
            }

            List <float> fPosXList = new List <float>();
            List <float> fPosYList = new List <float>();

            float bias = 0.001f;

            if (controlParam._valueType == apControlParam.TYPE.Float)
            {
                bias = Mathf.Abs((controlParam._float_Max - controlParam._float_Min) * 0.05f);
                bias = Mathf.Clamp(bias, 0.0001f, 0.1f);
            }
            else if (controlParam._valueType == apControlParam.TYPE.Vector2)
            {
                bias = Mathf.Min(Mathf.Abs((controlParam._vec2_Max.x - controlParam._vec2_Min.x) * 0.05f),
                                 Mathf.Abs((controlParam._vec2_Max.y - controlParam._vec2_Min.y) * 0.05f));
                bias = Mathf.Clamp(bias, 0.0001f, 0.1f);
            }


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

                if (keyValueSet._paramSet == null)
                {
                    continue;
                }

                apCalculatedLerpPoint newPoint = null;
                switch (controlParam._valueType)
                {
                case apControlParam.TYPE.Int:
                {
                    int iPos = keyValueSet._paramSet._conSyncValue_Int;
                    newPoint = new apCalculatedLerpPoint(iPos, true);
                }
                break;

                case apControlParam.TYPE.Float:
                {
                    float fPos = keyValueSet._paramSet._conSyncValue_Float;
                    newPoint = new apCalculatedLerpPoint(fPos, true);
                }
                break;

                case apControlParam.TYPE.Vector2:
                {
                    Vector2 vPos = keyValueSet._paramSet._conSyncValue_Vector2;
                    newPoint = new apCalculatedLerpPoint(vPos, true);

                    //위치를 저장해둔다.
                    AddLerpPos(vPos, fPosXList, fPosYList, bias);
                }
                break;
                }

                newPoint.AddPoint(keyValueSet, 1.0f);                //실제 키는 Weight가 1이다.
                _cpLerpPoints.Add(newPoint);
            }


            //2-1 1차원 값이면 오름차순 정렬하는 걸로 끝
            switch (controlParam._valueType)
            {
            case apControlParam.TYPE.Int:
                _cpLerpPoints.Sort(delegate(apCalculatedLerpPoint a, apCalculatedLerpPoint b)
                {
                    return(a._iPos - b._iPos);
                });
                break;

            case apControlParam.TYPE.Float:
                _cpLerpPoints.Sort(delegate(apCalculatedLerpPoint a, apCalculatedLerpPoint b)
                {
                    return((int)((a._pos.x - b._pos.x) * (1.0f / bias) * 100.0f));
                });
                break;
            }


            //2-2. (Vector2인 경우) Rect Area를 만들자.
            if (controlParam._valueType == apControlParam.TYPE.Vector2)
            {
                //1) Min, Max 위치에 대해서 확인 후 가상 포인트를 추가하자
                //2) X, Y 값에 대해서 정렬
                //3) X, Y 좌표를 순회하면서 "포인트가 없다면" 가상 포인트를 추가하자
                //4) X, Y 좌표 순회하면서 RectArea를 만들자.

                //1)
                float minX = controlParam._vec2_Min.x;
                float minY = controlParam._vec2_Min.y;
                float maxX = controlParam._vec2_Max.x;
                float maxY = controlParam._vec2_Max.y;

                MakeVirtualLerpPoint(new Vector2(minX, minY), bias);
                MakeVirtualLerpPoint(new Vector2(minX, minY), bias);
                MakeVirtualLerpPoint(new Vector2(minX, minY), bias);
                MakeVirtualLerpPoint(new Vector2(minX, minY), bias);

                //Min/Max 위치를 추가로 저장해둔다.
                AddLerpPos(new Vector2(minX, minY), fPosXList, fPosYList, bias);
                AddLerpPos(new Vector2(minX, maxY), fPosXList, fPosYList, bias);
                AddLerpPos(new Vector2(maxX, minY), fPosXList, fPosYList, bias);
                AddLerpPos(new Vector2(maxX, maxY), fPosXList, fPosYList, bias);

                //2) 위치 정렬
                fPosXList.Sort(delegate(float a, float b)
                {
                    return((int)((a - b) * (1.0f / bias) * 1000.0f));
                });

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

                //3) 좌표 순회하면서 포인트 추가
                for (int iX = 0; iX < fPosXList.Count; iX++)
                {
                    for (int iY = 0; iY < fPosYList.Count; iY++)
                    {
                        MakeVirtualLerpPoint(new Vector2(fPosXList[iX], fPosYList[iY]), bias);
                    }
                }

                apCalculatedLerpPoint pointLT = null;
                apCalculatedLerpPoint pointRT = null;
                apCalculatedLerpPoint pointLB = null;
                apCalculatedLerpPoint pointRB = null;

                //4) 좌표 순회하면서 RectArea 만들기
                for (int iX = 0; iX < fPosXList.Count - 1; iX++)
                {
                    for (int iY = 0; iY < fPosYList.Count - 1; iY++)
                    {
                        pointLT = GetLerpPoint(new Vector2(fPosXList[iX], fPosYList[iY]), bias);
                        pointRT = GetLerpPoint(new Vector2(fPosXList[iX + 1], fPosYList[iY]), bias);
                        pointLB = GetLerpPoint(new Vector2(fPosXList[iX], fPosYList[iY + 1]), bias);
                        pointRB = GetLerpPoint(new Vector2(fPosXList[iX + 1], fPosYList[iY + 1]), bias);

                        apCalculatedLerpArea lerpArea = new apCalculatedLerpArea(pointLT, pointRT, pointLB, pointRB);

                        _cpLerpAreas.Add(lerpArea);
                    }
                }
            }
        }
예제 #8
0
 // Functions
 //-----------------------------------------
 public void AddPoint(apCalculatedResultParam.ParamKeyValueSet point, float weight)
 {
     _refParams.Add(point);
     _refWeights.Add(weight);
 }
        /// <summary>
        /// ParamSet간의 Weight를 계산한다. [Keyframe이 입력값인 경우]
        /// </summary>
        private void CalculateWeight_Keyframe()
        {
            if (_keyParamSetGroup == null || _keyParamSetGroup._keyAnimTimelineLayer == null)
            {
                return;
            }

            bool isPlayedAnimClip = false;            //<<이 코드가 추가됨

            if (_keyParamSetGroup._keyAnimClip._isSelectedInEditor)
            {
                _keyParamSetGroup._layerWeight = 1.0f;
                isPlayedAnimClip = true;
            }
            else
            {
                _keyParamSetGroup._layerWeight = 0.0f;
                isPlayedAnimClip = false;
            }

            apAnimTimelineLayer timlineLayer = _keyParamSetGroup._keyAnimTimelineLayer;

            apCalculatedResultParam.ParamKeyValueSet curParamKeyValue = null;
            int curFrame = timlineLayer._parentAnimClip.CurFrame;

            bool isLoop = timlineLayer._parentAnimClip.IsLoop;


            _totalWeight = 0.0f;

            apAnimKeyframe curKeyframe  = null;
            apAnimKeyframe prevKeyframe = null;
            apAnimKeyframe nextKeyframe = null;

            int lengthFrames = timlineLayer._parentAnimClip.EndFrame - timlineLayer._parentAnimClip.StartFrame;
            int tmpCurFrame  = 0;


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

                //추가 11.29 : Animation Key 위치 타입이 추가되었다.
                curParamKeyValue._animKeyPos = apCalculatedResultParam.AnimKeyPos.NotCalculated;

                //유효하지 않은 키프레임이면 처리하지 않는다.
                if (curParamKeyValue._paramSet.SyncKeyframe == null ||
                    !curParamKeyValue._paramSet.SyncKeyframe._isActive ||
                    //!curParamKeyValue._isActive_InEditorExclusive
                    !curParamKeyValue.IsActive ||
                    !isPlayedAnimClip                     //<<애니메이션 재생 안될때는 여기서 생략이 되어야 하는데, 이게 왜 없었지;;
                    )
                {
                    //Debug.Log("[" + i + "] Not Active or Null Keyframe");
                    continue;
                }

                curKeyframe  = curParamKeyValue._paramSet.SyncKeyframe;
                prevKeyframe = curParamKeyValue._paramSet.SyncKeyframe._prevLinkedKeyframe;
                nextKeyframe = curParamKeyValue._paramSet.SyncKeyframe._nextLinkedKeyframe;


                //1. 프레임이 같다. => 100%
                if (curFrame == curKeyframe._frameIndex ||
                    ((curKeyframe._isLoopAsStart || curKeyframe._isLoopAsEnd) && curFrame == curKeyframe._loopFrameIndex))
                {
                    curParamKeyValue._dist         = 0.0f;
                    curParamKeyValue._isCalculated = true;
                    curParamKeyValue._weight       = 1.0f;
                    _totalWeight += 1.0f;

                    //추가 11.29 : AnimKeyPos - 동일 프레임
                    curParamKeyValue._animKeyPos = apCalculatedResultParam.AnimKeyPos.ExactKey;
                }
                //else if(curFrame >= curKeyframe._activeFrameIndexMin &&
                //		curFrame < curKeyframe._frameIndex)
                else if (curKeyframe.IsFrameIn(curFrame, apAnimKeyframe.LINKED_KEY.Prev))
                {
                    //범위 안에 들었다. [Prev - Cur]
                    if (prevKeyframe != null)
                    {
                        //indexOffsetA = 0;
                        //indexOffsetB = 0;
                        //if(prevKeyframe._frameIndex > curKeyframe._frameIndex)
                        //{
                        //	//Loop인 경우 Prev가 더 클 수 있다.
                        //	indexOffsetA = -lengthFrames;
                        //}

                        tmpCurFrame = curFrame;
                        if (tmpCurFrame > curKeyframe._frameIndex)
                        {
                            tmpCurFrame -= lengthFrames;
                        }

                        //float itp = apAnimCurve.GetCurvedRelativeInterpolation(prevKeyframe._curveKey, curKeyframe._curveKey, curFrame, curKeyframe._curveKey._isPrevKeyUseDummyIndex, false);
                        //float itp = apAnimCurve.GetCurvedRelativeInterpolation(curKeyframe._curveKey, prevKeyframe._curveKey, tmpCurFrame, true);

                        //>> 변경
                        float itp = curKeyframe._curveKey.GetItp_Int(tmpCurFrame, true);

                        curParamKeyValue._dist         = 0.0f;
                        curParamKeyValue._isCalculated = true;
                        curParamKeyValue._weight       = itp;
                        _totalWeight += itp;

                        //추가 : Rotation Bias
                        //Prev와 연결되었다면 Prev 설정을 적용한다.
                        if (curKeyframe._prevRotationBiasMode != apAnimKeyframe.ROTATION_BIAS.None)
                        {
                            curParamKeyValue.SetAnimRotationBias(curKeyframe._prevRotationBiasMode, curKeyframe._prevRotationBiasCount);
                        }

                        //Debug.Log("[" + i + "] [Prev ~ Cur] " + itp);
                        //Debug.Log("Prev ~ Next : " + itp);

                        //추가 11.29 : AnimKeyPos - Next 프레임으로서 Prev 프레임과 보간이 된다.
                        curParamKeyValue._animKeyPos = apCalculatedResultParam.AnimKeyPos.NextKey;
                    }
                    else
                    {
                        //연결된게 없다면 이게 100% 가중치를 갖는다.
                        curParamKeyValue._dist         = 0.0f;
                        curParamKeyValue._isCalculated = true;
                        curParamKeyValue._weight       = 1.0f;
                        _totalWeight += 1.0f;
                        //Debug.Log("[" + i + "] [Prev ?? ~ Cur] 1.0");

                        //추가 11.29 : AnimKeyPos - 동일 프레임
                        curParamKeyValue._animKeyPos = apCalculatedResultParam.AnimKeyPos.ExactKey;
                    }
                }
                //else if(curFrame > curKeyframe._frameIndex &&
                //		curFrame <= curKeyframe._activeFrameIndexMax)
                else if (curKeyframe.IsFrameIn(curFrame, apAnimKeyframe.LINKED_KEY.Next))
                {
                    //범위안에 들었다 [Cur - Next]
                    if (nextKeyframe != null)
                    {
                        //indexOffsetA = 0;
                        //indexOffsetB = 0;
                        //if(nextKeyframe._frameIndex < curKeyframe._frameIndex)
                        //{
                        //	//Loop인 경우 Next가 더 작을 수 있다.
                        //	indexOffsetB = lengthFrames;
                        //}

                        tmpCurFrame = curFrame;
                        if (tmpCurFrame < curKeyframe._frameIndex)
                        {
                            tmpCurFrame += lengthFrames;
                        }

                        //float itp = apAnimCurve.GetCurvedRelativeInterpolation(curKeyframe._curveKey, nextKeyframe._curveKey, curFrame, false, curKeyframe._curveKey._isNextKeyUseDummyIndex);
                        //float itp = apAnimCurve.GetCurvedRelativeInterpolation(curKeyframe._curveKey, nextKeyframe._curveKey, tmpCurFrame, false);

                        //>> 변경
                        float itp = curKeyframe._curveKey.GetItp_Int(tmpCurFrame, false);

                        //itp = 1.0f - itp;//결과가 B에 맞추어지므로 여기서는 Reverse

                        curParamKeyValue._dist         = 0.0f;
                        curParamKeyValue._isCalculated = true;
                        curParamKeyValue._weight       = itp;
                        _totalWeight += itp;

                        //추가 : Rotation Bias
                        //Next와 연결되었다면 Next 설정을 적용한다.
                        if (curKeyframe._nextRotationBiasMode != apAnimKeyframe.ROTATION_BIAS.None)
                        {
                            curParamKeyValue.SetAnimRotationBias(curKeyframe._nextRotationBiasMode, curKeyframe._nextRotationBiasCount);
                        }

                        //추가 11.29 : AnimKeyPos - Prev 프레임으로서 Next 프레임과 보간이 된다.
                        curParamKeyValue._animKeyPos = apCalculatedResultParam.AnimKeyPos.PrevKey;
                    }
                    else
                    {
                        //연결된게 없다면 이게 100% 가중치를 갖는다.
                        curParamKeyValue._dist         = 0.0f;
                        curParamKeyValue._isCalculated = true;
                        curParamKeyValue._weight       = 1.0f;
                        _totalWeight += 1.0f;

                        //추가 11.29 : AnimKeyPos - 동일 프레임
                        curParamKeyValue._animKeyPos = apCalculatedResultParam.AnimKeyPos.ExactKey;
                    }
                }
            }

            if (_totalWeight > 0.0f)
            {
                //Debug.Log("Result --------------------------------");
                //float prevWeight = 0.0f;
                for (int i = 0; i < _subParamKeyValues.Count; i++)
                {
                    curParamKeyValue = _subParamKeyValues[i];

                    if (curParamKeyValue._isCalculated)
                    {
                        curParamKeyValue._weight /= _totalWeight;
                        //Debug.Log("[" + curParamKeyValue._weight + "]");
                    }
                    else
                    {
                        curParamKeyValue._weight = 0.0f;
                    }
                }
                //Debug.Log("-------------------------------------");
            }
        }