[fixed]correct BoundingBox for SkinnedMesh

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
tprochownik
Posts: 7
Joined: Wed Sep 10, 2008 10:19 am

[fixed]correct BoundingBox for SkinnedMesh

Post by tprochownik »

Hi,

problem was in incorret calculatiing boundingbox. I think I solved this problem, in CSkinnedMesh.cpp:

Code: Select all

void CSkinnedMesh::finalize()
{
	u32 i;

	LastAnimatedFrame=-1;
	LastSkinnedFrame=-1;

	//calculate bounding box

	for (i=0; i<LocalBuffers.size(); ++i)
	{
		LocalBuffers[i]->recalculateBoundingBox();
	}

	if (AllJoints.size() || RootJoints.size())
	{
		// populate AllJoints or RootJoints, depending on which is empty
		if (!RootJoints.size())
		{

			for(u32 CheckingIdx=0; CheckingIdx < AllJoints.size(); ++CheckingIdx)
			{

				bool foundParent=false;
				for(i=0; i < AllJoints.size(); ++i)
				{
					for(u32 n=0; n < AllJoints[i]->Children.size(); ++n)
					{
						if (AllJoints[i]->Children[n] == AllJoints[CheckingIdx])
							foundParent=true;
					}
				}

				if (!foundParent)
					RootJoints.push_back(AllJoints[CheckingIdx]);
			}
		}
		else
		{
			AllJoints=RootJoints;
		}
	}

	for(i=0; i < AllJoints.size(); ++i)
	{
		AllJoints[i]->UseAnimationFrom=AllJoints[i];
	}

	//Set array sizes...

	for (i=0; i<LocalBuffers.size(); ++i)
	{
		Vertices_Moved.push_back( core::array<bool>() );
		Vertices_Moved[i].set_used(LocalBuffers[i]->getVertexCount());
	}

	//Todo: optimise keys here...

	checkForAnimation();

	if (HasAnimation)
	{
		//--- optimize and check keyframes ---
		for(i=0;i<AllJoints.size();++i)
		{
			core::array<SPositionKey> &PositionKeys =AllJoints[i]->PositionKeys;
			core::array<SScaleKey> &ScaleKeys = AllJoints[i]->ScaleKeys;
			core::array<SRotationKey> &RotationKeys = AllJoints[i]->RotationKeys;

			if (PositionKeys.size()>2)
			{
				for(u32 j=0;j<PositionKeys.size()-2;++j)
				{
					if (PositionKeys[j].position == PositionKeys[j+1].position && PositionKeys[j+1].position == PositionKeys[j+2].position)
					{
						PositionKeys.erase(j+1); //the middle key is unneeded
						--j;
					}
				}
			}

			if (PositionKeys.size()>1)
			{
				for(u32 j=0;j<PositionKeys.size()-1;++j)
				{
					if (PositionKeys[j].frame >= PositionKeys[j+1].frame) //bad frame, unneed and may cause problems
					{
						PositionKeys.erase(j+1);
						--j;
					}
				}
			}

			if (ScaleKeys.size()>2)
			{
				for(u32 j=0;j<ScaleKeys.size()-2;++j)
				{
					if (ScaleKeys[j].scale == ScaleKeys[j+1].scale && ScaleKeys[j+1].scale == ScaleKeys[j+2].scale)
					{
						ScaleKeys.erase(j+1); //the middle key is unneeded
						--j;
					}
				}
			}

			if (ScaleKeys.size()>1)
			{
				for(u32 j=0;j<ScaleKeys.size()-1;++j)
				{
					if (ScaleKeys[j].frame >= ScaleKeys[j+1].frame) //bad frame, unneed and may cause problems
					{
						ScaleKeys.erase(j+1);
						--j;
					}
				}
			}

			if (RotationKeys.size()>2)
			{
				for(u32 j=0;j<RotationKeys.size()-2;++j)
				{
					if (RotationKeys[j].rotation == RotationKeys[j+1].rotation && RotationKeys[j+1].rotation == RotationKeys[j+2].rotation)
					{
						RotationKeys.erase(j+1); //the middle key is unneeded
						--j;
					}
				}
			}

			if (RotationKeys.size()>1)
			{
				for(u32 j=0;j<RotationKeys.size()-1;++j)
				{
					if (RotationKeys[j].frame >= RotationKeys[j+1].frame) //bad frame, unneed and may cause problems
					{
						RotationKeys.erase(j+1);
						--j;
					}
				}
			}


			//Fill empty keyframe areas
			if (PositionKeys.size())
			{
				SPositionKey *Key;
				Key=&PositionKeys[0];//getFirst
				if (Key->frame!=0)
				{
					PositionKeys.push_front(*Key);
					Key=&PositionKeys[0];//getFirst
					Key->frame=0;
				}

				Key=&PositionKeys.getLast();
				if (Key->frame!=AnimationFrames)
				{
					PositionKeys.push_back(*Key);
					Key=&PositionKeys.getLast();
					Key->frame=AnimationFrames;
				}
			}

			if (ScaleKeys.size())
			{
				SScaleKey *Key;
				Key=&ScaleKeys[0];//getFirst
				if (Key->frame!=0)
				{
					ScaleKeys.push_front(*Key);
					Key=&ScaleKeys[0];//getFirst
					Key->frame=0;
				}

				Key=&ScaleKeys.getLast();
				if (Key->frame!=AnimationFrames)
				{
					ScaleKeys.push_back(*Key);
					Key=&ScaleKeys.getLast();
					Key->frame=AnimationFrames;
				}
			}

			if (RotationKeys.size())
			{
				SRotationKey *Key;
				Key=&RotationKeys[0];//getFirst
				if (Key->frame!=0)
				{
					RotationKeys.push_front(*Key);
					Key=&RotationKeys[0];//getFirst
					Key->frame=0;
				}

				Key=&RotationKeys.getLast();
				if (Key->frame!=AnimationFrames)
				{
					RotationKeys.push_back(*Key);
					Key=&RotationKeys.getLast();
					Key->frame=AnimationFrames;
				}
			}
		}
	}

	//Needed for animation and skinning...

	CalculateGlobalMatrices(0,0);

	//animateMesh(0, 1);
	//buildAll_LocalAnimatedMatrices();
	//buildAll_GlobalAnimatedMatrices();

	//rigid animation for non animated meshes
	for (i=0; i<AllJoints.size(); ++i)
	{
		for (u32 j=0; j<AllJoints[i]->AttachedMeshes.size(); ++j)
		{
			SSkinMeshBuffer* Buffer=(*SkinningBuffers)[ AllJoints[i]->AttachedMeshes[j] ];
			Buffer->Transformation=AllJoints[i]->GlobalAnimatedMatrix;
		}
	}


		// Get BoundingBox...
	if (LocalBuffers.empty())
		BoundingBox.reset(0,0,0);
	else
	{
		irr::core::aabbox3df bb(LocalBuffers[0]->BoundingBox);
		LocalBuffers[0]->Transformation.transformBoxEx(bb);
		BoundingBox.reset(bb);

		for (u32 j=1; j<LocalBuffers.size(); ++j)
		{
			bb = LocalBuffers[j]->BoundingBox;
			LocalBuffers[j]->Transformation.transformBoxEx(bb);

			BoundingBox.addInternalBox(bb);
		}
	}

	//add 5% padding to bounding box
	core::vector3df Padding=BoundingBox.getExtent()*0.05f;
	BoundingBox.MinEdge-=Padding;
	BoundingBox.MaxEdge+=Padding;
}
diffrient is location of this code and transforming local boundingbox. can be it commit on svn?

