mitsuba/include/mitsuba/render/records.inl

183 lines
5.8 KiB
C++

/*
This file is part of Mitsuba, a physically based rendering system.
Copyright (c) 2007-2014 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/>.
*/
#if !defined(__RECORDS_INLINE_H)
#define __RECORDS_INLINE_H
MTS_NAMESPACE_BEGIN
inline BSDFSamplingRecord::BSDFSamplingRecord(const Intersection &its, Sampler *sampler, ETransportMode mode)
: its(its), sampler(sampler), wi(its.wi), mode(mode),
typeMask(BSDF::EAll), component(-1), sampledType(0), sampledComponent(-1) {
}
inline BSDFSamplingRecord::BSDFSamplingRecord(const Intersection &its, const Vector &wo, ETransportMode mode)
: its(its), sampler(NULL), wi(its.wi), wo(wo), mode(mode),
typeMask(BSDF::EAll), component(-1), sampledType(0), sampledComponent(-1) {
}
inline BSDFSamplingRecord::BSDFSamplingRecord(const Intersection &its, const Vector &wi, const Vector &wo, ETransportMode mode)
: its(its), sampler(NULL), wi(wi), wo(wo), mode(mode),
typeMask(BSDF::EAll), component(-1), sampledType(0), sampledComponent(-1) {
}
void BSDFSamplingRecord::reverse() {
std::swap(wo, wi);
mode = (ETransportMode) (1-mode);
}
inline bool Intersection::hasSubsurface() const {
return shape->hasSubsurface();
}
inline bool Intersection::isEmitter() const {
return shape->isEmitter();
}
inline bool Intersection::isSensor() const {
return shape->isSensor();
}
inline Spectrum Intersection::Le(const Vector &d) const {
return shape->getEmitter()->eval(*this, d);
}
inline Spectrum Intersection::LoSub(const Scene *scene,
Sampler *sampler, const Vector &d, int depth) const {
return shape->getSubsurface()->Lo(scene, sampler, *this, d, depth);
}
inline const BSDF *Intersection::getBSDF() const {
return shape->getBSDF();
}
inline const BSDF *Intersection::getBSDF(const RayDifferential &ray) {
const BSDF *bsdf = shape->getBSDF();
if (bsdf && bsdf->usesRayDifferentials() && !hasUVPartials)
computePartials(ray);
return bsdf;
}
inline bool Intersection::isMediumTransition() const {
return shape->isMediumTransition();
}
inline const Medium *Intersection::getTargetMedium(const Vector &d) const {
if (dot(d, geoFrame.n) > 0)
return shape->getExteriorMedium();
else
return shape->getInteriorMedium();
}
inline const Medium *Intersection::getTargetMedium(Float cosTheta) const {
if (cosTheta > 0)
return shape->getExteriorMedium();
else
return shape->getInteriorMedium();
}
void Intersection::adjustTime(Float time) {
if (instance)
instance->adjustTime(*this, time);
else if (shape)
shape->adjustTime(*this, time);
else
this->time = time;
}
void Intersection::getNormalDerivative(Vector &dndu, Vector &dndv,
bool shadingFrame) const {
if (instance)
instance->getNormalDerivative(*this, dndu, dndv, shadingFrame);
else if (shape)
shape->getNormalDerivative(*this, dndu, dndv, shadingFrame);
}
inline const PhaseFunction *MediumSamplingRecord::getPhaseFunction() const {
return medium->getPhaseFunction();
}
inline bool RadianceQueryRecord::rayIntersect(const RayDifferential &ray) {
/* Only search for an intersection if this was explicitly requested */
if (type & EIntersection) {
scene->rayIntersect(ray, its);
if (type & EOpacity) {
int unused = INT_MAX;
if (its.isValid()) {
if (EXPECT_TAKEN(!its.isMediumTransition()))
alpha = 1.0f;
else
alpha = 1-scene->evalTransmittance(its.p, true,
ray(scene->getBSphere().radius*2), false,
ray.time, its.getTargetMedium(ray.d), unused).average();
} else if (medium) {
alpha = 1-scene->evalTransmittance(ray.o, false,
ray(scene->getBSphere().radius*2), false,
ray.time, medium, unused).average();
} else {
alpha = 0.0f;
}
}
if (type & EDistance)
dist = its.t;
type ^= EIntersection; // unset the intersection bit
}
return its.isValid();
}
inline Point2 RadianceQueryRecord::nextSample2D() {
return sampler->next2D();
}
inline Float RadianceQueryRecord::nextSample1D() {
return sampler->next1D();
}
inline PositionSamplingRecord::PositionSamplingRecord(const Intersection &its, EMeasure measure)
: p(its.p), time(its.time), n(its.shFrame.n), measure(measure), uv(its.uv), object(NULL) { }
inline DirectionSamplingRecord::DirectionSamplingRecord(const Intersection &its, EMeasure measure)
: d(its.toWorld(its.wi)), measure(measure) { }
inline DirectSamplingRecord::DirectSamplingRecord(const Intersection &refIts)
: PositionSamplingRecord(refIts.time), ref(refIts.p), refN(0.0f) {
if ((refIts.shape->getBSDF()->getType() & (BSDF::ETransmission | BSDF::EBackSide)) == 0)
refN = refIts.shFrame.n;
}
inline DirectSamplingRecord::DirectSamplingRecord(const MediumSamplingRecord &refM)
: PositionSamplingRecord(refM.time), ref(refM.p), refN(0.0f) {
}
void DirectSamplingRecord::setQuery(const Ray &ray, const Intersection &its, EMeasure _measure) {
p = its.p;
n = its.shFrame.n;
measure = _measure;
uv = its.uv;
object = its.shape->getEmitter();
d = ray.d;
dist = its.t;
}
MTS_NAMESPACE_END
#endif /* __RECORDS_INLINE_H */