If there's a better place to post this for posterity please let me know.
This is just a conversion of Mikkel Fredborg's PickedUVW code, without the example code. It isn't greatly tested yet, but so far it looks like it's doing the core of what it's supposed to (find the U/V coord of the texture on a picked entity, from which one can find the X/Y coord of the texture itself and then do any further figuring easily, i.e. transparency).
A note about use. You must use a pick command (CameraPick, LinePick, etc.) BEFORE calling any of the other commands as it uses the last picked item as it's target. Additionally you should only use PickedU(), PickedV() and PickedW() as it stores all the values whenever you make the first call to any of them after changing your picked elements, so it doesn't need to run all the point finding every time you call any of the functions. Quite a nice optimization in Mikkel's part I think.
This is just a conversion of Mikkel Fredborg's PickedUVW code, without the example code. It isn't greatly tested yet, but so far it looks like it's doing the core of what it's supposed to (find the U/V coord of the texture on a picked entity, from which one can find the X/Y coord of the texture itself and then do any further figuring easily, i.e. transparency).
A note about use. You must use a pick command (CameraPick, LinePick, etc.) BEFORE calling any of the other commands as it uses the last picked item as it's target. Additionally you should only use PickedU(), PickedV() and PickedW() as it stores all the values whenever you make the first call to any of them after changing your picked elements, so it doesn't need to run all the point finding every time you call any of the functions. Quite a nice optimization in Mikkel's part I think.
SuperStrict Import sidesign.minib3d Rem ; Created by Mikkel Fredborg ; Adapted for MiniB3D by Logan Chittenden ; ; Use as you please, but please Include a thank you :) ; End Rem '; PickedTri Type '; Necessary For the PickedU(), PickedV(), And PickedW() commands Type PickedTri Field ent:TEntity,surf:TSurface,tri:Float ';picked entity, surface And triangle Field px:Float,py:Float,pz:Float ';picked xyz Field pu:Float[1], pv:Float[1] ,pw:Float[1] ';picked uvw x 2 Field vx:Float[2], vy:Float[2] ,vz:Float[2] ';vertex xyz Field vnx:Float[2], vny:Float[2] ,vnz:Float[2] ';vertex normals Field vu:Float[5], vv:Float[5] ,vw:Float[5] ';vertex uvw x 2 End Type Global ptri:pickedtri = New pickedtri '; Returns the Texture U coordinate of the last successful pick command '; coordset may be set To either 0 Or 1 Function PickedU:Float(coordset:Byte = 0) '; If something New has been picked Then calculate the New uvw coordinates If (PickedX()<>ptri.px) Or (PickedY()<>ptri.py) Or (PickedZ()<>ptri.pz) Or (PickedSurface()<>ptri.surf) PickedUVW() End If Return ptri.pu[coordset] End Function '; Returns the Texture U coordinate of the last successful pick command '; coordset may be set To either 0 Or 1 Function PickedV:Float(coordset:Byte = 0) '; If something New has been picked Then calculate the New uvw coordinates If (PickedX()<>ptri.px) Or (PickedY()<>ptri.py) Or (PickedZ()<>ptri.pz) Or (PickedSurface()<>ptri.surf) PickedUVW() End If Return ptri.pv[coordset] End Function '; Returns the Texture U coordinate of the last successful pick command '; coordset may be set To either 0 Or 1 Function PickedW:Float(coordset:Byte = 0) '; If something New has been picked Then calculate the New uvw coordinates If (PickedX()<>ptri.px) Or (PickedY()<>ptri.py) Or (PickedZ()<>ptri.pz) Or (PickedSurface()<>ptri.surf) PickedUVW() End If Return ptri.pw[coordset] End Function '; Calculates the UVW coordinates of a pick '; Do Not call this by yourself, as PickedU(), PickedV(), And PickedW() '; takes care of calling it when nescessary Function PickedUVW() Local i:Byte If PickedSurface() ptri.ent = PickedEntity() ptri.surf = PickedSurface() ptri.tri = PickedTriangle() ptri.px = PickedX() ptri.py = PickedY() ptri.pz = PickedZ() For i = 0 To 2 TFormPoint VertexX(ptri.surf,TriangleVertex(ptri.surf,ptri.tri,i)),VertexY(ptri.surf,TriangleVertex(ptri.surf,ptri.tri,i)),VertexZ(ptri.surf,TriangleVertex(ptri.surf,ptri.tri,i)),ptri.ent,Null ptri.vx[i] = TFormedX() ptri.vy[i] = TFormedY() ptri.vz[i] = TFormedZ() ptri.vnx[i] = VertexNX(ptri.surf,TriangleVertex(ptri.surf,ptri.tri,i)) ptri.vny[i] = VertexNY(ptri.surf,TriangleVertex(ptri.surf,ptri.tri,i)) ptri.vnz[i] = VertexNZ(ptri.surf,TriangleVertex(ptri.surf,ptri.tri,i)) ptri.vu[i+0] = VertexU(ptri.surf,TriangleVertex(ptri.surf,ptri.tri,i),0) ptri.vv[i+0] = VertexV(ptri.surf,TriangleVertex(ptri.surf,ptri.tri,i),0) ptri.vw[i+0] = VertexW(ptri.surf,TriangleVertex(ptri.surf,ptri.tri,i),0) ptri.vu[i+3] = VertexU(ptri.surf,TriangleVertex(ptri.surf,ptri.tri,i),1) ptri.vv[i+3] = VertexV(ptri.surf,TriangleVertex(ptri.surf,ptri.tri,i),1) ptri.vw[i+3] = VertexW(ptri.surf,TriangleVertex(ptri.surf,ptri.tri,i),1) Next '; Select which component of xyz coordinates To ignore Local coords:Byte = 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:Float,a1:Float,b0:Float,b1:Float,c0:Float,c1:Float '; xy components If (coords = 3) '; edge 0 a0 = ptri.vx[1] - ptri.vx[0] a1 = ptri.vy[1] - ptri.vy[0] '; edge 1 b0 = ptri.vx[2] - ptri.vx[0] b1 = ptri.vy[2] - ptri.vy[0] '; picked offset from triangle vertex 0 c0 = PickedX() - ptri.vx[0] c1 = PickedY() - ptri.vy[0] Else '; xz components If (coords = 2) '; edge 0 a0 = ptri.vx[1] - ptri.vx[0] a1 = ptri.vz[1] - ptri.vz[0] '; edge 1 b0 = ptri.vx[2] - ptri.vx[0] b1 = ptri.vz[2] - ptri.vz[0] '; picked offset from triangle vertex 0 c0 = PickedX() - ptri.vx[0] c1 = PickedZ() - ptri.vz[0] Else '; yz components '; edge 0 a0 = ptri.vy[1] - ptri.vy[0] a1 = ptri.vz[1] - ptri.vz[0] '; edge 1 b0 = ptri.vy[2] - ptri.vy[0] b1 = ptri.vz[2] - ptri.vz[0] '; picked offset from triangle vertex 0 c0 = PickedY() - ptri.vy[0] c1 = PickedZ() - ptri.vz[0] End If End If Rem ; 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 ; End Rem Local u:Float = (c0*b1 - b0*c1) / (a0*b1 - b0*a1) Local v:Float = (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) ptri.pu[0] = (ptri.vu[0] + ((ptri.vu[1] - ptri.vu[0]) * u) + ((ptri.vu[2] - ptri.vu[0]) * v)) Mod 1 ptri.pv[0] = (ptri.vv[0] + ((ptri.vv[1] - ptri.vv[0]) * u) + ((ptri.vv[2] - ptri.vv[0]) * v)) Mod 1 ptri.pw[0] = (ptri.vw[0] + ((ptri.vw[1] - ptri.vw[0]) * u) + ((ptri.vw[2] - ptri.vw[0]) * v)) Mod 1 '; If any of the coords are negative If ptri.pu[0]<0.0 Then ptri.pu[0] = 1.0 + ptri.pu[0] If ptri.pv[0]<0.0 Then ptri.pv[0] = 1.0 + ptri.pv[0] If ptri.pw[0]<0.0 Then ptri.pw[0] = 1.0 + ptri.pw[0] '; Calculate picked uvw's for coordset 1 (and modulate them to be in the range of 0-1 nescessary) ptri.pu[1] = (ptri.vu[3] + ((ptri.vu[4] - ptri.vu[3]) * u) + ((ptri.vu[5] - ptri.vu[3]) * v)) Mod 1 ptri.pv[1] = (ptri.vv[3] + ((ptri.vv[4] - ptri.vv[3]) * u) + ((ptri.vv[5] - ptri.vv[3]) * v)) Mod 1 ptri.pw[1] = (ptri.vw[3] + ((ptri.vw[4] - ptri.vw[3]) * u) + ((ptri.vw[5] - ptri.vw[3]) * v)) Mod 1 '; If any of the coords are negative If ptri.pu[1]<0.0 Then ptri.pu[1] = 1.0 + ptri.pu[1] If ptri.pv[1]<0.0 Then ptri.pv[1] = 1.0 + ptri.pv[1] If ptri.pw[1]<0.0 Then ptri.pw[1] = 1.0 + ptri.pw[1] End If End Function