// commented, dpl 10 august 2005
Spectrum Lafortune::Sample_f(const Vector &wo, Vector *wi,
		float u1, float u2, float *pdf) const {
	u_int comp = RandomUInt() % (nLobes+1);
	if (comp == nLobes) {
		// Cosine-sample the hemisphere, flipping the direction if necessary
		*wi = CosineSampleHemisphere(u1, u2);
		if (wo.z < 0.) wi->z *= -1.f;
	}
	else {
		// Sample lobe _comp_ for Lafortune BRDF
		float xlum = x[comp].y();
		float ylum = y[comp].y();
		float zlum = z[comp].y();
		float costheta = powf(u1, 1.f / (.8f * exponent[comp].y() + 1));
		float sintheta = sqrtf(max(0.f, 1.f - costheta*costheta));
		float phi = u2 * 2.f * M_PI;
		Vector lobeCenter = Normalize(Vector(xlum * wo.x, ylum * wo.y, zlum * wo.z));
		Vector lobeX, lobeY;
		CoordinateSystem(lobeCenter, &lobeX, &lobeY);
		*wi = SphericalDirection(sintheta, costheta, phi, lobeX, lobeY,
			lobeCenter);
	}
	if (!SameHemisphere(wo, *wi)) return Spectrum(0.f);
	*pdf = Pdf(wo, *wi);
	return f(wo, *wi);
}
Example #2
0
Point Sphere::Sample(const Point &p, float u1, float u2,
                     Normal *ns) const {
    // Compute coordinate system for sphere sampling
    Point Pcenter = (*ObjectToWorld)(Point(0,0,0));
    Vector wc = Normalize(Pcenter - p);
    Vector wcX, wcY;
    CoordinateSystem(wc, &wcX, &wcY);

    // Sample uniformly on sphere if $\pt{}$ is inside it
    if (DistanceSquared(p, Pcenter) - radius*radius < 1e-4f)
        return Sample(u1, u2, ns);

    // Sample sphere uniformly inside subtended cone
    float cosThetaMax =
        sqrtf(max(0.f, 1.f - radius*radius / DistanceSquared(p, Pcenter)));
    DifferentialGeometry dgSphere;
    float thit, rayEpsilon;
    Point ps;
    Ray r(p, UniformSampleCone(u1, u2, cosThetaMax, wcX, wcY, wc),
          1e-3f);
    if (!Intersect(r, &thit, &rayEpsilon, &dgSphere))
        ps = Pcenter - radius * wc;
    else
        ps = r(thit);
    *ns = Normal(Normalize(ps - Pcenter));
    if (ReverseOrientation) *ns *= -1.f;
    return ps;
}
Example #3
0
Spectrum DiffuseAreaLight::Sample_Le(const Point2f &u1, const Point2f &u2,
                                     Float time, Ray *ray, Normal3f *nLight,
                                     Float *pdfPos, Float *pdfDir) const {
    ProfilePhase _(Prof::LightSample);
    // Sample a point on the area light's _Shape_, _pShape_
    Interaction pShape = shape->Sample(u1, pdfPos);
    pShape.mediumInterface = mediumInterface;
    *nLight = pShape.n;

    // Sample a cosine-weighted outgoing direction _w_ for area light
    Vector3f w;
    if (twoSided) {
        Point2f u = u2;
        // Choose a side to sample and then remap u[0] to [0,1] before
        // applying cosine-weighted hemisphere sampling for the chosen side.
        if (u[0] < .5) {
            u[0] = std::min(u[0] * 2, OneMinusEpsilon);
            w = CosineSampleHemisphere(u);
        } else {
            u[0] = std::min((u[0] - .5f) * 2, OneMinusEpsilon);
            w = CosineSampleHemisphere(u);
            w.z *= -1;
        }
        *pdfDir = 0.5f * CosineHemispherePdf(std::abs(w.z));
    } else {
        w = CosineSampleHemisphere(u2);
        *pdfDir = CosineHemispherePdf(w.z);
    }

    Vector3f v1, v2, n(pShape.n);
    CoordinateSystem(n, &v1, &v2);
    w = w.x * v1 + w.y * v2 + w.z * n;
    *ray = pShape.SpawnRay(w);
    return L(pShape, w);
}
Example #4
0
bool Sphere::Sample(const Interaction &ref, const Point2f &sample,
                    Interaction *it) const {
    // Compute coordinate system for sphere sampling
    Point3f pCenter = (*ObjectToWorld)(Point3f(0, 0, 0));
    Point3f pOrigin =
        OffsetRayOrigin(ref.p, ref.pError, ref.n, pCenter - ref.p);
    Vector3f wc = Normalize(pCenter - ref.p);
    Vector3f wcX, wcY;
    CoordinateSystem(wc, &wcX, &wcY);

    // Sample uniformly on sphere if $\pt{}$ is inside it
    if (DistanceSquared(pOrigin, pCenter) <= 1.0001f * radius * radius)
        return Sample(sample, it);

    // Sample sphere uniformly inside subtended cone
    Float sinThetaMax2 = radius * radius / DistanceSquared(ref.p, pCenter);
    Float cosThetaMax =
        std::sqrt(std::max((Float)0., (Float)1. - sinThetaMax2));
    SurfaceInteraction isectSphere;
    Float tHit;
    Ray r = ref.SpawnRay(UniformSampleCone(sample, cosThetaMax, wcX, wcY, wc));
    if (!Intersect(r, &tHit, &isectSphere)) return false;
    *it = isectSphere;
    if (ReverseOrientation) it->n *= -1.f;
    return true;
}
void TreeRepository::rebuild()
{
//	CX_LOG_CHANNEL_DEBUG("CA") << "  reuild tree...";
	for (unsigned i=0; i<mNodes.size(); ++i)
		disconnect(mNodes[i].get(), &TreeNode::changed, this, &TreeRepository::onChanged);
	mNodes.clear();

	this->insertTopNode();

	QStringList groups = QStringList() << "tool" << "data" << "space" << "view";
	for (unsigned i=0; i<groups.size(); ++i)
		this->insertGroupNode(groups[i]);

	this->insertSpaceNode(CoordinateSystem(csREF));

	std::map<QString, DataPtr> source = this->getServices()->patient()->getDatas();
	for (std::map<QString, DataPtr>::const_iterator iter = source.begin(); iter != source.end(); ++iter)
	{
		this->insertDataNode(iter->second);
	}
	for (std::map<QString, DataPtr>::const_iterator iter = source.begin(); iter != source.end(); ++iter)
	{
		QString space = iter->second->getParentSpace();
		if (space.isEmpty())
			continue;
		if (source.count(space))
			continue;
		this->insertSpaceNode(CoordinateSystem(csDATA, space));
	}

	this->insertSpaceNode(CoordinateSystem(csPATIENTREF));

	std::map<QString, ToolPtr> tools = this->getServices()->tracking()->getTools();
	for (std::map<QString, ToolPtr>::const_iterator iter = tools.begin(); iter != tools.end(); ++iter)
	{
		this->insertToolNode(iter->second);
	}

	for (unsigned i=0; i<this->getServices()->view()->groupCount(); ++i)
	{
		this->appendNode(new ViewGroupTreeNode(mSelf, i));
	}

//	for (unsigned i=0; i<mNodes.size(); ++i)
//		CX_LOG_CHANNEL_DEBUG("CA") << "  node: " << mNodes[i]->getUid();
}
Example #6
0
TreeNodePtr ToolTreeNode::getParent() const
{
	if (this->repo()->getMode()=="flat")
		return this->repo()->getNodeForGroup("tool");

	if (mTool->getUid() == this->getServices()->tracking()->getManualTool()->getUid())
		return this->repo()->getNode(CoordinateSystem(csPATIENTREF).toString());

	if (mTool->hasType(Tool::TOOL_REFERENCE))
		return this->repo()->getNode(CoordinateSystem(csPATIENTREF).toString());

	ToolPtr ref = this->getServices()->tracking()->getReferenceTool();
	if (ref)
		return this->repo()->getNode(ref->getUid());

	return this->repo()->getNode(CoordinateSystem(csPATIENTREF).toString());
}
Example #7
0
ON_BOOL32 ON_Light::GetLightXform( 
         const ON_Viewport& vp,
         ON::coordinate_system dest_cs, 
         ON_Xform& xform 
         ) const
{
  ON::coordinate_system src_cs = CoordinateSystem();
  return vp.GetXform( src_cs, dest_cs, xform );
}
Example #8
0
/** Utility function: return the coordinate the the reference space.
 *
 */
