[solved] Bullet HeighfieldShape() throwing assertion error

Trying to put together a simple geomipterrain app with bullet physics. Below is the relevant code and the error message. I have tried commenting everything out but the pnmImage line and making the shape, still gives the error. If I comment out the heightfield shape, no error.

def setupTerrainNode(self, terrain):
		img = PNMImage(TERRAIN_SOURCE)
		
		img.makeGrayscale()
		
		shape = BulletHeightfieldShape(img, TERRAIN_Z_SCALE, ZUp)
		bulletNode = BulletRigidBodyNode('Ground')
		bulletNode.addShape(shape)
		
		bulletNp = terrain.attachNewNode(bulletNode)
		bulletNp.setCollideMask(mask1)
		
		self.world.attachRigidBody(bulletNode)
		
		return bulletNp

And the error…

Assertion failed: x >= 0 && x < _x_size && y >= 0 && y < _y_size at line 301 of c:\buildslave\release_sdk_win32\build\panda3d\built\include\pnmImage.I

Any help would be appreciated…

make sure your pnmimage has a width and height > 0.
I think you can get it using img.getReadXSize() and img.getReadYSize()

Thanks for gettin back to me so quick.

It loads the same image with geomipterrain with no problem. I checked as you said though and it is registering to its correct size. It does occur to me however, does the image need to be square? its 4039x2709 currently.

The geomipterrain takes that image and breaks it up into 129x129 sections then loads them separately. I have not implemented that in the bullet system yet as I mostly just wanted to see how bullet works then get more complex.

The only reason its not using the image loaded under the terrain variable is because I thought maybe somehow geomipterrain was mangling it and I needed to load a new one, didn’t make any difference however.

Thanks for getting me thinking, I split the image up into its smaller components and it seems to be working now, I’m sure I have some adjustments to make but hey, its alive lol.

I hadn’t thought about it needing to be a power of 2+1 which it isn’t on its own, only after being broken up. I had figured it would automatically scale it to the closest power of 2+1, as geomipterrain would have. It didn’t, instead it gave the assertion error.

I’m curious what actually has been causing this assertion. Can you please run the following script and see if it crashes somewhere:

img = PNMImage(TERRAIN_SOURCE) 
img.makeGrayscale() 

nx = img.get_x_size()
ny = img.get_y_size()
print nx, ny

for x in range(nx):
  for y in range(ny):
    val = img.get_xel_val(x, y)
    print x, y, val

By the way, a power of 2 + 1 is not required for Bullet heightfields.

I ran it inside my source, right where the other code was. No crashes.

I do have another question though. I was roughing out a character with BulletCharacterControllerNode, however in the program the character would fall to the ground, stop for a moment, then fall straight through it.

I know it says in the manual about this node not being able to have proper interaction with dynamic nodes, does it also not interact properly with heightfields? I had figured in bullet a heightfield was a rigid node. Maybe I’m just missing something, I haven’t spent that much time on it yet.

This is my code:

	self.imgHeight = PNMImage(Filename('02.png'))
	self.terrain = GeoMipTerrain("img")
	self.terrain.setHeightfield(self.imgHeight)
	self.terrain.setBlockSize(64)
	self.terrain.setNear(128)
	self.terrain.setFar(256)
		...
		...
		...
	self.terrain.generate()

	shape = BulletHeightfieldShape(self.imgHeight, 50, ZUp)
		...
		...
		...
def renderScene(self, task):
		...
		...
		...
	for imgY in range(    max(int(ry-self.areaSize)+512,0), 
		                  min(int(ry+self.areaSize)+512,1024)):
		for imgX in range(max(int(rx-self.areaSize)+512,0), 
			              min(int(rx+self.areaSize)+512,1024)):
			self.imgHeight.setGray(imgX, imgY, 1)   # Set the imgHeight's color
	self.terrain.update()
	self.world.doPhysics(globalClock.getDt())

I want use self.imgHeight.setGray, self.terrain.update() and self.world.doPhysics(globalClock.getDt()) to update GeoMipTerrain and BulletHeightfieldShape, but it don’t work.

You can not modify Bullet collision geometry on the fly.
Remove the old node, and create a new one with the modified image.

Thank you !