Attach weapons to bones (X & ms3d) -code snippet-

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
Cristian

Attach weapons to bones (X & ms3d) -code snippet-

Post by Cristian »

Using this, you won't need to add one line of code to the engine.
Works both for .X & .ms3d files.
For ms3d support just replace all instances of "IAnimatedMeshX" with "IAnimatedMeshMS3D". I am curently using it in my game, so it's tested & tried. It works with as many animations as you want. (I have 5 animations inside my character's .x file & it works perfectly with all).

Before your main loop or in a function add and modify (as needed) this:

Code: Select all

player_mesh = smgr->getMesh([your player mesh]);
player_node = smgr->addAnimatedMeshSceneNode( player_mesh );
player_mesh->drop();

IAnimatedMesh* weapon_mesh = smgr->getMesh([your weapon mesh]);
IAnimatedMeshSceneNode* weapon_node = smgr->addAnimatedMeshSceneNode(weapon_mesh);

weapon_mesh->drop();
weapon_node->setScale(core::vector3df(0.25,0.25,0.25));//scale it as needed
weapon_node->setMaterialTexture(0,[your weapon texture])
	
int JointNo = ((IAnimatedMeshX*)mesh)->getJointNumber([Desired joint name]);

player_node->addChild( weapon_node ); 
and inside your main loop, do this:

Code: Select all

weapon_node->setPosition(((IAnimatedMeshX*)weapon_mesh)->getMatrixOfJoint(JointNo,0)->getTranslation()); 
weapon_node->setRotation(((IAnimatedMeshX*)weapon_mesh)->getMatrixOfJoint(JointNo,0)->getRotationDegrees());
It did wonders for me, & I didn't need engine recompilation anymore, nor hours spent for animating each weapon.
Saku
Posts: 158
Joined: Wed Jan 05, 2005 8:48 am
Location: Denmark

Post by Saku »

Thanks!!:!:
This is just what I needed!

/Saku
Call me Wice, Miami Wice!
Guest

Post by Guest »

can you maybe post a model where I can test that code?
dhenton9000
Posts: 395
Joined: Fri Apr 08, 2005 8:46 pm

Post by dhenton9000 »

I never got this to work for .X files, theres a bug reported on it for .X, see the following post.

http://irrlicht.sourceforge.net/phpBB2/ ... php?t=8975

The models you see in the screenshots are available at
http://www.s-fonline.com/webhosting/dhenton9000
Guest

Post by Guest »

in the function you posted...

Code: Select all

//! Returns a pointer to a transformation matrix
core::matrix4* CXAnimationPlayer::getMatrixOfJoint(s32 jointNumber, s32 frame)
{
   if (jointNumber < 0 || jointNumber >= (s32)Joints.size())
      return 0;

//   remove  this --> return // &Joints[jointNumber].CombinedAnimationMatrix;
   return &Joints[jointNumber].AnimatedMatrix; //replace with this
} 
what does the param frame exactly do? nothing. I have two models in my scene, both created from the same mesh. Now, when one moves, the weapon of the other guy moves too (I update both players and request the matrices of the joints twice per frame (one for each player). So the state of one weapon interacts with the others, but the really strange thing is that it worked (the frame param) for one player - so anyone who has more understanding of the engine can tell me how the current joint position is calculated so that I can control both players without a copy of the mesh (leads to another question: is there function to copy animated meshes?).

I tried to use the example above with the getMesh function (for the specific frame) which end up in a strange mess (felt like doing drugs..).
dhenton9000
Posts: 395
Joined: Fri Apr 08, 2005 8:46 pm

Post by dhenton9000 »

Guest

frame is the index into the mesh set for an animation, in other words the position in the animation. There's a mesh for each step in the animation and frame is the index.

I'm not sure, but I'm thinking that to get what you want, you will have to do what you dont want to do-- maintain separate meshes for each node.
guest01

Post by guest01 »

dhenton9000 wrote:Guest

frame is the index into the mesh set for an animation, in other words the position in the animation. There's a mesh for each step in the animation and frame is the index.

I'm not sure, but I'm thinking that to get what you want, you will have to do what you dont want to do-- maintain separate meshes for each node.
I know that it specifies the frame, but from the function code, there is no difference if you pass 0 or 1 or whatever... In fact the function always returns the joint matrices of the animation the first loaded character is currently playing....
Guest

Post by Guest »

I chose the simplier way by "preloading" all frame information into an array while my game is loading and then access the local array for precise frame transformation (avoid creating many meshes..)
sftb
Posts: 1
Joined: Fri Aug 04, 2006 8:47 pm

oops?

Post by sftb »

hi.
Cristian, i had no problems with your code at all (im currently adding it to the movement tutorial on the main site), however, right when i added this part:

Code: Select all

weapon_node->setPosition(((scene::IAnimatedMeshMS3D*)weapon_mesh)->getMatrixOfJoint(JointNo,0)->getTranslation());
weapon_node->setRotation(((scene::IAnimatedMeshMS3D*)weapon_mesh)->getMatrixOfJoint(JointNo,0)->getRotationDegrees());
an error occured. It was not a compiling error, everything was flawless there, but right as the program started running one of the old "projecttest.exe has encountered a problem and needs to close. We are sorry for the invoncenience." errors popped up.

Any clue as to why/how to fix it?

Im very new to irrlicht, and if you need anymore information please let me know.
Cristian
Posts: 55
Joined: Fri Nov 25, 2005 12:02 pm

Post by Cristian »

Code:
weapon_node->setPosition(((scene::IAnimatedMeshMS3D*)weapon_mesh)->getMatrixOfJoint(JointNo,0)->getTranslation());
weapon_node->setRotation(((scene::IAnimatedMeshMS3D*)weapon_mesh)->getMatrixOfJoint(JointNo,0)->getRotationDegrees());


an error occured. It was not a compiling error, everything was flawless there, but right as the program started running one of the old "projecttest.exe has encountered a problem and needs to close. We are sorry for the invoncenience." errors popped up.
MY bad :) replace "weapon_mesh" with "char_mesh" (or whatever mesh you use for your char). BTW new vers of irrlicht have the

