aboutsummaryrefslogtreecommitdiff
path: root/scene.c
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2020-03-22 18:44:26 +0100
committerJulian T <julian@jtle.dk>2020-03-22 18:44:26 +0100
commit6ca75e5d27980e082d977ffdb9a93589b55961ce (patch)
treec927280265129459fbcb0ac9b5ab2dd9eccbac42 /scene.c
parent66e3fe20bdd09ef431f612e02ffe0ce9809b5cc2 (diff)
Added container allowing scatic allocation of all the scene data.
This will make porting to arduino alot easier
Diffstat (limited to 'scene.c')
-rw-r--r--scene.c99
1 files changed, 91 insertions, 8 deletions
diff --git a/scene.c b/scene.c
index 5a41041..331cd30 100644
--- a/scene.c
+++ b/scene.c
@@ -1,6 +1,7 @@
#include "scene.h"
#include <stdlib.h>
+#include <string.h>
static inline void link_object(space_t *s, object_t *o)
{
@@ -12,24 +13,94 @@ static inline void link_object(space_t *s, object_t *o)
}
}
-object_t *add_sphere(space_t *s, vector_t *c, COORD_T r, material_t *m)
+container_t *container_init(container_t *c, unsigned objs, unsigned mats, unsigned ligs)
{
- object_t *o = (object_t *) malloc(sizeof(object_t));
+ c->obj_index = c->mat_index = c->lig_index = 0;
+ c->obj_cap = objs;
+ c->mat_cap = mats;
+ c->lig_cap = ligs;
+
+ return c;
+}
+
+space_t *container_prepare_space(container_t *c)
+{
+ memset(&c->space, 0, sizeof(space_t));
+}
+
+// Finds the next empty object_t space
+// Return NULL if full
+static inline object_t *container_obj_space(container_t *cont)
+{
+ if (cont->obj_index >= cont->obj_cap) {
+ fprintf(stderr, "Could not create object, because container is full\n");
+ return NULL;
+ }
+
+ // Find a nice spot in the content blob
+ return &((object_t *) cont->content)[cont->obj_index++];
+}
+
+static inline material_t *container_mat_space(container_t *cont)
+{
+ if (cont->mat_index >= cont->mat_cap) {
+ fprintf(stderr, "Could not create material, because container is full\n");
+ return NULL;
+ }
+
+ // Find a nice spot in the content blob.
+ // Remember to jump over objects
+ return &((material_t *) (
+ cont->content +
+ sizeof(object_t) * cont->obj_cap
+ ))[cont->mat_index++];
+}
+
+static inline light_t *container_lig_space(container_t *cont)
+{
+ if (cont->lig_index >= cont->lig_cap) {
+ fprintf(stderr, "Could not create light, because container is full\n");
+ return NULL;
+ }
+
+ // Find a nice spot in the content blob.
+ // Remember to jump over objects and materials
+ return &((light_t *) (
+ cont->content +
+ sizeof(object_t) * cont->obj_cap +
+ sizeof(material_t) * cont->mat_cap
+ ))[cont->lig_index++];
+}
+
+object_t *add_sphere(container_t *cont, vector_t *c, COORD_T r, material_t *m)
+{
+
+ object_t *o = container_obj_space(cont);
+ if (!o) {
+ return NULL;
+ }
+
+ // Fill out the data
o->type = TYPE_SPHERE;
o->m = m;
o->sph.center = c;
o->sph.radius = r;
- link_object(s, o);
+ // Link to the linked list
+ link_object(&cont->space, o);
return o;
}
-object_t *add_plane(space_t *s, vector_t *start, vector_t *dir, material_t *m)
+object_t *add_plane(container_t *cont, vector_t *start, vector_t *dir, material_t *m)
{
- object_t *o = (object_t *) malloc(sizeof(object_t));
+
+ object_t *o = container_obj_space(cont);
+ if (!o) {
+ return NULL;
+ }
o->type = TYPE_PLANE;
o->m = m;
@@ -37,19 +108,23 @@ object_t *add_plane(space_t *s, vector_t *start, vector_t *dir, material_t *m)
o->pl.start = start;
o->pl.norm = dir;
- link_object(s, o);
+ link_object(&cont->space, o);
return o;
}
-light_t *add_light(space_t *s, vector_t *pos, color_t *defuse, color_t *specular)
+light_t *add_light(container_t *cont, vector_t *pos, color_t *defuse, color_t *specular)
{
- light_t *o = (light_t *) malloc(sizeof(light_t));
+ light_t *o = container_lig_space(cont);
+ if (!o) {
+ return NULL;
+ }
o->pos = pos;
o->defuse = defuse;
o->specular = specular;
+ space_t *s = &cont->space;
if (s) {
o->next = s->lights;
s->lights = o;
@@ -60,6 +135,14 @@ light_t *add_light(space_t *s, vector_t *pos, color_t *defuse, color_t *specular
return o;
}
+// It's alot easier to set the stuff outside of this function
+material_t *add_material(container_t *cont)
+{
+ material_t *m = container_mat_space(cont);
+
+ return m;
+}
+
void obj_norm_at(object_t *o, vector_t *dest, vector_t *point)
{
switch(o->type) {