Update Sphere to inherit from Object

- Had to do a couple updates here to adapt to the new code style...
- Update DoesIntersect for code style and to pass back t values in the vector
instead of the float array.
This commit is contained in:
Eryn Wells 2014-07-20 16:49:15 -07:00
parent 2036521f42
commit 19aeb7b14e
2 changed files with 51 additions and 50 deletions

View file

@ -14,6 +14,7 @@
#include "object.h" #include "object.h"
#include "object_sphere.h" #include "object_sphere.h"
namespace charles {
/* /*
* Sphere::Sphere -- * Sphere::Sphere --
@ -36,7 +37,7 @@ Sphere::Sphere(float r)
Sphere::Sphere(Vector3 o, float r) Sphere::Sphere(Vector3 o, float r)
: Shape(o), : Object(o),
radius(r) radius(r)
{ } { }
@ -61,69 +62,64 @@ Sphere::set_radius(float r)
/* /*
* Sphere::does_intersect -- * Sphere::DoesIntersect --
*
* Compute the intersection of a ray with this Sphere. All intersection t values are returned in the **t argument. The
* number of values returned therein is indicated by the return value. Memory is allocated at *t. It is the caller's
* responsibility to free it when it is no longer needed. If 0 is returned, no memory needs to be freed.
*/ */
int bool
Sphere::does_intersect(const Ray &ray, float **t) Sphere::DoesIntersect(const Ray& ray,
TVector& t)
const const
{ {
// Origin of the vector in object space. /* Origin of the vector in object space. */
Vector3 ray_origin_obj = ray.origin - get_origin(); Vector3 rayOriginObj = ray.origin - GetOrigin();
// Coefficients for quadratic equation. /* Coefficients for quadratic equation. */
float a = ray.direction.dot(ray.direction); Double a = ray.direction.dot(ray.direction);
float b = ray.direction.dot(ray_origin_obj) * 2.0; Double b = ray.direction.dot(rayOriginObj) * 2.0;
float c = ray_origin_obj.dot(ray_origin_obj) - (radius * radius); Double c = rayOriginObj.dot(rayOriginObj) - (radius * radius);
// Discriminant for the quadratic equation. /* Discriminant for the quadratic equation. */
float discrim = (b * b) - (4.0 * a * c); Double discrim = (b * b) - (4.0 * a * c);
// If the discriminant is less than zero, there are no real (as in not imaginary) solutions to this intersection. /*
* If the discriminant is less than zero, there are no real (as in not
* imaginary) solutions to this intersection.
*/
if (discrim < 0) { if (discrim < 0) {
return 0; return false;
}
// Compute the intersections, the roots of the quadratic equation. Spheres have at most two intersections.
float sqrt_discrim = sqrtf(discrim);
float t0 = (-b - sqrt_discrim) / (2.0 * a);
float t1 = (-b + sqrt_discrim) / (2.0 * a);
// If t[1] is less than t[0], swap them (t[0] will always be the first intersection).
if (t1 < t0) {
float tmp = t0;
t0 = t1;
t1 = tmp;
} }
/* /*
* If the farther intersection of the two is in the negative direction, the sphere is in the ray's negative * Compute the intersections, the roots of the quadratic equation. Spheres
* direction. * have at most two intersections.
*/
Double sqrtDiscrim = sqrt(discrim);
Double t0 = (-b - sqrtDiscrim) / (2.0 * a);
Double t1 = (-b + sqrtDiscrim) / (2.0 * a);
/*
* If the farther intersection of the two is in the negative direction, the
* sphere is in the ray's negative direction.
*/ */
if (t1 < 0) { if (t1 < 0) {
return 0; return false;
} }
/* if (t0 == t1) {
* Allocate the memory and store the values. It's possible the two values are equal. Only allocate enough memory to t.push_back(t0);
* store the required number of values. }
*/ else {
int nints = (t0 != t1) ? 2 : 1; /* Push these on in ascending order, nearest intersection to farthest. */
if (t != NULL) { if (t0 < t1) {
*t = new float[nints]; t.push_back(t0);
if (*t == NULL) { t.push_back(t1);
return 0;
} }
(*t)[0] = t0; else {
if (nints > 1) { t.push_back(t1);
(*t)[1] = t1; t.push_back(t0);
} }
} }
return nints; return true;
} }
@ -136,7 +132,7 @@ bool
Sphere::point_is_on_surface(const Vector3 &p) Sphere::point_is_on_surface(const Vector3 &p)
const const
{ {
Vector3 o = get_origin(); Vector3 o = GetOrigin();
float x = p.x - o.x; float x = p.x - o.x;
float y = p.y - o.y; float y = p.y - o.y;
float z = p.z - o.z; float z = p.z - o.z;
@ -156,7 +152,9 @@ Sphere::compute_normal(const Vector3 &p)
const const
{ {
// The fun thing about sphere is the normal to any point on the sphere is the point itself. Woo! // The fun thing about sphere is the normal to any point on the sphere is the point itself. Woo!
Vector3 normal = p - get_origin(); Vector3 normal = p - GetOrigin();
normal.normalize(); normal.normalize();
return normal; return normal;
} }
} /* namespace charles */

View file

@ -11,9 +11,10 @@
#include "basics.h" #include "basics.h"
#include "object.h" #include "object.h"
namespace charles {
class Sphere class Sphere
: public Shape : public Object
{ {
public: public:
Sphere(); Sphere();
@ -23,11 +24,13 @@ public:
float get_radius(); float get_radius();
void set_radius(float r); void set_radius(float r);
int does_intersect(const Ray &ray, float **t) const; bool DoesIntersect(const Ray& ray, TVector& t) const;
bool point_is_on_surface(const Vector3 &p) const; bool point_is_on_surface(const Vector3 &p) const;
Vector3 compute_normal(const Vector3 &p) const; Vector3 compute_normal(const Vector3 &p) const;
private: private:
float radius; float radius;
}; };
} /* namespace charles */
#endif #endif