diff --git a/src/api/types/animator.c b/src/api/types/animator.c index 1b1bc391..0a199635 100644 --- a/src/api/types/animator.c +++ b/src/api/types/animator.c @@ -20,57 +20,37 @@ int l_lovrAnimatorGetAnimationCount(lua_State* L) { return 1; } -/* -int l_lovrAnimatorGetAnimationNames(lua_State* L) { - Animator* animator = luax_checktype(L, 1, Animator); - int animationCount = lovrAnimatorGetAnimationCount(animator); - - if (lua_istable(L, 2)) { - lua_settop(L, 2); - } else { - lua_settop(L, 1); - lua_createtable(L, animationCount, 0); - } - - for (int i = 0; i < animationCount; i++) { - lua_pushstring(L, lovrAnimatorGetAnimationName(animator, i)); - lua_rawseti(L, -2, i + 1); - } - - return 1; -} - int l_lovrAnimatorPlay(lua_State* L) { Animator* animator = luax_checktype(L, 1, Animator); - const char* animation = luaL_checkstring(L, 2); + int animation = luaL_checkinteger(L, 2); lovrAnimatorPlay(animator, animation); return 0; } int l_lovrAnimatorStop(lua_State* L) { Animator* animator = luax_checktype(L, 1, Animator); - const char* animation = luaL_checkstring(L, 2); + int animation = luaL_checkinteger(L, 2); lovrAnimatorStop(animator, animation); return 0; } int l_lovrAnimatorPause(lua_State* L) { Animator* animator = luax_checktype(L, 1, Animator); - const char* animation = luaL_checkstring(L, 2); + int animation = luaL_checkinteger(L, 2); lovrAnimatorPause(animator, animation); return 0; } int l_lovrAnimatorResume(lua_State* L) { Animator* animator = luax_checktype(L, 1, Animator); - const char* animation = luaL_checkstring(L, 2); + int animation = luaL_checkinteger(L, 2); lovrAnimatorResume(animator, animation); return 0; } int l_lovrAnimatorSeek(lua_State* L) { Animator* animator = luax_checktype(L, 1, Animator); - const char* animation = luaL_checkstring(L, 2); + int animation = luaL_checkinteger(L, 2); float time = luax_checkfloat(L, 3); lovrAnimatorSeek(animator, animation, time); return 0; @@ -78,7 +58,7 @@ int l_lovrAnimatorSeek(lua_State* L) { int l_lovrAnimatorTell(lua_State* L) { Animator* animator = luax_checktype(L, 1, Animator); - const char* animation = luaL_checkstring(L, 2); + int animation = luaL_checkinteger(L, 2); float time = lovrAnimatorTell(animator, animation); lua_pushnumber(L, time); return 1; @@ -86,7 +66,7 @@ int l_lovrAnimatorTell(lua_State* L) { int l_lovrAnimatorGetAlpha(lua_State* L) { Animator* animator = luax_checktype(L, 1, Animator); - const char* animation = luaL_checkstring(L, 2); + int animation = luaL_checkinteger(L, 2); float alpha = lovrAnimatorGetAlpha(animator, animation); lua_pushnumber(L, alpha); return 1; @@ -94,15 +74,15 @@ int l_lovrAnimatorGetAlpha(lua_State* L) { int l_lovrAnimatorSetAlpha(lua_State* L) { Animator* animator = luax_checktype(L, 1, Animator); - const char* animation = luaL_checkstring(L, 2); - float alpha = luax_checkfloat(L, 3); + int animation = luaL_checkinteger(L, 2); + float alpha = luaL_checkfloat(L, 3); lovrAnimatorSetAlpha(animator, animation, alpha); return 0; } int l_lovrAnimatorGetDuration(lua_State* L) { Animator* animator = luax_checktype(L, 1, Animator); - const char* animation = luaL_checkstring(L, 2); + int animation = luaL_checkinteger(L, 2); float duration = lovrAnimatorGetDuration(animator, animation); lua_pushnumber(L, duration); return 1; @@ -110,7 +90,7 @@ int l_lovrAnimatorGetDuration(lua_State* L) { int l_lovrAnimatorIsPlaying(lua_State* L) { Animator* animator = luax_checktype(L, 1, Animator); - const char* animation = luaL_checkstring(L, 2); + int animation = luaL_checkinteger(L, 2); bool playing = lovrAnimatorIsPlaying(animator, animation); lua_pushboolean(L, playing); return 1; @@ -118,7 +98,7 @@ int l_lovrAnimatorIsPlaying(lua_State* L) { int l_lovrAnimatorIsLooping(lua_State* L) { Animator* animator = luax_checktype(L, 1, Animator); - const char* animation = luaL_checkstring(L, 2); + int animation = luaL_checkinteger(L, 2); bool looping = lovrAnimatorIsLooping(animator, animation); lua_pushboolean(L, looping); return 1; @@ -126,7 +106,7 @@ int l_lovrAnimatorIsLooping(lua_State* L) { int l_lovrAnimatorSetLooping(lua_State* L) { Animator* animator = luax_checktype(L, 1, Animator); - const char* animation = luaL_checkstring(L, 2); + int animation = luaL_checkinteger(L, 2); bool looping = lua_toboolean(L, 3); lovrAnimatorSetLooping(animator, animation, looping); return 0; @@ -134,7 +114,7 @@ int l_lovrAnimatorSetLooping(lua_State* L) { int l_lovrAnimatorGetPriority(lua_State* L) { Animator* animator = luax_checktype(L, 1, Animator); - const char* animation = luaL_checkstring(L, 2); + int animation = luaL_checkinteger(L, 2); int priority = lovrAnimatorGetPriority(animator, animation); lua_pushinteger(L, priority); return 1; @@ -142,7 +122,7 @@ int l_lovrAnimatorGetPriority(lua_State* L) { int l_lovrAnimatorSetPriority(lua_State* L) { Animator* animator = luax_checktype(L, 1, Animator); - const char* animation = luaL_checkstring(L, 2); + int animation = luaL_checkinteger(L, 2); int priority = luaL_checkinteger(L, 3); lovrAnimatorSetPriority(animator, animation, priority); return 0; @@ -150,12 +130,12 @@ int l_lovrAnimatorSetPriority(lua_State* L) { int l_lovrAnimatorGetSpeed(lua_State* L) { Animator* animator = luax_checktype(L, 1, Animator); - if (lua_type(L, 2) == LUA_TSTRING) { - const char* animation = luaL_checkstring(L, 2); - float speed = lovrAnimatorGetSpeed(animator, animation); + if (lua_isnoneornil(L, 2)) { + float speed = lovrAnimatorGetSpeed(animator, -1); lua_pushnumber(L, speed); } else { - float speed = lovrAnimatorGetSpeed(animator, NULL); + int animation = luaL_checkinteger(L, 2); + float speed = lovrAnimatorGetSpeed(animator, animation); lua_pushnumber(L, speed); } return 1; @@ -163,24 +143,21 @@ int l_lovrAnimatorGetSpeed(lua_State* L) { int l_lovrAnimatorSetSpeed(lua_State* L) { Animator* animator = luax_checktype(L, 1, Animator); - if (lua_type(L, 2) == LUA_TSTRING) { - const char* animation = luaL_checkstring(L, 2); + if (lua_isnoneornil(L, 2)) { + float speed = luaL_checknumber(L, 2); + lovrAnimatorSetSpeed(animator, -1, speed); + } else { + int animation = luaL_checkinteger(L, 2); float speed = luax_checkfloat(L, 3); lovrAnimatorSetSpeed(animator, animation, speed); - } else { - float speed = luax_checkfloat(L, 2); - lovrAnimatorSetSpeed(animator, NULL, speed); } return 0; } -*/ const luaL_Reg lovrAnimator[] = { { "reset", l_lovrAnimatorReset }, { "update", l_lovrAnimatorUpdate }, - /* { "getAnimationCount", l_lovrAnimatorGetAnimationCount }, - { "getAnimationNames", l_lovrAnimatorGetAnimationNames }, { "play", l_lovrAnimatorPlay }, { "stop", l_lovrAnimatorStop }, { "pause", l_lovrAnimatorPause }, @@ -196,6 +173,6 @@ const luaL_Reg lovrAnimator[] = { { "getPriority", l_lovrAnimatorGetPriority }, { "setPriority", l_lovrAnimatorSetPriority }, { "getSpeed", l_lovrAnimatorGetSpeed }, - { "setSpeed", l_lovrAnimatorSetSpeed },*/ + { "setSpeed", l_lovrAnimatorSetSpeed }, { NULL, NULL } }; diff --git a/src/api/types/model.c b/src/api/types/model.c index b58c9f45..9357056c 100644 --- a/src/api/types/model.c +++ b/src/api/types/model.c @@ -11,7 +11,26 @@ int l_lovrModelDraw(lua_State* L) { return 0; } +int l_lovrModelGetAnimator(lua_State* L) { + Model* model = luax_checktype(L, 1, Model); + luax_pushobject(L, lovrModelGetAnimator(model)); + return 1; +} + +int l_lovrModelSetAnimator(lua_State* L) { + Model* model = luax_checktype(L, 1, Model); + if (lua_isnoneornil(L, 2)) { + lovrModelSetAnimator(model, NULL); + } else { + Animator* animator = luax_checktype(L, 2, Animator); + lovrModelSetAnimator(model, animator); + } + return 0; +} + const luaL_Reg lovrModel[] = { { "draw", l_lovrModelDraw }, + { "getAnimator", l_lovrModelGetAnimator }, + { "setAnimator", l_lovrModelSetAnimator }, { NULL, NULL } }; diff --git a/src/graphics/animator.c b/src/graphics/animator.c index 77ec1373..8bc9fd6e 100644 --- a/src/graphics/animator.c +++ b/src/graphics/animator.c @@ -76,8 +76,8 @@ bool lovrAnimatorEvaluate(Animator* animator, int nodeIndex, mat4 transform) { vec_foreach_ptr(&animator->tracks, track, i) { ModelAnimation* animation = &modelData->animations[i]; - for (int i = 0; i < animation->channelCount; i++) { - ModelAnimationChannel* channel = &animation->channels[i]; + for (int j = 0; j < animation->channelCount; j++) { + ModelAnimationChannel* channel = &animation->channels[j]; if (!track->playing || channel->nodeIndex != nodeIndex) { continue; diff --git a/src/graphics/model.c b/src/graphics/model.c index 133bd774..6044b395 100644 --- a/src/graphics/model.c +++ b/src/graphics/model.c @@ -8,8 +8,22 @@ static void renderNode(Model* model, uint32_t nodeIndex, mat4 transform, int ins float globalTransform[16]; mat4_init(globalTransform, transform); - if (!model->animator || !lovrAnimatorEvaluate(model->animator, nodeIndex, globalTransform)) { - mat4_multiply(globalTransform, node->transform); + float pose[16 * MAX_BONES]; + if (node->skin >= 0 && model->animator) { + ModelSkin* skin = &model->data->skins[node->skin]; + + for (uint32_t j = 0; j < skin->jointCount; j++) { + mat4_identity(pose + 16 * j); + lovrAnimatorEvaluate(model->animator, skin->joints[j], pose + 16 * j); + } + + if (!lovrAnimatorEvaluate(model->animator, skin->skeleton, globalTransform)) { + mat4_multiply(globalTransform, node->transform); + } + } else { + if (!model->animator || !lovrAnimatorEvaluate(model->animator, nodeIndex, globalTransform)) { + mat4_multiply(globalTransform, node->transform); + } } if (node->mesh >= 0) { @@ -31,7 +45,7 @@ static void renderNode(Model* model, uint32_t nodeIndex, mat4 transform, int ins .rangeStart = rangeStart, .rangeCount = rangeCount, .instances = instances, - .pose = NULL + .pose = node->skin >= 0 ? pose : NULL }, .transform = globalTransform //.material = model->materials[modelMesh->material] @@ -118,3 +132,15 @@ void lovrModelDestroy(void* ref) { void lovrModelDraw(Model* model, mat4 transform, int instances) { renderNode(model, 0, transform, instances); // TODO use root } + +Animator* lovrModelGetAnimator(Model* model) { + return model->animator; +} + +void lovrModelSetAnimator(Model* model, Animator* animator) { + if (model->animator != animator) { + lovrRetain(animator); + lovrRelease(model->animator); + model->animator = animator; + } +} diff --git a/src/graphics/model.h b/src/graphics/model.h index 18dee399..6fdf3752 100644 --- a/src/graphics/model.h +++ b/src/graphics/model.h @@ -18,3 +18,5 @@ Model* lovrModelInit(Model* model, ModelData* data); #define lovrModelCreate(...) lovrModelInit(lovrAlloc(Model), __VA_ARGS__) void lovrModelDestroy(void* ref); void lovrModelDraw(Model* model, mat4 transform, int instances); +Animator* lovrModelGetAnimator(Model* model); +void lovrModelSetAnimator(Model* model, Animator* animator);