UPhysics2D.pas
上传用户:zkjn0718
上传日期:2021-01-01
资源大小:776k
文件大小:341k
源码类别:

Delphi/CppBuilder

开发平台:

Delphi

  1. unit UPhysics2D;
  2. { This unit is written based on Box2D whose author is Erin Catto (http://www.gphysics.com)
  3.   All type names follow the Delphi custom Txxx and xxx means the corresponding
  4.   type in cpp source.
  5.   Because versions before Delphi 2007 don't support operator overloading, so
  6.   I write two versions of all math operations for vector and matrix, etc. But
  7.   later I found that the version without operator overloading runs faster.
  8.   So if you want a better performance, DEFINE BETTER_PERFORMANCE in Physics2D.inc
  9.   which will UNDEFINE OP_OVERLOAD even if you are using Delphi 2010.
  10.   This library supports three kinds of floats, Single(32bit), Double(64bit) and
  11.   Extended(80bit).
  12.        flags        EXTENDED_PRECISION        DOUBLE_PRECISION
  13.      Extended               ON                     whatever
  14.       Double(default)       OFF                       ON
  15.       Single                OFF                       OFF
  16.   There is also a flag SINGLE_PRECISION in the include file but it doesn't affect
  17.   Float type definition.
  18.   All assertions are ignored.
  19.   Translator:  Qianyuan Wang(王乾元)
  20.   Contact me: http://hi.baidu.com/wqyfavor
  21.               wqyfavor@163.com
  22.               QQ: 466798985
  23. }
  24. interface
  25. {$I Physics2D.inc}
  26. {$IFDEF D2009UP}
  27. {$POINTERMATH ON}
  28. {$ENDIF}
  29. uses
  30.    UPhysics2DTypes,
  31.    Math,
  32.    Classes,
  33.    SysUtils,
  34.    Dialogs;
  35. type
  36.    RGBA = array[0..3] of Single;
  37.    TRGBA = packed record
  38.       red, green, blue, alpha: Single;
  39.    end;
  40.    Tb2ContactID = record
  41.       /// The features that intersect to form the contact point
  42.       case Integer of
  43.          0: (referenceEdge: UInt8; ///< The edge that defines the outward contact normal.
  44.             incidentEdge: UInt8; ///< The edge most anti-parallel to the reference edge.
  45.             incidentVertex: UInt8; ///< The vertex (0 or 1) on the incident edge that was clipped.
  46.             flip: UInt8); ///< A value of 1 indicates that the reference edge is on shape2.
  47.          1: (key: UInt32); ///< Used to quickly compare contact ids.
  48.    end;
  49.    /// A manifold point is a contact point belonging to a contact
  50.    /// manifold. It holds details related to the geometry and dynamics
  51.    /// of the contact points.
  52.    /// The point is stored in local coordinates because CCD
  53.    /// requires sub-stepping in which the separation is stale.
  54.    Pb2ManifoldPoint = ^Tb2ManifoldPoint;
  55.    Tb2ManifoldPoint = record
  56.       localPoint1: TVector2; ///< local position of the contact point in body1
  57.       localPoint2: TVector2; ///< local position of the contact point in body2
  58.       separation: Float; ///< the separation of the shapes along the normal vector
  59.       normalImpulse: Float; ///< the non-penetration impulse
  60.       tangentImpulse: Float; ///< the friction impulse
  61.       id: Tb2ContactID; ///< uniquely identifies a contact point between two shapes
  62.    end;
  63.    /// A manifold for two touching convex shapes.
  64.    Pb2Manifold = ^Tb2Manifold;
  65.    Tb2Manifold = record
  66.       points: array[0..b2_maxManifoldPoints - 1] of Tb2ManifoldPoint; ///< the points of contact
  67.       normal: TVector2; ///< the shared unit normal vector
  68.       pointCount: Int32; ///< the number of manifold points
  69.    end;
  70.    /// A line segment.
  71.    Tb2Segment = record
  72.       p1, p2: TVector2; // The starting and ending points
  73.       {$IFDEF OP_OVERLOAD}
  74.       /// Ray cast against this segment with another segment.
  75.       function TestSegment(var lambda: Float; var normal: TVector2;
  76.          const segment: Tb2Segment; maxLambda: Float): Boolean;
  77.       {$ENDIF}
  78.    end;
  79.    /// An axis aligned bounding box.
  80.    Tb2AABB = record
  81.       lowerBound, upperBound: TVector2; // The lower and upper vertices
  82.       {$IFDEF OP_OVERLOAD}
  83.      /// Verify that the bounds are sorted.
  84.      function IsValid: Boolean;
  85.       {$ENDIF}
  86.    end;
  87.    /// An oriented bounding box.
  88.    Tb2OBB = record
  89.       R: TMatrix22; ///< the rotation matrix
  90.       center: TVector2; ///< the local centroid
  91.       extents: TVector2; ///< the half-widths
  92.    end;
  93.    Tb2BodyDef = class;
  94.    Pb2Body = ^Tb2Body;
  95.    Tb2Body = class;
  96.    Tb2JointDef = class;
  97.    Pb2Joint = ^Tb2Joint;
  98.    Tb2Joint = class;
  99.    Pb2Contact = ^Tb2Contact;
  100.    Tb2Contact = class;
  101.    Pb2Shape = ^Tb2Shape;
  102.    Tb2Shape = class;
  103.    Tb2BroadPhase = class;
  104.    Tb2ContactFilter = class;
  105.    Tb2ContactListener = class;
  106.    Tb2ContactManager = class;
  107.    Tb2PairManager = class;
  108.    Tb2PairCallback = class;
  109.    Tb2Island = class;
  110.    Pb2PolyVertices = ^Tb2PolyVertices;
  111.    Tb2PolyVertices = array[0..b2_maxPolygonVertices - 1] of TVector2;
  112.    //////////////////////////////////////////////////////////////
  113.    // World
  114.    Tb2TimeStep = record
  115.       dt: Float; // time step
  116.       inv_dt: Float; // inverse time step (0 if dt == 0).
  117.     dtRatio: Float; // dt * inv_dt0
  118.       maxIterations: Int32;
  119.       warmStarting, positionCorrection: Boolean;
  120.    end;
  121.    /// Joints and shapes are destroyed when their associated
  122.    /// body is destroyed. Implement this listener so that you
  123.    /// may nullify references to these joints and shapes.
  124.    Tb2DestructionListener = class
  125.    public
  126.       /// Called when any joint is about to be destroyed due
  127.       /// to the destruction of one of its attached bodies.
  128.       procedure SayGoodbye(joint: Tb2Joint); overload; virtual; abstract;
  129.       /// Called when any shape is about to be destroyed due
  130.       /// to the destruction of its parent body.
  131.       procedure SayGoodbye(shape: Tb2Shape); overload; virtual; abstract;
  132.    end;
  133.    /// This is called when a body's shape passes outside of the world boundary.
  134.    Tb2BoundaryListener = class
  135.    public
  136.       /// This is called for each body that leaves the world boundary.
  137.       /// @warning you can't modify the world inside this callback.
  138.       procedure Violation(body: Tb2Body); virtual; abstract;
  139.    end;
  140.    Tb2DebugDrawBits = (e_shapeBit, e_jointBit, e_coreShapeBit, e_aabbBit,
  141.       e_obbBit, e_pairBit, e_centerOfMassBit);
  142.    Tb2DebugDrawBitsSet = set of Tb2DebugDrawBits;
  143.    Tb2DebugDraw = class
  144.    public
  145.       m_drawFlags: Tb2DebugDrawBitsSet;
  146.       m_shapeColor_Static, m_shapeColor_Sleeping, m_shapeColor_Normal,
  147.       m_pairColor, m_aabbColor, m_obbColor, m_world_aabbColor, m_coreColor,
  148.       m_jointLineColor: RGBA;
  149.       constructor Create;
  150.       procedure DrawPolygon(const vertices: Tb2PolyVertices; vertexCount: Int32; const color: RGBA); virtual; abstract;
  151.       procedure DrawPolygon4(const vertices: TVectorArray4; vertexCount: Int32; const color: RGBA); virtual; abstract;
  152.       procedure DrawSolidPolygon(const vertices: Tb2PolyVertices; vertexCount: Int32; const color: RGBA); virtual; abstract;
  153.       procedure DrawCircle(const center: TVector2; radius: Float; const color: RGBA); virtual; abstract;
  154.       procedure DrawSolidCircle(const center, axis: TVector2; radius: Float; const color: RGBA); virtual; abstract;
  155.       procedure DrawSegment(const p1, p2: TVector2; const color: RGBA); virtual; abstract;
  156.       procedure DrawXForm(const xf: Tb2XForm); virtual; abstract;
  157.    end;
  158.    /// The world class manages all physics entities, dynamic simulation,
  159.    /// and asynchronous queries. The world also contains efficient memory
  160.    /// management facilities.
  161.    Tb2World = class
  162.    private
  163.       procedure Solve(const step: Tb2TimeStep);
  164.       procedure SolveTOI(const step: Tb2TimeStep);
  165.       procedure DrawShape(shape: Tb2Shape; const xf: Tb2XForm; const color: RGBA; core: Boolean);
  166.       procedure DrawJoint(joint: Tb2Joint);
  167.    public
  168.       m_lock: Boolean;
  169.       m_broadPhase: Tb2BroadPhase;
  170.       m_contactManager: Tb2ContactManager;
  171.       m_bodyList: Tb2Body;
  172.       m_groundBody: Tb2Body;
  173.       m_jointList: Tb2Joint;
  174.       // Do not access
  175.       m_contactList: Tb2Contact;
  176.       m_bodyCount,
  177.       m_contactCount,
  178.       m_jointCount: Int32;
  179.       m_gravity: TVector2;
  180.       m_allowSleep: Boolean;
  181.       m_destructionListener: Tb2DestructionListener;
  182.       m_boundaryListener: Tb2BoundaryListener;
  183.       m_contactFilter: Tb2ContactFilter;
  184.       m_contactListener: Tb2ContactListener;
  185.       m_debugDraw: Tb2DebugDraw;
  186.       m_inv_dt0: Float;
  187.       m_positionIterationCount: Int32;
  188.       m_positionCorrection: Boolean; // This is for debugging the solver.
  189.       m_warmStarting: Boolean; // This is for debugging the solver.
  190.       m_continuousPhysics: Boolean; // This is for debugging the solver.
  191.       /// Construct a world object.
  192.       /// @param worldAABB a bounding box that completely encompasses all your shapes.
  193.       /// @param gravity the world gravity vector.
  194.       /// @param doSleep improve performance by not simulating inactive bodies.
  195.       constructor Create(const worldAABB: Tb2AABB; const gravity: TVector2; doSleep: Boolean);
  196.       /// Destruct the world. All physics entities are destroyed and all heap memory is released.
  197.       destructor Destroy; override;
  198.       /// Create a rigid body given a definition. No reference to the definition is retained.
  199.       /// @warning This function is locked during callbacks.
  200.       function CreateBody(def: Tb2BodyDef; AutoFreeBodyDef: Boolean = True): Tb2Body;
  201.       /// Destroy a rigid body given a definition. No reference to the definition
  202.       /// is retained. This function is locked during callbacks.
  203.       /// @warning This automatically deletes all associated shapes and joints.
  204.       /// @warning This function is locked during callbacks.
  205.       procedure DestroyBody(body: Tb2Body; DoFree: Boolean = True);
  206.       /// Create a joint to constrain bodies together. No reference to the definition
  207.       /// is retained. This may cause the connected bodies to cease colliding.
  208.       /// @warning This function is locked during callbacks.
  209.       function CreateJoint(def: Tb2JointDef; AutoFreeJointDef: Boolean = True): Tb2Joint;
  210.       /// Destroy a joint. This may cause the connected bodies to begin colliding.
  211.       /// @warning This function is locked during callbacks.
  212.       procedure DestroyJoint(j: Tb2Joint);
  213.       /// Take a time step. This performs collision detection, integration,
  214.       /// and constraint solution.
  215.       /// @param timeStep the amount of time to simulate, this should not vary.
  216.       /// @param iterations the number of iterations to be used by the constraint solver.
  217.       procedure Step(timeStep: Float; iterations: Int32; drawThisStep: Boolean = True);
  218.       procedure DrawDebugData;
  219.       /// Query the world for all shapes that potentially overlap the
  220.       /// provided AABB. You provide a shape pointer buffer of specified
  221.       /// size. The number of shapes found is returned.
  222.       /// @param aabb the query box.
  223.       /// @param shapes a user allocated shape pointer array of size maxCount (or greater).
  224.       /// @param maxCount the capacity of the shapes array.
  225.       /// @return the number of shapes found in aabb.
  226.       function Query(const aabb: Tb2AABB; shapes: TList; maxCount: Int32): Int32; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  227.       /// Re-filter a shape. This re-runs contact filtering on a shape.
  228.       procedure Refilter(shape: Tb2Shape); {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  229.       /// Perform validation of internal data structures.
  230.       procedure Validate; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  231.       function GetProxyCount: Int32; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}/// Get the number of broad-phase proxies.
  232.       function GetPairCount: Int32; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}/// Get the number of broad-phase pairs.
  233.       /// Change the global gravity vector.
  234.       procedure SetGravity(const gravity: TVector2); {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  235.       procedure WakeAllSleepingBodies;
  236.       //////////////////////////////////////////////////////////////////////
  237.       property DestructionListener: Tb2DestructionListener read m_destructionListener write m_destructionListener;
  238.       property BoundaryListener: Tb2BoundaryListener read m_boundaryListener write m_boundaryListener;
  239.       property ContactFilter: Tb2ContactFilter read m_contactFilter write m_contactFilter;
  240.       property ContactListener: Tb2ContactListener read m_contactListener write m_contactListener;
  241.       property DebugDraw: Tb2DebugDraw read m_debugDraw write m_debugDraw;
  242.       property GetGroundBody: Tb2Body read m_groundBody;
  243.       property GetBodyList: Tb2Body read m_bodyList;
  244.       property GetJointList: Tb2Joint read m_jointList;
  245.       property GetBodyCount: Int32 read m_bodyCount;
  246.       property GetJointCount: Int32 read m_jointCount;
  247.       property GetContactCount: Int32 read m_contactCount;
  248.       property WarmStarting: Boolean read m_warmStarting write m_warmStarting;
  249.       property PositionCorrection: Boolean read m_positionCorrection write m_warmStarting;
  250.       property ContinuousPhysics: Boolean read m_continuousPhysics write m_continuousPhysics;
  251.    end;
  252.    ////////////////////////////////////////////////////
  253.    // Contact
  254.    /// A contact edge is used to connect bodies and contacts together
  255.    /// in a contact graph where each body is a node and each contact
  256.    /// is an edge. A contact edge belongs to a doubly linked list
  257.    /// maintained in each attached body. Each contact has two contact
  258.    /// nodes, one for each attached body.
  259.    Pb2ContactEdge = ^Tb2ContactEdge;
  260.    Tb2ContactEdge = record
  261.       other: Tb2Body; ///< provides quick access to the other body attached.
  262.       contact: Tb2Contact; ///< the contact
  263.       prev, next: Pb2ContactEdge;
  264.    end;
  265.    /// This structure is used to report contact points.
  266.    Tb2ContactPoint = record
  267.       shape1, shape2: Tb2Shape;
  268.       position: TVector2; ///< position in world coordinates
  269.       velocity: TVector2; ///< velocity of point on body2 relative to point on body1 (pre-solver)
  270.       normal: TVector2; ///< points from shape1 to shape2
  271.       separation: Float; ///< the separation is negative when shapes are touching
  272.       friction: Float ; ///< the combined friction coefficient
  273.       restitution: Float ; ///< the combined restitution coefficient
  274.       id: Tb2ContactID; ///< the contact id identifies the features in contact
  275.    end;
  276.    /// This structure is used to report contact point results.
  277.    Tb2ContactResult = record
  278.       shape1, shape2: Tb2Shape;
  279.       position: TVector2; ///< position in world coordinates
  280.       normal: TVector2; ///< points from shape1 to shape2
  281.       normalImpulse: Float; ///< the normal impulse applied to body2
  282.       tangentImpulse: Float; ///< the tangent impulse applied to body2
  283.       id: Tb2ContactID; ///< the contact id identifies the features in contact
  284.    end;
  285.    Pb2ContactConstraintPoint = ^Tb2ContactConstraintPoint;
  286.    Tb2ContactConstraintPoint = record
  287.       localAnchor1, localAnchor2: TVector2;
  288.       r1, r2: TVector2;
  289.       normalImpulse, tangentImpulse, positionImpulse: Float;
  290.       normalMass, tangentMass, equalizedMass: Float;
  291.       separation, velocityBias: Float;
  292.    end;
  293.    Pb2ContactConstraint = ^Tb2ContactConstraint;
  294.    Tb2ContactConstraint = record
  295.       points: array[0..b2_maxManifoldPoints - 1] of Tb2ContactConstraintPoint;
  296.       normal: TVector2;
  297.       manifold: Pb2Manifold;
  298.       body1, body2: Tb2Body;
  299.       friction, restitution: Float;
  300.       pointCount: Int32;
  301.    end;
  302.    /// Implement this class to provide collision filtering. In other words,
  303.    /// you can implement this class if you want finer control over contact creation.
  304.    Tb2ContactFilter = class
  305.    public
  306.       /// Return True if contact calculations should be performed between
  307.       /// these two shapes. @warning for performance reasons this is only
  308.       /// called when the AABBs begin to overlap.
  309.       function ShouldCollide(shape1, shape2: Tb2Shape): Boolean; virtual;
  310.    end;
  311.    /// Implement this class to get collision results. You can use these results for
  312.    /// things like sounds and game logic. You can also get contact results by
  313.    /// traversing the contact lists after the time step. However, you might miss
  314.    /// some contacts because continuous physics leads to sub-stepping.
  315.    /// Additionally you may receive multiple callbacks for the same contact in a
  316.    /// single time step.
  317.    /// You should strive to make your callbacks efficient because there may be
  318.    /// many callbacks per time step.
  319.    /// @warning The contact separation is the last computed value.
  320.    /// @warning You cannot create/destroy Box2D entities inside these callbacks.
  321.    Tb2ContactListener = class
  322.    public
  323.       /// Called when a contact point is added. This includes the geometry and the forces.
  324.       procedure Add(var point: Tb2ContactPoint); virtual;
  325.       /// Called when a contact point persists. This includes the geometry and the forces.
  326.       procedure Persist(var point: Tb2ContactPoint); virtual;
  327.       /// Called when a contact point is removed. This includes the last
  328.       /// computed geometry and forces.
  329.       procedure Remove(var point: Tb2ContactPoint); virtual;
  330.       /// Called after a contact point is solved.
  331.       procedure Result(var point: Tb2ContactResult); virtual;
  332.    end;
  333.    /// The class manages contact between two shapes. A contact exists for each overlapping
  334.    /// AABB in the broad-phase (except if filtered). Therefore a contact object may exist
  335.    /// that has no contact points.
  336.    Tb2ContactClass = class of Tb2Contact;
  337.    Tb2Contact = class
  338.    public
  339.       m_flags: UInt32;
  340.       /// The number of manifolds. This is 0 or 1 between convex shapes.
  341.       /// This may be greater than 1 for convex-vs-concave shapes. Each
  342.       /// manifold holds up to two contact points with a shared contact normal.
  343.       m_manifoldCount: Int32;
  344.       m_prev, m_next: Tb2Contact; // World pool and list pointers.
  345.       m_node1, m_node2: Tb2ContactEdge; // Nodes for connecting bodies.
  346.       m_shape1, m_shape2: Tb2Shape;
  347.       // Combined friction
  348.       m_friction: Float;
  349.       m_restitution: Float;
  350.       m_toi: Float;
  351.       constructor Create; overload;
  352.       constructor Create(shape1, shape2: Tb2Shape); overload; virtual;
  353.       class function CreateContact(Shape1, Shape2: Tb2Shape): Tb2Contact;
  354.       procedure Update(listener: Tb2ContactListener);
  355.       procedure Evaluate(listener: Tb2ContactListener); virtual; abstract;
  356.       /// Get the manifold array.
  357.       function GetManifolds: Pb2Manifold; virtual; abstract;
  358.       /// @return True if this contact should generate a response.
  359.       function IsSolid: Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  360.       property GetManifoldCount: Int32 read m_manifoldCount;
  361.       property GetShape1: Tb2Shape read m_shape1;
  362.       property GetShape2: Tb2Shape read m_shape2;
  363.       property GetNext: Tb2Contact read m_next;
  364.    end;
  365.    Tb2ContactSolver = class
  366.    public
  367.       m_step: Tb2TimeStep;
  368.       m_constraints: Pb2ContactConstraint;
  369.       m_constraintCount: Int32;
  370.     constructor Create(const step: Tb2TimeStep; contacts: TList; contactCount: Int32);
  371.       destructor Destroy; override;
  372.       procedure InitVelocityConstraints(const step: Tb2TimeStep);
  373.       procedure SolveVelocityConstraints;
  374.       procedure FinalizeVelocityConstraints;
  375.       function SolvePositionConstraints(baumgarte: Float): Boolean;
  376.    end;
  377.    Tb2NullContact = class(Tb2Contact)
  378.    public
  379.     procedure Evaluate(listener: Tb2ContactListener); override;
  380.     function GetManifolds(): Pb2Manifold; override;
  381.    end;
  382.    Tb2PairCallback = class
  383.    public
  384.       // This should return the new pair user data. It is ok if the user data is null.
  385.       function PairAdded(proxyUserData1, proxyUserData2: Pointer): Pointer; virtual; abstract;
  386.       // This should free the pair's user data. In extreme circumstances, it is possible
  387.       // this will be called with null pairUserData because the pair never existed.
  388.       procedure PairRemoved(proxyUserData1, proxyUserData2, pairUserData: Pointer); virtual; abstract;
  389.    end;
  390.    // Delegate of b2World.
  391.    Tb2ContactManager = class(Tb2PairCallback)
  392.    public
  393.       m_world: Tb2World;
  394.       // This lets us provide broadphase proxy pair user data for
  395.       // contacts that shouldn't exist.
  396.       m_nullContact: Tb2NullContact;
  397.       m_destroyImmediate: Boolean;
  398.       constructor Create(world: Tb2World);
  399.       // Implements PairCallback
  400.       function PairAdded(proxyUserData1, proxyUserData2: Pointer): Pointer; override;
  401.       // Implements PairCallback
  402.       procedure PairRemoved(proxyUserData1, proxyUserData2, pairUserData: Pointer); override;
  403.       procedure Destroy(c: Tb2Contact);
  404.       procedure Collide;
  405.    end;
  406.    ////////////////////////////////////////////////////
  407.    // Island
  408.    Tb2Island = class
  409.    public
  410.       m_listener: Tb2ContactListener;
  411.       m_bodies: TList;
  412.       m_contacts: TList;
  413.       m_joints: TList;
  414.       m_bodyCount: Int32;
  415.       m_jointCount: Int32;
  416.       m_contactCount: Int32;
  417.       m_bodyCapacity, m_contactCapacity, m_jointCapacity: Int32;
  418.       m_positionIterationCount: Int32;
  419.       constructor Create(bodyCapacity, contactCapacity, jointCapacity: Int32;
  420.          listener: Tb2ContactListener);
  421.       destructor Destroy; override;
  422.       procedure Clear;
  423.       procedure Solve(const step: Tb2TimeStep; const gravity: TVector2;
  424.          correctPositions, allowSleep: Boolean);
  425.       procedure SolveTOI(const subStep: Tb2TimeStep);
  426.       procedure Add(body: Tb2Body); overload; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  427.       procedure Add(contact: Tb2Contact); overload; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  428.       procedure Add(joint: Tb2Joint); overload; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  429.       procedure Report(constraints: Pb2ContactConstraint);
  430.    end;
  431.    ////////////////////////////////////////////////////
  432.    //
  433.    Pb2Bound = ^Tb2Bound;
  434.    Tb2Bound = record
  435.       value, proxyId, stabbingCount: UInt16;
  436.       {$IFDEF OP_OVERLOAD}
  437.     function IsLower: Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  438.       function IsUpper: Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  439.       {$ENDIF}
  440.    end;
  441.    Pb2Proxy = ^Tb2Proxy;
  442.    Tb2Proxy = record
  443.       lowerBounds, upperBounds: array[0..1] of UInt16;
  444.       overlapCount: UInt16;
  445.       timeStamp: UInt16;
  446.       userData: Pointer;
  447.       {$IFDEF OP_OVERLOAD}
  448.       function GetNext: UInt16; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  449.       procedure SetNext(Next: UInt16); {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  450.       function IsValid: Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  451.       {$ENDIF}
  452.    end;
  453.    Tb2BoundValuesArray = array[0..1] of UInt16;
  454.    Tb2BoundValues = record
  455.       lowerValues, upperValues: Tb2BoundValuesArray;
  456.    end;
  457.    Pb2AxialBoundsArray = ^Tb2AxialBoundsArray;
  458.    Tb2AxialBoundsArray = array[0..2 * b2_maxProxies - 1] of Tb2Bound;
  459.    Tb2BroadPhase = class
  460.    private
  461.       procedure ComputeBounds(var lowerValues, upperValues: Tb2BoundValuesArray; const aabb: Tb2AABB);
  462.       function TestOverlap(var p1, p2: Tb2Proxy): Boolean; overload;
  463.       function TestOverlap(const b: Tb2BoundValues; var p: Tb2Proxy): Boolean; overload;
  464.       procedure Query(var lowerIndex, upperIndex: Int32; lowerValue,
  465.          upperValue: UInt16; var bounds: Tb2AxialBoundsArray; boundCount, axis: Int32); overload;
  466.       procedure IncrementOverlapCount(proxyId: Int32);
  467.       procedure IncrementTimeStamp;
  468.    public
  469.       m_pairManager: Tb2PairManager;
  470.       m_proxyPool: array[0..b2_maxProxies - 1] of Tb2Proxy;
  471.       m_freeProxy: UInt16;
  472.       m_bounds: array[0..1] of Tb2AxialBoundsArray;
  473.       m_queryResults: array[0..b2_maxProxies - 1] of UInt16;
  474.       m_queryResultCount: Int32;
  475.       m_worldAABB: Tb2AABB;
  476.       m_quantizationFactor: TVector2;
  477.       m_proxyCount: Int32;
  478.       m_timeStamp: UInt16;
  479.       constructor Create(const worldAABB: Tb2AABB; callback: Tb2PairCallback);
  480.       destructor Destroy; override;
  481.       // Use this to see if your proxy is in range. If it is not in range,
  482.       // it should be destroyed. Otherwise you may get O(m^2) pairs, where m
  483.       // is the number of proxies that are out of range.
  484.       function InRange(const aabb: Tb2AABB): Boolean;
  485.       // Create and destroy proxies. These call Flush first.
  486.       function CreateProxy(const aabb: Tb2AABB; userData: Pointer): UInt16;
  487.       procedure DestroyProxy(proxyId: Int32);
  488.       // Call MoveProxy as many times as you like, then when you are done
  489.       // call Commit to finalized the proxy pairs (for your time step).
  490.       procedure MoveProxy(proxyId: Int32; const aabb: Tb2AABB);
  491.       procedure Commit; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  492.       // Get a single proxy. Returns NULL if the id is invalid.
  493.       function GetProxy(proxyId: Int32): Pb2Proxy;
  494.       // Query an AABB for overlapping proxies, returns the user data and
  495.       // the count, up to the supplied maximum count.
  496.       function Query(const aabb: Tb2AABB; userData: TList;
  497.          maxCount: Int32): Int32; overload;
  498.       procedure Validate;
  499.       procedure ValidatePairs;
  500.    {$IFDEF CLASSVAR_AVAIL}
  501.    class var
  502.       s_validate: Boolean;
  503.    {$ENDIF}
  504.    end;
  505.    ////////////////////////////////////////////////////
  506.    // Pair
  507.    Pb2Pair = ^Tb2Pair;
  508.    Tb2Pair = record
  509.       userData: Pointer;
  510.       proxyId1: UInt16;
  511.       proxyId2: UInt16;
  512.       next: UInt16;
  513.       status: UInt16;
  514.       {$IFDEF OP_OVERLOAD}
  515.     procedure SetBuffered; {$IFDEF INLINE_AVAIL}inline;{$ENDIF} { status |= e_pairBuffered; }
  516.     procedure ClearBuffered; {$IFDEF INLINE_AVAIL}inline;{$ENDIF} { status &= ~e_pairBuffered; }
  517.     function IsBuffered: Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF} { return (status & e_pairBuffered) == e_pairBuffered; }
  518.     procedure SetRemoved; {$IFDEF INLINE_AVAIL}inline;{$ENDIF} { status |= e_pairRemoved; }
  519.     procedure ClearRemoved; {$IFDEF INLINE_AVAIL}inline;{$ENDIF} { status &= ~e_pairRemoved; }
  520.     function IsRemoved: Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF} { return (status & e_pairRemoved) == e_pairRemoved; }
  521.     procedure SetFinal; {$IFDEF INLINE_AVAIL}inline;{$ENDIF} { status |= e_pairFinal; }
  522.     function IsFinal: Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF} { return (status & e_pairFinal) == e_pairFinal; }
  523.       {$ENDIF}
  524.    end;
  525.    Tb2BufferedPair = record
  526.       proxyId1: UInt16;
  527.       proxyId2: UInt16;
  528.    end;
  529.    Tb2PairManager = class
  530.    private
  531.       function Find(proxyId1, proxyId2: Int32): Pb2Pair; overload;
  532.       function Find(proxyId1, proxyId2: Int32; hashValue: UInt32): Pb2Pair; overload;
  533.       function AddPair(proxyId1, proxyId2: Int32): Pb2Pair; // Returns existing pair or creates a new one.
  534.       function RemovePair(proxyId1, proxyId2: Int32): Pointer;
  535.       procedure ValidateBuffer;
  536.       procedure ValidateTable;
  537.    public
  538.       m_broadPhase: Tb2BroadPhase;
  539.       m_callback: Tb2PairCallback;
  540.       m_pairs: array[0..b2_maxPairs - 1] of Tb2Pair;
  541.       m_freePair: UInt16;
  542.       m_pairCount: Int32;
  543.       m_pairBuffer: array[0..b2_maxPairs - 1] of Tb2BufferedPair;
  544.       m_pairBufferCount: Int32;
  545.       m_hashTable: array[0..b2_tableCapacity - 1] of UInt16;
  546.       constructor Create;
  547.       procedure Initialize(broadPhase: Tb2BroadPhase; callback: Tb2PairCallback);
  548.       procedure AddBufferedPair(proxyId1, proxyId2: Int32);
  549.       procedure RemoveBufferedPair(proxyId1, proxyId2: Int32);
  550.       procedure Commit;
  551.    end;
  552.    //////////////////////////////////////////////////////////////
  553.    // Shapes
  554.    /// This holds the mass data computed for a shape.
  555.    Tb2MassData = record
  556.     mass: Float; /// The mass of the shape, usually in kilograms.
  557.       I: Float;  /// The rotational inertia of the shape.
  558.       center: TVector2; /// The position of the shape's centroid relative to the shape's origin.
  559.    end;
  560.    /// This holds contact filtering data.
  561.    Pb2FilterData = ^Tb2FilterData;
  562.    Tb2FilterData = record
  563.       categoryBits: UInt16; /// The collision category bits. Normally you would just set one bit.
  564.       /// The collision mask bits. This states the categories that this
  565.       /// shape would accept for collision.
  566.       maskBits: UInt16;
  567.       /// Collision groups allow a certain group of objects to never collide (negative)
  568.       /// or always collide (positive). Zero means no collision group. Non-zero group
  569.       /// filtering always wins against the mask bits.
  570.       groupIndex: Int16;
  571.    end;
  572.    /// The various collision shape types supported by Box2D.
  573.    Tb2ShapeType = (e_unknownShape = -1, e_circleShape, e_polygonShape);
  574.    /// A shape definition is used to construct a shape. This class defines an
  575.    /// abstract shape definition. You can reuse shape definitions safely.
  576.    Tb2ShapeDef = class
  577.    public
  578.       ShapeType: Tb2ShapeType; /// Holds the shape type for down-casting.
  579.       userData: Pointer; /// Use this to store application specify shape data.
  580.       friction: Float; /// The shape's friction coefficient, usually in the range [0,1].
  581.       restitution: Float; /// The shape's restitution (elasticity) usually in the range [0,1].
  582.       density: Float; /// The shape's density, usually in kg/m^2.
  583.       isSensor: Boolean; /// A sensor shape collects contact information but never generates a collision response.
  584.       filter: Tb2FilterData; /// Contact filtering data.
  585.       constructor Create;
  586.    end;
  587.    /// A shape is used for collision detection. Shapes are created in b2World.
  588.    /// You can use shape for collision detection before they are attached to the world.
  589.    /// @warning you cannot reuse shapes.
  590.    Tb2Shape = class
  591.    private
  592.       destructor Destroy2; 
  593.    protected
  594.       procedure CreateProxy(broadPhase: Tb2BroadPhase; const xf: Tb2XForm);
  595.       procedure DestroyProxy(broadPhase: Tb2BroadPhase);
  596.       function Synchronize(broadPhase: Tb2BroadPhase; const xf1, xf2: Tb2XForm): Boolean;
  597.       procedure RefilterProxy(broadPhase: Tb2BroadPhase; const xf: Tb2XForm);
  598.       procedure UpdateSweepRadius(const center: TVector2); virtual; abstract;
  599.    public
  600.       m_type: Tb2ShapeType;
  601.       m_next: Tb2Shape;
  602.       m_body: Tb2Body;
  603.       // Sweep radius relative to the parent body's center of mass.
  604.       m_sweepRadius: Float;
  605.       m_density: Float;
  606.       m_friction: Float;
  607.       m_restitution: Float;
  608.       m_proxyId: UInt16;
  609.       m_filter: Tb2FilterData;
  610.       m_isSensor: Boolean;
  611.       m_userData: Pointer;
  612.       constructor Create(def: Tb2ShapeDef);
  613.       destructor Destroy; override;
  614.       /// Test a point for containment in this shape. This only works for convex shapes.
  615.       /// @param xf the shape world transform.
  616.       /// @param p a point in world coordinates.
  617.       function TestPoint(const xf: Tb2XForm; const p: TVector2): Boolean; virtual; abstract;
  618.       /// Perform a ray cast against this shape.
  619.       /// @param xf the shape world transform.
  620.       /// @param lambda returns the hit fraction. You can use this to compute
  621.       /// the contact point p = (1 - lambda) * segment.p1 + lambda * segment.p2.
  622.       /// @param normal returns the normal at the contact point. If there is no
  623.       /// intersection, the normal is not set.
  624.       /// @param segment defines the begin and end point of the ray cast.
  625.       /// @param maxLambda a number typically in the range [0,1].
  626.       /// @return True if there was an intersection.
  627.       function TestSegment(const xf: Tb2XForm; var lambda: Float; var normal: TVector2;
  628.          const segment: Tb2Segment; maxLambda: Float): Boolean; virtual; abstract;
  629.       /// Given a transform, compute the associated axis aligned bounding box for this shape.
  630.       /// @param aabb returns the axis aligned box.
  631.       /// @param xf the world transform of the shape.
  632.       procedure ComputeAABB(var aabb: Tb2AABB; const xf: Tb2XForm); virtual; abstract;
  633.       /// Given two transforms, compute the associated swept axis aligned bounding box for this shape.
  634.       /// @param aabb returns the axis aligned box.
  635.       /// @param xf1 the starting shape world transform.
  636.       /// @param xf2 the ending shape world transform.
  637.       procedure ComputeSweptAABB(var aabb: Tb2AABB; const xf1, xf2: Tb2XForm); virtual; abstract;
  638.       /// Compute the mass properties of this shape using its dimensions and density.
  639.       /// The inertia tensor is computed about the local origin, not the centroid.
  640.       /// @param massData returns the mass data for this shape.
  641.       procedure ComputeMass(var massData: Tb2MassData); virtual; abstract;
  642.       property GetType: Tb2ShapeType read m_type;
  643.       property GetBody: Tb2Body read m_body;
  644.       property GetFriction: Float read m_friction;
  645.       property GetRestitution: Float read m_restitution;
  646.       property GetSweepRadius: Float read m_sweepRadius;
  647.       property IsSensor: Boolean read m_isSensor write m_isSensor;
  648.    end;
  649.    //////////////////////////////////////////////////////////////
  650.    // Joints    
  651.    Tb2JointType = (e_unknownJoint, e_revoluteJoint, e_prismaticJoint, 
  652.       e_distanceJoint, e_pulleyJoint, e_mouseJoint, e_gearJoint, e_fixedJoint);
  653.    Tb2LimitState = (e_inactiveLimit, e_atLowerLimit, e_atUpperLimit, e_equalLimits);
  654.    Tb2Jacobian = record
  655.       linear1, linear2: TVector2;
  656.       angular1, angular2: Float;
  657.       {$IFDEF OP_OVERLOAD}
  658.       procedure SetZero;
  659.       procedure SetValue(const x1, x2: TVector2; a1, a2: Float);
  660.       function Compute(const x1, x2: TVector2; a1, a2: Float): Float; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  661.       {$ENDIF}      
  662.    end;
  663.    /// A joint edge is used to connect bodies and joints together
  664.    /// in a joint graph where each body is a node and each joint
  665.    /// is an edge. A joint edge belongs to a doubly linked list
  666.    /// maintained in each attached body. Each joint has two joint
  667.    /// nodes, one for each attached body.
  668.    Pb2JointEdge = ^Tb2JointEdge;
  669.    Tb2JointEdge = record
  670.       other: Tb2Body; ///< provides quick access to the other body attached.
  671.       joint: Tb2Joint; ///< the joint
  672.       prev, next: Pb2JointEdge;
  673.    end;
  674.    /// Joint definitions are used to construct joints.
  675.    Tb2JointDef = class
  676.    public            
  677.       JointType: Tb2JointType; /// The joint type is set automatically for concrete joint types.
  678.       userData: Pointer; /// Use this to attach application specific data to your joints.
  679.       body1, body2: Tb2Body ; /// The attached bodies.
  680.       collideConnected: Boolean; /// Set this flag to True if the attached bodies should collide.
  681.       constructor Create;
  682.    end;  
  683.    /// The base joint class. Joints are used to constraint two bodies together in
  684.    /// various fashions. Some joints also feature limits and motors.
  685.    Tb2Joint = class
  686.    protected     
  687.       procedure InitVelocityConstraints(const step: Tb2TimeStep); virtual; abstract;
  688.       procedure SolveVelocityConstraints(const step: Tb2TimeStep); virtual; abstract;
  689.       // This returns True if the position errors are within tolerance.
  690.       procedure InitPositionConstraints; virtual;
  691.       function SolvePositionConstraints: Boolean; virtual; abstract;
  692.    
  693.    public
  694.       m_type: Tb2JointType;
  695.       m_prev, m_next: Tb2Joint;
  696.       m_node1, m_node2: Tb2JointEdge; 
  697.       m_body1, m_body2: Tb2Body;
  698.       m_inv_dt: Float;
  699.       m_islandFlag, m_collideConnected: Boolean;
  700.       m_userData: Pointer;
  701.       constructor Create(def: Tb2JointDef);
  702.       /// Get the anchor point on body1 in world coordinates.
  703.       function GetAnchor1: TVector2; virtual; abstract;
  704.       /// Get the anchor point on body2 in world coordinates.
  705.       function GetAnchor2: TVector2; virtual; abstract;
  706.       /// Get the reaction force on body2 at the joint anchor.
  707.       function GetReactionForce: TVector2; virtual; abstract;
  708.       /// Get the reaction torque on body2.
  709.       function GetReactionTorque: Float; virtual; abstract;
  710.       property GetType: Tb2JointType read m_type;
  711.       property GetBody1: Tb2Body read m_body1;
  712.       property GetBody2: Tb2Body read m_body2;
  713.    end;
  714.    //////////////////////////////////////////////////////////////
  715.    // Body
  716.    /// A body definition holds all the data needed to construct a rigid body.
  717.    /// You can safely re-use body definitions.
  718.    Tb2BodyDef = class
  719.    public
  720.       /// You can use this to initialized the mass properties of the body.
  721.       /// If you prefer, you can set the mass properties after the shapes
  722.       /// have been added using b2Body::SetMassFromShapes.
  723.       massData: Tb2MassData;
  724.       userData: Pointer; /// Use this to store application specific body data.
  725.       /// The world position of the body. Avoid creating bodies at the origin
  726.       /// since this can lead to many overlapping shapes.
  727.       position: TVector2;
  728.       angle: Float; // The world angle of the body in radians.
  729.       /// Linear damping is use to reduce the linear velocity. The damping parameter
  730.       /// can be larger than 1.0f but the damping effect becomes sensitive to the
  731.       /// time step when the damping parameter is large.
  732.       linearDamping: Float;
  733.       /// Angular damping is use to reduce the angular velocity. The damping parameter
  734.       /// can be larger than 1.0f but the damping effect becomes sensitive to the
  735.       /// time step when the damping parameter is large.
  736.       angularDamping: Float;
  737.       /// Set this flag to false if this body should never fall asleep. Note that
  738.       /// this increases CPU usage.
  739.       allowSleep: Boolean;
  740.       isSleeping: Boolean; /// Is this body initially sleeping?
  741.       fixedRotation: Boolean; /// Should this body be prevented from rotating? Useful for characters.
  742.       /// Is this a fast moving body that should be prevented from tunneling through
  743.       /// other moving bodies? Note that all bodies are prevented from tunneling through
  744.       /// static bodies.
  745.       /// @warning You should use this flag sparingly since it increases processing time.
  746.       isBullet: Boolean;
  747.       constructor Create;
  748.    end;
  749.    /// A rigid body.
  750.    Tb2BodyType = (e_staticType, e_dynamicType, e_maxTypes);
  751.    Tb2Body = class
  752.    private
  753.       destructor Destroy2; // Only free heap
  754.    
  755.       function SynchronizeShapes: Boolean;
  756.       procedure SynchronizeTransform;
  757.       // This is used to prevent connected bodies from colliding.
  758.       // It may lie, depending on the collideConnected flag.
  759.       function IsConnected(other: Tb2Body): Boolean;
  760.       procedure Advance(t: Float);
  761.    public
  762.       m_flags: UInt16;
  763.       m_type: Tb2BodyType;
  764.       m_xf: Tb2XForm; // the body origin transform
  765.       m_sweep: Tb2Sweep; // the swept motion for CCD
  766.       m_linearVelocity: TVector2;
  767.       m_angularVelocity: Float;
  768.       m_force: TVector2;
  769.       m_torque: Float;
  770.       m_world: Tb2World;
  771.       m_prev, m_next: Tb2Body;
  772.       m_shapeList: Tb2Shape;
  773.       m_shapeCount: Int32;
  774.       m_jointList: Pb2JointEdge;
  775.       m_contactList: Pb2ContactEdge;
  776.       m_mass, m_invMass: Float;
  777.       m_I, m_invI: Float;
  778.       m_linearDamping: Float;
  779.       m_angularDamping: Float;
  780.       m_sleepTime: Float;
  781.       m_userData: Pointer;
  782.       constructor Create(bd: Tb2BodyDef; world: Tb2World);
  783.       destructor Destroy; override;        
  784.       /// Creates a shape and attach it to this body.
  785.       /// @param shapeDef the shape definition.
  786.       /// @warning This function is locked during callbacks.
  787.       function CreateShape(shapeDef: Tb2ShapeDef; AutoFreeShapeDef: Boolean = True): Tb2Shape;
  788.       /// Destroy a shape. This removes the shape from the broad-phase and
  789.       /// therefore destroys any contacts associated with this shape. All shapes
  790.       /// attached to a body are implicitly destroyed when the body is destroyed.
  791.       /// @param shape the shape to be removed.
  792.       /// @warning This function is locked during callbacks.
  793.       procedure DestroyShape(s: Tb2Shape; DoFree: Boolean = True);
  794.       /// Set the mass properties. Note that this changes the center of mass position.
  795.       /// If you are not sure how to compute mass properties, use SetMassFromShapes.
  796.       /// The inertia tensor is assumed to be relative to the center of mass.
  797.       /// @param massData the mass properties.
  798.       procedure SetMass(const massData: Tb2MassData);
  799.       /// Compute the mass properties from the attached shapes. You typically call this
  800.       /// after adding all the shapes. If you add or remove shapes later, you may want
  801.       /// to call this again. Note that this changes the center of mass position.
  802.       procedure SetMassFromShapes;
  803.       /// Set the position of the body's origin and rotation (radians).
  804.       /// This breaks any contacts and wakes the other bodies.
  805.       /// @param position the new world position of the body's origin (not necessarily
  806.       /// the center of mass).
  807.       /// @param angle the new world rotation angle of the body in radians.
  808.       /// @return false if the movement put a shape outside the world. In this case the
  809.       /// body is automatically frozen.
  810.       function SetXForm(const position: TVector2; angle: Float): Boolean;
  811.       /// Set the linear velocity of the center of mass.
  812.       /// @param v the new linear velocity of the center of mass.
  813.       procedure SetLinearVelocity(const v: TVector2); {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  814.       /// Set the angular velocity.
  815.       /// @param omega the new angular velocity in radians/second.
  816.       procedure SetAngularVelocity(omega: Float); {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  817.       /// Apply a force at a world point. If the force is not
  818.       /// applied at the center of mass, it will generate a torque and
  819.       /// affect the angular velocity. This wakes up the body.
  820.       /// @param force the world force vector, usually in Newtons (N).
  821.       /// @param point the world position of the point of application.
  822.       procedure ApplyForce(const force, point: TVector2);
  823.       /// Apply a torque. This affects the angular velocity
  824.       /// without affecting the linear velocity of the center of mass.
  825.       /// This wakes up the body.
  826.       /// @param torque about the z-axis (out of the screen), usually in N-m.
  827.       procedure ApplyTorque(torque: Float);
  828.       /// Apply an impulse at a point. This immediately modifies the velocity.
  829.       /// It also modifies the angular velocity if the point of application
  830.       /// is not at the center of mass. This wakes up the body.
  831.       /// @param impulse the world impulse vector, usually in N-seconds or kg-m/s.
  832.       /// @param point the world position of the point of application.
  833.       procedure ApplyImpulse(const impulse, point: TVector2);
  834.       /// Get the world coordinates of a point given the local coordinates.
  835.       /// @param localPoint a point on the body measured relative the the body's origin.
  836.       /// @return the same point expressed in world coordinates.
  837.       function GetWorldPoint(const localPoint: TVector2): TVector2; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  838.       /// Get the world coordinates of a vector given the local coordinates.
  839.       /// @param localVector a vector fixed in the body.
  840.       /// @return the same vector expressed in world coordinates.
  841.       function GetWorldVector(const localVector: TVector2): TVector2; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  842.       /// Gets a local point relative to the body's origin given a world point.
  843.       /// @param a point in world coordinates.
  844.       /// @return the corresponding local point relative to the body's origin.
  845.       function GetLocalPoint(const worldPoint: TVector2): TVector2; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  846.       /// Gets a local vector given a world vector.
  847.       /// @param a vector in world coordinates.
  848.       /// @return the corresponding local vector.
  849.       function GetLocalVector(const worldVector: TVector2): TVector2; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  850.       /// Get the world linear velocity of a world point attached to this body.
  851.       /// @param a point in world coordinates.
  852.       /// @return the world velocity of a point.
  853.       function GetLinearVelocityFromWorldPoint(const worldPoint: TVector2): TVector2; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  854.       /// Get the world velocity of a local point.
  855.       /// @param a point in local coordinates.
  856.       /// @return the world velocity of a point.
  857.       function GetLinearVelocityFromLocalPoint(const localPoint: TVector2): TVector2; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  858.       /// Is this body treated like a bullet for continuous collision detection?
  859.       function IsBullet: Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  860.       /// Should this body be treated like a bullet for continuous collision detection?
  861.       procedure SetBullet(flag: Boolean);
  862.       /// Is this body static (immovable)?
  863.       function IsStatic: Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  864.       /// Is this body dynamic (movable)?
  865.       function IsDynamic: Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  866.       /// Is this body frozen?
  867.       function IsFrozen: Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  868.       /// Is this body sleeping (not simulating).
  869.       function IsSleeping: Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  870.       /// You can disable sleeping on this body.
  871.       procedure AllowSleeping(flag: Boolean);
  872.       /// Wake up this body so it will begin simulating.
  873.       procedure WakeUp;
  874.       /// Put this body to sleep so it will stop simulating.
  875.       /// This also sets the velocity to zero.
  876.       procedure PutToSleep;
  877.       ////////////////////////////////////
  878.       property GetAngle: Float read m_sweep.a;
  879.       property GetPosition: TVector2 read m_xf.position;
  880.       property GetWorldCenter: TVector2 read m_sweep.c;
  881.       property GetLocalCenter: TVector2 read m_sweep.localCenter;
  882.       property GetLinearVelocity: TVector2 read m_linearVelocity;
  883.       property GetAngularVelocity: Float read m_angularVelocity;
  884.       property GetMass: Float read m_mass;
  885.       property GetInertia: Float read m_I;
  886.       property GetShapeList: Tb2Shape read m_shapeList;
  887.       property GetJointList: Pb2JointEdge read m_jointList;
  888.       property GetNext: Tb2Body read m_next;
  889.       property UserData: Pointer read m_userData write m_userData;
  890.       property GetWorld: Tb2World read m_world;
  891.    end;
  892.    ///////////////////////////////////////////////
  893.    // Specific implementations
  894.    Tb2CircleDef = class(Tb2ShapeDef)
  895.    public
  896.       localPosition: TVector2;
  897.       radius: Float;
  898.       constructor Create;
  899.    end;
  900.    Tb2CircleShape = class(Tb2Shape)
  901.    public
  902.       m_radius: Float;
  903.       m_localPosition: TVector2; // Local position in parent body
  904.       constructor Create(def: Tb2ShapeDef);
  905.       procedure UpdateSweepRadius(const center: TVector2); override;
  906.       function TestPoint(const transform: Tb2XForm; const p: TVector2): Boolean; override;
  907.       function TestSegment(const xf: Tb2XForm; var lambda: Float; var normal: TVector2;
  908.          const segment: Tb2Segment; maxLambda: Float): Boolean; override;
  909.       procedure ComputeAABB(var aabb: Tb2AABB; const xf: Tb2XForm); override;
  910.       procedure ComputeSweptAABB(var aabb: Tb2AABB; const xf1, xf2: Tb2XForm); override;
  911.       procedure ComputeMass(var massData: Tb2MassData); override;
  912.       /// Get the radius of this circle.
  913.       property GetRadius: Float read m_radius;
  914.    end;
  915.    /// Convex polygon. The vertices must be in CCW order for a right-handed
  916.    /// coordinate system with the z-axis coming out of the screen.
  917.    Tb2PolygonDef = class(Tb2ShapeDef)
  918.    public
  919.       /// The polygon vertices in local coordinates.
  920.       vertices: Tb2PolyVertices;
  921.       vertexCount: Int32;
  922.       constructor Create;
  923.       /// Build vertices to represent an axis-aligned box.
  924.       /// @param hx the half-width.
  925.       /// @param hy the half-height.
  926.       procedure SetAsBox(hx, hy: Float); overload;
  927.       /// Build vertices to represent an oriented box.
  928.       /// @param hx the half-width.
  929.       /// @param hy the half-height.
  930.       /// @param center the center of the box in local coordinates.
  931.       /// @param angle the rotation of the box in local coordinates.
  932.       procedure SetAsBox(hx, hy: Float; const center: TVector2; angle: Float); overload;
  933.    end;
  934.    /// A convex polygon.
  935.    Tb2PolygonShape = class(Tb2Shape)
  936.    private
  937.       pm_vertices, pm_normals, pm_coreVertices: PVector2;
  938.    public
  939.       m_centroid: TVector2; // Local position of the polygon centroid.
  940.       m_obb: Tb2OBB; // The oriented bounding box relative to the parent body.
  941.       m_vertices: Tb2PolyVertices;
  942.       m_normals: Tb2PolyVertices;
  943.       m_coreVertices: Tb2PolyVertices;
  944.       m_vertexCount: Int32;
  945.       constructor Create(const def: Tb2ShapeDef);
  946.     procedure UpdateSweepRadius(const center: TVector2); override;
  947.       function TestPoint(const transform: Tb2XForm; const p: TVector2): Boolean; override;
  948.       function TestSegment(const xf: Tb2XForm; var lambda: Float; var normal: TVector2;
  949.          const segment: Tb2Segment; maxLambda: Float): Boolean; override;
  950.       procedure ComputeAABB(var aabb: Tb2AABB; const xf: Tb2XForm); override;
  951.       procedure ComputeSweptAABB(var aabb: Tb2AABB; const xf1, xf2: Tb2XForm); override;
  952.       procedure ComputeMass(var massData: Tb2MassData); override;
  953.       /// Get the first vertex and apply the supplied transform.
  954.       function GetFirstVertex(const xf: Tb2XForm): TVector2;
  955.       /// Get the centroid and apply the supplied transform.
  956.       function Centroid(const xf: Tb2XForm): TVector2;
  957.       /// Get the support point in the given world direction.
  958.       /// Use the supplied transform.
  959.       function Support(const xf: Tb2XForm; const d: TVector2): TVector2;
  960.       property GetVertices: PVector2 read pm_vertices;
  961.       /// Get the core vertices in local coordinates. These vertices
  962.       /// represent a smaller polygon that is used for time of impact computations.
  963.       property GetCoreVertices: PVector2 read pm_coreVertices;
  964.       /// Get the edge normal vectors. There is one for each vertex.
  965.       property GetNormals: PVector2 read pm_normals;
  966.       property GetVertexCount: Integer read m_vertexCount;
  967.    end;
  968.    ////////////////////////////////////////////////////////////
  969.    Tb2CircleContact = class(Tb2Contact)
  970.    public
  971.       m_manifold: Tb2Manifold;
  972.       constructor Create(shape1, shape2: Tb2Shape); override;
  973.       procedure Evaluate(listener: Tb2ContactListener); override;
  974.       function GetManifolds: Pb2Manifold; override;
  975.    end;
  976.    Tb2PolyAndCircleContact = class(Tb2Contact)
  977.    public
  978.       m_manifold: Tb2Manifold;
  979.       constructor Create(shape1, shape2: Tb2Shape); override;
  980.       procedure Evaluate(listener: Tb2ContactListener); override;
  981.       function GetManifolds: Pb2Manifold; override;
  982.    end;
  983.    Tb2PolygonContact = class(Tb2Contact)
  984.    public
  985.       m_manifold: Tb2Manifold;
  986.       constructor Create(shape1, shape2: Tb2Shape); override;
  987.       procedure Evaluate(listener: Tb2ContactListener); override;
  988.       function GetManifolds: Pb2Manifold; override;
  989.    end;
  990.    ////////////////////////////////////////////////////////////
  991.    /// Distance joint definition. This requires defining an
  992.    /// anchor point on both bodies and the non-zero length of the
  993.    /// distance joint. The definition uses local anchor points
  994.    /// so that the initial configuration can violate the constraint
  995.    /// slightly. This helps when saving and loading a game.
  996.    /// @warning Do not use a zero or short length.
  997.    Tb2DistanceJointDef = class(Tb2JointDef)
  998.    public
  999.       localAnchor1: TVector2; /// The local anchor point relative to body1's origin.
  1000.       localAnchor2: TVector2; /// The local anchor point relative to body2's origin.
  1001.       length : Float; /// The equilibrium length between the anchor points.
  1002.       frequencyHz: Float; /// The response speed.
  1003.       dampingRatio: Float; /// The damping ratio. 0 = no damping, 1 = critical damping.
  1004.       constructor Create;
  1005.       procedure Initialize(body1, body2: Tb2Body; const anchor1, anchor2: TVector2);
  1006.    end;
  1007.    /// A distance joint constrains two points on two bodies
  1008.    /// to remain at a fixed distance from each other. You can view
  1009.    /// this as a massless, rigid rod.
  1010.    Tb2DistanceJoint = class(Tb2Joint)
  1011.    public
  1012.       m_localAnchor1, m_localAnchor2, m_u: TVector2;
  1013.       m_frequencyHz, m_dampingRatio: Float;
  1014.       m_gamma, m_bias, m_impulse,
  1015.       m_mass, // effective mass for the constraint.
  1016.       m_length: Float;
  1017.       constructor Create(def: Tb2DistanceJointDef);
  1018.       function GetAnchor1: TVector2; override;
  1019.       function GetAnchor2: TVector2; override;
  1020.       function GetReactionForce: TVector2; override;
  1021.       function GetReactionTorque: Float; override;
  1022.       procedure InitVelocityConstraints(const step: Tb2TimeStep); override;
  1023.       procedure SolveVelocityConstraints(const step: Tb2TimeStep); override;
  1024.       function SolvePositionConstraints: Boolean; override;
  1025.    end;
  1026.    /// Prismatic joint definition. This requires defining a line of
  1027.    /// motion using an axis and an anchor point. The definition uses local
  1028.    /// anchor points and a local axis so that the initial configuration
  1029.    /// can violate the constraint slightly. The joint translation is zero
  1030.    /// when the local anchor points coincide in world space. Using local
  1031.    /// anchors and a local axis helps when saving and loading a game.
  1032.    Tb2PrismaticJointDef = class(Tb2JointDef)
  1033.    public
  1034.       localAnchor1: TVector2;
  1035.       localAnchor2: TVector2;
  1036.       localAxis1: TVector2; /// The local translation axis in body1.
  1037.       referenceAngle: Float; /// The constrained angle between the bodies: body2_angle - body1_angle.
  1038.       enableLimit: Boolean; /// Enable/disable the joint limit.
  1039.       lowerTranslation: Float; /// The lower translation limit, usually in meters.
  1040.       upperTranslation: Float; /// The upper translation limit, usually in meters.
  1041.       enableMotor: Boolean; /// Enable/disable the joint motor.
  1042.       maxMotorForce: Float; /// The maximum motor torque, usually in N-m.
  1043.       motorSpeed: Float; /// The desired motor speed in radians per second.
  1044.       constructor Create;
  1045.       procedure Initialize(body1, body2: Tb2Body; const anchor, axis: TVector2); // world anchor and world axis
  1046.    end;
  1047.    /// A prismatic joint. This joint provides one degree of freedom: translation
  1048.    /// along an axis fixed in body1. Relative rotation is prevented. You can
  1049.    /// use a joint limit to restrict the range of motion and a joint motor to
  1050.    /// drive the motion or to model joint friction.
  1051.    Tb2PrismaticJoint = class(Tb2Joint)
  1052.    public
  1053.       m_localAnchor1, m_localAnchor2, m_localXAxis1, m_localYAxis1: TVector2;
  1054.       m_refAngle: Float;
  1055.       m_linearJacobian: Tb2Jacobian;
  1056.       m_linearMass: Float; // effective mass for point-to-line constraint.
  1057.       m_force: Float;
  1058.       m_angularMass: Float; // effective mass for angular constraint.
  1059.       m_torque: Float;
  1060.       m_motorJacobian: Tb2Jacobian;
  1061.       m_motorMass, // effective mass for motor/limit translational constraint.
  1062.       m_motorForce,
  1063.       m_limitForce,
  1064.       m_limitPositionImpulse: Float;
  1065.       m_lowerTranslation, m_upperTranslation: Float;
  1066.       m_maxMotorForce, m_motorSpeed: Float;
  1067.       m_enableLimit: Boolean;
  1068.       m_enableMotor: Boolean;
  1069.       m_limitState: Tb2LimitState;
  1070.       constructor Create(def: Tb2PrismaticJointDef);
  1071.       function GetAnchor1: TVector2; override;
  1072.       function GetAnchor2: TVector2; override;
  1073.       function GetReactionForce: TVector2; override;
  1074.       function GetReactionTorque: Float; override;
  1075.       procedure InitVelocityConstraints(const step: Tb2TimeStep); override;
  1076.       procedure SolveVelocityConstraints(const step: Tb2TimeStep); override;
  1077.       function SolvePositionConstraints: Boolean; override;
  1078.       /// Get the current joint translation, usually in meters.
  1079.       function GetJointTranslation: Float;
  1080.       /// Get the current joint translation speed, usually in meters per second.
  1081.       function GetJointSpeed: Float;
  1082.       /// Set the joint limits, usually in meters.
  1083.       procedure SetLimits(lower, upper: Float);
  1084.       property GetMotorSpeed: Float read m_motorSpeed; // usually in meters per second.
  1085.       property GetMotorForce: Float read m_motorForce; // usually in N.
  1086.       property LimitEnabled: Boolean read m_enableLimit write m_enableLimit;
  1087.       property GetLowerLimit: Float read m_lowerTranslation;
  1088.       property GetUpperLimit: Float read m_upperTranslation;
  1089.       property MotorEnabled: Boolean read m_enableMotor write m_enableMotor;
  1090.       property MotorSpeed: Float read m_motorSpeed write m_motorSpeed;
  1091.       property MaxMotorForce: Float read m_maxMotorForce write m_maxMotorForce;
  1092.    end;
  1093.    /// Mouse joint definition. This requires a world target point, tuning parameters, and the time step.
  1094.    Tb2MouseJointDef = class(Tb2JointDef)
  1095.    public
  1096.       /// The initial world target point. This is assumed to coincide with the body anchor initially.
  1097.       target: TVector2;
  1098.       /// The maximum constraint force that can be exerted
  1099.       /// to move the candidate body. Usually you will express
  1100.       /// as some multiple of the weight (multiplier * mass * gravity).
  1101.       maxForce: Float;
  1102.       frequencyHz: Float; /// The response speed.
  1103.       dampingRatio: Float; /// The damping ratio. 0 = no damping, 1 = critical damping.
  1104.       timeStep: Float; /// The time step used in the simulation.
  1105.       constructor Create;
  1106.    end;
  1107.    /// A mouse joint is used to make a point on a body track a
  1108.    /// specified world point. This a soft constraint with a maximum
  1109.    /// force. This allows the constraint to stretch and without
  1110.    /// applying huge forces.
  1111.    Tb2MouseJoint = class(Tb2Joint)
  1112.    public
  1113.       m_localAnchor, m_target, m_impulse: TVector2;
  1114.       m_mass: TMatrix22; // effective mass for point-to-point constraint.
  1115.       m_C: TVector2; // position error
  1116.       m_maxForce: Float;
  1117.       m_beta: Float; // bias factor
  1118.       m_gamma: Float; // softness
  1119.       constructor Create(def: Tb2MouseJointDef);
  1120.       function GetAnchor1: TVector2; override;
  1121.       function GetAnchor2: TVector2; override;
  1122.       function GetReactionForce: TVector2; override;
  1123.       function GetReactionTorque: Float; override;
  1124.       procedure InitVelocityConstraints(const step: Tb2TimeStep); override;
  1125.       procedure SolveVelocityConstraints(const step: Tb2TimeStep); override;
  1126.       function SolvePositionConstraints: Boolean; override;
  1127.     procedure SetTarget(const target: TVector2); /// Use this to update the target point.
  1128.    end;
  1129.    /// Pulley joint definition. This requires two ground anchors,
  1130.    /// two dynamic body anchor points, max lengths for each side,
  1131.    /// and a pulley ratio.
  1132.    Tb2PulleyJointDef = class(Tb2JointDef)
  1133.    public
  1134.       groundAnchor1: TVector2; /// The first ground anchor in world coordinates. This point never moves.
  1135.       groundAnchor2: TVector2; /// The second ground anchor in world coordinates. This point never moves.
  1136.       localAnchor1: TVector2; /// The local anchor point relative to body1's origin.
  1137.       localAnchor2: TVector2; /// The local anchor point relative to body2's origin.
  1138.       length1: Float; /// The a reference length for the segment attached to body1.
  1139.       maxLength1: Float; /// The maximum length of the segment attached to body1.
  1140.       length2: Float; /// The a reference length for the segment attached to body2.
  1141.       maxLength2: Float; /// The maximum length of the segment attached to body2.
  1142.       ratio: Float; /// The pulley ratio, used to simulate a block-and-tackle.
  1143.       constructor Create;
  1144.       /// Initialize the bodies, anchors, lengths, max lengths, and ratio using the world anchors.
  1145.       procedure Initialize(body1, body2: Tb2Body; const groundAnchor1, groundAnchor2,
  1146.         anchor1, anchor2: TVector2; ratio: Float);
  1147.    end;
  1148.    /// The pulley joint is connected to two bodies and two fixed ground points.
  1149.    /// The pulley supports a ratio such that:
  1150.    /// length1 + ratio * length2 <= constant
  1151.    /// Yes, the force transmitted is scaled by the ratio.
  1152.    /// The pulley also enforces a maximum length limit on both sides. This is
  1153.    /// useful to prevent one side of the pulley hitting the top.
  1154.    Tb2PulleyJoint = class(Tb2Joint)
  1155.    public
  1156.       m_ground: Tb2Body;
  1157.       m_groundAnchor1, m_groundAnchor2, m_localAnchor1, m_localAnchor2: TVector2;
  1158.       m_u1, m_u2: TVector2;
  1159.       m_constant, m_ratio: Float;
  1160.       m_maxLength1, m_maxLength2: Float;
  1161.       m_pulleyMass, m_limitMass1, m_limitMass2: Float; // Effective masses
  1162.       m_force, m_limitForce1, m_limitForce2: Float; // Impulses for accumulation/warm starting.
  1163.       // Position impulses for accumulation.
  1164.       m_positionImpulse, m_limitPositionImpulse1, m_limitPositionImpulse2: Float;
  1165.       m_state, m_limitState1, m_limitState2: Tb2LimitState;
  1166.       constructor Create(def: Tb2PulleyJointDef);
  1167.       function GetAnchor1: TVector2; override;
  1168.       function GetAnchor2: TVector2; override;
  1169.       function GetReactionForce: TVector2; override;
  1170.       function GetReactionTorque: Float; override;
  1171.       procedure InitVelocityConstraints(const step: Tb2TimeStep); override;
  1172.       procedure SolveVelocityConstraints(const step: Tb2TimeStep); override;
  1173.       function SolvePositionConstraints: Boolean; override;
  1174.       function GetLength1: Float;
  1175.       function GetLength2: Float;
  1176.       function GetGroundAnchor1: TVector2;
  1177.       function GetGroundAnchor2: TVector2;
  1178.       property GetRatio: Float read m_ratio;
  1179.    end;
  1180.    /// Revolute joint definition. This requires defining an
  1181.    /// anchor point where the bodies are joined. The definition
  1182.    /// uses local anchor points so that the initial configuration
  1183.    /// can violate the constraint slightly. You also need to
  1184.    /// specify the initial relative angle for joint limits. This
  1185.    /// helps when saving and loading a game.
  1186.    /// The local anchor points are measured from the body's origin
  1187.    /// rather than the center of mass because:
  1188.    /// 1. you might not know where the center of mass will be.
  1189.    /// 2. if you add/remove shapes from a body and recompute the mass,
  1190.    ///    the joints will be broken.
  1191.    Tb2RevoluteJointDef = class(Tb2JointDef)
  1192.    public
  1193.       localAnchor1: TVector2; /// The local anchor point relative to body1's origin.
  1194.       localAnchor2: TVector2; /// The local anchor point relative to body2's origin.
  1195.       referenceAngle: Float; /// The body2 angle minus body1 angle in the reference state (radians).
  1196.       enableLimit: Boolean; /// A flag to enable joint limits.
  1197.       lowerAngle, upperAngle: Float; /// The lower(upper) angle for the joint limit (radians).
  1198.       enableMotor: Boolean; /// A flag to enable the joint motor.
  1199.       motorSpeed: Float; /// The desired motor speed. Usually in radians per second.
  1200.       maxMotorTorque: Float; /// The maximum motor torque used to achieve the desired motor speed. Usually in N-m.
  1201.       constructor Create;
  1202.      /// Initialize the bodies, anchors, and reference angle using the world anchor.
  1203.      procedure Initialize( body1, body2: Tb2Body; const anchor: TVector2);
  1204.    end;
  1205.    /// A revolute joint constrains to bodies to share a common point while they
  1206.    /// are free to rotate about the point. The relative rotation about the shared
  1207.    /// point is the joint angle. You can limit the relative rotation with
  1208.    /// a joint limit that specifies a lower and upper angle. You can use a motor
  1209.    /// to drive the relative rotation about the shared point. A maximum motor torque
  1210.    /// is provided so that infinite forces are not generated.
  1211.    Tb2RevoluteJoint = class(Tb2Joint)
  1212.    public
  1213.       m_localAnchor1, m_localAnchor2: TVector2; // relative
  1214.       m_pivotForce: TVector2;
  1215.       m_motorForce, m_limitForce, m_limitPositionImpulse: Float;
  1216.       m_pivotMass: TMatrix22; // effective mass for point-to-point constraint.
  1217.       m_motorMass: Float; // effective mass for motor/limit angular constraint.
  1218.       m_enableMotor: Boolean;
  1219.       m_maxMotorTorque, m_motorSpeed: Float;
  1220.       m_enableLimit: Boolean;
  1221.       m_referenceAngle, m_lowerAngle, m_upperAngle: Float;
  1222.       m_limitState: Tb2LimitState;
  1223.       constructor Create(def: Tb2RevoluteJointDef);
  1224.       function GetAnchor1: TVector2; override;
  1225.       function GetAnchor2: TVector2; override;
  1226.       function GetReactionForce: TVector2; override;
  1227.       function GetReactionTorque: Float; override;
  1228.       procedure InitVelocityConstraints(const step: Tb2TimeStep); override;
  1229.       procedure SolveVelocityConstraints(const step: Tb2TimeStep); override;
  1230.       function SolvePositionConstraints: Boolean; override;
  1231.       function GetJointAngle: Float;
  1232.       function GetJointSpeed: Float; /// Get the current joint angle speed in radians per second.
  1233.       property LimitEnabled: Boolean read m_enableLimit write m_enableLimit;
  1234.       property LowerLimit: Float read m_lowerAngle write m_lowerAngle;
  1235.       property UpperLimit: Float read m_upperAngle write m_upperAngle;
  1236.       property MotorEnabled: Boolean read m_enableMotor write m_enableMotor;
  1237.       property MotorSpeed: Float read m_motorSpeed write m_motorSpeed; /// Get the motor speed in radians per second.
  1238.       property MaxMotorTorque: Float read m_maxMotorTorque write m_maxMotorTorque;
  1239.       property MotorTorque: Float read m_motorForce write m_motorForce;
  1240.    end;
  1241.    /// Gear joint definition. This definition requires two existing
  1242.    /// revolute or prismatic joints (any combination will work).
  1243.    /// The provided joints must attach a dynamic body to a static body.
  1244.    Tb2GearJointDef = class(Tb2JointDef)
  1245.    public
  1246.       joint1: Tb2Joint; /// The first revolute/prismatic joint attached to the gear joint.
  1247.       joint2: Tb2Joint; /// The second revolute/prismatic joint attached to the gear joint.
  1248.       ratio: Float; /// The gear ratio.
  1249.       constructor Create;
  1250.    end;
  1251.    /// A gear joint is used to connect two joints together. Either joint
  1252.    /// can be a revolute or prismatic joint. You specify a gear ratio
  1253.    /// to bind the motions together:
  1254.    /// coordinate1 + ratio * coordinate2 = constant
  1255.    /// The ratio can be negative or positive. If one joint is a revolute joint
  1256.    /// and the other joint is a prismatic joint, then the ratio will have units
  1257.    /// of length or units of 1/length.
  1258.    /// @warning The revolute and prismatic joints must be attached to
  1259.    /// fixed bodies (which must be body1 on those joints).
  1260.    Tb2GearJoint = class(Tb2Joint)
  1261.    public
  1262.       m_ground1, m_ground2: Tb2Body;
  1263.       // One of these is nil.
  1264.       m_revolute1: Tb2RevoluteJoint;
  1265.       m_prismatic1: Tb2PrismaticJoint;
  1266.       // One of these is nil.
  1267.       m_revolute2: Tb2RevoluteJoint;
  1268.       m_prismatic2: Tb2PrismaticJoint;
  1269.       m_groundAnchor1, m_groundAnchor2 :TVector2;
  1270.       m_localAnchor1, m_localAnchor2: TVector2;
  1271.       m_J: Tb2Jacobian;
  1272.       m_constant, m_ratio: Float;
  1273.       m_mass: Float; // Effective mass
  1274.       m_force: Float; // Impulse for accumulation/warm starting.
  1275.       constructor Create(def: Tb2GearJointDef);
  1276.       function GetAnchor1: TVector2; override;
  1277.       function GetAnchor2: TVector2; override;
  1278.       function GetReactionForce: TVector2; override;
  1279.       function GetReactionTorque: Float; override;
  1280.       procedure InitVelocityConstraints(const step: Tb2TimeStep); override;
  1281.       procedure SolveVelocityConstraints(const step: Tb2TimeStep); override;
  1282.       function SolvePositionConstraints: Boolean; override;
  1283.       property GetRatio: Float read m_ratio;
  1284.    end;
  1285.    /// FixedJoint: Attaches two bodies rigidly together
  1286.    Tb2FixedJointDef = class(Tb2JointDef)
  1287.    public
  1288.       constructor Create;
  1289.     procedure Initialize(body1, body2: Tb2Body); /// Initialize the bodies.
  1290.    end;
  1291.    /// A fixed joint constrains all degrees of freedom between two bodies
  1292.    /// Author: Jorrit Rouwe
  1293.    /// See: www.jrouwe.nl/fixedjoint/ for more info
  1294.    Tb2FixedJoint = class(Tb2Joint)
  1295.    private
  1296.     procedure CalculateMC; // Get effective constraint mass
  1297.    public
  1298.       // Configured state for bodies
  1299.       m_dp: TVector2; //< Distance between body->GetXForm().position between the two bodies at rest in the reference frame of body1
  1300.       m_a: Float; //< Angle between the bodies at rest
  1301.       m_R0: TMatrix22; //< Rotation matrix of m_a
  1302.       // State for solving
  1303.       m_inv_dt: Float; //< Stored 1/dt
  1304.       m_d: TVector2; //< Distance between center of masses for this time step (when the shapes of the bodies change, their local centers can change so we derive this from m_dp every frame)
  1305.       m_a1: Float; //< Stored angle of body 1 (a1) to determine if it changed
  1306.       m_c, m_s: Float; //< cos(a1) and sin(a1)
  1307.       m_Ax, m_Ay: Float; //< A = d/dt (R(a1) d)
  1308.       m_mc: array[0..2, 0..2] of Float; //< Effective constraint mass
  1309.       // State after solving
  1310.       m_lambda: array[0..2] of Float; //< Accumulated lambdas for warm starting and returning constraint force
  1311.       constructor Create(def: Tb2FixedJointDef);
  1312.       function GetAnchor1: TVector2; override;
  1313.       function GetAnchor2: TVector2; override;
  1314.       function GetReactionForce: TVector2; override;
  1315.       function GetReactionTorque: Float; override;
  1316.       procedure InitVelocityConstraints(const step: Tb2TimeStep); override;
  1317.       procedure SolveVelocityConstraints(const step: Tb2TimeStep); override;
  1318.       function SolvePositionConstraints: Boolean; override;
  1319.    end;
  1320. //////////////////////////////////
  1321. procedure b2CollideCircles(var manifold: Tb2Manifold;
  1322.    circle1, circle2: Tb2CircleShape; const xf1, xf2: Tb2XForm);
  1323. procedure b2CollidePolygonAndCircle(var manifold: Tb2Manifold;
  1324.    polygon: Tb2PolygonShape; circle: Tb2CircleShape; const xf1, xf2: Tb2XForm);
  1325. procedure b2CollidePolygons(var manifold: Tb2Manifold;
  1326.    polyA, polyB: Tb2PolygonShape; xfA, xfB: Tb2XForm);
  1327. function b2TimeOfImpact(shape1, shape2: Tb2Shape; const sweep1, sweep2: Tb2Sweep): Float;
  1328. function b2Distance(var x1, x2: TVector2; circle1, circle2: Tb2CircleShape;
  1329.    const xf1, xf2: Tb2XForm): Float; overload;
  1330. function b2Distance(var x1, x2: TVector2; poly: Tb2PolygonShape;
  1331.    circle: Tb2CircleShape; const xf1, xf2: Tb2XForm): Float; overload;
  1332. function b2Distance(var x1, x2: TVector2; circle: Tb2CircleShape;
  1333.    poly: Tb2PolygonShape; const xf1, xf2: Tb2XForm): Float; overload; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  1334. function b2Distance(var x1, x2: TVector2; poly1, poly2: Tb2PolygonShape;
  1335.    const xf1, xf2: Tb2XForm): Float; overload;
  1336. function b2Distance(var x1, x2: TVector2; shape1, shape2: Tb2Shape;
  1337.    const xf1, xf2: Tb2XForm): Float; overload;
  1338. /////////////////// Color functions //////
  1339. function MakeColor(r, g, b: Single; a: Single = 1.0): RGBA;
  1340. var
  1341.    g_GJK_Iterations: Int32;
  1342. implementation
  1343. var
  1344.    b2_defaultFilter: Tb2ContactFilter;
  1345. {$IFNDEF CLASSVAR_AVAIL}
  1346.    b2BroadPhase_s_validate: Boolean;
  1347. {$ENDIF}
  1348. const
  1349.    // Tb2Pair.status
  1350.    e_pairBuffered = 1;
  1351.    e_pairRemoved = 2;
  1352.    e_pairFinal = 4;
  1353.    // Tb2Contact.m_flags
  1354.    e_nonSolidFlag = 1;
  1355.    e_slowFlag = 2;
  1356.    e_contact_islandFlag = 4;
  1357.    e_toiFlag = 8;
  1358.    // Tb2Body.m_flags
  1359.    e_frozenFlag = $0002;
  1360.    e_body_islandFlag = $0004;
  1361.    e_sleepFlag = $0008;
  1362.    e_allowSleepFlag = $0010;
  1363.    e_bulletFlag = $0020;
  1364.    e_fixedRotationFlag = $0040;
  1365. function MakeColor(r, g, b: Single; a: Single = 1.0): RGBA;
  1366. begin
  1367.    Result[0] := r;
  1368.    Result[1] := g;
  1369.    Result[2] := b;
  1370.    Result[3] := a;
  1371. end;
  1372. //////////// Implements <b2Contact.cpp> InitializeRegisters and AddType
  1373. type
  1374.    TContactCreateRecord = record
  1375.       ClassType: Tb2ContactClass;
  1376.       Primary: Boolean;
  1377.    end;
  1378. const
  1379.    ContactCreateRecords: array[e_circleShape..e_polygonShape,
  1380.       e_circleShape..e_polygonShape] of TContactCreateRecord = (
  1381.       ((ClassType: Tb2CircleContact; Primary: True),
  1382.        (ClassType: Tb2PolyAndCircleContact; Primary: False)),
  1383.       ((ClassType: Tb2PolyAndCircleContact; Primary: True),
  1384.        (ClassType: Tb2PolygonContact; Primary: True)));
  1385. {$IFNDEF OP_OVERLOAD}
  1386. // Record methods
  1387. function TestSegment(const Self: Tb2Segment; var lambda: Float; 
  1388.    var normal: TVector2; const segment: Tb2Segment; maxLambda: Float): Boolean;
  1389. const
  1390.    k_slop = 100.0 * FLT_EPSILON;
  1391. var
  1392.    s, r, d, n, b: TVector2;
  1393.    denom, a, mu2: Float;
  1394. begin
  1395.    with Self do
  1396.    begin
  1397.       s := segment.p1;
  1398.       r := Subtract(segment.p2, s);
  1399.       d := Subtract(p2, p1);
  1400.       n := b2Cross(d, 1.0);
  1401.       denom := -b2Dot(r, n);
  1402.       // Cull back facing collision and ignore parallel segments.
  1403.       if denom > k_slop then
  1404.       begin
  1405.          // Does the segment intersect the infinite line associated with this segment?
  1406.          b := Subtract(s, p1);
  1407.          a := b2Dot(b, n);
  1408.          if (0.0 <= a) and (a <= maxLambda * denom) then
  1409.          begin
  1410.             mu2 := r.y * b.x - r.x * b.y;
  1411.             // Does the segment intersect this segment?
  1412.             if (-k_slop * denom <= mu2) and (mu2 <= denom * (1.0 + k_slop)) then
  1413.             begin
  1414.                Normalize(n);
  1415.                lambda := a / denom;
  1416.                normal := n;
  1417.                Result := True;
  1418.                Exit;
  1419.             end;
  1420.          end;
  1421.       end;
  1422.    end;
  1423.    Result := False;
  1424. end;
  1425. function IsValid(const AABB: Tb2AABB): Boolean; overload; 
  1426. var
  1427.    d: TVector2;
  1428. begin
  1429.    with AABB do
  1430.    begin
  1431.       d := Subtract(upperBound, lowerBound);
  1432.       Result := (d.x >= 0.0) and (d.y >= 0.0) and 
  1433.          UPhysics2DTypes.IsValid(upperBound) and UPhysics2DTypes.IsValid(lowerBound);
  1434.    end;
  1435. end;
  1436. function IsLower(const bound: Tb2Bound): Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  1437. begin
  1438.    with bound do
  1439.       Result := (value and 1) = 0;
  1440. end;
  1441. function IsUpper(const bound: Tb2Bound): Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  1442. begin
  1443.    with bound do
  1444.       Result := (value and 1) = 1;
  1445. end;
  1446.             
  1447. function GetNext(const proxy: Tb2Proxy): UInt16; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  1448. begin
  1449.    Result := proxy.lowerBounds[0];
  1450. end;
  1451. procedure SetNext(var proxy: Tb2Proxy; Next: UInt16); {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  1452. begin
  1453.    proxy.lowerBounds[0] := Next;
  1454. end;
  1455. function IsValid(const proxy: Tb2Proxy): Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF} overload;
  1456. begin
  1457.    Result := proxy.overlapCount <> b2_invalid;
  1458. end;
  1459. procedure SetBuffered(var pair: Tb2Pair); {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  1460. begin
  1461.    with pair do
  1462.       status := status or e_pairBuffered;
  1463. end;
  1464. procedure ClearBuffered(var pair: Tb2Pair); {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  1465. begin
  1466.    with pair do
  1467.       status := status and (not e_pairBuffered);
  1468. end;
  1469. function IsBuffered(const pair: Tb2Pair): Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  1470. begin
  1471.    with pair do
  1472.       Result := (status and e_pairBuffered) = e_pairBuffered;
  1473. end;
  1474. procedure SetRemoved(var pair: Tb2Pair); {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  1475. begin
  1476.    with pair do
  1477.       status := status or e_pairRemoved;
  1478. end;
  1479. procedure ClearRemoved(var pair: Tb2Pair); {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  1480. begin
  1481.    with pair do
  1482.       status := status and (not e_pairRemoved);
  1483. end;
  1484. function IsRemoved(const pair: Tb2Pair): Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  1485. begin
  1486.    with pair do
  1487.       Result := (status and e_pairRemoved) = e_pairRemoved;
  1488. end;
  1489. procedure SetFinal(var pair: Tb2Pair); {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  1490. begin
  1491.    with pair do
  1492.       status := status or e_pairFinal;
  1493. end;
  1494. function IsFinal(const pair: Tb2Pair): Boolean; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  1495. begin
  1496.    with pair do
  1497.       Result := (status and e_pairFinal) = e_pairFinal;
  1498. end;
  1499. procedure SetZero(var jb: Tb2Jacobian); overload;
  1500. begin
  1501.    with jb do
  1502.    begin
  1503.       SetZero(linear1);
  1504.       SetZero(linear2);
  1505.       angular1 := 0.0;
  1506.       angular2 := 0.0;
  1507.    end;
  1508. end;
  1509. procedure SetValue(var jb: Tb2Jacobian; const x1, x2: TVector2; a1, a2: Float); overload;
  1510. begin
  1511.    with jb do
  1512.    begin
  1513.       linear1 := x1;
  1514.       linear2 := x2;
  1515.       angular1 := a1;
  1516.       angular2 := a2;
  1517.    end;
  1518. end;
  1519. function Compute(var jb: Tb2Jacobian; const x1, x2: TVector2; a1, a2: Float): Float; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  1520. begin
  1521.    with jb do
  1522.       Result := b2Dot(linear1, x1) + angular1 * a1 + b2Dot(linear2, x2) + angular2 * a2;
  1523. end;
  1524. {$ENDIF}
  1525. procedure b2Swap(var a, b: Tb2Bound); {$IFDEF INLINE_AVAIL}inline;{$ENDIF} overload;
  1526. var
  1527.    tmp: Tb2Bound;
  1528. begin
  1529.    tmp := a;
  1530.    a := b;
  1531.    b := tmp;
  1532. end;
  1533. { b2BroadPhase.cpp }
  1534. function BroadPhase_BinarySearch(var bounds: Tb2AxialBoundsArray; count: Int32; value: UInt16): Int32;
  1535. var
  1536.    low, high, mid: Int32;
  1537.    pbm: Pb2Bound;
  1538. begin
  1539.    low := 0;
  1540.    high := count - 1;
  1541.    while (low <= high) do
  1542.    begin
  1543.       mid := (low + high) shr 1;
  1544.       pbm := @bounds[mid];
  1545.       if pbm^.value > value then
  1546.          high := mid - 1
  1547.       else if pbm^.value < value then
  1548.          low := mid + 1
  1549.       else
  1550.       begin
  1551.          Result := mid;
  1552.          Exit;
  1553.       end;
  1554.    end;
  1555.    Result := low;
  1556. end;
  1557. { b2PolygonShape. cpp}
  1558. function ComputeCentroid(const vs: Tb2PolyVertices; count: Int32): TVector2;
  1559. const
  1560.    inv3 = 1 / 3;
  1561. var
  1562.    i: Integer;
  1563.    pRef, p1, p2, p3, e1, e2: TVector2;
  1564.    area, triangleArea: Float;
  1565. begin
  1566.    //b2Assert(count >= 3);    
  1567.    area := 0.0;
  1568.    // pRef is the reference point for forming triangles.
  1569.    // It's location doesn't change the result (except for rounding error).   
  1570.    SetZero(Result);
  1571.    SetZero(pRef);
  1572.   (* // This code would put the reference point inside the polygon.
  1573.    for (int32 i = 0; i < count; ++i)
  1574.    {
  1575.      pRef += vs[i];
  1576.    }
  1577.    pRef *= 1.0f / count; *)
  1578.    for i := 0 to count - 1 do
  1579.    begin
  1580.       // Triangle vertices.
  1581.       p1 := pRef;
  1582.       p2 := vs[i];
  1583.       if i + 1 < count then
  1584.          p3 := vs[i + 1]
  1585.       else
  1586.          p3 := vs[0];   
  1587.       {$IFDEF OP_OVERLOAD}         
  1588.       e1 := p2 - p1;
  1589.       e2 := p3 - p1;
  1590.       {$ELSE}      
  1591.       e1 := Subtract(p2, p1);
  1592.       e2 := Subtract(p3, p1);
  1593.       {$ENDIF}            
  1594.       triangleArea := 0.5 * b2Cross(e1, e2);
  1595.       area := area + triangleArea;
  1596.       // Area weighted centroid    
  1597.       {$IFDEF OP_OVERLOAD}        
  1598.       Result := Result + triangleArea * inv3 * (p1 + p2 + p3);
  1599.       {$ELSE}
  1600.       AddBy(p1, p2);
  1601.       AddBy(p1, p3);
  1602.       MultiplyBy(p1, triangleArea * inv3);
  1603.       AddBy(Result, p1); 
  1604.       {$ENDIF}  
  1605.    end;
  1606.    // Centroid
  1607.    //b2Assert(area > B2_FLT_EPSILON);
  1608.    {$IFDEF OP_OVERLOAD}        
  1609.    Result := Result / area;
  1610.    {$ELSE}   
  1611.    DivideBy(Result, area);
  1612.    {$ENDIF}  
  1613. end;
  1614. // http://www.geometrictools.com/Documentation/MinimumAreaRectangle.pdf
  1615. procedure ComputeOBB(var obb: Tb2OBB; const vs: Tb2PolyVertices; count: Int32);
  1616. var
  1617.    i, j: Integer;
  1618.    p: array[0..b2_maxPolygonVertices] of TVector2;
  1619.    minArea, length, area: Float;
  1620.    root, ux, uy, lower, upper, d, r, center: TVector2;
  1621. begin
  1622.    //b2Assert(count <= b2_maxPolygonVertices);
  1623.    Move(vs, p, SizeOf(vs));
  1624.    p[count] := p[0];
  1625.    minArea := FLT_MAX;
  1626.    for i := 1 to Count - 1 do
  1627.    begin
  1628.       root := p[i - 1];        
  1629.       {$IFDEF OP_OVERLOAD}    
  1630.       ux := p[i] - root;  
  1631.       length := ux.Normalize;
  1632.       //b2Assert(length > B2_FLT_EPSILON);
  1633.       uy.SetValue(-ux.y, ux.x); 
  1634.       lower.SetValue(FLT_MAX, FLT_MAX);
  1635.       upper.SetValue(-FLT_MAX, -FLT_MAX);
  1636.       {$ELSE}
  1637.       ux := Subtract(p[i], root);
  1638.       length := Normalize(ux);
  1639.       //b2Assert(length > B2_FLT_EPSILON);
  1640.       SetValue(uy, -ux.y, ux.x);
  1641.       SetValue(lower, FLT_MAX, FLT_MAX);
  1642.       SetValue(upper, -FLT_MAX, -FLT_MAX);        
  1643.       {$ENDIF}      
  1644.       for j := 0 to Count - 1 do
  1645.       begin     
  1646.          {$IFDEF OP_OVERLOAD}       
  1647.          d := p[j] - root;
  1648.          {$ELSE}
  1649.          d := Subtract(p[j], root);
  1650.          {$ENDIF}
  1651.          r.x := b2Dot(ux, d);
  1652.          r.y := b2Dot(uy, d);
  1653.          lower := b2Min(lower, r);
  1654.          upper := b2Max(upper, r);
  1655.       end;
  1656.       area := (upper.x - lower.x) * (upper.y - lower.y);
  1657.       if area < 0.95 * minArea then
  1658.       begin
  1659.          minArea := area;
  1660.          obb.R.col1 := ux;
  1661.          obb.R.col2 := uy;
  1662.          {$IFDEF OP_OVERLOAD}         
  1663.          center := 0.5 * (lower + upper);
  1664.          obb.center := root + b2Mul(obb.R, center);
  1665.          obb.extents := 0.5 * (upper - lower);
  1666.          {$ELSE}
  1667.          center := Add(lower, upper);
  1668.          MultiplyBy(center, 0.5);
  1669.          obb.center := Add(root, b2Mul(obb.R, center)); 
  1670.          obb.extents := Subtract(upper, lower);
  1671.          MultiplyBy(obb.extents, 0.5);         
  1672.          {$ENDIF}         
  1673.       end;
  1674.    end;
  1675.    //b2Assert(minArea < B2_FLT_MAX);
  1676. end;
  1677. { b2Distance.cpp }
  1678. // GJK using Voronoi regions (Christer Ericson) and region selection
  1679. // optimizations (Casey Muratori).
  1680. // The origin is either in the region of points[1] or in the edge region. The origin is
  1681. // not in region of points[0] because that is the old point.
  1682. type
  1683.    TCalcDistanceVectors = array[0..2] of TVector2;
  1684. function Distance_ProcessTwo(var x1, x2: TVector2; var p1s, p2s,
  1685.    points: TCalcDistanceVectors): Int32;
  1686. var
  1687.    r, d: TVector2;
  1688.    length, lambda: Float;
  1689. begin
  1690.    {$IFDEF OP_OVERLOAD}
  1691.    r := -points[1];
  1692.    d := points[0] - points[1];
  1693.    length := d.Normalize;
  1694.    {$ELSE}
  1695.    r := Negative(points[1]);
  1696.    d := Subtract(points[0], points[1]);
  1697.    length := Normalize(d);   
  1698.    {$ENDIF}
  1699.    lambda := b2Dot(r, d);
  1700.    if (lambda <= 0.0) or (length < FLT_EPSILON) then
  1701.    begin
  1702.       // The simplex is reduced to a point.
  1703.       x1 := p1s[1];
  1704.       x2 := p2s[1];
  1705.       p1s[0] := p1s[1];
  1706.       p2s[0] := p2s[1];
  1707.       points[0] := points[1];
  1708.       Result := 1;
  1709.       Exit;
  1710.    end;
  1711.    // Else in edge region
  1712.    lambda := lambda / length;
  1713.    {$IFDEF OP_OVERLOAD}   
  1714.    x1 := p1s[1] + lambda * (p1s[0] - p1s[1]);
  1715.    x2 := p2s[1] + lambda * (p2s[0] - p2s[1]);
  1716.    {$ELSE}
  1717.    x1 := Subtract(p1s[0], p1s[1]);
  1718.    MultiplyBy(x1, lambda);
  1719.    AddBy(x1, p1s[1]);   
  1720.    x2 := Subtract(p2s[0], p2s[1]);
  1721.    MultiplyBy(x2, lambda);
  1722.    AddBy(x2, p2s[1]);          
  1723.    {$ENDIF}
  1724.    Result := 2;
  1725. end;
  1726. // Possible regions:
  1727. // - points[2]
  1728. // - edge points[0]-points[2]
  1729. // - edge points[1]-points[2]
  1730. // - inside the triangle
  1731. function Distance_ProcessThree(var x1, x2: TVector2; var p1s, p2s,
  1732.    points: TCalcDistanceVectors): Int32;
  1733. var
  1734.    a, b, c, ab, ac, bc: TVector2;
  1735.    tn, td, un, ud, n, vc, va, lambda, vb, denom: Float;
  1736. begin
  1737.    a := points[0];
  1738.    b := points[1];
  1739.    c := points[2];
  1740.    {$IFDEF OP_OVERLOAD}   
  1741.    ab := b - a;
  1742.    ac := c - a;
  1743.    bc := c - b;
  1744.    {$ELSE}
  1745.    ab := Subtract(b, a);
  1746.    ac := Subtract(c, a);
  1747.    bc := Subtract(c, b);
  1748.    {$ENDIF}   
  1749.    //float32 sn := -b2Dot(a, ab), sd := b2Dot(b, ab);
  1750.    tn := -b2Dot(a, ac);
  1751.    td := b2Dot(c, ac);
  1752.    un := -b2Dot(b, bc);
  1753.    ud := b2Dot(c, bc);
  1754.    // In vertex c region?
  1755.    if (td <= 0.0) and (ud <= 0.0) then
  1756.    begin
  1757.       // Single point
  1758.       x1 := p1s[2];
  1759.       x2 := p2s[2];
  1760.       p1s[0] := p1s[2];
  1761.       p2s[0] := p2s[2];
  1762.       points[0] := points[2];
  1763.       Result := 1;
  1764.       Exit;
  1765.    end;
  1766.    // Should not be in vertex a or b region.
  1767.    //B2_NOT_USED(sd);
  1768.    //B2_NOT_USED(sn);
  1769.    //b2Assert(sn > 0.0 || tn > 0.0);
  1770.    //b2Assert(sd > 0.0 || un > 0.0);
  1771.    n := b2Cross(ab, ac);
  1772.    // Should not be in edge ab region.
  1773.    vc := n * b2Cross(a, b);
  1774.    //b2Assert(vc > 0.0 || sn > 0.0 || sd > 0.0);
  1775.    // In edge bc region?
  1776.    va := n * b2Cross(b, c);
  1777.    if (va <= 0.0) and (un >= 0.0) and (ud >= 0.0) and (un + ud > 0.0) then
  1778.    begin
  1779.       //b2Assert(un + ud > 0.0);
  1780.       lambda := un / (un + ud);
  1781.       {$IFDEF OP_OVERLOAD}      
  1782.       x1 := p1s[1] + lambda * (p1s[2] - p1s[1]);
  1783.       x2 := p2s[1] + lambda * (p2s[2] - p2s[1]);
  1784.       {$ELSE}     
  1785.       x1 := Subtract(p1s[2], p1s[1]);
  1786.       MultiplyBy(x1, lambda);
  1787.       AddBy(x1, p1s[1]);
  1788.       x2 := Subtract(p2s[2], p2s[1]);
  1789.       MultiplyBy(x2, lambda);
  1790.       AddBy(x2, p2s[1]);      
  1791.       {$ENDIF}          
  1792.       p1s[0] := p1s[2];
  1793.       p2s[0] := p2s[2];
  1794.       points[0] := points[2];
  1795.       Result := 2;
  1796.       Exit;
  1797.    end;
  1798.    // In edge ac region?
  1799.    vb := n * b2Cross(c, a);
  1800.    if (vb <= 0.0) and (tn >= 0.0) and (td >= 0.0) and (tn + td > 0.0) then
  1801.    begin
  1802.       //b2Assert(tn + td > 0.0);
  1803.       lambda := tn / (tn + td);
  1804.       {$IFDEF OP_OVERLOAD}      
  1805.       x1 := p1s[0] + lambda * (p1s[2] - p1s[0]);
  1806.       x2 := p2s[0] + lambda * (p2s[2] - p2s[0]);
  1807.       {$ELSE}      
  1808.       x1 := Subtract(p1s[2], p1s[0]);
  1809.       MultiplyBy(x1, lambda);
  1810.       AddBy(x1, p1s[0]);
  1811.       x2 := Subtract(p2s[2], p2s[0]);
  1812.       MultiplyBy(x2, lambda);
  1813.       AddBy(x2, p2s[0]);     
  1814.       {$ENDIF}            
  1815.       p1s[1] := p1s[2];
  1816.       p2s[1] := p2s[2];
  1817.       points[1] := points[2];
  1818.       Result := 2;
  1819.       Exit;
  1820.    end;
  1821.    // Inside the triangle, compute barycentric coordinates
  1822.    denom := va + vb + vc;
  1823.    //b2Assert(denom > 0.0);
  1824.    denom := 1.0 / denom;
  1825.    tn := va * denom;
  1826.    td := vb * denom;
  1827.    un := 1.0 - tn - td;
  1828.    {$IFDEF OP_OVERLOAD}   
  1829.    x1 := tn * p1s[0] + td * p1s[1] + un * p1s[2];
  1830.    x2 := tn * p2s[0] + td * p2s[1] + un * p2s[2];
  1831.    {$ELSE}   
  1832.    MultiplyBy(p1s[0], tn);
  1833.    MultiplyBy(p1s[1], td);
  1834.    MultiplyBy(p1s[2], un);
  1835.    x1 := Add(p1s[0], p1s[1], p1s[2]);
  1836.    MultiplyBy(p2s[0], tn);
  1837.    MultiplyBy(p2s[1], td);
  1838.    MultiplyBy(p2s[2], un);
  1839.    x2 := Add(p2s[0], p2s[1], p2s[2]);       
  1840.    {$ENDIF}      
  1841.    Result := 3;
  1842. end;
  1843. function Distance_InPoints(const w: TVector2; var points: TCalcDistanceVectors;
  1844.    pointCount: Int32): Boolean;
  1845. const
  1846.    k_tolerance = 100.0 * FLT_EPSILON;
  1847. var
  1848.    i: Integer;
  1849.    d, m: TVector2;
  1850. begin
  1851.    for i := 0 to pointCount - 1 do
  1852.    begin
  1853.       {$IFDEF OP_OVERLOAD}   
  1854.       d := b2Abs(w - points[i]);
  1855.       {$ELSE}      
  1856.       d := b2Abs(Subtract(w, points[i]));
  1857.       {$ENDIF}            
  1858.       m := b2Max(b2Abs(w), b2Abs(points[i]));
  1859.       if (d.x < k_tolerance * (m.x + 1.0)) and (d.y < k_tolerance * (m.y + 1.0)) then
  1860.       begin
  1861.          Result := True;
  1862.          Exit;
  1863.       end;
  1864.    end;
  1865.    Result := False;
  1866. end;
  1867. { b2TimeOfImpact.cpp }
  1868. // This algorithm uses conservative advancement to compute the time of
  1869. // impact (TOI) of two shapes.
  1870. // Refs: Bullet, Young Kim
  1871. function b2TimeOfImpact(shape1, shape2: Tb2Shape; const sweep1, sweep2: Tb2Sweep): Float;
  1872. var
  1873.    t0: Float;
  1874.    omega1, omega2, alpha: Float;
  1875.    v1, v2, p1, p2, normal: TVector2;
  1876.    k_maxIterations, iter: Int32;
  1877.    distance, targetDistance, t, approachVelocityBound, newAlpha: Float;
  1878.    xf1, xf2: Tb2XForm;
  1879. begin
  1880.    //b2Assert(sweep1.t0 == sweep2.t0);
  1881.    //b2Assert(1.0 - sweep1.t0 > B2_FLT_EPSILON);
  1882.    t0 := sweep1.t0;
  1883.    {$IFDEF OP_OVERLOAD}   
  1884.    v1 := sweep1.c - sweep1.c0;
  1885.    v2 := sweep2.c - sweep2.c0;
  1886.    {$ELSE}   
  1887.    v1 := Subtract(sweep1.c, sweep1.c0);
  1888.    v2 := Subtract(sweep2.c, sweep2.c0);
  1889.    {$ENDIF}      
  1890.    omega1 := sweep1.a - sweep1.a0;
  1891.    omega2 := sweep2.a - sweep2.a0;
  1892.    alpha := 0.0;
  1893.    k_maxIterations := 20; // TODO_ERIN b2Settings
  1894.    iter := 0;
  1895.    normal := b2Vec2_zero;
  1896.    distance := 0.0;
  1897.    targetDistance := 0.0;
  1898.    while True do
  1899.    begin
  1900.       t := (1.0 - alpha) * t0 + alpha;
  1901.       {$IFDEF OP_OVERLOAD}      
  1902.       sweep1.GetXForm(xf1, t);
  1903.       sweep2.GetXForm(xf2, t);
  1904.       {$ELSE}      
  1905.       GetXForm(sweep1, xf1, t);
  1906.       GetXForm(sweep2, xf2, t);
  1907.       {$ENDIF}            
  1908.       // Get the distance between shapes.
  1909.       distance := b2Distance(p1, p2, shape1, shape2, xf1, xf2);
  1910.       if iter = 0 then
  1911.       begin
  1912.          // Compute a reasonable target distance to give some breathing room
  1913.          // for conservative advancement.
  1914.          if distance > 2.0 * b2_toiSlop then
  1915.             targetDistance := 1.5 * b2_toiSlop
  1916.          else
  1917.             targetDistance := b2Max(0.05 * b2_toiSlop, distance - 0.5 * b2_toiSlop);
  1918.       end;
  1919.       if (distance - targetDistance < 0.05 * b2_toiSlop) or (iter = k_maxIterations) then
  1920.          Break;
  1921.       {$IFDEF OP_OVERLOAD}         
  1922.       normal := p2 - p1;
  1923.       normal.Normalize;
  1924.       {$ELSE}      
  1925.       normal := Subtract(p2, p1);
  1926.       Normalize(normal);
  1927.       {$ENDIF}            
  1928.       // Compute upper bound on remaining movement.
  1929.       {$IFDEF OP_OVERLOAD}      
  1930.       approachVelocityBound := b2Dot(normal, v1 - v2) + Abs(omega1) *
  1931.          shape1.GetSweepRadius + Abs(omega2) * shape2.GetSweepRadius;
  1932.       {$ELSE}         
  1933.       approachVelocityBound := b2Dot(normal, Subtract(v1, v2)) + Abs(omega1) *
  1934.          shape1.GetSweepRadius + Abs(omega2) * shape2.GetSweepRadius;
  1935.       {$ENDIF}            
  1936.       if Abs(approachVelocityBound) < FLT_EPSILON then
  1937.       begin
  1938.          alpha := 1.0;
  1939.          Break;
  1940.       end;
  1941.       // Get the conservative time increment. Don't advance all the way.
  1942.       newAlpha := alpha + (distance - targetDistance) / approachVelocityBound;
  1943.       // The shapes may be moving apart or a safe distance apart.
  1944.       if (newAlpha < 0.0) or (1.0 < newAlpha) then
  1945.       begin
  1946.          alpha := 1.0;
  1947.          Break;
  1948.       end;
  1949.       // Ensure significant advancement.
  1950.       if newAlpha < (1.0 + 100.0 * FLT_EPSILON) * alpha then
  1951.          Break;
  1952.       alpha := newAlpha;
  1953.       Inc(iter);
  1954.    end;
  1955.    Result := alpha;
  1956. end;
  1957. { b2Distance.cpp }
  1958. // Circle to circle
  1959. function b2Distance(var x1, x2: TVector2; circle1, circle2: Tb2CircleShape;
  1960.    const xf1, xf2: Tb2XForm): Float; overload;
  1961. var
  1962.    p1, p2, d: TVector2;
  1963.    dsqr, r1, r2, r, dLen: Float;
  1964. begin
  1965.    p1 := b2Mul(xf1, circle1.m_localPosition);
  1966.    p2 := b2Mul(xf2, circle2.m_localPosition);
  1967.    {$IFDEF OP_OVERLOAD}
  1968.    d := p2 - p1;
  1969.    {$ELSE}
  1970.    d := Subtract(p2, p1);
  1971.    {$ENDIF}      
  1972.    dSqr := b2Dot(d, d);
  1973.    r1 := circle1.GetRadius - b2_toiSlop;
  1974.    r2 := circle2.GetRadius - b2_toiSlop;
  1975.    r := r1 + r2;
  1976.    if dSqr > r * r then
  1977.    begin
  1978.       {$IFDEF OP_OVERLOAD}   
  1979.       dLen := d.Normalize;
  1980.       x1 := p1 + r1 * d;
  1981.       x2 := p2 - r2 * d;
  1982.       {$ELSE}      
  1983.       dLen := Normalize(d);  
  1984.       x1 := Multiply(d, r1);   
  1985.       AddBy(x1, p1);
  1986.       x2 := Multiply(d, -r2);   
  1987.       AddBy(x2, p2);      
  1988.       {$ENDIF}       
  1989.       Result := dLen - r;     
  1990.       Exit;
  1991.    end
  1992.    else if (dSqr > FLT_EPSILON * FLT_EPSILON) then
  1993.    begin
  1994.       {$IFDEF OP_OVERLOAD}   
  1995.       d.Normalize;
  1996.       x1 := p1 + r1 * d;        
  1997.       {$ELSE}      
  1998.       Normalize(d);
  1999.       x1 := Multiply(d, r1);
  2000.       AddBy(x1, p1);
  2001.       {$ENDIF}  
  2002.       x2 := x1;          
  2003.       Result := 0.0;
  2004.       Exit;
  2005.    end;
  2006.    x1 := p1;
  2007.    x2 := x1;
  2008.    Result := 0.0;
  2009. end;
  2010. // Polygon to circle
  2011. const
  2012.    maxIterations = 20;
  2013. function Distance_Generic_Simulate(var x1, x2: TVector2;
  2014.    poly1: Tb2PolygonShape; poly2: Pointer; const xf1, xf2: Tb2XForm;
  2015.    poly2AsVector: Boolean): Float;
  2016. var
  2017.    i, iter: Integer;
  2018.    p1s, p2s, points: TCalcDistanceVectors;
  2019.    pointCount: Int32;
  2020.    vSqr, vw, maxSqr: Float;
  2021.    v, w1, w2, w: TVector2;
  2022. begin
  2023.    pointCount := 0;
  2024.    x1 := poly1.GetFirstVertex(xf1);
  2025.    if poly2AsVector then
  2026.       x2 := PVector2(poly2)^
  2027.    else
  2028.       x2 := Tb2PolygonShape(poly2).GetFirstVertex(xf2);
  2029.    vSqr := 0.0;
  2030.    for iter := 0 to maxIterations - 1 do
  2031.    begin
  2032.       {$IFDEF OP_OVERLOAD}   
  2033.       v := x2 - x1;
  2034.       {$ELSE}      
  2035.       v := Subtract(x2, x1);
  2036.       {$ENDIF}            
  2037.       w1 := poly1.Support(xf1, v);
  2038.       if poly2AsVector then
  2039.          w2 := PVector2(poly2)^ // Ths same
  2040.       else
  2041.          {$IFDEF OP_OVERLOAD}      
  2042.          w2 := Tb2PolygonShape(poly2).Support(xf2, -v);
  2043.          {$ELSE}         
  2044.          w2 := Tb2PolygonShape(poly2).Support(xf2, Negative(v));
  2045.          {$ENDIF}                  
  2046.       vSqr := b2Dot(v, v);
  2047.       {$IFDEF OP_OVERLOAD}      
  2048.       w := w2 - w1;
  2049.       {$ELSE}      
  2050.       w := Subtract(w2, w1);
  2051.       {$ENDIF}
  2052.       vw := b2Dot(v, w);
  2053.       if (vSqr - vw <= 0.01 * vSqr) or Distance_InPoints(w, points, pointCount) then // or w in points
  2054.       begin
  2055.          if pointCount = 0 then
  2056.          begin
  2057.             x1 := w1;
  2058.             x2 := w2;
  2059.          end;
  2060.          g_GJK_Iterations := iter;
  2061.          Result := Sqrt(vSqr);
  2062.          Exit;
  2063.       end;
  2064.       case pointCount of
  2065.          0: begin
  2066.             p1s[0] := w1;
  2067.             p2s[0] := w2;
  2068.             points[0] := w;
  2069.             x1 := p1s[0];
  2070.             x2 := p2s[0];
  2071.             Inc(pointCount);
  2072.          end;
  2073.          1: begin
  2074.             p1s[1] := w1;
  2075.             p2s[1] := w2;
  2076.             points[1] := w;
  2077.             pointCount := Distance_ProcessTwo(x1, x2, p1s, p2s, points);
  2078.          end;
  2079.          2: begin
  2080.             p1s[2] := w1;
  2081.             p2s[2] := w2;
  2082.             points[2] := w;
  2083.             pointCount := Distance_ProcessThree(x1, x2, p1s, p2s, points);
  2084.          end;
  2085.       end;
  2086.       // If we have three points, then the origin is in the corresponding triangle.
  2087.       if pointCount = 3 then
  2088.       begin
  2089.          g_GJK_Iterations := iter;
  2090.          Result := 0.0;
  2091.          Exit;
  2092.       end;
  2093.       maxSqr := -FLT_MAX;
  2094.       for i := 0 to pointCount - 1 do
  2095.          maxSqr := b2Max(maxSqr, b2Dot(points[i], points[i]));
  2096.       if (pointCount = 3) or (vSqr <= 100.0 * FLT_EPSILON * maxSqr) then
  2097.       begin
  2098.          g_GJK_Iterations := iter;
  2099.          {$IFDEF OP_OVERLOAD}
  2100.          v := x2 - x1;
  2101.          {$ELSE}         
  2102.          v := Subtract(x2, x1);
  2103.          {$ENDIF}                  
  2104.          vSqr := b2Dot(v, v);
  2105.          Result := Sqrt(vSqr);
  2106.          Exit;
  2107.       end;
  2108.    end;
  2109.    g_GJK_Iterations := maxIterations;
  2110.    Result := Sqrt(vSqr);
  2111. end;
  2112. function b2Distance(var x1, x2: TVector2; poly: Tb2PolygonShape;
  2113.    circle: Tb2CircleShape; const xf1, xf2: Tb2XForm): Float; overload;
  2114. var
  2115.    p: TVector2;
  2116.    r: Float;
  2117.    d: TVector2;
  2118. begin
  2119.    p := b2Mul(xf2, circle.m_localPosition);
  2120.    Result := Distance_Generic_Simulate(x1, x2, poly, Pointer(@p),
  2121.       xf1, b2XForm_identity, True);
  2122.    r := circle.GetRadius - b2_toiSlop;
  2123.    if Result > r then
  2124.    begin
  2125.       Result := Result - r;
  2126.       {$IFDEF OP_OVERLOAD}      
  2127.       d := x2 - x1;
  2128.       d.Normalize;
  2129.       x2 := x2 - r * d;
  2130.       {$ELSE}      
  2131.       d := Subtract(x2, x1);
  2132.       Normalize(d);
  2133.       SubtractBy(x2, Multiply(d, r));
  2134.       {$ENDIF}            
  2135.    end
  2136.    else
  2137.    begin
  2138.       Result := 0.0;
  2139.       x2 := x1;
  2140.    end;
  2141. end;
  2142. function b2Distance(var x1, x2: TVector2; circle: Tb2CircleShape;
  2143.    poly: Tb2PolygonShape; const xf1, xf2: Tb2XForm): Float; overload; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  2144. begin
  2145.    Result := b2Distance(x2, x1, poly, circle, xf2, xf1);
  2146. end;
  2147. function b2Distance(var x1, x2: TVector2; poly1, poly2: Tb2PolygonShape;
  2148.    const xf1, xf2: Tb2XForm): Float; overload;
  2149. begin
  2150.    Result := Distance_Generic_Simulate(x1, x2, poly1, poly2, xf1, xf2, False);
  2151. end;
  2152. function b2Distance(var x1, x2: TVector2; shape1, shape2: Tb2Shape;
  2153.    const xf1, xf2: Tb2XForm): Float; overload;
  2154. begin
  2155.    case shape1.m_type of
  2156.       e_circleShape:
  2157.          case shape2.m_type of
  2158.             e_circleShape: Result := b2Distance(x1, x2, Tb2CircleShape(shape1),
  2159.                Tb2CircleShape(shape2), xf1, xf2);
  2160.             e_polygonShape: Result := b2Distance(x2, x1, Tb2PolygonShape(shape2),
  2161.                Tb2CircleShape(shape1), xf2, xf1);
  2162.          else
  2163.             Result := 0.0;
  2164.          end;
  2165.       e_polygonShape:
  2166.          case shape2.m_type of
  2167.             e_circleShape: Result := b2Distance(x1, x2, Tb2PolygonShape(shape1),
  2168.                Tb2CircleShape(shape2), xf1, xf2);
  2169.             e_polygonShape: Result := Distance_Generic_Simulate(x1, x2,
  2170.                Tb2PolygonShape(shape1), shape2, xf1, xf2, False);
  2171.          else
  2172.             Result := 0.0;
  2173.          end;
  2174.    else
  2175.       Result := 0.0;
  2176.    end;
  2177. end;
  2178. { b2PairManager.cpp }
  2179. // Thomas Wang's hash, see: http://www.concentric.net/~Ttwang/tech/inthash.htm
  2180. // This assumes proxyId1 and proxyId2 are 16-bit.
  2181. function PairManager_Hash(proxyId1, proxyId2: UInt32): UInt32;
  2182. begin
  2183.    Result := (proxyId2 shl 16) or proxyId1;
  2184.    Result := (not Result) + (Result shl 15);
  2185.    Result := Result xor (Result shr 12);
  2186.    Result := Result + (Result shl 2);
  2187.    Result := Result xor (Result shr 4);
  2188.    Result := Result * 2057;
  2189.    Result := Result xor (Result shr 16);
  2190. end;
  2191. function PairManager_Equals(const pair: Tb2Pair; proxyId1,
  2192.    proxyId2: Int32): Boolean; overload; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  2193. begin
  2194.  Result := (pair.proxyId1 = proxyId1) and (pair.proxyId2 = proxyId2);
  2195. end;
  2196. function PairManager_Equals(const pair1, pair2: Tb2BufferedPair): Boolean; overload; {$IFDEF INLINE_AVAIL}inline;{$ENDIF}
  2197. begin
  2198.  Result := (pair1.proxyId1 = pair2.proxyId1) and (pair1.proxyId2 = pair2.proxyId2);
  2199. end;
  2200. { Tb2Segment }
  2201. // Collision Detection in Interactive 3D Environments by Gino van den Bergen
  2202. // From Section 3.4.1
  2203. // x = mu1 * p1 + mu2 * p2
  2204. // mu1 + mu2 = 1 && mu1 >= 0 && mu2 >= 0
  2205. // mu1 = 1 - mu2;
  2206. // x = (1 - mu2) * p1 + mu2 * p2
  2207. //   = p1 + mu2 * (p2 - p1)
  2208. // x = s + a * r (s := start, r := end - start)
  2209. // s + a * r = p1 + mu2 * d (d := p2 - p1)
  2210. // -a * r + mu2 * d = b (b := s - p1)
  2211. // [-r d] * [a; mu2] = b
  2212. // Cramer's rule:
  2213. // denom = det[-r d]
  2214. // a = det[b d] / denom
  2215. // mu2 = det[-r b] / denom
  2216. {$IFDEF OP_OVERLOAD}
  2217. function Tb2Segment.TestSegment(var lambda: Float; var normal: TVector2;
  2218.    const segment: Tb2Segment; maxLambda: Float): Boolean;
  2219. const
  2220.    k_slop = 100.0 * FLT_EPSILON;
  2221. var
  2222.    s, r, d, n, b: TVector2;
  2223.    denom, a, mu2: Float;
  2224. begin
  2225.    s := segment.p1;
  2226.    r := segment.p2 - s;
  2227.    d := p2 - p1;
  2228.    n := b2Cross(d, 1.0);
  2229.    denom := -b2Dot(r, n);
  2230.    // Cull back facing collision and ignore parallel segments.
  2231.    if denom > k_slop then
  2232.    begin
  2233.       // Does the segment intersect the infinite line associated with this segment?
  2234.       b := s - p1;
  2235.       a := b2Dot(b, n);
  2236.       if (0.0 <= a) and (a <= maxLambda * denom) then
  2237.       begin
  2238.          mu2 := r.y * b.x - r.x * b.y;
  2239.          // Does the segment intersect this segment?
  2240.          if (-k_slop * denom <= mu2) and (mu2 <= denom * (1.0 + k_slop)) then
  2241.          begin
  2242.             n.Normalize;
  2243.             lambda := a / denom;
  2244.             normal := n;
  2245.             Result := True;
  2246.             Exit;
  2247.          end;
  2248.       end;
  2249.    end;
  2250.    Result := False;
  2251. end;
  2252. {$ENDIF}
  2253. { Tb2AABB }
  2254. {$IFDEF OP_OVERLOAD}
  2255. function Tb2AABB.IsValid: Boolean;
  2256. var
  2257.    d: TVector2;
  2258. begin
  2259.    d := upperBound - lowerBound;
  2260.    Result := (d.x >= 0.0) and (d.y >= 0.0) and upperBound.IsValid and lowerBound.IsValid;
  2261. end;
  2262. {$ENDIF}
  2263. { Tb2DebugDraw }
  2264. constructor Tb2DebugDraw.Create;
  2265. begin
  2266.    m_drawFlags := [];
  2267.    m_shapeColor_Static := MakeColor(0.5, 0.9, 0.5);
  2268.    m_shapeColor_Sleeping := MakeColor(0.5, 0.5, 0.9);
  2269.    m_shapeColor_Normal := MakeColor(0.9, 0.9, 0.9);
  2270.    m_pairColor := MakeColor(0.9, 0.9, 0.3);
  2271.    m_aabbColor := MakeColor(0.9, 0.3, 0.9);
  2272.    m_obbColor := MakeColor(0.5, 0.3, 0.5);
  2273.    m_world_aabbColor := MakeColor(0.3, 0.9, 0.9);
  2274.    m_coreColor := MakeColor(0.9, 0.6, 0.6);
  2275.    m_jointLineColor := MakeColor(0.5, 0.8, 0.8);
  2276. end;
  2277. //////////////////////////////////////////////////////////////
  2278. // World
  2279. constructor Tb2World.Create(const worldAABB: Tb2AABB;
  2280.    const gravity: TVector2; doSleep: Boolean);
  2281. var
  2282.    bd: Tb2BodyDef;
  2283. begin
  2284.    m_destructionListener := nil;
  2285.    m_boundaryListener := nil;
  2286.    m_contactFilter := b2_defaultFilter;
  2287.    m_contactListener := nil;
  2288.    m_debugDraw := nil;
  2289.    m_bodyList := nil;
  2290.    m_contactList := nil;
  2291.    m_jointList := nil;
  2292.    m_bodyCount := 0;
  2293.    m_contactCount := 0;
  2294.    m_jointCount := 0;
  2295.    m_positionCorrection := True;
  2296.    m_warmStarting := True;
  2297.    m_continuousPhysics := True;
  2298.    m_allowSleep := doSleep;
  2299.    m_gravity := gravity;
  2300.    m_lock := False;
  2301.    m_inv_dt0 := 0.0;
  2302.    m_contactManager := Tb2ContactManager.Create(Self);
  2303.    m_broadPhase := Tb2BroadPhase.Create(worldAABB, m_contactManager);
  2304.    bd := Tb2BodyDef.Create;
  2305.  m_groundBody := CreateBody(bd);   
  2306. end;
  2307. destructor Tb2World.Destroy;
  2308. var
  2309.    p: Tb2Body;
  2310. begin
  2311.    // Free all shapes
  2312.    while Assigned(m_bodyList) do
  2313.    begin
  2314.       p := m_bodyList.m_next;
  2315.       DestroyBody(m_bodyList);
  2316.       m_bodyList := p;
  2317.    end;
  2318.    m_contactManager.Free;
  2319.  m_broadPhase.Free;
  2320. end;
  2321. procedure Tb2World.Solve(const step: Tb2TimeStep);
  2322. var
  2323.    i: Integer;
  2324.    island: Tb2Island;
  2325.    b, seed, other: Tb2Body;
  2326.    c: Tb2Contact;
  2327.    j: Tb2Joint;
  2328.    stackCount: Int32;
  2329.    stack: TList;
  2330.    cn: Pb2ContactEdge;
  2331.    jn: Pb2JointEdge;
  2332. begin
  2333.    m_positionIterationCount := 0;
  2334.    // Size the island for the worst case.
  2335.    island := Tb2Island.Create(m_bodyCount, m_contactCount, m_jointCount, m_contactListener);
  2336.    // Clear all the island flags.
  2337.    b := m_bodyList;
  2338.    while Assigned(b) do
  2339.    begin
  2340.       b.m_flags := b.m_flags and (not e_body_islandFlag);
  2341.       b := b.m_next;
  2342.    end;
  2343.    c := m_contactList;
  2344.    while Assigned(c) do
  2345.    begin
  2346.       c.m_flags := c.m_flags and (not e_contact_islandFlag);
  2347.       c := c.m_next;
  2348.    end;
  2349.    j := m_jointList;
  2350.    while Assigned(j) do
  2351.    begin
  2352.       j.m_islandFlag := False;
  2353.       j := j.m_next;
  2354.    end;
  2355.    // Build and simulate all awake islands.
  2356.    stack := TList.Create;
  2357.    stack.Count := m_bodyCount;
  2358.    seed := m_bodyList;
  2359.    while Assigned(seed) do
  2360.    begin
  2361.       if (seed.m_flags and (e_body_islandFlag or e_sleepFlag or e_frozenFlag)) <> 0 then
  2362.       begin
  2363.          seed := seed.m_next;
  2364.          Continue;
  2365.       end;
  2366.       if seed.IsStatic() then
  2367.       begin
  2368.          seed := seed.m_next;
  2369.          Continue;
  2370.       end;
  2371.       // Reset island and stack.
  2372.       island.Clear;
  2373.       stackCount := 0;
  2374.       stack[stackCount] := seed;
  2375.       Inc(stackCount);
  2376.       seed.m_flags := seed.m_flags or e_body_islandFlag;
  2377.       // Perform a depth first search (DFS) on the constraint graph.
  2378.       while (stackCount > 0) do
  2379.       begin
  2380.          // Grab the next body off the stack and add it to the island.
  2381.          Dec(stackCount);
  2382.          b := Tb2Body(stack[stackCount]);
  2383.          island.Add(b);
  2384.          // Make sure the body is awake.
  2385.          b.m_flags := b.m_flags and (not e_sleepFlag);
  2386.          // To keep islands as small as possible, we don't
  2387.          // propagate islands across static bodies.
  2388.          if b.IsStatic() then
  2389.             Continue;
  2390.          // Search all contacts connected to this body.
  2391.          cn := b.m_contactList;
  2392.          while Assigned(cn) do
  2393.          begin
  2394.             // Has this contact already been added to an island?
  2395.             if (cn^.contact.m_flags and (e_contact_islandFlag or e_nonSolidFlag)) <> 0 then
  2396.             begin
  2397.                cn := cn^.next;
  2398.                Continue;
  2399.             end;
  2400.             // Is this contact touching?
  2401.             if cn.contact.GetManifoldCount = 0 then
  2402.             begin
  2403.                cn := cn^.next;
  2404.                Continue;
  2405.             end;
  2406.             island.Add(cn.contact);
  2407.             cn.contact.m_flags := cn.contact.m_flags or e_contact_islandFlag;
  2408.             other := cn.other;
  2409.             // Was the other body already added to this island?
  2410.             if (other.m_flags and e_body_islandFlag) <> 0 then
  2411.             begin
  2412.                cn := cn^.next;
  2413.                Continue;
  2414.             end;
  2415.             //b2Assert(stackCount < stackSize);
  2416.             stack[stackCount] := other;
  2417.             Inc(stackCount);
  2418.             other.m_flags := other.m_flags or e_body_islandFlag;
  2419.             cn := cn^.next;
  2420.          end;
  2421.          // Search all joints connect to this body.
  2422.          jn := b.m_jointList;
  2423.          while Assigned(jn) do
  2424.          begin
  2425.             if jn^.joint.m_islandFlag then
  2426.             begin
  2427.                jn := jn^.next;
  2428.                Continue;
  2429.             end;
  2430.             island.Add(jn^.joint);
  2431.             jn^.joint.m_islandFlag := True;
  2432.             other := jn^.other;
  2433.             if (other.m_flags and e_body_islandFlag) <> 0 then
  2434.             begin
  2435.                jn := jn^.next;
  2436.                Continue;
  2437.             end;
  2438.             //b2Assert(stackCount < stackSize);
  2439.             stack[stackCount] := other;
  2440.             Inc(stackCount);
  2441.             other.m_flags := other.m_flags or e_body_islandFlag;
  2442.             jn := jn^.next;
  2443.          end;
  2444.       end;
  2445.       island.Solve(step, m_gravity, m_positionCorrection, m_allowSleep);
  2446.       m_positionIterationCount := b2Max(m_positionIterationCount, island.m_positionIterationCount);
  2447.       // Post solve cleanup.
  2448.       for i := 0 to island.m_bodyCount - 1 do
  2449.       begin
  2450.          // Allow static bodies to participate in other islands.
  2451.          b := Tb2Body(island.m_bodies[i]);
  2452.          if b.IsStatic() then
  2453.             b.m_flags := b.m_flags and (not e_body_islandFlag);
  2454.       end;
  2455.       seed := seed.m_next;
  2456.    end;
  2457.    stack.Free;
  2458.    // Synchronize shapes, check for out of range bodies.
  2459.    b := m_bodyList;
  2460.    while Assigned(b) do
  2461.    begin
  2462.       if (b.m_flags and (e_sleepFlag or e_frozenFlag)) <> 0 then
  2463.       begin
  2464.          b := b.GetNext;
  2465.          Continue;
  2466.       end;
  2467.       if b.IsStatic() then
  2468.       begin
  2469.          b := b.GetNext;
  2470.          Continue;
  2471.       end;
  2472.       // Update shapes (for broad-phase). If the shapes go out of
  2473.       // the world AABB then shapes and contacts may be destroyed,
  2474.       // including contacts that are
  2475.       // Did the body's shapes leave the world?
  2476.       if (not b.SynchronizeShapes()) and Assigned(m_boundaryListener) then
  2477.          m_boundaryListener.Violation(b);
  2478.       b := b.GetNext;
  2479.    end;
  2480.    // Commit shape proxy movements to the broad-phase so that new contacts are created.
  2481.    // Also, some contacts can be destroyed.
  2482.    m_broadPhase.Commit;
  2483.    island.Free;
  2484. end;
  2485. procedure Tb2World.SolveTOI(const step: Tb2TimeStep);
  2486. var
  2487.    i: Integer;
  2488.    island: Tb2Island;
  2489.    stackCount: Int32;
  2490.    stack: TList;
  2491.    b, b1, b2, seed, other: Tb2Body;
  2492.    c: Tb2Contact;
  2493.    minContact: Tb2Contact;
  2494.    cn: Pb2ContactEdge;
  2495.    minTOI, toi, t0: Float;
  2496.    subStep: Tb2TimeStep;
  2497.    inRange: Boolean;
  2498. begin
  2499.    // Reserve an island and a stack for TOI island solution.
  2500.    island := Tb2Island.Create(m_bodyCount, b2_maxTOIContactsPerIsland, 0, m_contactListener);
  2501.    stack := TList.Create;
  2502.    stack.Count := m_bodyCount;
  2503.    b := m_bodyList;
  2504.    while Assigned(b) do
  2505.    begin
  2506.       b.m_flags := b.m_flags and (not e_body_islandFlag);
  2507.       b.m_sweep.t0 := 0.0;
  2508.       b := b.m_next;
  2509.    end;
  2510.    c := m_contactList;
  2511.    while Assigned(c) do
  2512.    begin
  2513.       // Invalidate TOI
  2514.       c.m_flags := c.m_flags and (not (e_toiFlag or e_contact_islandFlag));
  2515.       c := c.m_next;
  2516.    end;
  2517.    // Find TOI events and solve them.
  2518.    while True do
  2519.    begin
  2520.       // Find the first TOI.
  2521.       minContact := nil;
  2522.       minTOI := 1.0;
  2523.       c := m_contactList;
  2524.       while Assigned(c) do
  2525.       begin
  2526.          if (c.m_flags and (e_slowFlag or e_nonSolidFlag)) <> 0 then
  2527.          begin
  2528.             c := c.m_next;
  2529.             Continue;     
  2530.          end;
  2531.          // TODO_ERIN keep a counter on the contact, only respond to M TOIs per contact.
  2532.          toi := 1.0;
  2533.          if (c.m_flags and e_toiFlag) <> 0 then
  2534.             toi := c.m_toi // This contact has a valid cached TOI.
  2535.          else
  2536.          begin
  2537.             // Compute the TOI for this contact.
  2538.             b1 := c.GetShape1.GetBody;
  2539.             b2 := c.GetShape2.GetBody;
  2540.             if (b1.IsStatic() or b1.IsSleeping()) and (b2.IsStatic() or b2.IsSleeping()) then
  2541.             begin
  2542.                c := c.m_next;
  2543.                Continue;     
  2544.             end;
  2545.             // Put the sweeps onto the same time interval.
  2546.             t0 := b1.m_sweep.t0;
  2547.             if b1.m_sweep.t0 < b2.m_sweep.t0 then
  2548.             begin
  2549.                t0 := b2.m_sweep.t0;
  2550.                {$IFDEF OP_OVERLOAD}
  2551.                b1.m_sweep.Advance(t0);
  2552.                {$ELSE}
  2553.                Advance(b1.m_sweep, t0);
  2554.                {$ENDIF}
  2555.             end
  2556.             else if b2.m_sweep.t0 < b1.m_sweep.t0 then
  2557.             begin
  2558.                t0 := b1.m_sweep.t0;
  2559.                {$IFDEF OP_OVERLOAD}
  2560.                b2.m_sweep.Advance(t0);
  2561.                {$ELSE}
  2562.                Advance(b2.m_sweep, t0);
  2563.                {$ENDIF}
  2564.             end;
  2565.             //b2Assert(t0 < 1.0);
  2566.             // Compute the time of impact.
  2567.             toi := b2TimeOfImpact(c.m_shape1, c.m_shape2, b1.m_sweep, b2.m_sweep);
  2568.             //b2Assert(0.0 <= toi && toi <= 1.0);
  2569.             if (toi > 0.0) and (toi < 1.0) then
  2570.                toi := b2Min((1.0 - toi) * t0 + toi, 1.0);
  2571.             c.m_toi := toi;
  2572.             c.m_flags := c.m_flags or e_toiFlag;
  2573.          end;
  2574.          if (FLT_EPSILON < toi) and (toi < minTOI) then
  2575.          begin
  2576.             // This is the minimum TOI found so far.
  2577.             minContact := c;
  2578.             minTOI := toi;
  2579.          end;
  2580.          c := c.m_next;
  2581.       end;
  2582.       if (not Assigned(minContact)) or (1.0 - 100.0 * FLT_EPSILON < minTOI) then // No more TOI events. Done!
  2583.          Break;
  2584.       // Advance the bodies to the TOI.
  2585.       b1 := minContact.GetShape1.GetBody;
  2586.       b2 := minContact.GetShape2.GetBody;
  2587.       b1.Advance(minTOI);
  2588.       b2.Advance(minTOI);
  2589.       // The TOI contact likely has some new contact points.
  2590.       minContact.Update(m_contactListener);
  2591.       minContact.m_flags := minContact.m_flags and (not e_toiFlag);
  2592.       if minContact.GetManifoldCount = 0 then // This shouldn't happen. Numerical error?
  2593.          Continue;
  2594.       // Build the TOI island. We need a dynamic seed.
  2595.       seed := b1;
  2596.       if seed.IsStatic() then
  2597.          seed := b2;
  2598.       // Reset island and stack.
  2599.       island.Clear;
  2600.       stackCount := 0;
  2601.       stack[stackCount] := seed;
  2602.       Inc(stackCount);
  2603.       seed.m_flags := seed.m_flags or e_body_islandFlag;
  2604.       // Perform a depth first search (DFS) on the contact graph.
  2605.       while (stackCount > 0) do
  2606.       begin
  2607.          // Grab the next body off the stack and add it to the island.
  2608.          Dec(stackCount);
  2609.          b := Tb2Body(stack[stackCount]);
  2610.          island.Add(b);
  2611.          // Make sure the body is awake.
  2612.          b.m_flags := b.m_flags and (not e_sleepFlag);
  2613.          // To keep islands as small as possible, we don't
  2614.          // propagate islands across static bodies.
  2615.          if b.IsStatic() then
  2616.             Continue;
  2617.          // Search all contacts connected to this body.
  2618.          cn := b.m_contactList;
  2619.          while Assigned(cn) do
  2620.          begin
  2621.             // Does the TOI island still have space for contacts?
  2622.             if island.m_contactCount = island.m_contactCapacity then
  2623.             begin
  2624.                cn := cn.next;
  2625.                Continue;
  2626.             end;
  2627.             // Has this contact already been added to an island? Skip slow or non-solid contacts.
  2628.             if (cn.contact.m_flags and (e_contact_islandFlag or
  2629.                e_slowFlag or e_nonSolidFlag)) <> 0 then
  2630.             begin
  2631.                cn := cn.next;
  2632.                Continue;
  2633.             end;
  2634.             // Is this contact touching? For performance we are not updating this contact.
  2635.             if cn.contact.GetManifoldCount = 0 then
  2636.             begin
  2637.                cn := cn.next;
  2638.                Continue;
  2639.             end;
  2640.             island.Add(cn.contact);
  2641.             cn.contact.m_flags := cn.contact.m_flags or e_contact_islandFlag;
  2642.             // Update other body.
  2643.             other := cn.other;
  2644.             // Was the other body already added to this island?
  2645.             if (other.m_flags and e_body_islandFlag) <> 0 then
  2646.             begin
  2647.                cn := cn.next;
  2648.                Continue;
  2649.             end;
  2650.             // March forward, this can do no harm since this is the min TOI.
  2651.             if not other.IsStatic() then
  2652.             begin
  2653.                other.Advance(minTOI);
  2654.                other.WakeUp;
  2655.             end;
  2656.             //b2Assert(stackCount < stackSize);
  2657.             stack[stackCount] := other;
  2658.             Inc(stackCount);
  2659.             other.m_flags := other.m_flags or e_body_islandFlag;
  2660.             cn := cn.next;
  2661.          end;
  2662.       end;
  2663.       subStep.dt := (1.0 - minTOI) * step.dt;
  2664.       //b2Assert(subStep.dt > B2_FLT_EPSILON);
  2665.       subStep.inv_dt := 1.0 / subStep.dt;
  2666.       subStep.maxIterations := step.maxIterations;
  2667.       island.SolveTOI(subStep);
  2668.       // Post solve cleanup.
  2669.       for i := 0 to island.m_bodyCount - 1 do
  2670.       begin
  2671.          // Allow bodies to participate in future TOI islands.
  2672.          b := Tb2Body(island.m_bodies[i]);
  2673.          b.m_flags := b.m_flags and (not e_body_islandFlag);
  2674.          if (b.m_flags and (e_sleepFlag or e_frozenFlag)) <> 0 then
  2675.             Continue;
  2676.          if b.IsStatic() then
  2677.             Continue;
  2678.          // Update shapes (for broad-phase). If the shapes go out of
  2679.          // the world AABB then shapes and contacts may be destroyed,
  2680.          // including contacts that are
  2681.          inRange := b.SynchronizeShapes;
  2682.          // Did the body's shapes leave the world?
  2683.          if (not inRange) and Assigned(m_boundaryListener) then
  2684.             m_boundaryListener.Violation(b);
  2685.          // Invalidate all contact TOIs associated with this body. Some of these
  2686.          // may not be in the island because they were not touching.
  2687.          cn := b.m_contactList;
  2688.          while Assigned(cn) do
  2689.          begin
  2690.             cn.contact.m_flags := cn.contact.m_flags and (not e_toiFlag);
  2691.             cn := cn.next;
  2692.          end;
  2693.       end;
  2694.       for i := 0 to island.m_contactCount - 1 do
  2695.          with Tb2Contact(island.m_contacts[i]) do
  2696.          begin
  2697.             // Allow contacts to participate in future TOI islands.
  2698.             m_flags := m_flags and (not (e_toiFlag or e_contact_islandFlag));
  2699.          end;
  2700.       // Commit shape proxy movements to the broad-phase so that new contacts are created.
  2701.       // Also, some contacts can be destroyed.
  2702.       m_broadPhase.Commit;
  2703.    end;
  2704.    stack.Free;
  2705.    island.Free;
  2706. end;
  2707. procedure Tb2World.DrawDebugData;
  2708. var
  2709.    core: Boolean;
  2710.    xf: Tb2XForm;
  2711.    b: Tb2Body;
  2712.    s: Tb2Shape;
  2713.    j: Tb2Joint;
  2714.    invQ, h: TVector2;
  2715.    i: Integer;
  2716.    b1, b2: Tb2AABB;
  2717.    index: UInt16;
  2718.    vs: TVectorArray4;
  2719. begin
  2720.    if not Assigned(m_debugDraw) then
  2721.       Exit;
  2722.    with m_debugDraw do
  2723.    begin
  2724.       if e_shapeBit in m_drawFlags then
  2725.       begin
  2726.          core := e_coreShapeBit in m_drawFlags;
  2727.          b := m_bodyList;
  2728.          while Assigned(b) do
  2729.          begin
  2730.             xf := b.m_xf;
  2731.             s := b.GetShapeList;
  2732.             while Assigned(s) do
  2733.             begin
  2734.                if b.IsStatic then
  2735.                   DrawShape(s, xf, m_shapeColor_Static, core)
  2736.                else if b.IsSleeping then
  2737.                   DrawShape(s, xf, m_shapeColor_Sleeping, core)
  2738.                else
  2739.                   DrawShape(s, xf, m_shapeColor_Normal, core);
  2740.                s := s.m_next;
  2741.             end;
  2742.             b := b.GetNext;
  2743.          end;
  2744.       end;
  2745.       if e_jointBit in m_drawFlags then
  2746.       begin
  2747.          j := m_jointList;
  2748.          while Assigned(j) do
  2749.          begin
  2750.             if j.m_type <> e_mouseJoint then
  2751.               DrawJoint(j);
  2752.             j := j.m_next;
  2753.          end;
  2754.       end;
  2755.       with m_broadPhase do
  2756.       begin
  2757.          if e_pairBit in m_drawFlags then
  2758.          begin
  2759.             {$IFDEF OP_OVERLOAD}
  2760.             invQ.SetValue(1.0 / m_quantizationFactor.x, 1.0 / m_quantizationFactor.y);
  2761.             {$ELSE}
  2762.             SetValue(invQ, 1.0 / m_quantizationFactor.x, 1.0 / m_quantizationFactor.y);
  2763.             {$ENDIF}
  2764.             for i := 0 to b2_tableCapacity - 1 do
  2765.             begin
  2766.                index := m_pairManager.m_hashTable[i];
  2767.                while (index <> b2_nullPair) do
  2768.                   with m_pairManager.m_pairs[index] do
  2769.                   begin
  2770.                      with m_proxyPool[proxyId1] do
  2771.                      begin
  2772.                         b1.lowerBound.x := m_worldAABB.lowerBound.x + invQ.x * m_bounds[0][lowerBounds[0]].value;
  2773.                         b1.lowerBound.y := m_worldAABB.lowerBound.y + invQ.y * m_bounds[1][lowerBounds[1]].value;
  2774.                         b1.upperBound.x := m_worldAABB.lowerBound.x + invQ.x * m_bounds[0][upperBounds[0]].value;
  2775.                         b1.upperBound.y := m_worldAABB.lowerBound.y + invQ.y * m_bounds[1][upperBounds[1]].value;
  2776.                      end;
  2777.                      with m_proxyPool[proxyId2] do
  2778.                      begin
  2779.                         b2.lowerBound.x := m_worldAABB.lowerBound.x + invQ.x * m_bounds[0][lowerBounds[0]].value;
  2780.                         b2.lowerBound.y := m_worldAABB.lowerBound.y + invQ.y * m_bounds[1][lowerBounds[1]].value;
  2781.                         b2.upperBound.x := m_worldAABB.lowerBound.x + invQ.x * m_bounds[0][upperBounds[0]].value;
  2782.                         b2.upperBound.y := m_worldAABB.lowerBound.y + invQ.y * m_bounds[1][upperBounds[1]].value;
  2783.                      end;
  2784.                      {$IFDEF OP_OVERLOAD}
  2785.                      DrawSegment(0.5 * (b1.lowerBound + b1.upperBound),
  2786.                         0.5 * (b2.lowerBound + b2.upperBound), m_pairColor);
  2787.                      {$ELSE}
  2788.                      DrawSegment(Multiply(Add(b1.lowerBound, b1.upperBound), 0.5),
  2789.                         Multiply(Add(b2.lowerBound, b2.upperBound), 0.5), m_pairColor);
  2790.                      {$ENDIF}
  2791.                      index := next;
  2792.                   end;
  2793.             end;
  2794.          end;
  2795.          if e_aabbBit in m_drawFlags then
  2796.          begin
  2797.             {$IFDEF OP_OVERLOAD}
  2798.             invQ.SetValue(1.0 / m_quantizationFactor.x, 1.0 / m_quantizationFactor.y);
  2799.             {$ELSE}
  2800.             SetValue(invQ, 1.0 / m_quantizationFactor.x, 1.0 / m_quantizationFactor.y);
  2801.             {$ENDIF}
  2802.             for i := 0 to b2_maxProxies - 1 do
  2803.             begin
  2804.                with m_proxyPool[i] do
  2805.                begin
  2806.                   {$IFDEF OP_OVERLOAD}
  2807.                   if not IsValid then
  2808.                   {$ELSE}
  2809.                   if not IsValid(m_proxyPool[i]) then
  2810.                   {$ENDIF}
  2811.                      Continue;
  2812.                   b1.lowerBound.x := m_worldAABB.lowerBound.x + invQ.x * m_bounds[0][lowerBounds[0]].value;
  2813.                   b1.lowerBound.y := m_worldAABB.lowerBound.y + invQ.y * m_bounds[1][lowerBounds[1]].value;
  2814.                   b1.upperBound.x := m_worldAABB.lowerBound.x + invQ.x * m_bounds[0][upperBounds[0]].value;
  2815.                   b1.upperBound.y := m_worldAABB.lowerBound.y + invQ.y * m_bounds[1][upperBounds[1]].value;
  2816.                end;
  2817.                vs[0] := b1.lowerBound;
  2818.                vs[2] := b1.upperBound;
  2819.                {$IFDEF OP_OVERLOAD}
  2820.                vs[1].SetValue(b1.upperBound.x, b1.lowerBound.y);
  2821.                vs[3].SetValue(b1.lowerBound.x, b1.upperBound.y);
  2822.                {$ELSE}
  2823.                SetValue(vs[1], b1.upperBound.x, b1.lowerBound.y);
  2824.                SetValue(vs[3], b1.lowerBound.x, b1.upperBound.y);
  2825.                {$ENDIF}
  2826.                DrawPolygon4(vs, 4, m_aabbColor);
  2827.             end;
  2828.             vs[0] := m_worldAABB.lowerBound;
  2829.             vs[2] := m_worldAABB.upperBound;
  2830.             {$IFDEF OP_OVERLOAD}
  2831.             vs[1].SetValue(m_worldAABB.upperBound.x, m_worldAABB.lowerBound.y);
  2832.             vs[3].SetValue(m_worldAABB.lowerBound.x, m_worldAABB.upperBound.y);
  2833.             {$ELSE}
  2834.             SetValue(vs[1], m_worldAABB.upperBound.x, m_worldAABB.lowerBound.y);
  2835.             SetValue(vs[3], m_worldAABB.lowerBound.x, m_worldAABB.upperBound.y);
  2836.             {$ENDIF}
  2837.             DrawPolygon4(vs, 4, m_world_aabbColor);
  2838.          end;
  2839.       end;
  2840.       if e_obbBit in m_drawFlags then
  2841.       begin
  2842.          b := m_bodyList;
  2843.          while Assigned(b) do
  2844.          begin
  2845.             xf := b.m_xf;
  2846.             s := b.GetShapeList;
  2847.             while Assigned(s) do
  2848.             begin
  2849.                if s.GetType <> e_polygonShape then
  2850.                begin
  2851.                   s := s.m_next;
  2852.                   Continue;
  2853.                end;
  2854.                h := Tb2PolygonShape(s).m_obb.extents;
  2855.                {$IFDEF OP_OVERLOAD}
  2856.                vs[0].SetValue(-h.x, -h.y);
  2857.                vs[1].SetValue(h.x, -h.y);
  2858.                vs[3].SetValue(-h.x,  h.y);
  2859.                {$ELSE}
  2860.                SetValue(vs[0], -h.x, -h.y);
  2861.                SetValue(vs[1], h.x, -h.y);
  2862.                SetValue(vs[3], -h.x,  h.y);
  2863.                {$ENDIF}
  2864.                vs[2] := h;
  2865.                for i := 0 to 3 do
  2866.                   with Tb2PolygonShape(s).m_obb do
  2867.                   begin
  2868.                      {$IFDEF OP_OVERLOAD}
  2869.                      vs[i] := center + b2Mul(R, vs[i]);
  2870.                      {$ELSE}
  2871.                      vs[i] := Add(center, b2Mul(R, vs[i]));
  2872.                      {$ENDIF}
  2873.                      vs[i] := b2Mul(xf, vs[i]);
  2874.                   end;
  2875.                DrawPolygon4(vs, 4, m_obbColor);
  2876.                s := s.m_next;
  2877.             end;
  2878.             b := b.GetNext;
  2879.          end;
  2880.       end;
  2881.       if e_centerOfMassBit in m_drawFlags then
  2882.       begin
  2883.          b := m_bodyList;
  2884.          while Assigned(b) do
  2885.          begin
  2886.             xf := b.m_xf;
  2887.             xf.position := b.GetWorldCenter;
  2888.             DrawXForm(xf);
  2889.             b := b.GetNext;
  2890.          end;
  2891.       end;
  2892.    end;
  2893. end;
  2894. procedure Tb2World.DrawShape(shape: Tb2Shape; const xf: Tb2XForm;
  2895.    const color: RGBA; core: Boolean);
  2896. var
  2897.    i: Integer;
  2898.    center: TVector2;
  2899.    vertices: Tb2PolyVertices;
  2900. begin
  2901.    with m_debugDraw do
  2902.       case shape.GetType of
  2903.          e_circleShape:
  2904.             with Tb2CircleShape(shape) do
  2905.             begin
  2906.                center := b2Mul(xf, m_localPosition);
  2907.                DrawSolidCircle(center, xf.R.col1, GetRadius, color);
  2908.                if core then
  2909.                   DrawCircle(center, GetRadius - b2_toiSlop, m_coreColor);
  2910.             end;
  2911.          e_polygonShape:
  2912.             with Tb2PolygonShape(shape) do
  2913.             begin
  2914.                //b2Assert(vertexCount <= b2_maxPolygonVertices);
  2915.                for i := 0 to GetVertexCount - 1 do
  2916.                   vertices[i] := b2Mul(xf, m_vertices[i]);
  2917.                DrawSolidPolygon(vertices, GetVertexCount, color);
  2918.                if core then
  2919.                begin
  2920.                   for i := 0 to GetVertexCount - 1 do
  2921.                      vertices[i] := b2Mul(xf, m_coreVertices[i]);
  2922.                   DrawPolygon(vertices, GetVertexCount, m_coreColor);
  2923.                end;
  2924.             end;
  2925.       end;
  2926. end;
  2927. procedure Tb2World.DrawJoint(joint: Tb2Joint);
  2928. var
  2929.    p1, p2, s1, s2: TVector2;
  2930. begin
  2931.    p1 := joint.GetAnchor1;
  2932.    p2 := joint.GetAnchor2;
  2933.    with m_debugDraw do
  2934.    begin
  2935.       case joint.GetType of
  2936.          e_distanceJoint: DrawSegment(p1, p2, m_jointLineColor);
  2937.          e_pulleyJoint:
  2938.             with Tb2PulleyJoint(joint) do
  2939.             begin
  2940.                s1 := GetGroundAnchor1;
  2941.                s2 := GetGroundAnchor2;
  2942.                DrawSegment(s1, p1, m_jointLineColor);
  2943.                DrawSegment(s2, p2, m_jointLineColor);
  2944.                DrawSegment(s1, s2, m_jointLineColor);
  2945.             end;
  2946.          e_mouseJoint: ;
  2947.          e_fixedJoint: DrawSegment(p1, p2, m_jointLineColor);
  2948.       else
  2949.          DrawSegment(joint.GetBody1.m_xf.position, p1, m_jointLineColor);
  2950.          DrawSegment(p1, p2, m_jointLineColor);
  2951.          DrawSegment(joint.GetBody2.m_xf.position, p2, m_jointLineColor);
  2952.       end;
  2953.    end;
  2954. end;
  2955. function Tb2World.CreateBody(def: Tb2BodyDef; AutoFreeBodyDef: Boolean = True): Tb2Body;
  2956. begin
  2957.    //b2Assert(m_lock == False);
  2958.    if m_lock then
  2959.    begin
  2960.       Result := nil;
  2961.       Exit;
  2962.    end;
  2963.    Result := Tb2Body.Create(def, Self);
  2964.    // Add to world doubly linked list.
  2965.    Result.m_prev := nil;
  2966.    Result.m_next := m_bodyList;
  2967.    if Assigned(m_bodyList) then
  2968.       m_bodyList.m_prev := Result;
  2969.    m_bodyList := Result;
  2970.    Inc(m_bodyCount);
  2971.    if AutoFreeBodyDef then
  2972.       def.Free;
  2973. end;
  2974. procedure Tb2World.DestroyBody(body: Tb2Body; DoFree: Boolean = True);
  2975. var
  2976.    jn, jn0: Pb2JointEdge;
  2977.    s, s0: Tb2Shape;
  2978. begin
  2979.    //b2Assert(m_bodyCount > 0);
  2980.    //b2Assert(m_lock == False);
  2981.    if m_lock then
  2982.       Exit;
  2983.    // Delete the attached joints.
  2984.    jn := body.m_jointList;
  2985.    if Assigned(m_destructionListener) then
  2986.    begin
  2987.       while Assigned(jn) do
  2988.       begin
  2989.          jn0 := jn;
  2990.          jn := jn^.next;
  2991.          m_destructionListener.SayGoodbye(jn0^.joint);
  2992.          DestroyJoint(jn0^.joint);
  2993.       end;
  2994.    end
  2995.    else
  2996.    begin
  2997.       while Assigned(jn) do
  2998.       begin
  2999.          jn0 := jn;
  3000.          jn := jn^.next;
  3001.          DestroyJoint(jn0^.joint);
  3002.       end;
  3003.    end;
  3004.    // Delete the attached shapes. This destroys broad-phase
  3005.    // proxies and pairs, leading to the destruction of contacts.
  3006.    s := body.m_shapeList;
  3007.    if Assigned(m_destructionListener) then
  3008.    begin
  3009.       while Assigned(s) do
  3010.       begin
  3011.          s0 := s;
  3012.          s := s.m_next;
  3013.          m_destructionListener.SayGoodbye(s0);
  3014.          s0.DestroyProxy(m_broadPhase);
  3015.          s0.Free;
  3016.       end;
  3017.    end
  3018.    else
  3019.    begin
  3020.       while Assigned(s) do
  3021.       begin
  3022.          s0 := s;
  3023.          s := s.m_next;
  3024.          s0.DestroyProxy(m_broadPhase);
  3025.          s0.Free;
  3026.       end;
  3027.    end;
  3028.    // Remove world body list.
  3029.    if Assigned(body.m_prev) then
  3030.       body.m_prev.m_next := body.m_next;
  3031.    if Assigned(body.m_next) then
  3032.       body.m_next.m_prev := body.m_prev;
  3033.    if body = m_bodyList then
  3034.       m_bodyList := body.m_next;
  3035.    Dec(m_bodyCount);
  3036.    if DoFree then
  3037.       body.Destroy2;
  3038. end;
  3039. function Tb2World.CreateJoint(def: Tb2JointDef; AutoFreeJointDef: Boolean = True): Tb2Joint;
  3040. var
  3041.    j: Tb2Joint;
  3042.    b: Tb2Body;
  3043.    s: Tb2Shape;
  3044. begin
  3045.    //b2Assert(m_lock == False);
  3046.    Result := nil;
  3047.    case def.JointType of
  3048.       e_unknownJoint: Exit;
  3049.       e_revoluteJoint: j := Tb2RevoluteJoint.Create(Tb2RevoluteJointDef(def));
  3050.       e_prismaticJoint: j := Tb2PrismaticJoint.Create(Tb2PrismaticJointDef(def));
  3051.       e_distanceJoint: j := Tb2DistanceJoint.Create(Tb2DistanceJointDef(def));
  3052.       e_pulleyJoint: j := Tb2PulleyJoint.Create(Tb2PulleyJointDef(def));
  3053.       e_mouseJoint: j := Tb2MouseJoint.Create(Tb2MouseJointDef(def));
  3054.       e_gearJoint: j := Tb2GearJoint.Create(Tb2GearJointDef(def));
  3055.       e_fixedJoint: j := Tb2FixedJoint.Create(Tb2FixedJointDef(def));
  3056.    end;
  3057.    // Connect to the world list.
  3058.    j.m_prev := nil;
  3059.    j.m_next := m_jointList;
  3060.    if Assigned(m_jointList) then
  3061.       m_jointList.m_prev := j;
  3062.    m_jointList := j;
  3063.    Inc(m_jointCount);
  3064.    // Connect to the bodies' doubly linked lists.
  3065.    j.m_node1.joint := j;
  3066.    j.m_node1.other := j.m_body2;
  3067.    j.m_node1.prev := nil;
  3068.    j.m_node1.next := j.m_body1.m_jointList;
  3069.    if Assigned(j.m_body1.m_jointList) then
  3070.       j.m_body1.m_jointList.prev := @j.m_node1;
  3071.    j.m_body1.m_jointList := @j.m_node1;
  3072.    j.m_node2.joint := j;
  3073.    j.m_node2.other := j.m_body1;
  3074.    j.m_node2.prev := nil;
  3075.    j.m_node2.next := j.m_body2.m_jointList;
  3076.    if Assigned(j.m_body2.m_jointList) then
  3077.       j.m_body2.m_jointList.prev := @j.m_node2;
  3078.    j.m_body2.m_jointList := @j.m_node2;
  3079.    // If the joint prevents collisions, then reset collision filtering.
  3080.    if not def.collideConnected then
  3081.    begin
  3082.      // Reset the proxies on the body with the minimum number of shapes.
  3083.      if def.body1.m_shapeCount < def.body2.m_shapeCount then
  3084.         b := def.body1
  3085.      else