PickObject() function for DBC by Relativity27th Jan 2006 11:06
|
---|
Summary This function uses Sparky's .DLL to pick an object from a 2D point, such as the mouse position. Description This program will allow the user to see if a vector extending from a 2D point on the screen into 3D space will pass through an object. It incorporates Sparky's .DLL with my PickScreen() function. Code ` This code was downloaded from The Game Creators ` It is reproduced here with full permission ` http://www.thegamecreators.com `========================================================================== `PickObject() EXAMPLE PROGRAM `========================================================================== `PickScreen() CODE WRITTEN BY: SITHSPAWN (SEE CODEBASE) `========================================================================== `RAYCASTING .DLL WRITTEN BY: SPARKY `(DOWNLOAD AT http://sparky152.homestead.com/files/DBCcollisions_v1.05.zip) `========================================================================== `ARRANGED BY: SITHSPAWN `========================================================================== `I M P O R T A N T: SPARKY'S DLL IS REQUIRED FOR THIS FUNCTION TO WORK!!! (SEE DOWNLOAD INFORMATION AT THE TOP OF THIS PROGRAM) `ALSO I M P O R T A N T: DarkBASIC ENHANCED IS REQUIRED FOR THIS FUNCTION!!! `AGAIN, I M P O R T A N T: YOU MUST DECLARE ALL OBJECTS AS SPARKY'S .DLL REQUIRES. SEE SPARKY'S .DLL COMMAND LIST. `LAST I M P O R T A N T: ANY CHANGES TO THE OBJECT YOU ARE PICKING (I.E. MOVEMENT, ROTATION) MUST BE ACCOUNTED FOR WITH `SPARKY'S updateObjectDBC() function. `W A R N I N G: SPARKY'S BOX COLLISION IS BUGGED. THEREFORE, IT IS STRONGLY ADVISED THAT YOU STAY AWAY FROM USING IT UNLESS YOU KNOW THAT `THE OBJECT WILL NEVER BE BEHIND ANOTHER OBJECT FROM THE CAMERA'S PERSPECTIVE. `INITIAL SETUP SYNC ON AUTOCAM OFF SET DISPLAY MODE 800,600,16 RANDOMIZE TIMER() `MAKE MATRIX FOR BASIS FOR COMPARISON MAKE MATRIX 1,200,200,10,10 SET MATRIX WIREFRAME ON 1 `MAKE OBJECTS MAKE OBJECT PLAIN 1,0,0 POSITION OBJECT 1,0,10,0 MAKE OBJECT CUBE 2,30 MAKE OBJECT SPHERE 3,50 MAKE OBJECT CONE 4,70 FOR OBJECT=2 TO 4 COLOR OBJECT OBJECT,RGB(RND(255),RND(255),RND(255)) POSITION OBJECT OBJECT,RND(200),RND(100),RND(200) ROTATE OBJECT OBJECT,RND(359),RND(359),RND(359) NEXT OBJECT `DECLARE OBJECTS WITH SPARKY'S .DLL setupObjectDBC(2,0,0) setupObjectDBC(3,0,1) setupComplexObjectDBC(4,0,2) `DECLARE AN ARRAY FOR USE WITH THE PICKSCREEN FUNCTION DIM VECTOR#(2) `MAIN LOOP DO ` CAMERA MOVEMENT IF UPKEY()=1 THEN MOVE OBJECT 1,3 IF DOWNKEY()=1 THEN MOVE OBJECT 1,-3 IF MOUSELOOK=1 IF LEFTKEY()=1 OR RIGHTKEY()=1 IF LEFTKEY()=1 THEN MLOOKY2#=WRAPVALUE(MLOOKY#-90) IF RIGHTKEY()=1 THEN MLOOKY2#=WRAPVALUE(MLOOKY#+90) ROTATE OBJECT 1,0,MLOOKY2#,0:MOVE OBJECT 1,3 ROTATE OBJECT 1,MLOOKX#,MLOOKY#,0 ENDIF POSITION MOUSE 400,300 MLOOKX#=WRAPVALUE(MLOOKX#+MOUSEMOVEY()) MLOOKY#=WRAPVALUE(MLOOKY#+MOUSEMOVEX()) IF MLOOKX#>180 AND MLOOKX#<270 THEN MLOOKX#=270 IF MLOOKX#<180 AND MLOOKX#>90 THEN MLOOKX#=90 ROTATE OBJECT 1,MLOOKX#,MLOOKY#,0 IF MOUSECLICK()=2 AND WAITMOUSE>5 WAITMOUSE=0 MOUSELOOK=0 SHOW MOUSE ENDIF ELSE IF LEFTKEY()=1 THEN ROTATE OBJECT 1,OBJECT ANGLE X(1),WRAPVALUE(OBJECT ANGLE Y(1)-3),0 IF RIGHTKEY()=1 THEN ROTATE OBJECT 1,OBJECT ANGLE X(1),WRAPVALUE(OBJECT ANGLE Y(1)+3),0 IF MOUSECLICK()=2 AND WAITMOUSE>5 WAITMOUSE=0 MOUSELOOK=1 HIDE MOUSE MLOOKX#=OBJECT ANGLE X(1) : MLOOKY#=OBJECT ANGLE Y(1) IF OBJECT_SELECTED>0 updateObjectDBC(OBJECT_SELECTED) OBJECT_SELECTED=0 ENDIF ENDIF `*********************************** `PICKING THE OBJECT (THE GOOD STUFF) `*********************************** IF MOUSECLICK()=1 AND WAITSELECT>5 WAITSELECT=0 IF OBJECT_SELECTED=0 OBJECT_SELECTED=PICKOBJECT(MOUSEX(),MOUSEY(),1000.0) IF OBJECT_SELECTED>0 THEN DISTANCE#=DISTANCETOCAM(OBJECT_SELECTED) ELSE updateObjectDBC(OBJECT_SELECTED) OBJECT_SELECTED=0 ENDIF ENDIF IF OBJECT_SELECTED>0 PICKSCREEN(MOUSEX(),MOUSEY(),DISTANCE#) PRINT VECTOR#(0),VECTOR#(1),VECTOR#(2) POSITION OBJECT OBJECT_SELECTED,VECTOR#(0),VECTOR#(1),VECTOR#(2) ENDIF ENDIF INC WAITMOUSE INC WAITSELECT POSITION CAMERA OBJECT POSITION X(1),OBJECT POSITION Y(1),OBJECT POSITION Z(1) ROTATE CAMERA OBJECT ANGLE X(1),OBJECT ANGLE Y(1),OBJECT ANGLE Z(1) SET CURSOR 0,0 PRINT "Select an object with the mouse to move it." PRINT "Click the right mouse button to use mouse look." PRINT "Use the arrow keys to move." PRINT PRINT "Object Selected> ",OBJECT_SELECTED IF OBJECT_SELECTED>0 PRINT "X POS> ",OBJECT POSITION X(OBJECT_SELECTED)," Y POS> ",OBJECT POSITION Y(OBJECT_SELECTED)," Z POS> ",OBJECT POSITION Z(OBJECT_SELECTED) ENDIF SYNC LOOP `I M P O R T A N T: SPARKY'S DLL IS REQUIRED FOR THIS FUNCTION TO WORK!!! (SEE DOWNLOAD INFORMATION AT THE TOP OF THIS PROGRAM) `ALSO I M P O R T A N T: DarkBASIC ENHANCED IS REQUIRED FOR THIS FUNCTION!!! `AGAIN, I M P O R T A N T: YOU MUST DECLARE ALL OBJECTS AS SPARKY'S .DLL REQUIRES. SEE SPARKY'S .DLL COMMAND LIST. `W A R N I N G: SPARKY'S BOX COLLISION IS BUGGED. THEREFORE, IT IS STRONGLY ADVISED THAT YOU STAY AWAY FROM USING IT UNLESS YOU KNOW THAT `THE OBJECT WILL NEVER BE BEHIND ANOTHER OBJECT FROM THE CAMERA'S PERSPECTIVE. `THIS FUNCTION WILL GIVE YOU A POINT IN 3D SPACE A CERTAIN DISTANCE AWAY FROM THE CAMERA `THAT CORRESPONDS TO A 2D POINT ON YOUR SCREEN. `SYNTAX: XPOINT# IS THE 2D X POINT ON YOUR SCREEN ` YPOINT# IS THE 2D Y POINT ON YOUR SCREEN ` DISTANCE# IS THE MAX DISTANCE AWAY FROM THE CAMERA YOU WANT TO CALCULATE PICK OBJECT `W A R N I N G: THERE MUST EXIST AN OBJECT DECLARED WITH SPARKY'S .DLL OR ELSE THIS FUNCTION WILL FAIL `RESULTS WILL BE OUTPUT BY THE FUNCTION. THE NUMBER OF THE CLOSEST OBJECT SELECTED WILL BE OUTPUT. `A RESULT OF 0 MEANS THAT NO OBJECT IS SELECTED FUNCTION PICKOBJECT(XPOINT,YPOINT,DISTANCE#) DIM PICKOBJECTVECTOR#(2) ` CALCULATE HALF THE SCREEN WIDTH AND HEIGHT ` SUBTRACT 1 BECAUSE POINTS START AT (0,0), NOT (1,1) HALFSW#=(SCREEN WIDTH()-1) HALFSW#=HALFSW#/2 HALFSH#=(SCREEN HEIGHT()-1) HALFSH#=HALFSH#/2 ` CALCULATE THE RATIO CONSTANTS. REMEMBER, HEIGHT CONSTANT IS ALWAYS .6 SW#=SCREEN WIDTH() SH#=SCREEN HEIGHT() WIDTHCONSTANT#=SW#/SH# WIDTHCONSTANT#=.6*WIDTHCONSTANT# ` CALCULATE 3D COORDINATE OF SCREEN POINT ASSUMING CAMERA ISN'T ROTATED AND IS AT POSITION 0,0,0 XPOINT#=XPOINT YPOINT#=YPOINT XPOINT#=XPOINT-HALFSW# YPOINT#=HALFSH#-YPOINT XVEC#=WIDTHCONSTANT#*(XPOINT#/HALFSW#) YVEC#=.6*(YPOINT#/HALFSH#) ZVEC#=1 ` CALCULATE LENGTH FROM CAMERA POINT TO 3D SCREEN POINT LENGTH#=SQRT((XVEC#*XVEC#)+(YVEC#*YVEC#)+(ZVEC#*ZVEC#)) ` MAKE VECTOR A UNIT VECTOR XVEC#=(XVEC#/LENGTH#) YVEC#=(YVEC#/LENGTH#) ZVEC#=(ZVEC#/LENGTH#) ` CALCULATE POINT ON VECTOR AT DESIRED DISTANCE FROM CAMERA XVEC#=DISTANCE#*XVEC# YVEC#=DISTANCE#*YVEC# ZVEC#=DISTANCE#*ZVEC# ` CALULATE X-AXIS ROTATION RELATIVE TO CAMERA OLDY#=YVEC# OLDZ#=ZVEC# YVEC#=(OLDY#*COS(CAMERA ANGLE X()))-(OLDZ#*SIN(CAMERA ANGLE X())) ZVEC#=(OLDY#*SIN(CAMERA ANGLE X()))+(OLDZ#*COS(CAMERA ANGLE X())) ` CALCULATE Y-AXIS ROTATION RELATIVE TO CAMERA OLDX#=XVEC# OLDZ#=ZVEC# XVEC#=(OLDX#*COS(CAMERA ANGLE Y()))+(OLDZ#*SIN(CAMERA ANGLE Y())) ZVEC#=(OLDZ#*COS(CAMERA ANGLE Y()))-(OLDX#*SIN(CAMERA ANGLE Y())) ` CALCULATE Z-AXIS ROTATION RELATIVE TO CAMERA OLDX#=XVEC# OLDY#=YVEC# XVEC#=(OLDX#*COS(CAMERA ANGLE Z()))-(OLDY#*SIN(CAMERA ANGLE Z())) YVEC#=(OLDX#*SIN(CAMERA ANGLE Z()))+(OLDY#*COS(CAMERA ANGLE Z())) ` CALCULATE THE VECTOR RELATIVE TO THE STANDARD AXIS RATHER THAN RELATIVE TO THE CAMERA VECTOR#(0)=XVEC#+CAMERA POSITION X() VECTOR#(1)=YVEC#+CAMERA POSITION Y() VECTOR#(2)=ZVEC#+CAMERA POSITION Z() ` CALCULATE RAYCASTING USING SPARKY'S .DLL (N O T E: IF USING GROUPS, SET THE GROUP FLAG TO 1) OBJECT_SELECTED=intersectObjectDBC(0,0,CAMERA POSITION X(),CAMERA POSITION Y(),CAMERA POSITION Z(),VECTOR#(0),VECTOR#(1),VECTOR#(2),0) UNDIM PICKOBJECTVECTOR#(2) ENDFUNCTION OBJECT_SELECTED `MY PICKSCREEN FUNCTION FUNCTION PICKSCREEN(XPOINT,YPOINT,DISTANCE#) ` CALCULATE HALF THE SCREEN WIDTH AND HEIGHT ` SUBTRACT 1 BECAUSE POINTS START AT (0,0), NOT (1,1) HALFSW#=(SCREEN WIDTH()-1) HALFSW#=HALFSW#/2 HALFSH#=(SCREEN HEIGHT()-1) HALFSH#=HALFSH#/2 ` CALCULATE THE RATIO CONSTANTS. REMEMBER, HEIGHT CONSTANT IS ALWAYS .6 SW#=SCREEN WIDTH() SH#=SCREEN HEIGHT() WIDTHCONSTANT#=SW#/SH# WIDTHCONSTANT#=.6*WIDTHCONSTANT# ` CALCULATE 3D COORDINATE OF SCREEN POINT ASSUMING CAMERA ISN'T ROTATED AND IS AT POSITION 0,0,0 XPOINT#=XPOINT YPOINT#=YPOINT XPOINT#=XPOINT-HALFSW# YPOINT#=HALFSH#-YPOINT XVEC#=WIDTHCONSTANT#*(XPOINT#/HALFSW#) YVEC#=.6*(YPOINT#/HALFSH#) ZVEC#=1 ` CALCULATE LENGTH FROM CAMERA POINT TO 3D SCREEN POINT LENGTH#=SQRT((XVEC#*XVEC#)+(YVEC#*YVEC#)+(ZVEC#*ZVEC#)) ` MAKE VECTOR A UNIT VECTOR XVEC#=(XVEC#/LENGTH#) YVEC#=(YVEC#/LENGTH#) ZVEC#=(ZVEC#/LENGTH#) ` CALCULATE POINT ON VECTOR AT DESIRED DISTANCE FROM CAMERA XVEC#=DISTANCE#*XVEC# YVEC#=DISTANCE#*YVEC# ZVEC#=DISTANCE#*ZVEC# ` CALULATE X-AXIS ROTATION RELATIVE TO CAMERA OLDY#=YVEC# OLDZ#=ZVEC# YVEC#=(OLDY#*COS(CAMERA ANGLE X()))-(OLDZ#*SIN(CAMERA ANGLE X())) ZVEC#=(OLDY#*SIN(CAMERA ANGLE X()))+(OLDZ#*COS(CAMERA ANGLE X())) ` CALCULATE Y-AXIS ROTATION RELATIVE TO CAMERA OLDX#=XVEC# OLDZ#=ZVEC# XVEC#=(OLDX#*COS(CAMERA ANGLE Y()))+(OLDZ#*SIN(CAMERA ANGLE Y())) ZVEC#=(OLDZ#*COS(CAMERA ANGLE Y()))-(OLDX#*SIN(CAMERA ANGLE Y())) ` CALCULATE Z-AXIS ROTATION RELATIVE TO CAMERA OLDX#=XVEC# OLDY#=YVEC# XVEC#=(OLDX#*COS(CAMERA ANGLE Z()))-(OLDY#*SIN(CAMERA ANGLE Z())) YVEC#=(OLDX#*SIN(CAMERA ANGLE Z()))+(OLDY#*COS(CAMERA ANGLE Z())) ` CALCULATE THE VECTOR RELATIVE TO THE STANDARD AXIS RATHER THAN RELATIVE TO THE CAMERA VECTOR#(0)=XVEC#+CAMERA POSITION X() VECTOR#(1)=YVEC#+CAMERA POSITION Y() VECTOR#(2)=ZVEC#+CAMERA POSITION Z() ENDFUNCTION `MY OBJECT DISTANCE TO CAMERA FUNCTION FUNCTION DISTANCETOCAM(OBJNUM) DISTANCE#=SQRT((OBJECT POSITION X(OBJNUM)-CAMERA POSITION X())^2+(OBJECT POSITION Y(OBJNUM)-CAMERA POSITION Y())^2+(OBJECT POSITION Z(OBJNUM)-CAMERA POSITION Z())^2) ENDFUNCTION DISTANCE# `SPARKY'S .DLL FUNCTIONS function setupObjectDBC(objNum,groupNum,objectType) commonSetup(objNum) vertData = get memblock ptr(254) objectData = get memblock ptr(255) call dll 1,"setupObject",objNum,groupNum,objectType,vertData,objectData delete memblock 254 endfunction function setupComplexObjectDBC(objNum,groupNum,facesPerNode) commonSetup(objNum) vertData = get memblock ptr(254) objectData = get memblock ptr(255) call dll 1,"setupComplexObject",objNum,groupNum,facesPerNode,vertData,objectData delete memblock 254 endfunction function commonSetup(objNum) if dll exist(1)=0 then load dll "DBCcollision.dll",1 if memblock exist(255)=0 then make memblock 255,24 x#=object position x(objNum) y#=object position y(objNum) z#=object position z(objNum) angx#=object angle x(objNum) angy#=object angle y(objNum) angz#=object angle z(objNum) write memblock float 255,0,x# write memblock float 255,4,y# write memblock float 255,8,z# write memblock float 255,12,angx# write memblock float 255,16,angy# write memblock float 255,20,angz# position object objNum,0,0,0 rotate object objNum,0,0,0 make mesh from object 255,objNum make memblock from mesh 254,255 delete mesh 255 position object objNum,x#,y#,z# rotate object objNum,angx#,angy#,angz# endfunction function updateObjectDBC(objNum) if memblock exist(255)=0 then make memblock 255,24 write memblock float 255,0,object position x(objNum) write memblock float 255,4,object position y(objNum) write memblock float 255,8,object position z(objNum) write memblock float 255,12,object angle x(objNum) write memblock float 255,16,object angle y(objNum) write memblock float 255,20,object angle z(objNum) objectData = get memblock ptr(255) call dll 1,"updateObject",objNum,objectData endfunction function intersectObjectDBC(objNum,groupFlag,oldx#,oldy#,oldz#,x#,y#,z#,excludeObj) collide=call dll(1,"intersectObject",objNum,groupFlag,oldx#,oldy#,oldz#,x#,y#,z#,excludeObj) endfunction collide function setObjectCollisionOnDBC(objNum) call dll 1,"set_object_collision_on",objNum endfunction function setObjectCollisionOffDBC(objNum) call dll 1,"set_object_collision_off",objNum endfunction function collisionStatusDBC(objNum) result=call dll(1,"collisionstatus",objNum) endfunction result function getStaticCollisionX() result#=call dll(1,"getStaticCollisionX") endfunction result# function getStaticCollisionY() result#=call dll(1,"getStaticCollisionY") endfunction result# function getStaticCollisionZ() result#=call dll(1,"getStaticCollisionZ") endfunction result# function getCollisionNormalX() result#=call dll(1,"getCollisionNormalX") endfunction result# function getCollisionNormalY() result#=call dll(1,"getCollisionNormalY") endfunction result# function getCollisionNormalZ() result#=call dll(1,"getCollisionNormalZ") endfunction result# |