A place to discuss everything related to Newton Dynamics.
Moderators: Sascha Willems, walaber
by Carli » Sat Dec 12, 2009 4:56 pm
Hi,
I need to move a body into a direction only a few units. If the body collides, I want to have him at the closest not-colliding position.
How do I solve that problem? Shall I make a RayCast and a matrix manipilation?
Or is there an Engine function?
-
Carli
-
- Posts: 245
- Joined: Fri Oct 02, 2009 5:28 am
by JernejL » Sat Dec 12, 2009 5:54 pm
Newtonupdate function performs a simulation step and automaticly does collision response to move bodies away.
-

JernejL
-
- Posts: 1587
- Joined: Mon Dec 06, 2004 2:00 pm
- Location: Slovenia
-
by Carli » Sun Dec 13, 2009 11:58 am
but I want to do 2 movements a frame! i cannot do it over 2 frames, it would shake around (no stable graphics) and it would bounce back when i use a speed of 1000
-
Carli
-
- Posts: 245
- Joined: Fri Oct 02, 2009 5:28 am
by JernejL » Sun Dec 13, 2009 12:50 pm
you could use newtonworldconvexcast to see how far you can move a object and then move it for desired or minumum distance there.
-

JernejL
-
- Posts: 1587
- Joined: Mon Dec 06, 2004 2:00 pm
- Location: Slovenia
-
by Carli » Sun Dec 13, 2009 2:37 pm
- Code: Select all
const dFloat* target - Destination of the casted object in global space (convex cast does not support rotations).
is it a 3 float vector? or a matrix? (i hate C semi-typed pointers)
an example code would be helpful, the documentation is confusing.
Edit: what is the new object position when i move an object a few units until it will collide?
-
Carli
-
- Posts: 245
- Joined: Fri Oct 02, 2009 5:28 am
by Carli » Mon Dec 14, 2009 11:53 am
It causes a SIGSEGV
i don't know what i'm making wrong.
i think the pascal interface is still wrong - in C++ it returns an int, in pascal it's a procedure.
- Code: Select all
function PathFree(home: PExecClass; pars:PData):TData; cdecl;
const lol:array[0..3] of single=(0,0,0,0);
var force:array[0..2] of single;
matrix: array[0..3,0..3] of single;
info: array of NewtonWorldConvexCastReturnInfo;
o:TWorldObject;
col:PNewtonCollision;
i:integer; max,len:single;
type pvec3=^TVec3;
begin
result:=novalue;
o:=GetWObject(home);
if o<>nil then begin
NewtonBodyGetMatrix(o.newton,@matrix[0][0]);
force[0]:=pars[0].float;
force[1]:=pars[1].float;
force[2]:=pars[2].float;
max:=Vlen(force);
force:=ApplyMatrixToVec3(matrix,force); //Richtung - gedreht zum Objekt
setlength(info,128);
col:=NewtonBodyGetCollision(o.newton);
if col=nil then writeln('lol');
i:=length(info);
i:=NewtonWorldConvexCast(GetLogic(home).world,@matrix[0][0],@force[0],col,@lol[0],o,@myprefilter,@info[0],i,0);
setlength(info,i);
for i:=0 to high(info) do begin
len:=vlen(SubtractVector(PVec3(@info[i].m_point[0])^,force));
if len<max then begin
result.int:=1;
max:=len;
end;
end;
end;
end;
what is the HitParam? it's not documented. i used 0,0,0,0 instead. How many components do the float *variables have?
-
Carli
-
- Posts: 245
- Joined: Fri Oct 02, 2009 5:28 am
by Carli » Mon Dec 14, 2009 12:33 pm
now I checked the parameters (* all from old posts), but there is still the SIGSEGFault
- Code: Select all
function myprefilter(const body : PNewtonBody; const collision : PNewtonCollision; userData : Pointer) : cardinal; cdecl;
begin
result:=integer(TWorldObject(userData).newton<>body);
end;
function vlen(v:TVec3):single;
begin
result:=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
end;
function PathFree(home: PExecClass; pars:PData):TData; cdecl;
var
matrix: TMatrix4;
pos, force: TVec3;
info: array of NewtonWorldConvexCastReturnInfo;
o:TWorldObject;
col:PNewtonCollision;
i:integer; max,len, lol:single;
type pvec3=^TVec3;
begin
result:=novalue;
o:=GetWObject(home);
if o<>nil then begin
NewtonBodyGetMatrix(o.newton,@matrix[0][0]); //Matrix holen
pos:=SetVector(pars[0].float,pars[1].float,pars[2].float); //Position holen
force:=ApplyMatrixToVec3(matrix,pos); //Zielposition
max:=Vlen(pos); //größte erlaubte Wegstrecke
pos:=ApplyMatrixToVec3(matrix,NullTVec3); //eigene Position
setlength(info,128); //Die Kollisionsinfos anlegen
col:=NewtonBodyGetCollision(o.newton);
i:=length(info);
i:=NewtonWorldConvexCast(GetLogic(home).world,@matrix[0][0],@force,col,@lol,o,@myprefilter,@info[0],i,0);
setlength(info,i);
for i:=0 to high(info) do begin
len:=vlen(SubtractVector(PVec3(@info[i].m_point[0])^,pos));
if len<max then begin
result.int:=1;
max:=len;
end;
end;
end;
end;
maybe you forgot to set the call convention to cdecl???
-
Carli
-
- Posts: 245
- Joined: Fri Oct 02, 2009 5:28 am
by Carli » Mon Dec 14, 2009 12:52 pm
or maybe the pascal header is wrong?
i don't know what the default call convention of your C++ is, but i think it's not cdecl.
what's the fault?
-
Carli
-
- Posts: 245
- Joined: Fri Oct 02, 2009 5:28 am
by JernejL » Mon Dec 14, 2009 2:37 pm
From my game - just checks if anythint is in front of a car using convex casting, this code 100% works, there's even gl rendering debug code that can help you.
- Code: Select all
function Tcar.check_obstacles(dist: single): boolean;
var
tvec: Vector;
tmatrix: Tmatrix4f;
hitparams: array[0..31] of NewtonWorldConvexCastReturnInfo;
hitparamsVecs: array[0..31] of VectorIdx;
// info: NewtonWorldConvexCastReturnInfo;
x: integer;
begin
tmatrix := Self.matrix;
tmatrix[3][2] := tmatrix[3][2] + 0.2;
Move(tmatrix[3], tvec, sizeof(tvec)); // get just the location
tvec := addVectors(tvec, MakeXYvectorFromRotation(radtodeg(heading) + 270, dist));
{
i := find_any_car_near(tvec, dist * 2);
Result := (i <> -1) and (Self.index <> i);
}
fillchar(hitparams, sizeof(hitparams), 0);
//fillchar(hitparamsVecs, sizeof(hitparamsVecs), 0);
x := NewtonWorldConvexCast(NWorld, @tmatrix, @tvec, NewtonBodyGetCollision(self.CarBody), @hitparamsVecs[0], self.CarBody, ignoreudbody, @hitparams[0], 32, 0);
{$ifdef debug_convexcast}
glDisable(gl_texture_2d);
glColor4f(1, 0, 0, 1);
glLineWidth(3);
glBegin(gl_line_loop);
for i := 0 to x do
if hitparams[i].m_point[0] <> 0 then
glVertex3fv(@hitparams[i].m_point[0]);
glend;
glenable(gl_texture_2d);
{$endif}
Result := x > 0;
end;
And this is dll import line, it is correct and works as i'm using it and it doesn't break:
- Code: Select all
function NewtonWorldConvexCast (const newtonWorld: PNewtonWorld; const matrix: PFloat; const target: PFloat; const shape: PNewtonCollision; hitParam: PFloat; userData: Pointer;
prefilter: PNewtonWorldRayPrefilterCallback; info: PNewtonWorldConvexCastReturnInfo; maxContactsCount: integer; threadIndex: integer): integer; cdecl; external newtondll;
-

