manipulating mesh data in real time?

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
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

manipulating mesh data in real time?

Post by arras »

Is there posibility to edit vertex data of mesh (position, normal, UV coordinate) in real time?
What I want to get is plane mesh (for terrain or wather surface) divided in to the squares, vhere I can manipulate individual points ditectly in real time. Basicly to change height.

I was looking at irr::scene::ISceneManager Class Reference especialy at addHillPlaneMesh, addTerrainMesh, addTerrainSceneNode, addWaterSurfaceSceneNode, but none of them lets you manipulate data directly.

I was looking quickly to rest of Irr help but found nothing (which doesnt mean that there is nothing)
I just need somebody to point me to the right direction, I am new to Irrlicht.

Thanks...
Gorgon Zola
Posts: 118
Joined: Thu Sep 18, 2003 10:05 pm
Location: switzerland

Post by Gorgon Zola »

Hi arras

unfortunately there's no prebuilt scenenode that supports what you're looking for.

also, if you'd like to manipulate prebuilt meshes in real time, that is you have a pointer to an IMesh, there's no optimized way in querying a 3d position and get the corresponding vertex, you'd have to traverse the whole mesh and compare each vertex to the position you want to change (very slow)!

so, if you need a heightfield scenenode that supports fast 2d access to vertecis you'll probably have to implement it yourself.

you could however use my adaption of a quadtree terrain scenenode from my ode tutorial (if you are adventerous), but it honestly is a total mess and very far from beeing documented.

good luck
tom
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

Hi Gordon and thanks for reply...
that doesnt sound wery good :( however
I was looking at Tutorial 3.CustomSceneNode -wouldnt be posible to do it that way? I just need simple matrix, where all data about points can be stored in 2d array and accesed through it.

Its sure posible to make Custom SceneNode of matrix shape only question is if I can change data of one (or few) vertices without deleting old node and building new one ...which would be probably slow.
Domarius
Posts: 178
Joined: Thu Mar 11, 2004 9:51 am
Location: Brisbane, QLD, Australia

Post by Domarius »

Well if your mesh was divided into squares to begin with (in a 3D modeller, or by making it yourself from vertice points in the code), then I'm sure there are functions available to move individual vertices. I just don't know them off the top of my head.

I think Gorgon Zola meant that there is no feature in irrlicht to actually divide an existing polygon up. Which I have never heard of in other game engines either. You just make the mesh that way to begin with.
Gorgon Zola
Posts: 118
Joined: Thu Sep 18, 2003 10:05 pm
Location: switzerland

Post by Gorgon Zola »

arras wrote:... only question is if I can change data of one (or few) vertices without deleting old node and building new one ...which would be probably slow.
changing the data of a vertex is possible without allocating a new vertex.
let's assume you have a meshbuffer with vertecis of type S3DVertex
then you can change the vertex data like this:

S3DVertex* v= ( (S3DVertex*)meshbuffer->getVertices() )[index];

change height:
f32 newHeight=v->pos.Y-100;
v->pos.set(v->pos.X,newHeight,v->pos.Z);

if you use an octree scenenode then this will not work since the octree doesn't hold a reference to the mesh you create it with, so you'll probably be working with your custom scenenode and a 2d array of vertices

cheers
tom
Guest

Post by Guest »

Simple matrix like mesh should be done by just modifiing Custom Scene node Tutorial.

When I have some free time I try that among with your code. (well I have to dig a little bit in Irr documentation since I am new to it)
Thanks :)
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

Ah, hell I forget to loog in ...that Guest, thats me... :)
Bog_Wraith
Posts: 12
Joined: Sun Jul 11, 2004 7:55 pm
Location: Tampa
Contact:

wondering

Post by Bog_Wraith »

Hey arras, was wondering if you ever solved this problem?
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

sure, here is sample code:

Code: Select all

#include "irrlicht.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace gui;


// build terain class based on custom scene node example
// terain will be represented by matrix 3*3 tiles big

//    03 - 07 - 11 - 15
//    |  3 |  6 |  9 |
//    02 - 06 - 10 - 14
//    |  2 |  5 |  8 |
//    01 - 05 - 09 - 13
//    |  1 |  4 |  7 |
//    00 - 04 - 08 - 12

class TestTerainSceneNode : public scene::ISceneNode
{
	core::aabbox3d<f32> Box;
	video::SMaterial Material;
	video::S3DVertex Vertices[16]; //number of vertices
	u16 indices[6*9];              //number of indices - 3*3=9 tiles each have 6 indices
	int index [3+1] [3+1];         //index for storing vertex number - 4*4=16 vertices

public:

