Collision Spheres Working - With No Drop on FPS

I finally got my collisions working.
You can have plenty low-poly objects, and your collisions don’t cost you a thing.

# initialize handler for tile collisions
self.tileColHandEvent = CollisionHandlerEvent()
self.tileColHandEvent.addInPattern('into-%in')
self.tileColHandEvent.addOutPattern('outof-%in')
            
# Model - player
# setup a collision solid for Mod1
self.Mod1Col = self.initCollisionSphere(self.Mod1, True) # You can have a seperate collision sphere so as to have seperate sizes for the player's sphere as well as the tile sphere
# set up bitmasks Mod1 can only collide into things
self.Mod1Col[0].node().setIntoCollideMask(BitMask32.allOff())
# Mod1 will only collide with objects with this bitmask
self.Mod1Col[0].node().setFromCollideMask(BitMask32.bit(1))
# add Mod1 to the traverser
base.cTrav.addCollider(self.Mod1Col[0] , self.tileColHandEvent)

# You can also have another model which collides with the tiles for creating a different effect.
## # Model - Object
## # setup a collision solid for Obj1
## self.Obj1Col = self.initCollisionSphere0(self.Obj1, True) 
## # set up bitmasks Obj1 can only collide into things
## self.Obj1Col[0].node().setIntoCollideMask(BitMask32.allOff())
## # Obj1 will only collide with objects with this bitmask
## self.Obj1Col[0].node().setFromCollideMask(BitMask32.bit(1))
## # add Obj1 to the traverser
## base.cTrav.addCollider(self.Obj1Col[0] , self.tileColHandEvent)
  
# Model 001
# setup a collision solid for tile model
self.tileCol001 = self.initCollisionSphere1(self.fieldtile001, True)
# set up bitmasks tile model can only be collided into and will collide with the other object
self.tileCol001[0].node().setIntoCollideMask(BitMask32.bit(1))
self.tileCol001[0].node().setFromCollideMask(BitMask32.allOff())
# add tile model to the traverser
base.cTrav.addCollider(self.tileCol001[0], self.tileColHandEvent)
# accept the events sent by the collisions
self.accept('into-' + self.tileCol001[1], self.collide1)
self.accept('outof-' + self.tileCol001[1], self.collide2)
            
# Model 002
# setup a collision solid for tile model
self.tileCol002 = self.initCollisionSphere1(self.fieldtile002, True)
# set up bitmasks tile model can only be collided into and will collide with the other object
self.tileCol002[0].node().setIntoCollideMask(BitMask32.bit(1))
self.tileCol002[0].node().setFromCollideMask(BitMask32.allOff())
# add tile model to the traverser
base.cTrav.addCollider(self.tileCol002[0], self.tileColHandEvent)
# accept the events sent by the collisions
self.accept('into-' + self.tileCol002[1], self.collide1)
self.accept('outof-' + self.tileCol002[1], self.collide2)
            
# Model 003
# setup a collision solid for tile model
self.tileCol003 = self.initCollisionSphere1(self.fieldtile003, True)
# set up bitmasks tile model can only be collided into and will collide with the other object
self.tileCol003[0].node().setIntoCollideMask(BitMask32.bit(1))
self.tileCol003[0].node().setFromCollideMask(BitMask32.allOff())
# add tile model to the traverser
base.cTrav.addCollider(self.tileCol003[0], self.tileColHandEvent)
# accept the events sent by the collisions
self.accept('into-' + self.tileCol003[1], self.collide1)
self.accept('outof-' + self.tileCol003[1], self.collide2)

def collide1(self, collEntry):
    # Get the name of the from object from the egg file
    # You can use this code to find out what the name is, but its usually in the top group - I think.
    print collEntry.getFromNodePath().getParent().getName()
    # Set the effect for each from object
    if collEntry.getFromNodePath().getParent().getName() == "name in egg file":
        collEntry.getIntoNodePath().getParent().setColor(1,0,0,1)
    else: collEntry.getIntoNodePath().getParent().setColor(1,1,0,1)

def collide2(self, collEntry):
    collEntry.getIntoNodePath().getParent().setColor(1,1,1,1)

def initCollisionSphere(self, obj, show = False):
    # get the size of the player object for the collision sphere
    bounds = obj.getChild(0).getBounds()
    center = bounds.getCenter()
    radius = bounds.getRadius()/1.5 
        
    # 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 corresponding string
    # return the collision node so that the bitmask can be set
    return (cNodepath, collSphereStr)

def initCollisionSphere1(self, obj, show = False):
    # get the size of the object for the collision sphere
    bounds1 = obj.getChild(0).getBounds()
    center1 = bounds1.getCenter()
    radius1 = bounds1.getRadius()/3 # Small sphere - Area for collision is lessened
        
    # create a collision sphere and name it something understandable
    collSphereStr1 = 'CollisionHull1' + obj.getName()
    cNode1 = CollisionNode(collSphereStr1)
    cNode1.addSolid(CollisionSphere(center1, radius1))
    cNodepath1 = obj.attachNewNode(cNode1)
    if show:
        cNodepath1.show()
        
    # return a tuple with the collision node and its corresponding string
    # return the collision node so that the bitmask can be set
    return (cNodepath1, collSphereStr1)

## def initCollisionSphere0(self, obj, show = False):
    ## # get the size of the object for the collision sphere
    ## bounds0 = obj.getChild(0).getBounds()
    ## center0 = bounds0.getCenter()
    ## radius0 = bounds0.getRadius()*1.5 # Bigger area
        
    ## # create a collision sphere and name it something understandable
    ## collSphereStr0 = 'CollisionHull1' + obj.getName()
    ## cNode0 = CollisionNode(collSphereStr0)
    ## cNode0.addSolid(CollisionSphere(center0, radius0))
    ## cNodepath0 = obj.attachNewNode(cNode0)
    ## if show:
        ## cNodepath1.show()
        
    ## # return a tuple with the collision node and its corresponding string
    ## # return the collision node so that the bitmask can be set
    ## return (cNodepath0, collSphereStr0)

Yes i find that people say that panda3d collisions system is slow is when they don’t use it right.

I know i was like this :slight_smile:

Panda3d collisions can be quite fast.

Any collision system is slow if you do stupid things with it. Okay, that’s a bit harsh; If you’ve never had experience with implementing collision detection and response, the idea of tens of thousands of triangles checking each other for intersection each frame might not sound all that bad. (I mean, modern PCs can render several times that amount of triangles, right? etc.)

I’ve not had any real complaints with Panda’s built-in system. It’s simple, fast, and pretty flexible. I originally started implementing my game using ODE, but realized this was way overkill and switched to basic Panda coldet along with its simple built-in physics. I haven’t had any issues with it.