Transform Texture Space To World Space?

Miscellaneous Forums/General Discussion/Transform Texture Space To World Space?

Thanks for that. I had a read of it, along with a couple of similar pages people suggested, and I came up with what I thought was good code, but it's not working properly. Perhaps someone with a better mathematical mind than me could take a look and spot where I've gone wrong.

It has a dash of TV and a dash of BMax but it should all be pretty readable whatever language/API you use. I've included all the important related functions and left out a couple of functions which I know are working perfectly and aren't related to this particular calculation anyway. ( For instance, PointInTri is definitely working and bears no correlation to the transformation from texture spsace to world space anyway.


' MAIN CODE - THIS IS THE ESSENCE OF THE LIGHTMAPPER. IT CHECKS IF EACH POINT IS IN A TRI
' AND IF IT IS, IT FINDS THE WORLD COORDINATES WITHIN THAT TRI THAT THE PIXEL COORDINATES MAP TO

	PrecalculateTriangles(Mesh,TexWidth,TexHeight,UVChannel)

	For Local TX:Int=0 To TexWidth-1
		For Local TY:Int=0 To TexHeight-1
			
			For Local T:LightmapTriangle=EachIn LightmapTriangle.List
				
				SearchU=(TX+0.5)/Float(TexWidth) ' TURN PIXEL COORDINATES INTO UV COORDINATES
				SearchV=(TY+0.5)/Float(TexHeight)
				
				Local PIT:Int=False
				
				Select UVChannel
				
					Case 0
						If PointInTriangle(SearchU,SearchV,T.TA1.X,T.TA1.Y,T.TA2.X,T.TA2.Y,T.TA3.X,T.TA3.Y)
							PIT=True
						End If
						
					Case 1
						If PointInTriangle(SearchU,SearchV,T.TB1.X,T.TB1.Y,T.TB2.X,T.TB2.Y,T.TB3.X,T.TB3.Y)
							PIT=True
						End If
						
				End Select
				
				If PIT=True
										
					Local DeltaUAdd:cTV_3DVECTOR=TVMathLibrary.VMultiply(T.DeltaU,SearchU)
					Local DeltaVAdd:cTV_3DVECTOR=TVMathLibrary.VMultiply(T.DeltaV,SearchV)
										
					TVMathLibrary.TVVec3Add(PointOut1,T.OriginWS3,DeltaUAdd)
					TVMathLibrary.TVVec3Add(PointOut2,PointOut1,DeltaVAdd)
					
					' WORLD COORDINATES SHOULD NOW BE IN POINT OUT 2!!

					' LIGHTING CALCULATION AND SETPIXEL'ING GOES HERE
				End If
				
			Next
			
		Next
	Next

' END OF LIGHTMAPPING CODE

' FUNCTIONS USED BY THE MAIN CODE

Function PrecalculateTriangles(Mesh:cTVMesh,TexWidth:Int,TexHeight:Int,UVChannel:Int)
	
	For Local TCount:Int=0 To Mesh.GetTriangleCount()-1
		
		Local T:LightmapTriangle=New LightmapTriangle
		
		T.Face=TCount
		
		Mesh.GetTriangleInfo(TCount,T.V1,T.V2,T.V3,T.Group)
		
		Mesh.GetVertex(T.V1,T.P1.x,T.P1.y,T.P1.z,T.N1.x,T.N1.y,T.N1.z,T.TA1.X,T.TA1.Y,T.TB1.X,T.TB1.Y,T.Col1)
		Mesh.GetVertex(T.V2,T.P2.x,T.P2.y,T.P2.z,T.N2.x,T.N2.y,T.N2.z,T.TA2.X,T.TA2.Y,T.TB2.X,T.TB2.Y,T.Col2)
		Mesh.GetVertex(T.V3,T.P3.x,T.P3.y,T.P3.z,T.N3.x,T.N3.y,T.N3.z,T.TA3.X,T.TA3.Y,T.TB3.X,T.TB3.Y,T.Col3)
			
		Select UVChannel
			Case 0
				ComputeTangentBasis(T.P1,T.P2,T.P3,T.TA1,T.TA2,T.TA3,T.Tangent,T.BiTangent)
			Case 1
				ComputeTangentBasis(T.P1,T.P2,T.P3,T.TB1,T.TB2,T.TB3,T.Tangent,T.BiTangent)
		End Select
		
		T.DeltaU=TVMathLibrary.VMultiply(T.Tangent,1/Float(TexWidth))
		T.DeltaV=TVMathLibrary.VMultiply(T.BiTangent,1/Float(TexHeight))
		
		T.OriginWS=cTV_3DVECTOR.create(T.P1.x,T.P1.y,T.P1.z)
		
		Select UVChannel
			Case 0
				T.XMult=T.TA1.X*TexWidth-0.5
				T.YMult=T.TA1.Y*TexHeight-0.5
			Case 1
				T.XMult=T.TB1.X*TexWidth-0.5
				T.YMult=T.TB1.Y*TexHeight-0.5
		End Select
		
		T.DeltaUSubtract=TVMathLibrary.VMultiply(T.DeltaU,T.XMult)
		T.DeltaVSubtract=TVMathLibrary.VMultiply(T.DeltaV,T.YMult)
		
		TVMathLibrary.TVVec3Subtract(T.OriginWS2,T.OriginWS,T.DeltaUSubtract)
		TVMathLibrary.TVVec3Subtract(T.OriginWS3,T.OriginWS2,T.DeltaVSubtract)
		
		' CALCULATE THE SURFACE NORMAL
		TVMathLibrary.TVVec3Subtract(T.P1P2,T.P2,T.P1)
		TVMathLibrary.TVVec3Subtract(T.P1P3,T.P3,T.P1)
		TVMathLibrary.TVVec3Cross(T.SurfaceNormal,T.P1P2,T.P1P3)
		T.SurfaceNormal.Normalize()
		
	Next
	
End Function

Function ComputeTangentBasis(P1:cTV_3DVECTOR,P2:cTV_3DVECTOR,P3:cTV_3DVECTOR,UV1:cTV_2DVECTOR,UV2:cTV_2DVECTOR,UV3:cTV_2DVECTOR,Tangent:cTV_3DVECTOR,Bitangent:cTV_3DVECTOR)
	
	Local Edge1:cTV_3DVECTOR=cTV_3DVECTOR.create(0,0,0)
	TVMathLibrary.TVVec3Subtract(Edge1,P2,P1)
	Local Edge2:cTV_3DVECTOR=cTV_3DVECTOR.create(0,0,0)
	TVMathLibrary.TVVec3Subtract(Edge2,P3,P1)
	Local Edge1UV:cTV_2DVECTOR=cTV_2DVECTOR.create(0,0)
	TVMathLibrary.TVVec2Subtract(Edge1UV,UV2,UV1)
	Local Edge2UV:cTV_2DVECTOR=cTV_2DVECTOR.create(0,0)
	TVMathLibrary.TVVec2Subtract(Edge2UV,UV3,UV1)
	
	Local CP:Float=(Edge1UV.Y*Edge2UV.X)-(Edge1UV.X*Edge2UV.Y)
	
	If CP<>0
		
		Local Mul:Float=1.0/CP
		
		Local TangentEdgeMult1:cTV_3DVECTOR=TVMathLibrary.VMultiply(Edge1,-Edge2UV.Y)
		Local TangentEdgeMult2:cTV_3DVECTOR=TVMathLibrary.VMultiply(Edge2,Edge1UV.Y)
		Local BiTangentEdgeMult1:cTV_3DVECTOR=TVMathLibrary.VMultiply(Edge1,-Edge2UV.X)
		Local BiTangentEdgeMult2:cTV_3DVECTOR=TVMathLibrary.VMultiply(Edge2,Edge1UV.X)
		
		Local TangentTotal:cTV_3DVECTOR=cTV_3DVECTOR.create(0,0,0)
		TVMathLibrary.TVVec3Add(TangentTotal,TangentEdgeMult1,TangentEdgeMult2)
		Local BiTangentTotal:cTV_3DVECTOR=cTV_3DVECTOR.create(0,0,0)
		TVMathLibrary.TVVec3Add(BiTangentTotal,BiTangentEdgeMult1,BiTangentEdgeMult2)
		
		Local VTangent:cTV_3DVECTOR=TVMathLibrary.VMultiply(TangentTotal,Mul)
		Local VBiTangent:cTV_3DVECTOR=TVMathLibrary.VMultiply(BiTangentTotal,Mul)
				
		Tangent.x=VTangent.x
		Tangent.y=VTangent.y
		Tangent.z=VTangent.z
		
		BiTangent.x=VBiTangent.x
		BiTangent.y=VBiTangent.y
		BiTangent.z=VBiTangent.z
		
	End If
	
	
	
End Function