void Shape::configure() {
	if (m_bsdf == NULL) {
		ref<BSDF> bsdf = NULL;
		if (isEmitter() || isSensor() || hasSubsurface()) {
			/* Light source / sensor and no BSDF! -> set an all-absorbing BSDF */
			Properties props("diffuse");
			props.setSpectrum("reflectance", Spectrum(0.0f));
			bsdf = static_cast<BSDF *> (PluginManager::getInstance()->
				createObject(MTS_CLASS(BSDF), props));
		} else if (!isMediumTransition()) {
			/* A surface without BSDF, which is not a medium
			   transition/sensor/emitter/subsurface emitter doesn't make
			   much sense. Assign it a 0.5 Lambertian BRDF for convenience */
			Properties props("diffuse");
			props.setSpectrum("reflectance", Spectrum(0.5f));
			bsdf = static_cast<BSDF *> (PluginManager::getInstance()->
				createObject(MTS_CLASS(BSDF), props));
		} else {
			/* Assign a "null" BSDF */
			bsdf = static_cast<BSDF *> (PluginManager::getInstance()->
				createObject(MTS_CLASS(BSDF), Properties("null")));
		}
		bsdf->configure();
		addChild(bsdf);
	}

	if ((m_bsdf->getType() & BSDF::ENull) && (isEmitter() || isSensor() || hasSubsurface()))
		Log(EError, "Shape \"%s\" has an index-matched BSDF and an "
			"emitter/sensor/subsurface attachment. This is not allowed!", getName().c_str());
}
Exemple #2
0
void Sensor::configure() {
	if (m_film == NULL) {
		/* Instantiate an EXR film by default */
		m_film = static_cast<Film*> (PluginManager::getInstance()->
			createObject(MTS_CLASS(Film), Properties("hdrfilm")));
		m_film->configure();
	}

	if (m_sampler == NULL) {
		/* No sampler has been selected - load an independent filter with 4 samples/pixel by default */
		Properties props("independent");
		props.setInteger("sampleCount", 4);
		m_sampler = static_cast<Sampler *> (PluginManager::getInstance()->
				createObject(MTS_CLASS(Sampler), props));
		m_sampler->configure();
	}

	m_aspect = m_film->getSize().x /
	   (Float) m_film->getSize().y;

	m_resolution = Vector2(m_film->getCropSize());
	m_invResolution = Vector2(
		(Float) 1 / m_resolution.x,
		(Float) 1 / m_resolution.y);
}
Exemple #3
0
std::pair<Texture *, Texture *> BSDF::ensureEnergyConservation(
		Texture *tex1, Texture *tex2, const std::string &paramName1,
		const std::string &paramName2, Float max) const {
	if (!m_ensureEnergyConservation)
		return std::make_pair(tex1, tex2);
	Float actualMax = (tex1->getMaximum() + tex2->getMaximum()).max();
	if (actualMax > max) {
		std::ostringstream oss;
		Float scale = 0.99f * (max / actualMax);
		oss << "The BSDF" << endl << toString() << endl
			<< "violates energy conservation! The parameters \"" << paramName1 << "\" "
			<< "and \"" << paramName2 << "\" sum to a component-wise maximum of "
			<< actualMax << " (which is > " << max << "!) and will therefore be "
			<< "scaled by " << scale << " to prevent issues. Specify the parameter "
			<< "ensureEnergyConservation=false to the BSDF to prevent this from "
			<< "happening.";
		Log(EWarn, "%s", oss.str().c_str());
		Properties props("scale");
		props.setFloat("scale", scale);
		Texture *scaleTexture1 = static_cast<Texture *> (PluginManager::getInstance()->
				createObject(MTS_CLASS(Texture), props));
		Texture *scaleTexture2 = static_cast<Texture *> (PluginManager::getInstance()->
				createObject(MTS_CLASS(Texture), props));
		scaleTexture1->addChild(tex1);
		scaleTexture1->configure();
		scaleTexture2->addChild(tex2);
		scaleTexture2->configure();
		return std::make_pair(scaleTexture1, scaleTexture2);
	}

	return std::make_pair(tex1, tex2);
}
Exemple #4
0
void Sensor::addChild(const std::string &name, ConfigurableObject *child) {
	if (child->getClass()->derivesFrom(MTS_CLASS(Sampler))) {
		m_sampler = static_cast<Sampler *>(child);
	} else if (child->getClass()->derivesFrom(MTS_CLASS(Film))) {
		m_film = static_cast<Film *>(child);
	} else {
		AbstractEmitter::addChild(name, child);
	}
}
Exemple #5
0
	void addChild(const std::string &name, ConfigurableObject *child) {
		if (child->getClass()->derivesFrom(MTS_CLASS(BSDF))) {
			BSDF *bsdf = static_cast<BSDF *>(child);
			m_bsdfs.push_back(bsdf);
			bsdf->incRef();
		} else if (child->getClass()->derivesFrom(MTS_CLASS(Texture)) && name == "weight") {
			m_weight = static_cast<Texture *>(child);
		} else {
			BSDF::addChild(name, child);
		}
	}
