October 28, 2021, 12:20:36

Author Topic: [bb] PickedU(), PickedV(), PickedW() by fredborg [ 1+ years ago ]  (Read 4748 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
Title : PickedU(), PickedV(), PickedW()
Author : fredborg
Posted : 1+ years ago

Description : A nice way to retrieve the texture coordinates of a pick (ex. CameraPick and LinePick).

Usage:
PickedU([coordset]) - Returns the U component of the last successful pick command. Coordset can be either 0 or 1 depending on which texture coord set you wish to get (defaults to 0).
PickedV([coordset]) - Returns the V component
PickedW([coordset]) - Returns the W component

Includes a small test program located at the bottom of the code, so you can see how it's used (if you hadn't figured it out by now ;)

Update: Example now shows how to retrieve a pixel color from a texture!

Limitation: This set of commands are not affected by the use of 'ScaleTexture', 'PositionTexture', or 'RotateTexture'. You have to make your own calculations, if you have used any of these commands!!!

Use as you please, but please include a mention/thanks to me :)


Code :
Code: BlitzBasic
  1. ;
  2. ; PickedU(), PickedV(), PickedW() commands
  3. ;
  4. ; Created by Mikkel Fredborg
  5. ;
  6. ; Use as you please, but please include a thank you :)
  7. ;
  8.  
  9. ;
  10. ; PickedTri type
  11. ; Necessary for the PickedU(), PickedV(), and PickedW() commands
  12. Type PickedTri
  13.         Field ent,surf,tri                              ;picked entity, surface and triangle
  14.         Field px#,py#,pz#                           ;picked xyz
  15.         Field pu#[1],  pv#[1]  ,pw#[1]  ;picked uvw x 2
  16.        
  17.         Field vx#[2],  vy#[2]  ,vz#[2]  ;vertex xyz
  18.         Field vnx#[2], vny#[2] ,vnz#[2] ;vertex normals
  19.         Field vu#[5],  vv#[5]  ,vw#[5]  ;vertex uvw x 2
  20. End Type
  21.  
  22. Global ptri.pickedtri = New pickedtri
  23.  
  24. ;
  25. ; Returns the Texture U coordinate of the last successful pick command
  26. ; coordset may be set to either 0 or 1
  27. Function PickedU#(coordset = 0)
  28.        
  29.         ; if something new has been picked then calculate the new uvw coordinates
  30.         If (PickedX()<>ptripx) Or (PickedY()<>ptripy) Or (PickedZ()<>ptripz) Or (PickedSurface()<>ptrisurf)
  31.                 PickedUVW()
  32.         End If
  33.        
  34.         Return ptripu[coordset]
  35.        
  36. End Function
  37.  
  38. ;
  39. ; Returns the Texture U coordinate of the last successful pick command
  40. ; coordset may be set to either 0 or 1
  41. Function PickedV#(coordset = 0)
  42.        
  43.         ; if something new has been picked then calculate the new uvw coordinates
  44.         If (PickedX()<>ptripx) Or (PickedY()<>ptripy) Or (PickedZ()<>ptripz) Or (PickedSurface()<>ptrisurf)
  45.                 PickedUVW()
  46.         End If
  47.        
  48.         Return ptripv[coordset]
  49.        
  50. End Function
  51.  
  52. ;
  53. ; Returns the Texture U coordinate of the last successful pick command
  54. ; coordset may be set to either 0 or 1
  55. Function PickedW#(coordset = 0)
  56.        
  57.         ; if something new has been picked then calculate the new uvw coordinates
  58.         If (PickedX()<>ptripx) Or (PickedY()<>ptripy) Or (PickedZ()<>ptripz) Or (PickedSurface()<>ptrisurf)
  59.                 PickedUVW()
  60.         End If
  61.        
  62.         Return ptripw[coordset]
  63.        
  64. End Function
  65.  
  66. ;
  67. ; Calculates the UVW coordinates of a pick
  68. ; Do not call this by yourself, as PickedU(), PickedV(), and PickedW()
  69. ; takes care of calling it when nescessary
  70. Function PickedUVW()
  71.  
  72.         If PickedSurface()
  73.                 ptrient  = PickedEntity()
  74.                 ptrisurf = PickedSurface()
  75.                 ptri    ri  = PickedTriangle()
  76.                        
  77.                 ptripx = PickedX()
  78.                 ptripy = PickedY()
  79.                 ptripz = PickedZ()
  80.                
  81.                 For i = 0 To 2
  82.                         TFormPoint VertexX(ptrisurf,TriangleVertex(ptrisurf,ptri        ri,i)),VertexY(ptrisurf,TriangleVertex(ptrisurf,ptri    ri,i)),VertexZ(ptrisurf,TriangleVertex(ptrisurf,ptri    ri,i)),ptrient,0
  83.  
  84.                         ptrivx[i] = TFormedX()
  85.                         ptrivy[i] = TFormedY()
  86.                         ptrivz[i] = TFormedZ()
  87.  
  88.                         ptrivnx[i] = VertexNX(ptrisurf,TriangleVertex(ptrisurf,ptri     ri,i))
  89.                         ptrivny[i] = VertexNY(ptrisurf,TriangleVertex(ptrisurf,ptri     ri,i))
  90.                         ptrivnz[i] = VertexNZ(ptrisurf,TriangleVertex(ptrisurf,ptri     ri,i))
  91.                                        
  92.                         ptrivu[i+0] = VertexU(ptrisurf,TriangleVertex(ptrisurf,ptri     ri,i),0)
  93.                         ptrivv[i+0] = VertexV(ptrisurf,TriangleVertex(ptrisurf,ptri     ri,i),0)
  94.                         ptrivw[i+0] = VertexW(ptrisurf,TriangleVertex(ptrisurf,ptri     ri,i),0)
  95.  
  96.                         ptrivu[i+3] = VertexU(ptrisurf,TriangleVertex(ptrisurf,ptri     ri,i),1)
  97.                         ptrivv[i+3] = VertexV(ptrisurf,TriangleVertex(ptrisurf,ptri     ri,i),1)
  98.                         ptrivw[i+3] = VertexW(ptrisurf,TriangleVertex(ptrisurf,ptri     ri,i),1)
  99.                 Next
  100.  
  101.                 ; Select which component of xyz coordinates to ignore
  102.                 Local coords = 3
  103.  
  104.                 If Abs(PickedNX()) > Abs(PickedNY())
  105.                         If Abs(PickedNX())>Abs(PickedNZ()) Then coords = 1
  106.                 Else
  107.                         If Abs(PickedNY())>Abs(PickedNZ()) Then coords = 2
  108.                 EndIf
  109.                
  110.                 Local a0#,a1#,b0#,b1#,c0#,c1#
  111.                
  112.                 ; xy components
  113.                 If (coords = 3)
  114.                         ; edge 0
  115.                         a0# = ptrivx[1] - ptrivx[0]
  116.                         a1# = ptrivy[1] - ptrivy[0]
  117.                
  118.                         ; edge 1
  119.                         b0# = ptrivx[2] - ptrivx[0]
  120.                         b1# = ptrivy[2] - ptrivy[0]
  121.  
  122.                         ; picked offset from triangle vertex 0
  123.                         c0# = PickedX() - ptrivx[0]
  124.                         c1# = PickedY() - ptrivy[0]
  125.                 Else           
  126.                         ; xz components
  127.                         If (coords = 2)
  128.                                 ; edge 0
  129.                                 a0# = ptrivx[1] - ptrivx[0]
  130.                                 a1# = ptrivz[1] - ptrivz[0]
  131.                
  132.                                 ; edge 1
  133.                                 b0# = ptrivx[2] - ptrivx[0]
  134.                                 b1# = ptrivz[2] - ptrivz[0]
  135.  
  136.                                 ; picked offset from triangle vertex 0
  137.                                 c0# = PickedX() - ptrivx[0]
  138.                                 c1# = PickedZ() - ptrivz[0]
  139.                         Else
  140.                                 ; yz components
  141.  
  142.                                 ; edge 0
  143.                                 a0# = ptrivy[1] - ptrivy[0]
  144.                                 a1# = ptrivz[1] - ptrivz[0]
  145.                
  146.                                 ; edge 1
  147.                                 b0# = ptrivy[2] - ptrivy[0]
  148.                                 b1# = ptrivz[2] - ptrivz[0]
  149.  
  150.                                 ; picked offset from triangle vertex 0
  151.                                 c0# = PickedY() - ptrivy[0]
  152.                                 c1# = PickedZ() - ptrivz[0]
  153.                         End If
  154.                 End If
  155.                                                
  156.                 ;
  157.                 ; u and v are offsets from vertex 0 along edge 0 and edge 1
  158.                 ; using these it is possible to calculate the Texture UVW coordinates
  159.                 ; of the picked XYZ location
  160.                 ;
  161.                 ; a0*u + b0*v = c0
  162.                 ; a1*u + b1*v = c1
  163.                 ;
  164.                 ; solve equation (standard equation with 2 unknown quantities)
  165.                 ; check a math book to see why the following is true
  166.                 ;
  167.                 Local u# = (c0*b1 - b0*c1) / (a0*b1 - b0*a1)
  168.                 Local v# = (a0*c1 - c0*a1) / (a0*b1 - b0*a1)
  169.                
  170.                 ; If either u or v is out of range then the
  171.                 ; picked entity was not a mesh, and therefore
  172.                 ; the uvw coordinates cannot be calculated
  173.                 If (u<0.0 Or u>1.0) Or (v<0.0 Or v>1.0)
  174.                         Return
  175.                 End If
  176.                
  177.                 ; Calculate picked uvw's for coordset 0 (and modulate them to be in the range of 0-1 nescessary)
  178.                 ptripu[0] = (ptrivu[0] + ((ptrivu[1] - ptrivu[0]) * u) + ((ptrivu[2] - ptrivu[0]) * v)) Mod 1
  179.                 ptripv[0] = (ptrivv[0] + ((ptrivv[1] - ptrivv[0]) * u) + ((ptrivv[2] - ptrivv[0]) * v)) Mod 1
  180.                 ptripw[0] = (ptrivw[0] + ((ptrivw[1] - ptrivw[0]) * u) + ((ptrivw[2] - ptrivw[0]) * v)) Mod 1
  181.                
  182.                 ; If any of the coords are negative
  183.                 If ptripu[0]<0.0 Then ptripu[0] = 1.0 + ptripu[0]
  184.                 If ptripv[0]<0.0 Then ptripv[0] = 1.0 + ptripv[0]
  185.                 If ptripw[0]<0.0 Then ptripw[0] = 1.0 + ptripw[0]
  186.                
  187.                 ; Calculate picked uvw's for coordset 1 (and modulate them to be in the range of 0-1 nescessary)
  188.                 ptripu[1] = (ptrivu[3] + ((ptrivu[4] - ptrivu[3]) * u) + ((ptrivu[5] - ptrivu[3]) * v)) Mod 1
  189.                 ptripv[1] = (ptrivv[3] + ((ptrivv[4] - ptrivv[3]) * u) + ((ptrivv[5] - ptrivv[3]) * v)) Mod 1
  190.                 ptripw[1] = (ptrivw[3] + ((ptrivw[4] - ptrivw[3]) * u) + ((ptrivw[5] - ptrivw[3]) * v)) Mod 1
  191.  
  192.                 ; If any of the coords are negative
  193.                 If ptripu[1]<0.0 Then ptripu[1] = 1.0 + ptripu[1]
  194.                 If ptripv[1]<0.0 Then ptripv[1] = 1.0 + ptripv[1]
  195.                 If ptripw[1]<0.0 Then ptripw[1] = 1.0 + ptripw[1]
  196.         End If
  197.  
  198. End Function
  199.  
  200.  
  201.  
  202.  
  203. ;
  204. ; Test example for
  205. ; PickedU(),PickedV(),PickedW() commands
  206. ;
  207. ; Created by Mikkel Fredborg
  208. ; Inspired by David Bird
  209. ;
  210. Graphics3D 640,480
  211. SetBuffer BackBuffer()
  212.  
  213. lit=CreateLight()
  214. LightColor lit,60,60,60
  215. PositionEntity lit,0,10,0
  216. RotateEntity lit,90,0,0
  217.  
  218. cam=CreateCamera()
  219. CameraRange cam,.1,1000
  220. PositionEntity cam,0,0,-3
  221. CameraClsColor cam,100,100,100
  222.  
  223. cubetex=CreateTexture(64,64)
  224. ; make some squares on the texture
  225. SetBuffer TextureBuffer(cubetex)
  226. Color 128,128,128
  227. Rect 0,0,TextureWidth(cubetex)/2.0,TextureHeight(cubetex)/2.0,True
  228. Rect TextureWidth(cubetex)/2.0,TextureHeight(cubetex)/2.0,(TextureWidth(cubetex)/2.0)-1,(TextureHeight(cubetex)/2.0)-1,True
  229. SetBuffer BackBuffer()
  230.  
  231. cube = CreateCube()
  232. PositionEntity cube,1,0,0
  233. EntityTexture cube,cubetex,0,0
  234. EntityPickMode cube,2
  235.  
  236. ; Adjust uv coordinates of the cube to tile the texture
  237. surf_n = CountSurfaces(cube)
  238. For i = 1 To surf_n
  239.         surf = GetSurface(cube,i)
  240.         n_verts = CountVertices(surf)-1
  241.         For j = 0 To n_verts
  242.                 VertexTexCoords surf,j,VertexU(surf,j)*5.0,VertexV(surf,j)*5.0,VertexW(surf,j)*5.0
  243.         Next
  244. Next
  245.  
  246. spheretex=CreateTexture(256,256)
  247. sphere = CreateSphere()
  248. PositionEntity sphere,-1,0,0
  249. EntityTexture sphere,spheretex,0,0
  250. EntityPickMode sphere,2
  251.  
  252. plane = CreatePlane()
  253. PositionEntity plane,0,-2,0
  254. EntityPickMode plane,2
  255.  
  256. Global dotred# = 0.0
  257. Global dotgrn# = 0.0
  258. Global dotblu# = 0.0
  259.  
  260. ang# = 0
  261. While Not KeyDown(1)
  262.  
  263.         xm = MouseX()
  264.         ym = MouseY()
  265.  
  266.         If MouseDown(1) Then
  267.                 Select CameraPick(cam,xm,ym)
  268.                         Case cube:    PaintRedDot(cubetex  ,PickedU()*(TextureWidth(cubetex)-1)  ,PickedV()*(TextureHeight(cubetex)-1))
  269.                         Case sphere:  PaintRedDot(spheretex,PickedU()*(TextureWidth(spheretex)-1),PickedV()*(TextureHeight(spheretex)-1))
  270.                 End Select
  271.         Else
  272.                 If MouseDown(2) Then
  273.                         Select CameraPick(cam,xm,ym)
  274.                                 Case cube:    ReadDot(cubetex  ,PickedU()*(TextureWidth(cubetex)-1)  ,PickedV()*(TextureHeight(cubetex)-1))
  275.                                 Case sphere:  ReadDot(spheretex,PickedU()*(TextureWidth(spheretex)-1),PickedV()*(TextureHeight(spheretex)-1))
  276.                         End Select
  277.                 End If
  278.         End If
  279.        
  280.         ang = (ang + 0.1) Mod 360
  281.         TurnEntity cube,-Sin(ang)*0.3,-Cos(ang)*0.3,0
  282.         TurnEntity sphere,Sin(ang)*0.1,Cos(ang)*0.1,0
  283.        
  284.         UpdateWorld
  285.         RenderWorld
  286.  
  287.         ; draw mouse cursor
  288.         Line xm-8,ym,xm-4,ym
  289.         Line xm+8,ym,xm+4,ym
  290.         Line xm,ym-8,xm,ym-4
  291.         Line xm,ym+8,xm,ym+4
  292.         Oval xm-4,ym-4,9,9,False       
  293.  
  294.         ; write some info
  295.         Text 0,  0,"Use left mousebutton to paint the cube and the sphere"
  296.         Text 0, 20,"ent = "+PickedEntity()
  297.         Text 0, 35,"surf = "+PickedSurface()
  298.         Text 0, 50,"tri = "+PickedTriangle()
  299.                        
  300.         Text 0, 80,"x = "+PickedX()
  301.         Text 0, 95,"y = "+PickedY()
  302.         Text 0,110,"z = "+PickedZ()
  303.        
  304.         Text 0,140,"u = "+PickedU()
  305.         Text 0,155,"v = "+PickedV()
  306.         Text 0,170,"w = "+PickedW()
  307.  
  308.         Text 0,200,"nx= "+PickedNX()
  309.         Text 0,215,"ny= "+PickedNY()
  310.         Text 0,230,"nz= "+PickedNZ()
  311.        
  312.         Text 14,460,"Use right mousebutton to pick up a texture color"
  313.         Color dotred,dotgrn,dotblu
  314.         Rect 0,460,12,12,True
  315.         Color 255,255,255
  316.         Flip
  317. Wend
  318.  
  319. ClearWorld
  320. End
  321.  
  322. ;
  323. ; Plots a red dot :)
  324. Function PaintRedDot(tex,x,y)
  325.         SetBuffer TextureBuffer(tex)
  326.        
  327.         maxwidth  = TextureWidth(tex)
  328.         maxheight = TextureHeight(tex)
  329.        
  330.         red# = 255
  331.         grn# = 0
  332.         blu# = 0
  333.         WritePixel x,y,blu Or (grn Shl 8) Or (red Shl 16)
  334.        
  335.         For xx = -1 To 1
  336.                 For yy = -1 To 1
  337.                         If (xx=0) Xor (yy=0)
  338.                                 If (xx<0 And x>0) Or (xx>0 And x<maxwidth) Or (yy<0 And y>0) Or (yy>0 And y<maxheight)
  339.                                         argb = ReadPixel(x+xx,y+yy)
  340.                                         red# =  64 + (argb Shr 16 And %11111111)
  341.                                         grn# =   0 + (argb Shr 8 And %11111111)
  342.                                         blu# =   0 + (argb Shr 8 And %11111111)
  343.  
  344.                                         If red>255 Then red = 255
  345.                                         If grn>255 Then grn = 255
  346.                                         If blu>255 Then blu = 255
  347.                
  348.                                         WritePixel x+xx,y+yy,blu Or (grn Shl 8) Or (red Shl 16)
  349.                                 End If
  350.                         End If
  351.                 Next
  352.         Next
  353.        
  354.         SetBuffer BackBuffer()
  355. End Function
  356.  
  357. ;
  358. ; Reads a pixel in a texture
  359. Function ReadDot(tex,x,y)
  360.         SetBuffer TextureBuffer(tex)
  361.        
  362.         maxwidth  = TextureWidth(tex)
  363.         maxheight = TextureHeight(tex)
  364.        
  365.         If x<maxwidth And y<maxheight
  366.                 argb = ReadPixel(x,y)
  367.                 dotred# = (argb Shr 16 And %11111111)
  368.                 dotgrn# = (argb Shr 8 And %11111111)
  369.                 dotblu# = (argb Shr 8 And %11111111)
  370.         End If
  371.        
  372.         SetBuffer BackBuffer()
  373. End Function


