summaryrefslogtreecommitdiff
path: root/test/raytracer/object.c
diff options
context:
space:
mode:
authorGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2008-08-09 08:06:33 +0000
committerGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2008-08-09 08:06:33 +0000
commit285f5bec5bb03d4e825e5d866e94008088dd6155 (patch)
tree9df69ded9ed4f4049e0b3887fdd99fcdf3b1746f /test/raytracer/object.c
parenta83f0c1710cc5143dd885e84c94e14f7d3216f93 (diff)
Ajout nouveaux tests
git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@708 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'test/raytracer/object.c')
-rw-r--r--test/raytracer/object.c214
1 files changed, 214 insertions, 0 deletions
diff --git a/test/raytracer/object.c b/test/raytracer/object.c
new file mode 100644
index 0000000..3dd6e77
--- /dev/null
+++ b/test/raytracer/object.c
@@ -0,0 +1,214 @@
+#include "config.h"
+#include "arrays.h"
+#include "point.h"
+#include "vector.h"
+#include "eval.h"
+#include "object.h"
+#include "matrix.h"
+
+static struct object * new_object(int kind, struct closure * c)
+{
+ struct object * o = arena_alloc(sizeof(struct object));
+ o->kind = kind;
+ ASSIGN(o->surf, *c);
+ o->world2obj = o->obj2world = mid;
+ o->max_scale_applied = 1.0;
+ o->radius = BS_NOT_COMPUTED;
+ return o;
+}
+
+struct object * cone(struct closure * c)
+{ return new_object(Cone, c); }
+
+struct object * cube(struct closure * c)
+{ return new_object(Cube, c); }
+
+struct object * cylinder(struct closure * c)
+{ return new_object(Cylinder, c); }
+
+struct object * plane(struct closure * c)
+{ return new_object(Plane, c); }
+
+struct object * sphere(struct closure * c)
+{ return new_object(Sphere, c); }
+
+static struct object * transform(struct object * o,
+ struct matrix * t,
+ struct matrix * tinv,
+ flt scale)
+{
+ struct object * no = arena_alloc(sizeof(struct object));
+ no->kind = o->kind;
+ switch (o->kind) {
+ case Union:
+ case Intersection:
+ case Difference:
+ no->o1 = transform(o->o1, t, tinv, scale);
+ no->o2 = transform(o->o2, t, tinv, scale);
+ break;
+ default:
+ ASSIGN(no->surf, o->surf);
+ no->world2obj = mcompose(o->world2obj, tinv);
+ no->obj2world = mcompose(t, o->obj2world);
+ no->max_scale_applied = o->max_scale_applied * scale;
+ }
+ no->radius = BS_NOT_COMPUTED;
+ return no;
+}
+
+struct object * orotatex(struct object * o1, flt a)
+{
+ return transform(o1, mrotatex(a), mrotatex(-a), 1.0);
+}
+
+struct object * orotatey(struct object * o1, flt a)
+{
+ return transform(o1, mrotatey(a), mrotatey(-a), 1.0);
+}
+
+struct object * orotatez(struct object * o1, flt a)
+{
+ return transform(o1, mrotatez(a), mrotatez(-a), 1.0);
+}
+
+struct object * oscale(struct object * o1, flt sx, flt sy, flt sz)
+{
+ flt scale = sx;
+ if (sy > scale) scale = sy;
+ if (sz > scale) scale = sz;
+ return transform(o1, mscale(sx, sy, sz), mscale(1 / sx, 1 / sy, 1 / sz),
+ scale);
+}
+
+struct object * otranslate(struct object * o1,
+ flt tx, flt ty, flt tz)
+{
+ return transform(o1, mtranslate(tx, ty, tz), mtranslate(- tx, - ty, - tz),
+ 1.0);
+}
+
+struct object * ouscale(struct object * o1, flt s)
+{
+ flt sinv = 1 / s;
+ return transform(o1, mscale(s, s, s), mscale(sinv, sinv, sinv), s);
+}
+
+struct object * odifference(struct object * o1, struct object * o2)
+{
+ struct object * o = arena_alloc(sizeof(struct object));
+ o->kind = Difference;
+ o->o1 = o1;
+ o->o2 = o2;
+ o->radius = BS_NOT_COMPUTED;
+ return o;
+}
+
+struct object * ointersect(struct object * o1, struct object * o2)
+{
+ struct object * o = arena_alloc(sizeof(struct object));
+ o->kind = Intersection;
+ o->o1 = o1;
+ o->o2 = o2;
+ o->radius = BS_NOT_COMPUTED;
+ return o;
+}
+
+struct object * ounion(struct object * o1, struct object * o2)
+{
+ struct object * o = arena_alloc(sizeof(struct object));
+ o->kind = Union;
+ o->o1 = o1;
+ o->o2 = o2;
+ o->radius = BS_NOT_COMPUTED;
+ return o;
+}
+
+static void normal_vector_object(struct object * obj,
+ struct point * p,
+ int face,
+ /*out*/ struct vector * v)
+{
+ switch (obj->kind) {
+ case Cone:
+ if (face == 0) {
+ v->dx = p->x; v->dy = - p->y; v->dz = p->z;
+ } else {
+ v->dx = 0; v->dy = 1; v->dz = 0;
+ }
+ break;
+ case Cube:
+ switch (face) {
+ case 0:
+ v->dx = 0; v->dy = 0; v->dz = -1; break;
+ case 1:
+ v->dx = 0; v->dy = 0; v->dz = 1; break;
+ case 2:
+ v->dx = -1; v->dy = 0; v->dz = 0; break;
+ case 3:
+ v->dx = 1; v->dy = 0; v->dz = 0; break;
+ case 4:
+ v->dx = 0; v->dy = 1; v->dz = 0; break;
+ case 5:
+ v->dx = 0; v->dy = -1; v->dz = 0; break;
+ }
+ break;
+ case Cylinder:
+ switch (face) {
+ case 0:
+ v->dx = p->x; v->dy = 0; v->dz = p->z; break;
+ case 1:
+ v->dx = 0; v->dy = 1; v->dz = 0; break;
+ case 2:
+ v->dx = 0; v->dy = -1; v->dz = 0; break;
+ }
+ break;
+ case Plane:
+ v->dx = 0; v->dy = 1; v->dz = 0; break;
+ case Sphere:
+ v->dx = p->x; v->dy = p->y; v->dz = p->z; break;
+ default:
+ assert(0);
+ }
+}
+
+static void tangent_vectors(struct vector * n,
+ /*out*/ struct vector * t1,
+ /*out*/ struct vector * t2)
+{
+ if (n->dy > 0) {
+ t1->dx = n->dy; t1->dy = - n->dx; t1->dz = 0;
+ t2->dx = 0; t2->dy = n->dz; t2->dz = - n->dy;
+ }
+ /* y 0 xy x
+ -x ^ z = yy = y y
+ 0 -y yz z */
+ else if (n->dy == 0) {
+ t1->dx = n->dz; t1->dy = 0; t1->dz = - n->dx;
+ t2->dx = n->dz; t2->dy = 1; t2->dz = - n->dx;
+ }
+ /* z z x x
+ 0 ^ 1 = 0 = 1 y
+ -x -x z z */
+ else {
+ t1->dx = n->dy; t1->dy = - n->dx; t1->dz = 0;
+ t2->dx = 0; t2->dy = - n->dz; t2->dz = n->dy;
+ }
+ /* y 0 -xy x
+ -x ^ -z = -yy = (-y) y
+ 0 y -zy z */
+}
+
+void normal_vector(struct object * obj, struct point * p, int face,
+ /*out*/ struct vector * n)
+{
+ struct point pobj;
+ struct vector nobj, tang_obj1, tang_obj2, tang_world1, tang_world2;
+
+ apply_to_point(obj->world2obj, p, &pobj);
+ normal_vector_object(obj, &pobj, face, &nobj);
+ tangent_vectors(&nobj, &tang_obj1, &tang_obj2);
+ apply_to_vect(obj->obj2world, &tang_obj1, &tang_world1);
+ apply_to_vect(obj->obj2world, &tang_obj2, &tang_world2);
+ product(&tang_world1, &tang_world2, n);
+ vnormalize(n, n);
+}