void Shape::addChild(const std::string &name, ConfigurableObject *child) {
	const Class *cClass = child->getClass();
	if (cClass->derivesFrom(MTS_CLASS(BSDF))) {
		m_bsdf = static_cast<BSDF *>(child);
	} else if (cClass->derivesFrom(MTS_CLASS(Emitter))) {
		Emitter *emitter = static_cast<Emitter *>(child);
		if (m_emitter != NULL)
			Log(EError, "Tried to attach multiple emitters to a shape!");
		if (emitter) {
			if (!emitter->isOnSurface())
				Log(EError, "Tried to attach an incompatible emitter to a surface!");
			if (m_exteriorMedium)
				emitter->setMedium(m_exteriorMedium);
		}
		m_emitter = emitter;
	} else if (cClass->derivesFrom(MTS_CLASS(Sensor))) {
		Sensor *sensor = static_cast<Sensor *>(child);
		if (m_sensor != NULL)
			Log(EError, "Tried to attach multiple sensors to a shape!");
		if (sensor) {
			if (!sensor->isOnSurface())
				Log(EError, "Tried to attach an incompatible sensor to a surface!");
			if (m_exteriorMedium)
				sensor->setMedium(m_exteriorMedium);
		}
		m_sensor = sensor;
	} else if (cClass->derivesFrom(MTS_CLASS(Subsurface))) {
		Assert(m_subsurface == NULL);
		if (m_interiorMedium != NULL)
			Log(EError, "Shape \"%s\" has both an interior medium "
				"and a subsurface scattering model -- please choose one or the other!", getName().c_str());
		m_subsurface = static_cast<Subsurface *>(child);
	} else if (cClass->derivesFrom(MTS_CLASS(Medium))) {
		if (name == "interior") {
			Assert(m_interiorMedium == NULL || m_interiorMedium == child);
			if (m_subsurface != NULL)
				Log(EError, "Shape \"%s\" has both an interior medium "
					"and a subsurface scattering model -- please choose one or the other!", getName().c_str());
			m_interiorMedium = static_cast<Medium *>(child);
		} else if (name == "exterior") {
			Assert(m_exteriorMedium == NULL || m_exteriorMedium == child);
			m_exteriorMedium = static_cast<Medium *>(child);
			if (m_emitter)
				m_emitter->setMedium(m_exteriorMedium);
			if (m_sensor)
				m_sensor->setMedium(m_exteriorMedium);
		} else {
			Log(EError, "Shape: Invalid medium child (must be named "
				"'interior' or 'exterior')!");
		}
	} else {
		ConfigurableObject::addChild(name, child);
	}
}
	void addChild(const std::string &name, ConfigurableObject *child) {
		const Class *cClass = child->getClass();

		if (cClass->derivesFrom(MTS_CLASS(Integrator))) {
			if (!cClass->derivesFrom(MTS_CLASS(SamplingIntegrator)))
				Log(EError, "The sub-integrator must be derived from the class SamplingIntegrator");
			m_subIntegrator = static_cast<SamplingIntegrator *>(child);
			m_subIntegrator->setParent(this);
		} else {
			Integrator::addChild(name, child);
		}
	}
