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);
}
else if ( typeid(*node) == typeid(TranslateBlockNode) )
else if (node->isTransformBlock())
{
processTransformBlock(node);
}
else if ( typeid(*node) == typeid(RotateBlockNode) )
{
processTransformBlock(node);
}
else if ( typeid(*node) == typeid(ScaleBlockNode) )
{
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(MaterialDefinitionNode) )
{
@ -131,15 +127,9 @@ refptr<Shape> Scene::processShape(refptr<Node> node)
{
return processCyl(node);
}
else if ( typeid(*node) == typeid(IntersectNode) )
{
return processBool(node);
}
else if ( typeid(*node) == typeid(UnionNode) )
{
return processBool(node);
}
else if ( typeid(*node) == typeid(SubtractNode) )
else if ( typeid(*node) == typeid(IntersectNode)
|| typeid(*node) == typeid(UnionNode)
|| typeid(*node) == typeid(SubtractNode) )
{
return processBool(node);
}
@ -151,6 +141,11 @@ refptr<Shape> Scene::processShape(refptr<Node> node)
{
return processShapeRef(node);
}
else
{
cerr << "Error: Unknown shape!" << endl;
exit(3);
}
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) )
{
@ -244,9 +239,39 @@ void Scene::processTransformBlock(refptr<Node> node)
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();
return shapes;
}
void Scene::processMaterialDefinition(refptr<Node> node)
@ -522,6 +547,23 @@ refptr<Shape> Scene::processBool(refptr<Node> node)
{
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)

View File

@ -76,7 +76,7 @@ class Scene
bool processTransforms(refptr<Node> node);
void processCamera(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 processShapeDefinition(refptr<Node> node);

View File

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

View File

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

View File

@ -7,11 +7,3 @@ void BoolShape::setMaterial(refptr<Material> material)
m_shape1->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:
virtual IntersectionList intersect(refptr<Shape> _this, const Ray & ray) = 0;
virtual void setMaterial(refptr<Material> material);
virtual void setTransform(Transform & t);
virtual refptr<Shape> clone() = 0;
protected:

View File

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