goat3d
diff libs/vmath/geom.c @ 27:4deb0b12fe14
wtf... corrupted heap?
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 29 Sep 2013 08:20:19 +0300 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/vmath/geom.c Sun Sep 29 08:20:19 2013 +0300 1.3 @@ -0,0 +1,150 @@ 1.4 +/* 1.5 +libvmath - a vector math library 1.6 +Copyright (C) 2004-2011 John Tsiombikas <nuclear@member.fsf.org> 1.7 + 1.8 +This program is free software: you can redistribute it and/or modify 1.9 +it under the terms of the GNU Lesser General Public License as published 1.10 +by the Free Software Foundation, either version 3 of the License, or 1.11 +(at your option) any later version. 1.12 + 1.13 +This program is distributed in the hope that it will be useful, 1.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 1.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.16 +GNU Lesser General Public License for more details. 1.17 + 1.18 +You should have received a copy of the GNU Lesser General Public License 1.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 1.20 +*/ 1.21 + 1.22 + 1.23 +#include <math.h> 1.24 +#include "geom.h" 1.25 +#include "vector.h" 1.26 + 1.27 +plane_t plane_cons(scalar_t nx, scalar_t ny, scalar_t nz, scalar_t d) 1.28 +{ 1.29 + plane_t p; 1.30 + p.norm.x = nx; 1.31 + p.norm.y = ny; 1.32 + p.norm.z = nz; 1.33 + p.d = d; 1.34 + return p; 1.35 +} 1.36 + 1.37 +plane_t plane_poly(vec3_t v0, vec3_t v1, vec3_t v2) 1.38 +{ 1.39 + vec3_t a, b, norm; 1.40 + 1.41 + a = v3_sub(v1, v0); 1.42 + b = v3_sub(v2, v0); 1.43 + norm = v3_cross(a, b); 1.44 + norm = v3_normalize(norm); 1.45 + 1.46 + return plane_ptnorm(v0, norm); 1.47 +} 1.48 + 1.49 +plane_t plane_ptnorm(vec3_t pt, vec3_t normal) 1.50 +{ 1.51 + plane_t plane; 1.52 + 1.53 + plane.norm = normal; 1.54 + plane.d = v3_dot(pt, normal); 1.55 + 1.56 + return plane; 1.57 +} 1.58 + 1.59 +plane_t plane_invert(plane_t p) 1.60 +{ 1.61 + p.norm = v3_neg(p.norm); 1.62 + p.d = -p.d; 1.63 + return p; 1.64 +} 1.65 + 1.66 +scalar_t plane_signed_dist(plane_t plane, vec3_t pt) 1.67 +{ 1.68 + vec3_t pp = plane_point(plane); 1.69 + vec3_t pptopt = v3_sub(pt, pp); 1.70 + return v3_dot(pptopt, plane.norm); 1.71 +} 1.72 + 1.73 +scalar_t plane_dist(plane_t plane, vec3_t pt) 1.74 +{ 1.75 + return fabs(plane_signed_dist(plane, pt)); 1.76 +} 1.77 + 1.78 +vec3_t plane_point(plane_t plane) 1.79 +{ 1.80 + return v3_scale(plane.norm, plane.d); 1.81 +} 1.82 + 1.83 +int plane_ray_intersect(ray_t ray, plane_t plane, scalar_t *pos) 1.84 +{ 1.85 + vec3_t pt, orig_to_pt; 1.86 + scalar_t ndotdir; 1.87 + 1.88 + pt = plane_point(plane); 1.89 + ndotdir = v3_dot(plane.norm, ray.dir); 1.90 + 1.91 + if(fabs(ndotdir) < 1e-7) { 1.92 + return 0; 1.93 + } 1.94 + 1.95 + if(pos) { 1.96 + orig_to_pt = v3_sub(pt, ray.origin); 1.97 + *pos = v3_dot(plane.norm, orig_to_pt) / ndotdir; 1.98 + } 1.99 + return 1; 1.100 +} 1.101 + 1.102 +sphere_t sphere_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t rad) 1.103 +{ 1.104 + sphere_t sph; 1.105 + sph.pos.x = x; 1.106 + sph.pos.y = y; 1.107 + sph.pos.z = z; 1.108 + sph.rad = rad; 1.109 + return sph; 1.110 +} 1.111 + 1.112 +int sphere_ray_intersect(ray_t ray, sphere_t sph, scalar_t *pos) 1.113 +{ 1.114 + scalar_t a, b, c, d, sqrt_d, t1, t2, t; 1.115 + 1.116 + a = v3_dot(ray.dir, ray.dir); 1.117 + b = 2.0 * ray.dir.x * (ray.origin.x - sph.pos.x) + 1.118 + 2.0 * ray.dir.y * (ray.origin.y - sph.pos.y) + 1.119 + 2.0 * ray.dir.z * (ray.origin.z - sph.pos.z); 1.120 + c = v3_dot(sph.pos, sph.pos) + v3_dot(ray.origin, ray.origin) + 1.121 + 2.0 * v3_dot(v3_neg(sph.pos), ray.origin) - sph.rad * sph.rad; 1.122 + 1.123 + d = b * b - 4.0 * a * c; 1.124 + if(d < 0.0) { 1.125 + return 0; 1.126 + } 1.127 + 1.128 + sqrt_d = sqrt(d); 1.129 + t1 = (-b + sqrt_d) / (2.0 * a); 1.130 + t2 = (-b - sqrt_d) / (2.0 * a); 1.131 + 1.132 + if(t1 < 1e-7 || t1 > 1.0) { 1.133 + t1 = t2; 1.134 + } 1.135 + if(t2 < 1e-7 || t2 > 1.0) { 1.136 + t2 = t1; 1.137 + } 1.138 + t = t1 < t2 ? t1 : t2; 1.139 + 1.140 + if(t < 1e-7 || t > 1.0) { 1.141 + return 0; 1.142 + } 1.143 + 1.144 + if(pos) { 1.145 + *pos = t; 1.146 + } 1.147 + return 1; 1.148 +} 1.149 + 1.150 +int sphere_sphere_intersect(sphere_t sph1, sphere_t sph2, scalar_t *pos, scalar_t *rad) 1.151 +{ 1.152 + return -1; 1.153 +}