polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

vec3.h (6272B)


      1 
      2 #ifndef VEC3_H
      3 #define VEC3_H
      4 
      5 #include <stdlib.h>
      6 #include <math.h>
      7 
      8 typedef float vec3;
      9 
     10 #define approxeq(a, b) (fabs(a-b) < EPSILON)
     11 #define EPSILON 0.0001
     12 #define vec3_approxeq(a, b) vec3_eq(a, b, EPSILON)
     13 #define V3(x,y,z) ((vec3[3]){x,y,z})
     14 
     15 static inline vec3 *vec3_create(vec3 *vec) {
     16     vec3 *dest = calloc(sizeof(float_t), 3);
     17 
     18     if (vec) {
     19         dest[0] = vec[0];
     20         dest[1] = vec[1];
     21         dest[2] = vec[2];
     22     } else {
     23         dest[0] = dest[1] = dest[2] = 0;
     24     }
     25 
     26     return dest;
     27 }
     28 
     29 static inline vec3 *vec3_set(vec3 *vec, vec3 *dest) {
     30     dest[0] = vec[0];
     31     dest[1] = vec[1];
     32     dest[2] = vec[2];
     33 
     34     return dest;
     35 }
     36 
     37 static inline vec3 *vec3_add(vec3 *vec, vec3 *vec2, vec3 *dest) {
     38     if (!dest || vec == dest) {
     39         vec[0] += vec2[0];
     40         vec[1] += vec2[1];
     41         vec[2] += vec2[2];
     42         return vec;
     43     }
     44 
     45     dest[0] = vec[0] + vec2[0];
     46     dest[1] = vec[1] + vec2[1];
     47     dest[2] = vec[2] + vec2[2];
     48 
     49     return dest;
     50 }
     51 
     52 static inline vec3 *vec3_subtract(vec3 *vec, vec3 *vec2, vec3 *dest) {
     53     if (!dest || vec == dest) {
     54         vec[0] -= vec2[0];
     55         vec[1] -= vec2[1];
     56         vec[2] -= vec2[2];
     57         return vec;
     58     }
     59 
     60     dest[0] = vec[0] - vec2[0];
     61     dest[1] = vec[1] - vec2[1];
     62     dest[2] = vec[2] - vec2[2];
     63     return dest;
     64 }
     65 
     66 static inline vec3 *vec3_multiply(vec3 *vec, vec3 *vec2, vec3 *dest) {
     67     if (!dest || vec == dest) {
     68         vec[0] *= vec2[0];
     69         vec[1] *= vec2[1];
     70         vec[2] *= vec2[2];
     71         return vec;
     72     }
     73 
     74     dest[0] = vec[0] * vec2[0];
     75     dest[1] = vec[1] * vec2[1];
     76     dest[2] = vec[2] * vec2[2];
     77     return dest;
     78 }
     79 
     80 static inline vec3 *vec3_negate(vec3 *vec, vec3 *dest) {
     81     if (!dest) { dest = vec; }
     82 
     83     dest[0] = -vec[0];
     84     dest[1] = -vec[1];
     85     dest[2] = -vec[2];
     86     return dest;
     87 }
     88 
     89 static inline vec3 *vec3_scale(vec3 *vec, float val, vec3 *dest) {
     90     if (!dest || vec == dest) {
     91         vec[0] *= val;
     92         vec[1] *= val;
     93         vec[2] *= val;
     94         return vec;
     95     }
     96 
     97     dest[0] = vec[0] * val;
     98     dest[1] = vec[1] * val;
     99     dest[2] = vec[2] * val;
    100     return dest;
    101 }
    102 
    103 static inline vec3 *vec3_normalize(vec3 *vec, vec3 *dest) {
    104     if (!dest) { dest = vec; }
    105 
    106     float x = vec[0], y = vec[1], z = vec[2],
    107         len = sqrt(x * x + y * y + z * z);
    108 
    109     if (!len) {
    110         dest[0] = 0;
    111         dest[1] = 0;
    112         dest[2] = 0;
    113         return dest;
    114     } else if (len == 1) {
    115         dest[0] = x;
    116         dest[1] = y;
    117         dest[2] = z;
    118         return dest;
    119     }
    120 
    121     len = 1 / len;
    122     dest[0] = x * len;
    123     dest[1] = y * len;
    124     dest[2] = z * len;
    125     return dest;
    126 }
    127 
    128 static inline vec3 *vec3_cross (vec3 *vec, vec3 *vec2, vec3 *dest) {
    129     if (!dest) { dest = vec; }
    130 
    131     float x = vec[0], y = vec[1], z = vec[2],
    132         x2 = vec2[0], y2 = vec2[1], z2 = vec2[2];
    133 
    134     dest[0] = y * z2 - z * y2;
    135     dest[1] = z * x2 - x * z2;
    136     dest[2] = x * y2 - y * x2;
    137     return dest;
    138 }
    139 
    140 static inline float vec3_lengthsq(vec3 *vec) {
    141   float x = vec[0], y = vec[1], z = vec[2];
    142   return x * x + y * y + z * z;
    143 }
    144 
    145 static inline float vec3_length(vec3 *vec) {
    146     return sqrt(vec3_lengthsq(vec));
    147 }
    148 
    149 static inline float vec3_dot(vec3 *vec, vec3 *vec2) {
    150     return vec[0] * vec2[0] + vec[1] * vec2[1] + vec[2] * vec2[2];
    151 }
    152 
    153 static inline vec3 *vec3_direction (vec3 *vec, vec3 *vec2, vec3 *dest) {
    154     if (!dest) { dest = vec; }
    155 
    156     float x = vec[0] - vec2[0],
    157         y = vec[1] - vec2[1],
    158         z = vec[2] - vec2[2],
    159         len = sqrt(x * x + y * y + z * z);
    160 
    161     if (!len) {
    162         dest[0] = 0;
    163         dest[1] = 0;
    164         dest[2] = 0;
    165         return dest;
    166     }
    167 
    168     len = 1 / len;
    169     dest[0] = x * len;
    170     dest[1] = y * len;
    171     dest[2] = z * len;
    172     return dest;
    173 }
    174 
    175 static inline vec3 *vec3_lerp(vec3 *vec, vec3 *vec2, float lerp, vec3 *dest) {
    176     if (!dest) { dest = vec; }
    177 
    178     dest[0] = vec[0] + lerp * (vec2[0] - vec[0]);
    179     dest[1] = vec[1] + lerp * (vec2[1] - vec[1]);
    180     dest[2] = vec[2] + lerp * (vec2[2] - vec[2]);
    181 
    182     return dest;
    183 }
    184 
    185 static inline float vec3_distsq(vec3 *vec, vec3 *vec2) {
    186   float x = vec2[0] - vec[0],
    187         y = vec2[1] - vec[1],
    188         z = vec2[2] - vec[2];
    189 
    190   return x*x + y*y + z*z;
    191 }
    192 
    193 
    194 static inline vec3 *vec3_all(vec3 *vec, float n) {
    195   vec[0] = n;
    196   vec[1] = n;
    197   vec[2] = n;
    198   return vec;
    199 }
    200 
    201 /* vec3 *vec3_unproject(vec3 *vec, mat4 view, mat4 proj, vec4_t viewport, vec3 *dest) { */
    202 /*     if (!dest) { dest = vec; } */
    203 
    204 /*     mat4 m = mat4_create(NULL); */
    205 /*     float *v = malloc(sizeof(float) * 4); */
    206 
    207 /*     v[0] = (vec[0] - viewport[0]) * 2.0 / viewport[2] - 1.0; */
    208 /*     v[1] = (vec[1] - viewport[1]) * 2.0 / viewport[3] - 1.0; */
    209 /*     v[2] = 2.0 * vec[2] - 1.0; */
    210 /*     v[3] = 1.0; */
    211 
    212 /*     mat4_multiply(proj, view, m); */
    213 /*     if(!mat4_inverse(m, NULL)) { return NULL; } */
    214 
    215 /*     mat4_multiplyVec4(m, v, NULL); */
    216 /*     if(v[3] == 0.0) { return NULL; } */
    217 
    218 /*     dest[0] = v[0] / v[3]; */
    219 /*     dest[1] = v[1] / v[3]; */
    220 /*     dest[2] = v[2] / v[3]; */
    221 
    222 /*     return dest; */
    223 /* } */
    224 
    225 static inline int vec3_isall(vec3 *vec, float n) {
    226   for (int i = 0; i < 3; ++i) {
    227     if (!approxeq(vec[i], n))
    228       return 0;
    229   }
    230 
    231   return 1;
    232 }
    233 
    234 static inline int vec3_eq(vec3 *a, vec3 *b, float precision) {
    235   return fabs(a[0] - b[0]) <= precision &&
    236          fabs(a[1] - b[1]) <= precision &&
    237          fabs(a[2] - b[2]) <= precision;
    238 }
    239 
    240 
    241 static inline void vec3_copy(vec3 *a, vec3 *dest) {
    242   dest[0] = a[0];
    243   dest[1] = a[1];
    244   dest[2] = a[2];
    245 }
    246 
    247 
    248 static inline double max(double a, double b) {
    249     return a > b ? a : b;
    250 }
    251 
    252 static inline double min(double a, double b) {
    253     return a < b ? a : b;
    254 }
    255 
    256 static inline vec3 *vec3_min(vec3 *vec, vec3* vec2, vec3 *dest) {
    257     dest[0] = min(vec[0], vec2[0]);
    258     dest[1] = min(vec[1], vec2[1]);
    259     dest[2] = min(vec[2], vec2[2]);
    260     return dest;
    261 }
    262 
    263 static inline vec3 *vec3_max(vec3 *vec, vec3* vec2, vec3 *dest) {
    264     dest[0] = max(vec[0], vec2[0]);
    265     dest[1] = max(vec[1], vec2[1]);
    266     dest[2] = max(vec[2], vec2[2]);
    267     return dest;
    268 }
    269 
    270 
    271 static inline vec3 *vec3_from_yaw_pitch(float yaw, float pitch, float *dest) {
    272     float theta = yaw;
    273     float phi = pitch;
    274     dest[0] = sin(theta) * cos(phi);
    275     dest[1] = sin(theta) * sin(phi);
    276     dest[2] = cos(theta);
    277     return dest;
    278 }
    279 
    280 
    281 
    282 #endif /* VEC3_H */