Page 1 of 1

How do I pick different parts of a animated mesh?

Posted: Sun May 03, 2009 7:32 pm
by pir
I want to be able to pick different parts on an animated mesh. What is the easiest way to do this?

I tried to use the bounding boxes of the scene::IBoneSceneNode in combination with ISceneManager::getSceneNodeFromScreenCoordinatesBB to pick arms legs etc.

It seems like the bounding boxes are not updated when the mesh is loaded. They all have values like: xmin=-1, ymin=-1, zmin=-1, xmax=1, ymax=1,zmax=1. It is only the bounding box for the actual mesh that is updated during loading.

Is there something I need to do to update the bounding boxes of the bones?

please tell me if my question is unclear.

BR
pir

Posted: Sun May 03, 2009 8:18 pm
by Lonesome Ducky
Well, if the model is split by materials, you can try checking all the mesh buffers seperately.

Posted: Sun May 03, 2009 9:11 pm
by pir
No, it is only one big skinned mesh. For example, the dwarf model that is included in the Irrlicht examples.

I've found that it is possible to get the uppdated bounding boxes by using
irr::scene::IBoneSceneNodegetTransformedBoundingBox(). But I'm not sure that these are the bounding boxes that are used during the collision detection. Will check this tomorrow. But if anyone has any suggestions on how to solve my problem in a bettter way, please tell me.

Posted: Sun May 03, 2009 11:09 pm
by Lonesome Ducky
Oh, so are you trying to select the bones? If so, you can just cast a ray from the mouse and see if it hits the triangle selector of the object, if it does, find the closest bone to the collision point. Is that what you're looking for?

Posted: Wed May 06, 2009 7:02 pm
by pir
Yes, thats what I want to do. I was thinking about doing it the way you described, was just hoping that there were some easier way to do it with bounding boxes. But since I can't make it work, I'll guess I should give it a try.

thanks

Posted: Sun May 10, 2009 12:19 pm
by pir
Is there any functionality in Irrlicht that can help me finding the bone closest to my selected triangle?

Posted: Sun May 10, 2009 3:37 pm
by Lonesome Ducky
You can write your own. Just find the collision point and loop through all the bones, find the distance, and store the closest. If you need, I can right you some code.

Posted: Sun May 10, 2009 3:49 pm
by pir
thanks, but I did it myself.

BR
pir

Posted: Sun May 10, 2009 6:16 pm
by pir
Well, I thought that I had done it... but I have problems finding the correct bone. I think that it is caused by different transformation spaces... maybe. Thats only speculation. Here is my code for finding the closest bone:

Code: Select all

	scene::IAnimatedMesh* animMesh = m_mesh->getMesh( );
	assert( animMesh->getMeshType() == scene::EAMT_SKINNED);
	
	ISkinnedMesh* skinnedMesh = reinterpret_cast< ISkinnedMesh*>( animMesh);
	
	core::array< ISkinnedMesh::SJoint*>& allJoints = skinnedMesh->getAllJoints( );
	
	float           tmpDistance;
	float           minDistance;
	u32             minIndex;
	core::vector3df animatedPos;
	for( u32 j = 0; j < allJoints.size( ); j++)
	{
	    animatedPos = allJoints[ j]->Animatedposition;
	    tmpDistance = fabs( animatedPos.getDistanceFrom( tri.pointA));

	    if( ( tmpDistance < minDistance) || ( j == 0))
	    {
		minDistance = tmpDistance;
		minIndex    = j;
	    }
	    
	}// for j
The code is quick and dirty and only uses one point in the triangle.

I think that the triangle and the animated point from the current joint is in different transformation spaces, causing the false distances. But I'm not sure which transformation space to use, if this is the case.

Posted: Sun May 10, 2009 6:47 pm
by pir
Ok, I found the problem. I shouldn't use SJoint::Animatedpos. I should use the transfomration matrix from the SJoint instead.