Quick question on CustomJoints

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Quick question on CustomJoints

Postby Pyritie » Tue Mar 02, 2010 8:20 pm

Hi, I'm using MogreNewt (C# wrapper for ogrenewt) and I've been working on a custom joint that allows rotation on all three axes but only allows movement on the X and Z axes.

Here's what I've got so far:

Code: Select all
        public override void SubmitConstraint(float timeStep, int threadIndex) {
            Vector3 globalPos;
            Quaternion globalOrient;
            // get the global position and orientation
            // Not sure if we need the orientation but we need the position at least
            this.m_body0.GetPositionOrientation(out globalPos, out globalOrient);
            // Set the Y of the new position to 0
            // TODO: since we're only constraining it to Y, couldn't this just be 0?
            newGlobalPos = globalPos;
            newGlobalPos.y = 0f;
            // I wonder if there's a way to do this without needing the two rows. Oh well.
            // The first argument is the position we'd like to move, the second argument is where we'd like
            // to move it to, and the third argument says which vector we want to move it along
            addLinearRow(globalPos, newGlobalPos, Vector3.UNIT_Y);
            addLinearRow(globalPos, newGlobalPos, Vector3.NEGATIVE_UNIT_Y);
        }


(I'm pretty sure ogrenewt doesn't have the min/maxLinearLimit stuff so I have to use the rows)

It seems to work right but I'm not sure if what I'm doing is the best way.
User avatar
Pyritie
 
Posts: 36
Joined: Tue Mar 02, 2010 8:13 pm

Re: Quick question on CustomJoints

Postby Julio Jerez » Tue Mar 02, 2010 8:45 pm

you almost have it, just one listle mistake that can make it unstable, here is the correction
Code: Select all
public override void SubmitConstraint(float timeStep, int threadIndex)
{
   Vector3 globalPos;
   Quaternion globalOrient;
   // get the global position and orientation
   // Not sure if we need the orientation but we need the position at least
   this.m_body0.GetPositionOrientation(out globalPos, out globalOrient);
   // Set the Y of the new position to 0
   // TODO: since we're only constraining it to Y, couldn't this just be 0?

   /   newGlobalPos = globalPos;
   newGlobalPos.y = 0f;
   // I wonder if there's a way to do this without needing the two rows. Oh well.
   // The first argument is the position we'd like to move, the second argument is where we'd like
   // to move it to, and the third argument says which vector we want to move it along
   addLinearRow(globalPos, newGlobalPos, Vector3.UNIT_Y);
               
      // remove this line and it should be fine.
      //addLinearRow(globalPos, newGlobalPos, Vector3.NEGATIVE_UNIT_Y);
}
Julio Jerez
Moderator
Moderator
 
Posts: 12452
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Quick question on CustomJoints

Postby Pyritie » Tue Mar 02, 2010 10:01 pm

I tried doing that before but then it'd only stop it from moving along negative Y. It could still move along positive Y though.

(By the way, Vector3.UNIT_Y is (0, 1, 0) and Vector3.NEGATIVE_UNIT_Y is (0, -1, 0))
User avatar
Pyritie
 
Posts: 36
Joined: Tue Mar 02, 2010 8:13 pm

Re: Quick question on CustomJoints

Postby Julio Jerez » Tue Mar 02, 2010 10:36 pm

the direction cancel the accelration not the moment
try the way I tell you, it should work
Julio Jerez
Moderator
Moderator
 
Posts: 12452
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Quick question on CustomJoints

Postby Pyritie » Wed Mar 03, 2010 7:50 am

hm, that seems to be working now

It didn't before, weird :0

By the way is there an easy way to add a "maximum velocity" to a body (maybe using this joint since everything in my game will be using it)?
User avatar
Pyritie
 
Posts: 36
Joined: Tue Mar 02, 2010 8:13 pm

Re: Quick question on CustomJoints

Postby Julio Jerez » Wed Mar 03, 2010 9:26 am

Lot of things are possible with joints, I am guessing you mean some kind of a velocity depended constraint.

what do you mean maximum velocity? can you explain?
Julio Jerez
Moderator
Moderator
 
Posts: 12452
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Quick question on CustomJoints

Postby Pyritie » Wed Mar 03, 2010 11:43 am

Well for example I don't want the player to move faster than a certain velocity.

At the moment I am doing this:

Code: Select all
        private Vector3 velocityVec = new Vector3();
        /// <summary>
        /// Makes a body move! :D
        /// </summary>
        /// <param name="body">The body you want to move</param>
        /// <param name="vec">The vector you want to move it in</param>
        public void ApplyForce(Body body, Vector3 vec) {
            body.AddImpulse(vec, body.Position);

            // Temporary until I find a proper way to do this
            velocityVec = body.Velocity;
            if (velocityVec.x > Kernel.Get<Main>().Player.MaxMoveSpeed)
                velocityVec.x = Kernel.Get<Main>().Player.MaxMoveSpeed;
            if (velocityVec.x < -Kernel.Get<Main>().Player.MaxMoveSpeed)
                velocityVec.x = -Kernel.Get<Main>().Player.MaxMoveSpeed;
            if (velocityVec.z > Kernel.Get<Main>().Player.MaxMoveSpeed)
                velocityVec.z = Kernel.Get<Main>().Player.MaxMoveSpeed;
            if (velocityVec.z < -Kernel.Get<Main>().Player.MaxMoveSpeed)
                velocityVec.z = -Kernel.Get<Main>().Player.MaxMoveSpeed;
            body.Velocity = velocityVec;
        }


