[Half-solved] Joints placed incorrectly

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
timetokill
Posts: 74
Joined: Tue Jul 22, 2008 4:28 am
Location: Los Angeles

[Half-solved] Joints placed incorrectly

Post by timetokill »

Hello,

I've been messing with animated B3D models and I wanted to add a transparent "helmet" to my model. What I tried doing was making a "helmet" model and attaching it to the "head" bone of my model. The problem is where the model gets placed is nowhere near the head bone :(

In this image, you can see that the helmet is displaced from the character. And yes, the helmet's model is centered at 0,0 in Maya -- no worries there.
Image

In this image, you can see that the helmet has moved/rotated appropriately with the model, though it is still displaced.
Image

Finally, here is the skeleton for the character. As you can see, the skeleton doesn't extend beyond the model, except for the animation curves, which I have labeled.
Image

Any ideas why this would be happening? If I do raycasting I also "find" the joints of the model to be out of place, though they are proportionally in the correct locations. Of course no bounding boxes appear for these displaced joints.


Edit: I've thought about attaching the helmet in the character model itself and exporting them together, but I would need a different material/texture for the helmet and the model. Is that possible with multi-texturing? How would I go about that?
Last edited by timetokill on Sun May 03, 2009 4:44 am, edited 1 time in total.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

You can define as many materials and groups in the b3d file as you want. So putting them all into one file would be possible. Note, though, that this would mean that the hat cannot be made invisible without some overhead in code.
Please show the code where you attach the hat, maybe it's a problem with transformation?
timetokill
Posts: 74
Joined: Tue Jul 22, 2008 4:28 am
Location: Los Angeles

Post by timetokill »

Thanks, hybrid. What kind of overhead are you talking about? Is it setting some flags or digging into the Irrlicht code?

Here's the code I'm using for the character:

Code: Select all

//assign the correct model
	if(isMale)		//character is male
	{
		if(currentAge > 15)		//character is an adult
		{
			//charMesh = gData->sm->getMesh("../media/meshes/anim/box2.b3d");
			charMesh = gData->sm->getMesh("../media/meshes/anim/Chr_Player_animTestQ_anim01.b3d");
			charNode = gData->sm->addAnimatedMeshSceneNode( charMesh );			
		}
		else					//character is a child
		{
			//charMesh = gData->sm->getMesh("../media/meshes/anim/guy3_shake1.b3d");
			//charMesh = gData->sm->getMesh("../media/meshes/anim/Chr_Player_animSet01.b3d");
			charMesh = gData->sm->getMesh("../media/meshes/anim/Chr_Player_animTestQ_anim01.b3d");
			charNode = gData->sm->addAnimatedMeshSceneNode( charMesh );
		}
	}
	else	//character is female
	{
		if(currentAge > 15)		//character is an adult
		{
			//charMesh = gData->sm->getMesh("../media/meshes/anim/guy3_shake1.b3d");
			//charMesh = gData->sm->getMesh("../media/meshes/anim/Chr_Player_animSet01.b3d");
			charMesh = gData->sm->getMesh("../media/meshes/anim/Chr_Player_animTestQ_anim01.b3d");
			charNode = gData->sm->addAnimatedMeshSceneNode( charMesh );
		}
		else					//character is a child
		{
			//charMesh = gData->sm->getMesh("../media/meshes/anim/guy3_shake1.b3d");
			//charMesh = gData->sm->getMesh("../media/meshes/anim/Chr_Player_animSet01.b3d");
			charMesh = gData->sm->getMesh("../media/meshes/anim/Chr_Player_animTestQ_anim01.b3d");
			charNode = gData->sm->addAnimatedMeshSceneNode( charMesh );
		}
	}

	//set the character joint mode
	charNode->setJointMode(EJUOR_READ);			//sets the joints to "read"

	//store the bones in the character
	charHead = charNode->getJointNode("head");
	//charHead->setIsDebugObject(true);
	charHeadTop = charNode->getJointNode("headTop");
	charHeadTop->setIsDebugObject(true);
	charLeftShoulder = charNode->getJointNode("shoulder_L");
	charLeftShoulder->setIsDebugObject(true);
	charRightShoulder = charNode->getJointNode("shoulder_R");
	charRightShoulder->setIsDebugObject(true);
	charLeftHand = charNode->getJointNode("hand_L");		//left hand
	charLeftHand->setIsDebugObject(true);
	charRightHand = charNode->getJointNode("hand_R");		//right hand
	charRightHand->setIsDebugObject(true);
	charPelvis = charNode->getJointNode("root");			//pelvis
	charPelvis->setIsDebugObject(true);

	//show debug info
	//charNode->setDebugDataVisible(scene::EDS_BBOX_BUFFERS);
	//charNode->setDebugDataVisible(EDS_SKELETON);
	//charNode->setDebugDataVisible(EDS_BBOX);
	//charNode->setDebugDataVisible(EDS_BBOX_BUFFERS);

	if( (myCharType == CHILD1) || (myCharType == CHILD2) || (myCharType == CHILD3) )
	{
		charNode->setScale(vector3df(2.8f,2.8f,2.8f));
	}
	else
	{
		charNode->setScale(vector3df(3.5f,3.5f,3.5f));
		charNode->updateAbsolutePosition();

		IAnimatedMesh* helmetMesh = gData->sm->getMesh("../media/meshes/anim/Chr_Player_helmet04.b3d");
		IAnimatedMeshSceneNode* helmetNode = gData->sm->addAnimatedMeshSceneNode( helmetMesh );
		helmetNode->setParent(charHead);
		//helmetNode->setPosition(vector3df(0.0f,0.1f,-1.4f));
	}
