useAnimationFrom problem

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.
B@z
Posts: 876
Joined: Thu Jan 31, 2008 5:05 pm
Location: Hungary

Post by B@z »

any ideas?
Image
Image
WarLocker
Posts: 3
Joined: Fri Aug 14, 2009 8:49 am

Post by WarLocker »

CuteAlien
I'm not sure my way is better, but here it is:

Code: Select all

       IAnimatedMesh *meshtest=smgr->getMesh("media/soldierMad.b3d");//    loading mesh that contains bones
       IMeshCache *k=smgr->getMeshCache();  
       core::stringw newname="blah";
       newname+=1;// make new unique file name
        const irr::c8* namw;
        namw=(irr::c8*)newname;
       k->setMeshFilename(meshtest,namw);
      ISkinnedMesh* meshdewalk= (ISkinnedMesh*)meshtest;
So here is how it works: Load an animated mesh. Get the mesh cache and change models FileName to something else - well I'm just changing it to "blah1". Now my model is ready to receive Animations and i can load my soldierMad.b3d again. This method will require lots of memory though cause every skeletal model is loaded N times. Sorry for my English
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

I'm not really sure if it even is still needed with all recent changes, but anyway - I updated my code recently to 1.6. And due to nice changes in the engine it's no longer necessary to patch Irrlicht, but can be done outside:

Code: Select all

//! Create a skinned mesh which has copied all meshbuffers and joints of the original mesh
/** Note, that this will not copy any other information like joints data.
\param mesh Original mesh
\return Newly created skinned mesh. You should call drop() when you don't need it anymore.
See IReferenceCounted::drop() for more information. */

irr::scene::ISkinnedMesh* createSkinnedMeshCopy(irr::scene::ISkinnedMesh* mesh, irr::scene::ISceneManager * sceneManager)
{
	using namespace irr;
	using namespace scene;

	ISkinnedMesh* skinnedMesh = sceneManager->createSkinnedMesh();

    if ( !mesh )
        return skinnedMesh;

    for ( u32 i=0; i < mesh->getMeshBuffers().size(); ++i )
    {
        SSkinMeshBuffer * buffer = skinnedMesh->addMeshBuffer();
        *buffer = *(mesh->getMeshBuffers()[i]);
    }

    for ( u32 j=0; j < mesh->getAllJoints().size(); ++j )
    {
        ISkinnedMesh::SJoint *joint = skinnedMesh->addJoint();
        *joint = *(mesh->getAllJoints()[j]);
	}

    // fix children pointers (they still have old pointers)
    core::array<ISkinnedMesh::SJoint*> & newJoints = skinnedMesh->getAllJoints();
    core::array<ISkinnedMesh::SJoint*> & oldJoints = mesh->getAllJoints();
    for ( u32 i=0; i < newJoints.size(); ++i )
    {
        ISkinnedMesh::SJoint * joint = newJoints[i];
        for ( u32 c=0; c < joint->Children.size(); ++c )
        {
            // the child is one of the oldJoints and must be replaced by the newjoint on the same index
            for ( u32 k=0; k < oldJoints.size(); ++k )
            {
                if ( joint->Children[c] == oldJoints[k] )
                {
                    joint->Children[c] = newJoints[k];
                    break;
                }
            }
        }
    }

	skinnedMesh->finalize();

    return skinnedMesh;
}
But maybe try figure out first if you even still need something like that before using it. Adapting my code was faster than starting new experiments so I just did that.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
KakCAT
Posts: 10
Joined: Fri May 14, 2010 10:09 am

Post by KakCAT »

it's also working on 1.7.1.

Thanks, CuteAlien!
eagletree
Posts: 28
Joined: Mon Jul 26, 2010 11:55 pm

Re:

Post by eagletree »

CuteAlien wrote:I'm not really sure if it even is still needed with all recent changes, but anyway - I updated my code recently to 1.6. And due to nice changes in the engine it's no longer necessary to patch Irrlicht, but can be done outside:

Code: Select all

 
//! Create a skinned mesh which has copied all meshbuffers and joints of the original mesh
/** Note, that this will not copy any other information like joints data.
\param mesh Original mesh
\return Newly created skinned mesh. You should call drop() when you don't need it anymore.
See IReferenceCounted::drop() for more information. */
 
irr::scene::ISkinnedMesh* createSkinnedMeshCopy(irr::scene::ISkinnedMesh* mesh, irr::scene::ISceneManager * sceneManager)
{
        using namespace irr;
        using namespace scene;
 
        ISkinnedMesh* skinnedMesh = sceneManager->createSkinnedMesh();
 
    if ( !mesh )
        return skinnedMesh;
 
    for ( u32 i=0; i < mesh->getMeshBuffers().size(); ++i )
    {
        SSkinMeshBuffer * buffer = skinnedMesh->addMeshBuffer();
        *buffer = *(mesh->getMeshBuffers()[i]);
    }
 
    for ( u32 j=0; j < mesh->getAllJoints().size(); ++j )
    {
        ISkinnedMesh::SJoint *joint = skinnedMesh->addJoint();
        *joint = *(mesh->getAllJoints()[j]);
        }
 
    // fix children pointers (they still have old pointers)
    core::array<ISkinnedMesh::SJoint*> & newJoints = skinnedMesh->getAllJoints();
    core::array<ISkinnedMesh::SJoint*> & oldJoints = mesh->getAllJoints();
    for ( u32 i=0; i < newJoints.size(); ++i )
    {
        ISkinnedMesh::SJoint * joint = newJoints[i];
        for ( u32 c=0; c < joint->Children.size(); ++c )
        {
            // the child is one of the oldJoints and must be replaced by the newjoint on the same index
            for ( u32 k=0; k < oldJoints.size(); ++k )
            {
                if ( joint->Children[c] == oldJoints[k] )
                {
                    joint->Children[c] = newJoints[k];
                    break;
                }
            }
        }
    }
 
        skinnedMesh->finalize();
 
    return skinnedMesh;
}
 
But maybe try figure out first if you even still need something like that before using it. Adapting my code was faster than starting new experiments so I just did that.
I attempted to use the code above to solve the issue of having multiple nodes sharing the mesh and duplicating my skeletal animations. It worked but rotated the mesh -90 on the y axis, and created some serious deformations when I applied skeletal animation to the model. Do either of these sound like something likely from using this method?

Thanks

Edit: just realized that the deformation is likely caused by not having the joint data. Still wondering why the rotation would occur.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: useAnimationFrom problem

Post by CuteAlien »

Sorry, don't know. But haven't tested the code yet with newest Irrlicht (will do so a in a few weeks as I'm working on upgrading the project using this).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
eagletree
Posts: 28
Joined: Mon Jul 26, 2010 11:55 pm

Re: useAnimationFrom problem

Post by eagletree »

Thanks for the response, I will attempt the filename hack as a fallback. The deformations are a show stopper so reloading from scratch to spawn duplicates, seems the prudent course. Hate to add disk accesses given the file size of a boned model. Hopefully someone will come up with an alternative.
Post Reply