Collision Problem, Infinite Tunnel sample

Hey I’m just looking for a second eye on a program I’m writing that’s due later tonight. I’m modifying the Infinite Tunnel sample to make a game where the player/camera collects objects around the tunnel for a score. My problem is the collectible objects, which are the ball model, seem to be colliding with something, but it is not my camera and I have no idea what it is. I have tried a couple ways of having the objects collide with a the camera, a CollisionRay and another ball object that is at the cameras position.

Here is one of the entries I get from the collectible object CollisionHandlerQueue:

CollisionEntry:
from render/ball1/ball1
into render/ball2/-PandaNode/ball []
at -0.264277 0.0528545 62.3579
normal 0.149373 -0.059348 -0.310911
interior -0.27134 0.0556609 62.3726 (depth 0.0165504)
respect_prev_transform = 0

Does anyone know what the
render/ball2/-PandaNode/ball [] is?

Now I’m posting most of the code, since I don’t know what the problem is, with the exception of the continuing tunnel code.

If anybody can help me out, it would be greatly appreciated. Thanks in advance.

# Author: Shao Zhang and Phil Saltzman
# Last Updated: 4/18/2005
#
# This tutorial will cover fog and how it can be used to make a finite length
# tunnel seem endless by hiding its endpoint in darkness. Fog in panda works by
# coloring objects based on their distance from the camera. Fog is not a 3D
# volume object like real world fog.
# With the right settings, Fog in panda can mimic the appearence of real world # fog.
#
# The tunnel and texture was originally created by Vamsi Bandaru and Victoria
# Webb for the Entertainment Technology Center class Building Virtual Worlds

import direct.directbase.DirectStart 
from panda3d.core import Fog
from panda3d.core import TextNode
from panda3d.core import CollisionSphere, CollisionHandlerQueue
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import BitMask32, CollisionRay
from direct.gui.OnscreenText import OnscreenText
from direct.showbase.DirectObject import DirectObject
from direct.interval.MetaInterval import Sequence
from direct.interval.LerpInterval import LerpFunc
from direct.interval.FunctionInterval import Func
import sys, os, random

#Global variables for the tunnel dimensions and speed of travel
TUNNEL_SEGMENT_LENGTH = 50           
TUNNEL_TIME = 2   #Amount of time for one segment to travel the
                  #distance of TUNNEL_SEGMENT_LENGTH

