commit 4ab2c240025aef85491b3f4d7a2864ce32db9d10
parent cca2a76abe04ffd902c46d000ffc2b087e5285f7
Author: William Casarin <jb55@jb55.com>
Date: Sun, 30 Jun 2019 19:51:25 -0700
dyn model wip
Diffstat:
13 files changed, 160 insertions(+), 73 deletions(-)
diff --git a/Makefile b/Makefile
@@ -49,6 +49,7 @@ OBJS += $(SRC)/vec3.o
OBJS += $(SRC)/scene.o
OBJS += $(SRC)/resource.o
OBJS += $(SRC)/quickhull.o
+OBJS += $(SRC)/procmesh.o
TESTS = test/test_animation
TESTS += test/test_resource
diff --git a/TODOs.org b/TODOs.org
@@ -18,15 +18,12 @@ CLOSED: [2019-06-22 Sat 12:52]
** DONE Load poses in engine
CLOSED: [2019-06-22 Sat 12:52]
-** TODO factor node properties
-
-perhaps there's a more minimal subset of node that would be useful to
-both joints and entities?
-
-** TODO use nodes for joints
+** DONE use nodes for joints
+CLOSED: [2019-06-30 Sun 17:26]
It will just be easier for interpolation
+
** TODO Load bone weights
** TODO Run pose
** TODO Simple animation test
@@ -40,6 +37,7 @@ It will just be easier for interpolation
** TODO Entity loading stress test
+
* Procedural
** TODO Trees
diff --git a/src/entity.h b/src/entity.h
@@ -16,7 +16,7 @@ enum entity_flags {
struct entity {
node_id node_id;
- struct model *model;
+ model_id model_id;
u32 flags;
float velocity[3];
float accel[3];
diff --git a/src/game.c b/src/game.c
@@ -12,6 +12,7 @@
#include "stb_image.h"
#include "skybox.h"
#include "quickhull.h"
+#include "procmesh.h"
#include "util.h"
#include <assert.h>
@@ -54,51 +55,6 @@ static void init_user_settings(struct user_settings *settings) {
}
-static void qh_mesh_to_geom(qh_mesh_t *qh, struct make_geometry *geom) {
- assert(!geom->vertices);
- assert(!geom->indices);
- float *new_normals = malloc(sizeof(float) * 3 * qh->nvertices);
-
- geom->vertices = (float*)qh->vertices;
- geom->normals = (float*)qh->normals;
- geom->indices = qh->indices;
- geom->num_verts = qh->nvertices;
- geom->num_indices = qh->nindices;
-
- for (u32 i = 0; i < qh->nnormals; i++) {
- int ndv = i * 9;
-
- qh_vertex_t *n = &qh->normals[i];
- for (int j = 0; j < 9; j++) {
- new_normals[ndv+j] = n->v[j%3];
- }
- }
-
- geom->normals = new_normals;
-}
-
-
-void proc_sphere(struct make_geometry *mkgeom, geometry_id *geom_id) {
- const int n = 50;
- qh_vertex_t *vertices = malloc(n*sizeof(qh_vertex_t));
- const float radius = 2.0;
-
-
- for (int i = 0; i < n; ++i) {
- float a0 = (rand_0to1() * TAU);
- float a1 = (rand_0to1() * TAU);
- vertices[i].z = sin(a0) * radius;
- vertices[i].x = cos(a1) * cos(a0) * rand_0to1() * radius;
- vertices[i].y = sin(a1) * cos(a0) * rand_0to1() * radius;
- }
-
- qh_mesh_t mesh = qh_quickhull3d(vertices, n);
- qh_mesh_to_geom(&mesh, mkgeom);
- make_buffer_geometry(mkgeom, geom_id);
-
- qh_free_mesh(mesh);
-}
-
void game_init(struct game *game, int width, int height) {
init_gl(&game->test_resources, width, height);
@@ -190,7 +146,14 @@ void game_init(struct game *game, int width, int height) {
struct node *pnode = get_node(&player->node_id);
assert(pnode);
assert(res->player_id.index == 1);
- player->model = get_model(model_pirate_officer);
+ /* player->model_id = get_static_model(model_pirate_officer, NULL); */
+
+ struct model *pmodel = new_model(&player->model_id); assert(pmodel);
+
+ proc_sphere(geom);
+
+ ok = load_model(&player->model, "pirate-officer");
+ assert(ok);
node_set_label(pnode, "player");
node_attach(&player->node_id, &res->root_id);
diff --git a/src/model.c b/src/model.c
@@ -32,22 +32,47 @@ static void initialize_static_models() {
static_models_initialized = 1;
}
-static inline struct model *new_uninitialized_model(model_id *id) {
+static inline struct model *new_uninitialized_model(struct resource_id *id) {
return new_resource(&dyn_modelman, id);
}
+static struct model *new_model_resource(model_id *model_id)
+{
+ struct model *model = new_uninitialized_model(&model_id->dyn_model_id);
+ new_geometry(&model->geom_id);
+ return model;
+}
+
void init_model_manager() {
init_resource_manager(&dyn_modelman, sizeof(struct model),
DEF_DYNAMIC_MODELS, MAX_DYNAMIC_MODELS);
}
-struct model *new_dynamic_model(model_id *id)
+struct model *new_model(model_id *id)
+{
+ id->type = DYNAMIC_MODEL;
+ return new_model_resource(id);
+}
+
+struct model *get_model(model_id *model_id)
{
- return init_model(new_uninitialized_model(id));
+
+ switch(model_id->type) {
+ case DYNAMIC_MODEL:
+ return get_resource(&dyn_modelman, &model_id->dyn_model_id);
+ case STATIC_MODEL: {
+ struct model *model;
+ get_static_model(model_id->static_model_id, &model);
+ return model;
+ }
+ }
+ assert(!"unhandled case in get_model");
}
-struct model *get_model(enum static_model m) {
+
+static struct model *load_static_model(enum static_model m)
+{
static char path[128] = {0};
if (!static_models_initialized)
@@ -68,3 +93,17 @@ struct model *get_model(enum static_model m) {
return model;
}
+
+model_id get_static_model(enum static_model m, struct model **model)
+{
+ model_id model_id;
+ model_id.type = STATIC_MODEL;
+ model_id.static_model_id = m;
+
+ if (model)
+ *model = load_static_model(m);
+
+ return model_id;
+}
+
+
diff --git a/src/model.h b/src/model.h
@@ -12,8 +12,6 @@
#define MAX_STATIC_MODELS 128
#define MAX_DYNAMIC_MODELS 2048
-typedef struct resource_id model_id;
-
enum static_model {
model_tower,
model_icosphere,
@@ -21,6 +19,21 @@ enum static_model {
NUM_STATIC_MODELS
};
+enum model_type {
+ STATIC_MODEL,
+ DYNAMIC_MODEL
+};
+
+typedef struct model_id_t
+{
+ enum model_type type;
+ union {
+ struct resource_id dyn_model_id;
+ enum static_model static_model_id;
+ };
+} model_id;
+
+
enum shading {
SHADING_TERRAIN,
SHADING_VERT_COLOR,
@@ -28,7 +41,8 @@ enum shading {
};
struct model {
- geometry_id geom_id;
+ /* geometry_id geom_id; */
+ struct geometry geom;
enum shading shading;
u32 texture;
};
@@ -43,8 +57,10 @@ struct model_def {
void init_model_manager();
struct model *init_model(struct model *model);
-struct model *get_model(enum static_model);
+struct model *get_model(model_id *);
+struct model *new_model(model_id *);
+struct model *new_static_model(model_id *);
-struct model *new_dynamic_model(model_id *);
+model_id get_static_model(enum static_model, struct model**);
#endif /* MODEL_H */
diff --git a/src/procmesh.c b/src/procmesh.c
@@ -0,0 +1,53 @@
+
+#include "quickhull.h"
+#include "geometry.h"
+#include "util.h"
+
+
+static void qh_mesh_to_geom(qh_mesh_t *qh, struct make_geometry *geom) {
+ assert(!geom->vertices);
+ assert(!geom->indices);
+ float *new_normals = malloc(sizeof(float) * 3 * qh->nvertices);
+
+ geom->vertices = (float*)qh->vertices;
+ geom->normals = (float*)qh->normals;
+ geom->indices = qh->indices;
+ geom->num_verts = qh->nvertices;
+ geom->num_indices = qh->nindices;
+
+ for (u32 i = 0; i < qh->nnormals; i++) {
+ int ndv = i * 9;
+
+ qh_vertex_t *n = &qh->normals[i];
+ for (int j = 0; j < 9; j++) {
+ new_normals[ndv+j] = n->v[j%3];
+ }
+ }
+
+ geom->normals = new_normals;
+}
+
+
+void proc_sphere(geometry_id *geom_id) {
+ struct make_geometry mkgeom;
+ const int n = 50;
+ qh_vertex_t *vertices = malloc(n*sizeof(qh_vertex_t));
+ const float radius = 2.0;
+
+
+ for (int i = 0; i < n; ++i) {
+ float a0 = (rand_0to1() * TAU);
+ float a1 = (rand_0to1() * TAU);
+ vertices[i].z = sin(a0) * radius;
+ vertices[i].x = cos(a1) * cos(a0) * rand_0to1() * radius;
+ vertices[i].y = sin(a1) * cos(a0) * rand_0to1() * radius;
+ }
+
+ qh_mesh_t mesh = qh_quickhull3d(vertices, n);
+ qh_mesh_to_geom(&mesh, &mkgeom);
+ make_buffer_geometry(&mkgeom, geom_id);
+
+ free(mkgeom.normals);
+ qh_free_mesh(mesh);
+}
+
diff --git a/src/procmesh.h b/src/procmesh.h
@@ -0,0 +1,9 @@
+
+#ifndef PROCMESH_H
+#define PROCMESH_H
+
+#include "geometry.h"
+
+void proc_sphere(struct make_geometry *mkgeom, geometry_id *geom_id);
+
+#endif /* PROCMESH_H */
diff --git a/src/render.c b/src/render.c
@@ -354,8 +354,10 @@ void render (struct game *game, struct render_config *config) {
recalc_normals(res->uniforms.normal_matrix, model_view, normal_matrix);
check_gl();
-
- struct geometry *geo = get_geometry(&entity->model->geom_id);
+ struct model *model = get_model(&entity->model_id);
+ assert(model);
+ struct geometry *geo = get_geometry(&model->geom_id);
+ assert(geo);
render_geometry(geo, res->vertex_attrs, current_program);
check_gl();
}
diff --git a/src/scene.c b/src/scene.c
@@ -30,7 +30,7 @@ void default_scene(struct game *game) {
struct node *pnode = get_node(&player->node_id);
assert(tnode);
- tower->model = get_model(model_tower);
+ tower->model_id = get_static_model_id(model_tower);
node_set_label(tnode, "tower");
node_attach(&tower->node_id, &player->node_id);
node_translate(tnode, V3(0.0, 50.0, 0.0));
diff --git a/src/terrain.c b/src/terrain.c
@@ -53,14 +53,15 @@ void reset_terrain(struct terrain *terrain, float size) {
void init_terrain(struct terrain *terrain, float size) {
init_id(&terrain->entity_id);
- struct entity *ent = new_entity(&terrain->entity_id);
- struct node *node = get_node(&ent->node_id);
+ struct entity *ent = new_entity(&terrain->entity_id); assert(ent);
+ struct node *node = get_node(&ent->node_id); assert(node);
+ struct model *model = get_model(&terrain->model_id); assert(model);
assert(node);
assert(terrain->entity_id.index == 0);
- terrain->model.shading = SHADING_TERRAIN;
- ent->model = &terrain->model;
+ model->shading = SHADING_TERRAIN;
+ ent->model_id = terrain->model_id;
node_set_label(node, "terrain");
ent->casts_shadows = 0;
diff --git a/src/terrain.h b/src/terrain.h
@@ -24,7 +24,7 @@ struct terrain {
entity_id entity_id;
struct perlin_settings settings;
struct point *samples;
- struct model model;
+ model_id model_id;
double (*fn)(struct terrain *, double, double);
int n_samples;
double size;
diff --git a/src/update.c b/src/update.c
@@ -187,7 +187,8 @@ static int try_reload_shaders(struct resources *res) {
#endif
void resize_fbos(struct entity *player, struct fbo *shadow_buffer,
- float *m4_ortho, int width, int height) {
+ float *m4_ortho, int width, int height)
+{
if (shadow_buffer->handle) {
// TODO: remove once delete_fbo deletes attachments
glDeleteTextures(1, &shadow_buffer->attachments[1]);
@@ -197,7 +198,10 @@ void resize_fbos(struct entity *player, struct fbo *shadow_buffer,
// TODO: compute better bounds based
const float factor = 4.5;
- struct geometry *geom = get_geometry(&player->model->geom_id);
+
+ struct model *model = get_model(&player->model_id); assert(model);
+ struct geometry *geom = get_geometry(&model->geom_id); assert(geom);
+
float left = geom->min[0] - factor;
float right = geom->max[0] + factor;
float bottom = geom->min[1] - factor;
@@ -292,7 +296,8 @@ void orbit_update_from_mouse(struct orbit *camera, struct input *input,
float target[3];
struct node *target_node = get_node(&player->node_id);
struct node *cam_node = get_node(&camera->node_id);
- struct geometry *player_geom = get_geometry(&player->model->geom_id);
+ struct model *pmodel = get_model(&player->model_id); assert(pmodel);
+ struct geometry *player_geom = get_geometry(model->geom_id);
assert(target_node);
assert(cam_node);