Using per-vertex animation (aka tweening) in irrlicht

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
guest22
Posts: 5
Joined: Mon Mar 12, 2007 2:55 pm

Using per-vertex animation (aka tweening) in irrlicht

Post by guest22 »

Hi,

I want to use a model with per vertex in animation in irrlicht.
The original model was done in 3DS Max.
It is very simple model for test, a plane moving like a wave.

As far as I've understood, this kind of animation is not supported in irrlicht in 3DS files, but just on MD2.

I've tried to convert the file to MD2 using milkshape, but I got various errors, and I couldnt do it.
I've post a q in milkshape forum, but no one could help.

Is there anyone that can help with this problem ?
Maybe there is another tool / or other way to do it ?

My final task is to show a 3D model with per vertex animation (talking face), where the model is either in 3DS Max or Maya.
If you have any other suggestions, or better ways to do it, other engines, etc., I will be happy to hear.


Any suggestion is most welcome.
10x for your help.
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

You could implement vertex interpolation yourself, using mesh buffers.

Here's a very simple example that uses linear interpolation. It gets the vertices by loading an animated mesh and then duplicating the mesh buffers that are returned from (skeletally) animating it. How you get your own vertex positions is really up to you.

Code: Select all

#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif

int main()
{
	IrrlichtDevice *device =
		createDevice( video::EDT_SOFTWARE, dimension2d<s32>(640, 480), 16,
			false, false, false, 0);
	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();
	IGUIEnvironment* guienv = device->getGUIEnvironment();


	IAnimatedMesh* mesh = smgr->getMesh("../../media/dwarf.x");

	// Instead of adding the skeletally animated mesh to the scene, instead
	// we are going to add a static mesh. First, we'll create copies of
	// the mesh buffers (i.e the vertex positions) for two frames of the
	// animated mesh
	IMeshBuffer * startBuffer = new SMeshBuffer;
	startBuffer->append(mesh->getMesh(0)->getMeshBuffer(0));

	IMeshBuffer * finalBuffer = new SMeshBuffer;
	finalBuffer->append(mesh->getMesh(50)->getMeshBuffer(0));

	// Now add the mesh to the scene, with its initial position.
	IMeshSceneNode * node = smgr->addMeshSceneNode(mesh->getMesh(0));

	if (node)
	{
		node->setMaterialFlag(EMF_LIGHTING, false);
		node->setMaterialTexture( 0, driver->getTexture("../../media/dwarf.jpg") );
	}

	smgr->addCameraSceneNode(0, vector3df(0,30,-100), vector3df(0,25,0));

	float interpolation = 0.f;
	float interpolationDelta = 0.01f; // Not framerate dependent

	while(device->run())
	{
		driver->beginScene(true, true, SColor(255,100,101,140));

		// Now we'll manipulate the vertices of the mesh, linearly interpolating between two positions
		IMeshBuffer * displayedBuffer = node->getMesh()->getMeshBuffer(0);
		if(video::EVT_STANDARD == displayedBuffer->getVertexType())
		{
			const video::S3DVertex * startVertices = static_cast<const video::S3DVertex *>(startBuffer->getVertices());
			const video::S3DVertex * finalVertices = static_cast<const video::S3DVertex *>(finalBuffer->getVertices());
			video::S3DVertex * displayedVertices = static_cast<video::S3DVertex *>(displayedBuffer->getVertices());

			for(int vertex = displayedBuffer->getVertexCount() - 1; vertex >= 0; --vertex)
			{
				displayedVertices[vertex].Pos = 
					(startVertices[vertex].Pos * (1.f - interpolation) + finalVertices[vertex].Pos * interpolation);
			}

			if(interpolation >= 1.f)
			{
				interpolationDelta = -1.f * fabs(interpolationDelta);
			}
			else if(interpolation < 0.f)
			{
				interpolationDelta = fabs(interpolationDelta);
			}

			interpolation += interpolationDelta;
		}

		smgr->drawAll();
		guienv->drawAll();

		driver->endScene();
	}

	device->drop();
	startBuffer->drop();
	finalBuffer->drop();

	return 0;
}
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
guest22
Posts: 5
Joined: Mon Mar 12, 2007 2:55 pm

Post by guest22 »

Thanks a lot.
Post Reply