But that is kinda crude and only works for the player. If I wanted to do that for every body then I'd have to do this for each body every time its velocity increased somehow (through a collision or whatever).
User avatar
Pyritie
 
Posts: 36
Joined: Tue Mar 02, 2010 8:13 pm

Re: Quick question on CustomJoints

Postby JernejL » Wed Mar 03, 2010 11:46 am

Pyritie wrote:Well for example I don't want the player to move faster than a certain velocity.

At the moment I am doing this:

Code: Select all
        private Vector3 velocityVec = new Vector3();
        /// <summary>
        /// Makes a body move! :D
        /// </summary>
        /// <param name="body">The body you want to move</param>
        /// <param name="vec">The vector you want to move it in</param>
        public void ApplyForce(Body body, Vector3 vec) {
            body.AddImpulse(vec, body.Position);

            // Temporary until I find a proper way to do this
            velocityVec = body.Velocity;
            if (velocityVec.x > Kernel.Get<Main>().Player.MaxMoveSpeed)
                velocityVec.x = Kernel.Get<Main>().Player.MaxMoveSpeed;
            if (velocityVec.x < -Kernel.Get<Main>().Player.MaxMoveSpeed)
                velocityVec.x = -Kernel.Get<Main>().Player.MaxMoveSpeed;
            if (velocityVec.z > Kernel.Get<Main>().Player.MaxMoveSpeed)
                velocityVec.z = Kernel.Get<Main>().Player.MaxMoveSpeed;
            if (velocityVec.z < -Kernel.Get<Main>().Player.MaxMoveSpeed)
                velocityVec.z = -Kernel.Get<Main>().Player.MaxMoveSpeed;
            body.Velocity = velocityVec;
        }


But that is kinda crude and only works for the player. If I wanted to do that for every body then I'd have to do this for each body every time its velocity increased somehow (through a collision or whatever).


You could consider a object entity hiearichal call chain in ApplyForce which would do that properly and you'd only have to do it in the main class.
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1587
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: Quick question on CustomJoints

Postby Julio Jerez » Wed Mar 03, 2010 12:04 pm

You can do that in a much simpler and faster way, than using a joint.
In your force call back you can just add a velocity clip fintion like this
Code: Select all
ForceCallback (body)
{
    // apply you gravity and oteh force here
     ...
    ...


  // clip the velocity
  Vector  veloc
  NetwonGetVeloc (body, veloc)
  Float mags =    DotProduct (veloc, veloc)
  If (mags > (MaxVeloc * MaxVeloc)) {
    Vector dir = Normalize (v)
    Veloc = dir .Scale (MaxVeloc)
    NetwonSetVelocity (body, veloc);
  }
}
Julio Jerez
Moderator
Moderator
 
Posts: 12452
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Quick question on CustomJoints

Postby Pyritie » Wed Mar 03, 2010 1:27 pm

Delfi, I have no idea what you just said D:

Julio Jerez wrote:You can do that in a much simpler and faster way, than using a joint.
In your force call back you can just add a velocity clip fintion like this
Code: Select all
ForceCallback (body)
{
    // apply you gravity and oteh force here
     ...
    ...


  // clip the velocity
  Vector  veloc
  NetwonGetVeloc (body, veloc)
  Float mags =    DotProduct (veloc, veloc)
  If (mags > (MaxVeloc * MaxVeloc)) {
    Vector dir = Normalize (v)
    Veloc = dir .Scale (MaxVeloc)
    NetwonSetVelocity (body, veloc);
  }
}


Thanks, that seems to work. :D

Here's my code if anyone wants it:

Code: Select all
// This goes wherever
body.ForceCallback += new ForceCallbackHandler(LimitMaximumVelocity);

Code: Select all
static void LimitMaximumVelocity(Body body, float timeStep, int threadIndex) {
            Vector3 veloc = body.Velocity;
            float mags = veloc.DotProduct(veloc);
            if (mags > (Kernel.Get<Main>().Player.MaxMoveSpeed * Kernel.Get<Main>().Player.MaxMoveSpeed)) {
                veloc.Normalise();
                veloc *= Kernel.Get<Main>().Player.MaxMoveSpeed;
                body.Velocity = veloc;
            }
        }
User avatar
Pyritie
 
Posts: 36
Joined: Tue Mar 02, 2010 8:13 pm

Re: Quick question on CustomJoints

Postby JernejL » Wed Mar 03, 2010 1:55 pm

i have no idea how to express it in C++ sorry, but basically every child class of another would call parent object's submit forces aswell, that way the base gravity capable object would be shared amongst all your entities..
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1587
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: Quick question on CustomJoints

Postby Pyritie » Wed Mar 03, 2010 2:16 pm

Would that be any better than using the force callback?
User avatar
Pyritie
 
Posts: 36
Joined: Tue Mar 02, 2010 8:13 pm


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 43 guests