Page 1 of 1

[Half-solved] Joints placed incorrectly

Posted: Wed Apr 29, 2009 11:10 pm
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?

Posted: Thu Apr 30, 2009 7:48 am
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?

Posted: Thu Apr 30, 2009 8:49 pm
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));
	}

Posted: Fri May 01, 2009 12:01 pm
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.

Posted: Fri May 01, 2009 3:11 pm
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.

Posted: Fri May 01, 2009 11:04 pm
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:

Posted: Sat May 02, 2009 4:44 am
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:

Posted: Sat May 02, 2009 5:40 am
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.

Posted: Sun May 03, 2009 4:44 am
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.

Posted: Sun May 03, 2009 10:28 am
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?

Posted: Tue May 05, 2009 11:50 am
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!

Posted: Wed May 06, 2009 7:03 am
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: