A question about collision patterns using tags [SOLVED]

I’m tryng to make work a piece of code using CollisionHandlerEvent - while I aint no problems using a pattern sucha

collisionHandler.addInPattern('%fn-into-%in')

I’m encountering big walls going with tags.
In my piece of code I defined, for what I got in the manual, a pattern like this:

collisionHandler.addInPattern("%fn-into-%(smileys)ih")

that should call an handler for colliders defined like this:

  cnodePath = smileCollider.attachNewNode(CollisionNode('smileycnode%d'%n))
  cnodePath.node().addSolid(CollisionSphere(0, 0, 0, 1))
  cnodePath.setTag('smileys', str(n))

while the mouse hover one of these colliders - the accept is as follows:

DO=DirectObject()
DO.accept('mouseraycnode-into-smileys', collideEventIn)

It is the same piece of code I used successfully with the first pattern described above and just changed thew patterns and added the setTag line - anybody knows what I’m missing or misunderstood?

Sorry, not exactly sure, but I had a question a while back asking how to structure it, hope it helps:

https://discourse.panda3d.org/viewtopic.php?t=7567&highlight=

P.S Mine was for values, not for the tag name

Your tag ‘smileys’ is set to the value of ‘smileys’, correct?

I see:

cnodePath.setTag('smileys', str(n))

But that doesn’t tell me what the tag smileys is being set to.

The pattern match string of “%(smileys)ih” will look for the tag named “smileys” and then whatever your accept requests is what it will be filtered upon. So in this case of accept(‘mouseraycnode-into-smileys’), it’s looking for the tag “smileys” with the content of “smileys”.

the manual clearly says that using those tags, it’s looking for the tag “smileys” with whatever content. But this wont happen - what you’re saying (as I’m getting it) is related to the tags mentioned above by Novora, and I tried that kind of pattern and seen it working. Beside, I provided a test for both the 2 patterning versions, for those who wanna try:

*** pattern filtering event coming FROM tag key named ‘rays’ with value ‘ray1’ TO tag named ‘smileys’ with value ‘smiley1’ (IT WORKS)

import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import CollisionHandlerEvent, CollisionNode, CollisionSphere, CollisionTraverser, CollisionRay
from pandac.PandaModules import VBase4, AmbientLight

base.disableMouse()

def collideEventIn(entry):
  np_from=entry.getFromNodePath()
  np_into=entry.getIntoNodePath()
  print "'%s' collide with '%s'" % (
    np_from.getName(), np_into.getName()
  )
  np_into.getParent().setColor(.6, 0.5, 1.0, 1)

def collideEventOut(entry):
  np_into=entry.getIntoNodePath()
  np_into.getParent().setColor(1.0, 1.0, 1.0, 1)

def rayupdate(task):
  if base.mouseWatcherNode.hasMouse():
    mpos=base.mouseWatcherNode.getMouse()
    pickerRay.setFromLens(base.camNode, mpos.getX(),mpos.getY())
  return task.cont

base.cTrav=CollisionTraverser()
collisionHandler = CollisionHandlerEvent()
collisionHandler.addInPattern("%(rays)ft-into-%(smileys)it")
collisionHandler.addOutPattern("%(rays)ft-out-%(smileys)it")

pickerNode=CollisionNode('mouseraycnode')
pickerNP=base.camera.attachNewNode(pickerNode)
pickerRay=CollisionRay()
pickerNode.addSolid(pickerRay)
pickerNode.setTag('rays', 'ray1')
base.cTrav.addCollider(pickerNP, collisionHandler)

smileCollider = loader.loadModel('smiley')
smileCollider.reparentTo(render)
smileCollider.setPos(0,20,0)
cnodePath = smileCollider.attachNewNode(CollisionNode('smileycnode'))
cnodePath.node().addSolid(CollisionSphere(0, 0, 0, 1))
cnodePath.setTag('smileys', 'smiley1')

DO=DirectObject()
DO.accept('ray1-into-smiley1', collideEventIn)
DO.accept('ray1-out-smiley1', collideEventOut)

taskMgr.add(rayupdate, "updatePicker")

run()

*** pattern filtering event coming FROM tag key named ‘rays’ with ANY value TO tag named ‘smileys’ with ANY value (IT FAILS)

import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import CollisionHandlerEvent, CollisionNode, CollisionSphere, CollisionTraverser, CollisionRay
from pandac.PandaModules import VBase4, AmbientLight

base.disableMouse()

def collideEventIn(entry):
  np_from=entry.getFromNodePath()
  np_into=entry.getIntoNodePath()
  print "'%s' collide with '%s'" % (
    np_from.getName(), np_into.getName()
  )
  np_into.getParent().setColor(.6, 0.5, 1.0, 1)

def collideEventOut(entry):
  np_into=entry.getIntoNodePath()
  np_into.getParent().setColor(1.0, 1.0, 1.0, 1)

