//--------------------------------------------------- // 계산함수 - KeyFrame //--------------------------------------------------- private void CalculateWeight_KeyFrame() { if (_keyParamSetGroup == null || _keyParamSetGroup._keyAnimTimelineLayer == null) { return; } apAnimTimelineLayer timlineLayer = _keyParamSetGroup._keyAnimTimelineLayer; apOptCalculatedResultParam.OptParamKeyValueSet curParamKeyValue = null; //9.26 : 이거 수정해야한다. //Int형 프레임과 Float형 프레임을 둘다 사용한다. int curFrame = timlineLayer._parentAnimClip.CurFrame; float curFrameFloat = timlineLayer._parentAnimClip.CurFrameFloat; //<<이건 실수형 bool isLoop = timlineLayer._parentAnimClip.IsLoop; //apAnimKeyframe firstKeyframe = timlineLayer._firstKeyFrame; //apAnimKeyframe lastKeyframe = timlineLayer._lastKeyFrame; _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 tmpCurFrameInt = 0; float tmpCurFrameFloat = 0; for (int i = 0; i < _subParamKeyValues.Count; i++) { curParamKeyValue = _subParamKeyValues[i]; curParamKeyValue._dist = -10.0f; curParamKeyValue._isCalculated = false; curParamKeyValue._weight = 0.0f; //추가 12.5 curParamKeyValue._animKeyPos = apOptCalculatedResultParam.AnimKeyPos.NotCalculated; //유효하지 않은 키프레임이면 처리하지 않는다. if (curParamKeyValue._paramSet.SyncKeyframe == null || !curParamKeyValue._paramSet.SyncKeyframe._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; //추가 12.5 : AnimKeyPos : 동일 프레임 curParamKeyValue._animKeyPos = apOptCalculatedResultParam.AnimKeyPos.ExactKey; } //else if(curFrame >= curKeyframe._activeFrameIndexMin && // curFrame < curKeyframe._frameIndex) else if (curKeyframe.IsFrameIn(curFrame, apAnimKeyframe.LINKED_KEY.Prev)) { //범위 안에 들었다. [Prev - Cur] if (prevKeyframe != null) { tmpCurFrameInt = curFrame; if (tmpCurFrameInt > curKeyframe._frameIndex) { tmpCurFrameInt -= lengthFrames; } tmpCurFrameFloat = curFrameFloat; if (tmpCurFrameFloat > curKeyframe._frameIndex) { tmpCurFrameFloat -= lengthFrames; } //[중요] 재생 프레임 -> 보간 가중치 계산 코드 //_cal_itp = curKeyframe._curveKey.GetItp_Int(tmpCurFrameInt, true);//기존 : Int _cal_itp = curKeyframe._curveKey.GetItp_Float(tmpCurFrameFloat, true, tmpCurFrameInt); //변경 : Float curParamKeyValue._dist = 0.0f; curParamKeyValue._isCalculated = true; curParamKeyValue._weight = _cal_itp; _totalWeight += _cal_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); //추가 12.5 : AnimKeyPos - Next 프레임으로서 Prev 프레임과 보간이 된다. curParamKeyValue._animKeyPos = apOptCalculatedResultParam.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"); //추가 12.5 : AnimKeyPos - 동일 프레임 curParamKeyValue._animKeyPos = apOptCalculatedResultParam.AnimKeyPos.ExactKey; } } //else if(curFrame > curKeyframe._frameIndex && // curFrame <= curKeyframe._activeFrameIndexMax) else if (curKeyframe.IsFrameIn(curFrame, apAnimKeyframe.LINKED_KEY.Next)) { //범위안에 들었다 [Cur - Next] if (nextKeyframe != null) { tmpCurFrameInt = curFrame; if (tmpCurFrameInt < curKeyframe._frameIndex) { tmpCurFrameInt += lengthFrames; } tmpCurFrameFloat = curFrameFloat; if (tmpCurFrameFloat < curKeyframe._frameIndex) { tmpCurFrameFloat += lengthFrames; } //[중요] 재생 프레임 -> 보간 가중치 계산 코드 //_cal_itp = curKeyframe._curveKey.GetItp_Int(tmpCurFrameInt, false);//기존 _cal_itp = curKeyframe._curveKey.GetItp_Float(tmpCurFrameFloat, false, tmpCurFrameInt); //변경 : Float //itp = 1.0f - itp;//결과가 B에 맞추어지므로 여기서는 Reverse curParamKeyValue._dist = 0.0f; curParamKeyValue._isCalculated = true; curParamKeyValue._weight = _cal_itp; _totalWeight += _cal_itp; //Debug.Log("[" + i + "] [Cur ~ Next] " + itp); //추가 : Rotation Bias //Next와 연결되었다면 Next 설정을 적용한다. if (curKeyframe._nextRotationBiasMode != apAnimKeyframe.ROTATION_BIAS.None) { curParamKeyValue.SetAnimRotationBias(curKeyframe._nextRotationBiasMode, curKeyframe._nextRotationBiasCount); } //추가 12.5 : AnimKeyPos - Prev 프레임으로서 Next 프레임과 보간이 된다. curParamKeyValue._animKeyPos = apOptCalculatedResultParam.AnimKeyPos.PrevKey; } else { //연결된게 없다면 이게 100% 가중치를 갖는다. curParamKeyValue._dist = 0.0f; curParamKeyValue._isCalculated = true; curParamKeyValue._weight = 1.0f; _totalWeight += 1.0f; //Debug.Log("[" + i + "] [Cur ~ Next ??] 1.0"); //추가 12.5 : AnimKeyPos - 동일 프레임 curParamKeyValue._animKeyPos = apOptCalculatedResultParam.AnimKeyPos.ExactKey; } } } if (_totalWeight > 0.0f) { //Debug.Log("Result --------------------------------"); 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("-------------------------------------"); } }
//--------------------------------------------------- // 계산함수 - KeyFrame //--------------------------------------------------- private void CalculateWeight_KeyFrame() { if (_keyParamSetGroup == null || _keyParamSetGroup._keyAnimTimelineLayer == null) { return; } apAnimTimelineLayer timlineLayer = _keyParamSetGroup._keyAnimTimelineLayer; apOptCalculatedResultParam.OptParamKeyValueSet curParamKeyValue = null; int curFrame = timlineLayer._parentAnimClip.CurFrame; bool isLoop = timlineLayer._parentAnimClip.IsLoop; //apAnimKeyframe firstKeyframe = timlineLayer._firstKeyFrame; //apAnimKeyframe lastKeyframe = timlineLayer._lastKeyFrame; _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; curParamKeyValue._weight = 0.0f; //유효하지 않은 키프레임이면 처리하지 않는다. if (curParamKeyValue._paramSet.SyncKeyframe == null || !curParamKeyValue._paramSet.SyncKeyframe._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, 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); //이전 코드 //_cal_itp = apAnimCurve.GetCurvedRelativeInterpolation(curKeyframe._curveKey, prevKeyframe._curveKey, tmpCurFrame, true); //>> 다음 코드 _cal_itp = curKeyframe._curveKey.GetItp_Int(tmpCurFrame, true); curParamKeyValue._dist = 0.0f; curParamKeyValue._isCalculated = true; curParamKeyValue._weight = _cal_itp; _totalWeight += _cal_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); } 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, 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); //이전 코드 //_cal_itp = apAnimCurve.GetCurvedRelativeInterpolation(curKeyframe._curveKey, nextKeyframe._curveKey, tmpCurFrame, false); //>> 다음 코드 _cal_itp = curKeyframe._curveKey.GetItp_Int(tmpCurFrame, false); //itp = 1.0f - itp;//결과가 B에 맞추어지므로 여기서는 Reverse curParamKeyValue._dist = 0.0f; curParamKeyValue._isCalculated = true; curParamKeyValue._weight = _cal_itp; _totalWeight += _cal_itp; //Debug.Log("[" + i + "] [Cur ~ Next] " + itp); //추가 : Rotation Bias //Next와 연결되었다면 Next 설정을 적용한다. if (curKeyframe._nextRotationBiasMode != apAnimKeyframe.ROTATION_BIAS.None) { curParamKeyValue.SetAnimRotationBias(curKeyframe._nextRotationBiasMode, curKeyframe._nextRotationBiasCount); } } 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 --------------------------------"); 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("-------------------------------------"); } }