Exemple #8
0
	void addChild(const std::string &name, ConfigurableObject *child) {
		if (child->getClass()->derivesFrom(MTS_CLASS(BSDF))) {
			if (m_nested != NULL)
				Log(EError, "Only a single nested BSDF can be added!");
			m_nested = static_cast<BSDF *>(child);
		} else if (child->getClass()->derivesFrom(MTS_CLASS(Texture))) {
			if (m_displacement != NULL)
				Log(EError, "Only a single displacement texture can be specified!");
			m_displacement = static_cast<Texture *>(child);
		} else {
			BSDF::addChild(name, child);
		}
	}
Exemple #9
0
Texture *BSDF::ensureEnergyConservation(Texture *texture,
		const std::string &paramName, Float max) const {
	if (!m_ensureEnergyConservation)
		return texture;

	Float actualMax = texture->getMaximum().max();
	if (actualMax > max) {
		std::ostringstream oss;
		Float scale = 0.99f * (max / actualMax);
		oss << "The BSDF" << endl << toString() << endl
			<< "violates energy conservation! The parameter \"" << paramName << "\" "
			<< "has a component-wise maximum of "<< actualMax << " (which is > " << max << "!) "
			<< "and will therefore be scaled by " << scale << " to prevent "
			<< "issues. Specify the parameter ensureEnergyConservation=false "
			<< "to the BSDF to prevent this from happening.";
		Log(EWarn, "%s", oss.str().c_str());
		Properties props("scale");
		props.setFloat("scale", scale);
		Texture *scaleTexture = static_cast<Texture *> (PluginManager::getInstance()->
				createObject(MTS_CLASS(Texture), props));
		scaleTexture->addChild(texture);
		scaleTexture->configure();
		return scaleTexture;
	}
	return texture;
}
	bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
		int sceneResID, int cameraResID, int samplerResID) {
		if (m_ready)
			return true;

		if (!scene->getIntegrator()->getClass()
				->derivesFrom(MTS_CLASS(SampleIntegrator))) {
			Log(EError, "The dipole subsurface integrator requires "
				"a sampling-based surface integrator!");
		}

		m_octree = new IrradianceOctree(m_maxDepth, m_minDelta, 
			scene->getKDTree()->getAABB());

		Float sa = 0;
		for (std::vector<Shape *>::iterator it = m_shapes.begin(); 
			it != m_shapes.end(); ++it) 
			sa += (*it)->getSurfaceArea();
		size_t sampleCount = (size_t) std::ceil(sa / (M_PI * m_minMFP * m_minMFP)
			* m_sampleMultiplier);
		Log(EInfo, "Generating " SIZE_T_FMT " irradiance samples..", sampleCount);

		ref<Scheduler> sched = Scheduler::getInstance();

		/* This could be a bit more elegant.. - inform the irradiance
		   sampler about the index of this subsurface integrator */
		std::vector<Subsurface *> ssIntegrators
			= scene->getSubsurfaceIntegrators();
		int index = -1;
		for (size_t i=0; i<ssIntegrators.size(); ++i) {
			if (ssIntegrators[i] == this) {
				index = (int) i;
				break;
			}
		}
		Assert(index != -1);

		ref<IrradianceSamplingProcess> proc = new IrradianceSamplingProcess(
			sampleCount, (size_t) std::ceil(sampleCount/100.0f), index, 
			m_irrSamples, m_irrIndirect, job);

		proc->bindResource("scene", sceneResID);
		scene->bindUsedResources(proc);
		m_proc = proc;
		sched->schedule(proc);
		sched->wait(proc);
		m_proc = NULL;
		if (proc->getReturnStatus() != ParallelProcess::ESuccess)
			return false;

		const IrradianceRecordVector &results = *proc->getSamples();
		for (size_t i=0; i<results.size(); ++i) 
			m_octree->addSample(results[i]);

		m_octree->preprocess();
		m_octreeResID = Scheduler::getInstance()->registerResource(m_octree);

		m_ready = true;
		return true;
	}
