Ray Casting Car Wheels demo in progress

Share with us how are you using the powerrrr of the force

Moderator: Alain

Ray Casting Car Wheels demo in progress

Postby JernejL » Wed May 11, 2005 2:36 am

this is what i got together: http://users.volja.net/delfi/raycast.rar

it casts rays, it shows tire compression but cannot handle appliying forces correctly yet.

i tried in torque callback with addforce and addtorque
and even using newtonaddbodyimpulse (which should be named newtonbodyaddimpulse)

it is written in delphi 7 and uses glscene.

the newton header it uses is my translation (because i thought there was
something wrong with offical headers but they appear to be ok)

i've setup this hovercraft nozzle class:

Code: Select all
type
  Tnozzle = class (Tobject)

  location:     TVector;
  raydirection: Tvector;
  suspforce:    Tvector;
  susploc:      Tvector;

  compression:  single;
  prevcomp:     single;
  tire_radius:  single;
  f_spring:     single;
  F_damp:       single;

  procedure RayCast(parentmatrix: Tmatrix);
  procedure draw(parentmatrix: Tmatrix);

  end;


then i initialize the wheels:

Code: Select all
  // right side

  tires[0]:= Tnozzle.create;
  tires[0].location:= VectorMake(-0.7, 0, -0.5);
  tires[0].raydirection:= vectormake(0, -1, 0);
  tires[0].tire_radius:= 0.5;

  tires[1]:= Tnozzle.create;
  tires[1].location:= VectorMake( 0.7, 0, -0.5);
  tires[1].raydirection:= vectormake(0, -1, 0);
  tires[1].tire_radius:= 0.5;

  // left side

  tires[2]:= Tnozzle.create;
  tires[2].location:= VectorMake(-0.7, 0, 0.5);
  tires[2].raydirection:= vectormake(0, -1, 0);
  tires[2].tire_radius:= 0.5;

  tires[3]:= Tnozzle.create;
  tires[3].location:= VectorMake( 0.7, 0, 0.5);
  tires[3].raydirection:= vectormake(0, -1, 0);
  tires[3].tire_radius:= 0.5;


this is the raycast code:

Code: Select all
procedure Tnozzle.RayCast(parentmatrix: Tmatrix);
var
newvec: Tvector;
endvec: Tvector;
temp1: Tvector;
begin

newvec:= matrix_transform_vector(location, parentmatrix);
endvec:= matrix_rotate_vector(VectorAdd(newvec, VectorScale(raydirection, tire_radius)), parentmatrix);

WorldRay(newvec, endvec);

susploc:=   intresectpoint; // world coordinates

// use hitn for friction, etc..

prevcomp:=    compression;
compression:= intersectdistance * tire_radius; // is this right??

F_spring:= compression * L_susp;
F_damp:= (compression - prevcomp) * F_damp;

temp1:= VectorSubtract(endvec, newvec); // vector un reverse direction

suspforce:= VectorScale(temp1, -compression);
suspforce:= VectorAdd(endvec, suspforce);

end;


worldray function is here:

Code: Select all
function WorldRay(start, stop: tVector): boolean;
var
point: tVector;

function NWRayCallback(const body : PNewtonBody; const hitNormal: PFloat; collisionID : Integer; userData: Pointer; intersetParam: Float ) : Float; cdecl;
begin
anyhit:= true; // something was hit
bodyhit:= body;
intersectdistance:= intersetParam;
move(hitNormal, hitn, 12);
result:= intersetParam; // tell newton to stop searching new intresecting points
end;

begin
result:= false;
anyhit:= false;

NewtonWorldRayCast(NWorld, @start, @stop, @NWRayCallback, nil);

// wiki says: intersectionPoint = p0 + intersetParam * (p1 - p0)

intresectpoint[0]:= start[0] + intersectdistance * (stop[0] - start[0]);
intresectpoint[1]:= start[1] + intersectdistance * (stop[1] - start[1]);
intresectpoint[2]:= start[2] + intersectdistance * (stop[2] - start[2]);

