Page 1 of 1

Editing Meshes in Engine

Posted: Fri Oct 01, 2004 2:18 am
by Guest
(I've posted this earlier, but was recommended to transfer the discussion to this forum).

I am currently looking for a way to dynamically modify a mesh or model within the engine. For example, a deformable terrain map. It doesn't have to be anything complex (yet), thus I could start by opening up a simple box, and having a red bouncing ball bounce out and bounce around...

I have played with dynamic models before, although it was in C coding for an OpenGL assignment. The problem is doing the same on the Irrlicht engine.

[/url]

Posted: Fri Oct 01, 2004 8:33 am
by arras
It is possible. But you have to do it by accesing vertices individualy, you can change their position, UV and several other atributes. I was not doing it with loaded meshes, just with meshes build inside engine.

Here is example code for deforming simple terrain:

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: Thu Jan 27, 2005 1:51 am
by deprecated
ooohh... this is a nice example...

thank you arras

8)

(another hidden treasure in the forum...)

Posted: Thu Jan 27, 2005 1:09 pm
by Electron
One thing to note: be careful with editing meshes in the engine. I've crashed my video driver and locked up the system doing that, I think because I accidentally made part of my indices array invalid.

Posted: Thu Jan 27, 2005 5:55 pm
by deprecated
I've crashed my video driver and locked up the system doing that[...]
:wink: sounds like windows to me!

Posted: Thu Jan 27, 2005 7:13 pm
by Spintz
deprecated wrote:
I've crashed my video driver and locked up the system doing that[...]
:wink: sounds like windows to me!

Boooo, you know that OpenGL you love, that works on Linux, well you know that Microsoft co-owns the right on OpenGL? They can't release OpenGL updates unless Microsoft agrees on them.....so Microsoft even has a part in your precious Linux!!! ;)

Posted: Thu Jan 27, 2005 7:48 pm
by deprecated
Hello to you spintz...

Or, would you prefer to be called, Dr. KillJoy :wink:

EDIT:

Well, My kernel is tained by nVidia anyways...

Besides, I would be happy to see more microsoft products that begin with "Open".

Posted: Thu May 12, 2005 8:16 pm
by MeisterK
Even when this an old thread is, I found it quite interesting to learn from (thx arras).

I extended it a litte to set the texture u,v coords of the vertices.

But I faild to attach a texture on it. I looked in the Irrlicht code to find out what might be missing- without success.

Is someone herewho can give me a hint (or some snippet) what must be changed in the TestTerainSceneNode class?

Thx


There is my code for attaching a texture

Code: Select all

		 terrain = new TestTerainSceneNode(irrScenemanager->getRootSceneNode(), irrScenemanager); 
		 terrain->setMaterialTexture(0,irrDriver->getTexture("c:\abc.bmp"));
		 terrain->setMaterialType(video::EMT_SOLID);
    	 terrain->setMaterialFlag(video::EMF_WIREFRAME, false);
	     terrain->drop();