// Get / Set //----------------------------------------------------------------------- //----------------------------------------------------------------------------------- // Copy For Bake //----------------------------------------------------------------------------------- public void CopyFromKeyframe(apAnimKeyframe srcKeyframe) { _uniqueID = srcKeyframe._uniqueID; _frameIndex = srcKeyframe._frameIndex; _curveKey = new apAnimCurve(srcKeyframe._curveKey, srcKeyframe._frameIndex); _isKeyValueSet = srcKeyframe._isKeyValueSet; _isActive = srcKeyframe._isActive; _isLoopAsStart = srcKeyframe._isLoopAsStart; _isLoopAsEnd = srcKeyframe._isLoopAsEnd; _loopFrameIndex = srcKeyframe._loopFrameIndex; _activeFrameIndexMin = srcKeyframe._activeFrameIndexMin; _activeFrameIndexMax = srcKeyframe._activeFrameIndexMax; _activeFrameIndexMin_Dummy = srcKeyframe._activeFrameIndexMin_Dummy; _activeFrameIndexMax_Dummy = srcKeyframe._activeFrameIndexMax_Dummy; _conSyncValue_Int = srcKeyframe._conSyncValue_Int; _conSyncValue_Float = srcKeyframe._conSyncValue_Float; _conSyncValue_Vector2 = srcKeyframe._conSyncValue_Vector2; }
//public void SetLinkedKeyframes(apAnimKeyframe prevKeyframe, apAnimKeyframe nextKeyframe, bool isPrevDummyIndex, bool isNextDummyIndex) public void SetLinkedKeyframes(apAnimKeyframe prevKeyframe, apAnimKeyframe nextKeyframe, int prevFrameIndex, int nextFrameIndex) { _isActive = true; _prevLinkedKeyframe = prevKeyframe; _nextLinkedKeyframe = nextKeyframe; apAnimCurve prevCurveKey = null; apAnimCurve nextCurveKey = null; if (_prevLinkedKeyframe != null) { prevCurveKey = _prevLinkedKeyframe._curveKey; } if (_nextLinkedKeyframe != null) { nextCurveKey = _nextLinkedKeyframe._curveKey; } //_isLoopAsStart = false; //_isLoopAsEnd = false; //_loopFrameIndex = -1; //_curveKey.Set //_curveKey.SetLinkedCurveKey(prevCurveKey, nextCurveKey, isPrevDummyIndex, isNextDummyIndex); _curveKey.SetLinkedCurveKey(prevCurveKey, nextCurveKey, prevFrameIndex, nextFrameIndex); }
//private int _tmpIndex = 0; //private int _iA = 0; //private int _iB = 0; //private float _lengthX = 0.0f; // Init //-------------------------------------------------------------------- public apAnimCurveTable(apAnimCurve parentAnimCurve) { _parentAnimCurve = parentAnimCurve; _linkedAnimCurve = null; Init(); }
// Link //-------------------------------------------------------------------- public bool LinkAnimCurve(apAnimCurve animCurve) { bool isChanged = _linkedAnimCurve != animCurve; _linkedAnimCurve = animCurve; return(isChanged); }
public override bool Save(object target, string strParam) { base.Save(target, strParam); apAnimKeyframe keyframe = target as apAnimKeyframe; if (keyframe == null) { return(false); } _key_TimelineLayer = keyframe._parentTimelineLayer; if (_key_TimelineLayer == null) { return(false); } _animCurve = new apAnimCurve(keyframe._curveKey, keyframe._frameIndex); _isKeyValueSet = keyframe._isKeyValueSet; //_conSyncValue_Bool = keyframe._conSyncValue_Bool; _conSyncValue_Int = keyframe._conSyncValue_Int; _conSyncValue_Float = keyframe._conSyncValue_Float; _conSyncValue_Vector2 = keyframe._conSyncValue_Vector2; //_conSyncValue_Vector3 = keyframe._conSyncValue_Vector3; //_conSyncValue_Color = keyframe._conSyncValue_Color; _vertices.Clear(); _transformMatrix = new apMatrix(); _meshColor = new Color(0.5f, 0.5f, 0.5f, 1.0f); _isVisible = true; if (keyframe._linkedModMesh_Editor != null) { apModifiedMesh modMesh = keyframe._linkedModMesh_Editor; _vertices.Clear(); int nVert = modMesh._vertices.Count; for (int i = 0; i < nVert; i++) { apModifiedVertex modVert = modMesh._vertices[i]; _vertices.Add(new VertData(modVert._vertex, modVert._deltaPos)); } _transformMatrix = new apMatrix(modMesh._transformMatrix); _meshColor = modMesh._meshColor; _isVisible = modMesh._isVisible; } else if (keyframe._linkedModBone_Editor != null) { apModifiedBone modBone = keyframe._linkedModBone_Editor; _transformMatrix = new apMatrix(modBone._transformMatrix); } return(true); }
public void ApplySync(bool isApplyForce, bool isMousePressed) { if (_syncStatus != SYNC_STATUS.Sync || !_isAnyChangedRequest) { return; } if (_curveSets == null || _curveSets.Count == 0) { return; } //isApplyForce = true이거나 //isMousePressed = false일때 Apply를 한다. if (!isApplyForce && isMousePressed) { return; } apEditorUtil.SetEditorDirty(); _syncCurve_Prev._nextCurveResult.MakeCurve(); _syncCurve_Next._prevCurveResult.MakeCurve(); //동기화를 적용하자 CurveSet curSet = null; apAnimCurve prevCurve = null; apAnimCurve nextCurve = null; for (int i = 0; i < _curveSets.Count; i++) { curSet = _curveSets[i]; if (curSet._prevKeyframe == null || curSet._nextKeyframe == null) { continue; } prevCurve = curSet._prevKeyframe._curveKey; nextCurve = curSet._nextKeyframe._curveKey; //공통 커브와 동일하게 만들자. //Prev의 Next와 Next의 Prev.. 아 헷갈려;; prevCurve._nextTangentType = _syncCurve_Prev._nextTangentType; prevCurve._nextSmoothX = _syncCurve_Prev._nextSmoothX; prevCurve._nextSmoothY = _syncCurve_Prev._nextSmoothY; nextCurve._prevTangentType = _syncCurve_Next._prevTangentType; nextCurve._prevSmoothX = _syncCurve_Next._prevSmoothX; nextCurve._prevSmoothY = _syncCurve_Next._prevSmoothY; prevCurve.Refresh(); nextCurve.Refresh(); } _isAnyChangedRequest = false; }
public apAnimCurve(apAnimCurve srcCurve, int keyIndex) { _prevTangentType = srcCurve._prevTangentType; _prevSmoothX = srcCurve._prevSmoothX; _prevSmoothY = srcCurve._prevSmoothY; #region [미사용 코드] //_prevSmoothAngle = srcCurve._prevSmoothAngle; //_prevSmoothYOffset = srcCurve._prevSmoothYOffset; //_prevDeltaX = srcCurve._prevDeltaX; //_prevDeltaY = srcCurve._prevDeltaY; #endregion _prevLinkedCurveKey = srcCurve._prevLinkedCurveKey; _nextTangentType = srcCurve._nextTangentType; _nextSmoothX = srcCurve._nextSmoothX; _nextSmoothY = srcCurve._nextSmoothY; #region [미사용 코드] //_nextSmoothAngle = srcCurve._nextSmoothAngle; //_nextSmoothYOffset = srcCurve._nextSmoothYOffset; //_nextDeltaX = srcCurve._nextDeltaX; //_nextDeltaY = srcCurve._nextDeltaY; #endregion _nextLinkedCurveKey = srcCurve._nextLinkedCurveKey; //_keyItpType = srcCurve._keyItpType; _keyIndex = keyIndex; //<키 인덱스만 따로 분리해서 복사한다. _prevIndex = keyIndex; _nextIndex = keyIndex; if (_prevCurveResult == null) { _prevCurveResult = new apAnimCurveResult(); } if (_nextCurveResult == null) { _nextCurveResult = new apAnimCurveResult(); } #region [미사용 코드] //_keyValue = srcCurve._keyValue; //_dimension = srcCurve._dimension; //_isRelativeKeyValue = srcCurve._isRelativeKeyValue; //_smoothRelativeWeight = srcCurve._smoothRelativeWeight; #endregion }
/// <summary> /// CurveKey를 Link한다. /// A가 Prev, B가 Next여야 한다. (반대로 하면 처리 잘못됨) /// </summary> /// <param name="curveKeyA"></param> /// <param name="curveKeyB"></param> /// <param name="isTargetIsA">이 Result를 소유하고 있는 CurveKey가 Prev면 True, Next면 False</param> /// <param name="isMakeCurve">Link와 함께 MakeCurve를 할 것인가</param> public void Link(apAnimCurve curveKeyA, apAnimCurve curveKeyB, bool isTargetIsA, bool isMakeCurve) { //bool isMakeCurveForce = true; //if(_curveKeyA == curveKeyA && _curveKeyB == curveKeyB) //{ // isMakeCurveForce = false; //} _curveKeyA = curveKeyA; _curveKeyB = curveKeyB; _isTargetIsA = isTargetIsA; if (isMakeCurve) { MakeCurve(); } }
public void Init() { //_keyItpType = KEY_ITP_TYPE.AutoSmooth; _prevTangentType = TANGENT_TYPE.Smooth; _nextTangentType = TANGENT_TYPE.Smooth; _prevSmoothX = CONTROL_POINT_X_OFFSET; _prevSmoothY = 0.0f; _nextSmoothX = CONTROL_POINT_X_OFFSET; _nextSmoothY = 0.0f; #region [미사용 코드] //SetSmoothAngle(Vector4.zero, KEY_POS.PREV); //SetSmoothAngle(Vector4.zero, KEY_POS.NEXT); #endregion _prevLinkedCurveKey = null; _nextLinkedCurveKey = null; #region [미사용 코드] //_prevDeltaX = 1.0f; //_prevDeltaY = Vector4.zero; //_nextDeltaX = 1.0f; //_nextDeltaY = Vector4.zero; //_isRelativeKeyValue = false; //_smoothRelativeWeight = MIN_RELATIVE_WEIGHT; #endregion //_prevTable = new apAnimCurveTable(this); //_nextTable = new apAnimCurveTable(this); if (_prevCurveResult == null) { _prevCurveResult = new apAnimCurveResult(); } if (_nextCurveResult == null) { _nextCurveResult = new apAnimCurveResult(); } }
private static void DrawSmoothLine(apAnimCurve curveA, apAnimCurve curveB, Color graphColorA, Color graphColorB, Vector2 posA, Vector2 posB) { _matBatch.SetPass_Color(); _matBatch.SetClippingSize(_glScreenClippingSize); GL.Begin(GL.TRIANGLES); Vector2 pos_Prev = Vector2.zero; Vector2 pos_Cur = Vector2.zero; float itp = 0.0f; float itpKey = 0.0f; float itpY = 0.0f; for (int i = 0; i <= 20; i++) { itp = ((float)i) / 20.0f; itpKey = curveA._keyIndex + (itp * (float)(curveA._nextIndex - curveA._keyIndex)); //itpY = 1.0f - apAnimCurve.GetCurvedRelativeInterpolation(curveA, curveB, itpKey, false); itpY = 1.0f - curveA.GetItp_Float(itpKey, false); pos_Cur = new Vector2( (posA.x * (1.0f - itp)) + (posB.x * itp), (posA.y * (1.0f - itpY)) + (posB.y * itpY) ); if (i > 0) { //DrawBoldLine(pos_Prev, pos_Cur, 3, graphColor, false); Color grdColor = graphColorA * (1.0f - itp) + graphColorB * itp; DrawBoldLine(pos_Prev, pos_Cur, 3, grdColor, false); } pos_Prev = pos_Cur; } GL.End(); }
/// <summary> /// CurveKey를 Link한다. /// A가 Prev, B가 Next여야 한다. (반대로 하면 처리 잘못됨) /// </summary> /// <param name="curveKeyA"></param> /// <param name="curveKeyB"></param> /// <param name="isTargetIsA">이 Result를 소유하고 있는 CurveKey가 Prev면 True, Next면 False</param> /// <param name="isMakeCurve">Link와 함께 MakeCurve를 할 것인가</param> //public void Link(apAnimCurve curveKeyA, apAnimCurve curveKeyB, bool isTargetIsA, bool isMakeCurve) public void Link(apAnimCurve curveKeyA, apAnimCurve curveKeyB, bool isTargetIsA) //isMakeCurve 삭제 : 19.5.20 { //bool isMakeCurveForce = true; //if(_curveKeyA == curveKeyA && _curveKeyB == curveKeyB) //{ // isMakeCurveForce = false; //} _curveKeyA = curveKeyA; _curveKeyB = curveKeyB; _isTargetIsA = isTargetIsA; //이전 //if (isMakeCurve) //{ // MakeCurve(); //} //변경 : 19.5.20 최적화 작업 MakeCurve(); }
public apAnimCurve(apAnimCurve srcCurve_Prev, apAnimCurve srcCurve_Next, int keyIndex) { //Prev는 Next의 Prev를 사용한다. _prevTangentType = srcCurve_Next._prevTangentType; _prevSmoothX = srcCurve_Next._prevSmoothX; _prevSmoothY = srcCurve_Next._prevSmoothY; _prevLinkedCurveKey = srcCurve_Next._prevLinkedCurveKey; //Next는 Prev의 Next를 사용한다. _nextTangentType = srcCurve_Prev._nextTangentType; _nextSmoothX = srcCurve_Prev._nextSmoothX; _nextSmoothY = srcCurve_Prev._nextSmoothY; _nextLinkedCurveKey = srcCurve_Prev._nextLinkedCurveKey; //_keyItpType = srcCurve._keyItpType; _keyIndex = keyIndex; //<키 인덱스만 따로 분리해서 복사한다. _prevIndex = keyIndex; _nextIndex = keyIndex; if (_prevCurveResult == null) { _prevCurveResult = new apAnimCurveResult(); } if (_nextCurveResult == null) { _nextCurveResult = new apAnimCurveResult(); } }
//---------------------------------------------------------------------------------------- // Draw Curve And Update //---------------------------------------------------------------------------------------- public static void DrawCurve(apAnimCurve curveA, apAnimCurve curveB, apAnimCurveResult curveResult, Color graphColorA, Color graphColorB) { if (_matBatch == null) { return; } if (_matBatch.IsNotReady()) { return; } //int leftAxisSize = 40; //int bottomAxisSize = 5; //int margin = 5; int leftAxisSize = 30; int bottomAxisSize = 0; int margin = 15; int gridWidth = _layoutWidth - (leftAxisSize + 2 * margin + 4); int gridHeight = _layoutHeight - (bottomAxisSize + 2 * margin + 4); //TODO //1. Grid를 그린다. + Grid의 축에 글씨를 쓴다. (왼쪽에 Percent) DrawGrid(leftAxisSize, bottomAxisSize, margin, gridWidth, gridHeight); Vector2 posA = new Vector2(leftAxisSize + margin, margin + gridHeight); Vector2 posB = new Vector2(leftAxisSize + margin + gridWidth, margin); //3. 계산되는 그래프를 BoldLine으로 그린다. switch (curveResult.CurveTangentType) { case apAnimCurve.TANGENT_TYPE.Linear: { DrawBoldLine(posA, posB, 3, graphColorA, graphColorB, true); } break; case apAnimCurve.TANGENT_TYPE.Smooth: { DrawSmoothLine(curveA, curveB, graphColorA, graphColorB, posA, posB); DrawSmoothLineControlPoints(curveA, curveB, posA, posB); } break; case apAnimCurve.TANGENT_TYPE.Constant: { Vector2 posC_Bottom = new Vector2((posA.x + posB.x) * 0.5f, posA.y); Vector2 posC_Top = new Vector2((posA.x + posB.x) * 0.5f, posB.y); DrawBoldLine(posA, posC_Bottom, 3, graphColorA, true); DrawBoldLine(posC_Bottom, posC_Top, 3, graphColorA, graphColorB, true); DrawBoldLine(posC_Top, posB, 3, graphColorB, true); } break; } //4. 컨트롤 포인트를 그리고 업데이트를 한다. DrawBox(posA, 10, 10, Color.white, true); DrawBox(posB, 10, 10, Color.white, true); if (_isLockMouse && _isMouseEvent) { if (_leftBtnStatus == apMouse.MouseBtnStatus.Up || _leftBtnStatus == apMouse.MouseBtnStatus.Released) { _isLockMouse = false; _selectedCurveKey = null; } } }
public bool IsSame(CurveSet target) { //Prev, Next간의 CurveResult의 값을 비교한다. apAnimCurve src_A = _prevKeyframe._curveKey; apAnimCurve src_B = _nextKeyframe._curveKey; apAnimCurve dst_A = target._prevKeyframe._curveKey; apAnimCurve dst_B = target._nextKeyframe._curveKey; //A의 Next와 B의 Prev끼리 묶어서 같은지 확인한다. if (src_A._nextTangentType != dst_A._nextTangentType || src_B._prevTangentType != dst_B._prevTangentType) { return(false); } apAnimCurve.TANGENT_TYPE srcTangentType = apAnimCurve.TANGENT_TYPE.Constant; apAnimCurve.TANGENT_TYPE dstTangentType = apAnimCurve.TANGENT_TYPE.Constant; //실제 탄젠트 타입 비교 if (src_A._nextTangentType == apAnimCurve.TANGENT_TYPE.Constant && src_B._prevTangentType == apAnimCurve.TANGENT_TYPE.Constant) { srcTangentType = apAnimCurve.TANGENT_TYPE.Constant; } else if (src_A._nextTangentType == apAnimCurve.TANGENT_TYPE.Linear && src_B._prevTangentType == apAnimCurve.TANGENT_TYPE.Linear) { srcTangentType = apAnimCurve.TANGENT_TYPE.Linear; } else { srcTangentType = apAnimCurve.TANGENT_TYPE.Smooth; } if (dst_A._nextTangentType == apAnimCurve.TANGENT_TYPE.Constant && dst_B._prevTangentType == apAnimCurve.TANGENT_TYPE.Constant) { dstTangentType = apAnimCurve.TANGENT_TYPE.Constant; } else if (dst_A._nextTangentType == apAnimCurve.TANGENT_TYPE.Linear && dst_B._prevTangentType == apAnimCurve.TANGENT_TYPE.Linear) { dstTangentType = apAnimCurve.TANGENT_TYPE.Linear; } else { dstTangentType = apAnimCurve.TANGENT_TYPE.Smooth; } if (srcTangentType != dstTangentType) { return(false); } if (srcTangentType == apAnimCurve.TANGENT_TYPE.Smooth && dstTangentType == apAnimCurve.TANGENT_TYPE.Smooth) { //Smooth의 경우, Smooth에 사용된 값도 같아야 한다. float bias = 0.001f; if (Mathf.Abs(src_A._nextSmoothX - dst_A._nextSmoothX) > bias || Mathf.Abs(src_A._nextSmoothY - dst_A._nextSmoothY) > bias || Mathf.Abs(src_B._prevSmoothX - dst_B._prevSmoothX) > bias || Mathf.Abs(src_B._prevSmoothY - dst_B._prevSmoothY) > bias) { return(false); } } return(true); }
// 계산용 Static 함수. 에디터에서만 사용하자 //------------------------------------------------------------------------------------- /// <summary> /// CurveKey 두개에 대한 임시 보간을 계산한다. /// 애니메이션 프레임을 직접 넣어줘야 한다. /// ITP 값은 B에 대한 값이 나온다. A는 (1-Result) 를 하자 /// 0이면 A에 가까운 값. 1이면 B에 가까운 값 /// </summary> /// <param name="curKeyIndex"></param> /// <param name="frameIndex_A"></param> /// <param name="frameIndex_B"></param> /// <param name="curveA"></param> /// <param name="curveB"></param> /// <returns></returns> public static float CalculateInterpolation_Float(float curKeyIndex, int iCurKeyframe, int frameIndex_A, int frameIndex_B, apAnimCurve curveA, apAnimCurve curveB) { if (frameIndex_A == frameIndex_B) { return(0.0f); } float keyRatio = Mathf.Clamp01((float)(curKeyIndex - (float)frameIndex_A) / (float)(frameIndex_B - frameIndex_A)); float resultItp = 0.0f; apAnimCurve.TANGENT_TYPE tangentType = apAnimCurve.TANGENT_TYPE.Linear; if (curveA._nextTangentType == apAnimCurve.TANGENT_TYPE.Constant || curveB._prevTangentType == apAnimCurve.TANGENT_TYPE.Constant) { tangentType = apAnimCurve.TANGENT_TYPE.Constant; } else if (curveA._nextTangentType == apAnimCurve.TANGENT_TYPE.Linear && curveB._prevTangentType == apAnimCurve.TANGENT_TYPE.Linear) { tangentType = apAnimCurve.TANGENT_TYPE.Linear; } else { tangentType = apAnimCurve.TANGENT_TYPE.Smooth; } float smoothX_A = curveA._nextSmoothX; float smoothY_A = curveA._nextSmoothY; float smoothX_B = curveB._prevSmoothX; float smoothY_B = curveB._prevSmoothY; switch (tangentType) { case apAnimCurve.TANGENT_TYPE.Constant: //변경전 : 0.5를 기준으로 바뀜 //변경후 : 1을 기준으로 바뀜 (int형 키프레임 받아와야함) //if (keyRatio < 0.5f) //{ // resultItp = 0.0f; //} //else //{ // resultItp = 1.0f; //} if (iCurKeyframe < frameIndex_B) { resultItp = 0.0f; } else { resultItp = 1.0f; } break; case apAnimCurve.TANGENT_TYPE.Linear: resultItp = keyRatio; break; case apAnimCurve.TANGENT_TYPE.Smooth: { float cpXRatio = 0.3f; Vector2 controlPointA = new Vector2(Mathf.Clamp01(smoothX_A), Mathf.Clamp01(smoothY_A)); Vector2 controlPointB = new Vector2(Mathf.Clamp01(1.0f - smoothX_B), Mathf.Clamp01(1.0f - smoothY_B)); float revT = 1.0f - keyRatio; float linearItp = Mathf.Clamp01( ((1.0f - Mathf.Sqrt(smoothX_A * smoothX_A + smoothY_A * smoothY_A)) * revT + (1.0f - Mathf.Sqrt(smoothX_B * smoothX_B + smoothY_B * smoothY_B)) * keyRatio) ); float convertTItp = (0.0f * revT * revT * revT) + (3.0f * ((1.0f - controlPointA.x) * cpXRatio) * revT * revT * keyRatio) + (3.0f * (1.0f - (controlPointB.x * cpXRatio)) * revT * keyRatio * keyRatio) + (1.0f * keyRatio * keyRatio * keyRatio); //float convertTItp = (0.0f * revT * revT * revT) + // (3.0f * (controlPointA.x) * revT * revT * keyRatio) + // (3.0f * (controlPointB.x) * revT * keyRatio * keyRatio) + // (1.0f * keyRatio * keyRatio * keyRatio); convertTItp = convertTItp * (1.0f - linearItp) + keyRatio * linearItp; resultItp = GetSmoothItp(controlPointA.y, controlPointB.y, convertTItp); resultItp = resultItp * (1.0f - linearItp) + convertTItp * linearItp; } break; } return(resultItp); }
public void SetLinkedCurveKey(apAnimCurve prevLinkedCurveKey, apAnimCurve nextLinkedCurveKey, int prevIndex, int nextIndex //bool isMakeCurveForce = false//<< 삭제 19.5.20 : 이게 문제가 아닌데?? //, bool isPrevDummyIndex, bool isNextDummyIndex ) { _prevLinkedCurveKey = prevLinkedCurveKey; _nextLinkedCurveKey = nextLinkedCurveKey; _prevIndex = prevIndex; _nextIndex = nextIndex; #region [미사용 코드] //_isPrevKeyUseDummyIndex = isPrevDummyIndex; //_isNextKeyUseDummyIndex = isNextDummyIndex; //Delta값은 항상 B-A 방식으로 한다. //float prevKeyIndex = _keyIndex; //float nextKeyIndex = _keyIndex; //if (_prevLinkedCurveKey == null) //{ // _prevDeltaX = 1.0f; // _prevDeltaY = Vector4.zero; //} //else //{ // //prevKeyIndex = _prevLinkedCurveKey.GetIndex(_isPrevKeyUseDummyIndex); // _prevDeltaX = (_keyIndex - _prevIndex); // _prevDeltaY = (_keyValue - _prevLinkedCurveKey._keyValue); //} //if(_nextLinkedCurveKey == null) //{ // _nextDeltaX = 1.0f; // _nextDeltaY = Vector4.zero; //} //else //{ // //nextKeyIndex = _nextLinkedCurveKey.GetIndex(_isNextKeyUseDummyIndex); // //_nextDeltaX = (nextKeyIndex - _keyIndex); // _nextDeltaX = (_nextIndex - _keyIndex); // _nextDeltaY = (_nextLinkedCurveKey._keyValue - _keyValue); //} //_prevDeltaX = Mathf.Max(_prevDeltaX, MIN_DELTA_X); //_nextDeltaX = Mathf.Max(_nextDeltaX, MIN_DELTA_X); //각도를 가지고 YOffset을 다시 계산하자 //CalculateSmooth(); #endregion //이전 //_prevCurveResult.Link(prevLinkedCurveKey, this, false, !(Application.isPlaying) || isMakeCurveForce); //_nextCurveResult.Link(this, nextLinkedCurveKey, true, !(Application.isPlaying) || isMakeCurveForce); //변경 : 19.5.20 : 최적화 작업 _prevCurveResult.Link(prevLinkedCurveKey, this, false); _nextCurveResult.Link(this, nextLinkedCurveKey, true); }
private static void DrawSmoothLineControlPoints(apAnimCurve curveA, apAnimCurve curveB, Vector2 posA, Vector2 posB) { Vector2 smoothA_Ratio = new Vector2(Mathf.Clamp01(curveA._nextSmoothX), Mathf.Clamp01(curveA._nextSmoothY)); Vector2 smoothB_Ratio = new Vector2(Mathf.Clamp01(curveB._prevSmoothX), Mathf.Clamp01(curveB._prevSmoothY)); Vector2 smoothA_Pos = new Vector2( posA.x * (1.0f - smoothA_Ratio.x) + posB.x * smoothA_Ratio.x, posA.y * (1.0f - smoothA_Ratio.y) + posB.y * smoothA_Ratio.y); Vector2 smoothB_Pos = new Vector2( posB.x * (1.0f - smoothB_Ratio.x) + posA.x * smoothB_Ratio.x, posB.y * (1.0f - smoothB_Ratio.y) + posA.y * smoothB_Ratio.y); int pointSize = 16; DrawBoldLine(posA, smoothA_Pos, 2, Color.red, true); DrawBoldLine(posB, smoothB_Pos, 2, Color.red, true); DrawTexture(_img_ControlPoint, smoothA_Pos, pointSize, pointSize, _color_Gray, true); DrawTexture(_img_ControlPoint, smoothB_Pos, pointSize, pointSize, _color_Gray, true); AddCursorRect(smoothA_Pos, pointSize, pointSize, MouseCursor.MoveArrow); AddCursorRect(smoothB_Pos, pointSize, pointSize, MouseCursor.MoveArrow); if (_isMouseEvent && !_isMouseEventUsed) { switch (_leftBtnStatus) { case apMouse.MouseBtnStatus.Down: case apMouse.MouseBtnStatus.Pressed: if (_leftBtnStatus == apMouse.MouseBtnStatus.Down) { if (IsMouseInLayout(_mousePos)) { apEditorUtil.SetEditorDirty(); if (IsMouseInButton(_mousePos, smoothA_Pos, pointSize, pointSize)) { //Debug.Log("Select A"); _selectedCurveKey = curveA; _isLockMouse = false; _prevMousePos = _mousePos; } else if (IsMouseInButton(_mousePos, smoothB_Pos, pointSize, pointSize)) { //Debug.Log("Select B"); _selectedCurveKey = curveB; _isLockMouse = false; _prevMousePos = _mousePos; } else { _selectedCurveKey = null; _isLockMouse = true; } } else { _selectedCurveKey = null; _isLockMouse = true; } } if (!_isLockMouse) { apEditorUtil.SetEditorDirty(); if (_selectedCurveKey == curveA) { Vector2 nextPos_Ratio = new Vector2( (_mousePos.x - posA.x) / (posB.x - posA.x), (_mousePos.y - posA.y) / (posB.y - posA.y)); curveA._nextSmoothX = Mathf.Clamp01(nextPos_Ratio.x); curveA._nextSmoothY = Mathf.Clamp01(nextPos_Ratio.y); } else if (_selectedCurveKey == curveB) { Vector2 nextPos_Ratio = new Vector2( (_mousePos.x - posA.x) / (posB.x - posA.x), (_mousePos.y - posA.y) / (posB.y - posA.y)); curveB._prevSmoothX = 1.0f - Mathf.Clamp01(nextPos_Ratio.x); curveB._prevSmoothY = 1.0f - Mathf.Clamp01(nextPos_Ratio.y); } if (Vector2.Distance(_prevMousePos, _mousePos) > 0.001f) { curveA.Refresh(); curveB.Refresh(); //Debug.LogError("Make Curve"); _prevMousePos = _mousePos; } } break; case apMouse.MouseBtnStatus.Released: case apMouse.MouseBtnStatus.Up: break; } } }
public void SetLinkedCurveKey(apAnimCurve prevLinkedCurveKey, apAnimCurve nextLinkedCurveKey, int prevIndex, int nextIndex //, bool isPrevDummyIndex, bool isNextDummyIndex ) { _prevLinkedCurveKey = prevLinkedCurveKey; _nextLinkedCurveKey = nextLinkedCurveKey; _prevIndex = prevIndex; _nextIndex = nextIndex; #region [미사용 코드] //_isPrevKeyUseDummyIndex = isPrevDummyIndex; //_isNextKeyUseDummyIndex = isNextDummyIndex; //Delta값은 항상 B-A 방식으로 한다. //float prevKeyIndex = _keyIndex; //float nextKeyIndex = _keyIndex; //if (_prevLinkedCurveKey == null) //{ // _prevDeltaX = 1.0f; // _prevDeltaY = Vector4.zero; //} //else //{ // //prevKeyIndex = _prevLinkedCurveKey.GetIndex(_isPrevKeyUseDummyIndex); // _prevDeltaX = (_keyIndex - _prevIndex); // _prevDeltaY = (_keyValue - _prevLinkedCurveKey._keyValue); //} //if(_nextLinkedCurveKey == null) //{ // _nextDeltaX = 1.0f; // _nextDeltaY = Vector4.zero; //} //else //{ // //nextKeyIndex = _nextLinkedCurveKey.GetIndex(_isNextKeyUseDummyIndex); // //_nextDeltaX = (nextKeyIndex - _keyIndex); // _nextDeltaX = (_nextIndex - _keyIndex); // _nextDeltaY = (_nextLinkedCurveKey._keyValue - _keyValue); //} //_prevDeltaX = Mathf.Max(_prevDeltaX, MIN_DELTA_X); //_nextDeltaX = Mathf.Max(_nextDeltaX, MIN_DELTA_X); //각도를 가지고 YOffset을 다시 계산하자 //CalculateSmooth(); #endregion ////Debug.Log("Link Curve Key"); //_prevTable.LinkAnimCurve(prevLinkedCurveKey); //_nextTable.LinkAnimCurve(nextLinkedCurveKey); //Refresh(); _prevCurveResult.Link(prevLinkedCurveKey, this, false, !(Application.isPlaying)); _nextCurveResult.Link(this, nextLinkedCurveKey, true, !(Application.isPlaying)); //Refresh(); }
// Functions //---------------------------------------------------- public void SetKeyframes(List <apAnimKeyframe> keyframes) { Clear(); //키프레임들을 하나씩 돌면서 CurveSet에 넣자. //중복을 막기 위해서 Key2CurveSet 확인 if (keyframes == null || keyframes.Count == 0) { return; } apAnimKeyframe srcKeyframe = null; apAnimKeyframe prevKey = null; apAnimKeyframe nextKey = null; for (int iKey = 0; iKey < keyframes.Count; iKey++) { srcKeyframe = keyframes[iKey]; _keyframes.Add(srcKeyframe); prevKey = srcKeyframe._prevLinkedKeyframe; nextKey = srcKeyframe._nextLinkedKeyframe; srcKeyframe._curveKey.Refresh(); if (prevKey != null && srcKeyframe != prevKey) { //Prev -> Src if (!_prevKey2CurveSet.ContainsKey(prevKey) && !_nextKey2CurveSet.ContainsKey(srcKeyframe)) { //아직 등록되지 않은 키프레임들 CurveSet newSet = new CurveSet(prevKey, srcKeyframe); _curveSets.Add(newSet); _prevKey2CurveSet.Add(prevKey, newSet); _nextKey2CurveSet.Add(srcKeyframe, newSet); } } if (nextKey != null && srcKeyframe != nextKey) { //Src -> Next if (!_prevKey2CurveSet.ContainsKey(srcKeyframe) && !_nextKey2CurveSet.ContainsKey(nextKey)) { //아직 등록되지 않은 키프레임들 CurveSet newSet = new CurveSet(srcKeyframe, nextKey); _curveSets.Add(newSet); _prevKey2CurveSet.Add(srcKeyframe, newSet); _nextKey2CurveSet.Add(nextKey, newSet); } } } if (_curveSets.Count <= 1) { Clear(); return; } //일단 동기화가 안됨 _syncStatus = SYNC_STATUS.NotSync; //커브값이 같은지 체크하자 CurveSet firstSet = _curveSets[0]; //<<첫번째것과 비교하자 bool isAllSame = true; //<<모두 동일한 커브를 가졌는가 CurveSet curSet = null; for (int i = 1; i < _curveSets.Count; i++) { curSet = _curveSets[i]; if (!curSet.IsSame(firstSet)) { //하나라도 다르다면 isAllSame = false; break; } } if (isAllSame) { //오잉 모두 같았다. //공통 Curve를 만든다. _syncStatus = SYNC_STATUS.Sync; //공통 Curve를 만들자 _syncCurve_Prev._nextLinkedCurveKey = _syncCurve_Next; _syncCurve_Next._prevLinkedCurveKey = _syncCurve_Prev; _syncCurve_Prev._keyIndex = 0; _syncCurve_Next._keyIndex = 1; _syncCurve_Prev._nextIndex = 1; _syncCurve_Next._prevIndex = 0; apAnimCurve prevCurve = firstSet._prevKeyframe._curveKey; apAnimCurve nextCurve = firstSet._nextKeyframe._curveKey; _syncCurve_Prev._nextSmoothX = prevCurve._nextSmoothX; _syncCurve_Prev._nextSmoothY = prevCurve._nextSmoothY; _syncCurve_Prev._nextTangentType = prevCurve._nextTangentType; _syncCurve_Next._prevSmoothX = nextCurve._prevSmoothX; _syncCurve_Next._prevSmoothY = nextCurve._prevSmoothY; _syncCurve_Next._prevTangentType = nextCurve._prevTangentType; //이전 //_syncCurve_Prev._nextCurveResult.Link(_syncCurve_Prev, _syncCurve_Next, true, true); //_syncCurve_Next._prevCurveResult.Link(_syncCurve_Prev, _syncCurve_Next, false, true); //변경 19.5.20 : MakeCurve를 항상 수행 _syncCurve_Prev._nextCurveResult.Link(_syncCurve_Prev, _syncCurve_Next, true); _syncCurve_Next._prevCurveResult.Link(_syncCurve_Prev, _syncCurve_Next, false); _syncCurve_Prev.Refresh(); _syncCurve_Next.Refresh(); _syncCurve_Prev._nextCurveResult.MakeCurve(); _syncCurve_Next._prevCurveResult.MakeCurve(); } else { //몇개가 다르다. _syncStatus = SYNC_STATUS.NotSync; _syncCurve_Prev.Refresh(); _syncCurve_Next.Refresh(); } }