result:= anyhit;

// try to render the ray visually

{$ifdef debugnewtonray}
glcolor3f(0, 0, 1);
glbegin(gl_lines);
glvertex3fv(@start);
glvertex3fv(@stop);
glend;

if anyhit = true then begin
glPointSize(3); // show the point bigger than just one pixel
glcolor3f(1, 0, 0);
glbegin(gl_points);
glvertex3fv(@intresectpoint);
glend;
end;
{$endif}

end;


and this is the force appliying code:

Code: Select all
function matrix_rotate_vector(vec: Tvector; matrix: Tmatrix): Tvector;
begin
result[0]:= vec[0] * matrix[0, 0] + vec[1] * matrix[1, 0] + vec[2] * matrix[2, 0];
result[1]:= vec[0] * matrix[0, 1] + vec[1] * matrix[1, 1] + vec[2] * matrix[2, 1];
result[2]:= vec[0] * matrix[0, 2] + vec[1] * matrix[1, 2] + vec[2] * matrix[2, 2];
end;

function matrix_transform_vector(vec: Tvector; matrix: Tmatrix): Tvector;
begin
result:= matrix_rotate_vector(vec, matrix);

result[0]:= result[0] + matrix[3, 0];
result[1]:= result[1] + matrix[3, 1];
result[2]:= result[2] + matrix[3, 2];
end;

//This is our callback procedure
procedure PhysicsApplyForceAndTorque(const body: PNewtonBody);cdecl ;
var
  mass : float ;
  Ixx :   float ;
  Iyy :   float ;
  Izz :   float ;
  force : TAffineVector ;
  i: integer;
  forcepos, forceadd: tvector;
  matr: Tmatrix;

  aforce, torque: tvector;

begin
  NewtonBodyGetMassMatrix (body, @mass, @Ixx, @Iyy, @Izz);

  NewtonBodyGetForce(body, @force);
  force[1] := -mass * (gravity) ;

  if body = carbody then begin
  NewtonBodyGetMatrix(body, @matr); // we need this

for i:= 0 to 3 do begin
  forcepos:= tires[i].susploc; // ray-world hitting point
  aforce:= vectormake(0, tires[i].compression / 100, 0); //tires[i].suspforce;

  aforce:= matrix_rotate_vector(aforce, matr);
  torque:= VectorCrossProduct(forcepos, aforce);
                                         
  NewtonBodyAddTorque(body, @torque);
  NewtonBodyAddForce(body, @aforce);
  end;

// uncomment to see something similar to how-it-should-be
//  NewtonAddBodyImpulse(body, @aforce, @tires[0].susploc);
//  NewtonAddBodyImpulse(body, @aforce, @tires[1].susploc);
//  NewtonAddBodyImpulse(body, @aforce, @tires[2].susploc);
//  NewtonAddBodyImpulse(body, @aforce, @tires[3].susploc);

  end;

    NewtonBodySetForce (body, @force);
end;


there are major errors in the raycast code and suspension, help me fix it.

the PhysicsApplyForceAndTorque callback is even worse, but it is a
start, i'm learning and with some help people will finally get a working
raycast car demo example, i need your help here!

there are weekly questions about raycast cars, wiki is promising an
example for which i am waiting for over a month and there is very
little documentation on raycast cars on the web.
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1492
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Postby walaber » Wed May 11, 2005 3:07 am

for applying the forces/torques, you need to implement some helper functions for yourself based in the info at the bottom of this page:

http://www.newtondynamics.com/forum/viewtopic.php?t=753

i apologize if you've already done this, I have a hard time reading delphi code. :?
Independent game developer of (mostly) physics-based games. Creator of "JellyCar" and lead designer of "Where's My Water?"
User avatar
walaber
Moderator
Moderator
 
Posts: 393
Joined: Wed Mar 17, 2004 3:40 am
Location: California, USA

Postby JernejL » Wed May 11, 2005 3:25 am

i did that already:

