Velocity

Report any bugs here and we'll post fixes

Moderators: Sascha Willems, Thomas

Velocity

Postby Carli » Mon Aug 16, 2010 11:23 am

Hi,

The value, I get with NewtonBodyGetVelocity grows when rolling on the ground.
I want to detect if a Body hits an other with a high speed or if it rolls.
So I calculate the hitspeed with this code:
Code: Select all
 NewtonBodyGetVelocity(body0, ap);
 NewtonBodyGetVelocity(body1, bp);
 ap:=ap - bp;
 par.float:=sqrt(ap * ap); // calculate speed


How do I test if a body really "hits" or if it just "contacts" the body?
Carli
 
Posts: 245
Joined: Fri Oct 02, 2009 5:28 am

Re: Velocity

Postby Julio Jerez » Mon Aug 16, 2010 12:43 pm

you can detect if a body hit anything by using teh joint interartion and teh contatct iterator opn a body.
you can get all teh information form all the contacts:

if teh contact wa simpulsive it iwll have a nozeor speed,
if the contat is restion it ill hav a force value and amost zero speed.
you cvna get normal and tangent
here is code from the SDK.

Code: Select all
void CheckIfBodiesCollide (NewtonBody* body)
{
       for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint (body); joint; joint = NewtonBodyGetNextContactJoint (body, joint)) {
          for (void* contact = NewtonContactJointGetFirstContact (joint); contact; contact = NewtonContactJointGetNextContact (joint, contact)) {
             dFloat speed;
             //dVector point;
             //dVector normal;   
             //dVector dir0;   
             //dVector dir1;   
             //dVector force;
             NewtonMaterial* material;
             material = NewtonContactGetMaterial (contact);

             // you can get all the information you want
             NewtonMaterialGetContactForce (material, &force.m_x);
             NewtonMaterialGetContactPositionAndNormal (material, &point.m_x, &normal.m_x);
             NewtonMaterialGetContactTangentDirections (material, &dir0.m_x, &dir1.m_x);
             speed = NewtonMaterialGetContactNormalSpeed(material);
          }
      }
}
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Velocity

Postby Carli » Mon Aug 16, 2010 6:17 pm

This does not give me my wished result.

I set a callback with
Code: Select all
 NewtonMaterialSetCollisionCallback(result, 0, 0, nil, nil, @xcollide);


My proxy for the collision call
Code: Select all
function xcollide( const contact : PNewtonJoint; timestep : Float; threadIndex : int ): integer; cdecl;
begin
 result:=collide(NewtonContactGetMaterial (contact), NewtonJointGetBody0(contact), NewtonJointGetBody1(contact), threadIndex);
end;           



The part of the code that generates unwished results (returns 0 on every collision)
Code: Select all
function collide( const material : PNewtonMaterial; const body0 : PNewtonBody; const body1 : PNewtonBody; threadIndex : int ) : int; cdecl;
var a, b: TObject;
    par: TData;
begin
 par.reftype:=0;
 par.float:=NewtonMaterialGetContactNormalSpeed(material);
 if par.float>0.01 then writeln(par.float:4:2);

 result:=1;
 a:=TObject(NewtonBodyGetUserData(body1));
 b:=TObject(NewtonBodyGetUserData(body0));
 CollideBody(a,b,par);
end;                 
Carli
 
Posts: 245
Joined: Fri Oct 02, 2009 5:28 am

Re: Velocity

Postby Julio Jerez » Mon Aug 16, 2010 6:37 pm

That is the function the engine used to read the force and or velocity at a contact point.

what result it is giniong you? and what do you expect it to be?
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Velocity

Postby ledahut » Tue Aug 17, 2010 3:06 am

I had some strange behaviors with this callback before with Delphi.
First when we look the wiki about NewtonMaterialSetCollisionCallback:
"NewtonOnAABBOverlap aabbOverlap - address of the event function called before contact calculation for collision. This parameter can be NULL. "
And when we go to NewtonOnAABBOverlap wiki, we read "return 1 to keep processing this material body pair for collisions or return 0 to reject it. "

When I put 'nil' parameter like you, the application never call NewtonContactsProcess [xcollide for you].
So I always use NewtonOnAABBOverlap with

Code: Select all
function NewtonOnAABBOverlap(const material: PNewtonMaterial;
  const body0: PNewtonBody; const body1: PNewtonBody;
  threadIndex: Integer): Integer;
begin
  Result := 1 // Boolean, if 1, continue, if 0, the two body won't collide and will go trough each other.
