commit 33051a9b86fb62ab292f5dff5cce17c5268dea9c
parent 089461edd69dcef733ef1c09c9c14a339bbff5a2
Author: William Casarin <jb55@jb55.com>
Date: Fri, 5 Jul 2019 16:45:53 -0700
I dont care anymore
Diffstat:
20 files changed, 165 insertions(+), 33 deletions(-)
diff --git a/src/animation.c b/src/animation.c
@@ -3,14 +3,17 @@
#include "xml.h"
#include "util.h"
#include "node.h"
+#include "debug.h"
#include "animation.h"
enum dae_state {
PARSING_START,
PARSING_NODE,
+ PARSING_FLOAT_ARRAY,
PARSING_POSE,
PARSING_JOINT,
PARSING_JOINT_MATRIX,
+ PARSING_WEIGHTS,
};
struct dae_data {
@@ -19,6 +22,8 @@ struct dae_data {
FILE *dae_file;
struct pose *poses;
int *nposes;
+ float *weights;
+ int nweights;
char current_name[JOINT_LABEL_SIZE];
};
@@ -68,10 +73,16 @@ static void dae_tag_start(struct xmlparser *x, const char *t, size_t tl)
{
struct dae_data *data = (struct dae_data*)x->user_data;
+ debug("state %d tag_start %.*s\n", data->state, (int)tl, t);
+
if (streq(t, "node")) {
data->state = PARSING_NODE;
data->node_level++;
}
+ else if (streq(t, "float_array")) {
+ debug("-> PARSING_FLOAT_ARRAY\n");
+ data->state = PARSING_FLOAT_ARRAY;
+ }
else if (data->state == PARSING_JOINT && streq(t, "matrix"))
data->state = PARSING_JOINT_MATRIX;
else
@@ -100,11 +111,12 @@ static void dae_tagbody(struct xmlparser *x, const char *d, size_t dl)
{
static int count = 0;
struct dae_data *data = (struct dae_data*)x->user_data;
+ struct pose *pose;
if (data->state == PARSING_JOINT_MATRIX) {
assert(*data->nposes);
- struct pose *pose = &data->poses[*data->nposes - 1];
+ pose = &data->poses[*data->nposes - 1];
assert(pose);
struct joint *joint = &pose->joints[pose->njoints];
@@ -122,6 +134,32 @@ static void dae_tagbody(struct xmlparser *x, const char *d, size_t dl)
pose->njoints++;
data->state = PARSING_POSE;
}
+ else if (data->state == PARSING_WEIGHTS) {
+ pose = &data->poses[*data->nposes];
+ assert(data->nweights > 0);
+ data->weights = calloc(data->nweights, sizeof(float));
+
+ const char *p = d;
+ float val;
+ int i;
+
+ for (i = 0; i < data->nweights; i++) {
+ sscanf(p, "%f", &val);
+ data->weights[i] = val;
+
+ while (p < d+dl) {
+ if (*(p++) == ' ')
+ break;
+ }
+ }
+
+ assert(data->nweights == i);
+
+ pose->nweights = data->nweights;
+ pose->weights = data->weights;
+
+ data->state = PARSING_POSE;
+ }
}
static int dae_getc(struct xmlparser *x)
@@ -137,21 +175,30 @@ void dae_attr(struct xmlparser *x, const char *t, size_t tl,
if (data->state == PARSING_NODE
&& streq(a, "id")
- && streq(v, "Armature"))
- {
+ && streq(v, "Armature")) {
+
struct pose *pose = &data->poses[(*data->nposes)++];
data->state = PARSING_POSE;
init_pose(pose);
}
+ else if (data->state == PARSING_FLOAT_ARRAY
+ && streq(a, "id")
+ && contains(v, "skin-weights-array")) {
+ debug("PARSING_SOURCE -> PARSING_WEIGHTS_START\n");
+ data->state = PARSING_WEIGHTS;
+ }
+ else if (data->state == PARSING_WEIGHTS
+ && streq(a, "count")) {
+ data->nweights = atoi(v);
+ }
else if (data->state == PARSING_NODE
- && streq(a, "name"))
- {
+ && streq(a, "name")) {
strncpy(data->current_name, v, sizeof(data->current_name));
}
else if (data->state == PARSING_NODE
&& streq(a, "type")
- && streq(v, "JOINT"))
- {
+ && streq(v, "JOINT")) {
+
data->state = PARSING_JOINT;
}
}
@@ -190,6 +237,8 @@ void load_poses(const char *filename, struct pose *poses, int *nposes)
.state = PARSING_START,
.poses = poses,
.nposes = nposes,
+ .nweights = -1,
+ .weights = NULL
};
data.dae_file = fopen("data/models/pirate-officer.dae", "rb");
diff --git a/src/animation.h b/src/animation.h
@@ -21,6 +21,8 @@ struct joint
struct pose
{
struct joint joints[MAX_JOINTS];
+ float *weights;
+ int nweights;
int njoints;
};
diff --git a/src/game.c b/src/game.c
@@ -86,9 +86,9 @@ void game_init(struct game *game, int width, int height) {
init_sdl(&game->window, width, height);
init_gl(&game->test_resources, width, height);
init_entity_system();
+ init_geometry_manager();
init_model_manager();
init_node_manager();
- init_geometry_manager();
init_user_settings(&game->user_settings);
check_gl();
@@ -175,13 +175,14 @@ void game_init(struct game *game, int width, int height) {
player = &static_entities()[entity_player];
struct node *pnode = &static_nodes()[node_player];
assert(pnode);
+ res->player_id = make_static_id(entity_player);
assert(res->player_id.index == entity_player);
/* player->model_id = get_static_model(model_pirate_officer, NULL); */
- struct model *pmodel = new_model(&player->model_id); assert(pmodel);
- struct geometry *geom = get_geometry(&pmodel->geom_id); assert(geom);
+ struct model *pmodel;
+ player->model_id = get_static_model(model_pirate_officer, &pmodel);
+ print_id(&player->model_id, true);
- proc_sphere(geom);
pmodel->shading = SHADING_VERT_COLOR;
node_set_label(pnode, "player");
diff --git a/src/geometry.c b/src/geometry.c
@@ -6,7 +6,7 @@
#include "static_resources.h"
#include <assert.h>
-static struct resource_manager geom_manager;
+struct resource_manager geom_manager;
void
destroy_buffer_geometry(geometry_id *geom_id) {
@@ -172,10 +172,15 @@ void geometry_centroid(struct geometry *geom, float *dest) {
vec3_scale(dest, 0.5, dest);
};
+
void init_geometry_manager() {
init_resource_manager(&geom_manager, sizeof(struct geometry),
DEF_NUM_GEOMETRY, MAX_GEOMETRY, "geometry",
NUM_STATIC_MODELS);
+
+ for (int i = 0; i < NUM_STATIC_MODELS; i++) {
+ init_geometry(&static_geometry()[i]);
+ }
}
struct geometry *get_geometry(geometry_id *geom_id) {
diff --git a/src/geometry.h b/src/geometry.h
@@ -59,5 +59,13 @@ struct geometry *new_geometry(geometry_id *);
struct geometry *get_geometry(geometry_id *);
struct geometry *get_all_geometry(u32 *count, geometry_id **ids);
void destroy_geometry(geometry_id *geom_id);
+struct resource_manager *get_geometry_manager();
+
+extern struct resource_manager geom_manager;
+
+static inline struct geometry *static_geometry()
+{
+ return (struct geometry *)geom_manager.resources;
+}
#endif /* GEOMETRY_H */
diff --git a/src/input.c b/src/input.c
@@ -82,9 +82,9 @@ void process_events(struct input *input, u64 current_frame) {
}
- if (input->resized_width)
- printf("checking resize %d %d\n", input->resized_width,
- input->resized_height);
+ /* if (input->resized_width) */
+ /* printf("checking resize %d %d\n", input->resized_width, */
+ /* input->resized_height); */
}
diff --git a/src/main.c b/src/main.c
@@ -68,8 +68,8 @@ int main(void)
game.frame++;
process_events(&game.input, game.frame);
if (game.input.resized_height) {
- printf("handling resize %d %d\n", game.input.resized_width,
- game.input.resized_height);
+ /* printf("handling resize %d %d\n", game.input.resized_width, */
+ /* game.input.resized_height); */
handle_resize(&game, game.input.resized_width, game.input.resized_height);
}
//default_config.camera = game.test_resources.camera_node->mat;
diff --git a/src/model.c b/src/model.c
@@ -76,15 +76,26 @@ static struct model *load_static_model(enum static_model m)
static char path[128] = {0};
struct model *model = &static_models()[m];
+ struct geometry *geom = &static_geometry()[m];
+ init_geometry(geom);
+ model->geom_id = make_static_id(m);
- if (is_id_allocated(&model->geom_id) && get_geometry(&model->geom_id))
+ if (get_geometry(&model->geom_id)->has_vbos) {
+ debug("model %s already loaded\n", static_model_defs[m].file);
return model;
+ }
int ok = 0;
// Load mesh
+ debug("loading %s model with geom_id ", static_model_defs[m].file);
+
+ print_id(&model->geom_id, true);
+ assert(m < NUM_STATIC_MODELS);
snprintf(path, 128, "data/models/%s.ply", static_model_defs[m].file);
- ok = parse_ply(path, &model->geom_id);
+ ok = parse_ply(path, geom);
+ if (m == model_pirate_officer)
+ printf("num_verts: %d\n", geom->num_verts);
if (!ok)
return 0;
diff --git a/src/node.c b/src/node.c
@@ -43,6 +43,9 @@ void init_node_manager()
{
init_resource_manager(&node_manager, sizeof(struct node), 128,
0xFFFF, "node", N_STATIC_NODES);
+
+ for (int i = 0; i < N_STATIC_NODES; i++)
+ node_init(&static_nodes()[i]);
}
struct node *node_init(struct node *node) {
diff --git a/src/ply.c b/src/ply.c
@@ -101,7 +101,7 @@ static int parse_magic(const char **cursor) {
}
-int parse_ply(const char *filename, geometry_id *geom_id) {
+int parse_ply(const char *filename, struct geometry *geom) {
size_t len;
int success = 0;
int nverts = 0;
@@ -222,7 +222,6 @@ int parse_ply(const char *filename, geometry_id *geom_id) {
free((void*)data);
if (success) {
- struct geometry *geom = new_geometry(geom_id);
assert(geom);
mkgeom.num_indices = ninds * 3;
diff --git a/src/ply.h b/src/ply.h
@@ -5,6 +5,6 @@
#include "geometry.h"
-int parse_ply(const char *filename, geometry_id *geom_id);
+int parse_ply(const char *filename, struct geometry *geom);
#endif /* PLYPARSER_H */
diff --git a/src/render.c b/src/render.c
@@ -10,6 +10,7 @@
#include "vbo.h"
#include "shader.h"
#include "geometry.h"
+#include "static_resources.h"
#include "debug.h"
#include "render.h"
#include "skybox.h"
@@ -342,6 +343,17 @@ void render (struct game *game, struct render_config *config) {
if (node == NULL)
return;
+ if (i == 1) {
+ debug("rendering %s\n", node->label);
+ print_id(&entity->model_id, true);
+ struct model *model = get_model(&entity->model_id);
+ struct geometry *geom = get_geometry(&model->geom_id);
+ print_id(&model->geom_id, true);
+
+ printf("num_verts: %d\n", geom->num_verts);
+ }
+
+
mat4_multiply(view_proj, node->mat, mvp);
mat4_copy(node->mat, model_view);
mat4_multiply(config->depth_vp, model_view, depth_mvp);
diff --git a/src/resource.c b/src/resource.c
@@ -164,6 +164,7 @@ void *new_resource(struct resource_manager *r, struct resource_id *id)
assert(id);
assert(id->uuid != STATIC_UUID && "called new_resource with a static id");
assert(id->index == 0xFFFFFFFF && "res_id is uninitialized");
+ assert(id->index >= r->static_elems);
struct resource_id *fresh_id;
@@ -240,6 +241,7 @@ void destroy_resource(struct resource_manager *r, struct resource_id *id) {
r->name, id->uuid, id->index, r->resource_count);
r->resource_count--;
+ assert(r->resource_count >= r->static_elems);
r->generation++;
assert((int)r->resource_count - (int)id->index >= 0);
diff --git a/src/resource.h b/src/resource.h
@@ -66,9 +66,4 @@ static inline int is_static_resource(struct resource_id *id)
}
-static inline int is_id_allocated(struct resource_id *id)
-{
- return (int)id->index != -1;
-}
-
#endif /* RESOURCE_H */
diff --git a/src/scene.c b/src/scene.c
@@ -52,7 +52,6 @@ void entity_test_scene(struct game *game)
{
struct entity *player = get_player(&game->test_resources);
struct terrain *terrain = &game->terrain;
- player->model_id = get_static_model(model_pirate_officer, NULL);
model_id rock_model;
init_id(&rock_model);
@@ -60,6 +59,10 @@ void entity_test_scene(struct game *game)
/* model_id rock_model = get_static_model(model_tower, NULL); */
struct model *pmodel = new_model(&rock_model); assert(pmodel);
struct geometry *geom = get_geometry(&pmodel->geom_id); assert(geom);
+ printf("rock geom ");
+ print_id(&pmodel->geom_id, 1);
+ printf("rock model ");
+ print_id(&rock_model, 1);
proc_sphere(geom);
for (int i = 0; i < terrain->size*0.2; i++) {
@@ -75,6 +78,7 @@ void entity_test_scene(struct game *game)
node_scale(node, pow(15.0, rand_0to1()));
node_rotate(node, V3(rand_0to1(),rand_0to1(),rand_0to1()));
node_translate(node, V3(x, y, z));
+ node_set_label(node, "rock");
node_recalc(node);
}
diff --git a/src/util.h b/src/util.h
@@ -30,6 +30,7 @@
#define min(a,b) (a < b ? a : b)
#define max(a,b) (a > b ? a : b)
#define streq(a,b) (strcmp(a,b) == 0)
+#define contains(a,b) (strstr(a,b) != NULL)
#define memeq(a,b,n1,n2) (memcmp(a,b,min(n1, n2)) == 0)
#define approxeq(a, b) (fabs(a-b) < EPSILON)
diff --git a/test/test_animation.c b/test/test_animation.c
@@ -1,6 +1,7 @@
#include "animation.h"
#include "util.h"
+#include "debug.h"
#include <assert.h>
#include <stdio.h>
@@ -21,8 +22,14 @@ int main(int argc, char *argv[])
load_poses("data/models/pirate-officer.dae", poses, &nposes);
assert(nposes == 1);
-
pose = &poses[0];
+
+ debug("pose->nweights %d\n", pose->nweights);
+ assert(pose->nweights == 389);
+ assert(approxeq(pose->weights[0], 0.05213558));
+ debug("pose last weight %f\n", pose->weights[388]);
+ assert(approxeq(pose->weights[388], 0.01394611));
+
assert(pose->njoints == 11);
joint = &pose->joints[0];
diff --git a/test/test_resource.c b/test/test_resource.c
@@ -3,6 +3,7 @@
#include "entity.h"
#include "model.h"
#include "util.h"
+#include "procmesh.h"
#include "debug.h"
#include <assert.h>
@@ -138,6 +139,37 @@ static void test_entity_system()
destroy_entity_system();
}
+void test_geometry()
+{
+ printf("test_geometry\n");
+ init_geometry_manager();
+ init_model_manager();
+
+ struct model *model;
+ model_id player_model_id =
+ get_static_model(model_pirate_officer, &model);
+
+ struct geometry *geom = get_geometry(&model->geom_id);
+ assert(geom);
+
+ assert(geom->num_verts == 2676);
+
+ model_id rock_model;
+ init_id(&rock_model);
+ struct model *pmodel = new_model(&rock_model); assert(pmodel);
+ struct geometry *pgeom = get_geometry(&pmodel->geom_id); assert(geom);
+ proc_sphere(pgeom);
+
+ model_id player_model_id2 = make_static_id(model_pirate_officer);
+
+ assert(ideq(&player_model_id, &player_model_id2));
+
+ pmodel = get_model(&player_model_id2);
+ pgeom = get_geometry(&pmodel->geom_id);
+
+ assert(geom->num_verts == 2676);
+}
+
void test_dynamic_model_manager()
{
printf("test_dynamic_model_manager\n");
@@ -146,6 +178,7 @@ void test_dynamic_model_manager()
int main(int argc, char *argv[])
{
+ test_geometry();
test_int_resource_manager();
test_compact();
test_dynamic_model_manager();
diff --git a/test/test_scene.c b/test/test_scene.c
@@ -25,9 +25,10 @@ void delete_every_other_entity()
if (i % 2 == 0) {
struct entity *ent = get_entity(&ids[i]); assert(ent);
- struct model *pmodel = get_model(&ent->model_id); assert(pmodel);
+ struct model *pmodel = get_model(&ent->model_id);
- destroy_model(&ent->model_id);
+ if (pmodel)
+ destroy_model(&ent->model_id);
destroy_entity(&ids[i]);
}
}
@@ -69,7 +70,6 @@ int scene_tests(struct game *game) {
/* assert(ent_count == 102); */
delete_every_other_entity();
- assert(ent_count == 502);
return 1;
}
diff --git a/todo.org b/todo.org
@@ -4,7 +4,7 @@
* TODO [#A] Instance rendering for ground debris :perf:rendering:
* TODO [#B] Load bone weights :anim:
:LOGBOOK:
-CLOCK: [2019-07-05 Fri 09:28]
+CLOCK: [2019-07-05 Fri 15:46]
:END:
* TODO Simple pthreads job system :jobs:threads: