Author Topic: picking an object  (Read 4972 times)

Offline Richard Rae

  • Mr. Drawsprite
  • **
  • Posts: 79
    • View Profile
picking an object
« on: 2007-Nov-08 »
I have 9 objects on screen(3D being used).How would I go about picking one with the mouse.I am assuming I could use the raytrace command.

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10746
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
picking an object
« Reply #1 on: 2007-Nov-08 »
Correct.
Use the X_SCREEN2WORLD to transform your mousepointer to 3D coordinates. Then use X_COLLISIONRAY to test, if you hit it.

Offline Richard Rae

  • Mr. Drawsprite
  • **
  • Posts: 79
    • View Profile
picking an object
« Reply #2 on: 2007-Nov-08 »
Can't get it.Any chance of an example? :)

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10746
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
picking an object
« Reply #3 on: 2007-Nov-08 »
Code: (glbasic) [Select]
// --------------------------------- //
// Project:
// Start: Saturday, July 20, 2002


// First we need an object. Here: a simple paper plane
// We assume Z is down, as most 3d programs will export
// The converter should be able to convert this one day...

// Also we assume the x axis (positive) is the direction
// the plane will fly forwards, so in a right hand system
// y will be left side of plane.

// Triangle Strips will be drawn:
//
//  1---2---5
//   \ / \ /|
//    3---4 |
//         \|
//          6

LOADSPRITE "News.bmp", 0

col = RGB(0xff, 0xff, 0xff)
X_OBJSTART 0 // PlaneID = 0
// Right wing:                 side updown
X_OBJADDVERTEX -7,  5,  0,     1.0, 1.0, col // Outer point
X_OBJADDVERTEX -7,  1,  0,     1.0, 0.5, col // Inner edge
X_OBJADDVERTEX  7,  0,  0,     0.0, 1.0, col // Top
// Right body:
X_OBJADDVERTEX -7,  0,  3,     0.0, 1.0, col
X_OBJNEWGROUP
// Left wing:
X_OBJADDVERTEX -7, -5,  0,     0.0, 0.0, col
X_OBJADDVERTEX -7, -1,  0,     0.0, 0.5, col
X_OBJADDVERTEX  7,  0,  0,     1.0, 0.0, col
// Left body:
X_OBJADDVERTEX -7,  0,  3,     0.0, 1.0, col
X_OBJEND

X_SAVEOBJ "plane.ddd", 0
X_LOADOBJ "plane.ddd", 0

LIMITFPS -1
WHILE TRUE

MOUSESTATE mx, my, mb1, mb2

DRAWRECT mx-8,my-8,16,16, RGB(255,0,0)

X_MAKE3D 1, 1000, 45 // Turn to 3D Viewport
X_CAMERA   200*SIN(mx*360/640), my*2-100, 200*COS(mx), 0,0,0 // Rotate CAMERA with mouse
dtime = GETTIMER()
psi=psi+(dtime/64); IF psi>=360 THEN psi=0
FOR phi = 0 TO 360 STEP 30
X_DRAWAXES 0,0,0 // Draw global axes (red=x, green=y, blue=z)

alpha = (phi+psi)*4
LOCAL px=200*SIN(phi+psi),py=SIN(alpha)*20,pz=100*COS(phi+psi)
X_MOVEMENT px,py,pz

X_SCALING 2,2,2
X_ROTATION 90,1,0,0 // Make plane body point down global y
X_ROTATION 45*COS(alpha),0,0,1 // make plane look up/down with mouse
X_ROTATION phi+psi, 0,1,0 // Rtoation due to position in circle

X_SETTEXTURE 0, -1
X_DRAWOBJ 0, 0 // Draw Object#0. Frame# is always 0 with user def. objects


// PICKING PART!
LOCAL x,y,z, x2,y2,z2
X_SCREEN2WORLD mx, my,  0, x, y, z
X_SCREEN2WORLD mx, my, -1, x2,y2,z2
IF X_COLLISIONRAY(0,0, x,y,z, x2-x, y2-y, z2-z)<>0
X_PRINT "PICK", px,py,pz, 0
ENDIF

NEXT

fps = ((1000/dtime)+fps)/2
delay=delay+dtime
IF delay>1000 // 1/2 sec
delay=0
showfps=fps
ENDIF
X_MAKE2D
PRINT "FPS: " +INTEGER(showfps), 100, 100 // + dtime, 0,0
SHOWSCREEN
WEND
Move the mouse over a paper plane.

Offline Richard Rae

  • Mr. Drawsprite
  • **
  • Posts: 79
    • View Profile
picking an object
« Reply #4 on: 2007-Nov-08 »
Thanks for that Gernot.I can get it to work in my programme no problem.Can I get the pick command to return the actual world co-ordinates(x,y,z)of the object picked?

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10746
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
picking an object
« Reply #5 on: 2007-Nov-09 »
uhm... you need the x,y,z position of the object for the x_collisionray test. Thus, uhm... you know them.

