From 285f5bec5bb03d4e825e5d866e94008088dd6155 Mon Sep 17 00:00:00 2001 From: xleroy Date: Sat, 9 Aug 2008 08:06:33 +0000 Subject: Ajout nouveaux tests git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@708 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e --- test/raytracer/light.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 test/raytracer/light.c (limited to 'test/raytracer/light.c') diff --git a/test/raytracer/light.c b/test/raytracer/light.c new file mode 100644 index 00000000..1c90104c --- /dev/null +++ b/test/raytracer/light.c @@ -0,0 +1,126 @@ +#include "config.h" +#include "point.h" +#include "vector.h" +#include "eval.h" +#include "object.h" +#include "intersect.h" +#include "light.h" + +struct light * dirlight(struct point * dir, struct point * c) +{ + struct light * l = arena_alloc(sizeof(struct light)); + l->kind = Directional; + ASSIGN(l->u.directional.dir, *dir); + ASSIGN(l->u.directional.col, *c); + return l; +} + +struct light * pointlight(struct point * orig, struct point * c) +{ + struct light * l = arena_alloc(sizeof(struct light)); + l->kind = Pointlight; + ASSIGN(l->u.point.orig, *orig); + ASSIGN(l->u.point.col, *c); + return l; +} + +struct light * spotlight(struct point * pos, struct point * at, + struct point * c, flt cutoff, flt exp) +{ + struct light * l = arena_alloc(sizeof(struct light)); + struct vector uv; + l->kind = Spot; + ASSIGN(l->u.spot.orig, *pos); + ASSIGN(l->u.spot.at, *at); + ASSIGN(l->u.spot.col, *c); + l->u.spot.cutoff = cutoff; + l->u.spot.exponent = exp; + between(at, pos, &uv); + vnormalize(&uv, &(l->u.spot.unit)); + return l; +} + +static void color_from_light(struct object * scene, + struct point * pt, + struct vector * v, + struct vector * n, + flt kd, flt ks, flt phong, + struct light * light, + /*out*/ struct point * il) +{ + struct vector dir; + struct object * obj; + struct vector L, H, vnorm; + struct point i; + flt t, att, dp, m; + + /* Compute direction towards light source */ + switch (light->kind) { + case Directional: + dir.dx = - light->u.directional.dir.x; + dir.dy = - light->u.directional.dir.y; + dir.dz = - light->u.directional.dir.z; + break; + case Pointlight: + between(pt, &light->u.point.orig, &dir); + break; + case Spot: + between(pt, &light->u.spot.orig, &dir); + break; + } + /* Check that light source is not behind us */ + if (dotproduct(&dir, n) <= 0.0) return; /*no contribution*/ + /* Check that no object blocks the light */ + obj = intersect_ray(pt, &dir, scene, 0 /*??*/, &t); + if (obj != NULL && (light->kind == Directional || t <= 1.0)) return; + /* Compute the L and H vectors */ + vnormalize(&dir, &L); + vnormalize(v, &vnorm); + vsub(&L, &vnorm, &H); + vnormalize(&H, &H); + /* Intensity of light source at object */ + switch (light->kind) { + case Directional: + i.x = light->u.directional.col.x; + i.y = light->u.directional.col.y; + i.z = light->u.directional.col.z; + break; + case Pointlight: + att = 100.0 / (99.0 + dist2(pt, &light->u.point.orig)); + i.x = light->u.point.col.x * att; + i.y = light->u.point.col.y * att; + i.z = light->u.point.col.z * att; + break; + case Spot: + dp = dotproduct(&L, &light->u.spot.unit); + if (acos(dp) >= light->u.spot.cutoff) return; + att = + pow(dp, light->u.spot.exponent) + * (100.0 / (99.0 + dist2(pt, &light->u.spot.orig))); + i.x = light->u.spot.col.x * att; + i.y = light->u.spot.col.y * att; + i.z = light->u.spot.col.z * att; + break; + } + /* Add final contribution */ + m = kd * dotproduct(n, &L) + ks * pow(dotproduct(n, &H), phong); + il->x += m * i.x; + il->y += m * i.y; + il->z += m * i.z; +} + +void color_from_lights(struct object * scene, + struct point * p, + struct vector * v, + struct vector * n, + flt kd, flt ks, flt phong, + struct light ** lights, + /*out*/ struct point * il) +{ + int i; + + il->x = il->y = il->z = 0.0; + for (i = 0; lights[i] != NULL; i++) + color_from_light(scene, p, v, n, kd, ks, phong, lights[i], il); +} + -- cgit