Commits

Anonymous committed c7e2526

Changes to use Environment texture coordinates

  • Participants
  • Parent commits 29da2b1
  • Branches ARLuxrender

Comments (0)

Files changed (27)

File CMakeLists.txt

 	"${LUX_CMAKE_DIR}"
 	"${LUX_CMAKE_DIR}/SpecializedConfig"
 )
-option(LUXRAYS_DISABLE_OPENCL "Build without OpenCL support" OFF)
+option(LUXRAYS_DISABLE_OPENCL "Build without OpenCL support" ON)
 option(LUX_DOCUMENTATION "Generate project documentation" ON)
 
 # Dade - uncomment to obtain verbose building output

File accelerators/qbvhaccel.cpp

 		const MeshBaryTriangle *triangle(static_cast<const MeshBaryTriangle *>(primitives[hit].get()));
 
 		//look if shape is a null type
-        if (null_shp_isect && triangle->GetPrimitiveType() == lux::ShapeType(AR_SHAPE) ) return false;
+		if (null_shp_isect && triangle->GetPrimitiveType() == lux::ShapeType(AR_SHAPE) ) return false;
 
 		const Point o(reinterpret_cast<const float *>(&origx)[hit],
 			reinterpret_cast<const float *>(&origy)[hit],
 		const float tu = tu_;
 		const float tv = tv_;
 
+		Point wtext = pp;
+		if (triangle->mesh->wuv) {
+			//wtext = Point (o + _b1 * e1 + _b2 * e2);
+			wtext = Point (triangle->mesh->wuv[triangle->v[0]] + _b1 * (triangle->mesh->wuv[triangle->v[1]] - triangle->mesh->wuv[triangle->v[0]]) + _b2 * (triangle->mesh->wuv[triangle->v[2]] - triangle->mesh->wuv[triangle->v[0]]));
+		}
 
 		isect->dg = DifferentialGeometry(pp, nn, dpdu, dpdv,
-			Normal(0, 0, 0), Normal(0, 0, 0), tu, tv, triangle);
+			Normal(0, 0, 0), Normal(0, 0, 0), tu, tv, triangle, 0.f, wtext);
 
 		isect->Set(triangle->mesh->WorldToObject, triangle,
 			triangle->mesh->GetMaterial(),

File core/geometry/raydifferential.cpp

 
 PartialDifferentialGeometry::PartialDifferentialGeometry(
 		const Point &P,
+		const Vector &DPDU,
+		const Vector &DPDV, const Point &WUV )
+	: p(P), dpdu(DPDU), dpdv(DPDV), wuv(WUV) {
+	nn = Normal(Normalize(Cross(dpdu, dpdv)));
+	scattered = false;
+}
+
+PartialDifferentialGeometry::PartialDifferentialGeometry(
+		const Point &P,
 		const Normal &NN,
 		const Vector &DPDU,
 		const Vector &DPDV)
 	scattered = false;
 }
 
+PartialDifferentialGeometry::PartialDifferentialGeometry(
+		const Point &P,
+		const Normal &NN,
+		const Vector &DPDU,
+		const Vector &DPDV, const Point &WUV )
+	: p(P), nn(NN), dpdu(DPDU), dpdv(DPDV), wuv(WUV) {
+	scattered = false;
+}
+
 DifferentialGeometry::DifferentialGeometry(const Point &P,
 		const Vector &DPDU, const Vector &DPDV,
 		const Normal &DNDU, const Normal &DNDV,
 DifferentialGeometry::DifferentialGeometry(const Point &P,
 		const Vector &DPDU, const Vector &DPDV,
 		const Normal &DNDU, const Normal &DNDV,
-		float uu, float vv, const void *pr, float scale)
-	: PartialDifferentialGeometry(P, DPDU, DPDV), dndu(DNDU), dndv(DNDV),
+					   float uu, float vv, const void *pr, float scale, const Point &WUV )
+	: PartialDifferentialGeometry(P, DPDU, DPDV, WUV), dndu(DNDU), dndv(DNDV),
 	  tangent(DPDU), bitangent(DPDV), btsign(1.f), Scale(scale) {
 	// Initialize _DifferentialGeometry_ from parameters
 	u = uu;
 		const Normal &NN,
 		const Vector &DPDU, const Vector &DPDV,
 		const Normal &DNDU, const Normal &DNDV,
-		float uu, float vv, const void *pr, float scale)
-	: PartialDifferentialGeometry(P, NN, DPDU, DPDV), dndu(DNDU), dndv(DNDV),
+		float uu, float vv, const void *pr, float scale, const Point &WUV)
+	: PartialDifferentialGeometry(P, NN, DPDU, DPDV, WUV), dndu(DNDU), dndv(DNDV),
 	  tangent(DPDU), bitangent(DPDV), btsign(1.f), Scale(scale) {
 	// Initialize _DifferentialGeometry_ from parameters
 	u = uu;
 		const Vector &DPDU, const Vector &DPDV,
 		const Normal &DNDU, const Normal &DNDV,
 		const Vector &T, const Vector &BiT, float BiTsign,
-		float uu, float vv, const void *pr, float scale)
-	: PartialDifferentialGeometry(P, NN, DPDU, DPDV), dndu(DNDU), dndv(DNDV),
+		float uu, float vv, const void *pr, float scale, const Point &WUV)
+	: PartialDifferentialGeometry(P, NN, DPDU, DPDV, WUV), dndu(DNDU), dndv(DNDV),
 	  tangent(T), bitangent(BiT), btsign(BiTsign), Scale(scale) {
 	// Initialize _DifferentialGeometry_ from parameters
 	u = uu;

File core/geometry/raydifferential.h

 	Vector dpdu, dpdv;
 	float time;
 	bool scattered;
+	Point wuv;
 
 	PartialDifferentialGeometry() { scattered = false; }
 
 			const Vector &DPDV);
 
 	PartialDifferentialGeometry(
+			const Point &P,
+			const Vector &DPDU,
+			const Vector &DPDV, const Point &WUV);
+
+	PartialDifferentialGeometry(
 		const Point &P,
 		const Normal &NN,
 		const Vector &DPDU,
 		const Vector &DPDV);
+
+	PartialDifferentialGeometry(
+		const Point &P,
+		const Normal &NN,
+		const Vector &DPDU,
+		const Vector &DPDV, const Point &WUV);
 };
 
 // DifferentialGeometry Declarations
 			const Vector &DPDU,	const Vector &DPDV,
 			const Normal &DNDU, const Normal &DNDV,
 			float uu, float vv,
-			const void *pr, float scale);
+			const void *pr, float scale, const Point &WUV);
 	DifferentialGeometry(
 			const Point &P, const Normal &NN,
 			const Vector &DPDU,	const Vector &DPDV,
 			const Vector &DPDU,	const Vector &DPDV,
 			const Normal &DNDU, const Normal &DNDV,
 			float uu, float vv,
-			const void *pr, float scale);
+			const void *pr, float scale, const Point &WUV);
 	DifferentialGeometry(
 			const Point &P, const Normal &NN,
 			const Vector &DPDU,	const Vector &DPDV,
 			const Normal &DNDU, const Normal &DNDV,
 			const Vector &T, const Vector &BiT, float BiTsign,
 			float uu, float vv,
-			const void *pr, float scale);
+			const void *pr, float scale, const Point &WUV);
 	void AdjustNormal(bool ro, bool swapsHandedness) {
 		// Adjust normal based on orientation and handedness
 		if (ro ^ swapsHandedness)
 	const void* ihandle; // handle to intersected primitive, used with instances
 	mutable float Scale;
 
+
 	// Dade - shape specific data, useful to "transport" informatin between
 	// shape intersection method and GetShadingGeometry()
 	IntersectionData iData;

File core/light.h

 	virtual bool IsDeltaLight() const = 0;
 	virtual bool IsEnvironmental() const = 0;
         virtual bool IsSupport() const { return false; }
-	virtual float DirProb(Vector N, Vector Z = Vector(0.f) ) const { return 1.f; }
+	virtual float DirProb(Vector N, Point P = Point(0.f) ) const { return 1.f; }
 	virtual bool LeSupport(const Scene &scene, const Sample &sample,
-		const Vector wr, SWCSpectrum *L) const { return false; }
+		const Point wr, SWCSpectrum *L) const { return false; }
 	virtual bool Le(const Scene &scene, const Sample &sample, const Ray &r,
 		BSDF **bsdf, float *pdf, float *pdfDirect,
 		SWCSpectrum *L) const { return false; }
+	virtual bool Le(const Scene &scene, const Sample &sample, const Point &p,
+		BSDF **bsdf, float *pdf, float *pdfDirect,
+		SWCSpectrum *L) const { return false; }
 	virtual float Pdf(const Point &p, const PartialDifferentialGeometry &dg) const = 0;
 	virtual bool SampleL(const Scene &scene, const Sample &sample,
 		float u1, float u2, float u3, BSDF **bsdf, float *pdf,
 		const Point &p, float u1, float u2, float u3,
 		BSDF **bsdf, float *pdf, float *pdfDirect,
 		SWCSpectrum *L) const = 0;