Comments :


Kryzon(Posted 1+ years ago)

 Looks nice.


Offline RemiD

  • Hero Member
  • *****
  • Posts: 1291
Re: [bb] PickedU(), PickedV(), PickedW() by fredborg [ 1+ years ago ]
« Reply #1 on: November 24, 2018, 19:07:23 »
Hello,

I have rewritten the function by our friend Fredborg so that you don't need custom types and the (useless) functions, only one function ( returns PickedU, PickedV )
also i have added a little addon to calculate the picked texel position X,Y ( PickedTX, PickedTY )
with a demo :
Code: [Select]
;PickedU,PickedV by Fredborg
;PickedTX,PickedTY addon by RemiD
;calculates picked U,V with some math wizardry (by Fredborg)
;once the U,V ( PickedU PickedV ) of the picked point is determined, we can calculate the position X,Y of the picked texel ( PickedTX, PickedTY )
Graphics3D(800,600,32,2)

SeedRnd(MilliSecs())

Global PickedU#, PickedV# ;picked U,V
Global PickedTX%, PickedTY% ;picked texel X,Y

Local Cam = CreateCamera()
CameraRange(Cam,0.1,100)
CameraClsColor(Cam,025,025,025)

Local Texture = CreateTexture(64,64,1)
SetBuffer(TextureBuffer(Texture))
ClsColor(250,250,250) : Cls()
;outline of the texture
Color(125,125,125) : Line(0,0,64-1,0)
Color(125,125,125) : Line(0,64-1,64-1,64-1)
Color(125,125,125) : Line(0,0,0,64-1)
Color(125,125,125) : Line(64-1,0,64-1,64-1)
;corner top left (red texel)
Color(255,000,000) : Plot(0,0)
;corner top right (green texel)
Color(000,255,000) : Plot(64-1,0)
;corner bottom left (blue texel)
Color(000,000,255) : Plot(0,64-1)
;corner bottom right (white texel)
Color(255,255,255) : Plot(64-1,64-1)
;some text
Color(025,025,025) : TStr$ = "Fredborg" : TX% = TextureWidth(Texture)/2-StringWidth(TStr)/2 : TY% = TextureHeight(Texture)/2-StringHeight(TStr)/2 : Text(TX,TY,TStr)

