collisionHandlerEvent question

I am trying to figure out exactly how the collision code works when handling events. I am working on a game where I need objects in motion to collide with other objects in motion and am not completely sure I understand what events are being thrown with the collision handler. The following code will help me explain what I do not understand and is a modification of what it is the manual.

import direct.directbase.DirectStart
from direct.interval.IntervalGlobal import Sequence
from direct.showbase import DirectObject
from pandac.PandaModules import *
import random


class World( DirectObject.DirectObject ):
	def __init__( self ):
		#initialize traverser
		base.cTrav = CollisionTraverser()
	
		#initialize handler
		self.collHandEvent=CollisionHandlerEvent()
		self.collHandEvent.addInPattern('into-%in')
		self.collHandEvent.addOutPattern('outof-%in')
	
		#initialize collision count (for unique collision strings)
		self.collCount=0


		self.loadObj1()
		self.loadObj2()
		
		
			


	def loadObj1(self):
		#load a model. reparent it to the camera so we can move it.
		s = loader.loadModel('smiley') 
		s.reparentTo(camera)
		s.setPos(0, 25,0)
	
		#setup a collision solid for this model
		sColl=self.initCollisionSphere(s, True)
	
		#set up bitmasks
		#this object can only collide into things
		sColl[0].node().setIntoCollideMask( BitMask32.bit(2) )
		#this object will only collide with objects with this bitmask
		sColl[0].node().setFromCollideMask( BitMask32.bit(1) )

		#add this object to the traverser
		base.cTrav .addCollider(sColl[0] , self.collHandEvent)
		self.accept( 'into-' + sColl[1], self.collide3)
		self.accept( 'outof-' + sColl[1], self.collide4)
		
		self.posint1 = s.posInterval(20,Point3(random.random()*200-100,0,0))
		self.AIPath = Sequence(self.posint1, name = 'AIPath')
		self.AIPath.start()

	def loadObj2(self):
		#load a model. 
		t = loader.loadModel('smiley') 
		t.reparentTo(render)
		t.setPos(5, 25,0)
	
		#setup a collision solid for this model
		tColl=self.initCollisionSphere(t, True)
	
		#set up bitmasks
		#this object can only be collided into and will collide with the other object
		tColl[0].node().setIntoCollideMask( BitMask32.bit( 1 ))
		tColl[0].node().setFromCollideMask( BitMask32.bit(2) )

		#add this object to the traverser
		base.cTrav .addCollider(tColl[0], self.collHandEvent)

		#accept the events sent by the collisions
		self.accept( 'into-' + tColl[1], self.collide)
		self.accept( 'outof-' + tColl[1], self.collide2)
		

	def collide(self, collEntry):
		print "WERT: object has collided into another object"
	
	def collide2(self, collEntry):
		print "WERT: object is no longer colliding with another object"
		
	def collide3(self, collEntry):
		print "The other collision"
	
	def collide4(self, collEntry):
		print "The other leave"

	def initCollisionSphere( self, obj, show=False):
		#get the size of the object for the collision sphere
		bounds = obj.getChild(0).getBounds()
		center = bounds.getCenter()
		radius = bounds.getRadius()*1.1

		#create a collision sphere and name it something understandable
		collSphereStr = 'CollisionHull' +obj.getName()
		cNode=CollisionNode(collSphereStr)
		cNode.addSolid(CollisionSphere(center, radius ) )
		cNodepath=obj.attachNewNode(cNode)
		if show:
			cNodepath.show()
	
		# return a tuple with the collision node and its corrsponding string
		# return the collison node so that the bitmask can be set
		return (cNodepath,collSphereStr )



#run the world. move around with the mouse to create collisions
w = World()
run()

When I run this and there is a collision I get two collide and collide2 events instead of getting one of each of the 4 collide events. I don’t understand why this is happening and would be thrilled if someone could explain what I am missing.

You’re not giving your collision nodes unique names so they only send out one event type.

Also note that you appear to be adding all of your collision objects to the traverser, which means that all of them are both “from” and “into” objects. This further means that a collision between any two objects A and B will be reported twice: once as A -> B, and again as B -> A (since both A and B are “from” objects).

David

Yeah, it was the naming thing. Thanks for pointing that out. I feel stupid for missing it. I loaded a different model into the code and it threw all 4 collisions like I expected.