Define constructors for Object and Shape; move a bunch of Sphere code to object_sphere
This commit is contained in:
parent
f062efc349
commit
e5601e7f43
2 changed files with 38 additions and 69 deletions
101
src/object.cc
101
src/object.cc
|
@ -1,11 +1,10 @@
|
||||||
/* object.c
|
/* object.c
|
||||||
*
|
*
|
||||||
* Definition of scene Objects.
|
* Definition of generic scene objects.
|
||||||
*
|
*
|
||||||
* Eryn Wells <eryn@erynwells.me>
|
* Eryn Wells <eryn@erynwells.me>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
@ -13,11 +12,7 @@
|
||||||
#include "basics.h"
|
#include "basics.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
|
|
||||||
|
#pragma mark - Objects
|
||||||
static int sphere_does_intersect(Object *obj, Ray ray, float **t);
|
|
||||||
static int sphere_point_lies_on_surface(Object *obj, Vector3 p);
|
|
||||||
static Vector3 sphere_compute_normal(Object *obj, Vector3 p);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Object::Object --
|
* Object::Object --
|
||||||
|
@ -25,7 +20,17 @@ static Vector3 sphere_compute_normal(Object *obj, Vector3 p);
|
||||||
* Default constructor. Create a new Object with an origin at (0, 0, 0).
|
* Default constructor. Create a new Object with an origin at (0, 0, 0).
|
||||||
*/
|
*/
|
||||||
Object::Object()
|
Object::Object()
|
||||||
: origin()
|
: Object(Vector3::Zero)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Object::Object --
|
||||||
|
*
|
||||||
|
* Constructor. Create a new Object with an origin at o.
|
||||||
|
*/
|
||||||
|
Object::Object(Vector3 o)
|
||||||
|
: origin(o)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,6 +42,7 @@ Object::Object()
|
||||||
*/
|
*/
|
||||||
Vector3
|
Vector3
|
||||||
Object::get_origin()
|
Object::get_origin()
|
||||||
|
const
|
||||||
{
|
{
|
||||||
return origin;
|
return origin;
|
||||||
}
|
}
|
||||||
|
@ -47,77 +53,33 @@ Object::set_origin(Vector3 v)
|
||||||
origin = v;
|
origin = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Shapes
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sphere::does_intersect --
|
* Shape::Shape --
|
||||||
*
|
*
|
||||||
* Compute the intersection of a ray with this Sphere. All intersection t values are returned in the **t argument. The
|
* Default constructor. Create a new Shape with an origin at (0, 0, 0).
|
||||||
* 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
|
Shape::Shape()
|
||||||
Sphere::does_intersect(const Ray &ray, float **t)
|
: Object()
|
||||||
{
|
{ }
|
||||||
// Origin of the vector in object space.
|
|
||||||
Vector3 ray_origin_obj = ray.origin - get_origin();
|
|
||||||
|
|
||||||
// Coefficients for quadratic equation.
|
|
||||||
float a = ray.direction.dot(ray.direction);
|
|
||||||
float b = ray.direction.dot(ray_origin_obj) * 2.0;
|
|
||||||
float c = ray_origin_obj.dot(ray_origin_obj) - (radius * radius);
|
|
||||||
|
|
||||||
// Discriminant for the quadratic equation.
|
|
||||||
float 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 (discrim < 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
* direction.
|
|
||||||
*/
|
|
||||||
if (t1 < 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate the memory and store the values. It's possible the two values are equal. Only allocate enough memory to
|
|
||||||
* store the required number of values.
|
|
||||||
*/
|
|
||||||
int nints = (t0 != t1) ? 2 : 1;
|
|
||||||
if (t != NULL) {
|
|
||||||
*t = malloc(sizeof(float) * nints);
|
|
||||||
if (*t == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
(*t)[0] = t0;
|
|
||||||
if (nints > 1) {
|
|
||||||
(*t)[1] = t1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nints;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shape::Shape --
|
||||||
|
*
|
||||||
|
* Constructor. Create a new Shape with an origin at o.
|
||||||
|
*/
|
||||||
|
Shape::Shape(Vector3 o)
|
||||||
|
: Object(o)
|
||||||
|
{ }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sphere_point_lies_on_surface --
|
* sphere_point_lies_on_surface --
|
||||||
*
|
*
|
||||||
* Determine if a point lies on the given sphere.
|
* Determine if a point lies on the given sphere.
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
int
|
int
|
||||||
sphere_point_lies_on_surface(Object *obj, Vector3 p)
|
sphere_point_lies_on_surface(Object *obj, Vector3 p)
|
||||||
{
|
{
|
||||||
|
@ -131,6 +93,7 @@ sphere_point_lies_on_surface(Object *obj, Vector3 p)
|
||||||
|
|
||||||
return (x * x) + (y * y) + (z * z) == (r * r);
|
return (x * x) + (y * y) + (z * z) == (r * r);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -139,6 +102,7 @@ sphere_point_lies_on_surface(Object *obj, Vector3 p)
|
||||||
* Compute the normal for the given Object (which must be a Sphere) at the given point. This point must lie on the
|
* Compute the normal for the given Object (which must be a Sphere) at the given point. This point must lie on the
|
||||||
* surface of the object.
|
* surface of the object.
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
/* static */ Vector3
|
/* static */ Vector3
|
||||||
sphere_compute_normal(Object *obj, Vector3 p)
|
sphere_compute_normal(Object *obj, Vector3 p)
|
||||||
{
|
{
|
||||||
|
@ -152,3 +116,4 @@ sphere_compute_normal(Object *obj, Vector3 p)
|
||||||
// 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!
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -17,8 +17,9 @@ class Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Object();
|
Object();
|
||||||
|
Object(Vector3 o);
|
||||||
|
|
||||||
Vector3 get_origin();
|
Vector3 get_origin() const;
|
||||||
void set_origin(Vector3 v);
|
void set_origin(Vector3 v);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -30,6 +31,9 @@ class Shape
|
||||||
: public Object
|
: public Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Shape();
|
||||||
|
Shape(Vector3 o);
|
||||||
|
|
||||||
virtual int does_intersect(const Ray &ray, float **t) = 0;
|
virtual int does_intersect(const Ray &ray, float **t) = 0;
|
||||||
virtual Vector3 compute_normal(const Vector3 &p) = 0;
|
virtual Vector3 compute_normal(const Vector3 &p) = 0;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue