btHeightfieldShape

jujojujo_2003
Posts: 3
Joined: Sun Feb 26, 2012 8:27 pm

btHeightfieldShape

Post by jujojujo_2003 »

Hi ,
I am trying to create a terrain and make objects collide with it , I dont know why but the terrain in the Collision world and the rendered terrain are not in the same position.
I have a class that reads bitmaps and converts them to heights and i store these heights in a float array and pass it to btheightfield.
What is the error??
Here is my Load terrain code

Code: Select all

LoadTerrain()
{
    int minh=0,maxh=0;
	Image* image = loadBMP(filename);
	Terrain* t = new Terrain(image->width, image->height);
	for(int y = 0; y < image->height; y++) {
		for(int x = 0; x < image->width; x++) {
			unsigned char color =
				(unsigned char)image->pixels[3 * (y * image->width + x)];
			float h = height * ((color / 255.0f) - 0.5f);
			t->setHeight(x, y, h);
			if(h<minh)
			 minh=h;
			 if(h>maxh)
			 maxh=h;
		}
	}
	t->image=image;
	
	//delete image;
	t->computeNormals();
   GLint list;
   list=glGenLists(1);
   glNewList(list,GL_COMPILE);
   t->disprender();
   glEndList();
   t->displistno=list;
   //BULLET START

	
	float *data;
	data = new float[t->length()*t->width()];
		for(int y = 0; y < t->length()-1; y++) {
		for(int x = 0; x < t->width()-1; x++) {
			data[y*t->width()+x]=t->getHeight(x,y);
	
		}
	}
	btHeightfieldTerrainShape *heightFieldShape = new btHeightfieldTerrainShape(t->width(), t->length(), data, 1, minh, maxh, 1, PHY_FLOAT, false);
	heightFieldShape->setUseDiamondSubdivision(true);
	heightFieldShape->setLocalScaling(btVector3(tscalex ,tscaley , tscalez));
	heightFieldShape->setMargin(0.1);
	
	btTransform ttrans;
	t->scalex=tscalex;
	t->scaley=tscaley;
	t->scalez=tscalez;
	btMotionState *motionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0),btVector3(x,y,z)));
	t->Body = new btRigidBody(btScalar(0.0), motionState, heightFieldShape, btVector3(0,0,0));
	World->addRigidBody(t->Body);
	return t;
}
Here is my render code
I use disprender() to create a Displaylist of the terrain
and call that every time in the render function.

Code: Select all

		void disprender()
		{
		  
		  GLfloat greenMaterial[] = {1.0, 1.0, 1.0,1};
		  glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,greenMaterial);
		  glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,greenMaterial);
		  glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,greenMaterial);
		  glEnable(GL_TEXTURE_2D);
		  glBindTexture(GL_TEXTURE_2D,TERN);
		  int point=0;
		  for(int z = 0; z < length() - 1; z++) 
			{
				for(int x = 0; x < width(); x++)
				{
		  			float hMapX=x;
					float hMapZ=z;
					float hmWidth=length();
					float hmHeight=width();
					glBegin(GL_TRIANGLE_STRIP);
					Vec3f normal = getNormal(x, z);
					glNormal3f(normal[0], normal[1], normal[2]);
					glTexCoord2f((float)hMapX / hmWidth, (float)hMapZ / hmHeight);
					glVertex3f(hMapX, getHeight(hMapX,hMapZ), hMapZ);

					normal = getNormal(x, z+1);
					glNormal3f(normal[0], normal[1], normal[2]);
					glTexCoord2f((float)hMapX / hmWidth, (float)(hMapZ + 1) / hmHeight) ;
					glVertex3f(hMapX, getHeight(hMapX,hMapZ + 1), hMapZ + 1);

					normal = getNormal(x+1, z);
					glNormal3f(normal[0], normal[1], normal[2]);			
					glTexCoord2f((float)(hMapX + 1) / hmWidth, (float)hMapZ / hmHeight);
					glVertex3f(hMapX + 1, getHeight(hMapX + 1,hMapZ), hMapZ);
			
					normal = getNormal(x+1, z+1);
					glNormal3f(normal[0], normal[1], normal[2]);
					glTexCoord2f((float)(hMapX + 1) / hmWidth, (float)(hMapZ + 1) / hmHeight);
					glVertex3f(hMapX + 1, getHeight(hMapX + 1,hMapZ + 1), hMapZ + 1);
					glEnd();
			   }

	       }
		   glDisable(GL_TEXTURE_2D);
		}
		void render()
		{

		btTransform ttrans;
		float tma[16];
		Body->getMotionState()->getWorldTransform(ttrans);
		ttrans.getOpenGLMatrix(tma);
		glPushMatrix();
		   glMultMatrixf(tma);
		   glScalef(scalex,scaley,scalez);
		   glCallList(displistno);
        glPopMatrix();
		}
what is wrong with it??
jujojujo_2003
Posts: 3
Joined: Sun Feb 26, 2012 8:27 pm

Re: btHeightfieldShape

Post by jujojujo_2003 »

I converted the btHeightfieldShape to a triangle mesh it works perfectly but is very slow when loading even for a 256x256 mesh(around 20 secs)
jujojujo_2003
Posts: 3
Joined: Sun Feb 26, 2012 8:27 pm

Re: btHeightfieldShape

Post by jujojujo_2003 »

SOLVED :D
I translated it by (-terrain->width()/2.0,0,-terrain->length()/2.0)
But why so??
xexuxjy
Posts: 225
Joined: Wed Jan 07, 2009 11:43 am
Location: London

Re: btHeightfieldShape

Post by xexuxjy »

If you look in btHeightFieldTerrainShape.h in the top comment it mentions that :


" The local origin of the heightfield is assumed to be the exact
center (as determined by width and length and height, with each
axis multiplied by the localScaling).
"
which is why your offset is needed.

It probably worth reading the note on terrain height in that comment as well to prevent further problems.