Local Mesh = CreateCube()
EntityTexture(Mesh,Texture)
RotateEntity(Mesh,0,Rand(-180,180),0,True)
EntityPickMode(Mesh,2)

PositionEntity(Cam,0,1.65,-3.0)
RotateEntity(Cam,22.5,0,0)

While Not KeyDown(1)

 If( KeyDown(200)=1 )
  TurnEntity(Mesh,+1,0,0)
 Else If( KeyDown(208)=1 )
  TurnEntity(Mesh,-1,0,0)
 EndIf
 If( KeyDown(203)=1 )
  TurnEntity(Mesh,0,-1,0)
 Else If( KeyDown(205)=1 )
  TurnEntity(Mesh,0,+1,0)
 EndIf

 If( MouseDown(1)=1 )
  CameraPick(Cam, MouseX(), MouseY())
  If( PickedEntity() <> 0 And PickedSurface() <> 0 )
   CalculatePickedUVvFredborg() ;by Fredborg
   PickedTX% = TextureWidth(Texture)*PickedU : PickedTY% = TextureHeight(Texture)*PickedV
   DebugLog(PickedU+","+PickedV+"->"+PickedTX+","+PickedTY)
   SetBuffer(TextureBuffer(Texture))
   Color(255,000,255) : Plot(PickedTX,PickedTY)
  EndIf
 EndIf

 SetBuffer(BackBuffer())
 RenderWorld()

 Color(255,255,255)
 Text(0,0,"Mouse Left to pick / color texels on the texture")
 Text(0,16,"Arrows to turn the shape up, down, left, right")

 Flip(True)

