Official Pascal-Header (SDK 1.53), last update 26.05.2006

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Postby JernejL » Wed Mar 02, 2005 4:39 pm

Sascha Willems wrote:Edit : I've removed the personal comments made by Delfi. If you have any personal problems to "discuss" with me, do it by PM or better don't tell me about it at all, I'm resistant to other peoples view and like to walk my own way. If you don't want to use the header cause you have problems with me, it's not my problem.


no problem, i'm sorry about it :/

here is my newtonworld unit with three quite useful functions :)

Code: Select all
{ *********************************************************************** }
{                                                                         }
{ Newton Dynamics engine additional utility functionality unit            }
{                                                                         }
{ Copyright (c) 2005 Jernej L. - Delfi (jernejcoder@gmail.com)            }
{                                                                         }
{ *********************************************************************** }


unit NewtonWorld;

interface

uses newtonimport;

type
// a vector for general processing, use your own type
Vector= packed record
x, y, z: decimal;
end;
Pvector = ^Vector;

var
hitn: Vector;
intersectdistance: single;
intresectpoint: Vector;

procedure DebugShowCollision;
function WorldRay(start, stop: Vector): boolean;
function NewtonLocateBody(body: PNewtonBody): Vector;
procedure AddGlobalForce(var body: PNewtonBody; Force, Point: Vector);

implementation

// draw geometry lines
procedure DebugShowGeometryCollision( const body : PNewtonBody; vertexCount : int; const FaceArray : PFloat; faceId : int ); cdecl;
var
i: integer;
vn: integer;

procedure rendervertex(const num: integer);
var
V0: pointer;
begin
V0:= pointer(integer(FaceArray) + num * 12);
glVertex3fv(V0);
end;

begin
vn:= vertexCount-1;

for i:= 0 to vertexCount-1 do begin
  rendervertex(vn);
  rendervertex(i);
  vn:= i;
end;
end;

// show rigid body collision geometry
procedure DebugShowBodyCollision (const body: Pnewtonbody); cdecl;
begin
NewtonBodyForEachPolygonDo(body, DebugShowGeometryCollision);
end;

// show all collision geometry in debug mode
procedure DebugShowCollision;
begin
NewtonWorldForEachBodyDo(nWorld, @DebugShowBodyCollision);
end;

// I hope this is translated correctly, i translated it from pseudocode in newton wiki
// it should be used in PhysicsApplyForceAndTorque callback
procedure AddGlobalForce(var body: PNewtonBody; Force, Point: Vector);
var
r: Vector;
BodyPos: Vector;
bodymatrix: Tmatrix4F;
torque: Vector;
begin
NewtonBodyGetMatrix(body, @bodymatrix);
Move(bodymatrix[3], bodypos, 12);

r:= subtractvectors(point, BodyPos);
Torque:= crossProduct(R, Force);

NewtonbodyAddForce(body, @Force);
NewtonbodyAddTorque(body, @Torque);
end;

// Return newton body position as vector
function NewtonLocateBody(body: PNewtonBody): Vector;
var
bodymatrix: Tmatrix4F;
begin
NewtonBodyGetMatrix(body, @bodymatrix);
Move(bodymatrix[3], result, 12);
end;

// Find first intresection point and return boolean if anything was hit,
// results are stored in global variables (so much about multithreading :P)
function WorldRay(start, stop: Vector): boolean;
var
point: Vector;

function NWRayCallback(const body : PNewtonBody; const hitNormal: PFloat; collisionID : Int; userData: Pointer; intersetParam: Float ) : Float; cdecl;
begin
anyhit:= true; // something was hit
intersectdistance:= intersetParam;
move(hitNormal, hitn, 12); // you have to copy this because callback gives you only pointer
result:= intersetParam; // tell newton to stop searching new intresecting points
end;

begin
result:= false;
anyhit:= false;

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

intresectpoint.x:= start.x + intersectdistance * (stop.x - start.x);
intresectpoint.y:= start.y + intersectdistance * (stop.y - start.y);
intresectpoint.z:= start.z + intersectdistance * (stop.z - start.z);

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 where the ray hit something
glcolor3f(1, 0, 0);
glbegin(gl_points);
glvertex3fv(@intresectpoint);
glend;
end;
{$endif}

end;


maybe other delphi (and pascal) programmers can find this useful :)

edit:

