Two colliding objects

Hai,

I tried many things to understand how collision works, but it never worked as it supposed to do.

My situation:
I have two boats, boat1 and boat2.
If boat1 hits boat2, it supposed to be pushed back (and offcourse the same with boat1)
It is a top-down situation, with the models both moving in one task-cycle.

How can I deal with this? I looked at the examples given in the manual, but I have to say that it doesn’t reveal the whole mystery of collision for me. Is there someone here able to write a small example for my situation?

Thanks,
Bob

Okay, I have the following… but there is still no pushback?

def Collision(self):
    
	    boundsboat1 = self.boat1.getChild(0).getBounds()
	    boundsboat2 = self.boat2.getChild(0).getBounds()
	    centerboat1 = boundsboat1.getCenter() 
	    radiusboat1 = boundsboat1.getRadius()
	    centerboat2 = boundsboat2.getCenter() 
	    radiusboat2 = boundsboat2.getRadius() 
	    cSphereboat1 = CollisionSphere(centerboat1,radiusboat1)
	    cSphereboat2 = CollisionSphere(centerboat2,radiusboat2)	    
	    cNodeboat1 = CollisionNode("boat1")
	    cNodeboat2 = CollisionNode("boat2")
	    cNodeboat1.addSolid(cSphereboat1)
	    cNodeboat2.addSolid(cSphereboat2)	    
	    self.boat1CollNodePath = self.boat1.attachNewNode(cNodeboat1)
	    self.boat2CollNodePath = self.boat2.attachNewNode(cNodeboat2) 
	    # Collision ray for the car. 
	    cRay = CollisionRay(0, 0, 0, 0, 0, -1) 
	    cNode = CollisionNode("boat1_Ray_Down")
	    cNode = CollisionNode("boat2_Ray_Down") 
	    cNode.addSolid(cRay) 
	    self.boat1CollRayNodePath = self.boat1.attachNewNode(cNode)
	    self.boat1CollRayNodePath.show() 
	    self.boat2CollRayNodePath = self.boat2.attachNewNode(cNode)
	    self.boat2CollRayNodePath.show() 
	    
	    self.cTrav = CollisionTraverser()    
	    self.pusher_boat1 = PhysicsCollisionHandler()
	    self.pusher_boat2 = PhysicsCollisionHandler()  

                     
    def Move(self, task):


	  elapsed = task.time - self.prevtime1
	  elapsed2 = task.time - self.prevtime1
	  heading = self.boat1.getR()
	  heading2 = self.boat2.getR()
	  DEG_TO_RAD = pi/180
	  heading_rad = DEG_TO_RAD * heading
	  heading_rad2 = DEG_TO_RAD * heading2
	  w.Collision()

You probably forgot to set collision masks on the object.

Ermh, could you explain that a little better?

long time ago i struggled with collision setup,too. back then i made a small grafic to visualize the collision setup. might help you a little. maybe not^^ well here it is http://home.arcor.de/positiveelectron/files/project-files/p3dcollisionsystem.png

Oke, I did understand what the collision is… But I can’t figure out how to implent that in Panda and Python code.

I set a bitmask in the functions, but they still won’t collide to each other.

    def CollisionAuto1(self):
    
        boundsauto1 = self.auto1.getChild(0).getBounds() 
        centerauto1 = boundsauto1.getCenter() 
        radiusauto1 = boundsauto1.getRadius() 
        cSphereauto1 = CollisionSphere(centerauto1,radiusauto1) 
        cNodeauto1 = CollisionNode("auto1") 
        cNodeauto1.addSolid(cSphereauto1) 
        self.auto1CollNodePath = self.auto1.attachNewNode(cNodeauto1)
        cNodeauto1.setFromCollideMask(BitMask32.bit(0))

        cRay = CollisionRay(0, 0, 0, 0, 0, -1) 
        cNode = CollisionNode("auto1_Ray_Down") 
        cNode.addSolid(cRay) 
        self.auto1CollRayNodePath = self.auto1.attachNewNode(cNode) 
        self.auto1CollRayNodePath.show() 
       
        self.cTrav = CollisionTraverser()    
        self.pusher_auto1 = CollisionHandlerPusher() 

    def CollisionAuto2(self):
    
        boundsauto2 = self.auto2.getChild(0).getBounds() 
        centerauto2 = boundsauto2.getCenter() 
        radiusauto2 = boundsauto2.getRadius() 
        cSphereauto2 = CollisionSphere(centerauto2,radiusauto2) 
        cNodeauto2 = CollisionNode("auto2") 
        cNodeauto2.addSolid(cSphereauto2)
        self.auto2CollNodePath = self.auto2.attachNewNode(cNodeauto2)
        cNodeauto2.setFromCollideMask(BitMask32.bit(1)) 

        cRay = CollisionRay(0, 0, 0, 0, 0, -1) 
        cNode = CollisionNode("auto2_Ray_Down") 
        cNode.addSolid(cRay) 
        self.auto2CollRayNodePath = self.auto2.attachNewNode(cNode) 
        self.auto2CollRayNodePath.show() 
       
        self.cTrav = CollisionTraverser()    
        self.pusher_auto2 = CollisionHandlerPusher() 

Sorry not to go very deep into the details. I’m waiting at an airport.

There is two quick check you can do for your collision code:

  1. Does the bitmask i set for my collider objets match the bit mask i set to
    my collided object?

ex: you have 1 ball and several boxes and you want to detect when ball collides into boxes.

You would set a bitmask of 001 to all boxes
You would set a bitmask of 001 to the ball.
(If you set a bitmask of 100 to the ball then it will never collide with the boxes)

  1. Did i add my collider objet to the collision Handler?
    in previous example, you would have to use “addCollider” function of your colllision traverser with your Ball