Wend

End()

Function CalculatePickedUVvFredborg()

  If( PickedSurface() )

picent = PickedEntity()
picsurf = PickedSurface()
pictri  = PickedTriangle()

picpx# = PickedX()
picpy# = PickedY()
picpz# = PickedZ()

Local picvx#[3], picvy#[3], picvz#[3]
;Local picvnx#[3], picvny#[3], picvnz#[3]
Local picvu#[3], picvv#[3] ; picvw#[3]
Local picpu#[1], picpv#[1] ; picpw#[1]

For i = 0 To 2

TFormPoint(VertexX(picsurf,TriangleVertex(picsurf,pictri,i)),VertexY(picsurf,TriangleVertex(picsurf,pictri,i)),VertexZ(picsurf,TriangleVertex(picsurf,pictri,i)),picent,0)

picvx[i] = TFormedX()
picvy[i] = TFormedY()
picvz[i] = TFormedZ()

;picvnx[i] = VertexNX(picsurf,TriangleVertex(picsurf,pictri,i))
;picvny[i] = VertexNY(picsurf,TriangleVertex(picsurf,pictri,i))
;picvnz[i] = VertexNZ(picsurf,TriangleVertex(picsurf,pictri,i))

picvu[i+0] = VertexU(picsurf,TriangleVertex(picsurf,pictri,i),0)
picvv[i+0] = VertexV(picsurf,TriangleVertex(picsurf,pictri,i),0)
;picvw[i+0] = VertexW(picsurf,TriangleVertex(picsurf,pictri,i),0)

