summaryrefslogtreecommitdiffstats
path: root/dimension/realize.c
diff options
context:
space:
mode:
Diffstat (limited to 'dimension/realize.c')
-rw-r--r--dimension/realize.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/dimension/realize.c b/dimension/realize.c
index 3b1d327..84d04c6 100644
--- a/dimension/realize.c
+++ b/dimension/realize.c
@@ -56,9 +56,42 @@ dmnsn_realize_vector(dmnsn_astnode astnode)
return dmnsn_new_vector(x, y, z);
}
+static dmnsn_color
+dmnsn_realize_color(dmnsn_astnode astnode)
+{
+ if (astnode.type != DMNSN_AST_VECTOR) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a color.");
+ }
+
+
+ dmnsn_astnode rnode, gnode, bnode, fnode, tnode;
+ dmnsn_array_get(astnode.children, 0, &rnode);
+ dmnsn_array_get(astnode.children, 1, &gnode);
+ dmnsn_array_get(astnode.children, 2, &bnode);
+ dmnsn_array_get(astnode.children, 3, &fnode);
+ dmnsn_array_get(astnode.children, 4, &tnode);
+
+ double r = dmnsn_realize_float(rnode),
+ g = dmnsn_realize_float(gnode),
+ b = dmnsn_realize_float(bnode),
+ f = dmnsn_realize_float(fnode),
+ t = dmnsn_realize_float(tnode);
+
+ dmnsn_sRGB sRGB = { .R = r, .G = g, .B = b };
+ dmnsn_color color = dmnsn_color_from_sRGB(sRGB);
+ color.filter = f;
+ color.trans = t;
+
+ return color;
+}
+
static dmnsn_object *
dmnsn_realize_rotation(dmnsn_astnode astnode, dmnsn_object *object)
{
+ if (astnode.type != DMNSN_AST_ROTATION) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a rotation.");
+ }
+
const double deg2rad = atan(1.0)/45.0;
dmnsn_astnode angle_node;
@@ -89,6 +122,10 @@ dmnsn_realize_rotation(dmnsn_astnode astnode, dmnsn_object *object)
static dmnsn_object *
dmnsn_realize_scale(dmnsn_astnode astnode, dmnsn_object *object)
{
+ if (astnode.type != DMNSN_AST_SCALE) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a scale.");
+ }
+
dmnsn_astnode scale_node;
dmnsn_array_get(astnode.children, 0, &scale_node);
dmnsn_vector scale = dmnsn_realize_vector(scale_node);
@@ -100,6 +137,10 @@ dmnsn_realize_scale(dmnsn_astnode astnode, dmnsn_object *object)
static dmnsn_object *
dmnsn_realize_translation(dmnsn_astnode astnode, dmnsn_object *object)
{
+ if (astnode.type != DMNSN_AST_TRANSLATION) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a translation.");
+ }
+
dmnsn_astnode trans_node;
dmnsn_array_get(astnode.children, 0, &trans_node);
dmnsn_vector trans = dmnsn_realize_vector(trans_node);
@@ -112,8 +153,77 @@ dmnsn_realize_translation(dmnsn_astnode astnode, dmnsn_object *object)
}
static dmnsn_object *
+dmnsn_realize_pigment(dmnsn_astnode astnode, dmnsn_object *object)
+{
+ if (astnode.type != DMNSN_AST_PIGMENT) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a pigment.");
+ }
+
+ if (!object->texture) {
+ object->texture = dmnsn_new_texture();
+ if (!object->texture) {
+ dmnsn_delete_object(object);
+ return NULL;
+ }
+ }
+ dmnsn_delete_pigment(object->texture->pigment);
+
+ dmnsn_astnode color_node;
+ dmnsn_array_get(astnode.children, 0, &color_node);
+
+ dmnsn_color color;
+ switch (color_node.type) {
+ case DMNSN_AST_NONE:
+ break;
+
+ case DMNSN_AST_VECTOR:
+ color = dmnsn_realize_color(color_node);
+ object->texture->pigment = dmnsn_new_solid_pigment(color);
+ if (!object->texture->pigment) {
+ dmnsn_delete_object(object);
+ return NULL;
+ }
+ break;
+
+ default:
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Invalid pigment color.");
+ }
+
+ return object;
+}
+
+static dmnsn_object *
+dmnsn_realize_texture(dmnsn_astnode astnode, dmnsn_object *object)
+{
+ if (astnode.type != DMNSN_AST_TEXTURE) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a texture.");
+ }
+
+ unsigned int i;
+ for (i = 0; i < dmnsn_array_size(astnode.children); ++i) {
+ dmnsn_astnode modifier;
+ dmnsn_array_get(astnode.children, i, &modifier);
+
+ switch (modifier.type) {
+ case DMNSN_AST_PIGMENT:
+ object = dmnsn_realize_pigment(modifier, object);
+ break;
+
+ default:
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Invalid texture item.");
+ }
+ }
+
+ return object;
+}
+
+static dmnsn_object *
dmnsn_realize_object_modifiers(dmnsn_astnode astnode, dmnsn_object *object)
{
+ if (astnode.type != DMNSN_AST_OBJECT_MODIFIERS) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected object modifiers.");
+ }
+
unsigned int i;
for (i = 0; i < dmnsn_array_size(astnode.children); ++i) {
dmnsn_astnode modifier;
@@ -130,6 +240,10 @@ dmnsn_realize_object_modifiers(dmnsn_astnode astnode, dmnsn_object *object)
object = dmnsn_realize_translation(modifier, object);
break;
+ case DMNSN_AST_TEXTURE:
+ object = dmnsn_realize_texture(modifier, object);
+ break;
+
default:
dmnsn_error(DMNSN_SEVERITY_HIGH, "Invalid object modifier.");
}
@@ -225,6 +339,14 @@ dmnsn_realize(const dmnsn_array *astree)
return NULL;
}
+ /* Default finish */
+ scene->default_texture->finish = dmnsn_new_phong_finish(1.0, 0.5, 50.0);
+ if (!scene->default_texture->finish) {
+ dmnsn_delete_scene(scene);
+ return NULL;
+ }
+ scene->default_texture->finish->ambient = 0.1;
+
/* Background color */
dmnsn_sRGB background_sRGB = { .R = 0.0, .G = 0.0, .B = 0.1 };
scene->background = dmnsn_color_from_sRGB(background_sRGB);
@@ -260,6 +382,18 @@ dmnsn_realize(const dmnsn_array *astree)
}
dmnsn_set_perspective_camera_trans(scene->camera, trans);
+ /* Make a light */
+
+ dmnsn_light *light = dmnsn_new_point_light(
+ dmnsn_new_vector(-15.0, 20.0, 10.0),
+ dmnsn_white
+ );
+ if (!light) {
+ dmnsn_delete_scene(scene);
+ return NULL;
+ }
+ dmnsn_array_push(scene->lights, &light);
+
/*
* Now parse the abstract syntax tree
*/