Collision detection with GeoMipTerrain problem

I have a GeoMipTerrain and a flying ship. The flying ship has some collision spheres with the same collide mask that has the root of GeoMipTerrain and a CollisionHandlerEvent that is called when a collision is detected. The problem is that even if the ship isn’t touching the terrain a collision is detected always, so I see all the time in the console that a collision has been detected!
Here is a print of the collision entry:

CollisionEntry:
from render/level2/shipSvB1.egg/playerActorColNode
into render/level2/myDynamicTerrain/gmm3x2 []
at 200.353 150.354 -8.58662
normal 0.00639738 -0.00295264 99.9975
interior 200.347 150.357 -105.177 (depth 96.5903)
respect_prev_transform = 0

The normal of the collision is always close to 0,0,100 and the ship isn’t touching the generated terrain, in fact the ship is flying over the terrain.

Some code:

terrain update function:

  
    def updateTerrain(self,task):
        self.terrain.getRoot().setCollideMask(BitMask32.bit(0))
        self.terrain.update()
        return task.cont

actor :

   self.ColNode = self.node.attachNewNode(CollisionNode('playerActorColNode'))
        self.ColNode.node().addSolid(CollisionSphere(0,-0.5,-2,1.1))
        self.ColNode.node().addSolid(CollisionSphere(-2.5,-0.5,-3,0.7))
        self.ColNode.node().addSolid(CollisionSphere(2.5,-0.5,-3,0.7))
        self.node.reparentTo(self.level.levelNode)
       
        self.ColNode.node().setCollideMask(BitMask32.bit(0))

  self.traverser = CollisionTraverser('traverser')
        base.cTrav = self.traverser
        self.playerActor.collisionHandler = CollisionHandlerEvent()
        self.playerActor.collisionHandler.addInPattern('actorCollision')
        self.accept('actorCollision',self.collisionEvent)
    
        self.traverser.addCollider(self.playerActor.ColNode, self.playerActor.collisionHandler)

I’ve been a lot of time trying to solve this problem… Please help!!

Hmm, maybe it would help if you made your collision spheres visible, with self.ColNode.show()? This would at least let you visualize precisely where the spheres are, in case they’re not where you think they are.

David

I make visible the ColNode and the spheres are in the correct place :frowning:

The next thing to try is self.traverser.showCollisions(render), which should make visible any polygons the spheres collide with (and test with). When it shows yellow, it is testing the bounding volume but did not detect an intersection; when it shows white, it has detected an intersection. This will help you see if the terrain is where you think it is.

David

I’m working with JuanReyes in this project. To solve this problem we are now using this:

def initCollisionNode(self, mapSize, precision = 16):
		self.colNode = self.levelNode.attachNewNode(CollisionNode("terrainColNode"))
		# Divide the plane in (x,y) points
		for x in range(mapSize/precision):
			for y in range(mapSize/precision):
				# get the elevation at that point
				X = x*precision
				Y = y*precision
				X2 = X+precision
				Y2 = Y+precision
				Z = self.terrain.getElevation(X,Y) * self.terrainRoot.getSz() + self.terrainRoot.getZ()
				Z2 = self.terrain.getElevation(X2,Y2) * self.terrainRoot.getSz() + self.terrainRoot.getZ()
				#add a colSolid in that position
				self.colNode.node().addSolid(CollisionTube(X,Y,Z,X2,Y2,Z2, precision/2))

This creates tubes that cover the whole map (mapSize is the size in pixels).

I hope this is useful for anyone with the same problems