Hope this can lead you a little farther…

Manakel, thanks for your input. The collision on the objects are working now.

But there is still one question left. I have a track model made in blender (Flat, it is a top-down sitution) with collision meshes in it.
How can I keep the objects on the track if they want to move out of it?

(Or better said: How can I push the objects back if they are NOT colliding on the track?)

I might not know what I’m talking about, but perhaps you can make an invisible barrier as part of the track model.

Yes I could, but isn’t it easier to use the model I already have and program collision around that?

So I have spheres around the moving models, it should be possible to let it collide when the model is moving out from the model. (The models are moving 1px above the track-model)

In the Egg I have the following:

    <Group> track_coll {
    <Collide> track_coll { polyset keep }
      <VertexPool> vpool1 {
        <Vertex> 0 {
          -7.87407 -1.28601 0.00592209
          <UV> { 0 1 }
          <Normal> { 0.0123911 -0.00283803 -0.999919 }


etc.
etc.

And for the track model:

      self.trackcols = self.track.find("**/track_coll")
      self.trackcols.node().setIntoCollideMask(BitMask32.bit(0))
      self.trackcols.show()

Hm, can anyone tell me what I’m doing wrong in the following code?
I tried to make it work, but it just won’t parse the message that it is colliding when not on the track.

     base.cTrav = CollisionTraverser() 
      #base.cTrav.showCollisions(render) 
      
      self.pusher = CollisionHandlerPusher() # Hier wordt de collision Handler ingeladen
      self.cHandler = CollisionHandlerEvent() # Hier wordt de collision event ingeladen
      self.cHandler.setInPattern("collide-%in")
      
      eventMASK = BitMask32.bit(2) # Bitmask aanmaken voor de events
      cNode1 = CollisionNode('Pusher')
      cNode1.addSolid(CollisionSphere(0,0,0,6.90))
      cNode1.setIntoCollideMask(BitMask32.allOff()) 
      cNode1.setFromCollideMask(BitMask32.bit(0)) 
      autoC1 = self.auto2.attachNewNode(cNode1) 
 
      cNode2 = CollisionNode('Event')
      cNode2.addSolid(CollisionSphere(0,0,0,1.1)) 
      cNode2.setIntoCollideMask(BitMask32.allOff()) 
      cNode1.setFromCollideMask(eventMASK)
      autoC2 = self.auto2.attachNewNode(cNode2)
            
      cNode = CollisionNode('auto1')
      cNode.addSolid(CollisionSphere(0,0,0,6.90))
      cNode.setFromCollideMask(BitMask32.allOff())
      cNode.setIntoCollideMask(eventMASK)
      autoC = self.auto1.attachNewNode(cNode)
      #autoC.show()

      self.ground = self.track.find("**/track_coll") 
      self.ground.node().setIntoCollideMask(BitMask32.bit(0)) 
      self.picker = CollisionTraverser() 
      self.queue = CollisionHandlerQueue() 
      self.pickerNode = CollisionNode('mouseRay') 
      self.pickerNP = camera.attachNewNode(self.pickerNode) 
      self.pickerNode.setFromCollideMask(BitMask32.bit(0)) 
      self.pickerNode.setIntoCollideMask(BitMask32.allOff()) 
      self.pickerRay = CollisionRay() 
      self.pickerNode.addSolid(self.pickerRay) 
      self.picker.addCollider(self.pickerNP, self.queue) 
        
      self.groundCol = CollisionNode('playerRay') 
      self.groundRay = CollisionRay() 
      self.groundColNp = self.auto1.attachNewNode(self.groundCol) 
      self.groundRay.setOrigin(0,25, -1) 
      self.groundRay.setDirection(0,-1,0) 
      self.groundCol.addSolid(self.groundRay) 
      self.groundCol.setFromCollideMask(BitMask32.bit(0)) 
      self.groundCol.setIntoCollideMask(BitMask32.allOff()) 
      self.floorHandler = CollisionHandlerFloor() 
      self.floorHandler.addCollider(self.groundColNp, self.auto1) 
        
      self.Zcoll = CollisionTraverser() 
      self.ZcollQueue = CollisionHandlerQueue() 
      self.Zcoll.addCollider(self.groundColNp, self.ZcollQueue) 
      self.Zcoll.showCollisions(render)
      self.groundColNp.show()
      self.pickerNP.show()
        
      self.pusher.addCollider(autoC1,self.auto2)
      base.cTrav.addCollider(autoC1,self.pusher)
      base.cTrav.addCollider(autoC2, self.cHandler)
      
      for i in range(self.ZcollQueue.getNumEntries()):
      	entry = self.cHandler.getEntry(i)
      	name = entry.getIntoNode().getName()
      	if name != "track_coll": self.TrackCollideHandler(entry)
    
    def TrackCollideHandler(self, colEntry):
      print "Collide op baan"

can you print the value of Name?
I dont remember if the name provided by the entry is the name of the collision node or the name of the parent.
In this first case, you may have to do a
name=entry.getIntoNode().Parents(0).getName()

(beware of syntax error, i have no panda3D installed right now)

Ehm, seems that I cant print the name at all… At least, it won’t show anything… Not with:

      for i in range(self.ZcollQueue.getNumEntries()):
      	entry = self.cHandler.getEntry(i)
      	name = entry.getIntoNode().Parents(0).getName()
      	if name != "track_coll": 
      		self.TrackCollideHandler(entry)
      	print name

And not with:

      for i in range(self.ZcollQueue.getNumEntries()):
      	entry = self.cHandler.getEntry(i)
      	name = entry.getIntoNode().getName()
      	if name != "track_coll": 
      		self.TrackCollideHandler(entry)
      	print name