This code detects if the mouse is hovering over an object. It's fast on high poly objects, but not on too many low poly objects (due to the speed of "object screen" commands). It could be good for level editors.
It uses 2 functions, the first is "update object pick()" which stores the memblock data of an object in an array, to reduce slowdown. This means that whenever you move/rotate/scale an object you should update it to have accurate detection. "pick object" returns a 1 if the mouse is on the object.
Syntax:
pick object(object number)
update pick object(object number)
Below is an example with functions. Up+down = zoom.
It's probably best used in conjunction with a distance test for relatively cube shaped objects.
FIXED CODE BELOW, NOT IN SOURCE BUTTON!!!
`Pick object for DBC
`By Hamish McHaggis
`5/9/03
`-------------------------------------
`Put this in all programs
`-------------------------------------
`Vertex data arrays
dim vertX#(100,2000,2)
dim vertY#(100,2000,2)
dim vertZ#(100,2000,2)
dim screenX(100,1000,2)
dim screenY(100,1000,2)
dim numFaces(100)
make object plain 65535,0,0
hide object 65535
`-------------------------------------
autocam off
sync on
sync rate 0
position camera 0,30,-50
point camera 0,0,0
`Make objects
make object cube 1,10
make object sphere 2,10
make object cone 3,10
make object cylinder 4,10
make object plain 5,10,10
make object box 6,3,10,10
position object 1,-20,0,0
position object 2,0,0,0
position object 3,20,0,0
position object 4,-20,0,-20
position object 5,0,0,-20
position object 6,20,0,-20
`Update object data
for x=1 to 6
update pick object(x)
next x
do
`Loop through to test if objects are hovered over, if so then colour
for x=1 to 6
if pick object(x)=1
color object x,rgb(255,0,0)
else
color object x,rgb(255,255,255)
endif
next x
`Camera zoom
if upkey()=1 then move camera 0.5
if downkey()=1 then move camera -0.5
text 20,20,"FPS: "+str$(screen fps())
sync
loop
`See if mouse is hovered over object
function pick object(obj)
`If the object isn't on screen then don't test it
if object in screen(obj)=0 then exitfunction 0
`Get mouse coordinates
mouseX=mousex()
mouseY=mousey()
`Reset flag
pick=0
`Loop through faces
for x = 0 to numFaces(obj)-1
`Loop through verteces
for y = 0 to 2
`Get screen coords for vertices
position object 65535,vertX#(obj,x,y),vertY#(obj,x,y),vertZ#(obj,x,y)
screenX(obj,x,y) = object screen x(65535)
screenY(obj,x,y) = object screen y(65535)
next y
`If mouse is above, below or beside the poly then don't test this one
if mouseX>screenX(obj,x,0) and mouseX>screenX(obj,x,1) and mouseX>screenX(obj,x,2) then goto nextTri
if mouseX<screenX(obj,x,0) and mouseX<screenX(obj,x,1) and mouseX<screenX(obj,x,2) then goto nextTri
if mouseY>screenY(obj,x,0) and mouseY>screenY(obj,x,1) and mouseY>screenX(obj,x,2) then goto nextTri
if mouseY<screenY(obj,x,0) and mouseY<screenY(obj,x,1) and mouseY<screenX(obj,x,2) then goto nextTri
`Work out the vectors and normals of vertices
vectX1=mouseX-screenX(obj,x,0)
vectY1=mouseY-screenY(obj,x,0)
normX1=0-(screenY(obj,x,1)-screenY(obj,x,0))
normY1=screenX(obj,x,1)-screenX(obj,x,0)
vectX2=mouseX-screenX(obj,x,1)
vectY2=mouseY-screenY(obj,x,1)
normX2=0-(screenY(obj,x,2)-screenY(obj,x,1))
normY2=screenX(obj,x,2)-screenX(obj,x,1)
vectX3=mouseX-screenX(obj,x,2)
vectY3=mouseY-screenY(obj,x,2)
normX3=0-(screenY(obj,x,0)-screenY(obj,x,2))
normY3=screenX(obj,x,0)-screenX(obj,x,2)
`Get dot products of normals/vectors
dot01#=vectX1*normX1+vectY1*normY1
dot12#=vectX2*normX2+vectY2*normY2
dot20#=vectX3*normX3+vectY3*normY3
`Work out if mouse is inside poly screen coords
if (dot01#>=0 and dot12#>=0 and dot20#>=0) or (dot01#<=0 and dot12#<=0 and dot20#<=0) then exitfunction 1
nextTri:
next x
endfunction 0
`Update 3D vertex information
function update pick object(obj)
`Make mesh from object and store info in memblock
make mesh from object 1,obj
make memblock from mesh 1,1
`Get number of faces and the face offset for object
numFaces(obj) = memblock dword(1,16)
faceOffset = memblock dword(1,20)
`Loop through faces
for x = 0 to numFaces(obj)-1
`Loop through verteces
for y = 0 to 2
`Get vertex index number
vertNum = memblock dword(1,faceOffset+(x*28)+4+y*8)
`Get vertex position
vertX#(obj,x,y) = memblock float(1,32+(vertNum*12))
vertY#(obj,x,y) = memblock float(1,32+(vertNum*12)+4)
vertZ#(obj,x,y) = memblock float(1,32+(vertNum*12)+8)
next y
next x
endfunction
100 Cubes test...
`Pick object for DBC
`By Hamish McHaggis
`5/9/03
`-------------------------------------
`Put this in all programs
`-------------------------------------
`Vertex data arrays
dim vertX#(1000,2000,2)
dim vertY#(1000,2000,2)
dim vertZ#(1000,2000,2)
dim screenX(1000,1000,2)
dim screenY(1000,1000,2)
dim numFaces(1000)
make object plain 65535,0,0
hide object 65535
`-------------------------------------
autocam off
sync on
sync rate 0
position camera 0,60,-50
point camera 0,0,50
`Number of cubes
xcube=10
zcube=10
`Make objects
for y=0 to zcube-1
for x=1 to xcube
make object cube x+y*xcube,10
position object x+y*10,-10*xcube+20*x-10,y*5,20*y
next x
next y
`Update object data
for x=1 to xcube*zcube
update pick object(x)
next x
do
`Loop through to test if objects are hovered over, if so then colour
for x=1 to xcube*zcube
if pick object(x)=1
color object x,rgb(255,0,0)
else
color object x,rgb(255,255,255)
endif
next x
`Camera zoom
if upkey()=1 then move camera 1
if downkey()=1 then move camera -1
text 20,20,"FPS: "+str$(screen fps())
sync
loop
`See if mouse is hovered over object
function pick object(obj)
`If the object isn't on screen then don't test it
if object in screen(obj)=0 then exitfunction 0
`Get mouse coordinates
mouseX=mousex()
mouseY=mousey()
`Reset flag
pick=0
`Loop through faces
for x = 0 to numFaces(obj)-1
`Loop through verteces
for y = 0 to 2
`Get screen coords for vertices
position object 65535,vertX#(obj,x,y),vertY#(obj,x,y),vertZ#(obj,x,y)
screenX(obj,x,y) = object screen x(65535)
screenY(obj,x,y) = object screen y(65535)
next y
`If mouse is above, below or beside the poly then don't test this one
if mouseX>screenX(obj,x,0) and mouseX>screenX(obj,x,1) and mouseX>screenX(obj,x,2) then goto nextTri
if mouseX<screenX(obj,x,0) and mouseX<screenX(obj,x,1) and mouseX<screenX(obj,x,2) then goto nextTri
if mouseY>screenY(obj,x,0) and mouseY>screenY(obj,x,1) and mouseY>screenX(obj,x,2) then goto nextTri
if mouseY<screenY(obj,x,0) and mouseY<screenY(obj,x,1) and mouseY<screenX(obj,x,2) then goto nextTri
`Work out the vectors and normals of vertices
vectX1=mouseX-screenX(obj,x,0)
vectY1=mouseY-screenY(obj,x,0)
normX1=0-(screenY(obj,x,1)-screenY(obj,x,0))
normY1=screenX(obj,x,1)-screenX(obj,x,0)
dot01#=vectX1*normX1+vectY1*normY1
vectX2=mouseX-screenX(obj,x,1)
vectY2=mouseY-screenY(obj,x,1)
normX2=0-(screenY(obj,x,2)-screenY(obj,x,1))
normY2=screenX(obj,x,2)-screenX(obj,x,1)
dot12#=vectX2*normX2+vectY2*normY2
`Work out if mouse is inside poly screen coords
if (dot01#<=0 and dot12#>=0) or (dot01#>=0 and dot12#<=0) then goto nextTri
vectX3=mouseX-screenX(obj,x,2)
vectY3=mouseY-screenY(obj,x,2)
normX3=0-(screenY(obj,x,0)-screenY(obj,x,2))
normY3=screenX(obj,x,0)-screenX(obj,x,2)
dot20#=vectX3*normX3+vectY3*normY3
`Work out if mouse is inside poly screen coords
if (dot01#>=0 and dot12#>=0 and dot20#>=0) or (dot01#<=0 and dot12#<=0 and dot20#<=0) then exitfunction 1
nextTri:
next x
endfunction 0
`Update 3D vertex information
function update pick object(obj)
`Make mesh from object and store info in memblock
make mesh from object 1,obj
make memblock from mesh 1,1
`Get number of faces and the face offset for object
numFaces(obj) = memblock dword(1,16)
faceOffset = memblock dword(1,20)
`Loop through faces
for x = 0 to numFaces(obj)-1
`Loop through verteces
for y = 0 to 2
`Get vertex index number
vertNum = memblock dword(1,faceOffset+(x*28)+4+y*8)
`Get vertex position
vertX#(obj,x,y) = memblock float(1,32+(vertNum*12))
vertY#(obj,x,y) = memblock float(1,32+(vertNum*12)+4)
vertZ#(obj,x,y) = memblock float(1,32+(vertNum*12)+8)
next y
next x
endfunction
Brains are for idiots.
Athelon XP 1400 Plus - Nvidia Geforce MX400 - 256mb RAM