chipmunk.nim 66 KB

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