Exemple #11
0
	void configure() {
		if (m_phase == NULL)
			m_phase = static_cast<PhaseFunction *> (PluginManager::getInstance()->
					createObject(MTS_CLASS(PhaseFunction), Properties("isotropic")));

		if (m_sigmaT != NULL || m_albedo != NULL) {
			/* Support for the alternative scattering/absorption
			 * coefficient parameter passing convention */
			if (m_sigmaT == NULL || m_albedo == NULL)
				SLog(EError, "Please provide *both* sigmaT & albedo!");

			m_sigmaS = new SpectrumProductTexture(m_sigmaT, m_albedo);
			m_sigmaA = new SpectrumSubtractionTexture(m_sigmaT, m_sigmaS);
			m_sigmaT = NULL;
			m_albedo = NULL;
		}

		int extraFlags = m_sigmaS->isConstant() && m_sigmaA->isConstant() ? 0 : ESpatiallyVarying;
		m_components.clear();
		m_components.push_back(EGlossyReflection   | EFrontSide | EBackSide | ECanUseSampler | extraFlags);

		if (m_thickness != std::numeric_limits<Float>::infinity()) {
			m_components.push_back(EGlossyTransmission | EFrontSide | EBackSide | ECanUseSampler | extraFlags);
			m_components.push_back(EDeltaTransmission  | EFrontSide | EBackSide | ECanUseSampler | extraFlags);
		}

		m_usesRayDifferentials = m_sigmaS->usesRayDifferentials()
			|| m_sigmaA->usesRayDifferentials();

		BSDF::configure();
	}
Exemple #12
0
	void addChild(const std::string &name, ConfigurableObject *child) {
		if (child->getClass()->derivesFrom(MTS_CLASS(BSDF))) {
			if (m_nested != NULL)
				Log(EError, "Only a single nested BRDF can be added!");
			m_nested = static_cast<BSDF *>(child);
		} else if (child->getClass()->derivesFrom(MTS_CLASS(Texture))) {
			if (name == "sigmaA")
				m_sigmaA = static_cast<Texture *>(child);
			else if (name == "alpha")
				m_alpha = static_cast<Texture *>(child);
			else
				BSDF::addChild(name, child);
		} else {
			BSDF::addChild(name, child);
		}
	}
Exemple #13
0
CausticPerturbation::CausticPerturbation(const Scene *scene, Sampler *sampler,
		MemoryPool &pool, Float minJump, Float coveredArea) :
	m_scene(scene), m_sampler(sampler), m_pool(pool) {

	if (!scene->getSensor()->getClass()->derivesFrom(MTS_CLASS(PerspectiveCamera)))
		Log(EError, "The caustic perturbation requires a perspective camera.");

	const PerspectiveCamera *camera = static_cast<const PerspectiveCamera *>(scene->getSensor());
	Vector2i filmSize = camera->getFilm()->getSize(),
	         cropSize = camera->getFilm()->getCropSize();

	/* Simple heuristic for choosing a jump size: assumes that each
	   pixel on the camera subtends the same area on the sphere */
	Float degPerPixel = std::min(
				camera->getXFov() / filmSize.x,
				camera->getYFov() / filmSize.y),
	      radPerPixel = degPerPixel * M_PI / 180.0f;

	Float r1 = minJump,
		  r2 = std::sqrt(coveredArea * cropSize.x*cropSize.y / M_PI); /* [Veach, p. 354] */

	/* These represent the *desired* angle change range as seen from the camera */
	m_theta1 = radPerPixel * r1;
	m_theta2 = radPerPixel * r2;
	m_logRatio = -math::fastlog(m_theta2 / m_theta1);
}
void Medium::configure() {
	if (m_phaseFunction == NULL) {
		m_phaseFunction = static_cast<PhaseFunction *> (PluginManager::getInstance()->
				createObject(MTS_CLASS(PhaseFunction), Properties("isotropic")));
		m_phaseFunction->configure();
	}
}
Exemple #15
0
	ref<Shape> createShape(const Scene *scene) {
		/* Create a bounding sphere that surrounds the scene */
		BSphere sceneBSphere(scene->getAABB().getBSphere());
		sceneBSphere.radius = std::max(Epsilon, sceneBSphere.radius * 1.5f);
		BSphere geoBSphere(scene->getKDTree()->getAABB().getBSphere());

		if (sceneBSphere != m_sceneBSphere || geoBSphere != m_geoBSphere) {
			m_sceneBSphere = sceneBSphere;
			m_geoBSphere = geoBSphere;
			configure();
		}

		Transform trafo =
			Transform::translate(Vector(m_sceneBSphere.center)) *
			Transform::scale(Vector(m_sceneBSphere.radius));

		Properties props("sphere");
		props.setTransform("toWorld", trafo);
		props.setBoolean("flipNormals", true);
		Shape *shape = static_cast<Shape *> (PluginManager::getInstance()->
			createObject(MTS_CLASS(Shape), props));
		shape->addChild(this);
		shape->configure();

		return shape;
	}
