summaryrefslogtreecommitdiffstats
path: root/libdimension
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2014-05-09 14:00:42 -0400
committerTavian Barnes <tavianator@tavianator.com>2014-05-26 14:08:57 -0400
commit68be10f11be6098f5cb19bf373e2c6ff82f93c71 (patch)
tree50eb89713b23e0c011e8b37c854e640c05318629 /libdimension
parent21137f8eaae886c034f62e18e6039cc48f09993e (diff)
downloaddimension-68be10f11be6098f5cb19bf373e2c6ff82f93c71.tar.xz
object: Get rid of void *ptr field.
Instead, allow dmnsn_object to be embedded in a larger struct. This gives a consistent 1% speed boost.
Diffstat (limited to 'libdimension')
-rw-r--r--libdimension/cone.c113
-rw-r--r--libdimension/csg.c53
-rw-r--r--libdimension/dimension/object.h18
-rw-r--r--libdimension/object.c24
-rw-r--r--libdimension/plane.c40
-rw-r--r--libdimension/torus.c59
-rw-r--r--libdimension/triangle.c40
7 files changed, 191 insertions, 156 deletions
diff --git a/libdimension/cone.c b/libdimension/cone.c
index a2d2d55..fe01e85 100644
--- a/libdimension/cone.c
+++ b/libdimension/cone.c
@@ -26,18 +26,19 @@
#include "dimension.h"
#include <math.h>
-/** Cone payload type. */
-typedef struct dmnsn_cone_payload {
+/** Cone type. */
+typedef struct dmnsn_cone {
+ dmnsn_object object;
double r1, r2;
-} dmnsn_cone_payload;
+} dmnsn_cone;
/** Intersection callback for a cone. */
static bool
-dmnsn_cone_intersection_fn(const dmnsn_object *cone, dmnsn_line l,
+dmnsn_cone_intersection_fn(const dmnsn_object *object, dmnsn_line l,
dmnsn_intersection *intersection)
{
- const dmnsn_cone_payload *payload = cone->ptr;
- double r1 = payload->r1, r2 = payload->r2;
+ const dmnsn_cone *cone = (const dmnsn_cone *)object;
+ double r1 = cone->r1, r2 = cone->r2;
/* Solve (x0 + nx*t)^2 + (z0 + nz*t)^2
== (((r2 - r1)*(y0 + ny*t) + r1 + r2)/2)^2 */
@@ -79,22 +80,29 @@ dmnsn_cone_intersection_fn(const dmnsn_object *cone, dmnsn_line l,
/** Inside callback for a cone. */
static bool
-dmnsn_cone_inside_fn(const dmnsn_object *cone, dmnsn_vector point)
+dmnsn_cone_inside_fn(const dmnsn_object *object, dmnsn_vector point)
{
- const dmnsn_cone_payload *payload = cone->ptr;
- double r1 = payload->r1, r2 = payload->r2;
+ const dmnsn_cone *cone = (const dmnsn_cone *)cone;
+ double r1 = cone->r1, r2 = cone->r2;
double r = (point.y*(r2 - r1) + r1 + r2)/2.0;
return point.x*point.x + point.z*point.z < r*r
&& point.y > -1.0 && point.y < 1.0;
}
+/** Cone cap type. */
+typedef struct dmnsn_cone_cap {
+ dmnsn_object object;
+ double r;
+} dmnsn_cone_cap;
+
/** Cone cap intersection function. */
static bool
-dmnsn_cone_cap_intersection_fn(const dmnsn_object *cap, dmnsn_line l,
+dmnsn_cone_cap_intersection_fn(const dmnsn_object *object, dmnsn_line l,
dmnsn_intersection *intersection)
{
if (l.n.y != 0.0) {
- double *rptr = cap->ptr, r = *rptr;
+ const dmnsn_cone_cap *cap = (const dmnsn_cone_cap *)object;
+ double r = cap->r;
double t = -l.x0.y/l.n.y;
dmnsn_vector p = dmnsn_line_point(l, t);
if (t >= 0.0 && p.x*p.x + p.z*p.z <= r*r) {
@@ -109,7 +117,7 @@ dmnsn_cone_cap_intersection_fn(const dmnsn_object *cap, dmnsn_line l,
/** Inside callback for a cone cap. */
static bool
-dmnsn_cone_cap_inside_fn(const dmnsn_object *cone, dmnsn_vector point)
+dmnsn_cone_cap_inside_fn(const dmnsn_object *object, dmnsn_vector point)
{
return false;
}
@@ -118,57 +126,52 @@ dmnsn_cone_cap_inside_fn(const dmnsn_object *cone, dmnsn_vector point)
dmnsn_object *
dmnsn_new_cone_cap(double r)
{
- dmnsn_object *cap = dmnsn_new_object();
- cap->intersection_fn = dmnsn_cone_cap_intersection_fn;
- cap->inside_fn = dmnsn_cone_cap_inside_fn;
- cap->bounding_box.min = dmnsn_new_vector(-r, 0.0, -r);
- cap->bounding_box.max = dmnsn_new_vector(+r, 0.0, +r);
-
- double *payload = DMNSN_MALLOC(double);
- *payload = r;
- cap->ptr = payload;
- cap->free_fn = dmnsn_free;
-
- return cap;
+ dmnsn_cone_cap *cap = DMNSN_MALLOC(dmnsn_cone_cap);
+ dmnsn_init_object(&cap->object);
+ cap->object.intersection_fn = dmnsn_cone_cap_intersection_fn;
+ cap->object.inside_fn = dmnsn_cone_cap_inside_fn;
+ cap->object.bounding_box.min = dmnsn_new_vector(-r, 0.0, -r);
+ cap->object.bounding_box.max = dmnsn_new_vector(+r, 0.0, +r);
+ cap->r = r;
+ return &cap->object;
}
/* Allocate a new cone object */
dmnsn_object *
dmnsn_new_cone(double r1, double r2, bool open)
{
- dmnsn_object *cone = dmnsn_new_object();
- cone->intersection_fn = dmnsn_cone_intersection_fn;
- cone->inside_fn = dmnsn_cone_inside_fn;
+ dmnsn_cone *cone = DMNSN_MALLOC(dmnsn_cone);
+ dmnsn_init_object(&cone->object);
+ cone->object.intersection_fn = dmnsn_cone_intersection_fn;
+ cone->object.inside_fn = dmnsn_cone_inside_fn;
double rmax = dmnsn_max(r1, r2);
- cone->bounding_box.min = dmnsn_new_vector(-rmax, -1.0, -rmax);
- cone->bounding_box.max = dmnsn_new_vector(rmax, 1.0, rmax);
-
- dmnsn_cone_payload *payload = DMNSN_MALLOC(dmnsn_cone_payload);
- payload->r1 = r1;
- payload->r2 = r2;
- cone->ptr = payload;
- cone->free_fn = dmnsn_free;
+ cone->object.bounding_box.min = dmnsn_new_vector(-rmax, -1.0, -rmax);
+ cone->object.bounding_box.max = dmnsn_new_vector(rmax, 1.0, rmax);
+ cone->r1 = r1;
+ cone->r2 = r2;
- /* Implement closed cones as a union with the caps */
- if (!open) {
- dmnsn_object *cap1 = dmnsn_new_cone_cap(r1);
- dmnsn_object *cap2 = dmnsn_new_cone_cap(r2);
- cap1->intrinsic_trans = dmnsn_translation_matrix(
- dmnsn_new_vector(0.0, -1.0, 0.0)
- );
- cap2->intrinsic_trans = dmnsn_translation_matrix(
- dmnsn_new_vector(0.0, +1.0, 0.0)
- );
- /* Flip the normal around for the top cap */
- cap2->intrinsic_trans.n[1][1] = -1.0;
-
- dmnsn_array *withcaps = dmnsn_new_array(sizeof(dmnsn_object *));
- dmnsn_array_push(withcaps, &cone);
- dmnsn_array_push(withcaps, &cap1);
- dmnsn_array_push(withcaps, &cap2);
- cone = dmnsn_new_csg_union(withcaps);
- dmnsn_delete_array(withcaps);
+ if (open) {
+ return &cone->object;
}
- return cone;
+ /* Implement closed cones as a union with the caps */
+ dmnsn_object *cap1 = dmnsn_new_cone_cap(r1);
+ dmnsn_object *cap2 = dmnsn_new_cone_cap(r2);
+ cap1->intrinsic_trans = dmnsn_translation_matrix(
+ dmnsn_new_vector(0.0, -1.0, 0.0)
+ );
+ cap2->intrinsic_trans = dmnsn_translation_matrix(
+ dmnsn_new_vector(0.0, +1.0, 0.0)
+ );
+ /* Flip the normal around for the top cap */
+ cap2->intrinsic_trans.n[1][1] = -1.0;
+
+ dmnsn_array *withcaps = dmnsn_new_array(sizeof(dmnsn_object *));
+ dmnsn_array_push(withcaps, &cone);
+ dmnsn_array_push(withcaps, &cap1);
+ dmnsn_array_push(withcaps, &cap2);
+ dmnsn_object *cone_cap_union = dmnsn_new_csg_union(withcaps);
+ dmnsn_delete_array(withcaps);
+
+ return cone_cap_union;
}
diff --git a/libdimension/csg.c b/libdimension/csg.c
index 2595f7d..b364e27 100644
--- a/libdimension/csg.c
+++ b/libdimension/csg.c
@@ -1,5 +1,5 @@
/*************************************************************************
- * Copyright (C) 2010-2012 Tavian Barnes <tavianator@tavianator.com> *
+ * Copyright (C) 2010-2014 Tavian Barnes <tavianator@tavianator.com> *
* *
* This file is part of The Dimension Library. *
* *
@@ -30,59 +30,68 @@
* Unions
*/
+typedef struct {
+ dmnsn_object object;
+ dmnsn_bvh *bvh;
+} dmnsn_csg_union;
+
/** CSG union intersection callback. */
static bool
-dmnsn_csg_union_intersection_fn(const dmnsn_object *csg,
+dmnsn_csg_union_intersection_fn(const dmnsn_object *object,
dmnsn_line line,
dmnsn_intersection *intersection)
{
- dmnsn_bvh *bvh = csg->ptr;
+ dmnsn_bvh *bvh = ((const dmnsn_csg_union *)object)->bvh;
return dmnsn_bvh_intersection(bvh, line, intersection, true);
}
/** CSG union inside callback. */
static bool
-dmnsn_csg_union_inside_fn(const dmnsn_object *csg, dmnsn_vector point)
+dmnsn_csg_union_inside_fn(const dmnsn_object *object, dmnsn_vector point)
{
- dmnsn_bvh *bvh = csg->ptr;
+ dmnsn_bvh *bvh = ((const dmnsn_csg_union *)object)->bvh;
return dmnsn_bvh_inside(bvh, point);
}
/** CSG union initialization callback. */
static void
-dmnsn_csg_union_initialize_fn(dmnsn_object *csg)
+dmnsn_csg_union_initialize_fn(dmnsn_object *object)
{
- csg->trans = dmnsn_identity_matrix();
+ dmnsn_csg_union *csg = (dmnsn_csg_union *)object;
+ csg->object.trans = dmnsn_identity_matrix();
- dmnsn_bvh *bvh = dmnsn_new_bvh(csg->children, DMNSN_BVH_PRTREE);
- csg->ptr = bvh;
- csg->bounding_box = dmnsn_bvh_bounding_box(bvh);
+ dmnsn_bvh *bvh = dmnsn_new_bvh(csg->object.children, DMNSN_BVH_PRTREE);
+ csg->bvh = bvh;
+ csg->object.bounding_box = dmnsn_bvh_bounding_box(bvh);
}
/** CSG union destruction callback. */
static void
-dmnsn_csg_union_free_fn(void *ptr)
+dmnsn_csg_union_free_fn(dmnsn_object *object)
{
- dmnsn_delete_bvh(ptr);
+ dmnsn_csg_union *csg = (dmnsn_csg_union *)object;
+ dmnsn_delete_bvh(csg->bvh);
+ dmnsn_free(csg);
}
/* Bulk-load a union */
dmnsn_object *
dmnsn_new_csg_union(const dmnsn_array *objects)
{
- dmnsn_object *csg = dmnsn_new_object();
+ dmnsn_csg_union *csg = DMNSN_MALLOC(dmnsn_csg_union);
+ dmnsn_init_object(&csg->object);
DMNSN_ARRAY_FOREACH (dmnsn_object **, object, objects) {
- dmnsn_array_push(csg->children, object);
+ dmnsn_array_push(csg->object.children, object);
}
- csg->split_children = true;
- csg->ptr = NULL;
- csg->intersection_fn = dmnsn_csg_union_intersection_fn;
- csg->inside_fn = dmnsn_csg_union_inside_fn;
- csg->initialize_fn = dmnsn_csg_union_initialize_fn;
- csg->free_fn = dmnsn_csg_union_free_fn;
-
- return csg;
+ csg->object.split_children = true;
+ csg->object.intersection_fn = dmnsn_csg_union_intersection_fn;
+ csg->object.inside_fn = dmnsn_csg_union_inside_fn;
+ csg->object.initialize_fn = dmnsn_csg_union_initialize_fn;
+ csg->object.free_fn = dmnsn_csg_union_free_fn;
+ csg->bvh = NULL;
+
+ return &csg->object;
}
/**
diff --git a/libdimension/dimension/object.h b/libdimension/dimension/object.h
index 28cc266..4d75582 100644
--- a/libdimension/dimension/object.h
+++ b/libdimension/dimension/object.h
@@ -1,5 +1,5 @@
/*************************************************************************
- * Copyright (C) 2009-2011 Tavian Barnes <tavianator@tavianator.com> *
+ * Copyright (C) 2009-2014 Tavian Barnes <tavianator@tavianator.com> *
* *
* This file is part of The Dimension Library. *
* *
@@ -67,6 +67,12 @@ typedef bool dmnsn_object_intersection_fn(const dmnsn_object *object,
typedef bool dmnsn_object_inside_fn(const dmnsn_object *object,
dmnsn_vector point);
+/**
+ * Object destruction callback.
+ * @param[in] object The object to delete.
+ */
+typedef void dmnsn_object_free_fn(dmnsn_object *object);
+
/** An object. */
struct dmnsn_object {
dmnsn_texture *texture; /**< Surface properties. */
@@ -85,9 +91,7 @@ struct dmnsn_object {
dmnsn_object_initialize_fn *initialize_fn; /**< Initialization callback. */
dmnsn_object_intersection_fn *intersection_fn; /**< Intersection callback. */
dmnsn_object_inside_fn *inside_fn; /**< Inside callback. */
- dmnsn_free_fn *free_fn; /**< Destruction callback. */
-
- void *ptr; /**< Generic pointer for object info. */
+ dmnsn_object_free_fn *free_fn; /**< Destruction callback. */
DMNSN_REFCOUNT; /**< Reference count. */
bool initialized; /**< @internal Whether the object is initialized yet. */
@@ -100,6 +104,12 @@ struct dmnsn_object {
dmnsn_object *dmnsn_new_object(void);
/**
+ * Initialize a dmnsn_object field.
+ * @param[in,out] object The object to initialize.
+ */
+void dmnsn_init_object(dmnsn_object *object);
+
+/**
* Free an object
* @param[in,out] object The object to destroy.
*/
diff --git a/libdimension/object.c b/libdimension/object.c
index b085cff..52b9558 100644
--- a/libdimension/object.c
+++ b/libdimension/object.c
@@ -26,11 +26,25 @@
#include "dimension-internal.h"
#include <stdlib.h>
+static void
+dmnsn_default_object_free_fn(dmnsn_object *object)
+{
+ dmnsn_free(object);
+}
+
/* Allocate a dummy object */
dmnsn_object *
dmnsn_new_object(void)
{
dmnsn_object *object = DMNSN_MALLOC(dmnsn_object);
+ dmnsn_init_object(object);
+ return object;
+}
+
+/* Initialize a dmnsn_object field */
+void
+dmnsn_init_object(dmnsn_object *object)
+{
object->texture = NULL;
object->interior = NULL;
object->trans = dmnsn_identity_matrix();
@@ -40,13 +54,12 @@ dmnsn_new_object(void)
object->intersection_fn = NULL;
object->inside_fn = NULL;
object->initialize_fn = NULL;
- object->free_fn = NULL;
+ object->free_fn = dmnsn_default_object_free_fn;
object->initialized = false;
DMNSN_REFCOUNT_INIT(object);
- return object;
}
-/* Free a dummy object */
+/* Free a dmnsn_object */
void
dmnsn_delete_object(dmnsn_object *object)
{
@@ -57,10 +70,7 @@ dmnsn_delete_object(dmnsn_object *object)
dmnsn_delete_array(object->children);
dmnsn_delete_interior(object->interior);
dmnsn_delete_texture(object->texture);
- if (object->free_fn) {
- object->free_fn(object->ptr);
- }
- dmnsn_free(object);
+ object->free_fn(object);
}
}
diff --git a/libdimension/plane.c b/libdimension/plane.c
index 33d2737..dc7fc1a 100644
--- a/libdimension/plane.c
+++ b/libdimension/plane.c
@@ -27,6 +27,12 @@
#include <math.h>
#include <stdlib.h>
+/** Plane type. */
+typedef struct {
+ dmnsn_object object;
+ dmnsn_vector normal;
+} dmnsn_plane;
+
/* Plane object callbacks */
static bool dmnsn_plane_intersection_fn(const dmnsn_object *plane,
@@ -39,32 +45,30 @@ static bool dmnsn_plane_inside_fn(const dmnsn_object *plane,
dmnsn_object *
dmnsn_new_plane(dmnsn_vector normal)
{
- dmnsn_object *plane = dmnsn_new_object();
-
- dmnsn_vector *param = DMNSN_MALLOC(dmnsn_vector);
- *param = normal;
+ dmnsn_plane *plane = DMNSN_MALLOC(dmnsn_plane);
+ dmnsn_init_object(&plane->object);
- plane->intersection_fn = dmnsn_plane_intersection_fn;
- plane->inside_fn = dmnsn_plane_inside_fn;
- plane->free_fn = dmnsn_free;
- plane->bounding_box = dmnsn_infinite_bounding_box();
- plane->ptr = param;
- return plane;
+ plane->object.intersection_fn = dmnsn_plane_intersection_fn;
+ plane->object.inside_fn = dmnsn_plane_inside_fn;
+ plane->object.bounding_box = dmnsn_infinite_bounding_box();
+ plane->normal = normal;
+ return &plane->object;
}
/* Returns the closest intersection of `line' with `plane' */
static bool
-dmnsn_plane_intersection_fn(const dmnsn_object *plane, dmnsn_line line,
+dmnsn_plane_intersection_fn(const dmnsn_object *object, dmnsn_line line,
dmnsn_intersection *intersection)
{
- dmnsn_vector *normal = plane->ptr;
+ const dmnsn_plane *plane = (const dmnsn_plane *)object;
+ dmnsn_vector normal = plane->normal;
- double den = dmnsn_vector_dot(line.n, *normal);
+ double den = dmnsn_vector_dot(line.n, normal);
if (den != 0.0) {
- double t = -dmnsn_vector_dot(line.x0, *normal)/den;
+ double t = -dmnsn_vector_dot(line.x0, normal)/den;
if (t >= 0.0) {
intersection->t = t;
- intersection->normal = *normal;
+ intersection->normal = normal;
return true;
}
}
@@ -73,8 +77,8 @@ dmnsn_plane_intersection_fn(const dmnsn_object *plane, dmnsn_line line,
/* Return whether a point is inside a plane */
static bool
-dmnsn_plane_inside_fn(const dmnsn_object *plane, dmnsn_vector point)
+dmnsn_plane_inside_fn(const dmnsn_object *object, dmnsn_vector point)
{
- dmnsn_vector *normal = plane->ptr;
- return dmnsn_vector_dot(point, *normal) < 0.0;
+ const dmnsn_plane *plane = (const dmnsn_plane *)object;
+ return dmnsn_vector_dot(point, plane->normal) < 0.0;
}
diff --git a/libdimension/torus.c b/libdimension/torus.c
index 67bed0f..53e8fcb 100644
--- a/libdimension/torus.c
+++ b/libdimension/torus.c
@@ -25,16 +25,17 @@
#include "dimension.h"
-/** Torus payload type. */
-typedef struct dmnsn_torus_payload {
+/** Torus type. */
+typedef struct {
+ dmnsn_object object;
double major, minor;
-} dmnsn_torus_payload;
+} dmnsn_torus;
/** Bound the torus in a cylindrical shell. */
static inline bool
-dmnsn_torus_bound_intersection(const dmnsn_torus_payload *payload, dmnsn_line l)
+dmnsn_torus_bound_intersection(const dmnsn_torus *torus, dmnsn_line l)
{
- double R = payload->major, r = payload->minor;
+ double R = torus->major, r = torus->minor;
double rmax = R + r, rmin = R - r;
double rmax2 = rmax*rmax, rmin2 = rmin*rmin;
@@ -77,15 +78,16 @@ dmnsn_torus_bound_intersection(const dmnsn_torus_payload *payload, dmnsn_line l)
/** Torus intersection callback. */
static bool
-dmnsn_torus_intersection_fn(const dmnsn_object *torus, dmnsn_line l,
+dmnsn_torus_intersection_fn(const dmnsn_object *object, dmnsn_line l,
dmnsn_intersection *intersection)
{
- const dmnsn_torus_payload *payload = torus->ptr;
- double R = payload->major, r = payload->minor;
+ const dmnsn_torus *torus = (const dmnsn_torus *)object;
+ double R = torus->major, r = torus->minor;
double R2 = R*R, r2 = r*r;
- if (!dmnsn_torus_bound_intersection(payload, l))
+ if (!dmnsn_torus_bound_intersection(torus, l)) {
return false;
+ }
/* This bit of algebra here is correct */
dmnsn_vector x0mod = dmnsn_new_vector(l.x0.x, -l.x0.y, l.x0.z);
@@ -119,7 +121,7 @@ dmnsn_torus_intersection_fn(const dmnsn_object *torus, dmnsn_line l,
dmnsn_vector p = dmnsn_line_point(l, t);
dmnsn_vector center = dmnsn_vector_mul(
- payload->major,
+ R,
dmnsn_vector_normalized(dmnsn_new_vector(p.x, 0.0, p.z))
);
dmnsn_vector normal = dmnsn_vector_sub(p, center);
@@ -131,31 +133,28 @@ dmnsn_torus_intersection_fn(const dmnsn_object *torus, dmnsn_line l,
/** Torus inside callback. */
static bool
-dmnsn_torus_inside_fn(const dmnsn_object *torus, dmnsn_vector point)
+dmnsn_torus_inside_fn(const dmnsn_object *object, dmnsn_vector point)
{
- const dmnsn_torus_payload *payload = torus->ptr;
- double dmajor = payload->major - sqrt(point.x*point.x + point.z*point.z);
- return dmajor*dmajor + point.y*point.y < payload->minor*payload->minor;
+ const dmnsn_torus *torus = (const dmnsn_torus *)object;
+ double dmajor = torus->major - sqrt(point.x*point.x + point.z*point.z);
+ return dmajor*dmajor + point.y*point.y < torus->minor*torus->minor;
}
/* Allocate a new torus */
dmnsn_object *
dmnsn_new_torus(double major, double minor)
{
- dmnsn_object *torus = dmnsn_new_object();
- torus->intersection_fn = dmnsn_torus_intersection_fn;
- torus->inside_fn = dmnsn_torus_inside_fn;
- torus->bounding_box.min = dmnsn_new_vector(-(major + minor),
- -minor,
- -(major + minor));
- torus->bounding_box.max = dmnsn_new_vector(major + minor,
- minor,
- major + minor);
-
- dmnsn_torus_payload *payload = DMNSN_MALLOC(dmnsn_torus_payload);
- payload->major = major;
- payload->minor = minor;
- torus->ptr = payload;
- torus->free_fn = dmnsn_free;
- return torus;
+ dmnsn_torus *torus = DMNSN_MALLOC(dmnsn_torus);
+ dmnsn_init_object(&torus->object);
+ torus->object.intersection_fn = dmnsn_torus_intersection_fn;
+ torus->object.inside_fn = dmnsn_torus_inside_fn;
+ torus->object.bounding_box.min = dmnsn_new_vector(
+ -(major + minor), -minor, -(major + minor)
+ );
+ torus->object.bounding_box.max = dmnsn_new_vector(
+ major + minor, minor, major + minor
+ );
+ torus->major = major;
+ torus->minor = minor;
+ return &torus->object;
}
diff --git a/libdimension/triangle.c b/libdimension/triangle.c
index 0e6daf4..9ddc3fc 100644
--- a/libdimension/triangle.c
+++ b/libdimension/triangle.c
@@ -25,16 +25,18 @@
#include "dimension.h"
-typedef struct dmnsn_triangle_payload {
+/** Triangle type. */
+typedef struct {
+ dmnsn_object object;
dmnsn_vector na, nab, nac;
-} dmnsn_triangle_payload;
+} dmnsn_triangle;
/** Triangle intersection callback. */
static bool
-dmnsn_triangle_intersection_fn(const dmnsn_object *triangle, dmnsn_line l,
+dmnsn_triangle_intersection_fn(const dmnsn_object *object, dmnsn_line l,
dmnsn_intersection *intersection)
{
- const dmnsn_triangle_payload *payload = triangle->ptr;
+ const dmnsn_triangle *triangle = (const dmnsn_triangle *)object;
/* See the change of basis in dmnsn_new_triangle() */
double t = -l.x0.z/l.n.z;
@@ -43,10 +45,10 @@ dmnsn_triangle_intersection_fn(const dmnsn_object *triangle, dmnsn_line l,
if (t >= 0.0 && u >= 0.0 && v >= 0.0 && u + v <= 1.0) {
intersection->t = t;
intersection->normal = dmnsn_vector_add(
- payload->na,
+ triangle->na,
dmnsn_vector_add(
- dmnsn_vector_mul(u, payload->nab),
- dmnsn_vector_mul(v, payload->nac)
+ dmnsn_vector_mul(u, triangle->nab),
+ dmnsn_vector_mul(v, triangle->nac)
)
);
return true;
@@ -71,18 +73,16 @@ dmnsn_new_triangle(dmnsn_vector a, dmnsn_vector b, dmnsn_vector c,
nb = dmnsn_vector_normalized(nb);
nc = dmnsn_vector_normalized(nc);
- dmnsn_triangle_payload *payload = DMNSN_MALLOC(dmnsn_triangle_payload);
- payload->na = na;
- payload->nab = dmnsn_vector_sub(nb, na);
- payload->nac = dmnsn_vector_sub(nc, na);
+ dmnsn_triangle *triangle = DMNSN_MALLOC(dmnsn_triangle);
+ triangle->na = na;
+ triangle->nab = dmnsn_vector_sub(nb, na);
+ triangle->nac = dmnsn_vector_sub(nc, na);
- dmnsn_object *triangle = dmnsn_new_object();
- 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_zero;
- triangle->bounding_box.max = dmnsn_new_vector(1.0, 1.0, 0.0);
+ dmnsn_init_object(&triangle->object);
+ triangle->object.intersection_fn = dmnsn_triangle_intersection_fn;
+ triangle->object.inside_fn = dmnsn_triangle_inside_fn;
+ triangle->object.bounding_box.min = dmnsn_zero;
+ triangle->object.bounding_box.max = dmnsn_new_vector(1.0, 1.0, 0.0);
/*
* Make a change-of-basis matrix
@@ -93,9 +93,9 @@ dmnsn_new_triangle(dmnsn_vector a, dmnsn_vector b, dmnsn_vector c,
dmnsn_vector ab = dmnsn_vector_sub(b, a);
dmnsn_vector ac = dmnsn_vector_sub(c, a);
dmnsn_vector normal = dmnsn_vector_cross(ab, ac);
- triangle->intrinsic_trans = dmnsn_new_matrix4(ab, ac, normal, a);
+ triangle->object.intrinsic_trans = dmnsn_new_matrix4(ab, ac, normal, a);
- return triangle;
+ return &triangle->object;
}
/* Allocate a new flat triangle */