def rayupdate(task):
  if base.mouseWatcherNode.hasMouse():
    mpos=base.mouseWatcherNode.getMouse()
    pickerRay.setFromLens(base.camNode, mpos.getX(),mpos.getY())
  return task.cont

base.cTrav=CollisionTraverser()
collisionHandler = CollisionHandlerEvent()
collisionHandler.addInPattern("%(rays)fh-into-%(smileys)ih")
collisionHandler.addOutPattern("%(rays)fh-out-%(smileys)ih")

pickerNode=CollisionNode('mouseraycnode')
pickerNP=base.camera.attachNewNode(pickerNode)
pickerRay=CollisionRay()
pickerNode.addSolid(pickerRay)
pickerNode.setTag('rays', 'ray1')
base.cTrav.addCollider(pickerNP, collisionHandler)

smileCollider = loader.loadModel('smiley')
smileCollider.reparentTo(render)
smileCollider.setPos(0,20,0)
cnodePath = smileCollider.attachNewNode(CollisionNode('smileycnode'))
cnodePath.node().addSolid(CollisionSphere(0, 0, 0, 1))
cnodePath.setTag('smileys', 'smiley1')

DO=DirectObject()
DO.accept('rays-into-smileys', collideEventIn)
DO.accept('rays-out-smileys', collideEventOut)

taskMgr.add(rayupdate, "updatePicker")

run()

with both code pieces we expect the ball changing color while mouse pointer is over.

Yeah, it matches based on the content of the tag. I’m not actually sure what’s correct behavior – What the manual says, or what actually happens in the code.

When writing patterns for the EventHandler, anything that ends with “h” or “x” is a condition to be satisfied, and doesn’t add anything to the generated event string.
So, to make the snippet work:

collisionHandler.addInPattern("rays-into-smileys%(""rays"")fh%(""smileys"")ih")
collisionHandler.addOutPattern("rays-out-smileys%(""rays"")fh%(""smileys"")ih")

The first part is the event string launched, the second are the condistion for it to be launched.

Actually, the generated event of your sample code is only “-into-”.
The phrase “generate event only if …” means it’s a condition to meet.

messenger.toggleVerbose() is your friend.

first off, thankyou guys for your hints

Ausir, dunno how you figured out but who cares: EUREKA, FUNZIONA (it works)!
I could just settle things like this:

collisionHandler.addInPattern("goofy%(""rays"")fh%(""smileys"")ih")
collisionHandler.addOutPattern("mickeymouse%(""rays"")fh%(""smileys"")ih")

#... and at last:

DO.accept('goofy', collideEventIn)
DO.accept('mickeymouse', collideEventOut)

and it still works - Honestly I’m not sure to have got the why (shortage of braincells I suppose) but it is enough for have things work as I need.

Here you go the working piece:

# -*- coding: utf-8 -*-
import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import CollisionHandlerEvent, CollisionNode, CollisionSphere, CollisionTraverser, CollisionRay
from pandac.PandaModules import VBase4, AmbientLight

base.disableMouse()

def collideEventIn(entry):
  np_from=entry.getFromNodePath()
  np_into=entry.getIntoNodePath()
  print "'%s' collide with '%s'" % (
    np_from.getName(), np_into.getName()
  )
  np_into.getParent().setColor(.6, 0.5, 1.0, 1)

def collideEventOut(entry):
  np_into=entry.getIntoNodePath()
  np_into.getParent().setColor(1.0, 1.0, 1.0, 1)

def rayupdate(task):
  if base.mouseWatcherNode.hasMouse():
    mpos=base.mouseWatcherNode.getMouse()
    pickerRay.setFromLens(base.camNode, mpos.getX(),mpos.getY())
  return task.cont

base.cTrav=CollisionTraverser()
collisionHandler = CollisionHandlerEvent()
collisionHandler.addInPattern("goofy%(""rays"")fh%(""smileys"")ih")
collisionHandler.addOutPattern("mickeymouse%(""rays"")fh%(""smileys"")ih")
pickerNode=CollisionNode('mouseraycnode')
pickerNP=base.camera.attachNewNode(pickerNode)
pickerRay=CollisionRay()
pickerNode.addSolid(pickerRay)
pickerNode.setTag('rays', 'ray1')
base.cTrav.addCollider(pickerNP, collisionHandler)

smileCollider = loader.loadModel('smiley')
smileCollider.reparentTo(render)
smileCollider.setPos(0,20,0)
cnodePath = smileCollider.attachNewNode(CollisionNode('smileycnode'))
cnodePath.node().addSolid(CollisionSphere(0, 0, 0, 1))
cnodePath.setTag('smileys', 'smiley1')

DO=DirectObject()
DO.accept('goofy', collideEventIn)
DO.accept('mickeymouse', collideEventOut)

taskMgr.add(rayupdate, "updatePicker")

run()

thanks again all folks!

  • UPDATE *
    luckily is not such a matter of braincells shortage but cos they are so slow - anyhow now I get why it work like that and for those eager to know it as well, check and download my stepping tutorial here, I explained all in the step5.