From 0d00364edcf22cc94d0b3cd55303498523bad930 Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Thu, 12 Aug 2010 20:13:34 +0200 Subject: [PATCH] starting to work on a directional luminaire --- ChangeLog | 7 ++ SConstruct | 1 + src/collada/converter.cpp | 14 +++- src/luminaires/directional.cpp | 135 +++++++++++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 src/luminaires/directional.cpp diff --git a/ChangeLog b/ChangeLog index c062ef4c..a975596c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-08-12 Wenzel Jakob + + * converter.cpp: Much better import of COLLADA scenes from + blender. + + * importdlg.cpp: User interface for importing scenes. + 2010-08-09 Wenzel Jakob * rendersettingsdlg.cpp: Try to maintain the number of diff --git a/SConstruct b/SConstruct index df1051eb..46219eeb 100644 --- a/SConstruct +++ b/SConstruct @@ -528,6 +528,7 @@ plugins += env.SharedLibrary('plugins/envmap', ['src/luminaires/envmap.cpp']) plugins += env.SharedLibrary('plugins/spot', ['src/luminaires/spot.cpp']) plugins += env.SharedLibrary('plugins/point', ['src/luminaires/point.cpp']) plugins += env.SharedLibrary('plugins/collimated', ['src/luminaires/collimated.cpp']) +plugins += env.SharedLibrary('plugins/directional', ['src/luminaires/directional.cpp']) # Integrators plugins += env.SharedLibrary('plugins/direct', ['src/integrators/direct/direct.cpp']) diff --git a/src/collada/converter.cpp b/src/collada/converter.cpp index 79cbf993..c0926fa1 100644 --- a/src/collada/converter.cpp +++ b/src/collada/converter.cpp @@ -543,6 +543,18 @@ void loadLight(Transform transform, std::ostream &os, domLight &light) { os << "\t\t" << endl; os << "\t" << endl << endl; } + + domLight::domTechnique_common::domDirectional *directional = light.getTechnique_common()->getDirectional().cast(); + if (directional) { + domFloat3 &color = directional->getColor()->getValue(); + os << "\t" << endl; + os << "\t\t" << endl << endl; + os << "\t\t" << endl; + os << "\t\t\t" << endl; + os << "\t\t" << endl << endl; + os << "\t" << endl << endl; + } + domLight::domTechnique_common::domSpot *spot = light.getTechnique_common()->getSpot().cast(); if (spot) { domFloat3 &color = spot->getColor()->getValue(); @@ -564,7 +576,7 @@ void loadLight(Transform transform, std::ostream &os, domLight &light) { os << "\t\t" << endl; os << "\t" << endl << endl; } - if (!point && !spot && !ambient) + if (!point && !spot && !ambient && !directional) SLog(EWarn, "Encountered an unknown light type!"); } diff --git a/src/luminaires/directional.cpp b/src/luminaires/directional.cpp new file mode 100644 index 00000000..e7a5dd43 --- /dev/null +++ b/src/luminaires/directional.cpp @@ -0,0 +1,135 @@ +#include + +MTS_NAMESPACE_BEGIN + +/** + * Simple directional luminaire + */ +class DirectionalLuminaire : public Luminaire { +public: + DirectionalLuminaire(const Properties &props) : Luminaire(props) { + m_radius = props.getFloat("radius", 0.01f); + m_surfaceArea = m_radius * m_radius * M_PI; + Spectrum power = props.getSpectrum("power", 1); + m_intensity = props.getSpectrum("intensity", power / m_surfaceArea); + m_invSurfaceArea = 1 / m_surfaceArea; + m_direction = m_luminaireToWorld(Vector(0, 0, 1)); + m_type = EDeltaDirection | EDeltaPosition; + } + + DirectionalLuminaire(Stream *stream, InstanceManager *manager) + : Luminaire(stream, manager) { + m_intensity = Spectrum(stream); + m_radius = stream->readFloat(); + m_invSurfaceArea = 1 / m_surfaceArea; + m_direction = m_luminaireToWorld(Vector(0, 0, 1)); + } + + void serialize(Stream *stream, InstanceManager *manager) const { + Luminaire::serialize(stream, manager); + m_intensity.serialize(stream); + stream->writeFloat(m_radius); + } + + Spectrum getPower() const { + return m_intensity * m_surfaceArea; + } + + Spectrum Le(const LuminaireSamplingRecord &lRec) const { + /* Collimated beam is not part of the scene */ + Log(EWarn, "This function should never be called."); + return Spectrum(0.0f); + } + + inline Float pdf(const Point &p, const LuminaireSamplingRecord &lRec) const { + /* PDF is a delta function - zero probability when a sample point was not + generated using sample() */ + return 0.0f; + } + + Float pdf(const Intersection &its, const LuminaireSamplingRecord &lRec) const { + return DirectionalLuminaire::pdf(its.p, lRec); + } + + inline void sample(const Point &p, LuminaireSamplingRecord &lRec, + const Point2 &sample) const { + Point local = m_worldToLuminaire(p); + Vector2 planeProjection = Vector2(local.x, local.y); + + if (planeProjection.length() > m_radius || local.z < 0) { + lRec.pdf = 0.0f; + } else { + lRec.sRec.p = m_luminaireToWorld(Point(local.x, local.y, 0)); + lRec.d = m_direction; + lRec.luminaire = this; + lRec.pdf = 1.0f; + lRec.Le = m_intensity; + } + } + + void sample(const Intersection &its, LuminaireSamplingRecord &lRec, + const Point2 &sample) const { + DirectionalLuminaire::sample(its.p, lRec, sample); + } + + void sampleEmission(EmissionRecord &eRec, const Point2 &sample1, const Point2 &sample2) const { + Point2 posOnDisk = squareToDiskConcentric(sample1) * m_radius; + eRec.sRec.p = m_luminaireToWorld(Point(posOnDisk.x, posOnDisk.y, 0)); + eRec.d = m_direction; + eRec.pdfArea = m_invSurfaceArea; + eRec.pdfDir = 1; + eRec.P = m_intensity; + } + + void sampleEmissionArea(EmissionRecord &eRec, const Point2 &sample) const { + Point2 posOnDisk = squareToDiskConcentric(sample) * m_radius; + eRec.sRec.p = m_luminaireToWorld(Point(posOnDisk.x, posOnDisk.y, 0)); + eRec.pdfArea = m_invSurfaceArea; + eRec.P = m_intensity; + } + + Spectrum sampleEmissionDirection(EmissionRecord &eRec, const Point2 &sample) const { + eRec.d = m_direction; + eRec.pdfDir = 1; + return Spectrum(1.0f); + } + + Spectrum fArea(const EmissionRecord &eRec) const { + return m_intensity; + } + + Spectrum f(const EmissionRecord &eRec) const { + /* Collimated beam is not part of the scene */ + Log(EWarn, "This function should never be called."); + return Spectrum(0.0f); + } + + void pdfEmission(EmissionRecord &eRec) const { + eRec.pdfArea = m_invSurfaceArea; + eRec.pdfDir = 0; + eRec.P = m_intensity; + } + + std::string toString() const { + std::ostringstream oss; + oss << "DirectionalLuminaire[" << std::endl + << " intensity = " << m_intensity.toString() << "," << std::endl + << " power = " << getPower().toString() << "," << std::endl + << " position = " << m_luminaireToWorld(Point(0, 0, 0)).toString() << "," << std::endl + << " direction = " << m_direction.toString() << "," << std::endl + << " radius = " << m_radius << std::endl + << "]"; + return oss.str(); + } + + MTS_DECLARE_CLASS() +private: + Spectrum m_intensity; + Vector m_direction; + Float m_invSurfaceArea; + Float m_radius; +}; + +MTS_IMPLEMENT_CLASS_S(DirectionalLuminaire, false, Luminaire) +MTS_EXPORT_PLUGIN(DirectionalLuminaire, "Directional luminaire"); +MTS_NAMESPACE_END