class World(DirectObject):
  #Macro-like function used to reduce the amount to code needed to create the
  #on screen instructions
  def genLabelText(self, text, i):
    return OnscreenText(text = text, pos = (-1.3, .95-.06*i), fg=(1,1,1,1),
                       align = TextNode.ALeft, scale = .05)
  
  def __init__(self):
    #Global Variable for Key Events
    self.keyMap = {"arrow_right":0, "arrow_left":0, 
                   "arrow_up":0, "arrow_down":0}
    self.score = 0
    self.cTrav = CollisionTraverser()
    self.cTrav.showCollisions(render)
    #self.ballColHandler = CollisionHandlerQueue()
  
    # Global Variable for collision spheres
    self.colNode = [None for i in range(10)]
    # Global Variable for collision sphere nodes
    self.colNN = [None for i in range(10)]
    
    ###Standard initialization stuff
    #Standard title that's on screen in every tutorial
    self.title = OnscreenText(
      text="Panda3D: Tutorial - Fog", style=1, fg=(1,1,1,1),
      pos=(0.9,-0.95), scale = .07)

    #Code to generate the on screen instructions
    self.escapeEventText = self.genLabelText("ESC: Quit", 0)
    self.pkeyEventText = self.genLabelText("[P]: Pause", 1)
    self.upkeyEventText = self.genLabelText("Up Arrow: Move Up", 2)
    self.downkeyEventText = self.genLabelText("Down Arrow: Move Down", 3)
    self.leftkeyEventText = self.genLabelText("Left Arrow: Move Left", 4)
    self.rightkeyEventText = self.genLabelText("Right Arrow: Move Right", 5)
    
    """ Commenting out the old instructions
    self.tkeyEventText = self.genLabelText("[T]: Toggle Fog", 2)
    self.dkeyEventText = self.genLabelText("[D]: Make fog color black", 3)
    self.sdkeyEventText = self.genLabelText(
      "[SHIFT+D]: Make background color black", 4)
    self.rkeyEventText = self.genLabelText("[R]: Make fog color red", 5)
    self.srkeyEventText = self.genLabelText(
      "[SHIFT+R]: Make background color red", 6)
    self.bkeyEventText = self.genLabelText("[B]: Make fog color blue", 7)
    self.sbkeyEventText = self.genLabelText(
      "[SHIFT+B]: Make background color blue", 8)
    self.gkeyEventText = self.genLabelText("[G]: Make fog color green", 9)
    self.sgkeyEventText = self.genLabelText(
      "[SHIFT+G]: Make background color green", 10)
    self.lkeyEventText = self.genLabelText(
      "[L]: Make fog color light grey", 11)
    self.slkeyEventText = self.genLabelText(
      "[SHIFT+L]: Make background color light grey", 12)
    self.pluskeyEventText = self.genLabelText("[+]: Increase fog density", 13)
    self.minuskeyEventText = self.genLabelText("[-]: Decrease fog density", 14)
    """

    base.disableMouse() #disable mouse control so that we can place the camera
    camera.setPosHpr(0,0,0, 0, -90, 0)
    base.setBackgroundColor(0,0,0) #set the background color to black
    
    ###World specific-code
    
    #Create an instance of fog called 'distanceFog'.
    #'distanceFog' is just a name for our fog, not a specific type of fog.
    self.fog = Fog('distanceFog')
    #Set the initial color of our fog to black.
    self.fog.setColor(0, 0, 0)
    #Set the density/falloff of the fog.  The range is 0-1.
    #The higher the numer, the "bigger" the fog effect.
    self.fog.setExpDensity(.07)
    #We will set fog on render which means that everything in our scene will
    #be affected by fog. Alternatively, you could only set fog on a specific
    #object/node and only it and the nodes below it would be affected by
    #the fog.
    render.setFog(self.fog)

    #Define the keyboard input
    #Escape closes the demo
    self.accept('escape', sys.exit)         
    #Handle pausing the tunnel
    self.accept('p', self.handlePause)
    #Handle the movement of the camera/player
    self.accept('arrow_up', self.setKey, ['arrow_up', 1])
    self.accept('arrow_up-up', self.setKey, ['arrow_up', 0])
    self.accept('arrow_left', self.setKey, ['arrow_left', 1])
    self.accept('arrow_left-up', self.setKey, ['arrow_left', 0])
    self.accept('arrow_down', self.setKey, ['arrow_down', 1])
    self.accept('arrow_down-up', self.setKey, ['arrow_down', 0])
    self.accept('arrow_right', self.setKey, ['arrow_right', 1])
    self.accept('arrow_right-up', self.setKey, ['arrow_right', 0])
    """ Commenting out the old functionality
    #Handle turning the fog on and off
    self.accept('t', ToggleFog, [render, self.fog])
    #Sets keys to set the fog to various colors
    self.accept('r', self.fog.setColor, [1,0,0])
    self.accept('g', self.fog.setColor, [0,1,0])
    self.accept('b', self.fog.setColor, [0,0,1])
    self.accept('l', self.fog.setColor, [.7,.7,.7])
    self.accept('d', self.fog.setColor, [0,0,0])
    #Sets keys to change the background colors
    self.accept('shift-r', base.setBackgroundColor, [1,0,0])
    self.accept('shift-g', base.setBackgroundColor, [0,1,0])
    self.accept('shift-b', base.setBackgroundColor, [0,0,1])
    self.accept('shift-l', base.setBackgroundColor, [.7,.7,.7])
    self.accept('shift-d', base.setBackgroundColor, [0,0,0])
    #Increases the fog density when "+" key is pressed
    self.accept('+', self.addFogDensity, [.01])
    #This is to handle the other "+" key (it's over = on the keyboard)
    self.accept('=', self.addFogDensity, [.01])
    self.accept('shift-=', self.addFogDensity, [.01])
    #Decreases the fog density when the "-" key is pressed
    self.accept('-', self.addFogDensity, [-.01])
    """
    
    taskMgr.add(self.mainLoop, "moveTask")
    
    self.camCollisionRay = CollisionRay()
    self.camCollisionRay.setOrigin(0, 0, 1000)
    self.camCollisionRay.setDirection(0, 0, -1)
    self.camCollisionNode = CollisionNode('camCollision')
    self.camCollisionNode.setFromCollideMask(BitMask32.bit(0))
    self.camCollisionNode.setIntoCollideMask(BitMask32.allOff())
    self.camCollisionNewNode = base.camera.attachNewNode(self.camCollisionNode)
    self.camCollisionHandler = CollisionHandlerQueue()
    self.cTrav.addCollider(self.camCollisionNewNode, self.camCollisionHandler)
  
    
    #Load the tunel and start the tunnel
    self.initTunnel()
    self.contTunnel()
    self.spawnCollectibles()

  #This function will change the fog density by the amount passed into it
  #This function is needed so that it can look up the current value and
  #change it when the key is pressed. If you wanted to bind a key to set it
  #at a given value you could call self.fog.setExpDensity directly
  def addFogDensity(self, change):
    #The min() statement makes sure the density is never over 1
    #The max() statement makes sure the density is never below 0
    self.fog.setExpDensity(
      min(1, max(0, self.fog.getExpDensity() + change)))
    
  # Map the keys to the value for key events
  def setKey(self, key, value):
      self.keyMap[key] = value
      
  #Main Loop 
  def mainLoop(self, task):
    #Set the direction of the camera/player
    if(self.keyMap['arrow_up'] != 0):
        if(base.camera.getY() <= 1):
            base.camera.setY(base.camera.getY() + 2 * globalClock.getDt())
    if(self.keyMap['arrow_down'] != 0):
        if(base.camera.getY() >= -1):
            base.camera.setY(base.camera.getY() - 2 * globalClock.getDt())
    if(self.keyMap['arrow_right'] != 0):
        if(base.camera.getX() <= 1):
            base.camera.setX(base.camera.getX() + 2 * globalClock.getDt())
    if(self.keyMap['arrow_left'] != 0):
        if(base.camera.getX() >= -1):
            base.camera.setX(base.camera.getX() - 2 * globalClock.getDt())
            
    # Set the ball to the camera pos so there is something to collide with
    
    #Make the ball collectibles move toward the player    
    for x in range(10):
        self.collect[x].setZ(self.collect[x].getZ() + 10 * globalClock.getDt())
    
    self.cTrav.traverse(render)
    
    
    entries = []
    for i in range(self.camCollisionHandler.getNumEntries()):
        self.score += 1
        entry = self.camCollisionHandler.getEntry(i)
        entries.append(entry)
        print entry
        # When Collision occurs, remove the ball and add to the score
        if entry.getIntoNode().getName() == 'ball0':
            entry.getIntoNodePath().remove()
            self.collect[0].remove()
            self.score += 1
        elif entry.getIntoNode().getName() == 'ball1':
            entry.getIntoNodePath().remove()
            self.collect[1].remove()
            self.score += 1
        elif entry.getIntoNode().getName() == 'ball2':
            entry.getIntoNodePath().remove()
            self.collect[2].remove()
            self.score += 1
        elif entry.getIntoNode().getName() == 'ball3':
            entry.getIntoNodePath().remove()
            self.collect[3].remove()
            self.score += 1
        elif entry.getIntoNode().getName() == 'ball4':
            entry.getIntoNodePath().remove()
            self.collect[4].remove()
            self.score += 1
        elif entry.getIntoNode().getName() == 'ball5':
            entry.getIntoNodePath().remove()
            self.collect[5].remove()
            self.score += 1
        elif entry.getIntoNode().getName() == 'ball6':
            entry.getIntoNodePath().remove()
            self.collect[6].remove()
            self.score += 1
        elif entry.getIntoNode().getName() == 'ball7':
            entry.getIntoNodePath().remove()
            self.collect[7].remove()
            self.score += 1
        elif entry.getIntoNode().getName() == 'ball8':
            entry.getIntoNodePath().remove()
            self.collect[8].remove()
            self.score += 1
        elif entry.getIntoNode().getName() == 'ball9':
            entry.getIntoNodePath().remove()
            self.collect[9].remove()
            self.score += 1
    
    if(self.collect[9].getZ() > base.camera.getZ()):
        for x in range(10):
            self.collect[x].remove()
        self.spawnCollectibles()
        #print "Score: " + str(self.score)

    return task.cont
  

    
  def initCollisionSphere(self, ball, num, show=True):
      collSphereStr = "ball" + str(num)
      cNode = CollisionNode(collSphereStr)
      cNode.addSolid(CollisionSphere(ball.getPos(), 2))
      return cNode
  
  #Handles the collectibles, spawn and move them.   
  def spawnCollectibles(self):
      self.collect = [None for i in range(10)]
      for x in range(10):
          # Set up the ball on the screen 
          self.collect[x] = loader.loadModel('models/ball')
          self.collect[x].setName('ball' + str(x))
          self.collect[x].setColor(random.uniform(.1, 1.0),
                                   random.uniform(.1, 1.0),
                                   random.uniform(.1, 1.0))
          self.collect[x].setScale(.35)
          self.collect[x].setPos(random.uniform(-.8, .8),
                                 random.uniform(-.8, .8), 
                                 random.uniform(-10.0 * x, -10.0))
          self.collect[x].reparentTo(render)
          # Set up the collision sphere for the ball
          self.colNode[x] = self.initCollisionSphere(self.collect[x], x)
          self.colNN[x] = self.collect[x].attachNewNode(self.colNode[x])
          self.cTrav.addCollider(self.colNN[x], self.camCollisionHandler)
          # print "ball" + str(x) + "made."
      self.scoreText = self.genLabelText("Score: " + str(self.score), 30)
      self.collect[9].setZ(-75.1)