nori/src/scene.cpp

124 lines
3.4 KiB
C++

/*
This file is part of Nori, a simple educational ray tracer
Copyright (c) 2015 by Wenzel Jakob
Nori is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License Version 3
as published by the Free Software Foundation.
Nori is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <nori/scene.h>
#include <nori/bitmap.h>
#include <nori/integrator.h>
#include <nori/sampler.h>
#include <nori/camera.h>
#include <nori/emitter.h>
NORI_NAMESPACE_BEGIN
Scene::Scene(const PropertyList &) {
m_accel = new Accel();
}
Scene::~Scene() {
delete m_accel;
delete m_sampler;
delete m_camera;
delete m_integrator;
}
void Scene::activate() {
m_accel->build();
if (!m_integrator)
throw NoriException("No integrator was specified!");
if (!m_camera)
throw NoriException("No camera was specified!");
if (!m_sampler) {
/* Create a default (independent) sampler */
m_sampler = static_cast<Sampler*>(
NoriObjectFactory::createInstance("independent", PropertyList()));
}
cout << endl;
cout << "Configuration: " << toString() << endl;
cout << endl;
}
void Scene::addChild(NoriObject *obj) {
switch (obj->getClassType()) {
case EMesh: {
Mesh *mesh = static_cast<Mesh *>(obj);
m_accel->addMesh(mesh);
m_meshes.push_back(mesh);
}
break;
case EEmitter: {
//Emitter *emitter = static_cast<Emitter *>(obj);
/* TBD */
throw NoriException("Scene::addChild(): You need to implement this for emitters");
}
break;
case ESampler:
if (m_sampler)
throw NoriException("There can only be one sampler per scene!");
m_sampler = static_cast<Sampler *>(obj);
break;
case ECamera:
if (m_camera)
throw NoriException("There can only be one camera per scene!");
m_camera = static_cast<Camera *>(obj);
break;
case EIntegrator:
if (m_integrator)
throw NoriException("There can only be one integrator per scene!");
m_integrator = static_cast<Integrator *>(obj);
break;
default:
throw NoriException("Scene::addChild(<%s>) is not supported!",
classTypeName(obj->getClassType()));
}
}
std::string Scene::toString() const {
std::string meshes;
for (size_t i=0; i<m_meshes.size(); ++i) {
meshes += std::string(" ") + indent(m_meshes[i]->toString(), 2);
if (i + 1 < m_meshes.size())
meshes += ",";
meshes += "\n";
}
return tfm::format(
"Scene[\n"
" integrator = %s,\n"
" sampler = %s\n"
" camera = %s,\n"
" meshes = {\n"
" %s }\n"
"]",
indent(m_integrator->toString()),
indent(m_sampler->toString()),
indent(m_camera->toString()),
indent(meshes, 2)
);
}
NORI_REGISTER_CLASS(Scene, "scene");
NORI_NAMESPACE_END