PickDepth(#Camera, x, y) - Misunderstood the manual

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

PickDepth(#Camera, x, y) - Misunderstood the manual

Post by DarkDragon »

Hello,

If we would have a function like this for getting the depth at a pixel we could multiply PickX/Y/Z with this depth and then we have the pixel exact point where we clicked on in 3D space. This would be very useful. But I don't know if there's a good method to get the exact depth with DirectX/OGRE. At the moment we just get the direction clamped to [-1, 1], so it's not very useful except for shooting.
Last edited by DarkDragon on Wed Jan 07, 2009 2:16 pm, edited 1 time in total.
bye,
Daniel
User avatar
Comtois
Addict
Addict
Posts: 1431
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Post by Comtois »

I do not understand what you want to get? can you clarify?
Is it the intersection with the first 3D object ?
Please correct my english
http://purebasic.developpez.com/
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Post by DarkDragon »

Comtois wrote:I do not understand what you want to get? can you clarify?
Is it the intersection with the first 3D object ?
Its the 3D intersection point with the object I clicked on.

Normally if you want to get this point, you just go this way:

Code: Select all

pixelX = mouseX ; for example
pixelY = mouseY ; for example
pixelZ = read depthbuffer from #Camera at pixelX, pixelY

Unproject(pixelX, pixelY, pixelZ, @objX, @objY, @objZ)

Debug objX
Debug objY
Debug objZ
This should be the internal way PickX/Y/Z works, but PickX/Y/Z just returns a value between [-1, 1] not the real range. So Z is lost again. It is much faster than creating a ray and checking the intersection with each triangle.
bye,
Daniel
User avatar
Comtois
Addict
Addict
Posts: 1431
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Post by Comtois »

Its the 3D intersection point with the object I clicked on.
you can get the 3D intersection point with MousePick() , or i do not understand again ?

Here an example

Code: Select all

;- Initialisation
IncludeFile "Screen3DRequester.pb"

If InitEngine3D() = 0
 MessageRequester( "Erreur" , "Impossible d'initialiser la 3D , vérifiez la présence de engine3D.dll" , 0 )
 End
EndIf

If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
 MessageRequester( "Erreur" , "Impossible d'initialiser DirectX 7 Ou plus" , 0 )
 End
ElseIf Screen3DRequester() = 0
 MessageRequester( "Erreur" , "Impossible d'ouvrir l'écran " , 0 )
 End
EndIf

Add3DArchive("Data\"          , #PB_3DArchive_FileSystem)
Add3DArchive("GUI\", #PB_3DArchive_FileSystem)
Add3DArchive("GUI\schemes", #PB_3DArchive_FileSystem)
Add3DArchive("GUI\imagesets", #PB_3DArchive_FileSystem)
Add3DArchive("GUI\fonts", #PB_3DArchive_FileSystem)
Add3DArchive("GUI\looknfeel", #PB_3DArchive_FileSystem)
Add3DArchive("GUI\layouts", #PB_3DArchive_FileSystem)
   
#PB_Node_Node = 1
#PB_Node_Entity = 2
Enumeration
  #Haut
  #Bas
  #Devant
  #Derriere
  #Gauche
  #Droit
  #CentreX
  #CentreY
  #CentreZ
EndEnumeration

Structure Vertex
px.f
py.f
pz.f
nx.f
ny.f
nz.f
co.l
tu.f
tv.f
EndStructure
Structure Face
  p1.w
  p2.w
  p3.w
  p4.w
  p5.w
  p6.w
EndStructure
Structure s_Cube
  No.l
EndStructure
Structure s_Angle
  AngleX.f
  AngleY.f
  AngleZ.f
EndStructure
Macro MaCouleur(Rouge,Vert,Bleu)
  Rouge << 16 + Vert << 8 + Bleu
EndMacro

;-Texture
UsePNGImageEncoder()
CreateImage(0,64,64)
StartDrawing(ImageOutput(0))
Box(0,0,64,64,$111111)
Box(1,1,62,62,$FFFFFF)
StopDrawing()
;-Material
Fichier$="Texture"+Str(0)+".png"
SaveImage(0,"Data\"+Fichier$,#PB_ImagePlugin_PNG)
LoadTexture(0,Fichier$)
CreateMaterial(0,TextureID(0))
MaterialAmbientColor(0,-1)

;-Entity
Global Taille=50
;Global AngleX.f,AngleY.f,AngleZ.f
Global Dim Rubik.s_Cube(2,2,2)
Global Dim Entity.s_Angle(26)
Global Dim Node(8)

;-Nodes
For i = 0 To 8
  Node(i) = CreateNode(#PB_Any)
Next i

Angle = 90

No=0
For z = 0 To 2
  For y = 0 To 2
    For x = 0 To 2
      *Ptr.Vertex=AllocateMemory(SizeOf(Vertex)*24)
      CopyMemory(?Vertices,*Ptr,SizeOf(Vertex)*24)
 
      ;Couleur dessus
      *Mem.Vertex = *Ptr
      If y = 2
        For i = 0 To 3
          *Mem\co=MaCouleur(0,0,255)
          *Mem + SizeOf(Vertex)
        Next i
      EndIf
      ;Couleur dessous
      *Mem.Vertex = *Ptr + 4 * SizeOf(Vertex)
      If y = 0
        For i = 0 To 3
          *Mem\co=MaCouleur(255,255,255)
          *Mem + SizeOf(Vertex)
        Next i
      EndIf
      ;Couleur devant
      *Mem.Vertex = *Ptr + 8 * SizeOf(Vertex)
      If z = 2
        For i = 0 To 3
          *Mem\co=MaCouleur(255,255,0)
          *Mem + SizeOf(Vertex)
        Next i
      EndIf
      ;Couleur derriere
      *Mem.Vertex = *Ptr + 12 * SizeOf(Vertex)
      If z = 0
        For i = 0 To 3
          *Mem\co=MaCouleur(255,128,0)
          *Mem + SizeOf(Vertex)
        Next i
      EndIf
      ;Couleur gauche
      *Mem.Vertex = *Ptr + 16 * SizeOf(Vertex)
      If x = 0
        For i = 0 To 3
          *Mem\co=MaCouleur(0,255,0)
          *Mem + SizeOf(Vertex)
        Next i
      EndIf       
      ;Couleur droit
      *Mem.Vertex = *Ptr + 20 * SizeOf(Vertex)
      If x = 2
        For i = 0 To 3
          *Mem\co=MaCouleur(255,0,0)
          *Mem + SizeOf(Vertex)
        Next i
      EndIf   
      CreateMesh(No,0.5)       
      SetMeshData(No, #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_Color | #PB_Mesh_UVCoordinate , *Ptr,24)
      SetMeshData(No,#PB_Mesh_Face,?Triangles,12)
      CreateEntity(No,MeshID(No),MaterialID(0))
      ScaleEntity(No,Taille - 1,Taille - 1,Taille - 1)
      EntityLocate(No, (x-1) * Taille, (y-1) * Taille, (z-1) * Taille)
      Rubik(x,y,z)\No=No
      No+1
    Next x
  Next y
Next z

;C'est le cube témoin
CreateMesh(30,0.5)       
SetMeshData(30, #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_Color | #PB_Mesh_UVCoordinate , *Ptr,24) 
SetMeshData(30,#PB_Mesh_Face,?Triangles,12)
CreateEntity(30,MeshID(30),MaterialID(0))
ScaleEntity(30,4,4,4)

;-Camera
CreateCamera(0,0,0,100,100)
CameraBackColor(0,RGB(0,0,255))
AmbientColor(RGB(200,200,200))
CameraLocate(0,EntityX(Centre) + 250 ,EntityY(Centre)+ 250,EntityZ(Centre))
MoveCamera(0,0,0,350)
CameraLookAt(0,EntityX(Centre),EntityY(Centre),EntityZ(Centre))

ShowGUI(128, #True)

;-Main loop

Repeat

  If ExamineKeyboard()
  EndIf

  If ExamineMouse()
   
    InputEvent3D(MouseX(), MouseY(), 0, "")
   
    If MouseButton(#PB_MouseButton_Left)
      Entity=MousePick(0, MouseX(), MouseY())
      If Entity<>30
      EntityLocate(30,PickX(),PickY(),PickZ())
      EndIf
      SetWindowTitle(0,"Entité sélectionnée " + Str(CameraProjectionX(0,PickX(),PickY(),PickZ())) + " - " + Str(CameraProjectionY(0,PickX(),PickY(),PickZ())))

    EndIf
  EndIf
     
  Repeat
     Event = WindowEvent3D()
    Until Event = 0
  RenderWorld()

  FlipBuffers()

Until KeyboardPushed(#PB_Key_Escape) Or event = #PB_Event_CloseWindow

End

DataSection
Vertices:
;Dessus 0 à 3
Data.f -0.5,0.5,-0.5
Data.f 0,1,0
Data.l 0
Data.f 0,0

Data.f 0.5,0.5,-0.5
Data.f 0,1,0
Data.l 0
Data.f 0,1

Data.f 0.5,0.5,0.5
Data.f 0,1,0
Data.l 0
Data.f 1,1

Data.f -0.5,0.5,0.5
Data.f 0,1,0
Data.l 0
Data.f 1,0

;Dessous 4 à 7
Data.f -0.5,-0.5,0.5
Data.f 0,-1,0
Data.l 0
Data.f 0,0

Data.f 0.5,-0.5,0.5
Data.f 0,-1,0
Data.l 0
Data.f 0,1

Data.f 0.5,-0.5,-0.5
Data.f 0,-1,0
Data.l 0
Data.f 1,1

Data.f -0.5,-0.5,-0.5
Data.f 0,-1,0
Data.l 0
Data.f 1,0

;Devant 8 à 11
Data.f -0.5,0.5,0.5
Data.f 0,0,1
Data.l 0
Data.f 0,0

Data.f 0.5,0.5,0.5
Data.f 0,0,1
Data.l 0
Data.f 0,1

Data.f 0.5,-0.5,0.5
Data.f 0,0,1
Data.l 0
Data.f 1,1

Data.f -0.5,-0.5,0.5
Data.f 0,0,1
Data.l 0
Data.f 1,0

;Derrière 12 à 15
Data.f 0.5,0.5,-0.5
Data.f 0,0,-1
Data.l 0
Data.f 0,0

Data.f -0.5,0.5,-0.5
Data.f 0,0,-1
Data.l 0
Data.f 0,1

Data.f -0.5,-0.5,-0.5
Data.f 0,0,-1
Data.l 0
Data.f 1,1

Data.f 0.5,-0.5,-0.5
Data.f 0,0,-1
Data.l 0
Data.f 1,0

;Cote gauche 16 à 19
Data.f -0.5,0.5,-0.5
Data.f -1,0,0
Data.l 0
Data.f 0,0

Data.f -0.5,0.5,0.5
Data.f -1,0,0
Data.l 0
Data.f 0,1

Data.f -0.5,-0.5,0.5
Data.f -1,0,0
Data.l 0
Data.f 1,1

Data.f -0.5,-0.5,-0.5
Data.f -1,0,0
Data.l 0
Data.f 1,0

;Cote droit 20 à 23
Data.f 0.5,0.5,0.5
Data.f 1,0,0
Data.l 0
Data.f 0,0

Data.f 0.5,0.5,-0.5
Data.f 1,0,0
Data.l 0
Data.f 0,1

Data.f 0.5,-0.5,-0.5
Data.f 1,0,0
Data.l 0
Data.f 1,1

Data.f 0.5,-0.5,0.5
Data.f 1,0,0
Data.l 0
Data.f 1,0

Triangles:
;0 à 3
Data.w 2,1,0
Data.w 0,3,2
;4 à 7
Data.w 6,5,4
Data.w 4,7,6
;8 à 11
Data.w 10,9,8
Data.w 8,11,10
;12 à 15
Data.w 14,13,12
Data.w 12,15,14
;16 à 19
Data.w 18,17,16
Data.w 16,19,18
;20 à 23
Data.w 22,21,20
Data.w 20,23,22
EndDataSection
Please correct my english
http://purebasic.developpez.com/
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Post by DarkDragon »

Hmm then the Help file says something different:
PB Helpfile to PickX() wrote:Nach einem MousePick() gibt dies die 'x' Position des ausgewählten Objekt in Welt-Koordinaten zurück.
Nach PointPick() gibt dies die 'x' Richtung des ausgewählten Punktes zurück, zwischen -1 und 1.
After a MousePick() it returns the x position of the object you clicked on, so it returns the EntityX() of the entity :? . And after a PointPick it returns the x direction relative to the camera clamped to [-1, 1].

But thanks, your example says something different.

Hmm well but the mousepick doesn't work correctly. My trees aren't where I clicked. The origin is correct, but it always places them too near to the camera instead of directly on the ground mesh.

We can move this thread or delete it.
bye,
Daniel
User avatar
Comtois
Addict
Addict
Posts: 1431
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Post by Comtois »

Yes, you are right, there is something strange with MousePick() and terrain.

I modified terrain.pb, i work fine only if camera is on top (top view).

Code: Select all

;
; ------------------------------------------------------------
;
;   PureBasic - Terrain
;
;    (c) 2003 - Fantaisie Software
;
; ------------------------------------------------------------
;

#CameraSpeed = 5

IncludeFile "Screen3DRequester.pb"

Define.f KeyX, KeyY, MouseX, MouseY

If InitEngine3D()
  Add3DArchive("Data", #PB_3DArchive_FileSystem)
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()

    AmbientColor(RGB(255,255,255))
    
  
    CreateMaterial  (0, LoadTexture(0, "Terrain_Texture.jpg"))
    AddMaterialLayer(0, LoadTexture(1, "Terrain_Detail.jpg"), #PB_Material_Add)
    
    CreateTerrain("terrain.png", MaterialID(0), 3, 2, 3, 4)


    LoadMesh   (2, "robot.mesh")
    
    CreateMaterial(2, LoadTexture(2, "r2skin.jpg"))
    
    CreateEntity(2, MeshID(2), MaterialID(2))
        
    CreateCamera(0, 0, 0, 100, 100)
    CameraLocate(0, 128, 225, 128)

    SkyDome("clouds.jpg",10)
    CreateSprite(0,8,8)
    
    StartDrawing(SpriteOutput(0))
      Circle(4,4,3,#Red)
    StopDrawing()
    
    Repeat
      Screen3DEvents()
            
      If ExamineKeyboard()
        
        If KeyboardPushed(#PB_Key_Left)
          KeyX = -#CameraSpeed 
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = #CameraSpeed 
        Else
          KeyX = 0
        EndIf
                  
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -#CameraSpeed 
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = #CameraSpeed 
        Else
          KeyY = 0
        EndIf

      EndIf
      
      If ExamineMouse()
        MouseX = -(MouseDeltaX()/10)*#CameraSpeed/2
        MouseY = -(MouseDeltaY()/10)*#CameraSpeed/2
        
        InputEvent3D(MouseX(), MouseY(), 0, "")
   
        If MouseButton(#PB_MouseButton_Left)
        
          entity=MousePick(0, MouseX(), MouseY())
          If entity<>2
            EntityLocate(2,PickX(),PickY(),PickZ()) 
          EndIf
        EndIf        
        
      EndIf
      
 
      
      ;Height.f = TerrainHeight(EntityX(2), EntityZ(2))
      ;EntityLocate(2,EntityX(2),Height,EntityZ(2))
      
      RotateCamera(0, MouseY, MouseX, RollZ, #PB_Relative)
      MoveCamera  (0, KeyX, 0, KeyY)
      
      RenderWorld()
      Screen3DStats()
      DisplayTransparentSprite(0,MouseX()-4,MouseY()-4)
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  EndIf
    
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
  
End
Last edited by Comtois on Tue Jan 06, 2009 11:32 pm, edited 1 time in total.
Please correct my english
http://purebasic.developpez.com/
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Post by DarkDragon »

Well in my game I create a mesh as terrain (Shadows don't work on a terrain right now) so the problem is not only with terrains, it's also with meshes - its a general problem. But your code is small and good for a bug report.
bye,
Daniel
User avatar
Comtois
Addict
Addict
Posts: 1431
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Post by Comtois »

i made something wrong in my code, now it work fine (previous code edited).

Added this

Code: Select all

          entity=MousePick(0, MouseX(), MouseY())
          If entity<>2
            EntityLocate(2,PickX(),PickY(),PickZ())
          EndIf

moved this

Code: Select all

      ;Height.f = TerrainHeight(EntityX(2), EntityZ(2))
      ;EntityLocate(2,EntityX(2),Height,EntityZ(2)) 
Please correct my english
http://purebasic.developpez.com/
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Post by DarkDragon »

But still it doesn't always work.

Especially when you are a bit outside of the terrain. On some corners you can't click everywhere. And I can get it outside the terrain.

Code: Select all

;
; ------------------------------------------------------------
;
;   PureBasic - Terrain
;
;    (c) 2003 - Fantaisie Software
;
; ------------------------------------------------------------
;

IncludeFile "Screen3DRequester.pb"

If InitEngine3D()
  Add3DArchive("Data", #PB_3DArchive_FileSystem)

  InitSprite()
  InitKeyboard()
  InitMouse()

  If Screen3DRequester()

    AmbientColor(RGB(255,255,255))


    CreateMaterial  (0, LoadTexture(0, "Terrain_Texture.jpg"))
    AddMaterialLayer(0, LoadTexture(1, "Terrain_Detail.jpg"), #PB_Material_Add)

    CreateTerrain("terrain.png", MaterialID(0), 3, 2, 3, 4)


    LoadMesh   (2, "robot.mesh")

    CreateMaterial(2, LoadTexture(2, "r2skin.jpg"))

    CreateEntity(2, MeshID(2), MaterialID(2))

    CreateCamera(0, 0, 0, 100, 100)
    CameraLocate(0,3280, 900, -100)
    CameraLookAt(0, 1500, 0, 1000)
    
    CreateSprite(0,8,8)

    StartDrawing(SpriteOutput(0))
    Circle(4,4,3,#Red)
    StopDrawing()

    Repeat
      Screen3DEvents()

      If ExamineMouse()
        InputEvent3D(MouseX(), MouseY(), 0, "")

        If MouseButton(#PB_MouseButton_Left)

          entity=MousePick(0, MouseX(), MouseY())
          If entity<>2
            EntityLocate(2,PickX(),PickY(),PickZ())
          EndIf
        EndIf

      EndIf

      RenderWorld()
      Screen3DStats()
      DisplayTransparentSprite(0,MouseX()-4,MouseY()-4)
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  EndIf

Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf

End
There it doesn't work.
bye,
Daniel
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Post by DarkDragon »

Hello,

I'm not sure if this is a bug, too, can you confirm it as a bug?

http://www.bradan.eu/files/ogre_bugs2.zip

The picking coordinates should be more away from the camera, shouldn't they?

Maybe it is related to the first one, but ...

That's why I requested for PickDepth. I thought it would always return something between [-1, 1] to the camera.
bye,
Daniel
User avatar
Comtois
Addict
Addict
Posts: 1431
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Post by Comtois »

Yes it doesnt work , i think it's a bug.

I created my own MousePick() et tested it with your mesh, it work fine.

http://herved25.free.fr/sources/DarkDragon.zip
Please correct my english
http://purebasic.developpez.com/
Post Reply