// Functions //--------------------------------------------------------- // Keyframe -> File public void SetAnimKeyframe(int unitID, apAnimKeyframe animKeyframe) { _unitID = unitID; _keyframeUniqueID = animKeyframe._uniqueID; _linkedKeyframe = animKeyframe; _frameIndex = animKeyframe._frameIndex; _isKeyValueSet = animKeyframe._isKeyValueSet; _isActive = animKeyframe._isActive; _isLoopAsStart = animKeyframe._isLoopAsStart; _isLoopAsEnd = animKeyframe._isLoopAsEnd; _loopFrameIndex = animKeyframe._loopFrameIndex; _activeFrameIndexMin = animKeyframe._activeFrameIndexMin; _activeFrameIndexMax = animKeyframe._activeFrameIndexMax; _activeFrameIndexMin_Dummy = animKeyframe._activeFrameIndexMin_Dummy; _activeFrameIndexMax_Dummy = animKeyframe._activeFrameIndexMax_Dummy; //Curve 정보 _curve_PrevTangentType = animKeyframe._curveKey._prevTangentType; _curve_PrevSmoothX = animKeyframe._curveKey._prevSmoothX; _curve_PrevSmoothY = animKeyframe._curveKey._prevSmoothY; _curve_NextTangentType = animKeyframe._curveKey._nextTangentType; _curve_NextSmoothX = animKeyframe._curveKey._nextSmoothX; _curve_NextSmoothY = animKeyframe._curveKey._nextSmoothY; //Control Param 타입이면 //Control Param의 어떤 값에 동기화되는가 _conSyncValue_Int = animKeyframe._conSyncValue_Int; _conSyncValue_Float = animKeyframe._conSyncValue_Float; _conSyncValue_Vector2 = animKeyframe._conSyncValue_Vector2; //Modifier Mesh 타입일때 _isModMeshType = animKeyframe._linkedModMesh_Editor != null; _isModBoneType = animKeyframe._linkedModBone_Editor != null; //>> Transform만 저장한다. _modTransformMatrix = new apMatrix(); _modMeshColor = Color.black; _modVisible = true; if (_isModMeshType) { _modTransformMatrix.SetMatrix(animKeyframe._linkedModMesh_Editor._transformMatrix); _modMeshColor = animKeyframe._linkedModMesh_Editor._meshColor; _modVisible = animKeyframe._linkedModMesh_Editor._isVisible; } else if (_isModBoneType) { _modTransformMatrix.SetMatrix(animKeyframe._linkedModBone_Editor._transformMatrix); } }
// File -> Keyframe //----------------------------------------------------------- public bool DecodeData(string strSrc) { try { string[] strUnits = strSrc.Split(new string[] { "/" }, StringSplitOptions.None); _unitID = int.Parse(strUnits[0]); _frameIndex = int.Parse(strUnits[1]); _isKeyValueSet = (int.Parse(strUnits[2]) == 1) ? true : false; _isActive = (int.Parse(strUnits[3]) == 1) ? true : false; _isLoopAsStart = (int.Parse(strUnits[4]) == 1) ? true : false; _isLoopAsEnd = (int.Parse(strUnits[5]) == 1) ? true : false; _loopFrameIndex = int.Parse(strUnits[6]); _activeFrameIndexMin = int.Parse(strUnits[7]); _activeFrameIndexMax = int.Parse(strUnits[8]); _activeFrameIndexMin_Dummy = int.Parse(strUnits[9]); _activeFrameIndexMax_Dummy = int.Parse(strUnits[10]); _curve_PrevTangentType = (apAnimCurve.TANGENT_TYPE) int.Parse(strUnits[11]); _curve_PrevSmoothX = float.Parse(strUnits[12]); _curve_PrevSmoothY = float.Parse(strUnits[13]); _curve_NextTangentType = (apAnimCurve.TANGENT_TYPE) int.Parse(strUnits[14]); _curve_NextSmoothX = float.Parse(strUnits[15]); _curve_NextSmoothY = float.Parse(strUnits[16]); _conSyncValue_Int = int.Parse(strUnits[17]); _conSyncValue_Float = float.Parse(strUnits[18]); _conSyncValue_Vector2.x = float.Parse(strUnits[19]); _conSyncValue_Vector2.y = float.Parse(strUnits[20]); _isModMeshType = (int.Parse(strUnits[21]) == 1) ? true : false; _isModBoneType = (int.Parse(strUnits[22]) == 1) ? true : false; _modTransformMatrix._pos.x = float.Parse(strUnits[23]); _modTransformMatrix._pos.y = float.Parse(strUnits[24]); _modTransformMatrix._angleDeg = float.Parse(strUnits[25]); _modTransformMatrix._scale.x = float.Parse(strUnits[26]); _modTransformMatrix._scale.y = float.Parse(strUnits[27]); _modMeshColor.r = float.Parse(strUnits[28]); _modMeshColor.g = float.Parse(strUnits[29]); _modMeshColor.b = float.Parse(strUnits[30]); _modMeshColor.a = float.Parse(strUnits[31]); _modVisible = (int.Parse(strUnits[32]) == 1) ? true : false; } catch (Exception ex) { Debug.LogError("Decode Exception : " + ex); return(false); } return(true); }
//-------------------------------------------------------- public void SetTangentType(apAnimCurve.TANGENT_TYPE tangentType) { if (_syncStatus != SYNC_STATUS.Sync) { return; } SyncCurveResult.SetTangent(tangentType); SetChanged(); ApplySync(true, false); }
public void SetTangent(apAnimCurve.TANGENT_TYPE tangentType) { if (_curveKeyA == null || _curveKeyB == null) { return; } _curveKeyA._nextTangentType = tangentType; _curveKeyB._prevTangentType = tangentType; _curveKeyA.Refresh(); _curveKeyB.Refresh(); MakeCurve(); }
//public void MakeCurve(bool isForce = false) public void MakeCurve() { if (_curveKeyA == null || _curveKeyB == null) { _frameIndex_A = -1; _frameIndex_B = -1; _tangentType = apAnimCurve.TANGENT_TYPE.Linear; return; } _smoothX_A = _curveKeyA._nextSmoothX; _smoothY_A = _curveKeyA._nextSmoothY; _smoothX_B = _curveKeyB._prevSmoothX; _smoothY_B = _curveKeyB._prevSmoothY; if (_isTargetIsA) { _frameIndex_A = _curveKeyA._keyIndex; _frameIndex_B = _curveKeyA._nextIndex; } else { _frameIndex_A = _curveKeyB._prevIndex; _frameIndex_B = _curveKeyB._keyIndex; } //Debug.Log("Make Curve [ A : " + _frameIndex_A + " / B : " + _frameIndex_B + " ]"); if (_curveKeyA._nextTangentType == apAnimCurve.TANGENT_TYPE.Constant || _curveKeyB._prevTangentType == apAnimCurve.TANGENT_TYPE.Constant) { _tangentType = apAnimCurve.TANGENT_TYPE.Constant; } else if (_curveKeyA._nextTangentType == apAnimCurve.TANGENT_TYPE.Linear && _curveKeyB._prevTangentType == apAnimCurve.TANGENT_TYPE.Linear) { _tangentType = apAnimCurve.TANGENT_TYPE.Linear; } else { _tangentType = apAnimCurve.TANGENT_TYPE.Smooth; } }
public void CopyCurve(apAnimCurveResult srcCurveResult) { if (_curveKeyA == null || _curveKeyB == null) { return; } _tangentType = srcCurveResult._tangentType; _curveKeyA._nextTangentType = srcCurveResult._curveKeyA._nextTangentType; _curveKeyA._nextSmoothX = srcCurveResult._curveKeyA._nextSmoothX; _curveKeyA._nextSmoothY = srcCurveResult._curveKeyA._nextSmoothY; _curveKeyB._prevTangentType = srcCurveResult._curveKeyB._prevTangentType; _curveKeyB._prevSmoothX = srcCurveResult._curveKeyB._prevSmoothX; _curveKeyB._prevSmoothY = srcCurveResult._curveKeyB._prevSmoothY; MakeCurve(); }
// 계산용 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 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); }