From 5dcc62e9f198094e3fd49be1847871853c1449bc Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Tue, 30 Jun 2009 15:53:41 +0000 Subject: New inline function framework. --- libdimension/Makefile.am | 1 + libdimension/array.c | 9 +-- libdimension/dimension.h | 21 +++++++ libdimension/dimension/array.h | 10 +++- libdimension/dimension/geometry.h | 105 +++++++++++++++++++++++++++++------ libdimension/geometry.c | 113 -------------------------------------- libdimension/inlines.c | 36 ++++++++++++ 7 files changed, 154 insertions(+), 141 deletions(-) create mode 100644 libdimension/inlines.c diff --git a/libdimension/Makefile.am b/libdimension/Makefile.am index d73f1e7..125ad77 100644 --- a/libdimension/Makefile.am +++ b/libdimension/Makefile.am @@ -42,6 +42,7 @@ libdimension_la_SOURCES = $(nobase_include_HEADERS) \ cube.c \ error.c \ geometry.c \ + inlines.c \ png.c \ progress.c \ object.c \ diff --git a/libdimension/array.c b/libdimension/array.c index a22b450..fcd77f5 100644 --- a/libdimension/array.c +++ b/libdimension/array.c @@ -99,14 +99,7 @@ dmnsn_array_at(dmnsn_array *array, size_t i) return (char *)array->ptr + array->obj_size*i; } -/* Get the size of the array */ -size_t -dmnsn_array_size(const dmnsn_array *array) -{ - return array->length; -} - -/* Set the size of the array, atomically */ +/* Set the size of the array */ void dmnsn_array_resize(dmnsn_array *array, size_t length) { diff --git a/libdimension/dimension.h b/libdimension/dimension.h index 3e1bcf9..4157f8b 100644 --- a/libdimension/dimension.h +++ b/libdimension/dimension.h @@ -25,6 +25,27 @@ #ifndef DIMENSION_H #define DIMENSION_H +/* Handle inlines nicely without cheating and making them static. The + DMNSN_INLINE macro is set appropriately for the version of C you're using, + and non-inline versions are emitted in exactly one translation unit when + necessary. */ +#ifndef DMNSN_INLINE + #ifdef __cplusplus + /* C++ inline semantics */ + #define DMNSN_INLINE inline + #elif (__STDC_VERSION__ >= 199901L) + /* C99 inline semantics */ + #define DMNSN_INLINE inline + #elif defined(__GNUC__) + /* GCC inline semantics */ + #define DMNSN_INLINE extern inline + #else + /* Unknown C - mark functions static and hope the compiler is smart enough + to inline them */ + #define DMNSN_INLINE static + #endif +#endif + #ifdef __cplusplus /* We've been included from a C++ file; mark everything here as extern "C" */ extern "C" { diff --git a/libdimension/dimension/array.h b/libdimension/dimension/array.h index 5d5e50e..036d6c8 100644 --- a/libdimension/dimension/array.h +++ b/libdimension/dimension/array.h @@ -45,7 +45,13 @@ void dmnsn_array_get(const dmnsn_array *array, size_t i, void *obj); void dmnsn_array_set(dmnsn_array *array, size_t i, const void *obj); void *dmnsn_array_at(dmnsn_array *array, size_t i); -size_t dmnsn_array_size(const dmnsn_array *array); -void dmnsn_array_resize(dmnsn_array *array, size_t length); +/* Inline so for-loops calling this are fast */ +DMNSN_INLINE size_t +dmnsn_array_size(const dmnsn_array *array) +{ + return array->length; +} + +void dmnsn_array_resize(dmnsn_array *array, size_t length); #endif /* DIMENSION_ARRAY_H */ diff --git a/libdimension/dimension/geometry.h b/libdimension/dimension/geometry.h index 9ddfbd9..2f08012 100644 --- a/libdimension/dimension/geometry.h +++ b/libdimension/dimension/geometry.h @@ -25,6 +25,8 @@ #ifndef DIMENSION_GEOMETRY_H #define DIMENSION_GEOMETRY_H +#include + /* Vector and matrix types. */ typedef struct { double x, y, z; } dmnsn_vector; @@ -39,12 +41,25 @@ typedef struct { /* Shorthand for vector/matrix construction */ -dmnsn_vector dmnsn_vector_construct(double x, double y, double z); - -dmnsn_matrix dmnsn_matrix_construct(double a0, double a1, double a2, double a3, - double b0, double b1, double b2, double b3, - double c0, double c1, double c2, double c3, - double d0, double d1, double d2, double d3); +DMNSN_INLINE dmnsn_vector +dmnsn_vector_construct(double x, double y, double z) +{ + dmnsn_vector v = { x, y, z }; + return v; +} + +DMNSN_INLINE dmnsn_matrix +dmnsn_matrix_construct(double a0, double a1, double a2, double a3, + double b0, double b1, double b2, double b3, + double c0, double c1, double c2, double c3, + double d0, double d1, double d2, double d3) +{ + dmnsn_matrix m = { { { a0, a1, a2, a3 }, + { b0, b1, b2, b3 }, + { c0, c1, c2, c3 }, + { d0, d1, d2, d3 } } }; + return m; +} dmnsn_matrix dmnsn_identity_matrix(); dmnsn_matrix dmnsn_scale_matrix(dmnsn_vector s); @@ -52,20 +67,69 @@ dmnsn_matrix dmnsn_translation_matrix(dmnsn_vector d); /* Left-handed rotation; theta/|theta| = axis, |theta| = angle */ dmnsn_matrix dmnsn_rotation_matrix(dmnsn_vector theta); -dmnsn_line dmnsn_line_construct(dmnsn_vector x0, dmnsn_vector n); +DMNSN_INLINE dmnsn_line +dmnsn_line_construct(dmnsn_vector x0, dmnsn_vector n) +{ + dmnsn_line l = { x0, n }; + return l; +} /* Vector and matrix arithmetic */ -dmnsn_vector dmnsn_vector_add(dmnsn_vector lhs, dmnsn_vector rhs); -dmnsn_vector dmnsn_vector_sub(dmnsn_vector lhs, dmnsn_vector rhs); -dmnsn_vector dmnsn_vector_mul(double lhs, dmnsn_vector rhs); -dmnsn_vector dmnsn_vector_div(dmnsn_vector lhs, double rhs); - -double dmnsn_vector_dot(dmnsn_vector lhs, dmnsn_vector rhs); -dmnsn_vector dmnsn_vector_cross(dmnsn_vector lhs, dmnsn_vector rhs); - -double dmnsn_vector_norm(dmnsn_vector n); -dmnsn_vector dmnsn_vector_normalize(dmnsn_vector n); +DMNSN_INLINE dmnsn_vector +dmnsn_vector_add(dmnsn_vector lhs, dmnsn_vector rhs) +{ + dmnsn_vector v = { lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z }; + return v; +} + +DMNSN_INLINE dmnsn_vector +dmnsn_vector_sub(dmnsn_vector lhs, dmnsn_vector rhs) +{ + dmnsn_vector v = { lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z }; + return v; +} + +DMNSN_INLINE dmnsn_vector +dmnsn_vector_mul(double lhs, dmnsn_vector rhs) +{ + dmnsn_vector v = { lhs*rhs.x, lhs*rhs.y, lhs*rhs.z }; + return v; +} + +DMNSN_INLINE dmnsn_vector +dmnsn_vector_div(dmnsn_vector lhs, double rhs) +{ + dmnsn_vector v = { lhs.x/rhs, lhs.y/rhs, lhs.z/rhs }; + return v; +} + +DMNSN_INLINE double +dmnsn_vector_dot(dmnsn_vector lhs, dmnsn_vector rhs) +{ + return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z; +} + +DMNSN_INLINE dmnsn_vector +dmnsn_vector_cross(dmnsn_vector lhs, dmnsn_vector rhs) +{ + dmnsn_vector v = { lhs.y*rhs.z - lhs.z*rhs.y, + lhs.z*rhs.x - lhs.x*rhs.z, + lhs.x*rhs.y - lhs.y*rhs.x }; + return v; +} + +DMNSN_INLINE double +dmnsn_vector_norm(dmnsn_vector n) +{ + return sqrt(dmnsn_vector_dot(n, n)); +} + +DMNSN_INLINE dmnsn_vector +dmnsn_vector_normalize(dmnsn_vector n) +{ + return dmnsn_vector_div(n, dmnsn_vector_norm(n)); +} dmnsn_matrix dmnsn_matrix_inverse(dmnsn_matrix A); dmnsn_matrix dmnsn_matrix_mul(dmnsn_matrix lhs, dmnsn_matrix rhs); @@ -73,7 +137,12 @@ dmnsn_vector dmnsn_matrix_vector_mul(dmnsn_matrix lhs, dmnsn_vector rhs); dmnsn_line dmnsn_matrix_line_mul(dmnsn_matrix lhs, dmnsn_line rhs); /* A point on a line, defined by x0 + t*n */ -dmnsn_vector dmnsn_line_point(dmnsn_line l, double t); +DMNSN_INLINE dmnsn_vector +dmnsn_line_point(dmnsn_line l, double t) +{ + return dmnsn_vector_add(l.x0, dmnsn_vector_mul(t, l.n)); +} + /* Solve for the t value such that x0 + t*n = x */ double dmnsn_line_index(dmnsn_line l, dmnsn_vector x); diff --git a/libdimension/geometry.c b/libdimension/geometry.c index 8008224..01345cf 100644 --- a/libdimension/geometry.c +++ b/libdimension/geometry.c @@ -21,28 +21,6 @@ #include "dimension.h" #include -/* Construct a vector from x, y, and z. Just for convienence. */ -dmnsn_vector -dmnsn_vector_construct(double x, double y, double z) -{ - dmnsn_vector v = { .x = x, .y = y, .z = z }; - return v; -} - -/* Construct a matrix. */ -dmnsn_matrix -dmnsn_matrix_construct(double a0, double a1, double a2, double a3, - double b0, double b1, double b2, double b3, - double c0, double c1, double c2, double c3, - double d0, double d1, double d2, double d3) -{ - dmnsn_matrix m = { { { a0, a1, a2, a3 }, - { b0, b1, b2, b3 }, - { c0, c1, c2, c3 }, - { d0, d1, d2, d3 } } }; - return m; -} - /* Identity matrix */ dmnsn_matrix dmnsn_identity_matrix() @@ -104,89 +82,6 @@ dmnsn_rotation_matrix(dmnsn_vector theta) ); } -/* Construct a line */ -dmnsn_line -dmnsn_line_construct(dmnsn_vector x0, dmnsn_vector n) -{ - dmnsn_line l = { .x0 = x0, .n = n }; - return l; -} - -/* Add two vectors */ -dmnsn_vector -dmnsn_vector_add(dmnsn_vector lhs, dmnsn_vector rhs) -{ - /* 3 additions */ - dmnsn_vector v = { .x = lhs.x + rhs.x, - .y = lhs.y + rhs.y, - .z = lhs.z + rhs.z }; - return v; -} - -/* Subtract two vectors */ -dmnsn_vector -dmnsn_vector_sub(dmnsn_vector lhs, dmnsn_vector rhs) -{ - /* 3 additions */ - dmnsn_vector v = { .x = lhs.x - rhs.x, - .y = lhs.y - rhs.y, - .z = lhs.z - rhs.z }; - return v; -} - -/* Multiply a vector by a scalar */ -dmnsn_vector -dmnsn_vector_mul(double lhs, dmnsn_vector rhs) -{ - /* 3 multiplications */ - dmnsn_vector v = { .x = lhs*rhs.x, .y = lhs*rhs.y, .z = lhs*rhs.z }; - return v; -} - -/* Divide a vector by a scalar */ -dmnsn_vector -dmnsn_vector_div(dmnsn_vector lhs, double rhs) -{ - /* 3 divisions */ - dmnsn_vector v = { .x = lhs.x/rhs, .y = lhs.y/rhs, .z = lhs.z/rhs }; - return v; -} - -/* Dot product */ -double -dmnsn_vector_dot(dmnsn_vector lhs, dmnsn_vector rhs) -{ - /* 3 multiplications, 2 additions */ - return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z; -} - -/* Cross product */ -dmnsn_vector -dmnsn_vector_cross(dmnsn_vector lhs, dmnsn_vector rhs) -{ - /* 6 multiplications, 3 additions */ - dmnsn_vector v = { .x = lhs.y*rhs.z - lhs.z*rhs.y, - .y = lhs.z*rhs.x - lhs.x*rhs.z, - .z = lhs.x*rhs.y - lhs.y*rhs.x }; - return v; -} - -/* Length of vector */ -double -dmnsn_vector_norm(dmnsn_vector n) -{ - /* 1 sqrt, 3 multiplications, 2 additions */ - return sqrt(n.x*n.x + n.y*n.y + n.z*n.z); -} - -/* Normalized vector */ -dmnsn_vector -dmnsn_vector_normalize(dmnsn_vector n) -{ - /* 1 sqrt, 3 divisions, 3 multiplications, 2 additions */ - return dmnsn_vector_div(n, dmnsn_vector_norm(n)); -} - /* Matrix inversion helper functions */ typedef struct { double n[2][2]; } dmnsn_matrix2; @@ -455,14 +350,6 @@ dmnsn_matrix_line_mul(dmnsn_matrix lhs, dmnsn_line rhs) return l; } -/* A point on a line, l. Returns l.x0 + t*l.n */ -dmnsn_vector -dmnsn_line_point(dmnsn_line l, double t) -{ - /* 3 multiplications, 3 additions */ - return dmnsn_vector_add(l.x0, dmnsn_vector_mul(t, l.n)); -} - /* Solve for the t value such that x0 + t*n = x */ double dmnsn_line_index(dmnsn_line l, dmnsn_vector x) diff --git a/libdimension/inlines.c b/libdimension/inlines.c new file mode 100644 index 0000000..a03d08f --- /dev/null +++ b/libdimension/inlines.c @@ -0,0 +1,36 @@ +/************************************************************************* + * Copyright (C) 2008 Tavian Barnes * + * * + * 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 * + * . * + *************************************************************************/ + +#ifdef __cplusplus + /* C++ inline semantics */ + #define DMNSN_INLINE inline +#elif (__STDC_VERSION__ >= 199901L) + /* C99 inline semantics */ + #define DMNSN_INLINE +#elif defined(__GNUC__) + /* GCC inline semantics */ + #define DMNSN_INLINE inline +#else + /* Unknown C - mark functions static and hope the compiler is smart enough + to inline them */ + #define DMNSN_INLINE static +#endif + +#include "dimension.h" -- cgit v1.2.3