summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libdimension/dimension/geometry.h19
-rw-r--r--libdimension/dimension/object.h18
-rw-r--r--libdimension/geometry.c17
-rw-r--r--libdimension/object.c11
4 files changed, 34 insertions, 31 deletions
diff --git a/libdimension/dimension/geometry.h b/libdimension/dimension/geometry.h
index c90c3c8..87e7ab7 100644
--- a/libdimension/dimension/geometry.h
+++ b/libdimension/dimension/geometry.h
@@ -281,7 +281,24 @@ double dmnsn_vector_axis_angle(dmnsn_vector v1, dmnsn_vector v2,
dmnsn_matrix dmnsn_matrix_inverse(dmnsn_matrix A);
dmnsn_matrix dmnsn_matrix_mul(dmnsn_matrix lhs, dmnsn_matrix rhs);
-dmnsn_vector dmnsn_transform_vector(dmnsn_matrix lhs, dmnsn_vector rhs);
+
+/* Affine transformation; lhs*(x,y,z,1), normalized so the fourth element is
+ 1 */
+DMNSN_INLINE dmnsn_vector
+dmnsn_transform_vector(dmnsn_matrix lhs, dmnsn_vector rhs)
+{
+ /* 12 multiplications, 3 divisions, 12 additions */
+ dmnsn_vector r;
+ double w;
+
+ r.x = lhs.n[0][0]*rhs.x + lhs.n[0][1]*rhs.y + lhs.n[0][2]*rhs.z + lhs.n[0][3];
+ r.y = lhs.n[1][0]*rhs.x + lhs.n[1][1]*rhs.y + lhs.n[1][2]*rhs.z + lhs.n[1][3];
+ r.z = lhs.n[2][0]*rhs.x + lhs.n[2][1]*rhs.y + lhs.n[2][2]*rhs.z + lhs.n[2][3];
+ w = lhs.n[3][0]*rhs.x + lhs.n[3][1]*rhs.y + lhs.n[3][2]*rhs.z + lhs.n[3][3];
+
+ return dmnsn_vector_div(r, w);
+}
+
dmnsn_bounding_box dmnsn_transform_bounding_box(dmnsn_matrix lhs,
dmnsn_bounding_box rhs);
diff --git a/libdimension/dimension/object.h b/libdimension/dimension/object.h
index f633a2d..cef1acb 100644
--- a/libdimension/dimension/object.h
+++ b/libdimension/dimension/object.h
@@ -41,8 +41,6 @@ typedef struct dmnsn_intersection {
const dmnsn_interior *interior;
} dmnsn_intersection;
-dmnsn_vector dmnsn_transform_normal(dmnsn_matrix trans, dmnsn_vector normal);
-
/* Forward-declare dmnsn_object */
typedef struct dmnsn_object dmnsn_object;
@@ -89,4 +87,20 @@ void dmnsn_delete_object(dmnsn_object *object);
void dmnsn_object_init(dmnsn_object *object);
+/* Useful function to transform a normal vector */
+DMNSN_INLINE dmnsn_vector
+dmnsn_transform_normal(dmnsn_matrix trans, dmnsn_vector normal)
+{
+ return dmnsn_vector_normalize(
+ dmnsn_vector_sub(
+ dmnsn_transform_vector(trans, normal),
+ /* Optimized form of dmnsn_transform_vector(trans, dmnsn_zero) */
+ dmnsn_vector_div(
+ dmnsn_new_vector(trans.n[0][3], trans.n[1][3], trans.n[2][3]),
+ trans.n[3][3]
+ )
+ )
+ );
+}
+
#endif /* DIMENSION_OBJECT_H */
diff --git a/libdimension/geometry.c b/libdimension/geometry.c
index 6b1019b..2a16313 100644
--- a/libdimension/geometry.c
+++ b/libdimension/geometry.c
@@ -345,23 +345,6 @@ dmnsn_matrix_mul(dmnsn_matrix lhs, dmnsn_matrix rhs)
return r;
}
-/* Affine transformation; lhs*(x,y,z,1), normalized so the fourth element is
- 1 */
-dmnsn_vector
-dmnsn_transform_vector(dmnsn_matrix lhs, dmnsn_vector rhs)
-{
- /* 12 multiplications, 3 divisions, 12 additions */
- dmnsn_vector r;
- double w;
-
- r.x = lhs.n[0][0]*rhs.x + lhs.n[0][1]*rhs.y + lhs.n[0][2]*rhs.z + lhs.n[0][3];
- r.y = lhs.n[1][0]*rhs.x + lhs.n[1][1]*rhs.y + lhs.n[1][2]*rhs.z + lhs.n[1][3];
- r.z = lhs.n[2][0]*rhs.x + lhs.n[2][1]*rhs.y + lhs.n[2][2]*rhs.z + lhs.n[2][3];
- w = lhs.n[3][0]*rhs.x + lhs.n[3][1]*rhs.y + lhs.n[3][2]*rhs.z + lhs.n[3][3];
-
- return dmnsn_vector_div(r, w);
-}
-
/* Give an axis-aligned box that contains the given box transformed by `lhs' */
dmnsn_bounding_box
dmnsn_transform_bounding_box(dmnsn_matrix trans, dmnsn_bounding_box box)
diff --git a/libdimension/object.c b/libdimension/object.c
index 97fa45d..768cf68 100644
--- a/libdimension/object.c
+++ b/libdimension/object.c
@@ -21,17 +21,6 @@
#include "dimension.h"
#include <stdlib.h>
-dmnsn_vector
-dmnsn_transform_normal(dmnsn_matrix trans, dmnsn_vector normal)
-{
- return dmnsn_vector_normalize(
- dmnsn_vector_sub(
- dmnsn_transform_vector(trans, normal),
- dmnsn_transform_vector(trans, dmnsn_zero)
- )
- );
-}
-
/* Allocate a dummy object */
dmnsn_object *
dmnsn_new_object()