Object gets catapulted away after colliding

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Object gets catapulted away after colliding

Postby DrGonzo » Wed May 20, 2009 7:41 am

Hi,

We're using Newton in conjunction with Ogre and OgreNewt, and it works great so far.

The only weird thing that is happening, is that sometimes, when our avatar collides with a static object, it gets catapulted away at an enormous high speed (in the opposite direction). But the catapult movement is not linear, it speeds up.

Does this have something to do with collisions in general, or perhaps with different behaviours with different materials?

Or is it just 'undefined behaviour'?
DrGonzo
 
Posts: 1
Joined: Wed May 20, 2009 7:12 am

Re: Object gets catapulted away after colliding

Postby JernejL » Wed May 20, 2009 8:23 am

There should be no undefined behavior in newton, can you create a demo to reproduce this? a video would be also useful.

I would suggest during testing that you make absolutely sure that your game is not applying the force, it should not happen in newton that velocity of a object would speed up with time if your game is not maintaining or adding force to speed it up.
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1578
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: Object gets catapulted away after colliding

Postby djbe » Wed May 20, 2009 11:39 am

Works now. I think it was my forceCallback function (for avatar control). Added some checks to see if the speed is too high. If so, don't apply any forces (except gravity ofcourse). If you're interested (or have any tips), here's the function:
Code: Select all
///
/// Force callback
///
void Avatar::forceCallback(OgreNewt::Body *me, float timestep, int threadindex) {
   Avatar *av = dynamic_cast<Avatar*>(Ogre::any_cast<Object*>(me->getUserData()));
   Ogre::Vector3 force = Ogre::Vector3::ZERO;
   Ogre::Vector3 vel = me->getVelocity();
   vel.y = 0; // we don't care about vertical speed
      
   // Always apply gravity
   force = Ogre::Vector3(0, -9.81, 0);
   
   // Cap speed (could happen sometimes)
   if (vel.length() > m_MaxRunSpeed * 2)
      me->setVelocity(vel * (m_MaxRunSpeed * 2) / vel.length());
   
   // Calculate movement force (for avatar control)
   else if (av->m_direction != eDirNone && vel.length() < m_MaxRunSpeed) {
      Ogre::Vector3 dir = Ogre::Vector3::ZERO;
      float tempX = 0.0, tempZ = 0.0;
      
      // depending on our current speed, walk or run
      // if we've been walking for 1s, we can start running
      if (vel.length() > m_MinRunSpeed || vel.length() > m_MinRunSpeed - 0.5 && m_timeWalking > 1.0) {
         tempX = (m_MaxRunSpeed - std::fabs(vel.x)) / timestep;
         tempZ = (m_MaxRunSpeed - std::fabs(vel.z)) / timestep;
      } else {
         tempX = (m_MinRunSpeed - std::fabs(vel.x)) / timestep;
         tempZ = (m_MinRunSpeed - std::fabs(vel.z)) / timestep;
         
         m_timeWalking += timestep;
      }
      
      // if we are jumping, reduce movement
      if (m_jumping) {
         tempX /= 10;
         tempZ /= 10;
      }
      
      // add direction forces
      if (av->m_direction & eLeft)
         force += tempX * Ogre::Vector3::NEGATIVE_UNIT_X;
      if (av->m_direction & eRight)
         force += tempX * Ogre::Vector3::UNIT_X;
      if (av->m_direction & eBackward)
         force += tempZ * Ogre::Vector3::NEGATIVE_UNIT_Z;
      if (av->m_direction & eForward)
         force += tempZ * Ogre::Vector3::UNIT_Z;
   } else
      m_timeWalking = 0.0;
   
   // Apply our calculated force
   me->addForce(force * av->m_mass);
   
   // Calculate our target orientation, and the difference with our current one
   Ogre::Degree current = calcCurrentAngle();
   Ogre::Degree target(90);
   if (vel.length() > m_MinWalkSpeed * 2 && std::fabs(vel.x) > std::fabs(vel.z))
      target += Ogre::Degree((vel.x < 0) ? -90 : 90);
   float diff = fabs((target - current).valueDegrees());
   
   // Rotate accordingly
   if (diff < m_MaxTurnError)
      me->setOmega(Ogre::Vector3::ZERO);
   else if (me->getOmega().y < m_MaxTurnSpeed) {
      diff /= m_MaxTurnSpeed;
      me->addLocalForce(Ogre::Vector3(0, 0, (current < target) ? -diff : diff) * av->m_mass, Ogre::Vector3(5, 0, 0));
      me->addLocalForce(Ogre::Vector3(0, 0, (current < target) ? diff : -diff) * av->m_mass, Ogre::Vector3(-5, 0, 0));
   }
}
djbe
 
Posts: 3
Joined: Mon Feb 16, 2009 11:20 am

Re: Object gets catapulted away after colliding

Postby JernejL » Wed May 20, 2009 12:37 pm

But that's a workaround, or did you figure out what actually produced the catapult forces?
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1578
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: Object gets catapulted away after colliding

Postby djbe » Wed May 20, 2009 4:51 pm

Nope I didn't, and honestly don't have the time right now... The deadline is next week monday, and if this (dirty) hack fixes it, then I'm happy. Oh by the way, it could as well be ogrenewt and not newton, who knows.

Edit:
What I think was the error is the following case: normally I only had this test
Code: Select all
// Calculate movement force (for avatar control)
   if (av->m_direction != eDirNone) {
so that I only add forces when the user is pressing a button to move in a certain direction.
What somehow happend (I think) is that the tempX/Z calculation bit went wrong making the function apply enormous forces on the avatar at each timestep, resulting in very high (go through walls) speeds :P

The bit that fixed it is changing the if test to this:
Code: Select all
   // Calculate movement force (for avatar control)
   if (av->m_direction != eDirNone && vel.length() < m_MaxRunSpeed) {
With this new test, I don't add new movement forces when the avatar reaches it's max speed.
Now for security reasons (as in: I don't want this happening during demos), I added a test before that that checks the speed to twice the max speed. If it's above that, cap it.
djbe
 
Posts: 3
Joined: Mon Feb 16, 2009 11:20 am


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 31 guests