added improved collision geometry rendering function, this one is
much cleaner that the one in sacha's demos (if you like to copy & paste code)
it uses pointers given by newton directly, no copying of memory (so it is faster).
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1578
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Postby Sascha Willems » Sun Apr 03, 2005 3:17 pm

I almost forgot that newton also now has support for double precision and one user asked me via mail how to use it.

If you want to know how to use double precision with newton under Delphi you should download this project (~430 KBytes) which includes a delphi app and the header and shows how to use the double precision dll.

The header only needed a very small change, and if you want to use double precision you need (besides the double precision DLL) to globally declare the symbol NEWTON_DOUBLE_PRECISION. Or you just uncomment it in the header itself (not a good idea if the header is in your basecode-directory, but otherwise this is the fastest way) at line 53.
User avatar
Sascha Willems
Moderator
Moderator
 
Posts: 346
Joined: Fri Aug 27, 2004 10:18 am
Location: Germany

Postby _Tux_ » Sat Apr 09, 2005 10:44 am

has


NewtonSetSolverModel
NewtonSetFrictionModel

been removed?
_Tux_
 
Posts: 81
Joined: Wed Sep 08, 2004 10:38 am
Location: UK

Postby Sascha Willems » Sat Apr 09, 2005 10:48 am

Seems like I did a mistake, since I was using those functions in my NewtonPlayGround and now they're no longer in the header.

I'll fix this ASAP, thanks for pointing it out!

Edit : Damn, seems like I updated the 1.30 headers (dunno how they got into my basecode) instead of the 1.31 headers. I'll fix it within the next few minutes.
User avatar
Sascha Willems
Moderator
Moderator
 
Posts: 346
Joined: Fri Aug 27, 2004 10:18 am
Location: Germany

Postby Sascha Willems » Sat Apr 09, 2005 10:56 am

The fixed header is up, and I apologize if I have caused problems to anyone by accidently uploading an older version of the header with the double fix.
User avatar
Sascha Willems
Moderator
Moderator
 
Posts: 346
Joined: Fri Aug 27, 2004 10:18 am
Location: Germany

Postby _Tux_ » Sat Apr 09, 2005 11:56 am

hehe thanks :)
_Tux_
 
Posts: 81
Joined: Wed Sep 08, 2004 10:38 am
Location: UK

Postby _Tux_ » Wed Apr 13, 2005 6:52 am

is there a problem with NewtonAllocMemory?


the c header is...
typedef void* (*NewtonAllocMemory) (int sizeInBytes);

the delphi header is...
NewtonAllocMemory = procedure( sizeInBytes : int ); cdecl;


c code usage is
Code: Select all
// memory allocation for Newton
void*  PhysicsAlloc (int sizeInBytes)
{
   return malloc (sizeInBytes);
}


so shouldnt the delphi procedure be a function and return pointer?

because atm it causes access violation, otherwise how do i get it working :D
_Tux_
 
Posts: 81
Joined: Wed Sep 08, 2004 10:38 am
Location: UK

Postby _Tux_ » Wed Apr 13, 2005 7:01 am

yes, this is correct for delphi

Code: Select all
function NewtonAllocMemory(aSizeInBytes: Integer): Pointer; cdecl;
Begin
  Result := AllocMem(aSizeInBytes);
  //FMemoryUsage := FMemoryUsage + aSizeInBytes;
end;



although i get a debugger error notification and the cpu window pops up when my app exits, this is the free mem im using

Code: Select all
procedure NewtonFreeMemory(aPointer: Pointer; aSizeInBytes: Integer); cdecl;
Begin
  FreeMem(aPointer, aSizeInBytes);
  //FMemoryUsage := FMemoryUsage - aSizeInBytes;
end;


anything wrong with that?
_Tux_
 
Posts: 81
Joined: Wed Sep 08, 2004 10:38 am
Location: UK

Postby Sascha Willems » Wed Apr 13, 2005 7:50 am

Looks like you are the first person ever that's trying to use NewtonAllocMemory and NewtonFreeMemory with Delphi and you're also right that NewtonAllocMemory was wrongly declared. I already fixed it and will update the headers today or tomorrow.

But I dunno why Delphi throws the exception, and I've just tried around and found no solution. I'll try some more things and let you know if I find a solution to it.
User avatar
Sascha Willems
Moderator
Moderator
 
Posts: 346
Joined: Fri Aug 27, 2004 10:18 am
Location: Germany

Postby _Tux_ » Wed Apr 13, 2005 3:27 pm

