Animating hillplane/terrain .. mesh locked ? Strategy wrong?

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
muenalan
Posts: 7
Joined: Tue Feb 26, 2008 9:11 pm

Animating hillplane/terrain .. mesh locked ? Strategy wrong?

Post by muenalan »

addHillPlaneMesh creates a Node where I am not able to access/animate the underlying mesh.

My main aim is that I just want to generate a terrain/hillplane where i can randomly animate the hills heights using the vertex indices.

Obviously I progressed to get things right, but I have trouble to access the underlying mesh object.

When creating in main.cpp

Code: Select all

	scene::IMesh *mesh = engine.scene->addHillPlaneMesh( (const irr::c8 *) "myHill_spikes",
								     a,
								     b,
								     0, 
								     0,
								     c,
								     d
								     );
	
	IMeshSceneNode *hill = engine.scene->addMeshSceneNode(mesh);
	core::vector3df position( .0f, -30.0f, .0f );

	hill->setPosition( position );

	hill->setMaterialTexture( 0, engine.driver->getTexture( engine.medium( "sprite--bubble-shining_big.jpg" ) ) );

	irrlicht_node_animator_meshplane_spikes *anim_meshplane_spikes = new irrlicht_node_animator_meshplane_spikes( engine, engine.device->getTimer()->getTime() );
	
	hill->addAnimator( anim_meshplane_spikes );

and inside the animateNode() method of the animator class I am getting 0 values for the underlying mesh:

meshBufferCount = 0, Mesh[0] = 0

?? Does hillplane not generate a real Mesh ?

