#define M_PI 3.1415926535 #define M_PI_2 M_PI/2 #define M_PI_3 M_PI/3 #define M_PI_4 M_PI/4 #define RAD1 M_PI/180.0f #define DEG1 180.0f/M_PI #define RAD2DEG(rad) rad*DEG1 #define DEG2RAD(deg) deg*RAD1 #define MAX_CHILDREN_COUNT 10 #define MAX_KEYFRAME_COUNT 20
typedef struct _Joint { //inheritanse _Joint* root; /* Pointer to root element. All elements have it. */ _Joint* parent; /* Pointer to parent */ //simple joints variables float x, y; /* Position */ float angle; /* Angle of rotate. In radians!!! */ uint8_t level; /* Level of hierarchy. Root have 0, next level +1 */ float dX, dY; /* Default Position */ float dAngle; /* Default Angle */ float aX, aY; /* Animation Position */ float aAngle; /* Animation Angle */ //children uint8_t childCount; /* Number of children */ _Joint* child[MAX_CHILDREN_COUNT]; /* Array of children */ //index uint16_t indexCount; /* Last number for index. Only Root have the var. */ uint16_t index; /* Unique index of joint */ } S_Joint;
_Joint.x += (KEY2 - KEY1) / TIME * NOW - _Joint.aX;
_Joint.aX = (KEY2 - KEY1) / TIME * NOW;
22,3 += (100-50) / 900 * 450 - 22,3
typedef struct _KeyData { float x, y, angle; } S_KeyData; typedef struct _Keyframe { S_KeyData data; /* data of Joint */ uint16_t time; /* ~32 sec.(32768 ms) is maximum time for animation. Only Root have it */ uint16_t index; /* Index of joint, which we want interpolate */ _Keyframe* parent; uint8_t childCount; /* Number of children */ _Keyframe* child[MAX_CHILDREN_COUNT]; } S_Keyframe;
typedef struct _Animation { uint8_t keyNumber; uint8_t keyCount; S_Keyframe* key[MAX_KEYFRAME_COUNT]; } S_Animation;
bool doAnimation(S_Joint *root, S_Animation *anim, uint16_t time) { if (!root) return false; if (!anim) return false; bool timeOut = true; for (int i = 0; i < anim->keyCount; i++) { if (time < anim->key[i]->time) //search keyframes for interpolation { // 1200, 2400, 2400-1200=1200 uint16_t mtime = anim->key[i]->time - anim->key[i - 1]->time; //nowTime is 1560, mtime = 1200(ERROR), 1560 - 1200(last key)=360(realtime) uint16_t nowTime = time - anim->key[i - 1]->time; if (i != anim->keyNumber) // keyNumber, { setDefaultAnimTree(root); //set to 0.0 animation changes(aX,yX,aAngle) } anim->keyNumber = i; // doInterpolate(root, anim->key[i - 1], anim->key[i], mtime, nowTime); timeOut = false; break; } } if (timeOut == true) { setDefaultTree(root); // } return timeOut; }
void doInterpolate(S_Joint* root, S_Keyframe* key1, S_Keyframe* key2, uint16_t time, uint16_t nowTime) { if (root->index != key2->index) return; float x = (key2->data.x - key1->data.x) / time * nowTime; // float y = (key2->data.y - key1->data.y) / time * nowTime; float angle = (key2->data.angle - key1->data.angle) / time * nowTime; root->x += x - root->aX; //root->aX - , root->y += y - root->aY; root->angle += angle - root->aAngle; root->aX = x; // , x,y,angle root->aY = y; root->aAngle = angle; // for (int i = 0; i < root->childCount; i++) { doInterpolate(root->child[i], key1->child[i], key2->child[i], time, nowTime); } }
4,47-6.28=-1,81
negAngle = BA; posAngle = (B-6.28)-A; if(fabs(posAngle) > fabs(negAngle)) { /* */ }
Source: https://habr.com/ru/post/219509/