end;


Secondly when we look the NewtonContactsProcess wiki, the return value is void, and in the NewtonImport.Pas we can see that it is a procedure and not a function. [idem in Newton.h for C user: typedef void (*NewtonContactsProcess)...].
ledahut
 
Posts: 98
Joined: Mon Jun 21, 2010 8:03 am
Location: France

Re: Velocity

Postby Carli » Tue Aug 17, 2010 5:24 am

Julio Jerez wrote:That is the function the engine used to read the force and or velocity at a contact point.

what result it is giniong you? and what do you expect it to be?


I get 0
and I expect a value >0 when it was a "real" hit.

I'm having a rock colliding with the ground and on each hit, it sould play a hit sound. (but not on rolling)

@ledahut: your solution does not have any effect on the velocity.
velocity still grows the longer the rock is rolling.
Last edited by Carli on Tue Aug 17, 2010 5:37 am, edited 1 time in total.
Carli
 
Posts: 245
Joined: Fri Oct 02, 2009 5:28 am

Re: Velocity

Postby ledahut » Tue Aug 17, 2010 5:35 am

Are you able to use breakpoints? To see value of 'par.float'.
ledahut
 
Posts: 98
Joined: Mon Jun 21, 2010 8:03 am
Location: France

Re: Velocity

Postby Carli » Tue Aug 17, 2010 5:41 am

Yes.

When I use my Idea of subtracting the velocities, the values of the hitspeed grow. (when I test at 5, the values grow to 6 etc.)
When I use Julios function, I get the same velocity every time, no matter if its rolling or not (0.45)

Edit:
Julio, why does the volocity grow?
Carli
 
Posts: 245
Joined: Fri Oct 02, 2009 5:28 am

Re: Velocity

Postby ledahut » Tue Aug 17, 2010 8:04 am

This is your reel code or just an algorithm?

Code: Select all
NewtonBodyGetVelocity(body0, ap);
NewtonBodyGetVelocity(body1, bp);
ap:=ap - bp;


Because ap and bp are vector [3 float].
---

Can you try this?

Code: Select all
NewtonMaterialSetCollisionCallback(NewtonWorld, 0, 0, nil, @xAABB, @xcollide);

---
function xAABB(const material: PNewtonMaterial;
  const body0: PNewtonBody; const body1: PNewtonBody;
  threadIndex: Integer): Integer;
begin
  Result := 1
end;

---
procedure xcollide(const contact: PNewtonJoint; timestep: Float;
  threadIndex: Integer);
var
 speed:Double;
 ThisContact: PNewtonJoint;
begin
ThisContact := NewtonContactJointGetFirstContact(contact);
speed:=NewtonMaterialGetContactNormalSpeed(NewtonContactGetMaterial (ThisContact ));
writeln(floattostr(speed));

end;


Be careful, I changed
Code: Select all
NewtonMaterialSetCollisionCallback(result, 0, 0, nil, nil, @xcollide);

to
Code: Select all
NewtonMaterialSetCollisionCallback(NewtonWorld, 0, 0, nil, @xAABB, @xcollide);
ledahut
 
Posts: 98
Joined: Mon Jun 21, 2010 8:03 am
Location: France

Re: Velocity

Postby Julio Jerez » Tue Aug 17, 2010 8:52 am

Carli wrote:
Julio Jerez wrote:That is the function the engine used to read the force and or velocity at a contact point.

what result it is giniong you? and what do you expect it to be?


I get 0
and I expect a value >0 when it was a "real" hit.

I'm having a rock colliding with the ground and on each hit, it sould play a hit sound. (but not on rolling)

@ledahut: your solution does not have any effect on the velocity.
velocity still grows the longer the rock is rolling.


actually 0 is the correct value, what you are decribing teh engine is doing is a perfect physical behevoir,
it may look extrange to you but that is wha the law of physics will do in reality.

this is what happens, when rock body hit the floor it has in instavelocity at each conat point, thefore to prevene penetration teh engien apply and impulse.
this is why you see and velocity at eteh contact point.
bu the the goer to rest on the suface normal and teh engien no longe nee to apply inpulse to prevenet penetration, it only nee to apply a force.
so you get contac velocity zero, but to get a force andteh contac point.

niether one of those value are of any use for rolling sound effect.

however you can appli no only rilling effect but evne frition effect different tha rolling.

for a friction effect all you nee to do is measure the tangent speed at eh contact point if is larger tha some small value it means teh body is sliding at the contat point.