Next

; Select which component of xyz coordinates to ignore
Local coords = 3

If Abs(PickedNX()) > Abs(PickedNY())
If Abs(PickedNX())>Abs(PickedNZ()) Then coords = 1
Else
If Abs(PickedNY())>Abs(PickedNZ()) Then coords = 2
EndIf

Local a0#,a1#,b0#,b1#,c0#,c1#

; xy components
If (coords = 3)
; edge 0
a0# = picvx[1] - picvx[0]
a1# = picvy[1] - picvy[0]

; edge 1
b0# = picvx[2] - picvx[0]
b1# = picvy[2] - picvy[0]

; picked offset from triangle vertex 0
c0# = PickedX() - picvx[0]
c1# = PickedY() - picvy[0]
Else
; xz components
If (coords = 2)
; edge 0
a0# = picvx[1] - picvx[0]
a1# = picvz[1] - picvz[0]

; edge 1
b0# = picvx[2] - picvx[0]
b1# = picvz[2] - picvz[0]

; picked offset from triangle vertex 0
c0# = PickedX() - picvx[0]
c1# = PickedZ() - picvz[0]
Else
; yz components

; edge 0
a0# = picvy[1] - picvy[0]
a1# = picvz[1] - picvz[0]

; edge 1
b0# = picvy[2] - picvy[0]
b1# = picvz[2] - picvz[0]

