How use terrain in irrlicht? Have you any example?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Turican

How use terrain in irrlicht? Have you any example?

Post by Turican »

I cannot find example or explanation, how create terrin in irrlicht, please give me any source code, thank you.
dingo
Posts: 95
Joined: Tue Mar 09, 2004 5:02 am
Location: Brisbane, Australia
Contact:

Post by dingo »

I too would like a nice simple tutorial to work from :)
-= Want your C code to control real life robots? www.users.on.net/~symes =-
puh
Posts: 356
Joined: Tue Aug 26, 2003 3:53 pm

Post by puh »

Code: Select all

video::IImage* heightmap1 = 0;
heightmap1=driver->createImageFromFile("media\\ext\\t3.bmp");

video::IImage* texture1 = 0;
texture1=driver->createImageFromFile("media\\ext\\t2.jpg");  


scene::IAnimatedMesh* terr1 = smgr->addTerrainMesh ("1",texture1,heightmap1,core::dimension2d<f32>(90.0f, 90.0f),200.0f );
scene::ISceneNode* q3node3 = 0;
q3node3 = smgr->addMeshSceneNode(terr1->getMesh(0));
q3node3->setPosition(core::vector3df(-1900,-44.7,-1800));
q3node3->setMaterialFlag(video::EMF_LIGHTING, false);

selector = smgr->createTriangleSelector(terr1->getMesh(0), q3node3);
metaSelector->addTriangleSelector(selector);
selector->drop();
t3.bmp MUST BE 64x64, else the terrain will be building TOO LONG and collision will be SLOW
Peter Müller
Posts: 292
Joined: Sun Mar 14, 2004 5:28 pm
Location: Germany
Contact:

Post by Peter Müller »

puh wrote:

Code: Select all

video::IImage* heightmap1 = 0;
heightmap1=driver->createImageFromFile("media\\ext\\t3.bmp");

video::IImage* texture1 = 0;
texture1=driver->createImageFromFile("media\\ext\\t2.jpg");  


scene::IAnimatedMesh* terr1 = smgr->addTerrainMesh ("1",texture1,heightmap1,core::dimension2d<f32>(90.0f, 90.0f),200.0f );
scene::ISceneNode* q3node3 = 0;
q3node3 = smgr->addMeshSceneNode(terr1->getMesh(0));
q3node3->setPosition(core::vector3df(-1900,-44.7,-1800));
q3node3->setMaterialFlag(video::EMF_LIGHTING, false);

selector = smgr->createTriangleSelector(terr1->getMesh(0), q3node3);
metaSelector->addTriangleSelector(selector);
selector->drop();
t3.bmp MUST BE 64x64, else the terrain will be building TOO LONG and collision will be SLOW
Thats not right! I use a 512x512 terrain and it runs with about 50fps. But it needs very long to load
http://www.games-forge.de - Die Community für Nachwuchsprogrammierer
dingo
Posts: 95
Joined: Tue Mar 09, 2004 5:02 am
Location: Brisbane, Australia
Contact:

Post by dingo »

Thanks guys for the response
-= Want your C code to control real life robots? www.users.on.net/~symes =-
soconne
Posts: 87
Joined: Fri Mar 05, 2004 2:00 pm

Post by soconne »

I got my terrain to run at about 900 fps because I controlled what triangles were being added to the triangleselector each frame. I simply got a pointer to the list of triangles in the triangleselector, and updated them with only a few triangles that were directly around the player. This way I'm only doing collision tests on about 8 - 16 polygons each frame, instead of about 1,000 or so :-p

You should try this instead and your terrain will run a lot faster.
puh
Posts: 356
Joined: Tue Aug 26, 2003 3:53 pm

Post by puh »

soconne, could you post your code here?
jl0206
Posts: 55
Joined: Mon Jun 07, 2004 4:56 am

Post by jl0206 »

Yes yes . :D please give us a code example with the collision detection in it . I want study it , heightmap and collision detection . :D
jl0206
Posts: 55
Joined: Mon Jun 07, 2004 4:56 am

Post by jl0206 »

