partial support for geometry instancing
parent
4c5b2a6942
commit
57d13dfe7b
|
@ -530,7 +530,8 @@ plugins += env.SharedLibrary('plugins/serialized', ['src/shapes/serialized.cpp']
|
|||
plugins += env.SharedLibrary('plugins/sphere', ['src/shapes/sphere.cpp'])
|
||||
plugins += env.SharedLibrary('plugins/cylinder', ['src/shapes/cylinder.cpp'])
|
||||
plugins += env.SharedLibrary('plugins/hair', ['src/shapes/hair.cpp'])
|
||||
#plugins += env.SharedLibrary('plugins/group', ['src/shapes/group.cpp'])
|
||||
plugins += env.SharedLibrary('plugins/shapegroup', ['src/shapes/shapegroup.cpp'])
|
||||
plugins += env.SharedLibrary('plugins/instance', ['src/shapes/instance.cpp'])
|
||||
|
||||
# Samplers
|
||||
plugins += env.SharedLibrary('plugins/independent', ['src/samplers/independent.cpp'])
|
||||
|
|
|
@ -34,6 +34,7 @@ class GatherPhotonProcess;
|
|||
class HemisphereSampler;
|
||||
class HWResource;
|
||||
class ImageBlock;
|
||||
class Instanced;
|
||||
class Integrator;
|
||||
struct Intersection;
|
||||
class IrradianceCache;
|
||||
|
|
|
@ -63,6 +63,7 @@ MTS_NAMESPACE_BEGIN
|
|||
*/
|
||||
class MTS_EXPORT_RENDER KDTree : public GenericKDTree<AABB, KDTree> {
|
||||
friend class GenericKDTree<AABB, KDTree>;
|
||||
friend class Instance;
|
||||
public:
|
||||
/// Create an empty kd-tree
|
||||
KDTree();
|
||||
|
|
|
@ -101,6 +101,7 @@
|
|||
<xsd:element name="subsurface" type="object"/>
|
||||
<xsd:element name="ref" type="reference"/>
|
||||
<xsd:element name="luminaire" type="luminaire"/>
|
||||
<xsd:element name="shape" type="shape"/>
|
||||
</xsd:choice>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
This file is part of Mitsuba, a physically based rendering system.
|
||||
|
||||
Copyright (c) 2007-2010 by Wenzel Jakob and others.
|
||||
|
||||
Mitsuba 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.
|
||||
|
||||
Mitsuba 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 "shapegroup.h"
|
||||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
class Instance : public Shape {
|
||||
public:
|
||||
Instance(const Properties &props) : Shape(props) {
|
||||
m_objectToWorld = props.getTransform("toWorld", Transform());
|
||||
m_worldToObject = m_objectToWorld.inverse();
|
||||
}
|
||||
|
||||
Instance(Stream *stream, InstanceManager *manager)
|
||||
: Shape(stream, manager) {
|
||||
m_shapeGroup = static_cast<ShapeGroup *>(manager->getInstance(stream));
|
||||
m_objectToWorld = Transform(stream);
|
||||
m_worldToObject = m_objectToWorld.inverse();
|
||||
}
|
||||
|
||||
void serialize(Stream *stream, InstanceManager *manager) const {
|
||||
Shape::serialize(stream, manager);
|
||||
m_objectToWorld.serialize(stream);
|
||||
manager->serialize(stream, m_shapeGroup.get());
|
||||
}
|
||||
|
||||
void configure() {
|
||||
if (!m_shapeGroup)
|
||||
Log(EError, "A reference to a 'shapegroup' must be specified!");
|
||||
}
|
||||
|
||||
AABB getAABB() const {
|
||||
const KDTree *kdtree = m_shapeGroup->getKDTree();
|
||||
const AABB &aabb = kdtree->getAABB();
|
||||
AABB result;
|
||||
for (int i=0; i<8; ++i)
|
||||
result.expandBy(m_objectToWorld(aabb.getCorner(i)));
|
||||
return result;
|
||||
}
|
||||
|
||||
Float getSurfaceArea() const {
|
||||
Log(EError, "Instance::getSurfaceArea(): not supported!");
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void addChild(const std::string &name, ConfigurableObject *child) {
|
||||
const Class *cClass = child->getClass();
|
||||
if (cClass->getName() == "ShapeGroup") {
|
||||
m_shapeGroup = static_cast<ShapeGroup *>(child);
|
||||
} else {
|
||||
Shape::addChild(name, child);
|
||||
}
|
||||
}
|
||||
|
||||
bool rayIntersect(const Ray &_ray, Float _mint,
|
||||
Float _maxt, Float &t, void *temp) const {
|
||||
const KDTree *kdtree = m_shapeGroup->getKDTree();
|
||||
Ray ray;
|
||||
m_worldToObject(_ray, ray);
|
||||
Float mint, maxt, tempT = std::numeric_limits<Float>::infinity();
|
||||
|
||||
if (kdtree->m_aabb.rayIntersect(ray, mint, maxt)) {
|
||||
if (_mint > mint) mint = _mint;
|
||||
if (_maxt < maxt) maxt = _maxt;
|
||||
|
||||
if (EXPECT_TAKEN(maxt > mint)) {
|
||||
if (kdtree->rayIntersectHavran<false>(ray, mint, maxt, tempT, temp)) {
|
||||
t = tempT;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rayIntersect(const Ray &_ray, Float _mint, Float _maxt) const {
|
||||
const KDTree *kdtree = m_shapeGroup->getKDTree();
|
||||
Ray ray;
|
||||
m_worldToObject(_ray, ray);
|
||||
Float mint, maxt, tempT = std::numeric_limits<Float>::infinity();
|
||||
|
||||
if (kdtree->m_aabb.rayIntersect(ray, mint, maxt)) {
|
||||
if (_mint > mint) mint = _mint;
|
||||
if (_maxt < maxt) maxt = _maxt;
|
||||
|
||||
if (EXPECT_TAKEN(maxt > mint)) {
|
||||
if (kdtree->rayIntersectHavran<true>(ray, mint, maxt, tempT, NULL))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void fillIntersectionRecord(const Ray &ray, Float t,
|
||||
const void *temp, Intersection &its) const {
|
||||
const KDTree *kdtree = m_shapeGroup->getKDTree();
|
||||
Log(EError, "fillIntersectionRecord(): Unsupported!");
|
||||
}
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
private:
|
||||
ref<ShapeGroup> m_shapeGroup;
|
||||
Transform m_objectToWorld, m_worldToObject;
|
||||
};
|
||||
|
||||
MTS_IMPLEMENT_CLASS_S(Instance, false, Shape)
|
||||
MTS_EXPORT_PLUGIN(Instance, "Instanced geometry");
|
||||
MTS_NAMESPACE_END
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
This file is part of Mitsuba, a physically based rendering system.
|
||||
|
||||
Copyright (c) 2007-2010 by Wenzel Jakob and others.
|
||||
|
||||
Mitsuba 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.
|
||||
|
||||
Mitsuba 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 "shapegroup.h"
|
||||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
ShapeGroup::ShapeGroup(const Properties &props) : Shape(props) {
|
||||
m_kdtree = new KDTree();
|
||||
}
|
||||
|
||||
ShapeGroup::ShapeGroup(Stream *stream, InstanceManager *manager)
|
||||
: Shape(stream, manager) {
|
||||
m_kdtree = new KDTree();
|
||||
size_t shapeCount = stream->readUInt();
|
||||
for (size_t i=0; i<shapeCount; ++i)
|
||||
m_kdtree->addShape(static_cast<Shape *>(manager->getInstance(stream)));
|
||||
configure();
|
||||
}
|
||||
|
||||
void ShapeGroup::serialize(Stream *stream, InstanceManager *manager) const {
|
||||
Shape::serialize(stream, manager);
|
||||
const std::vector<const Shape *> &shapes = m_kdtree->getShapes();
|
||||
stream->writeUInt((uint32_t) shapes.size());
|
||||
for (size_t i=0; i<shapes.size(); ++i)
|
||||
manager->serialize(stream, shapes[i]);
|
||||
}
|
||||
|
||||
void ShapeGroup::configure() {
|
||||
if (!m_kdtree->isBuilt())
|
||||
m_kdtree->build();
|
||||
}
|
||||
|
||||
AABB ShapeGroup::getAABB() const {
|
||||
return AABB();
|
||||
}
|
||||
|
||||
Float ShapeGroup::getSurfaceArea() const {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void ShapeGroup::addChild(const std::string &name, ConfigurableObject *child) {
|
||||
const Class *cClass = child->getClass();
|
||||
if (cClass->derivesFrom(ShapeGroup::m_theClass) || cClass->getName() == "ShapeInstance") {
|
||||
Log(EError, "Nested instancing is not supported!");
|
||||
} else if (cClass->derivesFrom(Shape::m_theClass)) {
|
||||
Shape *shape = static_cast<Shape *>(child);
|
||||
if (shape->isCompound()) {
|
||||
int index = 0;
|
||||
do {
|
||||
ref<Shape> element = shape->getElement(index++);
|
||||
if (element == NULL)
|
||||
break;
|
||||
addChild("", element);
|
||||
} while (true);
|
||||
} else {
|
||||
m_kdtree->addShape(shape);
|
||||
}
|
||||
} else {
|
||||
Shape::addChild(name, child);
|
||||
}
|
||||
}
|
||||
|
||||
bool ShapeGroup::isCompound() const {
|
||||
// this shape reduces to nothing (compound, no children)
|
||||
return true;
|
||||
}
|
||||
|
||||
MTS_IMPLEMENT_CLASS_S(ShapeGroup, false, Shape)
|
||||
MTS_EXPORT_PLUGIN(ShapeGroup, "Grouped geometry for instancing");
|
||||
MTS_NAMESPACE_END
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
This file is part of Mitsuba, a physically based rendering system.
|
||||
|
||||
Copyright (c) 2007-2010 by Wenzel Jakob and others.
|
||||
|
||||
Mitsuba 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.
|
||||
|
||||
Mitsuba 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 <mitsuba/render/kdtree.h>
|
||||
#include <mitsuba/render/bsdf.h>
|
||||
#include <mitsuba/render/subsurface.h>
|
||||
#include <mitsuba/render/luminaire.h>
|
||||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* \brief "Fake" shape that groups sub-shapes into a
|
||||
* separate KD-tree. When this shape is used by itself,
|
||||
* it doesn't actually generate any intersectable geometry.
|
||||
* Instead, the "instance" plugin must be used to create
|
||||
* references to the geometry stored inside it.
|
||||
*/
|
||||
class ShapeGroup : public Shape {
|
||||
public:
|
||||
/// Create a new shape group
|
||||
ShapeGroup(const Properties &props);
|
||||
|
||||
/// Unserialize from a binary data stream
|
||||
ShapeGroup(Stream *stream, InstanceManager *manager);
|
||||
|
||||
/// Serialize to a binary data stream
|
||||
void serialize(Stream *stream, InstanceManager *manager) const;
|
||||
|
||||
/// Build the internal KD-tree
|
||||
void configure();
|
||||
|
||||
/// Add a child object
|
||||
void addChild(const std::string &name, ConfigurableObject *child);
|
||||
|
||||
/// Return whether or not the shape is a compound object
|
||||
bool isCompound() const;
|
||||
|
||||
/// Returns an invalid AABB
|
||||
AABB getAABB() const;
|
||||
|
||||
/// Returns the surface area
|
||||
Float getSurfaceArea() const;
|
||||
|
||||
/// Return a pointer to the internal KD-tree
|
||||
inline const KDTree *getKDTree() const { return m_kdtree.get(); }
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
private:
|
||||
ref<KDTree> m_kdtree;
|
||||
};
|
||||
|
||||
MTS_NAMESPACE_END
|
Loading…
Reference in New Issue