aboutsummaryrefslogtreecommitdiffstats
path: root/test/raytracer/surface.c
diff options
context:
space:
mode:
authorxleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2008-08-09 08:06:33 +0000
committerxleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2008-08-09 08:06:33 +0000
commit285f5bec5bb03d4e825e5d866e94008088dd6155 (patch)
tree9df69ded9ed4f4049e0b3887fdd99fcdf3b1746f /test/raytracer/surface.c
parenta83f0c1710cc5143dd885e84c94e14f7d3216f93 (diff)
downloadcompcert-kvx-285f5bec5bb03d4e825e5d866e94008088dd6155.tar.gz
compcert-kvx-285f5bec5bb03d4e825e5d866e94008088dd6155.zip
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/surface.c')
-rw-r--r--test/raytracer/surface.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/test/raytracer/surface.c b/test/raytracer/surface.c
new file mode 100644
index 00000000..0059db10
--- /dev/null
+++ b/test/raytracer/surface.c
@@ -0,0 +1,148 @@
+#include "config.h"
+#include "point.h"
+#include "vector.h"
+#include "eval.h"
+#include "object.h"
+#include "surface.h"
+
+/* Sphere:
+ x = sqrt(1 - y^2) sin(360u)
+ y = 2v - 1
+ z = sqrt(1 - y^2) cos(360u)
+ hence v = (y+1)/2
+ and u = atan2_turns(x, z) (atan2 in "number of turns")
+*/
+
+#define INV2PI (1.0 / (2.0 * M_PI))
+
+static inline flt atan2_turns(flt x, flt z)
+{
+ flt r = atan2(x, z) * INV2PI;
+ if (r < 0.0) r += 1.0;
+ return r;
+}
+
+static inline void sphere_coords(flt x, flt y, flt z,
+ int * face, flt * u, flt * v)
+{
+ *face = 0;
+ *u = atan2_turns(x, z);
+ *v = (y + 1.0) * 0.5;
+}
+
+/* Cube:
+ (x, y, 0) -> (0, x, y)
+ (x, y, 1) -> (1, x, y)
+ (0, y, z) -> (2, z, y)
+ (1, y, z) -> (3, z, y)
+ (x, 1, z) -> (4, x, z)
+ (x, 0, z) -> (5, x, z)
+ Watch out for rounding errors when determining which coordinate is 0 or 1;
+ see which one is closest to 0 or 1 */
+
+static inline void cube_coords(flt x, flt y, flt z,
+ int * face, flt * u, flt * v)
+{
+ flt dists[6] =
+ { fabs(z), fabs(1 - z), fabs(x), fabs(1 - x), fabs(y), fabs(1 - y) };
+ flt min;
+ int f, i;
+
+ f = 0; min = dists[0];
+ for (i = 1; i < 6; i++)
+ if (dists[i] < min) { min = dists[i]; f = i; }
+ *face = f;
+ switch (f) {
+ case 0: case 1:
+ *u = x; *v = y; break;
+ case 2: case 3:
+ *u = z; *v = y; break;
+ case 4: case 5:
+ *u = x; *v = z; break;
+ }
+}
+
+/* Cylinder:
+ (x, 0, z) -> (2, u, v) where x = 2u-1 and z = 2v-1 hence
+ (x, 1, z) -> (1, x, z) u = (x+1)/2 and v = (z+1)/2
+ (x, y, z) -> (0, u, v) where x = sin(360u) v = y z = cos(360u)
+ hence u = atan2_turns(x, z) and v = y
+*/
+
+static inline void cylinder_coords(flt x, flt y, flt z,
+ int * face, flt * u, flt * v)
+{
+ flt min, d;
+ int f;
+
+ min = y * y; f = 0;
+ d = (1 - y) * (1 - y);
+ if (d < min) { min = d; f = 1; }
+ d = fabs(x * x + z * z - 1);
+ if (d < min) { min = d; f = 2; }
+ *face = 2 - f;
+ if (f < 2) {
+ *u = (x + 1) * 0.5;
+ *v = (z + 1) * 0.5;
+ } else {
+ *u = atan2_turns(x, z);
+ *v = y;
+ }
+}
+
+/* Cone:
+ (x, y, z) -> (0, u, v) where x = v sin 360u
+ y = v
+ z = v cos 360u
+ hence u = atan2_turns(x, z) and v = y
+ (x, 1, z) -> (1, u, v) where x = 2u-1 and z = 2v-1
+ hence u = (x+1)/2 and v = (z+1)/2
+*/
+
+static inline void cone_coords(flt x, flt y, flt z,
+ int * face, flt * u, flt * v)
+{
+ if ((1 - y) * (1 - y) < fabs(x * x + z * z - y * y)) {
+ *face = 1;
+ *u = (x + 1) * 0.5;
+ *v = (z + 1) * 0.5;
+ } else {
+ *face = 0;
+ *u = atan2_turns(x, z);
+ *v = y;
+ }
+}
+
+/* Plane */
+
+static inline void plane_coords(flt x, flt y, flt z,
+ int * face, flt * u, flt * v)
+{
+ *face = 0;
+ *u = x;
+ *v = z;
+}
+
+/* All together */
+
+void surface_coords(struct object * obj, struct point * p,
+ /*out*/ int * face,
+ /*out*/ flt * u,
+ /*out*/ flt * v)
+{
+ switch (obj->kind) {
+ case Cone:
+ cone_coords(p->x, p->y, p->z, face, u, v); break;
+ case Cube:
+ cube_coords(p->x, p->y, p->z, face, u, v); break;
+ case Cylinder:
+ cylinder_coords(p->x, p->y, p->z, face, u, v); break;
+ case Plane:
+ plane_coords(p->x, p->y, p->z, face, u, v); break;
+ case Sphere:
+ sphere_coords(p->x, p->y, p->z, face, u, v); break;
+ default:
+ assert(0);
+ }
+}
+