timetokill
Posts: 74
Joined: Tue Jul 22, 2008 4:28 am
Location: Los Angeles

Post by timetokill »

Hm, I have also noticed that I MUST combine any meshes I wish to export into a single mesh. Otherwise, Irrlicht doesn't know how to handle the animations or what mesh to apply them to, even if it works fine in a B3D viewer or in Max/Maya.
xray
Posts: 231
Joined: Fri Feb 02, 2007 1:06 pm
Location: Germany, Munich
Contact:

Post by xray »

Hey there, I dont know if my solution is right to your helmet placement problem, just an idea. For me it looks like that the center of your bones object is on pelvis, then maybe irrlicht places your helmet to the head bone position + the offset from pelvis bone to head bone! So try to decimate your helmet position by the vector of head position minus pelvis position.
timetokill
Posts: 74
Joined: Tue Jul 22, 2008 4:28 am
Location: Los Angeles

Post by timetokill »

Hi

Thank you for the suggestion, but it didn't quite work. I did try to manipulate the values as much as possible, and the following code puts the helmet near the appropriate position... though it doesn't follow the head exactly right when animating. The head still bobs around inside the helmet instead of the helmet being really attached to it.

Code: Select all

IAnimatedMesh* helmetMesh = gData->sm->getMesh("../media/meshes/anim/Chr_Player_helmet04.b3d");
		IAnimatedMeshSceneNode* helmetNode = gData->sm->addAnimatedMeshSceneNode( helmetMesh );
		helmetNode->setParent(charHead);
		helmetNode->setPosition( -(charHead->getPosition())*7.75 + charPelvis->getPosition()/7.75 );
Where's Luke, by the way? :lol:
kornwaretm
Competition winner
Posts: 189
Joined: Tue Oct 16, 2007 3:53 am
Location: Indonesia
Contact:

Post by kornwaretm »

in blender every object has world space transformation and model space transformation. in irrlicht also, and i'm sure maya does to. so have u check all transformation you did to your model? is the model and world space transformation is the same ( untransformed position(0,0,0) scale(1,1,1) rotation(0,0,0))? :?:
it's the same case when i attach weapon to hand, and as i remember there is where i go wrong. and i don't have to do extra transformation. :wink:
timetokill
Posts: 74
Joined: Tue Jul 22, 2008 4:28 am
Location: Los Angeles

Post by timetokill »

