Finding 3Dworld position of texture pixel (texel)?

Blitz3D Forums/Blitz3D Programming/Finding 3Dworld position of texture pixel (texel)?

I can probably work this out, but has anyone already created a function to calculate the 3D world position of a texture pixel on a particular triangle/surface?

Any help would be appreciated. Thanks.

This should do it, more or less:

http://www.blitzbasic.com/codearcs/codearcs.php?code=515

[edit]

Ooops, or maybe not... if I understud the question correctly after second reading.

As in a radar map?

I did it as a 2D image for the hud...

And I as I remember it's easy math, just get the pixel cordinate x&y subtract half the width&height (if you want the center to be 0) devide it by the whole width& height and multiply the result by the scale of the map.

So it would be something like...
x#=(Pixel_X-(ImageWidth(map)/2))/ImageWidth(map)
z#=(Pixel_Y-(ImageHeight(map)/2))/ImageHeight(map)
PositionEntity(obj,x#*Scale#,0,z#=*Scale#)

use LinePick (or CameraPick )
- Surf=pickedsurface()
- Tri=PickedTriangle()
- get the 3 vertices of the triangle :
V0=Trianglevertex(surf,0)
V1=Trianglevertex(surf,1)
V2=Trianglevertex(surf,2)

VU0#=vertexU(surf,V0)
VV0#=vertexV(surf,V0)

VU1#=vertexU(surf,V1)
VV1#=vertexV(surf,V1)

VU2#=vertexU(surf,V2)
VV2#=vertexV(surf,V2)

=> And get the coord :
U#=(VU0+VU1+VU2)/3
V#=(VV0+VV1+VV2)/3

Then convert the UV with texturecoord using:
=> GetSurfaceBrush => getBrushTexture()
And finally => texturewidth() , TextureHeight()
=> Pixel_I=U*TextureWidth()
=> Pixel_J=V*TextureHeight()

This will do what you want, I think :-)

Kind of the reverse of the code Mustang showed.

Look at the TFormTexel function:

;this will calculate the world coordinates of a texel, at the texture pixel coordinates specified
;results are grabbed with TFormedX(),TFormedY() and TFormedZ()
TFormTexel(mesh,texture,pixelx,pixely)


;Texel to world coordinates, use the TFormTexel function.


Graphics3D 800,600,32,2

HidePointer

camera=CreateCamera()

PositionEntity camera,3,4,-4
RotateEntity camera,50,0,0
CameraClsColor camera,0,0,255


tex=CreateTexture(512,512)

quad=CreateMesh()

surface=CreateSurface(quad)

AddVertex surface,0,0,0,0,0
AddVertex surface,2,0,0,1,0
AddVertex surface,2,0,-2,1,1
AddVertex surface,0,0,-4,0,1

AddTriangle surface,0,1,3
AddTriangle surface,1,2,3

EntityFX quad,1

sphere=CreateSphere(32)
PositionEntity sphere,3,0,0

EntityFX sphere,1

cube=CreateCube()
PositionEntity cube,6,0,0

EntityFX cube,1

EntityTexture quad,tex
EntityTexture sphere,tex
EntityTexture cube,tex

Local marker[2]

For n=0 To 2
	marker[n]=CreateCube()
	ScaleEntity marker[n],0.15,0.15,0.15
	EntityAlpha marker[n],0.8
	EntityFX marker[n],1
Next


Repeat

mx=MouseX()
my=MouseY()

DrawToTexture(tex,mx,my)

If TFormTexel(quad,tex,mx,my)=True

	PositionEntity marker[0],TFormedX(),TFormedY(),TFormedZ()

Else

	PositionEntity marker[0],10000,10000,10000

EndIf

If TFormTexel(sphere,tex,mx,my)=True

	PositionEntity marker[1],TFormedX(),TFormedY(),TFormedZ()

Else

	PositionEntity marker[1],10000,10000,10000

EndIf

If TFormTexel(cube,tex,mx,my)=True

	PositionEntity marker[2],TFormedX(),TFormedY(),TFormedZ()

Else

	PositionEntity marker[2],10000,10000,10000

EndIf

RenderWorld()

Plot mx,my

Rect 0,0,TextureWidth(tex),TextureHeight(tex),False
Color 255,255,255
Oval mx-4/2,my-4/2,4,4,True
Oval mx-40,my-40,80,80,False

Flip

Until KeyDown(1)
End

;this will calculate the world coordinates of a texel, at the texture pixel coordinates specified 
;results are grabbed with TFormedX(),TFormedY() and TFormedZ()
Function TFormTexel(mesh,texture,pixelx,pixely)

twid=TextureWidth(texture)-1
thei=TextureHeight(texture)-1

px#=Float(pixelx)/twid
py#=Float(pixely)/thei


surfs=CountSurfaces(mesh)

For surf=1 To surfs

surface=GetSurface(mesh,surf)

tris=CountTriangles(surface)-1