i still cant track down why it crashes on closing. its calling NewtonFreeMemory for what seems to be every body, then it frees larger amounts of memory a few times (the memory does exist to be free) then all a sudden the cpu crash window comes up.

are you able to reproduce?
_Tux_
 
Posts: 81
Joined: Wed Sep 08, 2004 10:38 am
Location: UK

Postby Sascha Willems » Thu Apr 14, 2005 3:59 pm

Yes, I'm able to reproduce it. If I use the free memory callback, I get an exception (and the CPU monitor) somewhere in the vast voids of memory (I think it is a newton function, since there are many int 3s around. If I don't use it and only use the memory allocation, I get an exception in ntDbgBreakpoint (or something like this).

I've tried with different kinds of memory allocation (New, GetMem, AllocMem) and even used a PChar instead of a pointer (which should btw. make no difference, but you never know). But that didn't help.

If I get the time, I'll try some more things and let you know if I succeed.
User avatar
Sascha Willems
Moderator
Moderator
 
Posts: 346
Joined: Fri Aug 27, 2004 10:18 am
Location: Germany

Postby Sury » Fri Apr 15, 2005 1:47 pm

the delphi header is...
NewtonAllocMemory = procedure( sizeInBytes : int ); cdecl;
...
so shouldnt the delphi procedure be a function and return pointer?

because atm it causes access violation, otherwise how do i get it working :)


Yeah,nice observation.
I'm sorry, looks like the bug list count is way bigger than i ever thought it would be :wink:

i still cant track down why it crashes on closing. its calling NewtonFreeMemory for what seems to be every body, then it frees larger amounts of memory a few times (the memory does exist to be free) then all a sudden the cpu crash window comes up.

are you able to reproduce?


As far as i know Delphi's GetMem , FreeMem ,AllocMem etc. allocate/free memory blocks using their own standards.
MSVC’s malloc routine handles memory allocation in a different manner than Delphi does. That is, we can’t rightly infer how it manages memory, but it certainly does not allocate memory in the same fashion as Delphi.

So i'm affraid you have to use MSVC memory allocation functions to make it work properly.

Make sure msvcrt.dll is in your path

Code: Select all
function malloc(size: Integer): Pointer; cdecl; external 'msvcrt.dll';
procedure free(P : Pointer) ; cdecl;external 'msvcrt.dll';

function PhysicsAlloc(sizeInBytes : Integer) : Pointer ;cdecl;
begin
  Result := malloc(sizeInBytes) ;
end ;

procedure NewtonFreeMemory(aPointer: Pointer; aSizeInBytes: Integer);cdecl;
Begin
  free(aPointer) ;
end;

....
nWorld := NewtonCreate(  @PhysicsAlloc,   @NewtonFreeMemory);



Fortunately msvcrt.dll is on almost every machine out there so it should't be much of a problem.
User avatar
Sury
 
Posts: 193
Joined: Sat Aug 14, 2004 5:32 am
Location: Bulgaria

Postby _Tux_ » Fri Apr 15, 2005 1:57 pm

damn :( i wont be allowed to use that fix (the management will eat me alive) because we aim for cross platform.

this isnt such a big deal for me, as the release code wont have these callbacks (i only use these callbacks to keep track of the memory usage).

so mabey some way of telling newton if we allocated/freed the memory would be usefull to others. or a NewtonGetMemoryUsage function :)
_Tux_
 
Posts: 81
Joined: Wed Sep 08, 2004 10:38 am
Location: UK

Static libNewton.a does not work with Kylix

Postby savage » Mon Jun 06, 2005 6:34 pm

Just tried the latest headers on Linux. When Kylix tries to link to the libNewton.a file I get a "bad object file format" error.

Any chance of getting a shared object for Linux as well?
savage
 
Posts: 3
Joined: Mon Jun 06, 2005 6:30 pm

Postby savage » Wed Jun 08, 2005 12:14 pm

Just tried to compile a Newton demo with FreePascal. It compiles without any problem but when I try and run the application, since FreePascal is extremely picky, I get errors saying that NewtonBodyCoriolisForcesMode does not exist in Newton.dll and also NewtonUpVectorSetUserCallback not existing either ( I stopped after those 2 ). Delphi lets you get away with this, but FreePascal does not.

May I suggest that any API calls that are not included in the DLL be commented out to avoid this type of error. It is also usefull from a developers point of view, which APIs will actually work.
savage
 
Posts: 3
Joined: Mon Jun 06, 2005 6:30 pm

PreviousNext

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 22 guests

cron