.B3D: How to make character body out of several parts

Post your questions, suggestions and experiences regarding to Image manipulation, 3d modeling and level editing for the Irrlicht engine here.
Alopex
Posts: 41
Joined: Sat Sep 12, 2015 10:12 pm

Re: .B3D: How to make character body out of several parts

Post by Alopex »

@SunnyStormy

I tried your second suggestion first, with the same result as before. My animnode mesh was moving; my other meshes were not.

I tried your first suggestion as well. I can't get it to work, and logically, there's no reason to believe it would do anything that my original code didn't. Here is an example of one of my nodes.

Code: Select all

 
IAnimatedMeshSceneNode* maletorsonode = smgr->addAnimatedMeshSceneNode(smgr->getMesh("C:/Users/James/Documents/Psychophagus/Assets/Male/Male_Chest.b3d"));
ISkinnedMesh* skintorso = (ISkinnedMesh*) (maletorsonode->getMesh());
maletorsonode->setMaterialFlag(EMF_LIGHTING, false);
skintorso->useAnimationFrom(animnode->getMesh());
 
Here are the errors returned:

||=== Build: Debug in Psychophagus (compiler: GNU GCC Compiler) ===|
C:\Users\James\Documents\Psychophagus\main.cpp||In function 'int main(int, char**)':|
C:\Users\James\Documents\Psychophagus\main.cpp|57|error: invalid conversion from 'irr::scene::IAnimatedMesh*' to 'const irr::scene::ISkinnedMesh*' [-fpermissive]|
C:\Users\James\Downloads\irrlicht-1.8.2\irrlicht-1.8.2\include\ISkinnedMesh.h|57|error: initializing argument 1 of 'virtual bool irr::scene::ISkinnedMesh::useAnimationFrom(const irr::scene::ISkinnedMesh*)' [-fpermissive]|
C:\Users\James\Documents\Psychophagus\main.cpp|63|error: invalid conversion from 'irr::scene::IAnimatedMesh*' to 'const irr::scene::ISkinnedMesh*' [-fpermissive]|
C:\Users\James\Downloads\irrlicht-1.8.2\irrlicht-1.8.2\include\ISkinnedMesh.h|57|error: initializing argument 1 of 'virtual bool irr::scene::ISkinnedMesh::useAnimationFrom(const irr::scene::ISkinnedMesh*)' [-fpermissive]|
C:\Users\James\Documents\Psychophagus\main.cpp|69|error: invalid conversion from 'irr::scene::IAnimatedMesh*' to 'const irr::scene::ISkinnedMesh*' [-fpermissive]|
C:\Users\James\Downloads\irrlicht-1.8.2\irrlicht-1.8.2\include\ISkinnedMesh.h|57|error: initializing argument 1 of 'virtual bool irr::scene::ISkinnedMesh::useAnimationFrom(const irr::scene::ISkinnedMesh*)' [-fpermissive]|
C:\Users\James\Documents\Psychophagus\main.cpp|75|error: invalid conversion from 'irr::scene::IAnimatedMesh*' to 'const irr::scene::ISkinnedMesh*' [-fpermissive]|
C:\Users\James\Downloads\irrlicht-1.8.2\irrlicht-1.8.2\include\ISkinnedMesh.h|57|error: initializing argument 1 of 'virtual bool irr::scene::ISkinnedMesh::useAnimationFrom(const irr::scene::ISkinnedMesh*)' [-fpermissive]|
C:\Users\James\Documents\Psychophagus\main.cpp|81|error: invalid conversion from 'irr::scene::IAnimatedMesh*' to 'const irr::scene::ISkinnedMesh*' [-fpermissive]|
C:\Users\James\Downloads\irrlicht-1.8.2\irrlicht-1.8.2\include\ISkinnedMesh.h|57|error: initializing argument 1 of 'virtual bool irr::scene::ISkinnedMesh::useAnimationFrom(const irr::scene::ISkinnedMesh*)' [-fpermissive]|
||=== Build failed: 10 error(s), 0 warning(s) (0 minute(s), 2 second(s)) ===|

Something about the way I tried to declare my skinned meshes must be wrong, and I guess I need to find a way to declare a skinned mesh for animnode.
sunnystormy
Posts: 105
Joined: Mon Jun 02, 2014 2:32 am
Location: Washington, D.C.
Contact:

Re: .B3D: How to make character body out of several parts

Post by sunnystormy »

@Alopex

Interesting.

It sounds like you're on the right track there. I'm wondering if the children nodes need to reference the animation of animnode, though? I think the torsonode referencing the animation should be enough. The other nodes should still be descended from the torso (and the feet from the legs), but I think the torso is the only one that needs to make that "useAnimationFrom()" method call. We'll find out. ;)

Once you figure out the ISkinnedMesh typecasting issue, give it another shot and let me know if it works. I think solving this and documenting it would be useful for the Irrlicht community as a whole. :)
My blog: http://fsgdp.wordpress.com "The Free Software Game Development Pipeline"
Alopex
Posts: 41
Joined: Sat Sep 12, 2015 10:12 pm

