1# Copyright (c) 2007 Scott Lembcke
2#
3#  Permission is hereby granted, free of charge, to any person obtaining a copy
4#  of this software and associated documentation files (the "Software"), to deal
5#  in the Software without restriction, including without limitation the rights
6#  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7#  copies of the Software, and to permit persons to whom the Software is
8#  furnished to do so, subject to the following conditions:
9#
10#  The above copyright notice and this permission notice shall be included in
11#  all copies or substantial portions of the Software.
12#
13#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14#  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18#  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19#  SOFTWARE.
20#
21
22const Lib = "libchipmunk.so.6.1.1"
23
24when defined(MoreNim):
25  {.hint: "MoreNim defined; some Chipmunk functions replaced in Nim".}
26from math import sqrt, sin, cos, arctan2
27when defined(CpUseFloat):
28  {.hint: "CpUseFloat defined; using float32 as float".}
29  type CpFloat* = cfloat
30else:
31  type CpFloat* = cdouble
32const
33  CP_BUFFER_BYTES* = (32 * 1024)
34  CP_MAX_CONTACTS_PER_ARBITER* = 4
35  CpInfinity*: CpFloat = 1.0/0
36{.pragma: pf, pure, final.}
37type
38  Bool32* = cint  #replace one day with cint-compatible bool
39  CpDataPointer* = pointer
40  TVector* {.final, pure.} = object
41    x*, y*: CpFloat
42  TTimestamp* = cuint
43  TBodyVelocityFunc* = proc(body: PBody, gravity: TVector,
44                            damping: CpFloat; dt: CpFloat){.cdecl.}
45  TBodyPositionFunc* = proc(body: PBody; dt: CpFloat){.cdecl.}
46  TComponentNode*{.pf.} = object
47    root*: PBody
48    next*: PBody
49    idleTime*: CpFloat
50
51  THashValue = cuint  # uintptr_t
52  TCollisionType* = cuint #uintptr_t
53  TGroup * = cuint #uintptr_t
54  TLayers* = cuint
55  PArray = ptr TArray
56  TArray{.pure,final.} = object
57  PHashSet = ptr THashSet
58  THashSet{.pf.} = object
59  PContact* = ptr TContact
60  TContact*{.pure,final.} = object
61  PArbiter* = ptr TArbiter
62  TArbiter*{.pf.} = object
63    e*: CpFloat
64    u*: CpFloat
65    surface_vr*: TVector
66    a*: PShape
67    b*: PShape
68    body_a*: PBody
69    body_b*: PBody
70    thread_a*: TArbiterThread
71    thread_b*: TArbiterThread
72    numContacts*: cint
73    contacts*: PContact
74    stamp*: TTimestamp
75    handler*: PCollisionHandler
76    swappedColl*: Bool32
77    state*: TArbiterState
78  PCollisionHandler* = ptr TCollisionHandler
79  TCollisionHandler*{.pf.} = object
80    a*: TCollisionType
81    b*: TCollisionType
82    begin*: TCollisionBeginFunc
83    preSolve*: TCollisionPreSolveFunc
84    postSolve*: TCollisionPostSolveFunc
85    separate*: TCollisionSeparateFunc
86    data*: pointer
87  TArbiterState*{.size: sizeof(cint).} = enum
88    ArbiterStateFirstColl,    # Arbiter is active and its not the first collision.
89    ArbiterStateNormal,       # Collision has been explicitly ignored.
90                              # Either by returning false from a begin collision handler or calling cpArbiterIgnore().
91    ArbiterStateIgnore,       # Collison is no longer active. A space will cache an arbiter for up to cpSpace.collisionPersistence more steps.
92    ArbiterStateCached
93  TArbiterThread*{.pf.} = object
94    next*: PArbiter        # Links to next and previous arbiters in the contact graph.
95    prev*: PArbiter
96
97  TContactPoint*{.pf.} = object
98    point*: TVector    #/ The position of the contact point.
99    normal*: TVector   #/ The normal of the contact point.
100    dist*: CpFloat     #/ The depth of the contact point.
101  #/ A struct that wraps up the important collision data for an arbiter.
102  PContactPointSet* = ptr TContactPointSet
103  TContactPointSet*{.pf.} = object
104    count*: cint              #/ The number of contact points in the set.
105    points*: array[0..CP_MAX_CONTACTS_PER_ARBITER - 1, TContactPoint] #/ The array of contact points.
106
107  #/ Collision begin event function callback type.
108  #/ Returning false from a begin callback causes the collision to be ignored until
109  #/ the separate callback is called when the objects stop colliding.
110  TCollisionBeginFunc* = proc (arb: PArbiter; space: PSpace; data: pointer): bool{.
111      cdecl.}
112  #/ Collision pre-solve event function callback type.
113  #/ Returning false from a pre-step callback causes the collision to be ignored until the next step.
114  TCollisionPreSolveFunc* = proc (arb: PArbiter; space: PSpace;
115                                  data: pointer): bool {.cdecl.}
116  #/ Collision post-solve event function callback type.
117  TCollisionPostSolveFunc* = proc (arb: PArbiter; space: PSpace;
118                                   data: pointer){.cdecl.}
119  #/ Collision separate event function callback type.
120  TCollisionSeparateFunc* = proc (arb: PArbiter; space: PSpace;
121                                  data: pointer){.cdecl.}
122
123  #/ Chipmunk's axis-aligned 2D bounding box type. (left, bottom, right, top)
124  PBB* = ptr TBB
125  TBB* {.pf.} = object
126    l*, b*, r*, t*: CpFloat
127
128  #/ Spatial index bounding box callback function type.
129  #/ The spatial index calls this function and passes you a pointer to an object you added
130  #/ when it needs to get the bounding box associated with that object.
131  TSpatialIndexBBFunc* = proc (obj: pointer): TBB{.cdecl.}
132  #/ Spatial index/object iterator callback function type.
133  TSpatialIndexIteratorFunc* = proc (obj: pointer; data: pointer){.cdecl.}
134  #/ Spatial query callback function type.
135  TSpatialIndexQueryFunc* = proc (obj1: pointer; obj2: pointer; data: pointer){.
136      cdecl.}
137  #/ Spatial segment query callback function type.
138  TSpatialIndexSegmentQueryFunc* = proc (obj1: pointer; obj2: pointer;
139      data: pointer): CpFloat {.cdecl.}
140  #/ private
141  PSpatialIndex = ptr TSpatialIndex
142  TSpatialIndex{.pf.} = object
143    klass: PSpatialIndexClass
144    bbfun: TSpatialIndexBBFunc
145    staticIndex: PSpatialIndex
146    dynamicIndex: PSpatialIndex
147
148  TSpatialIndexDestroyImpl* = proc (index: PSpatialIndex){.cdecl.}
149  TSpatialIndexCountImpl* = proc (index: PSpatialIndex): cint{.cdecl.}
150  TSpatialIndexEachImpl* = proc (index: PSpatialIndex;
151                                 fun: TSpatialIndexIteratorFunc; data: pointer){.
152      cdecl.}
153  TSpatialIndexContainsImpl* = proc (index: PSpatialIndex; obj: pointer;
154                                     hashid: THashValue): Bool32 {.cdecl.}
155  TSpatialIndexInsertImpl* = proc (index: PSpatialIndex; obj: pointer;
156                                   hashid: THashValue){.cdecl.}
157  TSpatialIndexRemoveImpl* = proc (index: PSpatialIndex; obj: pointer;
158                                   hashid: THashValue){.cdecl.}
159  TSpatialIndexReindexImpl* = proc (index: PSpatialIndex){.cdecl.}
160  TSpatialIndexReindexObjectImpl* = proc (index: PSpatialIndex;
161      obj: pointer; hashid: THashValue){.cdecl.}
162  TSpatialIndexReindexQueryImpl* = proc (index: PSpatialIndex;
163      fun: TSpatialIndexQueryFunc; data: pointer){.cdecl.}
164  TSpatialIndexPointQueryImpl* = proc (index: PSpatialIndex; point: TVector;
165                                       fun: TSpatialIndexQueryFunc;
166                                       data: pointer){.cdecl.}
167  TSpatialIndexSegmentQueryImpl* = proc (index: PSpatialIndex; obj: pointer;
168      a: TVector; b: TVector; t_exit: CpFloat; fun: TSpatialIndexSegmentQueryFunc;
169      data: pointer){.cdecl.}
170  TSpatialIndexQueryImpl* = proc (index: PSpatialIndex; obj: pointer;
171                                  bb: TBB; fun: TSpatialIndexQueryFunc;
172                                  data: pointer){.cdecl.}
173  PSpatialIndexClass* = ptr TSpatialIndexClass
174  TSpatialIndexClass*{.pf.} = object
175    destroy*: TSpatialIndexDestroyImpl
176    count*: TSpatialIndexCountImpl
177    each*: TSpatialIndexEachImpl
178    contains*: TSpatialIndexContainsImpl
179    insert*: TSpatialIndexInsertImpl
180    remove*: TSpatialIndexRemoveImpl
181    reindex*: TSpatialIndexReindexImpl
182    reindexObject*: TSpatialIndexReindexObjectImpl
183    reindexQuery*: TSpatialIndexReindexQueryImpl
184    pointQuery*: TSpatialIndexPointQueryImpl
185    segmentQuery*: TSpatialIndexSegmentQueryImpl
186    query*: TSpatialIndexQueryImpl
187
188  PSpaceHash* = ptr TSpaceHash
189  TSpaceHash* {.pf.} = object
190  PBBTree* = ptr TBBTree
191  TBBTree* {.pf.} = object
192  PSweep1D* = ptr TSweep1D
193  TSweep1D* {.pf.} = object
194
195  #/ Bounding box tree velocity callback function.
196  #/ This function should return an estimate for the object's velocity.
197  TBBTreeVelocityFunc* = proc (obj: pointer): TVector {.cdecl.}
198
199  PContactBufferHeader* = ptr TContentBufferHeader
200  TContentBufferHeader* {.pf.} = object
201  TSpaceArbiterApplyImpulseFunc* = proc (arb: PArbiter){.cdecl.}
202
203  PSpace* = ptr TSpace
204  TSpace* {.pf.} = object
205    iterations*: cint
206    gravity*: TVector
207    damping*: CpFloat
208    idleSpeedThreshold*: CpFloat
209    sleepTimeThreshold*: CpFloat
210    collisionSlop*: CpFloat
211    collisionBias*: CpFloat
212    collisionPersistence*: TTimestamp
213    enableContactGraph*: cint ##BOOL
214    data*: pointer
215    staticBody*: PBody
216    stamp: TTimestamp
217    currDT: CpFloat
218    bodies: PArray
219    rousedBodies: PArray
220    sleepingComponents: PArray
221    staticShapes: PSpatialIndex
222    activeShapes: PSpatialIndex
223    arbiters: PArray
224    contactBuffersHead: PContactBufferHeader
225    cachedArbiters: PHashSet
226    pooledArbiters: PArray
227    constraints: PArray
228    allocatedBuffers: PArray
229    locked: cint
230    collisionHandlers: PHashSet
231    defaultHandler: TCollisionHandler
232    postStepCallbacks: PHashSet
233    arbiterApplyImpulse: TSpaceArbiterApplyImpulseFunc
234    staticBody2: TBody  #_staticBody
235  PBody* = ptr TBody
236  TBody*{.pf.} = object
237    velocityFunc*: TBodyVelocityFunc
238    positionFunc*: TBodyPositionFunc
239    m*: CpFloat
240    mInv*: CpFloat
241    i*: CpFloat
242    iInv*: CpFloat
243    p*: TVector
244    v*: TVector
245    f*: TVector
246    a*: CpFloat
247    w*: CpFloat
248    t*: CpFloat
249    rot*: TVector
250    data*: pointer
251    vLimit*: CpFloat
252    wLimit*: CpFloat
253    vBias*: TVector
254    wBias*: CpFloat
255    space*: PSpace
256    shapeList*: PShape
257    arbiterList*: PArbiter
258    constraintList*: PConstraint
259    node*: TComponentNode
260  #/ Body/shape iterator callback function type.
261  TBodyShapeIteratorFunc* = proc (body: PBody; shape: PShape;
262                                   data: pointer) {.cdecl.}
263  #/ Body/constraint iterator callback function type.
264  TBodyConstraintIteratorFunc* = proc (body: PBody;
265                                        constraint: PConstraint;
266                                        data: pointer) {.cdecl.}
267  #/ Body/arbiter iterator callback function type.
268  TBodyArbiterIteratorFunc* = proc (body: PBody; arbiter: PArbiter;
269                                     data: pointer) {.cdecl.}
270
271  PNearestPointQueryInfo* = ptr TNearestPointQueryInfo
272  #/ Nearest point query info struct.
273  TNearestPointQueryInfo*{.pf.} = object
274    shape: PShape  #/ The nearest shape, NULL if no shape was within range.
275    p: TVector     #/ The closest point on the shape's surface. (in world space coordinates)
276    d: CpFloat      #/ The distance to the point. The distance is negative if the point is inside the shape.
277
278  PSegmentQueryInfo* = ptr TSegmentQueryInfo
279  #/ Segment query info struct.
280  TSegmentQueryInfo*{.pf.} = object
281    shape*: PShape         #/ The shape that was hit, NULL if no collision occurred.
282    t*: CpFloat            #/ The normalized distance along the query segment in the range [0, 1].
283    n*: TVector            #/ The normal of the surface hit.
284  TShapeType*{.size: sizeof(cint).} = enum
285    CP_CIRCLE_SHAPE, CP_SEGMENT_SHAPE, CP_POLY_SHAPE, CP_NUM_SHAPES
286  TShapeCacheDataImpl* = proc (shape: PShape; p: TVector; rot: TVector): TBB{.cdecl.}
287  TShapeDestroyImpl* = proc (shape: PShape){.cdecl.}
288  TShapePointQueryImpl* = proc (shape: PShape; p: TVector): Bool32 {.cdecl.}
289  TShapeSegmentQueryImpl* = proc (shape: PShape; a: TVector; b: TVector;
290                                  info: PSegmentQueryInfo){.cdecl.}
291  PShapeClass* = ptr TShapeClass
292  TShapeClass*{.pf.} = object
293    kind*: TShapeType
294    cacheData*: TShapeCacheDataImpl
295    destroy*: TShapeDestroyImpl
296    pointQuery*: TShapePointQueryImpl
297    segmentQuery*: TShapeSegmentQueryImpl
298  PShape* = ptr TShape
299  TShape*{.pf.} = object
300    klass: PShapeClass   #/ PRIVATE
301    body*: PBody           #/ The rigid body this collision shape is attached to.
302    bb*: TBB               #/ The current bounding box of the shape.
303    sensor*: Bool32        #/ Sensor flag.
304                           #/ Sensor shapes call collision callbacks but don't produce collisions.
305    e*: CpFloat            #/ Coefficient of restitution. (elasticity)
306    u*: CpFloat            #/ Coefficient of friction.
307    surface_v*: TVector    #/ Surface velocity used when solving for friction.
308    data*: pointer        #/ User definable data pointer. Generally this points to your the game object class so you can access it when given a cpShape reference in a callback.
309    collision_type*: TCollisionType #/ Collision type of this shape used when picking collision handlers.
310    group*: TGroup      #/ Group of this shape. Shapes in the same group don't collide.
311    layers*: TLayers   #/ Layer bitmask for this shape. Shapes only collide if the bitwise and of their layers is non-zero.
312    space: PSpace        #PRIVATE
313    next: PShape         #PRIVATE
314    prev: PShape         #PRIVATE
315    hashid: THashValue  #PRIVATE
316  PCircleShape* = ptr TCircleShape
317  TCircleShape*{.pf.} = object
318    shape: PShape
319    c, tc: TVector
320    r: CpFloat
321  PPolyShape* = ptr TPolyShape
322  TPolyShape*{.pf.} = object
323    shape: PShape
324    numVerts: cint
325    verts, tVerts: TVector
326    planes, tPlanes: PSplittingPlane
327  PSegmentShape* = ptr TSegmentShape
328  TSegmentShape*{.pf.} = object
329    shape: PShape
330    a, b, n: TVector
331    ta, tb, tn: TVector
332    r: CpFloat
333    aTangent, bTangent: TVector
334  PSplittingPlane* = ptr TSplittingPlane
335  TSplittingPlane*{.pf.} = object
336    n: TVector
337    d: CpFloat
338
339  #/ Post Step callback function type.
340  TPostStepFunc* = proc (space: PSpace; obj: pointer; data: pointer){.cdecl.}
341  #/ Point query callback function type.
342  TSpacePointQueryFunc* = proc (shape: PShape; data: pointer){.cdecl.}
343  #/ Segment query callback function type.
344  TSpaceSegmentQueryFunc* = proc (shape: PShape; t: CpFloat; n: TVector;
345                                  data: pointer){.cdecl.}
346  #/ Rectangle Query callback function type.
347  TSpaceBBQueryFunc* = proc (shape: PShape; data: pointer){.cdecl.}
348  #/ Shape query callback function type.
349  TSpaceShapeQueryFunc* = proc (shape: PShape; points: PContactPointSet;
350                                data: pointer){.cdecl.}
351  #/ Space/body iterator callback function type.
352  TSpaceBodyIteratorFunc* = proc (body: PBody; data: pointer){.cdecl.}
353  #/ Space/body iterator callback function type.
354  TSpaceShapeIteratorFunc* = proc (shape: PShape; data: pointer){.cdecl.}
355  #/ Space/constraint iterator callback function type.
356  TSpaceConstraintIteratorFunc* = proc (constraint: PConstraint;
357                                        data: pointer){.cdecl.}
358  #/ Opaque cpConstraint struct.
359  PConstraint* = ptr TConstraint
360  TConstraint*{.pf.} = object
361    klass: PConstraintClass #/PRIVATE
362    a*: PBody            #/ The first body connected to this constraint.
363    b*: PBody              #/ The second body connected to this constraint.
364    space: PSpace         #/PRIVATE
365    next_a: PConstraint  #/PRIVATE
366    next_b: PConstraint #/PRIVATE
367    maxForce*: CpFloat  #/ The maximum force that this constraint is allowed to use. Defaults to infinity.
368    errorBias*: CpFloat #/ The rate at which joint error is corrected. Defaults to pow(1.0 - 0.1, 60.0) meaning that it will correct 10% of the error every 1/60th of a second.
369    maxBias*: CpFloat    #/ The maximum rate at which joint error is corrected. Defaults to infinity.
370    preSolve*: TConstraintPreSolveFunc  #/ Function called before the solver runs. Animate your joint anchors, update your motor torque, etc.
371    postSolve*: TConstraintPostSolveFunc #/ Function called after the solver runs. Use the applied impulse to perform effects like breakable joints.
372    data*: CpDataPointer  # User definable data pointer. Generally this points to your the game object class so you can access it when given a cpConstraint reference in a callback.
373  TConstraintPreStepImpl = proc (constraint: PConstraint; dt: CpFloat){.cdecl.}
374  TConstraintApplyCachedImpulseImpl = proc (constraint: PConstraint; dt_coef: CpFloat){.cdecl.}
375  TConstraintApplyImpulseImpl = proc (constraint: PConstraint){.cdecl.}
376  TConstraintGetImpulseImpl = proc (constraint: PConstraint): CpFloat{.cdecl.}
377  PConstraintClass = ptr TConstraintClass
378  TConstraintClass{.pf.} = object
379    preStep*: TConstraintPreStepImpl
380    applyCachedImpulse*: TConstraintApplyCachedImpulseImpl
381    applyImpulse*: TConstraintApplyImpulseImpl
382    getImpulse*: TConstraintGetImpulseImpl
383  #/ Callback function type that gets called before solving a joint.
384  TConstraintPreSolveFunc* = proc (constraint: PConstraint; space: PSpace){.
385    cdecl.}
386  #/ Callback function type that gets called after solving a joint.
387  TConstraintPostSolveFunc* = proc (constraint: PConstraint; space: PSpace){.
388    cdecl.}
389
390##cp property emulators
391template defGetter(otype: typedesc, memberType: typedesc, memberName, procName: untyped) =
392  proc `get procName`*(obj: otype): memberType {.cdecl.} =
393    return obj.memberName
394template defSetter(otype: typedesc, memberType: typedesc, memberName, procName: untyped) =
395  proc `set procName`*(obj: otype, value: memberType) {.cdecl.} =
396    obj.memberName = value
397template defProp(otype: typedesc, memberType: typedesc, memberName, procName: untyped) =
398  defGetter(otype, memberType, memberName, procName)
399  defSetter(otype, memberType, memberName, procName)
400
401
402##cpspace.h
403proc allocSpace*(): PSpace {.
404  importc: "cpSpaceAlloc", dynlib: Lib.}
405proc Init*(space: PSpace): PSpace {.
406  importc: "cpSpaceInit", dynlib: Lib.}
407proc newSpace*(): PSpace {.
408  importc: "cpSpaceNew", dynlib: Lib.}
409proc destroy*(space: PSpace) {.
410  importc: "cpSpaceDestroy", dynlib: Lib.}
411proc free*(space: PSpace) {.
412  importc: "cpSpaceFree", dynlib: Lib.}
413
414defProp(PSpace, cint, iterations, Iterations)
415defProp(PSpace, TVector, gravity, Gravity)
416defProp(PSpace, CpFloat, damping, Damping)
417defProp(PSpace, CpFloat, idleSpeedThreshold, IdleSpeedThreshold)
418defProp(PSpace, CpFloat, sleepTimeThreshold, SleepTimeThreshold)
419defProp(PSpace, CpFloat, collisionSlop, CollisionSlop)
420defProp(PSpace, CpFloat, collisionBias, CollisionBias)
421defProp(PSpace, TTimestamp, collisionPersistence, CollisionPersistence)
422defProp(PSpace, Bool32, enableContactGraph, EnableContactGraph)
423defProp(PSpace, pointer, data, UserData)
424defGetter(PSpace, PBody, staticBody, StaticBody)
425defGetter(PSpace, CpFloat, currDt, CurrentTimeStep)
426
427
428#/ returns true from inside a callback and objects cannot be added/removed.
429proc isLocked*(space: PSpace): bool{.inline.} =
430  result = space.locked.bool
431
432#/ Set a default collision handler for this space.
433#/ The default collision handler is invoked for each colliding pair of shapes
434#/ that isn't explicitly handled by a specific collision handler.
435#/ You can pass NULL for any function you don't want to implement.
436proc setDefaultCollisionHandler*(space: PSpace; begin: TCollisionBeginFunc;
437                                  preSolve: TCollisionPreSolveFunc;
438                                  postSolve: TCollisionPostSolveFunc;
439                                  separate: TCollisionSeparateFunc;
440                                  data: pointer){.
441  cdecl, importc: "cpSpaceSetDefaultCollisionHandler", dynlib: Lib.}
442#/ Set a collision handler to be used whenever the two shapes with the given collision types collide.
443#/ You can pass NULL for any function you don't want to implement.
444proc addCollisionHandler*(space: PSpace; a, b: TCollisionType;
445                           begin: TCollisionBeginFunc;
446                           preSolve: TCollisionPreSolveFunc;
447                           postSolve: TCollisionPostSolveFunc;
448                           separate: TCollisionSeparateFunc; data: pointer){.
449  cdecl, importc: "cpSpaceAddCollisionHandler", dynlib: Lib.}
450#/ Unset a collision handler.
451proc removeCollisionHandler*(space: PSpace; a: TCollisionType;
452                                  b: TCollisionType){.
453  cdecl, importc: "cpSpaceRemoveCollisionHandler", dynlib: Lib.}
454#/ Add a collision shape to the simulation.
455#/ If the shape is attached to a static body, it will be added as a static shape.
456proc addShape*(space: PSpace; shape: PShape): PShape{.
457  cdecl, importc: "cpSpaceAddShape", dynlib: Lib.}
458#/ Explicitly add a shape as a static shape to the simulation.
459proc addStaticShape*(space: PSpace; shape: PShape): PShape{.
460  cdecl, importc: "cpSpaceAddStaticShape", dynlib: Lib.}
461#/ Add a rigid body to the simulation.
462proc addBody*(space: PSpace; body: PBody): PBody{.
463  cdecl, importc: "cpSpaceAddBody", dynlib: Lib.}
464#/ Add a constraint to the simulation.
465proc addConstraint*(space: PSpace; constraint: PConstraint): PConstraint{.
466    cdecl, importc: "cpSpaceAddConstraint", dynlib: Lib.}
467#/ Remove a collision shape from the simulation.
468proc removeShape*(space: PSpace; shape: PShape){.
469  cdecl, importc: "cpSpaceRemoveShape", dynlib: Lib.}
470#/ Remove a collision shape added using cpSpaceAddStaticShape() from the simulation.
471proc removeStaticShape*(space: PSpace; shape: PShape){.
472  cdecl, importc: "cpSpaceRemoveStaticShape", dynlib: Lib.}
473#/ Remove a rigid body from the simulation.
474proc removeBody*(space: PSpace; body: PBody){.
475  cdecl, importc: "cpSpaceRemoveBody", dynlib: Lib.}
476#/ Remove a constraint from the simulation.
477proc RemoveConstraint*(space: PSpace; constraint: PConstraint){.
478  cdecl, importc: "cpSpaceRemoveConstraint", dynlib: Lib.}
479#/ Test if a collision shape has been added to the space.
480proc containsShape*(space: PSpace; shape: PShape): bool{.
481  cdecl, importc: "cpSpaceContainsShape", dynlib: Lib.}
482#/ Test if a rigid body has been added to the space.
483proc containsBody*(space: PSpace; body: PBody): bool{.
484  cdecl, importc: "cpSpaceContainsBody", dynlib: Lib.}
485#/ Test if a constraint has been added to the space.
486
487proc containsConstraint*(space: PSpace; constraint: PConstraint): bool{.
488  cdecl, importc: "cpSpaceContainsConstraint", dynlib: Lib.}
489#/ Schedule a post-step callback to be called when cpSpaceStep() finishes.
490#/ @c obj is used a key, you can only register one callback per unique value for @c obj
491proc addPostStepCallback*(space: PSpace; fun: TPostStepFunc;
492                               obj: pointer; data: pointer){.
493  cdecl, importc: "cpSpaceAddPostStepCallback", dynlib: Lib.}
494
495#/ Query the space at a point and call @c func for each shape found.
496proc pointQuery*(space: PSpace; point: TVector; layers: TLayers;
497                      group: TGroup; fun: TSpacePointQueryFunc; data: pointer){.
498  cdecl, importc: "cpSpacePointQuery", dynlib: Lib.}
499
500#/ Query the space at a point and return the first shape found. Returns NULL if no shapes were found.
501proc pointQueryFirst*(space: PSpace; point: TVector; layers: TLayers;
502                       group: TGroup): PShape{.
503  cdecl, importc: "cpSpacePointQueryFirst", dynlib: Lib.}
504
505#/ Perform a directed line segment query (like a raycast) against the space calling @c func for each shape intersected.
506proc segmentQuery*(space: PSpace; start: TVector; to: TVector;
507                    layers: TLayers; group: TGroup;
508                    fun: TSpaceSegmentQueryFunc; data: pointer){.
509  cdecl, importc: "cpSpaceSegmentQuery", dynlib: Lib.}
510#/ Perform a directed line segment query (like a raycast) against the space and return the first shape hit. Returns NULL if no shapes were hit.
511proc segmentQueryFirst*(space: PSpace; start: TVector; to: TVector;
512                         layers: TLayers; group: TGroup;
513                         res: PSegmentQueryInfo): PShape{.
514  cdecl, importc: "cpSpaceSegmentQueryFirst", dynlib: Lib.}
515
516#/ Perform a fast rectangle query on the space calling @c func for each shape found.
517#/ Only the shape's bounding boxes are checked for overlap, not their full shape.
518proc BBQuery*(space: PSpace; bb: TBB; layers: TLayers; group: TGroup;
519                   fun: TSpaceBBQueryFunc; data: pointer){.
520  cdecl, importc: "cpSpaceBBQuery", dynlib: Lib.}
521
522#/ Query a space for any shapes overlapping the given shape and call @c func for each shape found.
523proc shapeQuery*(space: PSpace; shape: PShape; fun: TSpaceShapeQueryFunc; data: pointer): bool {.
524  cdecl, importc: "cpSpaceShapeQuery", dynlib: Lib.}
525#/ Call cpBodyActivate() for any shape that is overlaps the given shape.
526proc activateShapesTouchingShape*(space: PSpace; shape: PShape){.
527    cdecl, importc: "cpSpaceActivateShapesTouchingShape", dynlib: Lib.}
528
529#/ Call @c func for each body in the space.
530proc eachBody*(space: PSpace; fun: TSpaceBodyIteratorFunc; data: pointer){.
531  cdecl, importc: "cpSpaceEachBody", dynlib: Lib.}
532
533#/ Call @c func for each shape in the space.
534proc eachShape*(space: PSpace; fun: TSpaceShapeIteratorFunc;
535                     data: pointer){.
536  cdecl, importc: "cpSpaceEachShape", dynlib: Lib.}
537#/ Call @c func for each shape in the space.
538proc eachConstraint*(space: PSpace; fun: TSpaceConstraintIteratorFunc;
539                          data: pointer){.
540  cdecl, importc: "cpSpaceEachConstraint", dynlib: Lib.}
541#/ Update the collision detection info for the static shapes in the space.
542proc reindexStatic*(space: PSpace){.
543  cdecl, importc: "cpSpaceReindexStatic", dynlib: Lib.}
544#/ Update the collision detection data for a specific shape in the space.
545proc reindexShape*(space: PSpace; shape: PShape){.
546  cdecl, importc: "cpSpaceReindexShape", dynlib: Lib.}
547#/ Update the collision detection data for all shapes attached to a body.
548proc reindexShapesForBody*(space: PSpace; body: PBody){.
549  cdecl, importc: "cpSpaceReindexShapesForBody", dynlib: Lib.}
550#/ Switch the space to use a spatial has as it's spatial index.
551proc SpaceUseSpatialHash*(space: PSpace; dim: CpFloat; count: cint){.
552  cdecl, importc: "cpSpaceUseSpatialHash", dynlib: Lib.}
553#/ Step the space forward in time by @c dt.
554proc step*(space: PSpace; dt: CpFloat) {.
555  cdecl, importc: "cpSpaceStep", dynlib: Lib.}
556
557
558#/ Convenience constructor for cpVect structs.
559proc vector*(x, y: CpFloat): TVector {.inline.} =
560  result.x = x
561  result.y = y
562proc newVector*(x, y: CpFloat): TVector {.inline.} =
563  return vector(x, y)
564#let VectorZero* = newVector(0.0, 0.0)
565var VectorZero* = newVector(0.0, 0.0)
566
567#/ Vector dot product.
568proc dot*(v1, v2: TVector): CpFloat {.inline.} =
569  result = v1.x * v2.x + v1.y * v2.y
570
571#/ Returns the length of v.
572#proc len*(v: TVector): CpFloat {.
573#  cdecl, importc: "cpvlength", dynlib: Lib.}
574proc len*(v: TVector): CpFloat {.inline.} =
575  result = v.dot(v).sqrt
576#/ Spherical linearly interpolate between v1 and v2.
577proc slerp*(v1, v2: TVector; t: CpFloat): TVector {.
578  cdecl, importc: "cpvslerp", dynlib: Lib.}
579#/ Spherical linearly interpolate between v1 towards v2 by no more than angle a radians
580proc slerpconst*(v1, v2: TVector; a: CpFloat): TVector {.
581  cdecl, importc: "cpvslerpconst", dynlib: Lib.}
582#/ Returns the unit length vector for the given angle (in radians).
583#proc vectorForAngle*(a: CpFloat): TVector {.
584#  cdecl, importc: "cpvforangle", dynlib: Lib.}
585proc vectorForAngle*(a: CpFloat): TVector {.inline.} =
586  result = newVector(math.cos(a), math.sin(a))
587#/ Returns the angular direction v is pointing in (in radians).
588proc toAngle*(v: TVector): CpFloat {.inline.} =
589  result = math.arctan2(v.y, v.x)
590#/	Returns a string representation of v. Intended mostly for debugging purposes and not production use.
591#/	@attention The string points to a static local and is reset every time the function is called.
592#/	If you want to print more than one vector you will have to split up your printing onto separate lines.
593proc `$`*(v: TVector): cstring {.cdecl, importc: "cpvstr", dynlib: Lib.}
594
595
596#/ Check if two vectors are equal. (Be careful when comparing floating point numbers!)
597proc `==`*(v1, v2: TVector): bool {.inline.} =
598  result = v1.x == v2.x and v1.y == v2.y
599
600#/ Add two vectors
601proc `+`*(v1, v2: TVector): TVector {.inline.} =
602  result = newVector(v1.x + v2.x, v1.y + v2.y)
603proc `+=`*(v1: var TVector; v2: TVector) =
604  v1.x = v1.x + v2.x
605  v1.y = v1.y + v2.y
606
607#/ Subtract two vectors.
608proc `-`*(v1, v2: TVector): TVector {.inline.} =
609  result = newVector(v1.x - v2.x, v1.y - v2.y)
610proc `-=`*(v1: var TVector; v2: TVector) =
611  v1.x = v1.x - v2.x
612  v1.y = v1.y - v2.y
613
614#/ Negate a vector.
615proc `-`*(v: TVector): TVector {.inline.} =
616  result = newVector(- v.x, - v.y)
617
618#/ Scalar multiplication.
619proc `*`*(v: TVector, s: CpFloat): TVector {.inline.} =
620  result.x = v.x * s
621  result.y = v.y * s
622proc `*=`*(v: var TVector; s: CpFloat) =
623  v.x = v.x * s
624  v.y = v.y * s
625
626#/ 2D vector cross product analog.
627#/ The cross product of 2D vectors results in a 3D vector with only a z component.
628#/ This function returns the magnitude of the z value.
629proc cross*(v1, v2: TVector): CpFloat {.inline.} =
630  result = v1.x * v2.y - v1.y * v2.x
631
632#/ Returns a perpendicular vector. (90 degree rotation)
633proc perp*(v: TVector): TVector {.inline.} =
634  result = newVector(- v.y, v.x)
635
636#/ Returns a perpendicular vector. (-90 degree rotation)
637proc rperp*(v: TVector): TVector {.inline.} =
638  result = newVector(v.y, - v.x)
639
640#/ Returns the vector projection of v1 onto v2.
641proc project*(v1,v2: TVector): TVector {.inline.} =
642  result = v2 * (v1.dot(v2) / v2.dot(v2))
643
644#/ Uses complex number multiplication to rotate v1 by v2. Scaling will occur if v1 is not a unit vector.
645
646proc rotate*(v1, v2: TVector): TVector {.inline.} =
647  result = newVector(v1.x * v2.x - v1.y * v2.y, v1.x * v2.y + v1.y * v2.x)
648#/ Inverse of cpvrotate().
649proc unrotate*(v1, v2: TVector): TVector {.inline.} =
650  result = newVector(v1.x * v2.x + v1.y * v2.y, v1.y * v2.x - v1.x * v2.y)
651#/ Returns the squared length of v. Faster than cpvlength() when you only need to compare lengths.
652proc lenSq*(v: TVector): CpFloat {.inline.} =
653  result = v.dot(v)
654#/ Linearly interpolate between v1 and v2.
655proc lerp*(v1, v2: TVector; t: CpFloat): TVector {.inline.} =
656  result = (v1 * (1.0 - t)) + (v2 * t)
657#/ Returns a normalized copy of v.
658proc normalize*(v: TVector): TVector {.inline.} =
659  result = v * (1.0 / v.len)
660#/ Returns a normalized copy of v or cpvzero if v was already cpvzero. Protects against divide by zero errors.
661proc normalizeSafe*(v: TVector): TVector {.inline.} =
662  result = if v.x == 0.0 and v.y == 0.0: VectorZero else: v.normalize
663#/ Clamp v to length len.
664proc clamp*(v: TVector; len: CpFloat): TVector {.inline.} =
665  result = if v.dot(v) > len * len: v.normalize * len else: v
666#/ Linearly interpolate between v1 towards v2 by distance d.
667proc lerpconst*(v1, v2: TVector; d: CpFloat): TVector {.inline.} =
668  result = v1 + clamp(v2 - v1, d)             #vadd(v1 + vclamp(vsub(v2, v1), d))
669#/ Returns the distance between v1 and v2.
670proc dist*(v1, v2: TVector): CpFloat {.inline.} =
671  result = (v1 - v2).len #vlength(vsub(v1, v2))
672#/ Returns the squared distance between v1 and v2. Faster than cpvdist() when you only need to compare distances.
673proc distsq*(v1, v2: TVector): CpFloat {.inline.} =
674  result = (v1 - v2).lenSq  #vlengthsq(vsub(v1, v2))
675#/ Returns true if the distance between v1 and v2 is less than dist.
676proc near*(v1, v2: TVector; dist: CpFloat): bool{.inline.} =
677  result = v1.distSq(v2) < dist * dist
678
679
680
681##cpBody.h
682proc allocBody*(): PBody {.importc: "cpBodyAlloc", dynlib: Lib.}
683proc init*(body: PBody; m: CpFloat; i: CpFloat): PBody {.
684  importc: "cpBodyInit", dynlib: Lib.}
685proc newBody*(m: CpFloat; i: CpFloat): PBody {.
686  importc: "cpBodyNew", dynlib: Lib.}
687
688proc initStaticBody*(body: PBody): PBody{.
689  importc: "cpBodyInitStatic", dynlib: Lib.}
690#/ Allocate and initialize a static cpBody.
691proc newStatic*(): PBody{.importc: "cpBodyNewStatic", dynlib: Lib.}
692#/ Destroy a cpBody.
693proc destroy*(body: PBody){.importc: "cpBodyDestroy", dynlib: Lib.}
694#/ Destroy and free a cpBody.
695proc free*(body: PBody){.importc: "cpBodyFree", dynlib: Lib.}
696
697#/ Wake up a sleeping or idle body.
698proc activate*(body: PBody){.importc: "cpBodyActivate", dynlib: Lib.}
699#/ Wake up any sleeping or idle bodies touching a static body.
700proc activateStatic*(body: PBody; filter: PShape){.
701    importc: "cpBodyActivateStatic", dynlib: Lib.}
702#/ Force a body to fall asleep immediately.
703proc Sleep*(body: PBody){.importc: "cpBodySleep", dynlib: Lib.}
704#/ Force a body to fall asleep immediately along with other bodies in a group.
705proc SleepWithGroup*(body: PBody; group: PBody){.
706    importc: "cpBodySleepWithGroup", dynlib: Lib.}
707#/ Returns true if the body is sleeping.
708proc isSleeping*(body: PBody): bool {.inline.} =
709  return body.node.root != nil
710#/ Returns true if the body is static.
711proc isStatic*(body: PBody): bool {.inline.} =
712  return body.node.idleTime == CpInfinity
713#/ Returns true if the body has not been added to a space.
714proc isRogue*(body: PBody): bool {.inline.} =
715  return body.space == nil
716
717# #define CP_DefineBodyStructGetter(type, member, name) \
718# static inline type cpBodyGet##name(const cpBody *body){return body->member;}
719# #define CP_DefineBodyStructSetter(type, member, name) \
720# static inline void cpBodySet##name(cpBody *body, const type value){ \
721# 	cpBodyActivate(body); \
722# 	cpBodyAssertSane(body); \
723# 	body->member = value; \
724# }
725# #define CP_DefineBodyStructProperty(type, member, name) \
726# CP_DefineBodyStructGetter(type, member, name) \
727# CP_DefineBodyStructSetter(type, member, name)
728
729defGetter(PBody, CpFloat, m, Mass)
730#/ Set the mass of a body.
731when defined(MoreNim):
732  defSetter(PBody, CpFloat, m, Mass)
733else:
734  proc setMass*(body: PBody; m: CpFloat){.
735    cdecl, importc: "cpBodySetMass", dynlib: Lib.}
736
737#/ Get the moment of a body.
738defGetter(PBody, CpFloat, i, Moment)
739#/ Set the moment of a body.
740when defined(MoreNim):
741  defSetter(PBody, CpFloat, i, Moment)
742else:
743  proc SetMoment*(body: PBody; i: CpFloat) {.
744    cdecl, importc: "cpBodySetMoment", dynlib: Lib.}
745
746#/ Get the position of a body.
747defGetter(PBody, TVector, p, Pos)
748#/ Set the position of a body.
749when defined(MoreNim):
750  defSetter(PBody, TVector, p, Pos)
751else:
752  proc setPos*(body: PBody; pos: TVector) {.
753    cdecl, importc: "cpBodySetPos", dynlib: Lib.}
754
755defProp(PBody, TVector, v, Vel)
756defProp(PBody, TVector, f, Force)
757
758#/ Get the angle of a body.
759defGetter(PBody, CpFloat, a, Angle)
760#/ Set the angle of a body.
761proc setAngle*(body: PBody; a: CpFloat){.
762  cdecl, importc: "cpBodySetAngle", dynlib: Lib.}
763
764defProp(PBody, CpFloat, w, AngVel)
765defProp(PBody, CpFloat, t, Torque)
766defGetter(PBody, TVector, rot, Rot)
767defProp(PBody, CpFloat, v_limit, VelLimit)
768defProp(PBody, CpFloat, w_limit, AngVelLimit)
769defProp(PBody, pointer, data, UserData)
770
771#/ Default Integration functions.
772proc UpdateVelocity*(body: PBody; gravity: TVector; damping: CpFloat; dt: CpFloat){.
773  cdecl, importc: "cpBodyUpdateVelocity", dynlib: Lib.}
774proc UpdatePosition*(body: PBody; dt: CpFloat){.
775  cdecl, importc: "cpBodyUpdatePosition", dynlib: Lib.}
776#/ Convert body relative/local coordinates to absolute/world coordinates.
777proc Local2World*(body: PBody; v: TVector): TVector{.inline.} =
778  result = body.p + v.rotate(body.rot) ##return cpvadd(body.p, cpvrotate(v, body.rot))
779#/ Convert body absolute/world coordinates to  relative/local coordinates.
780proc world2Local*(body: PBody; v: TVector): TVector{.inline.} =
781  result = (v - body.p).unrotate(body.rot)
782#/ Set the forces and torque or a body to zero.
783proc resetForces*(body: PBody){.
784  cdecl, importc: "cpBodyResetForces", dynlib: Lib.}
785#/ Apply an force (in world coordinates) to the body at a point relative to the center of gravity (also in world coordinates).
786proc applyForce*(body: PBody; f, r: TVector){.
787  cdecl, importc: "cpBodyApplyForce", dynlib: Lib.}
788#/ Apply an impulse (in world coordinates) to the body at a point relative to the center of gravity (also in world coordinates).
789proc applyImpulse*(body: PBody; j, r: TVector){.
790  cdecl, importc: "cpBodyApplyImpulse", dynlib: Lib.}
791#/ Get the velocity on a body (in world units) at a point on the body in world coordinates.
792
793proc getVelAtWorldPoint*(body: PBody; point: TVector): TVector{.
794  cdecl, importc: "cpBodyGetVelAtWorldPoint", dynlib: Lib.}
795#/ Get the velocity on a body (in world units) at a point on the body in local coordinates.
796proc getVelAtLocalPoint*(body: PBody; point: TVector): TVector{.
797  cdecl, importc: "cpBodyGetVelAtLocalPoint", dynlib: Lib.}
798#/ Get the kinetic energy of a body.
799# static inline CpFloat cpBodyKineticEnergy(const cpBody *body)
800# {
801# 	// Need to do some fudging to avoid NaNs
802# 	cpFloat vsq = cpvdot(body->v, body->v);
803# 	cpFloat wsq = body->w*body->w;
804# 	return (vsq ? vsq*body->m : 0.0f) + (wsq ? wsq*body->i : 0.0f);
805# }
806proc kineticEnergy*(body: PBOdy): CpFloat =
807  result = (body.v.dot(body.v) * body.m) + (body.w * body.w * body.i)
808
809#/ Call @c func once for each shape attached to @c body and added to the space.
810proc eachShape*(body: PBody; fun: TBodyShapeIteratorFunc;
811                      data: pointer){.
812  cdecl, importc: "cpBodyEachShape", dynlib: Lib.}
813#/ Call @c func once for each constraint attached to @c body and added to the space.
814proc eachConstraint*(body: PBody; fun: TBodyConstraintIteratorFunc;
815                           data: pointer) {.
816  cdecl, importc: "cpBodyEachConstraint", dynlib: Lib.}
817#/ Call @c func once for each arbiter that is currently active on the body.
818proc eachArbiter*(body: PBody; fun: TBodyArbiterIteratorFunc;
819                        data: pointer){.
820  cdecl, importc: "cpBodyEachArbiter", dynlib: Lib.}
821#/ Allocate a spatial hash.
822proc SpaceHashAlloc*(): PSpaceHash{.
823  cdecl, importc: "cpSpaceHashAlloc", dynlib: Lib.}
824#/ Initialize a spatial hash.
825proc SpaceHashInit*(hash: PSpaceHash; celldim: CpFloat; numcells: cint;
826                    bbfun: TSpatialIndexBBFunc; staticIndex: PSpatialIndex): PSpatialIndex{.
827  cdecl, importc: "cpSpaceHashInit", dynlib: Lib.}
828#/ Allocate and initialize a spatial hash.
829proc SpaceHashNew*(celldim: CpFloat; cells: cint; bbfun: TSpatialIndexBBFunc;
830                   staticIndex: PSpatialIndex): PSpatialIndex{.
831  cdecl, importc: "cpSpaceHashNew", dynlib: Lib.}
832#/ Change the cell dimensions and table size of the spatial hash to tune it.
833#/ The cell dimensions should roughly match the average size of your objects
834#/ and the table size should be ~10 larger than the number of objects inserted.
835#/ Some trial and error is required to find the optimum numbers for efficiency.
836proc SpaceHashResize*(hash: PSpaceHash; celldim: CpFloat; numcells: cint){.
837  cdecl, importc: "cpSpaceHashResize", dynlib: Lib.}
838#MARK: AABB Tree
839
840
841#/ Allocate a bounding box tree.
842proc BBTreeAlloc*(): PBBTree{.cdecl, importc: "cpBBTreeAlloc", dynlib: Lib.}
843#/ Initialize a bounding box tree.
844proc BBTreeInit*(tree: PBBTree; bbfun: TSpatialIndexBBFunc;
845                 staticIndex: ptr TSpatialIndex): ptr TSpatialIndex{.cdecl,
846    importc: "cpBBTreeInit", dynlib: Lib.}
847#/ Allocate and initialize a bounding box tree.
848proc BBTreeNew*(bbfun: TSpatialIndexBBFunc; staticIndex: PSpatialIndex): PSpatialIndex{.
849    cdecl, importc: "cpBBTreeNew", dynlib: Lib.}
850#/ Perform a static top down optimization of the tree.
851proc BBTreeOptimize*(index: PSpatialIndex){.
852  cdecl, importc: "cpBBTreeOptimize", dynlib: Lib.}
853#/ Set the velocity function for the bounding box tree to enable temporal coherence.
854
855proc BBTreeSetVelocityFunc*(index: PSpatialIndex; fun: TBBTreeVelocityFunc){.
856    cdecl, importc: "cpBBTreeSetVelocityFunc", dynlib: Lib.}
857#MARK: Single Axis Sweep
858
859
860#/ Allocate a 1D sort and sweep broadphase.
861
862proc Sweep1DAlloc*(): ptr TSweep1D{.cdecl, importc: "cpSweep1DAlloc",
863                                    dynlib: Lib.}
864#/ Initialize a 1D sort and sweep broadphase.
865
866proc Sweep1DInit*(sweep: ptr TSweep1D; bbfun: TSpatialIndexBBFunc;
867                  staticIndex: ptr TSpatialIndex): ptr TSpatialIndex{.cdecl,
868    importc: "cpSweep1DInit", dynlib: Lib.}
869#/ Allocate and initialize a 1D sort and sweep broadphase.
870
871proc Sweep1DNew*(bbfun: TSpatialIndexBBFunc; staticIndex: ptr TSpatialIndex): ptr TSpatialIndex{.
872    cdecl, importc: "cpSweep1DNew", dynlib: Lib.}
873
874
875
876defProp(PArbiter, CpFloat, e, Elasticity)
877defProp(PArbiter, CpFloat, u, Friction)
878defProp(PArbiter, TVector, surface_vr, SurfaceVelocity)
879
880#/ Calculate the total impulse that was applied by this
881#/ This function should only be called from a post-solve, post-step or cpBodyEachArbiter callback.
882proc totalImpulse*(obj: PArbiter): TVector {.cdecl, importc: "cpArbiterTotalImpulse", dynlib: Lib.}
883
884#/ Calculate the total impulse including the friction that was applied by this arbiter.
885#/ This function should only be called from a post-solve, post-step or cpBodyEachArbiter callback.
886proc totalImpulseWithFriction*(obj: PArbiter): TVector {.cdecl, importc: "cpArbiterTotalImpulseWithFriction", dynlib: Lib.}
887
888#/ Calculate the amount of energy lost in a collision including static, but not dynamic friction.
889#/ This function should only be called from a post-solve, post-step or cpBodyEachArbiter callback.
890proc totalKE*(obj: PArbiter): CpFloat {.cdecl, importc: "cpArbiterTotalKE", dynlib: Lib.}
891
892
893#/ Causes a collision pair to be ignored as if you returned false from a begin callback.
894#/ If called from a pre-step callback, you will still need to return false
895#/ if you want it to be ignored in the current step.
896proc ignore*(arb: PArbiter) {.cdecl, importc: "cpArbiterIgnore", dynlib: Lib.}
897
898#/ Return the colliding shapes involved for this arbiter.
899#/ The order of their cpSpace.collision_type values will match
900#/ the order set when the collision handler was registered.
901proc getShapes*(arb: PArbiter, a, b: var PShape) {.inline.} =
902  if arb.swappedColl.bool:
903    a = arb.b
904    b = arb.a
905  else:
906    a = arb.a
907    b = arb.b
908
909#/ A macro shortcut for defining and retrieving the shapes from an arbiter.
910#define CP_ARBITER_GET_SHAPES(arb, a, b) cpShape *a, *b; cpArbiterGetShapes(arb, &a, &b);
911template getShapes*(arb: PArbiter, name1, name2: untyped) =
912  var name1, name2: PShape
913  getShapes(arb, name1, name2)
914
915
916#/ Return the colliding bodies involved for this arbiter.
917#/ The order of the cpSpace.collision_type the bodies are associated with values will match
918#/ the order set when the collision handler was registered.
919#proc getBodies*(arb: PArbiter, a, b: var PBody) {.inline.} =
920#  getShapes(arb, shape1, shape2)
921#  a = shape1.body
922#  b = shape2.body
923
924#/ A macro shortcut for defining and retrieving the bodies from an arbiter.
925#define CP_ARBITER_GET_BODIES(arb, a, b) cpBody *a, *b; cpArbiterGetBodies(arb, &a, &b);
926template getBodies*(arb: PArbiter, name1, name2: untyped) =
927  var name1, name2: PBOdy
928  getBodies(arb, name1, name2)
929
930proc isFirstContact*(arb: PArbiter): bool {.inline.} =
931  result = arb.state == ArbiterStateFirstColl
932
933proc getCount*(arb: PArbiter): cint {.inline.} =
934  result = arb.numContacts
935
936#/ Return a contact set from an arbiter.
937proc getContactPointSet*(arb: PArbiter): TContactPointSet {.
938  cdecl, importc: "cpArbiterGetContactPointSet", dynlib: Lib.}
939#/ Get the normal of the @c ith contact point.
940proc getNormal*(arb: PArbiter; i: cint): TVector {.
941  cdecl, importc: "cpArbiterGetNormal", dynlib: Lib.}
942#/ Get the position of the @c ith contact point.
943proc getPoint*(arb: PArbiter; i: cint): TVector {.
944  cdecl, importc: "cpArbiterGetPoint", dynlib: Lib.}
945#/ Get the depth of the @c ith contact point.
946proc getDepth*(arb: PArbiter; i: cint): CpFloat {.
947  cdecl, importc: "cpArbiterGetDepth", dynlib: Lib.}
948
949##Shapes
950template defShapeSetter(memberType: typedesc, memberName: untyped, procName: untyped, activates: bool) =
951  proc `set procName`*(obj: PShape, value: memberType) {.cdecl.} =
952    if activates and obj.body != nil: obj.body.activate()
953    obj.memberName = value
954template defShapeProp(memberType: typedesc, memberName: untyped, procName: untyped, activates: bool) =
955  defGetter(PShape, memberType, memberName, procName)
956  defShapeSetter(memberType, memberName, procName, activates)
957
958#/ Destroy a shape.
959proc destroy*(shape: PShape) {.
960  cdecl, importc: "cpShapeDestroy", dynlib: Lib.}
961#/ Destroy and Free a shape.
962proc free*(shape: PShape){.
963  cdecl, importc: "cpShapeFree", dynlib: Lib.}
964#/ Update, cache and return the bounding box of a shape based on the body it's attached to.
965proc cacheBB*(shape: PShape): TBB{.
966  cdecl, importc: "cpShapeCacheBB", dynlib: Lib.}
967#/ Update, cache and return the bounding box of a shape with an explicit transformation.
968proc update*(shape: PShape; pos: TVector; rot: TVector): TBB {.
969  cdecl, importc: "cpShapeUpdate", dynlib: Lib.}
970#/ Test if a point lies within a shape.
971proc pointQuery*(shape: PShape; p: TVector): Bool32 {.
972  cdecl, importc: "cpShapePointQuery", dynlib: Lib.}
973
974#/ Perform a nearest point query. It finds the closest point on the surface of shape to a specific point.
975#/ The value returned is the distance between the points. A negative distance means the point is inside the shape.
976proc nearestPointQuery*(shape: PShape; p: TVector; res: PNearestPointQueryInfo): CpFloat {.
977  cdecl, importc: "cpShapeNearestPointQuery", dynlib: Lib.}
978#/ Perform a segment query against a shape. @c info must be a pointer to a valid cpSegmentQueryInfo structure.
979proc segmentQuery*(shape: PShape, a, b: TVector, info: PSegmentQueryInfo): bool {.
980  cdecl, importc: "cpShapeSegmentQuery", dynlib: Lib.}
981
982#/ Get the hit point for a segment query.
983## Possibly change; info to PSegmentQueryInfo
984proc queryHitPoint*(start, to: TVector, info: TSegmentQueryInfo): TVector {.inline.} =
985  result = start.lerp(to, info.t)
986
987#/ Get the hit distance for a segment query.
988proc queryHitDist*(start, to: TVector, info: TSegmentQueryInfo): CpFloat {.inline.} =
989  result = start.dist(to) * info.t
990
991defGetter(PShape, PSpace, space, Space)
992
993defGetter(PShape, PBody, body, Body)
994proc setBody*(shape: PShape, value: PBody) {.
995  cdecl, importc: "cpShapeSetBody", dynlib: Lib.}
996
997
998defGetter(PShape, TBB, bb, BB)
999defShapeProp(Bool32, sensor, Sensor, true)
1000defShapeProp(CpFloat, e, Elasticity, false)
1001defShapeProp(CpFloat, u, Friction, true)
1002defShapeProp(TVector, surface_v, SurfaceVelocity, true)
1003defShapeProp(pointer, data, UserData, false)
1004defShapeProp(TCollisionType, collision_type, CollisionType, true)
1005defShapeProp(TGroup, group, Group, true)
1006defShapeProp(TLayers, layers, Layers, true)
1007
1008#/ When initializing a shape, it's hash value comes from a counter.
1009#/ Because the hash value may affect iteration order, you can reset the shape ID counter
1010#/ when recreating a space. This will make the simulation be deterministic.
1011proc resetShapeIdCounter*(): void {.cdecl, importc: "cpResetShapeIdCounter", dynlib: Lib.}
1012#/ Allocate a circle shape.
1013proc CircleShapeAlloc*(): PCircleShape {.cdecl, importc: "cpCircleShapeAlloc", dynlib: Lib.}
1014#/ Initialize a circle shape.
1015proc init*(circle: PCircleShape, body: PBody, radius: CpFloat, offset: TVector): PCircleShape {.
1016  cdecl, importc: "cpCircleShapeInit", dynlib: Lib.}
1017#/ Allocate and initialize a circle shape.
1018proc newCircleShape*(body: PBody, radius: CpFloat, offset: TVector): PShape {.
1019  cdecl, importc: "cpCircleShapeNew", dynlib: Lib.}
1020
1021proc getCircleOffset*(shape: PShape): TVector {.
1022  cdecl, importc: "cpCircleShapeGetOffset", dynlib: Lib.}
1023proc getCircleRadius*(shape: PShape): CpFloat {.
1024  cdecl, importc: "cpCircleShapeGetRadius", dynlib: Lib.}
1025
1026
1027#/ Allocate a polygon shape.
1028proc allocPolyShape*(): PPolyShape {.
1029  cdecl, importc: "cpPolyShapeAlloc", dynlib: Lib.}
1030#/ Initialize a polygon shape.
1031#/ A convex hull will be created from the vertices.
1032proc init*(poly: PPolyShape; body: PBody, numVerts: cint;
1033            verts: ptr TVector; offset: TVector): PPolyShape {.
1034  cdecl, importc: "cpPolyShapeInit", dynlib: Lib.}
1035#/ Allocate and initialize a polygon shape.
1036#/ A convex hull will be created from the vertices.
1037proc newPolyShape*(body: PBody; numVerts: cint; verts: ptr TVector;
1038                    offset: TVector): PShape {.
1039  cdecl, importc: "cpPolyShapeNew", dynlib: Lib.}
1040#/ Initialize a box shaped polygon shape.
1041proc init*(poly: PPolyShape; body: PBody; width, height: CpFloat): PPolyShape {.
1042  cdecl, importc: "cpBoxShapeInit", dynlib: Lib.}
1043#/ Initialize an offset box shaped polygon shape.
1044proc init*(poly: PPolyShape; body: PBody; box: TBB): PPolyShape {.
1045  cdecl, importc: "cpBoxShapeInit2", dynlib: Lib.}
1046#/ Allocate and initialize a box shaped polygon shape.
1047proc newBoxShape*(body: PBody; width, height: CpFloat): PShape {.
1048  cdecl, importc: "cpBoxShapeNew", dynlib: Lib.}
1049#/ Allocate and initialize an offset box shaped polygon shape.
1050proc newBoxShape*(body: PBody; box: TBB): PShape {.
1051  cdecl, importc: "cpBoxShapeNew2", dynlib: Lib.}
1052
1053#/ Check that a set of vertices is convex and has a clockwise winding.
1054#/ NOTE: Due to floating point precision issues, hulls created with cpQuickHull() are not guaranteed to validate!
1055proc validatePoly*(verts: ptr TVector; numVerts: cint): bool {.
1056  cdecl, importc: "cpPolyValidate", dynlib: Lib.}
1057#/ Get the number of verts in a polygon shape.
1058proc getNumVerts*(shape: PShape): cint {.
1059  cdecl, importc: "cpPolyShapeGetNumVerts", dynlib: Lib.}
1060#/ Get the @c ith vertex of a polygon shape.
1061proc getVert*(shape: PShape; index: cint): TVector {.
1062  cdecl, importc: "cpPolyShapeGetVert", dynlib: Lib.}
1063
1064#/ Allocate a segment shape.
1065proc allocSegmentShape*(): PSegmentShape {.
1066  cdecl, importc: "cpSegmentShapeAlloc", dynlib: Lib.}
1067#/ Initialize a segment shape.
1068proc init*(seg: PSegmentShape, body: PBody, a, b: TVector, radius: CpFloat): PSegmentShape {.
1069  cdecl, importc: "cpSegmentShapeInit", dynlib: Lib.}
1070#/ Allocate and initialize a segment shape.
1071proc newSegmentShape*(body: PBody, a, b: TVector, radius: CpFloat): PShape {.
1072  cdecl, importc: "cpSegmentShapeNew", dynlib: Lib.}
1073
1074proc setSegmentNeighbors*(shape: PShape, prev, next: TVector) {.
1075  cdecl, importc: "cpSegmentShapeSetNeighbors", dynlib: Lib.}
1076proc getSegmentA*(shape: PShape): TVector {.
1077  cdecl, importc: "cpSegmentShapeGetA", dynlib: Lib.}
1078proc getSegmentB*(shape: PShape): TVector {.
1079  cdecl, importc: "cpSegmentShapeGetB", dynlib: Lib.}
1080proc getSegmentNormal*(shape: PShape): TVector {.
1081  cdecl, importc: "cpSegmentShapeGetNormal", dynlib: Lib.}
1082proc getSegmentRadius*(shape: PShape): CpFloat {.
1083  cdecl, importc: "cpSegmentShapeGetRadius", dynlib: Lib.}
1084
1085
1086#/ Version string.
1087#var VersionString*{.importc: "cpVersionString", dynlib: Lib.}: cstring
1088#/ Calculate the moment of inertia for a circle.
1089#/ @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
1090when defined(MoreNim):
1091  proc momentForCircle*(m, r1, r2: CpFloat; offset: TVector): CpFloat {.cdecl.} =
1092    result = m * (0.5 * (r1 * r1 + r2 * r2) + lenSq(offset))
1093else:
1094  proc momentForCircle*(m, r1, r2: CpFloat; offset: TVector): CpFloat {.
1095    cdecl, importc: "cpMomentForCircle", dynlib: Lib.}
1096
1097#/ Calculate area of a hollow circle.
1098#/ @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
1099proc AreaForCircle*(r1: CpFloat; r2: CpFloat): CpFloat {.
1100  cdecl, importc: "cpAreaForCircle", dynlib: Lib.}
1101#/ Calculate the moment of inertia for a line segment.
1102#/ Beveling radius is not supported.
1103proc MomentForSegment*(m: CpFloat; a, b: TVector): CpFloat {.
1104  cdecl, importc: "cpMomentForSegment", dynlib: Lib.}
1105#/ Calculate the area of a fattened (capsule shaped) line segment.
1106proc AreaForSegment*(a, b: TVector; r: CpFloat): CpFloat {.
1107  cdecl, importc: "cpAreaForSegment", dynlib: Lib.}
1108#/ Calculate the moment of inertia for a solid polygon shape assuming it's center of gravity is at it's centroid. The offset is added to each vertex.
1109proc MomentForPoly*(m: CpFloat; numVerts: cint; verts: ptr TVector; offset: TVector): CpFloat {.
1110  cdecl, importc: "cpMomentForPoly", dynlib: Lib.}
1111#/ Calculate the signed area of a polygon. A Clockwise winding gives positive area.
1112#/ This is probably backwards from what you expect, but matches Chipmunk's the winding for poly shapes.
1113proc AreaForPoly*(numVerts: cint; verts: ptr TVector): CpFloat {.
1114  cdecl, importc: "cpAreaForPoly", dynlib: Lib.}
1115#/ Calculate the natural centroid of a polygon.
1116proc CentroidForPoly*(numVerts: cint; verts: ptr TVector): TVector {.
1117  cdecl, importc: "cpCentroidForPoly", dynlib: Lib.}
1118#/ Center the polygon on the origin. (Subtracts the centroid of the polygon from each vertex)
1119proc RecenterPoly*(numVerts: cint; verts: ptr TVector) {.
1120  cdecl, importc: "cpRecenterPoly", dynlib: Lib.}
1121#/ Calculate the moment of inertia for a solid box.
1122proc MomentForBox*(m, width, height: CpFloat): CpFloat {.
1123  cdecl, importc: "cpMomentForBox", dynlib: Lib.}
1124#/ Calculate the moment of inertia for a solid box.
1125proc MomentForBox2*(m: CpFloat; box: TBB): CpFloat {.
1126  cdecl, importc: "cpMomentForBox2", dynlib: Lib.}
1127
1128
1129
1130##constraints
1131type
1132  #TODO: all these are private
1133  #TODO: defConstraintProp()
1134  PPinJoint = ptr TPinJoint
1135  TPinJoint{.pf.} = object
1136    constraint: PConstraint
1137    anchr1: TVector
1138    anchr2: TVector
1139    dist: CpFloat
1140    r1: TVector
1141    r2: TVector
1142    n: TVector
1143    nMass: CpFloat
1144    jnAcc: CpFloat
1145    jnMax: CpFloat
1146    bias: CpFloat
1147  PSlideJoint = ptr TSlideJoint
1148  TSlideJoint{.pf.} = object
1149    constraint: PConstraint
1150    anchr1: TVector
1151    anchr2: TVector
1152    min: CpFloat
1153    max: CpFloat
1154    r1: TVector
1155    r2: TVector
1156    n: TVector
1157    nMass: CpFloat
1158    jnAcc: CpFloat
1159    jnMax: CpFloat
1160    bias: CpFloat
1161  PPivotJoint = ptr TPivotJoint
1162  TPivotJoint{.pf.} = object
1163    constraint: PConstraint
1164    anchr1: TVector
1165    anchr2: TVector
1166    r1: TVector
1167    r2: TVector
1168    k1: TVector
1169    k2: TVector
1170    jAcc: TVector
1171    jMaxLen: CpFloat
1172    bias: TVector
1173  PGrooveJoint = ptr TGrooveJoint
1174  TGrooveJoint{.pf.} = object
1175    constraint: PConstraint
1176    grv_n: TVector
1177    grv_a: TVector
1178    grv_b: TVector
1179    anchr2: TVector
1180    grv_tn: TVector
1181    clamp: CpFloat
1182    r1: TVector
1183    r2: TVector
1184    k1: TVector
1185    k2: TVector
1186    jAcc: TVector
1187    jMaxLen: CpFloat
1188    bias: TVector
1189  PDampedSpring = ptr TDampedSpring
1190  TDampedSpring{.pf.} = object
1191    constraint: PConstraint
1192    anchr1: TVector
1193    anchr2: TVector
1194    restLength: CpFloat
1195    stiffness: CpFloat
1196    damping: CpFloat
1197    springForceFunc: TDampedSpringForceFunc
1198    target_vrn: CpFloat
1199    v_coef: CpFloat
1200    r1: TVector
1201    r2: TVector
1202    nMass: CpFloat
1203    n: TVector
1204  PDampedRotarySpring = ptr TDampedRotarySpring
1205  TDampedRotarySpring{.pf.} = object
1206    constraint: PConstraint
1207    restAngle: CpFloat
1208    stiffness: CpFloat
1209    damping: CpFloat
1210    springTorqueFunc: TDampedRotarySpringTorqueFunc
1211    target_wrn: CpFloat
1212    w_coef: CpFloat
1213    iSum: CpFloat
1214  PRotaryLimitJoint = ptr TRotaryLimitJoint
1215  TRotaryLimitJoint{.pf.} = object
1216    constraint: PConstraint
1217    min: CpFloat
1218    max: CpFloat
1219    iSum: CpFloat
1220    bias: CpFloat
1221    jAcc: CpFloat
1222    jMax: CpFloat
1223  PRatchetJoint = ptr TRatchetJoint
1224  TRatchetJoint{.pf.} = object
1225    constraint: PConstraint
1226    angle: CpFloat
1227    phase: CpFloat
1228    ratchet: CpFloat
1229    iSum: CpFloat
1230    bias: CpFloat
1231    jAcc: CpFloat
1232    jMax: CpFloat
1233  PGearJoint = ptr TGearJoint
1234  TGearJoint{.pf.} = object
1235    constraint: PConstraint
1236    phase: CpFloat
1237    ratio: CpFloat
1238    ratio_inv: CpFloat
1239    iSum: CpFloat
1240    bias: CpFloat
1241    jAcc: CpFloat
1242    jMax: CpFloat
1243  PSimpleMotor = ptr TSimpleMotor
1244  TSimpleMotor{.pf.} = object
1245    constraint: PConstraint
1246    rate: CpFloat
1247    iSum: CpFloat
1248    jAcc: CpFloat
1249    jMax: CpFloat
1250  TDampedSpringForceFunc* = proc (spring: PConstraint; dist: CpFloat): CpFloat{.
1251    cdecl.}
1252  TDampedRotarySpringTorqueFunc* = proc (spring: PConstraint;
1253      relativeAngle: CpFloat): CpFloat {.cdecl.}
1254#/ Destroy a constraint.
1255proc destroy*(constraint: PConstraint){.
1256  cdecl, importc: "cpConstraintDestroy", dynlib: Lib.}
1257#/ Destroy and free a constraint.111
1258proc free*(constraint: PConstraint){.
1259  cdecl, importc: "cpConstraintFree", dynlib: Lib.}
1260
1261#/ @private
1262proc activateBodies(constraint: PConstraint) {.inline.} =
1263  if not constraint.a.isNil: constraint.a.activate()
1264  if not constraint.b.isNil: constraint.b.activate()
1265
1266# /// @private
1267# #define CP_DefineConstraintStructGetter(type, member, name) \
1268# static inline type cpConstraint##Get##name(const cpConstraint *constraint){return constraint->member;}
1269# /// @private
1270# #define CP_DefineConstraintStructSetter(type, member, name) \
1271# static inline void cpConstraint##Set##name(cpConstraint *constraint, type value){ \
1272# 	cpConstraintActivateBodies(constraint); \
1273# 	constraint->member = value; \
1274# }
1275template defConstraintSetter(memberType: typedesc, member, name: untyped) =
1276  proc `set name`*(constraint: PConstraint, value: memberType) {.cdecl.} =
1277    activateBodies(constraint)
1278    constraint.member = value
1279template defConstraintProp(memberType: typedesc, member, name: untyped) =
1280  defGetter(PConstraint, memberType, member, name)
1281  defConstraintSetter(memberType, member, name)
1282# CP_DefineConstraintStructGetter(cpSpace*, CP_PRIVATE(space), Space)
1283defGetter(PConstraint, PSpace, space, Space)
1284defGetter(PConstraint, PBody, a, A)
1285defGetter(PConstraint, PBody, a, B)
1286defGetter(PConstraint, CpFloat, maxForce, MaxForce)
1287defGetter(PConstraint, CpFloat, errorBias, ErrorBias)
1288defGetter(PConstraint, CpFloat, maxBias, MaxBias)
1289defGetter(PConstraint, TConstraintPreSolveFunc, preSolve, PreSolveFunc)
1290defGetter(PConstraint, TConstraintPostSolveFunc, postSolve, PostSolveFunc)
1291defGetter(PConstraint, CpDataPointer, data, UserData)
1292# Get the last impulse applied by this constraint.
1293proc getImpulse*(constraint: PConstraint): CpFloat {.inline.} =
1294  return constraint.klass.getImpulse(constraint)
1295
1296# #define cpConstraintCheckCast(constraint, struct) \
1297# 	cpAssertHard(constraint->CP_PRIVATE(klass) == struct##GetClass(), "Constraint is not a "#struct)
1298# #define CP_DefineConstraintGetter(struct, type, member, name) \
1299# static inline type struct##Get##name(const cpConstraint *constraint){ \
1300# 	cpConstraintCheckCast(constraint, struct); \
1301# 	return ((struct *)constraint)->member; \
1302# }
1303# #define CP_DefineConstraintSetter(struct, type, member, name) \
1304# static inline void struct##Set##name(cpConstraint *constraint, type value){ \
1305# 	cpConstraintCheckCast(constraint, struct); \
1306# 	cpConstraintActivateBodies(constraint); \
1307# 	((struct *)constraint)->member = value; \
1308# }
1309template constraintCheckCast(constraint: PConstraint, ctype: untyped) =
1310  assert(constraint.klass == `ctype getClass`(), "Constraint is the wrong class")
1311template defCGetter(ctype: untyped, memberType: typedesc, member, name: untyped) =
1312  proc `get ctype name`*(constraint: PConstraint): memberType {.cdecl.} =
1313    constraintCheckCast(constraint, ctype)
1314    result = cast[`P ctype`](constraint).member
1315template defCSetter(ctype: untyped, memberType: typedesc, member, name: untyped) =
1316  proc `set ctype name`*(constraint: PConstraint, value: memberType) {.cdecl.} =
1317    constraintCheckCast(constraint, ctype)
1318    activateBodies(constraint)
1319    cast[`P ctype`](constraint).member = value
1320template defCProp(ctype: untyped, memberType: typedesc, member, name: untyped) =
1321  defCGetter(ctype, memberType, member, name)
1322  defCSetter(ctype, memberType, member, name)
1323
1324proc PinJointGetClass*(): PConstraintClass{.
1325  cdecl, importc: "cpPinJointGetClass", dynlib: Lib.}
1326#/ @private
1327
1328#/ Allocate a pin joint.
1329proc AllocPinJoint*(): PPinJoint{.
1330  cdecl, importc: "cpPinJointAlloc", dynlib: Lib.}
1331#/ Initialize a pin joint.
1332proc PinJointInit*(joint: PPinJoint; a: PBody; b: PBody; anchr1: TVector;
1333                   anchr2: TVector): PPinJoint{.
1334  cdecl, importc: "cpPinJointInit", dynlib: Lib.}
1335#/ Allocate and initialize a pin joint.
1336proc newPinJoint*(a: PBody; b: PBody; anchr1: TVector; anchr2: TVector): PConstraint{.
1337  cdecl, importc: "cpPinJointNew", dynlib: Lib.}
1338# CP_DefineConstraintProperty(cpPinJoint, cpVect, anchr1, Anchr1)
1339defCProp(PinJoint, TVector, anchr1, Anchr1)
1340defCProp(PinJoint, TVector, anchr2, Anchr2)
1341defCProp(PinJoint, CpFloat, dist, Dist)
1342
1343proc SlideJointGetClass*(): PConstraintClass{.
1344  cdecl, importc: "cpSlideJointGetClass", dynlib: Lib.}
1345#/ Allocate a slide joint.
1346proc AllocSlideJoint*(): PSlideJoint{.
1347  cdecl, importc: "cpSlideJointAlloc", dynlib: Lib.}
1348#/ Initialize a slide joint.
1349proc init*(joint: PSlideJoint; a, b: PBody; anchr1, anchr2: TVector;
1350            min, max: CpFloat): PSlideJoint{.
1351  cdecl, importc: "cpSlideJointInit", dynlib: Lib.}
1352#/ Allocate and initialize a slide joint.
1353proc newSlideJoint*(a, b: PBody; anchr1, anchr2: TVector; min, max: CpFloat): PConstraint{.
1354  cdecl, importc: "cpSlideJointNew", dynlib: Lib.}
1355
1356defCProp(SlideJoint, TVector, anchr1, Anchr1)
1357defCProp(SlideJoint, TVector, anchr2, Anchr2)
1358defCProp(SlideJoint, CpFloat, min, Min)
1359defCProp(SlideJoint, CpFloat, max, Max)
1360
1361proc PivotJointGetClass*(): PConstraintClass {.
1362  cdecl, importc: "cpPivotJointGetClass", dynlib: Lib.}
1363
1364#/ Allocate a pivot joint
1365proc allocPivotJoint*(): PPivotJoint{.
1366  cdecl, importc: "cpPivotJointAlloc", dynlib: Lib.}
1367#/ Initialize a pivot joint.
1368proc init*(joint: PPivotJoint; a, b: PBody; anchr1, anchr2: TVector): PPivotJoint{.
1369  cdecl, importc: "cpPivotJointInit", dynlib: Lib.}
1370#/ Allocate and initialize a pivot joint.
1371proc newPivotJoint*(a, b: PBody; pivot: TVector): PConstraint{.
1372  cdecl, importc: "cpPivotJointNew", dynlib: Lib.}
1373#/ Allocate and initialize a pivot joint with specific anchors.
1374proc newPivotJoint*(a, b: PBody; anchr1, anchr2: TVector): PConstraint{.
1375  cdecl, importc: "cpPivotJointNew2", dynlib: Lib.}
1376
1377defCProp(PivotJoint, TVector, anchr1, Anchr1)
1378defCProp(PivotJoint, TVector, anchr2, Anchr2)
1379
1380
1381proc GrooveJointGetClass*(): PConstraintClass{.
1382  cdecl, importc: "cpGrooveJointGetClass", dynlib: Lib.}
1383#/ Allocate a groove joint.
1384proc GrooveJointAlloc*(): ptr TGrooveJoint{.
1385  cdecl, importc: "cpGrooveJointAlloc", dynlib: Lib.}
1386#/ Initialize a groove joint.
1387proc Init*(joint: PGrooveJoint; a, b: PBody; groove_a, groove_b, anchr2: TVector): PGrooveJoint{.
1388  cdecl, importc: "cpGrooveJointInit", dynlib: Lib.}
1389#/ Allocate and initialize a groove joint.
1390proc newGrooveJoint*(a, b: PBody; groove_a, groove_b, anchr2: TVector): PConstraint{.
1391  cdecl, importc: "cpGrooveJointNew", dynlib: Lib.}
1392
1393defCGetter(GrooveJoint, TVector, grv_a, GrooveA)
1394defCGetter(GrooveJoint, TVector, grv_b, GrooveB)
1395# /// Set endpoint a of a groove joint's groove
1396proc SetGrooveA*(constraint: PConstraint, value: TVector) {.
1397  cdecl, importc: "cpGrooveJointSetGrooveA", dynlib: Lib.}
1398# /// Set endpoint b of a groove joint's groove
1399proc SetGrooveB*(constraint: PConstraint, value: TVector) {.
1400  cdecl, importc: "cpGrooveJointSetGrooveB", dynlib: Lib.}
1401defCProp(GrooveJoint, TVector, anchr2, Anchr2)
1402
1403proc DampedSpringGetClass*(): PConstraintClass{.
1404  cdecl, importc: "cpDampedSpringGetClass", dynlib: Lib.}
1405#/ Allocate a damped spring.
1406proc AllocDampedSpring*(): PDampedSpring{.
1407  cdecl, importc: "cpDampedSpringAlloc", dynlib: Lib.}
1408#/ Initialize a damped spring.
1409proc init*(joint: PDampedSpring; a, b: PBody; anchr1, anchr2: TVector;
1410            restLength, stiffness, damping: CpFloat): PDampedSpring{.
1411  cdecl, importc: "cpDampedSpringInit", dynlib: Lib.}
1412#/ Allocate and initialize a damped spring.
1413proc newDampedSpring*(a, b: PBody; anchr1, anchr2: TVector;
1414                      restLength, stiffness, damping: CpFloat): PConstraint{.
1415  cdecl, importc: "cpDampedSpringNew", dynlib: Lib.}
1416
1417# CP_DefineConstraintProperty(cpDampedSpring, cpVect, anchr1, Anchr1)
1418defCProp(DampedSpring, TVector, anchr1, Anchr1)
1419defCProp(DampedSpring, TVector, anchr2, Anchr2)
1420defCProp(DampedSpring, CpFloat, restLength, RestLength)
1421defCProp(DampedSpring, CpFloat, stiffness, Stiffness)
1422defCProp(DampedSpring, CpFloat, damping, Damping)
1423defCProp(DampedSpring, TDampedSpringForceFunc, springForceFunc, SpringForceFunc)
1424
1425
1426proc DampedRotarySpringGetClass*(): PConstraintClass{.
1427  cdecl, importc: "cpDampedRotarySpringGetClass", dynlib: Lib.}
1428
1429#/ Allocate a damped rotary spring.
1430proc DampedRotarySpringAlloc*(): PDampedRotarySpring{.
1431  cdecl, importc: "cpDampedRotarySpringAlloc", dynlib: Lib.}
1432#/ Initialize a damped rotary spring.
1433proc init*(joint: PDampedRotarySpring; a, b: PBody;
1434            restAngle, stiffness, damping: CpFloat): PDampedRotarySpring{.
1435  cdecl, importc: "cpDampedRotarySpringInit", dynlib: Lib.}
1436#/ Allocate and initialize a damped rotary spring.
1437proc DampedRotarySpringNew*(a, b: PBody; restAngle, stiffness, damping: CpFloat): PConstraint{.
1438  cdecl, importc: "cpDampedRotarySpringNew", dynlib: Lib.}
1439
1440defCProp(DampedRotarySpring, CpFloat, restAngle, RestAngle)
1441defCProp(DampedRotarySpring, CpFloat, stiffness, Stiffness)
1442defCProp(DampedRotarySpring, CpFloat, damping, Damping)
1443defCProp(DampedRotarySpring, TDampedRotarySpringTorqueFunc, springTorqueFunc, SpringTorqueFunc)
1444
1445
1446proc RotaryLimitJointGetClass*(): PConstraintClass{.
1447  cdecl, importc: "cpRotaryLimitJointGetClass", dynlib: Lib.}
1448#/ Allocate a damped rotary limit joint.
1449proc allocRotaryLimitJoint*(): PRotaryLimitJoint{.
1450  cdecl, importc: "cpRotaryLimitJointAlloc", dynlib: Lib.}
1451#/ Initialize a damped rotary limit joint.
1452proc init*(joint: PRotaryLimitJoint; a, b: PBody; min, max: CpFloat): PRotaryLimitJoint{.
1453  cdecl, importc: "cpRotaryLimitJointInit", dynlib: Lib.}
1454#/ Allocate and initialize a damped rotary limit joint.
1455proc newRotaryLimitJoint*(a, b: PBody; min, max: CpFloat): PConstraint{.
1456  cdecl, importc: "cpRotaryLimitJointNew", dynlib: Lib.}
1457
1458defCProp(RotaryLimitJoint, CpFloat, min, Min)
1459defCProp(RotaryLimitJoint, CpFloat, max, Max)
1460
1461
1462proc RatchetJointGetClass*(): PConstraintClass{.
1463  cdecl, importc: "cpRatchetJointGetClass", dynlib: Lib.}
1464#/ Allocate a ratchet joint.
1465proc AllocRatchetJoint*(): PRatchetJoint{.
1466  cdecl, importc: "cpRatchetJointAlloc", dynlib: Lib.}
1467#/ Initialize a ratched joint.
1468proc init*(joint: PRatchetJoint; a, b: PBody; phase, ratchet: CpFloat): PRatchetJoint{.
1469  cdecl, importc: "cpRatchetJointInit", dynlib: Lib.}
1470#/ Allocate and initialize a ratchet joint.
1471proc NewRatchetJoint*(a, b: PBody; phase, ratchet: CpFloat): PConstraint{.
1472  cdecl, importc: "cpRatchetJointNew", dynlib: Lib.}
1473
1474defCProp(RatchetJoint, CpFloat, angle, Angle)
1475defCProp(RatchetJoint, CpFloat, phase, Phase)
1476defCProp(RatchetJoint, CpFloat, ratchet, Ratchet)
1477
1478
1479proc GearJointGetClass*(): PConstraintClass{.cdecl,
1480    importc: "cpGearJointGetClass", dynlib: Lib.}
1481#/ Allocate a gear joint.
1482proc AllocGearJoint*(): PGearJoint{.
1483  cdecl, importc: "cpGearJointAlloc", dynlib: Lib.}
1484#/ Initialize a gear joint.
1485proc init*(joint: PGearJoint; a, b: PBody, phase, ratio: CpFloat): PGearJoint{.
1486  cdecl, importc: "cpGearJointInit", dynlib: Lib.}
1487#/ Allocate and initialize a gear joint.
1488proc NewGearJoint*(a, b: PBody; phase, ratio: CpFloat): PConstraint{.
1489  cdecl, importc: "cpGearJointNew", dynlib: Lib.}
1490
1491defCProp(GearJoint, CpFloat, phase, Phase)
1492defCGetter(GearJoint, CpFloat, ratio, Ratio)
1493#/ Set the ratio of a gear joint.
1494proc GearJointSetRatio*(constraint: PConstraint; value: CpFloat){.
1495  cdecl, importc: "cpGearJointSetRatio", dynlib: Lib.}
1496
1497
1498proc SimpleMotorGetClass*(): PConstraintClass{.
1499  cdecl, importc: "cpSimpleMotorGetClass", dynlib: Lib.}
1500#/ Allocate a simple motor.
1501proc AllocSimpleMotor*(): PSimpleMotor{.
1502  cdecl, importc: "cpSimpleMotorAlloc", dynlib: Lib.}
1503#/ initialize a simple motor.
1504proc init*(joint: PSimpleMotor; a, b: PBody;
1505                      rate: CpFloat): PSimpleMotor{.
1506  cdecl, importc: "cpSimpleMotorInit", dynlib: Lib.}
1507#/ Allocate and initialize a simple motor.
1508proc newSimpleMotor*(a, b: PBody; rate: CpFloat): PConstraint{.
1509  cdecl, importc: "cpSimpleMotorNew", dynlib: Lib.}
1510
1511defCProp(SimpleMotor, CpFloat, rate, Rate)
1512
1513
1514
1515