Just for anyone who is interested in the equation I worked out while walking the dog...
The code currently looks for the two closest corners of the object to the point we are looking at:
_SELECT_POINT:
`get all vertices
`Pick object
prevbest#=100000
BestD#=100000
p=pick object(sw/2,sh/2,StartObj,3999)
if p=0 then p=pick object(sw/2-5,sh/2,StartObj,3999)
if p=0 then p=pick object(sw/2+5,sh/2,StartObj,3999)
if p=0 then p=pick object(sw/2,sh/2-5,StartObj,3999)
if p=0 then p=pick object(sw/2,sh/2+5,StartObj,3999)
if p=0 then p=pick object(sw/2,sh/2,StartObj,3999)
if p<>0 and p<>hinge
pd#=get pick distance()
px#=get pick vector x()
py#=get pick vector y()
pz#=get pick vector z()
wx#=px#+camera position x()
wy#=py#+camera position y()
wz#=pz#+camera position z()
`closest match
limbcount=GET LIMB COUNT(p)
`if limbcount>0
vcount=0
for n = 0 to 10
if limb exist(p,n)
LOCK VERTEXDATA FOR LIMB p,n,1
if limb exist(p,n)
vcount=vcount+get vertexdata vertex count()
if vcount>0 and limbcount=1 then MainLimb=n
endif
unlock vertexdata
endif
next n
`endif
if vcount>0
`loop through limbs
for x = 0 to limbcount
LOCK VERTEXDATA FOR LIMB p,x
vmax=get vertexdata vertex count()
`loop through vertices
if vmax>0
for v=0 to vmax-1
` Place into vertex 1 the position of object p, limb x, vertex v
GetVertexPosition(1, p, x, v)
x#=(x vector3(1)-object position x(p))+object position x(p)
y#=(y vector3(1)-object position y(p))+object position y(p)
z#=(z vector3(1)-object position z(p))+object position z(p)
diffx# = x#-wx#
diffy# = y#-wy#
diffz# = z#-wz#
distance#=sqrt(diffx#^2+diffy#^2+diffz#^2)
if distance#<prevbest#
prevbest#=distance#
if distance#<BestD#
thirdbestvertex(1).X=nextbestvertex(1).X
thirdbestvertex(1).Y=nextbestvertex(1).Y
thirdbestvertex(1).Z=nextbestvertex(1).Z
nextbestvertex(1).X=bestvertex(1).X
nextbestvertex(1).Y=bestvertex(1).Y
nextbestvertex(1).Z=bestvertex(1).Z
bestvertex(1).X=x#
bestvertex(1).Y=y#
bestvertex(1).Z=z#
BestD#=distance#
endif
else
if v=1 then prevbest#=distance#
endif
next v
endif
unlock vertexdata
next x
`closest points for current object
WrldX#=bestvertex(1).X
WrldY#=bestvertex(1).Y
WrldZ#=bestvertex(1).Z
`take best vertex locations and transfer to screen
GOSUB _project3dTo2d:
d3d_line ScrX#-5,ScrY#,ScrX#+5,ScrY#, RGB(255,0,0)
d3d_line ScrX#,ScrY#-5,ScrX#,ScrY#+5, RGB(255,0,0)
WrldX#=nextbestvertex(1).X
WrldY#=nextbestvertex(1).Y
WrldZ#=nextbestvertex(1).Z
GOSUB _project3dTo2d:
d3d_line ScrX#-5,ScrY#,ScrX#+5,ScrY#, RGB(0,255,0)
d3d_line ScrX#,ScrY#-5,ScrX#,ScrY#+5, RGB(0,255,0)
WrldX#=thirdbestvertex(1).X
WrldY#=thirdbestvertex(1).Y
WrldZ#=thirdbestvertex(1).Z
GOSUB _project3dTo2d:
d3d_line ScrX#-5,ScrY#,ScrX#+5,ScrY#, RGB(0,0,255)
d3d_line ScrX#,ScrY#-5,ScrX#,ScrY#+5, RGB(0,0,255)
`check for 90 degrees and if it exists then use third vertex
REM STILL TO DO!!
`use two best vertices to set hinge up
if clonedH=0
GOSUB _GET_OBJ
hinge=Obj
clone object hinge, 60
position object hinge, bestvertex(1).X,bestvertex(1).Y,bestvertex(1).Z
point object hinge, nextbestvertex(1).X,nextbestvertex(1).Y,nextbestvertex(1).Z
clonedH=1
else
position object hinge, bestvertex(1).X,bestvertex(1).Y,bestvertex(1).Z
point object hinge, nextbestvertex(1).X,nextbestvertex(1).Y,nextbestvertex(1).Z
endif
endif
endif
return
This gives the desired result if the two corners happen to be on the face we are looking at. If the two points are not on the face we are looking at we need to check the angles between the two closest corners and the point we are looking at. If the angle happens to be exactly 90 degrees then we are looking at the wrong two corners and need to use the third closest corner instead of the second closest...
Sorry if I've lost you!
Anyway below are a couple of quick images as an example.
In the first image we see that we are looking at the same face as the hinge and there are no 90 degree angles:
In the second image we see that we are looking at a different face because there is a 90 degree angle:
Hope that makes sense to anyone who's interested!!
Anyway I haven't actually written the code yet but it's mostly in my head...