# Collision Detection Problem (Bullet through paper)

I have a bunch of planets flying towards me and my ship shoots bullets. I’m using a LerpInterval to make the bullet travel into the far Z plane. The problem is that my bullets seem to randomly go through collision objects and I don’t know why. Any ideas on how to make the collision check every frame or slow down my projectiles so they always get checked?

Here’s some code.

``````def generateObstacles(self):
self.obstacleOldPos = [None for i in range(40)]
self.obstacle = [None for i in range(40)]
for i in range(len(self.obstacle)):
self.obstacle[i].setTexture(self.obs_tex, 1)
self.obstacle[i].reparentTo(render)
self.obstacle[i].setScale(.1)
self.obstacle[i].setPos(generateRandomFloat(),generateRandomFloat(), random.randint(-100, -20))
#print "obstacle position "+str(self.obstacle[i].getPos())
self.obstacleOldPos[i]=self.obstacle[i].getPos()

#Create collision for the obstacles
obstacleCS = CollisionSphere(0, 0, 0, 1.1)
obstaclePath = self.obstacle[i].attachNewNode(CollisionNode('obstacle'))
#obstaclePath.show()``````

and

``````  def shootObstacle(self, time):
self.laserSound.play()
pos = self.ship.getPos()
bullet.setTexture(self.bullet_tex, 1)
bullet.reparentTo(render)
bullet.setScale(.05)
bullet.setPos(pos)
#Set the bullet expiration time to be a certain amount past the current time
self.setExpires(bullet, time + 1.1)
self.bulletSeq = Sequence(
LerpFunc(bullet.setZ,
duration = 1,
fromData = bullet.getZ(),
toData = bullet.getZ()-40))
#print "loop pos "+str(self.obstacle[i].getPos())+" for "+str(i)
self.bulletSeq.start()
#print str(bullet.getPos())+" bullet"
#Finally, add the new bullet to the list
self.bullets.append(bullet)
#create a collsion solid for this model
bulletNode1 = CollisionNode('bulletPush')
bulletC1 = bullet.attachNewNode(bulletNode1)
#bulletC1.show()
#create another collsion solid for this model
bulletNode2 = CollisionNode('bulletEvent')
bulletC2 = bullet.attachNewNode(bulletNode2)
#bulletC2.show()

Thanks.

You will need to turn on fluid collision detection. This also means you will need to use CollisionPolygons for your planet targets, instead of CollisionSpheres (but you should continue to use CollisionSpheres for your bullets).

It’s all described here in the manual: http://panda3d.org/manual/index.php/Rapidly-Moving_Objects

David

Ok, cool. I’m not sure how to set up a CollisionPolygon. It takes in 4 Point3() values, but how do I determine which values to pass?

Also, it states that the collision traverser checks every frame. I can definitely see the bullet hitting the planet and penetrating it. I’m not sure what would cause this. When I show the collision meshes, it looks fine. Also, if I sit in the same spot and shoot multiple bullets, eventually it’ll cause a hit.

Your object moves with a speed of the form world-units/frame.

Let’s say you’ve got an object that’s just 1 world-unit thick and a bullet that moves 2 world units per frame.
Then the chances are great that your bullet will never even touch the position of your object, hence normal collision detection couldn’t detect it.
That’s what fluid collision detection is for. It takes into account where your bullet was in the frame before and triggers a collision event, if the bullet must have passed the object, even if it didn’t hit it directly.

I get how it works but I have no idea how to set it up. I can’t find any examples of fluid collision detection except for what’s in the manual and even that doesn’t explain how to fully set it up.

Here’s my updated shootObstacle code

``````def shootObstacle(self, time):
#self.laserSound.play()
pos = self.ship.getPos()
#bullet.setTexture(self.bullet_tex, 1)
bullet.reparentTo(render)
bullet.setScale(.005)
bullet.setPos(pos)
bullet.setP(-270)
#print str(len(self.bullets))+" bullets"
if (self.particleEffects > 45):
self.particleEffects = 0
self.effects[self.particleEffects].setPos(bullet.getPos())
self.effects[self.particleEffects].setZ(self.effects[self.particleEffects].getZ()-3)
self.effects[self.particleEffects].reparentTo(bullet)
#self.effects[self.particleEffects].start()
self.particleEffects += 1
else:
self.effects[self.particleEffects].setPos(bullet.getPos())
self.effects[self.particleEffects].setZ(self.effects[self.particleEffects].getZ()-3)
self.effects[self.particleEffects].reparentTo(bullet)
self.effects[self.particleEffects].start()
self.particleEffects += 1
#self.effect.setPos(bullet.getPos())
#self.effect.reparentTo(bullet)
#self.effect.start()
#Set the bullet expiration time to be a certain amount past the current time
self.setExpires(bullet, time + 3.1)
endPos = bullet.getPos()
endPos.setZ(endPos.getZ()-30)
self.bulletSeq = Sequence(
LerpPosInterval(bullet,
duration = 2.5,
pos = endPos,
fluid = 1))
#fromData = bullet.getZ(),
#toData = bullet.getZ()-40), fluid=1)
#print "loop pos "+str(self.obstacle[i].getPos())+" for "+str(i)
self.bulletSeq.start()
#print str(bullet.getPos())+" bullet"
#Finally, add the new bullet to the list
self.bullets.append(bullet)
#create a collsion solid for this model
bulletNode1 = CollisionNode('bulletPush')
bulletC1 = bullet.attachNewNode(bulletNode1)
#bulletC1.show()
#create another collsion solid for this model
bulletNode2 = CollisionNode('bulletEvent')
bulletC2 = bullet.attachNewNode(bulletNode2)
#bulletC2.show()