dudeabot
15-01-2008 17:32:18
hi im trying to do a "explosion"
the method im using is to create a spherical body in the place, and this body has a callback, activated between a contact of explosion and enemy
so in the callback i put(i dont have the code here, but you get the idea

)
OgreNewt::Body* enemy;
if (mbody0->getType()==BT_ENEMY)
enemy=mbody0;
else if (mbody1->getType()==BT_ENEMY)
enemy=mbody1;
Ogre::Real impulse=10;
enemy->addImpulse(direction*impulse,BodyUtil::get_body_position(enemy));
is this the right approach?
also how do you calculate the explosion direction?
walaber
15-01-2008 19:44:06
that sounds about right. to get started, the explosion direction would be normalise( bodypos - explosion_sphere_center );
dudeabot
16-01-2008 05:49:22
cool it works great thanks
just one question, it seems only to affect non auto freeze bodies,
would it be cpu expensive if i have many bodies?(if so is there a workaround?)
i tried calling unfreeze on the callback, but the callback isnt even called
i also thought calling unfreeze right before explosion, but there is the possibility the body gets frozen again in the meantime
walaber
16-01-2008 07:50:47
which callback is not called?
dudeabot
16-01-2008 18:11:06
explosionEnemy, if the enemy and the sphere representing the explosion are stopped, which is the common case.
walaber
17-01-2008 01:52:57
no, I mean... are you talking about the ForceAndTorque callback, or the ContactCallback, or what?
dudeabot
17-01-2008 02:11:07
contactcallback
to be more specific i made two materials, one for the enemy and the other for the explosion (actually a shperical body)
and setup a contact callback between them
the problem is -unless the enemy is set to autoFrozen(0)- when i place the sphere in the same place as the enemy (overlapping him) then contact is not ativate.. its only activated if i push him against the sphere, or move the sphere
make sense, since the both bodies are stopped,
so the solution would be, every body that is responsive to a explosion, always be active -autoFreeze(0)- but that would be a little overkill?
nullsquared
17-01-2008 02:50:50
contactcallback
to be more specific i made two materials, one for the enemy and the other for the explosion (actually a shperical body)
and setup a contact callback between them
the problem is -unless the enemy is set to autoFrozen(0)- when i place the sphere in the same place as the enemy (overlapping him) then contact is not ativate.. its only activated if i push him against the sphere, or move the sphere
make sense, since the both bodies are stopped,
so the solution would be, every body that is responsive to a explosion, always be active -autoFreeze(0)- but that would be a little overkill?
Wake all of the bodies within the exposion's radius with an axis aligned bounding box.
NewtonWorldForEachBodyInAABBDo(...)
Look it up here:
http://www.runehunter.phpnet.us/NewtonHelp.html
Just set up an Ogre::AxisAlignedBox and feed min/max to newton. Not sure if this is already integrated into OgreNewt.
Note that Newton's unfreeze function didn't always work for me. To unfreeze a body I had to apply a moderate impulse to it (says impulses wake the body). Which you can even further optimize, and instead of waking each body in the explosions radius with an impulse and then applying an impulse for the explosion, just apply the explosion's impulse, to begin with - it'll both wake and move the bodies.
dudeabot
17-01-2008 15:02:03
very nice documentation there
im not sure if ogewnewt has it also, so im trying to build a little wrapper for that function
thanks!
edit-
OgreNewt::Collision* explCol = new OgreNewt::CollisionPrimitives::Ellipsoid( mWorld, Vector3(10,10,10) ); // create a collision for the body
OgreNewt::Body* explBody= new OgreNewt::Body( mWorld, explCol ); // create the body
NewtonWorldForEachBodyInAABBDo(
mWorld->getNewtonWorld(),
&explCol->getAABB().getMinimum().x,
&explCol->getAABB().getMaximum().x,
&Level1::explCallback);
static void _cdecl explCallback(const NewtonBody* body){
OgreNewt::Body* me;
me = (OgreNewt::Body*) NewtonBodyGetUserData( body );
}
if anyone is interested
walaber
17-01-2008 16:27:28
I believe the BodyIterator class has that functionality built in... but if not I'll make sure to add it with the next update.
nullsquared
17-01-2008 23:33:47
very nice documentation there 
im not sure if ogewnewt has it also, so im trying to build a little wrapper for that function
thanks!
edit-
OgreNewt::Collision* explCol = new OgreNewt::CollisionPrimitives::Ellipsoid( mWorld, Vector3(10,10,10) ); // create a collision for the body
OgreNewt::Body* explBody= new OgreNewt::Body( mWorld, explCol ); // create the body
NewtonWorldForEachBodyInAABBDo(
mWorld->getNewtonWorld(),
&explCol->getAABB().getMinimum().x,
&explCol->getAABB().getMaximum().x,
&Level1::explCallback);
static void _cdecl explCallback(const NewtonBody* body){
OgreNewt::Body* me;
me = (OgreNewt::Body*) NewtonBodyGetUserData( body );
}
if anyone is interested
You seem to have a small error. I presume your explosions seem to currently only work at [0,0,0]? explCol's AABB is probably in local space (unless it takes the parenting body's position into consideration, but I doubt it since collisions should be reusable with multiple bodies). You'll need to move it somewhere (transform the AABB first) if you want explosions that occur at arbitrary points, rather than just at the origin.
dudeabot
17-01-2008 23:49:27
humm, i dont think ill need the body anymore, as it was a sphere and the AABB is the bounding box, ill just take the grenade scene node as reference and apply the explosion radius
nullsquared
18-01-2008 00:51:28
humm, i dont think ill need the body anymore, as it was a sphere and the AABB is the bounding box, ill just take the grenade scene node as reference and apply the explosion radius
That's what I'm saying. You'll need to take some "position" into account. Just taking the bounding box and not transforming it means that it is always at [0,0,0] (since it's just the collision's AABB, and collisions don't have a position), which is probably not what you want.