Here's the code I used:
If LinePick(EntityX(Entity), EntityY(Entity), EntityZ(Entity), 0, -15, 0, 0)
If PickedUVW()
ARGB = GetTexColor(LMapTex, PickedU(1), PickedV(1)) And $FFFFFF
R = (ARGB Shr 16 And %11111111) + 20
G = (ARGB Shr 8 And %11111111) + 20
B = (ARGB And %11111111) + 20
If R > 255 Then R = 255
If G > 255 Then G = 255
If B > 255 Then B = 255
EntityColor(Entity, R, G, B)
EndIf
EndIf
Function GetTexColor(tex,u#,v#)
u#=u#*(TextureWidth(tex)-1)
v#=v#*(TextureHeight(tex)-1)
col=ReadPixel(u,v,TextureBuffer(tex))
Return col
End Function
Type PickedTri
Field ent,surf,tri ;picked entity, surface and triangle
Field px#,py#,pz# ;picked xyz
Field pu#[1], pv#[1] ,pw#[1] ;picked uvw x 2
Field vx#[2], vy#[2] ,vz#[2] ;vertex xyz
Field vnx#[2], vny#[2] ,vnz#[2] ;vertex normals
Field vu#[5], vv#[5] ,vw#[5] ;vertex uvw x 2
End Type
Global g_PickedTri.pickedtri = New pickedtri
Function PickedU#(coordset = 0)
ptri.pickedtri = g_PickedTri
If (PickedX()<>ptri\px) Or (PickedY()<>ptri\py) Or (PickedZ()<>ptri\pz) Or (PickedSurface()<>ptri\surf)
uvwTime=PickedUVW()
End If
Return ptri\pu[coordset]
End Function
Function PickedV#(coordset = 0)
ptri.pickedtri = g_PickedTri
If (PickedX()<>ptri\px) Or (PickedY()<>ptri\py) Or (PickedZ()<>ptri\pz) Or (PickedSurface()<>ptri\surf)
uvwTime=PickedUVW()
End If
Return ptri\pv[coordset]
End Function
Function PickedW#(coordset = 0)
ptri.pickedtri = g_PickedTri
If (PickedX()<>ptri\px) Or (PickedY()<>ptri\py) Or (PickedZ()<>ptri\pz) Or (PickedSurface()<>ptri\surf)
uvwTime=PickedUVW()
End If
Return ptri\pw[coordset]
End Function
Function PickedUVW()
ptri.pickedtri = g_PickedTri
If EntityClass(PickedEntity()) = "Terrain"
terrain = PickedEntity()
tsize# = TerrainSize(terrain)
TFormPoint(PickedX(), PickedY(), PickedZ(), 0, terrain)
ptri\pu[0] = TFormedX() / tsize
ptri\pv[0] = 1.0 - (TFormedZ() / tsize)
ptri\pu[1] = ptri\pu[0]
ptri\pv[1] = ptri\pv[0]
Return True
EndIf
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,0
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
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#
If (coords = 3)
a0# = ptri\vx[1] - ptri\vx[0]
a1# = ptri\vy[1] - ptri\vy[0]
b0# = ptri\vx[2] - ptri\vx[0]
b1# = ptri\vy[2] - ptri\vy[0]
c0# = PickedX() - ptri\vx[0]
c1# = PickedY() - ptri\vy[0]
Else
If (coords = 2)
a0# = ptri\vx[1] - ptri\vx[0]
a1# = ptri\vz[1] - ptri\vz[0]
b0# = ptri\vx[2] - ptri\vx[0]
b1# = ptri\vz[2] - ptri\vz[0]
c0# = PickedX() - ptri\vx[0]
c1# = PickedZ() - ptri\vz[0]
Else
a0# = ptri\vy[1] - ptri\vy[0]
a1# = ptri\vz[1] - ptri\vz[0]
b0# = ptri\vy[2] - ptri\vy[0]
b1# = ptri\vz[2] - ptri\vz[0]
c0# = PickedY() - ptri\vy[0]
c1# = PickedZ() - ptri\vz[0]
End If
End If
Local u# = (c0*b1 - b0*c1) / (a0*b1 - b0*a1)
Local v# = (a0*c1 - c0*a1) / (a0*b1 - b0*a1)
If (u<0.0 Or u>1.0) Or (v<0.0 Or v>1.0)
Return False
End If
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 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]
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 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]
Return True
End If
Return False
End Function
Some hints:
- Don't linepick() every frame, instead, store the entity position of the last pick, and only do another linepick when the difference from the current position is greater than some thresold, this way if your character is stopped there's no processing at alll.
- Don't forget to create at least one directional dynamic light to shade your character.
|