for rolling effect you you need to do is measure the contact absolute velocity,
using body velocity, angular velocity, conta point position and contat and you do this, here is the modified funtion to do that

Code: Select all
void CheckIfBodiesCollide (NewtonBody* body)
{
   // also determine if the body is in rolling motion
   dVector omega;
   dVector velocity;
   NewtonBodyGetVelocity(body, velocity);
   NewtonBodyGetVelocity(body, omega);

   int maxImpactSpeed = 0;
   int maxMaxRollingSpeed = 0;
   for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint (body); joint; joint = NewtonBodyGetNextContactJoint (body, joint)) {
      for (void* contact = NewtonContactJointGetFirstContact (joint); contact; contact = NewtonContactJointGetNextContact (joint, contact)) {
         dFloat speed;
         dVector point;
         dVector normal;   
         //dVector dir0;   
         //dVector dir1;   
         //dVector force;
         NewtonMaterial* material;
         material = NewtonContactGetMaterial (contact);

         // you can get all the information you want
         //NewtonMaterialGetContactForce (material, &force.m_x);
         NewtonMaterialGetContactPositionAndNormal (material, &point.m_x, &normal.m_x);
         //NewtonMaterialGetContactTangentDirections (material, &dir0.m_x, &dir1.m_x);

         // get the impat velocity for impact sound
         speed = NewtonMaterialGetContactNormalSpeed(material);
         if (speed > maxImpactSpeed) {
            maxImpactSpeed = speed;
            // may wnat to save teh poition for 3d sound too.
         }

         // determine if the contact is rolling.
         
         // get tangent vector to the normal and perpendicular to the body velocity
         dVector lateralAxis (velocity * normal);

         //Get the magnitude of the velocity along this
         dFloat mag2 = lateralAxis % lateralAxis;
         // check if it is significant
         if (mag2 > (0.5f * 0.5f)) {

            // the center is moving parallel to the contact get the speed of teh contact along thsi diretion
            dFloat rollingAngularSpeed = fabsf ((omega % lateralAxis) / dSqrt (mag2));
            if (rollingAngularSpeed  > maxMaxRollingSpeed) {
               maxMaxRollingSpeed = rollingAngularSpeed ;
               // may wnat to save teh position also
            }
         }
      }
   }

   if (maxImpactSpeed > someValue) {
      // play impact sound
   }

   if (maxMaxRollingSpeed > someRollingValue) {
      // play impact sound
      // play the looping rolling sound and set the volume base on maxMaxRollingSpeed

      // the sound mamager sould take care of when the sound in not playing more to stop it or re initializ it.

      
   }
}



with that funtion you will see that you will get the hit sound, that it will stop, but ar eteh rock start to roll down teh hill it veloicity will grow gradually,
thefore the value of maxRolling sound will increase proportionally to the speed, and you will use that to control the volume of the rolling sound.
so as is move faster will is sound lowder.
if you is also save contact position it will also sound at the poistion that is support to.

is that what you want?
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Velocity

Postby Carli » Tue Aug 17, 2010 5:52 pm

@ledahut:
These are vectors and - and * are overloaded operators.

@Julio:
Not exactly.
I dont want to find out when it's rolling.
I want to find out when it's NOT rolling.
I get a hitspeed by length(Velocity(body0) - Velocity(body1))

But:
The hit is called for each frame when the rock is rolling. So I play the sound and it sounds bad because the sound should only play on hit, not permanently. So my idea was to have a minimum speed where a "hit" is a hit. (hit=collision)
The rock is not rolling a hill. The rock is on a flat shape and gets slower (in visibility). But the difference between the velocities grows permanantly.
Carli
 
Posts: 245
Joined: Fri Oct 02, 2009 5:28 am

Re: Velocity

Postby Julio Jerez » Tue Aug 17, 2010 5:56 pm

would the angular velocity tell you if the body is rolling?

if the velocity is ground then you should see the body moving. I am confused can you make a youtube video, to clarify?
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Velocity

Postby Carli » Tue Aug 17, 2010 6:06 pm

Ah i got it.-
Thanks to ledahut, the final code is:
Code: Select all
NewtonMaterialGetContactNormalSpeed(NewtonContactGetMaterial(NewtonContactJointGetFirstContact(contact)))
Carli
 
Posts: 245
Joined: Fri Oct 02, 2009 5:28 am


Return to Bugs and Fixes

Who is online

Users browsing this forum: No registered users and 3 guests