Merge with upstream
commit
d49e89fb94
|
@ -1,5 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
cp /opt/intel/composer_xe_*/compiler/lib/libiomp5.dylib Mitsuba.app/Contents/Frameworks
|
cp /opt/intel/composer_xe_*/compiler/lib/libiomp5.dylib Mitsuba.app/Contents/Frameworks
|
||||||
|
install_name_tool -id @rpath/libiomp5.dylib Mitsuba.app/Contents/Frameworks/libiomp5.dylib
|
||||||
find Mitsuba.app/Contents/MacOS/ Mitsuba.app/plugins -type f | xargs -n 1 install_name_tool -change libiomp5.dylib @rpath/libiomp5.dylib
|
find Mitsuba.app/Contents/MacOS/ Mitsuba.app/plugins -type f | xargs -n 1 install_name_tool -change libiomp5.dylib @rpath/libiomp5.dylib
|
||||||
find Mitsuba.app/Contents/Frameworks/libmitsuba-* -type f | xargs -n 1 install_name_tool -change libiomp5.dylib @rpath/libiomp5.dylib
|
find Mitsuba.app/Contents/Frameworks/libmitsuba-* -type f | xargs -n 1 install_name_tool -change libiomp5.dylib @rpath/libiomp5.dylib
|
||||||
find Mitsuba.app/python -type f | xargs -n 1 install_name_tool -change libiomp5.dylib @rpath/libiomp5.dylib
|
find Mitsuba.app/python -type f | xargs -n 1 install_name_tool -change libiomp5.dylib @rpath/libiomp5.dylib
|
||||||
|
|
|
@ -472,7 +472,7 @@ public:
|
||||||
template <typename T> void readArray(T *array, size_t count);
|
template <typename T> void readArray(T *array, size_t count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Read a known-size array from the stream (uses partial template
|
* \brief Read a known-size array from the stream (uses partial template
|
||||||
* specialization to select a method appropriate to the data type)
|
* specialization to select a method appropriate to the data type)
|
||||||
*/
|
*/
|
||||||
template <typename T, size_t N> inline void readArray(T (&arr)[N]) {
|
template <typename T, size_t N> inline void readArray(T (&arr)[N]) {
|
||||||
|
@ -484,9 +484,9 @@ public:
|
||||||
* specialization to select a method appropriate to the data type)
|
* specialization to select a method appropriate to the data type)
|
||||||
*/
|
*/
|
||||||
template <typename T> void writeArray(const T *array, size_t count);
|
template <typename T> void writeArray(const T *array, size_t count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Write a known-size array to the stream (uses partial template
|
* \brief Write a known-size array to the stream (uses partial template
|
||||||
* specialization to select a method appropriate to the data type)
|
* specialization to select a method appropriate to the data type)
|
||||||
*/
|
*/
|
||||||
template <typename T, size_t N> inline void writeArray(const T (&arr)[N]) {
|
template <typename T, size_t N> inline void writeArray(const T (&arr)[N]) {
|
||||||
|
|
|
@ -141,7 +141,8 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static void destruct(void *data) {
|
inline static void destruct(void *data) {
|
||||||
delete static_cast<ValueType *>(data);
|
if (data)
|
||||||
|
delete static_cast<ValueType *>(data);
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
detail::ThreadLocalBase m_base;
|
detail::ThreadLocalBase m_base;
|
||||||
|
|
|
@ -189,6 +189,13 @@ template <typename T> inline TVector1<T> normalize(const TVector1<T> &v) {
|
||||||
return v / v.length();
|
return v / v.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T> inline TVector1<T> normalizeStrict(const TVector1<T> &v, const char *errMsg) {
|
||||||
|
Float length = v.length();
|
||||||
|
if (length == 0)
|
||||||
|
SLog(EError, "normalizeStrict(): %s", errMsg);
|
||||||
|
return v / length;
|
||||||
|
}
|
||||||
|
|
||||||
template <> inline TVector1<int> TVector1<int>::operator/(int s) const {
|
template <> inline TVector1<int> TVector1<int>::operator/(int s) const {
|
||||||
#ifdef MTS_DEBUG
|
#ifdef MTS_DEBUG
|
||||||
if (s == 0)
|
if (s == 0)
|
||||||
|
@ -380,6 +387,13 @@ template <typename T> inline TVector2<T> normalize(const TVector2<T> &v) {
|
||||||
return v / v.length();
|
return v / v.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T> inline TVector2<T> normalizeStrict(const TVector2<T> &v, const char *errMsg) {
|
||||||
|
Float length = v.length();
|
||||||
|
if (length == 0)
|
||||||
|
SLog(EError, "normalizeStrict(): %s", errMsg);
|
||||||
|
return v / length;
|
||||||
|
}
|
||||||
|
|
||||||
template <> inline TVector2<int> TVector2<int>::operator/(int s) const {
|
template <> inline TVector2<int> TVector2<int>::operator/(int s) const {
|
||||||
#ifdef MTS_DEBUG
|
#ifdef MTS_DEBUG
|
||||||
if (s == 0)
|
if (s == 0)
|
||||||
|
@ -582,6 +596,13 @@ template <typename T> inline TVector3<T> normalize(const TVector3<T> &v) {
|
||||||
return v / v.length();
|
return v / v.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T> inline TVector3<T> normalizeStrict(const TVector3<T> &v, const char *errMsg) {
|
||||||
|
Float length = v.length();
|
||||||
|
if (length == 0)
|
||||||
|
SLog(EError, "normalizeStrict(): %s", errMsg);
|
||||||
|
return v / length;
|
||||||
|
}
|
||||||
|
|
||||||
template <> inline TVector3<int> TVector3<int>::operator/(int s) const {
|
template <> inline TVector3<int> TVector3<int>::operator/(int s) const {
|
||||||
#ifdef MTS_DEBUG
|
#ifdef MTS_DEBUG
|
||||||
if (s == 0)
|
if (s == 0)
|
||||||
|
@ -781,6 +802,13 @@ template <typename T> inline TVector4<T> normalize(const TVector4<T> &v) {
|
||||||
return v / v.length();
|
return v / v.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T> inline TVector4<T> normalizeStrict(const TVector4<T> &v, const char *errMsg) {
|
||||||
|
Float length = v.length();
|
||||||
|
if (length == 0)
|
||||||
|
SLog(EError, "normalizeStrict(): %s", errMsg);
|
||||||
|
return v / length;
|
||||||
|
}
|
||||||
|
|
||||||
template <> inline TVector4<int> TVector4<int>::operator/(int s) const {
|
template <> inline TVector4<int> TVector4<int>::operator/(int s) const {
|
||||||
#ifdef MTS_DEBUG
|
#ifdef MTS_DEBUG
|
||||||
if (s == 0)
|
if (s == 0)
|
||||||
|
|
|
@ -101,6 +101,9 @@ public:
|
||||||
/// Free the memory taken up by staticInitialization()
|
/// Free the memory taken up by staticInitialization()
|
||||||
static void staticShutdown();
|
static void staticShutdown();
|
||||||
|
|
||||||
|
/// Push a cleanup handler to be executed after loading the scene is done
|
||||||
|
static void pushCleanupHandler(void (*cleanup)());
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// Implementation of the SAX DocumentHandler interface
|
// Implementation of the SAX DocumentHandler interface
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
|
@ -312,9 +312,10 @@ protected:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Reads the header information of a compressed file, returning
|
* \brief Reads the header information of a compressed file, returning
|
||||||
* the version ID. This function assumes the stream is at the beginning
|
* the version ID.
|
||||||
* of the compressed file and leaves the stream located right after the
|
*
|
||||||
* header.
|
* This function assumes the stream is at the beginning of the compressed
|
||||||
|
* file and leaves the stream located right after the header.
|
||||||
*/
|
*/
|
||||||
static short readHeader(Stream *stream);
|
static short readHeader(Stream *stream);
|
||||||
|
|
||||||
|
|
|
@ -318,11 +318,11 @@ public:
|
||||||
|
|
||||||
Point2 sample(_sample);
|
Point2 sample(_sample);
|
||||||
if (sampleSpecular && sampleNested) {
|
if (sampleSpecular && sampleNested) {
|
||||||
if (sample.x > probSpecular) {
|
if (sample.x < probSpecular) {
|
||||||
|
sample.x /= probSpecular;
|
||||||
|
} else {
|
||||||
sample.x = (sample.x - probSpecular) / (1 - probSpecular);
|
sample.x = (sample.x - probSpecular) / (1 - probSpecular);
|
||||||
choseSpecular = false;
|
choseSpecular = false;
|
||||||
} else {
|
|
||||||
sample.x /= probSpecular;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -321,7 +321,7 @@ public:
|
||||||
(1-Fi) * (1-m_specularSamplingWeight));
|
(1-Fi) * (1-m_specularSamplingWeight));
|
||||||
|
|
||||||
/* Importance sample wrt. the Fresnel reflectance */
|
/* Importance sample wrt. the Fresnel reflectance */
|
||||||
if (sample.x <= probSpecular) {
|
if (sample.x < probSpecular) {
|
||||||
bRec.sampledComponent = 0;
|
bRec.sampledComponent = 0;
|
||||||
bRec.sampledType = EDeltaReflection;
|
bRec.sampledType = EDeltaReflection;
|
||||||
bRec.wo = reflect(bRec.wi);
|
bRec.wo = reflect(bRec.wi);
|
||||||
|
@ -384,7 +384,7 @@ public:
|
||||||
(1-Fi) * (1-m_specularSamplingWeight));
|
(1-Fi) * (1-m_specularSamplingWeight));
|
||||||
|
|
||||||
/* Importance sample wrt. the Fresnel reflectance */
|
/* Importance sample wrt. the Fresnel reflectance */
|
||||||
if (sample.x <= probSpecular) {
|
if (sample.x < probSpecular) {
|
||||||
bRec.sampledComponent = 0;
|
bRec.sampledComponent = 0;
|
||||||
bRec.sampledType = EDeltaReflection;
|
bRec.sampledType = EDeltaReflection;
|
||||||
bRec.wo = reflect(bRec.wi);
|
bRec.wo = reflect(bRec.wi);
|
||||||
|
|
|
@ -391,7 +391,7 @@ public:
|
||||||
(probSpecular*m_specularSamplingWeight +
|
(probSpecular*m_specularSamplingWeight +
|
||||||
(1-probSpecular) * (1-m_specularSamplingWeight));
|
(1-probSpecular) * (1-m_specularSamplingWeight));
|
||||||
|
|
||||||
if (sample.y <= probSpecular) {
|
if (sample.y < probSpecular) {
|
||||||
sample.y /= probSpecular;
|
sample.y /= probSpecular;
|
||||||
} else {
|
} else {
|
||||||
sample.y = (sample.y - probSpecular) / (1 - probSpecular);
|
sample.y = (sample.y - probSpecular) / (1 - probSpecular);
|
||||||
|
|
|
@ -254,7 +254,7 @@ public:
|
||||||
if (child->getClass()->derivesFrom(MTS_CLASS(Texture))) {
|
if (child->getClass()->derivesFrom(MTS_CLASS(Texture))) {
|
||||||
if (name == "reflectance" || name == "diffuseReflectance")
|
if (name == "reflectance" || name == "diffuseReflectance")
|
||||||
m_reflectance = static_cast<Texture *>(child);
|
m_reflectance = static_cast<Texture *>(child);
|
||||||
if (name == "alpha")
|
else if (name == "alpha")
|
||||||
m_alpha = static_cast<Texture *>(child);
|
m_alpha = static_cast<Texture *>(child);
|
||||||
else
|
else
|
||||||
BSDF::addChild(name, child);
|
BSDF::addChild(name, child);
|
||||||
|
|
|
@ -447,7 +447,7 @@ public:
|
||||||
(probSpecular*m_specularSamplingWeight +
|
(probSpecular*m_specularSamplingWeight +
|
||||||
(1-probSpecular) * (1-m_specularSamplingWeight));
|
(1-probSpecular) * (1-m_specularSamplingWeight));
|
||||||
|
|
||||||
if (sample.y <= probSpecular) {
|
if (sample.y < probSpecular) {
|
||||||
sample.y /= probSpecular;
|
sample.y /= probSpecular;
|
||||||
} else {
|
} else {
|
||||||
sample.y = (sample.y - probSpecular) / (1 - probSpecular);
|
sample.y = (sample.y - probSpecular) / (1 - probSpecular);
|
||||||
|
|
|
@ -50,7 +50,7 @@ void PSSMLTSampler::serialize(Stream *stream, InstanceManager *manager) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PSSMLTSampler::configure() {
|
void PSSMLTSampler::configure() {
|
||||||
m_logRatio = -std::log(m_s2/m_s1);
|
m_logRatio = -math::fastlog(m_s2/m_s1);
|
||||||
m_time = 0;
|
m_time = 0;
|
||||||
m_largeStepTime = 0;
|
m_largeStepTime = 0;
|
||||||
m_largeStep = false;
|
m_largeStep = false;
|
||||||
|
|
|
@ -133,22 +133,24 @@ struct ThreadLocalBase::ThreadLocalPrivate {
|
||||||
/// Look up a TLS entry. The goal is to make this operation very fast!
|
/// Look up a TLS entry. The goal is to make this operation very fast!
|
||||||
std::pair<void *, bool> get() {
|
std::pair<void *, bool> get() {
|
||||||
bool existed = true;
|
bool existed = true;
|
||||||
|
void *data;
|
||||||
|
|
||||||
#if defined(__OSX__)
|
#if defined(__OSX__)
|
||||||
PerThreadData *ptd = (PerThreadData *) pthread_getspecific(ptdLocal);
|
PerThreadData *ptd = (PerThreadData *) pthread_getspecific(ptdLocal);
|
||||||
#else
|
#else
|
||||||
PerThreadData *ptd = ptdLocal;
|
PerThreadData *ptd = ptdLocal;
|
||||||
#endif
|
#endif
|
||||||
if(EXPECT_NOT_TAKEN(!ptd)) {
|
if (EXPECT_NOT_TAKEN(!ptd))
|
||||||
throw std::runtime_error("null per-thread data");
|
throw std::runtime_error("Internal error: call to ThreadLocalPrivate::get() "
|
||||||
}
|
" precedes the construction of thread-specific data structures!");
|
||||||
|
|
||||||
void *data;
|
/* This is an uncontended thread-local lock (i.e. not to worry) */
|
||||||
boost::lock_guard<boost::recursive_mutex> guard(ptd->mutex);
|
boost::lock_guard<boost::recursive_mutex> guard(ptd->mutex);
|
||||||
PerThreadData::key_iterator it = ptd->map.find(this);
|
PerThreadData::key_iterator it = ptd->map.find(this);
|
||||||
if (EXPECT_TAKEN(it != ptd->map.end())) {
|
if (EXPECT_TAKEN(it != ptd->map.end())) {
|
||||||
data = it->second.data;
|
data = it->second.data;
|
||||||
} else {
|
} else {
|
||||||
|
/* This is the first access from this thread */
|
||||||
TLSEntry entry;
|
TLSEntry entry;
|
||||||
entry.data = data = constructFunctor();
|
entry.data = data = constructFunctor();
|
||||||
entry.destructFunctor = destructFunctor;
|
entry.destructFunctor = destructFunctor;
|
||||||
|
|
|
@ -189,8 +189,8 @@ Transform Transform::glOrthographic(Float clipLeft, Float clipRight,
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform Transform::lookAt(const Point &p, const Point &t, const Vector &up) {
|
Transform Transform::lookAt(const Point &p, const Point &t, const Vector &up) {
|
||||||
Vector dir = normalize(t-p);
|
Vector dir = normalizeStrict(t-p, "lookAt(): 'origin' and 'target' coincide!");
|
||||||
Vector left = normalize(cross(up, dir));
|
Vector left = normalizeStrict(cross(up, dir), "lookAt(): the forward and upward direction must be linearly independent!");
|
||||||
Vector newUp = cross(dir, left);
|
Vector newUp = cross(dir, left);
|
||||||
|
|
||||||
Matrix4x4 result, inverse;
|
Matrix4x4 result, inverse;
|
||||||
|
|
|
@ -137,7 +137,7 @@ Point2 Warp::squareToStdNormal(const Point2 &sample) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Float Warp::squareToStdNormalPdf(const Point2 &pos) {
|
Float Warp::squareToStdNormalPdf(const Point2 &pos) {
|
||||||
return INV_TWOPI * std::exp(-(pos.x*pos.x + pos.y*pos.y)/2.0f);
|
return INV_TWOPI * math::fastexp(-(pos.x*pos.x + pos.y*pos.y)/2.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Float intervalToTent(Float sample) {
|
static Float intervalToTent(Float sample) {
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <mitsuba/core/fresolver.h>
|
#include <mitsuba/core/fresolver.h>
|
||||||
#include <mitsuba/render/scene.h>
|
#include <mitsuba/render/scene.h>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <boost/unordered_set.hpp>
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
XERCES_CPP_NAMESPACE_USE
|
XERCES_CPP_NAMESPACE_USE
|
||||||
|
@ -46,6 +47,10 @@ XERCES_CPP_NAMESPACE_USE
|
||||||
level, NULL, __FILE__, __LINE__, fmt, ## __VA_ARGS__)
|
level, NULL, __FILE__, __LINE__, fmt, ## __VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef void (*CleanupFun) ();
|
||||||
|
typedef boost::unordered_set<CleanupFun> CleanupSet;
|
||||||
|
static PrimitiveThreadLocal<CleanupSet> __cleanup_tls;
|
||||||
|
|
||||||
SceneHandler::SceneHandler(const SAXParser *parser,
|
SceneHandler::SceneHandler(const SAXParser *parser,
|
||||||
const ParameterMap ¶ms, NamedObjectMap *namedObjects,
|
const ParameterMap ¶ms, NamedObjectMap *namedObjects,
|
||||||
bool isIncludedFile) : m_parser(parser), m_params(params),
|
bool isIncludedFile) : m_parser(parser), m_params(params),
|
||||||
|
@ -155,6 +160,13 @@ void SceneHandler::startDocument() {
|
||||||
|
|
||||||
void SceneHandler::endDocument() {
|
void SceneHandler::endDocument() {
|
||||||
SAssert(m_scene != NULL);
|
SAssert(m_scene != NULL);
|
||||||
|
|
||||||
|
/* Call cleanup handlers */
|
||||||
|
CleanupSet &cleanup = __cleanup_tls.get();
|
||||||
|
for (CleanupSet::iterator it = cleanup.begin();
|
||||||
|
it != cleanup.end(); ++it)
|
||||||
|
(*it)();
|
||||||
|
cleanup.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneHandler::characters(const XMLCh* const name,
|
void SceneHandler::characters(const XMLCh* const name,
|
||||||
|
@ -247,6 +259,10 @@ void SceneHandler::startElement(const XMLCh* const xmlName,
|
||||||
m_context.push(context);
|
m_context.push(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SceneHandler::pushCleanupHandler(void (*cleanup)()) {
|
||||||
|
__cleanup_tls.get().insert(cleanup);
|
||||||
|
}
|
||||||
|
|
||||||
void SceneHandler::endElement(const XMLCh* const xmlName) {
|
void SceneHandler::endElement(const XMLCh* const xmlName) {
|
||||||
std::string name = transcode(xmlName);
|
std::string name = transcode(xmlName);
|
||||||
ParseContext &context = m_context.top();
|
ParseContext &context = m_context.top();
|
||||||
|
|
|
@ -260,6 +260,7 @@ void PerspectiveCamera::configure() {
|
||||||
SLog(EError, "Could not parse the focal length (must be of the form "
|
SLog(EError, "Could not parse the focal length (must be of the form "
|
||||||
"<x>mm, where <x> is a positive integer)!");
|
"<x>mm, where <x> is a positive integer)!");
|
||||||
|
|
||||||
|
m_properties.removeProperty("focalLength");
|
||||||
setDiagonalFov(2 * 180/M_PI* std::atan(std::sqrt((Float) (36*36+24*24)) / (2*value)));
|
setDiagonalFov(2 * 180/M_PI* std::atan(std::sqrt((Float) (36*36+24*24)) / (2*value)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,7 +176,7 @@ void TriMesh::loadCompressed(Stream *_stream, int index) {
|
||||||
|
|
||||||
if (stream->getByteOrder() != Stream::ELittleEndian)
|
if (stream->getByteOrder() != Stream::ELittleEndian)
|
||||||
Log(EError, "Tried to unserialize a shape from a stream, "
|
Log(EError, "Tried to unserialize a shape from a stream, "
|
||||||
"which was not previously set to little endian byte order!");
|
"which was not previously set to little endian byte order!");
|
||||||
|
|
||||||
const short version = readHeader(stream);
|
const short version = readHeader(stream);
|
||||||
|
|
||||||
|
@ -305,7 +305,7 @@ int TriMesh::readOffsetDictionary(Stream *stream, short version,
|
||||||
+ sizeof(char) // Name
|
+ sizeof(char) // Name
|
||||||
+ 2*sizeof(uint64_t) // Number of vertices and triangles
|
+ 2*sizeof(uint64_t) // Number of vertices and triangles
|
||||||
+ 3*sizeof(float) // One vertex
|
+ 3*sizeof(float) // One vertex
|
||||||
+ 3*sizeof(uint32_t)); // One triange
|
+ 3*sizeof(uint32_t)); // One triangle
|
||||||
|
|
||||||
if (streamSize >= minSize) {
|
if (streamSize >= minSize) {
|
||||||
outOffsets.resize(count);
|
outOffsets.resize(count);
|
||||||
|
@ -314,9 +314,8 @@ int TriMesh::readOffsetDictionary(Stream *stream, short version,
|
||||||
if (typeid(size_t) == typeid(uint64_t)) {
|
if (typeid(size_t) == typeid(uint64_t)) {
|
||||||
stream->readArray(&outOffsets[0], count);
|
stream->readArray(&outOffsets[0], count);
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < count; ++i) {
|
for (size_t i = 0; i < count; ++i)
|
||||||
outOffsets[i] = static_cast<size_t>(stream->readSize());
|
outOffsets[i] = stream->readSize();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
stream->seek(stream->getSize() - sizeof(uint32_t) * (count + 1));
|
stream->seek(stream->getSize() - sizeof(uint32_t) * (count + 1));
|
||||||
|
@ -325,7 +324,7 @@ int TriMesh::readOffsetDictionary(Stream *stream, short version,
|
||||||
stream->readArray(&outOffsets[0], count);
|
stream->readArray(&outOffsets[0], count);
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < count; ++i) {
|
for (size_t i = 0; i < count; ++i) {
|
||||||
outOffsets[i] = stream->readUInt();
|
outOffsets[i] = (size_t) stream->readUInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,8 @@ public:
|
||||||
Float eval(Float x) const {
|
Float eval(Float x) const {
|
||||||
Float alpha = -1.0f / (2.0f * m_stddev*m_stddev);
|
Float alpha = -1.0f / (2.0f * m_stddev*m_stddev);
|
||||||
return std::max((Float) 0.0f,
|
return std::max((Float) 0.0f,
|
||||||
std::exp(alpha * x * x) -
|
math::fastexp(alpha * x * x) -
|
||||||
std::exp(alpha * m_radius * m_radius));
|
math::fastexp(alpha * m_radius * m_radius));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string toString() const {
|
std::string toString() const {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mitsuba/render/trimesh.h>
|
#include <mitsuba/render/trimesh.h>
|
||||||
|
#include <mitsuba/render/scenehandler.h>
|
||||||
#include <mitsuba/core/properties.h>
|
#include <mitsuba/core/properties.h>
|
||||||
#include <mitsuba/core/fstream.h>
|
#include <mitsuba/core/fstream.h>
|
||||||
#include <mitsuba/core/fresolver.h>
|
#include <mitsuba/core/fresolver.h>
|
||||||
|
@ -211,16 +212,15 @@ public:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class for loading serialized meshes from the same file
|
* Helper class for loading serialized meshes from the same file
|
||||||
* repeatedly: it is common for scene to load multiple meshes from the same
|
* repeatedly: it is common for scene to load multiple meshes from the same
|
||||||
* file, most times even in ascending order. This class loads the mesh
|
* file, most times even in ascending order. This class loads the mesh
|
||||||
* offsets dictionary only once and keeps the stream open.
|
* offsets dictionary only once and keeps the stream open.
|
||||||
*
|
*
|
||||||
* Instances of this class are not thread safe.
|
* Instances of this class are not thread safe.
|
||||||
*/
|
*/
|
||||||
class MeshLoader {
|
class MeshLoader {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MeshLoader(const fs::path& filePath) {
|
MeshLoader(const fs::path& filePath) {
|
||||||
m_fstream = new FileStream(filePath, FileStream::EReadOnly);
|
m_fstream = new FileStream(filePath, FileStream::EReadOnly);
|
||||||
m_fstream->setByteOrder(Stream::ELittleEndian);
|
m_fstream->setByteOrder(Stream::ELittleEndian);
|
||||||
|
@ -264,6 +264,11 @@ private:
|
||||||
&boost::make_shared<MeshLoader, const fs::path&>) {}
|
&boost::make_shared<MeshLoader, const fs::path&>) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Release all currently held offset caches / file streams
|
||||||
|
static void flushCache() {
|
||||||
|
m_cache.set(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/// Loads the mesh from the thread-local file stream cache
|
/// Loads the mesh from the thread-local file stream cache
|
||||||
void loadCompressed(const fs::path& filePath, const int idx) {
|
void loadCompressed(const fs::path& filePath, const int idx) {
|
||||||
if (EXPECT_NOT_TAKEN(idx < 0)) {
|
if (EXPECT_NOT_TAKEN(idx < 0)) {
|
||||||
|
@ -276,6 +281,7 @@ private:
|
||||||
if (EXPECT_NOT_TAKEN(cache == NULL)) {
|
if (EXPECT_NOT_TAKEN(cache == NULL)) {
|
||||||
cache = new FileStreamCache();
|
cache = new FileStreamCache();
|
||||||
m_cache.set(cache);
|
m_cache.set(cache);
|
||||||
|
SceneHandler::pushCleanupHandler(&SerializedMesh::flushCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<MeshLoader> meshLoader = cache->get(filePath);
|
boost::shared_ptr<MeshLoader> meshLoader = cache->get(filePath);
|
||||||
|
@ -288,7 +294,6 @@ private:
|
||||||
|
|
||||||
ThreadLocal<SerializedMesh::FileStreamCache> SerializedMesh::m_cache;
|
ThreadLocal<SerializedMesh::FileStreamCache> SerializedMesh::m_cache;
|
||||||
|
|
||||||
|
|
||||||
MTS_IMPLEMENT_CLASS_S(SerializedMesh, false, TriMesh)
|
MTS_IMPLEMENT_CLASS_S(SerializedMesh, false, TriMesh)
|
||||||
MTS_EXPORT_PLUGIN(SerializedMesh, "Serialized mesh loader");
|
MTS_EXPORT_PLUGIN(SerializedMesh, "Serialized mesh loader");
|
||||||
MTS_NAMESPACE_END
|
MTS_NAMESPACE_END
|
||||||
|
|
|
@ -58,7 +58,7 @@ public:
|
||||||
|
|
||||||
if (m_type == Properties::EFloat)
|
if (m_type == Properties::EFloat)
|
||||||
m_float = props.getFloat("value");
|
m_float = props.getFloat("value");
|
||||||
else if (m_type == Properties::EPoint)
|
else if (m_type == Properties::EVector)
|
||||||
m_vector = props.getVector("value");
|
m_vector = props.getVector("value");
|
||||||
else if (m_type == Properties::ESpectrum)
|
else if (m_type == Properties::ESpectrum)
|
||||||
m_spectrum = props.getSpectrum("value");
|
m_spectrum = props.getSpectrum("value");
|
||||||
|
@ -72,7 +72,7 @@ public:
|
||||||
m_type = stream->readInt();
|
m_type = stream->readInt();
|
||||||
if (m_type == Properties::EFloat)
|
if (m_type == Properties::EFloat)
|
||||||
m_float = stream->readFloat();
|
m_float = stream->readFloat();
|
||||||
else if (m_type == Properties::EPoint)
|
else if (m_type == Properties::EVector)
|
||||||
m_vector = Vector(stream);
|
m_vector = Vector(stream);
|
||||||
else if (m_type == Properties::ESpectrum)
|
else if (m_type == Properties::ESpectrum)
|
||||||
m_spectrum = Spectrum(stream);
|
m_spectrum = Spectrum(stream);
|
||||||
|
|
Loading…
Reference in New Issue