Re: .B3D: How to make character body out of several parts

Post by Alopex »

Once you figure out the ISkinnedMesh typecasting issue, give it another shot and let me know if it works. I think solving this and documenting it would be useful for the Irrlicht community as a whole. :)
Gee, thanks. :lol:

I'll keep trying, though.

It would be great if there was a way to store loc/rot/scale keys in a file and then have irrlicht import the file and apply the loc/rot/scale.

Would it be possible to do that? I know it would be tedious, but I think that my idea would be a little...prettier...than useAnimationFrom(). Of course, I'm sure that if it was worth doing, someone would have done it already. Thoughts?
sunnystormy
Posts: 105
Joined: Mon Jun 02, 2014 2:32 am
Location: Washington, D.C.
Contact:

Re: .B3D: How to make character body out of several parts

Post by sunnystormy »

@Alopex

Well, I'm certainly not a master of Irrlicht by any means. When it comes to digging beneath the surface of the mesh and node classes, I'm still learning myself. :)

I hope that you're able to figure this out, and that I was able to be helpful in some way.
My blog: http://fsgdp.wordpress.com "The Free Software Game Development Pipeline"
Alopex
Posts: 41
Joined: Sat Sep 12, 2015 10:12 pm

Re: .B3D: How to make character body out of several parts

Post by Alopex »

@sunnystormy

I'm just glad you guys didn't run me off or tell me to "do my own damn homework", as some communities have a tendency of doing.

Even if I can't get useAnimationFrom() to work, I've come up with another (insane) idea to keep me occupied.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: .B3D: How to make character body out of several parts

Post by mongoose7 »

Thinking about it again, I see that it can't work in an easy way. The skinning matrices move the vertices but they don't move nodes. One would have to extract the skinning matrices and apply them to the node transformations. This may be possible using bone scene nodes to obtain the skinning matrices, but I've never done this myself.
Alopex
Posts: 41
Joined: Sat Sep 12, 2015 10:12 pm

Re: .B3D: How to make character body out of several parts

Post by Alopex »

@mongoose7

Dang. I've got a lot of bones. This will be unpleasant.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: .B3D: How to make character body out of several parts

Post by mongoose7 »

It doesn't matter how many bones you have. If you want to break your body into three parts, you just need to create three nodes. The matrix to move a dependent node is got from composing the bones matrices from the root to the dependent node. So to control a gun, for example, you would compose the matrices for root, spine, right shoulder, right upper arm, right lower arm, hand. In principle, log2(# of bones), eg log2(128) = 7.
Alopex
Posts: 41
Joined: Sat Sep 12, 2015 10:12 pm

Re: .B3D: How to make character body out of several parts

Post by Alopex »

I'm not very math strong. Is there any way you can put that into layman's terms for me?
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Re: .B3D: How to make character body out of several parts

Post by christianclavet »

Hi!

I had some ideas about this with IRB. First is that every parts you would have to share the same skeleton in your modeling application. And you would have to playback all the "parts" from the same location at the same time. Ex: Legs, arms, torso. Anything that is rigid can be attached to the bones. The tricky part is for parts that are bending.

Having for example a way to change the chest armor of a character. And you would have to do the model in multiple parts and use the same complete skeleton and re skin the model for each part.

For the chest armor, you would have your character with the desired chest armor, skin it to the bones, then export the skeleton with the chest armor only. Then you would load the "naked" character, the chest armor, position them at the exact coordinates (they need to have the same skeleton structure). And use the "use animation from" command from Irrlicht to set the animation. Then playback the animation for both models at the same times. As in:

--> Base character --> Playback RUN
--> Chest Armor --> Playback RUN

So the more parts you have is like having more characters at the same place. Not the best, but this should work. The is also a extra care by using the "use animation from", this will apply to all references of the mesh you apply it to. For example, if you do 10 soldier like this, they will all play the same animation. I found a tricky way to no having of doing that by renaming each mesh instance in the mesh cache from Irrlicht, so Irrlicht will only apply it to the desired instance.

If you have a buckle, head armor, sword, or any rigid object, those can be "attached" to the bones and is much simpler to do.

Some suggestion on stuff that would be useful to future versions of Irrlicht for the animation system and make this a lot simpler and easier to do.
A desired thing is that if we could have tools inside Irrlicht that would "merge" the 2 meshes, and fuse the bones with the same name. If that was implemented, then you would import each part and rebuild the character as needed with the desired part, and use animations from to set the animations. This way, you would have a single FINAL model, with a single skeleton to animate, instead of multiple skeletons.

A command like this could be created:

Code: Select all

modelMerge(sourcemesh1, sourcemesh2, destinationmesh);
The command would merge the models together and create a new single model containing the meshbuffers and the bones would be fused in a single skeleton. If you have different skeletons, this would not work. You would need to have the exact same skeleton for each parts.


Also if the devs could "decouple" the animation data so it's copied and not used as a reference so the animation would be changed to the node instance we are working on. The animation data right now is stored in the mesh data, and this should be stored in the animated node instead. By storing it in the mesh data all the instances are affected because they take reference of the data from the same mesh. If the information would be inside the node data, each node would be independent for it's animations.