JernejL
-
- Posts: 1587
- Joined: Mon Dec 06, 2004 2:00 pm
- Location: Slovenia
-
by Carli » Mon Dec 14, 2009 5:53 pm
aah i mixed the order of hitparam and userdata and also gave just one float at hitparam. Thanks.
(Maybe someone would specialize the float *to a more meaningful datatype)
-
Carli
-
- Posts: 245
- Joined: Fri Oct 02, 2009 5:28 am
by JernejL » Mon Dec 14, 2009 6:05 pm
It really is just a pointer to a array of vector3f floats..
-

JernejL
-
- Posts: 1587
- Joined: Mon Dec 06, 2004 2:00 pm
- Location: Slovenia
-
by Stucuk » Mon Dec 14, 2009 6:49 pm
PFloat generally means that its more than 1 float and generally a 3f like Delfi said. Its rare in Newton for a PFloat to not be more than one float(Haven't checked to see if there is any that are just 1 float).
-

Stucuk
-
- Posts: 801
- Joined: Sat Mar 12, 2005 3:54 pm
- Location: Scotland
-
by Carli » Mon Dec 14, 2009 7:34 pm
yes, but for me it wasn't clear that the first float *is a matrix, the second *one is a vector3f, the third is a field of n floats....
-
Carli
-
- Posts: 245
- Joined: Fri Oct 02, 2009 5:28 am
Return to General Discussion
Who is online
Users browsing this forum: No registered users and 2 guests