Using a picking ray in aspect2d

OK makes sense, but how is one supposed to know that? The real kicker is your cam2d thing. Makes sense again, but again …

No seriously, you made my day/weekend/life. Thank you. It works now. Just with these little changes. Have to do a video at some point.
Thanks also go out to Astelix. Had some PM exchange with him and he now remembers that he once used cards and collisions in 2D too :wink:

One problem remains: I can also click all the buttons on the ScrolledFrame canvas, also the currently invisible ones. Is there some command to “mute” the buttons behind the DirectGUI?
The only other way I see is to check the mouse coords and only process clicks within a X,Y range.

It must be mentioned in the manual somewhere.

DSFrame used to use 4 clip planes to cut the canvas, so the clip planes culling wipes off the invisible collision solids.

But now it uses ScissorAttrib. Not sure how to deal with it.

Me neither :smiley: Looking at DirectGuiBase.py this is nowhere to be seen.
Why are the clicks registered anyway, if the visible stuff is already hidden - it seems the collision geometry is not?

Oh sorry, it’s ScissorEffect, not ScissorAttrib, so it does culling.

Try this on your canvas :
.node().setFinal(0)
.node().clearBounds()

No, that does nothing. The clicks still register and there’s still a notacable FPS drop when the map is open. Maybe that method doesnt work since the CardMakers and their collision geometry is not a traditional DirectGUI element?
Btw I just added a video where you can see the starmap in action. Thanks to you again.

I’ve tried the old setup using 4 clip planes, but that still can’t clip the collisions.

Simple bounds check works perfectly :

dsf = DirectScrolledFrame(frameColor=(0,0,0,.2))
canvas = dsf.getCanvas()
canvasParent = canvas.getParent()
canvas.setTransparency(1)
scale = .05
CM = CardMaker('')
CM.setFrame(0,1.5,-scale,0)
CM.setColor(.1,.1,.1,.2)
for z in range(30):
    card = canvas.attachNewNode(CM.generate())
    card.setPos(-1,0,1-z*scale*1.5)
    card.setCollideMask(BitMask32.bit(1))
    card.node().setBoundsType(BoundingVolume.BTBox)
ray = render2d.attachCollisionRay('ray', 0,0,0, 0,1,0, BitMask32.bit(1), BitMask32.allOff())
ray.show()
smiley = loader.loadModel('smiley')
smiley.reparentTo(ray)
smiley.setScale(.02)

CH = CollisionHandlerQueue()
CT = CollisionTraverser('')
CT.addCollider(ray,CH)
CT.showCollisions(render2d)

def checkColl(t):
    if base.mouseWatcherNode.hasMouse():
       m = base.mouseWatcherNode.getMouse()
       mRel = dsf.getRelativePoint(render2d,Point3(m[0],0,m[1]))
       dsfFrame = dsf.node().getFrame()
       if dsfFrame[0]<mRel[0]<dsfFrame[1] and dsfFrame[2]<mRel[2]<dsfFrame[3]:
          ray.setPos(m.getX(),0,m.getY())
          CT.traverse(canvas)
#           print CH.getNumEntries()
          if CH.getNumEntries():
             CH.sortEntries()
             print CH.getEntry(0)
    return t.cont
taskMgr.add(checkColl,'checkColl')

Thanks for your effort, but I am not sure what you’re trying to achieve. Do you want to limit click processing to the frame area?

I just do that by:

if mousepos.getX() < -0.46 or mousepos.getX() > 0.18 or mousepos.getY() > 0.41 or mousepos.getY() < -0.37:
return

which are the coords of the frame window. What I am currently thinking about is getting the FPS up. Where they drop I am not sure. Whether its the number of geometry or collision geometry or what else. What I hoped is that clipping the invisible buttons would bring the FPS up. I only check collisions on click, not every frame via a task.

To trade cull time with draw time, undo setFinal() and clearBounds().

Is there a way you can load the starmap once and just hide it?