He is my function to perform 3d object selection. It works for all camera rotations.
The first code is the function source and should be added to your project.
Rem *** Include File: fnMousePick.dba ***
Rem Created: 26/03/2003 09:31:08
Rem Included in Project: C:\Program Files\Dark Basic Software\Dark Basic Professional\Projects\Mouse Pick\Mouse Pick.dbpro
Global vx#
Global vy#
Global vz#
Function ProjectMouse(dist#)
Remstart
ProjectMouse - Written By Jason Clogg
based on DBv1 code snippet I created on Dark Basic Archive
Credit to Kensupen for the vector code from his 3D Mouse Selection
This function returns the 3d Coords of the mouse for a given distance from the camera
the co-ords are returned in the global variables vx#,vy#, & vz#
To perform object intersection correctly using this function you must call it twice to
get a nearpoint for the mouse and a farpoint.
example
ProjectMouse(1):sx#=vx#:sy#=vy#:sz#=vz#
ProjectMouse(5000):ex#=vx#:ey#=vy#:ez#=vz#
for check=FirstObject to LastObject
ObjDist#=intersect object(check,sx#,sy#,sz#,ex#,ey#,ez#)
if ObjDist#>0
' object 'check' has been hit
endif
next check
remend
Local DKMatView As Integer
Local DKVector As Integer
Local DKLineEnd As Integer
DKVector=1
DKLineEnd=2
DKMatView=3
r=Make Matrix4(DKMatView)
r=Make Vector3(DKVector)
r=Make Vector3(DKLineEnd)
px#=(((dist#*.8)+.8)*2)/screen width()
py#=(((dist#*.6)+.6)*2)/screen height()
CAX#=camera angle x()
CAY#=camera angle y()
CAZ#=camera angle z()
CPX#=camera position x()
CPY#=camera position y()
CPZ#=camera position z()
mx#=mousex()
my#=mousey()
rem calculate forward vector for camera
X#=(mx#*px#)-((dist#*.8)+.8)
Y#=((dist#*.6)+.6)-(my#*py#)
Z#=dist#
View Matrix4 DKMatView
r#=Inverse Matrix4(DKMatView, DKMatView)
Set Vector3 DKVector, dist#*X#, dist#*Y#, dist#*Z#
Transform Coords Vector3 DKLineEnd, DKVector, DKMatView
vx#=x vector3(DKLineEnd)
vy#=y vector3(DKLineEnd)
vz#=z vector3(DKLineEnd)
res=delete vector3(DKMatView)
res=delete vector3(DKVector)
res=delete vector3(DKLineEnd)
EndFunction
Function NearestObjIntersection(FirstObject,LastObject)
Remstart
NearestObjIntersection - Written By Jason Clogg
This function returns the object number of the nearest object selected by the mouse cursor
example
HitObj=NearestObjIntersection(firstobject,lastobject)
if HitObj>0 then
'Object has been hit
endif
remend
HitObj=0
NearObjDist#=99999999
projectMouse(1):sx#=vx#:sy#=vy#:sz#=vz#
projectMouse(5000):ex#=vx#:ey#=vy#:ez#=vz#
for check=FirstObject to LastObject
rem Check intersection with each object
ObjDist#=intersect object(check,sx#,sy#,sz#,ex#,ey#,ez#)
if ObjDist#>0
rem if intersection occurs only store object number if nearer than current nearest
if ObjDist#0 then
color object HitObj,rgb(255,0,0)
endif
text 0,0,"3d Object Selection Code " + str$(screen fps())+ " " + str$(HitObj)
text 0,15,"Written By Jason Clogg"
text 0,30,"Keyboard Controls"
text 0,45,"Cursor keys Rotate camera on x/y axis"
text 0,60,"'a,d' Rotate camera on z axis"
text 0,75,"mousebutton 2 and mouse the move forwards/backwards"
text 0,90,"mousebutton 1 to select object"
sync
if HitObj>0 then color object HitObj,rgb(0,255,0)
loop
end
Seems to run resonably fast, even for a few hundred objects.
Cheers,
Jason