├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── chipmunk7.nimble ├── examples ├── chipmunk_test.nim ├── hello.nim ├── nim.cfg └── planets.nim └── src └── chipmunk.nim /.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | 4 | !README* 5 | !*.md 6 | !LICENSE 7 | !*.nimble 8 | !*nim.cfg 9 | !/src 10 | !/src/*.nim 11 | !/examples 12 | !/examples/*.nim 13 | !/.travis.yml 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | install: 3 | - | 4 | if [ ! -x nim-master/bin/nim ]; then 5 | git clone -b master --depth 1 git://github.com/nim-lang/nim nim-master/ 6 | cd nim-master 7 | git clone -b master --depth 1 git://github.com/nim-lang/csources csources/ 8 | cd csources 9 | sh build.sh 10 | cd .. 11 | rm -rf csources 12 | bin/nim c koch 13 | ./koch boot -d:release 14 | else 15 | cd nim-master 16 | git fetch origin 17 | if ! git merge FETCH_HEAD | grep "Already up-to-date"; then 18 | bin/nim c koch 19 | ./koch boot -d:release 20 | fi 21 | fi 22 | cd .. 23 | cache: 24 | directories: 25 | - nim-master 26 | before_script: 27 | - export PATH="nim-master/bin${PATH:+:$PATH}" 28 | 29 | script: 30 | - nim doc src/chipmunk.nim 31 | after_success: 32 | - | 33 | if [ "$TRAVIS_BRANCH" = master ] && [ "$TRAVIS_PULL_REQUEST" != true ]; then 34 | rev="$(git rev-parse --short HEAD)" 35 | 36 | git clone "https://$GH_TOKEN@github.com/$TRAVIS_REPO_SLUG" -b gh-pages gh-pages/ 37 | cd gh-pages 38 | 39 | mv ../src/chipmunk.html index.html 40 | 41 | git config user.name 'Robot' 42 | git config user.email '<>' 43 | 44 | git add -A 45 | 46 | # See if there are any changes not related to generation time 47 | git diff --staged "index.html" | tail -n +5 | grep -E '^[+\-]' | 48 | grep -vE "Made with Nim. Generated" >/dev/null 49 | 50 | if [ $? == 0 ]; then 51 | git commit -m "Generate documentation ($rev)" 52 | git push origin gh-pages >/dev/null 2>&1 53 | fi 54 | fi 55 | env: 56 | global: 57 | - secure: "GND93QsHdGUOJsMUl1k39N9olHYA4t79pSyy/wP14NCOaQXkt0dx1ZuYFJ+MYoGSAvfgzTAo6miP5a3az7cWig89vESvZgxmX+gmJm0HkUA2nabeKOHtw3u97Zxdar5dm5zXkISYrv7/VthtkWtWdWjMzF+7d26OykHsMKCjV+0=" 58 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (C) 2007-2015 Scott Lembcke and Howling Moon Software 4 | Copyright (C) 2015 Oleh Prypin 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nim-chipmunk 2 | 3 | ### [Nim][] bindings to [Chipmunk][] v7 4 | 5 | [Documentation][] 6 | 7 | [License](LICENSE): MIT 8 | 9 | [nim]: http://nim-lang.org/ 10 | [chipmunk]: http://chipmunk-physics.net/ 11 | [documentation]: http://blaxpirit.github.io/nim-chipmunk 12 | -------------------------------------------------------------------------------- /chipmunk7.nimble: -------------------------------------------------------------------------------- 1 | [Package] 2 | name: "chipmunk7" 3 | version: "0.3.0" 4 | author: "Oleh Prypin" 5 | description: "Bindings for Chipmunk, a fast and lightweight 2D game physics library." 6 | license: "MIT" 7 | srcDir: "src" 8 | [Deps] 9 | requires: "nim >= 0.10.0" 10 | -------------------------------------------------------------------------------- /examples/chipmunk_test.nim: -------------------------------------------------------------------------------- 1 | import 2 | chipmunk, 3 | csfml, 4 | math 5 | 6 | const 7 | Width = 800 8 | Height = 600 9 | 10 | type 11 | GameObjPtr = ref object 12 | circleSprite: csfml.CircleShape 13 | rectangleSprite: csfml.RectangleShape 14 | body: chipmunk.Body 15 | shape: chipmunk.Shape 16 | 17 | ## Helper procedures 18 | proc cp2sfml(v: Vect): Vector2f {.inline.} = 19 | result.x = v.x 20 | result.y = v.y 21 | 22 | proc vectorToVec2f(a: Vect): Vector2f = 23 | result.x = a.x 24 | result.y = a.y 25 | 26 | ## Global variables 27 | var 28 | window = newRenderWindow( 29 | videoMode(Width, Height, 32), "Chipmunk Test", WindowStyle.Default 30 | ) 31 | space = newSpace() 32 | gameobjects: seq[GameObjPtr] = @[] 33 | event: Event 34 | oldPos: Vect 35 | 36 | window.framerateLimit = 60 37 | space.gravity = Vect(x:8.9, y:82.3) 38 | randomize() 39 | 40 | ## Set the filters that are used to determine which objects collide and which ones don't: 41 | ## http://chipmunk-physics.net/release/ChipmunkLatest-Docs/#cpShape-Filtering 42 | const 43 | cBorder = 0b0001.BitMask 44 | cBall = 0b0010.BitMask 45 | cBox = 0b0100.BitMask 46 | cBlueBall = 0b1000.BitMask 47 | 48 | let 49 | FilterBorder = chipmunk.ShapeFilter( 50 | group: nil, 51 | categories: cBorder, 52 | mask: cBorder or cBall or cBox or cBlueBall 53 | ) 54 | FilterBall = chipmunk.ShapeFilter( 55 | group:nil, 56 | categories: cBall, 57 | mask: cBorder or cBall 58 | ) 59 | FilterBox = chipmunk.ShapeFilter( 60 | group:nil, 61 | categories: cBox, 62 | mask: cBorder or cBox or cBlueBall 63 | ) 64 | FilterBlueBall = chipmunk.ShapeFilter( 65 | group:nil, 66 | categories: cBlueBall, 67 | mask: cBorder or cBox or cBlueBall 68 | ) 69 | ## Predefined CollisionType single assignment variables 70 | let 71 | ctBorder = cast[CollisionType](1) 72 | ctBall = cast[CollisionType](2) 73 | ctBox = cast[CollisionType](3) 74 | ctBlueBall = cast[CollisionType](4) 75 | 76 | ## Collision callback definition 77 | proc ballCallback(a: Arbiter; space: Space; data: pointer): bool {.cdecl.} = 78 | echo("Inside callback") 79 | result = true 80 | ## Add collision callback only to the blue ball (when it hits the border) 81 | var handler = space.addCollisionHandler(ctBorder, ctBlueBall) 82 | handler.postSolveFunc = cast[CollisionpostSolveFunc](ballCallback) 83 | 84 | ## Add the borders 85 | var borders: seq[Vect] 86 | borders = @[ 87 | Vect(x:0.0, y:0.0), 88 | Vect(x:Width, y:0.0), 89 | Vect(x:Width, y:Height), 90 | Vect(x:0.0, y:Height)] 91 | var sfBorders = newVertexArray(PrimitiveType.LinesStrip, 4) 92 | for i in 0..3: 93 | var shape = space.addShape( 94 | newSegmentShape( 95 | space.staticBody(), 96 | borders[i], 97 | borders[(i+1) mod 4], 98 | 1.0 99 | ) 100 | ) 101 | sfBorders.getVertex(i).position = borders[i].cp2sfml 102 | shape.filter = FilterBorder 103 | shape.collisionType = ctBorder 104 | 105 | ## Helper procedures for creating shapes 106 | proc newBall(mass = 10.0, radius = 10.0): GameObjPtr = 107 | let pos = Vect(x:100.0, y:30.0) 108 | new(result) 109 | result.rectangleSprite = nil 110 | result.circleSprite = newCircleShape() 111 | result.circleSprite.radius = radius 112 | result.circleSprite.origin = Vector2f(x: radius, y: radius) 113 | result.body = space.addBody( 114 | newBody(mass, momentForCircle(mass, 0.0, radius, vzero)) 115 | ) 116 | result.body.position = pos 117 | result.shape = space.addShape( 118 | newCircleShape(result.body, radius, vzero) 119 | ) 120 | result.shape.filter = FilterBall 121 | result.shape.collisionType = ctBall 122 | 123 | proc newBox(mass = 10.0, width = 10.0, height = 10.0, 124 | position = Vect(x:30.0, y:10.0)): GameObjPtr = 125 | new(result) 126 | result.circleSprite = nil 127 | result.rectangleSprite = newRectangleShape() 128 | result.rectangleSprite.size = Vector2f(x: width, y: height) 129 | result.rectangleSprite.origin = Vector2f(x: width/2, y: height/2) 130 | result.rectangleSprite.fillColor = Yellow 131 | result.body = space.addBody(newBody(mass, momentForBox(mass, width, height))) 132 | result.body.position = position 133 | result.shape = space.addShape(newBoxShape(result.body, width, height, radius=0.0)) 134 | result.shape.filter = FilterBox 135 | result.shape.collisionType = ctBox 136 | 137 | 138 | ## Add the shapes to the space 139 | for i in 0..20: 140 | gameobjects.add(newBall(50.0, 30.0)) 141 | for i in 0..10: 142 | gameobjects.add(newBox(50.0, 30.0, 30.0, Vect(x:600.0, y:50.0+float(i)))) 143 | var ball = newBall(10.0, 15.0) 144 | ball.rectangleSprite = nil 145 | ball.circleSprite.fillColor = Blue 146 | ball.shape.filter = FilterBlueBall 147 | ball.shape.collisionType = ctBlueBall 148 | gameobjects.add(ball) 149 | 150 | ## Main loop 151 | while window.open(): 152 | while window.pollEvent(event): 153 | if event.kind == EventType.Closed: 154 | window.close() 155 | break 156 | elif event.kind == EventType.KeyPressed: 157 | if event.key.code == KeyCode.R: 158 | oldPos = ball.body.position 159 | echo("oldPos = ", repr(ball.body.position)) 160 | elif event.key.code == KeyCode.O: 161 | ball.body.position = oldPos 162 | elif event.key.code == KeyCode.Escape: 163 | window.close() 164 | break 165 | 166 | space.step(1.0/60.0) 167 | window.clear(Black) 168 | for o in gameobjects: 169 | if o.rectangleSprite == nil: 170 | o.circleSprite.position = o.body.position.vectorToVec2f 171 | o.circleSprite.rotation = o.body.angle.radToDeg() 172 | window.draw(o.circleSprite) 173 | else: 174 | o.rectangleSprite.position = o.body.position.vectorToVec2f 175 | o.rectangleSprite.rotation = o.body.angle.radToDeg() 176 | window.draw(o.rectangleSprite) 177 | window.draw(sfBorders) 178 | window.display() 179 | 180 | ## Cleanup on exit 181 | for o in gameobjects: 182 | o.body.destroy() 183 | if o.rectangleSprite == nil: 184 | o.circleSprite.destroy() 185 | else: 186 | o.rectangleSprite.destroy() 187 | 188 | space.destroy() -------------------------------------------------------------------------------- /examples/hello.nim: -------------------------------------------------------------------------------- 1 | import strutils 2 | import chipmunk 3 | 4 | 5 | var gravity = v(0, -100) 6 | 7 | var space = newSpace() 8 | space.gravity = gravity 9 | 10 | var ground = newSegmentShape(space.staticBody, v(-20, 5), v(20, -5), 0) 11 | ground.friction = 1.0 12 | var discarded = space.addShape(ground) 13 | 14 | var radius = 5.0 15 | var mass = 1.0 16 | 17 | var moment = momentForCircle(mass, 0, radius, vzero) 18 | 19 | var ballBody = space.addBody(newBody(mass, moment)) 20 | ballBody.position = v(0, 15) 21 | 22 | var ballShape = space.addShape(newCircleShape(ballBody, radius, vzero)) 23 | ballShape.friction = 0.7 24 | 25 | var timeStep = 1.0/60.0 26 | 27 | var time = 0.0 28 | while time < 2: 29 | var pos = ballBody.position 30 | var vel = ballBody.velocity 31 | echo "Time is $#. ballBody is at ($#, $#). Its velocity is ($#, $#)".format( 32 | time, pos.x, pos.y, vel.x, vel.y 33 | ) 34 | 35 | space.step(timeStep) 36 | 37 | time += timeStep 38 | 39 | when defined chipmunkNoDestructors: 40 | ballShape.destroy() 41 | ballBody.destroy() 42 | ground.destroy() 43 | space.destroy() -------------------------------------------------------------------------------- /examples/nim.cfg: -------------------------------------------------------------------------------- 1 | path: "$projectPath/../src" 2 | define: "csfmlNoDestructors" 3 | -------------------------------------------------------------------------------- /examples/planets.nim: -------------------------------------------------------------------------------- 1 | import 2 | chipmunk, 3 | csfml, 4 | math, 5 | random 6 | 7 | ## Math's randomize 8 | randomize() 9 | 10 | const 11 | gravityStrength = 50.Float 12 | CTplanet = cast[CollisionType](1) 13 | CTgravity = cast[CollisionType](2) 14 | ScreenW = 640 15 | ScreenH = 480 16 | 17 | ## Global variables 18 | var 19 | space = newSpace() 20 | window = newRenderWindow( 21 | videoMode(ScreenW, ScreenH, 32), "Planets demo", WindowStyle.Default 22 | ) 23 | screenArea = IntRect(left: 20, top: 20, width: ScreenW-20, height: ScreenH-20) 24 | circleObjects: seq[chipmunk.Shape] = newSeq[chipmunk.Shape]() 25 | segmentObjects: seq[chipmunk.Shape] = newSeq[chipmunk.Shape]() 26 | running = true 27 | event: Event 28 | clock = newClock() 29 | 30 | ## Helper procedures 31 | proc floor(vec: Vect): Vector2f = 32 | result.x = vec.x.floor 33 | result.y = vec.y.floor 34 | 35 | proc cp2sfml(vec: Vect): Vector2f = 36 | result.x = vec.x 37 | result.y = vec.y 38 | 39 | proc initCircleShape(space: Space; shape: chipmunk.Shape; 40 | userData: pointer = nil): chipmunk.Shape {.discardable.} = 41 | result = space.addShape(shape) 42 | shape.userData = csfml.newCircleShape(cast[chipmunk.CircleShape](shape).radius, 30) 43 | let circleData = cast[csfml.CircleShape](shape.userData) 44 | circleData.origin = Vector2f( 45 | x:cast[chipmunk.CircleShape](shape).radius, 46 | y:cast[chipmunk.CircleShape](shape).radius 47 | ) 48 | circleData.fillColor = Green 49 | 50 | proc drawCircle(win: RenderWindow, shape: chipmunk.Shape) = 51 | let circle = cast[csfml.CircleShape](shape.userData) 52 | circle.position = shape.body.position.floor() 53 | win.draw(circle) 54 | 55 | proc drawSegment(win: RenderWindow, shape: chipmunk.Shape) = 56 | win.draw(cast[csfml.VertexArray](shape.userData)) 57 | 58 | proc randomPoint(rect: var IntRect): Vect = 59 | result.x = (random(rect.width) + rect.left).Float 60 | result.y = (random(rect.height) + rect.top).Float 61 | 62 | proc addPlanet() = 63 | let 64 | mass = random(10_000)/10_000*10.0 65 | radius = mass * 2.0 66 | gravityRadius = radius * 8.8 67 | body = space.addBody(newBody(mass, momentForCircle(mass, 0.0, radius, vzero))) 68 | shape = initCircleShape(space, body.newCircleShape(radius, vzero)) 69 | gravity = initCircleShape(space, body.newCircleShape(gravityRadius, vzero)) 70 | gravityCircle = cast[csfml.CircleShape](gravity.userData) 71 | body.position = randomPoint(screenArea) 72 | shape.collisionType = CTplanet 73 | gravity.sensor = true 74 | gravity.collisionType = CTgravity 75 | gravityCircle.fillColor = Transparent 76 | gravityCircle.outlineColor = Blue 77 | gravityCircle.outlineThickness = 2.0 78 | circleObjects.add(shape) 79 | circleObjects.add(gravity) 80 | 81 | ## Presolver callback procedure 82 | ## (Pre-Solve > collision happend, but has not been resolved yet) 83 | ## https://chipmunk-physics.net/release/Chipmunk-7.x/Chipmunk-7.0.1-Docs/#CollisionCallbacks 84 | proc gravityApplicator(arb: Arbiter; space: Space; data: pointer): bool {.cdecl.} = 85 | var 86 | bodyA: Body 87 | bodyB: Body 88 | dist: Vect 89 | arb.bodies(addr(bodyA), addr(bodyB)) 90 | dist = bodyA.position - bodyB.position 91 | bodyB.applyForceAtWorldPoint( 92 | dist * (1.0 / dist.vnormalize.vlength * gravityStrength), 93 | vzero 94 | ) 95 | 96 | 97 | ## Startup initialization 98 | window.frameRateLimit = 60 99 | space.iterations = 20 100 | ## Add the collision callback to the presolver 101 | var handler = space.addCollisionHandler(CTgravity, CTplanet) 102 | handler.preSolveFunc = cast[CollisionPreSolveFunc](gravityApplicator) 103 | 104 | ## Add the planets and the borders 105 | block: 106 | let borders = [Vect(x:0, y:0), Vect(x:0, y:ScreenH), 107 | Vect(x:ScreenW, y:ScreenH), Vect(x:ScreenW, y:0)] 108 | for i in 0..3: 109 | var newSegment = space.addShape(space.staticBody.newSegmentShape( 110 | borders[i], borders[(i + 1) mod 4], 16.0) 111 | ) 112 | newSegment.userData = csfml.newVertexArray(PrimitiveType.Lines, 2) 113 | let vertexData = cast[VertexArray](newSegment.userData) 114 | vertexData.getVertex(0).position = cast[SegmentShape](newSegment).a.cp2sfml() 115 | vertexData.getVertex(1).position = cast[SegmentShape](newSegment).b.cp2sfml() 116 | vertexData.getVertex(0).color = Blue 117 | vertexData.getVertex(1).color = Blue 118 | segmentObjects.add(newSegment) 119 | for i in 0..29: 120 | addPlanet() 121 | 122 | ## Main loop 123 | while running: 124 | while window.pollEvent(event): 125 | if event.kind == EventType.Closed: 126 | running = false 127 | break 128 | elif event.kind == EventType.KeyPressed: 129 | if event.key.code == KeyCode.Escape: 130 | running = false 131 | break 132 | 133 | let dt = clock.restart.asSeconds / 100 134 | 135 | space.step(dt) 136 | window.clear(Black) 137 | for obj in circleObjects: 138 | window.drawCircle(obj) 139 | for obj in segmentObjects: 140 | window.drawSegment(obj) 141 | window.display() 142 | 143 | ## Cleanup 144 | space.destroy() 145 | -------------------------------------------------------------------------------- /src/chipmunk.nim: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2015 Oleh Prypin 2 | # Licensed under terms of MIT license (see LICENSE) 3 | 4 | {.deadCodeElim: on.} 5 | {.warning[SmallLshouldNotBeUsed]: off.} 6 | 7 | when defined chipmunkDestructors: 8 | # Destroy is called automatically, based on scope 9 | {.experimental.} 10 | {.pragma: destroy, override.} 11 | else: 12 | # Call destroy() manually, beware of memory leaks! 13 | {.pragma: destroy.} 14 | 15 | {.passL: "-lpthread".} 16 | when defined(windows): 17 | const lib = "chipmunk.dll" 18 | elif defined(macosx): 19 | const lib = "libchipmunk.dylib" 20 | else: 21 | const lib = "libchipmunk.so" 22 | 23 | 24 | import math 25 | 26 | proc `div`(x, y: cdouble): cdouble = x / y 27 | 28 | converter toBool[T](x: ptr T): bool = x != nil 29 | 30 | 31 | {.push dynlib: lib.} 32 | 33 | 34 | type 35 | Float* = cdouble 36 | ## Chipmunk's floating point type. 37 | 38 | HashValue* = pointer 39 | ## Hash value type. 40 | 41 | CollisionID* = uint32 42 | ## Type used internally to cache colliding object info for cpCollideShapes(). 43 | ## Should be at least 32 bits. 44 | 45 | DataPointer* = pointer 46 | ## Type used for user data pointers. 47 | 48 | CollisionType* = pointer 49 | ## Type used for cpSpace.collision_type. 50 | 51 | Group* = pointer 52 | ## Type used for cpShape.group. 53 | 54 | Bitmask* = cuint 55 | ## Type used for cpShapeFilter category and mask. 56 | 57 | Timestamp* = cuint 58 | ## Type used for various timestamps in Chipmunk. 59 | 60 | Vect* {.bycopy.} = object 61 | ## Chipmunk's 2D vector type. 62 | x*: Float 63 | y*: Float 64 | 65 | Transform* {.bycopy.} = object 66 | ## Column major affine transform. 67 | a*: Float 68 | b*: Float 69 | c*: Float 70 | d*: Float 71 | tx*: Float 72 | ty*: Float 73 | 74 | Mat2x2* {.bycopy.} = object 75 | a*: Float 76 | b*: Float 77 | c*: Float 78 | d*: Float 79 | 80 | Array* = ptr object 81 | 82 | HashSet* = ptr object 83 | 84 | Body* = ptr object 85 | 86 | ShapeObj {.inheritable.} = object 87 | Shape* = ptr ShapeObj 88 | 89 | CircleShape* = ptr object of Shape 90 | 91 | SegmentShape* = ptr object of Shape 92 | 93 | PolyShape* = ptr object of Shape 94 | 95 | ConstraintObj {.inheritable.} = object 96 | Constraint* = ptr ConstraintObj 97 | 98 | PinJoint* = ptr object of Constraint 99 | 100 | SlideJoint* = ptr object of Constraint 101 | 102 | PivotJoint* = ptr object of Constraint 103 | 104 | GrooveJoint* = ptr object of Constraint 105 | 106 | DampedSpring* = ptr object of Constraint 107 | 108 | DampedRotarySpring* = ptr object of Constraint 109 | 110 | RotaryLimitJoint* = ptr object of Constraint 111 | 112 | RatchetJoint* = ptr object of Constraint 113 | 114 | GearJoint* = ptr object of Constraint 115 | 116 | SimpleMotorJoint* = ptr object 117 | 118 | Arbiter* = ptr object 119 | 120 | Space* = ptr object 121 | 122 | BB* {.bycopy.} = object 123 | ## Chipmunk's axis-aligned 2D bounding box type. (left, bottom, right, top) 124 | l*: Float 125 | b*: Float 126 | r*: Float 127 | t*: Float 128 | 129 | SpatialIndexBBFunc* = proc (obj: pointer): BB {.cdecl.} 130 | ## Spatial index bounding box callback function type. 131 | ## The spatial index calls this function and passes you a pointer to an object you added 132 | ## when it needs to get the bounding box associated with that object. 133 | 134 | SpatialIndexIteratorFunc* = proc (obj: pointer; data: pointer) {.cdecl.} 135 | ## Spatial index/object iterator callback function type. 136 | 137 | SpatialIndexQueryFunc* = proc (obj1: pointer; obj2: pointer; id: CollisionID; data: pointer): CollisionID {.cdecl.} 138 | ## Spatial query callback function type. 139 | 140 | SpatialIndexSegmentQueryFunc* = proc (obj1: pointer; obj2: pointer; data: pointer): Float {.cdecl.} 141 | ## Spatial segment query callback function type. 142 | 143 | SpatialIndexObj {.inheritable.} = object 144 | klass*: ptr SpatialIndexClass 145 | bbfunc*: SpatialIndexBBFunc 146 | staticIndex*: SpatialIndex 147 | dynamicIndex*: SpatialIndex 148 | SpatialIndex* = ptr SpatialIndexObj 149 | 150 | SpaceHash* = ptr object of SpatialIndex 151 | 152 | BBTree* = ptr object of SpatialIndex 153 | 154 | BBTreeVelocityFunc* = proc (obj: pointer): Vect {.cdecl.} 155 | ## Bounding box tree velocity callback function. 156 | ## This function should return an estimate for the object's velocity. 157 | 158 | 159 | Sweep1D* = ptr object of SpatialIndex 160 | 161 | SpatialIndexDestroyImpl* = proc (index: SpatialIndex) {.cdecl.} 162 | 163 | SpatialIndexCountImpl* = proc (index: SpatialIndex): cint {.cdecl.} 164 | 165 | SpatialIndexEachImpl* = proc (index: SpatialIndex; `func`: SpatialIndexIteratorFunc; data: pointer) {.cdecl.} 166 | 167 | SpatialIndexContainsImpl* = proc (index: SpatialIndex; obj: pointer; hashid: HashValue): bool {.cdecl.} 168 | 169 | SpatialIndexInsertImpl* = proc (index: SpatialIndex; obj: pointer; hashid: HashValue) {.cdecl.} 170 | 171 | SpatialIndexRemoveImpl* = proc (index: SpatialIndex; obj: pointer; hashid: HashValue) {.cdecl.} 172 | 173 | SpatialIndexReindexImpl* = proc (index: SpatialIndex) {.cdecl.} 174 | 175 | SpatialIndexReindexObjectImpl* = proc (index: SpatialIndex; obj: pointer; hashid: HashValue) {.cdecl.} 176 | 177 | SpatialIndexReindexQueryImpl* = proc (index: SpatialIndex; `func`: SpatialIndexQueryFunc; data: pointer) {.cdecl.} 178 | 179 | SpatialIndexQueryImpl* = proc (index: SpatialIndex; obj: pointer; bb: BB; `func`: SpatialIndexQueryFunc; data: pointer) {.cdecl.} 180 | 181 | SpatialIndexSegmentQueryImpl* = proc (index: SpatialIndex; obj: pointer; a: Vect; b: Vect; t_exit: Float; `func`: SpatialIndexSegmentQueryFunc; data: pointer) {.cdecl.} 182 | 183 | SpatialIndexClass* {.bycopy.} = object 184 | destroy*: SpatialIndexDestroyImpl 185 | count*: SpatialIndexCountImpl 186 | each*: SpatialIndexEachImpl 187 | contains*: SpatialIndexContainsImpl 188 | insert*: SpatialIndexInsertImpl 189 | remove*: SpatialIndexRemoveImpl 190 | reindex*: SpatialIndexReindexImpl 191 | reindexObject*: SpatialIndexReindexObjectImpl 192 | reindexQuery*: SpatialIndexReindexQueryImpl 193 | query*: SpatialIndexQueryImpl 194 | segmentQuery*: SpatialIndexSegmentQueryImpl 195 | 196 | ContactPoint* {.bycopy.} = object 197 | ## Used in ContactPointSet 198 | pointA*: Vect 199 | pointB*: Vect 200 | ## The position of the contact on the surface of each shape. 201 | distance*: Float 202 | ## Penetration distance of the two shapes. Overlapping means it will be negative. 203 | ## This value is calculated as cpvdot(cpvsub(point2, point1), normal) and is ignored by cpArbiterSetContactPointSet(). 204 | 205 | 206 | ContactPointSet* {.bycopy.} = object 207 | ## A struct that wraps up the important collision data for an arbiter. 208 | count*: cint 209 | ## The number of contact points in the set. 210 | normal*: Vect 211 | ## The normal of the collision. 212 | points*: array[2, ContactPoint] 213 | ## The array of contact points. 214 | 215 | BodyType* {.size: sizeof(cint).} = enum 216 | BODY_TYPE_DYNAMIC, 217 | ## A dynamic body is one that is affected by gravity, forces, and collisions. 218 | ## This is the default body type. 219 | BODY_TYPE_KINEMATIC, 220 | ## A kinematic body is an infinite mass, user controlled body that is not affected by gravity, forces or collisions. 221 | ## Instead the body only moves based on it's velocity. 222 | ## Dynamic bodies collide normally with kinematic bodies, though the kinematic body will be unaffected. 223 | ## Collisions between two kinematic bodies, or a kinematic body and a static body produce collision callbacks, but no collision response. 224 | BODY_TYPE_STATIC 225 | ## A static body is a body that never (or rarely) moves. If you move a static body, you must call one of the cpSpaceReindex*() functions. 226 | ## Chipmunk uses this information to optimize the collision detection. 227 | ## Static bodies do not produce collision callbacks when colliding with other static bodies. 228 | 229 | BodyVelocityFunc* = proc (body: Body; gravity: Vect; damping: Float; dt: Float) {.cdecl.} 230 | ## Rigid body velocity update function type. 231 | 232 | BodyPositionFunc* = proc (body: Body; dt: Float) {.cdecl.} 233 | ## Rigid body position update function type. 234 | 235 | BodyShapeIteratorFunc* = proc (body: Body; shape: Shape; data: pointer) {.cdecl.} 236 | ## Call `func` once for each shape attached to `body` and added to the space. 237 | 238 | BodyConstraintIteratorFunc* = proc (body: Body; constraint: Constraint; data: pointer) {.cdecl.} 239 | ## Body/constraint iterator callback function type. 240 | 241 | BodyArbiterIteratorFunc* = proc (body: Body; arbiter: Arbiter; data: pointer) {.cdecl.} 242 | ## Body/arbiter iterator callback function type. 243 | 244 | PointQueryInfo* {.bycopy.} = object 245 | ## Point query info struct. 246 | shape*: Shape 247 | ## The nearest shape, NULL if no shape was within range. 248 | point*: Vect 249 | ## The closest point on the shape's surface. (in world space coordinates) 250 | distance*: Float 251 | ## The distance to the point. The distance is negative if the point is inside the shape. 252 | gradient*: Vect 253 | ## The gradient of the signed distance function. 254 | ## The value should be similar to info.p/info.d, but accurate even for very small values of info.d. 255 | 256 | SegmentQueryInfo* {.bycopy.} = object 257 | ## Segment query info struct. 258 | shape*: Shape 259 | ## The shape that was hit, or NULL if no collision occured. 260 | point*: Vect 261 | ## The point of impact. 262 | normal*: Vect 263 | ## The normal of the surface hit. 264 | alpha*: Float 265 | ## The normalized distance along the query segment in the range [0, 1]. 266 | 267 | ShapeFilter* {.bycopy.} = object 268 | ## Fast collision filtering type that is used to determine if two objects collide before calling collision or query callbacks. 269 | group*: Group 270 | ## Two objects with the same non-zero group value do not collide. 271 | ## This is generally used to group objects in a composite object together to disable self collisions. 272 | categories*: Bitmask 273 | ## A bitmask of user definable categories that this object belongs to. 274 | ## The category/mask combinations of both objects in a collision must agree for a collision to occur. 275 | mask*: Bitmask 276 | ## A bitmask of user definable category types that this object object collides with. 277 | ## The category/mask combinations of both objects in a collision must agree for a collision to occur. 278 | 279 | ConstraintPreSolveFunc* = proc (constraint: Constraint; space: Space) {.cdecl.} 280 | ## Callback function type that gets called before solving a joint. 281 | 282 | ConstraintPostSolveFunc* = proc (constraint: Constraint; space: Space) {.cdecl.} 283 | ## Callback function type that gets called after solving a joint. 284 | 285 | DampedSpringForceFunc* = proc (spring: Constraint; dist: Float): Float {.cdecl.} 286 | ## Function type used for damped spring force callbacks. 287 | 288 | DampedRotarySpringTorqueFunc* = proc (spring: Constraint; relativeAngle: Float): Float {.cdecl.} 289 | ## Function type used for damped rotary spring force callbacks. 290 | 291 | SimpleMotor* = ptr object of Constraint 292 | ## Opaque struct type for damped rotary springs. 293 | 294 | CollisionBeginFunc* = proc (arb: Arbiter; space: Space; userData: DataPointer): bool {.cdecl.} 295 | ## Collision begin event function callback type. 296 | ## Returning false from a begin callback causes the collision to be ignored until 297 | ## the the separate callback is called when the objects stop colliding. 298 | 299 | CollisionPreSolveFunc* = proc (arb: Arbiter; space: Space; userData: DataPointer): bool {.cdecl.} 300 | ## Collision pre-solve event function callback type. 301 | ## Returning false from a pre-step callback causes the collision to be ignored until the next step. 302 | 303 | CollisionPostSolveFunc* = proc (arb: Arbiter; space: Space; userData: DataPointer) {.cdecl.} 304 | ## Collision post-solve event function callback type. 305 | 306 | CollisionSeparateFunc* = proc (arb: Arbiter; space: Space; userData: DataPointer) {.cdecl.} 307 | ## Collision separate event function callback type. 308 | 309 | CollisionHandler* {.bycopy.} = object 310 | ## Struct that holds function callback pointers to configure custom collision handling. 311 | ## Collision handlers have a pair of types; when a collision occurs between two shapes that have these types, the collision handler functions are triggered. 312 | typeA*: CollisionType 313 | ## Collision type identifier of the first shape that this handler recognizes. 314 | ## In the collision handler callback, the shape with this type will be the first argument. Read only. 315 | typeB*: CollisionType 316 | ## Collision type identifier of the second shape that this handler recognizes. 317 | ## In the collision handler callback, the shape with this type will be the second argument. Read only. 318 | beginFunc*: CollisionBeginFunc 319 | ## This function is called when two shapes with types that match this collision handler begin colliding. 320 | preSolveFunc*: CollisionPreSolveFunc 321 | ## This function is called each step when two shapes with types that match this collision handler are colliding. 322 | ## It's called before the collision solver runs so that you can affect a collision's outcome. 323 | postSolveFunc*: CollisionPostSolveFunc 324 | ## This function is called each step when two shapes with types that match this collision handler are colliding. 325 | ## It's called after the collision solver runs so that you can read back information about the collision to trigger events in your game. 326 | separateFunc*: CollisionSeparateFunc 327 | ## This function is called when two shapes with types that match this collision handler stop colliding. 328 | userData*: DataPointer 329 | ## This is a user definable context pointer that is passed to all of the collision handler functions. 330 | 331 | PostStepFunc* = proc (space: Space; key: pointer; data: pointer) {.cdecl.} 332 | ## Post Step callback function type. 333 | 334 | SpacePointQueryFunc* = proc (shape: Shape; point: Vect; distance: Float; gradient: Vect; data: pointer) {.cdecl.} 335 | ## Nearest point query callback function type. 336 | 337 | SpaceSegmentQueryFunc* = proc (shape: Shape; point: Vect; normal: Vect; alpha: Float; data: pointer) {.cdecl.} 338 | ## Segment query callback function type. 339 | 340 | SpaceBBQueryFunc* = proc (shape: Shape; data: pointer) {.cdecl.} 341 | ## Rectangle Query callback function type. 342 | 343 | SpaceShapeQueryFunc* = proc (shape: Shape; points: ptr ContactPointSet; data: pointer) {.cdecl.} 344 | ## Shape query callback function type. 345 | 346 | SpaceBodyIteratorFunc* = proc (body: Body; data: pointer) {.cdecl.} 347 | ## Space/body iterator callback function type. 348 | 349 | SpaceShapeIteratorFunc* = proc (shape: Shape; data: pointer) {.cdecl.} 350 | ## Space/body iterator callback function type. 351 | 352 | SpaceConstraintIteratorFunc* = proc (constraint: Constraint; data: pointer) {.cdecl.} 353 | ## Space/constraint iterator callback function type. 354 | 355 | SpaceDebugColor* {.bycopy.} = object 356 | ## Color type to use with the space debug drawing API. 357 | r*: cfloat 358 | g*: cfloat 359 | b*: cfloat 360 | a*: cfloat 361 | 362 | SpaceDebugDrawCircleImpl* = proc (pos: Vect; angle: Float; radius: Float; outlineColor: SpaceDebugColor; fillColor: SpaceDebugColor; data: DataPointer) {.cdecl.} 363 | ## Callback type for a function that draws a filled, stroked circle. 364 | 365 | SpaceDebugDrawSegmentImpl* = proc (a: Vect; b: Vect; color: SpaceDebugColor; data: DataPointer) {.cdecl.} 366 | ## Callback type for a function that draws a line segment. 367 | 368 | SpaceDebugDrawFatSegmentImpl* = proc (a: Vect; b: Vect; radius: Float; outlineColor: SpaceDebugColor; fillColor: SpaceDebugColor; data: DataPointer) {.cdecl.} 369 | ## Callback type for a function that draws a thick line segment. 370 | 371 | SpaceDebugDrawPolygonImpl* = proc (count: cint; verts: ptr Vect; radius: Float; outlineColor: SpaceDebugColor; fillColor: SpaceDebugColor; data: DataPointer) {.cdecl.} 372 | ## Callback type for a function that draws a convex polygon. 373 | 374 | SpaceDebugDrawDotImpl* = proc (size: Float; pos: Vect; color: SpaceDebugColor; data: DataPointer) {.cdecl.} 375 | ## Callback type for a function that draws a dot. 376 | 377 | SpaceDebugDrawColorForShapeImpl* = proc (shape: Shape; data: DataPointer): SpaceDebugColor {.cdecl.} 378 | ## Callback type for a function that returns a color for a given shape. This gives you an opportunity to color shapes based on how they are used in your engine. 379 | 380 | SpaceDebugDrawFlags* {.size: sizeof(cint).} = enum 381 | SPACE_DEBUG_DRAW_SHAPES = 1 shl 0, 382 | SPACE_DEBUG_DRAW_CONSTRAINTS = 1 shl 1, 383 | SPACE_DEBUG_DRAW_COLLISION_POINTS = 1 shl 2 384 | 385 | SpaceDebugDrawOptions* {.bycopy.} = object 386 | ## Struct used with cpSpaceDebugDraw() containing drawing callbacks and other drawing settings. 387 | drawCircle*: SpaceDebugDrawCircleImpl 388 | ## Function that will be invoked to draw circles. 389 | drawSegment*: SpaceDebugDrawSegmentImpl 390 | ## Function that will be invoked to draw line segments. 391 | drawFatSegment*: SpaceDebugDrawFatSegmentImpl 392 | ## Function that will be invoked to draw thick line segments. 393 | drawPolygon*: SpaceDebugDrawPolygonImpl 394 | ## Function that will be invoked to draw convex polygons. 395 | drawDot*: SpaceDebugDrawDotImpl 396 | ## Function that will be invoked to draw dots. 397 | flags*: SpaceDebugDrawFlags 398 | ## Flags that request which things to draw (collision shapes, constraints, contact points). 399 | shapeOutlineColor*: SpaceDebugColor 400 | ## Outline color passed to the drawing function. 401 | colorForShape*: SpaceDebugDrawColorForShapeImpl 402 | ## Function that decides what fill color to draw shapes using. 403 | constraintColor*: SpaceDebugColor 404 | ## Color passed to drawing functions for constraints. 405 | collisionPointColor*: SpaceDebugColor 406 | ## Color passed to drawing functions for collision points. 407 | data*: DataPointer 408 | ## User defined context pointer passed to all of the callback functions as the 'data' argument. 409 | 410 | 411 | proc message*(condition: cstring; file: cstring; line: cint; isError: cint; isHardError: cint; message: cstring) {.varargs, cdecl, importc: "cpMessage".} 412 | 413 | 414 | proc fmax*(a: Float; b: Float): Float {.inline, cdecl.} = 415 | ## Return the max of two cpFloats 416 | return if (a > b): a else: b 417 | 418 | 419 | proc fmin*(a: Float; b: Float): Float {.inline, cdecl.} = 420 | ## Return the min of two cpFloats 421 | return if (a < b): a else: b 422 | 423 | 424 | proc fabs*(f: Float): Float {.inline, cdecl.} = 425 | ## Return the absolute value of a cpFloat. 426 | return if (f < 0): - f else: f 427 | 428 | proc fmod*(x, y: float): float {.inline, cdecl.} = 429 | ## Calculate the modulus (remainder) of x divided by y. 430 | let quotient = floor(x / y) 431 | result = x - quotient * y 432 | 433 | 434 | proc fclamp*(f: Float; min: Float; max: Float): Float {.inline, cdecl.} = 435 | ## Clamp `f` to be between `min` and `max`. 436 | return fmin(fmax(f, min), max) 437 | 438 | 439 | proc fclamp01*(f: Float): Float {.inline, cdecl.} = 440 | ## Clamp `f` to be between 0 and 1. 441 | return fmax(0.0, fmin(f, 1.0)) 442 | 443 | 444 | proc flerp*(f1: Float; f2: Float; t: Float): Float {.inline, cdecl.} = 445 | ## Linearly interpolate (or extrapolate) between `f1` and `f2` by `t` percent. 446 | return f1 * (1.0 - t) + f2 * t 447 | 448 | 449 | proc flerpconst*(f1: Float; f2: Float; d: Float): Float {.inline, cdecl.} = 450 | ## Linearly interpolate from `f1` to `f2` by no more than `d`. 451 | return f1 + fclamp(f2 - f1, - d, d) 452 | 453 | 454 | 455 | var vzero* = Vect(x: 0.0, y: 0.0) 456 | ## Constant for the zero vector. 457 | 458 | 459 | proc v*(x: Float; y: Float): Vect {.inline, cdecl.} = 460 | ## Convenience constructor for cpVect structs. 461 | var v = Vect(x: x, y: y) 462 | return v 463 | 464 | 465 | proc veql*(v1: Vect; v2: Vect): bool {.inline, cdecl.} = 466 | ## Check if two vectors are equal. (Be careful when comparing floating point numbers!) 467 | return v1.x == v2.x and v1.y == v2.y 468 | 469 | 470 | proc vadd*(v1: Vect; v2: Vect): Vect {.inline, cdecl.} = 471 | ## Add two vectors 472 | return v(v1.x + v2.x, v1.y + v2.y) 473 | 474 | 475 | proc vsub*(v1: Vect; v2: Vect): Vect {.inline, cdecl.} = 476 | ## Subtract two vectors. 477 | return v(v1.x - v2.x, v1.y - v2.y) 478 | 479 | 480 | proc vneg*(v: Vect): Vect {.inline, cdecl.} = 481 | ## Negate a vector. 482 | return v(- v.x, - v.y) 483 | 484 | 485 | proc vmult*(v: Vect; s: Float): Vect {.inline, cdecl.} = 486 | ## Scalar multiplication. 487 | return v(v.x * s, v.y * s) 488 | 489 | 490 | proc vdot*(v1: Vect; v2: Vect): Float {.inline, cdecl.} = 491 | ## Vector dot product. 492 | return v1.x * v2.x + v1.y * v2.y 493 | 494 | 495 | proc vcross*(v1: Vect; v2: Vect): Float {.inline, cdecl.} = 496 | ## 2D vector cross product analog. 497 | ## The cross product of 2D vectors results in a 3D vector with only a z component. 498 | ## This function returns the magnitude of the z value. 499 | return v1.x * v2.y - v1.y * v2.x 500 | 501 | 502 | proc vperp*(v: Vect): Vect {.inline, cdecl.} = 503 | ## Returns a perpendicular vector. (90 degree rotation) 504 | return v(- v.y, v.x) 505 | 506 | 507 | proc vrperp*(v: Vect): Vect {.inline, cdecl.} = 508 | ## Returns a perpendicular vector. (-90 degree rotation) 509 | return v(v.y, - v.x) 510 | 511 | 512 | proc vproject*(v1: Vect; v2: Vect): Vect {.inline, cdecl.} = 513 | ## Returns the vector projection of v1 onto v2. 514 | return vmult(v2, vdot(v1, v2) div vdot(v2, v2)) 515 | 516 | 517 | proc vforangle*(a: Float): Vect {.inline, cdecl.} = 518 | ## Returns the unit length vector for the given angle (in radians). 519 | return v(cos(a), sin(a)) 520 | 521 | 522 | proc vtoangle*(v: Vect): Float {.inline, cdecl.} = 523 | ## Returns the angular direction v is pointing in (in radians). 524 | return arctan2(v.y, v.x) 525 | 526 | 527 | proc vrotate*(v1: Vect; v2: Vect): Vect {.inline, cdecl.} = 528 | ## Uses complex number multiplication to rotate v1 by v2. Scaling will occur if v1 is not a unit vector. 529 | return v(v1.x * v2.x - v1.y * v2.y, v1.x * v2.y + v1.y * v2.x) 530 | 531 | 532 | proc vunrotate*(v1: Vect; v2: Vect): Vect {.inline, cdecl.} = 533 | ## Inverse of cpvrotate(). 534 | return v(v1.x * v2.x + v1.y * v2.y, v1.y * v2.x - v1.x * v2.y) 535 | 536 | 537 | proc vlengthsq*(v: Vect): Float {.inline, cdecl.} = 538 | ## Returns the squared length of v. Faster than cpvlength() when you only need to compare lengths. 539 | return vdot(v, v) 540 | 541 | 542 | proc vlength*(v: Vect): Float {.inline, cdecl.} = 543 | ## Returns the length of v. 544 | return sqrt(vdot(v, v)) 545 | 546 | 547 | proc vlerp*(v1: Vect; v2: Vect; t: Float): Vect {.inline, cdecl.} = 548 | ## Linearly interpolate between v1 and v2. 549 | return vadd(vmult(v1, 1.0 - t), vmult(v2, t)) 550 | 551 | 552 | proc vnormalize*(v: Vect): Vect {.inline, cdecl.} = 553 | ## Returns a normalized copy of v. 554 | return vmult(v, 1.0 div 555 | (vlength(v) + (cast[cdouble](2.225073858507201e-308)))) 556 | 557 | 558 | proc vslerp*(v1: Vect; v2: Vect; t: Float): Vect {.inline, cdecl.} = 559 | ## Spherical linearly interpolate between v1 and v2. 560 | var dot: Float = vdot(vnormalize(v1), vnormalize(v2)) 561 | var omega: Float = arccos(fclamp(dot, - 1.0, 1.0)) 562 | if omega < 1e-3: 563 | return vlerp(v1, v2, t) 564 | else: 565 | var denom: Float = 1.0 div sin(omega) 566 | return vadd(vmult(v1, sin((1.0 - t) * omega) * denom), 567 | vmult(v2, sin(t * omega) * denom)) 568 | 569 | 570 | proc vslerpconst*(v1: Vect; v2: Vect; a: Float): Vect {.inline, cdecl.} = 571 | ## Spherical linearly interpolate between v1 towards v2 by no more than angle a radians 572 | var dot: Float = vdot(vnormalize(v1), vnormalize(v2)) 573 | var omega: Float = arccos(fclamp(dot, - 1.0, 1.0)) 574 | return vslerp(v1, v2, fmin(a, omega) div omega) 575 | 576 | 577 | proc vclamp*(v: Vect; len: Float): Vect {.inline, cdecl.} = 578 | ## Clamp v to length len. 579 | return if (vdot(v, v) > len * len): vmult(vnormalize(v), len) else: v 580 | 581 | 582 | proc vlerpconst*(v1: Vect; v2: Vect; d: Float): Vect {.inline, cdecl.} = 583 | ## Linearly interpolate between v1 towards v2 by distance d. 584 | return vadd(v1, vclamp(vsub(v2, v1), d)) 585 | 586 | 587 | proc vdist*(v1: Vect; v2: Vect): Float {.inline, cdecl.} = 588 | ## Returns the distance between v1 and v2. 589 | return vlength(vsub(v1, v2)) 590 | 591 | 592 | proc vdistsq*(v1: Vect; v2: Vect): Float {.inline, cdecl.} = 593 | ## Returns the squared distance between v1 and v2. Faster than cpvdist() when you only need to compare distances. 594 | return vlengthsq(vsub(v1, v2)) 595 | 596 | 597 | proc vnear*(v1: Vect; v2: Vect; dist: Float): bool {.inline, cdecl.} = 598 | ## Returns true if the distance between v1 and v2 is less than dist. 599 | return vdistsq(v1, v2) < dist * dist 600 | 601 | proc newMat2x2*(a: Float; b: Float; c: Float; d: Float): Mat2x2 {.inline, cdecl.} = 602 | var m = Mat2x2(a: a, b: b, c: c, d: d) 603 | return m 604 | 605 | proc transform*(m: Mat2x2; v: Vect): Vect {.inline, cdecl.} = 606 | #"cpMat2x2Transform" 607 | return v(v.x * m.a + v.y * m.b, v.x * m.c + v.y * m.d) 608 | 609 | 610 | 611 | proc newBB*(l: Float; b: Float; r: Float; t: Float): BB {.inline, cdecl.} = 612 | ## Convenience constructor for cpBB structs. 613 | var bb = BB(l: l, b: b, r: r, t: t) 614 | return bb 615 | 616 | 617 | proc newForExtentsBB*(c: Vect; hw: Float; hh: Float): BB {.inline, cdecl.} = 618 | ## Constructs a cpBB centered on a point with the given extents (half sizes). 619 | return newBB(c.x - hw, c.y - hh, c.x + hw, c.y + hh) 620 | 621 | 622 | proc newForCircleBB*(p: Vect; r: Float): BB {.inline, cdecl.} = 623 | ## Constructs a cpBB for a circle with the given position and radius. 624 | return newForExtentsBB(p, r, r) 625 | 626 | 627 | proc intersects*(a: BB; b: BB): bool {.inline, cdecl.} = 628 | ## Returns true if `a` and `b` intersect. 629 | return a.l <= b.r and b.l <= a.r and a.b <= b.t and b.b <= a.t 630 | 631 | 632 | proc containsBB*(bb: BB; other: BB): bool {.inline, cdecl.} = 633 | ## Returns true if `other` lies completely within `bb`. 634 | return bb.l <= other.l and bb.r >= other.r and bb.b <= other.b and 635 | bb.t >= other.t 636 | 637 | 638 | proc containsVect*(bb: BB; v: Vect): bool {.inline, cdecl.} = 639 | ## Returns true if `bb` contains `v`. 640 | return bb.l <= v.x and bb.r >= v.x and bb.b <= v.y and bb.t >= v.y 641 | 642 | 643 | proc merge*(a: BB; b: BB): BB {.inline, cdecl.} = 644 | ## Returns a bounding box that holds both bounding boxes. 645 | return newBB(fmin(a.l, b.l), fmin(a.b, b.b), fmax(a.r, b.r), 646 | fmax(a.t, b.t)) 647 | 648 | 649 | proc expand*(bb: BB; v: Vect): BB {.inline, cdecl.} = 650 | ## Returns a bounding box that holds both `bb` and `v`. 651 | return newBB(fmin(bb.l, v.x), fmin(bb.b, v.y), fmax(bb.r, v.x), 652 | fmax(bb.t, v.y)) 653 | 654 | 655 | proc center*(bb: BB): Vect {.inline, cdecl.} = 656 | ## Returns the center of a bounding box. 657 | return vlerp(v(bb.l, bb.b), v(bb.r, bb.t), 0.5) 658 | 659 | 660 | proc area*(bb: BB): Float {.inline, cdecl.} = 661 | ## Returns the area of the bounding box. 662 | return (bb.r - bb.l) * (bb.t - bb.b) 663 | 664 | 665 | proc mergedArea*(a: BB; b: BB): Float {.inline, cdecl.} = 666 | ## Merges `a` and `b` and returns the area of the merged bounding box. 667 | return (fmax(a.r, b.r) - fmin(a.l, b.l)) * 668 | (fmax(a.t, b.t) - fmin(a.b, b.b)) 669 | 670 | 671 | proc segmentQuery*(bb: BB; a: Vect; b: Vect): Float {.inline, cdecl.} = 672 | ## Returns the fraction along the segment query the cpBB is hit. Returns INFINITY if it doesn't hit. 673 | var idx: Float = 1.0 div (b.x - a.x) 674 | var tx1: Float = (if bb.l == a.x: - (Inf) else: (bb.l - a.x) * idx) 675 | var tx2: Float = (if bb.r == a.x: (Inf) else: (bb.r - a.x) * idx) 676 | var txmin: Float = fmin(tx1, tx2) 677 | var txmax: Float = fmax(tx1, tx2) 678 | var idy: Float = 1.0 div (b.y - a.y) 679 | var ty1: Float = (if bb.b == a.y: - (Inf) else: (bb.b - a.y) * idy) 680 | var ty2: Float = (if bb.t == a.y: (Inf) else: (bb.t - a.y) * idy) 681 | var tymin: Float = fmin(ty1, ty2) 682 | var tymax: Float = fmax(ty1, ty2) 683 | if tymin <= txmax and txmin <= tymax: 684 | var min: Float = fmax(txmin, tymin) 685 | var max: Float = fmin(txmax, tymax) 686 | if 0.0 <= max and min <= 1.0: return fmax(min, 0.0) 687 | return Inf 688 | 689 | 690 | proc intersectsSegment*(bb: BB; a: Vect; b: Vect): bool {.inline, cdecl.} = 691 | ## Return true if the bounding box intersects the line segment with ends `a` and `b`. 692 | return segmentQuery(bb, a, b) != (Inf) 693 | 694 | 695 | proc clampVect*(bb: BB; v: Vect): Vect {.inline, cdecl.} = 696 | ## Clamp a vector to a bounding box. 697 | return v(fclamp(v.x, bb.l, bb.r), fclamp(v.y, bb.b, bb.t)) 698 | 699 | 700 | proc wrapVect*(bb: BB; v: Vect): Vect {.inline, cdecl.} = 701 | ## Wrap a vector to a bounding box. 702 | var dx: Float = fabs(bb.r - bb.l) 703 | var modx: Float = fmod(v.x - bb.l, dx) 704 | var x: Float = if (modx > 0.0): modx else: modx + dx 705 | var dy: Float = fabs(bb.t - bb.b) 706 | var mody: Float = fmod(v.y - bb.b, dy) 707 | var y: Float = if (mody > 0.0): mody else: mody + dy 708 | return v(x + bb.l, y + bb.b) 709 | 710 | 711 | proc offset*(bb: BB; v: Vect): BB {.inline, cdecl.} = 712 | ## Returns a bounding box offseted by `v`. 713 | return newBB(bb.l + v.x, bb.b + v.y, bb.r + v.x, bb.t + v.y) 714 | 715 | 716 | var TransformIdentity* = Transform(a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0) 717 | ## Identity transform matrix. 718 | 719 | 720 | proc newTransform*(a: Float; b: Float; c: Float; d: Float; tx: Float; ty: Float): Transform {.inline, cdecl.} = 721 | ## Construct a new transform matrix. 722 | ## (a, b) is the x basis vector. 723 | ## (c, d) is the y basis vector. 724 | ## (tx, ty) is the translation. 725 | var t = Transform(a: a, b: b, c: c, d: d, tx: tx, ty: ty) 726 | return t 727 | 728 | 729 | proc newTransposeTransform*(a: Float; c: Float; tx: Float; b: Float; d: Float; ty: Float): Transform {.inline, cdecl.} = 730 | ## Construct a new transform matrix in transposed order. 731 | var t = Transform(a: a, b: b, c: c, d: d, tx: tx, ty: ty) 732 | return t 733 | 734 | 735 | proc inverse*(t: Transform): Transform {.inline, cdecl.} = 736 | ## Get the inverse of a transform matrix. 737 | var inv_det: Float = 1.0 div (t.a * t.d - t.c * t.b) 738 | return newTransposeTransform(t.d * inv_det, - (t.c * inv_det), 739 | (t.c * t.ty - t.tx * t.d) * inv_det, 740 | - (t.b * inv_det), t.a * inv_det, 741 | (t.tx * t.b - t.a * t.ty) * inv_det) 742 | 743 | 744 | proc mult*(t1: Transform; t2: Transform): Transform {.inline, cdecl.} = 745 | ## Multiply two transformation matrices. 746 | return newTransposeTransform(t1.a * t2.a + t1.c * t2.b, 747 | t1.a * t2.c + t1.c * t2.d, 748 | t1.a * t2.tx + t1.c * t2.ty + t1.tx, 749 | t1.b * t2.a + t1.d * t2.b, 750 | t1.b * t2.c + t1.d * t2.d, 751 | t1.b * t2.tx + t1.d * t2.ty + t1.ty) 752 | 753 | 754 | proc point*(t: Transform; p: Vect): Vect {.inline, cdecl.} = 755 | ## Transform an absolute point. (i.e. a vertex) 756 | return v(t.a * p.x + t.c * p.y + t.tx, t.b * p.x + t.d * p.y + t.ty) 757 | 758 | 759 | proc vect*(t: Transform; v: Vect): Vect {.inline, cdecl.} = 760 | ## Transform a vector (i.e. a normal) 761 | return v(t.a * v.x + t.c * v.y, t.b * v.x + t.d * v.y) 762 | 763 | 764 | proc transformBB*(t: Transform; bb: BB): BB {.inline, cdecl.} = 765 | ## Transform a cpBB. 766 | var center: Vect = center(bb) 767 | var hw: Float = (bb.r - bb.l) * 0.5 768 | var hh: Float = (bb.t - bb.b) * 0.5 769 | var 770 | a: Float = t.a * hw 771 | b: Float = t.c * hh 772 | d: Float = t.b * hw 773 | e: Float = t.d * hh 774 | var hw_max: Float = fmax(fabs(a + b), fabs(a - b)) 775 | var hh_max: Float = fmax(fabs(d + e), fabs(d - e)) 776 | return newForExtentsBB(point(t, center), hw_max, hh_max) 777 | 778 | 779 | proc transformTranslate*(translate: Vect): Transform {.inline, cdecl.} = 780 | ## Create a transation matrix. 781 | return newTransposeTransform(1.0, 0.0, translate.x, 0.0, 1.0, translate.y) 782 | 783 | 784 | proc transformScale*(scaleX: Float; scaleY: Float): Transform {.inline, cdecl.} = 785 | ## Create a scale matrix. 786 | return newTransposeTransform(scaleX, 0.0, 0.0, 0.0, scaleY, 0.0) 787 | 788 | 789 | proc transformRotate*(radians: Float): Transform {.inline, cdecl.} = 790 | ## Create a rotation matrix. 791 | var rot: Vect = vforangle(radians) 792 | return newTransposeTransform(rot.x, - rot.y, 0.0, rot.y, rot.x, 0.0) 793 | 794 | 795 | proc transformRigid*(translate: Vect; radians: Float): Transform {.inline, cdecl.} = 796 | ## Create a rigid transformation matrix. (transation + rotation) 797 | var rot: Vect = vforangle(radians) 798 | return newTransposeTransform(rot.x, - rot.y, translate.x, rot.y, rot.x, 799 | translate.y) 800 | 801 | 802 | proc transformRigidInverse*(t: Transform): Transform {.inline, cdecl.} = 803 | ## Fast inverse of a rigid transformation matrix. 804 | return newTransposeTransform(t.d, - t.c, (t.c * t.ty - t.tx * t.d), - t.b, 805 | t.a, (t.tx * t.b - t.a * t.ty)) 806 | 807 | proc transformWrap*(outer: Transform; inner: Transform): Transform {.inline, cdecl.} = 808 | return mult(inverse(outer), 809 | mult(inner, outer)) 810 | 811 | proc transformWrapInverse*(outer: Transform; inner: Transform): Transform {.inline, cdecl.} = 812 | return mult(outer, 813 | mult(inner, inverse(outer))) 814 | 815 | proc transformOrtho*(bb: BB): Transform {.inline, cdecl.} = 816 | return newTransposeTransform(2.0 div (bb.r - bb.l), 0.0, 817 | - ((bb.r + bb.l) div (bb.r - bb.l)), 0.0, 818 | 2.0 div (bb.t - bb.b), 819 | - ((bb.t + bb.b) div (bb.t - bb.b))) 820 | 821 | proc transformBoneScale*(v0: Vect; v1: Vect): Transform {.inline, cdecl.} = 822 | var d: Vect = vsub(v1, v0) 823 | return newTransposeTransform(d.x, - d.y, v0.x, d.y, d.x, v0.y) 824 | 825 | proc transformAxialScale*(axis: Vect; pivot: Vect; scale: Float): Transform {.inline, cdecl.} = 826 | var A: Float = axis.x * axis.y * (scale - 1.0) 827 | var B: Float = vdot(axis, pivot) * (1.0 - scale) 828 | return newTransposeTransform(scale * axis.x * axis.x + axis.y * axis.y, A, 829 | axis.x * B, A, 830 | axis.x * axis.x + scale * axis.y * axis.y, 831 | axis.y * B) 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | proc allocateSpaceHash*(): SpaceHash {.cdecl, importc: "cpSpaceHashAlloc".} 840 | ## Allocate a spatial hash. 841 | 842 | proc initializeSpaceHash*(hash: SpaceHash; celldim: Float; numcells: cint; bbfunc: SpatialIndexBBFunc; staticIndex: SpatialIndex): SpatialIndex {.cdecl, importc: "cpSpaceHashInit".} 843 | ## Initialize a spatial hash. 844 | 845 | proc newSpaceHash*(celldim: Float; cells: cint; bbfunc: SpatialIndexBBFunc; staticIndex: SpatialIndex): SpaceHash {.cdecl, importc: "cpSpaceHashNew".} 846 | ## Allocate and initialize a spatial hash. 847 | 848 | proc resize*(hash: SpaceHash; celldim: Float; numcells: cint) {.cdecl, importc: "cpSpaceHashResize".} 849 | ## Change the cell dimensions and table size of the spatial hash to tune it. 850 | ## The cell dimensions should roughly match the average size of your objects 851 | ## and the table size should be ~10 larger than the number of objects inserted. 852 | ## Some trial and error is required to find the optimum numbers for efficiency. 853 | 854 | 855 | proc allocateBBTree*(): BBTree {.cdecl, importc: "cpBBTreeAlloc".} 856 | ## Allocate a bounding box tree. 857 | 858 | proc initializeBBTree*(tree: BBTree; bbfunc: SpatialIndexBBFunc; staticIndex: SpatialIndex): SpatialIndex {.cdecl, importc: "cpBBTreeInit".} 859 | ## Initialize a bounding box tree. 860 | 861 | proc newBBTree*(bbfunc: SpatialIndexBBFunc; staticIndex: SpatialIndex): BBTree {.cdecl, importc: "cpBBTreeNew".} 862 | ## Allocate and initialize a bounding box tree. 863 | 864 | proc optimize*(index: BBTree) {.cdecl, importc: "cpBBTreeOptimize".} 865 | ## Perform a static top down optimization of the tree. 866 | 867 | proc `velocityFunc=`*(index: BBTree; `func`: BBTreeVelocityFunc) {.cdecl, importc: "cpBBTreeSetVelocityFunc".} 868 | ## Set the velocity function for the bounding box tree to enable temporal coherence. 869 | 870 | proc allocateSweep1D*(): Sweep1D {.cdecl, importc: "cpSweep1DAlloc".} 871 | ## Allocate a 1D sort and sweep broadphase. 872 | 873 | proc initializeSweep1D*(sweep: Sweep1D; bbfunc: SpatialIndexBBFunc; staticIndex: SpatialIndex): SpatialIndex {.cdecl, importc: "cpSweep1DInit".} 874 | ## Initialize a 1D sort and sweep broadphase. 875 | 876 | proc newSweep1D*(bbfunc: SpatialIndexBBFunc; staticIndex: SpatialIndex): Sweep1D {.cdecl, importc: "cpSweep1DNew".} 877 | ## Allocate and initialize a 1D sort and sweep broadphase. 878 | 879 | proc destroy*(index: SpatialIndex) {.destroy, cdecl, importc: "cpSpatialIndexFree".} 880 | ## Destroy and free a spatial index. 881 | proc destroy*(index: Sweep1D) {.destroy, cdecl, importc: "cpSpatialIndexFree".} 882 | proc destroy*(index: SpaceHash) {.destroy, cdecl, importc: "cpSpatialIndexFree".} 883 | proc destroy*(index: BBTree) {.destroy, cdecl, importc: "cpSpatialIndexFree".} 884 | 885 | proc collideStatic*(dynamicIndex: SpatialIndex; staticIndex: SpatialIndex; `func`: SpatialIndexQueryFunc; data: pointer) {.cdecl, importc: "cpSpatialIndexCollideStatic".} 886 | ## Collide the objects in `dynamicIndex` against the objects in `staticIndex` using the query callback function. 887 | 888 | proc finalize*(index: SpatialIndex) {.inline, cdecl.} = 889 | ## Destroy a spatial index. 890 | if index.klass: index.klass.destroy(index) 891 | 892 | 893 | proc count*(index: SpatialIndex): cint {.inline, cdecl.} = 894 | ## Get the number of objects in the spatial index. 895 | return index.klass.count(index) 896 | 897 | 898 | proc each*(index: SpatialIndex; `func`: SpatialIndexIteratorFunc; data: pointer) {.inline, cdecl.} = 899 | ## Iterate the objects in the spatial index. `func` will be called once for each object. 900 | index.klass.each(index, `func`, data) 901 | 902 | 903 | proc contains*(index: SpatialIndex; obj: pointer; hashid: HashValue): bool {.inline, cdecl.} = 904 | ## Returns true if the spatial index contains the given object. 905 | ## Most spatial indexes use hashed storage, so you must provide a hash value too. 906 | return index.klass.contains(index, obj, hashid) 907 | 908 | 909 | proc insert*(index: SpatialIndex; obj: pointer; hashid: HashValue) {.inline, cdecl.} = 910 | ## Add an object to a spatial index. 911 | ## Most spatial indexes use hashed storage, so you must provide a hash value too. 912 | index.klass.insert(index, obj, hashid) 913 | 914 | 915 | proc remove*(index: SpatialIndex; obj: pointer; hashid: HashValue) {.inline, cdecl.} = 916 | ## Remove an object from a spatial index. 917 | ## Most spatial indexes use hashed storage, so you must provide a hash value too. 918 | index.klass.remove(index, obj, hashid) 919 | 920 | 921 | proc reindex*(index: SpatialIndex) {.inline, cdecl.} = 922 | ## Perform a full reindex of a spatial index. 923 | index.klass.reindex(index) 924 | 925 | 926 | proc reindexObject*(index: SpatialIndex; obj: pointer; hashid: HashValue) {.inline, cdecl.} = 927 | ## Reindex a single object in the spatial index. 928 | index.klass.reindexObject(index, obj, hashid) 929 | 930 | 931 | proc query*(index: SpatialIndex; obj: pointer; bb: BB; `func`: SpatialIndexQueryFunc; data: pointer) {.inline, cdecl.} = 932 | ## Perform a rectangle query against the spatial index, calling `func` for each potential match. 933 | index.klass.query(index, obj, bb, `func`, data) 934 | 935 | 936 | proc segmentQuery*(index: SpatialIndex; obj: pointer; a: Vect; b: Vect; t_exit: Float; `func`: SpatialIndexSegmentQueryFunc; data: pointer) {.inline, cdecl.} = 937 | ## Perform a segment query against the spatial index, calling `func` for each potential match. 938 | index.klass.segmentQuery(index, obj, a, b, t_exit, `func`, data) 939 | 940 | 941 | proc reindexQuery*(index: SpatialIndex; `func`: SpatialIndexQueryFunc; data: pointer) {.inline, cdecl.} = 942 | ## Simultaneously reindex and find all colliding objects. 943 | ## `func` will be called once for each potentially overlapping pair of objects found. 944 | ## If the spatial index was initialized with a static index, it will collide it's objects against that as well. 945 | index.klass.reindexQuery(index, `func`, data) 946 | 947 | 948 | proc restitution*(arb: Arbiter): Float {.cdecl, importc: "cpArbiterGetRestitution".} 949 | ## Get the restitution (elasticity) that will be applied to the pair of colliding objects. 950 | 951 | proc `restitution=`*(arb: Arbiter; restitution: Float) {.cdecl, importc: "cpArbiterSetRestitution".} 952 | ## Override the restitution (elasticity) that will be applied to the pair of colliding objects. 953 | 954 | proc friction*(arb: Arbiter): Float {.cdecl, importc: "cpArbiterGetFriction".} 955 | ## Get the friction coefficient that will be applied to the pair of colliding objects. 956 | 957 | proc `friction=`*(arb: Arbiter; friction: Float) {.cdecl, importc: "cpArbiterSetFriction".} 958 | ## Override the friction coefficient that will be applied to the pair of colliding objects. 959 | 960 | proc surfaceVelocity*(arb: Arbiter): Vect {.cdecl, importc: "cpArbiterGetSurfaceVelocity".} 961 | 962 | proc `surfaceVelocity=`*(arb: Arbiter; vr: Vect) {.cdecl, importc: "cpArbiterSetSurfaceVelocity".} 963 | 964 | proc userData*(arb: Arbiter): DataPointer {.cdecl, importc: "cpArbiterGetUserData".} 965 | ## Get the user data pointer associated with this pair of colliding objects. 966 | 967 | proc `userData=`*(arb: Arbiter; userData: DataPointer) {.cdecl, importc: "cpArbiterSetUserData".} 968 | ## Set a user data point associated with this pair of colliding objects. 969 | ## If you need to perform any cleanup for this pointer, you must do it yourself, in the separate callback for instance. 970 | 971 | proc totalImpulse*(arb: Arbiter): Vect {.cdecl, importc: "cpArbiterTotalImpulse".} 972 | ## Calculate the total impulse including the friction that was applied by this arbiter. 973 | ## This function should only be called from a post-solve, post-step or cpBodyEachArbiter callback. 974 | 975 | proc totalKE*(arb: Arbiter): Float {.cdecl, importc: "cpArbiterTotalKE".} 976 | ## Calculate the amount of energy lost in a collision including static, but not dynamic friction. 977 | ## This function should only be called from a post-solve, post-step or cpBodyEachArbiter callback. 978 | 979 | proc ignore*(arb: Arbiter): bool {.cdecl, importc: "cpArbiterIgnore".} 980 | ## Mark a collision pair to be ignored until the two objects separate. 981 | ## Pre-solve and post-solve callbacks will not be called, but the separate callback will be called. 982 | 983 | proc shapes*(arb: Arbiter; a: ptr Shape; b: ptr Shape) {.cdecl, importc: "cpArbiterGetShapes".} 984 | ## Return the colliding shapes involved for this arbiter. 985 | ## The order of their cpSpace.collision_type values will match 986 | ## the order set when the collision handler was registered. 987 | 988 | proc bodies*(arb: Arbiter; a: ptr Body; b: ptr Body) {.cdecl, importc: "cpArbiterGetBodies".} 989 | ## Return the colliding bodies involved for this arbiter. 990 | ## The order of the cpSpace.collision_type the bodies are associated with values will match 991 | ## the order set when the collision handler was registered. 992 | 993 | proc contactPointSet*(arb: Arbiter): ContactPointSet {.cdecl, importc: "cpArbiterGetContactPointSet".} 994 | ## Return a contact set from an arbiter. 995 | 996 | proc `contactPointSet=`*(arb: Arbiter; set: ptr ContactPointSet) {.cdecl, importc: "cpArbiterSetContactPointSet".} 997 | ## Replace the contact point set for an arbiter. 998 | ## This can be a very powerful feature, but use it with caution! 999 | 1000 | proc isFirstContact*(arb: Arbiter): bool {.cdecl, importc: "cpArbiterIsFirstContact".} 1001 | ## Returns true if this is the first step a pair of objects started colliding. 1002 | 1003 | proc isRemoval*(arb: Arbiter): bool {.cdecl, importc: "cpArbiterIsRemoval".} 1004 | ## Returns true if the separate callback is due to a shape being removed from the space. 1005 | 1006 | proc count*(arb: Arbiter): cint {.cdecl, importc: "cpArbiterGetCount".} 1007 | ## Get the number of contact points for this arbiter. 1008 | 1009 | proc normal*(arb: Arbiter): Vect {.cdecl, importc: "cpArbiterGetNormal".} 1010 | ## Get the normal of the collision. 1011 | 1012 | proc pointA*(arb: Arbiter; i: cint): Vect {.cdecl, importc: "cpArbiterGetPointA".} 1013 | ## Get the position of the `ith` contact point on the surface of the first shape. 1014 | 1015 | proc pointB*(arb: Arbiter; i: cint): Vect {.cdecl, importc: "cpArbiterGetPointB".} 1016 | ## Get the position of the `ith` contact point on the surface of the second shape. 1017 | 1018 | proc depth*(arb: Arbiter; i: cint): Float {.cdecl, importc: "cpArbiterGetDepth".} 1019 | ## Get the depth of the `ith` contact point. 1020 | 1021 | proc callWildcardBeginA*(arb: Arbiter; space: Space): bool {.cdecl, importc: "cpArbiterCallWildcardBeginA".} 1022 | ## If you want a custom callback to invoke the wildcard callback for the first collision type, you must call this function explicitly. 1023 | ## You must decide how to handle the wildcard's return value since it may disagree with the other wildcard handler's return value or your own. 1024 | 1025 | proc callWildcardBeginB*(arb: Arbiter; space: Space): bool {.cdecl, importc: "cpArbiterCallWildcardBeginB".} 1026 | ## If you want a custom callback to invoke the wildcard callback for the second collision type, you must call this function explicitly. 1027 | ## You must decide how to handle the wildcard's return value since it may disagree with the other wildcard handler's return value or your own. 1028 | 1029 | proc callWildcardPreSolveA*(arb: Arbiter; space: Space): bool {.cdecl, importc: "cpArbiterCallWildcardPreSolveA".} 1030 | ## If you want a custom callback to invoke the wildcard callback for the first collision type, you must call this function explicitly. 1031 | ## You must decide how to handle the wildcard's return value since it may disagree with the other wildcard handler's return value or your own. 1032 | 1033 | proc callWildcardPreSolveB*(arb: Arbiter; space: Space): bool {.cdecl, importc: "cpArbiterCallWildcardPreSolveB".} 1034 | ## If you want a custom callback to invoke the wildcard callback for the second collision type, you must call this function explicitly. 1035 | ## You must decide how to handle the wildcard's return value since it may disagree with the other wildcard handler's return value or your own. 1036 | 1037 | proc callWildcardPostSolveA*(arb: Arbiter; space: Space) {.cdecl, importc: "cpArbiterCallWildcardPostSolveA".} 1038 | ## If you want a custom callback to invoke the wildcard callback for the first collision type, you must call this function explicitly. 1039 | 1040 | proc callWildcardPostSolveB*(arb: Arbiter; space: Space) {.cdecl, importc: "cpArbiterCallWildcardPostSolveB".} 1041 | ## If you want a custom callback to invoke the wildcard callback for the second collision type, you must call this function explicitly. 1042 | 1043 | proc callWildcardSeparateA*(arb: Arbiter; space: Space) {.cdecl, importc: "cpArbiterCallWildcardSeparateA".} 1044 | ## If you want a custom callback to invoke the wildcard callback for the first collision type, you must call this function explicitly. 1045 | 1046 | proc callWildcardSeparateB*(arb: Arbiter; space: Space) {.cdecl, importc: "cpArbiterCallWildcardSeparateB".} 1047 | ## If you want a custom callback to invoke the wildcard callback for the second collision type, you must call this function explicitly. 1048 | 1049 | 1050 | 1051 | 1052 | proc allocateBody*(): Body {.cdecl, importc: "cpBodyAlloc".} 1053 | ## Allocate a cpBody. 1054 | 1055 | proc initializeBody*(body: Body; mass: Float; moment: Float): Body {.cdecl, importc: "cpBodyInit".} 1056 | ## Initialize a cpBody. 1057 | 1058 | proc newBody*(mass: Float; moment: Float): Body {.cdecl, importc: "cpBodyNew".} 1059 | ## Allocate and initialize a cpBody. 1060 | 1061 | proc newKinematicBody*(): Body {.cdecl, importc: "cpBodyNewKinematic".} 1062 | ## Allocate and initialize a cpBody, and set it as a kinematic body. 1063 | 1064 | proc newStaticBody*(): Body {.cdecl, importc: "cpBodyNewStatic".} 1065 | ## Allocate and initialize a cpBody, and set it as a static body. 1066 | 1067 | proc finalize*(body: Body) {.cdecl, importc: "cpBodyDestroy".} 1068 | ## Destroy a cpBody. 1069 | 1070 | proc destroy*(body: Body) {.destroy, cdecl, importc: "cpBodyFree".} 1071 | ## Destroy and free a cpBody. 1072 | 1073 | proc activate*(body: Body) {.cdecl, importc: "cpBodyActivate".} 1074 | ## Wake up a sleeping or idle body. 1075 | 1076 | proc activateStatic*(body: Body; filter: Shape) {.cdecl, importc: "cpBodyActivateStatic".} 1077 | ## Wake up any sleeping or idle bodies touching a static body. 1078 | 1079 | proc sleep*(body: Body) {.cdecl, importc: "cpBodySleep".} 1080 | ## Force a body to fall asleep immediately. 1081 | 1082 | proc sleepWithGroup*(body: Body; group: Body) {.cdecl, importc: "cpBodySleepWithGroup".} 1083 | ## Force a body to fall asleep immediately along with other bodies in a group. 1084 | 1085 | proc isSleeping*(body: Body): bool {.cdecl, importc: "cpBodyIsSleeping".} 1086 | ## Returns true if the body is sleeping. 1087 | 1088 | proc bodyType*(body: Body): BodyType {.cdecl, importc: "cpBodyGetType".} 1089 | ## Get the type of the body. 1090 | 1091 | proc `bodyType=`*(body: Body; `type`: BodyType) {.cdecl, importc: "cpBodySetType".} 1092 | ## Set the type of the body. 1093 | 1094 | proc space*(body: Body): Space {.cdecl, importc: "cpBodyGetSpace".} 1095 | ## Get the space this body is added to. 1096 | 1097 | proc mass*(body: Body): Float {.cdecl, importc: "cpBodyGetMass".} 1098 | ## Get the mass of the body. 1099 | 1100 | proc `mass=`*(body: Body; m: Float) {.cdecl, importc: "cpBodySetMass".} 1101 | ## Set the mass of the body. 1102 | 1103 | proc moment*(body: Body): Float {.cdecl, importc: "cpBodyGetMoment".} 1104 | ## Get the moment of inertia of the body. 1105 | 1106 | proc `moment=`*(body: Body; i: Float) {.cdecl, importc: "cpBodySetMoment".} 1107 | ## Set the moment of inertia of the body. 1108 | 1109 | proc position*(body: Body): Vect {.cdecl, importc: "cpBodyGetPosition".} 1110 | ## Set the position of a body. 1111 | 1112 | proc `position=`*(body: Body; pos: Vect) {.cdecl, importc: "cpBodySetPosition".} 1113 | ## Set the position of the body. 1114 | 1115 | proc centerOfGravity*(body: Body): Vect {.cdecl, importc: "cpBodyGetCenterOfGravity".} 1116 | ## Get the offset of the center of gravity in body local coordinates. 1117 | 1118 | proc `centerOfGravity=`*(body: Body; cog: Vect) {.cdecl, importc: "cpBodySetCenterOfGravity".} 1119 | ## Set the offset of the center of gravity in body local coordinates. 1120 | 1121 | proc velocity*(body: Body): Vect {.cdecl, importc: "cpBodyGetVelocity".} 1122 | ## Get the velocity of the body. 1123 | 1124 | proc `velocity=`*(body: Body; velocity: Vect) {.cdecl, importc: "cpBodySetVelocity".} 1125 | ## Set the velocity of the body. 1126 | 1127 | proc force*(body: Body): Vect {.cdecl, importc: "cpBodyGetForce".} 1128 | ## Get the force applied to the body for the next time step. 1129 | 1130 | proc `force=`*(body: Body; force: Vect) {.cdecl, importc: "cpBodySetForce".} 1131 | ## Set the force applied to the body for the next time step. 1132 | 1133 | proc angle*(body: Body): Float {.cdecl, importc: "cpBodyGetAngle".} 1134 | ## Get the angle of the body. 1135 | 1136 | proc `angle=`*(body: Body; a: Float) {.cdecl, importc: "cpBodySetAngle".} 1137 | ## Set the angle of a body. 1138 | 1139 | proc angularVelocity*(body: Body): Float {.cdecl, importc: "cpBodyGetAngularVelocity".} 1140 | ## Get the angular velocity of the body. 1141 | 1142 | proc `angularVelocity=`*(body: Body; angularVelocity: Float) {.cdecl, importc: "cpBodySetAngularVelocity".} 1143 | ## Set the angular velocity of the body. 1144 | 1145 | proc torque*(body: Body): Float {.cdecl, importc: "cpBodyGetTorque".} 1146 | ## Get the torque applied to the body for the next time step. 1147 | 1148 | proc `torque=`*(body: Body; torque: Float) {.cdecl, importc: "cpBodySetTorque".} 1149 | ## Set the torque applied to the body for the next time step. 1150 | 1151 | proc rotation*(body: Body): Vect {.cdecl, importc: "cpBodyGetRotation".} 1152 | ## Get the rotation vector of the body. (The x basis vector of it's transform.) 1153 | 1154 | proc userData*(body: Body): DataPointer {.cdecl, importc: "cpBodyGetUserData".} 1155 | ## Get the user data pointer assigned to the body. 1156 | 1157 | proc `userData=`*(body: Body; userData: DataPointer) {.cdecl, importc: "cpBodySetUserData".} 1158 | ## Set the user data pointer assigned to the body. 1159 | 1160 | proc `velocityUpdateFunc=`*(body: Body; velocityFunc: BodyVelocityFunc) {.cdecl, importc: "cpBodySetVelocityUpdateFunc".} 1161 | ## Set the callback used to update a body's velocity. 1162 | 1163 | proc `positionUpdateFunc=`*(body: Body; positionFunc: BodyPositionFunc) {.cdecl, importc: "cpBodySetPositionUpdateFunc".} 1164 | ## Set the callback used to update a body's position. 1165 | ## NOTE: It's not generally recommended to override this unless you call the default position update function. 1166 | 1167 | proc updateVelocity*(body: Body; gravity: Vect; damping: Float; dt: Float) {.cdecl, importc: "cpBodyUpdateVelocity".} 1168 | ## Default velocity integration function.. 1169 | 1170 | proc updatePosition*(body: Body; dt: Float) {.cdecl, importc: "cpBodyUpdatePosition".} 1171 | ## Default position integration function. 1172 | 1173 | proc localToWorld*(body: Body; point: Vect): Vect {.cdecl, importc: "cpBodyLocalToWorld".} 1174 | ## Convert body relative/local coordinates to absolute/world coordinates. 1175 | 1176 | proc worldToLocal*(body: Body; point: Vect): Vect {.cdecl, importc: "cpBodyWorldToLocal".} 1177 | ## Convert body absolute/world coordinates to relative/local coordinates. 1178 | 1179 | proc applyForceAtWorldPoint*(body: Body; force: Vect; point: Vect) {.cdecl, importc: "cpBodyApplyForceAtWorldPoint".} 1180 | ## Apply a force to a body. Both the force and point are expressed in world coordinates. 1181 | 1182 | proc applyForceAtLocalPoint*(body: Body; force: Vect; point: Vect) {.cdecl, importc: "cpBodyApplyForceAtLocalPoint".} 1183 | ## Apply a force to a body. Both the force and point are expressed in body local coordinates. 1184 | 1185 | proc applyImpulseAtWorldPoint*(body: Body; impulse: Vect; point: Vect) {.cdecl, importc: "cpBodyApplyImpulseAtWorldPoint".} 1186 | ## Apply an impulse to a body. Both the impulse and point are expressed in world coordinates. 1187 | 1188 | proc applyImpulseAtLocalPoint*(body: Body; impulse: Vect; point: Vect) {.cdecl, importc: "cpBodyApplyImpulseAtLocalPoint".} 1189 | ## Apply an impulse to a body. Both the impulse and point are expressed in body local coordinates. 1190 | 1191 | proc velocityAtWorldPoint*(body: Body; point: Vect): Vect {.cdecl, importc: "cpBodyGetVelocityAtWorldPoint".} 1192 | ## Get the velocity on a body (in world units) at a point on the body in world coordinates. 1193 | 1194 | proc velocityAtLocalPoint*(body: Body; point: Vect): Vect {.cdecl, importc: "cpBodyGetVelocityAtLocalPoint".} 1195 | ## Get the velocity on a body (in world units) at a point on the body in local coordinates. 1196 | 1197 | proc kineticEnergy*(body: Body): Float {.cdecl, importc: "cpBodyKineticEnergy".} 1198 | ## Get the amount of kinetic energy contained by the body. 1199 | 1200 | proc eachShape*(body: Body; `func`: BodyShapeIteratorFunc; data: pointer) {.cdecl, importc: "cpBodyEachShape".} 1201 | ## Call `func` once for each shape attached to `body` and added to the space. 1202 | 1203 | proc eachConstraint*(body: Body; `func`: BodyConstraintIteratorFunc; data: pointer) {.cdecl, importc: "cpBodyEachConstraint".} 1204 | ## Call `func` once for each constraint attached to `body` and added to the space. 1205 | 1206 | proc eachArbiter*(body: Body; `func`: BodyArbiterIteratorFunc; data: pointer) {.cdecl, importc: "cpBodyEachArbiter".} 1207 | ## Call `func` once for each arbiter that is currently active on the body. 1208 | 1209 | var SHAPE_FILTER_ALL* = ShapeFilter(group: (cast[Group](0))) 1210 | ## Collision filter value for a shape that will collide with anything except CP_SHAPE_FILTER_NONE. 1211 | 1212 | var SHAPE_FILTER_NONE* = ShapeFilter(group: (cast[Group](0))) 1213 | ## Collision filter value for a shape that does not collide with anything. 1214 | 1215 | proc newShapeFilter*(group: Group; categories: Bitmask; mask: Bitmask): ShapeFilter {.inline, cdecl.} = 1216 | ## Create a new collision filter. 1217 | var filter = ShapeFilter(group: group) 1218 | return filter 1219 | 1220 | 1221 | proc finalize*(shape: Shape) {.cdecl, importc: "cpShapeDestroy".} 1222 | ## Destroy a shape. 1223 | 1224 | proc destroy*(shape: Shape) {.destroy, cdecl, importc: "cpShapeFree".} 1225 | ## Destroy and Free a shape. 1226 | proc destroy*(shape: PolyShape) {.destroy, cdecl, importc: "cpShapeFree".} 1227 | proc destroy*(shape: SegmentShape) {.destroy, cdecl, importc: "cpShapeFree".} 1228 | proc destroy*(shape: CircleShape) {.destroy, cdecl, importc: "cpShapeFree".} 1229 | 1230 | proc cacheBB*(shape: Shape): BB {.cdecl, importc: "cpShapeCacheBB".} 1231 | ## Update, cache and return the bounding box of a shape based on the body it's attached to. 1232 | 1233 | proc update*(shape: Shape; transform: Transform): BB {.cdecl, importc: "cpShapeUpdate".} 1234 | ## Update, cache and return the bounding box of a shape with an explicit transformation. 1235 | 1236 | proc pointQuery*(shape: Shape; p: Vect; `out`: ptr PointQueryInfo): Float {.cdecl, importc: "cpShapePointQuery".} 1237 | ## Perform a nearest point query. It finds the closest point on the surface of shape to a specific point. 1238 | ## The value returned is the distance between the points. A negative distance means the point is inside the shape. 1239 | 1240 | proc segmentQuery*(shape: Shape; a: Vect; b: Vect; radius: Float; info: ptr SegmentQueryInfo): bool {.cdecl, importc: "cpShapeSegmentQuery".} 1241 | ## Perform a segment query against a shape. `info` must be a pointer to a valid cpSegmentQueryInfo structure. 1242 | 1243 | proc collide*(a: Shape; b: Shape): ContactPointSet {.cdecl, importc: "cpShapesCollide".} 1244 | ## Return contact information about two shapes. 1245 | 1246 | proc space*(shape: Shape): Space {.cdecl, importc: "cpShapeGetSpace".} 1247 | ## The cpSpace this body is added to. 1248 | 1249 | proc body*(shape: Shape): Body {.cdecl, importc: "cpShapeGetBody".} 1250 | ## The cpBody this shape is connected to. 1251 | 1252 | proc `body=`*(shape: Shape; body: Body) {.cdecl, importc: "cpShapeSetBody".} 1253 | ## Set the cpBody this shape is connected to. 1254 | ## Can only be used if the shape is not currently added to a space. 1255 | 1256 | proc mass*(shape: Shape): Float {.cdecl, importc: "cpShapeGetMass".} 1257 | ## Get the mass of the shape if you are having Chipmunk calculate mass properties for you. 1258 | 1259 | proc `mass=`*(shape: Shape; mass: Float) {.cdecl, importc: "cpShapeSetMass".} 1260 | ## Set the mass of this shape to have Chipmunk calculate mass properties for you. 1261 | 1262 | proc density*(shape: Shape): Float {.cdecl, importc: "cpShapeGetDensity".} 1263 | ## Get the density of the shape if you are having Chipmunk calculate mass properties for you. 1264 | 1265 | proc `density=`*(shape: Shape; density: Float) {.cdecl, importc: "cpShapeSetDensity".} 1266 | ## Set the density of this shape to have Chipmunk calculate mass properties for you. 1267 | 1268 | proc moment*(shape: Shape): Float {.cdecl, importc: "cpShapeGetMoment".} 1269 | ## Get the calculated moment of inertia for this shape. 1270 | 1271 | proc area*(shape: Shape): Float {.cdecl, importc: "cpShapeGetArea".} 1272 | ## Get the calculated area of this shape. 1273 | 1274 | proc centerOfGravity*(shape: Shape): Vect {.cdecl, importc: "cpShapeGetCenterOfGravity".} 1275 | ## Get the centroid of this shape. 1276 | 1277 | proc bB*(shape: Shape): BB {.cdecl, importc: "cpShapeGetBB".} 1278 | ## Get the bounding box that contains the shape given it's current position and angle. 1279 | 1280 | proc sensor*(shape: Shape): bool {.cdecl, importc: "cpShapeGetSensor".} 1281 | ## Get if the shape is set to be a sensor or not. 1282 | 1283 | proc `sensor=`*(shape: Shape; sensor: bool) {.cdecl, importc: "cpShapeSetSensor".} 1284 | ## Set if the shape is a sensor or not. 1285 | 1286 | proc elasticity*(shape: Shape): Float {.cdecl, importc: "cpShapeGetElasticity".} 1287 | ## Get the elasticity of this shape. 1288 | 1289 | proc `elasticity=`*(shape: Shape; elasticity: Float) {.cdecl, importc: "cpShapeSetElasticity".} 1290 | ## Set the elasticity of this shape. 1291 | 1292 | proc friction*(shape: Shape): Float {.cdecl, importc: "cpShapeGetFriction".} 1293 | ## Get the friction of this shape. 1294 | 1295 | proc `friction=`*(shape: Shape; friction: Float) {.cdecl, importc: "cpShapeSetFriction".} 1296 | ## Set the friction of this shape. 1297 | 1298 | proc surfaceVelocity*(shape: Shape): Vect {.cdecl, importc: "cpShapeGetSurfaceVelocity".} 1299 | ## Get the surface velocity of this shape. 1300 | 1301 | proc `surfaceVelocity=`*(shape: Shape; surfaceVelocity: Vect) {.cdecl, importc: "cpShapeSetSurfaceVelocity".} 1302 | ## Set the surface velocity of this shape. 1303 | 1304 | proc userData*(shape: Shape): DataPointer {.cdecl, importc: "cpShapeGetUserData".} 1305 | ## Get the user definable data pointer of this shape. 1306 | 1307 | proc `userData=`*(shape: Shape; userData: DataPointer) {.cdecl, importc: "cpShapeSetUserData".} 1308 | ## Set the user definable data pointer of this shape. 1309 | 1310 | proc collisionType*(shape: Shape): CollisionType {.cdecl, importc: "cpShapeGetCollisionType".} 1311 | ## Get the collision type of this shape. 1312 | 1313 | proc `collisionType=`*(shape: Shape; collisionType: CollisionType) {.cdecl, importc: "cpShapeSetCollisionType".} 1314 | ## Set the collision type of this shape. 1315 | 1316 | proc filter*(shape: Shape): ShapeFilter {.cdecl, importc: "cpShapeGetFilter".} 1317 | ## Get the collision filtering parameters of this shape. 1318 | 1319 | proc `filter=`*(shape: Shape; filter: ShapeFilter) {.cdecl, importc: "cpShapeSetFilter".} 1320 | ## Set the collision filtering parameters of this shape. 1321 | 1322 | proc allocateCircleShape*(): CircleShape {.cdecl, importc: "cpCircleShapeAlloc".} 1323 | ## Allocate a circle shape. 1324 | 1325 | proc initializeCircleShape*(circle: CircleShape; body: Body; radius: Float; offset: Vect): CircleShape {.cdecl, importc: "cpCircleShapeInit".} 1326 | ## Initialize a circle shape. 1327 | 1328 | proc newCircleShape*(body: Body; radius: Float; offset: Vect): CircleShape {.cdecl, importc: "cpCircleShapeNew".} 1329 | ## Allocate and initialize a circle shape. 1330 | 1331 | proc offset*(shape: CircleShape): Vect {.cdecl, importc: "cpCircleShapeGetOffset".} 1332 | ## Get the offset of a circle shape. 1333 | 1334 | proc radius*(shape: CircleShape): Float {.cdecl, importc: "cpCircleShapeGetRadius".} 1335 | ## Get the radius of a circle shape. 1336 | 1337 | proc allocateSegmentShape*(): SegmentShape {.cdecl, importc: "cpSegmentShapeAlloc".} 1338 | ## Allocate a segment shape. 1339 | 1340 | proc initializeSegmentShape*(seg: SegmentShape; body: Body; a: Vect; b: Vect; radius: Float): SegmentShape {.cdecl, importc: "cpSegmentShapeInit".} 1341 | ## Initialize a segment shape. 1342 | 1343 | proc newSegmentShape*(body: Body; a: Vect; b: Vect; radius: Float): SegmentShape {.cdecl, importc: "cpSegmentShapeNew".} 1344 | ## Allocate and initialize a segment shape. 1345 | 1346 | proc `neighbors=`*(shape: SegmentShape; prev: Vect; next: Vect) {.cdecl, importc: "cpSegmentShapeSetNeighbors".} 1347 | ## Let Chipmunk know about the geometry of adjacent segments to avoid colliding with endcaps. 1348 | 1349 | proc a*(shape: SegmentShape): Vect {.cdecl, importc: "cpSegmentShapeGetA".} 1350 | ## Get the first endpoint of a segment shape. 1351 | 1352 | proc b*(shape: SegmentShape): Vect {.cdecl, importc: "cpSegmentShapeGetB".} 1353 | ## Get the second endpoint of a segment shape. 1354 | 1355 | proc normal*(shape: SegmentShape): Vect {.cdecl, importc: "cpSegmentShapeGetNormal".} 1356 | ## Get the normal of a segment shape. 1357 | 1358 | proc radius*(shape: SegmentShape): Float {.cdecl, importc: "cpSegmentShapeGetRadius".} 1359 | ## Get the first endpoint of a segment shape. 1360 | 1361 | proc allocatePolyShape*(): PolyShape {.cdecl, importc: "cpPolyShapeAlloc".} 1362 | ## Allocate a polygon shape. 1363 | 1364 | proc initializePolyShape*(poly: PolyShape; body: Body; count: cint; verts: ptr Vect; transform: Transform; radius: Float): PolyShape {.cdecl, importc: "cpPolyShapeInit".} 1365 | ## Initialize a polygon shape with rounded corners. 1366 | ## A convex hull will be created from the vertexes. 1367 | 1368 | proc initializePolyShape*(poly: PolyShape; body: Body; count: cint; verts: ptr Vect; radius: Float): PolyShape {.cdecl, importc: "cpPolyShapeInitRaw".} 1369 | ## Initialize a polygon shape with rounded corners. 1370 | ## The vertexes must be convex with a counter-clockwise winding. 1371 | 1372 | proc newPolyShape*(body: Body; count: cint; verts: ptr Vect; transform: Transform; radius: Float): PolyShape {.cdecl, importc: "cpPolyShapeNew".} 1373 | ## Allocate and initialize a polygon shape with rounded corners. 1374 | ## A convex hull will be created from the vertexes. 1375 | 1376 | proc newPolyShape*(body: Body; count: cint; verts: ptr Vect; radius: Float): PolyShape {.cdecl, importc: "cpPolyShapeNewRaw".} 1377 | ## Allocate and initialize a polygon shape with rounded corners. 1378 | ## The vertexes must be convex with a counter-clockwise winding. 1379 | 1380 | proc initializeBoxShape*(poly: PolyShape; body: Body; width: Float; height: Float; radius: Float): PolyShape {.cdecl, importc: "cpBoxShapeInit".} 1381 | ## Initialize a box shaped polygon shape with rounded corners. 1382 | 1383 | proc initializeBoxShape*(poly: PolyShape; body: Body; box: BB; radius: Float): PolyShape {.cdecl, importc: "cpBoxShapeInit2".} 1384 | ## Initialize an offset box shaped polygon shape with rounded corners. 1385 | 1386 | proc newBoxShape*(body: Body; width: Float; height: Float; radius: Float): PolyShape {.cdecl, importc: "cpBoxShapeNew".} 1387 | ## Allocate and initialize a box shaped polygon shape. 1388 | 1389 | proc newBoxShape*(body: Body; box: BB; radius: Float): PolyShape {.cdecl, importc: "cpBoxShapeNew2".} 1390 | ## Allocate and initialize an offset box shaped polygon shape. 1391 | 1392 | proc count*(shape: PolyShape): cint {.cdecl, importc: "cpPolyShapeGetCount".} 1393 | ## Get the number of verts in a polygon shape. 1394 | 1395 | proc vert*(shape: PolyShape; index: cint): Vect {.cdecl, importc: "cpPolyShapeGetVert".} 1396 | ## Get the `ith` vertex of a polygon shape. 1397 | 1398 | proc radius*(shape: PolyShape): Float {.cdecl, importc: "cpPolyShapeGetRadius".} 1399 | ## Get the radius of a polygon shape. 1400 | 1401 | proc finalize*(constraint: Constraint) {.cdecl, importc: "cpConstraintDestroy".} 1402 | ## Destroy a constraint. 1403 | 1404 | proc destroy*(constraint: Constraint) {.destroy, cdecl, importc: "cpConstraintFree".} 1405 | ## Destroy and free a constraint. 1406 | proc destroy*(constraint: PinJoint) {.destroy, cdecl, importc: "cpConstraintFree".} 1407 | proc destroy*(constraint: DampedSpring) {.destroy, cdecl, importc: "cpConstraintFree".} 1408 | proc destroy*(constraint: RotaryLimitJoint) {.destroy, cdecl, importc: "cpConstraintFree".} 1409 | proc destroy*(constraint: SlideJoint) {.destroy, cdecl, importc: "cpConstraintFree".} 1410 | proc destroy*(constraint: GearJoint) {.destroy, cdecl, importc: "cpConstraintFree".} 1411 | proc destroy*(constraint: DampedRotarySpring) {.destroy, cdecl, importc: "cpConstraintFree".} 1412 | proc destroy*(constraint: GrooveJoint) {.destroy, cdecl, importc: "cpConstraintFree".} 1413 | proc destroy*(constraint: RatchetJoint) {.destroy, cdecl, importc: "cpConstraintFree".} 1414 | proc destroy*(constraint: SimpleMotor) {.destroy, cdecl, importc: "cpConstraintFree".} 1415 | proc destroy*(constraint: PivotJoint) {.destroy, cdecl, importc: "cpConstraintFree".} 1416 | 1417 | proc space*(constraint: Constraint): Space {.cdecl, importc: "cpConstraintGetSpace".} 1418 | ## Get the cpSpace this constraint is added to. 1419 | 1420 | proc bodyA*(constraint: Constraint): Body {.cdecl, importc: "cpConstraintGetBodyA".} 1421 | ## Get the first body the constraint is attached to. 1422 | 1423 | proc bodyB*(constraint: Constraint): Body {.cdecl, importc: "cpConstraintGetBodyB".} 1424 | ## Get the second body the constraint is attached to. 1425 | 1426 | proc maxForce*(constraint: Constraint): Float {.cdecl, importc: "cpConstraintGetMaxForce".} 1427 | ## Get the maximum force that this constraint is allowed to use. 1428 | 1429 | proc `maxForce=`*(constraint: Constraint; maxForce: Float) {.cdecl, importc: "cpConstraintSetMaxForce".} 1430 | ## Set the maximum force that this constraint is allowed to use. (defaults to INFINITY) 1431 | 1432 | proc errorBias*(constraint: Constraint): Float {.cdecl, importc: "cpConstraintGetErrorBias".} 1433 | ## Get rate at which joint error is corrected. 1434 | 1435 | proc `errorBias=`*(constraint: Constraint; errorBias: Float) {.cdecl, importc: "cpConstraintSetErrorBias".} 1436 | ## Set rate at which joint error is corrected. 1437 | ## Defaults to pow(1.0 - 0.1, 60.0) meaning that it will 1438 | ## correct 10% of the error every 1/60th of a second. 1439 | 1440 | proc maxBias*(constraint: Constraint): Float {.cdecl, importc: "cpConstraintGetMaxBias".} 1441 | ## Get the maximum rate at which joint error is corrected. 1442 | 1443 | proc `maxBias=`*(constraint: Constraint; maxBias: Float) {.cdecl, importc: "cpConstraintSetMaxBias".} 1444 | ## Set the maximum rate at which joint error is corrected. (defaults to INFINITY) 1445 | 1446 | proc collideBodies*(constraint: Constraint): bool {.cdecl, importc: "cpConstraintGetCollideBodies".} 1447 | ## Get if the two bodies connected by the constraint are allowed to collide or not. 1448 | 1449 | proc `collideBodies=`*(constraint: Constraint; collideBodies: bool) {.cdecl, importc: "cpConstraintSetCollideBodies".} 1450 | ## Set if the two bodies connected by the constraint are allowed to collide or not. (defaults to cpFalse) 1451 | 1452 | proc preSolveFunc*(constraint: Constraint): ConstraintPreSolveFunc {.cdecl, importc: "cpConstraintGetPreSolveFunc".} 1453 | ## Get the pre-solve function that is called before the solver runs. 1454 | 1455 | proc `preSolveFunc=`*(constraint: Constraint; preSolveFunc: ConstraintPreSolveFunc) {.cdecl, importc: "cpConstraintSetPreSolveFunc".} 1456 | ## Set the pre-solve function that is called before the solver runs. 1457 | 1458 | proc postSolveFunc*(constraint: Constraint): ConstraintPostSolveFunc {.cdecl, importc: "cpConstraintGetPostSolveFunc".} 1459 | ## Get the post-solve function that is called before the solver runs. 1460 | 1461 | proc `postSolveFunc=`*(constraint: Constraint; postSolveFunc: ConstraintPostSolveFunc) {.cdecl, importc: "cpConstraintSetPostSolveFunc".} 1462 | ## Set the post-solve function that is called before the solver runs. 1463 | 1464 | proc userData*(constraint: Constraint): DataPointer {.cdecl, importc: "cpConstraintGetUserData".} 1465 | ## Get the user definable data pointer for this constraint 1466 | 1467 | proc `userData=`*(constraint: Constraint; userData: DataPointer) {.cdecl, importc: "cpConstraintSetUserData".} 1468 | ## Set the user definable data pointer for this constraint 1469 | 1470 | proc impulse*(constraint: Constraint): Float {.cdecl, importc: "cpConstraintGetImpulse".} 1471 | ## Get the last impulse applied by this constraint. 1472 | 1473 | proc isPinJoint*(constraint: Constraint): bool {.cdecl, importc: "cpConstraintIsPinJoint".} 1474 | ## Check if a constraint is a pin joint. 1475 | 1476 | proc allocatePinJoint*(): PinJoint {.cdecl, importc: "cpPinJointAlloc".} 1477 | ## Allocate a pin joint. 1478 | 1479 | proc initializePinJoint*(joint: PinJoint; a: Body; b: Body; anchorA: Vect; anchorB: Vect): PinJoint {.cdecl, importc: "cpPinJointInit".} 1480 | ## Initialize a pin joint. 1481 | 1482 | proc newPinJoint*(a: Body; b: Body; anchorA: Vect; anchorB: Vect): PinJoint {.cdecl, importc: "cpPinJointNew".} 1483 | ## Allocate and initialize a pin joint. 1484 | 1485 | proc anchorA*(constraint: PinJoint): Vect {.cdecl, importc: "cpPinJointGetAnchorA".} 1486 | ## Get the location of the first anchor relative to the first body. 1487 | 1488 | proc `anchorA=`*(constraint: PinJoint; anchorA: Vect) {.cdecl, importc: "cpPinJointSetAnchorA".} 1489 | ## Set the location of the first anchor relative to the first body. 1490 | 1491 | proc anchorB*(constraint: PinJoint): Vect {.cdecl, importc: "cpPinJointGetAnchorB".} 1492 | ## Get the location of the second anchor relative to the second body. 1493 | 1494 | proc `anchorB=`*(constraint: PinJoint; anchorB: Vect) {.cdecl, importc: "cpPinJointSetAnchorB".} 1495 | ## Set the location of the second anchor relative to the second body. 1496 | 1497 | proc dist*(constraint: PinJoint): Float {.cdecl, importc: "cpPinJointGetDist".} 1498 | ## Get the distance the joint will maintain between the two anchors. 1499 | 1500 | proc `dist=`*(constraint: PinJoint; dist: Float) {.cdecl, importc: "cpPinJointSetDist".} 1501 | ## Set the distance the joint will maintain between the two anchors. 1502 | 1503 | proc isSlideJoint*(constraint: Constraint): bool {.cdecl, importc: "cpConstraintIsSlideJoint".} 1504 | ## Check if a constraint is a slide joint. 1505 | 1506 | proc allocateSlideJoint*(): SlideJoint {.cdecl, importc: "cpSlideJointAlloc".} 1507 | ## Allocate a slide joint. 1508 | 1509 | proc initializeSlideJoint*(joint: SlideJoint; a: Body; b: Body; anchorA: Vect; anchorB: Vect; min: Float; max: Float): SlideJoint {.cdecl, importc: "cpSlideJointInit".} 1510 | ## Initialize a slide joint. 1511 | 1512 | proc newSlideJoint*(a: Body; b: Body; anchorA: Vect; anchorB: Vect; min: Float; max: Float): SlideJoint {.cdecl, importc: "cpSlideJointNew".} 1513 | ## Allocate and initialize a slide joint. 1514 | 1515 | proc anchorA*(constraint: SlideJoint): Vect {.cdecl, importc: "cpSlideJointGetAnchorA".} 1516 | ## Get the location of the first anchor relative to the first body. 1517 | 1518 | proc `anchorA=`*(constraint: SlideJoint; anchorA: Vect) {.cdecl, importc: "cpSlideJointSetAnchorA".} 1519 | ## Set the location of the first anchor relative to the first body. 1520 | 1521 | proc anchorB*(constraint: SlideJoint): Vect {.cdecl, importc: "cpSlideJointGetAnchorB".} 1522 | ## Get the location of the second anchor relative to the second body. 1523 | 1524 | proc `anchorB=`*(constraint: SlideJoint; anchorB: Vect) {.cdecl, importc: "cpSlideJointSetAnchorB".} 1525 | ## Set the location of the second anchor relative to the second body. 1526 | 1527 | proc min*(constraint: SlideJoint): Float {.cdecl, importc: "cpSlideJointGetMin".} 1528 | ## Get the minimum distance the joint will maintain between the two anchors. 1529 | 1530 | proc `min=`*(constraint: SlideJoint; min: Float) {.cdecl, importc: "cpSlideJointSetMin".} 1531 | ## Set the minimum distance the joint will maintain between the two anchors. 1532 | 1533 | proc max*(constraint: SlideJoint): Float {.cdecl, importc: "cpSlideJointGetMax".} 1534 | ## Get the maximum distance the joint will maintain between the two anchors. 1535 | 1536 | proc `max=`*(constraint: SlideJoint; max: Float) {.cdecl, importc: "cpSlideJointSetMax".} 1537 | ## Set the maximum distance the joint will maintain between the two anchors. 1538 | 1539 | proc isPivotJoint*(constraint: Constraint): bool {.cdecl, importc: "cpConstraintIsPivotJoint".} 1540 | ## Check if a constraint is a pivot joint. 1541 | 1542 | proc allocatePivotJoint*(): PivotJoint {.cdecl, importc: "cpPivotJointAlloc".} 1543 | ## Allocate a pivot joint 1544 | 1545 | proc initializePivotJoint*(joint: PivotJoint; a: Body; b: Body; anchorA: Vect; anchorB: Vect): PivotJoint {.cdecl, importc: "cpPivotJointInit".} 1546 | ## Initialize a pivot joint. 1547 | 1548 | proc newPivotJoint*(a: Body; b: Body; pivot: Vect): PivotJoint {.cdecl, importc: "cpPivotJointNew".} 1549 | ## Allocate and initialize a pivot joint. 1550 | 1551 | proc newPivotJoint*(a: Body; b: Body; anchorA: Vect; anchorB: Vect): PivotJoint {.cdecl, importc: "cpPivotJointNew2".} 1552 | ## Allocate and initialize a pivot joint with specific anchors. 1553 | 1554 | proc anchorA*(constraint: PivotJoint): Vect {.cdecl, importc: "cpPivotJointGetAnchorA".} 1555 | ## Get the location of the first anchor relative to the first body. 1556 | 1557 | proc `anchorA=`*(constraint: PivotJoint; anchorA: Vect) {.cdecl, importc: "cpPivotJointSetAnchorA".} 1558 | ## Set the location of the first anchor relative to the first body. 1559 | 1560 | proc anchorB*(constraint: PivotJoint): Vect {.cdecl, importc: "cpPivotJointGetAnchorB".} 1561 | ## Get the location of the second anchor relative to the second body. 1562 | 1563 | proc `anchorB=`*(constraint: PivotJoint; anchorB: Vect) {.cdecl, importc: "cpPivotJointSetAnchorB".} 1564 | ## Set the location of the second anchor relative to the second body. 1565 | 1566 | proc isGrooveJoint*(constraint: Constraint): bool {.cdecl, importc: "cpConstraintIsGrooveJoint".} 1567 | ## Check if a constraint is a slide joint. 1568 | 1569 | proc allocateGrooveJoint*(): GrooveJoint {.cdecl, importc: "cpGrooveJointAlloc".} 1570 | ## Allocate a groove joint. 1571 | 1572 | proc initializeGrooveJoint*(joint: GrooveJoint; a: Body; b: Body; groove_a: Vect; groove_b: Vect; anchorB: Vect): GrooveJoint {.cdecl, importc: "cpGrooveJointInit".} 1573 | ## Initialize a groove joint. 1574 | 1575 | proc newGrooveJoint*(a: Body; b: Body; groove_a: Vect; groove_b: Vect; anchorB: Vect): GrooveJoint {.cdecl, importc: "cpGrooveJointNew".} 1576 | ## Allocate and initialize a groove joint. 1577 | 1578 | proc grooveA*(constraint: GrooveJoint): Vect {.cdecl, importc: "cpGrooveJointGetGrooveA".} 1579 | ## Get the first endpoint of the groove relative to the first body. 1580 | 1581 | proc `grooveA=`*(constraint: GrooveJoint; grooveA: Vect) {.cdecl, importc: "cpGrooveJointSetGrooveA".} 1582 | ## Set the first endpoint of the groove relative to the first body. 1583 | 1584 | proc grooveB*(constraint: GrooveJoint): Vect {.cdecl, importc: "cpGrooveJointGetGrooveB".} 1585 | ## Get the first endpoint of the groove relative to the first body. 1586 | 1587 | proc `grooveB=`*(constraint: GrooveJoint; grooveB: Vect) {.cdecl, importc: "cpGrooveJointSetGrooveB".} 1588 | ## Set the first endpoint of the groove relative to the first body. 1589 | 1590 | proc anchorB*(constraint: GrooveJoint): Vect {.cdecl, importc: "cpGrooveJointGetAnchorB".} 1591 | ## Get the location of the second anchor relative to the second body. 1592 | 1593 | proc `anchorB=`*(constraint: GrooveJoint; anchorB: Vect) {.cdecl, importc: "cpGrooveJointSetAnchorB".} 1594 | ## Set the location of the second anchor relative to the second body. 1595 | 1596 | proc isDampedSpring*(constraint: Constraint): bool {.cdecl, importc: "cpConstraintIsDampedSpring".} 1597 | ## Check if a constraint is a slide joint. 1598 | 1599 | proc allocateDampedSpring*(): DampedSpring {.cdecl, importc: "cpDampedSpringAlloc".} 1600 | ## Allocate a damped spring. 1601 | 1602 | proc initializeDampedSpring*(joint: DampedSpring; a: Body; b: Body; anchorA: Vect; anchorB: Vect; restLength: Float; stiffness: Float; damping: Float): DampedSpring {.cdecl, importc: "cpDampedSpringInit".} 1603 | ## Initialize a damped spring. 1604 | 1605 | proc newDampedSpring*(a: Body; b: Body; anchorA: Vect; anchorB: Vect; restLength: Float; stiffness: Float; damping: Float): DampedSpring {.cdecl, importc: "cpDampedSpringNew".} 1606 | ## Allocate and initialize a damped spring. 1607 | 1608 | proc anchorA*(constraint: DampedSpring): Vect {.cdecl, importc: "cpDampedSpringGetAnchorA".} 1609 | ## Get the location of the first anchor relative to the first body. 1610 | 1611 | proc `anchorA=`*(constraint: DampedSpring; anchorA: Vect) {.cdecl, importc: "cpDampedSpringSetAnchorA".} 1612 | ## Set the location of the first anchor relative to the first body. 1613 | 1614 | proc anchorB*(constraint: DampedSpring): Vect {.cdecl, importc: "cpDampedSpringGetAnchorB".} 1615 | ## Get the location of the second anchor relative to the second body. 1616 | 1617 | proc `anchorB=`*(constraint: DampedSpring; anchorB: Vect) {.cdecl, importc: "cpDampedSpringSetAnchorB".} 1618 | ## Set the location of the second anchor relative to the second body. 1619 | 1620 | proc restLength*(constraint: DampedSpring): Float {.cdecl, importc: "cpDampedSpringGetRestLength".} 1621 | ## Get the rest length of the spring. 1622 | 1623 | proc `restLength=`*(constraint: DampedSpring; restLength: Float) {.cdecl, importc: "cpDampedSpringSetRestLength".} 1624 | ## Set the rest length of the spring. 1625 | 1626 | proc stiffness*(constraint: DampedSpring): Float {.cdecl, importc: "cpDampedSpringGetStiffness".} 1627 | ## Get the stiffness of the spring in force/distance. 1628 | 1629 | proc `stiffness=`*(constraint: DampedSpring; stiffness: Float) {.cdecl, importc: "cpDampedSpringSetStiffness".} 1630 | ## Set the stiffness of the spring in force/distance. 1631 | 1632 | proc damping*(constraint: DampedSpring): Float {.cdecl, importc: "cpDampedSpringGetDamping".} 1633 | ## Get the damping of the spring. 1634 | 1635 | proc `damping=`*(constraint: DampedSpring; damping: Float) {.cdecl, importc: "cpDampedSpringSetDamping".} 1636 | ## Set the damping of the spring. 1637 | 1638 | proc springForceFunc*(constraint: DampedSpring): DampedSpringForceFunc {.cdecl, importc: "cpDampedSpringGetSpringForceFunc".} 1639 | ## Get the damping of the spring. 1640 | 1641 | proc `springForceFunc=`*(constraint: DampedSpring; springForceFunc: DampedSpringForceFunc) {.cdecl, importc: "cpDampedSpringSetSpringForceFunc".} 1642 | ## Set the damping of the spring. 1643 | 1644 | proc isDampedRotarySpring*(constraint: Constraint): bool {.cdecl, importc: "cpConstraintIsDampedRotarySpring".} 1645 | ## Check if a constraint is a damped rotary springs. 1646 | 1647 | proc allocateDampedRotarySpring*(): DampedRotarySpring {.cdecl, importc: "cpDampedRotarySpringAlloc".} 1648 | ## Allocate a damped rotary spring. 1649 | 1650 | proc initializeDampedRotarySpring*(joint: DampedRotarySpring; a: Body; b: Body; restAngle: Float; stiffness: Float; damping: Float): DampedRotarySpring {.cdecl, importc: "cpDampedRotarySpringInit".} 1651 | ## Initialize a damped rotary spring. 1652 | 1653 | proc newDampedRotarySpring*(a: Body; b: Body; restAngle: Float; stiffness: Float; damping: Float): DampedRotarySpring {.cdecl, importc: "cpDampedRotarySpringNew".} 1654 | ## Allocate and initialize a damped rotary spring. 1655 | 1656 | proc restAngle*(constraint: DampedRotarySpring): Float {.cdecl, importc: "cpDampedRotarySpringGetRestAngle".} 1657 | ## Get the rest length of the spring. 1658 | 1659 | proc `restAngle=`*(constraint: DampedRotarySpring; restAngle: Float) {.cdecl, importc: "cpDampedRotarySpringSetRestAngle".} 1660 | ## Set the rest length of the spring. 1661 | 1662 | proc stiffness*(constraint: DampedRotarySpring): Float {.cdecl, importc: "cpDampedRotarySpringGetStiffness".} 1663 | ## Get the stiffness of the spring in force/distance. 1664 | 1665 | proc `stiffness=`*(constraint: DampedRotarySpring; stiffness: Float) {.cdecl, importc: "cpDampedRotarySpringSetStiffness".} 1666 | ## Set the stiffness of the spring in force/distance. 1667 | 1668 | proc damping*(constraint: DampedRotarySpring): Float {.cdecl, importc: "cpDampedRotarySpringGetDamping".} 1669 | ## Get the damping of the spring. 1670 | 1671 | proc `damping=`*(constraint: DampedRotarySpring; damping: Float) {.cdecl, importc: "cpDampedRotarySpringSetDamping".} 1672 | ## Set the damping of the spring. 1673 | 1674 | proc springTorqueFunc*(constraint: DampedRotarySpring): DampedRotarySpringTorqueFunc {.cdecl, importc: "cpDampedRotarySpringGetSpringTorqueFunc".} 1675 | ## Get the damping of the spring. 1676 | 1677 | proc `springTorqueFunc=`*(constraint: DampedRotarySpring; springTorqueFunc: DampedRotarySpringTorqueFunc) {.cdecl, importc: "cpDampedRotarySpringSetSpringTorqueFunc".} 1678 | ## Set the damping of the spring. 1679 | 1680 | proc isRotaryLimitJoint*(constraint: Constraint): bool {.cdecl, importc: "cpConstraintIsRotaryLimitJoint".} 1681 | ## Check if a constraint is a damped rotary springs. 1682 | 1683 | proc allocateRotaryLimitJoint*(): RotaryLimitJoint {.cdecl, importc: "cpRotaryLimitJointAlloc".} 1684 | ## Allocate a damped rotary limit joint. 1685 | 1686 | proc initializeRotaryLimitJoint*(joint: RotaryLimitJoint; a: Body; b: Body; min: Float; max: Float): RotaryLimitJoint {.cdecl, importc: "cpRotaryLimitJointInit".} 1687 | ## Initialize a damped rotary limit joint. 1688 | 1689 | proc newRotaryLimitJoint*(a: Body; b: Body; min: Float; max: Float): RotaryLimitJoint {.cdecl, importc: "cpRotaryLimitJointNew".} 1690 | ## Allocate and initialize a damped rotary limit joint. 1691 | 1692 | proc min*(constraint: RotaryLimitJoint): Float {.cdecl, importc: "cpRotaryLimitJointGetMin".} 1693 | ## Get the minimum distance the joint will maintain between the two anchors. 1694 | 1695 | proc `min=`*(constraint: RotaryLimitJoint; min: Float) {.cdecl, importc: "cpRotaryLimitJointSetMin".} 1696 | ## Set the minimum distance the joint will maintain between the two anchors. 1697 | 1698 | proc max*(constraint: RotaryLimitJoint): Float {.cdecl, importc: "cpRotaryLimitJointGetMax".} 1699 | ## Get the maximum distance the joint will maintain between the two anchors. 1700 | 1701 | proc `max=`*(constraint: RotaryLimitJoint; max: Float) {.cdecl, importc: "cpRotaryLimitJointSetMax".} 1702 | ## Set the maximum distance the joint will maintain between the two anchors. 1703 | 1704 | proc isRatchetJoint*(constraint: Constraint): bool {.cdecl, importc: "cpConstraintIsRatchetJoint".} 1705 | ## Check if a constraint is a damped rotary springs. 1706 | 1707 | proc allocateRatchetJoint*(): RatchetJoint {.cdecl, importc: "cpRatchetJointAlloc".} 1708 | ## Allocate a ratchet joint. 1709 | 1710 | proc initializeRatchetJoint*(joint: RatchetJoint; a: Body; b: Body; phase: Float; ratchet: Float): RatchetJoint {.cdecl, importc: "cpRatchetJointInit".} 1711 | ## Initialize a ratched joint. 1712 | 1713 | proc newRatchetJoint*(a: Body; b: Body; phase: Float; ratchet: Float): RatchetJoint {.cdecl, importc: "cpRatchetJointNew".} 1714 | ## Allocate and initialize a ratchet joint. 1715 | 1716 | proc angle*(constraint: RatchetJoint): Float {.cdecl, importc: "cpRatchetJointGetAngle".} 1717 | ## Get the angle of the current ratchet tooth. 1718 | 1719 | proc `angle=`*(constraint: RatchetJoint; angle: Float) {.cdecl, importc: "cpRatchetJointSetAngle".} 1720 | ## Set the angle of the current ratchet tooth. 1721 | 1722 | proc phase*(constraint: RatchetJoint): Float {.cdecl, importc: "cpRatchetJointGetPhase".} 1723 | ## Get the phase offset of the ratchet. 1724 | 1725 | proc `phase=`*(constraint: RatchetJoint; phase: Float) {.cdecl, importc: "cpRatchetJointSetPhase".} 1726 | ## Get the phase offset of the ratchet. 1727 | 1728 | proc ratchet*(constraint: RatchetJoint): Float {.cdecl, importc: "cpRatchetJointGetRatchet".} 1729 | ## Get the angular distance of each ratchet. 1730 | 1731 | proc `ratchet=`*(constraint: RatchetJoint; ratchet: Float) {.cdecl, importc: "cpRatchetJointSetRatchet".} 1732 | ## Set the angular distance of each ratchet. 1733 | 1734 | proc isGearJoint*(constraint: Constraint): bool {.cdecl, importc: "cpConstraintIsGearJoint".} 1735 | ## Check if a constraint is a damped rotary springs. 1736 | 1737 | proc allocateGearJoint*(): GearJoint {.cdecl, importc: "cpGearJointAlloc".} 1738 | ## Allocate a gear joint. 1739 | 1740 | proc initializeGearJoint*(joint: GearJoint; a: Body; b: Body; phase: Float; ratio: Float): GearJoint {.cdecl, importc: "cpGearJointInit".} 1741 | ## Initialize a gear joint. 1742 | 1743 | proc newGearJoint*(a: Body; b: Body; phase: Float; ratio: Float): GearJoint {.cdecl, importc: "cpGearJointNew".} 1744 | ## Allocate and initialize a gear joint. 1745 | 1746 | proc phase*(constraint: GearJoint): Float {.cdecl, importc: "cpGearJointGetPhase".} 1747 | ## Get the phase offset of the gears. 1748 | 1749 | proc `phase=`*(constraint: GearJoint; phase: Float) {.cdecl, importc: "cpGearJointSetPhase".} 1750 | ## Set the phase offset of the gears. 1751 | 1752 | proc ratio*(constraint: GearJoint): Float {.cdecl, importc: "cpGearJointGetRatio".} 1753 | ## Get the angular distance of each ratchet. 1754 | 1755 | proc `ratio=`*(constraint: GearJoint; ratio: Float) {.cdecl, importc: "cpGearJointSetRatio".} 1756 | ## Set the ratio of a gear joint. 1757 | 1758 | proc isSimpleMotor*(constraint: Constraint): bool {.cdecl, importc: "cpConstraintIsSimpleMotor".} 1759 | ## Check if a constraint is a damped rotary springs. 1760 | 1761 | proc allocateSimpleMotor*(): SimpleMotor {.cdecl, importc: "cpSimpleMotorAlloc".} 1762 | ## Allocate a simple motor. 1763 | 1764 | proc initializeSimpleMotor*(joint: SimpleMotor; a: Body; b: Body; rate: Float): SimpleMotor {.cdecl, importc: "cpSimpleMotorInit".} 1765 | ## initialize a simple motor. 1766 | 1767 | proc newSimpleMotor*(a: Body; b: Body; rate: Float): SimpleMotor {.cdecl, importc: "cpSimpleMotorNew".} 1768 | ## Allocate and initialize a simple motor. 1769 | 1770 | proc rate*(constraint: SimpleMotor): Float {.cdecl, importc: "cpSimpleMotorGetRate".} 1771 | ## Get the rate of the motor. 1772 | 1773 | proc `rate=`*(constraint: SimpleMotor; rate: Float) {.cdecl, importc: "cpSimpleMotorSetRate".} 1774 | ## Set the rate of the motor. 1775 | 1776 | proc allocateSpace*(): Space {.cdecl, importc: "cpSpaceAlloc".} 1777 | ## Allocate a cpSpace. 1778 | 1779 | proc initializeSpace*(space: Space): Space {.cdecl, importc: "cpSpaceInit".} 1780 | ## Initialize a cpSpace. 1781 | 1782 | proc newSpace*(): Space {.cdecl, importc: "cpSpaceNew".} 1783 | ## Allocate and initialize a cpSpace. 1784 | 1785 | proc finalize*(space: Space) {.cdecl, importc: "cpSpaceDestroy".} 1786 | ## Destroy a cpSpace. 1787 | 1788 | proc destroy*(space: Space) {.destroy, cdecl, importc: "cpSpaceFree".} 1789 | ## Destroy and free a cpSpace. 1790 | 1791 | proc iterations*(space: Space): cint {.cdecl, importc: "cpSpaceGetIterations".} 1792 | proc `iterations=`*(space: Space; iterations: cint) {.cdecl, importc: "cpSpaceSetIterations".} 1793 | ## Number of iterations to use in the impulse solver to solve contacts and other constraints. 1794 | 1795 | proc gravity*(space: Space): Vect {.cdecl, importc: "cpSpaceGetGravity".} 1796 | proc `gravity=`*(space: Space; gravity: Vect) {.cdecl, importc: "cpSpaceSetGravity".} 1797 | ## Gravity to pass to rigid bodies when integrating velocity. 1798 | 1799 | proc damping*(space: Space): Float {.cdecl, importc: "cpSpaceGetDamping".} 1800 | proc `damping=`*(space: Space; damping: Float) {.cdecl, importc: "cpSpaceSetDamping".} 1801 | ## Damping rate expressed as the fraction of velocity bodies retain each second. 1802 | ## A value of 0.9 would mean that each body's velocity will drop 10% per second. 1803 | ## The default value is 1.0, meaning no damping is applied. 1804 | ## @note This damping value is different than those of cpDampedSpring and cpDampedRotarySpring. 1805 | 1806 | proc idleSpeedThreshold*(space: Space): Float {.cdecl, importc: "cpSpaceGetIdleSpeedThreshold".} 1807 | proc `idleSpeedThreshold=`*(space: Space; idleSpeedThreshold: Float) {.cdecl, importc: "cpSpaceSetIdleSpeedThreshold".} 1808 | ## Speed threshold for a body to be considered idle. 1809 | ## The default value of 0 means to let the space guess a good threshold based on gravity. 1810 | 1811 | proc sleepTimeThreshold*(space: Space): Float {.cdecl, importc: "cpSpaceGetSleepTimeThreshold".} 1812 | proc `sleepTimeThreshold=`*(space: Space; sleepTimeThreshold: Float) {.cdecl, importc: "cpSpaceSetSleepTimeThreshold".} 1813 | ## Time a group of bodies must remain idle in order to fall asleep. 1814 | ## Enabling sleeping also implicitly enables the the contact graph. 1815 | ## The default value of INFINITY disables the sleeping algorithm. 1816 | 1817 | proc collisionSlop*(space: Space): Float {.cdecl, importc: "cpSpaceGetCollisionSlop".} 1818 | proc `collisionSlop=`*(space: Space; collisionSlop: Float) {.cdecl, importc: "cpSpaceSetCollisionSlop".} 1819 | ## Amount of encouraged penetration between colliding shapes. 1820 | ## Used to reduce oscillating contacts and keep the collision cache warm. 1821 | ## Defaults to 0.1. If you have poor simulation quality, 1822 | ## increase this number as much as possible without allowing visible amounts of overlap. 1823 | 1824 | proc collisionBias*(space: Space): Float {.cdecl, importc: "cpSpaceGetCollisionBias".} 1825 | proc `collisionBias=`*(space: Space; collisionBias: Float) {.cdecl, importc: "cpSpaceSetCollisionBias".} 1826 | ## Determines how fast overlapping shapes are pushed apart. 1827 | ## Expressed as a fraction of the error remaining after each second. 1828 | ## Defaults to pow(1.0 - 0.1, 60.0) meaning that Chipmunk fixes 10% of overlap each frame at 60Hz. 1829 | 1830 | proc collisionPersistence*(space: Space): Timestamp {.cdecl, importc: "cpSpaceGetCollisionPersistence".} 1831 | proc `collisionPersistence=`*(space: Space; collisionPersistence: Timestamp) {.cdecl, importc: "cpSpaceSetCollisionPersistence".} 1832 | ## Number of frames that contact information should persist. 1833 | ## Defaults to 3. There is probably never a reason to change this value. 1834 | 1835 | proc userData*(space: Space): DataPointer {.cdecl, importc: "cpSpaceGetUserData".} 1836 | proc `userData=`*(space: Space; userData: DataPointer) {.cdecl, importc: "cpSpaceSetUserData".} 1837 | ## User definable data pointer. 1838 | ## Generally this points to your game's controller or game state 1839 | ## class so you can access it when given a cpSpace reference in a callback. 1840 | 1841 | proc staticBody*(space: Space): Body {.cdecl, importc: "cpSpaceGetStaticBody".} 1842 | ## The Space provided static body for a given cpSpace. 1843 | ## This is merely provided for convenience and you are not required to use it. 1844 | 1845 | proc currentTimeStep*(space: Space): Float {.cdecl, importc: "cpSpaceGetCurrentTimeStep".} 1846 | ## Returns the current (or most recent) time step used with the given space. 1847 | ## Useful from callbacks if your time step is not a compile-time global. 1848 | 1849 | proc isLocked*(space: Space): bool {.cdecl, importc: "cpSpaceIsLocked".} 1850 | ## returns true from inside a callback when objects cannot be added/removed. 1851 | 1852 | proc addDefaultCollisionHandler*(space: Space): ptr CollisionHandler {.cdecl, importc: "cpSpaceAddDefaultCollisionHandler".} 1853 | ## Create or return the existing collision handler that is called for all collisions that are not handled by a more specific collision handler. 1854 | 1855 | proc addCollisionHandler*(space: Space; a: CollisionType; b: CollisionType): ptr CollisionHandler {.cdecl, importc: "cpSpaceAddCollisionHandler".} 1856 | ## Create or return the existing collision handler for the specified pair of collision types. 1857 | ## If wildcard handlers are used with either of the collision types, it's the responibility of the custom handler to invoke the wildcard handlers. 1858 | 1859 | proc addWildcardHandler*(space: Space; `type`: CollisionType): ptr CollisionHandler {.cdecl, importc: "cpSpaceAddWildcardHandler".} 1860 | ## Create or return the existing wildcard collision handler for the specified type. 1861 | 1862 | proc addShape*(space: Space; shape: Shape): Shape {.cdecl, importc: "cpSpaceAddShape".} 1863 | ## Add a collision shape to the simulation. 1864 | ## If the shape is attached to a static body, it will be added as a static shape. 1865 | 1866 | proc addBody*(space: Space; body: Body): Body {.cdecl, importc: "cpSpaceAddBody".} 1867 | ## Add a rigid body to the simulation. 1868 | 1869 | proc addConstraint*(space: Space; constraint: Constraint): Constraint {.cdecl, importc: "cpSpaceAddConstraint".} 1870 | ## Add a constraint to the simulation. 1871 | 1872 | proc removeShape*(space: Space; shape: Shape) {.cdecl, importc: "cpSpaceRemoveShape".} 1873 | ## Remove a collision shape from the simulation. 1874 | 1875 | proc removeBody*(space: Space; body: Body) {.cdecl, importc: "cpSpaceRemoveBody".} 1876 | ## Remove a rigid body from the simulation. 1877 | 1878 | proc removeConstraint*(space: Space; constraint: Constraint) {.cdecl, importc: "cpSpaceRemoveConstraint".} 1879 | ## Remove a constraint from the simulation. 1880 | 1881 | proc containsShape*(space: Space; shape: Shape): bool {.cdecl, importc: "cpSpaceContainsShape".} 1882 | ## Test if a collision shape has been added to the space. 1883 | 1884 | proc containsBody*(space: Space; body: Body): bool {.cdecl, importc: "cpSpaceContainsBody".} 1885 | ## Test if a rigid body has been added to the space. 1886 | 1887 | proc containsConstraint*(space: Space; constraint: Constraint): bool {.cdecl, importc: "cpSpaceContainsConstraint".} 1888 | ## Test if a constraint has been added to the space. 1889 | 1890 | proc addPostStepCallback*(space: Space; `func`: PostStepFunc; key: pointer; data: pointer): bool {.cdecl, importc: "cpSpaceAddPostStepCallback".} 1891 | ## Schedule a post-step callback to be called when cpSpaceStep() finishes. 1892 | ## You can only register one callback per unique value for `key`. 1893 | ## Returns true only if `key` has never been scheduled before. 1894 | ## It's possible to pass `NULL` for `func` if you only want to mark `key` as being used. 1895 | 1896 | proc pointQuery*(space: Space; point: Vect; maxDistance: Float; filter: ShapeFilter; `func`: SpacePointQueryFunc; data: pointer) {.cdecl, importc: "cpSpacePointQuery".} 1897 | ## Query the space at a point and call `func` for each shape found. 1898 | 1899 | proc pointQueryNearest*(space: Space; point: Vect; maxDistance: Float; filter: ShapeFilter; `out`: ptr PointQueryInfo): Shape {.cdecl, importc: "cpSpacePointQueryNearest".} 1900 | ## Query the space at a point and return the nearest shape found. Returns NULL if no shapes were found. 1901 | 1902 | proc segmentQuery*(space: Space; start: Vect; `end`: Vect; radius: Float; filter: ShapeFilter; `func`: SpaceSegmentQueryFunc; data: pointer) {.cdecl, importc: "cpSpaceSegmentQuery".} 1903 | ## Perform a directed line segment query (like a raycast) against the space calling `func` for each shape intersected. 1904 | 1905 | proc segmentQueryFirst*(space: Space; start: Vect; `end`: Vect; radius: Float; filter: ShapeFilter; `out`: ptr SegmentQueryInfo): Shape {.cdecl, importc: "cpSpaceSegmentQueryFirst".} 1906 | ## 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. 1907 | 1908 | proc bBQuery*(space: Space; bb: BB; filter: ShapeFilter; `func`: SpaceBBQueryFunc; data: pointer) {.cdecl, importc: "cpSpaceBBQuery".} 1909 | ## Perform a fast rectangle query on the space calling `func` for each shape found. 1910 | ## Only the shape's bounding boxes are checked for overlap, not their full shape. 1911 | 1912 | proc shapeQuery*(space: Space; shape: Shape; `func`: SpaceShapeQueryFunc; data: pointer): bool {.cdecl, importc: "cpSpaceShapeQuery".} 1913 | ## Query a space for any shapes overlapping the given shape and call `func` for each shape found. 1914 | 1915 | proc eachBody*(space: Space; `func`: SpaceBodyIteratorFunc; data: pointer) {.cdecl, importc: "cpSpaceEachBody".} 1916 | ## Call `func` for each body in the space. 1917 | 1918 | proc eachShape*(space: Space; `func`: SpaceShapeIteratorFunc; data: pointer) {.cdecl, importc: "cpSpaceEachShape".} 1919 | ## Call `func` for each shape in the space. 1920 | 1921 | proc eachConstraint*(space: Space; `func`: SpaceConstraintIteratorFunc; data: pointer) {.cdecl, importc: "cpSpaceEachConstraint".} 1922 | ## Call `func` for each shape in the space. 1923 | 1924 | proc reindexStatic*(space: Space) {.cdecl, importc: "cpSpaceReindexStatic".} 1925 | ## Update the collision detection info for the static shapes in the space. 1926 | 1927 | proc reindexShape*(space: Space; shape: Shape) {.cdecl, importc: "cpSpaceReindexShape".} 1928 | ## Update the collision detection data for a specific shape in the space. 1929 | 1930 | proc reindexShapesForBody*(space: Space; body: Body) {.cdecl, importc: "cpSpaceReindexShapesForBody".} 1931 | ## Update the collision detection data for all shapes attached to a body. 1932 | 1933 | proc useSpatialHash*(space: Space; dim: Float; count: cint) {.cdecl, importc: "cpSpaceUseSpatialHash".} 1934 | ## Switch the space to use a spatial has as it's spatial index. 1935 | 1936 | proc step*(space: Space; dt: Float) {.cdecl, importc: "cpSpaceStep".} 1937 | ## Step the space forward in time by `dt`. 1938 | 1939 | proc debugDraw*(space: Space; options: ptr SpaceDebugDrawOptions) {.cdecl, importc: "cpSpaceDebugDraw".} 1940 | ## Debug draw the current state of the space using the supplied drawing options. 1941 | 1942 | var VersionString* {.importc: "cpVersionString".}: cstring 1943 | ## Version string. 1944 | 1945 | proc momentForCircle*(m: Float; r1: Float; r2: Float; offset: Vect): Float {.cdecl, importc: "cpMomentForCircle".} 1946 | ## Calculate the moment of inertia for a circle. 1947 | ## `r1` and `r2` are the inner and outer diameters. A solid circle has an inner diameter of 0. 1948 | 1949 | proc areaForCircle*(r1: Float; r2: Float): Float {.cdecl, importc: "cpAreaForCircle".} 1950 | ## Calculate area of a hollow circle. 1951 | ## `r1` and `r2` are the inner and outer diameters. A solid circle has an inner diameter of 0. 1952 | 1953 | proc momentForSegment*(m: Float; a: Vect; b: Vect; radius: Float): Float {.cdecl, importc: "cpMomentForSegment".} 1954 | ## Calculate the moment of inertia for a line segment. 1955 | ## Beveling radius is not supported. 1956 | 1957 | proc areaForSegment*(a: Vect; b: Vect; radius: Float): Float {.cdecl, importc: "cpAreaForSegment".} 1958 | ## Calculate the area of a fattened (capsule shaped) line segment. 1959 | 1960 | proc momentForPoly*(m: Float; count: cint; verts: ptr Vect; offset: Vect; radius: Float): Float {.cdecl, importc: "cpMomentForPoly".} 1961 | ## 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. 1962 | 1963 | proc areaForPoly*(count: cint; verts: ptr Vect; radius: Float): Float {.cdecl, importc: "cpAreaForPoly".} 1964 | ## Calculate the signed area of a polygon. A Clockwise winding gives positive area. 1965 | ## This is probably backwards from what you expect, but matches Chipmunk's the winding for poly shapes. 1966 | 1967 | proc centroidForPoly*(count: cint; verts: ptr Vect): Vect {.cdecl, importc: "cpCentroidForPoly".} 1968 | ## Calculate the natural centroid of a polygon. 1969 | 1970 | proc momentForBox*(m: Float; width: Float; height: Float): Float {.cdecl, importc: "cpMomentForBox".} 1971 | ## Calculate the moment of inertia for a solid box. 1972 | 1973 | proc momentForBox*(m: Float; box: BB): Float {.cdecl, importc: "cpMomentForBox2".} 1974 | ## Calculate the moment of inertia for a solid box. 1975 | 1976 | proc convexHull*(count: cint; verts: ptr Vect; result: ptr Vect; first: ptr cint; tol: Float): cint {.cdecl, importc: "cpConvexHull".} 1977 | ## Calculate the convex hull of a given set of points. Returns the count of points in the hull. 1978 | ## `result` must be a pointer to a `cpVect` array with at least `count` elements. If `verts` == `result`, then `verts` will be reduced inplace. 1979 | ## `first` is an optional pointer to an integer to store where the first vertex in the hull came from (i.e. verts[first] == result[0]) 1980 | ## `tol` is the allowed amount to shrink the hull when simplifying it. A tolerance of 0.0 creates an exact hull. 1981 | 1982 | proc closestPointOnSegment*(p: Vect; a: Vect; b: Vect): Vect {.inline, cdecl.} = 1983 | ## Returns the closest point on the line segment ab, to the point p. 1984 | var delta: Vect = vsub(a, b) 1985 | var t: Float = fclamp01(vdot(delta, vsub(p, b)) div 1986 | vlengthsq(delta)) 1987 | return vadd(b, vmult(delta, t)) 1988 | 1989 | 1990 | 1991 | {.pop.} 1992 | 1993 | 1994 | proc `*`*(v: Vect; s: Float): Vect = vmult(v, s) 1995 | proc `+`*(v1, v2: Vect): Vect = vadd(v1, v2) 1996 | proc `-`*(v1, v2: Vect): Vect = vsub(v1, v2) 1997 | proc `==`*(v1, v2: Vect): bool = veql(v1, v2) 1998 | proc `-`*(v: Vect): Vect = vneg(v) 1999 | 2000 | 2001 | proc `|`*(a, b: SpaceDebugDrawFlags): SpaceDebugDrawFlags = 2002 | ## Combines multiple flags as a bitmask 2003 | cast[SpaceDebugDrawFlags](cint(a) or cint(b)) 2004 | --------------------------------------------------------------------------------