gpuray_glsl

annotate src/cone.cc @ 3:297dbc5080c4

cone intersection
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 09 Nov 2014 20:13:33 +0200
parents 6e3a4daf3159
children 2ed3da7dc0bc
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@3 68 pt->normal.z = sin(angle);
nuclear@3 69
nuclear@3 70 //pt->normal = (pt->pos - pos) / radius; TODO continue here
nuclear@3 71
nuclear@3 72 pt->pos.transform(xform);
nuclear@3 73 pt->normal.transform(dir_xform);
nuclear@2 74 }