/// <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; } }
public void Addpoints(apCalculatedLerpPoint lerpPoint, float weight) { for (int i = 0; i < lerpPoint._refParams.Count; i++) { AddPoint(lerpPoint._refParams[i], lerpPoint._refWeights[i] * weight); } }
// Init //----------------------------------------------- public apCalculatedLerpArea(apCalculatedLerpPoint pointLT, apCalculatedLerpPoint pointRT, apCalculatedLerpPoint pointLB, apCalculatedLerpPoint pointRB) { _pointLT = pointLT; _pointRT = pointRT; _pointLB = pointLB; _pointRB = pointRB; SetRangeVector2(_pointLT._pos, _pointRB._pos); }
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; } } } } }
/// <summary> /// 가상의 Lerp Point (Vector2)를 만든다. /// bias값을 이용하여 기존에 생성된 값이 있는지 확인한다. /// 기존에 생성된 값이나 새로 만든 값을 리턴한다. /// </summary> /// <param name="pos"></param> /// <param name="bias"></param> /// <returns></returns> private apCalculatedLerpPoint MakeVirtualLerpPoint(Vector2 pos, float bias) { apCalculatedLerpPoint existLerpPoint = GetLerpPoint(pos, bias); if (existLerpPoint != null) { return(existLerpPoint); } apCalculatedLerpPoint newPoint = new apCalculatedLerpPoint(pos, false); _cpLerpPoints.Add(newPoint); //실제 Control Param Key를 입력해야한다. List <apCalculatedLerpPoint> realLerpPoints = _cpLerpPoints.FindAll(delegate(apCalculatedLerpPoint a) { return(a._isRealPoint); }); if (realLerpPoints.Count == 0) { return(newPoint); } if (realLerpPoints.Count == 1) { newPoint.Addpoints(realLerpPoints[0], 1.0f); return(newPoint); } //Pos를 기준으로 Lerp의 합을 계산한다. //전체 거리의 평균을 잡고, 그 평균 이내의 Point만 계산한다. List <float> distList = new List <float>(); List <float> weightList = new List <float>(); float totalDist = 0.0f; float totalWeight = 0.0f; apCalculatedLerpPoint lerpPoint = null; for (int i = 0; i < realLerpPoints.Count; i++) { lerpPoint = realLerpPoints[i]; float dist = Vector2.Distance(pos, lerpPoint._pos); totalDist += dist; distList.Add(dist); } //float meanDist = totalDist / 2.0f;//<<이부분이 필요할까? for (int i = 0; i < realLerpPoints.Count; i++) { weightList.Add(1.0f); //if(distList[i] < meanDist) //{ // weightList.Add(1.0f); //} //else //{ // weightList.Add(-1.0f); //} } apCalculatedLerpPoint curPoint = null; apCalculatedLerpPoint nextpoint = null; for (int iCur = 0; iCur < realLerpPoints.Count - 1; iCur++) { curPoint = realLerpPoints[iCur]; if (weightList[iCur] <= 0.0f) { continue; } float distCur = distList[iCur]; for (int iNext = iCur + 1; iNext < realLerpPoints.Count; iNext++) { nextpoint = realLerpPoints[iNext]; if (weightList[iNext] <= 0.0f) { continue; } float distNext = distList[iNext]; float distSum = distCur + distNext; if (distSum <= 0.0f) { continue; } float itp = 1.0f - (distCur / distSum); weightList[iCur] *= itp; weightList[iNext] *= 1.0f - itp; } } for (int i = 0; i < realLerpPoints.Count - 1; i++) { if (weightList[i] < 0.0f) { weightList[i] = 0.0f; } else { totalWeight += weightList[i]; } } if (totalWeight > 0.0f) { for (int i = 0; i < realLerpPoints.Count; i++) { lerpPoint = realLerpPoints[i]; if (weightList[i] > 0.0f) { float pointWeight = weightList[i] / totalWeight; newPoint.Addpoints(lerpPoint, pointWeight); } } } return(newPoint); }
//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); } } } }