Code: Select all

 const c8 *  getJointName (s32 number) 
 s32  getJointNumber (const c8 *name)
 core::matrix4 *  getMatrixOfJoint (s32 jointNumber, s32 frame) 
functions for both X and MS3D so this is deprecated :)
vhson13
Posts: 10
Joined: Wed Mar 17, 2010 3:39 pm

Post by vhson13 »

Hi,

Currently, I using Irrlicth 1.7 to attach sword into character. But I got some problem. The sword does not really attach to right position of right hand. Anyone please help and explain for me. Thank you

Here is my code:

Code: Select all

scene::IAnimatedMesh* sword_mesh = (scene::IAnimatedMesh*)smgr->getMesh("E:/Blender Foundation/icebrand.3ds");
scene::IAnimatedMeshSceneNode* sword = smgr->addAnimatedMeshSceneNode(sword_mesh);
scene::ISkinnedMesh* char_mesh =(scene::ISkinnedMesh*) smgr->getMesh("E:/Blender Foundation/womxxxx.x");
scene::IAnimatedMeshSceneNode* anms = 		smgr->addAnimatedMeshSceneNode(char_mesh);
scene::ISkinnedMesh::SJoint* handjoint = char_mesh->getAllJoints()[char_mesh->getJointNumber("manoR")];
irr::scene::IBoneSceneNode* hand =  anms->getJointNode("manoR");
hand->addChild(sword);
sword->setPosition(handjoint->GlobalAnimatedMatrix.getTranslation());
sword->setRotation(handjoint->Animatedrotation.getMatrix().getTranslation());
anms->setPosition(core::vector3df(-12.f,2.f,42.f));
Image
shadowslair
Posts: 758
Joined: Mon Mar 31, 2008 3:32 pm
Location: Bulgaria

Post by shadowslair »

You don`t need the joint. Just do it like this:

Code: Select all

scene::IAnimatedMesh* sword_mesh = (scene::IAnimatedMesh*)smgr->getMesh("E:/Blender Foundation/icebrand.3ds");
scene::IAnimatedMeshSceneNode* sword = smgr->addAnimatedMeshSceneNode(sword_mesh);
scene::ISkinnedMesh* char_mesh =(scene::ISkinnedMesh*) smgr->getMesh("E:/Blender Foundation/womxxxx.x");
scene::IAnimatedMeshSceneNode* anms =       smgr->addAnimatedMeshSceneNode(char_mesh);
//#### scene::ISkinnedMesh::SJoint* handjoint = char_mesh->getAllJoints()[char_mesh->getJointNumber("manoR")];
irr::scene::IBoneSceneNode* hand =  anms->getJointNode("manoR");
hand->addChild(sword);
//sword->setPosition(/* position it manually if you wish to match properly- IN HAND SPACE*/);
//sword->setRotation(/* rotate it manually if you wish to match properly- IN HAND SPACE*/);
anms->setPosition(core::vector3df(-12.f,2.f,42.f)); 
Its because the IBoneSceneNode has the Joint transformation and when you add the sword as a child of it, Irrlicht updates it automatically.

You`re having problems, because you`re using some snippet from 2005. You don`t need those tweaks anymore...
"Although we walk on the ground and step in the mud... our dreams and endeavors reach the immense skies..."
vhson13
Posts: 10
Joined: Wed Mar 17, 2010 3:39 pm

Post by vhson13 »

@ shadowslair: I tried your code, but the sword still be in wrong position. So I want to know does I have to modify anything in sword model or character model?

Image
shadowslair
Posts: 758
Joined: Mon Mar 31, 2008 3:32 pm
Location: Bulgaria

Post by shadowslair »

If the sword is always at the same space of your character`s hand and following it while moving, you`re on the right way. Your sword origin may be wrong.
Assuming that your hand bone is in correct place in the model, you`re calling it by its correct name and your sword origin point is at the handle ( http://www.glowfoto.com/static_image/15 ... 6/glowfoto ) things should be fine, except the sword orientation maybe, so you may need to change it orientation either via the modelling program, or manually by setting rotation of the sword. You may need to play around a bit with the position and rotation to get it exactly at the palm. Keep in mind that positioning will be easier if your character model isn`t scaled.
"Although we walk on the ground and step in the mud... our dreams and endeavors reach the immense skies..."
vhson13
Posts: 10
Joined: Wed Mar 17, 2010 3:39 pm

Post by vhson13 »

@shadowslair: Thank you, after playing around with model, I can put sword at the right position.
Post Reply