Game Development Community

ComputeBounds problem

by Duncan Gray · in Torque Game Engine · 04/20/2007 (9:39 pm) · 20 replies

Hello all

To help solve an issue in several resources, I'm trying to calculate the bounds of a player during preload time.

The player can assume various positions and each would ideally require a correctly sized bounds box. Yes I know you can manually change the mObjBox size etc but that's not what I want.

I thought I'd select the animation pose and calculate the bounds of the character in it's first frame.

I've done the following
// si = shapeInstance
si->setSequence(thread,dp->sequence,0);
si->animate(0);
//si->getShape()->computeBounds(0,ActionAnimationList[i].Bounds); //mshape version
 si->computeBounds(0,ActionAnimationList[i].Bounds); // mshapeInstance version

The mshape (commented out) version seems to give me the same sized box regardless of the the chosen animation sequence.

The mshapeInstance version at least varies slightly but not in relation to the chosen animation thread.

Any ideas why the method does not behave as expected?

#1
04/20/2007 (10:19 pm)
Have you tried it with different shape files of a measurably different size?
#2
04/20/2007 (10:36 pm)
I'm sure it would then give me a different sized bounds box.

The problem seems that the computeBounds method is not taking into account the affect of the node transforms on the mesh because the bounds box height is always calculated as 2.4 which is the height of the player mesh in its static pose, prior to animation.

I would expect/want the computeBounds to be based on where the verts are in the current pose.
#3
04/20/2007 (10:45 pm)
Here's a picture

www.ultrabizz.com/biz/boundsprob.jpg
#4
04/20/2007 (10:54 pm)
Did you use the old version of that resource www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=4348

or the newer 2005 that "removes the rather hacky, hard-coded crouch/prone bounding box sizes" as it states
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=8593

Edit: sorry i just re-read your post n saw that you stated you know abotu manually setting and dotn want to do that, sorry I dont think I have an answer for you
#5
04/20/2007 (11:46 pm)
Hm, i'm pretty unfamiliar with this stuff, but i think you can get the position of various nodes in the skeleton,
and perhaps from them compute a bounding box ?

for example there's a method to get the eye transform, presuming the skeleton is set up correctly.

so perhaps you could make identifiable nodes for other extremities: feet, knees, hands, elbows, head, ass.
it seems if you had those points it should be possible to compute a minimal bounding box for not only any animation but any frame in any animation.

definitely a chunk of work, but it seems doable.

one simplification would be to calculate a "minimal" bounding box only in the player-space.
ie, a box who's axes are aligned to the player's local XYZ. this won't be the minimal box in world-space,
but it might be a simple start.
#6
04/21/2007 (12:27 am)
@Orion. It seems the easiest place to do that would be in the ::animate() method where the code runs through all the nodes anyway. You would then just need to record the max and min values and then you have a nodes bounds box which you then pad to get an acceptable dynamic mesh bounds box.

That should work, I was just hoping to get access to the verts as being more accurate. The TSanimate.cc code just manupulates all the nodes. I can't see where exactly those node transforms get applied to the vertices, if I could, then I could just insert some code at that point to record the min and max vertex extremities yielding a much more accurate dynamic bounds box.

I've followed the code in the animate() section and then in the render() section,
The animate section manipulates the nodes and then the render section uses the verts[] array to render from.

Where did the node changes get applied to the verts[] array? I don't see it so far.
#7
04/21/2007 (12:38 am)
Quote:Where did the node changes get applied to the verts[] array?

TSSkinMesh::updateSkin(), about line 2040 in tsMesh.cc.
#8
04/21/2007 (12:57 am)
Thanks Alex, that looks like the data I was missing.
#9
04/21/2007 (1:51 am)
Success !!, fully automatic bounds box. I'll post the full resource a bit later.

www.ultrabizz.com/biz/boundsfix.jpg
Its also a solution to this thread
#10
04/21/2007 (2:05 am)
Although I'm still concerned about the prone position being able to crawl through a narrow doorway.

The bounds box, being used as the collision box dimensions in the player class, will still be a problem in that pose. The hacky method would be to orient the player so that he squints down the rifle barrel straight-on like a noob soldier - not a nice solution.

The bounds box calculation should figure out the where the head and feet nodes are and then base the vertex positions as offsets from that.

It's probably easier to add a special 'ground' node to the player and use that to position and orient the bottom-middle of the bounds box.

later...
#11
04/21/2007 (7:23 am)
Very nice, Duncan !
#12
04/21/2007 (10:50 pm)
I need input from one of the matrix experts.

