miniB3D - request help with Camerapick

Ryan2003

New member
Tutorial Author
Joined
Jul 12, 2020
Messages
28
I am trying to use the camerapick function of miniB3D to pick an on screen entity.
When the camera is poistioned so that I have the view that I want, the pick does not work.
By changinging the camera position, I can get the pick to work, but now it does not
have the view that I want.
How can I have the view that I want and have picking work?

cam.PositionEntity 16, 8, 0 ' this is the view I want,but pick does not work
'cam.PositionEntity 0, 0, 0 ' this one pick works, but not the desired view
code_language.cerberus:
Import minib3d

Function Main()
    New Game
End

Class Game Extends App
    
    Field cam:TCamera
    
    Field light:TLight
    
    Field hexcell:TEntity = CreateCylinder(6)

    Field yTiles:Int = 4' Number of tiles on the y axis
    Field xTiles:Int = 4' Number of tiles on the x axis
    Field totalTiles:Int
    Field length:Float = 1.025    'Length of the hexagon so we can calculate the spacing between tiles

    Field A:Float
    Field B:Float
    Field C:Float
    
    Field coord:Float[]
    
    Method OnCreate()
    
        SetUpdateRate 30
        SetRender()

        totalTiles = yTiles * xTiles
        C = length
        A = Sin(30) * C
        B = Sin(60) * C
        coord = coord.Resize(totalTiles * 2)
        
        cam = CreateCamera()
        cam.CameraClsColor(0, 0, 80)
        cam.PositionEntity 16, 8, 0    ' this is the view I want,but pick does not work
        'cam.PositionEntity 0, 0, 0    ' this one pick works, but not the desired view
        
        hexcell.PositionEntity(5, 0, 0)
        hexcell.ScaleEntity(1.0, 0.3, 1.0)
        cam.PointEntity(hexcell)
        
        light = CreateLight(1)
        light.PositionEntity(10, 0, 7)
        light.RotateEntity(90, 0, 0)
    
        'Wireframe(True)
    
        'Calculate tile positions
        Local k:Int = 0
        For Local i:= 1 To yTiles
            For Local j:= 1 To xTiles
        
                If (i Mod 2)  Then
                    'store the center pixel
                    coord[k] = j * (B * 2) + B
                    k = k + 1
                    coord[k] = C + i * (A + C) - 5
                    k = k + 1
                Else
            
                    'store the center pixel
                    coord[k] = j * (B * 2) + B + B
                    k = k + 1
                    coord[k] = C + i * (A + C) - 5
                    k = k + 1
                EndIf
            Next
        Next
        
        ' place the hexagons
        Local x:Float = 0
        Local z:Float = 0
        Local j:Int = 0
        For Local i:= 0 To totalTiles - 1
            Local tile:TEntity = CopyEntity(hexcell)
            tile.EntityPickMode(2)
            x = coord[j]
            j = j + 1
            z = coord[j]
            j = j + 1
            tile.PositionEntity(x, 0.0, z)
        Next
        
        hexcell.EntityAlpha(0)' hide the orginal hexagon
        
    End
    
    Method OnUpdate()
    
        If KeyHit(KEY_CLOSE) Or KeyHit(KEY_ESCAPE) Then Error ""
        
        
        If TouchDown(0)
            Local e:TEntity = cam.CameraPick(TouchX(), TouchY())
            If Not e Then Print "null pick" Else Print "hex picked"
        EndIf
        
        UpdateWorld()

    End
    
    Method OnRender()

        RenderWorld()   
        
    End

End
View I want:
1597186323942.png
But Picking does not work.
 

SLotman

Active member
3rd Party Module Dev
Joined
Jul 3, 2017
Messages
173
I just tried camerapick here as well and I have a similar problem. Using the code I posted here, I do a CameraPick on all die on screen.

The only one that gets picked is the one at 0,0,0. The others, won't. I looked at the 'pick' example on MiniB3D folder, and if you move the sphere from 0,0,0 (there is even a PositionEntity command commented out in the sample) it also stops working.

I can confirm that if I place camera at 0,0,0 and move my dice, then picking occurs correctly :/
 

SLotman

Active member
3rd Party Module Dev
Joined
Jul 3, 2017
Messages
173
Just found something out: changing the camera viewport or even using scaleentity on the camera can also mess camera picking, even if its @ 0,0,0 :(

And cameraviewport / camerazoom / scaleentity cam is needed to get everything into the correct aspect ratio on multiple resolutions :/
 

SLotman

Active member
3rd Party Module Dev
Joined
Jul 3, 2017
Messages
173
CameraProject breaks too :/

(I thought about doing the opposite of CameraPick, projecting every object to screen coordinates and comparing with the mouse position... but no luck there either)
 

SLotman

Active member
3rd Party Module Dev
Joined
Jul 3, 2017
Messages
173
I thought the problem was at GluUnProject function, the one responsible from projecting a 2D point in 3D space - so I found a implementation of it here and tried to port it to MiniB3D.

And, of course, it didn't work :p

This is way beyond me :(
I may have to go to #$%& Unity for this :(
 

SLotman

Active member
3rd Party Module Dev
Joined
Jul 3, 2017
Messages
173
I think the problem is in CameraPick itself. This is the code:
Code:
    Function CameraPick:TEntity(cam:TCamera,vx:Float,vy:Float)
        Local vec:Vector
        Local dvec:Vector
        
        vy=cam.viewport[3]-vy

        vec = cam.GluUnProject(vx,vy,0.0,cam)
        
        dvec = cam.GluUnProject(vx,vy,1.0,cam)

        Return Pick(vec.x,vec.y,-vec.z,dvec.x,dvec.y,-dvec.z,0.0)   
    End Function

As you can see, it doesn't take into account *at all* if the viewport isn't at screen 0,0 - it just 'flips' y coord (with vy=cam.viewport[3]-vy)
 

SLotman

Active member
3rd Party Module Dev
Joined
Jul 3, 2017
Messages
173
Why don't you try Vortex?
I'll have to rewrite, re-export models into different format (they're in B3D for now)... having to re-do everything I might as well learn a bit of Unity with it.

But, back in MiniB3D... I almost got it.

If your viewport keeps the width intact, just scaling the height, then changing to this will fix it:

Code:
vy=cam.viewport[3]-vy + cam.viewport[1]*2

(Which kind of makes sense? I'm adding the borders to the calculation)
But if the horizontal scaling is changed, I got no clue how to fix it yet.
 

SLotman

Active member
3rd Party Module Dev
Joined
Jul 3, 2017
Messages
173
Hmmm... Don't know what I did, but apparently now with this code its working on all aspect ratios I tested:

Code:
    Function CameraPick:TEntity(cam:TCamera,vx:Float,vy:Float)
        Local vec:Vector
        Local dvec:Vector
       
        vy=cam.viewport[3]-vy + cam.viewport[1]*2

        vec = cam.GluUnProject(vx,vy,0.0,cam)
       
        dvec = cam.GluUnProject(vx,vy,1.0,cam)

        Return Pick(vec.x,vec.y,-vec.z,dvec.x,dvec.y,-dvec.z,0.0)  
    End Function

(It still doesn't work if camera is not on 0,0,0 though)
 
Last edited:
Top Bottom