2d texture coordinate (TX,TY) to 3d world coordinate (WX,WY,WZ) by Jeppe Nielsen


Attention! 👉Starting November 2024, BlitzCoder.org will now be BlitzBasic.org.

 

Tweet blitz3d code-archives effects
RemiD

a great code by "Jeppe Nielsen", that was apparently not in the codes archives :

;Texel to world coordinates, use the TFormTexel function (by Jeppe Nielsen)

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

and another example on how to use :

;2d texture coordinate (TX,TY) to 3d world coordinate (WX,WY,WZ) by Jeppe Nielsen
;another example on how to use it...

Graphics3D(854,480,32,2)

Camera = CreateCamera()
CameraRange(Camera,0.15,150)
CameraClsColor(Camera,000,000,000)

XMesh = CreateQuad()
ScaleMesh(XMesh,1.28/2,1.28/2,1.28/2)
PositionEntity(XMesh,1.5,1.5,1.5,True)
EntityFX(XMesh,1)

XTexture = CreateTexture(128,128,1)
SetBuffer(TextureBuffer(XTexture))
ClsColor(125,125,125) : Cls()
Color(255,255,255) : Rect(0,0,128,128,False)

EntityTexture(XMesh,XTexture,0,0)

;for displaying the texture on the screen
XImage = CreateImage(TextureWidth(XTexture),TextureHeight(XTexture))
CopyRect(0,0,TextureWidth(XTexture),TextureHeight(XTexture),0,0,TextureBuffer(XTexture),ImageBuffer(XImage))

Marker = CreateCube()
ScaleMesh(Marker,0.03/2,0.03/2,0.03/2)
EntityColor(Marker,255,000,255)
EntityFX(Marker,1)

PositionEntity(Camera,1.5,1.5+1.65,1.5-1.5)
RotateEntity(Camera,33.6,0,0)

Repeat

 MX% = MouseX() : MY% = MouseY()

 If( MX > 0 And MX < 0+ImageWidth(XImage) And MY > 0 And MY < 0+ImageHeight(XImage) ) ;if cursor above 2d area of the image (to get texel coordinate TX,TY)
  TX% = MX : TY% = MY
  TFormTexel(XMesh,XTexture,TX,TY)
  WX# = TFormedX() : WY# = TFormedY() : WZ# = TFormedZ()
  PositionEntity(Marker,WX,WY,WZ,True) : ShowEntity(Marker)
 Else
  TX% = 0 : TY% = 0
  WX# = 0 : WY# = 0 : WZ# = 0
  PositionEntity(Marker,0,-1000,0,True) : HideEntity(Marker)
 EndIf

 SetBuffer(BackBuffer())
 RenderWorld()

 DrawImage(XImage,0,0)
 If( MX > 0 And MX < 0+ImageWidth(XImage) And MY > 0 And MY < 0+ImageHeight(XImage) ) ;if cursor above 2d area of the image (to get texel coordinate TX,TY)
  Color(255,000,255) : Oval(MX-1,MY-1,2,2,True)
 EndIf

 Color(255,255,255)
 TStr$ = TX+","+TY+"->"+WX+","+WY+","+WZ
 Text(GraphicsWidth()/2-StringWidth(TStr)/2,0,TStr)

 Flip(1)

Until( KeyDown(1)=1 )

WaitKey()

End()

Function CreateQuad()

 TMesh = CreateMesh()
 TSurface = CreateSurface(TMesh)
 AddVertex(TSurface,-1.0,0.0,+1.0) : VertexTexCoords(TSurface,0,0.0/128,0.0/128)
 AddVertex(TSurface,+1.0,0.0,+1.0) : VertexTexCoords(TSurface,1,128.0/128,0.0/128)
 AddVertex(TSurface,-1.0,0.0,-1.0) : VertexTexCoords(TSurface,2,0.0/128,128.0/128)
 AddVertex(TSurface,+1.0,0.0,-1.0) : VertexTexCoords(TSurface,3,128.0/128,128.0/128)
 AddTriangle(TSurface,0,1,2)
 AddTriangle(TSurface,2,1,3)
 UpdateNormals(TMesh)
 Return TMesh

End Function

;function TFormTexel() by Jeppe Nielsen
Function TFormTexel%(mesh,texture,texelx%,texely%)

 twidth%=TextureWidth(texture)-1
 theight%=TextureHeight(texture)-1

 px#=Float(texelx)/twidth
 py#=Float(texely)/theight

 surfs=CountSurfaces(mesh)

 For surf=1 To surfs
  surface=GetSurface(mesh,surf)

  tris=CountTriangles(surface)-1

  For tri=0 To tris

   vert0=TriangleVertex(surface,tri,0)
   vert1=TriangleVertex(surface,tri,1)
   vert2=TriangleVertex(surface,tri,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# ) = True )

    ;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

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
BlitzCoder commented:

Thanks for this RemiD! btw, add the preferred category tag so this and other recent code archive that you have posted will show up accordingly on the right section.

Reply To Topic (minimum 10 characters)

Please log in to reply