Introduce animation trees, remove "standard animations" from core
This commit is contained in:
parent
96da001734
commit
dbced43b2b
2
k3ex.py
2
k3ex.py
@ -115,6 +115,8 @@ def write_some_data(context, filepath, doExportEverything):
|
||||
out.write(struct.pack("4f", m.col[c][0], m.col[c][1], m.col[c][2], m.col[c][3]))
|
||||
for b in dabones:
|
||||
out.write(struct.pack("B", dabones.index(b.parent) if b.parent else 255))
|
||||
for b in dabones:
|
||||
out.write(b.name.encode("UTF-8") + b'\x00')
|
||||
|
||||
for v in vertdict.keys():
|
||||
out.write(struct.pack("3f", v[0][0], v[0][2], -v[0][1]))
|
||||
|
11
src/game.c
11
src/game.c
@ -685,7 +685,7 @@ void game_update() {
|
||||
|
||||
size_t boneCount = Game.entities.render[ci].cache ? k3MdlGetBoneCount(Game.entities.render[ci].cache) : 0;
|
||||
if(boneCount) {
|
||||
struct CBoned *cb = game_getcomponent(Game.entities.render[ci].entity, boned);
|
||||
/*struct CBoned *cb = game_getcomponent(Game.entities.render[ci].entity, boned);
|
||||
|
||||
if(!cb) {
|
||||
cb = game_ensurecomponent(Game.entities.render[ci].entity, boned);
|
||||
@ -741,7 +741,7 @@ void game_update() {
|
||||
glm_decompose(cb->anim.cache.inter[m], cb->bones[m].translation, rot, scaleignore);
|
||||
glm_mat4_quat(cb->anim.cache.inter[m], cb->bones[m].rotation);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
dGeomID gid = cp->geom;
|
||||
@ -776,7 +776,7 @@ void game_update() {
|
||||
|
||||
for(size_t cm = 0; cm < Game.entities.movementCount; cm++) {
|
||||
struct CBoned *cb = game_getcomponent(Game.entities.movement[cm].entity, boned);
|
||||
if(cb && cb->anim.standard) {
|
||||
/*if(cb && cb->anim.standard) {
|
||||
struct CPhysics *cp = game_getcomponent(Game.entities.movement[cm].entity, physics);
|
||||
if(cp && cp->geom) {
|
||||
dBodyID bid = dGeomGetBody(cp->geom);
|
||||
@ -789,7 +789,7 @@ void game_update() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < Game.conveyorCount; i++) {
|
||||
@ -876,7 +876,6 @@ void game_update() {
|
||||
vec3 dif;
|
||||
glm_vec3_sub(conveyor->points[nextPoint], conveyor->points[currentPoint], dif);
|
||||
glm_vec3_scale_as(dif, conveyor->speed * (conveyor->active <= 0 ? -1 : 1), dif);
|
||||
//printf("set %f %f %f\n", dif[0], dif[1], dif[2]);
|
||||
dBodySetLinearVel(bid, dif[0], dif[1], dif[2]); // doesn't affect movement, but necessary for proper collision response
|
||||
}
|
||||
}
|
||||
@ -950,7 +949,7 @@ void game_cleanup() {
|
||||
Game.entities.renderCount = 0;
|
||||
|
||||
for(size_t i = 0; i < Game.entities.bonedCount; i++) {
|
||||
free(Game.entities.boned[i].bones);
|
||||
//free(Game.entities.boned[i].bones);
|
||||
}
|
||||
Game.entities.bonedCount = 0;
|
||||
|
||||
|
@ -118,14 +118,7 @@ struct CPlayerCtrl {
|
||||
struct CBoned {
|
||||
uint16_t entity;
|
||||
|
||||
size_t size;
|
||||
struct k3AnimationBone *bones;
|
||||
|
||||
struct {
|
||||
uint16_t id;
|
||||
struct k3Animator cache;
|
||||
bool standard;
|
||||
} anim;
|
||||
struct k3Animator animator;
|
||||
};
|
||||
|
||||
#define CONVEYOR_TYPE_LOOP 0
|
||||
|
@ -33,6 +33,17 @@ static int mdlloader(void *ud, struct ResManRes *res) {
|
||||
uint8_t *boneParents = malloc(header.boneCount);
|
||||
fread(boneParents, 1, header.boneCount, f);
|
||||
|
||||
char boneNames[1500] = {};
|
||||
size_t boneNamesLen = 0;
|
||||
for(size_t b = 0; b < header.boneCount; b++) {
|
||||
while(1) {
|
||||
fread(boneNames + boneNamesLen, 1, 1, f);
|
||||
if(boneNames[boneNamesLen++] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vec3 *pos = malloc(sizeof(*pos) * header.vertCount);
|
||||
fread(pos, sizeof(vec3), header.vertCount, f);
|
||||
|
||||
@ -59,6 +70,8 @@ static int mdlloader(void *ud, struct ResManRes *res) {
|
||||
|
||||
struct k3Mdl *mdl = k3MdlCreate(header.vertCount, header.indCount, header.boneCount, pos, nrm, uvs, cols, boneIDs, boneWeights, inds, invBind, boneParents);
|
||||
|
||||
k3MdlSetBoneNames(mdl, boneNames);
|
||||
|
||||
k3MdlSetDebugName(mdl, res->name);
|
||||
|
||||
free(pos);
|
||||
@ -87,22 +100,19 @@ static int mdlloader(void *ud, struct ResManRes *res) {
|
||||
for(size_t i = 0; i < header.animCount; i++) {
|
||||
struct {
|
||||
uint16_t id;
|
||||
uint16_t frames;
|
||||
uint16_t frameCount;
|
||||
uint16_t fps;
|
||||
uint16_t zero;
|
||||
} info;
|
||||
fread(&info, sizeof(info), 1, f);
|
||||
|
||||
struct k3Animation *anim = malloc(sizeof(*anim));
|
||||
anim->frames = _mm_malloc(sizeof(*anim->frames) * info.frames * header.boneCount, 16);
|
||||
anim->boneParents = boneParents;
|
||||
anim->invBind = invBind;
|
||||
struct k3AnimationFountain *anim = _mm_malloc(sizeof(*anim) + sizeof(*anim->frames) * info.frameCount * header.boneCount, 16);
|
||||
anim->id = info.id;
|
||||
anim->fps = info.fps;
|
||||
anim->frameCount = info.frames;
|
||||
anim->boneCount = header.boneCount;
|
||||
anim->frameCount = info.frameCount;
|
||||
anim->bones = header.boneCount;
|
||||
|
||||
fread(anim->frames, sizeof(*anim->frames), info.frames * header.boneCount, f);
|
||||
fread(anim->frames, sizeof(*anim->frames), info.frameCount * header.boneCount, f);
|
||||
|
||||
k3MdlAddAnim(mdl, anim);
|
||||
}
|
||||
|
611
src/luaapi.c
611
src/luaapi.c
@ -183,15 +183,6 @@ struct mixitem {
|
||||
int type;
|
||||
};
|
||||
|
||||
struct Animator {
|
||||
struct k3Mdl *mdl;
|
||||
struct k3Animator animator;
|
||||
struct k3AnimationBone *bones;
|
||||
|
||||
bool playing;
|
||||
double playStartTime;
|
||||
};
|
||||
|
||||
static int game_addentity(lua_State *L) {
|
||||
lua_Integer li;
|
||||
int i;
|
||||
@ -347,7 +338,7 @@ static int game_addentity(lua_State *L) {
|
||||
|
||||
setstrstatic("mdl", c.mdl, sizeof(c.mdl));
|
||||
|
||||
//c.animator.base = NULL;
|
||||
c.cache = k3MdlCopySubs((struct k3Mdl*) resman_ref(RESMAN_MODEL, c.mdl));
|
||||
|
||||
game_addcomponent(render, &c);
|
||||
}
|
||||
@ -380,76 +371,7 @@ static int game_addentity(lua_State *L) {
|
||||
|
||||
c.entity = id;
|
||||
|
||||
lua_getfield(L, -1, "size");
|
||||
if(lua_isnil(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
lua_getfield(L, -1, "bones");
|
||||
c.size = lua_isnil(L, -1) ? 0 : luaL_len(L, -1);
|
||||
} else {
|
||||
c.size = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_getfield(L, -1, "bones");
|
||||
}
|
||||
|
||||
c.bones = _mm_malloc(sizeof(*c.bones) * c.size, 16);
|
||||
|
||||
if(lua_isnil(L, -1)) {
|
||||
glm_quat_identity_array((versor*) c.bones, c.size * 2);
|
||||
} else {
|
||||
for(size_t i = 0; i < c.size; i++) {
|
||||
lua_rawgeti(L, -1, i + 1); // bone
|
||||
|
||||
if(lua_isnil(L, -1)) {
|
||||
c.bones[i].translation[0] = 0;
|
||||
c.bones[i].translation[1] = 0;
|
||||
c.bones[i].translation[2] = 0;
|
||||
c.bones[i].translation[3] = 1;
|
||||
|
||||
c.bones[i].rotation[0] = 0;
|
||||
c.bones[i].rotation[1] = 0;
|
||||
c.bones[i].rotation[2] = 0;
|
||||
c.bones[i].rotation[3] = 1;
|
||||
} else {
|
||||
lua_rawgeti(L, -1, 1); // translation
|
||||
lua_rawgeti(L, -1, 1); // x
|
||||
lua_rawgeti(L, -2, 2); // y
|
||||
lua_rawgeti(L, -3, 3); // z
|
||||
lua_rawgeti(L, -4, 4); // w
|
||||
c.bones[i].translation[0] = lua_tonumber(L, -4);
|
||||
c.bones[i].translation[1] = lua_tonumber(L, -3);
|
||||
c.bones[i].translation[2] = lua_tonumber(L, -2);
|
||||
c.bones[i].translation[3] = lua_tonumber(L, -1);
|
||||
lua_pop(L, 5);
|
||||
|
||||
lua_rawgeti(L, -1, 2); // rotation
|
||||
lua_rawgeti(L, -1, 1); // x
|
||||
lua_rawgeti(L, -2, 2); // y
|
||||
lua_rawgeti(L, -3, 3); // z
|
||||
lua_rawgeti(L, -4, 4); // w
|
||||
c.bones[i].rotation[0] = lua_tonumber(L, -4);
|
||||
c.bones[i].rotation[1] = lua_tonumber(L, -3);
|
||||
c.bones[i].rotation[2] = lua_tonumber(L, -2);
|
||||
c.bones[i].rotation[3] = lua_tonumber(L, -1);
|
||||
lua_pop(L, 5);
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "anim");
|
||||
if(lua_istable(L, -1)) {
|
||||
lua_getfield(L, -1, "id");
|
||||
c.anim.id = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "standard");
|
||||
c.anim.standard = lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
k3AnimatorInit(&c.animator, game_getcomponent(id, render)->cache);
|
||||
|
||||
game_addcomponent(boned, &c);
|
||||
}
|
||||
@ -912,26 +834,15 @@ static int game_batch(lua_State *L) {
|
||||
|
||||
struct k3AnimationBone *bones = NULL;
|
||||
|
||||
if(lua_gettop(L) >= 4) {
|
||||
struct Animator *anim = lua_touserdata(L, 4);
|
||||
|
||||
if(anim->playing) {
|
||||
k3AnimatorSet(&anim->animator, glfwGetTime() - anim->playStartTime);
|
||||
if(lua_type(L, 4) == LUA_TUSERDATA) {
|
||||
struct k3Animator *animator = *(void**) lua_touserdata(L, 4);
|
||||
if(animator->playing) {
|
||||
k3AnimatorSet(animator, glfwGetTime() - animator->playStartTime);
|
||||
}
|
||||
bones = animator->bones;
|
||||
}
|
||||
|
||||
bones = anim->bones;
|
||||
|
||||
size_t boneCount = k3MdlGetBoneCount(anim->mdl);
|
||||
|
||||
for(size_t m = 0; m < boneCount; m++) {
|
||||
vec3 scaleignore;
|
||||
mat4 rot;
|
||||
glm_decompose(anim->animator.inter[m], bones[m].translation, rot, scaleignore);
|
||||
glm_mat4_quat(anim->animator.inter[m], bones[m].rotation);
|
||||
}
|
||||
}
|
||||
|
||||
if(lua_gettop(L) >= 3) {
|
||||
if(lua_type(L, 3) == LUA_TTABLE) {
|
||||
mat4 anchor;
|
||||
for(int i = 0; i < 16; i++) {
|
||||
lua_rawgeti(L, 3, i + 1);
|
||||
@ -1084,8 +995,8 @@ static int game_cphysics_get(lua_State *L) {
|
||||
} else if(!strcmp(k, "vel")) {
|
||||
lua_newtable(L);
|
||||
|
||||
dBodyID bid = dGeomGetBody(c->geom);
|
||||
if(bid) {
|
||||
dBodyID bid;
|
||||
if(c->geom && (bid = dGeomGetBody(c->geom))) {
|
||||
const float *v = dBodyGetLinearVel(bid);
|
||||
|
||||
lua_pushnumber(L, v[0]);
|
||||
@ -1196,7 +1107,7 @@ static int game_cboned_get(lua_State *L) {
|
||||
|
||||
const char *k = lua_tostring(L, 2);
|
||||
|
||||
if(!strcmp(k, "bones")) {
|
||||
/*if(!strcmp(k, "bones")) {
|
||||
lua_newtable(L);
|
||||
|
||||
for(size_t i = 0; i < c->size; i++) {
|
||||
@ -1231,6 +1142,13 @@ static int game_cboned_get(lua_State *L) {
|
||||
*c2 = c;
|
||||
luaL_setmetatable(L, "k3cbonedanim");
|
||||
|
||||
return 1;
|
||||
}*/
|
||||
|
||||
if(!strcmp(k, "animator")) {
|
||||
*(void**) lua_newuserdata(L, sizeof(struct k3Animator*)) = &c->animator;
|
||||
luaL_setmetatable(L, "k4animatorptr");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1242,7 +1160,7 @@ static int game_cboned_set(lua_State *L) {
|
||||
|
||||
const char *k = lua_tostring(L, 2);
|
||||
|
||||
if(!strcmp(k, "bones")) {
|
||||
/*if(!strcmp(k, "bones")) {
|
||||
size_t newlen = luaL_len(L, 3);
|
||||
|
||||
if(newlen != c->size) {
|
||||
@ -1276,7 +1194,7 @@ static int game_cboned_set(lua_State *L) {
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1284,14 +1202,14 @@ static int game_cboned_set(lua_State *L) {
|
||||
static int game_cbonedanim_set(lua_State *L) {
|
||||
struct CBoned *c = *(struct CBoned**) lua_touserdata(L, 1);
|
||||
|
||||
const char *k = lua_tostring(L, 2);
|
||||
/*const char *k = lua_tostring(L, 2);
|
||||
|
||||
if(!strcmp(k, "id")) {
|
||||
c->anim.id = lua_tointeger(L, 3);
|
||||
c->anim.cache.base = NULL;
|
||||
//c->anim.cache.base = NULL;
|
||||
} else if(!strcmp(k, "standard")) {
|
||||
c->anim.standard = lua_toboolean(L, 3);
|
||||
}
|
||||
}*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1413,13 +1331,47 @@ static int game_k3mdl_addmesh(lua_State *L) {
|
||||
k3MdlAddMesh(mdl, &mat, start, count);
|
||||
}
|
||||
|
||||
static int game_k3mdl_query_weights(lua_State *L) {
|
||||
struct k3Mdl *mdl = *(struct k3Mdl**) lua_touserdata(L, 1);
|
||||
|
||||
int qbone = k3MdlGetBoneFromName(mdl, lua_tostring(L, 2));
|
||||
if(qbone < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t bones = k3MdlGetBoneCount(mdl);
|
||||
|
||||
float w[bones];
|
||||
memset(w, 0, sizeof(*w) * bones);
|
||||
|
||||
k3MdlQueryWeights(mdl, qbone, w);
|
||||
|
||||
// Inclusive
|
||||
if(lua_toboolean(L, 3)) {
|
||||
w[qbone] = 1.0f;
|
||||
}
|
||||
|
||||
lua_newtable(L);
|
||||
for(size_t b = 0; b < bones; b++) {
|
||||
// Invert
|
||||
if(lua_toboolean(L, 4)) {
|
||||
w[b] = 1.0f - w[b];
|
||||
}
|
||||
|
||||
lua_pushnumber(L, w[b]);
|
||||
lua_rawseti(L, -2, b + 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int game_k3mdl_get(lua_State *L) {
|
||||
struct k3Mdl *mdl = *(struct k3Mdl**) lua_touserdata(L, 1);
|
||||
|
||||
if(lua_type(L, 2) == LUA_TNUMBER) {
|
||||
size_t count;
|
||||
struct k3Mesh *meshes = k3MdlGetMeshes(mdl, &count);
|
||||
|
||||
if(lua_type(L, 2) == LUA_TNUMBER) {
|
||||
lua_Integer i = lua_tointeger(L, 2);
|
||||
if(i >= 1 && i <= count) {
|
||||
struct k3Mat **m = lua_newuserdata(L, sizeof(*m));
|
||||
@ -1428,8 +1380,14 @@ static int game_k3mdl_get(lua_State *L) {
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
} else if(!strcmp(lua_tostring(L, 2), "addmesh")) {
|
||||
} else {
|
||||
const char *key = lua_tostring(L, 2);
|
||||
|
||||
if(!strcmp(key, "addmesh")) {
|
||||
lua_pushcfunction(L, game_k3mdl_addmesh);
|
||||
} else if(!strcmp(key, "query_weights")) {
|
||||
lua_pushcfunction(L, game_k3mdl_query_weights);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -2687,55 +2645,169 @@ static int dagame_kill(lua_State *L) {
|
||||
}
|
||||
|
||||
static int dagame_animator(lua_State *L) {
|
||||
struct Animator *this = lua_newuserdata(L, sizeof(*this));
|
||||
struct k3Animator *this = (*(void**) lua_newuserdata(L, sizeof(void*)) = calloc(1, sizeof(struct k3Animator)));
|
||||
|
||||
this->mdl = *(struct k3Mdl**) lua_touserdata(L, 1);
|
||||
memset(&this->animator, 0, sizeof(this->animator));
|
||||
|
||||
size_t boneCount = k3MdlGetBoneCount(this->mdl);
|
||||
this->bones = _mm_malloc(boneCount * sizeof(*this->bones), 16);
|
||||
for(size_t b = 0; b < boneCount; b++) {
|
||||
this->bones[b].translation[0] = 0;
|
||||
this->bones[b].translation[1] = 0;
|
||||
this->bones[b].translation[2] = 0;
|
||||
this->bones[b].translation[3] = 1;
|
||||
|
||||
this->bones[b].rotation[0] = 0;
|
||||
this->bones[b].rotation[1] = 0;
|
||||
this->bones[b].rotation[2] = 0;
|
||||
this->bones[b].rotation[3] = 1;
|
||||
}
|
||||
k3AnimatorInit(this, *(struct k3Mdl**) lua_touserdata(L, 1));
|
||||
|
||||
luaL_setmetatable(L, "k4animator");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct k3Animation *parse_animation_table(struct k3Animator *this) {
|
||||
enum k3AnimationOp op;
|
||||
|
||||
lua_getfield(L, -1, "type");
|
||||
if(!strcmp(lua_tostring(L, -1), "base")) {
|
||||
lua_pop(L, 1);
|
||||
op = k3_ANIM_BASIC;
|
||||
} else if(!strcmp(lua_tostring(L, -1), "blend")) {
|
||||
lua_pop(L, 1);
|
||||
op = k3_ANIM_BLEND;
|
||||
} else if(!strcmp(lua_tostring(L, -1), "add")) {
|
||||
lua_pop(L, 1);
|
||||
op = k3_ANIM_ADD;
|
||||
} else {
|
||||
lua_pop(L, 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(op == k3_ANIM_BASIC) {
|
||||
lua_getfield(L, -1, "id");
|
||||
size_t idx = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "loop");
|
||||
bool loop = lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
struct k3AnimationBasic *b = calloc(1, sizeof(*b));
|
||||
b->op = op;
|
||||
b->bones = k3MdlGetBoneCount(this->mdl);
|
||||
b->fountain = k3MdlGetAnim(this->mdl, idx);
|
||||
b->loop = loop;
|
||||
|
||||
if(!b->fountain) {
|
||||
k3Log(k3_ERR, "Base %lu does not exist", idx);
|
||||
}
|
||||
|
||||
return (struct k3Animation*) b;
|
||||
} else if(op == k3_ANIM_BLEND) {
|
||||
struct k3AnimationBlend *b = calloc(1, sizeof(*b));
|
||||
b->op = op;
|
||||
b->bones = k3MdlGetBoneCount(this->mdl);
|
||||
|
||||
lua_len(L, -1);
|
||||
b->children = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
b->subs = calloc(b->children, sizeof(*b->subs));
|
||||
b->weights = calloc(b->children * b->bones, sizeof(*b->weights));
|
||||
b->offsets = calloc(b->children, sizeof(*b->offsets));
|
||||
b->speeds = calloc(b->children, sizeof(*b->speeds));
|
||||
|
||||
for(size_t c = 0; c < b->children; c++) {
|
||||
lua_geti(L, -1, c + 1);
|
||||
lua_getfield(L, -1, "anim");
|
||||
b->subs[c] = parse_animation_table(this);
|
||||
if(!b->subs[c]) {
|
||||
k3Log(k3_WARN, "Invalid child %lu in animation blend", c);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
lua_getfield(L, -1, "w");
|
||||
if(lua_type(L, -1) == LUA_TNUMBER) {
|
||||
float f = lua_tonumber(L, -1);
|
||||
for(size_t i = 0; i < b->bones; i++) {
|
||||
b->weights[c * b->bones + i] = f;
|
||||
}
|
||||
} else if(lua_type(L, -1) == LUA_TTABLE) {
|
||||
for(size_t i = 0; i < b->bones; i++) {
|
||||
lua_geti(L, -1, i + 1);
|
||||
b->weights[c * b->bones + i] = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
} else {
|
||||
k3Log(k3_WARN, "Invalid weights in for child %lu", c);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
lua_getfield(L, -1, "speed");
|
||||
if(lua_type(L, -1) == LUA_TNUMBER) {
|
||||
b->speeds[c] = lua_tonumber(L, -1);
|
||||
} else {
|
||||
b->speeds[c] = 1;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
lua_getfield(L, -1, "offset");
|
||||
if(lua_type(L, -1) == LUA_TNUMBER) {
|
||||
b->offsets[c] = lua_tonumber(L, -1);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
return (struct k3Animation*) b;
|
||||
} else if(op == k3_ANIM_ADD) {
|
||||
struct k3AnimationAdd *a = calloc(1, sizeof(*a));
|
||||
a->op = op;
|
||||
a->bones = k3MdlGetBoneCount(this->mdl);
|
||||
|
||||
lua_geti(L, -1, 1);
|
||||
a->sub1 = parse_animation_table(this);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_geti(L, -1, 2);
|
||||
a->sub2 = parse_animation_table(this);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "scale");
|
||||
if(lua_type(L, -1) == LUA_TNUMBER) {
|
||||
a->scale = lua_tonumber(L, -1);
|
||||
} else {
|
||||
a->scale = 1;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
return (struct k3Animation*) a;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int dagame_animator_set(lua_State *L) {
|
||||
struct Animator *this = lua_touserdata(L, 1);
|
||||
struct k3Animator *this = *(void**) lua_touserdata(L, 1);
|
||||
|
||||
size_t animIdx = lua_tointeger(L, 2);
|
||||
|
||||
this->animator.base = k3MdlGetAnim(this->mdl, animIdx);
|
||||
this->animator.loop = false;
|
||||
k3AnimationFree(this->anim);
|
||||
this->anim = parse_animation_table(this);
|
||||
|
||||
this->playStartTime = glfwGetTime();
|
||||
k3AnimatorSet(&this->animator, 0);
|
||||
k3AnimatorSet(this, 0);
|
||||
|
||||
lua_pushvalue(L, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dagame_animator_play(lua_State *L) {
|
||||
struct Animator *this = lua_touserdata(L, 1);
|
||||
struct k3Animator *this = *(void**) lua_touserdata(L, 1);
|
||||
|
||||
this->playing = true;
|
||||
this->playStartTime = glfwGetTime();
|
||||
|
||||
lua_pushvalue(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dagame_animator_get(lua_State *L) {
|
||||
struct k3Animator *this = *(void**) lua_touserdata(L, 1);
|
||||
|
||||
*(void**) lua_newuserdata(L, sizeof(void*)) = this->anim;
|
||||
this->anim->ref++;
|
||||
luaL_setmetatable(L, "k3animation");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dagame_animator_index(lua_State *L) {
|
||||
struct Animator *this = lua_touserdata(L, 1);
|
||||
struct k3Animator *this = *(void**) lua_touserdata(L, 1);
|
||||
|
||||
const char *key = lua_tostring(L, 2);
|
||||
|
||||
@ -2745,11 +2817,49 @@ static int dagame_animator_index(lua_State *L) {
|
||||
} else if(!strcmp(key, "play")) {
|
||||
lua_pushcfunction(L, dagame_animator_play);
|
||||
return 1;
|
||||
} else if(!strcmp(key, "time")) {
|
||||
lua_pushnumber(L, this->animator.time);
|
||||
} else if(!strcmp(key, "get")) {
|
||||
lua_pushcfunction(L, dagame_animator_get);
|
||||
return 1;
|
||||
} else if(!strcmp(key, "loop")) {
|
||||
lua_pushboolean(L, this->animator.loop);
|
||||
} else if(!strcmp(key, "time")) {
|
||||
lua_pushnumber(L, this->time);
|
||||
return 1;
|
||||
} else if(!strcmp(key, "model")) {
|
||||
*(struct k3Mdl**) lua_newuserdata(L, sizeof(void*)) = this->mdl;
|
||||
luaL_setmetatable(L, "k3mdl");
|
||||
|
||||
return 1;
|
||||
} else if(!strcmp(key, "bones")) {
|
||||
size_t bones = k3MdlGetBoneCount(this->mdl);
|
||||
|
||||
lua_newtable(L);
|
||||
for(size_t i = 0; i < bones; i++) {
|
||||
lua_newtable(L);
|
||||
|
||||
lua_newtable(L);
|
||||
lua_pushnumber(L, this->bones[i].translation[0]);
|
||||
lua_pushnumber(L, this->bones[i].translation[1]);
|
||||
lua_pushnumber(L, this->bones[i].translation[2]);
|
||||
lua_pushnumber(L, this->bones[i].translation[3]);
|
||||
lua_rawseti(L, -5, 4);
|
||||
lua_rawseti(L, -4, 3);
|
||||
lua_rawseti(L, -3, 2);
|
||||
lua_rawseti(L, -2, 1);
|
||||
lua_setfield(L, -2, "translation");
|
||||
|
||||
lua_newtable(L);
|
||||
lua_pushnumber(L, this->bones[i].rotation[0]);
|
||||
lua_pushnumber(L, this->bones[i].rotation[1]);
|
||||
lua_pushnumber(L, this->bones[i].rotation[2]);
|
||||
lua_pushnumber(L, this->bones[i].rotation[3]);
|
||||
lua_rawseti(L, -5, 4);
|
||||
lua_rawseti(L, -4, 3);
|
||||
lua_rawseti(L, -3, 2);
|
||||
lua_rawseti(L, -2, 1);
|
||||
lua_setfield(L, -2, "rotation");
|
||||
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2757,14 +2867,197 @@ static int dagame_animator_index(lua_State *L) {
|
||||
}
|
||||
|
||||
static int dagame_animator_newindex(lua_State *L) {
|
||||
struct Animator *this = lua_touserdata(L, 1);
|
||||
struct k3Animator *this = *(void**) lua_touserdata(L, 1);
|
||||
|
||||
const char *key = lua_tostring(L, 2);
|
||||
|
||||
if(!strcmp(key, "time")) {
|
||||
k3AnimatorSet(&this->animator, lua_tonumber(L, 3));
|
||||
k3AnimatorSet(this, lua_tonumber(L, 3));
|
||||
} else if(!strcmp(key, "loop")) {
|
||||
this->animator.loop = lua_toboolean(L, 3);
|
||||
//this->animator.loop = lua_toboolean(L, 3);
|
||||
} else if(!strcmp(key, "bones")) {
|
||||
size_t bones = k3MdlGetBoneCount(this->mdl);
|
||||
|
||||
for(size_t i = 0; i < bones; i++) {
|
||||
lua_rawgeti(L, 3, i + 1);
|
||||
|
||||
lua_getfield(L, -1, "translation");
|
||||
lua_rawgeti(L, -1, 1);
|
||||
lua_rawgeti(L, -2, 2);
|
||||
lua_rawgeti(L, -3, 3);
|
||||
lua_rawgeti(L, -4, 4);
|
||||
this->bones[i].translation[0] = lua_tonumber(L, -4);
|
||||
this->bones[i].translation[1] = lua_tonumber(L, -3);
|
||||
this->bones[i].translation[2] = lua_tonumber(L, -2);
|
||||
this->bones[i].translation[3] = lua_tonumber(L, -1);
|
||||
lua_pop(L, 5);
|
||||
|
||||
lua_getfield(L, -1, "rotation");
|
||||
lua_rawgeti(L, -1, 1);
|
||||
lua_rawgeti(L, -2, 2);
|
||||
lua_rawgeti(L, -3, 3);
|
||||
lua_rawgeti(L, -4, 4);
|
||||
this->bones[i].rotation[0] = lua_tonumber(L, -4);
|
||||
this->bones[i].rotation[1] = lua_tonumber(L, -3);
|
||||
this->bones[i].rotation[2] = lua_tonumber(L, -2);
|
||||
this->bones[i].rotation[3] = lua_tonumber(L, -1);
|
||||
lua_pop(L, 5);
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dagame_animator_gc(lua_State *L) {
|
||||
struct k3Animator *this = *(void**) lua_touserdata(L, 1);
|
||||
|
||||
k3AnimationFree(this->anim);
|
||||
free(this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct AnimBlendSub {
|
||||
struct k3AnimationBlend *blend;
|
||||
size_t c;
|
||||
};
|
||||
|
||||
static int dagame_animation_index(lua_State *L) {
|
||||
struct k3Animation *anim = *(void**) lua_touserdata(L, 1);
|
||||
|
||||
const char *key = NULL;
|
||||
size_t keyi = 0;
|
||||
|
||||
if(lua_type(L, 2) == LUA_TNUMBER) {
|
||||
keyi = lua_tointeger(L, 2);
|
||||
} else {
|
||||
key = lua_tostring(L, 2);
|
||||
}
|
||||
|
||||
if(key && !strcmp(key, "type")) {
|
||||
|
||||
switch(anim->op) {
|
||||
case k3_ANIM_BASIC:
|
||||
lua_pushstring(L, "base");
|
||||
break;
|
||||
case k3_ANIM_BLEND:
|
||||
lua_pushstring(L, "blend");
|
||||
break;
|
||||
case k3_ANIM_ADD:
|
||||
lua_pushstring(L, "add");
|
||||
break;
|
||||
default:
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
if(anim->op == k3_ANIM_BASIC) {
|
||||
struct k3AnimationBasic *basic = (void*) anim;
|
||||
|
||||
if(key && !strcmp(key, "loop")) {
|
||||
lua_pushboolean(L, basic->loop);
|
||||
return 1;
|
||||
}
|
||||
} else if(anim->op == k3_ANIM_BLEND) {
|
||||
struct k3AnimationBlend *blend = (void*) anim;
|
||||
|
||||
if(keyi == 0 || keyi > blend->children) {
|
||||
lua_pushnil(L);
|
||||
} else {
|
||||
struct AnimBlendSub *i = lua_newuserdata(L, sizeof(*i));
|
||||
i->blend = blend;
|
||||
i->blend->ref++;
|
||||
i->c = keyi;
|
||||
luaL_setmetatable(L, "k3animationblendsub");
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else if(anim->op == k3_ANIM_ADD) {
|
||||
struct k3AnimationAdd *add = (void*) anim;
|
||||
|
||||
if(key && !strcmp(key, "scale")) {
|
||||
lua_pushnumber(L, add->scale);
|
||||
} else if(keyi == 1 || keyi == 2) {
|
||||
struct k3Animation** s = lua_newuserdata(L, sizeof(*s));
|
||||
*s = keyi == 1 ? add->sub1 : add->sub2;
|
||||
(*s)->ref++;
|
||||
luaL_setmetatable(L, "k3animation");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dagame_animation_gc(lua_State *L) {
|
||||
struct k3Animation *anim = *(void**) lua_touserdata(L, 1);
|
||||
|
||||
k3AnimationFree(anim);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dagame_animationblendsub_index(lua_State *L) {
|
||||
struct AnimBlendSub *i = lua_touserdata(L, 1);
|
||||
|
||||
const char *key = lua_tostring(L, 2);
|
||||
|
||||
if(!strcmp(key, "anim")) {
|
||||
*(void**) lua_newuserdata(L, sizeof(void*)) = i->blend->subs[i->c - 1];
|
||||
i->blend->subs[i->c - 1]->ref++;
|
||||
luaL_setmetatable(L, "k3animation");
|
||||
return 1;
|
||||
} else if(!strcmp(key, "w")) {
|
||||
lua_newtable(L);
|
||||
for(size_t b = 0; b < i->blend->bones; b++) {
|
||||
lua_pushnumber(L, i->blend->weights[i->blend->bones * (i->c - 1) + b]);
|
||||
lua_rawseti(L, -2, b + 1);
|
||||
}
|
||||
return 1;
|
||||
} else if(!strcmp(key, "speed")) {
|
||||
lua_pushnumber(L, i->blend->speeds[i->c - 1]);
|
||||
return 1;
|
||||
} else if(!strcmp(key, "offset")) {
|
||||
lua_pushnumber(L, i->blend->offsets[i->c - 1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dagame_animationblendsub_newindex(lua_State *L) {
|
||||
struct AnimBlendSub *i = lua_touserdata(L, 1);
|
||||
|
||||
const char *key = lua_tostring(L, 2);
|
||||
|
||||
if(!strcmp(key, "anim")) {
|
||||
return luaL_error(L, "Setting anim field is unsupported.");
|
||||
} else if(!strcmp(key, "w")) {
|
||||
if(lua_type(L, 3) == LUA_TNUMBER) {
|
||||
float val = lua_tonumber(L, 3);
|
||||
for(size_t b = 0; b < i->blend->bones; b++) {
|
||||
i->blend->weights[i->blend->bones * (i->c - 1) + b] = val;
|
||||
}
|
||||
} else if(lua_type(L, 3) == LUA_TTABLE) {
|
||||
for(size_t b = 0; b < i->blend->bones; b++) {
|
||||
lua_rawgeti(L, 3, b + 1);
|
||||
i->blend->weights[i->blend->bones * (i->c - 1) + b] = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
} else {
|
||||
return luaL_error(L, "w field may be either number or table or numbers.");
|
||||
}
|
||||
} else if(!strcmp(key, "speed")) {
|
||||
i->blend->speeds[i->c - 1] = lua_tonumber(L, 3);
|
||||
} else if(!strcmp(key, "offset")) {
|
||||
i->blend->offsets[i->c - 1] = lua_tonumber(L, 3);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -3209,9 +3502,45 @@ void luaapi_init() {
|
||||
lua_pushcfunction(L, dagame_animator_newindex);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushcfunction(L, dagame_animator_gc);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
lua_pushboolean(L, 0);
|
||||
lua_setfield(L, -2, "__metatable");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, "k4animatorptr");
|
||||
lua_pushcfunction(L, dagame_animator_index);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, dagame_animator_newindex);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushboolean(L, 0);
|
||||
lua_setfield(L, -2, "__metatable");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, "k3animation");
|
||||
lua_pushcfunction(L, dagame_animation_index);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, dagame_animation_gc);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
lua_pushboolean(L, 0);
|
||||
lua_setfield(L, -2, "__metatable");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, "k3animationblendsub");
|
||||
lua_pushcfunction(L, dagame_animationblendsub_index);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, dagame_animationblendsub_newindex);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushcfunction(L, dagame_animation_gc);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
void luaapi_load(const char *name) {
|
||||
|
@ -590,7 +590,11 @@ int main(int argc_, char **argv_) {
|
||||
if(c->cache) {
|
||||
struct CBoned *b = game_getcomponent(c->entity, boned);
|
||||
|
||||
k3Batch(c->cache, transform, b ? b->bones : NULL);
|
||||
if(b && b->animator.anim) {
|
||||
k3AnimatorStep(&b->animator, dt);
|
||||
}
|
||||
|
||||
k3Batch(c->cache, transform, b ? b->animator.bones : NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ static void interpret_pkt(ENetPacket *pkt) {
|
||||
c->holding = b_ru16(&b);
|
||||
} if(ctype == CMD_CTYPE_BONED) {
|
||||
struct CBoned *c = game_ensurecomponent(ent, boned);
|
||||
c->anim.standard = b_ru8(&b);
|
||||
/*c->anim.standard =*/ b_ru8(&b);
|
||||
}
|
||||
} else if(cmd == CMD_SC_POSUPDATE) {
|
||||
uint16_t lastOurTick = b_ru16(&b);
|
||||
|
@ -121,7 +121,7 @@ static void send_full_state(ENetPeer **peers, size_t peerCount) {
|
||||
|
||||
b_wu16(&b, c->entity);
|
||||
|
||||
b_wu8(&b, c->anim.standard);
|
||||
b_wu8(&b, 0/*c->anim.standard*/);
|
||||
}
|
||||
|
||||
if(peers) {
|
||||
|
Loading…
Reference in New Issue
Block a user