/// <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("-------------------------------------"); } }
/// <summary> /// [Editor] 업데이트 중 Control Param 제어 Timeline에 대해 업데이트 후 적용을 한다. /// [Runtime] isAdaptToWeight = false로 두고 나머지 처리를 한다. /// </summary> /// <param name="isAdaptToWeight1">[Editor]에서 Weight=1로 두고 적용을 한다</param> public void UpdateControlParam(bool isAdaptToWeight1, int optLayer = 0, float optWeight = 1.0f, apAnimPlayUnit.BLEND_METHOD optBlendMethod = apAnimPlayUnit.BLEND_METHOD.Interpolation) { if (_controlParamResult.Count == 0) { return; } for (int i = 0; i < _controlParamResult.Count; i++) { _controlParamResult[i].Init(); } apAnimTimeline timeline = null; apAnimTimelineLayer layer = null; int curFrame = CurFrame; float curFrameF = CurFrameFloat; //apAnimKeyframe firstKeyframe = null; //apAnimKeyframe lastKeyframe = null; apAnimKeyframe curKeyframe = null; apAnimKeyframe prevKeyframe = null; apAnimKeyframe nextKeyframe = null; int lengthFrames = _endFrame - _startFrame; int tmpCurFrame = 0; apAnimControlParamResult cpResult = null; for (int iTL = 0; iTL < _timelines.Count; iTL++) { timeline = _timelines[iTL]; if (timeline._linkType != LINK_TYPE.ControlParam) { continue; } for (int iL = 0; iL < timeline._layers.Count; iL++) { layer = timeline._layers[iL]; if (layer._linkedControlParam == null || layer._linkedControlParamResult == null) { continue; } cpResult = layer._linkedControlParamResult; //firstKeyframe = layer._firstKeyFrame; //lastKeyframe = layer._lastKeyFrame; for (int iK = 0; iK < layer._keyframes.Count; iK++) { curKeyframe = layer._keyframes[iK]; prevKeyframe = curKeyframe._prevLinkedKeyframe; nextKeyframe = curKeyframe._nextLinkedKeyframe; if (curFrame == curKeyframe._frameIndex || ((curKeyframe._isLoopAsStart || curKeyframe._isLoopAsEnd) && curKeyframe._loopFrameIndex == curFrame) ) { cpResult.SetKeyframeResult(curKeyframe, 1.0f); } else if (curKeyframe.IsFrameIn(curFrame, apAnimKeyframe.LINKED_KEY.Prev)) { //Prev - Cur 범위 안에 들었다. if (prevKeyframe != null) { //Prev 키가 있다면 tmpCurFrame = curFrame; if (tmpCurFrame > curKeyframe._frameIndex) { //한바퀴 돌았다면 tmpCurFrame -= lengthFrames; } //TODO : 여길 나중에 "정식 Curve로 변경"할 것 //float itp = apAnimCurve.GetCurvedRelativeInterpolation(curKeyframe._curveKey, prevKeyframe._curveKey, tmpCurFrame, true); //>> 변경 float itp = curKeyframe._curveKey.GetItp_Int(tmpCurFrame, true); cpResult.SetKeyframeResult(curKeyframe, itp); } else { //Prev 키가 없다면 이게 100%다 cpResult.SetKeyframeResult(curKeyframe, 1.0f); } } else if (curKeyframe.IsFrameIn(curFrame, apAnimKeyframe.LINKED_KEY.Next)) { //Cur - Next 범위 안에 들었다. if (nextKeyframe != null) { //Next 키가 있다면 tmpCurFrame = curFrame; if (tmpCurFrame < curKeyframe._frameIndex) { //한바퀴 돌았다면 tmpCurFrame += lengthFrames; } //TODO : 여길 나중에 "정식 Curve로 변경"할 것 //float itp = apAnimCurve.GetCurvedRelativeInterpolation(curKeyframe._curveKey, nextKeyframe._curveKey, tmpCurFrame, false); //>> 변경 float itp = curKeyframe._curveKey.GetItp_Int(tmpCurFrame, false); cpResult.SetKeyframeResult(curKeyframe, itp); } else { //Prev 키가 없다면 이게 100%다 cpResult.SetKeyframeResult(curKeyframe, 1.0f); } } } } } //Control Param에 적용을 해야한다. if (isAdaptToWeight1) { //Editor인 경우 Weight 1로 강제한다. for (int i = 0; i < _controlParamResult.Count; i++) { _controlParamResult[i].AdaptToControlParam(); } } else { //Runtime인 경우 지정된 Weight, Layer로 처리한다. for (int i = 0; i < _controlParamResult.Count; i++) { //Debug.Log("AnimClip [" + _name + " > Control Param : " + _controlParamResult[i]._targetControlParam._keyName + " ]"); _controlParamResult[i].AdaptToControlParam_Opt(optWeight, optBlendMethod); } } }
//--------------------------------------------------- // 계산함수 - 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("-------------------------------------"); } }
//--------------------------------------------------- // 계산함수 - 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("-------------------------------------"); } }
/// <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("-------------------------------------"); } }