; picked offset from triangle vertex 0
c0# = PickedY() - picvy[0]
c1# = PickedZ() - picvz[0]
End If
End If

;
; u and v are offsets from vertex 0 along edge 0 and edge 1
; using these it is possible to calculate the Texture UVW coordinates
; of the picked XYZ location
;
; a0*u + b0*v = c0
; a1*u + b1*v = c1
;
; solve equation (standard equation with 2 unknown quantities)
; check a math book to see why the following is true
;
Local u# = (c0*b1 - b0*c1) / (a0*b1 - b0*a1)
Local v# = (a0*c1 - c0*a1) / (a0*b1 - b0*a1)

; If either u or v is out of range then the
; picked entity was not a mesh, and therefore
; the uvw coordinates cannot be calculated
If ( u < 0.0 Or u > 1.0 ) Or ( v < 0.0 Or v > 1.0 )
Return
End If

; Calculate picked uvw's for coordset 0 (and modulate them to be in the range of 0-1 nescessary)
picpu[0] = (picvu[0] + ((picvu[1] - picvu[0]) * u) + ((picvu[2] - picvu[0]) * v)) Mod 1
picpv[0] = (picvv[0] + ((picvv[1] - picvv[0]) * u) + ((picvv[2] - picvv[0]) * v)) Mod 1
;picpw[0] = (picvw[0] + ((picvw[1] - picvw[0]) * u) + ((picvw[2] - picvw[0]) * v)) Mod 1

; If any of the coords are negative
If( picpu[0] < 0.0 ) Then picpu[0] = 1.0 + picpu[0]
If( picpv[0] < 0.0 ) Then picpv[0] = 1.0 + picpv[0]
        ;If( picpw[0] < 0.0 ) Then picpw[0] = 1.0 + picpw[0]

PickedU = picpu[0] : PickedV = picpv[0]

End If

End Function
Thanks again Fredborg
« Last Edit: November 25, 2018, 09:08:02 by RemiD »
DualCore AMD E-450, 1646 MHz - 6 Go DDR3 1333 SDRAM - AMD Radeon HD 6320 Graphics (384 Mo) - Windows 7 Home Premium - DirectX 11.0

Offline peteswansen

  • Jr. Member
  • **
  • Posts: 68
As usual Remi's coding is really good....so I have been modifying this to load a model in and then "painting" the model in larger blocks of color...nice bit of fun!!

Offline _PJ_

  • Full Member
  • ***
  • Posts: 110
What an amazingly useful set of functions!!!
These really belonged in B3D from the start.

Thanks very much RemiD!

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal