mirror of
https://github.com/bjornbytes/lovr.git
synced 2024-07-04 13:33:34 +00:00
Add lovrAnimatorEvaluate;
This commit is contained in:
parent
855ffb9e34
commit
33ff7f2b9c
|
@ -47,7 +47,7 @@ const luaL_Reg lovrModel[] = {
|
||||||
{ "draw", l_lovrModelDraw },
|
{ "draw", l_lovrModelDraw },
|
||||||
{ "getAABB", l_lovrModelGetAABB },
|
{ "getAABB", l_lovrModelGetAABB },
|
||||||
{ "getAnimator", l_lovrModelGetAnimator },
|
{ "getAnimator", l_lovrModelGetAnimator },
|
||||||
{ "setAnimator", l_lovrModelGetAnimator },
|
{ "setAnimator", l_lovrModelSetAnimator },
|
||||||
{ "getMesh", l_lovrModelGetMesh },
|
{ "getMesh", l_lovrModelGetMesh },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "graphics/animator.h"
|
#include "graphics/animator.h"
|
||||||
#include "math/math.h"
|
#include "math/vec3.h"
|
||||||
|
#include "math/quat.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
static Track* lovrAnimatorEnsureTrack(Animator* animator, const char* animation) {
|
static Track* lovrAnimatorEnsureTrack(Animator* animator, const char* animation) {
|
||||||
|
@ -56,13 +57,120 @@ void lovrAnimatorUpdate(Animator* animator, float dt) {
|
||||||
const char* key;
|
const char* key;
|
||||||
while ((key = map_next(&animator->timeline, &iter)) != NULL) {
|
while ((key = map_next(&animator->timeline, &iter)) != NULL) {
|
||||||
Track* track = map_get(&animator->timeline, key);
|
Track* track = map_get(&animator->timeline, key);
|
||||||
track->time += dt * track->speed * animator->speed;
|
|
||||||
|
|
||||||
if (track->looping) {
|
if (track->playing) {
|
||||||
track->time = fmodf(track->time, track->animation->duration);
|
track->time += dt * track->speed * animator->speed;
|
||||||
} else if (track->time > track->animation->duration) {
|
|
||||||
track->time = 0;
|
if (track->looping) {
|
||||||
track->playing = false;
|
track->time = fmodf(track->time, track->animation->duration);
|
||||||
|
} else if (track->time > track->animation->duration) {
|
||||||
|
track->time = 0;
|
||||||
|
track->playing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void lovrAnimatorEvaluate(Animator* animator, const char* bone, mat4 transform) {
|
||||||
|
map_iter_t iter = map_iter(&animator->timeline);
|
||||||
|
const char* key;
|
||||||
|
while ((key = map_next(&animator->timeline, &iter)) != NULL) {
|
||||||
|
Track* track = map_get(&animator->timeline, key);
|
||||||
|
Animation* animation = track->animation;
|
||||||
|
AnimationChannel* channel = map_get(&animation->channels, bone);
|
||||||
|
|
||||||
|
if (!channel || !track->playing) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float time = fmodf(track->time, animation->duration);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// Position
|
||||||
|
if (channel->positionKeyframes.length > 0) {
|
||||||
|
i = 0;
|
||||||
|
while (i < channel->positionKeyframes.length) {
|
||||||
|
if (channel->positionKeyframes.data[i].time >= time) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float translation[3];
|
||||||
|
if (i == 0) {
|
||||||
|
Keyframe keyframe = channel->positionKeyframes.data[0];
|
||||||
|
vec3_init(translation, keyframe.data);
|
||||||
|
} else if (i >= channel->positionKeyframes.length) {
|
||||||
|
Keyframe keyframe = channel->positionKeyframes.data[channel->positionKeyframes.length - 1];
|
||||||
|
vec3_init(translation, keyframe.data);
|
||||||
|
} else {
|
||||||
|
Keyframe before, after;
|
||||||
|
before = channel->positionKeyframes.data[i - 1];
|
||||||
|
after = channel->positionKeyframes.data[i];
|
||||||
|
float t = (time - before.time) / (after.time - before.time);
|
||||||
|
vec3_lerp(vec3_init(translation, before.data), after.data, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4_translate(transform, translation[0], translation[1], translation[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotation
|
||||||
|
if (channel->rotationKeyframes.length > 0) {
|
||||||
|
i = 0;
|
||||||
|
while (i < channel->rotationKeyframes.length) {
|
||||||
|
if (channel->rotationKeyframes.data[i].time >= time) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float rotation[4];
|
||||||
|
if (i == 0) {
|
||||||
|
Keyframe keyframe = channel->rotationKeyframes.data[0];
|
||||||
|
quat_init(rotation, keyframe.data);
|
||||||
|
} else if (i >= channel->rotationKeyframes.length) {
|
||||||
|
Keyframe keyframe = channel->rotationKeyframes.data[channel->rotationKeyframes.length - 1];
|
||||||
|
quat_init(rotation, keyframe.data);
|
||||||
|
} else {
|
||||||
|
Keyframe before, after;
|
||||||
|
before = channel->rotationKeyframes.data[i - 1];
|
||||||
|
after = channel->rotationKeyframes.data[i];
|
||||||
|
float t = (time - before.time) / (after.time - before.time);
|
||||||
|
quat_slerp(quat_init(rotation, before.data), after.data, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4_rotateQuat(transform, rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scale
|
||||||
|
if (channel->scaleKeyframes.length > 0) {
|
||||||
|
i = 0;
|
||||||
|
while (i < channel->scaleKeyframes.length) {
|
||||||
|
if (channel->scaleKeyframes.data[i].time >= time) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float scale[3];
|
||||||
|
if (i == 0) {
|
||||||
|
Keyframe keyframe = channel->scaleKeyframes.data[0];
|
||||||
|
vec3_init(scale, keyframe.data);
|
||||||
|
} else if (i >= channel->scaleKeyframes.length) {
|
||||||
|
Keyframe keyframe = channel->scaleKeyframes.data[channel->scaleKeyframes.length - 1];
|
||||||
|
vec3_init(scale, keyframe.data);
|
||||||
|
} else {
|
||||||
|
Keyframe before, after;
|
||||||
|
before = channel->scaleKeyframes.data[i - 1];
|
||||||
|
after = channel->scaleKeyframes.data[i];
|
||||||
|
float t = (time - before.time) / (after.time - before.time);
|
||||||
|
vec3_lerp(vec3_init(scale, before.data), after.data, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4_scale(transform, scale[0], scale[1], scale[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "loaders/animation.h"
|
#include "loaders/animation.h"
|
||||||
#include "lib/map/map.h"
|
#include "math/mat4.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "lib/map/map.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -28,6 +29,7 @@ Animator* lovrAnimatorCreate(AnimationData* animationData);
|
||||||
void lovrAnimatorDestroy(const Ref* ref);
|
void lovrAnimatorDestroy(const Ref* ref);
|
||||||
void lovrAnimatorReset(Animator* animator);
|
void lovrAnimatorReset(Animator* animator);
|
||||||
void lovrAnimatorUpdate(Animator* animator, float dt);
|
void lovrAnimatorUpdate(Animator* animator, float dt);
|
||||||
|
void lovrAnimatorEvaluate(Animator* animator, const char* bone, mat4 transform);
|
||||||
int lovrAnimatorGetAnimationCount(Animator* animator);
|
int lovrAnimatorGetAnimationCount(Animator* animator);
|
||||||
const char* lovrAnimatorGetAnimationName(Animator* animator, int index);
|
const char* lovrAnimatorGetAnimationName(Animator* animator, int index);
|
||||||
void lovrAnimatorPlay(Animator* animator, const char* animation);
|
void lovrAnimatorPlay(Animator* animator, const char* animation);
|
||||||
|
|
Loading…
Reference in a new issue