Page 1 of 1

Using per-vertex animation (aka tweening) in irrlicht

Posted: Mon Oct 29, 2007 11:01 am
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.

Posted: Mon Oct 29, 2007 12:11 pm
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;
}

Posted: Sun Nov 04, 2007 3:35 pm
by guest22
Thanks a lot.