Offline Richard Rae

  • Mr. Drawsprite
  • **
  • Posts: 79
    • View Profile
picking an object
« Reply #6 on: 2007-Nov-09 »
How come the following code is only picking one cube

Code: (glbasic) [Select]
// --------------------------------- //
// Project: 3d test
// Start: Thursday, November 08, 2007
// IDE Version: 5.069


X_LOADOBJ "cube.ddd",1

LOADSPRITE "rub_cube.bmp",1
LOADSPRITE "back.bmp",2
LOADSPRITE "reflect.bmp",3

LOADSPRITE "../../pointers.png",4




leng=50

x=0
y=0
WHILE TRUE
ALPHAMODE -.999
STRETCHSPRITE 2,0,0,640,480

MOUSESTATE mxx,myy,b1,b2

IF b2
mx=mx+MOUSEAXIS(0)
my=my+MOUSEAXIS(1)
ENDIF




X_MAKE3D 1,1000,45


camx=(400*COS(mx))*COS(my)
camy=(400*SIN(mx))*COS(my)
camz=400*SIN(my)

camx1=(300*COS(mx))*COS(my)
camy1=(300*SIN(mx))*COS(my)
camz1=300*SIN(my)






X_CAMERA camx,camz,camy,0,0,0

INC phi,2
INC pi,1

FOR z=0 TO 2
FOR y=0 TO 2
FOR x=0 TO 2
X_MOVEMENT (x*48)-50,(y*48)-50,(z*48)-50

X_SETTEXTURE 1,-1

X_DRAWOBJ 1,0

LOCAL wx,wy,wz, wx2,wy2,wz2
        X_SCREEN2WORLD mxx, myy,0, wx, wy, wz
        X_SCREEN2WORLD mxx, myy, -1, wx2,wy2,wz2
        IF X_COLLISIONRAY(1,0,wx,wy,wz,wx2-wx,wy2-wy,wz2-wz)<>0
           
            picked=1
            ELSE
            picked=0



        ENDIF



NEXT
NEXT
NEXT





X_MAKE2D
DRAWSPRITE 4,mxx,myy
IF picked=1
PRINT "object picked",10,0
ELSE
PRINT "No object picked",10,0
ENDIF

SHOWSCREEN

WEND
I know it's probably something I am doing wrong.

Full programme and media available here

http://www.rrae.pwp.blueyonder.co.uk/my prog.zip

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10746
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
picking an object
« Reply #7 on: 2007-Nov-09 »
Hehehe!
Du setzt "picked=0" wenn Du nicht in einem Block bist und ├╝berschreibst damit picked=1 von vorherigen Block.
Nimm's vor die Schleife:
Code: (glbasic) [Select]
picked=0
FOR z=0 TO 2
FOR y=0 TO 2
FOR x=0 TO 2
LOCAL obx=(x*48)-50, oby=(y*48)-50, obz=(z*48)-50
X_MOVEMENT obx, oby, obz
X_SETTEXTURE 1,-1

X_DRAWOBJ 1,0

LOCAL wx,wy,wz, wx2,wy2,wz2
        X_SCREEN2WORLD mxx, myy,  0, wx, wy, wz
        X_SCREEN2WORLD mxx, myy, -1, wx2,wy2,wz2
        IF X_COLLISIONRAY(1,0,wx,wy,wz,  (wx2-wx)*1000,(wy2-wy)*1000,(wz2-wz)*1000)<>0

            picked=1
        ENDIF



NEXT
NEXT
NEXT

Offline Richard Rae

  • Mr. Drawsprite
  • **
  • Posts: 79
    • View Profile
picking an object
« Reply #8 on: 2007-Nov-09 »
Don't understand German !Sorry
Tried the new code and it works fine:)Another question ,If three cubes are in a line one behind the other,all three show as being hit(modified code slightly to use x_print).How can I find which one is the closest to the camera?Thank you for all your help,it is really appreciated.

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10746
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
picking an object
« Reply #9 on: 2007-Nov-09 »
Oh! Silly me.
Well, if the X_COLLISIONRAY returns <>0, then the object you're just drawing (or would draw at current X_MOVEMENT) is under the mouse.

Offline Richard Rae

  • Mr. Drawsprite
  • **
  • Posts: 79
    • View Profile
picking an object
« Reply #10 on: 2007-Nov-09 »
Sorry for being thick,but what if the one furthest away is drawn first.Won't it be the one under the mouse?I am looking for the one that is closest to the camera.

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10746
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
picking an object
« Reply #11 on: 2007-Nov-09 »
then also store the distance from camera to the object, and change the picked index, when you're closer. The distance is the retun value from X_COLLISIONRAY

Offline JohnnyB

  • Mc. Print
  • *
  • Posts: 35
    • View Profile
Re: picking an object
« Reply #12 on: 2019-Jul-15 »
What would be the best way to calculate the point where the ray first hits an object?