+int scn_object_index(const struct scene *scn, const struct object *obj)
+{
+ int i, num = darr_size(scn->objects);
+ for(i=0; i<num; i++) {
+ if(scn->objects[i] == obj) {
+ return i;
+ }
+ }
+ 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; i<num_mtl; i++) {
+ if(scn->mtl[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; i<num_mtl; i++) {
+ if(strcmp(scn->mtl[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; i<num_lights; i++) {
+ if(scn->lights[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; i<num_lights; i++) {
+ if(strcmp(scn->lights[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;
+ struct rayhit hit0, tmphit;
+
+ hit0.t = FLT_MAX;
+ hit0.obj = 0;
+
+ numobj = darr_size(scn->objects);
+ for(i=0; i<numobj; i++) {
+ if(ray_object(ray, scn->objects[i], &tmphit) && tmphit.t < hit0.t) {
+ hit0 = tmphit;
+ }
+ }
+
+ if(hit0.obj) {
+ if(hit) *hit = hit0;
+ return 1;
+ }
+ return 0;
+}
+
+
+/* --- object functions --- */
+