+	virtual bool SampleL(const Scene &scene, const Sample &sample,
+		const Point &p, const Normal &n, float u1, float u2, float u3,
+		BSDF **bsdf, float *pdf, float *pdfDirect,
+		SWCSpectrum *L) const {return false;}
 	const LightRenderingHints *GetRenderingHints() const { return &hints; }
 
 	void AddPortalShape(boost::shared_ptr<Primitive> &shape);

File core/primitive.cpp

 	LOG( LUX_SEVERE,LUX_BUG)<< "Unimplemented Primitive::Refine method called!";
 }
 
-bool Primitive::GetNormal(Vector *N) const
+Vector Primitive::GetNormal(u_int i) const
 {
 	LOG( LUX_SEVERE,LUX_BUG)<< "Unimplemented Primitive::GetNormal method called!";
-	return false;
+	return Vector(0.f);
 }
 
-bool Primitive::GetBaryPoint(Point *P) const
+Point Primitive::GetPoint(u_int i) const
 {
 	LOG( LUX_SEVERE,LUX_BUG)<< "Unimplemented Primitive::GetBaryPoint method called!";
-	return false;
+	return Point(0.f);
 }
 
-float Primitive::GetScale() const
+float Primitive::GetScale(u_int i) const
 {
 	return 1.f;
 }

File core/primitive.h

 		const PrimitiveRefinementHints &refineHints,
 		const boost::shared_ptr<Primitive> &thisPtr);
 
-    virtual ShapeType GetPrimitiveType() const { return ShapeType(LUX_SHAPE); }
-	virtual bool GetNormal(Vector *N) const;
-	virtual bool GetBaryPoint(Point *P) const;
-	virtual float GetScale() const;
-	virtual bool SetScale(float scale) const { return false; }
+	virtual ShapeType GetPrimitiveType() const { return ShapeType(LUX_SHAPE); }
+	virtual Vector GetNormal(u_int i) const;
+	virtual Point GetPoint(u_int i) const;
+	virtual float GetScale(u_int i) const;
+	virtual bool SetScale(float scale, u_int i) const { return false; }
 	// Intersection
 	/**
 	 * Returns whether this primitive can be intersected.
 		const PrimitiveRefinementHints& refineHints,
 		const boost::shared_ptr<Primitive> &thisPtr);
 
-    virtual ShapeType GetPrimitiveType() const { return prim->GetPrimitiveType(); }
+	virtual ShapeType GetPrimitiveType() const { return prim->GetPrimitiveType(); }
 	virtual bool CanIntersect() const { return prim->CanIntersect(); }
 	virtual bool Intersect(const Ray &r, Intersection *in, bool null_shp_isect = false) const;
 	virtual bool IntersectP(const Ray &r, bool null_shp_isect = false) const { return prim->IntersectP(r, null_shp_isect); }
 		return interior ? interior.get() : instance->GetInterior();
 	}
 
-    virtual ShapeType GetPrimitiveType() const { return instance->GetPrimitiveType(); }
+	virtual ShapeType GetPrimitiveType() const { return instance->GetPrimitiveType(); }
 	virtual bool CanIntersect() const { return instance->CanIntersect(); }
 	virtual bool Intersect(const Ray &r, Intersection *in, bool null_shp_isect = false) const;
 	virtual bool IntersectP(const Ray &r, bool null_shp_isect = false) const;
 public:
 	// Aggregate Public Methods
 	virtual ~Aggregate() { }
-    virtual ShapeType GetPrimitiveType() const { return ShapeType(LUX_SHAPE); }
+	virtual ShapeType GetPrimitiveType() const { return ShapeType(LUX_SHAPE); }
 	virtual bool CanIntersect() const { return true; }
 	virtual bool CanSample() const { return false; }
 
 		return interior ? interior.get() : instance->GetInterior();
 	}
 
-    virtual ShapeType GetPrimitiveType() const { return instance->GetPrimitiveType(); }
+	virtual ShapeType GetPrimitiveType() const { return instance->GetPrimitiveType(); }
 	virtual bool CanIntersect() const { return instance->CanIntersect(); }
 	virtual bool Intersect(const Ray &r, Intersection *in, bool null_shp_isect = false) const;
 	virtual bool IntersectP(const Ray &r, bool null_shp_isect = false) const;
 	 * Returns whether this primitive can be sampled.
 	 */
 	virtual bool CanSample() const { return false; }
-    virtual ShapeType GetPrimitiveType() const { return ShapeType(LUX_SHAPE); }
+	virtual ShapeType GetPrimitiveType() const { return ShapeType(LUX_SHAPE); }
 	virtual Transform GetWorldToLocal(float time) const {
 		return Transform();
 	}

File core/scene.cpp

 		shp = objects[i].get();
 		if( shp != NULL ) {
 
-            if( shp->GetPrimitiveType() == ShapeType(AR_SHAPE) ) {
+			if( shp->GetPrimitiveType() == ShapeType(AR_SHAPE) ) {
+
 				Vector N;
 				Point P;
-				float Pow =0.f;
-				shp->GetNormal(&N);
-				shp->GetBaryPoint(&P);
-				Z = cam-P;
-				if( Dot(N,Z) < 0.f )  
-					N = N * (-1);
-				for( u_int k=0 ; k < lights.size() ; k++ )
-					if (lights[k]->IsSupport()) {
-						Pow += lights[k]->DirProb(N, -Z);
+				for (u_int j = 0 ; j < 4 ; j++) {
+					float Pow =0.f;
+					N = shp->GetNormal(j);
+					if (N.LengthSquared() > 0.000001f) {
+						P = shp->GetPoint(j);
+						Z = cam-P;
+						if( Dot(N,Z) < 0.f )
+							N = N * (-1);
+						for( u_int k=0 ; k < lights.size() ; k++ )
+							if (lights[k]->IsSupport()) {
+								Pow += lights[k]->DirProb(N, P);
+							}
+						shp->SetScale(Pow, j);
 					}
-				shp->SetScale(Pow);
+
+				}
 			}
 		}
 	}

File core/shape.h

 		}
 	}
 
