static int lgetwpos(lua_State *L) { struct sprite *s = self(L); if (s->type == TYPE_ANCHOR) { struct matrix* mat = s->s.mat; lua_pushnumber(L,mat->m[4] /(float)SCREEN_SCALE); lua_pushnumber(L,mat->m[5] /(float)SCREEN_SCALE); return 2; } else { struct srt srt; fill_srt(L,&srt,2); struct matrix tmp; sprite_matrix(s, &tmp); int pos[2]; if (sprite_pos(s, &srt, &tmp, pos) == 0) { lua_pushinteger(L, pos[0]); lua_pushinteger(L, pos[1]); return 2; } else { return 0; } } return luaL_error(L, "Only anchor can get world matrix"); }
static int lcalc_matrix(lua_State *L) { struct sprite * s = self(L); struct matrix * mat = (struct matrix *)lua_touserdata(L, 2); if (mat == NULL) { return luaL_argerror(L, 2, "need a matrix"); } struct matrix *local_matrix = s->t.mat; if (local_matrix) { struct matrix tmp; sprite_matrix(s, &tmp); matrix_mul(mat, local_matrix, &tmp); } else { sprite_matrix(s, mat); } lua_settop(L, 2); return 1; }
void sprite_matrix(struct sprite * self, struct matrix *mat) { struct sprite * parent = self->parent; if (parent) { assert(parent->type == TYPE_ANIMATION); sprite_matrix(parent, mat); struct matrix tmp; struct matrix * parent_mat = parent->t.mat; struct matrix * child_mat = NULL; struct pack_animation *ani = parent->s.ani; int frame = real_frame(parent) + parent->start_frame; struct pack_frame * pf = &ani->frame[frame]; int i; for (i=0;i<pf->n;i++) { struct pack_part *pp = &pf->part[i]; int index = pp->component_id; struct sprite * child = parent->data.children[index]; if (child == self) { child_mat = pp->t.mat; break; } } if (parent_mat == NULL && child_mat == NULL) return; if (parent_mat) { matrix_mul(&tmp, parent_mat, mat); } else { tmp = *mat; } if (child_mat) { matrix_mul(mat, child_mat, &tmp); } else { *mat = tmp; } } else { matrix_identity(mat); } }
void sprite_aabb(struct sprite *s, struct srt *srt, bool world_aabb, int aabb[4]) { int i; if (s->visible) { struct matrix tmp; if (world_aabb) { sprite_matrix(s, &tmp); } else { matrix_identity(&tmp); } aabb[0] = INT_MAX; aabb[1] = INT_MAX; aabb[2] = INT_MIN; aabb[3] = INT_MIN; child_aabb(s,srt,&tmp,aabb); for (i=0;i<4;i++) aabb[i] /= SCREEN_SCALE; } else { for (i=0;i<4;i++) aabb[i] = 0; } }