Code: Select all


      void
	animateNode( scene::ISceneNode *node, u32 timeMs)
	{
	  IMesh *mesh = ( ( irr::scene::IMeshSceneNode *) node)->getMesh();

	  u32 meshBufferCount = mesh->getMeshBufferCount();

	  for (u32 b=0; b<meshBufferCount; ++b)
	    {
	      const u32 vtxCnt = mesh->getMeshBuffer(b)->getVertexCount();

	      CERR 
		<< "ANIMATING MESH with vertexcount = " 
		<< vtxCnt 
		<< " and vertextype = "
		<< mesh->getMeshBuffer(b)->getVertexType()
		<< " [while video::EVT_STANDARD = " 
		<< video::EVT_STANDARD
		<< " ] "
		<< endl;
	      
	      switch(mesh->getMeshBuffer(b)->getVertexType())
		{

		case video::EVT_STANDARD:

		  CERR << "EVT_STANDARD FOUND" << endl;
		  {
		    video::S3DVertex* v = (video::S3DVertex*) mesh->getMeshBuffer(b)->getVertices();	    
		    
		    for (u32 i=0; i<vtxCnt; ++i)
		      {
			if( i == 10 )
			CERR 
			  << "spiking vertex[" 
			  << i 
			  << "] = ( " 
			  << v[i].Pos.X
			  << ", "
			  << v[i].Pos.Y
			  << ", "
			  << v[i].Pos.Z
			  << " )"
			  << endl;

			v[i].Pos.X += 1;
		      }		    
		  }
		  break;
		  
		case video::EVT_2TCOORDS:

		  CERR << "EVT_2TCOORDS FOUND" << endl;

		  {

...


	  engine.scene->getMeshManipulator()->recalculateNormals(mesh);

	  return;
	}



After some debugging, I also attached an animatedmeshscenenode to the animator and found that modification with

Code: Select all


   v[i].Pos.X += 1;

does not work.



Any help would be highly appreciated !

Thx,
Murat
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Re: Animating hillplane/terrain .. mesh locked ? Strategy wr

Post by rogerborg »

muenalan wrote:?? Does hillplane not generate a real Mesh ?
No.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

So:

Code: Select all

!(!(hillplane generates a mesh)) == hillplane generates a mesh.
Have to love that rogerborg humor. :lol:
TheQuestion = 2B || !2B
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

I also don't see any problems with this. You can avoid the vertex type switch, because the hillplane is only a standard vertex mesh. Moreover, with Irrlicht 1.5 you will get direct access to vertex positions through the extended meshbuffer API.
muenalan
Posts: 7
Joined: Tue Feb 26, 2008 9:11 pm

addHillPlaneMesh addMeshBuffer/getMeshBufferCounter *BUG* ?

Post by muenalan »

Autsch,

JA, 1.5 has maybe everything - and the other comment was rather spam-kind of.

I dont understand why addHillPlaneMesh is not creating a "proper" mesh ? Technically, and logically !

Lets take you through the irrlicht engine code

Code: Select all

IAnimatedMesh* CSceneManager::addHillPlaneMesh(..)
{
//calls method below

//snip

	SAnimatedMesh* animatedMesh = new SAnimatedMesh();
	if (!animatedMesh)
		return 0;

	animatedMesh->addMesh(mesh);

//snip

 	return animatedMesh;
}

IMesh* CGeometryCreator::createHillPlaneMesh(..)
{

   ...

	SMesh* mesh = new SMesh();
	mesh->addMeshBuffer(buffer);
	mesh->recalculateBoundingBox();
	buffer->drop();
	return mesh;
}

In my understanding thius *should* create a proper IMesh albeit IAnimatedMesh.

MY TESTCODE WHICH LOOKS LIKE AS IF ITS NOT:

Code: Select all

	scene::IAnimatedMesh *mesh = engine.scene->addHillPlaneMesh( (const irr::c8 *) "myHill_spikes",
								     a,
								     b,
								     0, 
								     0,
								     c,
								     d
								     );



	CERR << "IAnimatedMesh has attributes " << std::endl
	     << " getMeshBufferCounter = " << mesh->getMeshBufferCount() << std::endl
	     << " getMeshBuffer(0) = " << mesh->getMeshBuffer(0)<< std::endl
	     << " getFrameCount()  = " << mesh->getFrameCount() << std::endl
	     << " Min x = " << mesh->getBoundingBox().MinEdge.X << std::endl
	     << " Min y = " << mesh->getBoundingBox().MinEdge.Y << std::endl
	     << " Min Z = " << mesh->getBoundingBox().MinEdge.Z << std::endl
	     << " Max x = " << mesh->getBoundingBox().MaxEdge.X << std::endl
	     << " Max y = " << mesh->getBoundingBox().MaxEdge.Y << std::endl
	     << " Max z = " << mesh->getBoundingBox().MaxEdge.Z << std::endl
	     << endl;
which returns

Code: Select all

IAnimatedMesh has attributes
 getMeshBufferCounter = 0
 getMeshBuffer(0) = 0
 getFrameCount()  = 1
 Min x = -400
 Min y = 0
 Min Z = -400
 Max x = 400
 Max y = 0
 Max z = 400

See ?! The fact that getMeshBufferCounter is returning 0 and getMeshBuffer(0) is returning 0 is a

*BUG*

to me !? Especially that the call

Code: Select all

mesh->addMeshBuffer(buffer);
is not leading to increase getMeshBufferCounter to 1.

PS: irrlicht 1.5 etc..

Erhm,
Murat
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

PS GHK RT GGTT?
Seems your keyboard swallows half of your words, at least I don't get any meaning from it. Besides that, you should do a mesh->getMesh(0) and work with the resulting IMesh* instead, makes life far more simple. Or try the SVN trunk, which does even more.
muenalan
Posts: 7
Joined: Tue Feb 26, 2008 9:11 pm

[SOLVED]

Post by muenalan »

Hybrid,

Thanks for the hint ! Indeed the getMesh(0) was the right hint.

Let me recap for others running in the same problems. The correct working code is...

Code: Select all


	scene::IAnimatedMesh *mesh_animated = engine.scene->addHillPlaneMesh( (const irr::c8 *) "myHill_spikes",
								     a,
								     b,
								     0, 
								     0,
								     c,
								     d
								     );
	
	CERR << "plane_spiking() hill IAnimatedMesh has attributes " << std::endl
	     << " getMeshBufferCounter = " << mesh_animated->getMesh(0)->getMeshBufferCount() << std::endl
	     << " getMeshBuffer(0) = " << mesh_animated->getMesh(0)->getMeshBuffer(0)<< std::endl
	     << " getFrameCount()  = " << mesh_animated->getFrameCount() << std::endl
	     << " Min x = " << mesh_animated->getBoundingBox().MinEdge.X << std::endl
	     << " Min y = " << mesh_animated->getBoundingBox().MinEdge.Y << std::endl
	     << " Min Z = " << mesh_animated->getBoundingBox().MinEdge.Z << std::endl
	     << " Max x = " << mesh_animated->getBoundingBox().MaxEdge.X << std::endl
	     << " Max y = " << mesh_animated->getBoundingBox().MaxEdge.Y << std::endl
	     << " Max z = " << mesh_animated->getBoundingBox().MaxEdge.Z << std::endl
	     << endl;

Note: The calls mesh->getMeshBufferCount() where not right. That has somehow to do with the difference between a IMesh and an IAnimatedMesh. May be a general rule can be derived where an IAnimatedMesh requires a prepended getMesh(0) to refer to the first (in case of a static animated mesh) mesh; this itself can have multiple mesh buffers, where we can access it by a call such as

Code: Select all


mesh_animated->getMesh(0)->getMeshBufferCount() 


CAVEAT: There will be no run-time/compile-time errors when you exercise this "mistake" - albeit "relaxed handling".

Thanks again, hybrid !

PS: "Ehrm" is a german vocalistic expression of something as "crunching teeth..".
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

The SVN trunk has this fixed, it's just a missing redirection in some methods (which simply returned 0 in 1.4). But in general it's always a wise idea to choose some frame when using methods that expect a mesh instead of an animated mesh. However, getMesh(x) is not properly working for skinned meshes as of now.
Post Reply