Page 1 of 1

manipulating mesh data in real time?

Posted: Mon Apr 05, 2004 8:48 am
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...

Posted: Mon Apr 05, 2004 11:42 am
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

Posted: Mon Apr 05, 2004 8:11 pm
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.

Posted: Tue Apr 06, 2004 1:50 am
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.

Posted: Tue Apr 06, 2004 9:36 am
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

Posted: Wed Apr 07, 2004 11:23 am
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 :)

Posted: Wed Apr 07, 2004 11:24 am
by arras
Ah, hell I forget to loog in ...that Guest, thats me... :)

wondering

Posted: Fri Jul 30, 2004 3:46 am
by Bog_Wraith
Hey arras, was wondering if you ever solved this problem?

Posted: Fri Jul 30, 2004 10:57 am
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;
}

Posted: Fri Jul 30, 2004 11:04 am
by arras
btw you can maniulate texture coordinates, vertex color or vertex normal in similar fasion, just add functions for that.

thanks

Posted: Fri Jul 30, 2004 1:33 pm
by Bog_Wraith
that's great arras, thanks a lot. I am gonna go play around with this now