822 lines
21 KiB
C++
822 lines
21 KiB
C++
|
|
#include <math.h>
|
|
|
|
#include <typeinfo>
|
|
#include <iostream>
|
|
|
|
#include "Scene.h"
|
|
#include "Light.h"
|
|
#include "parser/parser.h"
|
|
#include "parser/nodes.h"
|
|
#include "util/Polygon.h"
|
|
#include "util/Scope.h"
|
|
|
|
using namespace std;
|
|
|
|
typedef vector< refptr<Node> >::const_iterator Node_Iterator;
|
|
|
|
void Scene::load(const char * filename)
|
|
{
|
|
refptr<Scope> scope = new Scope();
|
|
refptr<Node> node = parse(filename, scope);
|
|
if ( ! node.isNull() )
|
|
{
|
|
/* evaluate any scripting nodes in the node tree */
|
|
refptr<Node> processed_scene = node->evaluate();
|
|
node->evaluateChildren(processed_scene);
|
|
|
|
/* now we have a new node tree under 'dummy' with no scripting nodes */
|
|
processScene(processed_scene);
|
|
}
|
|
}
|
|
|
|
void Scene::processScene(refptr<Node> node)
|
|
{
|
|
/* first process any cameras present */
|
|
int cameras_found = 0;
|
|
for (Node_Iterator it = node->getChildren().begin();
|
|
it != node->getChildren().end();
|
|
it++)
|
|
{
|
|
if ( typeid(**it) == typeid(CameraNode) )
|
|
{
|
|
cameras_found++;
|
|
if (cameras_found == 1)
|
|
processCamera(*it);
|
|
else
|
|
{
|
|
cerr << "Error: multiple camera definitions found!" << endl;
|
|
exit(5);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* then any other scene-specific items */
|
|
for (Node_Iterator it = node->getChildren().begin();
|
|
it != node->getChildren().end();
|
|
it++)
|
|
{
|
|
if ( typeid(**it) == typeid(LightNode) )
|
|
{
|
|
refptr<Light> light = processLight(*it);
|
|
if ( ! light.isNull() )
|
|
m_lights.push_back(light);
|
|
}
|
|
else if ( typeid(**it) == typeid(OptionsNode) )
|
|
{
|
|
processOptions(*it);
|
|
}
|
|
}
|
|
|
|
/* then any general items */
|
|
vector<ShapeRef> shapes = processGeneralItems(node);
|
|
for (vector<ShapeRef>::iterator it = shapes.begin();
|
|
it != shapes.end();
|
|
it++)
|
|
{
|
|
m_shapes.push_back(*it);
|
|
}
|
|
}
|
|
|
|
ShapeRef Scene::processShape(refptr<Node> node)
|
|
{
|
|
if ( typeid(*node) == typeid(BoxNode) )
|
|
{
|
|
return processBox(node);
|
|
}
|
|
else if ( typeid(*node) == typeid(PlaneNode) )
|
|
{
|
|
return processPlane(node);
|
|
}
|
|
else if ( typeid(*node) == typeid(SphereNode) )
|
|
{
|
|
return processSphere(node);
|
|
}
|
|
else if ( typeid(*node) == typeid(CylNode) )
|
|
{
|
|
return processCyl(node);
|
|
}
|
|
else if ( typeid(*node) == typeid(IntersectNode)
|
|
|| typeid(*node) == typeid(UnionNode)
|
|
|| typeid(*node) == typeid(SubtractNode) )
|
|
{
|
|
return processBool(node);
|
|
}
|
|
else if ( typeid(*node) == typeid(ExtrudeNode) )
|
|
{
|
|
return processExtrude(node);
|
|
}
|
|
else if ( typeid(*node) == typeid(ShapeRefNode) )
|
|
{
|
|
return processShapeRef(node);
|
|
}
|
|
else
|
|
{
|
|
cerr << "Error: Unknown shape!" << endl;
|
|
exit(3);
|
|
}
|
|
|
|
return ShapeRef(NULL);
|
|
}
|
|
|
|
void Scene::processCamera(refptr<Node> node)
|
|
{
|
|
Vector position(0, 0, 0);
|
|
Vector look_at(0, 1, 0);
|
|
Vector up(0, 0, 1);
|
|
|
|
for (Node_Iterator it = node->getChildren().begin();
|
|
it != node->getChildren().end();
|
|
it++)
|
|
{
|
|
if ( typeid(**it) == typeid(PositionNode) )
|
|
{
|
|
position = * (*it)->getVector();
|
|
}
|
|
else if ( typeid(**it) == typeid(LookAtNode) )
|
|
{
|
|
look_at = * (*it)->getVector();
|
|
}
|
|
else if ( typeid(**it) == typeid(UpNode) )
|
|
{
|
|
up = * (*it)->getVector();
|
|
}
|
|
else if ( typeid(**it) == typeid(VFOVNode) )
|
|
{
|
|
m_vfov = (*it)->getNumber();
|
|
}
|
|
}
|
|
|
|
m_transforms.top().lookAt(position, look_at, up);
|
|
}
|
|
|
|
void Scene::processOptions(refptr<Node> node)
|
|
{
|
|
for (Node_Iterator it = node->getChildren().begin();
|
|
it != node->getChildren().end();
|
|
it++)
|
|
{
|
|
if ( typeid(**it) == typeid(WidthNode) )
|
|
{
|
|
m_width = (*it)->getInteger();
|
|
}
|
|
else if ( typeid(**it) == typeid(HeightNode) )
|
|
{
|
|
m_height = (*it)->getInteger();
|
|
}
|
|
else if ( typeid(**it) == typeid(ExposureNode) )
|
|
{
|
|
m_exposure = (*it)->getNumber();
|
|
if (m_exposure < 0.0)
|
|
m_exposure = 0.0;
|
|
}
|
|
else if ( typeid(**it) == typeid(MultisampleNode) )
|
|
{
|
|
m_multisample_level = (*it)->getInteger();
|
|
}
|
|
else if ( typeid(**it) == typeid(MaxDepthNode) )
|
|
{
|
|
m_max_depth = (*it)->getInteger();
|
|
}
|
|
else if ( typeid(**it) == typeid(AmbientNode) )
|
|
{
|
|
setAmbientLight(Color((*it)->getVector()));
|
|
}
|
|
else if ( typeid(**it) == typeid(AmbientOcclusionNode) )
|
|
{
|
|
m_ambient_occlusion_level = (*it)->getInteger();
|
|
}
|
|
}
|
|
}
|
|
|
|
vector<ShapeRef> Scene::processTransformBlock(refptr<Node> node)
|
|
{
|
|
if ( typeid(*node) == typeid(TranslateBlockNode) )
|
|
{
|
|
m_transforms.push(m_transforms.top());
|
|
m_transforms.top().translate(node->getVector());
|
|
}
|
|
else if ( typeid(*node) == typeid(RotateBlockNode) )
|
|
{
|
|
m_transforms.push(m_transforms.top());
|
|
m_transforms.top().rotate(node->getNumber(),
|
|
node->getVector());
|
|
}
|
|
else if ( typeid(*node) == typeid(ScaleBlockNode) )
|
|
{
|
|
m_transforms.push(m_transforms.top());
|
|
m_transforms.top().scale(node->getVector());
|
|
}
|
|
else
|
|
{
|
|
cerr << "Unknown transformation block node type!" << endl;
|
|
exit(4);
|
|
}
|
|
|
|
vector<ShapeRef> shapes = processGeneralItems(node);
|
|
|
|
m_transforms.pop();
|
|
|
|
return shapes;
|
|
}
|
|
|
|
vector<ShapeRef> Scene::processGeneralItems(refptr<Node> node)
|
|
{
|
|
vector<ShapeRef> shapes, incoming;
|
|
|
|
for (Node_Iterator it = node->getChildren().begin();
|
|
it != node->getChildren().end();
|
|
it++)
|
|
{
|
|
if ((*it)->isTransformBlock())
|
|
{
|
|
incoming = processTransformBlock(*it);
|
|
}
|
|
else if ( typeid(**it) == typeid(MaterialDefinitionNode) )
|
|
{
|
|
processMaterialDefinition(*it);
|
|
}
|
|
else if ( typeid(**it) == typeid(ShapeDefinitionNode) )
|
|
{
|
|
processShapeDefinition(*it);
|
|
}
|
|
else if ( (*it)->isShape() )
|
|
{
|
|
shapes.push_back(processShape(*it));
|
|
}
|
|
while (incoming.size() > 0)
|
|
{
|
|
shapes.push_back(incoming[0]);
|
|
incoming.erase(incoming.begin());
|
|
}
|
|
}
|
|
|
|
return shapes;
|
|
}
|
|
|
|
void Scene::processMaterialDefinition(refptr<Node> node)
|
|
{
|
|
map< string, refptr<Material> >::iterator it =
|
|
m_materials.find(node->getString());
|
|
if ( it == m_materials.end() )
|
|
{
|
|
m_materials[node->getString()] = processMaterial(node);
|
|
}
|
|
else
|
|
{
|
|
cerr << "Error: duplicate material definition for material '"
|
|
<< node->getString() << "'" << endl;
|
|
exit(4);
|
|
}
|
|
}
|
|
|
|
refptr<Material> Scene::processMaterial(refptr<Node> node)
|
|
{
|
|
if ( typeid(*node) == typeid(MaterialRefNode) )
|
|
{
|
|
map< string, refptr<Material> >::iterator it =
|
|
m_materials.find(node->getString());
|
|
if ( it == m_materials.end() )
|
|
{
|
|
cerr << "Undefined material '" << node->getString()
|
|
<< "' requested!" << endl;
|
|
exit(4);
|
|
}
|
|
|
|
return m_materials[node->getString()];
|
|
}
|
|
|
|
refptr<Material> material = new Material();
|
|
|
|
for (Node_Iterator it = node->getChildren().begin();
|
|
it != node->getChildren().end();
|
|
it++)
|
|
{
|
|
if ( typeid(**it) == typeid(ColorNode) )
|
|
{
|
|
material->setDiffuseColor(Color((*it)->getVector()));
|
|
material->setAmbientColor(Color((*it)->getVector()));
|
|
}
|
|
else if ( typeid(**it) == typeid(AmbientNode) )
|
|
{
|
|
material->setAmbientColor(Color((*it)->getVector()));
|
|
}
|
|
else if ( typeid(**it) == typeid(DiffuseNode) )
|
|
{
|
|
material->setDiffuseColor(Color((*it)->getVector()));
|
|
}
|
|
else if ( typeid(**it) == typeid(SpecularNode) )
|
|
{
|
|
material->setSpecularColor(Color((*it)->getVector()));
|
|
}
|
|
else if ( typeid(**it) == typeid(ReflectanceNode) )
|
|
{
|
|
material->setReflectance((*it)->getNumber());
|
|
}
|
|
else if ( typeid(**it) == typeid(RefractionNode) )
|
|
{
|
|
material->setRefraction((*it)->getNumber());
|
|
}
|
|
else if ( typeid(**it) == typeid(ShininessNode) )
|
|
{
|
|
material->setShininess((*it)->getNumber());
|
|
}
|
|
else if ( typeid(**it) == typeid(TransparencyNode) )
|
|
{
|
|
material->setTransparency((*it)->getNumber());
|
|
}
|
|
else if ( typeid(**it) == typeid(TextureNode) )
|
|
{
|
|
string filename = (*it)->getString();
|
|
FIBITMAP * fib = NULL;
|
|
if (m_textures.find(filename) != m_textures.end())
|
|
{
|
|
/* texture already loaded */
|
|
fib = m_textures[filename];
|
|
}
|
|
else
|
|
{
|
|
fib = loadTexture((*it)->getString());
|
|
}
|
|
if (fib != NULL)
|
|
{
|
|
material->setTexture(fib);
|
|
}
|
|
}
|
|
}
|
|
|
|
return material;
|
|
}
|
|
|
|
ShapeRef Scene::processBox(refptr<Node> node)
|
|
{
|
|
refptr<Vector> size = new Vector(1, 1, 1);
|
|
refptr<Material> material;
|
|
|
|
bool restore_transform = processTransforms(node);
|
|
|
|
for (Node_Iterator it = node->getChildren().begin();
|
|
it != node->getChildren().end();
|
|
it++)
|
|
{
|
|
if ( typeid(**it) == typeid(SizeNode) )
|
|
{
|
|
size = (*it)->getVector();
|
|
}
|
|
else if ( (*it)->isMaterial() )
|
|
{
|
|
material = processMaterial(*it);
|
|
}
|
|
}
|
|
|
|
ShapeRef box = new Box(size);
|
|
if ( ! material.isNull() )
|
|
box->setMaterial(material);
|
|
box->setTransform(m_transforms.top());
|
|
|
|
if (restore_transform)
|
|
m_transforms.pop();
|
|
|
|
return box;
|
|
}
|
|
|
|
ShapeRef Scene::processCyl(refptr<Node> node)
|
|
{
|
|
double radius1 = 1.0;
|
|
double radius2 = 1.0;
|
|
double height = 1.0;
|
|
refptr<Material> material;
|
|
|
|
bool restore_transform = processTransforms(node);
|
|
|
|
for (Node_Iterator it = node->getChildren().begin();
|
|
it != node->getChildren().end();
|
|
it++)
|
|
{
|
|
if ( typeid(**it) == typeid(SizeNode) )
|
|
{
|
|
const Vector & v = *(*it)->getVector();
|
|
radius1 = v[0];
|
|
radius2 = v[1];
|
|
height = v[2];
|
|
}
|
|
else if ( (*it)->isMaterial() )
|
|
{
|
|
material = processMaterial(*it);
|
|
}
|
|
}
|
|
|
|
ShapeRef cyl = new Cyl(radius1, radius2, height);
|
|
if ( ! material.isNull() )
|
|
cyl->setMaterial(material);
|
|
cyl->setTransform(m_transforms.top());
|
|
|
|
if (restore_transform)
|
|
m_transforms.pop();
|
|
|
|
return cyl;
|
|
}
|
|
|
|
refptr<Light> Scene::processLight(refptr<Node> node)
|
|
{
|
|
refptr<Light> light = new PointLight();
|
|
|
|
for (Node_Iterator it = node->getChildren().begin();
|
|
it != node->getChildren().end();
|
|
it++)
|
|
{
|
|
if ( typeid(**it) == typeid(PositionNode) )
|
|
{
|
|
refptr<Vector> v = (*it)->getVector();
|
|
light->setPosition(m_transforms.top().transform_point(*v));
|
|
}
|
|
else if ( typeid(**it) == typeid(DiffuseNode) )
|
|
{
|
|
Color c((*it)->getVector());
|
|
light->setDiffuseColor(c);
|
|
}
|
|
else if ( typeid(**it) == typeid(SpecularNode) )
|
|
{
|
|
Color c((*it)->getVector());
|
|
light->setSpecularColor(c);
|
|
}
|
|
else if ( typeid(**it) == typeid(ColorNode) )
|
|
{
|
|
Color c((*it)->getVector());
|
|
light->setDiffuseColor(c);
|
|
light->setSpecularColor(c);
|
|
}
|
|
else if ( typeid(**it) == typeid(RadiusNode) )
|
|
{
|
|
light->setRadius((*it)->getNumber());
|
|
}
|
|
else if ( typeid(**it) == typeid(JitterNode) )
|
|
{
|
|
light->setJitter((*it)->getInteger());
|
|
}
|
|
}
|
|
|
|
return light;
|
|
}
|
|
|
|
ShapeRef Scene::processPlane(refptr<Node> node)
|
|
{
|
|
Vector normal(0, 0, 1);
|
|
double dist = 0;
|
|
refptr<Material> material;
|
|
|
|
bool restore_transform = processTransforms(node);
|
|
|
|
for (Node_Iterator it = node->getChildren().begin();
|
|
it != node->getChildren().end();
|
|
it++)
|
|
{
|
|
if ( typeid(**it) == typeid(PlanePositionNode) )
|
|
{
|
|
normal = *(*it)->getVector();
|
|
dist = (*it)->getNumber();
|
|
}
|
|
else if ( (*it)->isMaterial() )
|
|
{
|
|
material = processMaterial(*it);
|
|
}
|
|
}
|
|
|
|
ShapeRef plane = new Plane(normal[0],
|
|
normal[1],
|
|
normal[2],
|
|
dist);
|
|
if ( ! material.isNull() )
|
|
plane->setMaterial(material);
|
|
plane->setTransform(m_transforms.top());
|
|
|
|
if (restore_transform)
|
|
m_transforms.pop();
|
|
|
|
return plane;
|
|
}
|
|
|
|
ShapeRef Scene::processSphere(refptr<Node> node)
|
|
{
|
|
double radius = 1.0;
|
|
refptr<Material> material;
|
|
|
|
bool restore_transform = processTransforms(node);
|
|
|
|
for (Node_Iterator it = node->getChildren().begin();
|
|
it != node->getChildren().end();
|
|
it++)
|
|
{
|
|
if ( typeid(**it) == typeid(RadiusNode) )
|
|
{
|
|
radius = (*it)->getNumber();
|
|
}
|
|
else if ( (*it)->isMaterial() )
|
|
{
|
|
material = processMaterial(*it);
|
|
}
|
|
}
|
|
|
|
ShapeRef sphere = new Sphere(radius);
|
|
if ( ! material.isNull() )
|
|
sphere->setMaterial(material);
|
|
sphere->setTransform(m_transforms.top());
|
|
|
|
if (restore_transform)
|
|
m_transforms.pop();
|
|
|
|
return sphere;
|
|
}
|
|
|
|
ShapeRef Scene::processBool(refptr<Node> node)
|
|
{
|
|
vector<ShapeRef> shapes;
|
|
refptr<Material> material;
|
|
|
|
bool restore_transform = processTransforms(node);
|
|
m_transforms.push(Transform());
|
|
|
|
for (Node_Iterator it = node->getChildren().begin();
|
|
it != node->getChildren().end();
|
|
it++)
|
|
{
|
|
if ( (*it)->isShape() )
|
|
{
|
|
ShapeRef shape = processShape(*it);
|
|
if ( ! shape.isNull() )
|
|
shapes.push_back(shape);
|
|
}
|
|
else if ( (*it)->isMaterial() )
|
|
{
|
|
material = processMaterial(*it);
|
|
}
|
|
else if ( (*it)->isTransformBlock() )
|
|
{
|
|
vector<ShapeRef> 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);
|
|
}
|
|
}
|
|
|
|
if (shapes.size() < 2)
|
|
{
|
|
cerr << "Error: boolean objects must have 2 or more sub-objects!"
|
|
<< endl;
|
|
exit(3);
|
|
}
|
|
|
|
ShapeRef shape;
|
|
if ( typeid(*node) == typeid(IntersectNode) )
|
|
shape = new Intersect(shapes);
|
|
else if ( typeid(*node) == typeid(UnionNode) )
|
|
shape = new Union(shapes);
|
|
else if ( typeid(*node) == typeid(SubtractNode) )
|
|
shape = new Subtract(shapes);
|
|
else
|
|
{
|
|
cerr << __FILE__ << ": " << __LINE__
|
|
<< ": error: bool object unrecognized" << endl;
|
|
exit(3);
|
|
}
|
|
|
|
if ( ! material.isNull() )
|
|
shape->setMaterial(material);
|
|
|
|
m_transforms.pop();
|
|
shape->setTransform(m_transforms.top());
|
|
if (restore_transform)
|
|
m_transforms.pop();
|
|
|
|
return shape;
|
|
}
|
|
|
|
ShapeRef Scene::processExtrude(refptr<Node> node)
|
|
{
|
|
refptr<Material> material;
|
|
Extrude * extrude = new Extrude();
|
|
|
|
bool restore_transform = processTransforms(node);
|
|
|
|
for (Node_Iterator it = node->getChildren().begin();
|
|
it != node->getChildren().end();
|
|
it++)
|
|
{
|
|
if ( typeid(**it) == typeid(PolygonNode) )
|
|
{
|
|
extrude->addPolygon(processPolygon(*it));
|
|
}
|
|
else if ( typeid(**it) == typeid(NGonNode) )
|
|
{
|
|
extrude->addPolygon(processNGon(*it));
|
|
}
|
|
else if ( typeid(**it) == typeid(OffsetNode) )
|
|
{
|
|
double distance = (*it)->getNumber();
|
|
if (distance <= 0.0)
|
|
{
|
|
cerr << "Error: extrude distance must be positive" << endl;
|
|
exit(3);
|
|
}
|
|
Vector scale(1, 1, 1);
|
|
Vector position(0, 0, 0);
|
|
for (Node_Iterator it2 = (*it)->getChildren().begin();
|
|
it2 != (*it)->getChildren().end();
|
|
it2++)
|
|
{
|
|
if ( typeid(**it2) == typeid(ScaleNode) )
|
|
{
|
|
scale = * (*it2)->getVector();
|
|
}
|
|
else if ( typeid(**it2) == typeid(PositionNode) )
|
|
{
|
|
position = * (*it2)->getVector();
|
|
}
|
|
}
|
|
if (scale[0] < 0.0 || scale[1] < 0.0)
|
|
{
|
|
cerr << "Error: extrude scale cannot be negative" << endl;
|
|
exit(3);
|
|
}
|
|
extrude->addOffset(distance, scale, position);
|
|
}
|
|
else if ( (*it)->isMaterial() )
|
|
{
|
|
material = processMaterial(*it);
|
|
}
|
|
}
|
|
|
|
if ( ! material.isNull() )
|
|
extrude->setMaterial(material);
|
|
extrude->setTransform(m_transforms.top());
|
|
|
|
if (restore_transform)
|
|
m_transforms.pop();
|
|
|
|
return extrude;
|
|
}
|
|
|
|
refptr<Polygon> Scene::processPolygon(refptr<Node> node)
|
|
{
|
|
refptr<Polygon> p = new Polygon();
|
|
for (Node_Iterator it = node->getChildren().begin();
|
|
it != node->getChildren().end();
|
|
it++)
|
|
{
|
|
if ( typeid(**it) == typeid(VectorNode) )
|
|
{
|
|
p->push_back((*it)->getVector());
|
|
}
|
|
else
|
|
{
|
|
cerr << "Error: Unknown polygon sub-object" << endl;
|
|
exit(3);
|
|
}
|
|
}
|
|
if (p->size() < 3)
|
|
{
|
|
cerr << "Error: Polygon with fewer than three points!" << endl;
|
|
exit(3);
|
|
}
|
|
return p;
|
|
}
|
|
|
|
refptr<Polygon> Scene::processNGon(refptr<Node> node)
|
|
{
|
|
refptr<Polygon> p = new Polygon();
|
|
double radius = node->getChildren()[0]->getNumber();
|
|
int n = node->getInteger();
|
|
int step = n < 0 ? -1 : 1;
|
|
n = abs(n);
|
|
if (n < 3)
|
|
n = 3;
|
|
int pos = 0;
|
|
double astep = 2.0 * M_PI / n;
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
p->push_back(new Vector(
|
|
radius * cos(pos * astep),
|
|
radius * sin(pos * astep),
|
|
0.0));
|
|
pos += step;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
ShapeRef Scene::processShapeRef(refptr<Node> node)
|
|
{
|
|
if (m_shape_definitions.find(node->getString())
|
|
== m_shape_definitions.end())
|
|
{
|
|
cerr << "Error: no shape definition for '" << node->getString()
|
|
<< "' found!" << endl;
|
|
exit(3);
|
|
}
|
|
|
|
refptr<Material> material;
|
|
ShapeRef shape = m_shape_definitions[node->getString()]->clone();
|
|
|
|
bool restore_transform = processTransforms(node);
|
|
|
|
for (Node_Iterator it = node->getChildren().begin();
|
|
it != node->getChildren().end();
|
|
it++)
|
|
{
|
|
if ( (*it)->isMaterial() )
|
|
{
|
|
material = processMaterial(*it);
|
|
}
|
|
}
|
|
|
|
if ( ! material.isNull() )
|
|
shape->setMaterial(material);
|
|
shape->setTransform(m_transforms.top() * shape->getTransform());
|
|
|
|
if (restore_transform)
|
|
m_transforms.pop();
|
|
|
|
return shape;
|
|
}
|
|
|
|
bool Scene::processTransforms(refptr<Node> node)
|
|
{
|
|
bool did_any = false;
|
|
|
|
for (Node_Iterator it = node->getChildren().begin();
|
|
it != node->getChildren().end();
|
|
it++)
|
|
{
|
|
if ( typeid(**it) == typeid(TranslateNode) )
|
|
{
|
|
if (did_any == false)
|
|
{
|
|
m_transforms.push(m_transforms.top());
|
|
did_any = true;
|
|
}
|
|
m_transforms.top().translate((*it)->getVector());
|
|
}
|
|
else if ( typeid(**it) == typeid(RotateNode) )
|
|
{
|
|
if (did_any == false)
|
|
{
|
|
m_transforms.push(m_transforms.top());
|
|
did_any = true;
|
|
}
|
|
m_transforms.top().rotate((*it)->getNumber(),
|
|
(*it)->getVector());
|
|
}
|
|
else if ( typeid(**it) == typeid(ScaleNode) )
|
|
{
|
|
if (did_any == false)
|
|
{
|
|
m_transforms.push(m_transforms.top());
|
|
did_any = true;
|
|
}
|
|
m_transforms.top().scale((*it)->getVector());
|
|
}
|
|
}
|
|
|
|
return did_any;
|
|
}
|
|
|
|
void Scene::processShapeDefinition(refptr<Node> node)
|
|
{
|
|
m_transforms.push(Transform());
|
|
m_shape_definitions[node->getString()]
|
|
= processShape(node->getChildren()[0]);
|
|
m_transforms.pop();
|
|
}
|
|
|
|
FIBITMAP * Scene::loadTexture(const std::string & filename)
|
|
{
|
|
FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(filename.c_str(), 0);
|
|
if (fif == FIF_UNKNOWN)
|
|
{
|
|
fif = FreeImage_GetFIFFromFilename(filename.c_str());
|
|
if (fif == FIF_UNKNOWN)
|
|
{
|
|
cerr << "Error: couldn't determine image format for \""
|
|
<< filename << "\"" << endl;
|
|
return NULL;
|
|
}
|
|
}
|
|
if (!FreeImage_FIFSupportsReading(fif))
|
|
{
|
|
cerr << "Error: image format of \"" << filename
|
|
<< "\" does not support reading" << endl;
|
|
return NULL;
|
|
}
|
|
FIBITMAP * fib = FreeImage_Load(fif, filename.c_str(), 0);
|
|
if (fib == NULL)
|
|
{
|
|
cerr << "Error: image \"" << filename << "\" could not be loaded"
|
|
<< endl;
|
|
}
|
|
return fib;
|
|
}
|