aforce:= matrix_rotate_vector(aforce, matr);
torque:= VectorCrossProduct(forcepos, aforce);

Code: Select all
function matrix_rotate_vector(vec: Tvector; matrix: Tmatrix): Tvector;
begin
result[0]:= vec[0] * matrix[0, 0] + vec[1] * matrix[1, 0] + vec[2] * matrix[2, 0];
result[1]:= vec[0] * matrix[0, 1] + vec[1] * matrix[1, 1] + vec[2] * matrix[2, 1];
result[2]:= vec[0] * matrix[0, 2] + vec[1] * matrix[1, 2] + vec[2] * matrix[2, 2];
end;

function matrix_transform_vector(vec: Tvector; matrix: Tmatrix): Tvector;
begin
result:= matrix_rotate_vector(vec, matrix);

result[0]:= result[0] + matrix[3, 0];
result[1]:= result[1] + matrix[3, 1];
result[2]:= result[2] + matrix[3, 2];
end;
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1492
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Postby chrisfirefoxxx » Wed May 11, 2005 7:19 am

Hey Delfi!

I'm currently having a look at your code, I hope i will be able to help a bit.

regards

chrisfirefoxxx
chrisfirefoxxx
 
Posts: 2
Joined: Thu May 05, 2005 5:51 pm
Location: Austria - Vienna

Postby chrisfirefoxxx » Thu May 12, 2005 2:29 am

As there was no response to my mail from yesterday, I'll just try and post my current version here. I boldly replaced the code in PhysicsApplyForceAndTorque by a translated Version of Julios Code for a "hovering Hovercraft" http://www.newtondynamics.com/forum/viewtopic.php?t=405. I hope it is of use, at least the box now floats - an acceleration would be the next step - according to Julio in the same manner as the hovering.

So, heres the Code:
Code: Select all
procedure PhysicsApplyForceAndTorque(const body: PNewtonBody);cdecl ;
var
  mass : float ;
  Ixx :   float ;
  Iyy :   float ;
  Izz :   float ;
  force, torque, nrpAffine, hlp3, veloc, omega : TAffineVector ;
  i: integer;
  forcepos, forceadd: tvector;
  matr: Tmatrix;

  nozzleRelPosit, nozzleVeloc : tvector;
  netForce, netTorque: tAffinevector;

  distance, nozzleForce, nozzleDampCoef, nozzleDampForce : float;
  nozzlePosit, nozzlePosit1, nozzleDir, hlp : tvector;

begin
  NewtonBodyGetMassMatrix (body, @mass, @Ixx, @Iyy, @Izz);

//  NewtonBodyGetForce(body, @force);

  if body = carbody then begin
    netForce := AffineVectormake( 0, -mass * (gravity), 0 );
    netTorque := AffineVectormake( 0, 0, 0 );
    NewtonBodyGetMatrix(body, @matr); // we need this

    NewtonBodyGetOmega(body, @veloc);
    NewtonBodyGetVelocity(body, @omega);

    // get the force direction in global space
    nozzleDir := matrix_rotate_vector( vectorMake( 0, 1, 0 ), matr );

    for i:= 0 to 3 do begin
      // get the nozzle position in global space
      nozzlePosit := matrix_transform_vector( tires[i].location, matr );

      // get the point at which the nozzel become inefective
      setVector( hlp, nozzleDir );
      scaleVector( hlp, tires[i].tire_radius );
      nozzlePosit1 := VectorSubtract( nozzlePosit, hlp );

      // the effective nozzle distance
      if( WorldRay( nozzlePosit, nozzlePosit1 ) ) then
          distance := (1 - intersectdistance)
      else
          distance := 0;

      // this is the magnitud of the nozzle force
      nozzleForce := 40 * distance;

      // now we need to damp the nozzle force bu adding a force the oppoase the
      // velocity of the nozzle
      nozzleDampCoef := 0.25; // you need to tweak this value for gentle soft

      nozzleRelPosit := matrix_rotate_vector( tires[i].location, matr );
      nrpAffine := AffineVectorMake( nozzleRelPosit[0], nozzleRelPosit[1], nozzleRelPosit[2] );

      hlp3 := VectorCrossProduct( omega, nrpAffine );
      hlp := VectorMake( hlp3[0], hlp3[1], hlp3[2] );
      nozzleDampForce := - VectorDotProduct( hlp, nozzleDir ) * mass * nozzleDampCoef;

      // calculate the total nozzle force
      hlp3 := AffineVectorMake( nozzleDir[0], nozzleDir[1], nozzleDir[2] );
      force := VectorScale( hlp3, nozzleForce + nozzleDampForce );

      // calculate the total nozzle torque
      torque := VectorCrossProduct( nrpAffine, force );

      // accumulate force and torque
      netForce := VectorAdd( netForce, force );
      netTorque := VectorAdd( netTorque, torque );
    end;

    NewtonBodySetForce( body, @netForce );
    NewtonBodySetTorque( body, @netTorque );
  end;
