/// <summary> /// 입력된 Param Key Value를 보간하기 위한 보조 데이터를 만들어준다. /// Add ParamKeyValueSet을 모두 호출한 이후에 꼭 호출해야한다. /// </summary> public void MakeMetaData() { switch (_keyParamSetGroup._syncTarget) { case apModifierParamSetGroup.SYNC_TARGET.Controller: if (_keyParamSetGroup._keyControlParam != null) { //보간을 위한 Key Point와 Area를 만들자. if (_cpLerpPoints == null) { _cpLerpPoints = new List <apCalculatedLerpPoint>(); } if (_cpLerpAreas == null) { _cpLerpAreas = new List <apCalculatedLerpArea>(); } _cpLerpPoint_A = null; _cpLerpPoint_B = null; _cpLerpAreaLastSelected = null; MakeControlParamLerpAreas(); } break; } }
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; } } } }
//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); } } } }