Code: Select all

		// Get BoundingBox...
	if (LocalBuffers.empty())
		BoundingBox.reset(0,0,0);
	else
	{
		irr::core::aabbox3df bb(LocalBuffers[0]->BoundingBox);
		LocalBuffers[0]->Transformation.transformBoxEx(bb);
		BoundingBox.reset(bb);

		for (u32 j=1; j<LocalBuffers.size(); ++j)
		{
			bb = LocalBuffers[j]->BoundingBox;
			LocalBuffers[j]->Transformation.transformBoxEx(bb);

			BoundingBox.addInternalBox(bb);
		}
	}
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Yes, looks reasonable.
tprochownik
Posts: 7
Joined: Wed Sep 10, 2008 10:19 am

Post by tprochownik »

hybrid wrote:Yes, looks reasonable.
I saw, you commit to svn, but this is not resolving problem, You only moved code to another place, but solution is LocalBuffers[0]->Transformation.transformBoxEx for each boundingbox......

Code: Select all

     // Get BoundingBox... 
   if (LocalBuffers.empty()) 
      BoundingBox.reset(0,0,0); 
   else 
   { 
      irr::core::aabbox3df bb(LocalBuffers[0]->BoundingBox); 
      LocalBuffers[0]->Transformation.transformBoxEx(bb); 
      BoundingBox.reset(bb); 

      for (u32 j=1; j<LocalBuffers.size(); ++j) 
      { 
         bb = LocalBuffers[j]->BoundingBox; 
         LocalBuffers[j]->Transformation.transformBoxEx(bb); 

         BoundingBox.addInternalBox(bb); 
      } 
   } 
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

In that case you should start using a proper patch tool, or comment your changes exactly. Please also post a bug tracker ticket at the SF trackers next time:
https://sourceforge.net/tracker/?group_id=74339
Oh, and please also don't put [fixed] to your message, that's what added once we've fixed the issue in the library.
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

And a simple standalone test case is always nice.

THAT SAID: thanks for posting this, it does look like it should address the BB problem. Although a test case would help to demonstrate that. ;)
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
tprochownik
Posts: 7
Joined: Wed Sep 10, 2008 10:19 am

Post by tprochownik »

Ok, next time I do that, but is possible to do commit with this boundingbox patch?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Well, this makes the code a little more involved, so I have to check the things more thoroughly. But yes, probably it's possible sometime later.

Hmm, I just tested latest SVN trunk and found that there is no bounding box at all anymore. At least nothing's displayed in the meshviewer. Did anyone else also have this problem, and are there any assumptions when or why this changed (broke)?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Ok, the missing bboxes are fixed - the methods are currently dawing with alpha 0, which seems to lead to completely transparent lines in the used render state. Fixed it to alpha 255 for now, I'll check the render states later (was OpenGL, FYI).
I didn't see any problems with the transformed boxes, so far, but I also didn't find any meshes which work better. Do you have a simple example?
tprochownik
Posts: 7
Joined: Wed Sep 10, 2008 10:19 am

Post by tprochownik »

yes, a have a example, not only for this mesh
http://biostorm.eu/editor.zip or http://annis.ovh.org/editor.zip

when You click on the (unfortunately around) object it sets m_Node->setDebugDataVisible(EDS_BBOX_ALL);

EDS_BBOX_BUFFERS are correctly, but EDS_BBOX not. if You need source code of this editor I can sent You too....
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Ok, that does convince me :D already commited as rev 1611.
Luke
Admin
Posts: 449
Joined: Fri Jul 14, 2006 7:55 am
Location: Australia
Contact:

Post by Luke »

missed this, thanks for the fix.

only a few x meshes are using meshbuffer transformation, but still very good to fix. I won't go into the other problems with meshbuffer transformation here, but would like to remove or fix this.
[url=irc://irc.freenode.net/irrlicht]irrlicht irc[/url] - corrodinggames.com
Post Reply