polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

model.c (3431B)


      1 
      2 #include "model.h"
      3 #include "ply.h"
      4 #include "resource.h"
      5 #include "debug.h"
      6 #include "util.h"
      7 #include <assert.h>
      8 
      9 #define MODELDEF(name) { .id = model_##name, .loaded = 0, .file = #name }
     10 
     11 static struct model_def static_model_defs[NUM_STATIC_MODELS] = {
     12   MODELDEF(cube),
     13   MODELDEF(tower),
     14   MODELDEF(icosphere),
     15   MODELDEF(pirate_officer),
     16   MODELDEF(barrel),
     17 };
     18 
     19 static struct resource_manager dyn_modelman;
     20 
     21 struct model *init_model(struct model *model) {
     22     init_id(&model->geom_id);
     23     model->shading = SHADING_VERT_COLOR;
     24     model->texture = 0;
     25     model->nposes = 0;
     26     for (u16 i = 0; i < ARRAY_SIZE(model->poses); i++) {
     27         init_pose(model->poses);
     28     }
     29     return model;
     30 }
     31 
     32 static inline struct model *static_models()
     33 {
     34     return (struct model *)dyn_modelman.resources;
     35 }
     36 
     37 
     38 static void initialize_static_models() {
     39     struct model *models = static_models();
     40     for (int i = 0; i < NUM_STATIC_MODELS; i++) {
     41         struct model *sm = &models[i];
     42         init_model(sm);
     43     }
     44 }
     45 
     46 static inline struct model *new_uninitialized_model(struct resource_id *id) {
     47     return new_resource(&dyn_modelman, id);
     48 }
     49 
     50 static struct model *new_model_resource(model_id *model_id)
     51 {
     52     struct model *model = new_uninitialized_model(model_id);
     53     /* debug("new model %llu\n", model_id->dyn_model_id.uuid); */
     54     init_id(&model->geom_id);
     55     new_geometry(&model->geom_id);
     56     return model;
     57 }
     58 
     59 void init_model_manager()
     60 {
     61     init_resource_manager(&dyn_modelman, sizeof(struct model),
     62                           DEF_DYNAMIC_MODELS, MAX_DYNAMIC_MODELS, "model",
     63                           NUM_STATIC_MODELS);
     64 
     65     initialize_static_models();
     66 }
     67 
     68 
     69 struct model *new_model(model_id *id)
     70 {
     71     return new_model_resource(id);
     72 }
     73 
     74 
     75 struct model *get_model(model_id *model_id)
     76 {
     77     return get_resource(&dyn_modelman, model_id);
     78 }
     79 
     80 static struct model *load_static_model(enum static_model m)
     81 {
     82     static char path[128] = {0};
     83 
     84     struct model *model = &static_models()[m];
     85     struct geometry *geom = &static_geometry()[m];
     86     struct mdl_geometry lgeom;
     87     init_mdl_geometry(&lgeom);
     88     init_geometry(geom);
     89 
     90     model->geom_id = make_static_id(m);
     91 
     92     if (get_geometry(&model->geom_id)->has_vbos) {
     93         debug("model %s already loaded\n", static_model_defs[m].file);
     94         return model;
     95     }
     96 
     97     // Load mesh
     98     debug("loading %s model with geom_id ", static_model_defs[m].file);
     99 
    100     assert(m < NUM_STATIC_MODELS);
    101     snprintf(path, 128, "data/models/%s.mdl", static_model_defs[m].file);
    102     load_mdl(path, model, &lgeom);
    103 
    104     vec3_copy(lgeom.min, geom->min);
    105     vec3_copy(lgeom.max, geom->max);
    106 
    107     make_buffer_geometry(&lgeom.mkgeom, geom);
    108     free_make_geometry(&lgeom.mkgeom);
    109 
    110     return model;
    111 }
    112 
    113 void destroy_model(model_id *model_id)
    114 {
    115     if (is_static_resource(model_id))
    116         return;
    117 
    118     struct model *model = get_model(model_id);
    119 
    120     destroy_geometry(&model->geom_id);
    121     destroy_resource(&dyn_modelman, model_id);
    122 }
    123 
    124 
    125 model_id get_static_model(enum static_model m, struct model **model)
    126 {
    127     model_id model_id;
    128 
    129     if (!is_static_model_loaded(m)) {
    130         load_static_model(m);
    131     }
    132 
    133     model_id = make_static_id(m);
    134 
    135     if (model) {
    136         *model = get_model(&model_id);
    137     }
    138 
    139     return model_id;
    140 }
    141 
    142 
    143 bool is_static_model_loaded(enum static_model m)
    144 {
    145     geometry_id geom_id = make_static_id(m);
    146     struct geometry *geom = get_geometry(&geom_id);
    147     return geom->has_vbos;
    148 }
    149 
    150