The url now released I cann't download , so please give me a new url :shock:
Peter Müller
Posts: 292
Joined: Sun Mar 14, 2004 5:28 pm
Location: Germany
Contact:

Post by Peter Müller »

@soconne:
Are you using the ICollisionResponseAnimator?
http://www.games-forge.de - Die Community für Nachwuchsprogrammierer
soconne
Posts: 87
Joined: Fri Mar 05, 2004 2:00 pm

Post by soconne »

Here's how I did my collision. There's a lot of source code, so I tried to narrow it down to the important parts.

Here is my main draw loop

CTriangleSelector *selector=0;
selector = (CTriangleSelector *)smgr->createTriangleSelector(landscape->GetCollisionMesh(camera->getPosition().X, camera->getPosition().Z), landscape);
landscape->setTriangleSelector(selector);
selector->drop();

scene::IMetaTriangleSelector *mselector=0;
mselector = smgr->createMetaTriangleSelector();
mselector->addTriangleSelector(selector);

anim = (CSceneNodeAnimatorCollisionResponse *)smgr->createCollisionResponseAnimator(mselector,
camera, core::vector3df(1,1,1), core::vector3df(0,0,0), 0.0,
core::vector3df(0,1,0), .0005);
camera->addAnimator(anim);

scene::IMesh *collMesh;

while(device->run() && !quit)
{
collMesh = landscape->GetCollisionMesh(camera->getPosition().X, camera->getPosition().Z);
if(collMesh) {
selector = (CTriangleSelector *)smgr->createTriangleSelector(collMesh, landscape);
mselector->removeAllTriangleSelectors();
mselector->addTriangleSelector(selector);
anim->setWorld(mselector);
}

driver->beginScene(true, true, video::SColor(0,200,200,200));
smgr->drawAll();
guienv->drawAll();
driver->endScene();
}


Then here's the code that comes from the landscape->GetCollisionMesh(...)


scene::IMesh* GetCollisionMesh(f32 X, f32 Z)
{

static int lastcol=-1, lastrow=-1;

//get row and col of terrain where collision will occur
int col = floor( ( (X+(Width/2.0)) / (float)Width) * Cols);
int row = floor( ( (Z+(Length/2.0)) / (float)Length) * Rows);

if(lastcol == col && lastrow == row) return NULL;

lastcol = col;
lastrow = row;

//get pointer to mesh data
scene::SMeshBufferLightMap* tempBuffer = (scene::SMeshBufferLightMap* )Meshes[0].getMeshBuffer(0);

collBuff->Vertices.clear();
collBuff->Indices.clear();

int index=0;
for(int j=row-1; j <= row + 1; j++)
{
if(j < 0 || j >= Rows-1) continue;

for(int i=col-1; i <= col + 1; i++)
{
if(i < 0 || i >= Cols-1) continue;

collBuff->Vertices.push_back(tempBuffer->Vertices[j*Cols+i]);
collBuff->Vertices.push_back(tempBuffer->Vertices[(j+1)*Cols+i]);
collBuff->Vertices.push_back(tempBuffer->Vertices[(j+1)*Cols+i+1]);
collBuff->Vertices.push_back(tempBuffer->Vertices[j*Cols+i+1]);

collBuff->Indices.push_back(index);
collBuff->Indices.push_back(index+1);
collBuff->Indices.push_back(index+2);
collBuff->Indices.push_back(index);
collBuff->Indices.push_back(index+2);
collBuff->Indices.push_back(index+3);

index+=4;
}
}

//collMesh->MeshBuffers[0] = collBuff;
return collMesh;
}



Okay and now for an explanation. I basically just initialize a single triangleselector before my main loop to set the 'exact' size it will be for the remainder of the program, meaning 18 triangles if you look at the GetCollisionMesh functions. And during the main loop, I simply call GetCollisionMesh to change or update those triangles depending on where I am on the terrain. I also make sure that if the position hasn't moved enough from the last position, then no update is made, this makes it run faster.

Then the MetaTriangleSelector I declared above is then updated, but first all selectors are removed first, then the one I got from my landscape is added to it, then the CollisionResponseAnimator is then set to use this new MetaTriangleSelector variable.