Exemple #16
0
	BitmapTexture(Stream *stream, InstanceManager *manager)
	 : Texture2D(stream, manager) {
		m_filename = stream->readString();
		Log(EDebug, "Unserializing texture \"%s\"", m_filename.filename().string().c_str());
		m_filterType = (EMIPFilterType) stream->readUInt();
		m_wrapModeU = (ReconstructionFilter::EBoundaryCondition) stream->readUInt();
		m_wrapModeV = (ReconstructionFilter::EBoundaryCondition) stream->readUInt();
		m_gamma = stream->readFloat();
		m_maxAnisotropy = stream->readFloat();
		m_channel = stream->readString();

		size_t size = stream->readSize();
		ref<MemoryStream> mStream = new MemoryStream(size);
		stream->copyTo(mStream, size);
		mStream->seek(0);
		ref<Bitmap> bitmap = new Bitmap(Bitmap::EAuto, mStream);
		if (m_gamma != 0)
			bitmap->setGamma(m_gamma);

		/* Downsample using a 2-lobed Lanczos reconstruction filter */
		Properties rfilterProps("lanczos");
		rfilterProps.setInteger("lobes", 2);
		ref<ReconstructionFilter> rfilter = static_cast<ReconstructionFilter *> (
			PluginManager::getInstance()->createObject(
			MTS_CLASS(ReconstructionFilter), rfilterProps));
		rfilter->configure();

		Bitmap::EPixelFormat pixelFormat;
		if (!m_channel.empty()) {
			/* Create a texture from a certain channel of an image */
			pixelFormat = Bitmap::ELuminance;
			bitmap = bitmap->extractChannel(findChannel(bitmap, m_channel));
			if (m_channel == "a")
				bitmap->setGamma(1.0f);
		} else {
			switch (bitmap->getPixelFormat()) {
				case Bitmap::ELuminance:
				case Bitmap::ELuminanceAlpha:
					pixelFormat = Bitmap::ELuminance;
					break;
				case Bitmap::ERGB:
				case Bitmap::ERGBA:
					pixelFormat = Bitmap::ERGB;
					break;
				default:
					Log(EError, "The input image has an unsupported pixel format!");
					return;
			}
		}

		if (pixelFormat == Bitmap::ELuminance)
			m_mipmap1 = new MIPMap1(bitmap, pixelFormat, Bitmap::EFloat,
				rfilter, m_wrapModeU, m_wrapModeV, m_filterType, m_maxAnisotropy,
				fs::path(), 0);
		else
			m_mipmap3 = new MIPMap3(bitmap, pixelFormat, Bitmap::EFloat,
				rfilter, m_wrapModeU, m_wrapModeV, m_filterType, m_maxAnisotropy,
				fs::path(), 0);
	}
	void addChild(const std::string &name, ConfigurableObject *child) {
		if (child->getClass()->derivesFrom(MTS_CLASS(Texture)) && name == "specularReflectance") {
			m_specularReflectance = static_cast<Texture *>(child);
			m_usesRayDifferentials |= m_specularReflectance->usesRayDifferentials();
		} else {
			BSDF::addChild(name, child);
		}
	}
