diff -Naur povray-3.6.1/source/lighting.cpp povray-3.6.1_Bueno/source/lighting.cpp
--- povray-3.6.1/source/lighting.cpp	2004-08-03 01:11:36.000000000 +0200
+++ povray-3.6.1_Bueno/source/lighting.cpp	2009-05-13 20:19:38.000000000 +0200
@@ -232,7 +232,7 @@
 
 static void do_texture_map (COLOUR Result_Colour,
   TEXTURE *Texture, VECTOR IPoint, VECTOR Raw_Normal, RAY *Ray, DBL Weight,
-  INTERSECTION *Ray_Intersection, int Shadow_Flag);
+  INTERSECTION *Ray_Intersection, int Shadow_Flag, bool uvtex);
 
 static void average_textures (COLOUR Result_Colour,
   TEXTURE *Texture, VECTOR IPoint, VECTOR Raw_Normal, RAY *Ray, DBL Weight,
@@ -240,7 +240,7 @@
 
 static void compute_lighted_texture (COLOUR Result_Colour,
   TEXTURE *Texture, VECTOR IPoint, VECTOR Raw_Normal, RAY *Ray, DBL Weight,
-  INTERSECTION *Ray_Intersection);
+  INTERSECTION *Ray_Intersection, bool uvtex);
 
 static void compute_shadow_texture (COLOUR Filter_Colour,
   TEXTURE *Texture, VECTOR IPoint, VECTOR Raw_Normal, RAY *Ray,
@@ -585,7 +585,40 @@
   Texture_List=TextureListPool[LightingPoolIndex];
 
   /* Get texture list and weights. */
-  Texture_Count = create_texture_list (Ray_Intersection, Normal_Direction);
+    // hack: get normal of triangle to determine which texture to use!
+  if (Ray_Intersection->Object->Type == 515) {
+	MESH_TRIANGLE* Triangle = (MESH_TRIANGLE *)Ray_Intersection->Pointer;
+	MESH *Mesh = (MESH *)Ray_Intersection->Object;
+
+	VECTOR p1,p2,p3,a,b,flatNormal,n1,n2,n3;
+
+    Assign_Vector(p1, Mesh->Data->Vertices[Triangle->P1]);
+    Assign_Vector(p2, Mesh->Data->Vertices[Triangle->P2]);
+    Assign_Vector(p3, Mesh->Data->Vertices[Triangle->P3]);
+    Assign_Vector(n1, Mesh->Data->Normals[Triangle->P1]);
+    Assign_Vector(n2, Mesh->Data->Normals[Triangle->P2]);
+    Assign_Vector(n3, Mesh->Data->Normals[Triangle->P3]);
+
+	VSub(a, p2, p1);
+	VSub(b, p3, p1);
+	VCross(flatNormal, a, b);
+	VNormalize(flatNormal, flatNormal);
+
+	DBL flatNormalDir, val1, val2, val3;
+
+	//if (Triangle->UV1 != 0 || Triangle->UV2 != 1 || Triangle->UV3 != 2)
+	if ((Triangle->UV1 == 0 && Triangle->UV2 == 2 && Triangle->UV3 == 1)
+		|| (Triangle->UV1 == 1 && Triangle->UV2 == 0 && Triangle->UV3 == 2)
+		|| (Triangle->UV1 == 2 && Triangle->UV2 == 1 && Triangle->UV3 == 0))
+		VScaleEq(flatNormal, -1.0);
+
+	VDot(flatNormalDir, flatNormal, Ray->Direction);
+
+	Texture_Count = create_texture_list (Ray_Intersection, flatNormalDir);
+  }
+  else {
+	Texture_Count = create_texture_list (Ray_Intersection, Normal_Direction);
+  }
 
   /*
    * Now, we perform the lighting calculations by stepping through
@@ -614,11 +647,11 @@
       C1[0] = Colour[0]*Weight_List[i];
       C1[1] = Colour[1]*Weight_List[i];
       C1[2] = Colour[2]*Weight_List[i];
-      do_texture_map(C1, Texture, IPoint, Raw_Normal, Ray, Weight, Ray_Intersection, false);
+      do_texture_map(C1, Texture, IPoint, Raw_Normal, Ray, Weight, Ray_Intersection, false, false);
     }
     else
     {
-      do_texture_map(C1, Texture, IPoint, Raw_Normal, Ray, Weight, Ray_Intersection, false);
+      do_texture_map(C1, Texture, IPoint, Raw_Normal, Ray, Weight, Ray_Intersection, false, false);
 
       Colour[pRED]   += Weight_List[i] * C1[pRED];
       Colour[pGREEN] += Weight_List[i] * C1[pGREEN];
@@ -3532,7 +3565,7 @@
 ******************************************************************************/
 
 static void do_texture_map(COLOUR Result_Colour, TEXTURE *Texture, VECTOR IPoint, VECTOR  Raw_Normal,
-  RAY *Ray, DBL Weight, INTERSECTION *Ray_Intersection, int Shadow_Flag)
+  RAY *Ray, DBL Weight, INTERSECTION *Ray_Intersection, int Shadow_Flag, bool uvtex)
 {
   BLEND_MAP *Blend_Map = Texture->Blend_Map;
   BLEND_MAP_ENTRY *Prev, *Cur;
@@ -3590,12 +3623,12 @@
         TPoint[Y] = UV_Coords[V];
         TPoint[Z] = 0;
         Cur = &(Texture->Blend_Map->Blend_Map_Entries[0]);
-        do_texture_map(Result_Colour, Cur->Vals.Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag);
+        do_texture_map(Result_Colour, Cur->Vals.Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag, true);
         break;
       case BITMAP_PATTERN:
         Warp_EPoint (TPoint, IPoint, (TPATTERN *)Texture);
         Texture = material_map(TPoint, Texture);
-        do_texture_map(Result_Colour, Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag);
+        do_texture_map(Result_Colour, Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag, false);
         break;
       case PLAIN_PATTERN:
         if(backtraceFlag)
@@ -3603,7 +3636,7 @@
         else if(Shadow_Flag)
           compute_shadow_texture(Result_Colour, Texture, IPoint, Raw_Normal, Ray, Ray_Intersection);
         else
-          compute_lighted_texture(Result_Colour, Texture, IPoint, Raw_Normal, Ray, Weight, Ray_Intersection);
+          compute_lighted_texture(Result_Colour, Texture, IPoint, Raw_Normal, Ray, Weight, Ray_Intersection, uvtex);
         break;
       default:
         Error("Bad texture type in do_texture_map()");
@@ -3623,24 +3656,24 @@
     if(backtraceFlag)
     {
       if(Prev == Cur)
-        do_texture_map(Result_Colour, Cur->Vals.Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag);
+        do_texture_map(Result_Colour, Cur->Vals.Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag, false);
       else
       {
         value1 = (value1 - Prev->value) / (Cur->value - Prev->value);
         value2 = 1.0 - value1;
         VScale(C2, Result_Colour, value1);
-        do_texture_map(C2, Cur->Vals.Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag);
+        do_texture_map(C2, Cur->Vals.Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag, false);
         VScale(C2, Result_Colour, value2);
-        do_texture_map(C2, Prev->Vals.Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag);
+        do_texture_map(C2, Prev->Vals.Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag, false);
       }
     }
     else
     {
-      do_texture_map(Result_Colour, Cur->Vals.Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag);
+      do_texture_map(Result_Colour, Cur->Vals.Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag, false);
 
       if(Prev != Cur)
       {
-        do_texture_map(C2, Prev->Vals.Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag);
+        do_texture_map(C2, Prev->Vals.Texture, TPoint, Raw_Normal, Ray, Weight, Ray_Intersection, Shadow_Flag, false);
         value1 = (value1 - Prev->value) / (Cur->value - Prev->value);
         value2 = 1.0 - value1;
         CLinComb2(Result_Colour,value1,Result_Colour,value2,C2);
@@ -3700,7 +3733,7 @@
 *
 ******************************************************************************/
 
-static void compute_lighted_texture(COLOUR ResCol, TEXTURE *Texture, VECTOR IPoint, VECTOR  Raw_Normal, RAY *Ray, DBL Weight, INTERSECTION *Intersect)
+static void compute_lighted_texture(COLOUR ResCol, TEXTURE *Texture, VECTOR IPoint, VECTOR  Raw_Normal, RAY *Ray, DBL Weight, INTERSECTION *Intersect, bool uvtex)
 {
   int i, radiosity_done, radiosity_needed;
   int layer_number;
@@ -3819,7 +3852,14 @@
 
     New_Weight = Weight * Trans;
 
-    colour_found = Compute_Pigment (LayCol, Layer->Pigment, IPoint, Intersect);
+    if (uvtex)
+		colour_found = Compute_Pigment (LayCol, Layer->Pigment, IPoint, Intersect);
+    else
+		colour_found = Compute_Pigment (LayCol, Layer->Pigment, Intersect->IPoint, Intersect);
+
+	//if (fabs(IPoint[0]-Intersect->EPoint[0]) > 0.00001f || fabs(IPoint[1]-Intersect->EPoint[1]) > 0.00001f || fabs(IPoint[2]-Intersect->EPoint[2]) > 0.00001f)
+	//	int kkk=0;
+  
 
     /*
      * If a valid color was returned set one_colour_found to true.
@@ -5229,7 +5269,7 @@
 
     Texture = Texture_List[i];
 
-    do_texture_map(FC1, Texture, IPoint, Raw_Normal, Light_Source_Ray, 0.0, Ray_Intersection, true);
+    do_texture_map(FC1, Texture, IPoint, Raw_Normal, Light_Source_Ray, 0.0, Ray_Intersection, true, false);
 
     Temp_Colour[pRED]     += Weight_List[i] * FC1[pRED];
     Temp_Colour[pGREEN]   += Weight_List[i] * FC1[pGREEN];
@@ -5445,7 +5485,7 @@
    {
      Value = Map->Blend_Map_Entries[i].value;
 
-     do_texture_map (LC,Map->Blend_Map_Entries[i].Vals.Texture, IPoint,Raw_Normal,Ray,Weight,Ray_Intersection,Shadow_Flag);
+     do_texture_map (LC,Map->Blend_Map_Entries[i].Vals.Texture, IPoint,Raw_Normal,Ray,Weight,Ray_Intersection,Shadow_Flag, false);
 
      Result_Colour[pRED]   += LC[pRED]   *Value;
      Result_Colour[pGREEN] += LC[pGREEN] *Value;
@@ -5511,7 +5551,7 @@
      Value = Map->Blend_Map_Entries[i].value / Total;
      VScale(LC, Result_Colour, Value);
 
-     do_texture_map (LC,Map->Blend_Map_Entries[i].Vals.Texture, IPoint,Raw_Normal,Ray,Weight,Ray_Intersection,Shadow_Flag);
+     do_texture_map (LC,Map->Blend_Map_Entries[i].Vals.Texture, IPoint,Raw_Normal,Ray,Weight,Ray_Intersection,Shadow_Flag, false);
    }
 }
 
diff -Naur povray-3.6.1/source/mesh.cpp povray-3.6.1_Bueno/source/mesh.cpp
--- povray-3.6.1/source/mesh.cpp	2004-08-03 01:11:36.000000000 +0200
+++ povray-3.6.1_Bueno/source/mesh.cpp	2009-05-13 20:02:29.000000000 +0200
@@ -132,6 +132,7 @@
 /* NK ---- */
 
 static void get_triangle_vertices (MESH *Mesh, MESH_TRIANGLE *Triangle, VECTOR P1, VECTOR P2, VECTOR P3);
+static void get_triangle_texcoords3D (MESH *Mesh, MESH_TRIANGLE *Triangle, VECTOR X, VECTOR Y, VECTOR Z);
 static void get_triangle_normals (MESH *Mesh, MESH_TRIANGLE *Triangle, VECTOR N1, VECTOR N2, VECTOR N3);
 static void get_triangle_uvcoords (MESH *Mesh, MESH_TRIANGLE *Triangle, UV_VECT U1, UV_VECT U2, UV_VECT U3);
 
@@ -167,15 +168,15 @@
 *   All_Mesh_Intersections
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -209,15 +210,15 @@
 *   Intersect_Mesh
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -288,15 +289,15 @@
 *   Inside_Mesh
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Nathan Kopp & Dieter Bayer (adapted from Intersect_Mesh by Dieter Bayer)
-*   
+*
 * DESCRIPTION
 *
 *   Shoot a ray out from this point, if the ray hits an odd number of
@@ -394,15 +395,15 @@
 *   Mesh_Normal
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   Return the normalized normal in the given point.
@@ -421,7 +422,7 @@
 
   Triangle = (MESH_TRIANGLE *)Inter->Pointer;
 
-  if (Triangle->Smooth)
+  //if (Triangle->Smooth)
   {
     if (Mesh->Trans != NULL)
     {
@@ -433,7 +434,7 @@
     }
 
     smooth_mesh_normal(Mesh, Result, Triangle, IPoint);
-  
+
     if (Mesh->Trans != NULL)
     {
       MTransNormal(Result, Result, Mesh->Trans);
@@ -441,17 +442,17 @@
 
     VNormalize(Result, Result);
   }
-  else
-  {
-    Assign_Vector(Result, Mesh->Data->Normals[Triangle->Normal_Ind]);
-
-    if (Mesh->Trans != NULL)
-    {
-      MTransNormal(Result, Result, Mesh->Trans);
-
-      VNormalize(Result, Result);
-    }
-  }
+  //else
+  //{
+  //  Assign_Vector(Result, Mesh->Data->Normals[Triangle->Normal_Ind]);
+
+  //  if (Mesh->Trans != NULL)
+  //  {
+  //    MTransNormal(Result, Result, Mesh->Trans);
+
+  //    VNormalize(Result, Result);
+  //  }
+  //}
 }
 
 
@@ -463,15 +464,15 @@
 *   smooth_mesh_normal
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   Remove the un-normalized normal of a smoothed triangle.
@@ -524,15 +525,15 @@
 *   Translate_Mesh
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -557,15 +558,15 @@
 *   Rotate_Mesh
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -590,15 +591,15 @@
 *   Scale_Mesh
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -623,15 +624,15 @@
 *   Transfrom_Mesh
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -672,15 +673,15 @@
 *   Invert_Mesh
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -705,15 +706,15 @@
 *   Create_Mesh
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -755,15 +756,15 @@
 *   Copy_Mesh
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   Copy a mesh.
@@ -789,9 +790,9 @@
   /* Copy mesh. */
 
   *New = *((MESH *)Object);
-  
+
   New->Trans = Copy_Transform(New->Trans);
-  
+
   New->Data->References++;
 
   /* NK 1999 copy textures */
@@ -816,15 +817,15 @@
 *   Destroy_Mesh
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -896,17 +897,17 @@
 * INPUT
 *
 *   Mesh - Mesh
-*   
+*
 * OUTPUT
 *
 *   Mesh
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   Calculate the bounding box of a triangle.
@@ -951,15 +952,15 @@
 *   Compute_Mesh
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -1045,7 +1046,15 @@
     Triangle->P2 = Triangle->P1;
     Triangle->P1 = temp;
 
-    /* NK 1998 */
+ 		//temp = Triangle->Tex3D_2;
+		//Triangle->Tex3D_2 = Triangle->Tex3D_1;
+		//Triangle->Tex3D_1 = temp;
+ 		temp = Triangle->Texture3;
+		Triangle->Texture2 = Triangle->Texture;
+		Triangle->Texture = temp;
+
+
+		/* NK 1998 */
     temp = Triangle->UV2;
     Triangle->UV2 = Triangle->UV1;
     Triangle->UV1 = temp;
@@ -1089,15 +1098,15 @@
 *   compute_smooth_triangle
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -1149,15 +1158,15 @@
 *   intersect_mesh_triangle
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -1281,23 +1290,23 @@
 	DBL a, b, r;
 	VECTOR Q, B[3], IB[3], P1, P2, P3;
 	UV_VECT UV1, UV2, UV3;
-	
+
 	get_triangle_vertices(Mesh, Triangle, P1, P2, P3);
 	VSub(B[0], P2, P1);
 		VSub(B[1], P3, P1);
 		Assign_Vector(B[2], Mesh->Data->Normals[Triangle->Normal_Ind]);
-	
+
 	if (!MInvers3(B, IB)) {
 		// Failed to invert - that means this is a degenerate triangle
 		Result[U] = P[X];
 		Result[V] = P[Y];
 		return;
 	}
-	
+
 	VSub(Q, P, P1);
 	VDot(a, Q, IB[0]);
 	VDot(b, Q, IB[1]);
-	
+
 	if (a < BARY_VAL1 || b < BARY_VAL1 || a + b > BARY_VAL2)
 	{
 		// The use of BARY_VAL1 is an attempt to compensate for the
@@ -1309,14 +1318,14 @@
 		Result[V] = P[Y];
 		return;
 	}
-	
+
 	r = 1.0f - a - b;
-	
+
 	get_triangle_uvcoords(Mesh, Triangle, UV1, UV2, UV3);
 	VScale(Q, UV1, r);
 	VAddScaledEq(Q, a, UV2);
 	VAddScaledEq(Q, b, UV3);
-	
+
 	Result[U] = Q[U];
 	Result[V] = Q[V];
 }
@@ -1329,15 +1338,15 @@
 *   test_hit
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   Test if a hit is valid and push if on the intersection depth.
@@ -1348,14 +1357,15 @@
 *
 ******************************************************************************/
 
-static int test_hit(MESH_TRIANGLE *Triangle, MESH *Mesh, RAY *OrigRay, RAY * /*Ray*/, DBL Depth, DBL len, ISTACK *Depth_Stack)
+static int test_hit(MESH_TRIANGLE *Triangle, MESH *Mesh, RAY *OrigRay, RAY *MeshSpaceRay, DBL Depth, DBL len, ISTACK *Depth_Stack)
 {
   VECTOR IPoint;
   OBJECT *Object = (OBJECT *)Mesh;
   DBL world_dist = Depth / len;
-	
+
   VEvaluateRay(IPoint, OrigRay->Initial, world_dist, OrigRay->Direction);
-	
+  // compute intersection point in undeformed state
+
   if (Point_In_Clip(IPoint, Object->Clip))
   {
     /*
@@ -1363,14 +1373,91 @@
     UV_VECT uv;
     VECTOR P; // Object coordinates of intersection
     VEvaluateRay(P, Ray->Initial, Depth, Ray->Direction);
-    
-    MeshUV(P, Triangle, Mesh, uv);  
+
+    MeshUV(P, Triangle, Mesh, uv);
 
     push_entry_pointer_uv(world_dist, IPoint, uv, Object, Triangle, Depth_Stack);
     */
-    
-		push_entry_pointer(world_dist, IPoint, Object, Triangle, Depth_Stack);
-    return(true);
+		//push_entry_pointer(world_dist, IPoint, Object, Triangle, Depth_Stack);
+
+
+	  //compute tex3D coordinates for the intersection point
+
+	  VECTOR IPointMeshSpace;
+	  //VEvaluateRay(IPointMeshSpace, MeshSpaceRay->Initial, Depth, MeshSpaceRay->Direction);
+		// transform intersection point into mesh space
+		MInvTransPoint(IPointMeshSpace, IPoint, Mesh->Trans);
+
+	  VECTOR P1, P2, P3;
+	  get_triangle_vertices(Mesh, Triangle, P1, P2, P3);
+
+
+	  DBL EPS = 0.000000000001;
+	  VECTOR u,v,w,n,area;
+	  DBL det,c,b1,b2,b3,c1;
+
+		VSub(u,P2,P1);
+	  VSub(v,P3,P1);
+
+	  VCross(n,u,v);
+	  VLength(det,n);
+	  if (det < EPS) {
+			b1 = 1.0;
+			b2 = 0.0;
+			b3 = 0.0;
+		}
+		else {
+			VSub(w,IPointMeshSpace,P1);
+			VCross(area,w,v);
+			VDot(c1,area,n);
+			if (c1 < 0)
+				c = -1.0;
+			else
+				c = 1.0;		// must check if area is 'negative'
+
+			VLength(b2,area);
+			b2 = b2 / det * c;
+
+			VCross(area,u,w);
+			VDot(c1,area,n);
+			if (c1 < 0)
+				c = -1.0;
+			else
+				c = 1.0;
+
+			VLength(b3,area);
+			b3 = b3 / det * c;
+
+			b1 = 1.0 - b2 - b3;
+
+			//assert(b1 >= 0.0 && b1 <= 1.0 && b2 >= 0.0 && b2 <= 1.0 && b3 >= 0.0 && b3 <= 1.0);
+		}
+
+		// use barycentric coordinates to compute 3D texcoords of intersection point
+	  VECTOR tX, tY, tZ;
+	  get_triangle_texcoords3D (Mesh, Triangle, tX, tY, tZ);
+
+
+		// must transform mesh points from mesh space into world space because we need the intersection point in world space
+		MTransPoint(tX, tX, Mesh->Trans);
+		MTransPoint(tY, tY, Mesh->Trans);
+		MTransPoint(tZ, tZ, Mesh->Trans);
+
+
+		VECTOR EPoint;
+
+		EPoint[X] = b1*tX[X] + b2*tY[X] + b3*tZ[X];
+		EPoint[Y] = b1*tX[Y] + b2*tY[Y] + b3*tZ[Y];
+		EPoint[Z] = b1*tX[Z] + b2*tY[Z] + b3*tZ[Z];
+
+
+	  if (Mesh->Data->Number_Of_UVCoords <= 1)
+ 			push_entry_pointer(world_dist, IPoint, Object, Triangle, Depth_Stack);
+		else
+			push_entry_pointer_uv(world_dist, IPoint, EPoint, Object, Triangle, Depth_Stack);
+
+
+	return(true);
   }
 
   return(false);
@@ -1385,15 +1472,15 @@
 *   Init_Mesh_Triangle
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -1445,17 +1532,17 @@
 * INPUT
 *
 *   Triangle - Pointer to triangle
-*   
+*
 * OUTPUT
 *
 *   BBox     - Bounding box
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   Calculate the bounding box of a triangle.
@@ -1493,15 +1580,15 @@
 *   Build_Mesh_BBox_Tree
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   Create the bounding box hierarchy.
@@ -1564,19 +1651,19 @@
 *   Ray      - Current ray
 *   Orig_Ray - Original, untransformed ray
 *   len      - Length of the transformed ray direction
-*   
+*
 * OUTPUT
 *
 *   Depth_Stack - Stack of intersections
-*   
+*
 * RETURNS
 *
 *   int - true if an intersection was found
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   Intersect a ray with the bounding box tree of a mesh.
@@ -1681,22 +1768,22 @@
 * INPUT
 *
 *   aPoint - Normal/Vertex to store
-*   
+*
 * OUTPUT
 *
 *   Hash_Table - Normal/Vertex hash table
 *   Number     - Number of normals/vertices
 *   Max        - Max. number of normals/vertices
 *   Elements   - List of normals/vertices
-*   
+*
 * RETURNS
 *
 *   int - Index of normal/vertex into the normals/vertices list
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   Try to locate a triangle normal/vertex in the normal/vertex list.
@@ -1777,21 +1864,21 @@
 * INPUT
 *
 *   Vertex - Vertex to store
-*   
+*
 * OUTPUT
 *
 *   Number_Of_Vertices - Number of vertices
 *   Max_Vertices       - Max. number of vertices
 *   Vertices           - List of vertices
-*   
+*
 * RETURNS
 *
 *   int - Index of vertex into the vertices list
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   Try to locate a triangle vertex in the vertex list.
@@ -1819,21 +1906,21 @@
 * INPUT
 *
 *   Normal - Normal to store
-*   
+*
 * OUTPUT
 *
 *   Number_Of_Normals - Number of normals
 *   Max_Normals       - Max. number of normals
 *   Normals           - List of normals
-*   
+*
 * RETURNS
 *
 *   int - Index of normal into the normals list
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   Try to locate a triangle normal in the normal list.
@@ -1861,21 +1948,21 @@
 * INPUT
 *
 *   Texture - Texture to store
-*   
+*
 * OUTPUT
 *
 *   Number_Of_Textures - Number of textures
 *   Max_Textures       - Max. number of textures
 *   Textures           - List of textures
-*   
+*
 * RETURNS
 *
 *   int - Index of texture into the texture list
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   Try to locate a texture in the texture list.
@@ -2029,15 +2116,15 @@
 *   Create_Mesh_Hash_Tables
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -2085,15 +2172,15 @@
 *   Destroy_Mesh_Hash_Tables
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -2117,9 +2204,9 @@
     while (Vertex_Hash_Table[i] != NULL)
     {
       Temp = Vertex_Hash_Table[i];
-      
+
       Vertex_Hash_Table[i] = Temp->Next;
-      
+
       POV_FREE(Temp);
     }
   }
@@ -2131,9 +2218,9 @@
     while (Normal_Hash_Table[i] != NULL)
     {
       Temp = Normal_Hash_Table[i];
-      
+
       Normal_Hash_Table[i] = Temp->Next;
-      
+
       POV_FREE(Temp);
     }
   }
@@ -2169,17 +2256,17 @@
 *
 *   Mesh     - Mesh object
 *   Triangle - Triangle
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
 *
 *   P1, P2, P3 - Vertices of the triangle
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -2197,6 +2284,12 @@
   Assign_Vector(P3, Mesh->Data->Vertices[Triangle->P3]);
 }
 
+static void get_triangle_texcoords3D(MESH *Mesh, MESH_TRIANGLE *Triangle, VECTOR X, VECTOR  Y, VECTOR  Z)
+{
+  Assign_Vector(X, Mesh->Data->UVCoords[Triangle->Texture]);
+  Assign_Vector(Y, Mesh->Data->UVCoords[Triangle->Texture2]);
+  Assign_Vector(Z, Mesh->Data->UVCoords[Triangle->Texture3]);
+}
 
 
 /*****************************************************************************
@@ -2209,17 +2302,17 @@
 *
 *   Mesh     - Mesh object
 *   Triangle - Triangle
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
 *
 *   N1, N2, N3 - Normals of the triangle
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   -
@@ -2284,17 +2377,17 @@
 * INPUT
 *
 *   P1, P2, P3 - Triangle's vertices
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
 *
 *   int - true if degenerate
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   Test if a triangle is degenerate.
@@ -2328,15 +2421,15 @@
 *   Initialize_Mesh_Code
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   Initialize mesh specific variables.
@@ -2361,15 +2454,15 @@
 *   Deinitialize_Mesh_Code
 *
 * INPUT
-*   
+*
 * OUTPUT
-*   
+*
 * RETURNS
-*   
+*
 * AUTHOR
 *
 *   Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   Deinitialize mesh specific variables.
@@ -2571,17 +2664,17 @@
 *
 *   Mesh     - Mesh object
 *   Ray      - Current ray
-*   
+*
 * OUTPUT
 *
 * RETURNS
 *
 *   int - true if inside the object
-*   
+*
 * AUTHOR
 *
 *   Nathan Kopp & Dieter Bayer
-*   
+*
 * DESCRIPTION
 *
 *   Check if a point is within the bounding box tree of a mesh.
@@ -2652,8 +2745,8 @@
 /* AP and NK */
 
 /*
-  Determine the weights for interpolation of the three vertex textures of 
-  mesh-triangle tri at position IPoint. If mesh-triangle is not a 
+  Determine the weights for interpolation of the three vertex textures of
+  mesh-triangle tri at position IPoint. If mesh-triangle is not a
   smooth_texture_triange, ignore interpolation and return false
 */
 
@@ -2672,7 +2765,7 @@
     Assign_Vector(EPoint, IPoint);
   }
 
