allowing transform blocks inside boolean shapes, but using a shape reference to a boolean shape does not propagate transform properly

git-svn-id: svn://anubis/fart/trunk@286 7f9b0f55-74a9-4bce-be96-3c2cd072584d
This commit is contained in:
Josh Holtrop 2010-07-09 18:33:26 +00:00
parent fc2c62d5ac
commit b4a2c8ef8e
7 changed files with 73 additions and 36 deletions

View File

@ -45,17 +45,13 @@ void Scene::processNode(refptr<Node> node)
{ {
processOptions(node); processOptions(node);
} }
else if ( typeid(*node) == typeid(TranslateBlockNode) ) else if (node->isTransformBlock())
{ {
processTransformBlock(node); vector< refptr<Shape> > shapes = processTransformBlock(node);
for (int i = 0, sz = shapes.size(); i < sz; i++)
{
m_shapes.push_back(shapes[i]);
} }
else if ( typeid(*node) == typeid(RotateBlockNode) )
{
processTransformBlock(node);
}
else if ( typeid(*node) == typeid(ScaleBlockNode) )
{
processTransformBlock(node);
} }
else if ( typeid(*node) == typeid(MaterialDefinitionNode) ) else if ( typeid(*node) == typeid(MaterialDefinitionNode) )
{ {
@ -131,15 +127,9 @@ refptr<Shape> Scene::processShape(refptr<Node> node)
{ {
return processCyl(node); return processCyl(node);
} }
else if ( typeid(*node) == typeid(IntersectNode) ) else if ( typeid(*node) == typeid(IntersectNode)
{ || typeid(*node) == typeid(UnionNode)
return processBool(node); || typeid(*node) == typeid(SubtractNode) )
}
else if ( typeid(*node) == typeid(UnionNode) )
{
return processBool(node);
}
else if ( typeid(*node) == typeid(SubtractNode) )
{ {
return processBool(node); return processBool(node);
} }
@ -151,6 +141,11 @@ refptr<Shape> Scene::processShape(refptr<Node> node)
{ {
return processShapeRef(node); return processShapeRef(node);
} }
else
{
cerr << "Error: Unknown shape!" << endl;
exit(3);
}
return refptr<Shape>(NULL); return refptr<Shape>(NULL);
} }
@ -225,7 +220,7 @@ void Scene::processOptions(refptr<Node> node)
} }
} }
void Scene::processTransformBlock(refptr<Node> node) vector< refptr<Shape> > Scene::processTransformBlock(refptr<Node> node)
{ {
if ( typeid(*node) == typeid(TranslateBlockNode) ) if ( typeid(*node) == typeid(TranslateBlockNode) )
{ {
@ -244,9 +239,39 @@ void Scene::processTransformBlock(refptr<Node> node)
m_transforms.top().scale(node->getVector()); m_transforms.top().scale(node->getVector());
} }
processChildren(node); vector< refptr<Shape> > shapes;
for (Node_Iterator it = node->getChildren().begin();
it != node->getChildren().end();
it++)
{
if ((*it)->isTransformBlock())
{
vector< refptr<Shape> > in = processTransformBlock(*it);
for (int i = 0, sz = in.size(); i < sz; i++)
{
shapes.push_back(in[i]);
}
}
else if ( (*it)->isShape() )
{
shapes.push_back(processShape(*it));
}
else if ( typeid(**it) == typeid(ShapeDefinitionNode) )
{
processShapeDefinition(*it);
}
else
{
cerr << "Unknown transform block item: " << typeid(**it).name()
<< endl;
exit(3);
}
}
m_transforms.pop(); m_transforms.pop();
return shapes;
} }
void Scene::processMaterialDefinition(refptr<Node> node) void Scene::processMaterialDefinition(refptr<Node> node)
@ -522,6 +547,23 @@ refptr<Shape> Scene::processBool(refptr<Node> node)
{ {
material = processMaterial(*it); material = processMaterial(*it);
} }
else if ( (*it)->isTransformBlock() )
{
vector< refptr<Shape> > in = processTransformBlock(*it);
for (int i = 0, sz = in.size(); i < sz; i++)
{
shapes.push_back(in[i]);
}
}
else if ( typeid(**it) == typeid(ShapeDefinitionNode) )
{
processShapeDefinition(*it);
}
else
{
cerr << "Error: unknown boolean object item" << endl;
exit(3);
}
} }
if (shapes.size() < 2) if (shapes.size() < 2)

