X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fscene.c;h=36c9fba9aa0851eda4d5d903e7e62a00f9394dc7;hb=81dffafe4b045c854d8a97f9c6c41877ee7669ca;hp=48279cc5338159a8037b5857dd3ad9554a488ed7;hpb=c64a0d68e1bee56fd8b0375a747a896e8424398b;p=retroray diff --git a/src/scene.c b/src/scene.c index 48279cc..36c9fba 100644 --- a/src/scene.c +++ b/src/scene.c @@ -22,6 +22,8 @@ along with this program. If not, see . #include "darray.h" #include "logger.h" +static struct material *default_material(void); + struct scene *create_scene(void) { struct scene *scn; @@ -31,7 +33,8 @@ struct scene *create_scene(void) return 0; } scn->objects = darr_alloc(0, sizeof *scn->objects); - + scn->lights = darr_alloc(0, sizeof *scn->lights); + scn->mtl = darr_alloc(0, sizeof *scn->mtl); return scn; } @@ -45,6 +48,18 @@ void free_scene(struct scene *scn) free_object(scn->objects[i]); } darr_free(scn->objects); + + for(i=0; ilights); i++) { + free_light(scn->lights[i]); + } + darr_free(scn->lights); + + for(i=0; imtl); i++) { + mtl_destroy(scn->mtl[i]); + free(scn->mtl[i]); + } + darr_free(scn->mtl); + free(scn); } @@ -87,6 +102,119 @@ int scn_object_index(const struct scene *scn, const struct object *obj) return -1; } + + +int scn_add_material(struct scene *scn, struct material *mtl) +{ + darr_push(scn->mtl, &mtl); + return 0; +} + +int scn_rm_material(struct scene *scn, struct material *mtl) +{ + int idx, num_mtl; + + if((idx = scn_material_index(scn, mtl)) == -1) { + return -1; + } + + num_mtl = darr_size(scn->mtl); + + if(idx < num_mtl - 1) { + scn->mtl[idx] = scn->mtl[num_mtl - 1]; + } + darr_pop(scn->mtl); + return 0; +} + +int scn_num_materials(const struct scene *scn) +{ + return darr_size(scn->mtl); +} + +int scn_material_index(const struct scene *scn, const struct material *mtl) +{ + int i, num_mtl; + + num_mtl = darr_size(scn->mtl); + for(i=0; imtl[i] == mtl) { + return i; + } + } + return -1; +} + +struct material *scn_find_material(const struct scene *scn, const char *mname) +{ + int i, num_mtl; + + num_mtl = darr_size(scn->mtl); + for(i=0; imtl[i]->name, mname) == 0) { + return scn->mtl[i]; + } + } + return 0; +} + +/* manage lights */ + +int scn_add_light(struct scene *scn, struct light *light) +{ + darr_push(scn->lights, &light); + return 0; +} + +int scn_rm_light(struct scene *scn, struct light *light) +{ + int idx, num_lights; + + if((idx = scn_light_index(scn, light)) == -1) { + return -1; + } + + num_lights = darr_size(scn->lights); + + if(idx < num_lights - 1) { + scn->lights[idx] = scn->lights[num_lights - 1]; + } + darr_pop(scn->lights); + return 0; +} + +int scn_num_lights(const struct scene *scn) +{ + return darr_size(scn->lights); +} + +int scn_light_index(const struct scene *scn, const struct light *light) +{ + int i, num_lights; + + num_lights = darr_size(scn->lights); + for(i=0; ilights[i] == light) { + return i; + } + } + return -1; +} + +struct light *scn_find_light(const struct scene *scn, const char *mname) +{ + int i, num_lights; + + num_lights = darr_size(scn->lights); + for(i=0; ilights[i]->name, mname) == 0) { + return scn->lights[i]; + } + } + return 0; +} + + int scn_intersect(const struct scene *scn, const cgm_ray *ray, struct rayhit *hit) { int i, numobj; @@ -109,6 +237,9 @@ int scn_intersect(const struct scene *scn, const cgm_ray *ray, struct rayhit *hi return 0; } + +/* --- object functions --- */ + struct object *create_object(int type) { struct object *obj; @@ -143,6 +274,7 @@ struct object *create_object(int type) cgm_midentity(obj->xform); cgm_midentity(obj->inv_xform); obj->xform_valid = 1; + obj->mtl = default_material(); set_object_name(obj, buf); objid++; @@ -198,3 +330,65 @@ void calc_object_matrix(struct object *obj) obj->xform_valid = 1; } + +/* --- lights --- */ +struct light *create_light(void) +{ + struct light *lt; + static int ltidx; + char buf[64]; + + if(!(lt = malloc(sizeof *lt))) { + return 0; + } + cgm_vcons(<->pos, 0, 0, 0); + + set_light_color(lt, 1, 1, 1); + set_light_energy(lt, 1); + + sprintf(buf, "light%03d", ltidx++); + set_light_name(lt, buf); + + return lt; +} + +void free_light(struct light *lt) +{ + if(!lt) return; + free(lt->name); + free(lt); +} + +int set_light_name(struct light *lt, const char *name) +{ + char *tmp = strdup(name); + if(!tmp) return -1; + free(lt->name); + lt->name = tmp; + return 0; +} + +void set_light_color(struct light *lt, float r, float g, float b) +{ + cgm_vcons(<->orig_color, r, g, b); + lt->color = lt->orig_color; + cgm_vscale(<->color, lt->energy); +} + +void set_light_energy(struct light *lt, float e) +{ + lt->energy = e; + lt->color = lt->orig_color; + cgm_vscale(<->color, e); +} + +static struct material *default_material(void) +{ + static struct material defmtl; + + if(!defmtl.name) { + mtl_init(&defmtl); + mtl_set_name(&defmtl, "default_mtl"); + } + return &defmtl; +}