To cater for the situation where the player pose is not directly facing the forward direction, I added a ground node to the shape and orientated it in the direction I want the bounds box to be calculated along. i.e, along the player axis, not the eye vector.

It appears to calculate the size correctly, compared to the earlier prone position, but it now places the box incorrectly per the player position. I suspect I need to use another matrix to position the box correctly around the player. What logic am I missing here?

www.ultrabizz.com/biz/boundsprob2.jpg
void TSShapeInstance::computeBounds( Box3F & bounds)
{
	S32 dl=0;
   
   // get subshape and object detail
   const TSDetail * detail = &mShape->details[dl];
   S32 ss = detail->subShapeNum;
   S32 od = detail->objectDetailNum;

   // set up static data
   setStatics(dl);

   S32 start = mShape->subShapeFirstObject[ss];
   S32 end   = mShape->subShapeNumObjects[ss] + start;

   // run through objects and updating bounds as we go
   bounds.min.set( 10E30f, 10E30f, 10E30f);
   bounds.max.set(-10E30f,-10E30f,-10E30f);
   Box3F box;
   for (S32 i=start; i<end; i++)
   {
	   MeshObjectInstance * mesh = &mMeshObjects[i];
	   if (od >= mesh->object->numMeshes)
		   continue;  

	   if (mesh->getMesh(od))
	   {
		   if (mesh->getMesh(od)->getMeshType()==TSMesh::SkinMeshType)
		   {
			   TSMesh *m = mesh->getMesh(od);
			   TSSkinMesh * skin = (TSSkinMesh*)m;
			   skin->updateSkin(); // this will move the vertices into the currecnt pose

			   MatrixF useTransform;	  
			   S32 groundNode = getShape()->findNode("Ground");
			   if(groundNode > 0)				  
				   useTransform.mul(*mesh->getTransform(), mNodeTransforms[groundNode]);
			   else
				   useTransform = *mesh->getTransform(); 
			   Point3F p;
			   for (S32 vert=0; vert< m->vertsPerFrame; vert++)
			   {
				   useTransform.mulP(m->verts.address()[vert],&p);
				   bounds.max.setMax(p);
				   bounds.min.setMin(p);
			   }
		   }
		   else
			   mesh->getMesh(od)->computeBounds(*mesh->getTransform(),box);
                           // to-do, do a setmax and min with box against bounds
	   }
   }
   clearStatics();
}
#13
04/22/2007 (3:15 pm)
Hi duncan -

yes, looks to me like it's computing a correct bounding box for the player's "ground" transform,
but then treating the box as tho it's aligned to good old eye transform.

it seems like you'll need to remove TGE's assumption that the player bounding box is not necessarily aligned to the player's local coordinate system. - this seems like a hefty bit of work, to me, altho i'm certainly often wrong.

it seems like you might be able to avoid a lot of engineering if you could come up with an art solution such as keeping the player mostly facing forward in its own reference frame.


hm actually i think i'd investigate transforming the player's BB. i assume there's a function somewhere like "getBoundingBox" for ShapeBase, and if it's the only point of access it might be fairly simple to insert a matrix transform in there. - one thing which strikes me as odd about your code above is that there's potentially a different Ground Transform for each mesh in the object. - You maybe only have one mesh, but it still seems odd. anyhow, i imagine the transform you want to apply to the BB is something like useTransform or its inverse.
#14
04/22/2007 (5:47 pm)
I suspect its something simple. I mean the size of the box is now correct, it just needs a translate and rotate to the correct position.
#15
04/24/2007 (10:23 pm)
Resource here
#16
04/25/2007 (4:38 am)
Nice... thanks a lot Duncan! great work!
#17
04/25/2007 (6:50 am)
Thanks! I will try it out.
#18
02/21/2008 (9:18 am)
This code seems broken for TGE 1.52 and TGEA currently. Just wondering if anyone got this working?
#19
03/18/2008 (4:34 am)
Yes. It seems that the codes cause program crashed for TGE152.
#20
03/19/2008 (7:05 pm)
Very strange, it seems that mObjBox size doesn't work for my program(TGE152). I mean, when the player has been scaled larger, it will be out of the box (which is bounded with red and yellow lines like above) and still embedded into the ground. Even when I manully change the size of mObjBox to make box fit for the player, it doesn't work because the box will embedded into the ground too.

What may be wrong with me? Can the box be embedded into the ground? Which variable or member may decide the player height position after it has been scaled?