end;

I would greatly appreciaty some Feedback!

kind regards

chris

[edit]Fixed some BAD error - now it works even better ;-)[/edit]
chrisfirefoxxx
 
Posts: 2
Joined: Thu May 05, 2005 5:51 pm
Location: Austria - Vienna

Postby JernejL » Fri May 13, 2005 6:39 am

nice, i can't wait til i get home, acceleration and wheelspin needs to be interigrated yeah, acceleration can be done by appliying side-force to the nozzles, this has to be done in the tnozzle.raycast procedure, i'll do that when i get home :)
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1492
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Postby JernejL » Sun May 15, 2005 11:39 am

right, i tried the code and it works very well, i added some wheels to the car
and they move on the suspension nicely :)

i will try to improve the spring model and add some sort of car controller.

updated and interigrated code with binary demo:
http://www.gtatools.com/temp/raycast.rar
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1492
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Postby _Tux_ » Sun May 15, 2005 12:34 pm

something dodgy going on with glscene, doesnt like my drivers because they have opengl 2 (and not 1.1)
_Tux_
 
Posts: 81
Joined: Wed Sep 08, 2004 10:38 am
Location: UK

Postby JernejL » Sun May 15, 2005 3:51 pm

_Tux_ wrote:something dodgy going on with glscene, doesnt like my drivers because they have opengl 2 (and not 1.1)


try just updating them up-to-date.

what gfx card do you have to support gl 2.0??

i've enchanged some stuff, "partial" steering etc..

Julio and everyone else, is there any good websites dedicated
to raycast cars and its suspension dynamics?
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1492
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Postby _Tux_ » Sun May 15, 2005 3:55 pm

ive got a x800, the latest ati drivers implement opengl2. its a problem with glscene, try download a newer version
_Tux_
 
Posts: 81
Joined: Wed Sep 08, 2004 10:38 am
Location: UK

Postby JernejL » Mon May 16, 2005 1:46 am

_Tux_ wrote:ive got a x800, the latest ati drivers implement opengl2. its a problem with glscene, try download a newer version


what exactly happens with glscene?

try tweaking your graphical driver settings a bit..
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1492
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Postby _Tux_ » Mon May 16, 2005 4:25 am

GLScene.pas, line 6664

Code: Select all
         if not GL_VERSION_1_1 then
            raise EOpenGLError.Create(glsWrongVersion);


my drivers are using the new opengl 2.0, its glscene's code thats wrong.
_Tux_
 
Posts: 81
Joined: Wed Sep 08, 2004 10:38 am
Location: UK

Postby JernejL » Sat May 21, 2005 5:41 pm

try removing that error line?
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1492
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Postby _Tux_ » Sun May 22, 2005 12:31 pm

i cant get glscene to compile streight away, and dont have the time to work on it
_Tux_
 
Posts: 81
Joined: Wed Sep 08, 2004 10:38 am
Location: UK


Return to User Gallery

Who is online

Users browsing this forum: No registered users and 2 guests