I know it seems like a lot, but its very straightforward once you understand it. It took me forever to figure out how to do this without getting memory errors and my program crashing, ect....

Also, if anybody sees any memory leeks, please let me know. I think there might be, but I'm still unsure of how Irrlicht releases memory, ect...

Oh, and the collMesh variable inside of the landscape->GetCollisionMesh is declared within my terrain class so that it is only declared once and reused over and over, this speeds it up a lot also.

And its declared like so...

scene::SMeshBufferLightMap *collBuff;



Anyway, if anybody can think of a way to speed this up let me know, but like I said before when I use this method for collision with my terrain, I get about 900 fps, and just using the regular old send everything to an Octree method, I get about 150-200fps. And I'm also running this on a P4 2.8Ghz HT, 1GB PC3200, Radeon 9800 Pro. So don't expect to get the exact same framerate, but a lot better than before.
Evil Mr Sock
Posts: 37
Joined: Fri Jul 02, 2004 5:36 pm
Location: Albany, NY
Contact:

Post by Evil Mr Sock »

I'm having some issues implementing this, and I think they mostly stem from irrlicht telling my that the scene::C________ (ie. CSceneNodeAnimator) functions are not a part of scene:: - even though they appear as members in the list.

I've tried switching these to I__________ functions, and that results in a bunch of other stuff not working - the members of C__________ not being members of I_________

Any ideas why irrlicht might be sassing me about scene::C______'s?

Also, I was wondering if there's any way you could post a link to your main.cpp - a further problem for me that's coming up is that my camera is a 3rd person, tied to a mesh node - the animators for both the map and the model are 3rd person, and that conflicts with your camera animators. I'd like to try to merge the two different directions - so that I can have a third person view with terrain maps.
------------------------------------------
A monkey poured coffee in my boots.
------------------------------------------
soconne
Posts: 87
Joined: Fri Mar 05, 2004 2:00 pm

Post by soconne »

Yeah sure, here's the file

http://cs.selu.edu/~soconnell/MyIrrlicht.cpp

Don't mind all the other code for the terrain initialization, the important stuff is after that. Let me know if you have any problems or questions.
Evil Mr Sock
Posts: 37
Joined: Fri Jul 02, 2004 5:36 pm
Location: Albany, NY
Contact:

Post by Evil Mr Sock »

Well, I don't really think I can merge your code into mine - there's too many unobvious things to me (I know about 40% of the code that I should to be doing all the basic programming myself ^_^" I love opensource... )

However, I have come up with an extremely simple optimization for the initial code - this brought me from @27 fps (!) up to @250 (much better) with a bigger map, higher raising, and better looking to boot.

It's really a question of your process, and your parameters.
To start with, make your terrain like this - pick your terrain size in a multiple of 2 (I've used 256x256), and make your terrain height bitmap with that.

Now paint over it to make the terrain texture jpg. Be as precise as you want.

Save the jpg as 256x256 (or whatever you picked), and go ahead and scale the height bmp to 32x32 and save it. (Trust me, I'm a doctor, I do this for a living.)

now in the parameters, the ones given in the code example are this

Code: Select all

irr::scene::IAnimatedMesh* terr1 = smgr->addTerrainMesh ("1",texture1,heightmap1,irr::core::dimension2d<irr::f32>(90.0f, 90.0f),200.0f );
Go ahead and change
(90.0f, 90.0f),200.0f );
to
(JPG_Width.0f, JPG_Height.0f),Multiple_of_2.0f);
I like 512...

You've lost some precision in the height department with this, but that's not such a bad thing - nature is usually a bit more rounded than it is angular. I suggest making the map with an airbrush tool to accompany this concept, as the blends come naturally from the process. If you desperately wanted a cliff, take a pixel tool and edit the 32x32 manually.

However, the texture is nice and crisp and clean - just like mom used to make. You could even use an aerial photo, so long as it's the size of your terrain, or vice-versa, and stretching will be kept to a minimum.
------------------------------------------
A monkey poured coffee in my boots.
------------------------------------------
Post Reply