summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dimension/tests/demo.dmnsn22
-rw-r--r--libdimension-python/dimension.pxd3
-rw-r--r--libdimension-python/dimension.pyx14
-rwxr-xr-xlibdimension-python/tests/demo.py20
-rw-r--r--libdimension/Makefile.am3
-rw-r--r--libdimension/dimension/objects.h10
-rw-r--r--libdimension/tests/render.c33
-rw-r--r--libdimension/triangle.c83
8 files changed, 187 insertions, 1 deletions
diff --git a/dimension/tests/demo.dmnsn b/dimension/tests/demo.dmnsn
index a85a96e..550c57a 100644
--- a/dimension/tests/demo.dmnsn
+++ b/dimension/tests/demo.dmnsn
@@ -17,6 +17,9 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
#########################################################################
+# Background
+background = Clear
+
# Camera
camera = PerspectiveCamera(location = (0, 0.25, -4),
look_at = 0)
@@ -97,6 +100,24 @@ torii = Union(
spike = Union([arrow, torii]).transform(rotate(-45*X))
+strip_textures = [
+ Texture(pigment = Red),
+ Texture(pigment = Orange),
+ Texture(pigment = Yellow),
+]
+strip_triangles = []
+
+a = 0
+b = Vector(0, sqrt(3)/2, 0.5)
+c = Z
+for i in range(128):
+ strip_triangles.append(Triangle(a, b, c, texture = strip_textures[i%3]))
+ a = b
+ b = c
+ c = a + Z
+
+strip = Union(strip_triangles).transform(translate(5, -2, -4))
+
ground = Plane(
normal = Y, distance = -2,
@@ -112,6 +133,7 @@ ground = Plane(
objects = [
hollow_cube,
spike,
+ strip,
ground,
]
diff --git a/libdimension-python/dimension.pxd b/libdimension-python/dimension.pxd
index 6ac6319..f675501 100644
--- a/libdimension-python/dimension.pxd
+++ b/libdimension-python/dimension.pxd
@@ -307,6 +307,9 @@ cdef extern from "../libdimension/dimension.h":
dmnsn_object *dmnsn_new_object()
void dmnsn_delete_object(dmnsn_object *object)
+ dmnsn_object *dmnsn_new_triangle(dmnsn_vector a,
+ dmnsn_vector b,
+ dmnsn_vector c)
dmnsn_object *dmnsn_new_plane(dmnsn_vector normal)
dmnsn_object *dmnsn_new_sphere()
dmnsn_object *dmnsn_new_cube()
diff --git a/libdimension-python/dimension.pyx b/libdimension-python/dimension.pyx
index 8c25538..addba7e 100644
--- a/libdimension-python/dimension.pyx
+++ b/libdimension-python/dimension.pyx
@@ -939,6 +939,20 @@ cdef class Object:
self._object.texture.trans = dmnsn_matrix_mul(self._object.texture.trans,
trans.inverse()._m)
+cdef class Triangle(Object):
+ """A triangle."""
+ def __init__(self, a, b, c, *args, **kwargs):
+ """
+ Create a Triangle.
+
+ Keyword arguments:
+ a, b, c -- the corners of the triangle
+
+ Additionally, Triangle() accepts any arguments that Object() accepts.
+ """
+ self._object = dmnsn_new_triangle(Vector(a)._v, Vector(b)._v, Vector(c)._v)
+ Object.__init__(self, *args, **kwargs)
+
cdef class Plane(Object):
"""A plane."""
def __init__(self, normal, double distance, *args, **kwargs):
diff --git a/libdimension-python/tests/demo.py b/libdimension-python/tests/demo.py
index 96ef22c..e4e1e14 100755
--- a/libdimension-python/tests/demo.py
+++ b/libdimension-python/tests/demo.py
@@ -19,6 +19,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
#########################################################################
+from math import *
from dimension import *
# Treat warnings as errors for tests
@@ -116,6 +117,24 @@ torii = Union(
spike = Union([arrow, torii]).transform(rotate(-45*X))
+strip_textures = [
+ Texture(pigment = Red),
+ Texture(pigment = Orange),
+ Texture(pigment = Yellow),
+]
+strip_triangles = []
+
+a = 0
+b = Vector(0, sqrt(3)/2, 0.5)
+c = Z
+for i in range(128):
+ strip_triangles.append(Triangle(a, b, c, texture = strip_textures[i%3]))
+ a = b
+ b = c
+ c = a + Z
+
+strip = Union(strip_triangles).transform(translate(5, -2, -4))
+
ground = Plane(
normal = Y, distance = -2,
@@ -131,6 +150,7 @@ ground = Plane(
objects = [
hollow_cube,
spike,
+ strip,
ground,
]
diff --git a/libdimension/Makefile.am b/libdimension/Makefile.am
index 0f3dee5..b042fc9 100644
--- a/libdimension/Makefile.am
+++ b/libdimension/Makefile.am
@@ -111,7 +111,8 @@ libdimension_la_SOURCES = $(nobase_include_HEADERS) \
threads.c \
threads.h \
timer.c \
- torus.c
+ torus.c \
+ triangle.c
libdimension_la_CFLAGS = $(AM_CFLAGS)
libdimension_la_LDFLAGS = -version-info 0:0:0 -no-undefined $(AM_LDFLAGS)
libdimension_la_LIBADD = -lm -lpthread
diff --git a/libdimension/dimension/objects.h b/libdimension/dimension/objects.h
index aa53329..ba9547d 100644
--- a/libdimension/dimension/objects.h
+++ b/libdimension/dimension/objects.h
@@ -26,6 +26,16 @@
#include <stdbool.h>
/**
+ * A triangle.
+ * @param[in] a The first corner of the triangle.
+ * @param[in] b The second corner of the triangle.
+ * @param[in] c The third corner of the triangle.
+ */
+dmnsn_object *dmnsn_new_triangle(dmnsn_vector a,
+ dmnsn_vector b,
+ dmnsn_vector c);
+
+/**
* A plane.
* @param[in] normal The normal vector of the plane.
* @return A plane through the origin, with the given normal.
diff --git a/libdimension/tests/render.c b/libdimension/tests/render.c
index 04897d6..a9d20d7 100644
--- a/libdimension/tests/render.c
+++ b/libdimension/tests/render.c
@@ -190,6 +190,39 @@ dmnsn_new_test_scene(void)
);
dmnsn_array_push(scene->objects, &spike);
+ /* Triangle strip */
+
+ dmnsn_array *strip_array = dmnsn_new_array(sizeof(dmnsn_object *));
+ dmnsn_vector a = dmnsn_zero;
+ dmnsn_vector b = dmnsn_new_vector(0.0, sqrt(3.0)/2.0, 0.5);
+ dmnsn_vector c = dmnsn_z;
+ dmnsn_texture *strip_textures[3] = {
+ dmnsn_new_texture(),
+ dmnsn_new_texture(),
+ dmnsn_new_texture(),
+ };
+ strip_textures[0]->pigment = dmnsn_new_solid_pigment(dmnsn_red);
+ strip_textures[1]->pigment = dmnsn_new_solid_pigment(dmnsn_orange);
+ strip_textures[2]->pigment = dmnsn_new_solid_pigment(dmnsn_yellow);
+ for (unsigned int i = 0; i < 128; ++i) {
+ dmnsn_object *triangle = dmnsn_new_triangle(a, b, c);
+ triangle->texture = strip_textures[i%3];
+ DMNSN_INCREF(triangle->texture);
+ dmnsn_array_push(strip_array, &triangle);
+
+ a = b;
+ b = c;
+ c = dmnsn_vector_add(a, dmnsn_z);
+ }
+ for (unsigned int i = 0; i < 3; ++i) {
+ dmnsn_delete_texture(strip_textures[i]);
+ }
+
+ dmnsn_object *strip = dmnsn_new_csg_union(strip_array);
+ dmnsn_delete_array(strip_array);
+ strip->trans = dmnsn_translation_matrix(dmnsn_new_vector(5.0, -2.0, -4.0));
+ dmnsn_array_push(scene->objects, &strip);
+
dmnsn_object *plane = dmnsn_new_plane(dmnsn_new_vector(0.0, 1.0, 0.0));
plane->trans = dmnsn_translation_matrix(dmnsn_new_vector(0.0, -2.0, 0.0));
dmnsn_pattern *checker1 = dmnsn_new_checker_pattern();
diff --git a/libdimension/triangle.c b/libdimension/triangle.c
new file mode 100644
index 0000000..bd54e1a
--- /dev/null
+++ b/libdimension/triangle.c
@@ -0,0 +1,83 @@
+/*************************************************************************
+ * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Triangles.
+ */
+
+#include "dimension.h"
+
+typedef struct dmnsn_triangle_payload {
+ dmnsn_vector a, ab, ac, normal;
+} dmnsn_triangle_payload;
+
+/** Triangle intersection callback. */
+static bool
+dmnsn_triangle_intersection_fn(const dmnsn_object *triangle, dmnsn_line l,
+ dmnsn_intersection *intersection)
+{
+ const dmnsn_triangle_payload *payload = triangle->ptr;
+
+ double den = -dmnsn_vector_dot(l.n, payload->normal);
+ dmnsn_vector ax0 = dmnsn_vector_sub(l.x0, payload->a);
+ double t = dmnsn_vector_dot(ax0, payload->normal)/den;
+ double u = -dmnsn_vector_dot(l.n, dmnsn_vector_cross(ax0, payload->ac))/den;
+ double v = -dmnsn_vector_dot(l.n, dmnsn_vector_cross(payload->ab, ax0))/den;
+ if (t >= 0.0 && u >= 0.0 && v >= 0.0 && u + v <= 1.0) {
+ intersection->ray = l;
+ intersection->t = t;
+ intersection->normal = payload->normal;
+ intersection->texture = triangle->texture;
+ intersection->interior = triangle->interior;
+ return true;
+ }
+
+ return false;
+}
+
+/** Triangle inside callback. */
+static bool
+dmnsn_triangle_inside_fn(const dmnsn_object *triangle, dmnsn_vector point)
+{
+ return false;
+}
+
+/* Allocate a new triangle */
+dmnsn_object *
+dmnsn_new_triangle(dmnsn_vector a, dmnsn_vector b, dmnsn_vector c)
+{
+ dmnsn_object *triangle = dmnsn_new_object();
+
+ dmnsn_triangle_payload *payload =
+ dmnsn_malloc(sizeof(dmnsn_triangle_payload));
+ payload->a = a;
+ payload->ab = dmnsn_vector_sub(b, a);
+ payload->ac = dmnsn_vector_sub(c, a);
+ payload->normal = dmnsn_vector_cross(payload->ab, payload->ac);
+
+ triangle->ptr = payload;
+ triangle->intersection_fn = dmnsn_triangle_intersection_fn;
+ triangle->inside_fn = dmnsn_triangle_inside_fn;
+ triangle->free_fn = dmnsn_free;
+ triangle->bounding_box.min = dmnsn_vector_min(dmnsn_vector_min(a, b), c);
+ triangle->bounding_box.max = dmnsn_vector_max(dmnsn_vector_max(a, b), c);
+ return triangle;
+}