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
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
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