Exemple #18
0
	void addChild(const std::string &name, ConfigurableObject *child) {
		if (child->getClass()->derivesFrom(MTS_CLASS(Texture))
				&& (name == "reflectance" || name == "diffuseReflectance")) {

		} else {
			BSDF::addChild(name, child);
		}
	}
void AbstractEmitter::addChild(const std::string &name, ConfigurableObject *child) {
	if (child->getClass()->derivesFrom(MTS_CLASS(Medium))) {
		Assert(m_medium == NULL);
		m_medium = static_cast<Medium *>(child);
	} else {
		ConfigurableObject::addChild(name, child);
	}
}
size_t Scheduler::getLocalWorkerCount() const {
	size_t count = 0;
	LockGuard lock(m_mutex);
	for (size_t i=0; i<m_workers.size(); ++i) {
		if (m_workers[i]->getClass() == MTS_CLASS(LocalWorker))
			count++;
	}
	return count;
}
	void addChild(const std::string &name, ConfigurableObject *child) {
		if (child->getClass()->derivesFrom(MTS_CLASS(BSDF))) {
			if (m_nested != NULL)
				Log(EError, "Only a single nested BSDF can be added!");
			m_nested = static_cast<BSDF *>(child);
		} else if (child->getClass()->derivesFrom(MTS_CLASS(Texture))) {
			if (m_displacement != NULL)
				Log(EError, "Only a single displacement texture can be specified!");
			const Properties &props = child->getProperties();
			if (props.getPluginName() == "bitmap" && !props.hasProperty("gamma"))
				Log(EError, "When using a bitmap texture as a bump map, please explicitly specify "
						"the 'gamma' parameter of the bitmap plugin. In most cases the following is the correct choice: "
						"<float name=\"gamma\" value=\"1.0\"/>");
			m_displacement = static_cast<Texture *>(child);
		} else {
			BSDF::addChild(name, child);
		}
	}