-    virtual ShapeType GetPrimitiveType() const { return ShapeType(LUX_SHAPE); }
-	virtual bool GetNormal(Vector *N) const { return false; }
-	virtual bool GetBaryPoint(Point *P) const { return false; }
-	virtual float GetScale() const { return 1.f; }
-	virtual bool SetScale(float scale) const { return false; }
+	virtual ShapeType GetPrimitiveType() const { return ShapeType(LUX_SHAPE); }
+	virtual Vector GetNormal(u_int i) const { return Vector(0.f); }
+	virtual Point GetPoint(u_int i) const { return Point(0.f); }
+	virtual float GetScale(u_int i) const { return 1.f; }
+	virtual bool SetScale(float scale, u_int i) const { return false; }
 	virtual bool CanIntersect() const { return true; }
 	virtual bool Intersect(const Ray &r, Intersection *isect, bool null_shp_isect = false ) const {
 		float thit;
 	virtual ~PrimitiveSet() { }
 
 	virtual BBox WorldBound() const { return worldbound; }
-    virtual ShapeType GetPrimitiveType() const { return ShapeType(LUX_SHAPE); }
+	virtual ShapeType GetPrimitiveType() const { return ShapeType(LUX_SHAPE); }
 	virtual bool CanIntersect() const {
 		for (u_int i = 0; i < primitives.size(); ++i)
 			if (!primitives[i]->CanIntersect()) return false;

File core/transport.cpp

 {
 	SWCSpectrum Ld(0.f);
 
-	Point cam( scene.camera->CameraToWorld( Point(0.f, 0.f, 0.f) ) );
 	if ( to_IsSup ) {
 		if ( path_type || rayDepth == 0 ) {
 			// Check if MIS is needed
 			SWCSpectrum Li;
 			SWCSpectrum SupLi(1.f);
 			BSDF *lightBsdf;
-			Vector Wsup ( p - cam );
-			if (light.SampleL(scene, sample, p, ls1, ls2, ls3,
+			if (light.SampleL(scene, sample, p, n, ls1, ls2, ls3,
 				&lightBsdf, NULL, &lightPdf, &Li)) {
 				const Point &pL(lightBsdf->dgShading.p);
-				const Vector wi0(pL);
+				const Vector wi0(pL - p);
 				const Volume *volume = bsdf->GetVolume(wi0);
 				if (!volume)
 					volume = lightBsdf->GetVolume(-wi0);
 						Li *= bsdf->F(sample.swl, wi, wo, true);
 						if (!Li.Black()) {
 							// Add light's contribution
-							if( light.LeSupport(scene, sample, Wsup, &SupLi) )
+							if( light.LeSupport(scene, sample, bsdf->dgShading.wuv, &SupLi) )
 								Ld +=  SupLi * AbsDot (wi, n);
 							else
 								Ld += bsdf->GetBscale() * SupLi * AbsDot (wi, n);
 							Li *= bsdf->F(sample.swl, wi, wo, true);
 							if (!Li.Black()) {
 								const float bsdfPdf = bsdf->Pdf(sample.swl,wo, wi);
-								Li *= PowerHeuristic(1, lightPdf * d2, 1, bsdfPdf);
+								Li *= PowerHeuristic(1, lightPdf * d2 / AbsDot(wi, lightBsdf->dgShading.nn), 1, bsdfPdf);
 
 								// Add light's contribution
-								if( light.LeSupport(scene, sample, Wsup, &SupLi) )
+								if( light.LeSupport(scene, sample, bsdf->dgShading.wuv, &SupLi) )
 									Ld +=  SupLi * AbsDot (wi, n);
 								else
 									Ld += bsdf->GetBscale() * SupLi * AbsDot (wi, n);
 							Li = bsdf->F(sample.swl, wi, wo, true);
 							if (!Li.Black()) {
 								const float bsdfPdf = bsdf->Pdf(sample.swl, wo, wi);
-								Li *= PowerHeuristic(1, lightPdf * d2, 1, bsdfPdf);
+								Li *= PowerHeuristic(1, lightPdf * d2 / AbsDot(wi, lightBsdf->dgShading.nn), 1, bsdfPdf);
 
 								// Add light's contribution
-								if( light.LeSupport(scene, sample, Wsup, &SupLi) )
+								if( light.LeSupport(scene, sample, bsdf->dgShading.wuv, &SupLi) )
 									Ld +=  SupLi * AbsDot (wi, n);
 								else
 									Ld += bsdf->GetBscale() * SupLi * AbsDot (wi, n);
 						lit = !Li.Black();
 					}
 					else if (lightIsect.primitive) {
-                        if ( lightIsect.primitive->GetPrimitiveType() == ShapeType(ENV_SHAPE) && rayDepth > 0 ) {
-						    Ray ray2(Point(0.f), Vector(lightIsect.dg.p - cam));
-						    light.Le(scene, sample, ray2, &lightBsdf,
-						    NULL, &lightPdf, &Li);
-						    //float d2 = DistanceSquared(p, lightBsdf->dgShading.p);
-						    float lightPdf2 = lightPdf ;
-						    float weight = PowerHeuristic(1, bsdfPdf, 1, lightPdf2);
-						    Ld += Li * weight;
+						if ( lightIsect.primitive->GetPrimitiveType() == ShapeType(ENV_SHAPE) && rayDepth > 0 ) {
+
+							light.Le(scene, sample, ibsdf->dgShading.wuv, &lightBsdf,
+								 NULL, &lightPdf, &Li);
+							//float d2 = DistanceSquared(p, lightBsdf->dgShading.p);
+							//float lightPdf2 = lightPdf ;
+							float weight = PowerHeuristic(1, bsdfPdf, 1, lightPdf);
+							Ld += Li * weight;
 						}
 					}
 					if (lit) {
 				}
 				else if (lightIsect.primitive) {
 					if ( lightIsect.primitive->GetPrimitiveType() == ShapeType(ENV_SHAPE) ) {
-						Ray ray2(Point(0.f), Vector(lightIsect.dg.p - cam));
-						light.Le(scene, sample, ray2, &lightBsdf,
+						//Ray ray2(Point(0.f), Vector(lightIsect.dg.p - cam));
+						light.Le(scene, sample, ibsdf->dgShading.wuv, &lightBsdf,
 							 NULL, &lightPdf, &Li);
 						//float d2 = DistanceSquared(p, lightBsdf->dgShading.p);
-						float lightPdf2 = lightPdf ;
-						float weight = PowerHeuristic(1, bsdfPdf, 1, lightPdf2);
+						//float lightPdf2 = lightPdf ;
+						float weight = PowerHeuristic(1, bsdfPdf, 1, lightPdf);
 						Ld += Li * weight;
 					}
 				}

File integrators/envpath.cpp

 				pathThroughput /= spdf;
 				// Dade - now I know ray.maxt and I can call volumeIntegrator
 				SWCSpectrum Lv;
-				ray2 = Ray( Point(0.f), Vector(isect.dg.p - cam ) );
+				ray2 = Ray( Point(0.f), Vector(isect.dg.p ) );
 				u_int g = scene.volumeIntegrator->Li(scene, ray2, sample,
 								     &Lv, &alpha, from_IsSup, path_type);
 				if (!Lv.Black()) {
 				if (!enableDirectLightSampling || (
 							(includeEnvironment || vertexIndex > 0) && specularBounce && (path_type || pathLength==0) )) {
 					BSDF *ibsdf;
+
+					//Point dir = isect.dg.p;
+					//if (isect.primitive->UseWorldMapping())
+					//	dir = isect.dg.wuv;
+					//bsdf->dgShading.wuv
 					for (u_int i = 0; i < nLights; ++i) {
 						SWCSpectrum Le(pathThroughput);
 						if (scene.lights[i]->Le(scene, sample,
-									ray2, &ibsdf, NULL, NULL, &Le)) {
+									bsdf->dgShading.wuv, &ibsdf, NULL, NULL, &Le)) {
 							L[scene.lights[i]->group] += Le;
 							V[scene.lights[i]->group] += Le.Filter(sw) * VContrib;
 							++nrContribs;
 
 		if (to_IsSup) {
 			SWCSpectrum SupLi(1.f);
-			Vector Wsup ( p - cam );
-			Ray( Point(0.f), Vector(isect.dg.p - scene.camera->CameraToWorld( Point(0.f, 0.f, 0.f) ) ) );
+			//Vector Wsup ( p - cam );
+			//Ray( Point(0.f), Vector(isect.dg.p - scene.camera->CameraToWorld( Point(0.f, 0.f, 0.f) ) ) );
+			//Point dir = p;
+			//if (isect.primitive->UseWorldMapping())
+			//	dir = isect.dg.wuv;
 			for (u_int i = 0; i < nLights; ++i) {
 				//SWCSpectrum Le(1.f);
 				if (scene.lights[i]->IsSupport()) {
-					scene.lights[i]->LeSupport(scene, sample, Wsup, &SupLi);
+					scene.lights[i]->LeSupport(scene, sample, bsdf->dgShading.wuv, &SupLi);
 				}
 			}
 			//LeSupport(scene, sample, Wsup, &SupLi);

File lights/environment.cpp

 	MedCutLight C_MCLight;
 	MedCutSample( &C_MCLight, predata, depth, LNs, W, H );
 	LNsamples = C_MCLight.size();
-	lightdata = new float[4*LNsamples];
+
+	llum = new float[LNsamples];
+	lpos = new Point[LNsamples];
+	tlum = 0.f;
 	for( int i=0; i< LNsamples; i++){
-		lightdata[4*i]  = C_MCLight[i].x*C_MCLight[i].r;
-		lightdata[4*i+1]= C_MCLight[i].y*C_MCLight[i].r;
-		lightdata[4*i+2]= C_MCLight[i].z*C_MCLight[i].r;
-		lightdata[4*i+3]= C_MCLight[i].lum;
+		lpos[i] = LightToWorld( Point( C_MCLight[i].x*C_MCLight[i].r, C_MCLight[i].y*C_MCLight[i].r, C_MCLight[i].z*C_MCLight[i].r ) );
+		llum[i]= C_MCLight[i].lum;
+		tlum += llum[i];
 	}
+
 	C_MCLight.clear();
 	delete [] predata;
 	delete [] depth;
+	LOG(LUX_INFO, LUX_NOERROR) << "Environment light created";
 
 }
 
-float EnvironmentLight::DirProb(Vector N, Vector Z) const
+float EnvironmentLight::DirProb(Vector N, Point P) const
 {
-	Vector w = N;
 	// Compute infinite light radiance for direction
-	if (lightdata != NULL) {
-		Vector wh = Normalize(WorldToLight(w));
-		Vector dh = WorldToLight(Z);
-		float T_rad = 0.f, P_rad = 0.f; 
+	if (llum != NULL) {
+		float P_rad = 0.f;
+		Vector  dir;
+		for( int i = 0 ; i < LNsamples ; i++ ) {
 
-        for( int i=0; i < LNsamples; i++) {
-			Vector dummy, dir;
-			dummy.x = lightdata[4*i];
-			dummy.y = lightdata[4*i+1];
-			dummy.z = lightdata[4*i+2];
-			dir = Normalize(Vector(dummy-dh));
-			float cosN = Dot( wh, dir );
-	
+			dir = Normalize( Vector(lpos[i] - P) );
+			float cosN = Dot( N, dir );
+
 			if ( cosN > 0.f ) {
-				P_rad += lightdata[4*i+3] * cosN; 
-				T_rad += lightdata[4*i+3]; 
+				P_rad += llum[i] * cosN;
 			}
-			else
-				T_rad += lightdata[4*i+3];
 		}
-		return T_rad/P_rad;
+		return tlum/P_rad;
 	}
 	return 0.5f;
 }
 
 bool EnvironmentLight::LeSupport(const Scene &scene, const Sample &sample,
-	const Vector wr, SWCSpectrum *L) const
+	const Point p, SWCSpectrum *L) const
 {
-
 	*L *= SWCSpectrum(sample.swl, SPDbase);
-	const Vector wh = Normalize(WorldToLight(wr));
+	//Point lpos = WorldToLight(p);
+	const Vector wh = Normalize( Vector( WorldToLight(p) ) );
 	float s, t, pdfMap;
 	mapping->Map(wh, &s, &t, &pdfMap);
 	if (radianceMap != NULL) {
 	*bsdf = ARENA_ALLOC(sample.arena, EnvironmentBSDF)(dg, ns,
 		v, v, *this, WorldToLight);
 	*L *= SWCSpectrum(sample.swl, SPDbase);
-	const Vector wh = Normalize(WorldToLight(r.d));
+
+
+//	const Vector wh = Normalize(WorldToLight(r.d));
+
+	const Vector wh = Normalize( Vector( WorldToLight(Point(r.d.x, r.d.y, r.d.z) ) ) );
+
+
 	float s, t, pdfMap;
 	mapping->Map(wh, &s, &t, &pdfMap);
 	if (radianceMap != NULL)
 	return true;
 }
 
+bool EnvironmentLight::Le(const Scene &scene, const Sample &sample,
+	const Point &p, BSDF **bsdf, float *pdf, float *pdfDirect,
+	SWCSpectrum *L) const
+{
+
+	*L *= SWCSpectrum(sample.swl, SPDbase);
+	const Vector wh = Normalize( Vector( WorldToLight(p) ) );
+
+	float s, t, pdfMap;
+	mapping->Map(wh, &s, &t, &pdfMap);
+	if (radianceMap != NULL)
+		*L *= radianceMap->LookupSpectrum(sample.swl, s, t);
+
+	if (pdfDirect)
+		*pdfDirect = uvDistrib->Pdf(s, t) * pdfMap ; // *AbsDot(r.d, ns) / DistanceSquared(r.o, ps);
+	return true;
+
+}
+
 float EnvironmentLight::Pdf(const Point &p, const PartialDifferentialGeometry &dg) const
 {
 	const Vector d(Normalize(dg.p - p));
 	const Point &p, float u1, float u2, float u3, BSDF **bsdf, float *pdf,
 	float *pdfDirect, SWCSpectrum *Le) const
 {
-
-    float worldRadius;
+	float worldRadius;
 	// Find floating-point $(u,v)$ sample coordinates
 	float uv[2];
 	uvDistrib->SampleContinuous(u1, u2, uv, pdfDirect);
 	// Convert sample point to direction on the unit sphere
 	Vector wi;
 	float pdfMap;
-    mapping->Map(uv[0], uv[1], &wi, &pdfMap);
-    worldRadius = radianceMap->LookupFloat(CHANNEL_ALPHA, uv[0], uv[1]);
-    // Find the light point in World space
-    wi = LightToWorld( worldRadius*wi );
+	mapping->Map(uv[0], uv[1], &wi, &pdfMap);
+	worldRadius = radianceMap->LookupFloat(CHANNEL_ALPHA, uv[0], uv[1]);
+	// Find the light point in World space
+	wi = LightToWorld( worldRadius*wi );
 
 	if (!(pdfMap > 0.f))
 		return false;
 	// Compute PDF for sampled direction
 	*pdfDirect *= pdfMap;
-    // Squared distance from origin to light point
-    const float distance2 =  Dot(wi, wi);
+	// Squared distance from origin to light point
+	const float distance2 =  Dot(wi, wi);
 
-    const Point ps(wi.x, wi.y, wi.z);
-    const Normal ns( Normalize(-wi) );
+	const Point ps(wi.x, wi.y, wi.z);
+	const Normal ns( Normalize(-wi) );
 	Vector dpdu, dpdv;
-    CoordinateSystem(Vector(ns), &dpdu, &dpdv);
+	CoordinateSystem(Vector(ns), &dpdu, &dpdv);
 	DifferentialGeometry dg(ps, ns, dpdu, dpdv, Normal(0, 0, 0),
-		Normal (0, 0, 0), 0, 0, NULL);
+				Normal (0, 0, 0), 0, 0, NULL);
 	dg.time = sample.realTime;
 	const Volume *v = GetVolume();
-    *bsdf = ARENA_ALLOC(sample.arena, EnvironmentBSDF)(dg, ns,
-		v, v, *this, WorldToLight);
+	*bsdf = ARENA_ALLOC(sample.arena, EnvironmentBSDF)(dg, ns,
+							   v, v, *this, WorldToLight);
 	if (pdf)
 		*pdf = 1.f / (4.f * M_PI * worldRadius * worldRadius);
-    //AbsDot(Normalize(wi), ns) = 1.f
-    *pdfDirect *= 1.f / distance2;
+	//AbsDot(Normalize(wi), ns) = 1.f
+	*pdfDirect *= 1.f / distance2;
+
+	*Le = SWCSpectrum(sample.swl, SPDbase) * (M_PI / *pdfDirect);
+	return true;
+}
+
+bool EnvironmentLight::SampleL(const Scene &scene, const Sample &sample,
+	const Point &p, const Normal &n, float u1, float u2, float u3, BSDF **bsdf, float *pdf,
+	float *pdfDirect, SWCSpectrum *Le) const
+{
+	float worldRadius;
+	// Find floating-point $(u,v)$ sample coordinates
+	float uv[2];
+	uvDistrib->SampleContinuous(u1, u2, uv, pdfDirect);
+	// Convert sample point to direction on the unit sphere
+	Vector wi;
+	float pdfMap;
+	mapping->Map(uv[0], uv[1], &wi, &pdfMap);
+	worldRadius = radianceMap->LookupFloat(CHANNEL_ALPHA, uv[0], uv[1]);
+	// Find the light point in World space
+	const Point ps = LightToWorld( worldRadius * Point(wi.x ,wi.y, wi.z) );
+	wi = Normalize(ps - p);
+	if (!(pdfMap > 0.f))
+		return false;
+	// Compute PDF for sampled direction
+	*pdfDirect *= pdfMap;
+
+	Vector dpdu, dpdv;
+	CoordinateSystem(Vector(n), &dpdu, &dpdv);
+	DifferentialGeometry dg(ps, n, dpdu, dpdv, Normal(0, 0, 0),
+				Normal (0, 0, 0), 0, 0, NULL);
+	dg.time = sample.realTime;
+	const Volume *v = GetVolume();
+	*bsdf = ARENA_ALLOC(sample.arena, EnvironmentBSDF)(dg, n,
+							   v, v, *this, WorldToLight);
+	if (pdf)
+		*pdf = 1.f / (4.f * M_PI * worldRadius * worldRadius);
+
+	*pdfDirect *= AbsDot(Normalize(wi), n) / (worldRadius*worldRadius);
 
 	*Le = SWCSpectrum(sample.swl, SPDbase) * (M_PI / *pdfDirect);
 	return true;

File lights/environment.h

 		scene.WorldBound().BoundingSphere(&worldCenter, &worldRadius);
 		return SPDbase.Y() * mean_y * M_PI * worldRadius * worldRadius;
 	}
-	virtual float DirProb(Vector N, Vector Z  ) const;
+	virtual float DirProb(Vector N, Point P  ) const;
 	virtual bool IsSupport() const { return support; }
 	virtual bool IsDeltaLight() const { return false; }
 	virtual bool IsEnvironmental() const { return true; }
 	virtual bool LeSupport(const Scene &scene, const Sample &sample,
-		const Vector wr, SWCSpectrum *L) const;
+		const Point wr, SWCSpectrum *L) const;
 	virtual bool Le(const Scene &scene, const Sample &sample, const Ray &r,
 		BSDF **bsdf, float *pdf, float *pdfDirect,
 		SWCSpectrum *L) const;
+	virtual bool Le(const Scene &scene, const Sample &sample, const Point &p,
+		BSDF **bsdf, float *pdf, float *pdfDirect,
+		SWCSpectrum *L) const;
 	virtual float Pdf(const Point &p, const PartialDifferentialGeometry &dg) const;
 	virtual bool SampleL(const Scene &scene, const Sample &sample,
 		float u1, float u2, float u3, BSDF **bsdf, float *pdf,
 	virtual bool SampleL(const Scene &scene, const Sample &sample,
 		const Point &p, float u1, float u2, float u3, BSDF **bsdf,
 		float *pdf, float *pdfDirect, SWCSpectrum *Le) const;
+	virtual bool SampleL(const Scene &scene, const Sample &sample,
+		const Point &p, const Normal &n, float u1, float u2, float u3, BSDF **bsdf,
+		float *pdf, float *pdfDirect, SWCSpectrum *Le) const;
 
 	static Light *CreateLight(const Transform &light2world,
 		const ParamSet &paramSet);
 	MIPMap *radianceMap, *contribMap;
 	EnvironmentMapping *mapping;
 	u_int W, H, LNsamples;
-	float *lightdata;
+	float tlum;
+	float *llum;
+	Point *lpos;
 private:
 	// EnvironmentLight Private Data
 	RGBIllumSPD SPDbase;

File lights/infinitesample.cpp

 }
 
 bool InfiniteAreaLightIS::LeSupport(const Scene &scene, const Sample &sample,
-	const Vector wr, SWCSpectrum *L) const
+	const Point wr, SWCSpectrum *L) const
 {
 
 	*L *= SWCSpectrum(sample.swl, SPDbase);
-	const Vector wh = Normalize(WorldToLight(wr));
+	const Vector wh = Normalize( Vector(WorldToLight(wr)) );
 	float s, t, pdfMap;
 	mapping->Map(wh, &s, &t, &pdfMap);
 	if (radianceMap != NULL)

File lights/infinitesample.h

 	virtual bool IsDeltaLight() const { return false; }
 	virtual bool IsEnvironmental() const { return true; }
 	virtual bool LeSupport(const Scene &scene, const Sample &sample,
-		const Vector wr, SWCSpectrum *L) const;
+		const Point wr, SWCSpectrum *L) const;
 	virtual bool Le(const Scene &scene, const Sample &sample, const Ray &r,
 		BSDF **bsdf, float *pdf, float *pdfDirect,
 		SWCSpectrum *L) const;

File lights/mediancut/mediancut.cpp

 			y = sin( theta ) * sin( phi );
 			z = cos( theta );
 			if(depth !=NULL)
-				radius = BL->sumRectangle(MedCut0[j].x0, MedCut0[j].y0, MedCut0[j].x1, MedCut0[j].y1);
+				radius = BL->MeanValue( MedCut0[j].x0, MedCut0[j].y0, MedCut0[j].x1, MedCut0[j].y1 );
 			MC mc = MC( ( (float)( MedCut0[j].u) + 0.5f ), ( (float)( MedCut0[j].v ) + 0.5f ), x, y, z, MedCut0[j].Avsum, radius);
 			(*MCLight).push_back( mc );
 		}

File lights/mediancut/summedareatable.cpp

 	}
 }
 
+
+float SummedAreaTable::MeanValue( int x0, int y0, int x1, int y1 ) {
+
+    if ( x0 > 0 ) {
+
+	if ( y0 > 0 )
+	    return ( ( A[ width*(y0-1)+(x0-1) ] + A[ width*y1+x1 ] ) - ( A[ width*(y0-1)+x1 ] + A[ width*y1+(x0-1) ] ) ) / ( (x1-x0+1)*(y1-y0+1) ) ;
+	else
+	    return ( A[ width*y1+x1 ] - A[ width*y1+(x0-1) ] ) / ( (x1-x0+1)*(y1-y0+1) ) ;
+    }
+    else {
+
+	if ( y0 > 0 )
+	    return ( A[ width*y1+x1 ] - A[ width*(y0-1)+x1 ] ) / ( (x1-x0+1)*(y1-y0+1) ) ;
+	else
+	    return ( A[ width*y1+x1 ] ) / ( (x1-x0+1)*(y1-y0+1) ) ;
+    }
+}
 //-------------------------------------------------------------------------//
 
 float SummedAreaTable::getMaxValue( void ) {

File lights/mediancut/summedareatable.h

 		float &pixel( int x , int y ) { return A[width*y+x]; }
 		float &operator()( int x, int y ) { return A[width*y+x]; }
 		float sumRectangle( int x0, int y0, int x1, int y1 );
+		float MeanValue( int x0, int y0, int x1, int y1 );
 		float pixelOverAverage( int x, int y ) {
 
 			float pixel = sumRectangle(x,y,x,y) * width * height;

File shapes/loopsubdiv.h

 		float dmscale, float dmoffset, bool dmnormalsmooth,
 		bool dmsharpboundary, bool normalsplit, const string &name);
 	virtual ~LoopSubdiv();
-	virtual float GetScale() const { return Scale; }
-	virtual bool SetScale(float scale) const { Scale = scale; return true; }
+    virtual float GetScale(u_int i) const { return 1.f; }
+    virtual bool SetScale(float scale, u_int i) const {  return false; }
 	virtual u_int GetPrimitiveType() const { return shape_type; }
 	virtual bool GetNormal(Vector *N) const { return true; }
 	virtual bool GetBaryPoint(Point *P) const { return true; }
 	u_int shape_type;
 	bool proj_text;
 	Point cam;
-	mutable float Scale;
+	float *Scale;
 };
 
 // LoopSubdiv Inline Functions

File shapes/mesh.cpp

 
 Mesh::Mesh(const Transform &o2w, bool ro, const string &name,
 	ShapeType shpType, bool proj, Point cam_, MeshAccelType acceltype,
-	u_int nv, const Point *P, const Normal *N, const float *UV,
+	u_int nv, const Point *P, const Normal *N, const float *UV, const Point *WUV,
 	MeshTriangleType tritype, u_int trisCount, const int *tris,
 	MeshQuadType quadtype, u_int nquadsCount, const int *quads,
 	MeshSubdivType subdivtype, u_int nsubdivlevels,
 	bool dmNormalSmooth, bool dmSharpBoundary, bool normalsplit, bool genTangents)
 	: Shape(o2w, ro, name)
 {
+
 	shape_type = shpType;
 	proj_text = proj;
-	if ( shape_type == ShapeType(AR_SHAPE) )
+	cam = cam_;
+
+	if ( shape_type == ShapeType(AR_SHAPE) ) {
 		proj_text = true;
-	cam = cam_;
+		Scale = new float[nv];
+		for (u_int i  = 0; i < nv; ++i)
+			Scale[i] = -1.f;
+	}
+	else
+		Scale = NULL;
 
 	accelType = acceltype;
 
 	for (u_int i  = 0; i < nverts; ++i)
 		p[i] = ObjectToWorld(P[i]);
 
-	// Dade - copy UV and N vertex data, if present
+	// Aldo - copy WUV, if present
+	if (WUV) {
+		wuv = new Point[nverts];
+		for (u_int i  = 0; i < nverts; ++i)
+			wuv[i] = WUV[i];
+	} else
+		wuv = NULL;
+
 	if (UV) {
 		uvs = new float[2 * nverts];
 		memcpy(uvs, UV, 2 * nverts*sizeof(float));
 	} else
 		uvs = NULL;
 
+//	if (UV) {
+//		LOG(LUX_INFO, LUX_NOERROR) << "Criando worldtext";
+//		wuv = new Point[nverts];
+//		float phi;
+//		float theta, sinTheta;
+//		for (u_int i  = 0; i < nverts; ++i) {
+//			phi = UV[2*i] * 2.f * M_PI;
+//			theta = UV[2*i+1] * M_PI;
+//			sinTheta = sinf(theta);
+//			Vector wh = SphericalDirection(sinTheta, cosf(theta), phi);
+//			wuv[i] = Point(4*wh.x, 4*wh.y, 4*wh.z);
+//		}
+//		LOG(LUX_INFO, LUX_NOERROR) << "Worldtext criado";
+//	} else
+//		wuv = NULL;
+
+
+
 	if (N) {
 		n = new Normal[nverts];
 		// Dade - transform mesh normals to world space
 	vector<int> quadsToSplit;
 	if (nquads == 0)
 		quadVertexIndex = NULL;
-	else {
+	else { LOG(LUX_INFO, LUX_NOERROR) << "NQUaDS nao nulo: "<< nquads<< "Must subdivide?: "<< mustSubdivide;
 		// Dade - check quads and split them if required
 		for (u_int i = 0; i < nquads; i++) {
 			const u_int idx = 4 * i;
 	delete[] triVertexIndex;
 	delete[] quadVertexIndex;
 	delete[] p;
+	delete[] wuv;
+	delete[] Scale;
 	delete[] n;
 	delete[] uvs;
 	delete[] t;
 	const Point &p3 = p[v2];
 	const Vector e1 = p2 - p1;
 	const Vector e2 = p3 - p1;
-
+LOG(LUX_INFO, LUX_NOERROR) << "Mesh::GetIntersection ";
 	// Fill in _DifferentialGeometry_ from triangle hit
 	// Compute triangle partial derivatives
 	Vector dpdu, dpdv;
 
 void Mesh::GetShadingGeometry(const Transform &obj2world,
 	const DifferentialGeometry &dg, DifferentialGeometry *dgShading) const
-{
+{ LOG(LUX_INFO, LUX_NOERROR) << "Mesh::GetShadingGeometry";
+
 	if (!n) {
 		*dgShading = dg;
-		dgShading->Scale = GetScale();
+		dgShading->Scale = ( GetScale(0)+GetScale(1)+GetScale(2) )/3.f;
 		return;
 	}
 
 	const Normal nsi = dg.iData.mesh.coords[0] * n[v0] +
 		dg.iData.mesh.coords[1] * n[v1] + dg.iData.mesh.coords[2] * n[v2];
 	const Normal ns = Normalize(nsi);
+	const float lscale = dg.iData.mesh.coords[0] * Scale[v0] +
+		dg.iData.mesh.coords[1] * Scale[v1] + dg.iData.mesh.coords[2] * Scale[v2];
 
 	Vector ss, ts;
 	Vector tangent, bitangent;
 	}
 
 	*dgShading = DifferentialGeometry(dg.p, ns, ss, ts,
-		dndu, dndv, tangent, bitangent, sign, dg.u, dg.v, this, GetScale());
+		dndu, dndv, tangent, bitangent, sign, dg.u, dg.v, this, lscale, dg.wuv);
 }
 
 // Class for storing mesh data pointers and holding returned tangent space data
 						   const float* UV, u_int UVCount,
 						   const string& subdivSchemeStr, u_int nSubdivLevels,
 						   const Point* P, u_int npi,
-						   const Normal* N, u_int nni) {
+						   const Normal* N, u_int nni, const Point* WUV, u_int nWuv ) {
 
 	string name = params.FindOneString("name", "'mesh'");
 	// Lotus - read general data
 	if (!P)
 		return NULL;
 
+
+	if (WUV && (nWuv != npi)) {
+		SHAPE_LOG(name, LUX_ERROR,LUX_CONSISTENCY)<< "Number of \"WUV\"s for mesh must match \"P\"s";
+		WUV = NULL;
+	}
+
 	if (N && (nni != npi)) {
 		SHAPE_LOG(name, LUX_ERROR,LUX_CONSISTENCY)<< "Number of \"N\"s for mesh must match \"P\"s";
 		N = NULL;
 
 	bool  proj_text = params.FindOneBool( "projection", false );
 	Point  cam = params.FindOnePoint( "cam", Point(0,0,0) );
-
+LOG(LUX_INFO, LUX_NOERROR) << "Mesh Criando Shape 1";
 	return new Mesh(o2w, reverseOrientation, name,
 		shpType, proj_text, cam, accelType,
-		npi, P, N, UV,
+		npi, P, N, UV, WUV,
 		triType, triIndicesCount, triIndices,
 		quadType, quadIndicesCount, quadIndices,
 		subdivType, nSubdivLevels, displacementMap,
 	if (UV == NULL) {
 		UV = params.FindFloat("st", &UVCount);
 	}
+	u_int nWuv;
+	const Point *WUV = params.FindPoint("WUV", &nWuv);
 
 	// Triangles
 	u_int triIndicesCount;
 	accelTypeStr = params.FindOneString("acceltype", accelTypeStr);
  	string subdivscheme = params.FindOneString("subdivscheme", "loop");
 	int nSubdivLevels = max(0, params.FindOneInt("nsubdivlevels", params.FindOneInt("nlevels", 0)));
-
+LOG(LUX_INFO, LUX_NOERROR) << "Mesh Criando Shape 2";
 	return CreateShape(o2w, reverseOrientation, params,
 		accelTypeStr, triTypeStr, quadTypeStr,
 		triIndices, triIndicesCount,
 		UV, UVCount,
 		subdivscheme, nSubdivLevels,
 		P, npi,
-		N, nni);
+		N, nni, WUV, nWuv);
 }
 
 Shape *Mesh::CreateShape(const Transform &o2w, bool reverseOrientation, const ParamSet &params) {
+	LOG(LUX_INFO, LUX_NOERROR) << "Mesh create shape 0:";
 	return ::CreateShape( o2w, reverseOrientation, params, "auto", "auto");
 }
 
 static DynamicLoader::RegisterShape<Mesh> r("mesh");
 
 Shape* Mesh::BaryMesh::CreateShape(const Transform &o2w, bool reverseOrientation, const ParamSet &params) {
+	LOG(LUX_INFO, LUX_NOERROR) << "Mesh create shape 1:";
 	return ::CreateShape( o2w, reverseOrientation, params, "auto", "bary");
 }
 

File shapes/mesh.h

 
 	Mesh(const Transform &o2w, bool ro, const string &name,
 		ShapeType type, bool proj, Point cam_, MeshAccelType acceltype,
-		u_int nv, const Point *P, const Normal *N, const float *UV,
+		u_int nv, const Point *P, const Normal *N, const float *UV, const Point *WUV,
 		MeshTriangleType tritype, u_int trisCount, const int *tris,
 		MeshQuadType quadtype, u_int nquadsCount, const int *quads,
 		MeshSubdivType subdivType, u_int nsubdivlevels,
 
 	virtual BBox ObjectBound() const;
 	virtual BBox WorldBound() const;
-	virtual float GetScale() const { return 1.f; }
-	virtual bool SetScale(float scale) const { return true; }
+	virtual float GetScale(u_int i) const { return 1.f; }
+	virtual bool SetScale(float scale, u_int i) const { return false; }
 	virtual ShapeType GetPrimitiveType() const { return shape_type; }
+	virtual bool UseWorldMapping() const { return worldmap; }
 	virtual bool CanIntersect() const { return false; }
 	virtual void Refine(vector<boost::shared_ptr<Primitive> > &refined,
 		const PrimitiveRefinementHints &refineHints,
 	virtual void GetShadingGeometry(const Transform &obj2world,
 		const DifferentialGeometry &dg,
 		DifferentialGeometry *dgShading) const;
-	virtual bool GetNormal(Vector *N) const {
-		*N = Normalize( Cross( p[1]-p[0] , p[2] - p[0] ) ) ;
-		return true;
-	}
-	virtual bool GetBaryPoint(Point *P) const {
-		*P = 0.33333333f*(p[0]+p[1]+p[2]);
-		return true;
-	}
+	virtual Vector GetNormal(u_int i) const { return Vector(0.f); }
+	virtual Point GetPoint(u_int i) const { return Point(0.f); }
 
 	friend class MeshWaldTriangle;
 	friend class MeshBaryTriangle;
 	// Dade - vertices data
 	u_int nverts;
 	Point *p; // in world space if no subdivision is needed, object space otherwise
+	Point *wuv;
 	Normal *n; // in object space
 	float *uvs;
 	Vector *t;
 
 	// ARLuxrender support information
 	ShapeType shape_type;
-	bool proj_text;
+	bool proj_text, worldmap;
 	Point cam;
+	float *Scale;
 };
 
 //------------------------------------------------------------------------------
 	virtual const Volume *GetExterior() const { return mesh->GetExterior(); }
 	virtual const Volume *GetInterior() const { return mesh->GetInterior(); }
 	Material *GetMaterial() const { return mesh->material.get(); }
-	virtual float GetScale() const { return Scale; }
-	virtual bool SetScale(float scale) const { Scale = scale; return true; }
+	virtual float GetScale(u_int i) const { return mesh->Scale[v[i]]; }
+	virtual bool SetScale(float scale, u_int i) const { mesh->Scale[v[i]] = scale; return true; }
 	virtual ShapeType GetPrimitiveType() const { return mesh->shape_type; }
 	virtual bool CanIntersect() const { return true; }
 	virtual bool Intersect(const Ray &ray, Intersection *isect, bool null_shp_isect=false) const;
 		}
 	}
 	const Point &GetP(u_int i) const { return mesh->p[v[i]]; }
-	virtual bool GetNormal(Vector *N) const {
-		*N = Normalize( Cross( mesh->p[v[1]]-mesh->p[v[0]] , mesh->p[v[2]] - mesh->p[v[0]] ) ) ;
-		return true;
-	}
-	virtual bool GetBaryPoint(Point *P) const {
-		*P = 0.33333333f*(mesh->p[v[0]]+mesh->p[v[1]]+mesh->p[v[2]]);
-		return true;
-	}
+	virtual Vector GetNormal(u_int i) const { if (i < 3)  return Vector(mesh->n[v[i]]); return Vector(0.f); }
+	virtual Point GetPoint(u_int i) const { return mesh->p[v[i]]; }
 	// BaryTriangle Data
 	const Mesh *mesh;
 	const int *v;
 	bool is_Degenerate;
-	mutable float Scale;
+	//mutable float Scale;
 };
 
 class MeshWaldTriangle : public MeshBaryTriangle {
 	virtual const Volume *GetExterior() const { return mesh->GetExterior(); }
 	virtual const Volume *GetInterior() const { return mesh->GetInterior(); }
 	Material *GetMaterial() const { return mesh->material.get(); }
-	virtual float GetScale() const { return Scale; }
-	virtual bool SetScale(float scale) const { Scale = scale; return true; }
+	virtual float GetScale(u_int i) const { return mesh->Scale[v[i]]; }
+	virtual bool SetScale(float scale, u_int i) const { mesh->Scale[v[i]] = scale; return true; }
 	virtual ShapeType GetPrimitiveType() const { return mesh->shape_type; }
 	virtual bool CanIntersect() const { return true; }
 	virtual bool Intersect(const Ray &ray, Intersection *isect, bool null_shp_isect=false) const;
 	const Point &GetP(u_int i) const { return mesh->p[v[i]]; }
 	Point GetDisplacedP(const Point &pbase, const Vector &n, const float u, const float v, const float w) const;
 	Vector GetN(u_int i) const;
-	virtual bool GetNormal(Vector *N) const {
-		*N = Normalize( Cross( mesh->p[v[1]]-mesh->p[v[0]] , mesh->p[v[2]] - mesh->p[v[0]] ) ) ;
-		return true;
-	}
-	virtual bool GetBaryPoint(Point *P) const {
-		*P = 0.33333333f*(mesh->p[v[0]]+mesh->p[v[1]]+mesh->p[v[2]]);
-		return true;
-	}
+	virtual Vector GetNormal(u_int i) const { if(i < 3) return Vector(mesh->n[v[i]]) ; return Vector(0.f); }
+	virtual Point GetPoint(u_int i) const { return	mesh->p[v[i]];	}
 	// BaryTriangle Data
 	const Mesh *mesh;
 	const int *v;
 	Vector dpdu, dpdv, normalizedNormal;
 	float uvs[3][2];
 	bool is_Degenerate;
-	mutable float Scale;
+	//mutable float Scale;
 };
 
 //------------------------------------------------------------------------------
 	virtual BBox ObjectBound() const;
 	virtual BBox WorldBound() const;
 	Material *GetMaterial() const { return mesh->material.get(); }
-	virtual float GetScale() const { return Scale; }
-	virtual bool SetScale(float scale) const { Scale = scale; return true; }
+	virtual float GetScale(u_int i) const { return mesh->Scale[idx[i]]; }
+	virtual bool SetScale(float scale, u_int i) const { mesh->Scale[idx[i]] = scale; return true; }
 	virtual ShapeType GetPrimitiveType() const { return mesh->shape_type; }
 	virtual bool CanIntersect() const { return true; }
 	virtual bool Intersect(const Ray &ray, Intersection *isect, bool null_shp_isect=false) const;
 	static bool IsPlanar(const Point &p0, const Point &p1, const Point &p2, const Point &p3);
 	static bool IsDegenerate(const Point &p0, const Point &p1, const Point &p2, const Point &p3);
 	static bool IsConvex(const Point &p0, const Point &p1, const Point &p2, const Point &p3);
-	virtual bool GetNormal(Vector *N) const {
-		*N = Normalize( Cross( mesh->p[1]-mesh->p[0] , mesh->p[2] - mesh->p[0] ) ) ;
-		return true;
-	}
-	virtual bool GetBaryPoint(Point *P) const {
-		*P = 0.33333333f*(mesh->p[0]+mesh->p[1]+mesh->p[2]);
-		return true;
-	}
+	virtual Vector GetNormal(u_int i) const { return Vector(mesh->n[idx[i]]); }
+	virtual Point GetPoint(u_int i) const { return mesh->p[idx[i]]; }
 private:
 	static u_int MajorAxis(const Vector &v);
 
 	// Quadrilateral Private Data
 	const Mesh *mesh;
 	const int *idx;
-	mutable float Scale;
+	//mutable float Scale;
 };
 
 }//namespace lux

File shapes/meshbarytriangle.cpp

 }
 
 bool MeshBaryTriangle::Intersect(const Ray &ray, Intersection* isect, bool null_shp_isect) const
-{
+{//LOG(LUX_INFO, LUX_NOERROR) << "Mesh Barytriangle intersect ";
 	Vector e1, e2, s1;
 	// Compute $\VEC{s}_1$
 
 	//look if shape is a null type
-    if ( null_shp_isect && GetPrimitiveType() == ShapeType(AR_SHAPE) ) return false;
+	if ( null_shp_isect && GetPrimitiveType() == ShapeType(AR_SHAPE) ) return false;
 
 	// Get triangle vertices in _p1_, _p2_, and _p3_
 	const Point &p1 = mesh->p[v[0]];
 	const float tu = tu_;
 	const float tv = tv_;
 
+	Point wtext = pp;
+	if (mesh->wuv) {
+		wtext = Point (mesh->wuv[v[0]] + b1 * (mesh->wuv[v[1]] - mesh->wuv[v[0]]) + b2 * (mesh->wuv[v[2]] - mesh->wuv[v[0]]));
+	}
 	isect->dg = DifferentialGeometry(pp, nn, dpdu, dpdv,
-		Normal(0, 0, 0), Normal(0, 0, 0), tu, tv, this);
+		Normal(0, 0, 0), Normal(0, 0, 0), tu, tv, this, 0.f, wtext );
 
 	isect->Set(mesh->WorldToObject, this, mesh->GetMaterial(),
 		mesh->GetExterior(), mesh->GetInterior());
 {
 	if (!mesh->n) {
 		*dgShading = dg;
-		dgShading->Scale = GetScale();
+	if ( mesh->shape_type == ShapeType(AR_SHAPE) )
+	    dgShading->Scale =  ( GetScale(0)+GetScale(1)+GetScale(2) )/3.f ;
 		return;
 	}
 
 		dg.iData.baryTriangle.coords[1] * mesh->n[v[1]] + dg.iData.baryTriangle.coords[2] * mesh->n[v[2]];
 	const Normal ns = Normalize(nsi);
 
+    float lscale = 1.f;
+    if ( mesh->shape_type == ShapeType(AR_SHAPE) )
+	  lscale = dg.iData.baryTriangle.coords[0] * mesh->Scale[v[0]] +
+	    dg.iData.baryTriangle.coords[1] * mesh->Scale[v[1]] + dg.iData.baryTriangle.coords[2] * mesh->Scale[v[2]];
+
 	Vector ss, ts;
 	Vector tangent, bitangent;
 	float btsign;
 	}
 
 	*dgShading = DifferentialGeometry(dg.p, ns, ss, ts,
-		dndu, dndv, tangent, bitangent, btsign, dg.u, dg.v, this, GetScale());
+		dndu, dndv, tangent, bitangent, btsign, dg.u, dg.v, this, lscale, dg.wuv);
 }

File shapes/meshmicrodisplacementtriangle.cpp

 
 bool MeshMicroDisplacementTriangle::Intersect(const Ray &ray, Intersection* isect, bool null_shp_isect) const
 {
+	//LOG(LUX_INFO, LUX_NOERROR) << "Mesh MeshMicroDisplacementTriangle: ";
 	// Compute $\VEC{s}_1$
 	// Get triangle vertices in _p1_, _p2_, and _p3_
 	const Point &p1 = mesh->p[v[0]];
 {
 	if (!mesh->displacementMapNormalSmooth || !mesh->n) {
 		*dgShading = dg;
-		dgShading->Scale = GetScale();
+		if ( mesh->shape_type == ShapeType(AR_SHAPE) )
+			dgShading->Scale = ( GetScale(0)+GetScale(1)+GetScale(2 ) ) / 3.f;
 		return;
 	}
 
 	const Normal ns = Normalize(dg.iData.baryTriangle.coords[0] * mesh->n[v[0]] +
 		dg.iData.baryTriangle.coords[1] * mesh->n[v[1]] + dg.iData.baryTriangle.coords[2] * mesh->n[v[2]]);
 
+	float lscale = 1.f;
+	if ( mesh->shape_type == ShapeType(AR_SHAPE) )
+		lscale = dg.iData.baryTriangle.coords[0] * mesh->Scale[v[0]] +
+				dg.iData.baryTriangle.coords[1] * mesh->Scale[v[1]] + dg.iData.baryTriangle.coords[2] * mesh->Scale[v[2]];
+
 	Vector ts(Normalize(Cross(ns, dpdu)));
 	Vector ss(Cross(ts, ns));
 	// Lotus - the length of dpdu/dpdv can be important for bumpmapping
 	}
 
 	*dgShading = DifferentialGeometry(p, ns, ss, ts,
-		dndu, dndv, dg.u, dg.v, this, GetScale());
+		dndu, dndv, dg.u, dg.v, this, lscale, dg.wuv);
 	float dddu, dddv;
 	SpectrumWavelengths sw;
 	mesh->displacementMap->GetDuv(sw, *dgShading, 0.001f, &dddu, &dddv);

File shapes/meshquadrilateral.cpp

 	// by Ares Lagae and Philip Dutr�
 	// http://www.cs.kuleuven.be/~graphics/CGRG.PUBLICATIONS/LagaeDutre2005AnEfficientRayQuadrilateralIntersectionTest/
 	// http://jgt.akpeters.com/papers/LagaeDutre05/erqit.cpp.html
-
+//LOG(LUX_INFO, LUX_NOERROR) << "Mesh Quadrilateral intersect ";
 	if (!idx)
 		return false;
 
 	//look if shape is a null type
-    if ( null_shp_isect && GetPrimitiveType() == ShapeType(AR_SHAPE) ) return false;
+	if ( null_shp_isect && GetPrimitiveType() == ShapeType(AR_SHAPE) ) return false;
 
 	// Get quadrilateral vertices in _p00_, _p10_, _p11_ and _p01_
 	const Point &p00 = mesh->p[idx[0]];
 	Normal nn(Normal(Normalize(N)));
 
 	if (isect) {
+		Point wtext = ray(t);
+		//if (mesh->wuv) {
+		//	wtext = Point (mesh->wuv[v[0]] + b1 * (mesh->wuv[v[1]] - mesh->wuv[v[0]]) + b2 * (mesh->wuv[v[2]] - mesh->wuv[v[0]]));
+		//}
+	//LOG(LUX_INFO, LUX_NOERROR) << "Mesh Quadrilateral: "<< wtext;
 		isect->dg = DifferentialGeometry(ray(t),
 			nn,
 			dpdu, dpdv,
 			Normal(0, 0, 0), Normal(0, 0, 0),
-			u, v, this);
+			u, v, this, 0.f, wtext);
 		isect->dg.AdjustNormal(mesh->reverseOrientation, mesh->transformSwapsHandedness);
 		isect->Set(mesh->WorldToObject, this, mesh->GetMaterial(),
 			mesh->GetExterior(), mesh->GetInterior());
 {
 	if (!mesh->n) {
 		*dgShading = dg;
-		dgShading->Scale = GetScale();
+		if ( mesh->shape_type == ShapeType(AR_SHAPE) )
+			dgShading->Scale = ( mesh->Scale[idx[0]]+mesh->Scale[idx[1]]+mesh->Scale[idx[2]]+mesh->Scale[idx[3]] ) / 4.f;
 		if (!mesh->uvs) {
 			// Lotus - the length of dpdu/dpdv can be important for bumpmapping
 			const BBox bounds = MeshQuadrilateral::WorldBound();
 		(dg.u * (1.0f - dg.v)) * mesh->n[idx[1]] +
 		(dg.u * dg.v) * mesh->n[idx[2]] +
 		((1.0f - dg.u) * dg.v) * mesh->n[idx[3]])));
+
+	float lscale = 1.f;
+	if ( mesh->shape_type == ShapeType(AR_SHAPE) )
+		lscale =  ((1.0f - dg.u) * (1.0f - dg.v)) * mesh->Scale[idx[0]] +
+					 (dg.u * (1.0f - dg.v)) * mesh->Scale[idx[1]] +
+					 (dg.u * dg.v) * mesh->Scale[idx[2]] +
+					 ((1.0f - dg.u) * dg.v) * mesh->Scale[idx[3]];
+
 	float lenDpDu = dg.dpdu.Length();
 	float lenDpDv = dg.dpdv.Length();
 	Vector ts = Normalize(Cross(dg.dpdu, ns));
 	}
 
 	*dgShading = DifferentialGeometry(dg.p, ns, ss, ts, dndu, dndv,
-		dg.u, dg.v, this, GetScale());
+		dg.u, dg.v, this, lscale, dg.wuv);
 }

File shapes/meshwaldtriangle.cpp

 }
 
 bool MeshWaldTriangle::Intersect(const Ray &ray, Intersection *isect, bool null_shp_isect) const
-{
+{//LOG(LUX_INFO, LUX_NOERROR) << "Mesh Waldtriangle intersect ";
 	//look if shape is a null type
     if ( null_shp_isect && GetPrimitiveType() == ShapeType(AR_SHAPE) ) return false;
 
 	const float tu = tu_;
 	const float tv = tv_;
 
+	Point wtext = pp;
+	if (mesh->wuv) {
+		wtext = Point(b0 * mesh->wuv[v[0]] + uu * mesh->wuv[v[1]] + vv * mesh->wuv[v[2]]);
+	}
+//LOG(LUX_INFO, LUX_NOERROR) << "Mesh Wald: "<< wtext;
 	isect->dg = DifferentialGeometry(pp, normalizedNormal, dpdu, dpdv,
-		Normal(0, 0, 0), Normal(0, 0, 0), tu, tv, this);
+		Normal(0, 0, 0), Normal(0, 0, 0), tu, tv, this, 0.f, wtext);
 	isect->Set(mesh->WorldToObject, this, mesh->GetMaterial(),
 		mesh->GetExterior(), mesh->GetInterior());
 	isect->dg.iData.baryTriangle.coords[0] = b0;

File shapes/plymesh.cpp

 	return 1;
 }
 
+static int WorldTextureCB(p_ply_argument argument)
+{
+	long userIndex = 0;
+	void *userData = NULL;
+	ply_get_argument_user_data(argument, &userData, &userIndex);
+
+	Point* wuv = *static_cast<Point **>(userData);
+
+	long vertIndex;
+	ply_get_argument_element(argument, NULL, &vertIndex);
+
+	if (userIndex == 0)
+		wuv[vertIndex].x =
+			static_cast<float>(ply_get_argument_value(argument));
+	else if (userIndex == 1)
+		wuv[vertIndex].y =
+			static_cast<float>(ply_get_argument_value(argument));
+	else if (userIndex == 2)
+		wuv[vertIndex].z =
+			static_cast<float>(ply_get_argument_value(argument));
+/*	else
+		return 0;*/
+
+	return 1;
+}
+
+
 // rply st/uv callback
 static int TexCoordCB(p_ply_argument argument)
 {
 		return NULL;
 	}
 
+	Point *wuv;
+	long plyWVerts = ply_set_read_cb(plyfile, "vertex", "px",
+		WorldTextureCB, &wuv, 0);
+	ply_set_read_cb(plyfile, "vertex", "py", WorldTextureCB, &wuv, 1);
+	ply_set_read_cb(plyfile, "vertex", "pz", WorldTextureCB, &wuv, 2);
+
+
 	FaceData faceData;
 	long plyNbFaces = ply_set_read_cb(plyfile, "face", "vertex_indices",
 		FaceCB, &faceData, 0);
 	}
 
 	p = new Point[plyNbVerts];
+	if (plyWVerts <= 0)
+		wuv = NULL;
+	else
+		wuv = new Point[plyWVerts];
+
 	if (plyNbNormals <= 0)
 		n = NULL;
 	else
 	else
 		uv = new float[2*plyNbUVs];
 
+
 	if (!ply_read(plyfile)) {
 		SHAPE_LOG(name, LUX_ERROR,LUX_SYSTEM) << "Unable to parse PLY file '" << filename << "'";
 		delete[] p;
+		delete[] wuv;
 		delete[] n;
 		delete[] uv;
 		return NULL;
 		}
 	}
 
+	if (plyNbVerts != plyWVerts) {
+		if (wuv) {
+			SHAPE_LOG(name, LUX_ERROR,LUX_CONSISTENCY)<< "Incorrect number of world texture coordinates";
+			delete[] wuv;
+			wuv = NULL;
+		}
+	}
+
 	const int *triVerts = plyNbTris > 0 ? &faceData.triVerts[0] : NULL;
 	const int *quadVerts = plyNbQuads > 0 ? &faceData.quadVerts[0] : NULL;
 
 
 	boost::shared_ptr<Texture<float> > dummytex;
 	Mesh *mesh = new Mesh(o2w, reverseOrientation, name, shpType, proj_text, cam, Mesh::ACCEL_AUTO,
-			      plyNbVerts, p, n, uv, Mesh::TRI_AUTO, plyNbTris, triVerts,
+			      plyNbVerts, p, n, uv, wuv, Mesh::TRI_AUTO, plyNbTris, triVerts,
 			      Mesh::QUAD_QUADRILATERAL, plyNbQuads, quadVerts, subdivType,
 			      nsubdivlevels, displacementMap, displacementMapScale,
 			      displacementMapOffset, displacementMapNormalSmooth,
 	delete[] p;
 	delete[] n;
 	delete[] uv;
+	delete[] wuv;
 	return mesh;
 }
 

File shapes/stlmesh.cpp

 	boost::shared_ptr<Texture<float> > displacementMap;
 
 	return new Mesh(o2w, reverseOrientation, name, shpType,  proj_text, cam, Mesh::ACCEL_AUTO,
-					Vertices.size(), &Vertices[0], NULL, NULL,
+					Vertices.size(), &Vertices[0], NULL, NULL, NULL,
 					Mesh::TRI_AUTO, uNFaces, &Faces[0],
 					Mesh::QUAD_QUADRILATERAL, 0, NULL,
 					subdivType, nsubdivlevels, displacementMap, 0.1f, 0.0f, true, false,