A place to discuss everything related to Newton Dynamics.
Moderators: Sascha Willems, walaber
by 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.
-

Pyritie
-
- Posts: 36
- Joined: Tue Mar 02, 2010 8:13 pm
by 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

-
- Posts: 12452
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by 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))
-

Pyritie
-
- Posts: 36
- Joined: Tue Mar 02, 2010 8:13 pm
by 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

-
- Posts: 12452
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by 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)?
-

Pyritie
-
- Posts: 36
- Joined: Tue Mar 02, 2010 8:13 pm
by 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

-
- Posts: 12452
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by 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).
-

Pyritie
-
- Posts: 36
- Joined: Tue Mar 02, 2010 8:13 pm
by 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.
-

JernejL
-
- Posts: 1587
- Joined: Mon Dec 06, 2004 2:00 pm
- Location: Slovenia
-
by 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

-
- Posts: 12452
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by 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;
}
}
-

Pyritie
-
- Posts: 36
- Joined: Tue Mar 02, 2010 8:13 pm
by 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..
-

JernejL
-
- Posts: 1587
- Joined: Mon Dec 06, 2004 2:00 pm
- Location: Slovenia
-
by Pyritie » Wed Mar 03, 2010 2:16 pm
Would that be any better than using the force callback?
-

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 371 guests