void Luminaire::addChild(const std::string &name, ConfigurableObject *child) {
	const Class *cClass = child->getClass();
	if (cClass->derivesFrom(MTS_CLASS(Medium))) {
		Assert(m_medium == NULL);
		m_medium = static_cast<Medium *>(child);
	} else {
		ConfigurableObject::addChild(name, child);
	}
}
Exemple #23
0
void Medium::addChild(const std::string &name, ConfigurableObject *child) {
	const Class *cClass = child->getClass();

	if (cClass->derivesFrom(MTS_CLASS(PhaseFunction))) {
		Assert(m_phaseFunction == NULL);
		m_phaseFunction = static_cast<PhaseFunction *>(child);
	} else {
		Log(EError, "Medium: Invalid child node! (\"%s\")",
			cClass->getName().c_str());
	}
}
Exemple #24
0
	void addChild(const std::string &name, ConfigurableObject *child) {
		const Class *cClass = child->getClass();

		if (cClass->derivesFrom(MTS_CLASS(PhaseFunction))) {
			Assert(m_phase == NULL);
			m_phase = static_cast<PhaseFunction *>(child);
		} else if (cClass->derivesFrom(MTS_CLASS(Texture))) {
			if (name == "sigmaS")
				m_sigmaS = static_cast<Texture *>(child);
			else if (name == "sigmaA")
				m_sigmaA = static_cast<Texture *>(child);
			else if (name == "sigmaT")
				m_sigmaT = static_cast<Texture *>(child);
			else if (name == "albedo")
				m_albedo = static_cast<Texture *>(child);
			else
				BSDF::addChild(name, child);
		} else {
			BSDF::addChild(name, child);
		}
	}
	ref<Shape> createShape(const Scene *scene) {
		ref<AnimatedTransform> trafo = new AnimatedTransform(m_worldTransform);
		trafo->prependScale(Vector(m_apertureRadius));

		Properties props("disk");
		props.setAnimatedTransform("toWorld", trafo);
		Shape *shape = static_cast<Shape *> (PluginManager::getInstance()->
			createObject(MTS_CLASS(Shape), props));
		shape->addChild(this);
		shape->configure();

		return shape;
	}
	/// Connect to globally shared resources
	void wakeup(ConfigurableObject *parent, std::map<std::string, SerializableObject *> &params) {
		if (!m_globalPhotonMap.get() && params.find("globalPhotonMap") != params.end())
			m_globalPhotonMap = static_cast<PhotonMap *>(params["globalPhotonMap"]);
		if (!m_causticPhotonMap.get() && params.find("causticPhotonMap") != params.end())
			m_causticPhotonMap = static_cast<PhotonMap *>(params["causticPhotonMap"]);
		if (!m_bre.get() && params.find("bre") != params.end())
			m_bre = static_cast<BeamRadianceEstimator *>(params["bre"]);

		if (parent && parent->getClass()->derivesFrom(MTS_CLASS(SamplingIntegrator)))
			m_parentIntegrator = static_cast<SamplingIntegrator *>(parent);
		else
			m_parentIntegrator = this;
	}
	void addChild(const std::string &name, ConfigurableObject *child) {
		if (child->getClass()->derivesFrom(MTS_CLASS(Texture))) {
			if (name == "exponent")
				m_exponent = static_cast<Texture *>(child);
			else if (name == "specularReflectance")
				m_specularReflectance = static_cast<Texture *>(child);
			else if (name == "diffuseReflectance")
				m_diffuseReflectance = static_cast<Texture *>(child);
			else
				BSDF::addChild(name, child);
		} else {
			BSDF::addChild(name, child);
		}
	}
Exemple #28
0
	void configure() {
		PhaseFunction::configure();
		m_type = EAnisotropic | ENonSymmetric;

		Properties props("independent");
		m_sampler = static_cast<Sampler*>(PluginManager::getInstance()->createObject(MTS_CLASS(Sampler), props));
		m_sampler->configure();

		if (m_stddev != -1.f) {
			Float sigma1 = m_fiberDistr.sigmaT(0.f) * 2.f;
			Float sigma2 = sigma1;
			Float sigma3 = m_fiberDistr.sigmaT(1.f) * 2.f;
			D = Matrix3x3(Vector(sigma1 * sigma1, 0, 0), Vector(0, sigma2 * sigma2, 0), Vector(0, 0, sigma3 * sigma3));
		}
	}
	void setParent(ConfigurableObject *parent) {
		Sensor::setParent(parent);

		if (parent->getClass()->derivesFrom(MTS_CLASS(Shape))) {
			Shape *shape = static_cast<Shape *>(parent);
			if (m_shape == shape || shape->isCompound())
				return;

			if (m_shape != NULL)
				Log(EError, "An irradiance sensor cannot be parent of multiple shapes");

			m_shape = shape;
		} else {
			Log(EError, "An irradiance sensor must be child of a shape instance");
		}
	}
	void addChild(const std::string &name, ConfigurableObject *child) {
		if (child->getClass()->derivesFrom(MTS_CLASS(Texture))) {
			if (name == "alpha")
				m_alphaU = m_alphaV = static_cast<Texture *>(child);
			else if (name == "alphaU")
				m_alphaU = static_cast<Texture *>(child);
			else if (name == "alphaV")
				m_alphaV = static_cast<Texture *>(child);
			else if (name == "specularReflectance")
				m_specularReflectance = static_cast<Texture *>(child);
			else
				BSDF::addChild(name, child);
		} else {
			BSDF::addChild(name, child);
		}
	}