View File

@ -76,7 +76,7 @@ class Scene
bool processTransforms(refptr<Node> node); bool processTransforms(refptr<Node> node);
void processCamera(refptr<Node> node); void processCamera(refptr<Node> node);
void processOptions(refptr<Node> node); void processOptions(refptr<Node> node);
void processTransformBlock(refptr<Node> node); std::vector< refptr<Shape> > processTransformBlock(refptr<Node> node);
void processMaterialDefinition(refptr<Node> node); void processMaterialDefinition(refptr<Node> node);
void processShapeDefinition(refptr<Node> node); void processShapeDefinition(refptr<Node> node);

View File

@ -23,6 +23,7 @@ class Node
} }
virtual bool isShape() { return false; } virtual bool isShape() { return false; }
virtual bool isMaterial() { return false; } virtual bool isMaterial() { return false; }
virtual bool isTransformBlock() { return false; }
virtual std::string getString() { return ""; } virtual std::string getString() { return ""; }
protected: protected:
@ -267,9 +268,8 @@ class RotateBlockNode : public RotateNode
{ {
public: public:
RotateBlockNode(double angle, refptr<Vector> vector) RotateBlockNode(double angle, refptr<Vector> vector)
: RotateNode(angle, vector) : RotateNode(angle, vector) {}
{ bool isTransformBlock() { return true; }
}
}; };
class ScaleNode : public VectorNode class ScaleNode : public VectorNode
@ -282,6 +282,7 @@ class ScaleBlockNode : public ScaleNode
{ {
public: public:
ScaleBlockNode(refptr<Vector> vector) : ScaleNode(vector) {} ScaleBlockNode(refptr<Vector> vector) : ScaleNode(vector) {}
bool isTransformBlock() { return true; }
}; };
class SceneNode : public Node class SceneNode : public Node
@ -298,6 +299,7 @@ class ShapeRefNode : public IdentifierNode
{ {
public: public:
ShapeRefNode(const std::string & str) : IdentifierNode(str) {} ShapeRefNode(const std::string & str) : IdentifierNode(str) {}
bool isShape() { return true; }
}; };
class ShininessNode : public NumberNode class ShininessNode : public NumberNode
@ -340,6 +342,7 @@ class TranslateBlockNode : public TranslateNode
{ {
public: public:
TranslateBlockNode(refptr<Vector> vector) : TranslateNode(vector) {} TranslateBlockNode(refptr<Vector> vector) : TranslateNode(vector) {}
bool isTransformBlock() { return true; }
}; };
class TransparencyNode : public NumberNode class TransparencyNode : public NumberNode

View File

@ -121,6 +121,8 @@ bool_items: /* empty */
bool_item: shape bool_item: shape
| shape_item | shape_item
| shape_definition
| transform_block
; ;
box: BOX LCURLY box_items RCURLY { box: BOX LCURLY box_items RCURLY {
@ -532,7 +534,6 @@ transform_block_items: /* empty */
; ;
transform_block_item: transform_block { $$ = $1; } transform_block_item: transform_block { $$ = $1; }
| light { $$ = $1; }
| shape { $$ = $1; } | shape { $$ = $1; }
| shape_definition { $$ = $1; } | shape_definition { $$ = $1; }
; ;

View File

@ -7,11 +7,3 @@ void BoolShape::setMaterial(refptr<Material> material)
m_shape1->setMaterial(material); m_shape1->setMaterial(material);
m_shape2->setMaterial(material); m_shape2->setMaterial(material);
} }
void BoolShape::setTransform(Transform & t)
{
m_transform = t;
m_inverse = t.getInverse();
m_shape1->setTransform(t);
m_shape2->setTransform(t);
}

View File

@ -9,7 +9,6 @@ class BoolShape : public Shape
public: public:
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);
virtual void setTransform(Transform & t);
virtual refptr<Shape> clone() = 0; virtual refptr<Shape> clone() = 0;
protected: protected:

View File

@ -103,7 +103,7 @@ class Shape
const Ray & ray) = 0; const Ray & ray) = 0;
virtual refptr<Shape> clone() = 0; virtual refptr<Shape> clone() = 0;
virtual void setTransform(Transform & t) void setTransform(Transform & t)
{ {
m_transform = t; m_transform = t;
m_inverse = t.getInverse(); m_inverse = t.getInverse();