   //--- CONSTRUCTOR ---
   TestTerainSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id = -1);

   //--- DESTRUCTOR ---
   ~TestTerainSceneNode();

   virtual void OnPreRender();

   virtual void render();

   virtual const core::aabbox3d<f32>& getBoundingBox() const;

   virtual s32 getMaterialCount();

   virtual video::SMaterial& getMaterial(s32 i);
   
   // acess height of vertice based on its position in matrix
   void setHeight(int x, int z, float height);	
};

TestTerainSceneNode::TestTerainSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id)
   : scene::ISceneNode(parent, mgr, id)
{
   Material.Wireframe = true;
   Material.Lighting = false;

   //terain matrix = 3*3 tiles big, one tile = 10*10 units   

   // defining vertices of terain matrix
   int i = 0;
   for(int x=0; x<(3+1); x++)
   {
      for(int z=0; z<(3+1); z++)
      {
          Vertices[i] = video::S3DVertex( x*10, 0, z*10,
                                          0,1,0,
                                          video::SColor(255,100,200,100),
                                          0, 0);
          index[x][z] = i;
          i++;  
      }
   } 
   
   //defining indices of tiles
   i = 0;
   for(int x=0; x<3; x++)
   {
      for(int z=0; z<3; z++)
      {
          // firsth polygoon of tille
          indices[i] = index[x][z];
          i++;
          indices[i] = index[x][z+1];
          i++;
          indices[i] = index[x+1][z+1];
          i++;
          // second polygoon of tille
          indices[i] = index[x][z];
          i++;
          indices[i] = index[x+1][z+1];
          i++;
          indices[i] = index[x+1][z];
          i++;
      }
   }  

   Box.reset(Vertices[0].Pos);
   for (s32 i=1; i<16; ++i)
      Box.addInternalPoint(Vertices[i].Pos);
}

//--- DESTRUCTOR ---	
TestTerainSceneNode::~TestTerainSceneNode() {}

void TestTerainSceneNode::OnPreRender()
{
   if (IsVisible)
   {
      SceneManager->registerNodeForRendering(this);
      ISceneNode::OnPreRender();
   }
}

void TestTerainSceneNode::render()
{
   video::IVideoDriver* driver = SceneManager->getVideoDriver();

   driver->setMaterial(Material);
   driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
   driver->drawIndexedTriangleList(&Vertices[0], 16, &indices[0], 18); //num of vertices, num of polygoons
}

const core::aabbox3d<f32>& TestTerainSceneNode::getBoundingBox() const
{
   return Box;
}

s32 TestTerainSceneNode::getMaterialCount()
{
   return 1;
}

video::SMaterial& TestTerainSceneNode::getMaterial(s32 i)
{
   return Material;
}

void TestTerainSceneNode::setHeight(int x, int z, float height)
{
    core::vector3df position = Vertices[ index[x][z] ].Pos;
    position.Y = height;
    Vertices[ index[x][z] ].Pos = position;
}


int main()
{	
	IrrlichtDevice *device = createDevice(EDT_OPENGL, 
	   dimension2d<s32>(800, 600), 32, false, false, 0);
		
	device->setWindowCaption(L"Test terrain by arras");
	
	IVideoDriver* driver = device->getVideoDriver();

	ISceneManager* smgr = device->getSceneManager();
	
	IGUIEnvironment* guienv = device->getGUIEnvironment();

	smgr->addCameraSceneNode(0, core::vector3df(15,10,-10), core::vector3df(15,0,15));
	
	TestTerainSceneNode *terain = 
		new TestTerainSceneNode(smgr->getRootSceneNode(), smgr);
	terain->drop();
	
	float h = 0.0f;
	while(device->run())
	{		
        driver->beginScene(true, true, SColor(0,0,0,0));
		smgr->drawAll();
		guienv->drawAll();
		
		//change height (y coordinate) of vertice at position 1*1 inside terain matrix
		terain->setHeight(1,1,h);
		h += 0.01f;
		if(h>10.0f) h = 0.0f;
		
        driver->endScene();
    }		
	device->drop();
	return 0;
}
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

btw you can maniulate texture coordinates, vertex color or vertex normal in similar fasion, just add functions for that.
Bog_Wraith
Posts: 12
Joined: Sun Jul 11, 2004 7:55 pm
Location: Tampa
Contact:

thanks

Post by Bog_Wraith »

that's great arras, thanks a lot. I am gonna go play around with this now
Post Reply