|
|
|
|
@@ -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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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_type(L, 4) == LUA_TUSERDATA) {
|
|
|
|
|
struct k3Animator *animator = *(void**) lua_touserdata(L, 4);
|
|
|
|
|
if(animator->playing) {
|
|
|
|
|
k3AnimatorSet(animator, glfwGetTime() - animator->playStartTime);
|
|
|
|
|
}
|
|
|
|
|
bones = animator->bones;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
size_t count;
|
|
|
|
|
struct k3Mesh *meshes = k3MdlGetMeshes(mdl, &count);
|
|
|
|
|
|
|
|
|
|
if(lua_type(L, 2) == LUA_TNUMBER) {
|
|
|
|
|
size_t count;
|
|
|
|
|
struct k3Mesh *meshes = k3MdlGetMeshes(mdl, &count);
|
|
|
|
|
|
|
|
|
|
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")) {
|
|
|
|
|
lua_pushcfunction(L, game_k3mdl_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) {
|
|
|
|
|
|