Collision Problems...

I can’t get my collisions to work. I followed the way that the ball-in-maze sample does it. I know that the collision geometry is being detected since it shows up when I render it.

As far as I can tell, it should work similar to the maze…

What am I doing wrong. Oh, and I am using the latest 1.5.1.

Here is my code:

import direct.directbase.DirectStart
from direct.task import Task 
from pandac.PandaModules import AmbientLight,DirectionalLight,LightAttrib
from pandac.PandaModules import Material,Vec4,BitMask32,Vec3
from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import CollisionTraverser,CollisionNode
from pandac.PandaModules import CollisionHandlerQueue,CollisionRay

camera.setPosHpr(0, 0, 250, 0, -90, 0)

#load the board for the ball to stay on.
playBoard = render.attachNewNode("playBoard")

play = loader.loadModel("models/trayWater")


#load the ball
ballRoot = playBoard.attachNewNode("ballRoot")

ball = loader.loadModel("models/ball")


#load the paddle for the ball to bounce off of
paddleP1 = playBoard.attachNewNode("paddleP1")

paddle = loader.loadModel("models/paddle")


#set up lighting
lAttrib = LightAttrib.makeAllOff()

directionalLight = DirectionalLight( "directionalLight" )

directionalLight.setDirection( Vec3( 0, 0, -1 ) )

directionalLight.setColor( Vec4( 0.375, 0.375, 0.375, 1 ) )


lAttrib = lAttrib.addLight( directionalLight )

ball.node().setAttrib( lAttrib )
play.node().setAttrib( lAttrib )

paddle.node().setAttrib( lAttrib )

#ballV = Vec3(0,0,0)

#create tasks for testing purposes
def moveY(task):
    # Put some code here
    ballPosY = ball.getY()
    return Task.cont 
def moveX(task):
    # Put some code here
    ballPosX = ball.getX()
    return Task.cont 

#taskMgr.add(moveX, "moveX")

#create events to test things with
def mouseClick():
  print "mouse clicked"
  taskMgr.add(moveY, "moveY")
def mouse3Click():
  print "mouse3 clicked"
  taskMgr.add(moveX, "moveX")
base.accept("mouse1", mouseClick)
base.accept("mouse3", mouse3Click)

#get the colision stuff from the board model
playCol = play.find("**/trayWater")

#get the collision from the ball
ballCol = ball.find("**/ball")

#tell the computer to deal with the collisions
#pretty much ripped off from ball-in-maze
cTrav = CollisionTraverser()
cHandler = CollisionHandlerQueue()
cTrav.addCollider(playCol, cHandler)
cTrav.addCollider(ballCol, cHandler)


#create a task to detect when a collision occurs and move th ball to the middle of the tray.
def collisonTask(task):
  #print cHandler.getNumEntries()
  for i in range(cHandler.getNumEntries()):
    print "there was a collision"
    #entry = cHandler.getEntry(i)
    #name = entry.getIntoNode().getName()
    #if name == "ball":
    #   ball.setPos(0,0,0)
    #   print "trayWater collide"
  return Task.cont

taskMgr.add(collisonTask, "collisonTask")


Are you saying you modified the maze demo and now it isn’t working? What result exactly did you expect to obtain?

Um, I guess I wasn’t very clear… I followed the steps described in the maze demo to set up my collisions.

Basically I have a tray that the ball is in. When the ball hits the side of the tray, then there should be a collision. As far as I can tell, there isn’t… Hence why I asked for help.

Your collision traverser doesn’t do the traversal at all.
You should tell it to do the traversal :


in collisonTask.

The maze code is different, since the traverser used is base.cTrav, which always do the traversal for you under the hood.
Have you read this part ?

    #For a traverser to actually do collisions, you need to call
    #traverser.traverse() on a part of the scene. Fortunatly, base has a
    #task that does this for the entire scene once a frame. This sets up our
    #traverser as the one to be called automatically
    base.cTrav = self.cTrav

Thanks! That fixed my lack of collisions. :smiley:

I guess I did miss that section. :blush:

Ok, so my collisions are being detected. But it isn’t changing the position of the ball like it is supposed to.

def wallCollide(self, colEntry):
    print "wallCollide"
    norm = colEntry.getSurfaceNormal(render) * -1.0
    curSpeed = self.ballV.length()
    inVec = self.ballV / curSpeed                 #The direction of travel
    velAngle =                    #Angle of incidance
    hitDir = colEntry.getSurfacePoint(render) - self.ballRoot.getPos()
    hitAngle =
    if velAngle > 0 and hitAngle > .995:
      print "inside if velAngle"
      #Standard reflection equation
      reflectVec = (norm * * -1) * 2) + inVec
      #This makes the velocity half of what it was if the hit was dead-on
      #and nearly exactly what it was if this is a glancing blow
      self.ballV = reflectVec * (curSpeed * (((1-velAngle)*.5)+.5))
      #Since we have a collision, the ball is already a little bit buried in
      #the wall. This calculates a vector needed to move it so that it is
      #exactly touching the wall
      disp = (colEntry.getSurfacePoint(render) -
      newPos = self.ball.getPos() + disp

Again, ripped off of the ball-in-maze tutorial… The function is getting executed since my print statements get run.

I think my problem has to do with this error I get when I run the file.

What does that mean?


You can only use a sphere, ray, or line as the active (“from”) collision solid.