mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-07 14:28:12 +03:00
+4
-2
@@ -17,7 +17,6 @@
|
||||
#ifndef SYSTEM4_REIGN_H
|
||||
#define SYSTEM4_REIGN_H
|
||||
|
||||
#define RE_MAX_INSTANCES 32
|
||||
#define RE_NR_BACK_CGS 16
|
||||
|
||||
#include <cglm/types.h>
|
||||
@@ -66,7 +65,8 @@ struct RE_back_cg {
|
||||
struct RE_plugin {
|
||||
struct draw_plugin plugin;
|
||||
int sprite;
|
||||
struct RE_instance *instances[RE_MAX_INSTANCES];
|
||||
int nr_instances;
|
||||
struct RE_instance **instances;
|
||||
struct archive *aar;
|
||||
struct RE_renderer *renderer;
|
||||
struct RE_camera camera;
|
||||
@@ -142,6 +142,8 @@ bool RE_instance_load_motion(struct RE_instance *instance, const char *name);
|
||||
bool RE_instance_load_next_motion(struct RE_instance *instance, const char *name);
|
||||
bool RE_instance_free_next_motion(struct RE_instance *instance);
|
||||
bool RE_instance_set_vertex_pos(struct RE_instance *instance, int index, float x, float y, float z);
|
||||
int RE_instance_get_bone_index(struct RE_instance *instance, const char *name);
|
||||
bool RE_instance_trans_local_pos_to_world_pos_by_bone(struct RE_instance *instance, int bone, vec3 offset, vec3 out);
|
||||
|
||||
int RE_motion_get_state(struct motion *motion);
|
||||
bool RE_motion_set_state(struct motion *motion, int state);
|
||||
|
||||
@@ -121,6 +121,10 @@ struct billboard_texture {
|
||||
GLuint texture;
|
||||
};
|
||||
|
||||
// reign.c
|
||||
|
||||
void RE_instance_update_local_transform(struct RE_instance *inst);
|
||||
|
||||
// model.c
|
||||
|
||||
struct model *model_load(struct archive *aar, const char *path, struct RE_renderer *renderer);
|
||||
|
||||
+1
-1
@@ -120,7 +120,7 @@ void RE_debug_print(struct sact_sprite *sp, int indent)
|
||||
indent_printf(indent, "camera = {x=%f, y=%f, z=%f, pitch=%f, roll=%f, yaw=%f},\n",
|
||||
SPREAD_VEC3(p->camera.pos), p->camera.pitch, p->camera.roll, p->camera.yaw);
|
||||
|
||||
for (int i = 0; i < RE_MAX_INSTANCES; i++)
|
||||
for (int i = 0; i < p->nr_instances; i++)
|
||||
print_instance(p->instances[i], i, indent);
|
||||
|
||||
for (int i = 0; i < RE_NR_BACK_CGS; i++)
|
||||
|
||||
+57
-7
@@ -173,6 +173,8 @@ struct RE_plugin *RE_plugin_new(void)
|
||||
plugin->plugin.name = "ReignEngine";
|
||||
plugin->plugin.update = RE_render;
|
||||
plugin->plugin.debug_print = RE_debug_print;
|
||||
plugin->nr_instances = 16;
|
||||
plugin->instances = xcalloc(plugin->nr_instances, sizeof(struct RE_instance *));
|
||||
plugin->aar = aar;
|
||||
for (int i = 0; i < RE_NR_BACK_CGS; i++)
|
||||
RE_back_cg_init(&plugin->back_cg[i]);
|
||||
@@ -181,10 +183,11 @@ struct RE_plugin *RE_plugin_new(void)
|
||||
|
||||
void RE_plugin_free(struct RE_plugin *plugin)
|
||||
{
|
||||
for (int i = 0; i < RE_MAX_INSTANCES; i++) {
|
||||
for (int i = 0; i < plugin->nr_instances; i++) {
|
||||
if (plugin->instances[i])
|
||||
free_instance(plugin->instances[i]);
|
||||
}
|
||||
free(plugin->instances);
|
||||
archive_free(plugin->aar);
|
||||
if (plugin->renderer)
|
||||
RE_renderer_free(plugin->renderer);
|
||||
@@ -221,10 +224,8 @@ bool RE_build_model(struct RE_plugin *plugin, int elapsed_ms)
|
||||
{
|
||||
if (!plugin)
|
||||
return false;
|
||||
if (elapsed_ms <= 0)
|
||||
return true;
|
||||
|
||||
for (int i = 0; i < RE_MAX_INSTANCES; i++) {
|
||||
for (int i = 0; i < plugin->nr_instances; i++) {
|
||||
if (plugin->instances[i])
|
||||
animate(plugin->instances[i], elapsed_ms);
|
||||
}
|
||||
@@ -243,14 +244,17 @@ int RE_create_instance(struct RE_plugin *plugin)
|
||||
{
|
||||
if (!plugin)
|
||||
return -1;
|
||||
for (int i = 0; i < RE_MAX_INSTANCES; i++) {
|
||||
for (int i = 0; i < plugin->nr_instances; i++) {
|
||||
if (!plugin->instances[i]) {
|
||||
plugin->instances[i] = create_instance(plugin);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
WARNING("too many instances");
|
||||
return -1;
|
||||
int old_size = plugin->nr_instances;
|
||||
plugin->nr_instances *= 2;
|
||||
plugin->instances = xrealloc_array(plugin->instances, old_size, plugin->nr_instances, sizeof(struct RE_instance *));
|
||||
plugin->instances[old_size] = create_instance(plugin);
|
||||
return old_size;
|
||||
}
|
||||
|
||||
bool RE_release_instance(struct RE_plugin *plugin, int instance)
|
||||
@@ -346,6 +350,52 @@ bool RE_instance_set_vertex_pos(struct RE_instance *instance, int index, float x
|
||||
return false;
|
||||
}
|
||||
|
||||
int RE_instance_get_bone_index(struct RE_instance *instance, const char *name)
|
||||
{
|
||||
if (!instance || !instance->model)
|
||||
return -1;
|
||||
for (int i = 0; i < instance->model->nr_bones; i++) {
|
||||
if (!strcmp(instance->model->bones[i].name, name))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool RE_instance_trans_local_pos_to_world_pos_by_bone(struct RE_instance *instance, int bone, vec3 offset, vec3 out)
|
||||
{
|
||||
if (!instance || !instance->bone_transforms || (unsigned)bone >= (unsigned)instance->model->nr_bones)
|
||||
return false;
|
||||
|
||||
if (instance->local_transform_needs_update)
|
||||
RE_instance_update_local_transform(instance);
|
||||
|
||||
glm_mat4_mulv3(instance->bone_transforms[bone], offset, 1.0, out);
|
||||
glm_mat4_mulv3(instance->local_transform, out, 1.0, out);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RE_instance_update_local_transform(struct RE_instance *inst)
|
||||
{
|
||||
vec3 euler = {
|
||||
glm_rad(inst->pitch),
|
||||
glm_rad(inst->yaw),
|
||||
glm_rad(inst->roll)
|
||||
};
|
||||
mat4 rot;
|
||||
glm_euler(euler, rot);
|
||||
|
||||
glm_translate_make(inst->local_transform, inst->pos);
|
||||
glm_mat4_mul(inst->local_transform, rot, inst->local_transform);
|
||||
glm_scale(inst->local_transform, inst->scale);
|
||||
|
||||
mat3 normal;
|
||||
glm_mat4_pick3(inst->local_transform, normal);
|
||||
glm_mat3_inv(normal, normal);
|
||||
glm_mat3_transpose_to(normal, inst->normal_transform);
|
||||
|
||||
inst->local_transform_needs_update = false;
|
||||
}
|
||||
|
||||
int RE_motion_get_state(struct motion *motion)
|
||||
{
|
||||
return motion ? motion->state : RE_MOTION_STATE_STOP;
|
||||
|
||||
+3
-25
@@ -175,28 +175,6 @@ static void calc_view_matrix(struct RE_camera *camera, mat4 out)
|
||||
glm_look(camera->pos, front, up, out);
|
||||
}
|
||||
|
||||
static void update_local_transform(struct RE_instance *inst)
|
||||
{
|
||||
vec3 euler = {
|
||||
glm_rad(inst->pitch),
|
||||
glm_rad(inst->yaw),
|
||||
glm_rad(inst->roll)
|
||||
};
|
||||
mat4 rot;
|
||||
glm_euler(euler, rot);
|
||||
|
||||
glm_translate_make(inst->local_transform, inst->pos);
|
||||
glm_mat4_mul(inst->local_transform, rot, inst->local_transform);
|
||||
glm_scale(inst->local_transform, inst->scale);
|
||||
|
||||
mat3 normal;
|
||||
glm_mat4_pick3(inst->local_transform, normal);
|
||||
glm_mat3_inv(normal, normal);
|
||||
glm_mat3_transpose_to(normal, inst->normal_transform);
|
||||
|
||||
inst->local_transform_needs_update = false;
|
||||
}
|
||||
|
||||
static void render_model(struct RE_instance *inst, struct RE_renderer *r)
|
||||
{
|
||||
struct model *model = inst->model;
|
||||
@@ -204,7 +182,7 @@ static void render_model(struct RE_instance *inst, struct RE_renderer *r)
|
||||
return;
|
||||
|
||||
if (inst->local_transform_needs_update)
|
||||
update_local_transform(inst);
|
||||
RE_instance_update_local_transform(inst);
|
||||
|
||||
glUniformMatrix4fv(r->local_transform, 1, GL_FALSE, inst->local_transform[0]);
|
||||
glUniformMatrix3fv(r->normal_transform, 1, GL_FALSE, inst->normal_transform[0]);
|
||||
@@ -343,7 +321,7 @@ static void setup_lights(struct RE_plugin *plugin)
|
||||
struct RE_renderer *r = plugin->renderer;
|
||||
glUniform3fv(r->view_pos, 1, plugin->camera.pos);
|
||||
int light_index = 0;
|
||||
for (int i = 0; i < RE_MAX_INSTANCES; i++) {
|
||||
for (int i = 0; i < plugin->nr_instances; i++) {
|
||||
struct RE_instance *inst = plugin->instances[i];
|
||||
if (!inst)
|
||||
continue;
|
||||
@@ -419,7 +397,7 @@ void RE_render(struct sact_sprite *sp)
|
||||
|
||||
setup_lights(plugin);
|
||||
|
||||
for (int i = 0; i < RE_MAX_INSTANCES; i++) {
|
||||
for (int i = 0; i < plugin->nr_instances; i++) {
|
||||
struct RE_instance *inst = plugin->instances[i];
|
||||
if (!inst || !inst->draw)
|
||||
continue;
|
||||
|
||||
+17
-3
@@ -40,7 +40,7 @@ static struct RE_instance *get_instance(unsigned plugin, unsigned instance)
|
||||
struct RE_plugin *rp = get_plugin(plugin);
|
||||
if (!rp)
|
||||
return NULL;
|
||||
return instance < RE_MAX_INSTANCES ? rp->instances[instance] : NULL;
|
||||
return instance < (unsigned)rp->nr_instances ? rp->instances[instance] : NULL;
|
||||
}
|
||||
|
||||
static struct motion *get_motion(unsigned plugin, unsigned instance)
|
||||
@@ -463,8 +463,22 @@ static bool ReignEngine_SetInstanceFPS(int plugin, int instance, float fps)
|
||||
return true;
|
||||
}
|
||||
|
||||
HLL_WARN_UNIMPLEMENTED(0, int, ReignEngine, GetInstanceBoneIndex, int plugin, int instance, struct string *name);
|
||||
HLL_WARN_UNIMPLEMENTED(false, bool, ReignEngine, TransInstanceLocalPosToWorldPosByBone, int plugin, int instance, int bone, float offset_x, float offset_y, float offset_z, float *x, float *y, float *z);
|
||||
static int ReignEngine_GetInstanceBoneIndex(int plugin, int instance, struct string *name)
|
||||
{
|
||||
return RE_instance_get_bone_index(get_instance(plugin, instance), name->text);
|
||||
}
|
||||
|
||||
static bool ReignEngine_TransInstanceLocalPosToWorldPosByBone(int plugin, int instance, int bone, float offset_x, float offset_y, float offset_z, float *x, float *y, float *z)
|
||||
{
|
||||
vec3 offset = {offset_x, offset_y, -offset_z}, result;
|
||||
if (!RE_instance_trans_local_pos_to_world_pos_by_bone(get_instance(plugin, instance), bone, offset, result))
|
||||
return false;
|
||||
*x = result[0];
|
||||
*y = result[1];
|
||||
*z = -result[2];
|
||||
return true;
|
||||
}
|
||||
|
||||
//int ReignEngine_GetInstanceNumofPolygon(int plugin, int instance);
|
||||
//int ReignEngine_GetInstanceTextureMemorySize(int plugin, int instance);
|
||||
//void ReignEngine_GetInstanceInfoText(int plugin, int instance, struct string **pIText);
|
||||
|
||||
Reference in New Issue
Block a user