I've found this code here from 9 years ago, which uses vectors and transformation matrices to bypass the OBJECT SCREEN X/Y() commands.
It's a cute little solution, although i found a tiny problem with it: what if i want to input my own camera properties (including FOV) into it, and not the built in darkbasic camera's coords and angles?
The code:
sync on
hide mouse
null = make vector3(1)
null = make vector3(2)
null = make matrix4(3) : projection matrix4 3
null = make matrix4(4) : view matrix4 4
null = make matrix4(5) : world matrix4 5
rem just to give some 3d visual reference
make object cube 1,20
position object 1,40,0,350
make matrix 1,1000,1000,30,30
do
project3dTo2d(1,40,0,350)
view matrix4 4
project vector3 1,2,3,4,5
gosub camera_stuff
circle x vector3(1),y vector3(1),5
sync
loop
function project3dTo2d(result as integer,x as float, y as float, z as float)
set vector3 2,x,y,z
view matrix4 4
project vector3 1,2,3,4,5
endfunction
camera_stuff:
oldcx#=cx#
oldcz#=cz#
speed# = 0.1
if upkey()=1
cx#=newxvalue(cx#,a#,speed#)
cz#=newzvalue(cz#,a#,speed#)
endif
if downkey()=1
cx#=newxvalue(cx#,a#,-speed#)
cz#=newzvalue(cz#,a#,-speed#)
endif
if leftkey()=1
cx#=newxvalue(cx#,wrapvalue(a#-90.0),speed#)
cz#=newzvalue(cz#,wrapvalue(a#-90.0),speed#)
endif
if rightkey()=1
cx#=newxvalue(cx#,wrapvalue(a#+90.0),speed#)
cz#=newzvalue(cz#,wrapvalue(a#+90.0),speed#)
endif
if shiftkey() then inc cy#, 2
if controlkey() then dec cy#, 2
a# = wrapvalue(a#+(mousemovex()/3.0))
cxa# = cxa#+(mousemovey()/3.0)
if cxa#<-90.0 then cxa#=-90.0
if cxa#>90.0 then cxa#=90.0
position camera cx#, cy#+100, cz#
rotate camera wrapvalue(cxa#), a#, 0
RETURN
As a secondary question, on my quest to try figuring out this whole topic i've come across this neat looking formula on Wikipedia:
Dx# = cos( camRotY ) * [ sin( camRotZ ) * ( objPosY - camPosY ) + cos( camRotZ ) * ( objPosX - camPosX ) ] - sin( camRotY ) * ( objPosZ - camPosZ )
Dy# = sin( camRotX ) * [ cos( camRotY ) * ( objPosZ - camPosZ ) + sin( camRotY ) * ( sin( camRotZ ) * ( objPosY - camPosY ) + cos( camRotZ ) * ( objPosX - camPosX ) ) ] + cos( camRotX ) * [ cos( camRotZ ) * ( objPosY - camPosY ) - sin( camRotZ ) * ( objPosX - camPosX ) ]
Dz# = cos( camRotX ) * [ cos( camRotY ) * ( objPosZ - camPosZ ) + sin( camRotY ) * ( sin( camRotZ ) * ( objPosY - camPosY ) + cos( camRotZ ) * ( objPosX - camPosX ) ) ] - sin( camRotX ) * [ cos( camRotZ ) * ( objPosY - camPosY ) - sin( camRotZ ) * ( objPosX - camPosX ) ]
screenX = ( relativePlaneCamDistance_Z / Dz# ) * Dx# - plane_X
screenY = ( relativePlaneCamDistance_Z / Dz# ) * Dy# - plane_Y
Here on this page:
http://en.wikipedia.org/wiki/3D_projection
Should this work like the vector method? Because for the life of me i can't get anything not abnormal with that. But would prefer something similar so i'm not bound to only DarkBasic with my code.