Vector3D PointMetric::getRefCoord() const
{
	if (!mCachedRefCoord.isValid())
	{
		Transform3D rM1 = mSpaceProvider->get_toMfrom(this->getSpace(), CoordinateSystem(csREF));
		Vector3D val = rM1.coord(this->getCoordinate());
		mCachedRefCoord.set(val);
	}
	return mCachedRefCoord.get();
}
Example #9
0
CoordinateSystem Ship :: getCameraCoordinateSystem () const
{
	const Vector3& forward = getForward();
	const Vector3& up      = getUp();

	Vector3 camera_at = getPosition() +
	                    forward * CAMERA_FORWARD_DISTANCE +
	                    up      * CAMERA_UP_DISTANCE;

	return CoordinateSystem(camera_at, forward, up);
}
Example #10
0
void AxisConnector::changedSlot()
{
	Transform3D  rMs = mSpaceProvider->get_toMfrom(mListener->getSpace(), CoordinateSystem(csREF));
	mRep->setTransform(rMs);

	mRep->setVisible(true);

	// if connected to tool: check visibility
	if (mTool)
		mRep->setVisible(mTool->getVisible());

	// Dont show if equal to base
	if (mBase)
	{
		Transform3D rMb = mSpaceProvider->get_toMfrom(mBase->getSpace(), CoordinateSystem(csREF));
		if (similar(rMb, rMs))
			mRep->setVisible(false);
	}

}
Example #11
0
Point3f Sphere::Sample( const Point3f& p , LightSample& lightSample , Vector3f& SampleNormal )
{
	Vector3f dirZ = Normalize( mWorldPos - p );

	// 在球面上采样一个点
	if( ( p - mWorldPos ).LengthSq() - m_Radius * m_Radius < 1e4f )
	{
		// 使用默认的采样
		Vector3f SampleDir = UniformSampleHemisphere( Point2f( lightSample.value[0] , lightSample.value[1] ) );

		if( Dot( SampleDir , dirZ ) < 0.0 )
		{
			SampleDir *= -1.0;
		}

		Point3f SamplePoint = mWorldPos + Normalize( dirZ ) * m_Radius;

		// Compute Normal Dir
		SampleNormal = Normalize( Vector3f( SamplePoint - mWorldPos ) );
		
		return SamplePoint;
	}

	
	Vector3f dirX , dirY;
	CoordinateSystem( dirZ , &dirX , &dirY );

	// 均匀采样cone
	float sinThetaMax2 = m_Radius * m_Radius / ( p - mWorldPos ).LengthSq();
	float cosThetaMax = sqrt( MAX( 0.0f , 1.0f - sinThetaMax2 ) );

	Rayf r( p , UniformSampleCone( lightSample.value[0] , lightSample.value[1] , cosThetaMax , dirX , dirY , dirZ ) );

	// Test whether intersect
	float t;
	IntersectRecord record;
	Point3f SamplePoint;
	if( !Intersect( r , &record ) )
	{
		// 必定是切线但被判定为无交点
		t = Dot( mWorldPos - p , r.Direction );
		SamplePoint = r( t );
	}
	else
	{
		SamplePoint = record.HitPoint;
	}
	
	SampleNormal = Normalize( SamplePoint - mWorldPos );

	return SamplePoint;
}
Example #12
0
/** Utility function: return the coordinate the the reference space.
 *
 */