There would be no need to rename the mesh inside the mesh cache so the animation is not changed to all the mesh instances (if you are using copies of the character in your game)
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: .B3D: How to make character body out of several parts

Post by mongoose7 »

Can't you just move the mesh buffers yourself?

It would be nice to have the animation separate. Did Nadro have some ideas for the animation system?
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Re: .B3D: How to make character body out of several parts

Post by christianclavet »

Yes, there is a way to merge the meshes, but it's not simple. We have to do at the mesh buffer levels. If Irrlicht could have a command to do that it would be more accessible. Personally, I'm not sure I can do it myself. The skinning information from both model need to be merged too...

I've done another check on the animation information, in the source and the animations are stored in the bones data structures. When we use the command "useAnimationFrom", it simply copy the all the bone information from mesh to the other, so it's copying more information than needed. Most of this code is inside the SkinnedMesh and the Bones data structures source code.

Also for the animations that are being used for playback directly from the mesh data. Perhaps we could patch the skinnedmesh class to have a way to playback from custom data, instead of the reference of the mesh. So "useAnimationFrom" could be sent to a data pointer instead, and we could create another command to do a "custom" playback to use this pointer instead of the "default" animation from the mesh. From the code I've saw yesterday, this would be simpler to do than making it all external. Another command could be used to revert to the default animation that come with the mesh. So there would be 2-3 commands to do and perhaps keep "useAnimationFrom" as legacy.

I will not promise anything yet, but looking at this, I think I could perhaps create a patch that would allow more features to the animations, like appending, removing a range of frames, etc. Seem not so low level now, but this will need to be created as a patch since I'm not sure it's possible to do it outside of Irrlicht. The new commands would have to be added to the skinned mesh class since the "animation" I'm talking about it bone animation.

If I achieve something, I would need help to clean it up so the devs won't complain too much if they were to use the patch in Trunk. I'm still having trouble of Irrlicht working correctly on VS2015.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: .B3D: How to make character body out of several parts

Post by mongoose7 »

Err, useAnimationFrom doesn't copy any data, it just sets a pointer. And this is why, when a number of models use it, they all animate in the same way.

But you can do it all from outside Irrlicht. And you will have to because, without hybrid, you won't get anything past CuteAlien.

But you need to read CSkinnedMesh.cpp again (and again) first.
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Re: .B3D: How to make character body out of several parts

Post by christianclavet »

Hi, Perhaps I'm using the wrong terms.

If you look at this source code, it seem to take the data from a mesh and copy and replace it to the other (in this occurrence, all the JOINT data).

Code: Select all

//! uses animation from another mesh
bool CSkinnedMesh::useAnimationFrom(const ISkinnedMesh *mesh)
{
    bool unmatched=false;
 
    for(u32 i=0;i<AllJoints.size();++i)
    {
        SJoint *joint=AllJoints[i];
        joint->UseAnimationFrom=0;
 
        if (joint->Name=="")
            unmatched=true;
        else
        {
            for(u32 j=0;j<mesh->getAllJoints().size();++j)
            {
                SJoint *otherJoint=mesh->getAllJoints()[j];
                if (joint->Name==otherJoint->Name)
                {
                    joint->UseAnimationFrom=otherJoint;
                }
            }
            if (!joint->UseAnimationFrom)
                unmatched=true;
        }
    }
 
    checkForAnimation();
 
    return !unmatched;
}
when a number of models use it, they all animate in the same way.
From what I understand of it, it's that each NODE that accessing the same ISkinnedMesh class that contain the mesh data and animation. Since the animations are in the mesh data, each tampering will affect all the nodes since they look inside the same ISkinnedMesh for the animation data. That is what I want to change.

-1. Keep the animation in the mesh data as REFERENCE (or default)
-2. The playback from the NODE will give other data for the animation to the ISkinnedMesh (If I'm able to do it, I'm sure this part will be tricky as from what I see the animation is done inside the ISkinnedMesh class but triggered from the node class.)
-3. Use a command similar to UseAnimationFrom, to load ONLY the animation reference (see 1) from another mesh, and store it in the NODE class, so it's unique to the node.
-4. If I want to "reset" the animation stored in the node, retrieve the animation data reference stored in the mesh.
And you will have to because, without hybrid, you won't get anything past CuteAlien.
Perhaps, but B3D saving was integrated recently (I still find it one of the best feature added to Irrlicht in a long time!). So it' 50/50 and this part of code is completely unrelated to the new FVF format, hardware skinning, new improvement the devs are working on. And I will learn more about patching Irrlicht. I will put this patch for IRB to use, as if this work, I plan to add more feature to manipulate the animation data (append, clear, overwrite). But I'm still not sure it will work, I'm just trying at the moment.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: .B3D: How to make character body out of several parts

Post by mongoose7 »

Code: Select all

joint->UseAnimationFrom=otherJoint;
just sets a pointer - there is no data copy.
Post Reply