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.