gpuray_glsl
annotate src/cone.cc @ 5:000017955721
fixed the cone normal
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 11 Nov 2014 20:25:59 +0200 |
parents | 2ed3da7dc0bc |
children |
rev | line source |
---|---|
nuclear@3 | 1 /* |
nuclear@3 | 2 Simple introductory ray tracer |
nuclear@3 | 3 Copyright (C) 2012 John Tsiombikas <nuclear@member.fsf.org> |
nuclear@3 | 4 |
nuclear@3 | 5 This program is free software: you can redistribute it and/or modify |
nuclear@3 | 6 it under the terms of the GNU General Public License as published by |
nuclear@3 | 7 the Free Software Foundation, either version 3 of the License, or |
nuclear@3 | 8 (at your option) any later version. |
nuclear@3 | 9 |
nuclear@3 | 10 This program is distributed in the hope that it will be useful, |
nuclear@3 | 11 but WITHOUT ANY WARRANTY; without even the implied warranty of |
nuclear@3 | 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
nuclear@3 | 13 GNU General Public License for more details. |
nuclear@3 | 14 |
nuclear@3 | 15 You should have received a copy of the GNU General Public License |
nuclear@3 | 16 along with this program. If not, see <http://www.gnu.org/licenses/>. |
nuclear@3 | 17 */ |
nuclear@2 | 18 #include "cone.h" |
nuclear@2 | 19 |
nuclear@2 | 20 Cone::Cone() |
nuclear@2 | 21 { |
nuclear@2 | 22 angle = M_PI / 4.0; |
nuclear@2 | 23 ymin = 0.0f; |
nuclear@2 | 24 ymax = 1.0f; |
nuclear@2 | 25 } |
nuclear@2 | 26 |
nuclear@2 | 27 Cone::Cone(float angle, float ymin, float ymax) |
nuclear@2 | 28 { |
nuclear@2 | 29 this->angle = angle; |
nuclear@2 | 30 this->ymin = ymin; |
nuclear@2 | 31 this->ymax = ymax; |
nuclear@2 | 32 } |
nuclear@2 | 33 |
nuclear@3 | 34 #define SQ(x) ((x) * (x)) |
nuclear@3 | 35 bool Cone::intersect(const Ray &inray, HitPoint *pt) const |
nuclear@2 | 36 { |
nuclear@3 | 37 Ray ray = inray.transformed(inv_xform); |
nuclear@3 | 38 |
nuclear@3 | 39 float slope = 2.0 * angle / M_PI; |
nuclear@3 | 40 |
nuclear@3 | 41 float a = SQ(ray.dir.x) - SQ(slope * ray.dir.y) + SQ(ray.dir.z); |
nuclear@3 | 42 float b = 2.0 * ray.origin.x * ray.dir.x - 2.0 * SQ(slope) * ray.origin.y * ray.dir.y + |
nuclear@3 | 43 2.0 * ray.origin.z * ray.dir.z; |
nuclear@3 | 44 float c = SQ(ray.origin.x) - SQ(slope * ray.origin.y) + SQ(ray.origin.z); |
nuclear@3 | 45 |
nuclear@3 | 46 float discr = b * b - 4.0 * a * c; |
nuclear@3 | 47 if(discr < 1e-4) |
nuclear@3 | 48 return false; |
nuclear@3 | 49 |
nuclear@3 | 50 float sqrt_discr = sqrt(discr); |
nuclear@3 | 51 float t0 = (-b + sqrt_discr) / (2.0 * a); |
nuclear@3 | 52 float t1 = (-b - sqrt_discr) / (2.0 * a); |
nuclear@3 | 53 |
nuclear@3 | 54 if(t0 < 1e-4) |
nuclear@3 | 55 t0 = t1; |
nuclear@3 | 56 if(t1 < 1e-4) |
nuclear@3 | 57 t1 = t0; |
nuclear@3 | 58 |
nuclear@3 | 59 float t = t0 < t1 ? t0 : t1; |
nuclear@3 | 60 if(t < 1e-4) |
nuclear@3 | 61 return false; |
nuclear@3 | 62 |
nuclear@3 | 63 // fill the HitPoint structure |
nuclear@3 | 64 pt->obj = this; |
nuclear@3 | 65 pt->dist = t; |
nuclear@3 | 66 pt->pos = ray.origin + ray.dir * t; |
nuclear@3 | 67 |
nuclear@4 | 68 if(pt->pos.y < ymin || pt->pos.y >= ymax) { |
nuclear@4 | 69 return false; |
nuclear@4 | 70 } |
nuclear@3 | 71 |
nuclear@4 | 72 float radius = pt->pos.y * slope; |
nuclear@4 | 73 pt->normal = Vector3(pt->pos.x, 0.0, pt->pos.z) / radius; |
nuclear@4 | 74 |
nuclear@5 | 75 float ny = -sin(angle); |
nuclear@4 | 76 float xzlen = sqrt(1.0 - ny * ny); |
nuclear@4 | 77 pt->normal.x *= xzlen; |
nuclear@4 | 78 pt->normal.y = ny; |
nuclear@4 | 79 pt->normal.z *= xzlen; |
nuclear@3 | 80 |
nuclear@3 | 81 pt->pos.transform(xform); |
nuclear@3 | 82 pt->normal.transform(dir_xform); |
nuclear@4 | 83 return true; |
nuclear@2 | 84 } |