www.pudn.com > racecar.zip > ODEClasses.pas
{*************************************************************************
* *
* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
* All rights reserved. Email: russ@q12.org Web: www.q12.org *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of EITHER: *
* (1) The GNU Lesser General Public License as published by the Free *
* Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. The text of the GNU Lesser *
* General Public License is included with this library in the *
* file LICENSE.TXT. *
* (2) The BSD-style license that is included with this library in *
* the file LICENSE-BSD.TXT. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
* LICENSE.TXT and LICENSE-BSD.TXT for more details. *
* *
*************************************************************************}
{*************************************************************************
* *
* ODE Delphi Classes unit *
* *
* Created by Christophe Hosten ( chroma@skynet.be ) *
* *
* All real work was of course performed by Russell L. Smith, *
* who created ODE. *
* *
* Convertion started 2002-09-23. *
* *
* There is no Delphi documentation for ODE, see the original ODE files *
* for information http://www.q12.org/ode/ode-0.03-userguide.html *
* *
*************************************************************************}
{
Change history
CH = christophe hosten ( chroma@skynet.be )
MF = mattias fagerlund ( mattias@cambrianlabs.com )
SG = stuart gooding ( sgooding@flemings.com.au )
2002.09.? Initial release by CH
2002.09.29 Added ODEClasses.pas to official DelphiODE release by MF
2002.10.01 Updated ODESpace and descendants to handle new PdxSpace classes by MF
2003.01.? Added support for Cylinders (the non-capped kind) by SG
2003.03.18 Removed dGeomGroup due to deprecation, updated support for spaces by SG,
}
unit ODEClasses;
interface
uses Classes, ODEImport;
Type
TODEJoint = class;
TPointerList = class(TList)
private
function GetItems(i: integer): Pointer;
procedure SetItems(i: integer; const Value: Pointer);
public
property Items[i : integer] : Pointer read GetItems write SetItems; default;
end;
TODEWorld = class
private
{ Private declarations }
pWorld: PdxWorld;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create;
destructor Destroy; override;
function GetPointer: PdxWorld;
procedure SetCFM(const cfm: TdReal);
function GetCFM: TdReal;
procedure SetERP(const erp: TdReal);
function GetERP: TdReal;
procedure SetGravity(const x, y, z: TdReal);
function GetGravity: TdVector3;
procedure Step(const stepsize: TdReal);
function ImpulseToForce(const stepsize, ix, iy, iz: TdReal): TdVector3;
end;
TODEBody = class
private
{ Private declarations }
pBody: PdxBody;
pODEJoint: TPointerList;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(const World: TODEWorld);
destructor Destroy; override;
function GetPointer: PdxBody;
procedure AddForce(const fx, fy, fz: TdReal);
procedure AddForceAtPos(const fx, fy, fz, px, py, pz: TdReal);
procedure AddForceAtRelPos(const fx, fy, fz, px, py, pz: TdReal);
procedure AddRelForce(const fx, fy, fz: TdReal);
procedure AddRelForceAtPos(const fx, fy, fz, px, py, pz: TdReal);
procedure AddRelForceAtRelPos(const fx, fy, fz, px, py, pz: TdReal);
procedure AddRelTorque(const fx, fy, fz: TdReal);
procedure AddTorque(const fx, fy, fz: TdReal);
procedure Disable;
procedure Enable;
function GetAngularVel: TdVector3;
function GetFiniteRotationAxis: TdVector3;
function GetFiniteRotationMode: Integer;
function GetForce: TdVector3;
function GetGravityMode: Integer;
function GetJoint(const index: Integer): TODEJoint;
function GetLinearVel: TdVector3;
function GetMass: Pointer;
function GetNumJoints: Integer;
function GetPointVel(const px, py, pz: TdReal): TdVector3;
function GetPosRelPoint(const px, py, pz: TdReal): TdVector3;
function GetPosition: TdVector3;
function GetQuaternion: TdQuaternion;
function GetRelPointPos(const px, py, pz: TdReal): TdVector3;
function GetRelPointVel(const px, py, pz: TdReal): TdVector3;
function GetRotation: TdMatrix3;
function GetTorque: TdVector3;
function IsEnabled: Boolean;
procedure SetAngularVel(const x, y, z: TdReal);
procedure SetFiniteRotationAxis(const x, y, z: TdReal);
procedure SetFiniteRotationMode(const mode: Integer);
procedure SetForce(const x, y, z: TdReal);
procedure SetGravityMode(const mode: Integer);
procedure SetLinearVel(const x, y, z: TdReal);
procedure SetMass(const mass: TdMass);
procedure SetPosition(const x, y, z: TdReal);
procedure SetQuaternion(const q: TdQuaternion);
procedure SetRotation(const R: TdMatrix3);
procedure SetTorque(const x, y, z: TdReal);
function VectorFromWorld(const px, py, pz: TdReal): TdVector3;
function VectorToWorld(const px, py, pz: TdReal): TdVector3;
function IsConnectedTo(const b: TODEBody): Boolean;
procedure SetData(const data: Pointer);
function GetData: Pointer;
end;
TODEJointGroup = class
private
{ Private declarations }
pJointGroup: TdJointGroupID;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(const max_size: Integer);
destructor Destroy; override;
function GetPointer: TdJointGroupID;
procedure Empty;
end;
TODEJoint = class
private
{ Private declarations }
pJoint: TdJointID;
pODEBody: TPointerList;
protected
{ Protected declarations }
public
{ Public declarations }
destructor Destroy; override;
function GetPointer: TdJointID;
procedure Attach(const body1, body2: TODEBody); overload;
procedure Attach(const pbody1, pbody2: PdxBody); overload;
function GetType: Integer;
function GetBody(const index: Integer): TODEBody;
procedure SetData(const data: Pointer);
function GetData: Pointer;
end;
TODEJointBall = class(TODEJoint)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(const World: TODEWorld; const JointGroup: TODEJointGroup);
procedure SetAnchor(const x, y, z: TdReal);
function GetAnchor: TdVector3;
end;
TODEJointHinge = class(TODEJoint)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(const World: TODEWorld; const JointGroup: TODEJointGroup);
procedure SetAnchor(const x, y, z: TdReal);
function GetAnchor: TdVector3;
procedure SetAxis(const x, y, z: TdReal);
function GetAxis: TdVector3;
function GetAngle: TdReal;
function GetAngleRate: TdReal;
procedure SetParam(const parameter: Integer; const value: TdReal);
function GetParam(const parameter: Integer): TdReal;
end;
TODEJointHinge2 = class(TODEJoint)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(const World: TODEWorld; const JointGroup: TODEJointGroup);
procedure SetAnchor(const x, y, z: TdReal);
function GetAnchor: TdVector3;
procedure SetAxis1(const x, y, z: TdReal);
procedure SetAxis2(const x, y, z: TdReal);
function GetAxis1: TdVector3;
function GetAxis2: TdVector3;
function GetAngle1: TdReal;
function GetAngle1Rate: TdReal;
function GetAngle2Rate: TdReal;
procedure SetParam(const parameter: Integer; const value: TdReal);
function GetParam(const parameter: Integer): TdReal;
end;
TODEJointContact = class(TODEJoint)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(const World: TODEWorld; const JointGroup: TODEJointGroup; const dContact: TdContact);
end;
TODEJointSlider = class(TODEJoint)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(const World: TODEWorld; const JointGroup: TODEJointGroup);
procedure SetAxis(const x, y, z: TdReal);
function GetAxis: TdVector3;
function GetPosition: TdReal;
function GetPositionRate: TdReal;
procedure SetParam(const parameter: Integer; const value: TdReal);
function GetParam(const parameter: Integer): TdReal;
end;
TODEJointFixed = class(TODEJoint)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(const World: TODEWorld; const JointGroup: TODEJointGroup);
procedure SetFixed;
end;
TODEJointAMotor = class(TODEJoint)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(const World: TODEWorld; const JointGroup: TODEJointGroup);
procedure SetAngle(const anum: Integer; const angle: TdReal);
function GetAngle(const anum: Integer): TdReal;
function GetAngleRate(const anum: Integer): TdReal;
procedure SetAxis(const anum, rel: Integer; const x, y, z: TdReal);
function GetAxis(const anum: Integer): TdVector3;
function GetAxisRel(const anum: Integer): Integer;
procedure SetMode(const mode: TdAngularMotorModeNumbers);
function GetMode: Integer;
procedure SetNumAxes(const num: Integer);
function GetNumAxes: Integer;
procedure SetParam(const parameter: Integer; const value: TdReal);
function GetParam(const parameter: Integer): TdReal;
end;
TODEJointUniversal = class(TODEJoint)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(const World: TODEWorld; const JointGroup: TODEJointGroup);
procedure SetAnchor(const x, y, z: TdReal);
function GetAnchor: TdVector3;
procedure SetAxis1(const x, y, z: TdReal);
procedure SetAxis2(const x, y, z: TdReal);
function GetAxis1: TdVector3;
function GetAxis2: TdVector3;
end;
TODEGeom = class
private
{ Private declarations }
pGeom: PdxGeom;
pODEBody: ^TODEBody;
protected
{ Protected declarations }
public
{ Public declarations }
{ TODO : Is dCreateGeom needed ? }
destructor Destroy; override;
function GetPointer: PdxGeom;
function Collide(Geom: TODEGeom; flags: Integer; var Contact: TdContactGeom; Skip: Integer): Integer;
function GetAABB: TdAABB;
procedure SetBody(Body: TODEBody);
function GetBody: TODEBody;
function GetClass: Integer;
function GetClassData: Pointer;
procedure SetPosition(const x, y, z: TdReal);
function GetPosition: PdVector3;
procedure SetRotation(const R: TdMatrix3);
function GetRotation: PdMatrix3;
function GetSpaceAABB: TdReal;
procedure SetData(const data: Pointer);
function GetData: Pointer;
end;
TODESpace = class
private
{ Private declarations }
_pSpace: PdxSpace;
ParentODESpace : TODESpace;
protected
{ Protected declarations }
public
{ Public declarations }
destructor Destroy; override;
function GetPointer: PdxSpace;
procedure Add(const Geom: TODEGeom);
procedure Remove(const Geom: TODEGeom);
function Query(const Geom: TODEGeom): Integer;
procedure Collide(data: pointer; callback: TdNearCallback);
constructor Create(aSpace:TODESpace);virtual;
end;
TODESpaceSimple = class(TODESpace)
private
{ Private declarations }
protected
{ Protected declarations }
pSpace : PdxSimpleSpace;
public
{ Public declarations }
constructor Create(aSpace:TODESpace);override;
end;
TODESpaceHash = class(TODESpace)
private
{ Private declarations }
protected
{ Protected declarations }
pSpace : PdxHashSpace;
public
{ Public declarations }
constructor Create(aSpace:TODESpace);override;
procedure SetLevels(const minlevel, maxlevel: Integer);
function GetMinLevel : integer;
function GetMaxLevel : integer;
end;
TODESphere = class(TODEGeom)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(const Space: TODESpace; const radius: TdReal);
procedure SetRadius(const radius: TdReal);
function GetRadius: TdReal;
end;
TODEBox = class(TODEGeom)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(const Space: TODESpace; const lx, ly, lz: TdReal);
procedure SetLengths(const lx, ly, lz: TdReal);
function GetLengths: TdVector3;
end;
TODEPlane = class(TODEGeom)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(const Space: TODESpace; const a, b, c, d: TdReal);
procedure SetParams(const a, b, c, d: TdReal);
function GetParams: TdVector4;
end;
TODECCylinder = class(TODEGeom)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(const Space: TODESpace; const radius, length: TdReal);
procedure SetParams(const radius, length: TdReal);
procedure GetParams(var radius, length: TdReal);
end;
TODECylinder = class(TODEGeom)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(const Space: TODESpace; const radius, length: TdReal);
procedure SetParams(const radius, length: TdReal);
procedure GetParams(var radius, length: TdReal);
end;
TODEGeomTransform = class(TODEGeom)
private
{ Private declarations }
pODEGeom: ^TODEGeom;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(const Space: TODESpace);
procedure SetGeom(const Geom: TODEGeom);
function GetGeom: TODEGeom;
procedure SetCleanup(const mode: Integer);
function GetCleanup: Integer;
end;
implementation
// --------------------- TPointerList ---------------------
function TPointerList.GetItems(i: integer): Pointer;
begin
result := Get(i);
end;
procedure TPointerList.SetItems(i: integer; const Value: Pointer);
begin
Put(i, Value);
end;
// --------------------- TODEWorld ---------------------
constructor TODEWorld.Create;
begin
pWorld := dWorldCreate();
end;
destructor TODEWorld.Destroy;
begin
dWorldDestroy(pWorld);
inherited Destroy;
end;
function TODEWorld.GetPointer: PdxWorld;
begin
result := pWorld;
end;
procedure TODEWorld.SetCFM(const cfm: TdReal);
begin
dWorldSetCFM(pWorld, cfm);
end;
function TODEWorld.GetCFM: TdReal;
begin
result := pWorld.global_cfm;
end;
procedure TODEWorld.SetERP(const erp: TdReal);
begin
dWorldSetERP(pWorld, erp);
end;
function TODEWorld.GetERP: TdReal;
begin
result := pWorld.global_erp;
end;
procedure TODEWorld.SetGravity(const x, y, z: TdReal);
begin
dWorldSetGravity(pWorld, x, y, z);
end;
function TODEWorld.GetGravity: TdVector3;
begin
result := pWorld.gravity;
end;
procedure TODEWorld.Step(const stepsize: TdReal);
begin
dWorldStep(pWorld, stepsize);
end;
function TODEWorld.ImpulseToForce(const stepsize, ix, iy, iz: TdReal): TdVector3;
begin
dWorldImpulseToForce(pWorld, stepsize, ix, iy, iz, result);
end;
// --------------------- TODEBody ---------------------
constructor TODEBody.Create(const World: TODEWorld);
begin
pBody := dBodyCreate(World.GetPointer);
pODEJoint := TPointerList.Create;
end;
destructor TODEBody.Destroy;
begin
pODEJoint.Free;
dBodyDestroy(pBody);
inherited Destroy;
end;
function TODEBody.GetPointer: PdxBody;
begin
result := pBody;
end;
procedure TODEBody.AddForce(const fx, fy, fz: TdReal);
begin
dBodyAddForce(pBody, fx, fy, fz);
end;
procedure TODEBody.AddForceAtPos(const fx, fy, fz, px, py, pz: TdReal);
begin
dBodyAddForceAtPos(pBody, fx, fy, fz, px, py, pz);
end;
procedure TODEBody.AddForceAtRelPos(const fx, fy, fz, px, py, pz: TdReal);
begin
dBodyAddForceAtRelPos(pBody, fx, fy, fz, px, py, pz);
end;
procedure TODEBody.AddRelForce(const fx, fy, fz: TdReal);
begin
dBodyAddRelForce(pBody, fx, fy, fz);
end;
procedure TODEBody.AddRelForceAtPos(const fx, fy, fz, px, py, pz: TdReal);
begin
dBodyAddRelForceAtPos(pBody, fx, fy, fz, px, py, pz);
end;
procedure TODEBody.AddRelForceAtRelPos(const fx, fy, fz, px, py, pz: TdReal);
begin
dBodyAddRelForceAtRelPos(pBody, fx, fy, fz, px, py, pz);
end;
procedure TODEBody.AddRelTorque(const fx, fy, fz: TdReal);
begin
dBodyAddRelTorque(pBody, fx, fy, fz);
end;
procedure TODEBody.AddTorque(const fx, fy, fz: TdReal);
begin
dBodyAddTorque(pBody, fx, fy, fz);
end;
procedure TODEBody.Disable;
begin
dBodyDisable(pBody);
end;
procedure TODEBody.Enable;
begin
dBodyEnable(pBody);
end;
function TODEBody.GetAngularVel: TdVector3;
begin
result := pBody.avel;
end;
function TODEBody.GetFiniteRotationAxis: TdVector3;
begin
result := pBody.finite_rot_axis;
end;
function TODEBody.GetFiniteRotationMode: Integer;
begin
//enum would be better :(
if ((pBody.flags AND dxBodyFlagFiniteRotation) = 0) then
result := dxBodyFlagFiniteRotationAxis
else
result := dxBodyFlagFiniteRotation;
end;
function TODEBody.GetForce: TdVector3;
begin
result := pBody.facc;
end;
function TODEBody.GetGravityMode: Integer;
begin
//enum would be better :(
if ((pBody.flags AND dxBodyNoGravity) = 0) then
result := 0 //Object is influenced by gravity
else
result := dxBodyNoGravity;
end;
function TODEBody.GetJoint(const index: Integer): TODEJoint;
begin
result := TODEJoint(pODEJoint[index]^);
end;
function TODEBody.GetLinearVel: TdVector3;
begin
result := pBody.lvel;
end;
function TODEBody.GetMass: Pointer;
begin
dBodyGetMass(pBody, result);
end;
function TODEBody.GetNumJoints: Integer;
begin
result := dBodyGetNumJoints(pBody);
end;
function TODEBody.GetPointVel(const px, py, pz: TdReal): TdVector3;
begin
dBodyGetPointVel(pBody, px, py, pz, result);
end;
function TODEBody.GetPosRelPoint(const px, py, pz: TdReal): TdVector3;
begin
dBodyGetPosRelPoint(pBody, px, py, pz, result);
end;
function TODEBody.GetPosition: TdVector3;
begin
result := pBody.pos;
end;
function TODEBody.GetQuaternion: TdQuaternion;
begin
result := pBody.q;
end;
function TODEBody.GetRelPointPos(const px, py, pz: TdReal): TdVector3;
begin
dBodyGetRelPointPos(pBody, px, py, pz, result);
end;
function TODEBody.GetRelPointVel(const px, py, pz: TdReal): TdVector3;
begin
dBodyGetRelPointVel(pBody, px, py, pz, result);
end;
function TODEBody.GetRotation: TdMatrix3;
begin
result := pBody.R;
end;
function TODEBody.GetTorque: TdVector3;
begin
result := pBody.tacc;
end;
function TODEBody.IsEnabled: Boolean;
begin
if ((pBody.flags AND dxBodyDisabled) = 0) then
result := True
else
result := False;
end;
procedure TODEBody.SetAngularVel(const x, y, z: TdReal);
begin
dBodySetAngularVel(pBody, x, y, z);
end;
procedure TODEBody.SetFiniteRotationAxis(const x, y, z: TdReal);
begin
dBodySetFiniteRotationAxis(pBody, x, y, z);
end;
procedure TODEBody.SetFiniteRotationMode(const mode: Integer);
begin
dBodySetFiniteRotationMode(pBody, mode);
end;
procedure TODEBody.SetForce(const x, y, z: TdReal);
begin
dBodySetForce(pBody, x, y, z);
end;
procedure TODEBody.SetGravityMode(const mode: Integer);
begin
dBodySetGravityMode(pBody, mode);
end;
procedure TODEBody.SetLinearVel(const x, y, z: TdReal);
begin
dBodySetLinearVel(pBody, x, y, z);
end;
procedure TODEBody.SetMass(const mass: TdMass);
begin
dBodySetMass(pBody, mass);
end;
procedure TODEBody.SetPosition(const x, y, z: TdReal);
begin
dBodySetPosition(pBody, x, y, z);
end;
procedure TODEBody.SetQuaternion(const q: TdQuaternion);
begin
dBodySetQuaternion(pBody, q);
end;
procedure TODEBody.SetRotation(const R: TdMatrix3);
begin
dBodySetRotation(pBody, R);
end;
procedure TODEBody.SetTorque(const x, y, z: TdReal);
begin
dBodySetTorque(pBody, x, y, z);
end;
function TODEBody.VectorFromWorld(const px, py, pz: TdReal): TdVector3;
begin
dBodyVectorFromWorld(pBody, px, py, pz, result);
end;
function TODEBody.VectorToWorld(const px, py, pz: TdReal): TdVector3;
begin
dBodyVectorToWorld(pBody, px, py, pz, result);
end;
function TODEBody.IsConnectedTo(const b: TODEBody): Boolean;
begin
result := (dAreConnected(pBody, b.GetPointer) = 1);
end;
procedure TODEBody.SetData(const data: Pointer);
begin
dBodySetData(pBody, data);
end;
function TODEBody.GetData: Pointer;
begin
result := pBody.BaseObject.userdata;
end;
// --------------------- TODEJointGroup ---------------------
constructor TODEJointGroup.Create(const max_size: Integer);
begin
pJointGroup := dJointGroupCreate(max_size);
end;
destructor TODEJointGroup.Destroy;
begin
dJointGroupDestroy(pJointGroup);
inherited Destroy;
end;
procedure TODEJointGroup.Empty;
begin
dJointGroupEmpty(pJointGroup);
end;
function TODEJointGroup.GetPointer: TdJointGroupID;
begin
result := pJointGroup;
end;
// --------------------- TODEJoint ---------------------
destructor TODEJoint.Destroy;
begin
pODEBody.Free;
dJointDestroy(pJoint);
inherited Destroy;
end;
function TODEJoint.GetPointer: TdJointID;
begin
result := pJoint;
end;
procedure TODEJoint.Attach(const body1, body2: TODEBody);
begin
dJointAttach(pJoint, body1.GetPointer, body2.GetPointer);
if (body1.GetPointer <> nil) then
begin
pODEBody.Add(@body1);
body1.pODEJoint.Add(@self);
end;
if (body2.GetPointer <> nil) then
begin
pODEBody.Add(@body2);
body2.pODEJoint.Add(@self);
end;
end;
procedure TODEJoint.Attach(const pbody1, pbody2: PdxBody);
begin
dJointAttach(pJoint, pBody1, pBody2);
//if (body1.GetPointer <> nil) then
//begin
// pODEBody.Add(@body1);
// body1.pODEJoint.Add(@self);
//end;
//if (body2.GetPointer <> nil) then
//begin
// pODEBody.Add(@body2);
// body2.pODEJoint.Add(@self);
//end;
end;
function TODEJoint.GetType: Integer;
begin
result := dJointGetType(pJoint);
end;
function TODEJoint.GetBody(const index: Integer): TODEBody;
begin
result := TODEBody(pODEBody.Items[index]^);
end;
procedure TODEJoint.SetData(const data: Pointer);
begin
dJointSetData(pJoint, data);
end;
function TODEJoint.GetData: Pointer;
begin
result := dJointGetData(pJoint);
end;
// --------------------- TODEJointBall ---------------------
constructor TODEJointBall.Create(const World: TODEWorld; const JointGroup: TODEJointGroup);
begin
if Assigned(JointGroup) then
pJoint := dJointCreateBall(World.GetPointer, JointGroup.GetPointer)
else
pJoint := dJointCreateBall(World.GetPointer, 0);
pODEBody := TPointerList.Create;
end;
procedure TODEJointBall.SetAnchor(const x, y, z: TdReal);
begin
dJointSetBallAnchor(pJoint, x, y, z);
end;
function TODEJointBall.GetAnchor: TdVector3;
begin
dJointGetBallAnchor(pJoint, result);
end;
// --------------------- TODEJointHinge ---------------------
constructor TODEJointHinge.Create(const World: TODEWorld; const JointGroup: TODEJointGroup);
begin
if Assigned(JointGroup) then
pJoint := dJointCreateHinge(World.GetPointer, JointGroup.GetPointer)
else
pJoint := dJointCreateHinge(World.GetPointer, 0);
pODEBody := TPointerList.Create;
end;
procedure TODEJointHinge.SetAnchor(const x, y, z: TdReal);
begin
dJointSetHingeAnchor(pJoint, x, y, z);
end;
function TODEJointHinge.GetAnchor: TdVector3;
begin
dJointGetHingeAnchor(pJoint, result);
end;
procedure TODEJointHinge.SetAxis(const x, y, z: TdReal);
begin
dJointSetHingeAxis(pJoint, x, y, z);
end;
function TODEJointHinge.GetAxis: TdVector3;
begin
dJointGetHingeAxis(pJoint, result);
end;
function TODEJointHinge.GetAngle: TdReal;
begin
result := dJointGetHingeAngle(pJoint);
end;
function TODEJointHinge.GetAngleRate: TdReal;
begin
result := dJointGetHingeAngleRate(pJoint);
end;
procedure TODEJointHinge.SetParam(const parameter: Integer; const value: TdReal);
begin
dJointSetHingeParam(pJoint, parameter, value);
end;
function TODEJointHinge.GetParam(const parameter: Integer): TdReal;
begin
result := dJointGetHingeParam(pJoint, parameter);
end;
// --------------------- TODEJointHinge2 ---------------------
constructor TODEJointHinge2.Create(const World: TODEWorld; const JointGroup: TODEJointGroup);
begin
if Assigned(JointGroup) then
pJoint := dJointCreateHinge2(World.GetPointer, JointGroup.GetPointer)
else
pJoint := dJointCreateHinge2(World.GetPointer, 0);
pODEBody := TPointerList.Create;
end;
procedure TODEJointHinge2.SetAnchor(const x, y, z: TdReal);
begin
dJointSetHinge2Anchor(pJoint, x, y, z);
end;
function TODEJointHinge2.GetAnchor: TdVector3;
begin
dJointGetHinge2Anchor(pJoint, result);
end;
procedure TODEJointHinge2.SetAxis1(const x, y, z: TdReal);
begin
dJointSetHinge2Axis1(pJoint, x, y, z);
end;
procedure TODEJointHinge2.SetAxis2(const x, y, z: TdReal);
begin
dJointSetHinge2Axis2(pJoint, x, y, z);
end;
function TODEJointHinge2.GetAxis1: TdVector3;
begin
dJointGetHinge2Axis1(pJoint, result);
end;
function TODEJointHinge2.GetAxis2: TdVector3;
begin
dJointGetHinge2Axis2(pJoint, result);
end;
function TODEJointHinge2.GetAngle1: TdReal;
begin
result := dJointGetHinge2Angle1(pJoint);
end;
function TODEJointHinge2.GetAngle1Rate: TdReal;
begin
result := dJointGetHinge2Angle1Rate(pJoint);
end;
function TODEJointHinge2.GetAngle2Rate: TdReal;
begin
result := dJointGetHinge2Angle2Rate(pJoint);
end;
procedure TODEJointHinge2.SetParam(const parameter: Integer; const value: TdReal);
begin
dJointSetHinge2Param(pJoint, parameter, value);
end;
function TODEJointHinge2.GetParam(const parameter: Integer): TdReal;
begin
result := dJointGetHinge2Param(pJoint, parameter);
end;
// --------------------- TODEJointContact ---------------------
constructor TODEJointContact.Create(const World: TODEWorld; const JointGroup: TODEJointGroup; const dContact: TdContact);
begin
if Assigned(JointGroup) then
pJoint := dJointCreateContact(World.GetPointer, JointGroup.GetPointer, dContact)
else
pJoint := dJointCreateContact(World.GetPointer, 0, dContact);
pODEBody := TPointerList.Create;
end;
// --------------------- TODEJointSlider ---------------------
constructor TODEJointSlider.Create(const World: TODEWorld; const JointGroup: TODEJointGroup);
begin
if Assigned(JointGroup) then
pJoint := dJointCreateSlider(World.GetPointer, JointGroup.GetPointer)
else
pJoint := dJointCreateSlider(World.GetPointer, 0);
pODEBody := TPointerList.Create;
end;
procedure TODEJointSlider.SetAxis(const x, y, z: TdReal);
begin
dJointSetSliderAxis(pJoint, x, y, z);
end;
function TODEJointSlider.GetAxis: TdVector3;
begin
dJointGetSliderAxis(pJoint, result);
end;
function TODEJointSlider.GetPosition: TdReal;
begin
result := dJointGetSliderPosition(pJoint);
end;
function TODEJointSlider.GetPositionRate: TdReal;
begin
result := dJointGetSliderPositionRate(pJoint);
end;
procedure TODEJointSlider.SetParam(const parameter: Integer; const value: TdReal);
begin
dJointSetSliderParam(pJoint, parameter, value);
end;
function TODEJointSlider.GetParam(const parameter: Integer): TdReal;
begin
result := dJointGetSliderParam(pJoint, parameter);
end;
// --------------------- TODEJointFixed ---------------------
constructor TODEJointFixed.Create(const World: TODEWorld; const JointGroup: TODEJointGroup);
begin
if Assigned(JointGroup) then
pJoint := dJointCreateFixed(World.GetPointer, JointGroup.GetPointer)
else
pJoint := dJointCreateFixed(World.GetPointer, 0);
pODEBody := TPointerList.Create;
end;
procedure TODEJointFixed.SetFixed;
begin
dJointSetFixed(pJoint);
end;
// --------------------- TODEJointAMotor ---------------------
constructor TODEJointAMotor.Create(const World: TODEWorld; const JointGroup: TODEJointGroup);
begin
if Assigned(JointGroup) then
pJoint := dJointCreateAMotor(World.GetPointer, JointGroup.GetPointer)
else
pJoint := dJointCreateAMotor(World.GetPointer, 0);
pODEBody := TPointerList.Create;
end;
procedure TODEJointAMotor.SetAngle(const anum: Integer; const angle: TdReal);
begin
dJointSetAMotorAngle(pJoint, anum, angle);
end;
function TODEJointAMotor.GetAngle(const anum: Integer): TdReal;
begin
result := dJointGetAMotorAngle(pJoint, anum);
end;
function TODEJointAMotor.GetAngleRate(const anum: Integer): TdReal;
begin
result := dJointGetAMotorAngleRate(pJoint, anum);
end;
procedure TODEJointAMotor.SetAxis(const anum, rel: Integer; const x, y, z: TdReal);
begin
dJointSetAMotorAxis(pJoint, anum, rel, x, y, z);
end;
function TODEJointAMotor.GetAxis(const anum: Integer): TdVector3;
begin
dJointGetAMotorAxis(pJoint, anum, result);
end;
function TODEJointAMotor.GetAxisRel(const anum: Integer): Integer;
begin
result := dJointGetAMotorAxisRel(pJoint, anum);
end;
procedure TODEJointAMotor.SetMode(const mode: TdAngularMotorModeNumbers);
begin
dJointSetAMotorMode(pJoint, mode);
end;
function TODEJointAMotor.GetMode: Integer;
begin
result := dJointGetAMotorMode(pJoint);
end;
procedure TODEJointAMotor.SetNumAxes(const num: Integer);
begin
dJointSetAMotorNumAxes(pJoint, num);
end;
function TODEJointAMotor.GetNumAxes: Integer;
begin
result := dJointGetAMotorNumAxes(pJoint);
end;
procedure TODEJointAMotor.SetParam(const parameter: Integer; const value: TdReal);
begin
dJointSetAMotorParam(pJoint, parameter, value);
end;
function TODEJointAMotor.GetParam(const parameter: Integer): TdReal;
begin
result := dJointGetAMotorParam(pJoint, parameter);
end;
// --------------------- TODEJointUniversal ---------------------
constructor TODEJointUniversal.Create(const World: TODEWorld; const JointGroup: TODEJointGroup);
begin
if Assigned(JointGroup) then
pJoint := dJointCreateUniversal(World.GetPointer, JointGroup.GetPointer)
else
pJoint := dJointCreateUniversal(World.GetPointer, 0);
pODEBody := TPointerList.Create;
end;
procedure TODEJointUniversal.SetAnchor(const x, y, z: TdReal);
begin
dJointSetUniversalAnchor(pJoint, x, y, z);
end;
function TODEJointUniversal.GetAnchor: TdVector3;
begin
dJointGetUniversalAnchor(pJoint, result);
end;
procedure TODEJointUniversal.SetAxis1(const x, y, z: TdReal);
begin
dJointSetUniversalAxis1(pJoint, x, y, z);
end;
procedure TODEJointUniversal.SetAxis2(const x, y, z: TdReal);
begin
dJointSetUniversalAxis2(pJoint, x, y, z);
end;
function TODEJointUniversal.GetAxis1: TdVector3;
begin
dJointGetUniversalAxis1(pJoint, result);
end;
function TODEJointUniversal.GetAxis2: TdVector3;
begin
dJointGetUniversalAxis2(pJoint, result);
end;
// --------------------- TODEGeom ---------------------
destructor TODEGeom.Destroy;
begin
pODEBody.Free;
dGeomDestroy(pGeom);
inherited Destroy;
end;
function TODEGeom.GetPointer: PdxGeom;
begin
result := pGeom;
end;
function TODEGeom.Collide(Geom: TODEGeom; flags: Integer; var Contact: TdContactGeom; Skip: Integer): Integer;
begin
result := dCollide(pGeom, Geom.GetPointer, flags, Contact, Skip);
end;
function TODEGeom.GetAABB: TdAABB;
begin
pGeom._class^.aabb(pGeom, result);
end;
procedure TODEGeom.SetBody(Body: TODEBody);
begin
dGeomSetBody(pGeom, Body.GetPointer);
if (Body.GetPointer <> nil) then
pODEBody := @Body
else if Assigned(pGeom.Body) then
pODEBody := nil;
end;
function TODEGeom.GetBody: TODEBody;
begin
if Assigned(pODEBody) then
result := pODEBody^
else
result := nil;
end;
function TODEGeom.GetClass: Integer;
begin
result := pGeom._class^.num;
end;
function TODEGeom.GetClassData: Pointer;
begin
result := dGeomGetClassData(pGeom);
end;
procedure TODEGeom.SetPosition(const x, y, z: TdReal);
begin
dGeomSetPosition(pGeom, x, y, z);
end;
function TODEGeom.GetPosition: PdVector3;
begin
result := pGeom.Pos
end;
procedure TODEGeom.SetRotation(const R: TdMatrix3);
begin
dGeomSetRotation(pGeom, R);
end;
function TODEGeom.GetRotation: PdMatrix3;
begin
result := pGeom.R;
end;
function TODEGeom.GetSpaceAABB: TdReal;
begin
result := TdReal(pGeom.space_aabb^);
end;
procedure TODEGeom.SetData(const data: Pointer);
begin
dGeomSetData(pGeom, data);
end;
function TODEGeom.GetData: Pointer;
begin
result := dGeomGetData(pGeom);
end;
// --------------------- TODESpace ---------------------
destructor TODESpace.Destroy;
begin
dSpaceDestroy(_pSpace);
inherited Destroy;
end;
function TODESpace.GetPointer: PdxSpace;
begin
result := _pSpace;
end;
procedure TODESpace.Add(const Geom: TODEGeom);
begin
dSpaceAdd(_pSpace, Geom.GetPointer);
end;
procedure TODESpace.Remove(const Geom: TODEGeom);
begin
dSpaceRemove(_pSpace, Geom.GetPointer);
end;
function TODESpace.Query(const Geom: TODEGeom): Integer;
begin
result := dSpaceQuery(_pSpace, Geom.GetPointer);
end;
procedure TODESpace.Collide(data: pointer; callback: TdNearCallback);
begin
dSpaceCollide(_pSpace, data, callback);
end;
constructor TODESpace.Create(aSpace: TODESpace);
begin
Assert(false, 'You should never create TODESpace directly, use TODESpaceSimple or TODESpaceHash instead!');
end;
// --------------------- TODESpaceSimple ---------------------
constructor TODESpaceSimple.Create(aSpace:TODESpace);
begin
ParentODESpace := aSpace;
if Assigned(aSpace) then
pSpace := PdxSimpleSpace(dSimpleSpaceCreate(aSpace._pSpace))
else
pSpace := PdxSimpleSpace(nil);
_pSpace := PdxSpace(pSpace);
end;
// --------------------- TODESpaceHash ---------------------
constructor TODESpaceHash.Create(aSpace:TODESpace);
begin
ParentODESpace := aSpace;
if Assigned(aSpace) then
pSpace := PdxHashSpace(dHashSpaceCreate(aSpace._pSpace))
else
pSpace := PdxHashSpace(dHashSpaceCreate(nil));
_pSpace := PdxSpace(pSpace);
end;
function TODESpaceHash.GetMaxLevel: integer;
begin
result := pSpace.global_maxlevel;
end;
function TODESpaceHash.GetMinLevel: integer;
begin
result := pSpace.global_minlevel;
end;
procedure TODESpaceHash.SetLevels(const minlevel, maxlevel: Integer);
begin
dHashSpaceSetLevels(_pSpace, minlevel, maxlevel);
end;
// --------------------- TODESphere ---------------------
constructor TODESphere.Create(const Space: TODESpace; const radius: TdReal);
begin
pGeom := dCreateSphere(Space.GetPointer, radius);
end;
procedure TODESphere.SetRadius(const radius: TdReal);
begin
dGeomSphereSetRadius(pGeom, radius);
end;
function TODESphere.GetRadius: TdReal;
begin
result := dGeomSphereGetRadius(pGeom);
end;
// --------------------- TODEBox ---------------------
constructor TODEBox.Create(const Space: TODESpace; const lx, ly, lz: TdReal);
begin
pGeom := dCreateBox(Space.GetPointer, lx, ly, lz);
end;
procedure TODEBox.SetLengths(const lx, ly, lz: TdReal);
begin
dGeomBoxSetLengths(pGeom, lx, ly, lz);
end;
function TODEBox.GetLengths: TdVector3;
begin
dGeomBoxGetLengths(pGeom, result);
end;
// --------------------- TODEPlane ---------------------
constructor TODEPlane.Create(const Space: TODESpace; const a, b, c, d: TdReal);
begin
pGeom := dCreatePlane(Space.GetPointer, a, b, c, d);
end;
procedure TODEPlane.SetParams(const a, b, c, d: TdReal);
begin
dGeomPlaneSetParams(pGeom, a, b, c, d);
end;
function TODEPlane.GetParams: TdVector4;
begin
dGeomPlaneGetParams(pGeom, result);
end;
// --------------------- TODECCylinder ---------------------
constructor TODECCylinder.Create(const Space: TODESpace; const radius, length: TdReal);
begin
pGeom := dCreateCCylinder(Space.GetPointer, radius, length);
end;
procedure TODECCylinder.SetParams(const radius, length: TdReal);
begin
dGeomCCylinderSetParams(pGeom, radius, length);
end;
procedure TODECCylinder.GetParams(var radius, length: TdReal);
begin
dGeomCCylinderGetParams(pGeom, radius, length);
end;
// --------------------- TODECylinder ---------------------
constructor TODECylinder.Create(const Space: TODESpace; const radius, length: TdReal);
begin
pGeom := dCreateCylinder(Space.GetPointer, radius, length);
end;
procedure TODECylinder.SetParams(const radius, length: TdReal);
begin
//dGeomCylinderSetParams(pGeom, radius, length);
end;
procedure TODECylinder.GetParams(var radius, length: TdReal);
begin
//dGeomCylinderGetParams(pGeom, radius, length);
end;
// --------------------- TODEGeomTransform ---------------------
constructor TODEGeomTransform.Create(const Space: TODESpace);
begin
pGeom := dCreateGeomTransform(Space.GetPointer);
end;
procedure TODEGeomTransform.SetGeom(const Geom: TODEGeom);
begin
dGeomTransformSetGeom(pGeom, Geom.GetPointer);
pODEGeom := @Geom;
end;
function TODEGeomTransform.GetGeom: TODEGeom;
begin
result := TODEGeom(pODEGeom^);
end;
procedure TODEGeomTransform.SetCleanup(const mode: Integer);
begin
dGeomTransformSetCleanup(pGeom, mode);
end;
function TODEGeomTransform.GetCleanup: Integer;
begin
result := dGeomTransformGetCleanup(pGeom);
end;
end.