nuclear@3: /* nuclear@3: Simple introductory ray tracer nuclear@3: Copyright (C) 2012 John Tsiombikas nuclear@3: nuclear@3: This program is free software: you can redistribute it and/or modify nuclear@3: it under the terms of the GNU General Public License as published by nuclear@3: the Free Software Foundation, either version 3 of the License, or nuclear@3: (at your option) any later version. nuclear@3: nuclear@3: This program is distributed in the hope that it will be useful, nuclear@3: but WITHOUT ANY WARRANTY; without even the implied warranty of nuclear@3: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nuclear@3: GNU General Public License for more details. nuclear@3: nuclear@3: You should have received a copy of the GNU General Public License nuclear@3: along with this program. If not, see . nuclear@3: */ nuclear@2: #include "cone.h" nuclear@2: nuclear@2: Cone::Cone() nuclear@2: { nuclear@2: angle = M_PI / 4.0; nuclear@2: ymin = 0.0f; nuclear@2: ymax = 1.0f; nuclear@2: } nuclear@2: nuclear@2: Cone::Cone(float angle, float ymin, float ymax) nuclear@2: { nuclear@2: this->angle = angle; nuclear@2: this->ymin = ymin; nuclear@2: this->ymax = ymax; nuclear@2: } nuclear@2: nuclear@3: #define SQ(x) ((x) * (x)) nuclear@3: bool Cone::intersect(const Ray &inray, HitPoint *pt) const nuclear@2: { nuclear@3: Ray ray = inray.transformed(inv_xform); nuclear@3: nuclear@3: float slope = 2.0 * angle / M_PI; nuclear@3: nuclear@3: float a = SQ(ray.dir.x) - SQ(slope * ray.dir.y) + SQ(ray.dir.z); nuclear@3: float b = 2.0 * ray.origin.x * ray.dir.x - 2.0 * SQ(slope) * ray.origin.y * ray.dir.y + nuclear@3: 2.0 * ray.origin.z * ray.dir.z; nuclear@3: float c = SQ(ray.origin.x) - SQ(slope * ray.origin.y) + SQ(ray.origin.z); nuclear@3: nuclear@3: float discr = b * b - 4.0 * a * c; nuclear@3: if(discr < 1e-4) nuclear@3: return false; nuclear@3: nuclear@3: float sqrt_discr = sqrt(discr); nuclear@3: float t0 = (-b + sqrt_discr) / (2.0 * a); nuclear@3: float t1 = (-b - sqrt_discr) / (2.0 * a); nuclear@3: nuclear@3: if(t0 < 1e-4) nuclear@3: t0 = t1; nuclear@3: if(t1 < 1e-4) nuclear@3: t1 = t0; nuclear@3: nuclear@3: float t = t0 < t1 ? t0 : t1; nuclear@3: if(t < 1e-4) nuclear@3: return false; nuclear@3: nuclear@3: // fill the HitPoint structure nuclear@3: pt->obj = this; nuclear@3: pt->dist = t; nuclear@3: pt->pos = ray.origin + ray.dir * t; nuclear@3: nuclear@3: pt->normal.z = sin(angle); nuclear@3: nuclear@3: //pt->normal = (pt->pos - pos) / radius; TODO continue here nuclear@3: nuclear@3: pt->pos.transform(xform); nuclear@3: pt->normal.transform(dir_xform); nuclear@2: }