├── CHANGES.txt ├── haxelib.json ├── phx.hxml └── phx ├── Allocator.hx ├── Arbiter.hx ├── Axis.hx ├── Body.hx ├── Circle.hx ├── Collision.hx ├── Const.hx ├── Contact.hx ├── FlashDraw.hx ├── Island.hx ├── JsCanvas.hx ├── Material.hx ├── Polygon.hx ├── Properties.hx ├── Segment.hx ├── Shape.hx ├── Timer.hx ├── Vector.hx ├── World.hx ├── col ├── AABB.hx ├── BroadPhase.hx ├── BruteForce.hx ├── IAABB.hx ├── Quantize.hx └── SortedList.hx ├── demo ├── BasicStack.hx ├── BoxPyramidDemo.hx ├── Demo.hx ├── DominoPyramid.hx ├── FontArray.hx ├── Jumble.hx ├── Main.hx ├── Makefile ├── PentagonRain.hx ├── PyramidThree.hx ├── SegmentDemo.hx ├── Test.hx ├── TitleDemo.hx ├── application.nmml └── physaxeDemo.hxproj └── joint └── Joint.hx /CHANGES.txt: -------------------------------------------------------------------------------- 1 | 2013-09-18 : 1.2.1 2 | haxe 3 changes 3 | 4 | 2009-01-02 : 1.2 5 | fixed issue when removed body had living arbiters 6 | fixed body inertia calculus (issues with density) 7 | allow dynamic slop - maxDist in properties - and set default to 0.5 pixels 8 | 9 | 2008-08-13 : 1.1 10 | allowed static bodies, call world.sync() if position changed 11 | minor friction/restitution changes 12 | added JS support 13 | added phx.col.Quantize for large worlds 14 | FlashDraw only draw shapes in specified bounds 15 | adjusted island energy calculus 16 | sleepEpsilon is now a variable of world 17 | fixed broadphase.pick : pick the shapes contained in the box 18 | 19 | 2008-04-06 : 1.0 20 | base engine 21 | -------------------------------------------------------------------------------- /haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "physaxe", 3 | "url": "http://github.com/ncannasse/physaxe", 4 | "license": "BSD", 5 | "description": "A 2D Rigid Body Physics Library optimized for Flash9", 6 | "version": "1.2.1", 7 | "releasenote": "See CHANGES.txt", 8 | "contributors": ["ncannasse"] 9 | } -------------------------------------------------------------------------------- /phx.hxml: -------------------------------------------------------------------------------- 1 | -cp . 2 | -main phx.demo.Main 3 | --each 4 | 5 | --next 6 | -swf phx.swf 7 | -swf-header 800:600:60:FFFFFF 8 | --flash-strict 9 | -swf-version 9 10 | 11 | --next 12 | -js phx.js 13 | -------------------------------------------------------------------------------- /phx/Allocator.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | 27 | class Allocator { 28 | 29 | var contactPool : Contact; 30 | var islandPool : Island; 31 | 32 | public function new() { 33 | } 34 | 35 | public inline function allocIsland(w) { 36 | var i = islandPool; 37 | if( i == null ) 38 | return new Island(w); 39 | else { 40 | islandPool = i.allocNext; 41 | return i; 42 | } 43 | } 44 | 45 | public inline function freeIsland( i : Island ) { 46 | i.bodies.head = null; 47 | i.arbiters.head = null; 48 | i.joints.head = null; 49 | i.sleeping = false; 50 | i.allocNext = islandPool; 51 | islandPool = i; 52 | } 53 | 54 | public inline function allocArbiter() { 55 | return new Arbiter(this); 56 | } 57 | 58 | public inline function freeArbiter( a : Arbiter ) { 59 | } 60 | 61 | public inline function allocContact() { 62 | var c = contactPool; 63 | if( c == null ) 64 | return new Contact(); 65 | else { 66 | contactPool = c.next; 67 | return c; 68 | } 69 | } 70 | 71 | public inline function freeContact( c : Contact ) { 72 | c.next = contactPool; 73 | contactPool = c; 74 | } 75 | 76 | public inline function freeAllContacts( c : Contact ) { 77 | while( c != null ) { 78 | var next = c.next; 79 | c.next = contactPool; 80 | contactPool = c; 81 | c = next; 82 | } 83 | } 84 | 85 | } -------------------------------------------------------------------------------- /phx/Arbiter.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | 27 | class Arbiter { 28 | 29 | public var contacts : Contact; 30 | 31 | var friction : Float; 32 | var restitution : Float; 33 | var bias : Float; 34 | var maxDist : Float; 35 | public var s1 : Shape; 36 | public var s2 : Shape; 37 | 38 | public var stamp : Int; 39 | public var island : Island; 40 | public var allocator : Allocator; 41 | public var sleeping : Bool; 42 | 43 | public function new(alloc) { 44 | allocator = alloc; 45 | } 46 | 47 | public function assign( s1, s2 ) { 48 | this.s1 = s1; 49 | this.s2 = s2; 50 | var m1 = s1.material; 51 | var m2 = s2.material; 52 | var p1 = s1.body.properties; 53 | var p2 = s2.body.properties; 54 | restitution = if( m1.restitution > m2.restitution ) m1.restitution else m2.restitution; 55 | friction = Math.sqrt(m1.friction * m2.friction); 56 | bias = (p1.biasCoef > p2.biasCoef) ? p1.biasCoef : p2.biasCoef; 57 | maxDist = (p1.maxDist > p2.maxDist) ? p2.maxDist : p1.maxDist; 58 | } 59 | 60 | public function injectContact( p : Vector, n : Vector, nCoef : Float, dist : Float, hash : Int ) { 61 | var c = contacts; 62 | while( c != null ) { 63 | if( hash == c.hash ) 64 | break; 65 | c = c.next; 66 | } 67 | if( c == null ) { 68 | c = allocator.allocContact(); 69 | c.hash = hash; 70 | c.jnAcc = c.jtAcc = 0; 71 | c.next = contacts; 72 | contacts = c; 73 | } 74 | // init datas 75 | c.px = p.x; 76 | c.py = p.y; 77 | c.nx = n.x * nCoef; 78 | c.ny = n.y * nCoef; 79 | c.dist = dist; 80 | c.updated = true; 81 | } 82 | 83 | inline function bodyImpulse( c : Contact, b1 : Body, b2 : Body, cjTx : Float, cjTy : Float ) { 84 | b1.v.x -= cjTx * b1.invMass; 85 | b1.v.y -= cjTy * b1.invMass; 86 | b1.w -= b1.invInertia * (c.r1x * cjTy - c.r1y * cjTx); 87 | b2.v.x += cjTx * b2.invMass; 88 | b2.v.y += cjTy * b2.invMass; 89 | b2.w += b2.invInertia * (c.r2x * cjTy - c.r2y * cjTx); 90 | } 91 | 92 | public function preStep( dt : Float ) { 93 | var b1 = s1.body; 94 | var b2 = s2.body; 95 | var mass_sum = b1.invMass + b2.invMass; 96 | 97 | var c = contacts; 98 | var prev = null; 99 | 100 | while( c != null ) { 101 | if( !c.updated ) { 102 | var old = c; 103 | c = c.next; 104 | allocator.freeContact(old); 105 | if( prev == null ) 106 | contacts = c; 107 | else 108 | prev.next = c; 109 | continue; 110 | } 111 | c.updated = false; 112 | 113 | // local anchors and their normals 114 | c.r1x = c.px - b1.x; 115 | c.r1y = c.py - b1.y; 116 | c.r2x = c.px - b2.x; 117 | c.r2y = c.py - b2.y; 118 | 119 | c.r1nx = -c.r1y; 120 | c.r1ny = c.r1x; 121 | c.r2nx = -c.r2y; 122 | c.r2ny = c.r2x; 123 | 124 | // we will calculate the factor which is the inverse of 125 | // 1/M1 + 1/M2 + (R1 x N) ^ 2 / I1 + (R2 x N) ^ 2 / I2 126 | // in the past (R1.R1 - (R1.N)^2) was used in Box2D but 127 | // this is no longer the case 128 | 129 | // normal mass 130 | var r1cn = c.r1x * c.ny - c.r1y * c.nx; 131 | var r2cn = c.r2x * c.ny - c.r2y * c.nx; 132 | var kn = mass_sum + (b1.invInertia * r1cn * r1cn) + (b2.invInertia * r2cn * r2cn); 133 | c.nMass = 1.0 / kn; 134 | 135 | // tangent mass 136 | var tx = -c.ny; 137 | var ty = c.nx; 138 | var r1ct = c.r1x * ty - c.r1y * tx; 139 | var r2ct = c.r2x * ty - c.r2y * tx; 140 | var kt = mass_sum + b1.invInertia * r1ct * r1ct + b2.invInertia * r2ct * r2ct; 141 | c.tMass = 1.0 / kt; 142 | 143 | // bias 144 | c.bias = -bias * (c.dist + maxDist); 145 | c.jBias = 0; 146 | 147 | // vrel = N . ((V2 + W2 x N2) - (V1 + W1 x N1)) 148 | var vrx = (c.r2nx * b2.w + b2.v.x) - (c.r1nx * b1.w + b1.v.x); 149 | var vry = (c.r2ny * b2.w + b2.v.y) - (c.r1ny * b1.w + b1.v.y); 150 | c.bounce = (c.nx * vrx + c.ny * vry) * restitution * dt; 151 | 152 | // apply impulse 153 | var cjTx = (c.nx * c.jnAcc) + (tx * c.jtAcc); 154 | var cjTy = (c.ny * c.jnAcc) + (ty * c.jtAcc); 155 | bodyImpulse(c,b1,b2,cjTx,cjTy); 156 | 157 | prev = c; 158 | c = c.next; 159 | } 160 | } 161 | 162 | public function applyImpulse() { 163 | var b1 = s1.body; 164 | var b2 = s2.body; 165 | var c = contacts; 166 | while( c != null ) { 167 | // calculate the relative bias velocities 168 | var vbn = 169 | ((c.r2nx * b2.w_bias + b2.v_bias.x) - (c.r1nx * b1.w_bias + b1.v_bias.x)) * c.nx + 170 | ((c.r2ny * b2.w_bias + b2.v_bias.y) - (c.r1ny * b1.w_bias + b1.v_bias.y)) * c.ny; 171 | 172 | // calculate and clamp the bias impulse 173 | var jbn = (c.bias - vbn) * c.nMass; 174 | var jbnOld = c.jBias; 175 | c.jBias = jbnOld + jbn; 176 | if( c.jBias < 0 ) c.jBias = 0; 177 | jbn = c.jBias - jbnOld; 178 | 179 | // apply the bias impulse 180 | var cjTx = c.nx * jbn; 181 | var cjTy = c.ny * jbn; 182 | 183 | b1.v_bias.x -= cjTx * b1.invMass; 184 | b1.v_bias.y -= cjTy * b1.invMass; 185 | b1.w_bias -= b1.invInertia * (c.r1x * cjTy - c.r1y * cjTx); 186 | 187 | b2.v_bias.x += cjTx * b2.invMass; 188 | b2.v_bias.y += cjTy * b2.invMass; 189 | b2.w_bias += b2.invInertia * (c.r2x * cjTy - c.r2y * cjTx); 190 | 191 | // calculate the relative velocity 192 | var vrx = (c.r2nx * b2.w + b2.v.x) - (c.r1nx * b1.w + b1.v.x); 193 | var vry = (c.r2ny * b2.w + b2.v.y) - (c.r1ny * b1.w + b1.v.y); 194 | 195 | // calculate and clamp the normal impulse 196 | var jn = (c.bounce + (vrx * c.nx + vry * c.ny)) * c.nMass; 197 | var jnOld = c.jnAcc; 198 | c.jnAcc = jnOld - jn; 199 | if( c.jnAcc < 0 ) c.jnAcc = 0; 200 | jn = c.jnAcc - jnOld; 201 | 202 | // calculate the relative tangent velocity 203 | var vrt = c.nx * vry - c.ny * vrx; 204 | 205 | // calculate and clamp the friction impulse 206 | var jtMax = friction * c.jnAcc; 207 | var jt = vrt * c.tMass; 208 | var jtOld = c.jtAcc; 209 | c.jtAcc = jtOld - jt; 210 | if( c.jtAcc < -jtMax ) c.jtAcc = -jtMax else if( c.jtAcc > jtMax ) c.jtAcc = jtMax; 211 | jt = c.jtAcc - jtOld; 212 | 213 | // apply the impulse 214 | var cjTx = c.nx * jn - c.ny * jt; 215 | var cjTy = c.ny * jn + c.nx * jt; 216 | bodyImpulse(c,b1,b2,cjTx,cjTy); 217 | 218 | c = c.next; 219 | } 220 | } 221 | 222 | } 223 | -------------------------------------------------------------------------------- /phx/Axis.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | 27 | class Axis { 28 | 29 | public var n : Vector; // normal 30 | public var d : Float; // distance from origin 31 | 32 | public var next : Axis; 33 | 34 | public function new( n : Vector, d : Float ) { 35 | this.n = n; 36 | this.d = d; 37 | } 38 | 39 | public inline function clone() { 40 | return new Axis( this.n.clone(), this.d ); 41 | } 42 | 43 | public function toString() { 44 | return "[Axis= " + n.x + "," + n.y + " d=" + d+"]"; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /phx/Body.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | 27 | class Body { 28 | 29 | static var ID = 0; 30 | 31 | public var id : Int; 32 | 33 | public var mass : Float; 34 | public var invMass : Float; 35 | public var inertia : Float; 36 | public var invInertia : Float; 37 | 38 | public var x:Float; // position 39 | public var y:Float; 40 | public var v:Vector; // velocity 41 | public var f:Vector; // force 42 | public var v_bias:Vector; // used internally for penetration/joint correction 43 | 44 | public var a:Float; // angle 45 | public var w:Float; // angular velocity 46 | public var t:Float; // torque 47 | public var w_bias:Float; // used internally for penetration/joint correction 48 | public var rcos:Float; // current rotation 49 | public var rsin:Float; 50 | 51 | public var motion:Float; 52 | public var isStatic:Bool; 53 | public var island : Island; 54 | 55 | public var shapes : haxe.ds.GenericStack; 56 | public var arbiters : haxe.ds.GenericStack; 57 | public var properties : Properties; 58 | 59 | public function new( x, y, ?props ) { 60 | id = ID++; 61 | properties = if( props == null ) Const.DEFAULT_PROPERTIES else props; 62 | this.x = x; 63 | this.y = y; 64 | v = new phx.Vector(0,0); 65 | f = new phx.Vector(0,0); 66 | v_bias = new phx.Vector(0,0); 67 | a = w = t = w_bias = 0; 68 | rcos = 1; rsin = 0; 69 | shapes = new haxe.ds.GenericStack(); 70 | arbiters = new haxe.ds.GenericStack(); 71 | } 72 | 73 | public function addShape( s : Shape ) { 74 | shapes.add(s); 75 | s.body = this; 76 | } 77 | 78 | public function removeShape( s : Shape ) { 79 | shapes.remove(s); 80 | s.body = null; 81 | } 82 | 83 | public function updatePhysics() { 84 | var m = 0.; 85 | var i = 0.; 86 | for( s in shapes ) { 87 | var sm = s.area * s.material.density; 88 | m += sm; 89 | i += s.calculateInertia() * sm; 90 | } 91 | if( m > 0 ) { 92 | mass = m; 93 | invMass = 1 / m; 94 | } else { 95 | mass = Math.POSITIVE_INFINITY; 96 | invMass = 0; 97 | isStatic = true; 98 | } 99 | if( i > 0 ) { 100 | inertia = i; 101 | invInertia = 1 / i; 102 | } else { 103 | inertia = Math.POSITIVE_INFINITY; 104 | invInertia = 0; 105 | } 106 | } 107 | 108 | public function preventRotation() { 109 | inertia = Math.POSITIVE_INFINITY; 110 | invInertia = 0; 111 | } 112 | 113 | public function setAngle( a : Float ) { 114 | this.a = a; 115 | rcos = Math.cos(a); 116 | rsin = Math.sin(a); 117 | } 118 | 119 | public function set( ?pos : Vector, ?a : Float, ?v : Vector, ?w : Float ) { 120 | if( pos != null ) { 121 | x = pos.x; 122 | y = pos.y; 123 | } 124 | if( a != null ) setAngle(a); 125 | if( v != null ) { 126 | this.v.x = v.x; 127 | this.v.y = v.y; 128 | } 129 | if( w != null ) this.w = w; 130 | } 131 | 132 | public function setPos( x, y, ?a ) { 133 | this.x = x; 134 | this.y = y; 135 | if( a != null ) setAngle(a); 136 | } 137 | 138 | public function setSpeed( vx, vy, ?w ) { 139 | v.x = vx; 140 | v.y = vy; 141 | if( w != null ) this.w = w; 142 | } 143 | 144 | public function toString() { 145 | return "Body#"+id; 146 | } 147 | 148 | public dynamic function onDestroy() { 149 | } 150 | 151 | } 152 | -------------------------------------------------------------------------------- /phx/Circle.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | 27 | class Circle extends Shape { 28 | 29 | public var c:Vector; 30 | public var r:Float; 31 | public var tC:Vector; 32 | 33 | public function new( radius, offset : Vector, ?material ) { 34 | super(Shape.CIRCLE, material); 35 | circle = this; 36 | this.offset = offset.clone(); 37 | c = offset.clone(); 38 | r = radius; 39 | area = Math.PI * (r * r); 40 | tC = c.clone(); 41 | } 42 | 43 | public override function update() { 44 | tC.x = body.x + Const.XROT(c,body); 45 | tC.y = body.y + Const.YROT(c,body); 46 | aabb.l = tC.x - r; 47 | aabb.r = tC.x + r; 48 | aabb.t = tC.y - r; 49 | aabb.b = tC.y + r; 50 | } 51 | 52 | public override function calculateInertia() { 53 | return 0.5 * (r * r) + offset.dot(offset); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /phx/Collision.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | 27 | class Collision { 28 | 29 | public function new() { 30 | } 31 | 32 | public inline function testShapes( s1 : Shape, s2 : Shape, a : Arbiter ) { 33 | return if( s1.type == Shape.POLYGON && s2.type == Shape.POLYGON ) 34 | poly2poly(s1.polygon,s2.polygon,a); 35 | else if( s1.type == Shape.CIRCLE ) { 36 | if( s2.type == Shape.POLYGON ) 37 | circle2poly(s1.circle,s2.polygon,a); 38 | else if( s2.type == Shape.CIRCLE ) 39 | circle2circle(s1.circle,s2.circle,a); 40 | else /* type = SEGMENT */ 41 | circle2segment(s1.circle,s2.segment,a); 42 | } else if( s1.type == Shape.SEGMENT && s2.type == Shape.POLYGON ) 43 | segment2poly(s1.segment,s2.polygon,a); 44 | else 45 | false; // segment-segment 46 | } 47 | 48 | inline function polyAxisProject( s : Polygon, n : Vector, d : Float ) { 49 | var v = s.tVerts; 50 | var min = phx.Const.FMAX; 51 | while( v != null ) { 52 | var k = n.dot(v); 53 | if( k < min ) min = k; 54 | v = v.next; 55 | } 56 | return min - d; 57 | } 58 | 59 | function poly2poly( shape1 : Polygon, shape2 : Polygon, arb : Arbiter ) { 60 | // first, project shape 2 vertices onto shape 1 axes & find MSA 61 | var max1 = -Const.FMAX; 62 | var axis1 = null; 63 | var a = shape1.tAxes; 64 | while( a != null ) { 65 | var min = polyAxisProject(shape2,a.n,a.d); 66 | if( min > 0 ) return false; 67 | if( min > max1 ) { 68 | max1 = min; 69 | axis1 = a; 70 | } 71 | a = a.next; 72 | } 73 | 74 | // Second, project shape 1 vertices onto shape 2 axes & find MSA 75 | var max2 = -Const.FMAX; 76 | var axis2 = null; 77 | a = shape2.tAxes; 78 | while( a != null ) { 79 | var min = polyAxisProject(shape1,a.n,a.d); 80 | if( min > 0 ) return false; 81 | if( min > max2 ) { 82 | max2 = min; 83 | axis2 = a; 84 | } 85 | a = a.next; 86 | } 87 | if( max1 > max2 ) 88 | findVerts(arb, shape1, shape2, axis1, 1, max1); 89 | else 90 | findVerts(arb, shape1, shape2, axis2, -1, max2); 91 | return true; 92 | } 93 | 94 | function findVerts( arb : Arbiter, poly1 : Polygon, poly2 : Polygon, n : Axis, nCoef : Float, dist : Float ) { 95 | // we need to uniquely identify the contact 96 | // and the poly can be swaped so the id calculus 97 | // needs to be commutative 98 | var id = (poly1.id > poly2.id) ? 0 : 65000; 99 | var c = 0; 100 | var v = poly1.tVerts; 101 | while( v != null ) { 102 | if( polyContainsPoint(poly2,v) ) { 103 | arb.injectContact(v,n.n,nCoef,dist,id); 104 | if( ++c > 1 ) return; // max = 2 contacts 105 | } 106 | id++; 107 | v = v.next; 108 | } 109 | id = (poly1.id > poly2.id) ? 65000 : 0; 110 | v = poly2.tVerts; 111 | while( v != null ) { 112 | if( polyContainsPoint(poly1,v) ) { 113 | arb.injectContact(v,n.n,nCoef,dist,id); 114 | if( ++c > 1 ) return; // max = 2 contacts 115 | } 116 | id++; 117 | v = v.next; 118 | } 119 | } 120 | 121 | inline function circle2circle( circle1, circle2, arb ) { 122 | return circle2circleQuery( arb, circle1.tC, circle2.tC, circle1.r, circle2.r ); 123 | } 124 | 125 | function circle2circleQuery( arb : Arbiter, p1 : Vector, p2 : Vector, r1 : Float, r2 : Float ) { 126 | var minDist = r1 + r2; 127 | var x = p2.x - p1.x; 128 | var y = p2.y - p1.y; 129 | var distSqr = x * x + y * y; 130 | if( distSqr >= minDist * minDist ) 131 | return false; 132 | var dist = Math.sqrt(distSqr); 133 | var invDist = (dist < Const.EPSILON) ? 0 : 1 / dist; 134 | var df = 0.5 + (r1 - 0.5 * minDist) * invDist; 135 | arb.injectContact( new Vector(p1.x + x * df,p1.y + y * df), new Vector(x * invDist, y * invDist), 1.0, dist - minDist, 0); 136 | return true; 137 | } 138 | 139 | function circle2segment( circle : Circle, seg : Segment, arb : Arbiter ) { 140 | var dn = seg.tN.dot(circle.tC) - seg.tA.dot(seg.tN); 141 | var dist = (dn < 0 ? -dn : dn) - circle.r - seg.r; 142 | if( dist > 0 ) 143 | return false; 144 | var dt = -seg.tN.cross(circle.tC); 145 | var dtMin = -seg.tN.cross(seg.tA); 146 | var dtMax = -seg.tN.cross(seg.tB); 147 | if( dt < dtMin ) { 148 | if( dt < dtMin - circle.r ) 149 | return false; 150 | return circle2circleQuery(arb, circle.tC, seg.tA, circle.r, seg.r); 151 | } else { 152 | if( dt < dtMax ) { 153 | var n = (dn < 0) ? seg.tN : seg.tN.mult(-1); 154 | var hdist = circle.r + dist * 0.5; 155 | arb.injectContact(new Vector(circle.tC.x + n.x * hdist, circle.tC.y + n.y * hdist),n,1.0,dist,0); 156 | return true; 157 | } 158 | if( dt < dtMax + circle.r ) 159 | return circle2circleQuery(arb,circle.tC, seg.tB, circle.r, seg.r); 160 | } 161 | return false; 162 | } 163 | 164 | function findPolyPointsBehindSegment( seg : Segment, poly : Polygon, pDist : Float, coef : Float, arb : Arbiter ) { 165 | var dta = seg.tN.cross(seg.tA); 166 | var dtb = seg.tN.cross(seg.tB); 167 | var n = new Vector(seg.tN.x * coef, seg.tN.y * coef); 168 | var k = seg.tN.dot(seg.tA) * coef; 169 | var v = poly.tVerts; 170 | var i = 2; // 0 and 1 are reserved for segment 171 | while( v != null ) { 172 | if( v.dot(n) < k + seg.r ) { 173 | var dt = seg.tN.cross(v); 174 | if( dta >= dt && dt >= dtb ) 175 | arb.injectContact(v, n, 1.0, pDist, i ); 176 | } 177 | i++; 178 | v = v.next; 179 | } 180 | } 181 | 182 | inline function segAxisProject( seg : Segment, n : Vector, d : Float ) { 183 | var vA = n.dot(seg.tA) - seg.r; 184 | var vB = n.dot(seg.tB) - seg.r; 185 | return if( vA < vB ) vA - d else vB - d; 186 | } 187 | 188 | function segment2poly( seg : Segment, poly : Polygon, arb : Arbiter ) { 189 | var segD = seg.tN.dot(seg.tA); 190 | var minNorm = polyAxisProject(poly,seg.tN,segD) - seg.r; 191 | var minNeg = polyAxisProject(poly,seg.tNneg,-segD) - seg.r; 192 | if( minNeg > 0 || minNorm > 0 ) return false; 193 | 194 | var a = poly.tAxes; 195 | var polyMin = -Const.FMAX; 196 | var axis = null; 197 | while( a != null ) { 198 | var dist = segAxisProject(seg,a.n,a.d); 199 | if( dist > 0 ) 200 | return false; 201 | if( dist > polyMin ) { 202 | polyMin = dist; 203 | axis = a; 204 | } 205 | a = a.next; 206 | } 207 | 208 | var n = axis.n; 209 | var va = new Vector( seg.tA.x - n.x * seg.r, seg.tA.y - n.y * seg.r ); 210 | var vb = new Vector( seg.tB.x - n.x * seg.r, seg.tB.y - n.y * seg.r ); 211 | if( polyContainsPoint(poly,va) ) 212 | arb.injectContact(va, n, -1.0, polyMin, 0 ); 213 | if( polyContainsPoint(poly,vb) ) 214 | arb.injectContact(vb, n, -1.0, polyMin, 1 ); 215 | if( minNorm >= polyMin || minNeg >= polyMin ) { 216 | if( minNorm > minNeg ) 217 | findPolyPointsBehindSegment(seg, poly, minNorm, 1.0, arb); 218 | else 219 | findPolyPointsBehindSegment(seg, poly, minNeg, -1.0, arb); 220 | } 221 | return true; 222 | 223 | } 224 | 225 | function circle2poly( circle : Circle, poly : Polygon, arb : Arbiter ) { 226 | var a0 = null, v0 = null; 227 | var a = poly.tAxes; 228 | var v = poly.tVerts; 229 | 230 | var min = -Const.FMAX; 231 | while( a != null ) { 232 | var dist = a.n.dot(circle.tC) - a.d - circle.r; 233 | if( dist > 0 ) 234 | return false; 235 | if( dist > min ) { 236 | min = dist; 237 | a0 = a; 238 | v0 = v; 239 | } 240 | a = a.next; 241 | v = v.next; 242 | } 243 | 244 | var n = a0.n; 245 | var v1 = (v0.next == null)?poly.tVerts:v0.next; 246 | var dt = n.cross(circle.tC); 247 | if( dt < n.cross(v1) ) 248 | return circle2circleQuery(arb, circle.tC, v1, circle.r, 0); 249 | if( dt >= n.cross(v0) ) 250 | return circle2circleQuery(arb, circle.tC, v0, circle.r, 0); 251 | 252 | var nx = n.x * (circle.r + min * 0.5); 253 | var ny = n.y * (circle.r + min * 0.5); 254 | arb.injectContact(new Vector(circle.tC.x - nx, circle.tC.y - ny),n,-1.0,min,0) ; 255 | return true; 256 | } 257 | 258 | function polyContainsPoint( s : Polygon, p : Vector ) { 259 | var a = s.tAxes; 260 | while( a != null ) { 261 | if( a.n.dot(p) > a.d ) 262 | return false; 263 | a = a.next; 264 | } 265 | return true; 266 | } 267 | 268 | public inline function testPoint( s : Shape, p : Vector ) { 269 | return switch( s.type ) { 270 | case Shape.POLYGON: 271 | polyContainsPoint(s.polygon,p); 272 | case Shape.CIRCLE: 273 | var c = s.circle; 274 | var dx = c.tC.x - p.x; 275 | var dy = c.tC.y - p.y; 276 | (dx * dx + dy * dy) <= (c.r * c.r); 277 | default: 278 | false; 279 | } 280 | } 281 | 282 | } 283 | -------------------------------------------------------------------------------- /phx/Const.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | 27 | class Const { 28 | 29 | public static inline var FMAX = 1e99; 30 | public static inline var EPSILON = 1e-99; 31 | public static inline var WORLD_BOUNDS_FREQ = 120; 32 | 33 | public static var DEFAULT_MATERIAL = new Material( 0.001, 0.81, 1 ); 34 | public static var DEFAULT_PROPERTIES = new Properties( 0.999, 0.999, 0.1, FMAX, 0.5 ); 35 | 36 | // sleep 37 | public static inline var SLEEP_BIAS = 0.95; 38 | public static inline var DEFAULT_SLEEP_EPSILON = 0.002; 39 | public static inline var WAKEUP_FACTOR = 2; 40 | public static inline var ANGULAR_TO_LINEAR = 30.0; // 1 degree ~= 0.5 pix 41 | 42 | public static inline function XROT( v : Vector, b : Body ) { 43 | return v.x * b.rcos - v.y * b.rsin; 44 | } 45 | 46 | public static inline function YROT( v : Vector, b : Body ) { 47 | return v.x * b.rsin + v.y * b.rcos; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /phx/Contact.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | 27 | class Contact { 28 | 29 | public var px:Float; // contact point 30 | public var py:Float; 31 | public var nx:Float; // contact normal 32 | public var ny:Float; 33 | public var dist:Float; // contact penetration distance 34 | 35 | // cache prestep values 36 | public var r1x:Float; 37 | public var r1y:Float; 38 | public var r2x:Float; 39 | public var r2y:Float; 40 | public var r1nx:Float; 41 | public var r1ny:Float; 42 | public var r2nx:Float; 43 | public var r2ny:Float; 44 | public var nMass:Float; 45 | public var tMass:Float; 46 | public var bounce:Float; 47 | 48 | // persistant contact infomation 49 | public var jnAcc:Float; 50 | public var jtAcc:Float; 51 | public var jBias:Float; 52 | public var bias:Float; 53 | 54 | public var hash:Int; 55 | public var updated:Bool; 56 | public var next:Contact; 57 | 58 | public function new() { 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /phx/FlashDraw.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | import phx.joint.Joint; 27 | 28 | typedef Color = { 29 | public var lineSize : Float; 30 | public var line : Null; 31 | public var fill : Null; 32 | public var alpha : Float; 33 | } 34 | 35 | class FlashDraw { 36 | 37 | #if (flash || neko || cpp) 38 | var g : flash.display.Graphics; 39 | #elseif js 40 | var g : phx.JsCanvas; 41 | #end 42 | 43 | public var shape : Color; 44 | public var staticShape : Color; 45 | public var sleepingShape : Color; 46 | public var boundingBox : Color; 47 | public var contact : Color; 48 | public var sleepingContact : Color; 49 | public var contactSize : Color; 50 | public var drawSegmentsBorders : Bool; 51 | public var drawSegmentsNormals : Bool; 52 | public var drawCircleRotation : Bool; 53 | 54 | public var xmin : Int; 55 | public var ymin : Int; 56 | public var xmax : Int; 57 | public var ymax : Int; 58 | 59 | public function new( g ) { 60 | this.g = g; 61 | this.xmin = this.ymin = -1000000000; 62 | this.xmax = this.ymax = 1000000000; 63 | drawSegmentsBorders = true; 64 | drawSegmentsNormals = false; 65 | shape = { lineSize : 2., line : 0x333333, fill : 0xDFECEC, alpha : 1. }; 66 | staticShape = { lineSize : 2., line : 0x333333, fill : 0xE6DC64, alpha : 1. }; 67 | sleepingShape = { lineSize : 2., line : 0x333333, fill : 0x7FECEC, alpha : 1. }; 68 | boundingBox = { lineSize : 0., line : null, fill : null, alpha : 1. }; 69 | contact = { lineSize : 1., line : null, fill : null, alpha : 1. }; 70 | sleepingContact = { lineSize : 1., line : null, fill : null, alpha : 1. }; 71 | contactSize = { lineSize : 1., line : null, fill : null, alpha : 1. }; 72 | } 73 | 74 | function begin( c : Color ) { 75 | if( c == null || (c.line == null && c.fill == null) ) return false; 76 | if( c.line == null ) g.lineStyle() else g.lineStyle(c.lineSize,c.line); 77 | if( c.fill != null ) g.beginFill(c.fill,c.alpha); 78 | return true; 79 | } 80 | 81 | function end( c : Color ) { 82 | if( c.fill != null ) g.endFill(); 83 | } 84 | 85 | function selectColor( s : Shape ) { 86 | return s.body.isStatic ? staticShape : (s.body.island != null && s.body.island.sleeping ? sleepingShape : shape); 87 | } 88 | 89 | function selectArbiterColor( a : Arbiter ) { 90 | return a.sleeping ? sleepingContact : contact; 91 | } 92 | 93 | public function drawWorld( w : World ) { 94 | drawBody(w.staticBody); 95 | for( b in w.bodies ) 96 | drawBody(b); 97 | for( j in w.joints ) 98 | drawJoint(j); 99 | for( a in w.arbiters ) { 100 | var col = selectArbiterColor(a); 101 | if( begin(col) ) { 102 | var c = a.contacts; 103 | if( c == null ) { 104 | var b1 = a.s1.body; 105 | var b2 = a.s2.body; 106 | var p1 = (a.s1.offset == null) ? new phx.Vector(b1.x,b1.y) : new phx.Vector( b1.x + Const.XROT(a.s1.offset,b1), b1.y + Const.YROT(a.s1.offset,b1) ); 107 | var p2 = (a.s2.offset == null) ? new phx.Vector(b1.x,b1.y) : new phx.Vector( b2.x + Const.XROT(a.s2.offset,b2), b2.y + Const.YROT(a.s2.offset,b2) ); 108 | g.moveTo(p1.x,p1.y); 109 | g.lineTo(p2.x,p2.y); 110 | g.drawCircle(p1.x,p1.y,5); 111 | g.drawCircle(p2.x,p2.y,5); 112 | } 113 | while( c != null ) { 114 | if( c.updated ) 115 | g.drawRect(c.px - 1,c.py - 1,2,2); 116 | c = c.next; 117 | } 118 | end(col); 119 | } 120 | if( begin(contactSize) ) { 121 | var c = a.contacts; 122 | while( c != null ) { 123 | if( c.updated ) 124 | g.drawCircle(c.px, c.py, c.dist); 125 | c = c.next; 126 | } 127 | end(contactSize); 128 | } 129 | } 130 | } 131 | 132 | public function drawBody( b : Body ) { 133 | for( s in b.shapes ) { 134 | var b = s.aabb; 135 | if( b.r < xmin || b.b < ymin || b.l > xmax || b.t > ymax ) 136 | continue; 137 | drawShape(s); 138 | } 139 | } 140 | 141 | public function drawShape( s : Shape ) { 142 | var c = selectColor(s); 143 | if( begin(c) ) { 144 | switch( s.type ) { 145 | case Shape.CIRCLE: drawCircle(s.circle); 146 | case Shape.POLYGON: drawPoly(s.polygon); 147 | case Shape.SEGMENT: drawSegment(s.segment); 148 | } 149 | end(c); 150 | } 151 | if( begin(boundingBox) ) { 152 | g.drawRect(s.aabb.l, s.aabb.t, s.aabb.r - s.aabb.l, s.aabb.b - s.aabb.t); 153 | end(boundingBox); 154 | } 155 | } 156 | 157 | function drawSegment( s : Segment ) { 158 | var delta = s.tB.minus(s.tA); 159 | var angle = Math.atan2( delta.x, delta.y ); 160 | var dx = Math.cos(angle) * s.r; 161 | var dy = Math.sin(angle) * s.r; 162 | if( drawSegmentsBorders ) { 163 | g.drawCircle(s.tA.x, s.tA.y, s.r); 164 | g.drawCircle(s.tB.x, s.tB.y, s.r); 165 | } 166 | if( drawSegmentsNormals ) { 167 | var hx = (s.tA.x + s.tB.x) / 2; 168 | var hy = (s.tA.y + s.tB.y) / 2; 169 | g.moveTo(hx,hy); 170 | g.lineTo(hx + s.tN.x * (s.r * 2),hy + s.tN.y * (s.r * 2)); 171 | } 172 | g.moveTo(s.tA.x + dx,s.tA.y - dy); 173 | g.lineTo(s.tB.x + dx,s.tB.y - dy); 174 | g.lineTo(s.tB.x - dx,s.tB.y + dy); 175 | g.lineTo(s.tA.x - dx,s.tA.y + dy); 176 | g.moveTo(s.tA.x + dx,s.tA.y - dy); 177 | } 178 | 179 | function drawCircle( c : Circle ) { 180 | g.drawCircle(c.tC.x, c.tC.y, c.r ); 181 | if( drawCircleRotation ) { 182 | g.moveTo(c.tC.x, c.tC.y); 183 | g.lineTo(c.tC.x + c.body.rcos * c.r, c.tC.y + c.body.rsin * c.r); 184 | } 185 | } 186 | 187 | function drawPoly( p : Polygon ) { 188 | var v = p.tVerts; 189 | g.moveTo( v.x, v.y ); 190 | while( v != null ) { 191 | g.lineTo(v.x, v.y); 192 | v = v.next; 193 | } 194 | g.lineTo( p.tVerts.x, p.tVerts.y ); 195 | } 196 | 197 | public function drawJoint( j : Joint ) { 198 | } 199 | 200 | } -------------------------------------------------------------------------------- /phx/Island.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | import phx.joint.Joint; 27 | 28 | class Island { 29 | 30 | static var ID = 0; 31 | 32 | public var id : Int; 33 | public var bodies : haxe.ds.GenericStack; 34 | public var arbiters : haxe.ds.GenericStack; 35 | public var joints : haxe.ds.GenericStack; 36 | public var sleeping : Bool; 37 | public var energy : Float; 38 | var world : World; 39 | 40 | public var allocNext : Island; 41 | 42 | public function new(w) { 43 | id = ID++; 44 | world = w; 45 | sleeping = false; 46 | bodies = new haxe.ds.GenericStack(); 47 | joints = new haxe.ds.GenericStack(); 48 | arbiters = new haxe.ds.GenericStack(); 49 | } 50 | 51 | public function solve( dt : Float, invDt : Float, iterations : Int ) { 52 | 53 | // update bodies 54 | var g = world.gravity; 55 | for( b in bodies ) { 56 | var v = b.v; 57 | var p = b.properties; 58 | v.x = v.x * p.lfdt + (g.x + b.f.x * b.invMass) * dt; 59 | v.y = v.y * p.lfdt + (g.y + b.f.y * b.invMass) * dt; 60 | b.w = b.w * p.afdt + b.t * b.invInertia * dt; 61 | } 62 | 63 | // prestep arbiters and joints 64 | for( a in arbiters ) 65 | a.preStep(dt); 66 | for( joint in joints ) 67 | joint.preStep(invDt); 68 | 69 | // solve velocity constraints 70 | for( i in 0...iterations ) { 71 | for( a in arbiters ) 72 | a.applyImpulse(); 73 | for( j in joints ) 74 | j.applyImpuse(); 75 | } 76 | 77 | // update bodies position 78 | var bf = world.broadphase; 79 | var e = 0.; 80 | var n = 0; 81 | #if flash9 82 | var Math = Math; 83 | #end 84 | for( b in bodies ) { 85 | var motion = b.v.x * b.v.x + b.v.y * b.v.y + b.w * b.w * Const.ANGULAR_TO_LINEAR; 86 | if( motion > b.properties.maxMotion ) { 87 | var k = Math.sqrt(b.properties.maxMotion / motion); 88 | b.v.x *= k; 89 | b.v.y *= k; 90 | b.w *= k; 91 | motion *= k * k; 92 | } 93 | b.x += b.v.x * dt + b.v_bias.x; 94 | b.y += b.v.y * dt + b.v_bias.y; 95 | b.a += b.w * dt + b.w_bias; 96 | b.rcos = Math.cos(b.a); 97 | b.rsin = Math.sin(b.a); 98 | b.motion = b.motion * Const.SLEEP_BIAS + (1 - Const.SLEEP_BIAS) * motion; 99 | b.f.x = b.f.y = b.t = 0; 100 | b.v_bias.x = b.v_bias.y = b.w_bias = 0; 101 | e += b.motion; 102 | n++; 103 | for( s in b.shapes ) { 104 | s.update(); 105 | bf.syncShape(s); 106 | } 107 | } 108 | energy = e / Math.sqrt(n); 109 | if( energy < world.sleepEpsilon ) { 110 | for( b in bodies ) { 111 | b.v.x = 0; 112 | b.v.y = 0; 113 | b.w = 0; 114 | } 115 | for( a in arbiters ) 116 | a.sleeping = true; 117 | sleeping = true; 118 | } 119 | } 120 | 121 | } -------------------------------------------------------------------------------- /phx/JsCanvas.hx: -------------------------------------------------------------------------------- 1 | package phx; 2 | 3 | import js.html.CanvasElement; 4 | import js.html.CanvasRenderingContext2D; 5 | 6 | class JsCanvas { 7 | 8 | var ctx : CanvasRenderingContext2D; 9 | 10 | public function new( canvas : CanvasElement ) { 11 | ctx = canvas.getContext( '2d' ); 12 | } 13 | 14 | public inline function clear() { 15 | ctx.clearRect( 0, 0, ctx.canvas.width, ctx.canvas.height ); 16 | } 17 | 18 | public function lineStyle( ?width : Float, ?color : Int ) { 19 | if( width == null ) 20 | return; 21 | ctx.lineWidth = width; 22 | ctx.strokeStyle = COL(color); 23 | } 24 | 25 | public inline function beginFill( color : Int, alpha : Float ) { 26 | ctx.fillStyle = COL(color); 27 | ctx.beginPath(); 28 | } 29 | 30 | public inline function endFill() { 31 | ctx.fill(); 32 | ctx.stroke(); 33 | } 34 | 35 | public inline function drawCircle( x : Float, y : Float, radius : Float ) { 36 | ctx.arc(x,y,radius,0,6.29,true); 37 | } 38 | 39 | public inline function drawRect( x : Float, y : Float, w : Float, h : Float ) { 40 | ctx.rect(x,y,w,h); 41 | } 42 | 43 | public inline function moveTo( x : Float, y : Float ) { 44 | ctx.moveTo(x,y); 45 | } 46 | 47 | public inline function lineTo( x : Float, y : Float ) { 48 | ctx.lineTo(x,y); 49 | } 50 | 51 | static inline function COL( color : Int ) { 52 | return "rgb("+(color>>16)+","+((color>>8)&0xFF)+","+(color&0xFF)+")"; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /phx/Material.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | 27 | class Material { 28 | 29 | public var restitution:Float; 30 | public var friction:Float; 31 | public var density:Float; 32 | 33 | public function new( restitution, friction, density ) { 34 | this.restitution = restitution; 35 | this.friction = friction; 36 | this.density = density; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /phx/Polygon.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | 27 | class Polygon extends Shape { 28 | 29 | public var verts : Vector; 30 | public var tVerts : Vector; 31 | public var vcount : Int; 32 | 33 | public var axes : Axis; 34 | public var tAxes : Axis; 35 | 36 | public function new( vl : Array, offset : Vector, ?material : Material ) { 37 | super(Shape.POLYGON, material); 38 | polygon = this; 39 | this.offset = offset; 40 | initVertexes(vl); 41 | } 42 | 43 | function initVertexes( vl : Array ) { 44 | var l_verts = null, l_tVerts = null, l_axes = null, l_tAxes = null; 45 | var count = vl.length; 46 | vcount = count; 47 | area = 0; 48 | var off = (offset != null); 49 | for( i in 0...count ) { 50 | var v0 = vl[i]; 51 | var v1 = vl[(i + 1) % count]; 52 | var v2 = vl[(i + 2) % count]; 53 | area += v1.x * (v0.y - v2.y); 54 | 55 | var v = off ? v0.plus(offset) : v0; 56 | var n = Vector.normal(v1.x - v0.x,v1.y - v0.y); 57 | var a = new Axis(n, n.dot(v)); 58 | 59 | var vt = v.clone(); 60 | var at = a.clone(); 61 | 62 | // enqueue 63 | if( i == 0 ) { 64 | verts = v; 65 | tVerts = vt; 66 | axes = a; 67 | tAxes = at; 68 | } else { 69 | l_verts.next = v; 70 | l_tVerts.next = vt; 71 | l_axes.next = a; 72 | l_tAxes.next = at; 73 | } 74 | l_verts = v; 75 | l_tVerts = vt; 76 | l_axes = a; 77 | l_tAxes = at; 78 | } 79 | area *= 0.5; 80 | } 81 | 82 | public override function update() { 83 | var v = verts; 84 | var tv = tVerts; 85 | var body = body; 86 | var aabb = aabb; 87 | 88 | // reset bounding box 89 | aabb.l = aabb.t = Const.FMAX; 90 | aabb.r = aabb.b = -Const.FMAX; 91 | 92 | // transform points 93 | while( v != null ) { 94 | tv.x = body.x + Const.XROT(v,body); 95 | tv.y = body.y + Const.YROT(v,body); 96 | if( tv.x < aabb.l ) aabb.l = tv.x; 97 | if( tv.x > aabb.r ) aabb.r = tv.x; 98 | if( tv.y < aabb.t ) aabb.t = tv.y; 99 | if( tv.y > aabb.b ) aabb.b = tv.y; 100 | v = v.next; 101 | tv = tv.next; 102 | } 103 | 104 | // transform axes 105 | var a = axes; 106 | var ta = tAxes; 107 | while( a != null ) { 108 | var n = a.n; 109 | ta.n.x = Const.XROT(n,body); 110 | ta.n.y = Const.YROT(n,body); 111 | ta.d = body.x * ta.n.x + body.y * ta.n.y + a.d; 112 | a = a.next; 113 | ta = ta.next; 114 | } 115 | } 116 | 117 | public override function calculateInertia() { 118 | // not very optimized (using a tmp array) 119 | // but simplifying the maths is not easy here 120 | var tVertsTemp = new Array(); 121 | var v = verts; 122 | while( v != null ) { 123 | tVertsTemp.push( new Vector( v.x + offset.x , v.y + offset.y) ); 124 | v = v.next; 125 | } 126 | var sum1 = 0.; 127 | var sum2 = 0.; 128 | for( i in 0...vcount ) { 129 | var v0 = tVertsTemp[i]; 130 | var v1 = tVertsTemp[(i + 1) % vcount]; 131 | var a = v1.cross(v0); 132 | var b = v0.dot(v0) + v0.dot(v1) + v1.dot(v1); 133 | sum1 += a * b; 134 | sum2 += a; 135 | } 136 | return sum1 / (6 * sum2); 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /phx/Properties.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | 27 | class Properties { 28 | 29 | static var PID = 0; 30 | 31 | /** 32 | The amount the linear speed of the object is reduced by time 33 | **/ 34 | public var linearFriction : Float; 35 | 36 | /** 37 | The amount the angular speed of the object is reduced by time 38 | **/ 39 | public var angularFriction : Float; 40 | 41 | /** 42 | The percentage the object position will be modified if it is inside another object 43 | **/ 44 | public var biasCoef : Float; 45 | 46 | /** 47 | The maximum movement of the object 48 | **/ 49 | public var maxMotion : Float; 50 | 51 | /** 52 | The maximum distance at which we can interpenerate another object without applying position bias 53 | **/ 54 | public var maxDist : Float; 55 | 56 | // internal 57 | public var id : Int; 58 | public var count : Int; 59 | public var lfdt : Float; 60 | public var afdt : Float; 61 | 62 | public function new( linearFriction, angularFriction, biasCoef, maxMotion, maxDist ) { 63 | id = PID++; 64 | count = 0; 65 | this.linearFriction = linearFriction; 66 | this.angularFriction = angularFriction; 67 | this.biasCoef = biasCoef; 68 | this.maxMotion = maxMotion; 69 | this.maxDist = maxDist; 70 | } 71 | 72 | } -------------------------------------------------------------------------------- /phx/Segment.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | 27 | class Segment extends Shape { 28 | 29 | public var a : Vector; 30 | public var b : Vector; 31 | public var n : Vector; 32 | 33 | public var r : Float; 34 | 35 | public var tA : Vector; 36 | public var tB : Vector; 37 | public var tN : Vector; 38 | public var tNneg : Vector; 39 | 40 | public function new( a : Vector, b : Vector, r : Float, ?material : Material ) { 41 | super(Shape.SEGMENT, material); 42 | segment = this; 43 | offset = new Vector(0,0); 44 | this.a = a.clone(); 45 | this.b = b.clone(); 46 | this.r = r; 47 | var delta = b.minus(a); 48 | n = Vector.normal(delta.x,delta.y); 49 | area = r * delta.length(); 50 | tA = new Vector(0,0); 51 | tB = new Vector(0,0); 52 | tN = new Vector(0,0); 53 | tNneg = new Vector(0,0); 54 | } 55 | 56 | public override function update() { 57 | // transform 58 | tA.x = body.x + Const.XROT(a,body); 59 | tA.y = body.y + Const.YROT(a,body); 60 | tB.x = body.x + Const.XROT(b,body); 61 | tB.y = body.y + Const.YROT(b,body); 62 | tN.x = Const.XROT(n,body); 63 | tN.y = Const.YROT(n,body); 64 | tNneg.x = -tN.x; 65 | tNneg.y = -tN.y; 66 | 67 | // update bounding box 68 | if( tA.x < tB.x ) { 69 | aabb.l = tA.x - r; 70 | aabb.r = tB.x + r; 71 | } else { 72 | aabb.l = tB.x - r; 73 | aabb.r = tA.x + r; 74 | } 75 | if( tA.y < tB.y ) { 76 | aabb.t = tA.y - r; 77 | aabb.b = tB.y + r; 78 | } else { 79 | aabb.t = tB.y - r; 80 | aabb.b = tA.y + r; 81 | } 82 | } 83 | 84 | public override function calculateInertia() { 85 | return 1.; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /phx/Shape.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | 27 | class Shape { 28 | 29 | static var ID = 0; 30 | 31 | public static inline var CIRCLE = 0; 32 | public static inline var SEGMENT = 1; 33 | public static inline var POLYGON = 2; 34 | 35 | public var id : Int; 36 | public var type : Int; 37 | public var circle : Circle; 38 | public var segment : Segment; 39 | public var polygon : Polygon; 40 | 41 | public var body : Body; 42 | public var offset : Vector; 43 | public var aabb : phx.col.AABB; 44 | 45 | public var material : Material; 46 | public var area : Float; 47 | 48 | public var groups : Int; 49 | 50 | function new( type : Int, material : Material ) { 51 | id = ID++; 52 | groups = 1; 53 | this.type = type; 54 | this.material = (material == null) ? Const.DEFAULT_MATERIAL : material; 55 | this.area = 0; 56 | aabb = new phx.col.AABB(0,0,0,0); 57 | } 58 | 59 | public function update() { 60 | } 61 | 62 | public function calculateInertia() { 63 | return 1.; 64 | } 65 | 66 | public function toString() { 67 | return "Shape#"+id; 68 | } 69 | 70 | public static function makeBox( width : Float, height : Float, ?px, ?py, ?mat ) { 71 | if( px == null ) px = -width / 2; 72 | if( py == null ) py = -height / 2; 73 | return new Polygon([ 74 | new phx.Vector(0,0), 75 | new phx.Vector(0,height), 76 | new phx.Vector(width,height), 77 | new phx.Vector(width,0), 78 | ],new phx.Vector(px,py),mat); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /phx/Timer.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | 27 | class Timer { 28 | 29 | var times : Array; 30 | var curs : Array; 31 | var datas : Map; 32 | public var total : Float; 33 | 34 | public function new() { 35 | total = 0.; 36 | datas = new Map(); 37 | times = new Array(); 38 | curs = new Array(); 39 | } 40 | 41 | public function start( phase ) { 42 | times.push(haxe.Timer.stamp()); 43 | curs.push(phase); 44 | } 45 | 46 | public function stop() { 47 | var dt = (haxe.Timer.stamp() - times.pop()) * 1000; 48 | var name = curs.pop(); 49 | var data = datas.get(name); 50 | if( data == null ) { 51 | data = { total : 0., avg : 0. }; 52 | datas.set(name,data); 53 | } 54 | data.total += dt; 55 | data.avg = data.avg * 0.99 + 0.01 * dt; 56 | if( curs.length == 0 ) total += dt; 57 | } 58 | 59 | public function getTotal( name : String ) { 60 | var data = datas.get(name); 61 | if( data == null ) return 0.; 62 | return data.total; 63 | } 64 | 65 | public function format( name ) { 66 | var data = datas.get(name); 67 | if( data == null ) return name + " ????"; 68 | return name + " : "+Std.int(data.avg*1000) + " ("+(Std.int(data.total*1000/total)/10)+"%)"; 69 | } 70 | 71 | } -------------------------------------------------------------------------------- /phx/Vector.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | 27 | class Vector { 28 | 29 | public var x:Float; 30 | public var y:Float; 31 | 32 | public var next:Vector; 33 | 34 | public function new( px : Float, py : Float ) { 35 | x = px; 36 | y = py; 37 | } 38 | 39 | public inline function clone() { 40 | return new Vector(x,y); 41 | } 42 | 43 | public inline function set( px : Float, py : Float) { 44 | x = px; 45 | y = py; 46 | } 47 | 48 | public inline function dot( v : Vector ) { 49 | return x * v.x + y * v.y; 50 | } 51 | 52 | public inline function cross( v : Vector ) { 53 | return x * v.y - y * v.x; 54 | } 55 | 56 | public inline function plus( v : Vector ) { 57 | return new Vector(x + v.x, y + v.y); 58 | } 59 | 60 | public inline function minus( v : Vector ) : Vector { 61 | return new Vector(x - v.x, y - v.y); 62 | } 63 | 64 | public inline function mult( s : Float ) { 65 | return new Vector(x * s, y * s); 66 | } 67 | 68 | public inline function length() { 69 | return Math.sqrt(x * x + y * y); 70 | } 71 | 72 | public function toString() { 73 | return "("+(Math.round(x*100)/100)+","+(Math.round(y*100)/100)+")"; 74 | } 75 | 76 | public static inline function normal( x : Float, y : Float ) { 77 | var d = Math.sqrt(x * x + y * y); 78 | var k = if( d < Const.EPSILON ) 0 else 1 / d; 79 | return new Vector( -y * k , x * k ); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /phx/World.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx; 26 | import phx.joint.Joint; 27 | import phx.col.BroadPhase; 28 | 29 | class World implements BroadCallback { 30 | 31 | public var stamp : Int; 32 | public var bodies : haxe.ds.GenericStack; 33 | public var joints : haxe.ds.GenericStack; 34 | public var arbiters : haxe.ds.GenericStack; 35 | public var staticBody : Body; 36 | public var allocator : Allocator; 37 | public var broadphase : phx.col.BroadPhase; 38 | public var collision : Collision; 39 | public var timer : Timer; 40 | public var box : phx.col.AABB; 41 | 42 | // config 43 | public var gravity : Vector; 44 | public var boundsCheck : Int; 45 | public var useIslands : Bool; 46 | public var debug : Bool; 47 | public var testedCollisions : Int; 48 | public var activeCollisions : Int; 49 | public var sleepEpsilon : Float; 50 | 51 | public var islands : haxe.ds.GenericStack; 52 | var properties : Map; 53 | var waitingBodies : haxe.ds.GenericStack; 54 | 55 | public function new( worldBoundary, broadphase ) { 56 | bodies = new haxe.ds.GenericStack(); 57 | joints = new haxe.ds.GenericStack(); 58 | arbiters = new haxe.ds.GenericStack(); 59 | properties = new Map(); 60 | gravity = new Vector(0,0); 61 | stamp = 0; 62 | debug = false; 63 | useIslands = true; 64 | sleepEpsilon = Const.DEFAULT_SLEEP_EPSILON; 65 | boundsCheck = Const.WORLD_BOUNDS_FREQ; 66 | allocator = new Allocator(); 67 | collision = new Collision(); 68 | staticBody = new phx.Body(0,0); 69 | staticBody.island = new Island(this); 70 | staticBody.updatePhysics(); 71 | box = worldBoundary; 72 | this.broadphase = broadphase; 73 | broadphase.init(box,this,staticBody); 74 | timer = new Timer(); 75 | 76 | islands = new haxe.ds.GenericStack(); 77 | waitingBodies = new haxe.ds.GenericStack(); 78 | } 79 | 80 | public function setBroadPhase( bf : BroadPhase ) { 81 | bf.init(box,this,staticBody); 82 | for( b in bodies ) { 83 | for( s in b.shapes ) { 84 | broadphase.removeShape(s); 85 | bf.addShape(s); 86 | } 87 | } 88 | for( s in staticBody.shapes ) { 89 | broadphase.removeShape(s); 90 | bf.addShape(s); 91 | } 92 | broadphase = bf; 93 | } 94 | 95 | function buildIslands() { 96 | var stack = new haxe.ds.GenericStack(); 97 | for( b in waitingBodies ) { 98 | if( b.island != null || b.isStatic ) 99 | continue; 100 | var i = allocator.allocIsland(this); 101 | islands.add(i); 102 | stack.add(b); 103 | b.island = i; 104 | while( true ) { 105 | var b = stack.pop(); 106 | if( b == null ) break; 107 | i.bodies.add(b); 108 | for( a in b.arbiters ) { 109 | if( a.island != null ) continue; 110 | i.arbiters.add(a); 111 | a.island = i; 112 | var b1 = a.s1.body; 113 | if( b1.island == null && !b1.isStatic ) { 114 | b1.island = i; 115 | stack.add(b1); 116 | } 117 | var b2 = a.s2.body; 118 | if( b2.island == null && !b2.isStatic ) { 119 | b2.island = i; 120 | stack.add(b2); 121 | } 122 | } 123 | } 124 | } 125 | waitingBodies = new haxe.ds.GenericStack(); 126 | } 127 | 128 | public function step( dt : Float, iterations : Int ) { 129 | if( dt < Const.EPSILON ) dt = 0; 130 | timer.start("all"); 131 | 132 | // update properties 133 | var invDt = if( dt == 0 ) 0 else 1 / dt; 134 | for( p in properties ) { 135 | p.lfdt = Math.pow(p.linearFriction,dt); 136 | p.afdt = Math.pow(p.angularFriction,dt); 137 | } 138 | 139 | // build islands 140 | timer.start("island"); 141 | if( useIslands ) 142 | buildIslands(); 143 | else { 144 | var i = allocator.allocIsland(this); 145 | i.bodies = bodies; 146 | i.arbiters = arbiters; 147 | i.joints = joints; 148 | sleepEpsilon = 0; // disable sleeping 149 | islands = new haxe.ds.GenericStack(); 150 | islands.add(i); 151 | } 152 | if( debug ) checkDatas(); 153 | timer.stop(); 154 | 155 | 156 | // solve physics 157 | timer.start("solve"); 158 | for( i in islands ) 159 | if( !i.sleeping ) 160 | i.solve(dt,invDt,iterations); 161 | timer.stop(); 162 | 163 | // cleanup old living arbiters 164 | for( a in arbiters ) 165 | if( stamp - a.stamp > 3 ) { 166 | allocator.freeAllContacts(a.contacts); 167 | var b1 = a.s1.body; 168 | var b2 = a.s2.body; 169 | b1.arbiters.remove(a); 170 | b2.arbiters.remove(a); 171 | arbiters.remove(a); 172 | allocator.freeArbiter(a); 173 | destroyIsland(b1.island); 174 | destroyIsland(b2.island); 175 | } 176 | 177 | // collide 178 | timer.start("col"); 179 | broadphase.commit(); 180 | testedCollisions = 0; 181 | activeCollisions = 0; 182 | if( debug && !broadphase.validate() ) 183 | throw "INVALID BF DATAS"; 184 | broadphase.collide(); 185 | timer.stop(); 186 | 187 | // cleanup 188 | stamp++; 189 | if( boundsCheck > 0 && stamp % boundsCheck == 0 ) { 190 | var tmp = new haxe.ds.GenericStack(); 191 | for( b in bodies ) 192 | tmp.add(b); 193 | for( s in broadphase.pick(box) ) 194 | tmp.remove(s.body); 195 | for( b in tmp ) 196 | if( removeBody(b) ) 197 | b.onDestroy(); 198 | } 199 | timer.stop(); 200 | } 201 | 202 | function destroyIsland( i : Island ) { 203 | if( i == null || !useIslands ) 204 | return; 205 | if( !islands.remove(i) ) 206 | return; 207 | for( b in i.bodies ) { 208 | b.island = null; 209 | waitingBodies.add(b); 210 | } 211 | for( a in i.arbiters ) { 212 | a.sleeping = false; 213 | a.island = null; 214 | } 215 | for( j in i.joints ) 216 | j.island = null; 217 | allocator.freeIsland(i); 218 | } 219 | 220 | public function onCollide( s1 : Shape, s2 : Shape ) { 221 | var b1 = s1.body; 222 | var b2 = s2.body; 223 | 224 | testedCollisions++; 225 | 226 | if( b1 == b2 || (s1.groups & s2.groups) == 0 ) 227 | return false; 228 | 229 | // prepare for testShapes 230 | if( s1.type > s2.type ) { 231 | var tmp = s1; 232 | s1 = s2; 233 | s2 = tmp; 234 | } 235 | 236 | var pairFound = true; 237 | var a = null; 238 | for( arb in b1.arbiters ) 239 | if( (arb.s1 == s1 && arb.s2 == s2) || (arb.s1 == s2 && arb.s2 == s1) ) { 240 | a = arb; 241 | break; 242 | } 243 | if( a == null ) { 244 | a = allocator.allocArbiter(); 245 | a.assign(s1,s2); 246 | pairFound = false; 247 | } else if( a.sleeping ) { 248 | a.stamp = stamp; 249 | return true; 250 | } else if( a.stamp == stamp ) // this contact has already been processed 251 | return true; 252 | 253 | a.sleeping = false; 254 | activeCollisions++; 255 | 256 | var col = collision.testShapes(s1,s2,a); 257 | if( col ) { 258 | a.stamp = stamp; 259 | if( pairFound ) { 260 | // in case it's been flipped 261 | a.s1 = s1; 262 | a.s2 = s2; 263 | } else { 264 | arbiters.add(a); 265 | var i1 = b1.island; 266 | if( i1 != b2.island ) { 267 | destroyIsland(i1); 268 | destroyIsland(b2.island); 269 | } else if( i1 != null ) { 270 | i1.arbiters.add(a); 271 | a.island = i1; 272 | } 273 | s2.body.arbiters.add(a); 274 | s1.body.arbiters.add(a); 275 | } 276 | } else if( !pairFound ) 277 | allocator.freeArbiter(a); 278 | return col; 279 | } 280 | 281 | public function addStaticShape(s) { 282 | staticBody.addShape(s); 283 | s.update(); 284 | broadphase.addShape(s); 285 | return s; 286 | } 287 | 288 | public function removeStaticShape(s) { 289 | staticBody.removeShape(s); 290 | broadphase.removeShape(s); 291 | } 292 | 293 | public function addBody(b) { 294 | bodies.add(b); 295 | waitingBodies.add(b); 296 | b.properties.count++; 297 | b.motion = sleepEpsilon * Const.WAKEUP_FACTOR; 298 | properties.set(b.properties.id,b.properties); 299 | if( b.isStatic ) { 300 | b.mass = Math.POSITIVE_INFINITY; 301 | b.invMass = 0; 302 | b.inertia = Math.POSITIVE_INFINITY; 303 | b.invInertia = 0; 304 | for( s in b.shapes ) 305 | s.update(); 306 | } else 307 | b.updatePhysics(); 308 | for( s in b.shapes ) 309 | broadphase.addShape(s); 310 | } 311 | 312 | public function removeBody(b) { 313 | if( !bodies.remove(b) ) return false; 314 | b.properties.count--; 315 | if( b.properties.count == 0 ) 316 | properties.remove(b.properties.id); 317 | for( s in b.shapes ) 318 | broadphase.removeShape(s); 319 | destroyIsland(b.island); 320 | waitingBodies.remove(b); 321 | // remove arbiters for the other bodies 322 | for( a in b.arbiters ) { 323 | var b1 = a.s1.body; 324 | (if( b1 == b ) a.s2.body else b1).arbiters.remove(a); 325 | } 326 | return true; 327 | } 328 | 329 | public function activate( b : Body ) { 330 | var i = b.island; 331 | b.motion = sleepEpsilon * Const.WAKEUP_FACTOR; 332 | if( i != null && i.sleeping ) { 333 | i.sleeping = false; 334 | for( a in i.arbiters ) 335 | a.sleeping = false; 336 | } 337 | } 338 | 339 | public function addJoint(j) { 340 | joints.add(j); 341 | } 342 | 343 | public function removeJoint(j) { 344 | joints.remove(j); 345 | destroyIsland(j.b1.island); 346 | destroyIsland(j.b2.island); 347 | } 348 | 349 | public function sync( b : Body ) { 350 | for( s in b.shapes ) { 351 | s.update(); 352 | broadphase.syncShape(s); 353 | } 354 | } 355 | 356 | function checkBody( b : Body, i : Island ) { 357 | if( b.island != i ) 358 | throw "ASSERT"; 359 | for( a in b.arbiters ) { 360 | if( a.island != i ) 361 | throw "ASSERT"; 362 | if( a.s1.body.island != i && !a.s1.body.isStatic ) 363 | throw "ASSERT"; 364 | if( a.s2.body.island != i && !a.s2.body.isStatic ) 365 | throw "ASSERT"; 366 | } 367 | } 368 | 369 | function checkDatas() { 370 | for( b in waitingBodies ) 371 | checkBody(b,null); 372 | for( i in islands ) 373 | for( b in i.bodies ) 374 | checkBody(b,i); 375 | } 376 | 377 | } 378 | -------------------------------------------------------------------------------- /phx/col/AABB.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.col; 26 | 27 | class AABB { 28 | 29 | public var l:Float; 30 | public var b:Float; 31 | public var r:Float; 32 | public var t:Float; 33 | 34 | public var shape : phx.Shape; 35 | public var prev : AABB; 36 | public var next : AABB; 37 | public var bounds : IAABB; 38 | 39 | public function new(left,top,right,bottom) { 40 | this.l = left; 41 | this.t = top; 42 | this.r = right; 43 | this.b = bottom; 44 | } 45 | 46 | public inline function intersects( aabb : AABB ) { 47 | return !(aabb.l > r || aabb.r < l || aabb.t > b || aabb.b < t); 48 | } 49 | 50 | public inline function intersects2( aabb:AABB ) { 51 | return (l<=aabb.r && aabb.l<=r && t<=aabb.b && aabb.t<=b); 52 | } 53 | 54 | public inline function containsPoint( v : phx.Vector ) { 55 | return !(v.y < t || v.y > b || v.x < l || v.x > r); 56 | } 57 | 58 | public function toString() { 59 | return "[l=" + l + " b=" + b + " r=" + r + " t=" + t + "]"; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /phx/col/BroadPhase.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.col; 26 | 27 | interface BroadCallback { 28 | function onCollide( s1 : phx.Shape, s2 : phx.Shape ) : Bool; 29 | } 30 | 31 | interface BroadPhase { 32 | // initiliaze when added into world 33 | function init( bounds : AABB, cb : BroadCallback, staticBody : phx.Body ) : Void; 34 | // modify the shape list 35 | function addShape( s : phx.Shape ) : Void; 36 | function removeShape( s : phx.Shape ) : Void; 37 | // when modified : one sync per shape then one final commit 38 | function syncShape( s : phx.Shape ) : Void; 39 | function commit() : Void; 40 | // perform the collisions 41 | function collide() : Void; 42 | // pick the content of the box 43 | function pick( bounds : AABB ) : haxe.ds.GenericStack; 44 | // check the validity of inner datas (for debug) 45 | function validate() : Bool; 46 | } 47 | -------------------------------------------------------------------------------- /phx/col/BruteForce.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.col; 26 | import phx.col.BroadPhase; 27 | import phx.Shape; 28 | 29 | class BruteForce implements BroadPhase { 30 | 31 | var shapes : haxe.ds.GenericStack; 32 | var callb : BroadCallback; 33 | 34 | public function new() { 35 | } 36 | 37 | public function init( bounds, callb, staticBody ) { 38 | this.callb = callb; 39 | shapes = new haxe.ds.GenericStack(); 40 | } 41 | 42 | public function addShape( s : Shape ) { 43 | shapes.add(s); 44 | } 45 | 46 | public function removeShape( s : Shape ) { 47 | shapes.remove(s); 48 | } 49 | 50 | public function collide() { 51 | var s1 = shapes.head; 52 | while( s1 != null ) { 53 | var box1 = s1.elt.aabb; 54 | var s2 = s1.next; 55 | while( s2 != null ) { 56 | if( box1.intersects2(s2.elt.aabb) ) 57 | callb.onCollide(s1.elt,s2.elt); 58 | s2 = s2.next; 59 | } 60 | s1 = s1.next; 61 | } 62 | } 63 | 64 | public function pick( box : AABB ) { 65 | var shapes = new haxe.ds.GenericStack(); 66 | for( s in this.shapes ) 67 | if( s.aabb.intersects(box) ) 68 | shapes.add(s); 69 | return shapes; 70 | } 71 | 72 | public function syncShape( s : phx.Shape ) { 73 | // nothing 74 | } 75 | 76 | public function commit() { 77 | // nothing 78 | } 79 | 80 | public function validate() { 81 | return true; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /phx/col/IAABB.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.col; 26 | 27 | class IAABB { 28 | 29 | public var l:Int; 30 | public var b:Int; 31 | public var r:Int; 32 | public var t:Int; 33 | 34 | public function new(left,top,right,bottom) { 35 | this.l = left; 36 | this.t = top; 37 | this.r = right; 38 | this.b = bottom; 39 | } 40 | 41 | public function toString() { 42 | return "[l=" + l + " b=" + b + " r=" + r + " t=" + t + "]"; 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /phx/col/Quantize.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.col; 26 | import phx.col.BroadPhase; 27 | import haxe.ds.GenericStack; 28 | 29 | /** 30 | This broaphase is optimized for large worlds with a majority of static 31 | shapes and few moving shapes. It divides the space in squares of 2^nbits 32 | pixels. Shapes are stored into one several squares that they cover. 33 | Collisions are only tested between dynamic shapes and all other shapes into 34 | each square. World bounds should be positive. Shapes outside of the world 35 | might be in the wrong square (but that's ok) or in a special square. 36 | **/ 37 | class Quantize implements BroadPhase { 38 | 39 | var nbits : Int; 40 | var size : Int; 41 | 42 | var width : Int; 43 | var height : Int; 44 | var spanbits : Int; 45 | 46 | var all : GenericStack>; 47 | var world : Array>; 48 | var out : GenericStack; 49 | var cb : BroadCallback; 50 | var staticBody : phx.Body; 51 | 52 | public function new( nbits : Int ) { 53 | this.nbits = nbits; 54 | this.size = 1 << nbits; 55 | } 56 | 57 | inline function ADDR(x,y) { 58 | return (x << spanbits) | y; 59 | } 60 | 61 | public function init( bounds : AABB, cb : BroadCallback, staticBody ) { 62 | this.cb = cb; 63 | this.staticBody = staticBody; 64 | 65 | all = new GenericStack>(); 66 | world = new Array(); 67 | out = new GenericStack(); 68 | all.add(out); 69 | 70 | width = Std.int(bounds.r + size - 0.1) >> nbits; 71 | height = Std.int(bounds.b + size - 0.1) >> nbits; 72 | 73 | var tmp = width - 1; 74 | var spanbits = 0; 75 | while( tmp > 0 ) { 76 | spanbits++; 77 | tmp >>= 1; 78 | } 79 | } 80 | 81 | function add( l : GenericStack, box : AABB ) { 82 | if( box.shape.body != staticBody ) { 83 | l.add(box); 84 | return; 85 | } 86 | var b = l.head; 87 | var prev = null; 88 | while( b != null ) { 89 | if( b.elt.shape.body == staticBody ) 90 | break; 91 | prev = b; 92 | b = b.next; 93 | } 94 | if( prev == null ) 95 | l.head = new GenericCell(box,b); 96 | else 97 | prev.next = new GenericCell(box,b); 98 | } 99 | 100 | public function addShape( s : phx.Shape ) { 101 | var box = s.aabb; 102 | var nbits = this.nbits; 103 | var x1 = Std.int(box.l) >> nbits; 104 | var y1 = Std.int(box.t) >> nbits; 105 | var x2 = (Std.int(box.r) >> nbits) + 1; 106 | var y2 = (Std.int(box.b) >> nbits) + 1; 107 | box.shape = s; 108 | box.bounds = new phx.col.IAABB(x1,y1,x2,y2); 109 | var isout = false; 110 | for( x in x1...x2 ) { 111 | for( y in y1...y2 ) { 112 | var l = world[ADDR(x,y)]; 113 | if( l == null ) { 114 | if( x >= 0 && x < width && y >= 0 && y < height ) { 115 | l = new GenericStack(); 116 | all.add(l); 117 | world[ADDR(x,y)] = l; 118 | } else { 119 | if( isout ) continue; 120 | isout = true; 121 | l = out; 122 | } 123 | } 124 | add(l,box); 125 | } 126 | } 127 | } 128 | 129 | public function removeShape( s : phx.Shape ) { 130 | var box = s.aabb; 131 | var ib = box.bounds; 132 | for( x in ib.l...ib.r ) { 133 | for( y in ib.t...ib.b ) { 134 | var l = world[ADDR(x,y)]; 135 | if( l == null ) l = out; 136 | l.remove(box); 137 | } 138 | } 139 | } 140 | 141 | public function syncShape( s : phx.Shape ) { 142 | var box = s.aabb; 143 | var nbits = this.nbits; 144 | var x1 = Std.int(box.l) >> nbits; 145 | var y1 = Std.int(box.t) >> nbits; 146 | var x2 = (Std.int(box.r) >> nbits) + 1; 147 | var y2 = (Std.int(box.b) >> nbits) + 1; 148 | var ib = box.bounds; 149 | if( x1 == ib.l && y1 == ib.t && x2 == ib.r && y2 == ib.b ) 150 | return; 151 | removeShape(s); 152 | ib.l = x1; 153 | ib.t = y1; 154 | ib.r = x2; 155 | ib.b = y2; 156 | var isout = false; 157 | for( x in x1...x2 ) { 158 | for( y in y1...y2 ) { 159 | var l = world[ADDR(x,y)]; 160 | if( l == null ) { 161 | if( x >= 0 && x < width && y >= 0 && y < height ) { 162 | l = new GenericStack(); 163 | all.add(l); 164 | world[ADDR(x,y)] = l; 165 | } else { 166 | if( isout ) continue; 167 | isout = true; 168 | l = out; 169 | } 170 | } 171 | add(l,box); 172 | } 173 | } 174 | } 175 | 176 | public function commit() { 177 | // NOTHING 178 | } 179 | 180 | public function collide() { 181 | for( list in all ) { 182 | var box1 = list.head; 183 | while( box1 != null ) { 184 | var b = box1.elt; 185 | if( b.shape.body == staticBody ) 186 | break; 187 | var box2 = list.head; 188 | while( box2 != null ) { 189 | if( b.intersects2(box2.elt) && box1 != box2 ) 190 | cb.onCollide(b.shape,box2.elt.shape); 191 | box2 = box2.next; 192 | } 193 | box1 = box1.next; 194 | } 195 | } 196 | } 197 | 198 | public function pick( box : AABB ) { 199 | var nbits = this.nbits; 200 | var x1 = Std.int(box.l) >> nbits; 201 | var y1 = Std.int(box.t) >> nbits; 202 | var x2 = (Std.int(box.r) >> nbits) + 1; 203 | var y2 = (Std.int(box.b) >> nbits) + 1; 204 | var isout = false; 205 | var shapes = new GenericStack(); 206 | for( x in x1...x2 ) 207 | for( y in y1...y2 ) { 208 | var l = world[ADDR(x,y)]; 209 | if( l == null ) { 210 | if( x >= 0 && x < width && y >= 0 && y < height ) 211 | continue; 212 | if( isout ) 213 | continue; 214 | isout = true; 215 | l = out; 216 | } 217 | for( b in l ) 218 | if( b.intersects(box) ) 219 | shapes.add(b.shape); 220 | } 221 | return shapes; 222 | } 223 | 224 | public function validate() { 225 | // check internal data structures 226 | return true; 227 | } 228 | 229 | } -------------------------------------------------------------------------------- /phx/col/SortedList.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.col; 26 | import phx.col.BroadPhase; 27 | import phx.Shape; 28 | 29 | class SortedList implements BroadPhase { 30 | 31 | var boxes : AABB; 32 | var callb : BroadCallback; 33 | 34 | public function new() { 35 | } 36 | 37 | public function init( bounds, callb, staticBody ) { 38 | this.callb = callb; 39 | boxes = null; 40 | } 41 | 42 | function addSort( b : AABB ) { 43 | var cur = boxes; 44 | var prev = null; 45 | while( cur != null && cur.t < b.t ) { 46 | prev = cur; 47 | cur = cur.next; 48 | } 49 | b.prev = prev; 50 | b.next = cur; 51 | if( prev == null ) 52 | boxes = b; 53 | else 54 | prev.next = b; 55 | if( cur != null ) 56 | cur.prev = b; 57 | } 58 | 59 | public function addShape( s : Shape ) { 60 | var b = s.aabb; 61 | b.shape = s; 62 | addSort(b); 63 | } 64 | 65 | public function removeShape( s : Shape ) { 66 | var b = s.aabb; 67 | var next = b.next; 68 | var prev = b.prev; 69 | if( prev == null ) 70 | boxes = next; 71 | else 72 | prev.next = next; 73 | if( next != null ) 74 | next.prev = prev; 75 | } 76 | 77 | public function collide() { 78 | var b1 = boxes; 79 | while( b1 != null ) { 80 | var b2 = b1.next; 81 | var bottom = b1.b; 82 | while( b2 != null ) { 83 | if( b2.t > bottom ) break; 84 | if( b1.intersects2(b2) ) 85 | callb.onCollide(b1.shape,b2.shape); 86 | b2 = b2.next; 87 | } 88 | b1 = b1.next; 89 | } 90 | } 91 | 92 | public function pick( box : AABB ) { 93 | var shapes = new haxe.ds.GenericStack(); 94 | var b = boxes; 95 | // skip top boxes 96 | while( b != null ) { 97 | if( b.t <= box.b ) 98 | break; 99 | b = b.next; 100 | } 101 | while( b != null ) { 102 | if( b.intersects(box) ) 103 | shapes.add(b.shape); 104 | b = b.next; 105 | } 106 | return shapes; 107 | } 108 | 109 | public function syncShape( s : Shape ) { 110 | var b = s.aabb; 111 | var prev = b.prev; 112 | var next = b.next; 113 | if( prev != null && prev.t > b.t ) { 114 | prev.next = next; 115 | if( next != null ) 116 | next.prev = prev; 117 | addSort(b); 118 | } else if( next != null && next.t < b.t ) { 119 | if( prev == null ) 120 | boxes = next; 121 | else 122 | prev.next = next; 123 | next.prev = prev; 124 | addSort(b); 125 | } 126 | } 127 | 128 | public function commit() { 129 | // nothing, syncShape already sorted the list 130 | } 131 | 132 | public function validate() { 133 | var cur = boxes; 134 | while( cur != null ) { 135 | var next = cur.next; 136 | if( next != null && next.t < cur.t ) 137 | return false; 138 | cur = next; 139 | } 140 | return true; 141 | } 142 | 143 | 144 | } -------------------------------------------------------------------------------- /phx/demo/BasicStack.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.demo; 26 | 27 | class BasicStack extends Demo { 28 | 29 | public override function init() { 30 | world.gravity.set(0,0.1875); 31 | createFloor(); 32 | var box = phx.Shape.makeBox( 30, 30, new phx.Material(0.0, .8, 1) ); 33 | var startY = floor - 15; 34 | for( y in 0...18 ) { 35 | var offset = (y % 2) != 0 ? 15:0; 36 | for( x in 0...10 ) 37 | createPoly( offset + 150 + (x * 30), startY - (y * 30), 0, box ); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /phx/demo/BoxPyramidDemo.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.demo; 26 | 27 | class BoxPyramidDemo extends Demo { 28 | 29 | public override function init() { 30 | createFloor(); 31 | world.gravity.set(0,0.09375); 32 | 33 | var box = phx.Shape.makeBox( 30, 30, new phx.Material(0.01,1,.8) ); 34 | var cirBody = new phx.Body( 300, floor-30 ); 35 | var circ = new phx.Circle( 14, new phx.Vector(0,0), new phx.Material(0.0,0.9,1) ); 36 | cirBody.addShape(circ); 37 | world.addBody(cirBody); 38 | 39 | for( y in 0...14 ) 40 | for( x in 0...y ) 41 | createPoly( 300 + (x * 32) - (y*16), 70 + y*32, 0, box ); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /phx/demo/Demo.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.demo; 26 | 27 | class Demo { 28 | 29 | var world : phx.World; 30 | var floor : Float; 31 | var size : phx.Vector; 32 | public var steps : Int; 33 | 34 | public function new() { 35 | size = new phx.Vector(600,600); 36 | floor = 580; 37 | steps = 3; 38 | } 39 | 40 | public function start( world ) { 41 | this.world = world; 42 | init(); 43 | } 44 | 45 | public function init() { 46 | } 47 | 48 | public function step( dt :Float) { 49 | } 50 | 51 | public function addRectangle(x,y,w,h,?mat) { 52 | return addBody(x,y,phx.Shape.makeBox(w,h,null,null,mat)); 53 | } 54 | 55 | public function addBody( x, y, shape, ?props ) { 56 | var b = new phx.Body(x,y); 57 | b.addShape(shape); 58 | if( props != null ) b.properties = props; 59 | world.addBody(b); 60 | return b; 61 | } 62 | 63 | public function createWord( str : String, xp, yp, size, spacing, ?mat ) : Void { 64 | for( i in 0...str.length ) { 65 | var letter = str.charCodeAt(i); 66 | if( letter == 32 ) { 67 | xp += size; 68 | continue; 69 | } 70 | var datas = FontArray.lowerCase[letter - 97]; 71 | if( datas == null ) 72 | continue; 73 | var xmax = 0; 74 | for( y in 0...FontArray.HEIGHT ) { 75 | for( x in 0...FontArray.WIDTH ) { 76 | if( datas[ x + y * FontArray.WIDTH] == 1 ) { 77 | if( x > xmax ) xmax = x; 78 | addRectangle( xp + x * (size + spacing), yp + y * (size + spacing), size, size, mat ); 79 | } 80 | } 81 | } 82 | xp += (xmax + 1) * (size + spacing) + size; 83 | } 84 | } 85 | 86 | public function createConvexPoly( nverts : Int, radius : Float, rotation : Float, ?mat ) { 87 | var vl = new Array(); 88 | for( i in 0...nverts ) { 89 | var angle = ( -2 * Math.PI * i ) / nverts; 90 | angle += rotation; 91 | vl.push( new phx.Vector(radius * Math.cos(angle), radius * Math.sin(angle)) ); 92 | } 93 | return new phx.Polygon(vl,new phx.Vector(0,0),mat); 94 | } 95 | 96 | public function createPoly( x, y, a, shape : phx.Polygon, ?props ) { 97 | var b = new phx.Body(x,y); 98 | var vl = new Array(); 99 | var v = shape.verts; 100 | while( v != null ) { 101 | vl.push(v); 102 | v = v.next; 103 | } 104 | b.addShape( new phx.Polygon(vl,new phx.Vector(0,0),shape.material) ); 105 | b.setAngle(a); 106 | if( props != null ) 107 | b.properties = props; 108 | world.addBody(b); 109 | return b; 110 | } 111 | 112 | public function createFloor( ?mat ) { 113 | var s = phx.Shape.makeBox(600,40,0,floor,mat); 114 | world.addStaticShape(s); 115 | } 116 | 117 | public function rand( min : Float, max : Float ) { 118 | return Math.round(Math.random() * (max - min + 1)) + min; 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /phx/demo/DominoPyramid.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.demo; 26 | 27 | class DominoPyramid extends Demo { 28 | 29 | public override function init() { 30 | world.gravity.set(0,0.3125); 31 | createFloor(); 32 | 33 | var d_width = 5; 34 | var d_heigth = 20; 35 | var stackHeigth = 9; 36 | var xstart = 60.0; 37 | var yp = floor; 38 | var d90 = Math.PI / 2; 39 | var domino = phx.Shape.makeBox(d_width*2, d_heigth*2, new phx.Material(0.0, 0.6, 0.5)); 40 | 41 | for( i in 0...stackHeigth ) { 42 | var dw = ((i == 0)?2 * d_width:0); 43 | for( j in 0...stackHeigth - i ) { 44 | var xp = xstart + (3*d_heigth*j); 45 | if( i == 0 ) { 46 | createPoly( xp , yp - d_heigth, 0, domino ); 47 | createPoly( xp , yp - (2 * d_heigth) - d_width, d90, domino ); 48 | } else { 49 | createPoly( xp , yp - d_width, d90, domino ); 50 | createPoly( xp , yp - (2 * d_width) - d_heigth, 0, domino ); 51 | createPoly( xp , yp - (3 * d_width) - (2 * d_heigth), d90, domino ); 52 | } 53 | if( j == 0 ) 54 | createPoly( xp - d_heigth + d_width , yp - (3 * d_heigth) - (4 * d_width) + dw, 0, domino ); 55 | if( j == stackHeigth - i - 1 ) 56 | createPoly( xp + d_heigth - d_width , yp - (3 * d_heigth) - (4 * d_width) + dw, 0, domino ); 57 | } 58 | yp -= (2*d_heigth)+(4*d_width) - dw; 59 | xstart += 1.5 * d_heigth; 60 | } 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /phx/demo/FontArray.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.demo; 26 | 27 | class FontArray { 28 | public inline static var WIDTH = 5; 29 | public inline static var HEIGHT = 10; 30 | 31 | public static var num_0 = [ 32 | 0,0,0,0,0, 33 | 1,1,1,1,0, 34 | 1,0,0,1,0, 35 | 1,0,0,1,0, 36 | 1,0,0,1,0, 37 | 1,0,0,1,0, 38 | 1,0,0,1,0, 39 | 1,1,1,1,0, 40 | 0,0,0,0,0, 41 | 0,0,0,0,0 42 | ]; 43 | 44 | public static var num_1 = [ 45 | 0,0,0,0,0, 46 | 1,1,0,0,0, 47 | 0,1,0,0,0, 48 | 0,1,0,0,0, 49 | 0,1,0,0,0, 50 | 0,1,0,0,0, 51 | 0,1,0,0,0, 52 | 0,1,0,0,0, 53 | 0,0,0,0,0, 54 | 0,0,0,0,0 55 | ]; 56 | 57 | public static var num_2 = [ 58 | 0,0,0,0,0, 59 | 1,1,1,1,0, 60 | 0,0,0,1,0, 61 | 0,0,0,1,0, 62 | 1,1,1,1,0, 63 | 1,0,0,0,0, 64 | 1,0,0,0,0, 65 | 1,1,1,1,0, 66 | 0,0,0,0,0, 67 | 0,0,0,0,0 68 | ]; 69 | 70 | public static var num_3 = [ 71 | 0,0,0,0,0, 72 | 1,1,1,1,0, 73 | 0,0,0,1,0, 74 | 0,0,0,1,0, 75 | 0,1,1,1,0, 76 | 0,0,0,1,0, 77 | 0,0,0,1,0, 78 | 1,1,1,1,0, 79 | 0,0,0,0,0, 80 | 0,0,0,0,0 81 | ]; 82 | 83 | public static var num_4 = [ 84 | 0,0,0,0,0, 85 | 1,0,0,1,0, 86 | 1,0,0,1,0, 87 | 1,0,0,1,0, 88 | 1,0,0,1,0, 89 | 1,1,1,1,0, 90 | 0,0,0,1,0, 91 | 0,0,0,1,0, 92 | 0,0,0,0,0, 93 | 0,0,0,0,0 94 | ]; 95 | 96 | public static var num_5 = [ 97 | 0,0,0,0,0, 98 | 1,1,1,1,0, 99 | 1,0,0,0,0, 100 | 1,0,0,0,0, 101 | 1,1,1,1,0, 102 | 0,0,0,1,0, 103 | 0,0,0,1,0, 104 | 1,1,1,1,0, 105 | 0,0,0,0,0, 106 | 0,0,0,0,0 107 | ]; 108 | 109 | public static var num_6 = [ 110 | 0,0,0,0,0, 111 | 1,1,1,1,0, 112 | 1,0,0,0,0, 113 | 1,1,1,1,0, 114 | 1,0,0,1,0, 115 | 1,0,0,1,0, 116 | 1,0,0,1,0, 117 | 1,1,1,1,0, 118 | 0,0,0,0,0, 119 | 0,0,0,0,0 120 | ]; 121 | 122 | public static var num_7 = [ 123 | 0,0,0,0,0, 124 | 1,1,1,1,0, 125 | 0,0,0,1,0, 126 | 0,0,1,0,0, 127 | 0,0,1,0,0, 128 | 0,1,0,0,0, 129 | 0,1,0,0,0, 130 | 0,1,0,0,0, 131 | 0,0,0,0,0, 132 | 0,0,0,0,0 133 | ]; 134 | 135 | public static var num_8 = [ 136 | 0,0,0,0,0, 137 | 1,1,1,1,0, 138 | 1,0,0,1,0, 139 | 1,0,0,1,0, 140 | 1,1,1,1,0, 141 | 1,0,0,1,0, 142 | 1,0,0,1,0, 143 | 1,1,1,1,0, 144 | 0,0,0,0,0, 145 | 0,0,0,0,0 146 | ]; 147 | 148 | public static var num_9 = [ 149 | 0,0,0,0,0, 150 | 1,1,1,1,0, 151 | 1,0,0,1,0, 152 | 1,0,0,1,0, 153 | 1,0,0,1,0, 154 | 1,1,1,1,0, 155 | 0,0,0,1,0, 156 | 1,1,1,1,0, 157 | 0,0,0,0,0, 158 | 0,0,0,0,0 159 | ]; 160 | 161 | public static var a_lower = [ 162 | 0,0,0,0,0, 163 | 0,0,0,0,0, 164 | 0,0,0,0,0, 165 | 1,1,1,1,0, 166 | 0,0,0,1,0, 167 | 1,1,1,1,0, 168 | 1,0,0,1,0, 169 | 1,1,1,1,0, 170 | 0,0,0,0,0, 171 | 0,0,0,0,0 172 | ]; 173 | 174 | public static var b_lower = [ 175 | 1,0,0,0,0, 176 | 1,0,0,0,0, 177 | 1,0,0,0,0, 178 | 1,1,1,1,0, 179 | 1,0,0,1,0, 180 | 1,0,0,1,0, 181 | 1,0,0,1,0, 182 | 1,1,1,1,0, 183 | 0,0,0,0,0, 184 | 0,0,0,0,0 185 | ]; 186 | 187 | public static var c_lower = [ 188 | 0,0,0,0,0, 189 | 0,0,0,0,0, 190 | 0,0,0,0,0, 191 | 1,1,1,1,0, 192 | 1,0,0,0,0, 193 | 1,0,0,0,0, 194 | 1,0,0,0,0, 195 | 1,1,1,1,0, 196 | 0,0,0,0,0, 197 | 0,0,0,0,0 198 | ]; 199 | 200 | public static var d_lower = [ 201 | 0,0,0,1,0, 202 | 0,0,0,1,0, 203 | 0,0,0,1,0, 204 | 1,1,1,1,0, 205 | 1,0,0,1,0, 206 | 1,0,0,1,0, 207 | 1,0,0,1,0, 208 | 1,1,1,1,0, 209 | 0,0,0,0,0, 210 | 0,0,0,0,0 211 | ]; 212 | 213 | public static var e_lower = [ 214 | 0,0,0,0,0, 215 | 0,0,0,0,0, 216 | 0,0,0,0,0, 217 | 1,1,1,1,0, 218 | 1,0,0,1,0, 219 | 1,1,1,1,0, 220 | 1,0,0,0,0, 221 | 1,1,1,1,0, 222 | 0,0,0,0,0, 223 | 0,0,0,0,0 224 | ]; 225 | 226 | public static var f_lower = [ 227 | 1,1,1,1,0, 228 | 1,0,0,0,0, 229 | 1,0,0,0,0, 230 | 1,1,1,0,0, 231 | 1,0,0,0,0, 232 | 1,0,0,0,0, 233 | 1,0,0,0,0, 234 | 1,0,0,0,0, 235 | 0,0,0,0,0, 236 | 0,0,0,0,0 237 | ]; 238 | 239 | public static var g_lower = [ 240 | 0,0,0,0,0, 241 | 0,0,0,0,0, 242 | 0,0,0,0,0, 243 | 1,1,1,1,0, 244 | 1,0,0,1,0, 245 | 1,0,0,1,0, 246 | 1,0,0,1,0, 247 | 1,1,1,1,0, 248 | 0,0,0,1,0, 249 | 1,1,1,1,0 250 | ]; 251 | 252 | public static var h_lower = [ 253 | 1,0,0,0,0, 254 | 1,0,0,0,0, 255 | 1,0,0,0,0, 256 | 1,1,1,1,0, 257 | 1,0,0,1,0, 258 | 1,0,0,1,0, 259 | 1,0,0,1,0, 260 | 1,0,0,1,0, 261 | 0,0,0,0,0, 262 | 0,0,0,0,0 263 | ]; 264 | 265 | public static var i_lower = [ 266 | 0,0,0,0,0, 267 | 1,0,0,0,0, 268 | 0,0,0,0,0, 269 | 1,0,0,0,0, 270 | 1,0,0,0,0, 271 | 1,0,0,0,0, 272 | 1,0,0,0,0, 273 | 1,0,0,0,0, 274 | 0,0,0,0,0, 275 | 0,0,0,0,0 276 | ]; 277 | 278 | public static var j_lower = [ 279 | 0,0,0,0,0, 280 | 1,1,0,0,0, 281 | 0,0,0,0,0, 282 | 0,1,0,0,0, 283 | 0,1,0,0,0, 284 | 0,1,0,0,0, 285 | 0,1,0,0,0, 286 | 0,1,0,0,0, 287 | 1,1,0,0,0, 288 | 0,0,0,0,0 289 | ]; 290 | 291 | public static var k_lower = [ 292 | 0,0,0,0,0, 293 | 1,0,0,0,0, 294 | 1,0,0,0,0, 295 | 1,0,0,1,0, 296 | 1,0,1,0,0, 297 | 1,1,0,0,0, 298 | 1,0,1,0,0, 299 | 1,0,0,1,0, 300 | 0,0,0,0,0, 301 | 0,0,0,0,0 302 | ]; 303 | 304 | public static var l_lower = [ 305 | 0,0,0,0,0, 306 | 1,0,0,0,0, 307 | 1,0,0,0,0, 308 | 1,0,0,0,0, 309 | 1,0,0,0,0, 310 | 1,0,0,0,0, 311 | 1,0,0,0,0, 312 | 1,1,0,0,0, 313 | 0,0,0,0,0, 314 | 0,0,0,0,0 315 | ]; 316 | 317 | public static var m_lower = [ 318 | 0,0,0,0,0, 319 | 0,0,0,0,0, 320 | 0,0,0,0,0, 321 | 1,1,1,1,1, 322 | 1,0,1,0,1, 323 | 1,0,1,0,1, 324 | 1,0,1,0,1, 325 | 1,0,1,0,1, 326 | 0,0,0,0,0, 327 | 0,0,0,0,0 328 | ]; 329 | 330 | public static var n_lower = [ 331 | 0,0,0,0,0, 332 | 0,0,0,0,0, 333 | 0,0,0,0,0, 334 | 1,1,1,1,0, 335 | 1,0,0,1,0, 336 | 1,0,0,1,0, 337 | 1,0,0,1,0, 338 | 1,0,0,1,0, 339 | 0,0,0,0,0, 340 | 0,0,0,0,0 341 | ]; 342 | 343 | public static var o_lower = [ 344 | 0,0,0,0,0, 345 | 0,0,0,0,0, 346 | 0,0,0,0,0, 347 | 1,1,1,1,0, 348 | 1,0,0,1,0, 349 | 1,0,0,1,0, 350 | 1,0,0,1,0, 351 | 1,1,1,1,0, 352 | 0,0,0,0,0, 353 | 0,0,0,0,0 354 | ]; 355 | 356 | public static var p_lower = [ 357 | 0,0,0,0,0, 358 | 0,0,0,0,0, 359 | 0,0,0,0,0, 360 | 1,1,1,1,0, 361 | 1,0,0,1,0, 362 | 1,0,0,1,0, 363 | 1,0,0,1,0, 364 | 1,1,1,1,0, 365 | 1,0,0,0,0, 366 | 1,0,0,0,0 367 | ]; 368 | 369 | public static var q_lower = [ 370 | 0,0,0,0,0, 371 | 0,0,0,0,0, 372 | 0,0,0,0,0, 373 | 1,1,1,1,0, 374 | 1,0,0,1,0, 375 | 1,0,0,1,0, 376 | 1,0,0,1,0, 377 | 1,1,1,1,0, 378 | 0,0,0,1,0, 379 | 0,0,0,1,0 380 | ]; 381 | 382 | public static var r_lower = [ 383 | 0,0,0,0,0, 384 | 0,0,0,0,0, 385 | 0,0,0,0,0, 386 | 1,1,1,1,0, 387 | 1,0,0,1,0, 388 | 1,0,0,0,0, 389 | 1,0,0,0,0, 390 | 1,0,0,0,0, 391 | 0,0,0,0,0, 392 | 0,0,0,0,0 393 | ]; 394 | 395 | public static var s_lower = [ 396 | 0,0,0,0,0, 397 | 0,0,0,0,0, 398 | 0,0,0,0,0, 399 | 1,1,1,1,0, 400 | 1,0,0,0,0, 401 | 1,1,1,1,0, 402 | 0,0,0,1,0, 403 | 1,1,1,1,0, 404 | 0,0,0,0,0, 405 | 0,0,0,0,0 406 | ]; 407 | 408 | public static var t_lower = [ 409 | 0,0,0,0,0, 410 | 0,0,0,0,0, 411 | 1,0,0,0,0, 412 | 1,1,0,0,0, 413 | 1,0,0,0,0, 414 | 1,0,0,0,0, 415 | 1,0,0,0,0, 416 | 1,1,1,0,0, 417 | 0,0,0,0,0, 418 | 0,0,0,0,0 419 | ]; 420 | 421 | public static var u_lower = [ 422 | 0,0,0,0,0, 423 | 0,0,0,0,0, 424 | 1,0,0,0,0, 425 | 1,0,0,1,0, 426 | 1,0,0,1,0, 427 | 1,0,0,1,0, 428 | 0,0,0,1,0, 429 | 1,1,1,1,0, 430 | 0,0,0,0,0, 431 | 0,0,0,0,0 432 | ]; 433 | 434 | public static var v_lower = [ 435 | 0,0,0,0,0, 436 | 0,0,0,0,0, 437 | 0,0,0,0,0, 438 | 1,0,0,0,1, 439 | 1,0,0,0,1, 440 | 0,1,0,1,0, 441 | 0,1,0,1,0, 442 | 0,0,1,0,0, 443 | 0,0,0,0,0, 444 | 0,0,0,0,0 445 | ]; 446 | 447 | public static var w_lower = [ 448 | 0,0,0,0,0, 449 | 0,0,0,0,0, 450 | 0,0,0,0,0, 451 | 1,0,1,0,1, 452 | 1,0,1,0,1, 453 | 1,0,1,0,1, 454 | 1,0,0,0,1, 455 | 1,1,1,1,1, 456 | 0,0,0,0,0, 457 | 0,0,0,0,0 458 | ]; 459 | 460 | public static var x_lower = [ 461 | 0,0,0,0,0, 462 | 0,0,0,0,0, 463 | 0,0,0,0,0, 464 | 1,0,0,1,0, 465 | 1,0,0,1,0, 466 | 0,1,1,0,0, 467 | 1,0,0,1,0, 468 | 1,0,0,1,0, 469 | 0,0,0,0,0, 470 | 0,0,0,0,0 471 | ]; 472 | 473 | public static var y_lower = [ 474 | 0,0,0,0,0, 475 | 0,0,0,0,0, 476 | 0,0,0,0,0, 477 | 1,0,0,1,0, 478 | 1,0,0,1,0, 479 | 1,0,0,1,0, 480 | 1,0,0,1,0, 481 | 1,1,1,1,0, 482 | 0,0,0,1,0, 483 | 1,1,1,1,0 484 | ]; 485 | 486 | public static var z_lower = [ 487 | 0,0,0,0,0, 488 | 0,0,0,0,0, 489 | 0,0,0,0,0, 490 | 1,1,1,1,0, 491 | 0,0,1,0,0, 492 | 0,1,0,0,0, 493 | 1,0,0,0,0, 494 | 1,1,1,1,0, 495 | 0,0,0,0,0, 496 | 0,0,0,0,0 497 | ]; 498 | 499 | public static var lowerCase = [a_lower, b_lower, c_lower, d_lower, e_lower, 500 | f_lower, g_lower, h_lower, i_lower, j_lower, 501 | k_lower, l_lower, m_lower, n_lower, o_lower, p_lower, 502 | q_lower, r_lower, s_lower, t_lower, u_lower, 503 | v_lower, w_lower, x_lower, y_lower, z_lower]; 504 | 505 | 506 | } 507 | -------------------------------------------------------------------------------- /phx/demo/Jumble.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.demo; 26 | 27 | class Jumble extends Demo { 28 | 29 | var addDelay : Int; 30 | var lastAdd : Int; 31 | var material : phx.Material; 32 | 33 | public function new() { 34 | super(); 35 | addDelay = 30; 36 | lastAdd = 50; 37 | material = new phx.Material(0.1, 0.5, 1); 38 | } 39 | 40 | public override function init() { 41 | world.gravity.set(0,0.3125); 42 | createFloor(); 43 | } 44 | 45 | public override function step( dt : Float) { 46 | lastAdd += 1; 47 | if( lastAdd < addDelay ) return; 48 | lastAdd = 0; 49 | 50 | var body = new phx.Body(0,0); 51 | body.addShape(phx.Shape.makeBox(60,10,material)); 52 | body.addShape(phx.Shape.makeBox(10,60,material)); 53 | body.addShape(new phx.Circle(12,new phx.Vector(-30,0),material)); 54 | body.addShape(new phx.Circle(12,new phx.Vector(30,0),material)); 55 | body.addShape(new phx.Circle(12,new phx.Vector(0,-30),material)); 56 | body.addShape(new phx.Circle(12,new phx.Vector(0,30),material)); 57 | body.setPos( 300 + rand(-250,250), rand(-200,-20), rand(0,2*Math.PI) ); 58 | body.w = rand( -2, 2 ) / 40; 59 | world.addBody(body); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /phx/demo/Main.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.demo; 26 | 27 | #if js 28 | import js.Browser.document; 29 | import js.Browser.window; 30 | #end 31 | 32 | class Main { 33 | 34 | public var debug : Bool; 35 | public var stopped : Bool; 36 | public var recalStep : Bool; 37 | 38 | #if js 39 | var root : js.html.CanvasElement; 40 | var tf : js.html.DivElement; 41 | #else 42 | var root : flash.display.MovieClip; 43 | var tf : flash.text.TextField; 44 | #end 45 | 46 | #if flash 47 | var defaultFrameRate : Float; 48 | #end 49 | 50 | var world : phx.World; 51 | var demo : phx.demo.Demo; 52 | var draw : Bool; 53 | var curbf : Int; 54 | var frame : Int; 55 | var broadphases : Array; 56 | 57 | public function new(root) { 58 | 59 | frame = 0; 60 | curbf = 0; 61 | draw = true; 62 | debug = false; 63 | stopped = false; 64 | this.root = root; 65 | 66 | #if js 67 | tf = document.createDivElement(); 68 | tf.id = "info"; 69 | document.body.appendChild(tf); 70 | #else 71 | tf = new flash.text.TextField(); 72 | tf.selectable = true; 73 | tf.x = 500; 74 | tf.width = 300; 75 | tf.height = 500; 76 | root.addChild(tf); 77 | root.stage.scaleMode = flash.display.StageScaleMode.NO_SCALE; 78 | #end 79 | 80 | #if flash 81 | defaultFrameRate = root.stage.frameRate; 82 | #end 83 | 84 | broadphases = new Array(); 85 | broadphases.push(new phx.col.SortedList()); 86 | broadphases.push(new phx.col.Quantize(6)); 87 | broadphases.push(new phx.col.BruteForce()); 88 | } 89 | 90 | function start() { 91 | var me = this; 92 | #if js 93 | document.onkeydown = function(e) me.onKeyDown(e.keyCode); 94 | document.onmousedown = function(e) me.fireBlock(e.clientX,e.clientY); 95 | loop(); 96 | #else 97 | root.stage.addEventListener(flash.events.Event.ENTER_FRAME,function(_) me.loop()); 98 | root.stage.addEventListener(flash.events.MouseEvent.MOUSE_DOWN,function(_) me.fireBlock(me.root.mouseX,me.root.mouseY)); 99 | root.stage.addEventListener(flash.events.KeyboardEvent.KEY_DOWN,function(e:flash.events.KeyboardEvent) me.onKeyDown(e.keyCode)); 100 | #end 101 | } 102 | 103 | function loop() { 104 | 105 | // step 106 | var steps = if( stopped ) 0 else demo.steps; 107 | var dt = 1; 108 | var niter = #if js 5 #else 20 #end; 109 | for( i in 0...steps ) { 110 | try { 111 | demo.step(dt/steps); 112 | world.step(dt/steps,niter); 113 | } catch( e : Dynamic ) { 114 | trace("STOPPED!"); 115 | stopped = true; 116 | throw e; 117 | } 118 | } 119 | if( recalStep ) world.step(0,1); 120 | 121 | // draw 122 | #if !js 123 | var g = root.graphics; 124 | #else 125 | var g = new phx.JsCanvas( root ); 126 | #end 127 | g.clear(); 128 | var fd = new phx.FlashDraw(g); 129 | if( debug ) { 130 | fd.boundingBox.line = 0x000000; 131 | fd.contact.line = 0xFF0000; 132 | fd.sleepingContact.line = 0xFF00FF; 133 | fd.drawCircleRotation = true; 134 | } 135 | if( draw ) 136 | fd.drawWorld(world); 137 | 138 | #if js 139 | tf.innerText = buildInfos().join("\n"); 140 | window.requestAnimationFrame( cast loop ); 141 | #else 142 | if( frame++ % Std.int(flash.Lib.current.stage.frameRate / 4) == 0 ) 143 | tf.text = buildInfos().join("\n"); 144 | #end 145 | } 146 | 147 | function onKeyDown( code : Int ) { 148 | switch( code ) { 149 | case 32:/*SPACE*/ 150 | debug = !debug; 151 | case 66: /*B*/ 152 | curbf = (curbf + 1) % broadphases.length; 153 | world.setBroadPhase(broadphases[curbf]); 154 | case 68: /*D*/ 155 | draw = !draw; 156 | #if flash 157 | case 83: /*S*/ 158 | root.stage.frameRate = (root.stage.frameRate == 1) ? defaultFrameRate : 1; 159 | #end 160 | case 49: /*1*/ setDemo(new phx.demo.DominoPyramid()); 161 | case 50:/*2*/ setDemo(new phx.demo.BasicStack()); 162 | case 51:/*3*/ setDemo(new phx.demo.PyramidThree()); 163 | case 52:/*4*/ setDemo(new phx.demo.BoxPyramidDemo()); 164 | case 53:/*5*/ setDemo(new phx.demo.PentagonRain()); 165 | case 54:/*6*/ setDemo(new phx.demo.Jumble()); 166 | case 55:/*7*/ setDemo(new phx.demo.SegmentDemo()); 167 | case 56:/*8*/ setDemo(new phx.demo.TitleDemo()); 168 | case 57:/*9*/ setDemo(new phx.demo.Test()); 169 | case 27:/*ESC*/ setDemo(demo); 170 | } 171 | } 172 | 173 | public function setDemo( demo : phx.demo.Demo ) { 174 | this.demo = demo; 175 | stopped = false; 176 | recalStep = false; 177 | world = new phx.World(new phx.col.AABB(-2000,-2000,2000,2000),broadphases[curbf]); 178 | demo.start(world); 179 | } 180 | 181 | public function buildInfos() { 182 | var t = world.timer; 183 | var tot = t.total; 184 | var log = [ 185 | "Stamp=" + world.stamp, 186 | "Demo=" + Type.getClassName(Type.getClass(demo)), 187 | "Bodies=" + Lambda.count(world.bodies), 188 | "Arbit=" + Lambda.filter(world.arbiters,function(a) return !a.sleeping).length + " / " + Lambda.count(world.arbiters), 189 | "BF=" + Type.getClassName(Type.getClass(world.broadphase)), 190 | "COLS=" + world.activeCollisions+ " / "+world.testedCollisions, 191 | t.format("all"), 192 | t.format("col"), 193 | t.format("island"), 194 | t.format("solve"), 195 | ]; 196 | #if flash9 197 | if( flash.system.Capabilities.isDebugger ) 198 | log.unshift("DEBUG"); 199 | #end 200 | var nislands = Lambda.count(world.islands); 201 | if( nislands > 5 ) 202 | log.push("Islands="+nislands); 203 | else 204 | for( i in world.islands ) { 205 | var str = "Island= #" + Lambda.count(i.bodies); 206 | str += if( i.sleeping ) " SLEEP" else " e=" + Math.ceil(i.energy*1000)/1000; 207 | var b = i.bodies.first(); 208 | str += " (" + Math.ceil(b.x) + "," + Math.ceil(b.y) + ")"; 209 | log.push(str); 210 | } 211 | return log; 212 | } 213 | 214 | public function fireBlock( mouseX : Float, mouseY : Float ) { 215 | #if !js 216 | var width = root.stage.stageWidth; 217 | var height = root.stage.stageHeight; 218 | #else 219 | var width : Int = untyped root.width; 220 | var height : Int = untyped root.height; 221 | #end 222 | 223 | var pos = new phx.Vector(width,height); 224 | pos.x += 100; 225 | pos.y /= 3; 226 | 227 | var v = new phx.Vector( mouseX - pos.x, mouseY - pos.y ); 228 | var k = 15 / v.length(); 229 | v.x *= k; 230 | v.y *= k; 231 | 232 | var b = new phx.Body(0,0); 233 | b.set(pos,0,v,2); 234 | b.addShape( phx.Shape.makeBox(20,20,new phx.Material(0.0, 1, 5)) ); 235 | world.addBody(b); 236 | } 237 | 238 | public static var inst : Main; 239 | 240 | static function main() { 241 | 242 | #if neko 243 | neash.Lib.Init("Physaxe",800,600,false,true); 244 | neash.Lib.SetBackgroundColour(0xffffff); 245 | var root = flash.Lib.current; 246 | 247 | #elseif js 248 | var root = document.createCanvasElement(); 249 | root.width = window.innerWidth; 250 | root.height = window.innerHeight; 251 | document.body.appendChild( root ); 252 | 253 | #else 254 | flash.Lib.current.stage.scaleMode = flash.display.StageScaleMode.NO_SCALE; 255 | var root = flash.Lib.current; 256 | #end 257 | 258 | inst = new Main(root); 259 | inst.setDemo(new phx.demo.TitleDemo()); 260 | inst.start(); 261 | 262 | #if neko 263 | neash.Lib.SetFrameRate(100); 264 | //neash.Lib.ShowFPS(true); 265 | neash.Lib.Run(); 266 | #end 267 | } 268 | 269 | } 270 | -------------------------------------------------------------------------------- /phx/demo/Makefile: -------------------------------------------------------------------------------- 1 | run: build 2 | debugfp Main.swf 3 | 4 | build: 5 | haxe -lib physaxe -swf-header 800:600:60:333333 -swf Main.swf -main phx.demo.Main -swf-version 10.1 --dead-code-elimination 6 | -------------------------------------------------------------------------------- /phx/demo/PentagonRain.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.demo; 26 | 27 | class PentagonRain extends Demo { 28 | 29 | var pentagons : Array; 30 | var numPentagons : Int; 31 | 32 | var refreshDelay : Float; 33 | var lastRefresh : Float; 34 | 35 | public function new() { 36 | super(); 37 | pentagons = new Array(); 38 | numPentagons = 500; 39 | refreshDelay = 1; 40 | lastRefresh = 0; 41 | } 42 | 43 | public override function init() { 44 | world.gravity.set(0,0.0625); 45 | steps = 1; 46 | 47 | var triangle = [ new phx.Vector(-15,15), new phx.Vector(15,15), new phx.Vector(0,-10) ]; 48 | var mat = new phx.Material(1, .1, 1); 49 | for( i in 0...8 ) { 50 | for( j in 0...7 ) { 51 | var stagger = (j%2)*40; 52 | var offset = new phx.Vector(i * 80 + stagger, 80 + j * 70 ); 53 | world.addStaticShape( new phx.Polygon(triangle, offset, mat) ); 54 | } 55 | } 56 | 57 | var mat = new phx.Material(0.2, 0, 1); 58 | for( i in 0...numPentagons ) { 59 | var p = addBody( 300 + rand(-300,300), rand(-50,-150), createConvexPoly(5, 10, 0, mat) ); 60 | pentagons.push(p); 61 | } 62 | } 63 | 64 | public override function step( dt : Float ) { 65 | lastRefresh += dt; 66 | if( lastRefresh < refreshDelay ) return; 67 | for( p in pentagons ) { 68 | if( (p.y > size.y + 20) || (p.x < -20) || (p.y > size.x + 20) ) { 69 | p.setPos( 300 + rand(-280,280), rand(-50,-100) ); 70 | p.setSpeed( rand(-10,10)/40, rand(10,100)/40 ); 71 | } 72 | } 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /phx/demo/PyramidThree.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.demo; 26 | 27 | class PyramidThree extends Demo { 28 | 29 | public override function init() { 30 | world.gravity.set(0,0.125); 31 | createFloor(); 32 | 33 | var width = 70; 34 | var height = 11; 35 | var slab = phx.Shape.makeBox(width,height,new phx.Material(0.0, 1, 1)); 36 | var p0 = phx.Const.DEFAULT_PROPERTIES; 37 | var props = new phx.Properties(p0.linearFriction,p0.angularFriction,0.001,phx.Const.FMAX,p0.maxDist); 38 | 39 | var startY = floor - (height / 2); 40 | var startX = size.y / 2; 41 | var segcount = 5; 42 | for( i in 0...5 ) { 43 | createPoly( startX - width, startY, 0, slab, props ); 44 | createPoly( startX + width, startY, 0, slab, props ); 45 | for( y in 0...segcount ) { 46 | for( x in 0...y+1 ) 47 | createPoly( startX - (x * width) + y * (width / 2), startY, 0, slab, props ); 48 | startY -= height; 49 | } 50 | var y = segcount; 51 | while( y > 0 ) { 52 | for( x in 0...y+1 ) 53 | createPoly( startX - (x * width) + y * (width / 2), startY, 0, slab, props ); 54 | startY -= height; 55 | y--; 56 | } 57 | } 58 | } 59 | 60 | } 61 | 62 | -------------------------------------------------------------------------------- /phx/demo/SegmentDemo.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.demo; 26 | 27 | class SegmentDemo extends Demo { 28 | 29 | var bodies : Array; 30 | var numBodies : Int; 31 | var refreshDelay : Int; 32 | var lastRefresh : Int; 33 | 34 | public function new() { 35 | super(); 36 | bodies = new Array(); 37 | numBodies = 200; 38 | refreshDelay = 9; 39 | lastRefresh = 50; 40 | } 41 | 42 | public override function init() { 43 | world.gravity.set(0, 0.3125); 44 | 45 | world.addStaticShape( new phx.Segment( new phx.Vector(0, 0), new phx.Vector(220, 200), 4)); 46 | world.addStaticShape( new phx.Segment( new phx.Vector(600, 0), new phx.Vector(380, 200), 4)); 47 | 48 | world.addStaticShape( new phx.Segment( new phx.Vector(200, 350), new phx.Vector(300, 300), 4)); 49 | world.addStaticShape( new phx.Segment( new phx.Vector(400, 350), new phx.Vector(300, 300), 4)); 50 | 51 | world.addStaticShape( new phx.Segment( new phx.Vector(100, 400), new phx.Vector(200, 500), 2)); 52 | world.addStaticShape( new phx.Segment( new phx.Vector(500, 400), new phx.Vector(400, 500), 2)); 53 | 54 | var material = new phx.Material(0.0, 0.2, 1); 55 | for( i in 0...numBodies ) { 56 | var s : phx.Shape; 57 | if( rand(0,2) > 0 ) 58 | s = createConvexPoly(Std.int(rand(3, 4)),rand(12, 20),0, material); 59 | else 60 | s = new phx.Circle(rand(8,20),new phx.Vector(0,0)); 61 | var b = addBody( 300 + rand(-200, 200), rand(-50,-150), s ); 62 | bodies.push(b); 63 | } 64 | } 65 | 66 | public override function step( dt : Float ) { 67 | lastRefresh += 1; 68 | if( lastRefresh < refreshDelay ) 69 | return; 70 | for( b in bodies ) { 71 | if( (b.y > size.y + 20) || (b.x < -20) || (b.y > size.x + 20) ) { 72 | b.setPos( 300 + rand(-200, 200), rand(-50,-100) ); 73 | b.setSpeed( rand(-10,10)/40, rand(10,100)/40 ); 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /phx/demo/Test.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.demo; 26 | 27 | class Test extends Demo { 28 | 29 | var body : phx.Body; 30 | var body2 : phx.Body; 31 | var dir : Int; 32 | var et : Float; 33 | 34 | public override function init() { 35 | #if flash9 36 | var stage = flash.Lib.current.stage; 37 | //stage.frameRate = 1; 38 | #end 39 | Main.inst.recalStep = true; 40 | Main.inst.debug = true; 41 | world.gravity = new phx.Vector(0,0.9); 42 | steps = 1; 43 | body = addBody( 300, 500, phx.Shape.makeBox(128,16) ); 44 | body.isStatic = true; 45 | world.removeBody(body); 46 | world.addBody(body); 47 | body2 = addBody( 250, 500 - 64, new phx.Circle(10,new phx.Vector(0,0)) ); 48 | body2.v.x = 0.5; 49 | //body2 = addBody( 250, 500 - 64, phx.Shape.makeBox(64,64) ); 50 | body2.preventRotation(); 51 | dir = 1; 52 | et = 0; 53 | } 54 | 55 | public override function step( dt : Float ) { 56 | et += dt; 57 | if( et > 100 ) { 58 | et -= 100; 59 | dir *= -1; 60 | } 61 | body.v.x = 1 * dir; 62 | body.v.y = -0.5 * dir; 63 | body.x += body.v.x * dt; 64 | body.y += body.v.y * dt; 65 | world.sync(body); 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /phx/demo/TitleDemo.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.demo; 26 | 27 | class TitleDemo extends Demo { 28 | 29 | public override function init() { 30 | createWord("physaxe", 60, 180, 20, 0); 31 | var material = new phx.Material(0.1, 0.7, 3); 32 | var stick1 = addRectangle( -100, 0, 100, 20, material ); 33 | stick1.setSpeed( 2, 1, .075 ); 34 | var stick2 = addRectangle( 700, 600, 100, 20, material ); 35 | stick2.setSpeed( -2, -1, -.025 ); 36 | var stick3 = addBody( 290, 750, createConvexPoly(3,30,0,material) ); 37 | stick3.setSpeed( .25, -1.25, .005 ); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /phx/demo/application.nmml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /phx/demo/physaxeDemo.hxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /phx/joint/Joint.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008, Nicolas Cannasse 3 | * All rights reserved. 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * - Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR 17 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 23 | * DAMAGE. 24 | */ 25 | package phx.joint; 26 | 27 | class Joint { 28 | 29 | public var b1:phx.Body; 30 | public var b2:phx.Body; 31 | 32 | public var anchr1:phx.Vector; 33 | public var anchr2:phx.Vector; 34 | 35 | public var island : phx.Island; 36 | 37 | function new( b1, b2, anchr1, anchr2 ) { 38 | this.b1 = b1; 39 | this.b2 = b2; 40 | this.anchr1 = anchr1; 41 | this.anchr2 = anchr2; 42 | } 43 | 44 | public function preStep( invDt : Float ) { 45 | } 46 | 47 | public function applyImpuse() { 48 | } 49 | 50 | } 51 | --------------------------------------------------------------------------------