Kornwaretm, that is a good thing to keep in mind, definitely. I do reset transformations on my models before exporting, but what you posted did make me think to look into something else -- when I export from Maya to Max, it converts units from centimeters to inches... I think what might be happening is the joints are retaining (in some form) their unconverted position when the units are converted. I'm going to do some tests to see if I can avoid the conversion and report back with the results on that.
timetokill
Posts: 74
Joined: Tue Jul 22, 2008 4:28 am
Location: Los Angeles

Post by timetokill »

It appears to be solved at least in one regard. I'm posting my solution here for others who might have the same problem in the future.

My pipeline right now is to work in Maya, then export to FBX to open in Max, and then export to B3D using the onigirl b3d export tool. It works pretty well actually... now that Autodesk owns Maya and Max, the FBX tools are getting pretty good.

The issue that was happening for me is that the units I was using in Maya were in centimeters, and when it converted into Max it was being converted into inches. This works fine for the mesh, but the joints seem to get confused on some level. So what was happening to me was the joints were staying located in their "centimeter" position and weren't being scaled down.

I'm still having the issue of "checkJoints" preventing me from selecting scene nodes (because the joints seem to take over) but this is good for now. I'll probably just figure out a "interact with nearest scene node" option instead of relying on the mouse for input, at least until Luke or somebody comes to look at the joints issue.
B@z
Posts: 876
Joined: Thu Jan 31, 2008 5:05 pm
Location: Hungary

Post by B@z »

timetokill wrote:Hi

Thank you for the suggestion, but it didn't quite work. I did try to manipulate the values as much as possible, and the following code puts the helmet near the appropriate position... though it doesn't follow the head exactly right when animating. The head still bobs around inside the helmet instead of the helmet being really attached to it.

Code: Select all

IAnimatedMesh* helmetMesh = gData->sm->getMesh("../media/meshes/anim/Chr_Player_helmet04.b3d");
		IAnimatedMeshSceneNode* helmetNode = gData->sm->addAnimatedMeshSceneNode( helmetMesh );
		helmetNode->setParent(charHead);
		helmetNode->setPosition( -(charHead->getPosition())*7.75 + charPelvis->getPosition()/7.75 );
Where's Luke, by the way? :lol:
isnt it this problem?
Image
Image
timetokill
Posts: 74
Joined: Tue Jul 22, 2008 4:28 am
Location: Los Angeles

Post by timetokill »

B@z wrote:
timetokill wrote:Hi

Thank you for the suggestion, but it didn't quite work. I did try to manipulate the values as much as possible, and the following code puts the helmet near the appropriate position... though it doesn't follow the head exactly right when animating. The head still bobs around inside the helmet instead of the helmet being really attached to it.

Code: Select all

IAnimatedMesh* helmetMesh = gData->sm->getMesh("../media/meshes/anim/Chr_Player_helmet04.b3d");
		IAnimatedMeshSceneNode* helmetNode = gData->sm->addAnimatedMeshSceneNode( helmetMesh );
		helmetNode->setParent(charHead);
		helmetNode->setPosition( -(charHead->getPosition())*7.75 + charPelvis->getPosition()/7.75 );
Where's Luke, by the way? :lol:
isnt it this problem?

It's not, but that bit of code did help me out with an issue I ran into later!
kornwaretm
Competition winner
Posts: 189
Joined: Tue Oct 16, 2007 3:53 am
Location: Indonesia
Contact:

Post by kornwaretm »

timetokill wrote:.........
The issue that was happening for me is that the units I was using in Maya were in centimeters, and when it converted into Max it was being converted into inches. This works fine for the mesh, but the joints seem to get confused on some level. So what was happening to me was the joints were staying located in their "centimeter" position and weren't being scaled down.....
1. then scale the helmet if it just scaled up or :?:
2. try to rotate the helmet before before exporting. i mean:
we dont know the head bone orientation (it's relative coord),
but we can try by assuming z+/z- as the top of the bone?
or try assuming x+/x-, or y+/y- as the top of the bone?
so try to rotate the helmet in your editor using those 3
assumption, and re-export it. sorry i'm not a mathematician :wink:
Post Reply