Fixed boolean objects to determine if rays start inside or outside the boolean; changed constructors to accept a list of shapes instead of just two shapes; changed parser to accept any number of top-level shapes inside of a boolean shape block; changed scenes/die.fart to reflect this change (a drastic simplification)
git-svn-id: svn://anubis/fart/trunk@215 7f9b0f55-74a9-4bce-be96-3c2cd072584d
This commit is contained in:
parent
f103b71ed6
commit
5590c533ce
2
.todo
2
.todo
@ -4,14 +4,12 @@ FART To-Do List
|
|||||||
High Priority:
|
High Priority:
|
||||||
- Add distribution infrastructure
|
- Add distribution infrastructure
|
||||||
- Multi-threading
|
- Multi-threading
|
||||||
- Rework booleans to base them on regions instead of in/out for each side
|
|
||||||
|
|
||||||
Medium Priority:
|
Medium Priority:
|
||||||
- Shape definitions / reusability
|
- Shape definitions / reusability
|
||||||
- Scene file pre-parser to allow includes, macros, and comments
|
- Scene file pre-parser to allow includes, macros, and comments
|
||||||
- Vim syntax file
|
- Vim syntax file
|
||||||
- Add jitter parameter to lights to effect soft shadow edges
|
- Add jitter parameter to lights to effect soft shadow edges
|
||||||
- Allow >2 sub-shapes in boolean shape definitions in scene files
|
|
||||||
|
|
||||||
Low Priority:
|
Low Priority:
|
||||||
- Refraction
|
- Refraction
|
||||||
|
@ -465,9 +465,8 @@ refptr<Shape> Scene::processSphere(refptr<Node> node)
|
|||||||
|
|
||||||
refptr<Shape> Scene::processBool(refptr<Node> node)
|
refptr<Shape> Scene::processBool(refptr<Node> node)
|
||||||
{
|
{
|
||||||
refptr<Shape> shape1, shape2;
|
vector< refptr<Shape> > shapes;
|
||||||
refptr<Material> material;
|
refptr<Material> material;
|
||||||
int shapes_seen = 0;
|
|
||||||
|
|
||||||
bool restore_transform = processTransforms(node);
|
bool restore_transform = processTransforms(node);
|
||||||
|
|
||||||
@ -477,14 +476,9 @@ refptr<Shape> Scene::processBool(refptr<Node> node)
|
|||||||
{
|
{
|
||||||
if ( (*it)->isShape() )
|
if ( (*it)->isShape() )
|
||||||
{
|
{
|
||||||
switch (shapes_seen)
|
refptr<Shape> shape = processShape(*it);
|
||||||
{
|
if ( ! shape.isNull() )
|
||||||
case 0: shape1 = processShape(*it);
|
shapes.push_back(shape);
|
||||||
break;
|
|
||||||
case 1: shape2 = processShape(*it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
shapes_seen++;
|
|
||||||
}
|
}
|
||||||
else if ( (*it)->isMaterial() )
|
else if ( (*it)->isMaterial() )
|
||||||
{
|
{
|
||||||
@ -492,30 +486,20 @@ refptr<Shape> Scene::processBool(refptr<Node> node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shapes_seen < 2 || shape1.isNull() || shape2.isNull())
|
if (shapes.size() < 2)
|
||||||
{
|
{
|
||||||
if (shapes_seen < 2)
|
cerr << "Error: boolean objects must have 2 or more sub-objects!"
|
||||||
cerr << __FILE__ << ": " << __LINE__
|
|
||||||
<< ": error: only saw "
|
|
||||||
<< shapes_seen
|
|
||||||
<< " child shapes!"
|
|
||||||
<< endl;
|
<< endl;
|
||||||
if (shape1.isNull())
|
|
||||||
cerr << __FILE__ << ": " << __LINE__
|
|
||||||
<< ": error: shape1 is null!" << endl;
|
|
||||||
if (shape2.isNull())
|
|
||||||
cerr << __FILE__ << ": " << __LINE__
|
|
||||||
<< ": error: shape2 is null!" << endl;
|
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
refptr<Shape> shape;
|
refptr<Shape> shape;
|
||||||
if ( typeid(*node) == typeid(IntersectNode) )
|
if ( typeid(*node) == typeid(IntersectNode) )
|
||||||
shape = new Intersect(shape1, shape2);
|
shape = new Intersect(shapes);
|
||||||
else if ( typeid(*node) == typeid(UnionNode) )
|
else if ( typeid(*node) == typeid(UnionNode) )
|
||||||
shape = new Union(shape1, shape2);
|
shape = new Union(shapes);
|
||||||
else if ( typeid(*node) == typeid(SubtractNode) )
|
else if ( typeid(*node) == typeid(SubtractNode) )
|
||||||
shape = new Subtract(shape1, shape2);
|
shape = new Subtract(shapes);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cerr << __FILE__ << ": " << __LINE__
|
cerr << __FILE__ << ": " << __LINE__
|
||||||
|
@ -103,6 +103,18 @@ scene: SCENE LCURLY scene_items RCURLY {
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
bool_items: /* empty */
|
||||||
|
| bool_item bool_items {
|
||||||
|
$$ = new ItemsNode();
|
||||||
|
$$->addChild($1);
|
||||||
|
$$->addChildren($2);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
bool_item: shape
|
||||||
|
| shape_item
|
||||||
|
;
|
||||||
|
|
||||||
box: BOX LCURLY box_items RCURLY {
|
box: BOX LCURLY box_items RCURLY {
|
||||||
$$ = new BoxNode();
|
$$ = new BoxNode();
|
||||||
$$->addChildren($3);
|
$$->addChildren($3);
|
||||||
@ -171,11 +183,9 @@ cyl_item: SIZE vector {
|
|||||||
| shape_item { $$ = $1; }
|
| shape_item { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
intersect: INTERSECT LCURLY shape shape shape_items RCURLY {
|
intersect: INTERSECT LCURLY bool_items RCURLY {
|
||||||
$$ = new IntersectNode();
|
$$ = new IntersectNode();
|
||||||
$$->addChild($3);
|
$$->addChildren($3);
|
||||||
$$->addChild($4);
|
|
||||||
$$->addChildren($5);
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -368,11 +378,9 @@ sphere_item: radius { $$ = $1; }
|
|||||||
| shape_item { $$ = $1; }
|
| shape_item { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
subtract: SUBTRACT LCURLY shape shape shape_items RCURLY {
|
subtract: SUBTRACT LCURLY bool_items RCURLY {
|
||||||
$$ = new SubtractNode();
|
$$ = new SubtractNode();
|
||||||
$$->addChild($3);
|
$$->addChildren($3);
|
||||||
$$->addChild($4);
|
|
||||||
$$->addChildren($5);
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -414,11 +422,9 @@ transform_block_item: transform_block { $$ = $1; }
|
|||||||
| shape { $$ = $1; }
|
| shape { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
union: UNION LCURLY shape shape shape_items RCURLY {
|
union: UNION LCURLY bool_items RCURLY {
|
||||||
$$ = new UnionNode();
|
$$ = new UnionNode();
|
||||||
$$->addChild($3);
|
$$->addChildren($3);
|
||||||
$$->addChild($4);
|
|
||||||
$$->addChildren($5);
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
130
scenes/die.fart
130
scenes/die.fart
@ -19,115 +19,33 @@ scene
|
|||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
union {
|
|
||||||
union {
|
|
||||||
box { size <1, 0.8, 0.8> }
|
box { size <1, 0.8, 0.8> }
|
||||||
union {
|
|
||||||
box { size <0.8, 1, 0.8> }
|
box { size <0.8, 1, 0.8> }
|
||||||
box { size <0.8, 0.8, 1> }
|
box { size <0.8, 0.8, 1> }
|
||||||
}
|
|
||||||
}
|
cyl { size <0.1, 0.1, 0.8> translate <0.4, 0.4, -0.4> }
|
||||||
union {
|
cyl { size <0.1, 0.1, 0.8> translate <0.4, -0.4, -0.4> }
|
||||||
union {
|
cyl { size <0.1, 0.1, 0.8> translate <-0.4, 0.4, -0.4> }
|
||||||
union {
|
cyl { size <0.1, 0.1, 0.8> translate <-0.4, -0.4, -0.4> }
|
||||||
cyl {
|
|
||||||
size <0.1, 0.1, 0.8>
|
cyl { size <.1, .1, .8> translate <.4, -.4, .4> rotate -90, <1, 0, 0> }
|
||||||
translate <0.4, 0.4, -0.4>
|
cyl { size <.1, .1, .8> translate <.4, -.4, -.4> rotate -90, <1, 0, 0> }
|
||||||
}
|
cyl { size <.1, .1, .8> translate <-.4, -.4, .4> rotate -90, <1, 0, 0> }
|
||||||
cyl {
|
cyl { size <.1, .1, .8> translate <-.4, -.4, -.4> rotate -90, <1, 0, 0> }
|
||||||
size <0.1, 0.1, 0.8>
|
|
||||||
translate <0.4, -0.4, -0.4>
|
cyl { size <.1, .1, .8> translate <.4, -.4, .4> rotate -90, <0, 1, 0> }
|
||||||
}
|
cyl { size <.1, .1, .8> translate <.4, -.4, -.4> rotate -90, <0, 1, 0> }
|
||||||
}
|
cyl { size <.1, .1, .8> translate <.4, .4, .4> rotate -90, <0, 1, 0> }
|
||||||
union {
|
cyl { size <.1, .1, .8> translate <.4, .4, -.4> rotate -90, <0, 1, 0> }
|
||||||
cyl {
|
|
||||||
size <0.1, 0.1, 0.8>
|
sphere { radius .1 translate <.4, .4, .4> }
|
||||||
translate <-0.4, 0.4, -0.4>
|
sphere { radius .1 translate <.4, .4, -.4> }
|
||||||
}
|
sphere { radius .1 translate <.4, -.4, .4> }
|
||||||
cyl {
|
sphere { radius .1 translate <.4, -.4, -.4> }
|
||||||
size <0.1, 0.1, 0.8>
|
sphere { radius .1 translate <-.4, .4, .4> }
|
||||||
translate <-0.4, -0.4, -0.4>
|
sphere { radius .1 translate <-.4, .4, -.4> }
|
||||||
}
|
sphere { radius .1 translate <-.4, -.4, .4> }
|
||||||
}
|
sphere { radius .1 translate <-.4, -.4, -.4> }
|
||||||
}
|
|
||||||
union {
|
|
||||||
union {
|
|
||||||
union {
|
|
||||||
cyl {
|
|
||||||
size <0.1, 0.1, 0.8>
|
|
||||||
translate <0.4, -0.4, 0.4>
|
|
||||||
rotate -90, <1, 0, 0>
|
|
||||||
}
|
|
||||||
cyl {
|
|
||||||
size <0.1, 0.1, 0.8>
|
|
||||||
translate <0.4, -0.4, -0.4>
|
|
||||||
rotate -90, <1, 0, 0>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
union {
|
|
||||||
cyl {
|
|
||||||
size <0.1, 0.1, 0.8>
|
|
||||||
translate <-0.4, -0.4, 0.4>
|
|
||||||
rotate -90, <1, 0, 0>
|
|
||||||
}
|
|
||||||
cyl {
|
|
||||||
size <0.1, 0.1, 0.8>
|
|
||||||
translate <-0.4, -0.4, -0.4>
|
|
||||||
rotate -90, <1, 0, 0>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
union {
|
|
||||||
union {
|
|
||||||
cyl {
|
|
||||||
size <0.1, 0.1, 0.8>
|
|
||||||
translate <0.4, -0.4, 0.4>
|
|
||||||
rotate -90, <0, 1, 0>
|
|
||||||
}
|
|
||||||
cyl {
|
|
||||||
size <0.1, 0.1, 0.8>
|
|
||||||
translate <0.4, -0.4, -0.4>
|
|
||||||
rotate -90, <0, 1, 0>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
union {
|
|
||||||
cyl {
|
|
||||||
size <0.1, 0.1, 0.8>
|
|
||||||
translate <0.4, 0.4, 0.4>
|
|
||||||
rotate -90, <0, 1, 0>
|
|
||||||
}
|
|
||||||
cyl {
|
|
||||||
size <0.1, 0.1, 0.8>
|
|
||||||
translate <0.4, 0.4, -0.4>
|
|
||||||
rotate -90, <0, 1, 0>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
union {
|
|
||||||
union {
|
|
||||||
union {
|
|
||||||
sphere { radius 0.1 translate <0.4, 0.4, 0.4> }
|
|
||||||
sphere { radius 0.1 translate <0.4, 0.4, -0.4> }
|
|
||||||
}
|
|
||||||
union {
|
|
||||||
sphere { radius 0.1 translate <0.4, -0.4, 0.4> }
|
|
||||||
sphere { radius 0.1 translate <0.4, -0.4, -0.4> }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
union {
|
|
||||||
union {
|
|
||||||
sphere { radius 0.1 translate <-0.4, 0.4, 0.4> }
|
|
||||||
sphere { radius 0.1 translate <-0.4, 0.4, -0.4> }
|
|
||||||
}
|
|
||||||
union {
|
|
||||||
sphere { radius 0.1 translate <-0.4, -0.4, 0.4> }
|
|
||||||
sphere { radius 0.1 translate <-0.4, -0.4, -0.4> }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
material
|
material
|
||||||
{
|
{
|
||||||
|
@ -1,16 +1,6 @@
|
|||||||
|
|
||||||
#include "BoolShape.h"
|
#include "BoolShape.h"
|
||||||
|
|
||||||
BoolShape::BoolShape(refptr<Shape> shape1, refptr<Shape> shape2)
|
|
||||||
{
|
|
||||||
m_shape1 = shape1;
|
|
||||||
m_shape2 = shape2;
|
|
||||||
}
|
|
||||||
|
|
||||||
BoolShape::~BoolShape()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void BoolShape::setMaterial(refptr<Material> material)
|
void BoolShape::setMaterial(refptr<Material> material)
|
||||||
{
|
{
|
||||||
m_material = material;
|
m_material = material;
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
class BoolShape : public Shape
|
class BoolShape : public Shape
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BoolShape(refptr<Shape> shape1, refptr<Shape> shape2);
|
|
||||||
~BoolShape();
|
|
||||||
virtual IntersectionList intersect(refptr<Shape> _this, const Ray & ray) = 0;
|
virtual IntersectionList intersect(refptr<Shape> _this, const Ray & ray) = 0;
|
||||||
virtual void setMaterial(refptr<Material> material);
|
virtual void setMaterial(refptr<Material> material);
|
||||||
|
|
||||||
|
@ -3,9 +3,30 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Intersect::Intersect(refptr<Shape> shape1, refptr<Shape> shape2)
|
Intersect::Intersect(const vector< refptr<Shape> > & shapes)
|
||||||
: BoolShape(shape1, shape2)
|
|
||||||
{
|
{
|
||||||
|
int num_shapes = shapes.size();
|
||||||
|
if (num_shapes > 2)
|
||||||
|
{
|
||||||
|
m_shape2 = shapes[num_shapes - 1];
|
||||||
|
vector< refptr<Shape> > rest = shapes;
|
||||||
|
rest.pop_back();
|
||||||
|
m_shape1 = new Intersect(rest);
|
||||||
|
}
|
||||||
|
else if (num_shapes == 2)
|
||||||
|
{
|
||||||
|
m_shape1 = shapes[0];
|
||||||
|
m_shape2 = shapes[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cerr << __FILE__ << ": " << __LINE__
|
||||||
|
<< ": error: Intersect::Intersect() called with only "
|
||||||
|
<< num_shapes
|
||||||
|
<< " sub-shapes!"
|
||||||
|
<< endl;
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Shape::IntersectionList Intersect::intersect(refptr<Shape> _this, const Ray & ray)
|
Shape::IntersectionList Intersect::intersect(refptr<Shape> _this, const Ray & ray)
|
||||||
@ -16,8 +37,31 @@ Shape::IntersectionList Intersect::intersect(refptr<Shape> _this, const Ray & ra
|
|||||||
|
|
||||||
IntersectionList res;
|
IntersectionList res;
|
||||||
bool in1 = false, in2 = false;
|
bool in1 = false, in2 = false;
|
||||||
bool in_bool = false;
|
|
||||||
|
|
||||||
|
/* initially go through the merged intersections to see whether
|
||||||
|
* the ray started inside one of the sub-objects */
|
||||||
|
for (int i = 0, sz = merged.size(), saw1 = 0, saw2 = 0;
|
||||||
|
i < sz && (!saw1 || !saw2);
|
||||||
|
i++)
|
||||||
|
{
|
||||||
|
Vector normal = merged[i].intersection.normal;
|
||||||
|
double dot = - (ray.getDirection() % normal);
|
||||||
|
bool back = dot < 0.0;
|
||||||
|
bool left = merged[i].left;
|
||||||
|
if (back)
|
||||||
|
{
|
||||||
|
if (left && !saw1)
|
||||||
|
in1 = true;
|
||||||
|
else if (!left && !saw2)
|
||||||
|
in2 = true;
|
||||||
|
}
|
||||||
|
if (left)
|
||||||
|
saw1 = 1;
|
||||||
|
else
|
||||||
|
saw2 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool in_bool = in1 && in2;
|
||||||
for (int i = 0, sz = merged.size(); i < sz; i++)
|
for (int i = 0, sz = merged.size(); i < sz; i++)
|
||||||
{
|
{
|
||||||
Vector normal = merged[i].intersection.normal;
|
Vector normal = merged[i].intersection.normal;
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
#define INTERSECT_H INTERSECT_H
|
#define INTERSECT_H INTERSECT_H
|
||||||
|
|
||||||
#include "BoolShape.h"
|
#include "BoolShape.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class Intersect : public BoolShape
|
class Intersect : public BoolShape
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Intersect(refptr<Shape> shape1, refptr<Shape> shape2);
|
Intersect(const std::vector< refptr<Shape> > & shapes);
|
||||||
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,9 +3,30 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Subtract::Subtract(refptr<Shape> shape1, refptr<Shape> shape2)
|
Subtract::Subtract(const vector< refptr<Shape> > & shapes)
|
||||||
: BoolShape(shape1, shape2)
|
|
||||||
{
|
{
|
||||||
|
int num_shapes = shapes.size();
|
||||||
|
if (num_shapes > 2)
|
||||||
|
{
|
||||||
|
m_shape2 = shapes[num_shapes - 1];
|
||||||
|
vector< refptr<Shape> > rest = shapes;
|
||||||
|
rest.pop_back();
|
||||||
|
m_shape1 = new Subtract(rest);
|
||||||
|
}
|
||||||
|
else if (num_shapes == 2)
|
||||||
|
{
|
||||||
|
m_shape1 = shapes[0];
|
||||||
|
m_shape2 = shapes[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cerr << __FILE__ << ": " << __LINE__
|
||||||
|
<< ": error: Subtract::Subtract() called with only "
|
||||||
|
<< num_shapes
|
||||||
|
<< " sub-shapes!"
|
||||||
|
<< endl;
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Shape::IntersectionList Subtract::intersect(refptr<Shape> _this, const Ray & ray)
|
Shape::IntersectionList Subtract::intersect(refptr<Shape> _this, const Ray & ray)
|
||||||
@ -16,8 +37,31 @@ Shape::IntersectionList Subtract::intersect(refptr<Shape> _this, const Ray & ray
|
|||||||
|
|
||||||
IntersectionList res;
|
IntersectionList res;
|
||||||
bool in1 = false, in2 = false;
|
bool in1 = false, in2 = false;
|
||||||
bool in_bool = false;
|
|
||||||
|
|
||||||
|
/* initially go through the merged intersections to see whether
|
||||||
|
* the ray started inside one of the sub-objects */
|
||||||
|
for (int i = 0, sz = merged.size(), saw1 = 0, saw2 = 0;
|
||||||
|
i < sz && (!saw1 || !saw2);
|
||||||
|
i++)
|
||||||
|
{
|
||||||
|
Vector normal = merged[i].intersection.normal;
|
||||||
|
double dot = - (ray.getDirection() % normal);
|
||||||
|
bool back = dot < 0.0;
|
||||||
|
bool left = merged[i].left;
|
||||||
|
if (back)
|
||||||
|
{
|
||||||
|
if (left && !saw1)
|
||||||
|
in1 = true;
|
||||||
|
else if (!left && !saw2)
|
||||||
|
in2 = true;
|
||||||
|
}
|
||||||
|
if (left)
|
||||||
|
saw1 = 1;
|
||||||
|
else
|
||||||
|
saw2 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool in_bool = in1 && !in2;
|
||||||
for (int i = 0, sz = merged.size(); i < sz; i++)
|
for (int i = 0, sz = merged.size(); i < sz; i++)
|
||||||
{
|
{
|
||||||
Vector normal = merged[i].intersection.normal;
|
Vector normal = merged[i].intersection.normal;
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
#define SUBTRACT_H SUBTRACT_H
|
#define SUBTRACT_H SUBTRACT_H
|
||||||
|
|
||||||
#include "BoolShape.h"
|
#include "BoolShape.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class Subtract : public BoolShape
|
class Subtract : public BoolShape
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Subtract(refptr<Shape> shape1, refptr<Shape> shape2);
|
Subtract(const std::vector< refptr<Shape> > & shapes);
|
||||||
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,11 +1,33 @@
|
|||||||
|
|
||||||
#include "Union.h"
|
#include "Union.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Union::Union(refptr<Shape> shape1, refptr<Shape> shape2)
|
Union::Union(const vector< refptr<Shape> > & shapes)
|
||||||
: BoolShape(shape1, shape2)
|
|
||||||
{
|
{
|
||||||
|
int num_shapes = shapes.size();
|
||||||
|
if (num_shapes > 2)
|
||||||
|
{
|
||||||
|
m_shape2 = shapes[num_shapes - 1];
|
||||||
|
vector< refptr<Shape> > rest = shapes;
|
||||||
|
rest.pop_back();
|
||||||
|
m_shape1 = new Union(rest);
|
||||||
|
}
|
||||||
|
else if (num_shapes == 2)
|
||||||
|
{
|
||||||
|
m_shape1 = shapes[0];
|
||||||
|
m_shape2 = shapes[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cerr << __FILE__ << ": " << __LINE__
|
||||||
|
<< ": error: Union::Union() called with only "
|
||||||
|
<< num_shapes
|
||||||
|
<< " sub-shapes!"
|
||||||
|
<< endl;
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Shape::IntersectionList Union::intersect(refptr<Shape> _this, const Ray & ray)
|
Shape::IntersectionList Union::intersect(refptr<Shape> _this, const Ray & ray)
|
||||||
@ -16,8 +38,31 @@ Shape::IntersectionList Union::intersect(refptr<Shape> _this, const Ray & ray)
|
|||||||
|
|
||||||
IntersectionList res;
|
IntersectionList res;
|
||||||
bool in1 = false, in2 = false;
|
bool in1 = false, in2 = false;
|
||||||
bool in_bool = false;
|
|
||||||
|
|
||||||
|
/* initially go through the merged intersections to see whether
|
||||||
|
* the ray started inside one of the sub-objects */
|
||||||
|
for (int i = 0, sz = merged.size(), saw1 = 0, saw2 = 0;
|
||||||
|
i < sz && (!saw1 || !saw2);
|
||||||
|
i++)
|
||||||
|
{
|
||||||
|
Vector normal = merged[i].intersection.normal;
|
||||||
|
double dot = - (ray.getDirection() % normal);
|
||||||
|
bool back = dot < 0.0;
|
||||||
|
bool left = merged[i].left;
|
||||||
|
if (back)
|
||||||
|
{
|
||||||
|
if (left && !saw1)
|
||||||
|
in1 = true;
|
||||||
|
else if (!left && !saw2)
|
||||||
|
in2 = true;
|
||||||
|
}
|
||||||
|
if (left)
|
||||||
|
saw1 = 1;
|
||||||
|
else
|
||||||
|
saw2 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool in_bool = in1 || in2;
|
||||||
for (int i = 0, sz = merged.size(); i < sz; i++)
|
for (int i = 0, sz = merged.size(); i < sz; i++)
|
||||||
{
|
{
|
||||||
Vector normal = merged[i].intersection.normal;
|
Vector normal = merged[i].intersection.normal;
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
#define UNION_H UNION_H
|
#define UNION_H UNION_H
|
||||||
|
|
||||||
#include "BoolShape.h"
|
#include "BoolShape.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class Union : public BoolShape
|
class Union : public BoolShape
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Union(refptr<Shape> shape1, refptr<Shape> shape2);
|
Union(const std::vector< refptr<Shape> > & shapes);
|
||||||
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
IntersectionList intersect(refptr<Shape> _this, const Ray & ray);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user