I thought it was a nice problem, so I tried to figure it out. This routine imitates the CameraPick with a LinePick. It uses CameraPick to initialize, and later on, it interpolates these coords to use it on LinePick:
;setup graphics
Graphics3D 800, 600, 0, 2
SetBuffer BackBuffer()
;create camera
cam = CreateCamera()
;set far/near range
InitCoords(cam, 1, 1000)
MoveEntity cam, 0, 0, -15
;setup cubes
For i = 0 To 100
cube = CreateCube()
EntityColor cube, Rand(255), Rand(255), Rand(255)
PositionEntity cube, Rnd(-10, 10), Rnd(-10, 10), Rnd(0, 10)
EntityPickMode cube, 2
Next
;main loop
Repeat
If KeyDown(203) Then MoveEntity cam, +0.1, 0, 0
If KeyDown(205) Then MoveEntity cam, -0.1, 0, 0
If KeyDown(200) Then MoveEntity cam, 0, -0.1, 0
If KeyDown(208) Then MoveEntity cam, 0, +0.1, 0
RenderWorld()
CamPick cam, MouseX(), MouseY()
Text 0, 0, PickedEntity()
Flip
Until KeyHit(1)
End
;-----------------------------------------------------------------------------------------------------
; InitCoords()
;-----------------------------------------------------------------------------------------------------
Dim cx#(0, 0)
Dim cy#(0, 0)
Dim cz#(0, 0)
Function InitCoords(cam, near#, far#)
;to store points
Dim cx#(1, 1)
Dim cy#(1, 1)
Dim cz#(1, 1)
;set camerarange
CameraRange cam, near#, far# + 1
;create picking plane
plane = CreatePlane(1, cam)
PositionEntity plane, 0, 0, 0
RotateEntity plane, -90, 0, 0
EntityPickMode plane, 2
;place plane near
PositionEntity plane, 0, 0, near#
;pick upperleft corner
CameraPick cam, 0, 0
TFormPoint PickedX(), PickedY(), PickedZ(), 0, cam
cx(0, 0) = TFormedX()
cy(0, 0) = TFormedY()
cz(0, 0) = TFormedZ()
;pick right corner
CameraPick cam, GraphicsWidth(), 0
TFormPoint PickedX(), PickedY(), PickedZ(), 0, cam
cx(0, 1) = TFormedX()
;pick bottom corner
CameraPick cam, 0, GraphicsHeight()
TFormPoint PickedX(), PickedY(), PickedZ(), 0, cam
cy(0, 1) = TFormedY()
;place plane far
PositionEntity plane, 0, 0, far#
;pick upperleft corner
CameraPick cam, 0, 0
TFormPoint PickedX(), PickedY(), PickedZ(), 0, cam
cx(1, 0) = TFormedX()
cy(1, 0) = TFormedY()
cz(1, 0) = TFormedZ()
;pick right corner
CameraPick cam, GraphicsWidth(), 0
TFormPoint PickedX(), PickedY(), PickedZ(), 0, cam
cx(1, 1) = TFormedX()
;pick bottom corner
CameraPick cam, 0, GraphicsHeight()
TFormPoint PickedX(), PickedY(), PickedZ(), 0, cam
cy(1, 1) = TFormedY()
;free temp. plane
FreeEntity plane
;set camerarange
CameraRange cam, near#, far#
End Function
;-----------------------------------------------------------------------------------------------------
; CamPick()
;-----------------------------------------------------------------------------------------------------
Function CamPick(cam, x, y)
;convert x/y in range 0..1
px2# = x / Float(GraphicsWidth())
py2# = y / Float(GraphicsHeight())
px# = 1 - px2
py# = 1 - py2
;convert to near 'corner' coordinates (from initcoords)
x1# = (cx(0, 0) * px + cx(0, 1) * px2)
y1# = (cy(0, 0) * py + cy(0, 1) * py2)
z1# = cz(0, 0)
;convert to far 'corner' coordinates (from initcoords)
x2# = (cx(1, 0) * px + cx(1, 1) * px2)
y2# = (cy(1, 0) * py + cy(1, 1) * py2)
z2# = cz(1, 0)
;convert to current cameraposition
TFormPoint x1, y1, z1, cam, 0
x1# = TFormedX()
y1# = TFormedY()
z1# = TFormedZ()
TFormPoint x2, y2, z2, cam, 0
x2# = TFormedX()
y2# = TFormedY()
z2# = TFormedZ()
;perform linepick
LinePick x1, y1, z1, x2 - x1, y2 - y1, z2 - z1
;debug preview dots
Color 255, 0, 0 ;near=red
CameraProject cam, x1, y1, z1
Oval ProjectedX() - 5, ProjectedY() - 5, 11, 11
Color 255, 255, 255 ;far=white
CameraProject cam, x2, y2, z2
Oval ProjectedX() - 2, ProjectedY() - 2, 5, 5
End Function
And if you want to adjust the far/near variables realtime, you could interpolate between the start and end point of the picking line.