Vector3D PointMetric::getRefCoord() const
{
//	std::cout << " ** PointMetric::getRefCoord" << std::endl;

//	return Vector3D(1,2,3);
	if (!mCachedRefCoord.isValid())
	{
//		std::cout << " ** PointMetric::getRefCoord FILL CACHE" << std::endl;
		Transform3D rM1 = mSpaceProvider->get_toMfrom(this->getSpace(), CoordinateSystem(csREF));
		Vector3D val = rM1.coord(this->getCoordinate());
		mCachedRefCoord.set(val);
	}
	return mCachedRefCoord.get();
}
Example #13
0
Vector SampleHG(const Vector &w, float g, const float u1, const float u2) {
	float costheta;
	if (fabsf(g) < 1e-3f)
		costheta = 1.f - 2.f * u1;
	else {
		// NOTE - lordcrc - Bugfix, pbrt tracker id 0000082: bug in SampleHG
		const float sqrTerm = (1.f - g * g) / (1.f - g + 2.f * g * u1);
		costheta = (1.f + g * g - sqrTerm * sqrTerm) / (2.f * g);
	}
	const float sintheta = sqrtf(Max(0.f, 1.f - costheta * costheta));
	const float phi = 2.f * M_PI * u2;
	Vector v1, v2;
	CoordinateSystem(w, &v1, &v2);
	return SphericalDirection(sintheta, costheta, phi, v1, v2, w);
}
Example #14
0
Vector SampleHG(const Vector &w, float g, float u1, float u2) {
    float costheta;
    if (fabsf(g) < 1e-3)
        costheta = 1.f - 2.f * u1;
    else {
        float sqrTerm = (1.f - g * g) /
                        (1.f - g + 2.f * g * u1);
        costheta = (1.f + g * g - sqrTerm * sqrTerm) / (2.f * g);
    }
    float sintheta = sqrtf(max(0.f, 1.f-costheta*costheta));
    float phi = 2.f * M_PI * u2;
    Vector v1, v2;
    CoordinateSystem(w, &v1, &v2);
    return SphericalDirection(sintheta, costheta, phi, v1, v2, w);
}
Example #15
0
Spectrum DistantLight::Sample_L(const Point2f &sample1, const Point2f &sample2,
                                Float time, Ray *ray, Normal3f *Ns,
                                Float *pdfPos, Float *pdfDir) const {
    // Choose point on disk oriented toward infinite light direction
    Vector3f v1, v2;
    CoordinateSystem(wLight, &v1, &v2);
    Point2f cd = ConcentricSampleDisk(sample1);
    Point3f Pdisk = worldCenter + worldRadius * (cd.x * v1 + cd.y * v2);

    // Set ray origin and direction for infinite light ray
    *ray = Ray(Pdisk + worldRadius * wLight, -wLight, Infinity, time);
    *Ns = (Normal3f)ray->d;
    *pdfPos = 1.f / (Pi * worldRadius * worldRadius);
    *pdfDir = 1.f;
    return L;
}
Example #16
0
Spectrum DiffuseAreaLight::Sample_Le(const Point2f &u1, const Point2f &u2,
                                     Float time, Ray *ray, Normal3f *nLight,
                                     Float *pdfPos, Float *pdfDir) const {
    Interaction pShape = shape->Sample(u1);
    pShape.mediumInterface = mediumInterface;
    Vector3f w = CosineSampleHemisphere(u2);
    *pdfDir = CosineHemispherePdf(w.z);
    // Transform cosine-weighted direction to normal's coordinate system
    Vector3f v1, v2, n(pShape.n);
    CoordinateSystem(n, &v1, &v2);
    w = w.x * v1 + w.y * v2 + w.z * n;
    *ray = pShape.SpawnRay(w);
    *nLight = pShape.n;
    *pdfPos = shape->Pdf(pShape);
    return L(pShape, w);
}
Example #17
0
bool DistanceEstimator::Intersect(const Ray &r, float *tHit, float *rayEpsilon,
    DifferentialGeometry *dg) const {
  bool succeed = DoesIntersect(r, tHit);
  if (!succeed) return false;

  Ray ray;
  (*WorldToObject)(r, &ray);
  Point p = ray(*tHit);
  *rayEpsilon = DE_params.hitEpsilon * DE_params.rayEpsilonMultiplier;
  Vector n = CalculateNormal(p, DE_params.normalEpsilon);
  Vector DPDU, DPDV;
  CoordinateSystem(n, &DPDU, &DPDV);

  const Transform &o2w = *ObjectToWorld;
  *dg = DifferentialGeometry(o2w(p), o2w(DPDU), o2w(DPDV), Normal(), Normal(), 0, 0, this);
  return true;
}
Example #18
0
Interaction Sphere::Sample(const Interaction &ref, const Point2f &u) const {
    // Compute coordinate system for sphere sampling
    Point3f pCenter = (*ObjectToWorld)(Point3f(0, 0, 0));
    Vector3f wc = Normalize(pCenter - ref.p);
    Vector3f wcX, wcY;
    CoordinateSystem(wc, &wcX, &wcY);

    // Sample uniformly on sphere if $\pt{}$ is inside it
    Point3f pOrigin =
        OffsetRayOrigin(ref.p, ref.pError, ref.n, pCenter - ref.p);
    if (DistanceSquared(pOrigin, pCenter) <= radius * radius) return Sample(u);

    // Sample sphere uniformly inside subtended cone

    // Compute $\theta$ and $\phi$ values for sample in cone
    Float sinThetaMax2 = radius * radius / DistanceSquared(ref.p, pCenter);
    Float cosThetaMax = std::sqrt(std::max((Float)0, 1 - sinThetaMax2));
    Float cosTheta = (1 - u[0]) + u[0] * cosThetaMax;
    Float sinTheta = std::sqrt(1 - cosTheta * cosTheta);
    Float phi = u[1] * 2 * Pi;

    // Compute angle $\alpha$ from center of sphere to sampled point on surface
    Float dc = Distance(ref.p, pCenter);
    Float ds = dc * cosTheta -
               std::sqrt(std::max(
                   (Float)0, radius * radius - dc * dc * sinTheta * sinTheta));
    Float cosAlpha = (dc * dc + radius * radius - ds * ds) / (2 * dc * radius);
    Float sinAlpha = std::sqrt(std::max((Float)0, 1 - cosAlpha * cosAlpha));

    // Compute surface normal and sampled point on sphere
    Vector3f nObj =
        SphericalDirection(sinAlpha, cosAlpha, phi, -wcX, -wcY, -wc);
    Point3f pObj = radius * Point3f(nObj.x, nObj.y, nObj.z);

    // Return _Interaction_ for sampled point on sphere
    Interaction it;

    // Reproject _pObj_ to sphere surface and compute _pObjError_
    pObj *= radius / Distance(pObj, Point3f(0, 0, 0));
    Vector3f pObjError = gamma(5) * Abs((Vector3f)pObj);
    it.p = (*ObjectToWorld)(pObj, pObjError, &it.pError);
    it.n = (*ObjectToWorld)(Normal3f(nObj));
    if (reverseOrientation) it.n *= -1.f;
    return it;
}
Example #19
0
Spectrum DiffuseAreaLight::Sample_Le(const Point2f &u1, const Point2f &u2,
                                     Float time, Ray *ray, Normal3f *nLight,
                                     Float *pdfPos, Float *pdfDir) const {
    // Sample a point on the area light's _Shape_, _pShape_
    Interaction pShape = shape->Sample(u1);
    pShape.mediumInterface = mediumInterface;
    *pdfPos = shape->Pdf(pShape);
    *nLight = pShape.n;

    // Sample a cosine-weighted outgoing direction _w_ for area light
    Vector3f w = CosineSampleHemisphere(u2);
    *pdfDir = CosineHemispherePdf(w.z);
    Vector3f v1, v2, n(pShape.n);
    CoordinateSystem(n, &v1, &v2);
    w = w.x * v1 + w.y * v2 + w.z * n;
    *ray = pShape.SpawnRay(w);
    return L(pShape, w);
}
Example #20
0
Spectrum DistantLight::Sample_L(const Scene *scene, const LightSample &ls,
        float u1, float u2, float time, Ray *ray, Normal *Ns,
        float *pdf) const {
    // Choose point on disk oriented toward infinite light direction
    Point worldCenter;
    float worldRadius;
    scene->WorldBound().BoundingSphere(&worldCenter, &worldRadius);
    Vector v1, v2;
    CoordinateSystem(lightDir, &v1, &v2);
    float d1, d2;
    ConcentricSampleDisk(ls.uPos[0], ls.uPos[1], &d1, &d2);
    Point Pdisk = worldCenter + worldRadius * (d1 * v1 + d2 * v2);

    // Set ray origin and direction for infinite light ray
    *ray = Ray(Pdisk + worldRadius * lightDir, -lightDir, 0.f, INFINITY, time);
    *pdf = 1.f / (M_PI * worldRadius * worldRadius);
    return L;
}
Example #21
0
void CustomMetric::createOrDestroyToolListener()
{
	if (this->needForToolListenerHasChanged())
	{
		bool toolDefinesUp = mDefineVectorUpMethod == mDefineVectorUpMethods.tool;
		if (mTextureFollowTool || toolDefinesUp)
		{
			mToolListener = mSpaceProvider->createListener();
			mToolListener->setSpace(CoordinateSystem(csTOOL_OFFSET, "active"));
			connect(mToolListener.get(), &SpaceListener::changed, this, &CustomMetric::transformChanged);
		}
		else
		{
			disconnect(mToolListener.get(), &SpaceListener::changed, this, &CustomMetric::transformChanged);
			mToolListener.reset();
		}
	}
}
Example #22
0
// HenyeyGreenstein Method Definitions
Float HenyeyGreenstein::Sample_p(const Vector3f &wo, Vector3f *wi,
                                 const Point2f &u) const {
    // Compute $\cos \theta$ for Henyey--Greenstein sample
    Float cosTheta;
    if (std::abs(g) < 1e-3)
        cosTheta = 1 - 2 * u[0];
    else {
        Float sqrTerm = (1 - g * g) / (1 - g + 2 * g * u[0]);
        cosTheta = (1 + g * g - sqrTerm * sqrTerm) / (2 * g);
    }

    // Compute direction _wi_ for Henyey--Greenstein sample
    Float sinTheta = std::sqrt(std::max((Float)0, 1 - cosTheta * cosTheta));
    Float phi = 2 * Pi * u[1];
    Vector3f v1, v2;
    CoordinateSystem(wo, &v1, &v2);
    *wi = SphericalDirection(sinTheta, cosTheta, phi, v1, v2, -wo);
    return PhaseHG(-cosTheta, g);
}
Spectrum DistantLight::Sample_L(const Scene *scene,
		float u1, float u2, float u3, float u4,
		Ray *ray, float *pdf) const {
	// Choose point on disk oriented toward infinite light direction
	Point worldCenter;
	float worldRadius;
	scene->WorldBound().BoundingSphere(&worldCenter,
	                                   &worldRadius);
	Vector v1, v2;
	CoordinateSystem(lightDir, &v1, &v2);
	float d1, d2;
	ConcentricSampleDisk(u1, u2, &d1, &d2);
	Point Pdisk =
		worldCenter + worldRadius * (d1 * v1 + d2 * v2);
	// Set ray origin and direction for infinite light ray
	ray->o = Pdisk + worldRadius * lightDir;
	ray->d = -lightDir;
	*pdf = 1.f / (M_PI * worldRadius * worldRadius);
	return L;
}
void
MobileRootJoint::velocity(const Task& task, const Environment& environment,
                          const ContinousStateValueVector& continousState,
                          ChildLink& childLink) const
{
  Vector3 position = continousState[*mPositionStateInfo];
  Quaternion orientation = continousState[*mOrientationStateInfo];
  Vector6 velocity = continousState[*mVelocityStateInfo];

  childLink.setCoordinateSystem(CoordinateSystem(position, orientation));

  velocity = childLink.getCoordinateSystem().rotToReference(velocity);
  Vector3 angularBaseVelocity = environment.getAngularVelocity(task.getTime());
  Vector6 baseVelocity(angularMotionTo(position, angularBaseVelocity));
  childLink.setVelocity(velocity);
  childLink.setInertialVelocity(baseVelocity + velocity);

  childLink.setForce(Vector6::zeros());
  childLink.setInertia(SpatialInertia::zeros());
}
Example #25
0
std::shared_ptr<SpotLight> CreateSpotLight(const Transform &l2w,
                                           const Medium *medium,
                                           const ParamSet &paramSet) {
    Spectrum I = paramSet.FindOneSpectrum("I", Spectrum(1.0));
    Spectrum sc = paramSet.FindOneSpectrum("scale", Spectrum(1.0));
    Float coneangle = paramSet.FindOneFloat("coneangle", 30.);
    Float conedelta = paramSet.FindOneFloat("conedeltaangle", 5.);
    // Compute spotlight world to light transformation
    Point3f from = paramSet.FindOnePoint3f("from", Point3f(0, 0, 0));
    Point3f to = paramSet.FindOnePoint3f("to", Point3f(0, 0, 1));
    Vector3f dir = Normalize(to - from);
    Vector3f du, dv;
    CoordinateSystem(dir, &du, &dv);
    Transform dirToZ =
        Transform(Matrix4x4(du.x, du.y, du.z, 0., dv.x, dv.y, dv.z, 0., dir.x,
                            dir.y, dir.z, 0., 0, 0, 0, 1.));
    Transform light2world =
        l2w * Translate(Vector3f(from.x, from.y, from.z)) * Inverse(dirToZ);
    return std::make_shared<SpotLight>(light2world, medium, I * sc, coneangle,
                                       coneangle - conedelta);
}
Example #26
0
bool Curve::Intersect(const Ray &r, Float *tHit, SurfaceInteraction *isect,
                      bool testAlphaTexture) const {
    ++nTests;
    // Transform _Ray_ to object space
    Vector3f oErr, dErr;
    Ray ray = (*WorldToObject)(r, &oErr, &dErr);

    // Compute object-space control points for curve segment, _cpObj_
    Point3f cpObj[4];
    cpObj[0] = BlossomBezier(common->cpObj, uMin, uMin, uMin);
    cpObj[1] = BlossomBezier(common->cpObj, uMin, uMin, uMax);
    cpObj[2] = BlossomBezier(common->cpObj, uMin, uMax, uMax);
    cpObj[3] = BlossomBezier(common->cpObj, uMax, uMax, uMax);

    // Project curve control points to plane perpendicular to ray
    Vector3f dx, dy;
    CoordinateSystem(ray.d, &dx, &dy);
    Transform objectToRay = LookAt(ray.o, ray.o + ray.d, dx);
    Point3f cp[4] = {objectToRay(cpObj[0]), objectToRay(cpObj[1]),
                     objectToRay(cpObj[2]), objectToRay(cpObj[3])};

    // Compute refinement depth for curve, _maxDepth_
    Float L0 = 0;
    for (int i = 0; i < 2; ++i)
        L0 = std::max(
            L0, std::max(
                    std::max(std::abs(cp[i].x - 2 * cp[i + 1].x + cp[i + 2].x),
                             std::abs(cp[i].y - 2 * cp[i + 1].y + cp[i + 2].y)),
                    std::abs(cp[i].z - 2 * cp[i + 1].z + cp[i + 2].z)));
    Float eps =
        std::max(common->width[0], common->width[1]) * .05f;  // width / 20
#define LOG4(x) (std::log(x) * 0.7213475108f)
    Float fr0 = LOG4(1.41421356237f * 12.f * L0 / (8.f * eps));
#undef LOG4
    int r0 = (int)std::round(fr0);
    int maxDepth = Clamp(r0, 0, 10);
    return recursiveIntersect(ray, tHit, isect, cp, Inverse(objectToRay), uMin,
                              uMax, maxDepth);
}
Example #27
0
bool RGBVolume::Scatter(const Sample &sample, bool scatteredStart,
	const Ray &ray, float u, Intersection *isect, float *pdf,
	float *pdfBack, SWCSpectrum *L) const
{
	// Determine scattering distance
	const float k = sigS.Filter();
	const float d = logf(1 - u) / k; //the real distance is ray.mint-d
	bool scatter = d > ray.mint - ray.maxt;
	if (scatter) {
		// The ray is scattered
		ray.maxt = ray.mint - d;
		isect->dg.p = ray(ray.maxt);
		isect->dg.nn = Normal(-ray.d);
		isect->dg.scattered = true;
		CoordinateSystem(Vector(isect->dg.nn), &(isect->dg.dpdu), &(isect->dg.dpdv));
		isect->ObjectToWorld = Transform();
		isect->primitive = &primitive;
		isect->material = &material;
		isect->interior = this;
		isect->exterior = this;
		isect->arealight = NULL; // Update if volumetric emission
		if (L)
			*L *= SigmaT(sample.swl, isect->dg);
	}
	if (pdf) {
		*pdf = expf((ray.mint - ray.maxt) * k);
		if (isect->dg.scattered)
			*pdf *= k;
	}
	if (pdfBack) {
		*pdfBack = expf((ray.mint - ray.maxt) * k);
			if (scatteredStart)
				*pdfBack *= k;
	}
	if (L)
		*L *= Exp(-Tau(sample.swl, ray));
	return scatter;
}
Example #28
0
void Triangle::GetShadingGeometry(const Transform &obj2world,
        const DifferentialGeometry &dg,
        DifferentialGeometry *dgShading) const {
    if (!mesh->n && !mesh->s) {
        *dgShading = dg;
        return;
    }
    // Initialize _Triangle_ shading geometry with _n_ and _s_

    // Compute barycentric coordinates for point
    float b[3];

    // Initialize _A_ and _C_ matrices for barycentrics
    float uv[3][2];
    GetUVs(uv);
    float A[2][2] =
        { { uv[1][0] - uv[0][0], uv[2][0] - uv[0][0] },
          { uv[1][1] - uv[0][1], uv[2][1] - uv[0][1] } };
    float C[2] = { dg.u - uv[0][0], dg.v - uv[0][1] };
    if (!SolveLinearSystem2x2(A, C, &b[1], &b[2])) {
        // Handle degenerate parametric mapping
        b[0] = b[1] = b[2] = 1.f/3.f;
    }
    else
        b[0] = 1.f - b[1] - b[2];

    // Use _n_ and _s_ to compute shading tangents for triangle, _ss_ and _ts_
    Normal ns;
    Vector ss, ts;
    if (mesh->n) ns = Normalize(obj2world(b[0] * mesh->n[v[0]] +
                                          b[1] * mesh->n[v[1]] +
                                          b[2] * mesh->n[v[2]]));
    else   ns = dg.nn;
    if (mesh->s) ss = Normalize(obj2world(b[0] * mesh->s[v[0]] +
                                          b[1] * mesh->s[v[1]] +
                                          b[2] * mesh->s[v[2]]));
    else   ss = Normalize(dg.dpdu);
    
    ts = Cross(ss, ns);
    if (ts.LengthSquared() > 0.f) {
        ts = Normalize(ts);
        ss = Cross(ts, ns);
    }
    else
        CoordinateSystem((Vector)ns, &ss, &ts);
    Normal dndu, dndv;

    // Compute $\dndu$ and $\dndv$ for triangle shading geometry
    if (mesh->n) {
        float uvs[3][2];
        GetUVs(uvs);
        // Compute deltas for triangle partial derivatives of normal
        float du1 = uvs[0][0] - uvs[2][0];
        float du2 = uvs[1][0] - uvs[2][0];
        float dv1 = uvs[0][1] - uvs[2][1];
        float dv2 = uvs[1][1] - uvs[2][1];
        Normal dn1 = mesh->n[v[0]] - mesh->n[v[2]];
        Normal dn2 = mesh->n[v[1]] - mesh->n[v[2]];
        float determinant = du1 * dv2 - dv1 * du2;
        if (determinant == 0.f)
            dndu = dndv = Normal(0,0,0);
        else {
            float invdet = 1.f / determinant;
            dndu = ( dv2 * dn1 - dv1 * dn2) * invdet;
            dndv = (-du2 * dn1 + du1 * dn2) * invdet;
        }
    }
    else
        dndu = dndv = Normal(0,0,0);
    *dgShading = DifferentialGeometry(dg.p, ss, ts,
        (*ObjectToWorld)(dndu), (*ObjectToWorld)(dndv),
        dg.u, dg.v, dg.shape);
    dgShading->dudx = dg.dudx;  dgShading->dvdx = dg.dvdx;
    dgShading->dudy = dg.dudy;  dgShading->dvdy = dg.dvdy;
    dgShading->dpdx = dg.dpdx;  dgShading->dpdy = dg.dpdy;
}
Example #29
0
bool Triangle::IntersectP(const Ray &ray) const {
    PBRT_RAY_TRIANGLE_INTERSECTIONP_TEST(const_cast<Ray *>(&ray), const_cast<Triangle *>(this));
    // Compute $\VEC{s}_1$

    // Get triangle vertices in _p1_, _p2_, and _p3_
    const Point &p1 = mesh->p[v[0]];
    const Point &p2 = mesh->p[v[1]];
    const Point &p3 = mesh->p[v[2]];
    Vector e1 = p2 - p1;
    Vector e2 = p3 - p1;
    Vector s1 = Cross(ray.d, e2);
    float divisor = Dot(s1, e1);
    
    if (divisor == 0.)
        return false;
    float invDivisor = 1.f / divisor;

    // Compute first barycentric coordinate
    Vector d = ray.o - p1;
    float b1 = Dot(d, s1) * invDivisor;
    if (b1 < 0. || b1 > 1.)
        return false;

    // Compute second barycentric coordinate
    Vector s2 = Cross(d, e1);
    float b2 = Dot(ray.d, s2) * invDivisor;
    if (b2 < 0. || b1 + b2 > 1.)
        return false;

    // Compute _t_ to intersection point
    float t = Dot(e2, s2) * invDivisor;
    if (t < ray.mint || t > ray.maxt)
        return false;

    // Test shadow ray intersection against alpha texture, if present
    if (ray.depth != -1 && mesh->alphaTexture) {
        // Compute triangle partial derivatives
        Vector dpdu, dpdv;
        float uvs[3][2];
        GetUVs(uvs);

        // Compute deltas for triangle partial derivatives
        float du1 = uvs[0][0] - uvs[2][0];
        float du2 = uvs[1][0] - uvs[2][0];
        float dv1 = uvs[0][1] - uvs[2][1];
        float dv2 = uvs[1][1] - uvs[2][1];
        Vector dp1 = p1 - p3, dp2 = p2 - p3;
        float determinant = du1 * dv2 - dv1 * du2;
        if (determinant == 0.f) {
            // Handle zero determinant for triangle partial derivative matrix
            CoordinateSystem(Normalize(Cross(e2, e1)), &dpdu, &dpdv);
        }
        else {
            float invdet = 1.f / determinant;
            dpdu = ( dv2 * dp1 - dv1 * dp2) * invdet;
            dpdv = (-du2 * dp1 + du1 * dp2) * invdet;
        }

        // Interpolate $(u,v)$ triangle parametric coordinates
        float b0 = 1 - b1 - b2;
        float tu = b0*uvs[0][0] + b1*uvs[1][0] + b2*uvs[2][0];
        float tv = b0*uvs[0][1] + b1*uvs[1][1] + b2*uvs[2][1];
        DifferentialGeometry dgLocal(ray(t), dpdu, dpdv,
                                     Normal(0,0,0), Normal(0,0,0),
                                     tu, tv, this);
        if (mesh->alphaTexture->Evaluate(dgLocal) == 0.f)
            return false;
    }
    PBRT_RAY_TRIANGLE_INTERSECTIONP_HIT(const_cast<Ray *>(&ray), t);
    return true;
}
TerrainManager::TerrainManager(
		const Time & runTime,
		const dictionary & dict,
		const searchableSurface * const stl_
		):
		BlockMeshManager(runTime),
		stl_(stl_),
		blockNrs_(dict.lookup("blocks")),
		cellNrs_(dict.lookup("cells")),
		domainBox_
		(
				CoordinateSystem
				(
						point(dict.lookup("p_corner")),
						List< Foam::vector >(dict.subDict("coordinates").lookup("baseVectors"))
				),
				scalarList(dict.lookup("dimensions")),
				dict.lookupOrDefault< scalar >("boxResolution",0.0001)
		),
		stlBox_(domainBox_),
		splineNormalDist_(0),
		mode_upwardSplines_(0),
		zeroLevel_(0),
		gradingFactors_(dict.lookup("gradingFactors")),
		cylinderModule_(this),
		modificationModule_(this),
		gradingModule_(this),
		blendingFunction_
		(
				new ScalarBlendingFunction()
		){

	// Read dictionary:
	p_above_     = point(dict.lookup("p_above"));
	maxDistProj_ = readScalar(dict.lookup("maxDistProj"));

	// option for stl_ inside the domain box:
	if(dict.found("stlInsideBox")){
		if(dict.subDict("stlInsideBox").found("zeroLevel")){
			zeroLevel_ = readScalar(dict.subDict("stlInsideBox").lookup("zeroLevel"));
		}
		stlBox_ = Box
		(
				CoordinateSystem
				(
						point(dict.subDict("stlInsideBox").lookup("p_corner_inside_stl")),
						coordinateSystem().axes()
				),
				scalarList(dict.subDict("stlInsideBox").lookup("dimensions_inside_stl")),
				dict.subDict("stlInsideBox").lookupOrDefault< scalar >("boxResolution",0.0001)
		);
		blendingFunction_ =
				ScalarBlendingFunction::New
				(
					dict.subDict("stlInsideBox").subDict("blendingFunction")
				);
		if(dict.subDict("stlInsideBox").subDict("blendingFunction").found("writePDF")){
			const dictionary & writeDict = dict.subDict("stlInsideBox").subDict("blendingFunction").subDict("writePDF");
			blendingFunction_().writePDFs
			(
					word(writeDict.lookup("baseName")),
					fileName(writeDict.lookup("resultsFolder")),
					point(writeDict.lookup("probePoint0")),
					point(writeDict.lookup("probePoint1")),
					0,1,
					readLabel(writeDict.lookup("steps")),
					readLabel(writeDict.lookup("plotPoints")),
					readLabel(writeDict.lookup("interpolOrder"))
			);
		} else {
			Info << "TerrainManager: keyword 'writePDF' not found in sub dictionary 'blendingFunction'." << endl;
		}
	}

    // module orography modifications:
    if(dict.found("terrainModification")){
    	Info << "   loading orography modification module" << endl;
    	if(!modificationModule_.load(dict.subDict("terrainModification"))){
    		Info << "\n   TerrainManager: Error while loading orography modification module." << endl;
    		throw;
    	}
    }

    // module block grading:
    if(dict.found("blockGrading")){
    	Info << "   loading block grading module" << endl;
    	if(!gradingModule_.load(dict.subDict("blockGrading"))){
    		Info << "\n   TerrainManager: Error while loading block grading module." << endl;
    		throw;
    	}
    }

    // module outer cylinder:
    if(dict.found("outerCylinder")){
    	Info << "   loading cylinder module" << endl;
    	if(!cylinderModule_.load(dict.subDict("outerCylinder"))){
    		Info << "\n   TerrainManager: Error while loading cylinder module." << endl;
    		throw;
    	}
    }

	// option for othogonalization of upward splines:
	if(dict.found("orthogonalizeUpwardSplines")){
		dictionary upsDict = dict.subDict("orthogonalizeUpwardSplines");
		splineNormalDist_ = readScalar(upsDict.lookup("splineNormalDist"));
		if(upsDict.found("ignoreBoundary")) mode_upwardSplines_ = 2;
		else mode_upwardSplines_ = 1;
	}

	// add patches:
	patchesRef().resize(6);
	patchesRef().set
	(
			Block::WEST,
			new BlockMeshPatch
			(
					*this,
					word(dict.lookup("patch_name_west")),
					word(dict.lookup("patch_type_west"))
			)
	);
	patchesRef().set
	(
			Block::EAST,
			new BlockMeshPatch
			(
					*this,
					word(dict.lookup("patch_name_east")),
					word(dict.lookup("patch_type_east"))
			)
	);
	patchesRef().set
	(
			Block::SOUTH,
			new BlockMeshPatch
			(
					*this,
					word(dict.lookup("patch_name_south")),
					word(dict.lookup("patch_type_south"))
			)
	);
	patchesRef().set
	(
			Block::NORTH,
			new BlockMeshPatch
			(
					*this,
					word(dict.lookup("patch_name_north")),
					word(dict.lookup("patch_type_north"))
			)
	);
	patchesRef().set
	(
			Block::GROUND,
			new BlockMeshPatch
			(
					*this,
					word(dict.lookup("patch_name_ground")),
					word(dict.lookup("patch_type_ground"))
			)
	);
	patchesRef().set
	(
			Block::SKY,
			new BlockMeshPatch
			(
					*this,
					word(dict.lookup("patch_name_sky")),
					word(dict.lookup("patch_type_sky"))
			)
	);

	// only one block in up direction:
	blockNrs_[UP] = 1;

	// set spline point numbers:
	splinePointNrs_.resize(3);
	splinePointNrs_[0] = cellNrs_[0] - 1;
	splinePointNrs_[1] = cellNrs_[1] - 1;
	splinePointNrs_[2] = cellNrs_[2] - 1;

	// init landscape_:
	if(stl_){
		landscape_.set
		(
				new STLLandscape
				(
						stl_,
						&(blendingFunction_()),
						&domainBox_,
						&stlBox_,
						zeroLevel_
				)
		);
	}

	// output boxes:
	domainBox_.writeSTL("domainBox.stl");
	stlBox_.writeSTL("stlBox.stl");
}