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 }