For triangle=0 To tris

vert0=TriangleVertex(surface,triangle,0)
vert1=TriangleVertex(surface,triangle,1)
vert2=TriangleVertex(surface,triangle,2)

x0#=VertexU(surface,vert0)
y0#=VertexV(surface,vert0)

x1#=VertexU(surface,vert1)
y1#=VertexV(surface,vert1)

x2#=VertexU(surface,vert2)
y2#=VertexV(surface,vert2)

;check if the point is in the texture triangle
If IsInTriangle( px#,py#, x0#,y0#,x1#,y1#,x2#,y2# )

;equations taken from here:
;
;http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/
;
ua#=( (x2-x1)*(y0-y1)-(y2-y1)*(x0-x1) ) / ( (y2-y1)*(px-x0)-(x2-x1)*(py-y0) )

ex#=x0+ua*(px-x0)
ey#=y0+ua*(py-y0)

dx#=ex-x1
dy#=ey-y1
le#=Sqr(dx*dx+dy*dy)

dx#=x2-x1
dy#=y2-y1
d1#=le#/Sqr(dx*dx+dy*dy)

ua#=( (x2-x0)*(y1-y0)-(y2-y0)*(x1-x0) ) / ( (y2-y0)*(px-x1)-(x2-x0)*(py-y1) )

ex#=x1+ua*(px-x1)
ey#=y1+ua*(py-y1)

dx#=ex-x0
dy#=ey-y0
le#=Sqr(dx*dx+dy*dy)

dx#=x2-x0
dy#=y2-y0
d2#=le#/Sqr(dx*dx+dy*dy)

px1#=VertexX(surface,vert0)
py1#=VertexY(surface,vert0)
pz1#=VertexZ(surface,vert0)

px3#=VertexX(surface,vert1)
py3#=VertexY(surface,vert1)
pz3#=VertexZ(surface,vert1)

dx#=VertexX(surface,vert2)-VertexX(surface,vert1)
dy#=VertexY(surface,vert2)-VertexY(surface,vert1)
dz#=VertexZ(surface,vert2)-VertexZ(surface,vert1)

px2#=px3+dx*d1#
py2#=py3+dy*d1#
pz2#=pz3+dz*d1#

dx#=VertexX(surface,vert2)-VertexX(surface,vert0)
dy#=VertexY(surface,vert2)-VertexY(surface,vert0)
dz#=VertexZ(surface,vert2)-VertexZ(surface,vert0)

px4#=px1+dx*d2#
py4#=py1+dy*d2#
pz4#=pz1+dz*d2#


;equations taken from here:
;
;http://mathworld.wolfram.com/Line-LineIntersection.html
;

ax#=px2#-px1#
ay#=py2#-py1#
az#=pz2#-pz1#

bx#=px4#-px3#
by#=py4#-py3#
bz#=pz4#-pz3#

cx#=px3#-px1#
cy#=py3#-py1#
cz#=pz3#-pz1#

qx1# = cy * bz - by * cz
qy1# = cz * bx - bz * cx
qz1# = cx * by - bx * cy

qx2# = ay * bz - by * az
qy2# = az * bx - bz * ax
qz2# = ax * by - bx * ay

dot#=qx1*qx2+qy1*qy2+qz1*qz2

le#=Sqr(qx2*qx2+qy2*qy2+qz2*qz2)

si#=dot#/(le#*le#)

pointx#=px1#+ax#*si#
pointy#=py1#+ay#*si#
pointz#=pz1#+az#*si#

TFormPoint pointx,pointy,pointz,mesh,0

Return True

EndIf

Next

Next

End Function

;taken from the blitzbasic site:
;
;http://www.blitzbasic.co.nz/codearcs/codearcs.php?code=483
;
Function IsInTriangle( px#,py#, ax#,ay#,bx#,by#,cx#,cy# ) 

	Local bc#,ca#,ab#,ap#,bp#,cp#,abc#

	bc# = bx*cy - by*cx 
	ca# = cx*ay - cy*ax 
	ab# = ax*by - ay*bx
	ap# = ax*py - ay*px
	bp# = bx*py - by*px
	cp# = cx*py - cy*px
	abc# = Sgn(bc + ca + ab)

	Return (abc*(bc-bp+cp)>0) And (abc*(ca-cp+ap)>0) And (abc*(ab-ap+bp)>0)
End Function


Function DrawToTexture(tex,mx,my,size=4)

SetBuffer TextureBuffer(tex)
	
	Cls
	
	Color 255,255,255
	Oval mx-size/2,my-size/2,size,size,True
	Oval mx-40,my-40,80,80,False
		
SetBuffer BackBuffer()

End Function



good work. But maybe parsing all triangles of the mesh to get one coord could be long .

Maybe using a preloading system to store triangles datas should get it work faster no ? But it should also use bigs array ...

Thanks guys, particularly Jeppe. Just what I needed.