-  if(tri->ThreeTex) 
+  if(tri->ThreeTex)
   {
     /*if(tri->C1==-1 ||
        tri->C2==-1 ||
@@ -2697,8 +2790,8 @@
     VScaleEq(Weights, 1.0/wsum);
 
     return true;
-  } 
-  else 
+  }
+  else
   {
     return false;
   }
diff -Naur povray-3.6.1/source/render.cpp povray-3.6.1_Bueno/source/render.cpp
--- povray-3.6.1/source/render.cpp	2004-08-03 01:11:37.000000000 +0200
+++ povray-3.6.1_Bueno/source/render.cpp	2009-05-13 19:42:47.000000000 +0200
@@ -1445,7 +1445,7 @@
   int x, y, xx, xxx, yy, skip_odd_lines;
   int sub_pixel_size, antialias_line = true;
   long size;
-  COLOUR unclippedColour;
+  COLOUR clippedColour, unclippedColour;
   PIXEL *First_Row, *Last_Row, *TempRow;
   PIXEL **Block;
   PIXEL TempPixel;
@@ -1590,7 +1590,9 @@
 
       POV_PRE_PIXEL (x, Current_Line_Number, unclippedColour)
       trace_sub_pixel(1, Block, x, Current_Line_Number, 0, 0, sub_pixel_size, sub_pixel_size, sub_pixel_size, unclippedColour, antialias_line);
-      POV_POST_PIXEL (x, Current_Line_Number, unclippedColour)
+      Clip_Colour(clippedColour, unclippedColour);
+      gamma_correct(clippedColour);
+      POV_POST_PIXEL (x, Current_Line_Number, clippedColour)
 
       /* Do histogram stuff. */
 
@@ -1601,12 +1603,12 @@
 
       /* Store colour in current line */
 
-      Assign_Colour(Current_Line[x], unclippedColour);
+      Assign_Colour(Current_Line[x], clippedColour);
       
       /* Display pixel */
       POV_ASSIGN_PIXEL_UNCLIPPED (x, Current_Line_Number, unclippedColour)
-      plot_pixel(x, Current_Line_Number, unclippedColour);
-      POV_ASSIGN_PIXEL (x, Current_Line_Number, unclippedColour)
+      plot_pixel(x, Current_Line_Number, clippedColour);
+      POV_ASSIGN_PIXEL (x, Current_Line_Number, clippedColour)
 
       /* Store current block in rows */
 
@@ -1922,6 +1924,9 @@
 
   /* Test difference to pixel left of current pixel. */
 
+	if (x==197 && y==39)
+		int kk=0;
+
   if (x != 0)
   {
     if (Colour_Distance_RGBT(Current_Line[x-1],Current_Line[x]) >= Frame.Antialias_Threshold)
@@ -2111,6 +2116,8 @@
   /* Average pixel's color. */
   Scale_Colour(result,result,(1.0/samples));
 
+  Clip_Colour(result, result);
+  gamma_correct(result);
 }
 
 
@@ -2446,8 +2453,7 @@
 
         Trace(Ray, C, 1.0);
 
-        /* Commented out Jul 2004 C.H. */
-        /*Clip_Colour(C, C);*/
+        Clip_Colour(C, C);
 
         Add_Colour(Colour, Colour, C);
       }
@@ -2585,6 +2591,7 @@
 * DESCRIPTION
 *
 *   Trace a primary ray regarding focal blur and vista buffer.
+*   The color of the pixel is clipped and the number of pixels is increased.
 *
 * CHANGES
 *
@@ -2640,6 +2647,8 @@
   }
 
   Assign_Colour(ColourClipped, ColourUnclipped);
+  Clip_Colour(ColourClipped, ColourUnclipped);
+  gamma_correct(ColourClipped);
 
   /* Do histogram stuff. */
   if (opts.histogram_on)
