oculus1
annotate src/bezmath.c @ 29:9a973ef0e2a3
fixed the performance issue under MacOSX by replacing glutSolidTeapot (which
uses glEvalMesh) with my own teapot generator.
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 27 Oct 2013 06:31:18 +0200 |
parents | |
children |
rev | line source |
---|---|
nuclear@29 | 1 #include <math.h> |
nuclear@29 | 2 #include "bezmath.h" |
nuclear@29 | 3 |
nuclear@29 | 4 static float bernstein(int i, float x); |
nuclear@29 | 5 |
nuclear@29 | 6 |
nuclear@29 | 7 struct vec3 v3_add(struct vec3 a, struct vec3 b) |
nuclear@29 | 8 { |
nuclear@29 | 9 a.x += b.x; |
nuclear@29 | 10 a.y += b.y; |
nuclear@29 | 11 a.z += b.z; |
nuclear@29 | 12 return a; |
nuclear@29 | 13 } |
nuclear@29 | 14 |
nuclear@29 | 15 struct vec3 v3_sub(struct vec3 a, struct vec3 b) |
nuclear@29 | 16 { |
nuclear@29 | 17 a.x -= b.x; |
nuclear@29 | 18 a.y -= b.y; |
nuclear@29 | 19 a.z -= b.z; |
nuclear@29 | 20 return a; |
nuclear@29 | 21 } |
nuclear@29 | 22 |
nuclear@29 | 23 struct vec3 v3_cross(struct vec3 a, struct vec3 b) |
nuclear@29 | 24 { |
nuclear@29 | 25 struct vec3 res; |
nuclear@29 | 26 res.x = a.y * b.z - a.z * b.y; |
nuclear@29 | 27 res.y = a.z * b.x - a.x * b.z; |
nuclear@29 | 28 res.z = a.x * b.y - a.y * b.x; |
nuclear@29 | 29 return res; |
nuclear@29 | 30 } |
nuclear@29 | 31 |
nuclear@29 | 32 struct vec3 v3_normalize(struct vec3 v) |
nuclear@29 | 33 { |
nuclear@29 | 34 float len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z); |
nuclear@29 | 35 v.x /= len; |
nuclear@29 | 36 v.y /= len; |
nuclear@29 | 37 v.z /= len; |
nuclear@29 | 38 return v; |
nuclear@29 | 39 } |
nuclear@29 | 40 |
nuclear@29 | 41 struct vec3 bezier_patch(struct vec3 *cp, float u, float v) |
nuclear@29 | 42 { |
nuclear@29 | 43 int i, j; |
nuclear@29 | 44 struct vec3 res = {0, 0, 0}; |
nuclear@29 | 45 |
nuclear@29 | 46 for(j=0; j<4; j++) { |
nuclear@29 | 47 for(i=0; i<4; i++) { |
nuclear@29 | 48 float bu = bernstein(i, u); |
nuclear@29 | 49 float bv = bernstein(j, v); |
nuclear@29 | 50 |
nuclear@29 | 51 res.x += cp->x * bu * bv; |
nuclear@29 | 52 res.y += cp->y * bu * bv; |
nuclear@29 | 53 res.z += cp->z * bu * bv; |
nuclear@29 | 54 |
nuclear@29 | 55 cp++; |
nuclear@29 | 56 } |
nuclear@29 | 57 } |
nuclear@29 | 58 return res; |
nuclear@29 | 59 } |
nuclear@29 | 60 |
nuclear@29 | 61 #define DT 0.001 |
nuclear@29 | 62 |
nuclear@29 | 63 struct vec3 bezier_patch_norm(struct vec3 *cp, float u, float v) |
nuclear@29 | 64 { |
nuclear@29 | 65 struct vec3 tang, bitan, norm; |
nuclear@29 | 66 |
nuclear@29 | 67 tang = v3_sub(bezier_patch(cp, u + DT, v), bezier_patch(cp, u - DT, v)); |
nuclear@29 | 68 bitan = v3_sub(bezier_patch(cp, u, v + DT), bezier_patch(cp, u, v - DT)); |
nuclear@29 | 69 norm = v3_cross(tang, bitan); |
nuclear@29 | 70 |
nuclear@29 | 71 return v3_normalize(norm); |
nuclear@29 | 72 } |
nuclear@29 | 73 |
nuclear@29 | 74 |
nuclear@29 | 75 |
nuclear@29 | 76 static float bernstein(int i, float x) |
nuclear@29 | 77 { |
nuclear@29 | 78 float invx = 1.0 - x; |
nuclear@29 | 79 |
nuclear@29 | 80 switch(i) { |
nuclear@29 | 81 case 0: |
nuclear@29 | 82 return invx * invx * invx; |
nuclear@29 | 83 case 1: |
nuclear@29 | 84 return 3 * x * invx * invx; |
nuclear@29 | 85 case 2: |
nuclear@29 | 86 return 3 * x * x * invx; |
nuclear@29 | 87 case 3: |
nuclear@29 | 88 return x * x * x; |
nuclear@29 | 89 default: |
nuclear@29 | 90 break; |
nuclear@29 | 91 } |
nuclear@29 | 92 return 0; |
nuclear@29 | 93 } |