Added additional games

This commit is contained in:
TheEmeraldStarr 2021-01-02 18:35:41 -08:00
parent 44afd26253
commit 1ca1a43b26
207 changed files with 29679 additions and 0 deletions

View file

@ -0,0 +1,114 @@
body {
background: #837400;
color: #333;
padding: 50px;
}
#game {
position: relative;
width: 768px;
height: 440px;
overflow: hidden;
}
#game, footer {
width: 768px;
margin: 0 auto;
}
.scene {
position: absolute;
width: 100%;
height: 100%;
}
#menu-scene {
background: #ccc url(../images/menu_bg.jpg);
display: -webkit-box;
-webkit-box-pack:center;
-webkit-box-align: center;
display: -moz-box;
-moz-box-pack:center;
-moz-box-align: center;
display: box;
box-pack:center;
box-align: center;
}
#game-scene {
background: #efefef url(../images/game_bg.jpg);
top: -440px;
}
#game-scene.show-scene {
top: 0;
-webkit-transition: top .3s linear;
-moz-transition: top .3s linear;
transition: top .3s linear;
}
#game-canvas, #game-background-canvas {
position: absolute;
}
/* Menu Scene Elements */
a[href='#game'] {
width: 146px;
height: 78px;
background: url(../images/play_button.png);
overflow: hidden;
display: block;
}
a[href='#game']:hover {
background-position: -146px;
}
a[href='#game']:active {
background-position: -292px;
}
a[href='#game'] span {
display: block;
margin-top: -999px;
}
/* Game Scene Elements */
.hit-line {
background: url(../images/hit_line.png);
position: absolute;
width: 50px;
height: 50px;
}
.show {
opacity: 1;
}
.hide{
opacity: 0;
-webkit-transition: opacity .2s linear;
-moz-transition: opacity .2s linear;
transition: opacity .2s linear;
}
#hit-line-1 {
left: 259px;
top: 335px;
}
#hit-line-2 {
left: 359px;
top: 335px;
}
#hit-line-3 {
left: 459px;
top: 335px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

View file

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>HTML5 Audio Game</title>
<link rel="stylesheet" href="css/audiogame.css" />
</head>
<body>
<div id="game">
<section id="menu-scene" class="scene">
<a href="#game"><span>Play</span></a>
</section>
<section id="game-scene" class="scene">
<canvas id="game-background-canvas" width="768" height="440">
Sorry, your web browser does not support canvas content.
</canvas>
<canvas id="game-canvas" width="768" height="440">
Sorry, your web browser does not support canvas content.
</canvas>
<div id="hit-line-1" class="hit-line hide"></div>
<div id="hit-line-2" class="hit-line hide"></div>
<div id="hit-line-3" class="hit-line hide"></div>
</section>
</div>
<audio id="buttonover">
<source src="media/button_over.wav" />
<source src="media/button_over.ogg" />
</audio>
<audio id="buttonactive">
<source src="media/button_active.mp3" />
<source src="media/button_active.ogg" />
</audio>
<audio id="melody">
<source src="media/minuet_in_g_melody.mp3" />
<source src="media/minuet_in_g_melody.ogg" />
</audio>
<audio id="base">
<source src="media/minuet_in_g.mp3" />
<source src="media/minuet_in_g.ogg" />
</audio>
<footer>
<p>This is an example of making audio game in HTML5. Press J, K, L to play.</p>
</footer>
<script src="js/jquery-1.6.min.js"></script>
<script src="js/html5games.audio.js"></script>
</body>
</html>

View file

@ -0,0 +1,314 @@
function MusicNote(time,line){
this.time = time;
this.line = line;
}
function Dot(distance, line) {
this.distance = distance;
this.line = line;
this.missed = false;
}
// a global object variable to store all game scope variable.
var audiogame = {};
// toggle the game between play mode and record mode.
audiogame.isRecordMode = false;
// an array to store all music notes data.
audiogame.musicNotes = [];
audiogame.leveldata = "1.592,3;1.984,2;2.466,1;2.949,2;4.022,3;4.443,2;4.594,1;5.498,3;5.92,2;6.04,1;7.034,2;7.395,3;7.968,2;8.45,1;8.962,2;10.018,3;10.258,2;10.44,2;10.711,1;10.977,2;11.556,3;12.008,1;13.588,3;14.013,2;14.495,1;14.946,2;16.003,3;16.395,2;16.546,1;17.48,3;17.85,2;18.001,1;19.026,2;19.508,3;19.96,2;20.412,1;20.955,2;22.01,3;22.252,2;22.432,2;22.673,1;23.518,3;23.788,2;24.029,1;25.024,3;25.506,2;26.019,1;26.531,2;27.043,3;28.038,3;28.52,2;28.972,1;29.454,2;29.967,3;30.51,2;31.022,3;31.474,2;31.956,3;32.408,2;32.89,3;33.433,2;34.006,3;34.398,2;34.518,1;35.453,3;35.875,2;36.026,1;37.111,2;37.504,3;38.016,1;38.529,3;38.981,2;39.524,3;40.007,2;40.459,1;40.971,2;41.483,3;41.936,2;42.448,1;42.992,2;43.444,3;43.956,2;44.378,3;44.92,2;45.945,3;46.337,2;46.488,1;47.513,3;47.875,2;47.995,1;49.141,2;49.533,3;50.045,2;50.557,1;51.039,2;51.521,3;52.004,2;52.486,1;52.998,2;53.481,3;53.993,2;54.505,1;54.988,2;55.44,3;55.952,2;56.434,3;56.916,2;57.429,1;57.911,2;58.454,3;58.966,2;59.539,3;60.051,2;61.256,3;61.739,2;62.222,1;62.704,2;63.216,3;63.699,2;64.212,1;64.755,2;65.267,3;65.749,2;66.261,3;66.743,2;67.256,3;67.738,2;68.251,1;68.764,2;69.247,3;69.729,2;70.271,3;70.753,2;71.265,1;71.717,2;72.289,3;73.223,3;73.736,2;74.249,1;74.731,2;75.274,3;75.756,2;76.268,3;76.78,2;77.262,3;77.744,2;78.257,3;78.77,2;79.252,1;79.765,2;80.277,3;80.729,2;81.241,1;81.754,2;82.266,3;82.779,3;83.261,2;83.744,1;84.256,2;84.799,3;85.643,3;86.276,2;86.758,3;87.24,2;87.722,3;88.236,2;88.778,1;89.26,2;89.773,3;90.256,2;90.708,1;91.191,2;91.763,3;92.216,2;92.729,3;93.241,2;93.753,1;94.235,3;94.748,3;95.29,2;95.742,3;96.224,2;96.827,3;97.671,3;98.334,3;98.906,3;100.022,3;100.444,2;100.564,1;101.468,3;101.859,2;102.01,1;102.975,2;103.367,3;103.518,2;103.88,3;104.031,2;104.393,3;104.544,2;104.905,3;105.057,2;105.961,3;106.205,2;106.416,2;106.657,1;106.928,2;107.169,3;107.441,2;107.712,1;107.984,3;108.527,2;109.009,1;109.401,2;109.521,3;110.034,2;110.546,3;111.029,2;111.964,3;112.084,2;112.265,1;112.416,2;112.988,3;113.501,3;113.892,2;114.043,1;114.525,2;115.037,3;115.399,2;115.55,1;115.852,3;116.002,2;116.365,3;116.485,2;116.847,3;116.998,2;117.963,3;118.354,2;118.506,1;119.503,3;119.865,2;120.015,1;";
// the visual dots drawn on the canvas.
audiogame.dots = [];
audiogame.startingTime = 0;
// reference of the dot image
audiogame.dotImage = new Image();
audiogame.totalDotsCount = 0;
audiogame.totalSuccessCount = 0;
// storing the success count of last 5 results.
audiogame.successCount = 5;
function setupLevelData()
{
var notes = audiogame.leveldata.split(";");
// store the total number of dots
audiogame.totalDotsCount = notes.length;
for(var i in notes)
{
var note = notes[i].split(",");
var time = parseFloat(note[0]);
var line = parseInt(note[1]);
var musicNote = new MusicNote(time,line);
audiogame.musicNotes.push(musicNote);
}
}
// init function when the DOM is ready
$(function(){
// get the references of the audio element.
audiogame.melody = document.getElementById("melody");
$(audiogame.melody).bind('ended', onMelodyEnded);
audiogame.base = document.getElementById("base");
audiogame.buttonOverSound = document.getElementById("buttonover");
audiogame.buttonOverSound.volume = .3;
audiogame.buttonActiveSound = document.getElementById("buttonactive");
audiogame.buttonActiveSound.volume = .3;
// load the dot image
audiogame.dotImage.src = "images/dot.png";
// listen the button event that links to #game
$("a[href='#game']")
.hover(function(){
audiogame.buttonOverSound.currentTime = 0;
audiogame.buttonOverSound.play();
},function(){
audiogame.buttonOverSound.pause();
})
.click(function(){
audiogame.buttonActiveSound.currentTime = 0;
audiogame.buttonActiveSound.play();
$("#game-scene").addClass('show-scene');
startGame();
return false;
});
// keydown
$(document).keydown(function(e){
var line = e.which-73;
$('#hit-line-'+line).removeClass('hide');
$('#hit-line-'+line).addClass('show');
if (audiogame.isRecordMode)
{
// print the stored music notes data when press ";" (186)
if (e.which == 186)
{
var musicNotesString = "";
for(var i in audiogame.musicNotes)
{
musicNotesString += audiogame.musicNotes[i].time+","+audiogame.musicNotes[i].line+";";
}
console.log(musicNotesString);
}
var currentTime = audiogame.melody.currentTime.toFixed(3);
var note = new MusicNote(currentTime, e.which-73);
audiogame.musicNotes.push(note);
}
else
{
// our target is J(74), K(75), L(76)
var hitLine = e.which-73;
// check if hit a music note dot
for(var i in audiogame.dots)
{
if (hitLine == audiogame.dots[i].line && Math.abs(audiogame.dots[i].distance) < 20)
{
// remove the hit dot from the dots array
audiogame.dots.splice(i, 1);
// increase the success count
audiogame.successCount++;
// keep only 5 success count max.
audiogame.successCount = Math.min(5, audiogame.successCount);
// increase the total success count
audiogame.totalSuccessCount ++;
}
}
}
});
$(document).keyup(function(e){
var line = e.which-73;
$('#hit-line-'+line).removeClass('show');
$('#hit-line-'+line).addClass('hide');
});
if (!audiogame.isRecordMode)
{
setupLevelData();
}
drawBackground();
if (!audiogame.isRecordMode)
{
setInterval(gameloop, 30);
}
});
function playMusic()
{
// play both the melody and base
audiogame.melody.play();
audiogame.base.play();
}
function startGame()
{
// starting game
var date = new Date();
audiogame.startingTime = date.getTime();
setTimeout(playMusic, 3550);
}
function drawBackground()
{
// get the reference of the canvas and the context.
var game = document.getElementById("game-background-canvas");
var ctx = game.getContext('2d');
// set the line style of the three vertical lines.
ctx.lineWidth = 10;
ctx.strokeStyle = "#000";
var center = game.width/2;
// draw the three lines
// the left line is placed 100 pixels on the left of center.
ctx.beginPath();
ctx.moveTo(center-100, 50);
ctx.lineTo(center-100, ctx.canvas.height - 50);
ctx.stroke();
// the middle line is placed at the center
ctx.beginPath();
ctx.moveTo(center, 50);
ctx.lineTo(center, ctx.canvas.height - 50);
ctx.stroke();
// the right line is placed 100 pixels on the right of center.
ctx.beginPath();
ctx.moveTo(center+100, 50);
ctx.lineTo(center+100, ctx.canvas.height - 50);
ctx.stroke();
// draw the horizontal line
ctx.beginPath();
ctx.moveTo(center-150, ctx.canvas.height - 80);
ctx.lineTo(center+150, ctx.canvas.height - 80);
// reset the line style to 1px width and grey before actually drawing the horizontal line.
ctx.lineWidth = 1;
ctx.strokeStyle = "rgba(50,50,50,.8)";
ctx.stroke();
}
// logic that run every 30ms.
function gameloop()
{
var game = document.getElementById("game-canvas");
var ctx = game.getContext('2d');
// show new dots
// if the game is started
if (audiogame.startingTime != 0)
{
for(var i in audiogame.musicNotes)
{
var date = new Date();
var elapsedTime = (date.getTime() - audiogame.startingTime)/1000;
var note = audiogame.musicNotes[i];
var timeDiff = note.time - elapsedTime;
if (timeDiff >= 0 && timeDiff <= .03)
{
var dot = new Dot(ctx.canvas.height-150, note.line);
audiogame.dots.push(dot);
}
}
}
// check missed dots
for(var i in audiogame.dots)
{
if (!audiogame.dots[i].missed && audiogame.dots[i].distance < -10)
{
audiogame.dots[i].missed = true;
// reduce the success count
audiogame.successCount--;
// reset the success count to 0 if it is lower than 0.
audiogame.successCount = Math.max(0, audiogame.successCount);
}
// remove missed dots after moved to the bottom
if (audiogame.dots[i].distance < -100)
{
audiogame.dots.splice(i, 1);
}
}
// calculate the percentage of the success in last 5 music dots
var successPercent = audiogame.successCount / 5;
// prevent the successPercent to exceed range(fail safe)
successPercent = Math.max(0, Math.min(1, successPercent));
// change the volume of the melody according to the success percentange
audiogame.melody.volume = successPercent;
// move the dots
for(var i in audiogame.dots)
{
audiogame.dots[i].distance -= 2.5;
}
// only clear the dirty area, that is the middle area
ctx.clearRect(ctx.canvas.width/2-200, 0, 400, ctx.canvas.height);
// draw the music note dots
for(var i in audiogame.dots)
{
// prepare the radial gradients fill style
var circle_gradient = ctx.createRadialGradient(-3,-3,1,0,0,20);
circle_gradient.addColorStop(0, "#fff");
circle_gradient.addColorStop(1, "#cc0");
ctx.fillStyle = circle_gradient;
// draw the path
//console.log(ctx.canvas.height-80-audiogame.dots[i].distance);
ctx.save();
var center = game.width/2;
var dot = audiogame.dots[i];
var x = center-100
if (dot.line == 2)
{
x = center;
}
else if (dot.line == 3)
{
x = center+100;
}
ctx.translate(x, ctx.canvas.height-80-audiogame.dots[i].distance);
ctx.drawImage(audiogame.dotImage, -audiogame.dotImage.width/2, -audiogame.dotImage.height/2);
ctx.restore();
}
}
// show game over scene on melody ended.
function onMelodyEnded()
{
console.log('song ended');
console.log('success percent: ',audiogame.totalSuccessCount / audiogame.totalDotsCount * 100 + '%');
}

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,9 @@
# Audio Game
This game makes use of audio tag and keyboard input to create a music notes dropping game.
This is originally from the book [HTML5 Games Development by Examples][1].
Please note that this code was written in 2012 and I didn't followed some best practice in Javasscript programming. It is suggested to learn the concept and update the code to follow latest JavaScript practice.
[1]: http://www.packtpub.com/html5-games-development-using-css-javascript-beginners-guide/book

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimal-ui">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>Shoot the ball</title>
<link rel="stylesheet" href="styles/game.css">
</head>
<body>
<section id="game" class="row">
<canvas id="debug-canvas" width="480" height="360"></canvas>
<canvas id="canvas" width="480" height="360"></canvas>
</section>
<header>
<div class="row">
<h1>Shoot the ball</h1>
</div>
</header>
<section class="how-to-play row">
<h2>How to Play?</h2>
</section>
<footer>
<div class="row">
<p>This is a game example for my HTML5 game develapment book.</p>
</div>
</footer>
<!-- Having all the javascirpts separated here for readability. Please merge them into one file in production. -->
<script src="vendors/easeljs-0.7.1.min.js"></script>
<script src="vendors/tweenjs-0.5.1.min.js"></script>
<script src="vendors/movieclip-0.7.1.min.js"></script>
<script src="vendors/preloadjs-0.4.1.min.js"></script>
<script src="vendors/Box2dWeb-2.1.a.3.min.js"></script>
<script src="scripts/assets.js"></script>
<script src="scripts/level.js"></script>
<script src="scripts/physics.js"></script>
<script src="scripts/view.js"></script>
<script src="scripts/game.js"></script>
<!-- made by makzan, 2014.
__
/\ \
___ ___ __ \ \ \/'\ ____ __ ___
/' __` __`\ /'__`\ \ \ , < /\_ ,`\ /'__`\ /' _ `\
/\ \/\ \/\ \/\ \L\.\_\ \ \\`\\/_/ /_/\ \L\.\_/\ \/\ \
\ \_\ \_\ \_\ \__/.\_\\ \_\ \_\/\____\ \__/.\_\ \_\ \_\
\/_/\/_/\/_/\/__/\/_/ \/_/\/_/\/____/\/__/\/_/\/_/\/_/
-->
</body>
</html>

View file

@ -0,0 +1,421 @@
(function (lib, img, cjs) {
var p; // shortcut to reference prototypes
// library properties:
lib.properties = {
width: 550,
height: 400,
fps: 24,
color: "#FFFFFF",
manifest: [
{src:"../images/lv1.png", id:"lv1"},
{src:"../images/lv2.png", id:"lv2"},
{src:"../images/lv3.png", id:"lv3"},
{src:"../images/lv4.png", id:"lv4"},
{src:"../images/lv5.jpg", id:"lv5"},
{src:"../images/lv6.jpg", id:"lv6"}
]
};
// stage content:
(lib.assets = function() {
this.initialize();
// Layer 1
this.instance = new lib.ScoreBoard();
this.instance.setTransform(215,197.4,1,1,0,0,0,76.9,17.8);
// Layer 1
this.instance_1 = new lib.LevelSelection();
this.instance_1.setTransform(344.6,298.8);
// Layer 1
this.instance_2 = new lib.BouncyBall();
this.instance_2.setTransform(408.2,88.7);
this.instance_3 = new lib.PowerArrow();
this.instance_3.setTransform(180,94.9);
this.instance_4 = new lib.HoopSensor();
this.instance_4.setTransform(56.9,98);
this.instance_5 = new lib.BrownSquare();
this.instance_5.setTransform(361.7,71.9);
this.instance_6 = new lib.Cross();
this.instance_6.setTransform(490,97.6);
this.instance_7 = new lib.HoopBoard();
this.instance_7.setTransform(23.4,57.3);
this.instance_8 = new lib.HoopSquare();
this.instance_8.setTransform(28.4,97.3);
this.instance_9 = new lib.SlowBall();
this.instance_9.setTransform(411.2,132.3);
this.instance_9.cache(-16,-16,32,32);
this.addChild(this.instance_9,this.instance_8,this.instance_7,this.instance_6,this.instance_5,this.instance_4,this.instance_3,this.instance_2,this.instance_1,this.instance);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(292.9,216.8,806.7,642.1);
// symbols:
(lib.lv1 = function() {
this.initialize(img.lv1);
}).prototype = p = new cjs.Bitmap();
p.nominalBounds = new cjs.Rectangle(0,0,894,668);
(lib.lv2 = function() {
this.initialize(img.lv2);
}).prototype = p = new cjs.Bitmap();
p.nominalBounds = new cjs.Rectangle(0,0,924,688);
(lib.lv3 = function() {
this.initialize(img.lv3);
}).prototype = p = new cjs.Bitmap();
p.nominalBounds = new cjs.Rectangle(0,0,918,652);
(lib.lv4 = function() {
this.initialize(img.lv4);
}).prototype = p = new cjs.Bitmap();
p.nominalBounds = new cjs.Rectangle(0,0,904,660);
(lib.lv5 = function() {
this.initialize(img.lv5);
}).prototype = p = new cjs.Bitmap();
p.nominalBounds = new cjs.Rectangle(0,0,912,678);
(lib.lv6 = function() {
this.initialize(img.lv6);
}).prototype = p = new cjs.Bitmap();
p.nominalBounds = new cjs.Rectangle(0,0,920,696);
(lib.SlowBall = function() {
this.initialize();
// Layer 1
this.shape = new cjs.Shape();
this.shape.graphics.f().s("#CC6633").ss(1,1,1).p("Ag8BzQgQgJgOgOQgngmAAg2QAAg0AngmQAOgOAQgJQAcgQAgAAQAhAAAcAPQAQAJAPAPQAmAmAAA0QAAA2gmAmQgPAOgRAJQgbAPghAAQggAAgcgPgAA9hyIgBDlAg8hxIAADk");
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f("#C27400").s().p("AA9hyQAQAJAPAPQAmAmgBA0QABA1gmAnQgPAOgRAJgAhaBcQgngnABg1QgBg0AngmQAOgOAQgJIAADjQgQgIgOgOg");
this.shape_2 = new cjs.Shape();
this.shape_2.graphics.f("#FF9900").s().p("Ag8BzIAAjkQAcgPAgAAQAhAAAcAOIgBDlQgbAPghgBQggAAgcgOg");
this.addChild(this.shape_2,this.shape_1,this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-14,-14,28,28);
(lib.ScoreBoard = function() {
this.initialize();
// Layer 1
this.textField = new cjs.Text("0", "bold 19px 'Arial'", "#333333");
this.textField.name = "textField";
this.textField.lineHeight = 23;
this.textField.lineWidth = 35;
this.textField.setTransform(8.6,3.1);
this.shape = new cjs.Shape();
this.shape.graphics.f().s("#000000").p("AESCJQAAAGgCAFQgCAFgEAAIhkgBQgmgBgdACIghABQhAABiEABQgWgDgMAAIhkAAQgDAAgDgFQgDgEAAgHIAAhBQgChJAChKIAAhCQAAgGADgEQADgEADAAIISAAQAEAAACAEQACAEAAAGIAABCQgBAZABAxQACAugCAbg");
this.shape.setTransform(27.5,15.7);
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f("#FFFCE2").s().p("AikCZIhkAAQgDAAgDgFQgDgEAAgHIAAhBQgChJAChKIAAhCQAAgGADgEQADgEADAAIISAAQAEAAACAEQACAEAAAGIAABCQgBAZABAxQACAugCAbIAABBQAAAGgCAFQgCAFgEAAIhkgBQgmgBgdACIghABIjEACQgWgDgMAAg");
this.shape_1.setTransform(27.5,15.7);
this.addChild(this.shape_1,this.shape,this.textField);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-1,-1,57.1,34.6);
(lib.RightButton = function() {
this.initialize();
// Layer 1
this.shape = new cjs.Shape();
this.shape.graphics.f().s("#000000").p("AB8gBIj3i+IAAF/ID3i+g");
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f("#FFFCE2").s().p("Ah7i/ID3C+IAAADIj3C+g");
this.addChild(this.shape_1,this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-13.4,-20.2,27,40.6);
(lib.PowerBar = function() {
this.initialize();
// Layer 1
this.shape = new cjs.Shape();
this.shape.graphics.f("#FF3300").s().p("AgvAKIAAgSIBfAAIAAASg");
this.shape.setTransform(0,-1);
this.addChild(this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-4.8,-2,9.8,2);
(lib.PlayButton = function() {
this.initialize();
// Layer 1
this.text = new cjs.Text("Play Level", "26px 'Andola'");
this.text.lineHeight = 32;
this.text.setTransform(-70.6,-11.9);
this.shape = new cjs.Shape();
this.shape.graphics.f().s("#000000").p("ANCDbQAAAKgGAGQgHAHgKAAQhAAAjxgCQiHgBhvADQjZAFkQgBQlHgDjCgBIg8AAQgJAAgIgHQgGgGAAgKIAAhlQAEhOgBhAQgDiJAAg0QAAgKAGgGQAHgHAKAAIBrAAQC/gNFpAFQFwAGBbgGQDZABB+ADQCAAEAgAAQAKAAAHAHQAGAHAAAJIAABlQgEBOABBAQADCKAAAzg");
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f("#FFFCE2").s().p("AjlD2IoJgEIg8AAQgJAAgIgHQgGgGAAgKIAAhlQAEhOgBhAQgDiJAAg0QAAgKAGgGQAHgHAKAAIBrAAQC/gNFpAFQFwAGBbgGQDZABB+ADICgAEQAKAAAHAHQAGAHAAAJIAABlQgEBOABBAQADCKAAAzQAAAKgGAGQgHAHgKAAIkxgCQiHgBhvADQi4AEjeAAIhTAAg");
this.addChild(this.shape_1,this.shape,this.text);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-84.4,-26.9,169,56.1);
(lib.Levels = function(mode,startPosition,loop) {
this.initialize(mode,startPosition,loop,{});
// Layer 1
this.instance = new lib.lv1();
this.instance.setTransform(-168.4,-70.2,0.21,0.21);
this.shape = new cjs.Shape();
this.shape.graphics.f("#000000").s().p("Aj3EAQgFgBgCgDQgDgDgCgEQgBgFAAgFIABgLIABACIAPACIgBANIANABIADgYIgehjIAZgBIAKAoIAEAXIAEAAQAGgcAGglIARACIgOA8IgLAxQgDATgJAIQgFAEgKAAQgFAAgEgCgAiqD/IgDiEIAPABIADAKQAGgKAFgEIAHgDQAEgCAGAAQAIAAAGAEQAHADAEAHQAEAGACAHQACAIAAAIQAAAOgCAKQgDAKgEAHQgEAHgHAEQgGADgJAAQgGAAgLgFIAAAxgAiXDAIAfgBIAAguIgfAAgApzDXIgegCIACiIQAYgBAXAAQAJAAAHABQAGACAFADQAHAEADAGQADAGAAAIQAAAagYAKIAAAFQAHABAGADQAFADAEAEQAEAFACAFQACAGAAAHQAAAJgDAHQgCAGgFAEQgEAFgHACQgHADgIAAIgdgCgApxDIIAhgDIgBgpIghgBgAp7CJIAigCIACgpIgjAAgAIkDWQgEgBgDgDQgDgDgBgEQgCgEAAgGQAAgHACgHQADgKAFgDQAEgDAMgCQALgDAUgCIgBgTQgRgFgFAAIgDAAIgDAAIgBANIgNgBIgKAAQAAgGADgGQADgFAGgEIAMgGQAHgCAHAAQAJAAAGADQAHACAEAEQAFAFACAGQACAHAAAIIgBAcQABAVACANIgHAAIgPACIgEgMQgIAHgHAEQgIADgIAAQgFAAgEgCgAI9CsIgNAEIAAAXIAYgCIABgbIgMACgAD2DUQgHgFgGgJQgEgHgCgJQgCgIAAgLQAAgJACgJQACgIAEgGQAFgIAHgEQAHgEAKAAQAFAAAEACQAFABADACIAIAGIAGAIQAEAIACAJQADAKAAAKQAAAJgDAIQgDAHgFAHQgFAHgHAEQgHADgJAAQgJAAgIgEgAEVDBIgEg6IgXADIgEAxIAMAEQAGACAIAAIAFAAgAg5DUQgIgDgFgIQgFgGgCgJQgDgIAAgLQAAgKACgJQACgJAFgHQAFgIAHgEQAIgFAJAAQAGAAAEACIAIADIAHAGIAGAHQAIAPAAAWQgYAAgfADIACAYIAbABIABgLIAXgBQgBAHgDAGQgDAFgEAEQgFAEgGACQgFACgHAAQgKAAgIgEgAgaCfIgBgaIgaABIAAAZIAbAAgAkqDWQgFgBgDgDQgEgDgCgFQgCgEAAgGIAAgMQAAgKAEgeIgMgCIABgPIAMABIAKggIAKAAIgBAbIAWABIgBAVIgWAAIgBA4IASAAIgBgNIALAAIAAAJIgBAKQgCAFgDACQgDADgEACQgFABgGAAQgGAAgEgCgAobDWQgEgBgDgDQgCgDgCgEQgBgEAAgGQAAgHACgHQACgKAFgDQAEgDAMgCQAMgDATgCIgBgTQgQgFgFAAIgEAAIgDAAIAAANIgNgBIgKAAQAAgGADgGQADgFAGgEIAMgGQAGgCAHAAQAJAAAHADQAGACAFAEQAEAFACAGQACAHAAAIIAAAcQABAVACANIgHAAIgQACIgEgMQgHAHgIAEQgHADgIAAQgFAAgFgCgAoBCsIgOAEIAAAXIAZgCIABgbIgMACgABvDUIACiJIAfAAIAgBFQAEAIAEAQIAEgBIgChYIAUABIgBCDIgdAAIgXgvQgIgUgKgdIgEABIgBBggAJ4DSIABiJIAZACIgBCIgAHwDSIAAgCIAAgQQAAgZgCgZIgYgBIAABEIgagBIAAhBIgZACIgBBAIgYACIABgpIgBgwIATAAIABARQAGgLAFgFQAEgEAFgCQAEgCAFAAQAFAAAEACQADACADADQAEAFAEAKQAFgLAFgFQADgCAFgCIAKgBQAZAAABAgIAAA/gAE+DPIABg7IAAgaIAQAAIABAMIAEAAQADgJAFgFQAFgFAIAAQAFAAADACQAEACACADQACADABAFQACAFAAAHIgBATIgUAAIAAgWIgSAAIADBIQgSgEgIAAgAmZDSIAAiJIAZACIgBCIgAnGDSIAAiJIAZACIgBCIgAAVDQQgEgBgCgDQgFgFAAgIQAAgKAEgFQAFgFAIAAQAEAAADACQADACACADQADAGAAAJQAAAGgEAFQgEAGgGAAQgEAAgDgCgAAPCTQgEgFAAgIQAAgJAEgFQADgFAIAAQAIAAAEAGQAEAFAAAIQAAAIgEAIQgCADgIAAQgIAAgFgGgAing/QgNgEgKgJIgKgKQgEgFgDgHQgDgGgBgHIgBgQQAAgLAFgTIAGgMQADgGAFgFIALgIIAMgHQAJgDAVgCQAJAAAIACQAIABAHADIAMAHIAKAKIAIAMIAFANQAFAVAAAMQgsAAg1ADIAAAGIACATIApABIABgOIAygCQgCAMgGAJQgFAKgKAGQgIAFgLADQgLADgNAAQgQAAgOgFgAh1iOIgCgbIgmABIAAAaIAoAAgAnMg/QgNgEgKgJIgKgKQgEgFgDgHQgDgGgBgHIgBgQQAAgLAFgTIAGgMQADgGAFgFIALgIIAMgHQAJgDAVgCQAJAAAIACQAIABAHADIAMAHIAKAKIAIAMIAFANQAFAVAAAMQgsAAg1ADIAAAGIACATIApABIABgOIAygCQgCAMgGAJQgFAKgKAGQgIAFgLADQgLADgNAAQgQAAgOgFgAmaiOIgCgbIgmABIAAAaIAoAAgAqLhBIADhhIgBhaIA7gCIgBCTIBNgBIgCAvgACkhDQAFgrACgmQADglAAgfIgcgCIAEgeQASAAATgCIAngHQgEAkgBAeIgBB/gAgthDQAChBgBh8IAyACIgCC+gAk5hDIgoh/IA2gCQACARAGAeIAKAuQAEgXAUhCIAlAAQgEARgJAYQgWA2gKAeg");
this.shape.setTransform(100.4,-42.1);
this.instance_1 = new lib.lv2();
this.instance_1.setTransform(-168.4,-70.2,0.203,0.203);
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f("#000000").s().p("Aj3EDQgFgCgCgCQgDgDgCgFQgBgEAAgGIABgKIABABIAPADIgBANIANABIADgYIgehkIAZgBIAKApIAEAXIAEAAQAGgcAGgmIARADIgOA7IgLAyQgDATgJAHQgFAFgKAAQgFgBgEgBgAiqECIgDiEIAPABIADAKQAGgLAFgDIAHgEQAEgBAGAAQAIAAAGADQAHAEAEAHQAEAGACAHQACAIAAAIQAAAOgCAKQgDAKgEAHQgEAHgHAEQgGADgJAAQgGAAgLgGIAAAygAiXDDIAfgCIAAguIgfAAgApzDZIgegBIACiIQAYgBAXAAQAJAAAHABQAGABAFAEQAHAEADAGQADAGAAAIQAAAZgYAKIAAAGQAHABAGADQAFADAEAEQAEAFACAFQACAGAAAHQAAAJgDAGQgCAHgFAEQgEAEgHADQgHACgIAAIgdgCgApxDLIAhgDIgBgpIghgBgAp7CMIAigCIACgpIgjAAgAIkDZQgEgCgDgCQgDgDgBgEQgCgFAAgFQAAgHACgIQADgJAFgDQAEgDAMgDQALgCAUgCIgBgTQgRgFgFAAIgDAAIgDAAIgBAMIgNgBIgKABQAAgHADgFQADgGAGgDIAMgGQAHgCAHAAQAJAAAGACQAHACAEAFQAFAEACAHQACAGAAAJIgBAcQABAVACANIgHAAIgPACIgEgMQgIAHgHAEQgIADgIAAQgFAAgEgCgAI9CuIgNAFIAAAWIAYgCIABgaIgMABgAD2DXQgHgFgGgJQgEgHgCgJQgCgJAAgKQAAgJACgJQACgIAEgGQAFgIAHgEQAHgEAKAAQAFAAAEABQAFABADADIAIAGIAGAIQAEAIACAJQADAJAAALQAAAJgDAHQgDAIgFAHQgFAHgHAEQgHADgJAAQgJAAgIgEgAEVDEIgEg6IgXADIgEAxIAMAEQAGACAIAAIAFAAgAg5DXQgIgDgFgIQgFgGgCgJQgDgIAAgLQAAgKACgJQACgJAFgHQAFgIAHgEQAIgFAJAAQAGAAAEABIAIAEIAHAFIAGAIQAIAOAAAWQgYABgfACIACAZIAbAAIABgKIAXgBQgBAHgDAFQgDAGgEAEQgFAEgGACQgFACgHAAQgKAAgIgEgAgaCiIgBgbIgaABIAAAaIAbAAgAkqDZQgFgCgDgCQgEgDgCgFQgCgEAAgGIAAgNQAAgJAEgeIgMgCIABgPIAMAAIAKgfIAKgBIgBAcIAWABIgBAVIgWAAIgBA3IASAAIgBgMIALAAIAAAJIgBAKQgCAFgDACQgDADgEABQgFACgGAAQgGAAgEgCgAobDZQgEgCgDgCQgCgDgCgEQgBgFAAgFQAAgHACgIQACgJAFgDQAEgDAMgDQAMgCATgCIgBgTQgQgFgFAAIgEAAIgDAAIAAAMIgNgBIgKABQAAgHADgFQADgGAGgDIAMgGQAGgCAHAAQAJAAAHACQAGACAFAFQAEAEACAHQACAGAAAJIAAAcQABAVACANIgHAAIgQACIgEgMQgHAHgIAEQgHADgIAAQgFAAgFgCgAoBCuIgOAFIAAAWIAZgCIABgaIgMABgABvDXIACiJIAfAAIAgBEQAEAJAEAQIAEgBIgChYIAUAAIgBCEIgdAAIgXgwQgIgTgKgdIgEABIgBBggAJ4DVIABiJIAZACIgBCIgAHwDVIAAgDIAAgPQAAgZgCgaIgYAAIAABEIgagCIAAhAIgZABIgBBBIgYACIABgpIgBgwIATAAIABARQAGgMAFgEQAEgEAFgCQAEgCAFAAQAFAAAEACQADACADADQAEAFAEAKQAFgLAFgFQADgCAFgCIAKgBQAZAAABAgIAAA/gAE+DSIABg7IAAgaIAQAAIABALIAEABQADgJAFgFQAFgFAIAAQAFAAADACQAEACACADQACADABAFQACAFAAAGIgBATIgUAAIAAgVIgSAAIADBIQgSgEgIAAgAmZDVIAAiJIAZACIgBCIgAnGDVIAAiJIAZACIgBCIgAAVDTQgEgBgCgDQgFgFAAgJQAAgJAEgFQAFgFAIAAQAEAAADABQADADACADQADAGAAAJQAAAFgEAGQgEAGgGAAQgEAAgDgCgAAPCWQgEgFAAgJQAAgJAEgEQADgFAIAAQAIAAAEAGQAEAFAAAIQAAAIgEAIQgCACgIAAQgIABgFgGgAing8QgNgEgKgJIgKgKQgEgFgDgHQgDgHgBgGIgBgQQAAgLAFgTIAGgMQADgGAFgFIALgJIAMgGQAJgDAVgCQAJAAAIABQAIACAHADIAMAHIAKAKIAIAMIAFANQAFAUAAANQgsgBg1ADIAAAHIACATIApAAIABgOIAygBQgCAMgGAJQgFAKgKAFQgIAGgLADQgLADgNAAQgQAAgOgFgAh1iMIgCgaIgmABIAAAZIAoAAgAnMg8QgNgEgKgJIgKgKQgEgFgDgHQgDgHgBgGIgBgQQAAgLAFgTIAGgMQADgGAFgFIALgJIAMgGQAJgDAVgCQAJAAAIABQAIACAHADIAMAHIAKAKIAIAMIAFANQAFAUAAANQgsgBg1ADIAAAHIACATIApAAIABgOIAygBQgCAMgGAJQgFAKgKAFQgIAGgLADQgLADgNAAQgQAAgOgFgAmaiMIgCgaIgmABIAAAZIAoAAgAqLg+IADhiIgBhaIA7gBIgBCTIBNgBIgCAugAgthAQAChBgBh8IAyACIgCC+gACzhDIg4ACIABgnQABgPADgIQACgLAGgHQAGgIAJgGQAIgEAPgFIAkgLIAAguIgjAAIgBAnIgxgBIAAgTQAAgNAFgKQAGgKAMgIQAKgGAMgEQAMgCANAAQAQAAAMADQAMAFAIAIQAJAHAEANQAFALAAAQQAAAMgEAJQgDAJgGAHQgFAGgJAFQgJAGgMAEQgTAHgVAGQgDAAAAARIAaAAQAcAAAigEQgCAjABANQg6gDgUAAgAk5hAIgoiAIA2gCQACASAGAdIAKAvQAEgXAUhCIAlAAQgEARgJAYQgWA2gKAeg");
this.shape_1.setTransform(100.4,-42.4);
this.instance_2 = new lib.lv3();
this.instance_2.setTransform(-168.4,-70.2,0.205,0.205);
this.shape_2 = new cjs.Shape();
this.shape_2.graphics.f("#000000").s().p("AJSEDQgFgCgCgCQgDgDgCgFQgBgEAAgGIABgKIABABIAQADIgBANIAMABIADgYIgehkIAZgBIALApIADAXIAFAAQAFgcAGgmIARADIgNA7IgMAyQgDATgJAHQgFAFgKAAQgFgBgEgBgAj0EDQgFgCgDgCQgDgDgBgFQgCgEAAgGIACgKIABABIAPADIgBANIANABIADgYIgehkIAYgBIALApIADAXIAFAAQAGgcAGgmIARADIgOA7IgLAyQgEATgIAHQgGAFgJAAQgGgBgDgBgAioECIgCiEIAPABIADAKQAGgLAEgDIAIgEQAEgBAFAAQAJAAAGADQAGAEAFAHQAEAGACAHQACAIAAAIQAAAOgCAKQgDAKgEAHQgEAHgHAEQgHADgIAAQgGAAgLgGIAAAygAiUDDIAfgCIAAguIgfAAgACODZIgdgBIABiIQAYgBAXAAQAJAAAHABQAHABAEAEQAHAEADAGQADAGAAAIQAAAZgYAKIAAAGQAHABAGADQAFADAEAEQAEAFACAFQACAGAAAHQAAAJgDAGQgCAHgFAEQgEAEgHADQgHACgIAAIgdgCgACQDLIAhgDIAAgpIgigBgACGCMIAjgCIABgpIgjAAgApwDZIgegBIACiIQAYgBAXAAQAIAAAIABQAGABAFAEQAHAEADAGQACAGAAAIQAAAZgXAKIAAAGQAHABAFADQAGADAEAEQAEAFACAFQACAGAAAHQgBAJgCAGQgCAHgFAEQgFAEgGADQgHACgIAAIgdgCgApuDLIAhgDIgBgpIghgBgAp4CMIAigCIACgpIgjAAgAIJDXQgHgEgGgIQgFgHgDgJQgCgJAAgJQAAgLACgIQACgJAEgHQAFgIAIgEQAHgEALAAQAIAAAHADQAHACAFAGQAFAFAEAIQACAHAAAIIgWgBIgBgTIgaACIgBAdQAAAPABAMIAMACQAJgBACgBIABgMIAYAAQgBAJgCAGQgCAGgFAFQgEAFgHACQgGADgIAAQgKAAgIgEgADyDXQgHgFgGgJQgEgHgCgJQgCgJAAgKQAAgJACgJQACgIAEgGQAFgIAHgEQAHgEAKAAQAEAAAFABQAFABADADIAIAGIAFAIQAEAIADAJQACAJAAALQAAAJgCAHQgDAIgFAHQgGAHgGAEQgIADgIAAQgKAAgHgEgAD2CNIgFAxIAMAEQAHACAIAAIAFAAIgEg6gAg2DXQgIgDgFgIQgGgGgBgJQgDgIAAgLQAAgKACgJQACgJAEgHQAGgIAHgEQAIgFAJAAQAGAAAEABIAIAEIACABIAAAxIgkACIABAZIAbAAIABgKIAHAAIARgBQgBAHgEAFQgCAGgEAEIgGAEIAAgZIAAAZIgFACQgGACgHAAQgJAAgIgEgAgzCIIAAAaIAcAAIgCgbgAkoDZQgEgCgEgCQgDgDgCgFQgCgEAAgGIAAgNQAAgJAEgeIgMgCIABgPIALAAIAKgfIALgBIgBAcIAWABIgBAVIgWAAIgBA3IASAAIgBgMIAKAAIAAAJIAAAKQgCAFgDACQgDADgEABQgFACgGAAQgGAAgFgCgAoYDZQgEgCgDgCQgCgDgCgEQgBgFgBgFQAAgHACgIQADgJAFgDQAEgDAMgDQALgCAUgCIgBgTQgQgFgFAAIgEAAIgDAAIgBAMIgMgBIgKABQAAgHADgFQACgGAHgDIALgGQAHgCAHAAQAJAAAGACQAHACAFAFQAEAEACAHQACAGAAAJIAAAcQABAVACANIgIAAIgPACIgEgMQgIAHgHAEQgIADgHAAQgGAAgEgCgAn/CuIgNAFIAAAWIAZgCIABgaIgNABgAFIDYQgFgDgDgFQgDgDgCgGIgBgMIgBg/QALABAPAAIgCBGIAbAAIAAhJIAYABIAABXIgSgBIgBgKQgIAJgGAGQgIAEgIAAQgGAAgFgCgAHIDYIABgkIgCgjIgZACIABAgIgBAgIgVACIAAhXIARABIACANQAJgKAJgFQAIgFAIAAQAFAAAFADQAEADACAFQADAGAAAPIgBBAgAmWDVIAAiJIAZACIgBCIgAnDDVIAAiJIAZACIgBCIgAAYDTQgEgBgCgDQgFgFAAgJQAAgJAEgFQAEgFAJAAQAEAAACABQAEADACADQADAGAAAJQAAAFgEAGQgFAGgFAAQgFAAgCgCgAgTCtIAAgxIAFAEIAFAIQAJAOAAAWIgTABgAASCWQgFgFABgJQAAgJADgEQAEgFAIAAQAIAAAEAGQAEAFAAAIQAAAIgEAIQgDACgHAAQgJABgEgGgAgTB8IAAAAgACig6QgNgDgIgGQgFgDgDgFQgEgEgDgHQgDgHgCgVIABgHIA3ACIgCAeIAnAAIgDgtIgpgEIADgkIAfAAIAEgpIgkgEIgCAhIgwgDQAAgMAEgSQAGgNAJgJQAJgJANgFQAJgDAVgBQAPAAANADQAMADAIAIQAJAIAGALQAEALAAAQQAAAHgCAHQgDAGgFAFQgDAFgGADIgPAHQALACAHAFQAIAEAGAFQAEAGADAHQADAIAAAJQAAAIgBAGQgCAHgDAFQgDAGgEAEIgLAJQgKAHgNADQgNADgPAAQgSAAgNgDgAikg8QgOgEgKgJIgKgKQgDgFgDgHQgDgHgBgGIgBgQQAAgLAEgTIAGgMQAEgGAFgFIAKgJIANgGQAJgDAVgCQAIAAAJABQAHACAHADIANAHIAKAKIAIAMIAFANQAEAUABANQgsgBg2ADIAAAHIACATIAqAAIABgOIAygBQgCAMgGAJQgFAKgKAFQgIAGgLADQgLADgNAAQgRAAgNgFgAiailIAAAZIAoAAIgDgagAnJg8QgOgEgJgJIgKgKQgEgFgDgHQgDgHgBgGIgCgQQAAgLAGgTIAFgMQAEgGAFgFIALgJIAMgGQAJgDAUgCQAKAAAHABQAIACAIADIAMAHIAKAKIAIAMIAFANQAFAUgBANQgrgBg2ADIAAAHIADATIAoAAIACgOIAygBQgCAMgGAJQgFAKgKAFQgJAGgLADQgKADgNAAQgQAAgOgFgAm/ilIAAAZIAoAAIgCgagAqJg+IADhiIgBhaIA8gBIgBCTIBMgBIgCAugAgTg/IAAi9IAbABIgBC+gAgqhAQAChBgCh8IAXABIAAC9gAk2hAIgoiAIA1gCQADASAFAdIAKAvQAFgXAUhCIAlAAQgEARgJAYQgWA2gKAeg");
this.shape_2.setTransform(100.1,-42.4);
this.instance_3 = new lib.lv4();
this.instance_3.setTransform(-168.4,-70.2,0.208,0.208);
this.shape_3 = new cjs.Shape();
this.shape_3.graphics.f("#000000").s().p("Aj3EEQgFgBgCgCQgDgDgCgFQgBgEAAgGIABgKIABABIAPACIgBAOIANABIADgZIgehjIAZgBIAKAoIAEAYIAEAAQAGgdAGglIARADIgOA7IgLAxQgDATgJAIQgFAEgKAAQgFAAgEgCgAiqEDIgDiEIAPACIADAKQAGgLAFgEIAHgDQAEgBAGAAQAIAAAGADQAHAEAEAGQAEAHACAHQACAHAAAIQAAAOgCAKQgDAKgEAIQgEAGgHAEQgGADgJAAQgGAAgLgFIAAAxgAiXDEIAfgBIAAguIgfAAgApzDbIgegCIACiIQAYgBAXAAQAJAAAHABQAGACAFAEQAHAEADAFQADAGAAAJQAAAZgYAKIAAAFQAHABAGAEQAFACAEAEQAEAFACAFQACAGAAAIQAAAIgDAHQgCAGgFAFQgEAEgHADQgHACgIAAIgdgCgApxDMIAhgCIgBgqIghgBgAp7CNIAigBIACgqIgjAAgAIkDbQgEgCgDgDQgDgDgBgEQgCgEAAgGQAAgGACgIQADgKAFgDQAEgDAMgCQALgDAUgCIgBgTQgRgFgFAAIgDAAIgDAAIgBANIgNgBIgKABQAAgHADgGQADgFAGgEIAMgFQAHgCAHAAQAJAAAGACQAHACAEAFQAFAEACAHQACAGAAAIIgBAdQABAUACANIgHAAIgPADIgEgNQgIAIgHADQgIADgIABQgFAAgEgCgAI9CwIgNAEIAAAXIAYgCIABgaIgMABgAD2DYQgHgFgGgIQgEgIgCgJQgCgIAAgKQAAgKACgIQACgJAEgGQAFgIAHgEQAHgDAKAAQAFAAAEABQAFABADACIAIAHIAGAIQAEAHACAKQADAJAAALQAAAIgDAIQgDAIgFAGQgFAHgHAEQgHADgJABQgJgBgIgEgAEVDFIgEg5IgXACIgEAyIAMADQAGACAIAAIAFAAgAg5DYQgIgDgFgIQgFgGgCgJQgDgIAAgLQAAgKACgJQACgIAFgIQAFgIAHgEQAIgFAJABQAGAAAEABIAIADIAHAGIAGAIQAIAOAAAWQgYAAgfADIACAZIAbAAIABgKIAXgCQgBAIgDAFQgDAGgEAEQgFADgGADQgFACgHAAQgKAAgIgFgAgaCjIgBgaIgaABIAAAZIAbAAgAkqDbQgFgCgDgDQgEgDgCgFQgCgEAAgGIAAgMQAAgJAEgfIgMgCIABgPIAMABIAKggIAKAAIgBAbIAWABIgBAVIgWAAIgBA4IASAAIgBgNIALAAIAAAJIgBAKQgCAFgDACQgDADgEACQgFABgGABQgGAAgEgCgAobDbQgEgCgDgDQgCgDgCgEQgBgEAAgGQAAgGACgIQACgKAFgDQAEgDAMgCQAMgDATgCIgBgTQgQgFgFAAIgEAAIgDAAIAAANIgNgBIgKABQAAgHADgGQADgFAGgEIAMgFQAGgCAHAAQAJAAAHACQAGACAFAFQAEAEACAHQACAGAAAIIAAAdQABAUACANIgHAAIgQADIgEgNQgHAIgIADQgHADgIABQgFAAgFgCgAoBCwIgOAEIAAAXIAZgCIABgaIgMABgABvDYIACiJIAfAAIAgBFQAEAJAEAPIAEgBIgChXIAUAAIgBCDIgdAAIgXgvQgIgTgKgdIgEABIgBBfgAJ4DWIABiIIAZABIgBCIgAHwDWIAAgCIAAgQQAAgZgCgZIgYgBIAABEIgagBIAAhAIgZABIgBBAIgYACIABgoIgBgxIATAAIABARQAGgLAFgFQAEgEAFgBQAEgCAFAAQAFAAAEACQADABADADQAEAGAEAJQAFgLAFgFQADgCAFgBIAKgBQAZgBABAgIAAA/gAE+DUIABg8IAAgaIAQAAIABAMIAEABQADgKAFgFQAFgEAIAAQAFAAADACQAEABACADQACAEABAEQACAGAAAGIgBATIgUAAIAAgWIgSAAIADBIQgSgDgIAAgAmZDWIAAiIIAZABIgBCIgAnGDWIAAiIIAZABIgBCIgAAVDVQgEgCgCgDQgFgFAAgIQAAgKAEgFQAFgFAIABQAEgBADACQADACACAEQADAFAAAJQAAAGgEAFQgEAGgGAAQgEAAgDgBgAAPCXQgEgEAAgJQAAgJAEgFQADgEAIAAQAIgBAEAGQAEAFAAAJQAAAHgEAIQgCADgIAAQgIAAgFgGgAC5g2IABgxIhKAAIAAgoQASgeAUgdIArg7QARADAjADIABBwIAdAAIgCAnIgcAAIAAAygACeiTIAsAAIABhIQgcApgRAfgAing6QgNgFgKgJIgKgKQgEgFgDgGQgDgHgBgHIgBgQQAAgKAFgUIAGgLQADgHAFgEIALgJIAMgGQAJgEAVgCQAJAAAIACQAIACAHACIAMAIIAKAKIAIALIAFAOQAFAUAAAMQgsAAg1ADIAAAGIACATIApABIABgOIAygBQgCALgGAJQgFAKgKAGQgIAGgLADQgLACgNAAQgQAAgOgEgAh1iKIgCgaIgmABIAAAZIAoAAgAnMg6QgNgFgKgJIgKgKQgEgFgDgGQgDgHgBgHIgBgQQAAgKAFgUIAGgLQADgHAFgEIALgJIAMgGQAJgEAVgCQAJAAAIACQAIACAHACIAMAIIAKAKIAIALIAFAOQAFAUAAAMQgsAAg1ADIAAAGIACATIApABIABgOIAygBQgCALgGAJQgFAKgKAGQgIAGgLADQgLACgNAAQgQAAgOgEgAmaiKIgCgaIgmABIAAAZIAoAAgAqLg9IADhhIgBhaIA7gCIgBCUIBNgBIgCAugAgtg/QAChBgBh8IAyACIgCC+gAk5g/Igoh/IA2gCQACASAGAdIAKAuQAEgXAUhCIAlAAQgEARgJAZQgWA1gKAeg");
this.shape_3.setTransform(100.4,-42.5);
this.instance_4 = new lib.lv5();
this.instance_4.setTransform(-168.4,-70.2,0.206,0.206);
this.shape_4 = new cjs.Shape();
this.shape_4.graphics.f("#000000").s().p("Aj3EAQgFgBgCgCQgDgDgCgFQgBgEAAgGIABgKIABABIAPACIgBAOIANABIADgZIgehjIAZgBIAKAoIAEAYIAEAAQAGgdAGglIARADIgOA7IgLAxQgDATgJAIQgFAEgKAAQgFAAgEgCgAiqD/IgDiEIAPACIADAKQAGgLAFgEIAHgDQAEgBAGAAQAIAAAGADQAHAEAEAGQAEAHACAHQACAHAAAIQAAAOgCAKQgDAKgEAIQgEAGgHAEQgGADgJAAQgGAAgLgFIAAAxgAiXDAIAfgBIAAguIgfAAgApzDXIgegCIACiIQAYgBAXAAQAJAAAHABQAGACAFAEQAHAEADAFQADAGAAAJQAAAZgYAKIAAAFQAHABAGAEQAFACAEAEQAEAFACAFQACAGAAAIQAAAIgDAHQgCAGgFAFQgEAEgHADQgHACgIAAIgdgCgApxDIIAhgCIgBgqIghgBgAp7CJIAigBIACgqIgjAAgAIkDXQgEgCgDgDQgDgDgBgEQgCgEAAgGQAAgGACgIQADgKAFgDQAEgDAMgCQALgDAUgCIgBgTQgRgFgFAAIgDAAIgDAAIgBANIgNgBIgKABQAAgHADgGQADgFAGgEIAMgFQAHgCAHAAQAJAAAGACQAHACAEAFQAFAEACAHQACAGAAAIIgBAdQABAUACANIgHAAIgPADIgEgNQgIAIgHADQgIADgIABQgFAAgEgCgAI9CsIgNAEIAAAXIAYgCIABgaIgMABgAD2DUQgHgFgGgIQgEgIgCgJQgCgIAAgKQAAgKACgIQACgJAEgGQAFgIAHgEQAHgDAKAAQAFAAAEABQAFABADACIAIAHIAGAIQAEAHACAKQADAJAAALQAAAIgDAIQgDAIgFAGQgFAHgHAEQgHADgJABQgJgBgIgEgAEVDBIgEg5IgXACIgEAyIAMADQAGACAIAAIAFAAgAg5DUQgIgDgFgIQgFgGgCgJQgDgIAAgLQAAgKACgJQACgIAFgIQAFgIAHgEQAIgFAJABQAGAAAEABIAIADIAHAGIAGAIQAIAOAAAWQgYAAgfADIACAZIAbAAIABgKIAXgCQgBAIgDAFQgDAGgEAEQgFADgGADQgFACgHAAQgKAAgIgFgAgaCfIgBgaIgaABIAAAZIAbAAgAkqDXQgFgCgDgDQgEgDgCgFQgCgEAAgGIAAgMQAAgJAEgfIgMgCIABgPIAMABIAKggIAKAAIgBAbIAWABIgBAVIgWAAIgBA4IASAAIgBgNIALAAIAAAJIgBAKQgCAFgDACQgDADgEACQgFABgGABQgGAAgEgCgAobDXQgEgCgDgDQgCgDgCgEQgBgEAAgGQAAgGACgIQACgKAFgDQAEgDAMgCQAMgDATgCIgBgTQgQgFgFAAIgEAAIgDAAIAAANIgNgBIgKABQAAgHADgGQADgFAGgEIAMgFQAGgCAHAAQAJAAAHACQAGACAFAFQAEAEACAHQACAGAAAIIAAAdQABAUACANIgHAAIgQADIgEgNQgHAIgIADQgHADgIABQgFAAgFgCgAoBCsIgOAEIAAAXIAZgCIABgaIgMABgABvDUIACiJIAfAAIAgBFQAEAJAEAPIAEgBIgChXIAUAAIgBCDIgdAAIgXgvQgIgTgKgdIgEABIgBBfgAJ4DSIABiIIAZABIgBCIgAHwDSIAAgCIAAgQQAAgZgCgZIgYgBIAABEIgagBIAAhAIgZABIgBBAIgYACIABgoIgBgxIATAAIABARQAGgLAFgFQAEgEAFgBQAEgCAFAAQAFAAAEACQADABADADQAEAGAEAJQAFgLAFgFQADgCAFgBIAKgBQAZgBABAgIAAA/gAE+DQIABg8IAAgaIAQAAIABAMIAEABQADgKAFgFQAFgEAIAAQAFAAADACQAEABACADQACAEABAEQACAGAAAGIgBATIgUAAIAAgWIgSAAIADBIQgSgDgIAAgAmZDSIAAiIIAZABIgBCIgAnGDSIAAiIIAZABIgBCIgAAVDRQgEgCgCgDQgFgFAAgIQAAgKAEgFQAFgFAIABQAEgBADACQADACACAEQADAFAAAJQAAAGgEAFQgEAGgGAAQgEAAgDgBgAAPCTQgEgEAAgJQAAgJAEgFQADgEAIAAQAIgBAEAGQAEAFAAAJQAAAHgEAIQgCADgIAAQgIAAgFgGgACng9QgNgEgKgGIgKgJQgEgFgDgGQgDgGgBgHQgCgGAAgIIA3gDIAAAeIALAAQAOAAALgCIAAg2IgtgBIgEALIgngCIAHh2IA9ADIA6gDQgDAXgBAUIgTABIg/gCIgCAnQAJgGAKgEQAKgDANAAQAOAAAMAEQAMAFAJAIQAJAIAEAMQAFALAAAOIgBAPQgCAHgDAGQgCAGgFAGIgJAKQgLAKgMAFQgNAEgPAAQgQAAgNgDgAing+QgNgFgKgJIgKgKQgEgFgDgGQgDgHgBgHIgBgQQAAgKAFgUIAGgLQADgHAFgEIALgJIAMgGQAJgEAVgCQAJAAAIACQAIACAHACIAMAIIAKAKIAIALIAFAOQAFAUAAAMQgsAAg1ADIAAAGIACATIApABIABgOIAygBQgCALgGAJQgFAKgKAGQgIAGgLADQgLACgNAAQgQAAgOgEgAh1iOIgCgaIgmABIAAAZIAoAAgAnMg+QgNgFgKgJIgKgKQgEgFgDgGQgDgHgBgHIgBgQQAAgKAFgUIAGgLQADgHAFgEIALgJIAMgGQAJgEAVgCQAJAAAIACQAIACAHACIAMAIIAKAKIAIALIAFAOQAFAUAAAMQgsAAg1ADIAAAGIACATIApABIABgOIAygBQgCALgGAJQgFAKgKAGQgIAGgLADQgLACgNAAQgQAAgOgEgAmaiOIgCgaIgmABIAAAZIAoAAgAqLhBIADhhIgBhaIA7gCIgBCUIBNgBIgCAugAgthDQAChBgBh8IAyACIgCC+gAk5hDIgoh/IA2gCQACASAGAdIAKAuQAEgXAUhCIAlAAQgEARgJAZQgWA1gKAeg");
this.shape_4.setTransform(100.4,-42.1);
this.instance_5 = new lib.lv6();
this.instance_5.setTransform(-168.4,-70.2,0.204,0.204);
this.shape_5 = new cjs.Shape();
this.shape_5.graphics.f("#000000").s().p("Aj3EDQgFgCgCgCQgDgDgCgFQgBgEAAgGIABgKIABABIAPADIgBANIANABIADgYIgehkIAZgBIAKApIAEAXIAEAAQAGgcAGgmIARADIgOA7IgLAyQgDATgJAHQgFAFgKAAQgFgBgEgBgAiqECIgDiEIAPABIADAKQAGgLAFgDIAHgEQAEgBAGAAQAIAAAGADQAHAEAEAHQAEAGACAHQACAIAAAIQAAAOgCAKQgDAKgEAHQgEAHgHAEQgGADgJAAQgGAAgLgGIAAAygAiXDDIAfgCIAAguIgfAAgApzDZIgegBIACiIQAYgBAXAAQAJAAAHABQAGABAFAEQAHAEADAGQADAGAAAIQAAAZgYAKIAAAGQAHABAGADQAFADAEAEQAEAFACAFQACAGAAAHQAAAJgDAGQgCAHgFAEQgEAEgHADQgHACgIAAIgdgCgApxDLIAhgDIgBgpIghgBgAp7CMIAigCIACgpIgjAAgAIkDZQgEgCgDgCQgDgDgBgEQgCgFAAgFQAAgHACgIQADgJAFgDQAEgDAMgDQALgCAUgCIgBgTQgRgFgFAAIgDAAIgDAAIgBAMIgNgBIgKABQAAgHADgFQADgGAGgDIAMgGQAHgCAHAAQAJAAAGACQAHACAEAFQAFAEACAHQACAGAAAJIgBAcQABAVACANIgHAAIgPACIgEgMQgIAHgHAEQgIADgIAAQgFAAgEgCgAI9CuIgNAFIAAAWIAYgCIABgaIgMABgAD2DXQgHgFgGgJQgEgHgCgJQgCgJAAgKQAAgJACgJQACgIAEgGQAFgIAHgEQAHgEAKAAQAFAAAEABQAFABADADIAIAGIAGAIQAEAIACAJQADAJAAALQAAAJgDAHQgDAIgFAHQgFAHgHAEQgHADgJAAQgJAAgIgEgAEVDEIgEg6IgXADIgEAxIAMAEQAGACAIAAIAFAAgAg5DXQgIgDgFgIQgFgGgCgJQgDgIAAgLQAAgKACgJQACgJAFgHQAFgIAHgEQAIgFAJAAQAGAAAEABIAIAEIAHAFIAGAIQAIAOAAAWQgYABgfACIACAZIAbAAIABgKIAXgBQgBAHgDAFQgDAGgEAEQgFAEgGACQgFACgHAAQgKAAgIgEgAgaCiIgBgbIgaABIAAAaIAbAAgAkqDZQgFgCgDgCQgEgDgCgFQgCgEAAgGIAAgNQAAgJAEgeIgMgCIABgPIAMAAIAKgfIAKgBIgBAcIAWABIgBAVIgWAAIgBA3IASAAIgBgMIALAAIAAAJIgBAKQgCAFgDACQgDADgEABQgFACgGAAQgGAAgEgCgAobDZQgEgCgDgCQgCgDgCgEQgBgFAAgFQAAgHACgIQACgJAFgDQAEgDAMgDQAMgCATgCIgBgTQgQgFgFAAIgEAAIgDAAIAAAMIgNgBIgKABQAAgHADgFQADgGAGgDIAMgGQAGgCAHAAQAJAAAHACQAGACAFAFQAEAEACAHQACAGAAAJIAAAcQABAVACANIgHAAIgQACIgEgMQgHAHgIAEQgHADgIAAQgFAAgFgCgAoBCuIgOAFIAAAWIAZgCIABgaIgMABgABvDXIACiJIAfAAIAgBEQAEAJAEAQIAEgBIgChYIAUAAIgBCEIgdAAIgXgwQgIgTgKgdIgEABIgBBggAJ4DVIABiJIAZACIgBCIgAHwDVIAAgDIAAgPQAAgZgCgaIgYAAIAABEIgagCIAAhAIgZABIgBBBIgYACIABgpIgBgwIATAAIABARQAGgMAFgEQAEgEAFgCQAEgCAFAAQAFAAAEACQADACADADQAEAFAEAKQAFgLAFgFQADgCAFgCIAKgBQAZAAABAgIAAA/gAE+DSIABg7IAAgaIAQAAIABALIAEABQADgJAFgFQAFgFAIAAQAFAAADACQAEACACADQACADABAFQACAFAAAGIgBATIgUAAIAAgVIgSAAIADBIQgSgEgIAAgAmZDVIAAiJIAZACIgBCIgAnGDVIAAiJIAZACIgBCIgAAVDTQgEgBgCgDQgFgFAAgJQAAgJAEgFQAFgFAIAAQAEAAADABQADADACADQADAGAAAJQAAAFgEAGQgEAGgGAAQgEAAgDgCgAAPCWQgEgFAAgJQAAgJAEgEQADgFAIAAQAIAAAEAGQAEAFAAAIQAAAIgEAIQgCACgIAAQgIABgFgGgACug5QgKgDgJgEQgLgGgIgJQgIgJgEgNQgDgIgCgNQgBgMAAgRQAAgbAFgUQAFgVAKgNQAKgOAPgGQAPgIATABQAPAAANADQAMAFAIAIQAJAJAEALQAFAMAAAPIgqABIgBgVIgtgDIAAAxQAIgHAJgDQAKgDAKAAQANAAAKAEQAKADAIAIQAHAIAEAJQAEAKAAAMQgCAWgDAKIgGAMQgEAGgEAEIgLAJIgMAGQgUAFgLAAQgLAAgKgCgAClhhIAtADIADgwIgxAAgAing8QgNgEgKgJIgKgKQgEgFgDgHQgDgHgBgGIgBgQQAAgLAFgTIAGgMQADgGAFgFIALgJIAMgGQAJgDAVgCQAJAAAIABQAIACAHADIAMAHIAKAKIAIAMIAFANQAFAUAAANQgsgBg1ADIAAAHIACATIApAAIABgOIAygBQgCAMgGAJQgFAKgKAFQgIAGgLADQgLADgNAAQgQAAgOgFgAh1iMIgCgaIgmABIAAAZIAoAAgAnMg8QgNgEgKgJIgKgKQgEgFgDgHQgDgHgBgGIgBgQQAAgLAFgTIAGgMQADgGAFgFIALgJIAMgGQAJgDAVgCQAJAAAIABQAIACAHADIAMAHIAKAKIAIAMIAFANQAFAUAAANQgsgBg1ADIAAAHIACATIApAAIABgOIAygBQgCAMgGAJQgFAKgKAFQgIAGgLADQgLADgNAAQgQAAgOgFgAmaiMIgCgaIgmABIAAAZIAoAAgAqLg+IADhiIgBhaIA7gBIgBCTIBNgBIgCAugAgthAQAChBgBh8IAyACIgCC+gAk5hAIgoiAIA2gCQACASAGAdIAKAvQAEgXAUhCIAlAAQgEARgJAYQgWA2gKAeg");
this.shape_5.setTransform(100.4,-42.4);
this.timeline.addTween(cjs.Tween.get({}).to({state:[{t:this.shape},{t:this.instance}]}).to({state:[{t:this.shape_1},{t:this.instance_1}]},1).to({state:[{t:this.shape_2},{t:this.instance_2}]},1).to({state:[{t:this.shape_3},{t:this.instance_3}]},1).to({state:[{t:this.shape_4},{t:this.instance_4}]},1).to({state:[{t:this.shape_5},{t:this.instance_5}]},1).wait(1));
}).prototype = p = new cjs.MovieClip();
p.nominalBounds = new cjs.Rectangle(-168.4,-70.2,334.6,140.4);
(lib.LeftButton = function() {
this.initialize();
// Layer 1
this.shape = new cjs.Shape();
this.shape.graphics.f().s("#000000").p("Ah8ACID5C+IAAl/Ij5C+g");
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f("#FFFCE2").s().p("Ah8ACIAAgDID5i+IAAF/g");
this.addChild(this.shape_1,this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-13.5,-20.2,27,40.6);
(lib.HoopSquare = function() {
this.initialize();
// Layer 1
this.shape = new cjs.Shape();
this.shape.graphics.f("#C27400").s().p("AgxAyIAAhjIBjAAIAABjg");
this.addChild(this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-5,-5,10,10);
(lib.HoopSensor = function() {
this.initialize();
// Layer 1
this.shape = new cjs.Shape();
this.shape.graphics.f("rgba(102,255,0,0.62)").s().p("AjGAdIAAg5IGNAAIAAA5g");
this.addChild(this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-20,-3,40,6);
(lib.HoopBoard = function() {
this.initialize();
// Layer 1
this.shape = new cjs.Shape();
this.shape.graphics.f().s("#CC6633").ss(1,1,1).p("AgxmOIBjAAIAAMdIhjAAg");
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f("#C27400").s().p("AgxGPIAAsdIBjAAIAAMdg");
this.addChild(this.shape_1,this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-6,-41,12,82);
(lib.Cross = function() {
this.initialize();
// Layer 1
this.shape = new cjs.Shape();
this.shape.graphics.f().s("#CC6633").ss(1,1,1).p("ApXhjISvAAIAADHIyvAAg");
this.shape.setTransform(0,0,1,1,90);
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f("#FFCC33").s().p("ApXBjIAAjFISvAAIAADFg");
this.shape_1.setTransform(0,0,1,1,90);
this.shape_2 = new cjs.Shape();
this.shape_2.graphics.f().s("#CC6633").ss(1,1,1).p("ApXhjISvAAIAADHIyvAAg");
this.shape_3 = new cjs.Shape();
this.shape_3.graphics.f("#FFCC33").s().p("ApXBjIAAjFISvAAIAADFg");
this.addChild(this.shape_3,this.shape_2,this.shape_1,this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-61,-61,122,122);
(lib.BrownSquare = function() {
this.initialize();
// Layer 1
this.shape = new cjs.Shape();
this.shape.graphics.f().s("#CC6633").ss(1,1,1).p("AhjhjIDHAAIAADHIjHAAg");
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f("#663333").s().p("AhiBjIAAjFIDFAAIAADFg");
this.addChild(this.shape_1,this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-11,-11,22,22);
(lib.BouncyBall = function() {
this.initialize();
// Layer 1
this.shape = new cjs.Shape();
this.shape.graphics.f().s("#FFFF00").ss(1,1,1).p("AguhXQAVgMAZAAQAaAAAVAMQANAHALALQAdAdAAAoQAAApgdAeQgLALgNAHQgVALgaAAQgZAAgVgMQgMgGgLgLQgegeAAgpQAAgoAegdQALgLAMgHIAACvAAvhXIAACw");
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f("#FFFF00").s().p("AguBYIAAivQAVgMAZABQAaAAAVALIAACwQgVALgagBQgZAAgVgLg");
this.shape_2 = new cjs.Shape();
this.shape_2.graphics.f("#FFCC00").s().p("AAuhXQAOAHALALQAdAdgBAoQABApgdAeQgLALgOAGgAhFBHQgegeABgpQgBgoAegdQALgLAMgHIAACvQgMgHgLgKg");
this.addChild(this.shape_2,this.shape_1,this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(-11,-11,22,22);
(lib.PowerArrow = function() {
this.initialize();
// Layer 1
this.powerBar = new lib.PowerBar();
this.powerBar.setTransform(10.2,0.3,1,1,90);
this.shape = new cjs.Shape();
this.shape.graphics.f("rgba(102,255,0,0.4)").s().p("ACoCJIpMAAIAAkRIJMAAIAAiaID9EiIj9EjgAk+AzIHjAAIAAhfInjAAg");
this.shape.setTransform(42.2,0);
this.addChild(this.shape,this.powerBar);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(0,-29.2,84.3,58.4);
(lib.LevelSelection = function() {
this.initialize();
// Layer 1
this.levels = new lib.Levels();
this.levels.setTransform(239.9,171.9);
// Layer 1
this.playButton = new lib.PlayButton();
this.playButton.setTransform(241.6,286.3,1,1,0,0,0,0,1.1);
this.leftButton = new lib.LeftButton();
this.leftButton.setTransform(22,191.7);
this.rightButton = new lib.RightButton();
this.rightButton.setTransform(456,191.7);
this.text = new cjs.Text("Ball Game", "39px 'Andola'");
this.text.lineHeight = 47;
this.text.setTransform(137.6,19.1);
this.shape = new cjs.Shape();
this.shape.graphics.f().s("#000000").ss(1,1,1).p("AewOuIAAFcMggBAAAQh3AIiWgCQhBgBjJgHQjDgHh6ADIjxAEQh1ACh2AAIoxAAIAAnKQgMikAEj6QAIkUAAiJIAA0NILMAAQCmgMEQAIQFVAJBcgCQAZAAA0ACQCZgCEzgGQEPgDC+AIQAZAAAxgCICWAAQCFgDDDABQBtABDZABIHbAAIAAUMQAKE+ABCXQACECgNDTg");
this.shape.setTransform(237.7,194.5);
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f().s("#000000").ss(1,1,1).p("AezhPIhnCfMg6aAAAIhkie");
this.shape_1.setTransform(237.7,331.4);
this.shape_2 = new cjs.Shape();
this.shape_2.graphics.f("#FFFFFF").s().p("AlRAAIgBAAIKlAAIh1AAg");
this.shape_2.setTransform(74.5,323.4);
this.shape_3 = new cjs.Shape();
this.shape_3.graphics.f("#FFFFFF").s().p("AwCADQhAAAjKgFMAoZAAAIAAABMggBAAAQhfAEh0AAIg7AAg");
this.shape_3.setTransform(305.2,323.7);
this.shape_4 = new cjs.Shape();
this.shape_4.graphics.f("#B1A793").s().p("A9OBQIhjieIIxAAQB1AAB1gBIIuAAQDJAHBBAAQCWACB3gIMAgBAAAIAAgBIADAAIhnCfg");
this.shape_4.setTransform(237.7,331.4);
this.shape_5 = new cjs.Shape();
this.shape_5.graphics.f("#EEDEC2").s().p("ApoUMQjDgHh6ADIjxAEIscAAIAAnIQgMikAEj6QAIkUAAiJIAA0NILMAAQCmgMEQAIQFVAJBcgCIBNACIHMgIQEPgDC+AIQAZAAAxgCICWAAQCFgDDDABIFGACIHbAAIAAUMQAKE+ABCXQACECgNDTIAAFag");
this.shape_5.setTransform(237.7,194.1);
this.shape_6 = new cjs.Shape();
this.shape_6.graphics.f("#DEF0E5").s().p("EglfAcIMAAAg4PMBK/AAAMAAAA4Pg");
this.shape_6.setTransform(240,180);
this.addChild(this.shape_6,this.shape_5,this.shape_4,this.shape_3,this.shape_2,this.shape_1,this.shape,this.text,this.rightButton,this.leftButton,this.playButton,this.levels);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(0,0,480,360);
})(lib = lib||{}, images = images||{}, createjs = createjs||{});
var lib, images, createjs;

View file

@ -0,0 +1,119 @@
var game = this.game || (this.game={});
var createjs = createjs || {};
var images = images||{};
;(function(game, cjs, b2d){
game.load = function() {
// load bitmap assets before starts the game
var loader = new createjs.LoadQueue(false);
loader.addEventListener("fileload", function(e){
if (e.item.type === "image") { images[e.item.id] = e.result; } // assgin to images object for assets.js to use
});
loader.addEventListener("complete", game.start);
loader.loadManifest(lib.properties.manifest);
};
game.start = function() {
console.log("Let's start.");
cjs.EventDispatcher.initialize(game); // allow the game object to listen and dispatch custom events.
game.canvas = document.getElementById('canvas');
game.stage = new cjs.Stage(game.canvas);
cjs.Touch.enable(game.stage, /*single touch=*/ true, /*allow default=*/ true);
cjs.Ticker.setFPS(60);
cjs.Ticker.addEventListener('tick', game.stage); // add game.stage to ticker make the stage.update call automatically.
cjs.Ticker.addEventListener('tick', game.tick); // gameloop
game.physics.createWorld();
game.view.initPowerIndicator();
var levelSelection = new lib.LevelSelection();
game.stage.addChild(levelSelection);
levelSelection.levels.stop();
levelSelection.rightButton.on('click', function(){
var next = levelSelection.levels.currentFrame + 1;
levelSelection.levels.gotoAndStop(next);
});
levelSelection.leftButton.on('click', function(){
var prev = levelSelection.levels.currentFrame - 1;
levelSelection.levels.gotoAndStop(prev);
});
var isPlaying = false;
levelSelection.playButton.on('click', function() {
levelSelection.parent.removeChild(levelSelection);
// game.physics.showDebugDraw();
game.score = 0;
game.currentLevel = game.levels[levelSelection.levels.currentFrame];
game.physics.createLevel();
game.view.showScoreBoard();
isPlaying = true;
});
game.tickWhenDown = 0;
game.tickWhenUp = 0;
game.stage.on('stagemousedown', function(e){
if (!isPlaying) { return; }
var position = game.physics.ballPosition();
game.view.showPowerIndicator(position.x, position.y);
var rotation = game.physics.launchAngle(e.stageX, e.stageY);
game.view.rotatePowerIndicator(rotation* 180 / Math.PI);
game.tickWhenDown = cjs.Ticker.getTicks();
game.view.updatePowerBar(0);
});
game.stage.on('stagemousemove', function(e){
if (!isPlaying) { return; }
var rotation = game.physics.launchAngle(e.stageX, e.stageY);
game.view.rotatePowerIndicator(rotation* 180 / Math.PI);
});
game.stage.on('stagemouseup', function(e){
if (!isPlaying) { return; }
game.view.hidePowerIndicator();
game.tickWhenUp = cjs.Ticker.getTicks();
ticksDiff = game.tickWhenUp - game.tickWhenDown;
game.physics.shootBall(e.stageX, e.stageY, ticksDiff);
setTimeout(game.spawnBall, 500);
});
};
game.increaseScore = function() {
game.score += 1;
game.view.updateScore();
console.log(game.score);
};
game.spawnBall = function() {
game.physics.spawnBall();
};
game.tick = function(){
if (cjs.Ticker.getPaused()) { return; } // run when not paused
game.physics.update();
// launch power preview
var ticksDiff = cjs.Ticker.getTicks() - game.tickWhenDown;
game.view.updatePowerBar(ticksDiff);
};
game.load();
}).call(this, game, createjs, Box2D);

View file

@ -0,0 +1,7 @@
var game = this.game || (this.game={});
var createjs = createjs || {};
;(function(game, cjs){
game.helper = game.helper || {};
}).call(this, game, createjs);

View file

@ -0,0 +1,126 @@
var game = this.game || (this.game={});
(function(game){
var degrees = Math.PI / 180
game.balls = {
'slow ball': {
className: 'SlowBall',
radius: 13,
density: 0.6,
friction: 0.8,
restitution: 0.1
},
'bouncy ball': {
className: 'BouncyBall',
radius: 10,
density: 1.1,
friction: 0.8,
restitution: 0.4
}
};
game.levels = [
{
hoopPosition: {x:50, y:150},
ballName: 'slow ball',
ballPosition: {x:350, y:250},
ballRandomRange: {x:60, y:60},
obstacles: []
},
{
hoopPosition: {x:50, y:200},
ballName: 'slow ball',
ballPosition: {x:350, y:200},
ballRandomRange: {x:160, y:0},
obstacles: []
},
{
hoopPosition: {x:50, y:160},
ballName: 'bouncy ball',
ballPosition: {x:350, y:250},
ballRandomRange: {x:80, y:80},
obstacles: []
},
{
hoopPosition: {x:50, y:160},
ballName: 'slow ball',
ballPosition: {x:350, y:250},
ballRandomRange: {x:80, y:80},
obstacles: [
{
type: 'rect',
graphicName: 'BrownSquare',
position: {x: 200, y: 160},
dimension: {width: 10, height:10},
angle: 0
},
{
type: 'rect',
graphicName: 'BrownSquare',
position: {x: 200, y: 120},
dimension: {width: 10, height:10},
angle: 0
},
]
},
{
hoopPosition: {x:50, y:160},
ballName: 'slow ball',
ballPosition: {x:350, y:250},
ballRandomRange: {x:80, y:80},
obstacles: [
{
type: 'cross',
graphicName: 'Cross',
position: {x: 165, y: 140},
length: 60,
width: 10,
enableMotor: true,
maxTorque: 25,
motorSpeed: 3.0
},
]
},
{
hoopPosition: {x:50, y:150},
ballName: 'slow ball',
ballPosition: {x:350, y:250},
ballRandomRange: {x:60, y:60},
obstacles: [
{
type: 'cross',
graphicName: 'Cross',
position: {x: 165, y: 140},
length: 60,
width: 10,
enableMotor: true,
maxTorque: 25,
motorSpeed: 3.0
},
{
type: 'rect',
graphicName: 'BrownSquare',
position: {x: 200, y: 55},
dimension: {width: 10, height:10},
angle: 0
},
{
type: 'rect',
graphicName: 'BrownSquare',
position: {x: 260, y: 100},
dimension: {width: 10, height:10},
angle: 0
},
{
type: 'rect',
graphicName: 'BrownSquare',
position: {x: 300, y: 100},
dimension: {width: 10, height:10},
angle: 0
}
]
}
];
game.currentLevel = game.levels[0]; // default the 1st level.
}).call(this, game);

View file

@ -0,0 +1,370 @@
var game = this.game || (this.game={});
var createjs = createjs || {};
;(function(game, cjs, b2d){
var b2Vec2 = Box2D.Common.Math.b2Vec2
, b2AABB = Box2D.Collision.b2AABB
, b2BodyDef = Box2D.Dynamics.b2BodyDef
, b2Body = Box2D.Dynamics.b2Body
, b2FixtureDef = Box2D.Dynamics.b2FixtureDef
, b2Fixture = Box2D.Dynamics.b2Fixture
, b2World = Box2D.Dynamics.b2World
, b2MassData = Box2D.Collision.Shapes.b2MassData
, b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape
, b2CircleShape = Box2D.Collision.Shapes.b2CircleShape
, b2DebugDraw = Box2D.Dynamics.b2DebugDraw
, b2MouseJointDef = Box2D.Dynamics.Joints.b2MouseJointDef
, b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef
;
var pxPerMeter = 30; // 30 pixels = 1 meter. Box3D uses meters and we use pixels.
var shouldDrawDebug = false;
var physics = game.physics = {};
physics.bodiesToBeRemove = [];
physics.createWorld = function() {
var gravity = new b2Vec2(0, 9.8);
this.world = new b2World(gravity, /*allow sleep= */ true);
};
physics.createLevel = function() {
var level = game.currentLevel;
this.createObstacles(level);
this.createHoop(level);
this.createWorldBoundary();
this.setupContactListener();
// the first ball
game.spawnBall();
};
physics.clearWorld = function() {
var body = this.world.GetBodyList();
while (body) {
var sprite = body.GetUserData();
if (sprite) {
sprite.parent.removeChild(sprite);
}
var b = body;
body = body.GetNext();
this.world.DestroyBody(b);
}
};
physics.createWorldBoundary = function() {
var bodyDef = new b2BodyDef;
var fixDef = new b2FixtureDef;
bodyDef.type = b2Body.b2_staticBody;
bodyDef.position.x = -800/pxPerMeter;
bodyDef.position.y = 500/pxPerMeter;
bodyDef.angle = 0;
fixDef.isSensor = true;
fixDef.shape = new b2PolygonShape();
fixDef.shape.SetAsBox(2000/pxPerMeter, 10/pxPerMeter);
body = this.world.CreateBody(bodyDef);
body.CreateFixture(fixDef);
};
physics.createObstacles = function(level) {
var bodyDef = new b2BodyDef;
var fixDef = new b2FixtureDef;
// default fixture
fixDef.density = 1.0;
fixDef.friction = 0.5;
fixDef.restitution = 0.2;
// obstacles
var body, sprite;
for(var i=0, len=level.obstacles.length; i<len; i++) {
var o = level.obstacles[i];
bodyDef.type = b2Body.b2_staticBody;
bodyDef.position.x = o.position.x/pxPerMeter;
bodyDef.position.y = o.position.y/pxPerMeter;
bodyDef.angle = o.angle;
if (o.type === 'rect') {
fixDef.shape = new b2PolygonShape();
fixDef.shape.SetAsBox(o.dimension.width/pxPerMeter, o.dimension.height/pxPerMeter);
body = this.world.CreateBody(bodyDef);
body.CreateFixture(fixDef);
game.view.addSpriteToBody(body, o.graphicName);
} else if (o.type === 'cross') {
this.createCross(o);
}
}
};
physics.createCross = function(obstacle) {
var bodyDef = new b2BodyDef;
var fixDef = new b2FixtureDef;
// default fixture
fixDef.density = 0.2;
fixDef.friction = 0.5;
fixDef.restitution = 0.2;
bodyDef.type = b2Body.b2_dynamicBody;
bodyDef.position.x = obstacle.position.x/pxPerMeter;
bodyDef.position.y = obstacle.position.y/pxPerMeter;
fixDef.shape = new b2PolygonShape();
fixDef.shape.SetAsBox(obstacle.length/pxPerMeter, obstacle.width/pxPerMeter);
var cross = this.world.CreateBody(bodyDef);
cross.CreateFixture(fixDef);
fixDef.shape.SetAsBox(obstacle.width/pxPerMeter, obstacle.length/pxPerMeter);
cross.CreateFixture(fixDef);
game.view.addSpriteToBody(cross, obstacle.graphicName);
// a circel as the spinning joint
bodyDef.type = b2Body.b2_staticBody;
fixDef.shape = new b2CircleShape(10/pxPerMeter);
var circle = this.world.CreateBody(bodyDef);
circle.CreateFixture(fixDef);
var revoluteJointDef = new b2RevoluteJointDef;
revoluteJointDef.bodyA = cross;
revoluteJointDef.bodyB = circle;
revoluteJointDef.collideConnected = false;
revoluteJointDef.maxMotorTorque = obstacle.maxTorque;
revoluteJointDef.motorSpeed = obstacle.motorSpeed;
revoluteJointDef.enableMotor = obstacle.enableMotor;
this.world.CreateJoint(revoluteJointDef);
};
physics.createHoop = function(level) {
var bodyDef = new b2BodyDef;
var fixDef = new b2FixtureDef;
// default fixture
fixDef.density = 1.0;
fixDef.friction = 0.5;
fixDef.restitution = 0.2;
var hoopX = level.hoopPosition.x;
var hoopY = level.hoopPosition.y;
// hoop
bodyDef.type = b2Body.b2_staticBody;
bodyDef.position.x = hoopX/pxPerMeter;
bodyDef.position.y = hoopY/pxPerMeter;
bodyDef.angle = 0;
fixDef.shape = new b2PolygonShape();
fixDef.shape.SetAsBox(5/pxPerMeter, 5/pxPerMeter);
var body = this.world.CreateBody(bodyDef);
body.CreateFixture(fixDef);
game.view.addSpriteToBody(body, 'HoopSquare');
bodyDef.type = b2Body.b2_staticBody;
bodyDef.position.x = (hoopX+45)/pxPerMeter;
bodyDef.position.y = hoopY/pxPerMeter;
bodyDef.angle = 0;
fixDef.shape = new b2PolygonShape();
fixDef.shape.SetAsBox(5/pxPerMeter, 5/pxPerMeter);
body = this.world.CreateBody(bodyDef);
body.CreateFixture(fixDef);
game.view.addSpriteToBody(body, 'HoopSquare');
// hoop board
bodyDef.type = b2Body.b2_staticBody;
bodyDef.position.x = (hoopX-5)/pxPerMeter;
bodyDef.position.y = (hoopY-40)/pxPerMeter;
bodyDef.angle = 0;
fixDef.shape = new b2PolygonShape();
fixDef.shape.SetAsBox(5/pxPerMeter, 40/pxPerMeter);
fixDef.restitution = 0.05;
var board = this.world.CreateBody(bodyDef);
board.CreateFixture(fixDef);
game.view.addSpriteToBody(board, 'HoopBoard');
// hoop sensor
bodyDef.type = b2Body.b2_staticBody;
bodyDef.position.x = (hoopX+20)/pxPerMeter;
bodyDef.position.y = hoopY/pxPerMeter;
bodyDef.angle = 0;
fixDef.isSensor = true;
fixDef.shape = new b2PolygonShape();
fixDef.shape.SetAsBox(20/pxPerMeter, 3/pxPerMeter);
body = this.world.CreateBody(bodyDef);
body.CreateFixture(fixDef);
game.view.addSpriteToBody(body, 'HoopSensor', 0);
};
physics.setupContactListener = function() {
// contact
var contactListener = new Box2D.Dynamics.b2ContactListener;
contactListener.BeginContact = function(contact, manifold) {
if (contact.GetFixtureA().IsSensor() || contact.GetFixtureB().IsSensor()) {
// is hoop sensor or world boundary?
var sensor = contact.GetFixtureA().GetBody();
var body = contact.GetFixtureB().GetBody();
if (contact.GetFixtureB().IsSensor()) {
sensor = contact.GetFixtureB().GetBody();
body = contact.GetFixtureA().GetBody();
}
// hoop sensor has sprite as user data
if (sensor.GetUserData() !== null) {
game.increaseScore();
} else {
physics.bodiesToBeRemove.push(body);
}
}
};
this.world.SetContactListener(contactListener);
};
physics.spawnBall = function() {
var level = game.currentLevel;
var ball = game.balls[level.ballName];
var bodyDef = new b2BodyDef;
var fixDef = new b2FixtureDef;
fixDef.density = ball.density;
fixDef.friction = ball.friction;
fixDef.restitution = ball.restitution;
bodyDef.type = b2Body.b2_staticBody;
var positionX = level.ballPosition.x + Math.random()*level.ballRandomRange.x - level.ballRandomRange.x/2;
var positionY = level.ballPosition.y + Math.random()*level.ballRandomRange.y - level.ballRandomRange.y/2;
bodyDef.position.x = positionX/pxPerMeter;
bodyDef.position.y = positionY/pxPerMeter;
fixDef.shape = new b2CircleShape(ball.radius/pxPerMeter);
this.ball = this.world.CreateBody(bodyDef);
this.ball.CreateFixture(fixDef);
game.view.addSpriteToBody(this.ball, ball.className);
};
physics.ballPosition = function(){
var pos = this.ball.GetPosition();
return {
x: pos.x * pxPerMeter,
y: pos.y * pxPerMeter
};
};
physics.launchAngle = function(stageX, stageY) {
var ballPos = this.ballPosition();
var diffX = stageX - ballPos.x;
var diffY = stageY - ballPos.y;
// Quadrant
var degreeAddition = 0; // Quadrant I
if (diffX < 0 && diffY > 0) {
degreeAddition = Math.PI; // Quadrant II
} else if (diffX < 0 && diffY < 0) {
degreeAddition = Math.PI; // Quadrant III
} else if (diffX > 0 && diffY < 0) {
degreeAddition = Math.PI * 2; // Quadrant IV
}
var theta = Math.atan(diffY / diffX) + degreeAddition;
return theta;
};
physics.shootBall = function(stageX, stageY, ticksDiff) {
this.ball.SetType(b2Body.b2_dynamicBody);
var theta = this.launchAngle(stageX, stageY);
var r = Math.log(ticksDiff) * 50; // power
var resultX = r * Math.cos(theta);
var resultY = r * Math.sin(theta);
this.ball.ApplyTorque(30); // rotate it
// shoot the ball
this.ball.ApplyImpulse(new b2Vec2(resultX/pxPerMeter, resultY/pxPerMeter), this.ball.GetWorldCenter());
this.ball = undefined;
};
physics.update = function() {
this.world.Step(1 / 60, 10, 10);
if (shouldDrawDebug) {
this.world.DrawDebugData();
}
this.world.ClearForces();
// draw sprites
var body = this.world.GetBodyList();
while (body) {
var sprite = body.GetUserData();
if (sprite) {
var position = body.GetWorldCenter();
sprite.x = position.x * pxPerMeter;
sprite.y = position.y * pxPerMeter;
sprite.rotation = body.GetAngle() * 180 / Math.PI; // rad to degree
}
body = body.GetNext();
}
// remove bodies
for (var i=0, len=this.bodiesToBeRemove.length; i<len; i++) {
var body = this.bodiesToBeRemove[i];
var sprite = body.GetUserData();
if (sprite) {
sprite.parent.removeChild(sprite);
}
this.world.DestroyBody(body);
}
this.bodiesToBeRemove.length = 0;
};
physics.showDebugDraw = function() {
shouldDrawDebug = true;
//setup debug draw
var debugDraw = new b2DebugDraw();
debugDraw.SetSprite(document.getElementById("debug-canvas").getContext("2d"));
debugDraw.SetDrawScale(pxPerMeter);
debugDraw.SetFillAlpha(0.3);
debugDraw.SetLineThickness(1.0);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
this.world.SetDebugDraw(debugDraw);
};
}).call(this, game, createjs, Box2D);

View file

@ -0,0 +1,50 @@
var game = this.game || (this.game={});
var createjs = createjs || {};
;(function(game, cjs){
game.view = game.view || {};
game.view.showScoreBoard = function(){
this.scoreBoard = new lib.ScoreBoard();
this.scoreBoard.x = 10;
this.scoreBoard.y = 10;
game.stage.addChild(this.scoreBoard);
};
game.view.updateScore = function() {
this.scoreBoard.textField.text = game.score + '';
};
game.view.addSpriteToBody = function(body, spriteName, index) {
var sprite = new lib[spriteName]();
sprite.x = -99;
if (index !== undefined) {
game.stage.addChildAt(sprite, index);
} else {
game.stage.addChild(sprite);
}
body.SetUserData(sprite);
};
game.view.initPowerIndicator = function() {
this.power = new lib.PowerArrow();
game.stage.addChild(this.power);
this.power.visible = false;
};
game.view.showPowerIndicator = function(x, y) {
this.power.visible = true;
this.power.x = x;
this.power.y = y;
};
game.view.hidePowerIndicator = function() {
this.power.visible = false;
};
game.view.rotatePowerIndicator = function(rotation) {
this.power.rotation = rotation;
};
game.view.updatePowerBar = function(value) {
this.power.powerBar.scaleY = Math.min(30, value);
};
}).call(this, game, createjs);

View file

@ -0,0 +1,70 @@
/* normalize */
body, h1, h2, p {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
/* page layout */
body {
background: #333;
color: ghostwhite;
}
.row {
width: 480px;
max-width: 100%;
margin: 0 auto;
}
/* Scenes */
#game {
width: 480px;
height: 360px;
max-width: 100%;
margin: 0 auto;
border-radius: 8px;
text-align: center;
position: relative;
background-color: #DEF0E5;
}
canvas {
position: absolute;
top: 0;
left: 0;
}
#hud {
position: absolute;
width: 100%;
height: 60px;
background: rgba(0, 0, 0, 0.5);
color: white;
}
.add-buttons {
position: absolute;
width: 100%;
height: 60px;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
}
.add-button {
display: inline-block;
width: 50px;
height: 50px;
background-color: rgba(255, 255, 255, 0.3);
color: white;
text-decoration: none;
text-align: center;
line-height: 50px;
cursor: pointer;
}
.add-button:hover {
background-color: rgba(255, 255, 255, 0.6);
}

View file

@ -0,0 +1,445 @@
var Box2D={};
(function(F,G){function K(){}if(!(Object.prototype.defineProperty instanceof Function)&&Object.prototype.__defineGetter__ instanceof Function&&Object.prototype.__defineSetter__ instanceof Function)Object.defineProperty=function(y,w,A){A.get instanceof Function&&y.__defineGetter__(w,A.get);A.set instanceof Function&&y.__defineSetter__(w,A.set)};F.inherit=function(y,w){K.prototype=w.prototype;y.prototype=new K;y.prototype.constructor=y};F.generateCallback=function(y,w){return function(){w.apply(y,arguments)}};
F.NVector=function(y){if(y===G)y=0;for(var w=Array(y||0),A=0;A<y;++A)w[A]=0;return w};F.is=function(y,w){if(y===null)return false;if(w instanceof Function&&y instanceof w)return true;if(y.constructor.__implements!=G&&y.constructor.__implements[w])return true;return false};F.parseUInt=function(y){return Math.abs(parseInt(y))}})(Box2D);var Vector=Array,Vector_a2j_Number=Box2D.NVector;if(typeof Box2D==="undefined")Box2D={};if(typeof Box2D.Collision==="undefined")Box2D.Collision={};
if(typeof Box2D.Collision.Shapes==="undefined")Box2D.Collision.Shapes={};if(typeof Box2D.Common==="undefined")Box2D.Common={};if(typeof Box2D.Common.Math==="undefined")Box2D.Common.Math={};if(typeof Box2D.Dynamics==="undefined")Box2D.Dynamics={};if(typeof Box2D.Dynamics.Contacts==="undefined")Box2D.Dynamics.Contacts={};if(typeof Box2D.Dynamics.Controllers==="undefined")Box2D.Dynamics.Controllers={};if(typeof Box2D.Dynamics.Joints==="undefined")Box2D.Dynamics.Joints={};
(function(){function F(){F.b2AABB.apply(this,arguments)}function G(){G.b2Bound.apply(this,arguments)}function K(){K.b2BoundValues.apply(this,arguments);this.constructor===K&&this.b2BoundValues.apply(this,arguments)}function y(){y.b2Collision.apply(this,arguments)}function w(){w.b2ContactID.apply(this,arguments);this.constructor===w&&this.b2ContactID.apply(this,arguments)}function A(){A.b2ContactPoint.apply(this,arguments)}function U(){U.b2Distance.apply(this,arguments)}function p(){p.b2DistanceInput.apply(this,
arguments)}function B(){B.b2DistanceOutput.apply(this,arguments)}function Q(){Q.b2DistanceProxy.apply(this,arguments)}function V(){V.b2DynamicTree.apply(this,arguments);this.constructor===V&&this.b2DynamicTree.apply(this,arguments)}function M(){M.b2DynamicTreeBroadPhase.apply(this,arguments)}function L(){L.b2DynamicTreeNode.apply(this,arguments)}function I(){I.b2DynamicTreePair.apply(this,arguments)}function W(){W.b2Manifold.apply(this,arguments);this.constructor===W&&this.b2Manifold.apply(this,arguments)}
function Y(){Y.b2ManifoldPoint.apply(this,arguments);this.constructor===Y&&this.b2ManifoldPoint.apply(this,arguments)}function k(){k.b2Point.apply(this,arguments)}function z(){z.b2RayCastInput.apply(this,arguments);this.constructor===z&&this.b2RayCastInput.apply(this,arguments)}function u(){u.b2RayCastOutput.apply(this,arguments)}function D(){D.b2Segment.apply(this,arguments)}function H(){H.b2SeparationFunction.apply(this,arguments)}function O(){O.b2Simplex.apply(this,arguments);this.constructor===
O&&this.b2Simplex.apply(this,arguments)}function E(){E.b2SimplexCache.apply(this,arguments)}function R(){R.b2SimplexVertex.apply(this,arguments)}function N(){N.b2TimeOfImpact.apply(this,arguments)}function S(){S.b2TOIInput.apply(this,arguments)}function aa(){aa.b2WorldManifold.apply(this,arguments);this.constructor===aa&&this.b2WorldManifold.apply(this,arguments)}function Z(){Z.ClipVertex.apply(this,arguments)}function d(){d.Features.apply(this,arguments)}function h(){h.b2CircleShape.apply(this,arguments);
this.constructor===h&&this.b2CircleShape.apply(this,arguments)}function l(){l.b2EdgeChainDef.apply(this,arguments);this.constructor===l&&this.b2EdgeChainDef.apply(this,arguments)}function j(){j.b2EdgeShape.apply(this,arguments);this.constructor===j&&this.b2EdgeShape.apply(this,arguments)}function o(){o.b2MassData.apply(this,arguments)}function q(){q.b2PolygonShape.apply(this,arguments);this.constructor===q&&this.b2PolygonShape.apply(this,arguments)}function n(){n.b2Shape.apply(this,arguments);this.constructor===
n&&this.b2Shape.apply(this,arguments)}function a(){a.b2Color.apply(this,arguments);this.constructor===a&&this.b2Color.apply(this,arguments)}function c(){c.b2Settings.apply(this,arguments)}function g(){g.b2Mat22.apply(this,arguments);this.constructor===g&&this.b2Mat22.apply(this,arguments)}function b(){b.b2Mat33.apply(this,arguments);this.constructor===b&&this.b2Mat33.apply(this,arguments)}function e(){e.b2Math.apply(this,arguments)}function f(){f.b2Sweep.apply(this,arguments)}function m(){m.b2Transform.apply(this,
arguments);this.constructor===m&&this.b2Transform.apply(this,arguments)}function r(){r.b2Vec2.apply(this,arguments);this.constructor===r&&this.b2Vec2.apply(this,arguments)}function s(){s.b2Vec3.apply(this,arguments);this.constructor===s&&this.b2Vec3.apply(this,arguments)}function v(){v.b2Body.apply(this,arguments);this.constructor===v&&this.b2Body.apply(this,arguments)}function t(){t.b2BodyDef.apply(this,arguments);this.constructor===t&&this.b2BodyDef.apply(this,arguments)}function x(){x.b2ContactFilter.apply(this,
arguments)}function C(){C.b2ContactImpulse.apply(this,arguments)}function J(){J.b2ContactListener.apply(this,arguments)}function T(){T.b2ContactManager.apply(this,arguments);this.constructor===T&&this.b2ContactManager.apply(this,arguments)}function P(){P.b2DebugDraw.apply(this,arguments);this.constructor===P&&this.b2DebugDraw.apply(this,arguments)}function X(){X.b2DestructionListener.apply(this,arguments)}function $(){$.b2FilterData.apply(this,arguments)}function ba(){ba.b2Fixture.apply(this,arguments);
this.constructor===ba&&this.b2Fixture.apply(this,arguments)}function ca(){ca.b2FixtureDef.apply(this,arguments);this.constructor===ca&&this.b2FixtureDef.apply(this,arguments)}function da(){da.b2Island.apply(this,arguments);this.constructor===da&&this.b2Island.apply(this,arguments)}function Fa(){Fa.b2TimeStep.apply(this,arguments)}function ea(){ea.b2World.apply(this,arguments);this.constructor===ea&&this.b2World.apply(this,arguments)}function Ga(){Ga.b2CircleContact.apply(this,arguments)}function fa(){fa.b2Contact.apply(this,
arguments);this.constructor===fa&&this.b2Contact.apply(this,arguments)}function ga(){ga.b2ContactConstraint.apply(this,arguments);this.constructor===ga&&this.b2ContactConstraint.apply(this,arguments)}function Ha(){Ha.b2ContactConstraintPoint.apply(this,arguments)}function Ia(){Ia.b2ContactEdge.apply(this,arguments)}function ha(){ha.b2ContactFactory.apply(this,arguments);this.constructor===ha&&this.b2ContactFactory.apply(this,arguments)}function Ja(){Ja.b2ContactRegister.apply(this,arguments)}function Ka(){Ka.b2ContactResult.apply(this,
arguments)}function ia(){ia.b2ContactSolver.apply(this,arguments);this.constructor===ia&&this.b2ContactSolver.apply(this,arguments)}function La(){La.b2EdgeAndCircleContact.apply(this,arguments)}function ja(){ja.b2NullContact.apply(this,arguments);this.constructor===ja&&this.b2NullContact.apply(this,arguments)}function Ma(){Ma.b2PolyAndCircleContact.apply(this,arguments)}function Na(){Na.b2PolyAndEdgeContact.apply(this,arguments)}function Oa(){Oa.b2PolygonContact.apply(this,arguments)}function ka(){ka.b2PositionSolverManifold.apply(this,
arguments);this.constructor===ka&&this.b2PositionSolverManifold.apply(this,arguments)}function Pa(){Pa.b2BuoyancyController.apply(this,arguments)}function Qa(){Qa.b2ConstantAccelController.apply(this,arguments)}function Ra(){Ra.b2ConstantForceController.apply(this,arguments)}function Sa(){Sa.b2Controller.apply(this,arguments)}function Ta(){Ta.b2ControllerEdge.apply(this,arguments)}function Ua(){Ua.b2GravityController.apply(this,arguments)}function Va(){Va.b2TensorDampingController.apply(this,arguments)}
function la(){la.b2DistanceJoint.apply(this,arguments);this.constructor===la&&this.b2DistanceJoint.apply(this,arguments)}function ma(){ma.b2DistanceJointDef.apply(this,arguments);this.constructor===ma&&this.b2DistanceJointDef.apply(this,arguments)}function na(){na.b2FrictionJoint.apply(this,arguments);this.constructor===na&&this.b2FrictionJoint.apply(this,arguments)}function oa(){oa.b2FrictionJointDef.apply(this,arguments);this.constructor===oa&&this.b2FrictionJointDef.apply(this,arguments)}function pa(){pa.b2GearJoint.apply(this,
arguments);this.constructor===pa&&this.b2GearJoint.apply(this,arguments)}function qa(){qa.b2GearJointDef.apply(this,arguments);this.constructor===qa&&this.b2GearJointDef.apply(this,arguments)}function Wa(){Wa.b2Jacobian.apply(this,arguments)}function ra(){ra.b2Joint.apply(this,arguments);this.constructor===ra&&this.b2Joint.apply(this,arguments)}function sa(){sa.b2JointDef.apply(this,arguments);this.constructor===sa&&this.b2JointDef.apply(this,arguments)}function Xa(){Xa.b2JointEdge.apply(this,arguments)}
function ta(){ta.b2LineJoint.apply(this,arguments);this.constructor===ta&&this.b2LineJoint.apply(this,arguments)}function ua(){ua.b2LineJointDef.apply(this,arguments);this.constructor===ua&&this.b2LineJointDef.apply(this,arguments)}function va(){va.b2MouseJoint.apply(this,arguments);this.constructor===va&&this.b2MouseJoint.apply(this,arguments)}function wa(){wa.b2MouseJointDef.apply(this,arguments);this.constructor===wa&&this.b2MouseJointDef.apply(this,arguments)}function xa(){xa.b2PrismaticJoint.apply(this,
arguments);this.constructor===xa&&this.b2PrismaticJoint.apply(this,arguments)}function ya(){ya.b2PrismaticJointDef.apply(this,arguments);this.constructor===ya&&this.b2PrismaticJointDef.apply(this,arguments)}function za(){za.b2PulleyJoint.apply(this,arguments);this.constructor===za&&this.b2PulleyJoint.apply(this,arguments)}function Aa(){Aa.b2PulleyJointDef.apply(this,arguments);this.constructor===Aa&&this.b2PulleyJointDef.apply(this,arguments)}function Ba(){Ba.b2RevoluteJoint.apply(this,arguments);
this.constructor===Ba&&this.b2RevoluteJoint.apply(this,arguments)}function Ca(){Ca.b2RevoluteJointDef.apply(this,arguments);this.constructor===Ca&&this.b2RevoluteJointDef.apply(this,arguments)}function Da(){Da.b2WeldJoint.apply(this,arguments);this.constructor===Da&&this.b2WeldJoint.apply(this,arguments)}function Ea(){Ea.b2WeldJointDef.apply(this,arguments);this.constructor===Ea&&this.b2WeldJointDef.apply(this,arguments)}Box2D.Collision.IBroadPhase="Box2D.Collision.IBroadPhase";Box2D.Collision.b2AABB=
F;Box2D.Collision.b2Bound=G;Box2D.Collision.b2BoundValues=K;Box2D.Collision.b2Collision=y;Box2D.Collision.b2ContactID=w;Box2D.Collision.b2ContactPoint=A;Box2D.Collision.b2Distance=U;Box2D.Collision.b2DistanceInput=p;Box2D.Collision.b2DistanceOutput=B;Box2D.Collision.b2DistanceProxy=Q;Box2D.Collision.b2DynamicTree=V;Box2D.Collision.b2DynamicTreeBroadPhase=M;Box2D.Collision.b2DynamicTreeNode=L;Box2D.Collision.b2DynamicTreePair=I;Box2D.Collision.b2Manifold=W;Box2D.Collision.b2ManifoldPoint=Y;Box2D.Collision.b2Point=
k;Box2D.Collision.b2RayCastInput=z;Box2D.Collision.b2RayCastOutput=u;Box2D.Collision.b2Segment=D;Box2D.Collision.b2SeparationFunction=H;Box2D.Collision.b2Simplex=O;Box2D.Collision.b2SimplexCache=E;Box2D.Collision.b2SimplexVertex=R;Box2D.Collision.b2TimeOfImpact=N;Box2D.Collision.b2TOIInput=S;Box2D.Collision.b2WorldManifold=aa;Box2D.Collision.ClipVertex=Z;Box2D.Collision.Features=d;Box2D.Collision.Shapes.b2CircleShape=h;Box2D.Collision.Shapes.b2EdgeChainDef=l;Box2D.Collision.Shapes.b2EdgeShape=j;Box2D.Collision.Shapes.b2MassData=
o;Box2D.Collision.Shapes.b2PolygonShape=q;Box2D.Collision.Shapes.b2Shape=n;Box2D.Common.b2internal="Box2D.Common.b2internal";Box2D.Common.b2Color=a;Box2D.Common.b2Settings=c;Box2D.Common.Math.b2Mat22=g;Box2D.Common.Math.b2Mat33=b;Box2D.Common.Math.b2Math=e;Box2D.Common.Math.b2Sweep=f;Box2D.Common.Math.b2Transform=m;Box2D.Common.Math.b2Vec2=r;Box2D.Common.Math.b2Vec3=s;Box2D.Dynamics.b2Body=v;Box2D.Dynamics.b2BodyDef=t;Box2D.Dynamics.b2ContactFilter=x;Box2D.Dynamics.b2ContactImpulse=C;Box2D.Dynamics.b2ContactListener=
J;Box2D.Dynamics.b2ContactManager=T;Box2D.Dynamics.b2DebugDraw=P;Box2D.Dynamics.b2DestructionListener=X;Box2D.Dynamics.b2FilterData=$;Box2D.Dynamics.b2Fixture=ba;Box2D.Dynamics.b2FixtureDef=ca;Box2D.Dynamics.b2Island=da;Box2D.Dynamics.b2TimeStep=Fa;Box2D.Dynamics.b2World=ea;Box2D.Dynamics.Contacts.b2CircleContact=Ga;Box2D.Dynamics.Contacts.b2Contact=fa;Box2D.Dynamics.Contacts.b2ContactConstraint=ga;Box2D.Dynamics.Contacts.b2ContactConstraintPoint=Ha;Box2D.Dynamics.Contacts.b2ContactEdge=Ia;Box2D.Dynamics.Contacts.b2ContactFactory=
ha;Box2D.Dynamics.Contacts.b2ContactRegister=Ja;Box2D.Dynamics.Contacts.b2ContactResult=Ka;Box2D.Dynamics.Contacts.b2ContactSolver=ia;Box2D.Dynamics.Contacts.b2EdgeAndCircleContact=La;Box2D.Dynamics.Contacts.b2NullContact=ja;Box2D.Dynamics.Contacts.b2PolyAndCircleContact=Ma;Box2D.Dynamics.Contacts.b2PolyAndEdgeContact=Na;Box2D.Dynamics.Contacts.b2PolygonContact=Oa;Box2D.Dynamics.Contacts.b2PositionSolverManifold=ka;Box2D.Dynamics.Controllers.b2BuoyancyController=Pa;Box2D.Dynamics.Controllers.b2ConstantAccelController=
Qa;Box2D.Dynamics.Controllers.b2ConstantForceController=Ra;Box2D.Dynamics.Controllers.b2Controller=Sa;Box2D.Dynamics.Controllers.b2ControllerEdge=Ta;Box2D.Dynamics.Controllers.b2GravityController=Ua;Box2D.Dynamics.Controllers.b2TensorDampingController=Va;Box2D.Dynamics.Joints.b2DistanceJoint=la;Box2D.Dynamics.Joints.b2DistanceJointDef=ma;Box2D.Dynamics.Joints.b2FrictionJoint=na;Box2D.Dynamics.Joints.b2FrictionJointDef=oa;Box2D.Dynamics.Joints.b2GearJoint=pa;Box2D.Dynamics.Joints.b2GearJointDef=qa;
Box2D.Dynamics.Joints.b2Jacobian=Wa;Box2D.Dynamics.Joints.b2Joint=ra;Box2D.Dynamics.Joints.b2JointDef=sa;Box2D.Dynamics.Joints.b2JointEdge=Xa;Box2D.Dynamics.Joints.b2LineJoint=ta;Box2D.Dynamics.Joints.b2LineJointDef=ua;Box2D.Dynamics.Joints.b2MouseJoint=va;Box2D.Dynamics.Joints.b2MouseJointDef=wa;Box2D.Dynamics.Joints.b2PrismaticJoint=xa;Box2D.Dynamics.Joints.b2PrismaticJointDef=ya;Box2D.Dynamics.Joints.b2PulleyJoint=za;Box2D.Dynamics.Joints.b2PulleyJointDef=Aa;Box2D.Dynamics.Joints.b2RevoluteJoint=
Ba;Box2D.Dynamics.Joints.b2RevoluteJointDef=Ca;Box2D.Dynamics.Joints.b2WeldJoint=Da;Box2D.Dynamics.Joints.b2WeldJointDef=Ea})();Box2D.postDefs=[];
(function(){var F=Box2D.Collision.Shapes.b2CircleShape,G=Box2D.Collision.Shapes.b2PolygonShape,K=Box2D.Collision.Shapes.b2Shape,y=Box2D.Common.b2Settings,w=Box2D.Common.Math.b2Math,A=Box2D.Common.Math.b2Sweep,U=Box2D.Common.Math.b2Transform,p=Box2D.Common.Math.b2Vec2,B=Box2D.Collision.b2AABB,Q=Box2D.Collision.b2Bound,V=Box2D.Collision.b2BoundValues,M=Box2D.Collision.b2Collision,L=Box2D.Collision.b2ContactID,I=Box2D.Collision.b2ContactPoint,W=Box2D.Collision.b2Distance,Y=Box2D.Collision.b2DistanceInput,
k=Box2D.Collision.b2DistanceOutput,z=Box2D.Collision.b2DistanceProxy,u=Box2D.Collision.b2DynamicTree,D=Box2D.Collision.b2DynamicTreeBroadPhase,H=Box2D.Collision.b2DynamicTreeNode,O=Box2D.Collision.b2DynamicTreePair,E=Box2D.Collision.b2Manifold,R=Box2D.Collision.b2ManifoldPoint,N=Box2D.Collision.b2Point,S=Box2D.Collision.b2RayCastInput,aa=Box2D.Collision.b2RayCastOutput,Z=Box2D.Collision.b2Segment,d=Box2D.Collision.b2SeparationFunction,h=Box2D.Collision.b2Simplex,l=Box2D.Collision.b2SimplexCache,j=
Box2D.Collision.b2SimplexVertex,o=Box2D.Collision.b2TimeOfImpact,q=Box2D.Collision.b2TOIInput,n=Box2D.Collision.b2WorldManifold,a=Box2D.Collision.ClipVertex,c=Box2D.Collision.Features,g=Box2D.Collision.IBroadPhase;B.b2AABB=function(){this.lowerBound=new p;this.upperBound=new p};B.prototype.IsValid=function(){var b=this.upperBound.y-this.lowerBound.y;return b=(b=this.upperBound.x-this.lowerBound.x>=0&&b>=0)&&this.lowerBound.IsValid()&&this.upperBound.IsValid()};B.prototype.GetCenter=function(){return new p((this.lowerBound.x+
this.upperBound.x)/2,(this.lowerBound.y+this.upperBound.y)/2)};B.prototype.GetExtents=function(){return new p((this.upperBound.x-this.lowerBound.x)/2,(this.upperBound.y-this.lowerBound.y)/2)};B.prototype.Contains=function(b){var e=true;return e=(e=(e=(e=e&&this.lowerBound.x<=b.lowerBound.x)&&this.lowerBound.y<=b.lowerBound.y)&&b.upperBound.x<=this.upperBound.x)&&b.upperBound.y<=this.upperBound.y};B.prototype.RayCast=function(b,e){var f=-Number.MAX_VALUE,m=Number.MAX_VALUE,r=e.p1.x,s=e.p1.y,v=e.p2.x-
e.p1.x,t=e.p2.y-e.p1.y,x=Math.abs(t),C=b.normal,J=0,T=0,P=J=0;P=0;if(Math.abs(v)<Number.MIN_VALUE){if(r<this.lowerBound.x||this.upperBound.x<r)return false}else{J=1/v;T=(this.lowerBound.x-r)*J;J=(this.upperBound.x-r)*J;P=-1;if(T>J){P=T;T=J;J=P;P=1}if(T>f){C.x=P;C.y=0;f=T}m=Math.min(m,J);if(f>m)return false}if(x<Number.MIN_VALUE){if(s<this.lowerBound.y||this.upperBound.y<s)return false}else{J=1/t;T=(this.lowerBound.y-s)*J;J=(this.upperBound.y-s)*J;P=-1;if(T>J){P=T;T=J;J=P;P=1}if(T>f){C.y=P;C.x=0;f=
T}m=Math.min(m,J);if(f>m)return false}b.fraction=f;return true};B.prototype.TestOverlap=function(b){var e=b.lowerBound.y-this.upperBound.y,f=this.lowerBound.y-b.upperBound.y;if(b.lowerBound.x-this.upperBound.x>0||e>0)return false;if(this.lowerBound.x-b.upperBound.x>0||f>0)return false;return true};B.Combine=function(b,e){var f=new B;f.Combine(b,e);return f};B.prototype.Combine=function(b,e){this.lowerBound.x=Math.min(b.lowerBound.x,e.lowerBound.x);this.lowerBound.y=Math.min(b.lowerBound.y,e.lowerBound.y);
this.upperBound.x=Math.max(b.upperBound.x,e.upperBound.x);this.upperBound.y=Math.max(b.upperBound.y,e.upperBound.y)};Q.b2Bound=function(){};Q.prototype.IsLower=function(){return(this.value&1)==0};Q.prototype.IsUpper=function(){return(this.value&1)==1};Q.prototype.Swap=function(b){var e=this.value,f=this.proxy,m=this.stabbingCount;this.value=b.value;this.proxy=b.proxy;this.stabbingCount=b.stabbingCount;b.value=e;b.proxy=f;b.stabbingCount=m};V.b2BoundValues=function(){};V.prototype.b2BoundValues=function(){this.lowerValues=
new Vector_a2j_Number;this.lowerValues[0]=0;this.lowerValues[1]=0;this.upperValues=new Vector_a2j_Number;this.upperValues[0]=0;this.upperValues[1]=0};M.b2Collision=function(){};M.ClipSegmentToLine=function(b,e,f,m){if(m===undefined)m=0;var r,s=0;r=e[0];var v=r.v;r=e[1];var t=r.v,x=f.x*v.x+f.y*v.y-m;r=f.x*t.x+f.y*t.y-m;x<=0&&b[s++].Set(e[0]);r<=0&&b[s++].Set(e[1]);if(x*r<0){f=x/(x-r);r=b[s];r=r.v;r.x=v.x+f*(t.x-v.x);r.y=v.y+f*(t.y-v.y);r=b[s];r.id=(x>0?e[0]:e[1]).id;++s}return s};M.EdgeSeparation=
function(b,e,f,m,r){if(f===undefined)f=0;parseInt(b.m_vertexCount);var s=b.m_vertices;b=b.m_normals;var v=parseInt(m.m_vertexCount),t=m.m_vertices,x,C;x=e.R;C=b[f];b=x.col1.x*C.x+x.col2.x*C.y;m=x.col1.y*C.x+x.col2.y*C.y;x=r.R;var J=x.col1.x*b+x.col1.y*m;x=x.col2.x*b+x.col2.y*m;for(var T=0,P=Number.MAX_VALUE,X=0;X<v;++X){C=t[X];C=C.x*J+C.y*x;if(C<P){P=C;T=X}}C=s[f];x=e.R;f=e.position.x+(x.col1.x*C.x+x.col2.x*C.y);e=e.position.y+(x.col1.y*C.x+x.col2.y*C.y);C=t[T];x=r.R;s=r.position.x+(x.col1.x*C.x+
x.col2.x*C.y);r=r.position.y+(x.col1.y*C.x+x.col2.y*C.y);s-=f;r-=e;return s*b+r*m};M.FindMaxSeparation=function(b,e,f,m,r){var s=parseInt(e.m_vertexCount),v=e.m_normals,t,x;x=r.R;t=m.m_centroid;var C=r.position.x+(x.col1.x*t.x+x.col2.x*t.y),J=r.position.y+(x.col1.y*t.x+x.col2.y*t.y);x=f.R;t=e.m_centroid;C-=f.position.x+(x.col1.x*t.x+x.col2.x*t.y);J-=f.position.y+(x.col1.y*t.x+x.col2.y*t.y);x=C*f.R.col1.x+J*f.R.col1.y;J=C*f.R.col2.x+J*f.R.col2.y;C=0;for(var T=-Number.MAX_VALUE,P=0;P<s;++P){t=v[P];
t=t.x*x+t.y*J;if(t>T){T=t;C=P}}v=M.EdgeSeparation(e,f,C,m,r);t=parseInt(C-1>=0?C-1:s-1);x=M.EdgeSeparation(e,f,t,m,r);J=parseInt(C+1<s?C+1:0);T=M.EdgeSeparation(e,f,J,m,r);var X=P=0,$=0;if(x>v&&x>T){$=-1;P=t;X=x}else if(T>v){$=1;P=J;X=T}else{b[0]=C;return v}for(;;){C=$==-1?P-1>=0?P-1:s-1:P+1<s?P+1:0;v=M.EdgeSeparation(e,f,C,m,r);if(v>X){P=C;X=v}else break}b[0]=P;return X};M.FindIncidentEdge=function(b,e,f,m,r,s){if(m===undefined)m=0;parseInt(e.m_vertexCount);var v=e.m_normals,t=parseInt(r.m_vertexCount);
e=r.m_vertices;r=r.m_normals;var x;x=f.R;f=v[m];v=x.col1.x*f.x+x.col2.x*f.y;var C=x.col1.y*f.x+x.col2.y*f.y;x=s.R;f=x.col1.x*v+x.col1.y*C;C=x.col2.x*v+x.col2.y*C;v=f;x=0;for(var J=Number.MAX_VALUE,T=0;T<t;++T){f=r[T];f=v*f.x+C*f.y;if(f<J){J=f;x=T}}r=parseInt(x);v=parseInt(r+1<t?r+1:0);t=b[0];f=e[r];x=s.R;t.v.x=s.position.x+(x.col1.x*f.x+x.col2.x*f.y);t.v.y=s.position.y+(x.col1.y*f.x+x.col2.y*f.y);t.id.features.referenceEdge=m;t.id.features.incidentEdge=r;t.id.features.incidentVertex=0;t=b[1];f=e[v];
x=s.R;t.v.x=s.position.x+(x.col1.x*f.x+x.col2.x*f.y);t.v.y=s.position.y+(x.col1.y*f.x+x.col2.y*f.y);t.id.features.referenceEdge=m;t.id.features.incidentEdge=v;t.id.features.incidentVertex=1};M.MakeClipPointVector=function(){var b=new Vector(2);b[0]=new a;b[1]=new a;return b};M.CollidePolygons=function(b,e,f,m,r){var s;b.m_pointCount=0;var v=e.m_radius+m.m_radius;s=0;M.s_edgeAO[0]=s;var t=M.FindMaxSeparation(M.s_edgeAO,e,f,m,r);s=M.s_edgeAO[0];if(!(t>v)){var x=0;M.s_edgeBO[0]=x;var C=M.FindMaxSeparation(M.s_edgeBO,
m,r,e,f);x=M.s_edgeBO[0];if(!(C>v)){var J=0,T=0;if(C>0.98*t+0.0010){t=m;m=e;e=r;f=f;J=x;b.m_type=E.e_faceB;T=1}else{t=e;m=m;e=f;f=r;J=s;b.m_type=E.e_faceA;T=0}s=M.s_incidentEdge;M.FindIncidentEdge(s,t,e,J,m,f);x=parseInt(t.m_vertexCount);r=t.m_vertices;t=r[J];var P;P=J+1<x?r[parseInt(J+1)]:r[0];J=M.s_localTangent;J.Set(P.x-t.x,P.y-t.y);J.Normalize();r=M.s_localNormal;r.x=J.y;r.y=-J.x;m=M.s_planePoint;m.Set(0.5*(t.x+P.x),0.5*(t.y+P.y));C=M.s_tangent;x=e.R;C.x=x.col1.x*J.x+x.col2.x*J.y;C.y=x.col1.y*
J.x+x.col2.y*J.y;var X=M.s_tangent2;X.x=-C.x;X.y=-C.y;J=M.s_normal;J.x=C.y;J.y=-C.x;var $=M.s_v11,ba=M.s_v12;$.x=e.position.x+(x.col1.x*t.x+x.col2.x*t.y);$.y=e.position.y+(x.col1.y*t.x+x.col2.y*t.y);ba.x=e.position.x+(x.col1.x*P.x+x.col2.x*P.y);ba.y=e.position.y+(x.col1.y*P.x+x.col2.y*P.y);e=J.x*$.x+J.y*$.y;x=C.x*ba.x+C.y*ba.y+v;P=M.s_clipPoints1;t=M.s_clipPoints2;ba=0;ba=M.ClipSegmentToLine(P,s,X,-C.x*$.x-C.y*$.y+v);if(!(ba<2)){ba=M.ClipSegmentToLine(t,P,C,x);if(!(ba<2)){b.m_localPlaneNormal.SetV(r);
b.m_localPoint.SetV(m);for(m=r=0;m<y.b2_maxManifoldPoints;++m){s=t[m];if(J.x*s.v.x+J.y*s.v.y-e<=v){C=b.m_points[r];x=f.R;X=s.v.x-f.position.x;$=s.v.y-f.position.y;C.m_localPoint.x=X*x.col1.x+$*x.col1.y;C.m_localPoint.y=X*x.col2.x+$*x.col2.y;C.m_id.Set(s.id);C.m_id.features.flip=T;++r}}b.m_pointCount=r}}}}};M.CollideCircles=function(b,e,f,m,r){b.m_pointCount=0;var s,v;s=f.R;v=e.m_p;var t=f.position.x+(s.col1.x*v.x+s.col2.x*v.y);f=f.position.y+(s.col1.y*v.x+s.col2.y*v.y);s=r.R;v=m.m_p;t=r.position.x+
(s.col1.x*v.x+s.col2.x*v.y)-t;r=r.position.y+(s.col1.y*v.x+s.col2.y*v.y)-f;s=e.m_radius+m.m_radius;if(!(t*t+r*r>s*s)){b.m_type=E.e_circles;b.m_localPoint.SetV(e.m_p);b.m_localPlaneNormal.SetZero();b.m_pointCount=1;b.m_points[0].m_localPoint.SetV(m.m_p);b.m_points[0].m_id.key=0}};M.CollidePolygonAndCircle=function(b,e,f,m,r){var s=b.m_pointCount=0,v=0,t,x;x=r.R;t=m.m_p;var C=r.position.y+(x.col1.y*t.x+x.col2.y*t.y);s=r.position.x+(x.col1.x*t.x+x.col2.x*t.y)-f.position.x;v=C-f.position.y;x=f.R;f=s*
x.col1.x+v*x.col1.y;x=s*x.col2.x+v*x.col2.y;var J=0;C=-Number.MAX_VALUE;r=e.m_radius+m.m_radius;var T=parseInt(e.m_vertexCount),P=e.m_vertices;e=e.m_normals;for(var X=0;X<T;++X){t=P[X];s=f-t.x;v=x-t.y;t=e[X];s=t.x*s+t.y*v;if(s>r)return;if(s>C){C=s;J=X}}s=parseInt(J);v=parseInt(s+1<T?s+1:0);t=P[s];P=P[v];if(C<Number.MIN_VALUE){b.m_pointCount=1;b.m_type=E.e_faceA;b.m_localPlaneNormal.SetV(e[J]);b.m_localPoint.x=0.5*(t.x+P.x);b.m_localPoint.y=0.5*(t.y+P.y)}else{C=(f-P.x)*(t.x-P.x)+(x-P.y)*(t.y-P.y);
if((f-t.x)*(P.x-t.x)+(x-t.y)*(P.y-t.y)<=0){if((f-t.x)*(f-t.x)+(x-t.y)*(x-t.y)>r*r)return;b.m_pointCount=1;b.m_type=E.e_faceA;b.m_localPlaneNormal.x=f-t.x;b.m_localPlaneNormal.y=x-t.y;b.m_localPlaneNormal.Normalize();b.m_localPoint.SetV(t)}else if(C<=0){if((f-P.x)*(f-P.x)+(x-P.y)*(x-P.y)>r*r)return;b.m_pointCount=1;b.m_type=E.e_faceA;b.m_localPlaneNormal.x=f-P.x;b.m_localPlaneNormal.y=x-P.y;b.m_localPlaneNormal.Normalize();b.m_localPoint.SetV(P)}else{J=0.5*(t.x+P.x);t=0.5*(t.y+P.y);C=(f-J)*e[s].x+
(x-t)*e[s].y;if(C>r)return;b.m_pointCount=1;b.m_type=E.e_faceA;b.m_localPlaneNormal.x=e[s].x;b.m_localPlaneNormal.y=e[s].y;b.m_localPlaneNormal.Normalize();b.m_localPoint.Set(J,t)}}b.m_points[0].m_localPoint.SetV(m.m_p);b.m_points[0].m_id.key=0};M.TestOverlap=function(b,e){var f=e.lowerBound,m=b.upperBound,r=f.x-m.x,s=f.y-m.y;f=b.lowerBound;m=e.upperBound;var v=f.y-m.y;if(r>0||s>0)return false;if(f.x-m.x>0||v>0)return false;return true};Box2D.postDefs.push(function(){Box2D.Collision.b2Collision.s_incidentEdge=
M.MakeClipPointVector();Box2D.Collision.b2Collision.s_clipPoints1=M.MakeClipPointVector();Box2D.Collision.b2Collision.s_clipPoints2=M.MakeClipPointVector();Box2D.Collision.b2Collision.s_edgeAO=new Vector_a2j_Number(1);Box2D.Collision.b2Collision.s_edgeBO=new Vector_a2j_Number(1);Box2D.Collision.b2Collision.s_localTangent=new p;Box2D.Collision.b2Collision.s_localNormal=new p;Box2D.Collision.b2Collision.s_planePoint=new p;Box2D.Collision.b2Collision.s_normal=new p;Box2D.Collision.b2Collision.s_tangent=
new p;Box2D.Collision.b2Collision.s_tangent2=new p;Box2D.Collision.b2Collision.s_v11=new p;Box2D.Collision.b2Collision.s_v12=new p;Box2D.Collision.b2Collision.b2CollidePolyTempVec=new p;Box2D.Collision.b2Collision.b2_nullFeature=255});L.b2ContactID=function(){this.features=new c};L.prototype.b2ContactID=function(){this.features._m_id=this};L.prototype.Set=function(b){this.key=b._key};L.prototype.Copy=function(){var b=new L;b.key=this.key;return b};Object.defineProperty(L.prototype,"key",{enumerable:false,
configurable:true,get:function(){return this._key}});Object.defineProperty(L.prototype,"key",{enumerable:false,configurable:true,set:function(b){if(b===undefined)b=0;this._key=b;this.features._referenceEdge=this._key&255;this.features._incidentEdge=(this._key&65280)>>8&255;this.features._incidentVertex=(this._key&16711680)>>16&255;this.features._flip=(this._key&4278190080)>>24&255}});I.b2ContactPoint=function(){this.position=new p;this.velocity=new p;this.normal=new p;this.id=new L};W.b2Distance=
function(){};W.Distance=function(b,e,f){++W.b2_gjkCalls;var m=f.proxyA,r=f.proxyB,s=f.transformA,v=f.transformB,t=W.s_simplex;t.ReadCache(e,m,s,r,v);var x=t.m_vertices,C=W.s_saveA,J=W.s_saveB,T=0;t.GetClosestPoint().LengthSquared();for(var P=0,X,$=0;$<20;){T=t.m_count;for(P=0;P<T;P++){C[P]=x[P].indexA;J[P]=x[P].indexB}switch(t.m_count){case 1:break;case 2:t.Solve2();break;case 3:t.Solve3();break;default:y.b2Assert(false)}if(t.m_count==3)break;X=t.GetClosestPoint();X.LengthSquared();P=t.GetSearchDirection();
if(P.LengthSquared()<Number.MIN_VALUE*Number.MIN_VALUE)break;X=x[t.m_count];X.indexA=m.GetSupport(w.MulTMV(s.R,P.GetNegative()));X.wA=w.MulX(s,m.GetVertex(X.indexA));X.indexB=r.GetSupport(w.MulTMV(v.R,P));X.wB=w.MulX(v,r.GetVertex(X.indexB));X.w=w.SubtractVV(X.wB,X.wA);++$;++W.b2_gjkIters;var ba=false;for(P=0;P<T;P++)if(X.indexA==C[P]&&X.indexB==J[P]){ba=true;break}if(ba)break;++t.m_count}W.b2_gjkMaxIters=w.Max(W.b2_gjkMaxIters,$);t.GetWitnessPoints(b.pointA,b.pointB);b.distance=w.SubtractVV(b.pointA,
b.pointB).Length();b.iterations=$;t.WriteCache(e);if(f.useRadii){e=m.m_radius;r=r.m_radius;if(b.distance>e+r&&b.distance>Number.MIN_VALUE){b.distance-=e+r;f=w.SubtractVV(b.pointB,b.pointA);f.Normalize();b.pointA.x+=e*f.x;b.pointA.y+=e*f.y;b.pointB.x-=r*f.x;b.pointB.y-=r*f.y}else{X=new p;X.x=0.5*(b.pointA.x+b.pointB.x);X.y=0.5*(b.pointA.y+b.pointB.y);b.pointA.x=b.pointB.x=X.x;b.pointA.y=b.pointB.y=X.y;b.distance=0}}};Box2D.postDefs.push(function(){Box2D.Collision.b2Distance.s_simplex=new h;Box2D.Collision.b2Distance.s_saveA=
new Vector_a2j_Number(3);Box2D.Collision.b2Distance.s_saveB=new Vector_a2j_Number(3)});Y.b2DistanceInput=function(){};k.b2DistanceOutput=function(){this.pointA=new p;this.pointB=new p};z.b2DistanceProxy=function(){};z.prototype.Set=function(b){switch(b.GetType()){case K.e_circleShape:b=b instanceof F?b:null;this.m_vertices=new Vector(1,true);this.m_vertices[0]=b.m_p;this.m_count=1;this.m_radius=b.m_radius;break;case K.e_polygonShape:b=b instanceof G?b:null;this.m_vertices=b.m_vertices;this.m_count=
b.m_vertexCount;this.m_radius=b.m_radius;break;default:y.b2Assert(false)}};z.prototype.GetSupport=function(b){for(var e=0,f=this.m_vertices[0].x*b.x+this.m_vertices[0].y*b.y,m=1;m<this.m_count;++m){var r=this.m_vertices[m].x*b.x+this.m_vertices[m].y*b.y;if(r>f){e=m;f=r}}return e};z.prototype.GetSupportVertex=function(b){for(var e=0,f=this.m_vertices[0].x*b.x+this.m_vertices[0].y*b.y,m=1;m<this.m_count;++m){var r=this.m_vertices[m].x*b.x+this.m_vertices[m].y*b.y;if(r>f){e=m;f=r}}return this.m_vertices[e]};
z.prototype.GetVertexCount=function(){return this.m_count};z.prototype.GetVertex=function(b){if(b===undefined)b=0;y.b2Assert(0<=b&&b<this.m_count);return this.m_vertices[b]};u.b2DynamicTree=function(){};u.prototype.b2DynamicTree=function(){this.m_freeList=this.m_root=null;this.m_insertionCount=this.m_path=0};u.prototype.CreateProxy=function(b,e){var f=this.AllocateNode(),m=y.b2_aabbExtension,r=y.b2_aabbExtension;f.aabb.lowerBound.x=b.lowerBound.x-m;f.aabb.lowerBound.y=b.lowerBound.y-r;f.aabb.upperBound.x=
b.upperBound.x+m;f.aabb.upperBound.y=b.upperBound.y+r;f.userData=e;this.InsertLeaf(f);return f};u.prototype.DestroyProxy=function(b){this.RemoveLeaf(b);this.FreeNode(b)};u.prototype.MoveProxy=function(b,e,f){y.b2Assert(b.IsLeaf());if(b.aabb.Contains(e))return false;this.RemoveLeaf(b);var m=y.b2_aabbExtension+y.b2_aabbMultiplier*(f.x>0?f.x:-f.x);f=y.b2_aabbExtension+y.b2_aabbMultiplier*(f.y>0?f.y:-f.y);b.aabb.lowerBound.x=e.lowerBound.x-m;b.aabb.lowerBound.y=e.lowerBound.y-f;b.aabb.upperBound.x=e.upperBound.x+
m;b.aabb.upperBound.y=e.upperBound.y+f;this.InsertLeaf(b);return true};u.prototype.Rebalance=function(b){if(b===undefined)b=0;if(this.m_root!=null)for(var e=0;e<b;e++){for(var f=this.m_root,m=0;f.IsLeaf()==false;){f=this.m_path>>m&1?f.child2:f.child1;m=m+1&31}++this.m_path;this.RemoveLeaf(f);this.InsertLeaf(f)}};u.prototype.GetFatAABB=function(b){return b.aabb};u.prototype.GetUserData=function(b){return b.userData};u.prototype.Query=function(b,e){if(this.m_root!=null){var f=new Vector,m=0;for(f[m++]=
this.m_root;m>0;){var r=f[--m];if(r.aabb.TestOverlap(e))if(r.IsLeaf()){if(!b(r))break}else{f[m++]=r.child1;f[m++]=r.child2}}}};u.prototype.RayCast=function(b,e){if(this.m_root!=null){var f=e.p1,m=e.p2,r=w.SubtractVV(f,m);r.Normalize();r=w.CrossFV(1,r);var s=w.AbsV(r),v=e.maxFraction,t=new B,x=0,C=0;x=f.x+v*(m.x-f.x);C=f.y+v*(m.y-f.y);t.lowerBound.x=Math.min(f.x,x);t.lowerBound.y=Math.min(f.y,C);t.upperBound.x=Math.max(f.x,x);t.upperBound.y=Math.max(f.y,C);var J=new Vector,T=0;for(J[T++]=this.m_root;T>
0;){v=J[--T];if(v.aabb.TestOverlap(t)!=false){x=v.aabb.GetCenter();C=v.aabb.GetExtents();if(!(Math.abs(r.x*(f.x-x.x)+r.y*(f.y-x.y))-s.x*C.x-s.y*C.y>0))if(v.IsLeaf()){x=new S;x.p1=e.p1;x.p2=e.p2;x.maxFraction=e.maxFraction;v=b(x,v);if(v==0)break;if(v>0){x=f.x+v*(m.x-f.x);C=f.y+v*(m.y-f.y);t.lowerBound.x=Math.min(f.x,x);t.lowerBound.y=Math.min(f.y,C);t.upperBound.x=Math.max(f.x,x);t.upperBound.y=Math.max(f.y,C)}}else{J[T++]=v.child1;J[T++]=v.child2}}}}};u.prototype.AllocateNode=function(){if(this.m_freeList){var b=
this.m_freeList;this.m_freeList=b.parent;b.parent=null;b.child1=null;b.child2=null;return b}return new H};u.prototype.FreeNode=function(b){b.parent=this.m_freeList;this.m_freeList=b};u.prototype.InsertLeaf=function(b){++this.m_insertionCount;if(this.m_root==null){this.m_root=b;this.m_root.parent=null}else{var e=b.aabb.GetCenter(),f=this.m_root;if(f.IsLeaf()==false){do{var m=f.child1;f=f.child2;f=Math.abs((m.aabb.lowerBound.x+m.aabb.upperBound.x)/2-e.x)+Math.abs((m.aabb.lowerBound.y+m.aabb.upperBound.y)/
2-e.y)<Math.abs((f.aabb.lowerBound.x+f.aabb.upperBound.x)/2-e.x)+Math.abs((f.aabb.lowerBound.y+f.aabb.upperBound.y)/2-e.y)?m:f}while(f.IsLeaf()==false)}e=f.parent;m=this.AllocateNode();m.parent=e;m.userData=null;m.aabb.Combine(b.aabb,f.aabb);if(e){if(f.parent.child1==f)e.child1=m;else e.child2=m;m.child1=f;m.child2=b;f.parent=m;b.parent=m;do{if(e.aabb.Contains(m.aabb))break;e.aabb.Combine(e.child1.aabb,e.child2.aabb);m=e;e=e.parent}while(e)}else{m.child1=f;m.child2=b;f.parent=m;this.m_root=b.parent=
m}}};u.prototype.RemoveLeaf=function(b){if(b==this.m_root)this.m_root=null;else{var e=b.parent,f=e.parent;b=e.child1==b?e.child2:e.child1;if(f){if(f.child1==e)f.child1=b;else f.child2=b;b.parent=f;for(this.FreeNode(e);f;){e=f.aabb;f.aabb=B.Combine(f.child1.aabb,f.child2.aabb);if(e.Contains(f.aabb))break;f=f.parent}}else{this.m_root=b;b.parent=null;this.FreeNode(e)}}};D.b2DynamicTreeBroadPhase=function(){this.m_tree=new u;this.m_moveBuffer=new Vector;this.m_pairBuffer=new Vector;this.m_pairCount=0};
D.prototype.CreateProxy=function(b,e){var f=this.m_tree.CreateProxy(b,e);++this.m_proxyCount;this.BufferMove(f);return f};D.prototype.DestroyProxy=function(b){this.UnBufferMove(b);--this.m_proxyCount;this.m_tree.DestroyProxy(b)};D.prototype.MoveProxy=function(b,e,f){this.m_tree.MoveProxy(b,e,f)&&this.BufferMove(b)};D.prototype.TestOverlap=function(b,e){var f=this.m_tree.GetFatAABB(b),m=this.m_tree.GetFatAABB(e);return f.TestOverlap(m)};D.prototype.GetUserData=function(b){return this.m_tree.GetUserData(b)};
D.prototype.GetFatAABB=function(b){return this.m_tree.GetFatAABB(b)};D.prototype.GetProxyCount=function(){return this.m_proxyCount};D.prototype.UpdatePairs=function(b){var e=this;var f=e.m_pairCount=0,m;for(f=0;f<e.m_moveBuffer.length;++f){m=e.m_moveBuffer[f];var r=e.m_tree.GetFatAABB(m);e.m_tree.Query(function(t){if(t==m)return true;if(e.m_pairCount==e.m_pairBuffer.length)e.m_pairBuffer[e.m_pairCount]=new O;var x=e.m_pairBuffer[e.m_pairCount];x.proxyA=t<m?t:m;x.proxyB=t>=m?t:m;++e.m_pairCount;return true},
r)}for(f=e.m_moveBuffer.length=0;f<e.m_pairCount;){r=e.m_pairBuffer[f];var s=e.m_tree.GetUserData(r.proxyA),v=e.m_tree.GetUserData(r.proxyB);b(s,v);for(++f;f<e.m_pairCount;){s=e.m_pairBuffer[f];if(s.proxyA!=r.proxyA||s.proxyB!=r.proxyB)break;++f}}};D.prototype.Query=function(b,e){this.m_tree.Query(b,e)};D.prototype.RayCast=function(b,e){this.m_tree.RayCast(b,e)};D.prototype.Validate=function(){};D.prototype.Rebalance=function(b){if(b===undefined)b=0;this.m_tree.Rebalance(b)};D.prototype.BufferMove=
function(b){this.m_moveBuffer[this.m_moveBuffer.length]=b};D.prototype.UnBufferMove=function(b){this.m_moveBuffer.splice(parseInt(this.m_moveBuffer.indexOf(b)),1)};D.prototype.ComparePairs=function(){return 0};D.__implements={};D.__implements[g]=true;H.b2DynamicTreeNode=function(){this.aabb=new B};H.prototype.IsLeaf=function(){return this.child1==null};O.b2DynamicTreePair=function(){};E.b2Manifold=function(){this.m_pointCount=0};E.prototype.b2Manifold=function(){this.m_points=new Vector(y.b2_maxManifoldPoints);
for(var b=0;b<y.b2_maxManifoldPoints;b++)this.m_points[b]=new R;this.m_localPlaneNormal=new p;this.m_localPoint=new p};E.prototype.Reset=function(){for(var b=0;b<y.b2_maxManifoldPoints;b++)(this.m_points[b]instanceof R?this.m_points[b]:null).Reset();this.m_localPlaneNormal.SetZero();this.m_localPoint.SetZero();this.m_pointCount=this.m_type=0};E.prototype.Set=function(b){this.m_pointCount=b.m_pointCount;for(var e=0;e<y.b2_maxManifoldPoints;e++)(this.m_points[e]instanceof R?this.m_points[e]:null).Set(b.m_points[e]);
this.m_localPlaneNormal.SetV(b.m_localPlaneNormal);this.m_localPoint.SetV(b.m_localPoint);this.m_type=b.m_type};E.prototype.Copy=function(){var b=new E;b.Set(this);return b};Box2D.postDefs.push(function(){Box2D.Collision.b2Manifold.e_circles=1;Box2D.Collision.b2Manifold.e_faceA=2;Box2D.Collision.b2Manifold.e_faceB=4});R.b2ManifoldPoint=function(){this.m_localPoint=new p;this.m_id=new L};R.prototype.b2ManifoldPoint=function(){this.Reset()};R.prototype.Reset=function(){this.m_localPoint.SetZero();this.m_tangentImpulse=
this.m_normalImpulse=0;this.m_id.key=0};R.prototype.Set=function(b){this.m_localPoint.SetV(b.m_localPoint);this.m_normalImpulse=b.m_normalImpulse;this.m_tangentImpulse=b.m_tangentImpulse;this.m_id.Set(b.m_id)};N.b2Point=function(){this.p=new p};N.prototype.Support=function(){return this.p};N.prototype.GetFirstVertex=function(){return this.p};S.b2RayCastInput=function(){this.p1=new p;this.p2=new p};S.prototype.b2RayCastInput=function(b,e,f){if(b===undefined)b=null;if(e===undefined)e=null;if(f===undefined)f=
1;b&&this.p1.SetV(b);e&&this.p2.SetV(e);this.maxFraction=f};aa.b2RayCastOutput=function(){this.normal=new p};Z.b2Segment=function(){this.p1=new p;this.p2=new p};Z.prototype.TestSegment=function(b,e,f,m){if(m===undefined)m=0;var r=f.p1,s=f.p2.x-r.x,v=f.p2.y-r.y;f=this.p2.y-this.p1.y;var t=-(this.p2.x-this.p1.x),x=100*Number.MIN_VALUE,C=-(s*f+v*t);if(C>x){var J=r.x-this.p1.x,T=r.y-this.p1.y;r=J*f+T*t;if(0<=r&&r<=m*C){m=-s*T+v*J;if(-x*C<=m&&m<=C*(1+x)){r/=C;m=Math.sqrt(f*f+t*t);f/=m;t/=m;b[0]=r;e.Set(f,
t);return true}}}return false};Z.prototype.Extend=function(b){this.ExtendForward(b);this.ExtendBackward(b)};Z.prototype.ExtendForward=function(b){var e=this.p2.x-this.p1.x,f=this.p2.y-this.p1.y;b=Math.min(e>0?(b.upperBound.x-this.p1.x)/e:e<0?(b.lowerBound.x-this.p1.x)/e:Number.POSITIVE_INFINITY,f>0?(b.upperBound.y-this.p1.y)/f:f<0?(b.lowerBound.y-this.p1.y)/f:Number.POSITIVE_INFINITY);this.p2.x=this.p1.x+e*b;this.p2.y=this.p1.y+f*b};Z.prototype.ExtendBackward=function(b){var e=-this.p2.x+this.p1.x,
f=-this.p2.y+this.p1.y;b=Math.min(e>0?(b.upperBound.x-this.p2.x)/e:e<0?(b.lowerBound.x-this.p2.x)/e:Number.POSITIVE_INFINITY,f>0?(b.upperBound.y-this.p2.y)/f:f<0?(b.lowerBound.y-this.p2.y)/f:Number.POSITIVE_INFINITY);this.p1.x=this.p2.x+e*b;this.p1.y=this.p2.y+f*b};d.b2SeparationFunction=function(){this.m_localPoint=new p;this.m_axis=new p};d.prototype.Initialize=function(b,e,f,m,r){this.m_proxyA=e;this.m_proxyB=m;var s=parseInt(b.count);y.b2Assert(0<s&&s<3);var v,t,x,C,J=C=x=m=e=0,T=0;J=0;if(s==
1){this.m_type=d.e_points;v=this.m_proxyA.GetVertex(b.indexA[0]);t=this.m_proxyB.GetVertex(b.indexB[0]);s=v;b=f.R;e=f.position.x+(b.col1.x*s.x+b.col2.x*s.y);m=f.position.y+(b.col1.y*s.x+b.col2.y*s.y);s=t;b=r.R;x=r.position.x+(b.col1.x*s.x+b.col2.x*s.y);C=r.position.y+(b.col1.y*s.x+b.col2.y*s.y);this.m_axis.x=x-e;this.m_axis.y=C-m;this.m_axis.Normalize()}else{if(b.indexB[0]==b.indexB[1]){this.m_type=d.e_faceA;e=this.m_proxyA.GetVertex(b.indexA[0]);m=this.m_proxyA.GetVertex(b.indexA[1]);t=this.m_proxyB.GetVertex(b.indexB[0]);
this.m_localPoint.x=0.5*(e.x+m.x);this.m_localPoint.y=0.5*(e.y+m.y);this.m_axis=w.CrossVF(w.SubtractVV(m,e),1);this.m_axis.Normalize();s=this.m_axis;b=f.R;J=b.col1.x*s.x+b.col2.x*s.y;T=b.col1.y*s.x+b.col2.y*s.y;s=this.m_localPoint;b=f.R;e=f.position.x+(b.col1.x*s.x+b.col2.x*s.y);m=f.position.y+(b.col1.y*s.x+b.col2.y*s.y);s=t;b=r.R;x=r.position.x+(b.col1.x*s.x+b.col2.x*s.y);C=r.position.y+(b.col1.y*s.x+b.col2.y*s.y);J=(x-e)*J+(C-m)*T}else if(b.indexA[0]==b.indexA[0]){this.m_type=d.e_faceB;x=this.m_proxyB.GetVertex(b.indexB[0]);
C=this.m_proxyB.GetVertex(b.indexB[1]);v=this.m_proxyA.GetVertex(b.indexA[0]);this.m_localPoint.x=0.5*(x.x+C.x);this.m_localPoint.y=0.5*(x.y+C.y);this.m_axis=w.CrossVF(w.SubtractVV(C,x),1);this.m_axis.Normalize();s=this.m_axis;b=r.R;J=b.col1.x*s.x+b.col2.x*s.y;T=b.col1.y*s.x+b.col2.y*s.y;s=this.m_localPoint;b=r.R;x=r.position.x+(b.col1.x*s.x+b.col2.x*s.y);C=r.position.y+(b.col1.y*s.x+b.col2.y*s.y);s=v;b=f.R;e=f.position.x+(b.col1.x*s.x+b.col2.x*s.y);m=f.position.y+(b.col1.y*s.x+b.col2.y*s.y);J=(e-
x)*J+(m-C)*T}else{e=this.m_proxyA.GetVertex(b.indexA[0]);m=this.m_proxyA.GetVertex(b.indexA[1]);x=this.m_proxyB.GetVertex(b.indexB[0]);C=this.m_proxyB.GetVertex(b.indexB[1]);w.MulX(f,v);v=w.MulMV(f.R,w.SubtractVV(m,e));w.MulX(r,t);J=w.MulMV(r.R,w.SubtractVV(C,x));r=v.x*v.x+v.y*v.y;t=J.x*J.x+J.y*J.y;b=w.SubtractVV(J,v);f=v.x*b.x+v.y*b.y;b=J.x*b.x+J.y*b.y;v=v.x*J.x+v.y*J.y;T=r*t-v*v;J=0;if(T!=0)J=w.Clamp((v*b-f*t)/T,0,1);if((v*J+b)/t<0)J=w.Clamp((v-f)/r,0,1);v=new p;v.x=e.x+J*(m.x-e.x);v.y=e.y+J*(m.y-
e.y);t=new p;t.x=x.x+J*(C.x-x.x);t.y=x.y+J*(C.y-x.y);if(J==0||J==1){this.m_type=d.e_faceB;this.m_axis=w.CrossVF(w.SubtractVV(C,x),1);this.m_axis.Normalize();this.m_localPoint=t}else{this.m_type=d.e_faceA;this.m_axis=w.CrossVF(w.SubtractVV(m,e),1);this.m_localPoint=v}}J<0&&this.m_axis.NegativeSelf()}};d.prototype.Evaluate=function(b,e){var f,m,r=0;switch(this.m_type){case d.e_points:f=w.MulTMV(b.R,this.m_axis);m=w.MulTMV(e.R,this.m_axis.GetNegative());f=this.m_proxyA.GetSupportVertex(f);m=this.m_proxyB.GetSupportVertex(m);
f=w.MulX(b,f);m=w.MulX(e,m);return r=(m.x-f.x)*this.m_axis.x+(m.y-f.y)*this.m_axis.y;case d.e_faceA:r=w.MulMV(b.R,this.m_axis);f=w.MulX(b,this.m_localPoint);m=w.MulTMV(e.R,r.GetNegative());m=this.m_proxyB.GetSupportVertex(m);m=w.MulX(e,m);return r=(m.x-f.x)*r.x+(m.y-f.y)*r.y;case d.e_faceB:r=w.MulMV(e.R,this.m_axis);m=w.MulX(e,this.m_localPoint);f=w.MulTMV(b.R,r.GetNegative());f=this.m_proxyA.GetSupportVertex(f);f=w.MulX(b,f);return r=(f.x-m.x)*r.x+(f.y-m.y)*r.y;default:y.b2Assert(false);return 0}};
Box2D.postDefs.push(function(){Box2D.Collision.b2SeparationFunction.e_points=1;Box2D.Collision.b2SeparationFunction.e_faceA=2;Box2D.Collision.b2SeparationFunction.e_faceB=4});h.b2Simplex=function(){this.m_v1=new j;this.m_v2=new j;this.m_v3=new j;this.m_vertices=new Vector(3)};h.prototype.b2Simplex=function(){this.m_vertices[0]=this.m_v1;this.m_vertices[1]=this.m_v2;this.m_vertices[2]=this.m_v3};h.prototype.ReadCache=function(b,e,f,m,r){y.b2Assert(0<=b.count&&b.count<=3);var s,v;this.m_count=b.count;
for(var t=this.m_vertices,x=0;x<this.m_count;x++){var C=t[x];C.indexA=b.indexA[x];C.indexB=b.indexB[x];s=e.GetVertex(C.indexA);v=m.GetVertex(C.indexB);C.wA=w.MulX(f,s);C.wB=w.MulX(r,v);C.w=w.SubtractVV(C.wB,C.wA);C.a=0}if(this.m_count>1){b=b.metric;s=this.GetMetric();if(s<0.5*b||2*b<s||s<Number.MIN_VALUE)this.m_count=0}if(this.m_count==0){C=t[0];C.indexA=0;C.indexB=0;s=e.GetVertex(0);v=m.GetVertex(0);C.wA=w.MulX(f,s);C.wB=w.MulX(r,v);C.w=w.SubtractVV(C.wB,C.wA);this.m_count=1}};h.prototype.WriteCache=
function(b){b.metric=this.GetMetric();b.count=Box2D.parseUInt(this.m_count);for(var e=this.m_vertices,f=0;f<this.m_count;f++){b.indexA[f]=Box2D.parseUInt(e[f].indexA);b.indexB[f]=Box2D.parseUInt(e[f].indexB)}};h.prototype.GetSearchDirection=function(){switch(this.m_count){case 1:return this.m_v1.w.GetNegative();case 2:var b=w.SubtractVV(this.m_v2.w,this.m_v1.w);return w.CrossVV(b,this.m_v1.w.GetNegative())>0?w.CrossFV(1,b):w.CrossVF(b,1);default:y.b2Assert(false);return new p}};h.prototype.GetClosestPoint=
function(){switch(this.m_count){case 0:y.b2Assert(false);return new p;case 1:return this.m_v1.w;case 2:return new p(this.m_v1.a*this.m_v1.w.x+this.m_v2.a*this.m_v2.w.x,this.m_v1.a*this.m_v1.w.y+this.m_v2.a*this.m_v2.w.y);default:y.b2Assert(false);return new p}};h.prototype.GetWitnessPoints=function(b,e){switch(this.m_count){case 0:y.b2Assert(false);break;case 1:b.SetV(this.m_v1.wA);e.SetV(this.m_v1.wB);break;case 2:b.x=this.m_v1.a*this.m_v1.wA.x+this.m_v2.a*this.m_v2.wA.x;b.y=this.m_v1.a*this.m_v1.wA.y+
this.m_v2.a*this.m_v2.wA.y;e.x=this.m_v1.a*this.m_v1.wB.x+this.m_v2.a*this.m_v2.wB.x;e.y=this.m_v1.a*this.m_v1.wB.y+this.m_v2.a*this.m_v2.wB.y;break;case 3:e.x=b.x=this.m_v1.a*this.m_v1.wA.x+this.m_v2.a*this.m_v2.wA.x+this.m_v3.a*this.m_v3.wA.x;e.y=b.y=this.m_v1.a*this.m_v1.wA.y+this.m_v2.a*this.m_v2.wA.y+this.m_v3.a*this.m_v3.wA.y;break;default:y.b2Assert(false)}};h.prototype.GetMetric=function(){switch(this.m_count){case 0:y.b2Assert(false);return 0;case 1:return 0;case 2:return w.SubtractVV(this.m_v1.w,
this.m_v2.w).Length();case 3:return w.CrossVV(w.SubtractVV(this.m_v2.w,this.m_v1.w),w.SubtractVV(this.m_v3.w,this.m_v1.w));default:y.b2Assert(false);return 0}};h.prototype.Solve2=function(){var b=this.m_v1.w,e=this.m_v2.w,f=w.SubtractVV(e,b);b=-(b.x*f.x+b.y*f.y);if(b<=0)this.m_count=this.m_v1.a=1;else{e=e.x*f.x+e.y*f.y;if(e<=0){this.m_count=this.m_v2.a=1;this.m_v1.Set(this.m_v2)}else{f=1/(e+b);this.m_v1.a=e*f;this.m_v2.a=b*f;this.m_count=2}}};h.prototype.Solve3=function(){var b=this.m_v1.w,e=this.m_v2.w,
f=this.m_v3.w,m=w.SubtractVV(e,b),r=w.Dot(b,m),s=w.Dot(e,m);r=-r;var v=w.SubtractVV(f,b),t=w.Dot(b,v),x=w.Dot(f,v);t=-t;var C=w.SubtractVV(f,e),J=w.Dot(e,C);C=w.Dot(f,C);J=-J;v=w.CrossVV(m,v);m=v*w.CrossVV(e,f);f=v*w.CrossVV(f,b);b=v*w.CrossVV(b,e);if(r<=0&&t<=0)this.m_count=this.m_v1.a=1;else if(s>0&&r>0&&b<=0){x=1/(s+r);this.m_v1.a=s*x;this.m_v2.a=r*x;this.m_count=2}else if(x>0&&t>0&&f<=0){s=1/(x+t);this.m_v1.a=x*s;this.m_v3.a=t*s;this.m_count=2;this.m_v2.Set(this.m_v3)}else if(s<=0&&J<=0){this.m_count=
this.m_v2.a=1;this.m_v1.Set(this.m_v2)}else if(x<=0&&C<=0){this.m_count=this.m_v3.a=1;this.m_v1.Set(this.m_v3)}else if(C>0&&J>0&&m<=0){s=1/(C+J);this.m_v2.a=C*s;this.m_v3.a=J*s;this.m_count=2;this.m_v1.Set(this.m_v3)}else{s=1/(m+f+b);this.m_v1.a=m*s;this.m_v2.a=f*s;this.m_v3.a=b*s;this.m_count=3}};l.b2SimplexCache=function(){this.indexA=new Vector_a2j_Number(3);this.indexB=new Vector_a2j_Number(3)};j.b2SimplexVertex=function(){};j.prototype.Set=function(b){this.wA.SetV(b.wA);this.wB.SetV(b.wB);this.w.SetV(b.w);
this.a=b.a;this.indexA=b.indexA;this.indexB=b.indexB};o.b2TimeOfImpact=function(){};o.TimeOfImpact=function(b){++o.b2_toiCalls;var e=b.proxyA,f=b.proxyB,m=b.sweepA,r=b.sweepB;y.b2Assert(m.t0==r.t0);y.b2Assert(1-m.t0>Number.MIN_VALUE);var s=e.m_radius+f.m_radius;b=b.tolerance;var v=0,t=0,x=0;o.s_cache.count=0;for(o.s_distanceInput.useRadii=false;;){m.GetTransform(o.s_xfA,v);r.GetTransform(o.s_xfB,v);o.s_distanceInput.proxyA=e;o.s_distanceInput.proxyB=f;o.s_distanceInput.transformA=o.s_xfA;o.s_distanceInput.transformB=
o.s_xfB;W.Distance(o.s_distanceOutput,o.s_cache,o.s_distanceInput);if(o.s_distanceOutput.distance<=0){v=1;break}o.s_fcn.Initialize(o.s_cache,e,o.s_xfA,f,o.s_xfB);var C=o.s_fcn.Evaluate(o.s_xfA,o.s_xfB);if(C<=0){v=1;break}if(t==0)x=C>s?w.Max(s-b,0.75*s):w.Max(C-b,0.02*s);if(C-x<0.5*b){if(t==0){v=1;break}break}var J=v,T=v,P=1;C=C;m.GetTransform(o.s_xfA,P);r.GetTransform(o.s_xfB,P);var X=o.s_fcn.Evaluate(o.s_xfA,o.s_xfB);if(X>=x){v=1;break}for(var $=0;;){var ba=0;ba=$&1?T+(x-C)*(P-T)/(X-C):0.5*(T+P);
m.GetTransform(o.s_xfA,ba);r.GetTransform(o.s_xfB,ba);var ca=o.s_fcn.Evaluate(o.s_xfA,o.s_xfB);if(w.Abs(ca-x)<0.025*b){J=ba;break}if(ca>x){T=ba;C=ca}else{P=ba;X=ca}++$;++o.b2_toiRootIters;if($==50)break}o.b2_toiMaxRootIters=w.Max(o.b2_toiMaxRootIters,$);if(J<(1+100*Number.MIN_VALUE)*v)break;v=J;t++;++o.b2_toiIters;if(t==1E3)break}o.b2_toiMaxIters=w.Max(o.b2_toiMaxIters,t);return v};Box2D.postDefs.push(function(){Box2D.Collision.b2TimeOfImpact.b2_toiCalls=0;Box2D.Collision.b2TimeOfImpact.b2_toiIters=
0;Box2D.Collision.b2TimeOfImpact.b2_toiMaxIters=0;Box2D.Collision.b2TimeOfImpact.b2_toiRootIters=0;Box2D.Collision.b2TimeOfImpact.b2_toiMaxRootIters=0;Box2D.Collision.b2TimeOfImpact.s_cache=new l;Box2D.Collision.b2TimeOfImpact.s_distanceInput=new Y;Box2D.Collision.b2TimeOfImpact.s_xfA=new U;Box2D.Collision.b2TimeOfImpact.s_xfB=new U;Box2D.Collision.b2TimeOfImpact.s_fcn=new d;Box2D.Collision.b2TimeOfImpact.s_distanceOutput=new k});q.b2TOIInput=function(){this.proxyA=new z;this.proxyB=new z;this.sweepA=
new A;this.sweepB=new A};n.b2WorldManifold=function(){this.m_normal=new p};n.prototype.b2WorldManifold=function(){this.m_points=new Vector(y.b2_maxManifoldPoints);for(var b=0;b<y.b2_maxManifoldPoints;b++)this.m_points[b]=new p};n.prototype.Initialize=function(b,e,f,m,r){if(f===undefined)f=0;if(r===undefined)r=0;if(b.m_pointCount!=0){var s=0,v,t,x=0,C=0,J=0,T=0,P=0;v=0;switch(b.m_type){case E.e_circles:t=e.R;v=b.m_localPoint;s=e.position.x+t.col1.x*v.x+t.col2.x*v.y;e=e.position.y+t.col1.y*v.x+t.col2.y*
v.y;t=m.R;v=b.m_points[0].m_localPoint;b=m.position.x+t.col1.x*v.x+t.col2.x*v.y;m=m.position.y+t.col1.y*v.x+t.col2.y*v.y;v=b-s;t=m-e;x=v*v+t*t;if(x>Number.MIN_VALUE*Number.MIN_VALUE){x=Math.sqrt(x);this.m_normal.x=v/x;this.m_normal.y=t/x}else{this.m_normal.x=1;this.m_normal.y=0}v=e+f*this.m_normal.y;m=m-r*this.m_normal.y;this.m_points[0].x=0.5*(s+f*this.m_normal.x+(b-r*this.m_normal.x));this.m_points[0].y=0.5*(v+m);break;case E.e_faceA:t=e.R;v=b.m_localPlaneNormal;x=t.col1.x*v.x+t.col2.x*v.y;C=t.col1.y*
v.x+t.col2.y*v.y;t=e.R;v=b.m_localPoint;J=e.position.x+t.col1.x*v.x+t.col2.x*v.y;T=e.position.y+t.col1.y*v.x+t.col2.y*v.y;this.m_normal.x=x;this.m_normal.y=C;for(s=0;s<b.m_pointCount;s++){t=m.R;v=b.m_points[s].m_localPoint;P=m.position.x+t.col1.x*v.x+t.col2.x*v.y;v=m.position.y+t.col1.y*v.x+t.col2.y*v.y;this.m_points[s].x=P+0.5*(f-(P-J)*x-(v-T)*C-r)*x;this.m_points[s].y=v+0.5*(f-(P-J)*x-(v-T)*C-r)*C}break;case E.e_faceB:t=m.R;v=b.m_localPlaneNormal;x=t.col1.x*v.x+t.col2.x*v.y;C=t.col1.y*v.x+t.col2.y*
v.y;t=m.R;v=b.m_localPoint;J=m.position.x+t.col1.x*v.x+t.col2.x*v.y;T=m.position.y+t.col1.y*v.x+t.col2.y*v.y;this.m_normal.x=-x;this.m_normal.y=-C;for(s=0;s<b.m_pointCount;s++){t=e.R;v=b.m_points[s].m_localPoint;P=e.position.x+t.col1.x*v.x+t.col2.x*v.y;v=e.position.y+t.col1.y*v.x+t.col2.y*v.y;this.m_points[s].x=P+0.5*(r-(P-J)*x-(v-T)*C-f)*x;this.m_points[s].y=v+0.5*(r-(P-J)*x-(v-T)*C-f)*C}}}};a.ClipVertex=function(){this.v=new p;this.id=new L};a.prototype.Set=function(b){this.v.SetV(b.v);this.id.Set(b.id)};
c.Features=function(){};Object.defineProperty(c.prototype,"referenceEdge",{enumerable:false,configurable:true,get:function(){return this._referenceEdge}});Object.defineProperty(c.prototype,"referenceEdge",{enumerable:false,configurable:true,set:function(b){if(b===undefined)b=0;this._referenceEdge=b;this._m_id._key=this._m_id._key&4294967040|this._referenceEdge&255}});Object.defineProperty(c.prototype,"incidentEdge",{enumerable:false,configurable:true,get:function(){return this._incidentEdge}});Object.defineProperty(c.prototype,
"incidentEdge",{enumerable:false,configurable:true,set:function(b){if(b===undefined)b=0;this._incidentEdge=b;this._m_id._key=this._m_id._key&4294902015|this._incidentEdge<<8&65280}});Object.defineProperty(c.prototype,"incidentVertex",{enumerable:false,configurable:true,get:function(){return this._incidentVertex}});Object.defineProperty(c.prototype,"incidentVertex",{enumerable:false,configurable:true,set:function(b){if(b===undefined)b=0;this._incidentVertex=b;this._m_id._key=this._m_id._key&4278255615|
this._incidentVertex<<16&16711680}});Object.defineProperty(c.prototype,"flip",{enumerable:false,configurable:true,get:function(){return this._flip}});Object.defineProperty(c.prototype,"flip",{enumerable:false,configurable:true,set:function(b){if(b===undefined)b=0;this._flip=b;this._m_id._key=this._m_id._key&16777215|this._flip<<24&4278190080}})})();
(function(){var F=Box2D.Common.b2Settings,G=Box2D.Collision.Shapes.b2CircleShape,K=Box2D.Collision.Shapes.b2EdgeChainDef,y=Box2D.Collision.Shapes.b2EdgeShape,w=Box2D.Collision.Shapes.b2MassData,A=Box2D.Collision.Shapes.b2PolygonShape,U=Box2D.Collision.Shapes.b2Shape,p=Box2D.Common.Math.b2Mat22,B=Box2D.Common.Math.b2Math,Q=Box2D.Common.Math.b2Transform,V=Box2D.Common.Math.b2Vec2,M=Box2D.Collision.b2Distance,L=Box2D.Collision.b2DistanceInput,I=Box2D.Collision.b2DistanceOutput,W=Box2D.Collision.b2DistanceProxy,
Y=Box2D.Collision.b2SimplexCache;Box2D.inherit(G,Box2D.Collision.Shapes.b2Shape);G.prototype.__super=Box2D.Collision.Shapes.b2Shape.prototype;G.b2CircleShape=function(){Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this,arguments);this.m_p=new V};G.prototype.Copy=function(){var k=new G;k.Set(this);return k};G.prototype.Set=function(k){this.__super.Set.call(this,k);if(Box2D.is(k,G))this.m_p.SetV((k instanceof G?k:null).m_p)};G.prototype.TestPoint=function(k,z){var u=k.R,D=k.position.x+(u.col1.x*this.m_p.x+
u.col2.x*this.m_p.y);u=k.position.y+(u.col1.y*this.m_p.x+u.col2.y*this.m_p.y);D=z.x-D;u=z.y-u;return D*D+u*u<=this.m_radius*this.m_radius};G.prototype.RayCast=function(k,z,u){var D=u.R,H=z.p1.x-(u.position.x+(D.col1.x*this.m_p.x+D.col2.x*this.m_p.y));u=z.p1.y-(u.position.y+(D.col1.y*this.m_p.x+D.col2.y*this.m_p.y));D=z.p2.x-z.p1.x;var O=z.p2.y-z.p1.y,E=H*D+u*O,R=D*D+O*O,N=E*E-R*(H*H+u*u-this.m_radius*this.m_radius);if(N<0||R<Number.MIN_VALUE)return false;E=-(E+Math.sqrt(N));if(0<=E&&E<=z.maxFraction*
R){E/=R;k.fraction=E;k.normal.x=H+E*D;k.normal.y=u+E*O;k.normal.Normalize();return true}return false};G.prototype.ComputeAABB=function(k,z){var u=z.R,D=z.position.x+(u.col1.x*this.m_p.x+u.col2.x*this.m_p.y);u=z.position.y+(u.col1.y*this.m_p.x+u.col2.y*this.m_p.y);k.lowerBound.Set(D-this.m_radius,u-this.m_radius);k.upperBound.Set(D+this.m_radius,u+this.m_radius)};G.prototype.ComputeMass=function(k,z){if(z===undefined)z=0;k.mass=z*F.b2_pi*this.m_radius*this.m_radius;k.center.SetV(this.m_p);k.I=k.mass*
(0.5*this.m_radius*this.m_radius+(this.m_p.x*this.m_p.x+this.m_p.y*this.m_p.y))};G.prototype.ComputeSubmergedArea=function(k,z,u,D){if(z===undefined)z=0;u=B.MulX(u,this.m_p);var H=-(B.Dot(k,u)-z);if(H<-this.m_radius+Number.MIN_VALUE)return 0;if(H>this.m_radius){D.SetV(u);return Math.PI*this.m_radius*this.m_radius}z=this.m_radius*this.m_radius;var O=H*H;H=z*(Math.asin(H/this.m_radius)+Math.PI/2)+H*Math.sqrt(z-O);z=-2/3*Math.pow(z-O,1.5)/H;D.x=u.x+k.x*z;D.y=u.y+k.y*z;return H};G.prototype.GetLocalPosition=
function(){return this.m_p};G.prototype.SetLocalPosition=function(k){this.m_p.SetV(k)};G.prototype.GetRadius=function(){return this.m_radius};G.prototype.SetRadius=function(k){if(k===undefined)k=0;this.m_radius=k};G.prototype.b2CircleShape=function(k){if(k===undefined)k=0;this.__super.b2Shape.call(this);this.m_type=U.e_circleShape;this.m_radius=k};K.b2EdgeChainDef=function(){};K.prototype.b2EdgeChainDef=function(){this.vertexCount=0;this.isALoop=true;this.vertices=[]};Box2D.inherit(y,Box2D.Collision.Shapes.b2Shape);
y.prototype.__super=Box2D.Collision.Shapes.b2Shape.prototype;y.b2EdgeShape=function(){Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this,arguments);this.s_supportVec=new V;this.m_v1=new V;this.m_v2=new V;this.m_coreV1=new V;this.m_coreV2=new V;this.m_normal=new V;this.m_direction=new V;this.m_cornerDir1=new V;this.m_cornerDir2=new V};y.prototype.TestPoint=function(){return false};y.prototype.RayCast=function(k,z,u){var D,H=z.p2.x-z.p1.x,O=z.p2.y-z.p1.y;D=u.R;var E=u.position.x+(D.col1.x*this.m_v1.x+
D.col2.x*this.m_v1.y),R=u.position.y+(D.col1.y*this.m_v1.x+D.col2.y*this.m_v1.y),N=u.position.y+(D.col1.y*this.m_v2.x+D.col2.y*this.m_v2.y)-R;u=-(u.position.x+(D.col1.x*this.m_v2.x+D.col2.x*this.m_v2.y)-E);D=100*Number.MIN_VALUE;var S=-(H*N+O*u);if(S>D){E=z.p1.x-E;var aa=z.p1.y-R;R=E*N+aa*u;if(0<=R&&R<=z.maxFraction*S){z=-H*aa+O*E;if(-D*S<=z&&z<=S*(1+D)){R/=S;k.fraction=R;z=Math.sqrt(N*N+u*u);k.normal.x=N/z;k.normal.y=u/z;return true}}}return false};y.prototype.ComputeAABB=function(k,z){var u=z.R,
D=z.position.x+(u.col1.x*this.m_v1.x+u.col2.x*this.m_v1.y),H=z.position.y+(u.col1.y*this.m_v1.x+u.col2.y*this.m_v1.y),O=z.position.x+(u.col1.x*this.m_v2.x+u.col2.x*this.m_v2.y);u=z.position.y+(u.col1.y*this.m_v2.x+u.col2.y*this.m_v2.y);if(D<O){k.lowerBound.x=D;k.upperBound.x=O}else{k.lowerBound.x=O;k.upperBound.x=D}if(H<u){k.lowerBound.y=H;k.upperBound.y=u}else{k.lowerBound.y=u;k.upperBound.y=H}};y.prototype.ComputeMass=function(k){k.mass=0;k.center.SetV(this.m_v1);k.I=0};y.prototype.ComputeSubmergedArea=
function(k,z,u,D){if(z===undefined)z=0;var H=new V(k.x*z,k.y*z),O=B.MulX(u,this.m_v1);u=B.MulX(u,this.m_v2);var E=B.Dot(k,O)-z;k=B.Dot(k,u)-z;if(E>0)if(k>0)return 0;else{O.x=-k/(E-k)*O.x+E/(E-k)*u.x;O.y=-k/(E-k)*O.y+E/(E-k)*u.y}else if(k>0){u.x=-k/(E-k)*O.x+E/(E-k)*u.x;u.y=-k/(E-k)*O.y+E/(E-k)*u.y}D.x=(H.x+O.x+u.x)/3;D.y=(H.y+O.y+u.y)/3;return 0.5*((O.x-H.x)*(u.y-H.y)-(O.y-H.y)*(u.x-H.x))};y.prototype.GetLength=function(){return this.m_length};y.prototype.GetVertex1=function(){return this.m_v1};y.prototype.GetVertex2=
function(){return this.m_v2};y.prototype.GetCoreVertex1=function(){return this.m_coreV1};y.prototype.GetCoreVertex2=function(){return this.m_coreV2};y.prototype.GetNormalVector=function(){return this.m_normal};y.prototype.GetDirectionVector=function(){return this.m_direction};y.prototype.GetCorner1Vector=function(){return this.m_cornerDir1};y.prototype.GetCorner2Vector=function(){return this.m_cornerDir2};y.prototype.Corner1IsConvex=function(){return this.m_cornerConvex1};y.prototype.Corner2IsConvex=
function(){return this.m_cornerConvex2};y.prototype.GetFirstVertex=function(k){var z=k.R;return new V(k.position.x+(z.col1.x*this.m_coreV1.x+z.col2.x*this.m_coreV1.y),k.position.y+(z.col1.y*this.m_coreV1.x+z.col2.y*this.m_coreV1.y))};y.prototype.GetNextEdge=function(){return this.m_nextEdge};y.prototype.GetPrevEdge=function(){return this.m_prevEdge};y.prototype.Support=function(k,z,u){if(z===undefined)z=0;if(u===undefined)u=0;var D=k.R,H=k.position.x+(D.col1.x*this.m_coreV1.x+D.col2.x*this.m_coreV1.y),
O=k.position.y+(D.col1.y*this.m_coreV1.x+D.col2.y*this.m_coreV1.y),E=k.position.x+(D.col1.x*this.m_coreV2.x+D.col2.x*this.m_coreV2.y);k=k.position.y+(D.col1.y*this.m_coreV2.x+D.col2.y*this.m_coreV2.y);if(H*z+O*u>E*z+k*u){this.s_supportVec.x=H;this.s_supportVec.y=O}else{this.s_supportVec.x=E;this.s_supportVec.y=k}return this.s_supportVec};y.prototype.b2EdgeShape=function(k,z){this.__super.b2Shape.call(this);this.m_type=U.e_edgeShape;this.m_nextEdge=this.m_prevEdge=null;this.m_v1=k;this.m_v2=z;this.m_direction.Set(this.m_v2.x-
this.m_v1.x,this.m_v2.y-this.m_v1.y);this.m_length=this.m_direction.Normalize();this.m_normal.Set(this.m_direction.y,-this.m_direction.x);this.m_coreV1.Set(-F.b2_toiSlop*(this.m_normal.x-this.m_direction.x)+this.m_v1.x,-F.b2_toiSlop*(this.m_normal.y-this.m_direction.y)+this.m_v1.y);this.m_coreV2.Set(-F.b2_toiSlop*(this.m_normal.x+this.m_direction.x)+this.m_v2.x,-F.b2_toiSlop*(this.m_normal.y+this.m_direction.y)+this.m_v2.y);this.m_cornerDir1=this.m_normal;this.m_cornerDir2.Set(-this.m_normal.x,-this.m_normal.y)};
y.prototype.SetPrevEdge=function(k,z,u,D){this.m_prevEdge=k;this.m_coreV1=z;this.m_cornerDir1=u;this.m_cornerConvex1=D};y.prototype.SetNextEdge=function(k,z,u,D){this.m_nextEdge=k;this.m_coreV2=z;this.m_cornerDir2=u;this.m_cornerConvex2=D};w.b2MassData=function(){this.mass=0;this.center=new V(0,0);this.I=0};Box2D.inherit(A,Box2D.Collision.Shapes.b2Shape);A.prototype.__super=Box2D.Collision.Shapes.b2Shape.prototype;A.b2PolygonShape=function(){Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this,arguments)};
A.prototype.Copy=function(){var k=new A;k.Set(this);return k};A.prototype.Set=function(k){this.__super.Set.call(this,k);if(Box2D.is(k,A)){k=k instanceof A?k:null;this.m_centroid.SetV(k.m_centroid);this.m_vertexCount=k.m_vertexCount;this.Reserve(this.m_vertexCount);for(var z=0;z<this.m_vertexCount;z++){this.m_vertices[z].SetV(k.m_vertices[z]);this.m_normals[z].SetV(k.m_normals[z])}}};A.prototype.SetAsArray=function(k,z){if(z===undefined)z=0;var u=new Vector,D=0,H;for(D=0;D<k.length;++D){H=k[D];u.push(H)}this.SetAsVector(u,
z)};A.AsArray=function(k,z){if(z===undefined)z=0;var u=new A;u.SetAsArray(k,z);return u};A.prototype.SetAsVector=function(k,z){if(z===undefined)z=0;if(z==0)z=k.length;F.b2Assert(2<=z);this.m_vertexCount=z;this.Reserve(z);var u=0;for(u=0;u<this.m_vertexCount;u++)this.m_vertices[u].SetV(k[u]);for(u=0;u<this.m_vertexCount;++u){var D=parseInt(u),H=parseInt(u+1<this.m_vertexCount?u+1:0);D=B.SubtractVV(this.m_vertices[H],this.m_vertices[D]);F.b2Assert(D.LengthSquared()>Number.MIN_VALUE);this.m_normals[u].SetV(B.CrossVF(D,
1));this.m_normals[u].Normalize()}this.m_centroid=A.ComputeCentroid(this.m_vertices,this.m_vertexCount)};A.AsVector=function(k,z){if(z===undefined)z=0;var u=new A;u.SetAsVector(k,z);return u};A.prototype.SetAsBox=function(k,z){if(k===undefined)k=0;if(z===undefined)z=0;this.m_vertexCount=4;this.Reserve(4);this.m_vertices[0].Set(-k,-z);this.m_vertices[1].Set(k,-z);this.m_vertices[2].Set(k,z);this.m_vertices[3].Set(-k,z);this.m_normals[0].Set(0,-1);this.m_normals[1].Set(1,0);this.m_normals[2].Set(0,
1);this.m_normals[3].Set(-1,0);this.m_centroid.SetZero()};A.AsBox=function(k,z){if(k===undefined)k=0;if(z===undefined)z=0;var u=new A;u.SetAsBox(k,z);return u};A.prototype.SetAsOrientedBox=function(k,z,u,D){if(k===undefined)k=0;if(z===undefined)z=0;if(u===undefined)u=null;if(D===undefined)D=0;this.m_vertexCount=4;this.Reserve(4);this.m_vertices[0].Set(-k,-z);this.m_vertices[1].Set(k,-z);this.m_vertices[2].Set(k,z);this.m_vertices[3].Set(-k,z);this.m_normals[0].Set(0,-1);this.m_normals[1].Set(1,0);
this.m_normals[2].Set(0,1);this.m_normals[3].Set(-1,0);this.m_centroid=u;k=new Q;k.position=u;k.R.Set(D);for(u=0;u<this.m_vertexCount;++u){this.m_vertices[u]=B.MulX(k,this.m_vertices[u]);this.m_normals[u]=B.MulMV(k.R,this.m_normals[u])}};A.AsOrientedBox=function(k,z,u,D){if(k===undefined)k=0;if(z===undefined)z=0;if(u===undefined)u=null;if(D===undefined)D=0;var H=new A;H.SetAsOrientedBox(k,z,u,D);return H};A.prototype.SetAsEdge=function(k,z){this.m_vertexCount=2;this.Reserve(2);this.m_vertices[0].SetV(k);
this.m_vertices[1].SetV(z);this.m_centroid.x=0.5*(k.x+z.x);this.m_centroid.y=0.5*(k.y+z.y);this.m_normals[0]=B.CrossVF(B.SubtractVV(z,k),1);this.m_normals[0].Normalize();this.m_normals[1].x=-this.m_normals[0].x;this.m_normals[1].y=-this.m_normals[0].y};A.AsEdge=function(k,z){var u=new A;u.SetAsEdge(k,z);return u};A.prototype.TestPoint=function(k,z){var u;u=k.R;for(var D=z.x-k.position.x,H=z.y-k.position.y,O=D*u.col1.x+H*u.col1.y,E=D*u.col2.x+H*u.col2.y,R=0;R<this.m_vertexCount;++R){u=this.m_vertices[R];
D=O-u.x;H=E-u.y;u=this.m_normals[R];if(u.x*D+u.y*H>0)return false}return true};A.prototype.RayCast=function(k,z,u){var D=0,H=z.maxFraction,O=0,E=0,R,N;O=z.p1.x-u.position.x;E=z.p1.y-u.position.y;R=u.R;var S=O*R.col1.x+E*R.col1.y,aa=O*R.col2.x+E*R.col2.y;O=z.p2.x-u.position.x;E=z.p2.y-u.position.y;R=u.R;z=O*R.col1.x+E*R.col1.y-S;R=O*R.col2.x+E*R.col2.y-aa;for(var Z=parseInt(-1),d=0;d<this.m_vertexCount;++d){N=this.m_vertices[d];O=N.x-S;E=N.y-aa;N=this.m_normals[d];O=N.x*O+N.y*E;E=N.x*z+N.y*R;if(E==
0){if(O<0)return false}else if(E<0&&O<D*E){D=O/E;Z=d}else if(E>0&&O<H*E)H=O/E;if(H<D-Number.MIN_VALUE)return false}if(Z>=0){k.fraction=D;R=u.R;N=this.m_normals[Z];k.normal.x=R.col1.x*N.x+R.col2.x*N.y;k.normal.y=R.col1.y*N.x+R.col2.y*N.y;return true}return false};A.prototype.ComputeAABB=function(k,z){for(var u=z.R,D=this.m_vertices[0],H=z.position.x+(u.col1.x*D.x+u.col2.x*D.y),O=z.position.y+(u.col1.y*D.x+u.col2.y*D.y),E=H,R=O,N=1;N<this.m_vertexCount;++N){D=this.m_vertices[N];var S=z.position.x+(u.col1.x*
D.x+u.col2.x*D.y);D=z.position.y+(u.col1.y*D.x+u.col2.y*D.y);H=H<S?H:S;O=O<D?O:D;E=E>S?E:S;R=R>D?R:D}k.lowerBound.x=H-this.m_radius;k.lowerBound.y=O-this.m_radius;k.upperBound.x=E+this.m_radius;k.upperBound.y=R+this.m_radius};A.prototype.ComputeMass=function(k,z){if(z===undefined)z=0;if(this.m_vertexCount==2){k.center.x=0.5*(this.m_vertices[0].x+this.m_vertices[1].x);k.center.y=0.5*(this.m_vertices[0].y+this.m_vertices[1].y);k.mass=0;k.I=0}else{for(var u=0,D=0,H=0,O=0,E=1/3,R=0;R<this.m_vertexCount;++R){var N=
this.m_vertices[R],S=R+1<this.m_vertexCount?this.m_vertices[parseInt(R+1)]:this.m_vertices[0],aa=N.x-0,Z=N.y-0,d=S.x-0,h=S.y-0,l=aa*h-Z*d,j=0.5*l;H+=j;u+=j*E*(0+N.x+S.x);D+=j*E*(0+N.y+S.y);N=aa;Z=Z;d=d;h=h;O+=l*(E*(0.25*(N*N+d*N+d*d)+(0*N+0*d))+0+(E*(0.25*(Z*Z+h*Z+h*h)+(0*Z+0*h))+0))}k.mass=z*H;u*=1/H;D*=1/H;k.center.Set(u,D);k.I=z*O}};A.prototype.ComputeSubmergedArea=function(k,z,u,D){if(z===undefined)z=0;var H=B.MulTMV(u.R,k),O=z-B.Dot(k,u.position),E=new Vector_a2j_Number,R=0,N=parseInt(-1);z=
parseInt(-1);var S=false;for(k=k=0;k<this.m_vertexCount;++k){E[k]=B.Dot(H,this.m_vertices[k])-O;var aa=E[k]<-Number.MIN_VALUE;if(k>0)if(aa){if(!S){N=k-1;R++}}else if(S){z=k-1;R++}S=aa}switch(R){case 0:if(S){k=new w;this.ComputeMass(k,1);D.SetV(B.MulX(u,k.center));return k.mass}else return 0;case 1:if(N==-1)N=this.m_vertexCount-1;else z=this.m_vertexCount-1}k=parseInt((N+1)%this.m_vertexCount);H=parseInt((z+1)%this.m_vertexCount);O=(0-E[N])/(E[k]-E[N]);E=(0-E[z])/(E[H]-E[z]);N=new V(this.m_vertices[N].x*
(1-O)+this.m_vertices[k].x*O,this.m_vertices[N].y*(1-O)+this.m_vertices[k].y*O);z=new V(this.m_vertices[z].x*(1-E)+this.m_vertices[H].x*E,this.m_vertices[z].y*(1-E)+this.m_vertices[H].y*E);E=0;O=new V;R=this.m_vertices[k];for(k=k;k!=H;){k=(k+1)%this.m_vertexCount;S=k==H?z:this.m_vertices[k];aa=0.5*((R.x-N.x)*(S.y-N.y)-(R.y-N.y)*(S.x-N.x));E+=aa;O.x+=aa*(N.x+R.x+S.x)/3;O.y+=aa*(N.y+R.y+S.y)/3;R=S}O.Multiply(1/E);D.SetV(B.MulX(u,O));return E};A.prototype.GetVertexCount=function(){return this.m_vertexCount};
A.prototype.GetVertices=function(){return this.m_vertices};A.prototype.GetNormals=function(){return this.m_normals};A.prototype.GetSupport=function(k){for(var z=0,u=this.m_vertices[0].x*k.x+this.m_vertices[0].y*k.y,D=1;D<this.m_vertexCount;++D){var H=this.m_vertices[D].x*k.x+this.m_vertices[D].y*k.y;if(H>u){z=D;u=H}}return z};A.prototype.GetSupportVertex=function(k){for(var z=0,u=this.m_vertices[0].x*k.x+this.m_vertices[0].y*k.y,D=1;D<this.m_vertexCount;++D){var H=this.m_vertices[D].x*k.x+this.m_vertices[D].y*
k.y;if(H>u){z=D;u=H}}return this.m_vertices[z]};A.prototype.Validate=function(){return false};A.prototype.b2PolygonShape=function(){this.__super.b2Shape.call(this);this.m_type=U.e_polygonShape;this.m_centroid=new V;this.m_vertices=new Vector;this.m_normals=new Vector};A.prototype.Reserve=function(k){if(k===undefined)k=0;for(var z=parseInt(this.m_vertices.length);z<k;z++){this.m_vertices[z]=new V;this.m_normals[z]=new V}};A.ComputeCentroid=function(k,z){if(z===undefined)z=0;for(var u=new V,D=0,H=1/
3,O=0;O<z;++O){var E=k[O],R=O+1<z?k[parseInt(O+1)]:k[0],N=0.5*((E.x-0)*(R.y-0)-(E.y-0)*(R.x-0));D+=N;u.x+=N*H*(0+E.x+R.x);u.y+=N*H*(0+E.y+R.y)}u.x*=1/D;u.y*=1/D;return u};A.ComputeOBB=function(k,z,u){if(u===undefined)u=0;var D=0,H=new Vector(u+1);for(D=0;D<u;++D)H[D]=z[D];H[u]=H[0];z=Number.MAX_VALUE;for(D=1;D<=u;++D){var O=H[parseInt(D-1)],E=H[D].x-O.x,R=H[D].y-O.y,N=Math.sqrt(E*E+R*R);E/=N;R/=N;for(var S=-R,aa=E,Z=N=Number.MAX_VALUE,d=-Number.MAX_VALUE,h=-Number.MAX_VALUE,l=0;l<u;++l){var j=H[l].x-
O.x,o=H[l].y-O.y,q=E*j+R*o;j=S*j+aa*o;if(q<N)N=q;if(j<Z)Z=j;if(q>d)d=q;if(j>h)h=j}l=(d-N)*(h-Z);if(l<0.95*z){z=l;k.R.col1.x=E;k.R.col1.y=R;k.R.col2.x=S;k.R.col2.y=aa;E=0.5*(N+d);R=0.5*(Z+h);S=k.R;k.center.x=O.x+(S.col1.x*E+S.col2.x*R);k.center.y=O.y+(S.col1.y*E+S.col2.y*R);k.extents.x=0.5*(d-N);k.extents.y=0.5*(h-Z)}}};Box2D.postDefs.push(function(){Box2D.Collision.Shapes.b2PolygonShape.s_mat=new p});U.b2Shape=function(){};U.prototype.Copy=function(){return null};U.prototype.Set=function(k){this.m_radius=
k.m_radius};U.prototype.GetType=function(){return this.m_type};U.prototype.TestPoint=function(){return false};U.prototype.RayCast=function(){return false};U.prototype.ComputeAABB=function(){};U.prototype.ComputeMass=function(){};U.prototype.ComputeSubmergedArea=function(){return 0};U.TestOverlap=function(k,z,u,D){var H=new L;H.proxyA=new W;H.proxyA.Set(k);H.proxyB=new W;H.proxyB.Set(u);H.transformA=z;H.transformB=D;H.useRadii=true;k=new Y;k.count=0;z=new I;M.Distance(z,k,H);return z.distance<10*Number.MIN_VALUE};
U.prototype.b2Shape=function(){this.m_type=U.e_unknownShape;this.m_radius=F.b2_linearSlop};Box2D.postDefs.push(function(){Box2D.Collision.Shapes.b2Shape.e_unknownShape=parseInt(-1);Box2D.Collision.Shapes.b2Shape.e_circleShape=0;Box2D.Collision.Shapes.b2Shape.e_polygonShape=1;Box2D.Collision.Shapes.b2Shape.e_edgeShape=2;Box2D.Collision.Shapes.b2Shape.e_shapeTypeCount=3;Box2D.Collision.Shapes.b2Shape.e_hitCollide=1;Box2D.Collision.Shapes.b2Shape.e_missCollide=0;Box2D.Collision.Shapes.b2Shape.e_startsInsideCollide=
parseInt(-1)})})();
(function(){var F=Box2D.Common.b2Color,G=Box2D.Common.b2Settings,K=Box2D.Common.Math.b2Math;F.b2Color=function(){this._b=this._g=this._r=0};F.prototype.b2Color=function(y,w,A){if(y===undefined)y=0;if(w===undefined)w=0;if(A===undefined)A=0;this._r=Box2D.parseUInt(255*K.Clamp(y,0,1));this._g=Box2D.parseUInt(255*K.Clamp(w,0,1));this._b=Box2D.parseUInt(255*K.Clamp(A,0,1))};F.prototype.Set=function(y,w,A){if(y===undefined)y=0;if(w===undefined)w=0;if(A===undefined)A=0;this._r=Box2D.parseUInt(255*K.Clamp(y,
0,1));this._g=Box2D.parseUInt(255*K.Clamp(w,0,1));this._b=Box2D.parseUInt(255*K.Clamp(A,0,1))};Object.defineProperty(F.prototype,"r",{enumerable:false,configurable:true,set:function(y){if(y===undefined)y=0;this._r=Box2D.parseUInt(255*K.Clamp(y,0,1))}});Object.defineProperty(F.prototype,"g",{enumerable:false,configurable:true,set:function(y){if(y===undefined)y=0;this._g=Box2D.parseUInt(255*K.Clamp(y,0,1))}});Object.defineProperty(F.prototype,"b",{enumerable:false,configurable:true,set:function(y){if(y===
undefined)y=0;this._b=Box2D.parseUInt(255*K.Clamp(y,0,1))}});Object.defineProperty(F.prototype,"color",{enumerable:false,configurable:true,get:function(){return this._r<<16|this._g<<8|this._b}});G.b2Settings=function(){};G.b2MixFriction=function(y,w){if(y===undefined)y=0;if(w===undefined)w=0;return Math.sqrt(y*w)};G.b2MixRestitution=function(y,w){if(y===undefined)y=0;if(w===undefined)w=0;return y>w?y:w};G.b2Assert=function(y){if(!y)throw"Assertion Failed";};Box2D.postDefs.push(function(){Box2D.Common.b2Settings.VERSION=
"2.1alpha";Box2D.Common.b2Settings.USHRT_MAX=65535;Box2D.Common.b2Settings.b2_pi=Math.PI;Box2D.Common.b2Settings.b2_maxManifoldPoints=2;Box2D.Common.b2Settings.b2_aabbExtension=0.1;Box2D.Common.b2Settings.b2_aabbMultiplier=2;Box2D.Common.b2Settings.b2_polygonRadius=2*G.b2_linearSlop;Box2D.Common.b2Settings.b2_linearSlop=0.0050;Box2D.Common.b2Settings.b2_angularSlop=2/180*G.b2_pi;Box2D.Common.b2Settings.b2_toiSlop=8*G.b2_linearSlop;Box2D.Common.b2Settings.b2_maxTOIContactsPerIsland=32;Box2D.Common.b2Settings.b2_maxTOIJointsPerIsland=
32;Box2D.Common.b2Settings.b2_velocityThreshold=1;Box2D.Common.b2Settings.b2_maxLinearCorrection=0.2;Box2D.Common.b2Settings.b2_maxAngularCorrection=8/180*G.b2_pi;Box2D.Common.b2Settings.b2_maxTranslation=2;Box2D.Common.b2Settings.b2_maxTranslationSquared=G.b2_maxTranslation*G.b2_maxTranslation;Box2D.Common.b2Settings.b2_maxRotation=0.5*G.b2_pi;Box2D.Common.b2Settings.b2_maxRotationSquared=G.b2_maxRotation*G.b2_maxRotation;Box2D.Common.b2Settings.b2_contactBaumgarte=0.2;Box2D.Common.b2Settings.b2_timeToSleep=
0.5;Box2D.Common.b2Settings.b2_linearSleepTolerance=0.01;Box2D.Common.b2Settings.b2_angularSleepTolerance=2/180*G.b2_pi})})();
(function(){var F=Box2D.Common.Math.b2Mat22,G=Box2D.Common.Math.b2Mat33,K=Box2D.Common.Math.b2Math,y=Box2D.Common.Math.b2Sweep,w=Box2D.Common.Math.b2Transform,A=Box2D.Common.Math.b2Vec2,U=Box2D.Common.Math.b2Vec3;F.b2Mat22=function(){this.col1=new A;this.col2=new A};F.prototype.b2Mat22=function(){this.SetIdentity()};F.FromAngle=function(p){if(p===undefined)p=0;var B=new F;B.Set(p);return B};F.FromVV=function(p,B){var Q=new F;Q.SetVV(p,B);return Q};F.prototype.Set=function(p){if(p===undefined)p=0;
var B=Math.cos(p);p=Math.sin(p);this.col1.x=B;this.col2.x=-p;this.col1.y=p;this.col2.y=B};F.prototype.SetVV=function(p,B){this.col1.SetV(p);this.col2.SetV(B)};F.prototype.Copy=function(){var p=new F;p.SetM(this);return p};F.prototype.SetM=function(p){this.col1.SetV(p.col1);this.col2.SetV(p.col2)};F.prototype.AddM=function(p){this.col1.x+=p.col1.x;this.col1.y+=p.col1.y;this.col2.x+=p.col2.x;this.col2.y+=p.col2.y};F.prototype.SetIdentity=function(){this.col1.x=1;this.col2.x=0;this.col1.y=0;this.col2.y=
1};F.prototype.SetZero=function(){this.col1.x=0;this.col2.x=0;this.col1.y=0;this.col2.y=0};F.prototype.GetAngle=function(){return Math.atan2(this.col1.y,this.col1.x)};F.prototype.GetInverse=function(p){var B=this.col1.x,Q=this.col2.x,V=this.col1.y,M=this.col2.y,L=B*M-Q*V;if(L!=0)L=1/L;p.col1.x=L*M;p.col2.x=-L*Q;p.col1.y=-L*V;p.col2.y=L*B;return p};F.prototype.Solve=function(p,B,Q){if(B===undefined)B=0;if(Q===undefined)Q=0;var V=this.col1.x,M=this.col2.x,L=this.col1.y,I=this.col2.y,W=V*I-M*L;if(W!=
0)W=1/W;p.x=W*(I*B-M*Q);p.y=W*(V*Q-L*B);return p};F.prototype.Abs=function(){this.col1.Abs();this.col2.Abs()};G.b2Mat33=function(){this.col1=new U;this.col2=new U;this.col3=new U};G.prototype.b2Mat33=function(p,B,Q){if(p===undefined)p=null;if(B===undefined)B=null;if(Q===undefined)Q=null;if(!p&&!B&&!Q){this.col1.SetZero();this.col2.SetZero();this.col3.SetZero()}else{this.col1.SetV(p);this.col2.SetV(B);this.col3.SetV(Q)}};G.prototype.SetVVV=function(p,B,Q){this.col1.SetV(p);this.col2.SetV(B);this.col3.SetV(Q)};
G.prototype.Copy=function(){return new G(this.col1,this.col2,this.col3)};G.prototype.SetM=function(p){this.col1.SetV(p.col1);this.col2.SetV(p.col2);this.col3.SetV(p.col3)};G.prototype.AddM=function(p){this.col1.x+=p.col1.x;this.col1.y+=p.col1.y;this.col1.z+=p.col1.z;this.col2.x+=p.col2.x;this.col2.y+=p.col2.y;this.col2.z+=p.col2.z;this.col3.x+=p.col3.x;this.col3.y+=p.col3.y;this.col3.z+=p.col3.z};G.prototype.SetIdentity=function(){this.col1.x=1;this.col2.x=0;this.col3.x=0;this.col1.y=0;this.col2.y=
1;this.col3.y=0;this.col1.z=0;this.col2.z=0;this.col3.z=1};G.prototype.SetZero=function(){this.col1.x=0;this.col2.x=0;this.col3.x=0;this.col1.y=0;this.col2.y=0;this.col3.y=0;this.col1.z=0;this.col2.z=0;this.col3.z=0};G.prototype.Solve22=function(p,B,Q){if(B===undefined)B=0;if(Q===undefined)Q=0;var V=this.col1.x,M=this.col2.x,L=this.col1.y,I=this.col2.y,W=V*I-M*L;if(W!=0)W=1/W;p.x=W*(I*B-M*Q);p.y=W*(V*Q-L*B);return p};G.prototype.Solve33=function(p,B,Q,V){if(B===undefined)B=0;if(Q===undefined)Q=0;
if(V===undefined)V=0;var M=this.col1.x,L=this.col1.y,I=this.col1.z,W=this.col2.x,Y=this.col2.y,k=this.col2.z,z=this.col3.x,u=this.col3.y,D=this.col3.z,H=M*(Y*D-k*u)+L*(k*z-W*D)+I*(W*u-Y*z);if(H!=0)H=1/H;p.x=H*(B*(Y*D-k*u)+Q*(k*z-W*D)+V*(W*u-Y*z));p.y=H*(M*(Q*D-V*u)+L*(V*z-B*D)+I*(B*u-Q*z));p.z=H*(M*(Y*V-k*Q)+L*(k*B-W*V)+I*(W*Q-Y*B));return p};K.b2Math=function(){};K.IsValid=function(p){if(p===undefined)p=0;return isFinite(p)};K.Dot=function(p,B){return p.x*B.x+p.y*B.y};K.CrossVV=function(p,B){return p.x*
B.y-p.y*B.x};K.CrossVF=function(p,B){if(B===undefined)B=0;return new A(B*p.y,-B*p.x)};K.CrossFV=function(p,B){if(p===undefined)p=0;return new A(-p*B.y,p*B.x)};K.MulMV=function(p,B){return new A(p.col1.x*B.x+p.col2.x*B.y,p.col1.y*B.x+p.col2.y*B.y)};K.MulTMV=function(p,B){return new A(K.Dot(B,p.col1),K.Dot(B,p.col2))};K.MulX=function(p,B){var Q=K.MulMV(p.R,B);Q.x+=p.position.x;Q.y+=p.position.y;return Q};K.MulXT=function(p,B){var Q=K.SubtractVV(B,p.position),V=Q.x*p.R.col1.x+Q.y*p.R.col1.y;Q.y=Q.x*
p.R.col2.x+Q.y*p.R.col2.y;Q.x=V;return Q};K.AddVV=function(p,B){return new A(p.x+B.x,p.y+B.y)};K.SubtractVV=function(p,B){return new A(p.x-B.x,p.y-B.y)};K.Distance=function(p,B){var Q=p.x-B.x,V=p.y-B.y;return Math.sqrt(Q*Q+V*V)};K.DistanceSquared=function(p,B){var Q=p.x-B.x,V=p.y-B.y;return Q*Q+V*V};K.MulFV=function(p,B){if(p===undefined)p=0;return new A(p*B.x,p*B.y)};K.AddMM=function(p,B){return F.FromVV(K.AddVV(p.col1,B.col1),K.AddVV(p.col2,B.col2))};K.MulMM=function(p,B){return F.FromVV(K.MulMV(p,
B.col1),K.MulMV(p,B.col2))};K.MulTMM=function(p,B){var Q=new A(K.Dot(p.col1,B.col1),K.Dot(p.col2,B.col1)),V=new A(K.Dot(p.col1,B.col2),K.Dot(p.col2,B.col2));return F.FromVV(Q,V)};K.Abs=function(p){if(p===undefined)p=0;return p>0?p:-p};K.AbsV=function(p){return new A(K.Abs(p.x),K.Abs(p.y))};K.AbsM=function(p){return F.FromVV(K.AbsV(p.col1),K.AbsV(p.col2))};K.Min=function(p,B){if(p===undefined)p=0;if(B===undefined)B=0;return p<B?p:B};K.MinV=function(p,B){return new A(K.Min(p.x,B.x),K.Min(p.y,B.y))};
K.Max=function(p,B){if(p===undefined)p=0;if(B===undefined)B=0;return p>B?p:B};K.MaxV=function(p,B){return new A(K.Max(p.x,B.x),K.Max(p.y,B.y))};K.Clamp=function(p,B,Q){if(p===undefined)p=0;if(B===undefined)B=0;if(Q===undefined)Q=0;return p<B?B:p>Q?Q:p};K.ClampV=function(p,B,Q){return K.MaxV(B,K.MinV(p,Q))};K.Swap=function(p,B){var Q=p[0];p[0]=B[0];B[0]=Q};K.Random=function(){return Math.random()*2-1};K.RandomRange=function(p,B){if(p===undefined)p=0;if(B===undefined)B=0;var Q=Math.random();return Q=
(B-p)*Q+p};K.NextPowerOfTwo=function(p){if(p===undefined)p=0;p|=p>>1&2147483647;p|=p>>2&1073741823;p|=p>>4&268435455;p|=p>>8&16777215;p|=p>>16&65535;return p+1};K.IsPowerOfTwo=function(p){if(p===undefined)p=0;return p>0&&(p&p-1)==0};Box2D.postDefs.push(function(){Box2D.Common.Math.b2Math.b2Vec2_zero=new A(0,0);Box2D.Common.Math.b2Math.b2Mat22_identity=F.FromVV(new A(1,0),new A(0,1));Box2D.Common.Math.b2Math.b2Transform_identity=new w(K.b2Vec2_zero,K.b2Mat22_identity)});y.b2Sweep=function(){this.localCenter=
new A;this.c0=new A;this.c=new A};y.prototype.Set=function(p){this.localCenter.SetV(p.localCenter);this.c0.SetV(p.c0);this.c.SetV(p.c);this.a0=p.a0;this.a=p.a;this.t0=p.t0};y.prototype.Copy=function(){var p=new y;p.localCenter.SetV(this.localCenter);p.c0.SetV(this.c0);p.c.SetV(this.c);p.a0=this.a0;p.a=this.a;p.t0=this.t0;return p};y.prototype.GetTransform=function(p,B){if(B===undefined)B=0;p.position.x=(1-B)*this.c0.x+B*this.c.x;p.position.y=(1-B)*this.c0.y+B*this.c.y;p.R.Set((1-B)*this.a0+B*this.a);
var Q=p.R;p.position.x-=Q.col1.x*this.localCenter.x+Q.col2.x*this.localCenter.y;p.position.y-=Q.col1.y*this.localCenter.x+Q.col2.y*this.localCenter.y};y.prototype.Advance=function(p){if(p===undefined)p=0;if(this.t0<p&&1-this.t0>Number.MIN_VALUE){var B=(p-this.t0)/(1-this.t0);this.c0.x=(1-B)*this.c0.x+B*this.c.x;this.c0.y=(1-B)*this.c0.y+B*this.c.y;this.a0=(1-B)*this.a0+B*this.a;this.t0=p}};w.b2Transform=function(){this.position=new A;this.R=new F};w.prototype.b2Transform=function(p,B){if(p===undefined)p=
null;if(B===undefined)B=null;if(p){this.position.SetV(p);this.R.SetM(B)}};w.prototype.Initialize=function(p,B){this.position.SetV(p);this.R.SetM(B)};w.prototype.SetIdentity=function(){this.position.SetZero();this.R.SetIdentity()};w.prototype.Set=function(p){this.position.SetV(p.position);this.R.SetM(p.R)};w.prototype.GetAngle=function(){return Math.atan2(this.R.col1.y,this.R.col1.x)};A.b2Vec2=function(){};A.prototype.b2Vec2=function(p,B){if(p===undefined)p=0;if(B===undefined)B=0;this.x=p;this.y=B};
A.prototype.SetZero=function(){this.y=this.x=0};A.prototype.Set=function(p,B){if(p===undefined)p=0;if(B===undefined)B=0;this.x=p;this.y=B};A.prototype.SetV=function(p){this.x=p.x;this.y=p.y};A.prototype.GetNegative=function(){return new A(-this.x,-this.y)};A.prototype.NegativeSelf=function(){this.x=-this.x;this.y=-this.y};A.Make=function(p,B){if(p===undefined)p=0;if(B===undefined)B=0;return new A(p,B)};A.prototype.Copy=function(){return new A(this.x,this.y)};A.prototype.Add=function(p){this.x+=p.x;
this.y+=p.y};A.prototype.Subtract=function(p){this.x-=p.x;this.y-=p.y};A.prototype.Multiply=function(p){if(p===undefined)p=0;this.x*=p;this.y*=p};A.prototype.MulM=function(p){var B=this.x;this.x=p.col1.x*B+p.col2.x*this.y;this.y=p.col1.y*B+p.col2.y*this.y};A.prototype.MulTM=function(p){var B=K.Dot(this,p.col1);this.y=K.Dot(this,p.col2);this.x=B};A.prototype.CrossVF=function(p){if(p===undefined)p=0;var B=this.x;this.x=p*this.y;this.y=-p*B};A.prototype.CrossFV=function(p){if(p===undefined)p=0;var B=
this.x;this.x=-p*this.y;this.y=p*B};A.prototype.MinV=function(p){this.x=this.x<p.x?this.x:p.x;this.y=this.y<p.y?this.y:p.y};A.prototype.MaxV=function(p){this.x=this.x>p.x?this.x:p.x;this.y=this.y>p.y?this.y:p.y};A.prototype.Abs=function(){if(this.x<0)this.x=-this.x;if(this.y<0)this.y=-this.y};A.prototype.Length=function(){return Math.sqrt(this.x*this.x+this.y*this.y)};A.prototype.LengthSquared=function(){return this.x*this.x+this.y*this.y};A.prototype.Normalize=function(){var p=Math.sqrt(this.x*this.x+
this.y*this.y);if(p<Number.MIN_VALUE)return 0;var B=1/p;this.x*=B;this.y*=B;return p};A.prototype.IsValid=function(){return K.IsValid(this.x)&&K.IsValid(this.y)};U.b2Vec3=function(){};U.prototype.b2Vec3=function(p,B,Q){if(p===undefined)p=0;if(B===undefined)B=0;if(Q===undefined)Q=0;this.x=p;this.y=B;this.z=Q};U.prototype.SetZero=function(){this.x=this.y=this.z=0};U.prototype.Set=function(p,B,Q){if(p===undefined)p=0;if(B===undefined)B=0;if(Q===undefined)Q=0;this.x=p;this.y=B;this.z=Q};U.prototype.SetV=
function(p){this.x=p.x;this.y=p.y;this.z=p.z};U.prototype.GetNegative=function(){return new U(-this.x,-this.y,-this.z)};U.prototype.NegativeSelf=function(){this.x=-this.x;this.y=-this.y;this.z=-this.z};U.prototype.Copy=function(){return new U(this.x,this.y,this.z)};U.prototype.Add=function(p){this.x+=p.x;this.y+=p.y;this.z+=p.z};U.prototype.Subtract=function(p){this.x-=p.x;this.y-=p.y;this.z-=p.z};U.prototype.Multiply=function(p){if(p===undefined)p=0;this.x*=p;this.y*=p;this.z*=p}})();
(function(){var F=Box2D.Common.Math.b2Math,G=Box2D.Common.Math.b2Sweep,K=Box2D.Common.Math.b2Transform,y=Box2D.Common.Math.b2Vec2,w=Box2D.Common.b2Color,A=Box2D.Common.b2Settings,U=Box2D.Collision.b2AABB,p=Box2D.Collision.b2ContactPoint,B=Box2D.Collision.b2DynamicTreeBroadPhase,Q=Box2D.Collision.b2RayCastInput,V=Box2D.Collision.b2RayCastOutput,M=Box2D.Collision.Shapes.b2CircleShape,L=Box2D.Collision.Shapes.b2EdgeShape,I=Box2D.Collision.Shapes.b2MassData,W=Box2D.Collision.Shapes.b2PolygonShape,Y=Box2D.Collision.Shapes.b2Shape,
k=Box2D.Dynamics.b2Body,z=Box2D.Dynamics.b2BodyDef,u=Box2D.Dynamics.b2ContactFilter,D=Box2D.Dynamics.b2ContactImpulse,H=Box2D.Dynamics.b2ContactListener,O=Box2D.Dynamics.b2ContactManager,E=Box2D.Dynamics.b2DebugDraw,R=Box2D.Dynamics.b2DestructionListener,N=Box2D.Dynamics.b2FilterData,S=Box2D.Dynamics.b2Fixture,aa=Box2D.Dynamics.b2FixtureDef,Z=Box2D.Dynamics.b2Island,d=Box2D.Dynamics.b2TimeStep,h=Box2D.Dynamics.b2World,l=Box2D.Dynamics.Contacts.b2Contact,j=Box2D.Dynamics.Contacts.b2ContactFactory,
o=Box2D.Dynamics.Contacts.b2ContactSolver,q=Box2D.Dynamics.Joints.b2Joint,n=Box2D.Dynamics.Joints.b2PulleyJoint;k.b2Body=function(){this.m_xf=new K;this.m_sweep=new G;this.m_linearVelocity=new y;this.m_force=new y};k.prototype.connectEdges=function(a,c,g){if(g===undefined)g=0;var b=Math.atan2(c.GetDirectionVector().y,c.GetDirectionVector().x);g=F.MulFV(Math.tan((b-g)*0.5),c.GetDirectionVector());g=F.SubtractVV(g,c.GetNormalVector());g=F.MulFV(A.b2_toiSlop,g);g=F.AddVV(g,c.GetVertex1());var e=F.AddVV(a.GetDirectionVector(),
c.GetDirectionVector());e.Normalize();var f=F.Dot(a.GetDirectionVector(),c.GetNormalVector())>0;a.SetNextEdge(c,g,e,f);c.SetPrevEdge(a,g,e,f);return b};k.prototype.CreateFixture=function(a){if(this.m_world.IsLocked()==true)return null;var c=new S;c.Create(this,this.m_xf,a);this.m_flags&k.e_activeFlag&&c.CreateProxy(this.m_world.m_contactManager.m_broadPhase,this.m_xf);c.m_next=this.m_fixtureList;this.m_fixtureList=c;++this.m_fixtureCount;c.m_body=this;c.m_density>0&&this.ResetMassData();this.m_world.m_flags|=
h.e_newFixture;return c};k.prototype.CreateFixture2=function(a,c){if(c===undefined)c=0;var g=new aa;g.shape=a;g.density=c;return this.CreateFixture(g)};k.prototype.DestroyFixture=function(a){if(this.m_world.IsLocked()!=true){for(var c=this.m_fixtureList,g=null;c!=null;){if(c==a){if(g)g.m_next=a.m_next;else this.m_fixtureList=a.m_next;break}g=c;c=c.m_next}for(c=this.m_contactList;c;){g=c.contact;c=c.next;var b=g.GetFixtureA(),e=g.GetFixtureB();if(a==b||a==e)this.m_world.m_contactManager.Destroy(g)}this.m_flags&
k.e_activeFlag&&a.DestroyProxy(this.m_world.m_contactManager.m_broadPhase);a.Destroy();a.m_body=null;a.m_next=null;--this.m_fixtureCount;this.ResetMassData()}};k.prototype.SetPositionAndAngle=function(a,c){if(c===undefined)c=0;var g;if(this.m_world.IsLocked()!=true){this.m_xf.R.Set(c);this.m_xf.position.SetV(a);g=this.m_xf.R;var b=this.m_sweep.localCenter;this.m_sweep.c.x=g.col1.x*b.x+g.col2.x*b.y;this.m_sweep.c.y=g.col1.y*b.x+g.col2.y*b.y;this.m_sweep.c.x+=this.m_xf.position.x;this.m_sweep.c.y+=
this.m_xf.position.y;this.m_sweep.c0.SetV(this.m_sweep.c);this.m_sweep.a0=this.m_sweep.a=c;b=this.m_world.m_contactManager.m_broadPhase;for(g=this.m_fixtureList;g;g=g.m_next)g.Synchronize(b,this.m_xf,this.m_xf);this.m_world.m_contactManager.FindNewContacts()}};k.prototype.SetTransform=function(a){this.SetPositionAndAngle(a.position,a.GetAngle())};k.prototype.GetTransform=function(){return this.m_xf};k.prototype.GetPosition=function(){return this.m_xf.position};k.prototype.SetPosition=function(a){this.SetPositionAndAngle(a,
this.GetAngle())};k.prototype.GetAngle=function(){return this.m_sweep.a};k.prototype.SetAngle=function(a){if(a===undefined)a=0;this.SetPositionAndAngle(this.GetPosition(),a)};k.prototype.GetWorldCenter=function(){return this.m_sweep.c};k.prototype.GetLocalCenter=function(){return this.m_sweep.localCenter};k.prototype.SetLinearVelocity=function(a){this.m_type!=k.b2_staticBody&&this.m_linearVelocity.SetV(a)};k.prototype.GetLinearVelocity=function(){return this.m_linearVelocity};k.prototype.SetAngularVelocity=
function(a){if(a===undefined)a=0;if(this.m_type!=k.b2_staticBody)this.m_angularVelocity=a};k.prototype.GetAngularVelocity=function(){return this.m_angularVelocity};k.prototype.GetDefinition=function(){var a=new z;a.type=this.GetType();a.allowSleep=(this.m_flags&k.e_allowSleepFlag)==k.e_allowSleepFlag;a.angle=this.GetAngle();a.angularDamping=this.m_angularDamping;a.angularVelocity=this.m_angularVelocity;a.fixedRotation=(this.m_flags&k.e_fixedRotationFlag)==k.e_fixedRotationFlag;a.bullet=(this.m_flags&
k.e_bulletFlag)==k.e_bulletFlag;a.awake=(this.m_flags&k.e_awakeFlag)==k.e_awakeFlag;a.linearDamping=this.m_linearDamping;a.linearVelocity.SetV(this.GetLinearVelocity());a.position=this.GetPosition();a.userData=this.GetUserData();return a};k.prototype.ApplyForce=function(a,c){if(this.m_type==k.b2_dynamicBody){this.IsAwake()==false&&this.SetAwake(true);this.m_force.x+=a.x;this.m_force.y+=a.y;this.m_torque+=(c.x-this.m_sweep.c.x)*a.y-(c.y-this.m_sweep.c.y)*a.x}};k.prototype.ApplyTorque=function(a){if(a===
undefined)a=0;if(this.m_type==k.b2_dynamicBody){this.IsAwake()==false&&this.SetAwake(true);this.m_torque+=a}};k.prototype.ApplyImpulse=function(a,c){if(this.m_type==k.b2_dynamicBody){this.IsAwake()==false&&this.SetAwake(true);this.m_linearVelocity.x+=this.m_invMass*a.x;this.m_linearVelocity.y+=this.m_invMass*a.y;this.m_angularVelocity+=this.m_invI*((c.x-this.m_sweep.c.x)*a.y-(c.y-this.m_sweep.c.y)*a.x)}};k.prototype.Split=function(a){for(var c=this.GetLinearVelocity().Copy(),g=this.GetAngularVelocity(),
b=this.GetWorldCenter(),e=this.m_world.CreateBody(this.GetDefinition()),f,m=this.m_fixtureList;m;)if(a(m)){var r=m.m_next;if(f)f.m_next=r;else this.m_fixtureList=r;this.m_fixtureCount--;m.m_next=e.m_fixtureList;e.m_fixtureList=m;e.m_fixtureCount++;m.m_body=e;m=r}else{f=m;m=m.m_next}this.ResetMassData();e.ResetMassData();f=this.GetWorldCenter();a=e.GetWorldCenter();f=F.AddVV(c,F.CrossFV(g,F.SubtractVV(f,b)));c=F.AddVV(c,F.CrossFV(g,F.SubtractVV(a,b)));this.SetLinearVelocity(f);e.SetLinearVelocity(c);
this.SetAngularVelocity(g);e.SetAngularVelocity(g);this.SynchronizeFixtures();e.SynchronizeFixtures();return e};k.prototype.Merge=function(a){var c;for(c=a.m_fixtureList;c;){var g=c.m_next;a.m_fixtureCount--;c.m_next=this.m_fixtureList;this.m_fixtureList=c;this.m_fixtureCount++;c.m_body=e;c=g}b.m_fixtureCount=0;var b=this,e=a;b.GetWorldCenter();e.GetWorldCenter();b.GetLinearVelocity().Copy();e.GetLinearVelocity().Copy();b.GetAngularVelocity();e.GetAngularVelocity();b.ResetMassData();this.SynchronizeFixtures()};
k.prototype.GetMass=function(){return this.m_mass};k.prototype.GetInertia=function(){return this.m_I};k.prototype.GetMassData=function(a){a.mass=this.m_mass;a.I=this.m_I;a.center.SetV(this.m_sweep.localCenter)};k.prototype.SetMassData=function(a){A.b2Assert(this.m_world.IsLocked()==false);if(this.m_world.IsLocked()!=true)if(this.m_type==k.b2_dynamicBody){this.m_invI=this.m_I=this.m_invMass=0;this.m_mass=a.mass;if(this.m_mass<=0)this.m_mass=1;this.m_invMass=1/this.m_mass;if(a.I>0&&(this.m_flags&k.e_fixedRotationFlag)==
0){this.m_I=a.I-this.m_mass*(a.center.x*a.center.x+a.center.y*a.center.y);this.m_invI=1/this.m_I}var c=this.m_sweep.c.Copy();this.m_sweep.localCenter.SetV(a.center);this.m_sweep.c0.SetV(F.MulX(this.m_xf,this.m_sweep.localCenter));this.m_sweep.c.SetV(this.m_sweep.c0);this.m_linearVelocity.x+=this.m_angularVelocity*-(this.m_sweep.c.y-c.y);this.m_linearVelocity.y+=this.m_angularVelocity*+(this.m_sweep.c.x-c.x)}};k.prototype.ResetMassData=function(){this.m_invI=this.m_I=this.m_invMass=this.m_mass=0;this.m_sweep.localCenter.SetZero();
if(!(this.m_type==k.b2_staticBody||this.m_type==k.b2_kinematicBody)){for(var a=y.Make(0,0),c=this.m_fixtureList;c;c=c.m_next)if(c.m_density!=0){var g=c.GetMassData();this.m_mass+=g.mass;a.x+=g.center.x*g.mass;a.y+=g.center.y*g.mass;this.m_I+=g.I}if(this.m_mass>0){this.m_invMass=1/this.m_mass;a.x*=this.m_invMass;a.y*=this.m_invMass}else this.m_invMass=this.m_mass=1;if(this.m_I>0&&(this.m_flags&k.e_fixedRotationFlag)==0){this.m_I-=this.m_mass*(a.x*a.x+a.y*a.y);this.m_I*=this.m_inertiaScale;A.b2Assert(this.m_I>
0);this.m_invI=1/this.m_I}else this.m_invI=this.m_I=0;c=this.m_sweep.c.Copy();this.m_sweep.localCenter.SetV(a);this.m_sweep.c0.SetV(F.MulX(this.m_xf,this.m_sweep.localCenter));this.m_sweep.c.SetV(this.m_sweep.c0);this.m_linearVelocity.x+=this.m_angularVelocity*-(this.m_sweep.c.y-c.y);this.m_linearVelocity.y+=this.m_angularVelocity*+(this.m_sweep.c.x-c.x)}};k.prototype.GetWorldPoint=function(a){var c=this.m_xf.R;a=new y(c.col1.x*a.x+c.col2.x*a.y,c.col1.y*a.x+c.col2.y*a.y);a.x+=this.m_xf.position.x;
a.y+=this.m_xf.position.y;return a};k.prototype.GetWorldVector=function(a){return F.MulMV(this.m_xf.R,a)};k.prototype.GetLocalPoint=function(a){return F.MulXT(this.m_xf,a)};k.prototype.GetLocalVector=function(a){return F.MulTMV(this.m_xf.R,a)};k.prototype.GetLinearVelocityFromWorldPoint=function(a){return new y(this.m_linearVelocity.x-this.m_angularVelocity*(a.y-this.m_sweep.c.y),this.m_linearVelocity.y+this.m_angularVelocity*(a.x-this.m_sweep.c.x))};k.prototype.GetLinearVelocityFromLocalPoint=function(a){var c=
this.m_xf.R;a=new y(c.col1.x*a.x+c.col2.x*a.y,c.col1.y*a.x+c.col2.y*a.y);a.x+=this.m_xf.position.x;a.y+=this.m_xf.position.y;return new y(this.m_linearVelocity.x-this.m_angularVelocity*(a.y-this.m_sweep.c.y),this.m_linearVelocity.y+this.m_angularVelocity*(a.x-this.m_sweep.c.x))};k.prototype.GetLinearDamping=function(){return this.m_linearDamping};k.prototype.SetLinearDamping=function(a){if(a===undefined)a=0;this.m_linearDamping=a};k.prototype.GetAngularDamping=function(){return this.m_angularDamping};
k.prototype.SetAngularDamping=function(a){if(a===undefined)a=0;this.m_angularDamping=a};k.prototype.SetType=function(a){if(a===undefined)a=0;if(this.m_type!=a){this.m_type=a;this.ResetMassData();if(this.m_type==k.b2_staticBody){this.m_linearVelocity.SetZero();this.m_angularVelocity=0}this.SetAwake(true);this.m_force.SetZero();this.m_torque=0;for(a=this.m_contactList;a;a=a.next)a.contact.FlagForFiltering()}};k.prototype.GetType=function(){return this.m_type};k.prototype.SetBullet=function(a){if(a)this.m_flags|=
k.e_bulletFlag;else this.m_flags&=~k.e_bulletFlag};k.prototype.IsBullet=function(){return(this.m_flags&k.e_bulletFlag)==k.e_bulletFlag};k.prototype.SetSleepingAllowed=function(a){if(a)this.m_flags|=k.e_allowSleepFlag;else{this.m_flags&=~k.e_allowSleepFlag;this.SetAwake(true)}};k.prototype.SetAwake=function(a){if(a){this.m_flags|=k.e_awakeFlag;this.m_sleepTime=0}else{this.m_flags&=~k.e_awakeFlag;this.m_sleepTime=0;this.m_linearVelocity.SetZero();this.m_angularVelocity=0;this.m_force.SetZero();this.m_torque=
0}};k.prototype.IsAwake=function(){return(this.m_flags&k.e_awakeFlag)==k.e_awakeFlag};k.prototype.SetFixedRotation=function(a){if(a)this.m_flags|=k.e_fixedRotationFlag;else this.m_flags&=~k.e_fixedRotationFlag;this.ResetMassData()};k.prototype.IsFixedRotation=function(){return(this.m_flags&k.e_fixedRotationFlag)==k.e_fixedRotationFlag};k.prototype.SetActive=function(a){if(a!=this.IsActive()){var c;if(a){this.m_flags|=k.e_activeFlag;a=this.m_world.m_contactManager.m_broadPhase;for(c=this.m_fixtureList;c;c=
c.m_next)c.CreateProxy(a,this.m_xf)}else{this.m_flags&=~k.e_activeFlag;a=this.m_world.m_contactManager.m_broadPhase;for(c=this.m_fixtureList;c;c=c.m_next)c.DestroyProxy(a);for(a=this.m_contactList;a;){c=a;a=a.next;this.m_world.m_contactManager.Destroy(c.contact)}this.m_contactList=null}}};k.prototype.IsActive=function(){return(this.m_flags&k.e_activeFlag)==k.e_activeFlag};k.prototype.IsSleepingAllowed=function(){return(this.m_flags&k.e_allowSleepFlag)==k.e_allowSleepFlag};k.prototype.GetFixtureList=
function(){return this.m_fixtureList};k.prototype.GetJointList=function(){return this.m_jointList};k.prototype.GetControllerList=function(){return this.m_controllerList};k.prototype.GetContactList=function(){return this.m_contactList};k.prototype.GetNext=function(){return this.m_next};k.prototype.GetUserData=function(){return this.m_userData};k.prototype.SetUserData=function(a){this.m_userData=a};k.prototype.GetWorld=function(){return this.m_world};k.prototype.b2Body=function(a,c){this.m_flags=0;
if(a.bullet)this.m_flags|=k.e_bulletFlag;if(a.fixedRotation)this.m_flags|=k.e_fixedRotationFlag;if(a.allowSleep)this.m_flags|=k.e_allowSleepFlag;if(a.awake)this.m_flags|=k.e_awakeFlag;if(a.active)this.m_flags|=k.e_activeFlag;this.m_world=c;this.m_xf.position.SetV(a.position);this.m_xf.R.Set(a.angle);this.m_sweep.localCenter.SetZero();this.m_sweep.t0=1;this.m_sweep.a0=this.m_sweep.a=a.angle;var g=this.m_xf.R,b=this.m_sweep.localCenter;this.m_sweep.c.x=g.col1.x*b.x+g.col2.x*b.y;this.m_sweep.c.y=g.col1.y*
b.x+g.col2.y*b.y;this.m_sweep.c.x+=this.m_xf.position.x;this.m_sweep.c.y+=this.m_xf.position.y;this.m_sweep.c0.SetV(this.m_sweep.c);this.m_contactList=this.m_controllerList=this.m_jointList=null;this.m_controllerCount=0;this.m_next=this.m_prev=null;this.m_linearVelocity.SetV(a.linearVelocity);this.m_angularVelocity=a.angularVelocity;this.m_linearDamping=a.linearDamping;this.m_angularDamping=a.angularDamping;this.m_force.Set(0,0);this.m_sleepTime=this.m_torque=0;this.m_type=a.type;if(this.m_type==
k.b2_dynamicBody)this.m_invMass=this.m_mass=1;else this.m_invMass=this.m_mass=0;this.m_invI=this.m_I=0;this.m_inertiaScale=a.inertiaScale;this.m_userData=a.userData;this.m_fixtureList=null;this.m_fixtureCount=0};k.prototype.SynchronizeFixtures=function(){var a=k.s_xf1;a.R.Set(this.m_sweep.a0);var c=a.R,g=this.m_sweep.localCenter;a.position.x=this.m_sweep.c0.x-(c.col1.x*g.x+c.col2.x*g.y);a.position.y=this.m_sweep.c0.y-(c.col1.y*g.x+c.col2.y*g.y);g=this.m_world.m_contactManager.m_broadPhase;for(c=this.m_fixtureList;c;c=
c.m_next)c.Synchronize(g,a,this.m_xf)};k.prototype.SynchronizeTransform=function(){this.m_xf.R.Set(this.m_sweep.a);var a=this.m_xf.R,c=this.m_sweep.localCenter;this.m_xf.position.x=this.m_sweep.c.x-(a.col1.x*c.x+a.col2.x*c.y);this.m_xf.position.y=this.m_sweep.c.y-(a.col1.y*c.x+a.col2.y*c.y)};k.prototype.ShouldCollide=function(a){if(this.m_type!=k.b2_dynamicBody&&a.m_type!=k.b2_dynamicBody)return false;for(var c=this.m_jointList;c;c=c.next)if(c.other==a)if(c.joint.m_collideConnected==false)return false;
return true};k.prototype.Advance=function(a){if(a===undefined)a=0;this.m_sweep.Advance(a);this.m_sweep.c.SetV(this.m_sweep.c0);this.m_sweep.a=this.m_sweep.a0;this.SynchronizeTransform()};Box2D.postDefs.push(function(){Box2D.Dynamics.b2Body.s_xf1=new K;Box2D.Dynamics.b2Body.e_islandFlag=1;Box2D.Dynamics.b2Body.e_awakeFlag=2;Box2D.Dynamics.b2Body.e_allowSleepFlag=4;Box2D.Dynamics.b2Body.e_bulletFlag=8;Box2D.Dynamics.b2Body.e_fixedRotationFlag=16;Box2D.Dynamics.b2Body.e_activeFlag=32;Box2D.Dynamics.b2Body.b2_staticBody=
0;Box2D.Dynamics.b2Body.b2_kinematicBody=1;Box2D.Dynamics.b2Body.b2_dynamicBody=2});z.b2BodyDef=function(){this.position=new y;this.linearVelocity=new y};z.prototype.b2BodyDef=function(){this.userData=null;this.position.Set(0,0);this.angle=0;this.linearVelocity.Set(0,0);this.angularDamping=this.linearDamping=this.angularVelocity=0;this.awake=this.allowSleep=true;this.bullet=this.fixedRotation=false;this.type=k.b2_staticBody;this.active=true;this.inertiaScale=1};u.b2ContactFilter=function(){};u.prototype.ShouldCollide=
function(a,c){var g=a.GetFilterData(),b=c.GetFilterData();if(g.groupIndex==b.groupIndex&&g.groupIndex!=0)return g.groupIndex>0;return(g.maskBits&b.categoryBits)!=0&&(g.categoryBits&b.maskBits)!=0};u.prototype.RayCollide=function(a,c){if(!a)return true;return this.ShouldCollide(a instanceof S?a:null,c)};Box2D.postDefs.push(function(){Box2D.Dynamics.b2ContactFilter.b2_defaultFilter=new u});D.b2ContactImpulse=function(){this.normalImpulses=new Vector_a2j_Number(A.b2_maxManifoldPoints);this.tangentImpulses=
new Vector_a2j_Number(A.b2_maxManifoldPoints)};H.b2ContactListener=function(){};H.prototype.BeginContact=function(){};H.prototype.EndContact=function(){};H.prototype.PreSolve=function(){};H.prototype.PostSolve=function(){};Box2D.postDefs.push(function(){Box2D.Dynamics.b2ContactListener.b2_defaultListener=new H});O.b2ContactManager=function(){};O.prototype.b2ContactManager=function(){this.m_world=null;this.m_contactCount=0;this.m_contactFilter=u.b2_defaultFilter;this.m_contactListener=H.b2_defaultListener;
this.m_contactFactory=new j(this.m_allocator);this.m_broadPhase=new B};O.prototype.AddPair=function(a,c){var g=a instanceof S?a:null,b=c instanceof S?c:null,e=g.GetBody(),f=b.GetBody();if(e!=f){for(var m=f.GetContactList();m;){if(m.other==e){var r=m.contact.GetFixtureA(),s=m.contact.GetFixtureB();if(r==g&&s==b)return;if(r==b&&s==g)return}m=m.next}if(f.ShouldCollide(e)!=false)if(this.m_contactFilter.ShouldCollide(g,b)!=false){m=this.m_contactFactory.Create(g,b);g=m.GetFixtureA();b=m.GetFixtureB();
e=g.m_body;f=b.m_body;m.m_prev=null;m.m_next=this.m_world.m_contactList;if(this.m_world.m_contactList!=null)this.m_world.m_contactList.m_prev=m;this.m_world.m_contactList=m;m.m_nodeA.contact=m;m.m_nodeA.other=f;m.m_nodeA.prev=null;m.m_nodeA.next=e.m_contactList;if(e.m_contactList!=null)e.m_contactList.prev=m.m_nodeA;e.m_contactList=m.m_nodeA;m.m_nodeB.contact=m;m.m_nodeB.other=e;m.m_nodeB.prev=null;m.m_nodeB.next=f.m_contactList;if(f.m_contactList!=null)f.m_contactList.prev=m.m_nodeB;f.m_contactList=
m.m_nodeB;++this.m_world.m_contactCount}}};O.prototype.FindNewContacts=function(){this.m_broadPhase.UpdatePairs(Box2D.generateCallback(this,this.AddPair))};O.prototype.Destroy=function(a){var c=a.GetFixtureA(),g=a.GetFixtureB();c=c.GetBody();g=g.GetBody();a.IsTouching()&&this.m_contactListener.EndContact(a);if(a.m_prev)a.m_prev.m_next=a.m_next;if(a.m_next)a.m_next.m_prev=a.m_prev;if(a==this.m_world.m_contactList)this.m_world.m_contactList=a.m_next;if(a.m_nodeA.prev)a.m_nodeA.prev.next=a.m_nodeA.next;
if(a.m_nodeA.next)a.m_nodeA.next.prev=a.m_nodeA.prev;if(a.m_nodeA==c.m_contactList)c.m_contactList=a.m_nodeA.next;if(a.m_nodeB.prev)a.m_nodeB.prev.next=a.m_nodeB.next;if(a.m_nodeB.next)a.m_nodeB.next.prev=a.m_nodeB.prev;if(a.m_nodeB==g.m_contactList)g.m_contactList=a.m_nodeB.next;this.m_contactFactory.Destroy(a);--this.m_contactCount};O.prototype.Collide=function(){for(var a=this.m_world.m_contactList;a;){var c=a.GetFixtureA(),g=a.GetFixtureB(),b=c.GetBody(),e=g.GetBody();if(b.IsAwake()==false&&e.IsAwake()==
false)a=a.GetNext();else{if(a.m_flags&l.e_filterFlag){if(e.ShouldCollide(b)==false){c=a;a=c.GetNext();this.Destroy(c);continue}if(this.m_contactFilter.ShouldCollide(c,g)==false){c=a;a=c.GetNext();this.Destroy(c);continue}a.m_flags&=~l.e_filterFlag}if(this.m_broadPhase.TestOverlap(c.m_proxy,g.m_proxy)==false){c=a;a=c.GetNext();this.Destroy(c)}else{a.Update(this.m_contactListener);a=a.GetNext()}}}};Box2D.postDefs.push(function(){Box2D.Dynamics.b2ContactManager.s_evalCP=new p});E.b2DebugDraw=function(){};
E.prototype.b2DebugDraw=function(){};E.prototype.SetFlags=function(){};E.prototype.GetFlags=function(){};E.prototype.AppendFlags=function(){};E.prototype.ClearFlags=function(){};E.prototype.SetSprite=function(){};E.prototype.GetSprite=function(){};E.prototype.SetDrawScale=function(){};E.prototype.GetDrawScale=function(){};E.prototype.SetLineThickness=function(){};E.prototype.GetLineThickness=function(){};E.prototype.SetAlpha=function(){};E.prototype.GetAlpha=function(){};E.prototype.SetFillAlpha=
function(){};E.prototype.GetFillAlpha=function(){};E.prototype.SetXFormScale=function(){};E.prototype.GetXFormScale=function(){};E.prototype.DrawPolygon=function(){};E.prototype.DrawSolidPolygon=function(){};E.prototype.DrawCircle=function(){};E.prototype.DrawSolidCircle=function(){};E.prototype.DrawSegment=function(){};E.prototype.DrawTransform=function(){};Box2D.postDefs.push(function(){Box2D.Dynamics.b2DebugDraw.e_shapeBit=1;Box2D.Dynamics.b2DebugDraw.e_jointBit=2;Box2D.Dynamics.b2DebugDraw.e_aabbBit=
4;Box2D.Dynamics.b2DebugDraw.e_pairBit=8;Box2D.Dynamics.b2DebugDraw.e_centerOfMassBit=16;Box2D.Dynamics.b2DebugDraw.e_controllerBit=32});R.b2DestructionListener=function(){};R.prototype.SayGoodbyeJoint=function(){};R.prototype.SayGoodbyeFixture=function(){};N.b2FilterData=function(){this.categoryBits=1;this.maskBits=65535;this.groupIndex=0};N.prototype.Copy=function(){var a=new N;a.categoryBits=this.categoryBits;a.maskBits=this.maskBits;a.groupIndex=this.groupIndex;return a};S.b2Fixture=function(){this.m_filter=
new N};S.prototype.GetType=function(){return this.m_shape.GetType()};S.prototype.GetShape=function(){return this.m_shape};S.prototype.SetSensor=function(a){if(this.m_isSensor!=a){this.m_isSensor=a;if(this.m_body!=null)for(a=this.m_body.GetContactList();a;){var c=a.contact,g=c.GetFixtureA(),b=c.GetFixtureB();if(g==this||b==this)c.SetSensor(g.IsSensor()||b.IsSensor());a=a.next}}};S.prototype.IsSensor=function(){return this.m_isSensor};S.prototype.SetFilterData=function(a){this.m_filter=a.Copy();if(!this.m_body)for(a=
this.m_body.GetContactList();a;){var c=a.contact,g=c.GetFixtureA(),b=c.GetFixtureB();if(g==this||b==this)c.FlagForFiltering();a=a.next}};S.prototype.GetFilterData=function(){return this.m_filter.Copy()};S.prototype.GetBody=function(){return this.m_body};S.prototype.GetNext=function(){return this.m_next};S.prototype.GetUserData=function(){return this.m_userData};S.prototype.SetUserData=function(a){this.m_userData=a};S.prototype.TestPoint=function(a){return this.m_shape.TestPoint(this.m_body.GetTransform(),
a)};S.prototype.RayCast=function(a,c){return this.m_shape.RayCast(a,c,this.m_body.GetTransform())};S.prototype.GetMassData=function(a){if(a===undefined)a=null;if(a==null)a=new I;this.m_shape.ComputeMass(a,this.m_density);return a};S.prototype.SetDensity=function(a){if(a===undefined)a=0;this.m_density=a};S.prototype.GetDensity=function(){return this.m_density};S.prototype.GetFriction=function(){return this.m_friction};S.prototype.SetFriction=function(a){if(a===undefined)a=0;this.m_friction=a};S.prototype.GetRestitution=
function(){return this.m_restitution};S.prototype.SetRestitution=function(a){if(a===undefined)a=0;this.m_restitution=a};S.prototype.GetAABB=function(){return this.m_aabb};S.prototype.b2Fixture=function(){this.m_aabb=new U;this.m_shape=this.m_next=this.m_body=this.m_userData=null;this.m_restitution=this.m_friction=this.m_density=0};S.prototype.Create=function(a,c,g){this.m_userData=g.userData;this.m_friction=g.friction;this.m_restitution=g.restitution;this.m_body=a;this.m_next=null;this.m_filter=g.filter.Copy();
this.m_isSensor=g.isSensor;this.m_shape=g.shape.Copy();this.m_density=g.density};S.prototype.Destroy=function(){this.m_shape=null};S.prototype.CreateProxy=function(a,c){this.m_shape.ComputeAABB(this.m_aabb,c);this.m_proxy=a.CreateProxy(this.m_aabb,this)};S.prototype.DestroyProxy=function(a){if(this.m_proxy!=null){a.DestroyProxy(this.m_proxy);this.m_proxy=null}};S.prototype.Synchronize=function(a,c,g){if(this.m_proxy){var b=new U,e=new U;this.m_shape.ComputeAABB(b,c);this.m_shape.ComputeAABB(e,g);
this.m_aabb.Combine(b,e);c=F.SubtractVV(g.position,c.position);a.MoveProxy(this.m_proxy,this.m_aabb,c)}};aa.b2FixtureDef=function(){this.filter=new N};aa.prototype.b2FixtureDef=function(){this.userData=this.shape=null;this.friction=0.2;this.density=this.restitution=0;this.filter.categoryBits=1;this.filter.maskBits=65535;this.filter.groupIndex=0;this.isSensor=false};Z.b2Island=function(){};Z.prototype.b2Island=function(){this.m_bodies=new Vector;this.m_contacts=new Vector;this.m_joints=new Vector};
Z.prototype.Initialize=function(a,c,g,b,e,f){if(a===undefined)a=0;if(c===undefined)c=0;if(g===undefined)g=0;var m=0;this.m_bodyCapacity=a;this.m_contactCapacity=c;this.m_jointCapacity=g;this.m_jointCount=this.m_contactCount=this.m_bodyCount=0;this.m_allocator=b;this.m_listener=e;this.m_contactSolver=f;for(m=this.m_bodies.length;m<a;m++)this.m_bodies[m]=null;for(m=this.m_contacts.length;m<c;m++)this.m_contacts[m]=null;for(m=this.m_joints.length;m<g;m++)this.m_joints[m]=null};Z.prototype.Clear=function(){this.m_jointCount=
this.m_contactCount=this.m_bodyCount=0};Z.prototype.Solve=function(a,c,g){var b=0,e=0,f;for(b=0;b<this.m_bodyCount;++b){e=this.m_bodies[b];if(e.GetType()==k.b2_dynamicBody){e.m_linearVelocity.x+=a.dt*(c.x+e.m_invMass*e.m_force.x);e.m_linearVelocity.y+=a.dt*(c.y+e.m_invMass*e.m_force.y);e.m_angularVelocity+=a.dt*e.m_invI*e.m_torque;e.m_linearVelocity.Multiply(F.Clamp(1-a.dt*e.m_linearDamping,0,1));e.m_angularVelocity*=F.Clamp(1-a.dt*e.m_angularDamping,0,1)}}this.m_contactSolver.Initialize(a,this.m_contacts,
this.m_contactCount,this.m_allocator);c=this.m_contactSolver;c.InitVelocityConstraints(a);for(b=0;b<this.m_jointCount;++b){f=this.m_joints[b];f.InitVelocityConstraints(a)}for(b=0;b<a.velocityIterations;++b){for(e=0;e<this.m_jointCount;++e){f=this.m_joints[e];f.SolveVelocityConstraints(a)}c.SolveVelocityConstraints()}for(b=0;b<this.m_jointCount;++b){f=this.m_joints[b];f.FinalizeVelocityConstraints()}c.FinalizeVelocityConstraints();for(b=0;b<this.m_bodyCount;++b){e=this.m_bodies[b];if(e.GetType()!=
k.b2_staticBody){var m=a.dt*e.m_linearVelocity.x,r=a.dt*e.m_linearVelocity.y;if(m*m+r*r>A.b2_maxTranslationSquared){e.m_linearVelocity.Normalize();e.m_linearVelocity.x*=A.b2_maxTranslation*a.inv_dt;e.m_linearVelocity.y*=A.b2_maxTranslation*a.inv_dt}m=a.dt*e.m_angularVelocity;if(m*m>A.b2_maxRotationSquared)e.m_angularVelocity=e.m_angularVelocity<0?-A.b2_maxRotation*a.inv_dt:A.b2_maxRotation*a.inv_dt;e.m_sweep.c0.SetV(e.m_sweep.c);e.m_sweep.a0=e.m_sweep.a;e.m_sweep.c.x+=a.dt*e.m_linearVelocity.x;e.m_sweep.c.y+=
a.dt*e.m_linearVelocity.y;e.m_sweep.a+=a.dt*e.m_angularVelocity;e.SynchronizeTransform()}}for(b=0;b<a.positionIterations;++b){m=c.SolvePositionConstraints(A.b2_contactBaumgarte);r=true;for(e=0;e<this.m_jointCount;++e){f=this.m_joints[e];f=f.SolvePositionConstraints(A.b2_contactBaumgarte);r=r&&f}if(m&&r)break}this.Report(c.m_constraints);if(g){g=Number.MAX_VALUE;c=A.b2_linearSleepTolerance*A.b2_linearSleepTolerance;m=A.b2_angularSleepTolerance*A.b2_angularSleepTolerance;for(b=0;b<this.m_bodyCount;++b){e=
this.m_bodies[b];if(e.GetType()!=k.b2_staticBody){if((e.m_flags&k.e_allowSleepFlag)==0)g=e.m_sleepTime=0;if((e.m_flags&k.e_allowSleepFlag)==0||e.m_angularVelocity*e.m_angularVelocity>m||F.Dot(e.m_linearVelocity,e.m_linearVelocity)>c)g=e.m_sleepTime=0;else{e.m_sleepTime+=a.dt;g=F.Min(g,e.m_sleepTime)}}}if(g>=A.b2_timeToSleep)for(b=0;b<this.m_bodyCount;++b){e=this.m_bodies[b];e.SetAwake(false)}}};Z.prototype.SolveTOI=function(a){var c=0,g=0;this.m_contactSolver.Initialize(a,this.m_contacts,this.m_contactCount,
this.m_allocator);var b=this.m_contactSolver;for(c=0;c<this.m_jointCount;++c)this.m_joints[c].InitVelocityConstraints(a);for(c=0;c<a.velocityIterations;++c){b.SolveVelocityConstraints();for(g=0;g<this.m_jointCount;++g)this.m_joints[g].SolveVelocityConstraints(a)}for(c=0;c<this.m_bodyCount;++c){g=this.m_bodies[c];if(g.GetType()!=k.b2_staticBody){var e=a.dt*g.m_linearVelocity.x,f=a.dt*g.m_linearVelocity.y;if(e*e+f*f>A.b2_maxTranslationSquared){g.m_linearVelocity.Normalize();g.m_linearVelocity.x*=A.b2_maxTranslation*
a.inv_dt;g.m_linearVelocity.y*=A.b2_maxTranslation*a.inv_dt}e=a.dt*g.m_angularVelocity;if(e*e>A.b2_maxRotationSquared)g.m_angularVelocity=g.m_angularVelocity<0?-A.b2_maxRotation*a.inv_dt:A.b2_maxRotation*a.inv_dt;g.m_sweep.c0.SetV(g.m_sweep.c);g.m_sweep.a0=g.m_sweep.a;g.m_sweep.c.x+=a.dt*g.m_linearVelocity.x;g.m_sweep.c.y+=a.dt*g.m_linearVelocity.y;g.m_sweep.a+=a.dt*g.m_angularVelocity;g.SynchronizeTransform()}}for(c=0;c<a.positionIterations;++c){e=b.SolvePositionConstraints(0.75);f=true;for(g=0;g<
this.m_jointCount;++g){var m=this.m_joints[g].SolvePositionConstraints(A.b2_contactBaumgarte);f=f&&m}if(e&&f)break}this.Report(b.m_constraints)};Z.prototype.Report=function(a){if(this.m_listener!=null)for(var c=0;c<this.m_contactCount;++c){for(var g=this.m_contacts[c],b=a[c],e=0;e<b.pointCount;++e){Z.s_impulse.normalImpulses[e]=b.points[e].normalImpulse;Z.s_impulse.tangentImpulses[e]=b.points[e].tangentImpulse}this.m_listener.PostSolve(g,Z.s_impulse)}};Z.prototype.AddBody=function(a){a.m_islandIndex=
this.m_bodyCount;this.m_bodies[this.m_bodyCount++]=a};Z.prototype.AddContact=function(a){this.m_contacts[this.m_contactCount++]=a};Z.prototype.AddJoint=function(a){this.m_joints[this.m_jointCount++]=a};Box2D.postDefs.push(function(){Box2D.Dynamics.b2Island.s_impulse=new D});d.b2TimeStep=function(){};d.prototype.Set=function(a){this.dt=a.dt;this.inv_dt=a.inv_dt;this.positionIterations=a.positionIterations;this.velocityIterations=a.velocityIterations;this.warmStarting=a.warmStarting};h.b2World=function(){this.s_stack=
new Vector;this.m_contactManager=new O;this.m_contactSolver=new o;this.m_island=new Z};h.prototype.b2World=function(a,c){this.m_controllerList=this.m_jointList=this.m_contactList=this.m_bodyList=this.m_debugDraw=this.m_destructionListener=null;this.m_controllerCount=this.m_jointCount=this.m_contactCount=this.m_bodyCount=0;h.m_warmStarting=true;h.m_continuousPhysics=true;this.m_allowSleep=c;this.m_gravity=a;this.m_inv_dt0=0;this.m_contactManager.m_world=this;this.m_groundBody=this.CreateBody(new z)};
h.prototype.SetDestructionListener=function(a){this.m_destructionListener=a};h.prototype.SetContactFilter=function(a){this.m_contactManager.m_contactFilter=a};h.prototype.SetContactListener=function(a){this.m_contactManager.m_contactListener=a};h.prototype.SetDebugDraw=function(a){this.m_debugDraw=a};h.prototype.SetBroadPhase=function(a){var c=this.m_contactManager.m_broadPhase;this.m_contactManager.m_broadPhase=a;for(var g=this.m_bodyList;g;g=g.m_next)for(var b=g.m_fixtureList;b;b=b.m_next)b.m_proxy=
a.CreateProxy(c.GetFatAABB(b.m_proxy),b)};h.prototype.Validate=function(){this.m_contactManager.m_broadPhase.Validate()};h.prototype.GetProxyCount=function(){return this.m_contactManager.m_broadPhase.GetProxyCount()};h.prototype.CreateBody=function(a){if(this.IsLocked()==true)return null;a=new k(a,this);a.m_prev=null;if(a.m_next=this.m_bodyList)this.m_bodyList.m_prev=a;this.m_bodyList=a;++this.m_bodyCount;return a};h.prototype.DestroyBody=function(a){if(this.IsLocked()!=true){for(var c=a.m_jointList;c;){var g=
c;c=c.next;this.m_destructionListener&&this.m_destructionListener.SayGoodbyeJoint(g.joint);this.DestroyJoint(g.joint)}for(c=a.m_controllerList;c;){g=c;c=c.nextController;g.controller.RemoveBody(a)}for(c=a.m_contactList;c;){g=c;c=c.next;this.m_contactManager.Destroy(g.contact)}a.m_contactList=null;for(c=a.m_fixtureList;c;){g=c;c=c.m_next;this.m_destructionListener&&this.m_destructionListener.SayGoodbyeFixture(g);g.DestroyProxy(this.m_contactManager.m_broadPhase);g.Destroy()}a.m_fixtureList=null;a.m_fixtureCount=
0;if(a.m_prev)a.m_prev.m_next=a.m_next;if(a.m_next)a.m_next.m_prev=a.m_prev;if(a==this.m_bodyList)this.m_bodyList=a.m_next;--this.m_bodyCount}};h.prototype.CreateJoint=function(a){var c=q.Create(a,null);c.m_prev=null;if(c.m_next=this.m_jointList)this.m_jointList.m_prev=c;this.m_jointList=c;++this.m_jointCount;c.m_edgeA.joint=c;c.m_edgeA.other=c.m_bodyB;c.m_edgeA.prev=null;if(c.m_edgeA.next=c.m_bodyA.m_jointList)c.m_bodyA.m_jointList.prev=c.m_edgeA;c.m_bodyA.m_jointList=c.m_edgeA;c.m_edgeB.joint=c;
c.m_edgeB.other=c.m_bodyA;c.m_edgeB.prev=null;if(c.m_edgeB.next=c.m_bodyB.m_jointList)c.m_bodyB.m_jointList.prev=c.m_edgeB;c.m_bodyB.m_jointList=c.m_edgeB;var g=a.bodyA,b=a.bodyB;if(a.collideConnected==false)for(a=b.GetContactList();a;){a.other==g&&a.contact.FlagForFiltering();a=a.next}return c};h.prototype.DestroyJoint=function(a){var c=a.m_collideConnected;if(a.m_prev)a.m_prev.m_next=a.m_next;if(a.m_next)a.m_next.m_prev=a.m_prev;if(a==this.m_jointList)this.m_jointList=a.m_next;var g=a.m_bodyA,b=
a.m_bodyB;g.SetAwake(true);b.SetAwake(true);if(a.m_edgeA.prev)a.m_edgeA.prev.next=a.m_edgeA.next;if(a.m_edgeA.next)a.m_edgeA.next.prev=a.m_edgeA.prev;if(a.m_edgeA==g.m_jointList)g.m_jointList=a.m_edgeA.next;a.m_edgeA.prev=null;a.m_edgeA.next=null;if(a.m_edgeB.prev)a.m_edgeB.prev.next=a.m_edgeB.next;if(a.m_edgeB.next)a.m_edgeB.next.prev=a.m_edgeB.prev;if(a.m_edgeB==b.m_jointList)b.m_jointList=a.m_edgeB.next;a.m_edgeB.prev=null;a.m_edgeB.next=null;q.Destroy(a,null);--this.m_jointCount;if(c==false)for(a=
b.GetContactList();a;){a.other==g&&a.contact.FlagForFiltering();a=a.next}};h.prototype.AddController=function(a){a.m_next=this.m_controllerList;a.m_prev=null;this.m_controllerList=a;a.m_world=this;this.m_controllerCount++;return a};h.prototype.RemoveController=function(a){if(a.m_prev)a.m_prev.m_next=a.m_next;if(a.m_next)a.m_next.m_prev=a.m_prev;if(this.m_controllerList==a)this.m_controllerList=a.m_next;this.m_controllerCount--};h.prototype.CreateController=function(a){if(a.m_world!=this)throw Error("Controller can only be a member of one world");
a.m_next=this.m_controllerList;a.m_prev=null;if(this.m_controllerList)this.m_controllerList.m_prev=a;this.m_controllerList=a;++this.m_controllerCount;a.m_world=this;return a};h.prototype.DestroyController=function(a){a.Clear();if(a.m_next)a.m_next.m_prev=a.m_prev;if(a.m_prev)a.m_prev.m_next=a.m_next;if(a==this.m_controllerList)this.m_controllerList=a.m_next;--this.m_controllerCount};h.prototype.SetWarmStarting=function(a){h.m_warmStarting=a};h.prototype.SetContinuousPhysics=function(a){h.m_continuousPhysics=
a};h.prototype.GetBodyCount=function(){return this.m_bodyCount};h.prototype.GetJointCount=function(){return this.m_jointCount};h.prototype.GetContactCount=function(){return this.m_contactCount};h.prototype.SetGravity=function(a){this.m_gravity=a};h.prototype.GetGravity=function(){return this.m_gravity};h.prototype.GetGroundBody=function(){return this.m_groundBody};h.prototype.Step=function(a,c,g){if(a===undefined)a=0;if(c===undefined)c=0;if(g===undefined)g=0;if(this.m_flags&h.e_newFixture){this.m_contactManager.FindNewContacts();
this.m_flags&=~h.e_newFixture}this.m_flags|=h.e_locked;var b=h.s_timestep2;b.dt=a;b.velocityIterations=c;b.positionIterations=g;b.inv_dt=a>0?1/a:0;b.dtRatio=this.m_inv_dt0*a;b.warmStarting=h.m_warmStarting;this.m_contactManager.Collide();b.dt>0&&this.Solve(b);h.m_continuousPhysics&&b.dt>0&&this.SolveTOI(b);if(b.dt>0)this.m_inv_dt0=b.inv_dt;this.m_flags&=~h.e_locked};h.prototype.ClearForces=function(){for(var a=this.m_bodyList;a;a=a.m_next){a.m_force.SetZero();a.m_torque=0}};h.prototype.DrawDebugData=
function(){if(this.m_debugDraw!=null){this.m_debugDraw.m_sprite.graphics.clear();var a=this.m_debugDraw.GetFlags(),c,g,b;new y;new y;new y;var e;new U;new U;e=[new y,new y,new y,new y];var f=new w(0,0,0);if(a&E.e_shapeBit)for(c=this.m_bodyList;c;c=c.m_next){e=c.m_xf;for(g=c.GetFixtureList();g;g=g.m_next){b=g.GetShape();if(c.IsActive()==false)f.Set(0.5,0.5,0.3);else if(c.GetType()==k.b2_staticBody)f.Set(0.5,0.9,0.5);else if(c.GetType()==k.b2_kinematicBody)f.Set(0.5,0.5,0.9);else c.IsAwake()==false?
f.Set(0.6,0.6,0.6):f.Set(0.9,0.7,0.7);this.DrawShape(b,e,f)}}if(a&E.e_jointBit)for(c=this.m_jointList;c;c=c.m_next)this.DrawJoint(c);if(a&E.e_controllerBit)for(c=this.m_controllerList;c;c=c.m_next)c.Draw(this.m_debugDraw);if(a&E.e_pairBit){f.Set(0.3,0.9,0.9);for(c=this.m_contactManager.m_contactList;c;c=c.GetNext()){b=c.GetFixtureA();g=c.GetFixtureB();b=b.GetAABB().GetCenter();g=g.GetAABB().GetCenter();this.m_debugDraw.DrawSegment(b,g,f)}}if(a&E.e_aabbBit){b=this.m_contactManager.m_broadPhase;e=[new y,
new y,new y,new y];for(c=this.m_bodyList;c;c=c.GetNext())if(c.IsActive()!=false)for(g=c.GetFixtureList();g;g=g.GetNext()){var m=b.GetFatAABB(g.m_proxy);e[0].Set(m.lowerBound.x,m.lowerBound.y);e[1].Set(m.upperBound.x,m.lowerBound.y);e[2].Set(m.upperBound.x,m.upperBound.y);e[3].Set(m.lowerBound.x,m.upperBound.y);this.m_debugDraw.DrawPolygon(e,4,f)}}if(a&E.e_centerOfMassBit)for(c=this.m_bodyList;c;c=c.m_next){e=h.s_xf;e.R=c.m_xf.R;e.position=c.GetWorldCenter();this.m_debugDraw.DrawTransform(e)}}};h.prototype.QueryAABB=
function(a,c){var g=this.m_contactManager.m_broadPhase;g.Query(function(b){return a(g.GetUserData(b))},c)};h.prototype.QueryShape=function(a,c,g){if(g===undefined)g=null;if(g==null){g=new K;g.SetIdentity()}var b=this.m_contactManager.m_broadPhase,e=new U;c.ComputeAABB(e,g);b.Query(function(f){f=b.GetUserData(f)instanceof S?b.GetUserData(f):null;if(Y.TestOverlap(c,g,f.GetShape(),f.GetBody().GetTransform()))return a(f);return true},e)};h.prototype.QueryPoint=function(a,c){var g=this.m_contactManager.m_broadPhase,
b=new U;b.lowerBound.Set(c.x-A.b2_linearSlop,c.y-A.b2_linearSlop);b.upperBound.Set(c.x+A.b2_linearSlop,c.y+A.b2_linearSlop);g.Query(function(e){e=g.GetUserData(e)instanceof S?g.GetUserData(e):null;if(e.TestPoint(c))return a(e);return true},b)};h.prototype.RayCast=function(a,c,g){var b=this.m_contactManager.m_broadPhase,e=new V,f=new Q(c,g);b.RayCast(function(m,r){var s=b.GetUserData(r);s=s instanceof S?s:null;if(s.RayCast(e,m)){var v=e.fraction,t=new y((1-v)*c.x+v*g.x,(1-v)*c.y+v*g.y);return a(s,
t,e.normal,v)}return m.maxFraction},f)};h.prototype.RayCastOne=function(a,c){var g;this.RayCast(function(b,e,f,m){if(m===undefined)m=0;g=b;return m},a,c);return g};h.prototype.RayCastAll=function(a,c){var g=new Vector;this.RayCast(function(b){g[g.length]=b;return 1},a,c);return g};h.prototype.GetBodyList=function(){return this.m_bodyList};h.prototype.GetJointList=function(){return this.m_jointList};h.prototype.GetContactList=function(){return this.m_contactList};h.prototype.IsLocked=function(){return(this.m_flags&
h.e_locked)>0};h.prototype.Solve=function(a){for(var c,g=this.m_controllerList;g;g=g.m_next)g.Step(a);g=this.m_island;g.Initialize(this.m_bodyCount,this.m_contactCount,this.m_jointCount,null,this.m_contactManager.m_contactListener,this.m_contactSolver);for(c=this.m_bodyList;c;c=c.m_next)c.m_flags&=~k.e_islandFlag;for(var b=this.m_contactList;b;b=b.m_next)b.m_flags&=~l.e_islandFlag;for(b=this.m_jointList;b;b=b.m_next)b.m_islandFlag=false;parseInt(this.m_bodyCount);b=this.s_stack;for(var e=this.m_bodyList;e;e=
e.m_next)if(!(e.m_flags&k.e_islandFlag))if(!(e.IsAwake()==false||e.IsActive()==false))if(e.GetType()!=k.b2_staticBody){g.Clear();var f=0;b[f++]=e;for(e.m_flags|=k.e_islandFlag;f>0;){c=b[--f];g.AddBody(c);c.IsAwake()==false&&c.SetAwake(true);if(c.GetType()!=k.b2_staticBody){for(var m,r=c.m_contactList;r;r=r.next)if(!(r.contact.m_flags&l.e_islandFlag))if(!(r.contact.IsSensor()==true||r.contact.IsEnabled()==false||r.contact.IsTouching()==false)){g.AddContact(r.contact);r.contact.m_flags|=l.e_islandFlag;
m=r.other;if(!(m.m_flags&k.e_islandFlag)){b[f++]=m;m.m_flags|=k.e_islandFlag}}for(c=c.m_jointList;c;c=c.next)if(c.joint.m_islandFlag!=true){m=c.other;if(m.IsActive()!=false){g.AddJoint(c.joint);c.joint.m_islandFlag=true;if(!(m.m_flags&k.e_islandFlag)){b[f++]=m;m.m_flags|=k.e_islandFlag}}}}}g.Solve(a,this.m_gravity,this.m_allowSleep);for(f=0;f<g.m_bodyCount;++f){c=g.m_bodies[f];if(c.GetType()==k.b2_staticBody)c.m_flags&=~k.e_islandFlag}}for(f=0;f<b.length;++f){if(!b[f])break;b[f]=null}for(c=this.m_bodyList;c;c=
c.m_next)c.IsAwake()==false||c.IsActive()==false||c.GetType()!=k.b2_staticBody&&c.SynchronizeFixtures();this.m_contactManager.FindNewContacts()};h.prototype.SolveTOI=function(a){var c,g,b,e=this.m_island;e.Initialize(this.m_bodyCount,A.b2_maxTOIContactsPerIsland,A.b2_maxTOIJointsPerIsland,null,this.m_contactManager.m_contactListener,this.m_contactSolver);var f=h.s_queue;for(c=this.m_bodyList;c;c=c.m_next){c.m_flags&=~k.e_islandFlag;c.m_sweep.t0=0}for(b=this.m_contactList;b;b=b.m_next)b.m_flags&=~(l.e_toiFlag|
l.e_islandFlag);for(b=this.m_jointList;b;b=b.m_next)b.m_islandFlag=false;for(;;){var m=null,r=1;for(b=this.m_contactList;b;b=b.m_next)if(!(b.IsSensor()==true||b.IsEnabled()==false||b.IsContinuous()==false)){c=1;if(b.m_flags&l.e_toiFlag)c=b.m_toi;else{c=b.m_fixtureA;g=b.m_fixtureB;c=c.m_body;g=g.m_body;if((c.GetType()!=k.b2_dynamicBody||c.IsAwake()==false)&&(g.GetType()!=k.b2_dynamicBody||g.IsAwake()==false))continue;var s=c.m_sweep.t0;if(c.m_sweep.t0<g.m_sweep.t0){s=g.m_sweep.t0;c.m_sweep.Advance(s)}else if(g.m_sweep.t0<
c.m_sweep.t0){s=c.m_sweep.t0;g.m_sweep.Advance(s)}c=b.ComputeTOI(c.m_sweep,g.m_sweep);A.b2Assert(0<=c&&c<=1);if(c>0&&c<1){c=(1-c)*s+c;if(c>1)c=1}b.m_toi=c;b.m_flags|=l.e_toiFlag}if(Number.MIN_VALUE<c&&c<r){m=b;r=c}}if(m==null||1-100*Number.MIN_VALUE<r)break;c=m.m_fixtureA;g=m.m_fixtureB;c=c.m_body;g=g.m_body;h.s_backupA.Set(c.m_sweep);h.s_backupB.Set(g.m_sweep);c.Advance(r);g.Advance(r);m.Update(this.m_contactManager.m_contactListener);m.m_flags&=~l.e_toiFlag;if(m.IsSensor()==true||m.IsEnabled()==
false){c.m_sweep.Set(h.s_backupA);g.m_sweep.Set(h.s_backupB);c.SynchronizeTransform();g.SynchronizeTransform()}else if(m.IsTouching()!=false){c=c;if(c.GetType()!=k.b2_dynamicBody)c=g;e.Clear();m=b=0;f[b+m++]=c;for(c.m_flags|=k.e_islandFlag;m>0;){c=f[b++];--m;e.AddBody(c);c.IsAwake()==false&&c.SetAwake(true);if(c.GetType()==k.b2_dynamicBody){for(g=c.m_contactList;g;g=g.next){if(e.m_contactCount==e.m_contactCapacity)break;if(!(g.contact.m_flags&l.e_islandFlag))if(!(g.contact.IsSensor()==true||g.contact.IsEnabled()==
false||g.contact.IsTouching()==false)){e.AddContact(g.contact);g.contact.m_flags|=l.e_islandFlag;s=g.other;if(!(s.m_flags&k.e_islandFlag)){if(s.GetType()!=k.b2_staticBody){s.Advance(r);s.SetAwake(true)}f[b+m]=s;++m;s.m_flags|=k.e_islandFlag}}}for(c=c.m_jointList;c;c=c.next)if(e.m_jointCount!=e.m_jointCapacity)if(c.joint.m_islandFlag!=true){s=c.other;if(s.IsActive()!=false){e.AddJoint(c.joint);c.joint.m_islandFlag=true;if(!(s.m_flags&k.e_islandFlag)){if(s.GetType()!=k.b2_staticBody){s.Advance(r);s.SetAwake(true)}f[b+
m]=s;++m;s.m_flags|=k.e_islandFlag}}}}}b=h.s_timestep;b.warmStarting=false;b.dt=(1-r)*a.dt;b.inv_dt=1/b.dt;b.dtRatio=0;b.velocityIterations=a.velocityIterations;b.positionIterations=a.positionIterations;e.SolveTOI(b);for(r=r=0;r<e.m_bodyCount;++r){c=e.m_bodies[r];c.m_flags&=~k.e_islandFlag;if(c.IsAwake()!=false)if(c.GetType()==k.b2_dynamicBody){c.SynchronizeFixtures();for(g=c.m_contactList;g;g=g.next)g.contact.m_flags&=~l.e_toiFlag}}for(r=0;r<e.m_contactCount;++r){b=e.m_contacts[r];b.m_flags&=~(l.e_toiFlag|
l.e_islandFlag)}for(r=0;r<e.m_jointCount;++r){b=e.m_joints[r];b.m_islandFlag=false}this.m_contactManager.FindNewContacts()}}};h.prototype.DrawJoint=function(a){var c=a.GetBodyA(),g=a.GetBodyB(),b=c.m_xf.position,e=g.m_xf.position,f=a.GetAnchorA(),m=a.GetAnchorB(),r=h.s_jointColor;switch(a.m_type){case q.e_distanceJoint:this.m_debugDraw.DrawSegment(f,m,r);break;case q.e_pulleyJoint:c=a instanceof n?a:null;a=c.GetGroundAnchorA();c=c.GetGroundAnchorB();this.m_debugDraw.DrawSegment(a,f,r);this.m_debugDraw.DrawSegment(c,
m,r);this.m_debugDraw.DrawSegment(a,c,r);break;case q.e_mouseJoint:this.m_debugDraw.DrawSegment(f,m,r);break;default:c!=this.m_groundBody&&this.m_debugDraw.DrawSegment(b,f,r);this.m_debugDraw.DrawSegment(f,m,r);g!=this.m_groundBody&&this.m_debugDraw.DrawSegment(e,m,r)}};h.prototype.DrawShape=function(a,c,g){switch(a.m_type){case Y.e_circleShape:var b=a instanceof M?a:null;this.m_debugDraw.DrawSolidCircle(F.MulX(c,b.m_p),b.m_radius,c.R.col1,g);break;case Y.e_polygonShape:b=0;b=a instanceof W?a:null;
a=parseInt(b.GetVertexCount());var e=b.GetVertices(),f=new Vector(a);for(b=0;b<a;++b)f[b]=F.MulX(c,e[b]);this.m_debugDraw.DrawSolidPolygon(f,a,g);break;case Y.e_edgeShape:b=a instanceof L?a:null;this.m_debugDraw.DrawSegment(F.MulX(c,b.GetVertex1()),F.MulX(c,b.GetVertex2()),g)}};Box2D.postDefs.push(function(){Box2D.Dynamics.b2World.s_timestep2=new d;Box2D.Dynamics.b2World.s_xf=new K;Box2D.Dynamics.b2World.s_backupA=new G;Box2D.Dynamics.b2World.s_backupB=new G;Box2D.Dynamics.b2World.s_timestep=new d;
Box2D.Dynamics.b2World.s_queue=new Vector;Box2D.Dynamics.b2World.s_jointColor=new w(0.5,0.8,0.8);Box2D.Dynamics.b2World.e_newFixture=1;Box2D.Dynamics.b2World.e_locked=2})})();
(function(){var F=Box2D.Collision.Shapes.b2CircleShape,G=Box2D.Collision.Shapes.b2EdgeShape,K=Box2D.Collision.Shapes.b2PolygonShape,y=Box2D.Collision.Shapes.b2Shape,w=Box2D.Dynamics.Contacts.b2CircleContact,A=Box2D.Dynamics.Contacts.b2Contact,U=Box2D.Dynamics.Contacts.b2ContactConstraint,p=Box2D.Dynamics.Contacts.b2ContactConstraintPoint,B=Box2D.Dynamics.Contacts.b2ContactEdge,Q=Box2D.Dynamics.Contacts.b2ContactFactory,V=Box2D.Dynamics.Contacts.b2ContactRegister,M=Box2D.Dynamics.Contacts.b2ContactResult,
L=Box2D.Dynamics.Contacts.b2ContactSolver,I=Box2D.Dynamics.Contacts.b2EdgeAndCircleContact,W=Box2D.Dynamics.Contacts.b2NullContact,Y=Box2D.Dynamics.Contacts.b2PolyAndCircleContact,k=Box2D.Dynamics.Contacts.b2PolyAndEdgeContact,z=Box2D.Dynamics.Contacts.b2PolygonContact,u=Box2D.Dynamics.Contacts.b2PositionSolverManifold,D=Box2D.Dynamics.b2Body,H=Box2D.Dynamics.b2TimeStep,O=Box2D.Common.b2Settings,E=Box2D.Common.Math.b2Mat22,R=Box2D.Common.Math.b2Math,N=Box2D.Common.Math.b2Vec2,S=Box2D.Collision.b2Collision,
aa=Box2D.Collision.b2ContactID,Z=Box2D.Collision.b2Manifold,d=Box2D.Collision.b2TimeOfImpact,h=Box2D.Collision.b2TOIInput,l=Box2D.Collision.b2WorldManifold;Box2D.inherit(w,Box2D.Dynamics.Contacts.b2Contact);w.prototype.__super=Box2D.Dynamics.Contacts.b2Contact.prototype;w.b2CircleContact=function(){Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this,arguments)};w.Create=function(){return new w};w.Destroy=function(){};w.prototype.Reset=function(j,o){this.__super.Reset.call(this,j,o)};w.prototype.Evaluate=
function(){var j=this.m_fixtureA.GetBody(),o=this.m_fixtureB.GetBody();S.CollideCircles(this.m_manifold,this.m_fixtureA.GetShape()instanceof F?this.m_fixtureA.GetShape():null,j.m_xf,this.m_fixtureB.GetShape()instanceof F?this.m_fixtureB.GetShape():null,o.m_xf)};A.b2Contact=function(){this.m_nodeA=new B;this.m_nodeB=new B;this.m_manifold=new Z;this.m_oldManifold=new Z};A.prototype.GetManifold=function(){return this.m_manifold};A.prototype.GetWorldManifold=function(j){var o=this.m_fixtureA.GetBody(),
q=this.m_fixtureB.GetBody(),n=this.m_fixtureA.GetShape(),a=this.m_fixtureB.GetShape();j.Initialize(this.m_manifold,o.GetTransform(),n.m_radius,q.GetTransform(),a.m_radius)};A.prototype.IsTouching=function(){return(this.m_flags&A.e_touchingFlag)==A.e_touchingFlag};A.prototype.IsContinuous=function(){return(this.m_flags&A.e_continuousFlag)==A.e_continuousFlag};A.prototype.SetSensor=function(j){if(j)this.m_flags|=A.e_sensorFlag;else this.m_flags&=~A.e_sensorFlag};A.prototype.IsSensor=function(){return(this.m_flags&
A.e_sensorFlag)==A.e_sensorFlag};A.prototype.SetEnabled=function(j){if(j)this.m_flags|=A.e_enabledFlag;else this.m_flags&=~A.e_enabledFlag};A.prototype.IsEnabled=function(){return(this.m_flags&A.e_enabledFlag)==A.e_enabledFlag};A.prototype.GetNext=function(){return this.m_next};A.prototype.GetFixtureA=function(){return this.m_fixtureA};A.prototype.GetFixtureB=function(){return this.m_fixtureB};A.prototype.FlagForFiltering=function(){this.m_flags|=A.e_filterFlag};A.prototype.b2Contact=function(){};
A.prototype.Reset=function(j,o){if(j===undefined)j=null;if(o===undefined)o=null;this.m_flags=A.e_enabledFlag;if(!j||!o)this.m_fixtureB=this.m_fixtureA=null;else{if(j.IsSensor()||o.IsSensor())this.m_flags|=A.e_sensorFlag;var q=j.GetBody(),n=o.GetBody();if(q.GetType()!=D.b2_dynamicBody||q.IsBullet()||n.GetType()!=D.b2_dynamicBody||n.IsBullet())this.m_flags|=A.e_continuousFlag;this.m_fixtureA=j;this.m_fixtureB=o;this.m_manifold.m_pointCount=0;this.m_next=this.m_prev=null;this.m_nodeA.contact=null;this.m_nodeA.prev=
null;this.m_nodeA.next=null;this.m_nodeA.other=null;this.m_nodeB.contact=null;this.m_nodeB.prev=null;this.m_nodeB.next=null;this.m_nodeB.other=null}};A.prototype.Update=function(j){var o=this.m_oldManifold;this.m_oldManifold=this.m_manifold;this.m_manifold=o;this.m_flags|=A.e_enabledFlag;var q=false;o=(this.m_flags&A.e_touchingFlag)==A.e_touchingFlag;var n=this.m_fixtureA.m_body,a=this.m_fixtureB.m_body,c=this.m_fixtureA.m_aabb.TestOverlap(this.m_fixtureB.m_aabb);if(this.m_flags&A.e_sensorFlag){if(c){q=
this.m_fixtureA.GetShape();c=this.m_fixtureB.GetShape();n=n.GetTransform();a=a.GetTransform();q=y.TestOverlap(q,n,c,a)}this.m_manifold.m_pointCount=0}else{if(n.GetType()!=D.b2_dynamicBody||n.IsBullet()||a.GetType()!=D.b2_dynamicBody||a.IsBullet())this.m_flags|=A.e_continuousFlag;else this.m_flags&=~A.e_continuousFlag;if(c){this.Evaluate();q=this.m_manifold.m_pointCount>0;for(c=0;c<this.m_manifold.m_pointCount;++c){var g=this.m_manifold.m_points[c];g.m_normalImpulse=0;g.m_tangentImpulse=0;for(var b=
g.m_id,e=0;e<this.m_oldManifold.m_pointCount;++e){var f=this.m_oldManifold.m_points[e];if(f.m_id.key==b.key){g.m_normalImpulse=f.m_normalImpulse;g.m_tangentImpulse=f.m_tangentImpulse;break}}}}else this.m_manifold.m_pointCount=0;if(q!=o){n.SetAwake(true);a.SetAwake(true)}}if(q)this.m_flags|=A.e_touchingFlag;else this.m_flags&=~A.e_touchingFlag;o==false&&q==true&&j.BeginContact(this);o==true&&q==false&&j.EndContact(this);(this.m_flags&A.e_sensorFlag)==0&&j.PreSolve(this,this.m_oldManifold)};A.prototype.Evaluate=
function(){};A.prototype.ComputeTOI=function(j,o){A.s_input.proxyA.Set(this.m_fixtureA.GetShape());A.s_input.proxyB.Set(this.m_fixtureB.GetShape());A.s_input.sweepA=j;A.s_input.sweepB=o;A.s_input.tolerance=O.b2_linearSlop;return d.TimeOfImpact(A.s_input)};Box2D.postDefs.push(function(){Box2D.Dynamics.Contacts.b2Contact.e_sensorFlag=1;Box2D.Dynamics.Contacts.b2Contact.e_continuousFlag=2;Box2D.Dynamics.Contacts.b2Contact.e_islandFlag=4;Box2D.Dynamics.Contacts.b2Contact.e_toiFlag=8;Box2D.Dynamics.Contacts.b2Contact.e_touchingFlag=
16;Box2D.Dynamics.Contacts.b2Contact.e_enabledFlag=32;Box2D.Dynamics.Contacts.b2Contact.e_filterFlag=64;Box2D.Dynamics.Contacts.b2Contact.s_input=new h});U.b2ContactConstraint=function(){this.localPlaneNormal=new N;this.localPoint=new N;this.normal=new N;this.normalMass=new E;this.K=new E};U.prototype.b2ContactConstraint=function(){this.points=new Vector(O.b2_maxManifoldPoints);for(var j=0;j<O.b2_maxManifoldPoints;j++)this.points[j]=new p};p.b2ContactConstraintPoint=function(){this.localPoint=new N;
this.rA=new N;this.rB=new N};B.b2ContactEdge=function(){};Q.b2ContactFactory=function(){};Q.prototype.b2ContactFactory=function(j){this.m_allocator=j;this.InitializeRegisters()};Q.prototype.AddType=function(j,o,q,n){if(q===undefined)q=0;if(n===undefined)n=0;this.m_registers[q][n].createFcn=j;this.m_registers[q][n].destroyFcn=o;this.m_registers[q][n].primary=true;if(q!=n){this.m_registers[n][q].createFcn=j;this.m_registers[n][q].destroyFcn=o;this.m_registers[n][q].primary=false}};Q.prototype.InitializeRegisters=
function(){this.m_registers=new Vector(y.e_shapeTypeCount);for(var j=0;j<y.e_shapeTypeCount;j++){this.m_registers[j]=new Vector(y.e_shapeTypeCount);for(var o=0;o<y.e_shapeTypeCount;o++)this.m_registers[j][o]=new V}this.AddType(w.Create,w.Destroy,y.e_circleShape,y.e_circleShape);this.AddType(Y.Create,Y.Destroy,y.e_polygonShape,y.e_circleShape);this.AddType(z.Create,z.Destroy,y.e_polygonShape,y.e_polygonShape);this.AddType(I.Create,I.Destroy,y.e_edgeShape,y.e_circleShape);this.AddType(k.Create,k.Destroy,
y.e_polygonShape,y.e_edgeShape)};Q.prototype.Create=function(j,o){var q=parseInt(j.GetType()),n=parseInt(o.GetType());q=this.m_registers[q][n];if(q.pool){n=q.pool;q.pool=n.m_next;q.poolCount--;n.Reset(j,o);return n}n=q.createFcn;if(n!=null){if(q.primary){n=n(this.m_allocator);n.Reset(j,o)}else{n=n(this.m_allocator);n.Reset(o,j)}return n}else return null};Q.prototype.Destroy=function(j){if(j.m_manifold.m_pointCount>0){j.m_fixtureA.m_body.SetAwake(true);j.m_fixtureB.m_body.SetAwake(true)}var o=parseInt(j.m_fixtureA.GetType()),
q=parseInt(j.m_fixtureB.GetType());o=this.m_registers[o][q];o.poolCount++;j.m_next=o.pool;o.pool=j;o=o.destroyFcn;o(j,this.m_allocator)};V.b2ContactRegister=function(){};M.b2ContactResult=function(){this.position=new N;this.normal=new N;this.id=new aa};L.b2ContactSolver=function(){this.m_step=new H;this.m_constraints=new Vector};L.prototype.b2ContactSolver=function(){};L.prototype.Initialize=function(j,o,q,n){if(q===undefined)q=0;var a;this.m_step.Set(j);this.m_allocator=n;j=0;for(this.m_constraintCount=
q;this.m_constraints.length<this.m_constraintCount;)this.m_constraints[this.m_constraints.length]=new U;for(j=0;j<q;++j){a=o[j];n=a.m_fixtureA;var c=a.m_fixtureB,g=n.m_shape.m_radius,b=c.m_shape.m_radius,e=n.m_body,f=c.m_body,m=a.GetManifold(),r=O.b2MixFriction(n.GetFriction(),c.GetFriction()),s=O.b2MixRestitution(n.GetRestitution(),c.GetRestitution()),v=e.m_linearVelocity.x,t=e.m_linearVelocity.y,x=f.m_linearVelocity.x,C=f.m_linearVelocity.y,J=e.m_angularVelocity,T=f.m_angularVelocity;O.b2Assert(m.m_pointCount>
0);L.s_worldManifold.Initialize(m,e.m_xf,g,f.m_xf,b);c=L.s_worldManifold.m_normal.x;a=L.s_worldManifold.m_normal.y;n=this.m_constraints[j];n.bodyA=e;n.bodyB=f;n.manifold=m;n.normal.x=c;n.normal.y=a;n.pointCount=m.m_pointCount;n.friction=r;n.restitution=s;n.localPlaneNormal.x=m.m_localPlaneNormal.x;n.localPlaneNormal.y=m.m_localPlaneNormal.y;n.localPoint.x=m.m_localPoint.x;n.localPoint.y=m.m_localPoint.y;n.radius=g+b;n.type=m.m_type;for(g=0;g<n.pointCount;++g){r=m.m_points[g];b=n.points[g];b.normalImpulse=
r.m_normalImpulse;b.tangentImpulse=r.m_tangentImpulse;b.localPoint.SetV(r.m_localPoint);r=b.rA.x=L.s_worldManifold.m_points[g].x-e.m_sweep.c.x;s=b.rA.y=L.s_worldManifold.m_points[g].y-e.m_sweep.c.y;var P=b.rB.x=L.s_worldManifold.m_points[g].x-f.m_sweep.c.x,X=b.rB.y=L.s_worldManifold.m_points[g].y-f.m_sweep.c.y,$=r*a-s*c,ba=P*a-X*c;$*=$;ba*=ba;b.normalMass=1/(e.m_invMass+f.m_invMass+e.m_invI*$+f.m_invI*ba);var ca=e.m_mass*e.m_invMass+f.m_mass*f.m_invMass;ca+=e.m_mass*e.m_invI*$+f.m_mass*f.m_invI*ba;
b.equalizedMass=1/ca;ba=a;ca=-c;$=r*ca-s*ba;ba=P*ca-X*ba;$*=$;ba*=ba;b.tangentMass=1/(e.m_invMass+f.m_invMass+e.m_invI*$+f.m_invI*ba);b.velocityBias=0;r=n.normal.x*(x+-T*X-v- -J*s)+n.normal.y*(C+T*P-t-J*r);if(r<-O.b2_velocityThreshold)b.velocityBias+=-n.restitution*r}if(n.pointCount==2){C=n.points[0];x=n.points[1];m=e.m_invMass;e=e.m_invI;v=f.m_invMass;f=f.m_invI;t=C.rA.x*a-C.rA.y*c;C=C.rB.x*a-C.rB.y*c;J=x.rA.x*a-x.rA.y*c;x=x.rB.x*a-x.rB.y*c;c=m+v+e*t*t+f*C*C;a=m+v+e*J*J+f*x*x;f=m+v+e*t*J+f*C*x;if(c*
c<100*(c*a-f*f)){n.K.col1.Set(c,f);n.K.col2.Set(f,a);n.K.GetInverse(n.normalMass)}else n.pointCount=1}}};L.prototype.InitVelocityConstraints=function(j){for(var o=0;o<this.m_constraintCount;++o){var q=this.m_constraints[o],n=q.bodyA,a=q.bodyB,c=n.m_invMass,g=n.m_invI,b=a.m_invMass,e=a.m_invI,f=q.normal.x,m=q.normal.y,r=m,s=-f,v=0,t=0;if(j.warmStarting){t=q.pointCount;for(v=0;v<t;++v){var x=q.points[v];x.normalImpulse*=j.dtRatio;x.tangentImpulse*=j.dtRatio;var C=x.normalImpulse*f+x.tangentImpulse*
r,J=x.normalImpulse*m+x.tangentImpulse*s;n.m_angularVelocity-=g*(x.rA.x*J-x.rA.y*C);n.m_linearVelocity.x-=c*C;n.m_linearVelocity.y-=c*J;a.m_angularVelocity+=e*(x.rB.x*J-x.rB.y*C);a.m_linearVelocity.x+=b*C;a.m_linearVelocity.y+=b*J}}else{t=q.pointCount;for(v=0;v<t;++v){n=q.points[v];n.normalImpulse=0;n.tangentImpulse=0}}}};L.prototype.SolveVelocityConstraints=function(){for(var j=0,o,q=0,n=0,a=0,c=n=n=q=q=0,g=q=q=0,b=q=a=0,e=0,f,m=0;m<this.m_constraintCount;++m){a=this.m_constraints[m];var r=a.bodyA,
s=a.bodyB,v=r.m_angularVelocity,t=s.m_angularVelocity,x=r.m_linearVelocity,C=s.m_linearVelocity,J=r.m_invMass,T=r.m_invI,P=s.m_invMass,X=s.m_invI;b=a.normal.x;var $=e=a.normal.y;f=-b;g=a.friction;for(j=0;j<a.pointCount;j++){o=a.points[j];q=C.x-t*o.rB.y-x.x+v*o.rA.y;n=C.y+t*o.rB.x-x.y-v*o.rA.x;q=q*$+n*f;q=o.tangentMass*-q;n=g*o.normalImpulse;n=R.Clamp(o.tangentImpulse+q,-n,n);q=n-o.tangentImpulse;c=q*$;q=q*f;x.x-=J*c;x.y-=J*q;v-=T*(o.rA.x*q-o.rA.y*c);C.x+=P*c;C.y+=P*q;t+=X*(o.rB.x*q-o.rB.y*c);o.tangentImpulse=
n}parseInt(a.pointCount);if(a.pointCount==1){o=a.points[0];q=C.x+-t*o.rB.y-x.x- -v*o.rA.y;n=C.y+t*o.rB.x-x.y-v*o.rA.x;a=q*b+n*e;q=-o.normalMass*(a-o.velocityBias);n=o.normalImpulse+q;n=n>0?n:0;q=n-o.normalImpulse;c=q*b;q=q*e;x.x-=J*c;x.y-=J*q;v-=T*(o.rA.x*q-o.rA.y*c);C.x+=P*c;C.y+=P*q;t+=X*(o.rB.x*q-o.rB.y*c);o.normalImpulse=n}else{o=a.points[0];j=a.points[1];q=o.normalImpulse;g=j.normalImpulse;var ba=(C.x-t*o.rB.y-x.x+v*o.rA.y)*b+(C.y+t*o.rB.x-x.y-v*o.rA.x)*e,ca=(C.x-t*j.rB.y-x.x+v*j.rA.y)*b+(C.y+
t*j.rB.x-x.y-v*j.rA.x)*e;n=ba-o.velocityBias;c=ca-j.velocityBias;f=a.K;n-=f.col1.x*q+f.col2.x*g;for(c-=f.col1.y*q+f.col2.y*g;;){f=a.normalMass;$=-(f.col1.x*n+f.col2.x*c);f=-(f.col1.y*n+f.col2.y*c);if($>=0&&f>=0){q=$-q;g=f-g;a=q*b;q=q*e;b=g*b;e=g*e;x.x-=J*(a+b);x.y-=J*(q+e);v-=T*(o.rA.x*q-o.rA.y*a+j.rA.x*e-j.rA.y*b);C.x+=P*(a+b);C.y+=P*(q+e);t+=X*(o.rB.x*q-o.rB.y*a+j.rB.x*e-j.rB.y*b);o.normalImpulse=$;j.normalImpulse=f;break}$=-o.normalMass*n;f=0;ca=a.K.col1.y*$+c;if($>=0&&ca>=0){q=$-q;g=f-g;a=q*b;
q=q*e;b=g*b;e=g*e;x.x-=J*(a+b);x.y-=J*(q+e);v-=T*(o.rA.x*q-o.rA.y*a+j.rA.x*e-j.rA.y*b);C.x+=P*(a+b);C.y+=P*(q+e);t+=X*(o.rB.x*q-o.rB.y*a+j.rB.x*e-j.rB.y*b);o.normalImpulse=$;j.normalImpulse=f;break}$=0;f=-j.normalMass*c;ba=a.K.col2.x*f+n;if(f>=0&&ba>=0){q=$-q;g=f-g;a=q*b;q=q*e;b=g*b;e=g*e;x.x-=J*(a+b);x.y-=J*(q+e);v-=T*(o.rA.x*q-o.rA.y*a+j.rA.x*e-j.rA.y*b);C.x+=P*(a+b);C.y+=P*(q+e);t+=X*(o.rB.x*q-o.rB.y*a+j.rB.x*e-j.rB.y*b);o.normalImpulse=$;j.normalImpulse=f;break}f=$=0;ba=n;ca=c;if(ba>=0&&ca>=0){q=
$-q;g=f-g;a=q*b;q=q*e;b=g*b;e=g*e;x.x-=J*(a+b);x.y-=J*(q+e);v-=T*(o.rA.x*q-o.rA.y*a+j.rA.x*e-j.rA.y*b);C.x+=P*(a+b);C.y+=P*(q+e);t+=X*(o.rB.x*q-o.rB.y*a+j.rB.x*e-j.rB.y*b);o.normalImpulse=$;j.normalImpulse=f;break}break}}r.m_angularVelocity=v;s.m_angularVelocity=t}};L.prototype.FinalizeVelocityConstraints=function(){for(var j=0;j<this.m_constraintCount;++j)for(var o=this.m_constraints[j],q=o.manifold,n=0;n<o.pointCount;++n){var a=q.m_points[n],c=o.points[n];a.m_normalImpulse=c.normalImpulse;a.m_tangentImpulse=
c.tangentImpulse}};L.prototype.SolvePositionConstraints=function(j){if(j===undefined)j=0;for(var o=0,q=0;q<this.m_constraintCount;q++){var n=this.m_constraints[q],a=n.bodyA,c=n.bodyB,g=a.m_mass*a.m_invMass,b=a.m_mass*a.m_invI,e=c.m_mass*c.m_invMass,f=c.m_mass*c.m_invI;L.s_psm.Initialize(n);for(var m=L.s_psm.m_normal,r=0;r<n.pointCount;r++){var s=n.points[r],v=L.s_psm.m_points[r],t=L.s_psm.m_separations[r],x=v.x-a.m_sweep.c.x,C=v.y-a.m_sweep.c.y,J=v.x-c.m_sweep.c.x;v=v.y-c.m_sweep.c.y;o=o<t?o:t;t=
R.Clamp(j*(t+O.b2_linearSlop),-O.b2_maxLinearCorrection,0);t=-s.equalizedMass*t;s=t*m.x;t=t*m.y;a.m_sweep.c.x-=g*s;a.m_sweep.c.y-=g*t;a.m_sweep.a-=b*(x*t-C*s);a.SynchronizeTransform();c.m_sweep.c.x+=e*s;c.m_sweep.c.y+=e*t;c.m_sweep.a+=f*(J*t-v*s);c.SynchronizeTransform()}}return o>-1.5*O.b2_linearSlop};Box2D.postDefs.push(function(){Box2D.Dynamics.Contacts.b2ContactSolver.s_worldManifold=new l;Box2D.Dynamics.Contacts.b2ContactSolver.s_psm=new u});Box2D.inherit(I,Box2D.Dynamics.Contacts.b2Contact);
I.prototype.__super=Box2D.Dynamics.Contacts.b2Contact.prototype;I.b2EdgeAndCircleContact=function(){Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this,arguments)};I.Create=function(){return new I};I.Destroy=function(){};I.prototype.Reset=function(j,o){this.__super.Reset.call(this,j,o)};I.prototype.Evaluate=function(){var j=this.m_fixtureA.GetBody(),o=this.m_fixtureB.GetBody();this.b2CollideEdgeAndCircle(this.m_manifold,this.m_fixtureA.GetShape()instanceof G?this.m_fixtureA.GetShape():null,j.m_xf,
this.m_fixtureB.GetShape()instanceof F?this.m_fixtureB.GetShape():null,o.m_xf)};I.prototype.b2CollideEdgeAndCircle=function(){};Box2D.inherit(W,Box2D.Dynamics.Contacts.b2Contact);W.prototype.__super=Box2D.Dynamics.Contacts.b2Contact.prototype;W.b2NullContact=function(){Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this,arguments)};W.prototype.b2NullContact=function(){this.__super.b2Contact.call(this)};W.prototype.Evaluate=function(){};Box2D.inherit(Y,Box2D.Dynamics.Contacts.b2Contact);Y.prototype.__super=
Box2D.Dynamics.Contacts.b2Contact.prototype;Y.b2PolyAndCircleContact=function(){Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this,arguments)};Y.Create=function(){return new Y};Y.Destroy=function(){};Y.prototype.Reset=function(j,o){this.__super.Reset.call(this,j,o);O.b2Assert(j.GetType()==y.e_polygonShape);O.b2Assert(o.GetType()==y.e_circleShape)};Y.prototype.Evaluate=function(){var j=this.m_fixtureA.m_body,o=this.m_fixtureB.m_body;S.CollidePolygonAndCircle(this.m_manifold,this.m_fixtureA.GetShape()instanceof
K?this.m_fixtureA.GetShape():null,j.m_xf,this.m_fixtureB.GetShape()instanceof F?this.m_fixtureB.GetShape():null,o.m_xf)};Box2D.inherit(k,Box2D.Dynamics.Contacts.b2Contact);k.prototype.__super=Box2D.Dynamics.Contacts.b2Contact.prototype;k.b2PolyAndEdgeContact=function(){Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this,arguments)};k.Create=function(){return new k};k.Destroy=function(){};k.prototype.Reset=function(j,o){this.__super.Reset.call(this,j,o);O.b2Assert(j.GetType()==y.e_polygonShape);
O.b2Assert(o.GetType()==y.e_edgeShape)};k.prototype.Evaluate=function(){var j=this.m_fixtureA.GetBody(),o=this.m_fixtureB.GetBody();this.b2CollidePolyAndEdge(this.m_manifold,this.m_fixtureA.GetShape()instanceof K?this.m_fixtureA.GetShape():null,j.m_xf,this.m_fixtureB.GetShape()instanceof G?this.m_fixtureB.GetShape():null,o.m_xf)};k.prototype.b2CollidePolyAndEdge=function(){};Box2D.inherit(z,Box2D.Dynamics.Contacts.b2Contact);z.prototype.__super=Box2D.Dynamics.Contacts.b2Contact.prototype;z.b2PolygonContact=
function(){Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this,arguments)};z.Create=function(){return new z};z.Destroy=function(){};z.prototype.Reset=function(j,o){this.__super.Reset.call(this,j,o)};z.prototype.Evaluate=function(){var j=this.m_fixtureA.GetBody(),o=this.m_fixtureB.GetBody();S.CollidePolygons(this.m_manifold,this.m_fixtureA.GetShape()instanceof K?this.m_fixtureA.GetShape():null,j.m_xf,this.m_fixtureB.GetShape()instanceof K?this.m_fixtureB.GetShape():null,o.m_xf)};u.b2PositionSolverManifold=
function(){};u.prototype.b2PositionSolverManifold=function(){this.m_normal=new N;this.m_separations=new Vector_a2j_Number(O.b2_maxManifoldPoints);this.m_points=new Vector(O.b2_maxManifoldPoints);for(var j=0;j<O.b2_maxManifoldPoints;j++)this.m_points[j]=new N};u.prototype.Initialize=function(j){O.b2Assert(j.pointCount>0);var o=0,q=0,n=0,a,c=0,g=0;switch(j.type){case Z.e_circles:a=j.bodyA.m_xf.R;n=j.localPoint;o=j.bodyA.m_xf.position.x+(a.col1.x*n.x+a.col2.x*n.y);q=j.bodyA.m_xf.position.y+(a.col1.y*
n.x+a.col2.y*n.y);a=j.bodyB.m_xf.R;n=j.points[0].localPoint;c=j.bodyB.m_xf.position.x+(a.col1.x*n.x+a.col2.x*n.y);a=j.bodyB.m_xf.position.y+(a.col1.y*n.x+a.col2.y*n.y);n=c-o;g=a-q;var b=n*n+g*g;if(b>Number.MIN_VALUE*Number.MIN_VALUE){b=Math.sqrt(b);this.m_normal.x=n/b;this.m_normal.y=g/b}else{this.m_normal.x=1;this.m_normal.y=0}this.m_points[0].x=0.5*(o+c);this.m_points[0].y=0.5*(q+a);this.m_separations[0]=n*this.m_normal.x+g*this.m_normal.y-j.radius;break;case Z.e_faceA:a=j.bodyA.m_xf.R;n=j.localPlaneNormal;
this.m_normal.x=a.col1.x*n.x+a.col2.x*n.y;this.m_normal.y=a.col1.y*n.x+a.col2.y*n.y;a=j.bodyA.m_xf.R;n=j.localPoint;c=j.bodyA.m_xf.position.x+(a.col1.x*n.x+a.col2.x*n.y);g=j.bodyA.m_xf.position.y+(a.col1.y*n.x+a.col2.y*n.y);a=j.bodyB.m_xf.R;for(o=0;o<j.pointCount;++o){n=j.points[o].localPoint;q=j.bodyB.m_xf.position.x+(a.col1.x*n.x+a.col2.x*n.y);n=j.bodyB.m_xf.position.y+(a.col1.y*n.x+a.col2.y*n.y);this.m_separations[o]=(q-c)*this.m_normal.x+(n-g)*this.m_normal.y-j.radius;this.m_points[o].x=q;this.m_points[o].y=
n}break;case Z.e_faceB:a=j.bodyB.m_xf.R;n=j.localPlaneNormal;this.m_normal.x=a.col1.x*n.x+a.col2.x*n.y;this.m_normal.y=a.col1.y*n.x+a.col2.y*n.y;a=j.bodyB.m_xf.R;n=j.localPoint;c=j.bodyB.m_xf.position.x+(a.col1.x*n.x+a.col2.x*n.y);g=j.bodyB.m_xf.position.y+(a.col1.y*n.x+a.col2.y*n.y);a=j.bodyA.m_xf.R;for(o=0;o<j.pointCount;++o){n=j.points[o].localPoint;q=j.bodyA.m_xf.position.x+(a.col1.x*n.x+a.col2.x*n.y);n=j.bodyA.m_xf.position.y+(a.col1.y*n.x+a.col2.y*n.y);this.m_separations[o]=(q-c)*this.m_normal.x+
(n-g)*this.m_normal.y-j.radius;this.m_points[o].Set(q,n)}this.m_normal.x*=-1;this.m_normal.y*=-1}};Box2D.postDefs.push(function(){Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointA=new N;Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointB=new N})})();
(function(){var F=Box2D.Common.Math.b2Mat22,G=Box2D.Common.Math.b2Math,K=Box2D.Common.Math.b2Vec2,y=Box2D.Common.b2Color,w=Box2D.Dynamics.Controllers.b2BuoyancyController,A=Box2D.Dynamics.Controllers.b2ConstantAccelController,U=Box2D.Dynamics.Controllers.b2ConstantForceController,p=Box2D.Dynamics.Controllers.b2Controller,B=Box2D.Dynamics.Controllers.b2ControllerEdge,Q=Box2D.Dynamics.Controllers.b2GravityController,V=Box2D.Dynamics.Controllers.b2TensorDampingController;Box2D.inherit(w,Box2D.Dynamics.Controllers.b2Controller);
w.prototype.__super=Box2D.Dynamics.Controllers.b2Controller.prototype;w.b2BuoyancyController=function(){Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this,arguments);this.normal=new K(0,-1);this.density=this.offset=0;this.velocity=new K(0,0);this.linearDrag=2;this.angularDrag=1;this.useDensity=false;this.useWorldGravity=true;this.gravity=null};w.prototype.Step=function(){if(this.m_bodyList){if(this.useWorldGravity)this.gravity=this.GetWorld().GetGravity().Copy();for(var M=this.m_bodyList;M;M=
M.nextBody){var L=M.body;if(L.IsAwake()!=false){for(var I=new K,W=new K,Y=0,k=0,z=L.GetFixtureList();z;z=z.GetNext()){var u=new K,D=z.GetShape().ComputeSubmergedArea(this.normal,this.offset,L.GetTransform(),u);Y+=D;I.x+=D*u.x;I.y+=D*u.y;var H=0;H=1;k+=D*H;W.x+=D*u.x*H;W.y+=D*u.y*H}I.x/=Y;I.y/=Y;W.x/=k;W.y/=k;if(!(Y<Number.MIN_VALUE)){k=this.gravity.GetNegative();k.Multiply(this.density*Y);L.ApplyForce(k,W);W=L.GetLinearVelocityFromWorldPoint(I);W.Subtract(this.velocity);W.Multiply(-this.linearDrag*
Y);L.ApplyForce(W,I);L.ApplyTorque(-L.GetInertia()/L.GetMass()*Y*L.GetAngularVelocity()*this.angularDrag)}}}}};w.prototype.Draw=function(M){var L=new K,I=new K;L.x=this.normal.x*this.offset+this.normal.y*1E3;L.y=this.normal.y*this.offset-this.normal.x*1E3;I.x=this.normal.x*this.offset-this.normal.y*1E3;I.y=this.normal.y*this.offset+this.normal.x*1E3;var W=new y(0,0,1);M.DrawSegment(L,I,W)};Box2D.inherit(A,Box2D.Dynamics.Controllers.b2Controller);A.prototype.__super=Box2D.Dynamics.Controllers.b2Controller.prototype;
A.b2ConstantAccelController=function(){Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this,arguments);this.A=new K(0,0)};A.prototype.Step=function(M){M=new K(this.A.x*M.dt,this.A.y*M.dt);for(var L=this.m_bodyList;L;L=L.nextBody){var I=L.body;I.IsAwake()&&I.SetLinearVelocity(new K(I.GetLinearVelocity().x+M.x,I.GetLinearVelocity().y+M.y))}};Box2D.inherit(U,Box2D.Dynamics.Controllers.b2Controller);U.prototype.__super=Box2D.Dynamics.Controllers.b2Controller.prototype;U.b2ConstantForceController=
function(){Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this,arguments);this.F=new K(0,0)};U.prototype.Step=function(){for(var M=this.m_bodyList;M;M=M.nextBody){var L=M.body;L.IsAwake()&&L.ApplyForce(this.F,L.GetWorldCenter())}};p.b2Controller=function(){};p.prototype.Step=function(){};p.prototype.Draw=function(){};p.prototype.AddBody=function(M){var L=new B;L.controller=this;L.body=M;L.nextBody=this.m_bodyList;L.prevBody=null;this.m_bodyList=L;if(L.nextBody)L.nextBody.prevBody=L;this.m_bodyCount++;
L.nextController=M.m_controllerList;L.prevController=null;M.m_controllerList=L;if(L.nextController)L.nextController.prevController=L;M.m_controllerCount++};p.prototype.RemoveBody=function(M){for(var L=M.m_controllerList;L&&L.controller!=this;)L=L.nextController;if(L.prevBody)L.prevBody.nextBody=L.nextBody;if(L.nextBody)L.nextBody.prevBody=L.prevBody;if(L.nextController)L.nextController.prevController=L.prevController;if(L.prevController)L.prevController.nextController=L.nextController;if(this.m_bodyList==
L)this.m_bodyList=L.nextBody;if(M.m_controllerList==L)M.m_controllerList=L.nextController;M.m_controllerCount--;this.m_bodyCount--};p.prototype.Clear=function(){for(;this.m_bodyList;)this.RemoveBody(this.m_bodyList.body)};p.prototype.GetNext=function(){return this.m_next};p.prototype.GetWorld=function(){return this.m_world};p.prototype.GetBodyList=function(){return this.m_bodyList};B.b2ControllerEdge=function(){};Box2D.inherit(Q,Box2D.Dynamics.Controllers.b2Controller);Q.prototype.__super=Box2D.Dynamics.Controllers.b2Controller.prototype;
Q.b2GravityController=function(){Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this,arguments);this.G=1;this.invSqr=true};Q.prototype.Step=function(){var M=null,L=null,I=null,W=0,Y=null,k=null,z=null,u=0,D=0,H=0;u=null;if(this.invSqr)for(M=this.m_bodyList;M;M=M.nextBody){L=M.body;I=L.GetWorldCenter();W=L.GetMass();for(Y=this.m_bodyList;Y!=M;Y=Y.nextBody){k=Y.body;z=k.GetWorldCenter();u=z.x-I.x;D=z.y-I.y;H=u*u+D*D;if(!(H<Number.MIN_VALUE)){u=new K(u,D);u.Multiply(this.G/H/Math.sqrt(H)*
W*k.GetMass());L.IsAwake()&&L.ApplyForce(u,I);u.Multiply(-1);k.IsAwake()&&k.ApplyForce(u,z)}}}else for(M=this.m_bodyList;M;M=M.nextBody){L=M.body;I=L.GetWorldCenter();W=L.GetMass();for(Y=this.m_bodyList;Y!=M;Y=Y.nextBody){k=Y.body;z=k.GetWorldCenter();u=z.x-I.x;D=z.y-I.y;H=u*u+D*D;if(!(H<Number.MIN_VALUE)){u=new K(u,D);u.Multiply(this.G/H*W*k.GetMass());L.IsAwake()&&L.ApplyForce(u,I);u.Multiply(-1);k.IsAwake()&&k.ApplyForce(u,z)}}}};Box2D.inherit(V,Box2D.Dynamics.Controllers.b2Controller);V.prototype.__super=
Box2D.Dynamics.Controllers.b2Controller.prototype;V.b2TensorDampingController=function(){Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this,arguments);this.T=new F;this.maxTimestep=0};V.prototype.SetAxisAligned=function(M,L){if(M===undefined)M=0;if(L===undefined)L=0;this.T.col1.x=-M;this.T.col1.y=0;this.T.col2.x=0;this.T.col2.y=-L;this.maxTimestep=M>0||L>0?1/Math.max(M,L):0};V.prototype.Step=function(M){M=M.dt;if(!(M<=Number.MIN_VALUE)){if(M>this.maxTimestep&&this.maxTimestep>0)M=this.maxTimestep;
for(var L=this.m_bodyList;L;L=L.nextBody){var I=L.body;if(I.IsAwake()){var W=I.GetWorldVector(G.MulMV(this.T,I.GetLocalVector(I.GetLinearVelocity())));I.SetLinearVelocity(new K(I.GetLinearVelocity().x+W.x*M,I.GetLinearVelocity().y+W.y*M))}}}}})();
(function(){var F=Box2D.Common.b2Settings,G=Box2D.Common.Math.b2Mat22,K=Box2D.Common.Math.b2Mat33,y=Box2D.Common.Math.b2Math,w=Box2D.Common.Math.b2Vec2,A=Box2D.Common.Math.b2Vec3,U=Box2D.Dynamics.Joints.b2DistanceJoint,p=Box2D.Dynamics.Joints.b2DistanceJointDef,B=Box2D.Dynamics.Joints.b2FrictionJoint,Q=Box2D.Dynamics.Joints.b2FrictionJointDef,V=Box2D.Dynamics.Joints.b2GearJoint,M=Box2D.Dynamics.Joints.b2GearJointDef,L=Box2D.Dynamics.Joints.b2Jacobian,I=Box2D.Dynamics.Joints.b2Joint,W=Box2D.Dynamics.Joints.b2JointDef,
Y=Box2D.Dynamics.Joints.b2JointEdge,k=Box2D.Dynamics.Joints.b2LineJoint,z=Box2D.Dynamics.Joints.b2LineJointDef,u=Box2D.Dynamics.Joints.b2MouseJoint,D=Box2D.Dynamics.Joints.b2MouseJointDef,H=Box2D.Dynamics.Joints.b2PrismaticJoint,O=Box2D.Dynamics.Joints.b2PrismaticJointDef,E=Box2D.Dynamics.Joints.b2PulleyJoint,R=Box2D.Dynamics.Joints.b2PulleyJointDef,N=Box2D.Dynamics.Joints.b2RevoluteJoint,S=Box2D.Dynamics.Joints.b2RevoluteJointDef,aa=Box2D.Dynamics.Joints.b2WeldJoint,Z=Box2D.Dynamics.Joints.b2WeldJointDef;
Box2D.inherit(U,Box2D.Dynamics.Joints.b2Joint);U.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;U.b2DistanceJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.m_localAnchor1=new w;this.m_localAnchor2=new w;this.m_u=new w};U.prototype.GetAnchorA=function(){return this.m_bodyA.GetWorldPoint(this.m_localAnchor1)};U.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchor2)};U.prototype.GetReactionForce=function(d){if(d===undefined)d=
0;return new w(d*this.m_impulse*this.m_u.x,d*this.m_impulse*this.m_u.y)};U.prototype.GetReactionTorque=function(){return 0};U.prototype.GetLength=function(){return this.m_length};U.prototype.SetLength=function(d){if(d===undefined)d=0;this.m_length=d};U.prototype.GetFrequency=function(){return this.m_frequencyHz};U.prototype.SetFrequency=function(d){if(d===undefined)d=0;this.m_frequencyHz=d};U.prototype.GetDampingRatio=function(){return this.m_dampingRatio};U.prototype.SetDampingRatio=function(d){if(d===
undefined)d=0;this.m_dampingRatio=d};U.prototype.b2DistanceJoint=function(d){this.__super.b2Joint.call(this,d);this.m_localAnchor1.SetV(d.localAnchorA);this.m_localAnchor2.SetV(d.localAnchorB);this.m_length=d.length;this.m_frequencyHz=d.frequencyHz;this.m_dampingRatio=d.dampingRatio;this.m_bias=this.m_gamma=this.m_impulse=0};U.prototype.InitVelocityConstraints=function(d){var h,l=0,j=this.m_bodyA,o=this.m_bodyB;h=j.m_xf.R;var q=this.m_localAnchor1.x-j.m_sweep.localCenter.x,n=this.m_localAnchor1.y-
j.m_sweep.localCenter.y;l=h.col1.x*q+h.col2.x*n;n=h.col1.y*q+h.col2.y*n;q=l;h=o.m_xf.R;var a=this.m_localAnchor2.x-o.m_sweep.localCenter.x,c=this.m_localAnchor2.y-o.m_sweep.localCenter.y;l=h.col1.x*a+h.col2.x*c;c=h.col1.y*a+h.col2.y*c;a=l;this.m_u.x=o.m_sweep.c.x+a-j.m_sweep.c.x-q;this.m_u.y=o.m_sweep.c.y+c-j.m_sweep.c.y-n;l=Math.sqrt(this.m_u.x*this.m_u.x+this.m_u.y*this.m_u.y);l>F.b2_linearSlop?this.m_u.Multiply(1/l):this.m_u.SetZero();h=q*this.m_u.y-n*this.m_u.x;var g=a*this.m_u.y-c*this.m_u.x;
h=j.m_invMass+j.m_invI*h*h+o.m_invMass+o.m_invI*g*g;this.m_mass=h!=0?1/h:0;if(this.m_frequencyHz>0){l=l-this.m_length;g=2*Math.PI*this.m_frequencyHz;var b=this.m_mass*g*g;this.m_gamma=d.dt*(2*this.m_mass*this.m_dampingRatio*g+d.dt*b);this.m_gamma=this.m_gamma!=0?1/this.m_gamma:0;this.m_bias=l*d.dt*b*this.m_gamma;this.m_mass=h+this.m_gamma;this.m_mass=this.m_mass!=0?1/this.m_mass:0}if(d.warmStarting){this.m_impulse*=d.dtRatio;d=this.m_impulse*this.m_u.x;h=this.m_impulse*this.m_u.y;j.m_linearVelocity.x-=
j.m_invMass*d;j.m_linearVelocity.y-=j.m_invMass*h;j.m_angularVelocity-=j.m_invI*(q*h-n*d);o.m_linearVelocity.x+=o.m_invMass*d;o.m_linearVelocity.y+=o.m_invMass*h;o.m_angularVelocity+=o.m_invI*(a*h-c*d)}else this.m_impulse=0};U.prototype.SolveVelocityConstraints=function(){var d,h=this.m_bodyA,l=this.m_bodyB;d=h.m_xf.R;var j=this.m_localAnchor1.x-h.m_sweep.localCenter.x,o=this.m_localAnchor1.y-h.m_sweep.localCenter.y,q=d.col1.x*j+d.col2.x*o;o=d.col1.y*j+d.col2.y*o;j=q;d=l.m_xf.R;var n=this.m_localAnchor2.x-
l.m_sweep.localCenter.x,a=this.m_localAnchor2.y-l.m_sweep.localCenter.y;q=d.col1.x*n+d.col2.x*a;a=d.col1.y*n+d.col2.y*a;n=q;q=-this.m_mass*(this.m_u.x*(l.m_linearVelocity.x+-l.m_angularVelocity*a-(h.m_linearVelocity.x+-h.m_angularVelocity*o))+this.m_u.y*(l.m_linearVelocity.y+l.m_angularVelocity*n-(h.m_linearVelocity.y+h.m_angularVelocity*j))+this.m_bias+this.m_gamma*this.m_impulse);this.m_impulse+=q;d=q*this.m_u.x;q=q*this.m_u.y;h.m_linearVelocity.x-=h.m_invMass*d;h.m_linearVelocity.y-=h.m_invMass*
q;h.m_angularVelocity-=h.m_invI*(j*q-o*d);l.m_linearVelocity.x+=l.m_invMass*d;l.m_linearVelocity.y+=l.m_invMass*q;l.m_angularVelocity+=l.m_invI*(n*q-a*d)};U.prototype.SolvePositionConstraints=function(){var d;if(this.m_frequencyHz>0)return true;var h=this.m_bodyA,l=this.m_bodyB;d=h.m_xf.R;var j=this.m_localAnchor1.x-h.m_sweep.localCenter.x,o=this.m_localAnchor1.y-h.m_sweep.localCenter.y,q=d.col1.x*j+d.col2.x*o;o=d.col1.y*j+d.col2.y*o;j=q;d=l.m_xf.R;var n=this.m_localAnchor2.x-l.m_sweep.localCenter.x,
a=this.m_localAnchor2.y-l.m_sweep.localCenter.y;q=d.col1.x*n+d.col2.x*a;a=d.col1.y*n+d.col2.y*a;n=q;q=l.m_sweep.c.x+n-h.m_sweep.c.x-j;var c=l.m_sweep.c.y+a-h.m_sweep.c.y-o;d=Math.sqrt(q*q+c*c);q/=d;c/=d;d=d-this.m_length;d=y.Clamp(d,-F.b2_maxLinearCorrection,F.b2_maxLinearCorrection);var g=-this.m_mass*d;this.m_u.Set(q,c);q=g*this.m_u.x;c=g*this.m_u.y;h.m_sweep.c.x-=h.m_invMass*q;h.m_sweep.c.y-=h.m_invMass*c;h.m_sweep.a-=h.m_invI*(j*c-o*q);l.m_sweep.c.x+=l.m_invMass*q;l.m_sweep.c.y+=l.m_invMass*c;
l.m_sweep.a+=l.m_invI*(n*c-a*q);h.SynchronizeTransform();l.SynchronizeTransform();return y.Abs(d)<F.b2_linearSlop};Box2D.inherit(p,Box2D.Dynamics.Joints.b2JointDef);p.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;p.b2DistanceJointDef=function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,arguments);this.localAnchorA=new w;this.localAnchorB=new w};p.prototype.b2DistanceJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_distanceJoint;this.length=1;this.dampingRatio=
this.frequencyHz=0};p.prototype.Initialize=function(d,h,l,j){this.bodyA=d;this.bodyB=h;this.localAnchorA.SetV(this.bodyA.GetLocalPoint(l));this.localAnchorB.SetV(this.bodyB.GetLocalPoint(j));d=j.x-l.x;l=j.y-l.y;this.length=Math.sqrt(d*d+l*l);this.dampingRatio=this.frequencyHz=0};Box2D.inherit(B,Box2D.Dynamics.Joints.b2Joint);B.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;B.b2FrictionJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.m_localAnchorA=new w;
this.m_localAnchorB=new w;this.m_linearMass=new G;this.m_linearImpulse=new w};B.prototype.GetAnchorA=function(){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA)};B.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB)};B.prototype.GetReactionForce=function(d){if(d===undefined)d=0;return new w(d*this.m_linearImpulse.x,d*this.m_linearImpulse.y)};B.prototype.GetReactionTorque=function(d){if(d===undefined)d=0;return d*this.m_angularImpulse};B.prototype.SetMaxForce=
function(d){if(d===undefined)d=0;this.m_maxForce=d};B.prototype.GetMaxForce=function(){return this.m_maxForce};B.prototype.SetMaxTorque=function(d){if(d===undefined)d=0;this.m_maxTorque=d};B.prototype.GetMaxTorque=function(){return this.m_maxTorque};B.prototype.b2FrictionJoint=function(d){this.__super.b2Joint.call(this,d);this.m_localAnchorA.SetV(d.localAnchorA);this.m_localAnchorB.SetV(d.localAnchorB);this.m_linearMass.SetZero();this.m_angularMass=0;this.m_linearImpulse.SetZero();this.m_angularImpulse=
0;this.m_maxForce=d.maxForce;this.m_maxTorque=d.maxTorque};B.prototype.InitVelocityConstraints=function(d){var h,l=0,j=this.m_bodyA,o=this.m_bodyB;h=j.m_xf.R;var q=this.m_localAnchorA.x-j.m_sweep.localCenter.x,n=this.m_localAnchorA.y-j.m_sweep.localCenter.y;l=h.col1.x*q+h.col2.x*n;n=h.col1.y*q+h.col2.y*n;q=l;h=o.m_xf.R;var a=this.m_localAnchorB.x-o.m_sweep.localCenter.x,c=this.m_localAnchorB.y-o.m_sweep.localCenter.y;l=h.col1.x*a+h.col2.x*c;c=h.col1.y*a+h.col2.y*c;a=l;h=j.m_invMass;l=o.m_invMass;
var g=j.m_invI,b=o.m_invI,e=new G;e.col1.x=h+l;e.col2.x=0;e.col1.y=0;e.col2.y=h+l;e.col1.x+=g*n*n;e.col2.x+=-g*q*n;e.col1.y+=-g*q*n;e.col2.y+=g*q*q;e.col1.x+=b*c*c;e.col2.x+=-b*a*c;e.col1.y+=-b*a*c;e.col2.y+=b*a*a;e.GetInverse(this.m_linearMass);this.m_angularMass=g+b;if(this.m_angularMass>0)this.m_angularMass=1/this.m_angularMass;if(d.warmStarting){this.m_linearImpulse.x*=d.dtRatio;this.m_linearImpulse.y*=d.dtRatio;this.m_angularImpulse*=d.dtRatio;d=this.m_linearImpulse;j.m_linearVelocity.x-=h*d.x;
j.m_linearVelocity.y-=h*d.y;j.m_angularVelocity-=g*(q*d.y-n*d.x+this.m_angularImpulse);o.m_linearVelocity.x+=l*d.x;o.m_linearVelocity.y+=l*d.y;o.m_angularVelocity+=b*(a*d.y-c*d.x+this.m_angularImpulse)}else{this.m_linearImpulse.SetZero();this.m_angularImpulse=0}};B.prototype.SolveVelocityConstraints=function(d){var h,l=0,j=this.m_bodyA,o=this.m_bodyB,q=j.m_linearVelocity,n=j.m_angularVelocity,a=o.m_linearVelocity,c=o.m_angularVelocity,g=j.m_invMass,b=o.m_invMass,e=j.m_invI,f=o.m_invI;h=j.m_xf.R;var m=
this.m_localAnchorA.x-j.m_sweep.localCenter.x,r=this.m_localAnchorA.y-j.m_sweep.localCenter.y;l=h.col1.x*m+h.col2.x*r;r=h.col1.y*m+h.col2.y*r;m=l;h=o.m_xf.R;var s=this.m_localAnchorB.x-o.m_sweep.localCenter.x,v=this.m_localAnchorB.y-o.m_sweep.localCenter.y;l=h.col1.x*s+h.col2.x*v;v=h.col1.y*s+h.col2.y*v;s=l;h=0;l=-this.m_angularMass*(c-n);var t=this.m_angularImpulse;h=d.dt*this.m_maxTorque;this.m_angularImpulse=y.Clamp(this.m_angularImpulse+l,-h,h);l=this.m_angularImpulse-t;n-=e*l;c+=f*l;h=y.MulMV(this.m_linearMass,
new w(-(a.x-c*v-q.x+n*r),-(a.y+c*s-q.y-n*m)));l=this.m_linearImpulse.Copy();this.m_linearImpulse.Add(h);h=d.dt*this.m_maxForce;if(this.m_linearImpulse.LengthSquared()>h*h){this.m_linearImpulse.Normalize();this.m_linearImpulse.Multiply(h)}h=y.SubtractVV(this.m_linearImpulse,l);q.x-=g*h.x;q.y-=g*h.y;n-=e*(m*h.y-r*h.x);a.x+=b*h.x;a.y+=b*h.y;c+=f*(s*h.y-v*h.x);j.m_angularVelocity=n;o.m_angularVelocity=c};B.prototype.SolvePositionConstraints=function(){return true};Box2D.inherit(Q,Box2D.Dynamics.Joints.b2JointDef);
Q.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;Q.b2FrictionJointDef=function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,arguments);this.localAnchorA=new w;this.localAnchorB=new w};Q.prototype.b2FrictionJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_frictionJoint;this.maxTorque=this.maxForce=0};Q.prototype.Initialize=function(d,h,l){this.bodyA=d;this.bodyB=h;this.localAnchorA.SetV(this.bodyA.GetLocalPoint(l));this.localAnchorB.SetV(this.bodyB.GetLocalPoint(l))};
Box2D.inherit(V,Box2D.Dynamics.Joints.b2Joint);V.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;V.b2GearJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.m_groundAnchor1=new w;this.m_groundAnchor2=new w;this.m_localAnchor1=new w;this.m_localAnchor2=new w;this.m_J=new L};V.prototype.GetAnchorA=function(){return this.m_bodyA.GetWorldPoint(this.m_localAnchor1)};V.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchor2)};V.prototype.GetReactionForce=
function(d){if(d===undefined)d=0;return new w(d*this.m_impulse*this.m_J.linearB.x,d*this.m_impulse*this.m_J.linearB.y)};V.prototype.GetReactionTorque=function(d){if(d===undefined)d=0;var h=this.m_bodyB.m_xf.R,l=this.m_localAnchor1.x-this.m_bodyB.m_sweep.localCenter.x,j=this.m_localAnchor1.y-this.m_bodyB.m_sweep.localCenter.y,o=h.col1.x*l+h.col2.x*j;j=h.col1.y*l+h.col2.y*j;l=o;return d*(this.m_impulse*this.m_J.angularB-l*this.m_impulse*this.m_J.linearB.y+j*this.m_impulse*this.m_J.linearB.x)};V.prototype.GetRatio=
function(){return this.m_ratio};V.prototype.SetRatio=function(d){if(d===undefined)d=0;this.m_ratio=d};V.prototype.b2GearJoint=function(d){this.__super.b2Joint.call(this,d);var h=parseInt(d.joint1.m_type),l=parseInt(d.joint2.m_type);this.m_prismatic2=this.m_revolute2=this.m_prismatic1=this.m_revolute1=null;var j=0,o=0;this.m_ground1=d.joint1.GetBodyA();this.m_bodyA=d.joint1.GetBodyB();if(h==I.e_revoluteJoint){this.m_revolute1=d.joint1 instanceof N?d.joint1:null;this.m_groundAnchor1.SetV(this.m_revolute1.m_localAnchor1);
this.m_localAnchor1.SetV(this.m_revolute1.m_localAnchor2);j=this.m_revolute1.GetJointAngle()}else{this.m_prismatic1=d.joint1 instanceof H?d.joint1:null;this.m_groundAnchor1.SetV(this.m_prismatic1.m_localAnchor1);this.m_localAnchor1.SetV(this.m_prismatic1.m_localAnchor2);j=this.m_prismatic1.GetJointTranslation()}this.m_ground2=d.joint2.GetBodyA();this.m_bodyB=d.joint2.GetBodyB();if(l==I.e_revoluteJoint){this.m_revolute2=d.joint2 instanceof N?d.joint2:null;this.m_groundAnchor2.SetV(this.m_revolute2.m_localAnchor1);
this.m_localAnchor2.SetV(this.m_revolute2.m_localAnchor2);o=this.m_revolute2.GetJointAngle()}else{this.m_prismatic2=d.joint2 instanceof H?d.joint2:null;this.m_groundAnchor2.SetV(this.m_prismatic2.m_localAnchor1);this.m_localAnchor2.SetV(this.m_prismatic2.m_localAnchor2);o=this.m_prismatic2.GetJointTranslation()}this.m_ratio=d.ratio;this.m_constant=j+this.m_ratio*o;this.m_impulse=0};V.prototype.InitVelocityConstraints=function(d){var h=this.m_ground1,l=this.m_ground2,j=this.m_bodyA,o=this.m_bodyB,
q=0,n=0,a=0,c=0,g=a=0,b=0;this.m_J.SetZero();if(this.m_revolute1){this.m_J.angularA=-1;b+=j.m_invI}else{h=h.m_xf.R;n=this.m_prismatic1.m_localXAxis1;q=h.col1.x*n.x+h.col2.x*n.y;n=h.col1.y*n.x+h.col2.y*n.y;h=j.m_xf.R;a=this.m_localAnchor1.x-j.m_sweep.localCenter.x;c=this.m_localAnchor1.y-j.m_sweep.localCenter.y;g=h.col1.x*a+h.col2.x*c;c=h.col1.y*a+h.col2.y*c;a=g;a=a*n-c*q;this.m_J.linearA.Set(-q,-n);this.m_J.angularA=-a;b+=j.m_invMass+j.m_invI*a*a}if(this.m_revolute2){this.m_J.angularB=-this.m_ratio;
b+=this.m_ratio*this.m_ratio*o.m_invI}else{h=l.m_xf.R;n=this.m_prismatic2.m_localXAxis1;q=h.col1.x*n.x+h.col2.x*n.y;n=h.col1.y*n.x+h.col2.y*n.y;h=o.m_xf.R;a=this.m_localAnchor2.x-o.m_sweep.localCenter.x;c=this.m_localAnchor2.y-o.m_sweep.localCenter.y;g=h.col1.x*a+h.col2.x*c;c=h.col1.y*a+h.col2.y*c;a=g;a=a*n-c*q;this.m_J.linearB.Set(-this.m_ratio*q,-this.m_ratio*n);this.m_J.angularB=-this.m_ratio*a;b+=this.m_ratio*this.m_ratio*(o.m_invMass+o.m_invI*a*a)}this.m_mass=b>0?1/b:0;if(d.warmStarting){j.m_linearVelocity.x+=
j.m_invMass*this.m_impulse*this.m_J.linearA.x;j.m_linearVelocity.y+=j.m_invMass*this.m_impulse*this.m_J.linearA.y;j.m_angularVelocity+=j.m_invI*this.m_impulse*this.m_J.angularA;o.m_linearVelocity.x+=o.m_invMass*this.m_impulse*this.m_J.linearB.x;o.m_linearVelocity.y+=o.m_invMass*this.m_impulse*this.m_J.linearB.y;o.m_angularVelocity+=o.m_invI*this.m_impulse*this.m_J.angularB}else this.m_impulse=0};V.prototype.SolveVelocityConstraints=function(){var d=this.m_bodyA,h=this.m_bodyB,l=-this.m_mass*this.m_J.Compute(d.m_linearVelocity,
d.m_angularVelocity,h.m_linearVelocity,h.m_angularVelocity);this.m_impulse+=l;d.m_linearVelocity.x+=d.m_invMass*l*this.m_J.linearA.x;d.m_linearVelocity.y+=d.m_invMass*l*this.m_J.linearA.y;d.m_angularVelocity+=d.m_invI*l*this.m_J.angularA;h.m_linearVelocity.x+=h.m_invMass*l*this.m_J.linearB.x;h.m_linearVelocity.y+=h.m_invMass*l*this.m_J.linearB.y;h.m_angularVelocity+=h.m_invI*l*this.m_J.angularB};V.prototype.SolvePositionConstraints=function(){var d=this.m_bodyA,h=this.m_bodyB,l=0,j=0;l=this.m_revolute1?
this.m_revolute1.GetJointAngle():this.m_prismatic1.GetJointTranslation();j=this.m_revolute2?this.m_revolute2.GetJointAngle():this.m_prismatic2.GetJointTranslation();l=-this.m_mass*(this.m_constant-(l+this.m_ratio*j));d.m_sweep.c.x+=d.m_invMass*l*this.m_J.linearA.x;d.m_sweep.c.y+=d.m_invMass*l*this.m_J.linearA.y;d.m_sweep.a+=d.m_invI*l*this.m_J.angularA;h.m_sweep.c.x+=h.m_invMass*l*this.m_J.linearB.x;h.m_sweep.c.y+=h.m_invMass*l*this.m_J.linearB.y;h.m_sweep.a+=h.m_invI*l*this.m_J.angularB;d.SynchronizeTransform();
h.SynchronizeTransform();return 0<F.b2_linearSlop};Box2D.inherit(M,Box2D.Dynamics.Joints.b2JointDef);M.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;M.b2GearJointDef=function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,arguments)};M.prototype.b2GearJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_gearJoint;this.joint2=this.joint1=null;this.ratio=1};L.b2Jacobian=function(){this.linearA=new w;this.linearB=new w};L.prototype.SetZero=function(){this.linearA.SetZero();
this.angularA=0;this.linearB.SetZero();this.angularB=0};L.prototype.Set=function(d,h,l,j){if(h===undefined)h=0;if(j===undefined)j=0;this.linearA.SetV(d);this.angularA=h;this.linearB.SetV(l);this.angularB=j};L.prototype.Compute=function(d,h,l,j){if(h===undefined)h=0;if(j===undefined)j=0;return this.linearA.x*d.x+this.linearA.y*d.y+this.angularA*h+(this.linearB.x*l.x+this.linearB.y*l.y)+this.angularB*j};I.b2Joint=function(){this.m_edgeA=new Y;this.m_edgeB=new Y;this.m_localCenterA=new w;this.m_localCenterB=
new w};I.prototype.GetType=function(){return this.m_type};I.prototype.GetAnchorA=function(){return null};I.prototype.GetAnchorB=function(){return null};I.prototype.GetReactionForce=function(){return null};I.prototype.GetReactionTorque=function(){return 0};I.prototype.GetBodyA=function(){return this.m_bodyA};I.prototype.GetBodyB=function(){return this.m_bodyB};I.prototype.GetNext=function(){return this.m_next};I.prototype.GetUserData=function(){return this.m_userData};I.prototype.SetUserData=function(d){this.m_userData=
d};I.prototype.IsActive=function(){return this.m_bodyA.IsActive()&&this.m_bodyB.IsActive()};I.Create=function(d){var h=null;switch(d.type){case I.e_distanceJoint:h=new U(d instanceof p?d:null);break;case I.e_mouseJoint:h=new u(d instanceof D?d:null);break;case I.e_prismaticJoint:h=new H(d instanceof O?d:null);break;case I.e_revoluteJoint:h=new N(d instanceof S?d:null);break;case I.e_pulleyJoint:h=new E(d instanceof R?d:null);break;case I.e_gearJoint:h=new V(d instanceof M?d:null);break;case I.e_lineJoint:h=
new k(d instanceof z?d:null);break;case I.e_weldJoint:h=new aa(d instanceof Z?d:null);break;case I.e_frictionJoint:h=new B(d instanceof Q?d:null)}return h};I.Destroy=function(){};I.prototype.b2Joint=function(d){F.b2Assert(d.bodyA!=d.bodyB);this.m_type=d.type;this.m_next=this.m_prev=null;this.m_bodyA=d.bodyA;this.m_bodyB=d.bodyB;this.m_collideConnected=d.collideConnected;this.m_islandFlag=false;this.m_userData=d.userData};I.prototype.InitVelocityConstraints=function(){};I.prototype.SolveVelocityConstraints=
function(){};I.prototype.FinalizeVelocityConstraints=function(){};I.prototype.SolvePositionConstraints=function(){return false};Box2D.postDefs.push(function(){Box2D.Dynamics.Joints.b2Joint.e_unknownJoint=0;Box2D.Dynamics.Joints.b2Joint.e_revoluteJoint=1;Box2D.Dynamics.Joints.b2Joint.e_prismaticJoint=2;Box2D.Dynamics.Joints.b2Joint.e_distanceJoint=3;Box2D.Dynamics.Joints.b2Joint.e_pulleyJoint=4;Box2D.Dynamics.Joints.b2Joint.e_mouseJoint=5;Box2D.Dynamics.Joints.b2Joint.e_gearJoint=6;Box2D.Dynamics.Joints.b2Joint.e_lineJoint=
7;Box2D.Dynamics.Joints.b2Joint.e_weldJoint=8;Box2D.Dynamics.Joints.b2Joint.e_frictionJoint=9;Box2D.Dynamics.Joints.b2Joint.e_inactiveLimit=0;Box2D.Dynamics.Joints.b2Joint.e_atLowerLimit=1;Box2D.Dynamics.Joints.b2Joint.e_atUpperLimit=2;Box2D.Dynamics.Joints.b2Joint.e_equalLimits=3});W.b2JointDef=function(){};W.prototype.b2JointDef=function(){this.type=I.e_unknownJoint;this.bodyB=this.bodyA=this.userData=null;this.collideConnected=false};Y.b2JointEdge=function(){};Box2D.inherit(k,Box2D.Dynamics.Joints.b2Joint);
k.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;k.b2LineJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.m_localAnchor1=new w;this.m_localAnchor2=new w;this.m_localXAxis1=new w;this.m_localYAxis1=new w;this.m_axis=new w;this.m_perp=new w;this.m_K=new G;this.m_impulse=new w};k.prototype.GetAnchorA=function(){return this.m_bodyA.GetWorldPoint(this.m_localAnchor1)};k.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchor2)};k.prototype.GetReactionForce=
function(d){if(d===undefined)d=0;return new w(d*(this.m_impulse.x*this.m_perp.x+(this.m_motorImpulse+this.m_impulse.y)*this.m_axis.x),d*(this.m_impulse.x*this.m_perp.y+(this.m_motorImpulse+this.m_impulse.y)*this.m_axis.y))};k.prototype.GetReactionTorque=function(d){if(d===undefined)d=0;return d*this.m_impulse.y};k.prototype.GetJointTranslation=function(){var d=this.m_bodyA,h=this.m_bodyB,l=d.GetWorldPoint(this.m_localAnchor1),j=h.GetWorldPoint(this.m_localAnchor2);h=j.x-l.x;l=j.y-l.y;d=d.GetWorldVector(this.m_localXAxis1);
return d.x*h+d.y*l};k.prototype.GetJointSpeed=function(){var d=this.m_bodyA,h=this.m_bodyB,l;l=d.m_xf.R;var j=this.m_localAnchor1.x-d.m_sweep.localCenter.x,o=this.m_localAnchor1.y-d.m_sweep.localCenter.y,q=l.col1.x*j+l.col2.x*o;o=l.col1.y*j+l.col2.y*o;j=q;l=h.m_xf.R;var n=this.m_localAnchor2.x-h.m_sweep.localCenter.x,a=this.m_localAnchor2.y-h.m_sweep.localCenter.y;q=l.col1.x*n+l.col2.x*a;a=l.col1.y*n+l.col2.y*a;n=q;l=h.m_sweep.c.x+n-(d.m_sweep.c.x+j);q=h.m_sweep.c.y+a-(d.m_sweep.c.y+o);var c=d.GetWorldVector(this.m_localXAxis1),
g=d.m_linearVelocity,b=h.m_linearVelocity;d=d.m_angularVelocity;h=h.m_angularVelocity;return l*-d*c.y+q*d*c.x+(c.x*(b.x+-h*a-g.x- -d*o)+c.y*(b.y+h*n-g.y-d*j))};k.prototype.IsLimitEnabled=function(){return this.m_enableLimit};k.prototype.EnableLimit=function(d){this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_enableLimit=d};k.prototype.GetLowerLimit=function(){return this.m_lowerTranslation};k.prototype.GetUpperLimit=function(){return this.m_upperTranslation};k.prototype.SetLimits=function(d,
h){if(d===undefined)d=0;if(h===undefined)h=0;this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_lowerTranslation=d;this.m_upperTranslation=h};k.prototype.IsMotorEnabled=function(){return this.m_enableMotor};k.prototype.EnableMotor=function(d){this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_enableMotor=d};k.prototype.SetMotorSpeed=function(d){if(d===undefined)d=0;this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_motorSpeed=d};k.prototype.GetMotorSpeed=function(){return this.m_motorSpeed};
k.prototype.SetMaxMotorForce=function(d){if(d===undefined)d=0;this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_maxMotorForce=d};k.prototype.GetMaxMotorForce=function(){return this.m_maxMotorForce};k.prototype.GetMotorForce=function(){return this.m_motorImpulse};k.prototype.b2LineJoint=function(d){this.__super.b2Joint.call(this,d);this.m_localAnchor1.SetV(d.localAnchorA);this.m_localAnchor2.SetV(d.localAnchorB);this.m_localXAxis1.SetV(d.localAxisA);this.m_localYAxis1.x=-this.m_localXAxis1.y;
this.m_localYAxis1.y=this.m_localXAxis1.x;this.m_impulse.SetZero();this.m_motorImpulse=this.m_motorMass=0;this.m_lowerTranslation=d.lowerTranslation;this.m_upperTranslation=d.upperTranslation;this.m_maxMotorForce=d.maxMotorForce;this.m_motorSpeed=d.motorSpeed;this.m_enableLimit=d.enableLimit;this.m_enableMotor=d.enableMotor;this.m_limitState=I.e_inactiveLimit;this.m_axis.SetZero();this.m_perp.SetZero()};k.prototype.InitVelocityConstraints=function(d){var h=this.m_bodyA,l=this.m_bodyB,j,o=0;this.m_localCenterA.SetV(h.GetLocalCenter());
this.m_localCenterB.SetV(l.GetLocalCenter());var q=h.GetTransform();l.GetTransform();j=h.m_xf.R;var n=this.m_localAnchor1.x-this.m_localCenterA.x,a=this.m_localAnchor1.y-this.m_localCenterA.y;o=j.col1.x*n+j.col2.x*a;a=j.col1.y*n+j.col2.y*a;n=o;j=l.m_xf.R;var c=this.m_localAnchor2.x-this.m_localCenterB.x,g=this.m_localAnchor2.y-this.m_localCenterB.y;o=j.col1.x*c+j.col2.x*g;g=j.col1.y*c+j.col2.y*g;c=o;j=l.m_sweep.c.x+c-h.m_sweep.c.x-n;o=l.m_sweep.c.y+g-h.m_sweep.c.y-a;this.m_invMassA=h.m_invMass;this.m_invMassB=
l.m_invMass;this.m_invIA=h.m_invI;this.m_invIB=l.m_invI;this.m_axis.SetV(y.MulMV(q.R,this.m_localXAxis1));this.m_a1=(j+n)*this.m_axis.y-(o+a)*this.m_axis.x;this.m_a2=c*this.m_axis.y-g*this.m_axis.x;this.m_motorMass=this.m_invMassA+this.m_invMassB+this.m_invIA*this.m_a1*this.m_a1+this.m_invIB*this.m_a2*this.m_a2;this.m_motorMass=this.m_motorMass>Number.MIN_VALUE?1/this.m_motorMass:0;this.m_perp.SetV(y.MulMV(q.R,this.m_localYAxis1));this.m_s1=(j+n)*this.m_perp.y-(o+a)*this.m_perp.x;this.m_s2=c*this.m_perp.y-
g*this.m_perp.x;q=this.m_invMassA;n=this.m_invMassB;a=this.m_invIA;c=this.m_invIB;this.m_K.col1.x=q+n+a*this.m_s1*this.m_s1+c*this.m_s2*this.m_s2;this.m_K.col1.y=a*this.m_s1*this.m_a1+c*this.m_s2*this.m_a2;this.m_K.col2.x=this.m_K.col1.y;this.m_K.col2.y=q+n+a*this.m_a1*this.m_a1+c*this.m_a2*this.m_a2;if(this.m_enableLimit){j=this.m_axis.x*j+this.m_axis.y*o;if(y.Abs(this.m_upperTranslation-this.m_lowerTranslation)<2*F.b2_linearSlop)this.m_limitState=I.e_equalLimits;else if(j<=this.m_lowerTranslation){if(this.m_limitState!=
I.e_atLowerLimit){this.m_limitState=I.e_atLowerLimit;this.m_impulse.y=0}}else if(j>=this.m_upperTranslation){if(this.m_limitState!=I.e_atUpperLimit){this.m_limitState=I.e_atUpperLimit;this.m_impulse.y=0}}else{this.m_limitState=I.e_inactiveLimit;this.m_impulse.y=0}}else this.m_limitState=I.e_inactiveLimit;if(this.m_enableMotor==false)this.m_motorImpulse=0;if(d.warmStarting){this.m_impulse.x*=d.dtRatio;this.m_impulse.y*=d.dtRatio;this.m_motorImpulse*=d.dtRatio;d=this.m_impulse.x*this.m_perp.x+(this.m_motorImpulse+
this.m_impulse.y)*this.m_axis.x;j=this.m_impulse.x*this.m_perp.y+(this.m_motorImpulse+this.m_impulse.y)*this.m_axis.y;o=this.m_impulse.x*this.m_s1+(this.m_motorImpulse+this.m_impulse.y)*this.m_a1;q=this.m_impulse.x*this.m_s2+(this.m_motorImpulse+this.m_impulse.y)*this.m_a2;h.m_linearVelocity.x-=this.m_invMassA*d;h.m_linearVelocity.y-=this.m_invMassA*j;h.m_angularVelocity-=this.m_invIA*o;l.m_linearVelocity.x+=this.m_invMassB*d;l.m_linearVelocity.y+=this.m_invMassB*j;l.m_angularVelocity+=this.m_invIB*
q}else{this.m_impulse.SetZero();this.m_motorImpulse=0}};k.prototype.SolveVelocityConstraints=function(d){var h=this.m_bodyA,l=this.m_bodyB,j=h.m_linearVelocity,o=h.m_angularVelocity,q=l.m_linearVelocity,n=l.m_angularVelocity,a=0,c=0,g=0,b=0;if(this.m_enableMotor&&this.m_limitState!=I.e_equalLimits){b=this.m_motorMass*(this.m_motorSpeed-(this.m_axis.x*(q.x-j.x)+this.m_axis.y*(q.y-j.y)+this.m_a2*n-this.m_a1*o));a=this.m_motorImpulse;c=d.dt*this.m_maxMotorForce;this.m_motorImpulse=y.Clamp(this.m_motorImpulse+
b,-c,c);b=this.m_motorImpulse-a;a=b*this.m_axis.x;c=b*this.m_axis.y;g=b*this.m_a1;b=b*this.m_a2;j.x-=this.m_invMassA*a;j.y-=this.m_invMassA*c;o-=this.m_invIA*g;q.x+=this.m_invMassB*a;q.y+=this.m_invMassB*c;n+=this.m_invIB*b}c=this.m_perp.x*(q.x-j.x)+this.m_perp.y*(q.y-j.y)+this.m_s2*n-this.m_s1*o;if(this.m_enableLimit&&this.m_limitState!=I.e_inactiveLimit){g=this.m_axis.x*(q.x-j.x)+this.m_axis.y*(q.y-j.y)+this.m_a2*n-this.m_a1*o;a=this.m_impulse.Copy();d=this.m_K.Solve(new w,-c,-g);this.m_impulse.Add(d);
if(this.m_limitState==I.e_atLowerLimit)this.m_impulse.y=y.Max(this.m_impulse.y,0);else if(this.m_limitState==I.e_atUpperLimit)this.m_impulse.y=y.Min(this.m_impulse.y,0);c=-c-(this.m_impulse.y-a.y)*this.m_K.col2.x;g=0;g=this.m_K.col1.x!=0?c/this.m_K.col1.x+a.x:a.x;this.m_impulse.x=g;d.x=this.m_impulse.x-a.x;d.y=this.m_impulse.y-a.y;a=d.x*this.m_perp.x+d.y*this.m_axis.x;c=d.x*this.m_perp.y+d.y*this.m_axis.y;g=d.x*this.m_s1+d.y*this.m_a1;b=d.x*this.m_s2+d.y*this.m_a2}else{d=0;d=this.m_K.col1.x!=0?-c/
this.m_K.col1.x:0;this.m_impulse.x+=d;a=d*this.m_perp.x;c=d*this.m_perp.y;g=d*this.m_s1;b=d*this.m_s2}j.x-=this.m_invMassA*a;j.y-=this.m_invMassA*c;o-=this.m_invIA*g;q.x+=this.m_invMassB*a;q.y+=this.m_invMassB*c;n+=this.m_invIB*b;h.m_linearVelocity.SetV(j);h.m_angularVelocity=o;l.m_linearVelocity.SetV(q);l.m_angularVelocity=n};k.prototype.SolvePositionConstraints=function(){var d=this.m_bodyA,h=this.m_bodyB,l=d.m_sweep.c,j=d.m_sweep.a,o=h.m_sweep.c,q=h.m_sweep.a,n,a=0,c=0,g=0,b=0,e=n=0,f=0;c=false;
var m=0,r=G.FromAngle(j);g=G.FromAngle(q);n=r;f=this.m_localAnchor1.x-this.m_localCenterA.x;var s=this.m_localAnchor1.y-this.m_localCenterA.y;a=n.col1.x*f+n.col2.x*s;s=n.col1.y*f+n.col2.y*s;f=a;n=g;g=this.m_localAnchor2.x-this.m_localCenterB.x;b=this.m_localAnchor2.y-this.m_localCenterB.y;a=n.col1.x*g+n.col2.x*b;b=n.col1.y*g+n.col2.y*b;g=a;n=o.x+g-l.x-f;a=o.y+b-l.y-s;if(this.m_enableLimit){this.m_axis=y.MulMV(r,this.m_localXAxis1);this.m_a1=(n+f)*this.m_axis.y-(a+s)*this.m_axis.x;this.m_a2=g*this.m_axis.y-
b*this.m_axis.x;var v=this.m_axis.x*n+this.m_axis.y*a;if(y.Abs(this.m_upperTranslation-this.m_lowerTranslation)<2*F.b2_linearSlop){m=y.Clamp(v,-F.b2_maxLinearCorrection,F.b2_maxLinearCorrection);e=y.Abs(v);c=true}else if(v<=this.m_lowerTranslation){m=y.Clamp(v-this.m_lowerTranslation+F.b2_linearSlop,-F.b2_maxLinearCorrection,0);e=this.m_lowerTranslation-v;c=true}else if(v>=this.m_upperTranslation){m=y.Clamp(v-this.m_upperTranslation+F.b2_linearSlop,0,F.b2_maxLinearCorrection);e=v-this.m_upperTranslation;
c=true}}this.m_perp=y.MulMV(r,this.m_localYAxis1);this.m_s1=(n+f)*this.m_perp.y-(a+s)*this.m_perp.x;this.m_s2=g*this.m_perp.y-b*this.m_perp.x;r=new w;s=this.m_perp.x*n+this.m_perp.y*a;e=y.Max(e,y.Abs(s));f=0;if(c){c=this.m_invMassA;g=this.m_invMassB;b=this.m_invIA;n=this.m_invIB;this.m_K.col1.x=c+g+b*this.m_s1*this.m_s1+n*this.m_s2*this.m_s2;this.m_K.col1.y=b*this.m_s1*this.m_a1+n*this.m_s2*this.m_a2;this.m_K.col2.x=this.m_K.col1.y;this.m_K.col2.y=c+g+b*this.m_a1*this.m_a1+n*this.m_a2*this.m_a2;this.m_K.Solve(r,
-s,-m)}else{c=this.m_invMassA;g=this.m_invMassB;b=this.m_invIA;n=this.m_invIB;m=c+g+b*this.m_s1*this.m_s1+n*this.m_s2*this.m_s2;c=0;c=m!=0?-s/m:0;r.x=c;r.y=0}m=r.x*this.m_perp.x+r.y*this.m_axis.x;c=r.x*this.m_perp.y+r.y*this.m_axis.y;s=r.x*this.m_s1+r.y*this.m_a1;r=r.x*this.m_s2+r.y*this.m_a2;l.x-=this.m_invMassA*m;l.y-=this.m_invMassA*c;j-=this.m_invIA*s;o.x+=this.m_invMassB*m;o.y+=this.m_invMassB*c;q+=this.m_invIB*r;d.m_sweep.a=j;h.m_sweep.a=q;d.SynchronizeTransform();h.SynchronizeTransform();return e<=
F.b2_linearSlop&&f<=F.b2_angularSlop};Box2D.inherit(z,Box2D.Dynamics.Joints.b2JointDef);z.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;z.b2LineJointDef=function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,arguments);this.localAnchorA=new w;this.localAnchorB=new w;this.localAxisA=new w};z.prototype.b2LineJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_lineJoint;this.localAxisA.Set(1,0);this.enableLimit=false;this.upperTranslation=this.lowerTranslation=
0;this.enableMotor=false;this.motorSpeed=this.maxMotorForce=0};z.prototype.Initialize=function(d,h,l,j){this.bodyA=d;this.bodyB=h;this.localAnchorA=this.bodyA.GetLocalPoint(l);this.localAnchorB=this.bodyB.GetLocalPoint(l);this.localAxisA=this.bodyA.GetLocalVector(j)};Box2D.inherit(u,Box2D.Dynamics.Joints.b2Joint);u.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;u.b2MouseJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.K=new G;this.K1=new G;this.K2=new G;
this.m_localAnchor=new w;this.m_target=new w;this.m_impulse=new w;this.m_mass=new G;this.m_C=new w};u.prototype.GetAnchorA=function(){return this.m_target};u.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchor)};u.prototype.GetReactionForce=function(d){if(d===undefined)d=0;return new w(d*this.m_impulse.x,d*this.m_impulse.y)};u.prototype.GetReactionTorque=function(){return 0};u.prototype.GetTarget=function(){return this.m_target};u.prototype.SetTarget=function(d){this.m_bodyB.IsAwake()==
false&&this.m_bodyB.SetAwake(true);this.m_target=d};u.prototype.GetMaxForce=function(){return this.m_maxForce};u.prototype.SetMaxForce=function(d){if(d===undefined)d=0;this.m_maxForce=d};u.prototype.GetFrequency=function(){return this.m_frequencyHz};u.prototype.SetFrequency=function(d){if(d===undefined)d=0;this.m_frequencyHz=d};u.prototype.GetDampingRatio=function(){return this.m_dampingRatio};u.prototype.SetDampingRatio=function(d){if(d===undefined)d=0;this.m_dampingRatio=d};u.prototype.b2MouseJoint=
function(d){this.__super.b2Joint.call(this,d);this.m_target.SetV(d.target);var h=this.m_target.x-this.m_bodyB.m_xf.position.x,l=this.m_target.y-this.m_bodyB.m_xf.position.y,j=this.m_bodyB.m_xf.R;this.m_localAnchor.x=h*j.col1.x+l*j.col1.y;this.m_localAnchor.y=h*j.col2.x+l*j.col2.y;this.m_maxForce=d.maxForce;this.m_impulse.SetZero();this.m_frequencyHz=d.frequencyHz;this.m_dampingRatio=d.dampingRatio;this.m_gamma=this.m_beta=0};u.prototype.InitVelocityConstraints=function(d){var h=this.m_bodyB,l=h.GetMass(),
j=2*Math.PI*this.m_frequencyHz,o=l*j*j;this.m_gamma=d.dt*(2*l*this.m_dampingRatio*j+d.dt*o);this.m_gamma=this.m_gamma!=0?1/this.m_gamma:0;this.m_beta=d.dt*o*this.m_gamma;o=h.m_xf.R;l=this.m_localAnchor.x-h.m_sweep.localCenter.x;j=this.m_localAnchor.y-h.m_sweep.localCenter.y;var q=o.col1.x*l+o.col2.x*j;j=o.col1.y*l+o.col2.y*j;l=q;o=h.m_invMass;q=h.m_invI;this.K1.col1.x=o;this.K1.col2.x=0;this.K1.col1.y=0;this.K1.col2.y=o;this.K2.col1.x=q*j*j;this.K2.col2.x=-q*l*j;this.K2.col1.y=-q*l*j;this.K2.col2.y=
q*l*l;this.K.SetM(this.K1);this.K.AddM(this.K2);this.K.col1.x+=this.m_gamma;this.K.col2.y+=this.m_gamma;this.K.GetInverse(this.m_mass);this.m_C.x=h.m_sweep.c.x+l-this.m_target.x;this.m_C.y=h.m_sweep.c.y+j-this.m_target.y;h.m_angularVelocity*=0.98;this.m_impulse.x*=d.dtRatio;this.m_impulse.y*=d.dtRatio;h.m_linearVelocity.x+=o*this.m_impulse.x;h.m_linearVelocity.y+=o*this.m_impulse.y;h.m_angularVelocity+=q*(l*this.m_impulse.y-j*this.m_impulse.x)};u.prototype.SolveVelocityConstraints=function(d){var h=
this.m_bodyB,l,j=0,o=0;l=h.m_xf.R;var q=this.m_localAnchor.x-h.m_sweep.localCenter.x,n=this.m_localAnchor.y-h.m_sweep.localCenter.y;j=l.col1.x*q+l.col2.x*n;n=l.col1.y*q+l.col2.y*n;q=j;j=h.m_linearVelocity.x+-h.m_angularVelocity*n;var a=h.m_linearVelocity.y+h.m_angularVelocity*q;l=this.m_mass;j=j+this.m_beta*this.m_C.x+this.m_gamma*this.m_impulse.x;o=a+this.m_beta*this.m_C.y+this.m_gamma*this.m_impulse.y;a=-(l.col1.x*j+l.col2.x*o);o=-(l.col1.y*j+l.col2.y*o);l=this.m_impulse.x;j=this.m_impulse.y;this.m_impulse.x+=
a;this.m_impulse.y+=o;d=d.dt*this.m_maxForce;this.m_impulse.LengthSquared()>d*d&&this.m_impulse.Multiply(d/this.m_impulse.Length());a=this.m_impulse.x-l;o=this.m_impulse.y-j;h.m_linearVelocity.x+=h.m_invMass*a;h.m_linearVelocity.y+=h.m_invMass*o;h.m_angularVelocity+=h.m_invI*(q*o-n*a)};u.prototype.SolvePositionConstraints=function(){return true};Box2D.inherit(D,Box2D.Dynamics.Joints.b2JointDef);D.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;D.b2MouseJointDef=function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,
arguments);this.target=new w};D.prototype.b2MouseJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_mouseJoint;this.maxForce=0;this.frequencyHz=5;this.dampingRatio=0.7};Box2D.inherit(H,Box2D.Dynamics.Joints.b2Joint);H.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;H.b2PrismaticJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.m_localAnchor1=new w;this.m_localAnchor2=new w;this.m_localXAxis1=new w;this.m_localYAxis1=new w;this.m_axis=new w;
this.m_perp=new w;this.m_K=new K;this.m_impulse=new A};H.prototype.GetAnchorA=function(){return this.m_bodyA.GetWorldPoint(this.m_localAnchor1)};H.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchor2)};H.prototype.GetReactionForce=function(d){if(d===undefined)d=0;return new w(d*(this.m_impulse.x*this.m_perp.x+(this.m_motorImpulse+this.m_impulse.z)*this.m_axis.x),d*(this.m_impulse.x*this.m_perp.y+(this.m_motorImpulse+this.m_impulse.z)*this.m_axis.y))};H.prototype.GetReactionTorque=
function(d){if(d===undefined)d=0;return d*this.m_impulse.y};H.prototype.GetJointTranslation=function(){var d=this.m_bodyA,h=this.m_bodyB,l=d.GetWorldPoint(this.m_localAnchor1),j=h.GetWorldPoint(this.m_localAnchor2);h=j.x-l.x;l=j.y-l.y;d=d.GetWorldVector(this.m_localXAxis1);return d.x*h+d.y*l};H.prototype.GetJointSpeed=function(){var d=this.m_bodyA,h=this.m_bodyB,l;l=d.m_xf.R;var j=this.m_localAnchor1.x-d.m_sweep.localCenter.x,o=this.m_localAnchor1.y-d.m_sweep.localCenter.y,q=l.col1.x*j+l.col2.x*o;
o=l.col1.y*j+l.col2.y*o;j=q;l=h.m_xf.R;var n=this.m_localAnchor2.x-h.m_sweep.localCenter.x,a=this.m_localAnchor2.y-h.m_sweep.localCenter.y;q=l.col1.x*n+l.col2.x*a;a=l.col1.y*n+l.col2.y*a;n=q;l=h.m_sweep.c.x+n-(d.m_sweep.c.x+j);q=h.m_sweep.c.y+a-(d.m_sweep.c.y+o);var c=d.GetWorldVector(this.m_localXAxis1),g=d.m_linearVelocity,b=h.m_linearVelocity;d=d.m_angularVelocity;h=h.m_angularVelocity;return l*-d*c.y+q*d*c.x+(c.x*(b.x+-h*a-g.x- -d*o)+c.y*(b.y+h*n-g.y-d*j))};H.prototype.IsLimitEnabled=function(){return this.m_enableLimit};
H.prototype.EnableLimit=function(d){this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_enableLimit=d};H.prototype.GetLowerLimit=function(){return this.m_lowerTranslation};H.prototype.GetUpperLimit=function(){return this.m_upperTranslation};H.prototype.SetLimits=function(d,h){if(d===undefined)d=0;if(h===undefined)h=0;this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_lowerTranslation=d;this.m_upperTranslation=h};H.prototype.IsMotorEnabled=function(){return this.m_enableMotor};
H.prototype.EnableMotor=function(d){this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_enableMotor=d};H.prototype.SetMotorSpeed=function(d){if(d===undefined)d=0;this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_motorSpeed=d};H.prototype.GetMotorSpeed=function(){return this.m_motorSpeed};H.prototype.SetMaxMotorForce=function(d){if(d===undefined)d=0;this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_maxMotorForce=d};H.prototype.GetMotorForce=function(){return this.m_motorImpulse};
H.prototype.b2PrismaticJoint=function(d){this.__super.b2Joint.call(this,d);this.m_localAnchor1.SetV(d.localAnchorA);this.m_localAnchor2.SetV(d.localAnchorB);this.m_localXAxis1.SetV(d.localAxisA);this.m_localYAxis1.x=-this.m_localXAxis1.y;this.m_localYAxis1.y=this.m_localXAxis1.x;this.m_refAngle=d.referenceAngle;this.m_impulse.SetZero();this.m_motorImpulse=this.m_motorMass=0;this.m_lowerTranslation=d.lowerTranslation;this.m_upperTranslation=d.upperTranslation;this.m_maxMotorForce=d.maxMotorForce;this.m_motorSpeed=
d.motorSpeed;this.m_enableLimit=d.enableLimit;this.m_enableMotor=d.enableMotor;this.m_limitState=I.e_inactiveLimit;this.m_axis.SetZero();this.m_perp.SetZero()};H.prototype.InitVelocityConstraints=function(d){var h=this.m_bodyA,l=this.m_bodyB,j,o=0;this.m_localCenterA.SetV(h.GetLocalCenter());this.m_localCenterB.SetV(l.GetLocalCenter());var q=h.GetTransform();l.GetTransform();j=h.m_xf.R;var n=this.m_localAnchor1.x-this.m_localCenterA.x,a=this.m_localAnchor1.y-this.m_localCenterA.y;o=j.col1.x*n+j.col2.x*
a;a=j.col1.y*n+j.col2.y*a;n=o;j=l.m_xf.R;var c=this.m_localAnchor2.x-this.m_localCenterB.x,g=this.m_localAnchor2.y-this.m_localCenterB.y;o=j.col1.x*c+j.col2.x*g;g=j.col1.y*c+j.col2.y*g;c=o;j=l.m_sweep.c.x+c-h.m_sweep.c.x-n;o=l.m_sweep.c.y+g-h.m_sweep.c.y-a;this.m_invMassA=h.m_invMass;this.m_invMassB=l.m_invMass;this.m_invIA=h.m_invI;this.m_invIB=l.m_invI;this.m_axis.SetV(y.MulMV(q.R,this.m_localXAxis1));this.m_a1=(j+n)*this.m_axis.y-(o+a)*this.m_axis.x;this.m_a2=c*this.m_axis.y-g*this.m_axis.x;this.m_motorMass=
this.m_invMassA+this.m_invMassB+this.m_invIA*this.m_a1*this.m_a1+this.m_invIB*this.m_a2*this.m_a2;if(this.m_motorMass>Number.MIN_VALUE)this.m_motorMass=1/this.m_motorMass;this.m_perp.SetV(y.MulMV(q.R,this.m_localYAxis1));this.m_s1=(j+n)*this.m_perp.y-(o+a)*this.m_perp.x;this.m_s2=c*this.m_perp.y-g*this.m_perp.x;q=this.m_invMassA;n=this.m_invMassB;a=this.m_invIA;c=this.m_invIB;this.m_K.col1.x=q+n+a*this.m_s1*this.m_s1+c*this.m_s2*this.m_s2;this.m_K.col1.y=a*this.m_s1+c*this.m_s2;this.m_K.col1.z=a*
this.m_s1*this.m_a1+c*this.m_s2*this.m_a2;this.m_K.col2.x=this.m_K.col1.y;this.m_K.col2.y=a+c;this.m_K.col2.z=a*this.m_a1+c*this.m_a2;this.m_K.col3.x=this.m_K.col1.z;this.m_K.col3.y=this.m_K.col2.z;this.m_K.col3.z=q+n+a*this.m_a1*this.m_a1+c*this.m_a2*this.m_a2;if(this.m_enableLimit){j=this.m_axis.x*j+this.m_axis.y*o;if(y.Abs(this.m_upperTranslation-this.m_lowerTranslation)<2*F.b2_linearSlop)this.m_limitState=I.e_equalLimits;else if(j<=this.m_lowerTranslation){if(this.m_limitState!=I.e_atLowerLimit){this.m_limitState=
I.e_atLowerLimit;this.m_impulse.z=0}}else if(j>=this.m_upperTranslation){if(this.m_limitState!=I.e_atUpperLimit){this.m_limitState=I.e_atUpperLimit;this.m_impulse.z=0}}else{this.m_limitState=I.e_inactiveLimit;this.m_impulse.z=0}}else this.m_limitState=I.e_inactiveLimit;if(this.m_enableMotor==false)this.m_motorImpulse=0;if(d.warmStarting){this.m_impulse.x*=d.dtRatio;this.m_impulse.y*=d.dtRatio;this.m_motorImpulse*=d.dtRatio;d=this.m_impulse.x*this.m_perp.x+(this.m_motorImpulse+this.m_impulse.z)*this.m_axis.x;
j=this.m_impulse.x*this.m_perp.y+(this.m_motorImpulse+this.m_impulse.z)*this.m_axis.y;o=this.m_impulse.x*this.m_s1+this.m_impulse.y+(this.m_motorImpulse+this.m_impulse.z)*this.m_a1;q=this.m_impulse.x*this.m_s2+this.m_impulse.y+(this.m_motorImpulse+this.m_impulse.z)*this.m_a2;h.m_linearVelocity.x-=this.m_invMassA*d;h.m_linearVelocity.y-=this.m_invMassA*j;h.m_angularVelocity-=this.m_invIA*o;l.m_linearVelocity.x+=this.m_invMassB*d;l.m_linearVelocity.y+=this.m_invMassB*j;l.m_angularVelocity+=this.m_invIB*
q}else{this.m_impulse.SetZero();this.m_motorImpulse=0}};H.prototype.SolveVelocityConstraints=function(d){var h=this.m_bodyA,l=this.m_bodyB,j=h.m_linearVelocity,o=h.m_angularVelocity,q=l.m_linearVelocity,n=l.m_angularVelocity,a=0,c=0,g=0,b=0;if(this.m_enableMotor&&this.m_limitState!=I.e_equalLimits){b=this.m_motorMass*(this.m_motorSpeed-(this.m_axis.x*(q.x-j.x)+this.m_axis.y*(q.y-j.y)+this.m_a2*n-this.m_a1*o));a=this.m_motorImpulse;d=d.dt*this.m_maxMotorForce;this.m_motorImpulse=y.Clamp(this.m_motorImpulse+
b,-d,d);b=this.m_motorImpulse-a;a=b*this.m_axis.x;c=b*this.m_axis.y;g=b*this.m_a1;b=b*this.m_a2;j.x-=this.m_invMassA*a;j.y-=this.m_invMassA*c;o-=this.m_invIA*g;q.x+=this.m_invMassB*a;q.y+=this.m_invMassB*c;n+=this.m_invIB*b}g=this.m_perp.x*(q.x-j.x)+this.m_perp.y*(q.y-j.y)+this.m_s2*n-this.m_s1*o;c=n-o;if(this.m_enableLimit&&this.m_limitState!=I.e_inactiveLimit){d=this.m_axis.x*(q.x-j.x)+this.m_axis.y*(q.y-j.y)+this.m_a2*n-this.m_a1*o;a=this.m_impulse.Copy();d=this.m_K.Solve33(new A,-g,-c,-d);this.m_impulse.Add(d);
if(this.m_limitState==I.e_atLowerLimit)this.m_impulse.z=y.Max(this.m_impulse.z,0);else if(this.m_limitState==I.e_atUpperLimit)this.m_impulse.z=y.Min(this.m_impulse.z,0);g=-g-(this.m_impulse.z-a.z)*this.m_K.col3.x;c=-c-(this.m_impulse.z-a.z)*this.m_K.col3.y;c=this.m_K.Solve22(new w,g,c);c.x+=a.x;c.y+=a.y;this.m_impulse.x=c.x;this.m_impulse.y=c.y;d.x=this.m_impulse.x-a.x;d.y=this.m_impulse.y-a.y;d.z=this.m_impulse.z-a.z;a=d.x*this.m_perp.x+d.z*this.m_axis.x;c=d.x*this.m_perp.y+d.z*this.m_axis.y;g=d.x*
this.m_s1+d.y+d.z*this.m_a1;b=d.x*this.m_s2+d.y+d.z*this.m_a2}else{d=this.m_K.Solve22(new w,-g,-c);this.m_impulse.x+=d.x;this.m_impulse.y+=d.y;a=d.x*this.m_perp.x;c=d.x*this.m_perp.y;g=d.x*this.m_s1+d.y;b=d.x*this.m_s2+d.y}j.x-=this.m_invMassA*a;j.y-=this.m_invMassA*c;o-=this.m_invIA*g;q.x+=this.m_invMassB*a;q.y+=this.m_invMassB*c;n+=this.m_invIB*b;h.m_linearVelocity.SetV(j);h.m_angularVelocity=o;l.m_linearVelocity.SetV(q);l.m_angularVelocity=n};H.prototype.SolvePositionConstraints=function(){var d=
this.m_bodyA,h=this.m_bodyB,l=d.m_sweep.c,j=d.m_sweep.a,o=h.m_sweep.c,q=h.m_sweep.a,n,a=0,c=0,g=0,b=a=n=0,e=0;c=false;var f=0,m=G.FromAngle(j),r=G.FromAngle(q);n=m;e=this.m_localAnchor1.x-this.m_localCenterA.x;var s=this.m_localAnchor1.y-this.m_localCenterA.y;a=n.col1.x*e+n.col2.x*s;s=n.col1.y*e+n.col2.y*s;e=a;n=r;r=this.m_localAnchor2.x-this.m_localCenterB.x;g=this.m_localAnchor2.y-this.m_localCenterB.y;a=n.col1.x*r+n.col2.x*g;g=n.col1.y*r+n.col2.y*g;r=a;n=o.x+r-l.x-e;a=o.y+g-l.y-s;if(this.m_enableLimit){this.m_axis=
y.MulMV(m,this.m_localXAxis1);this.m_a1=(n+e)*this.m_axis.y-(a+s)*this.m_axis.x;this.m_a2=r*this.m_axis.y-g*this.m_axis.x;var v=this.m_axis.x*n+this.m_axis.y*a;if(y.Abs(this.m_upperTranslation-this.m_lowerTranslation)<2*F.b2_linearSlop){f=y.Clamp(v,-F.b2_maxLinearCorrection,F.b2_maxLinearCorrection);b=y.Abs(v);c=true}else if(v<=this.m_lowerTranslation){f=y.Clamp(v-this.m_lowerTranslation+F.b2_linearSlop,-F.b2_maxLinearCorrection,0);b=this.m_lowerTranslation-v;c=true}else if(v>=this.m_upperTranslation){f=
y.Clamp(v-this.m_upperTranslation+F.b2_linearSlop,0,F.b2_maxLinearCorrection);b=v-this.m_upperTranslation;c=true}}this.m_perp=y.MulMV(m,this.m_localYAxis1);this.m_s1=(n+e)*this.m_perp.y-(a+s)*this.m_perp.x;this.m_s2=r*this.m_perp.y-g*this.m_perp.x;m=new A;s=this.m_perp.x*n+this.m_perp.y*a;r=q-j-this.m_refAngle;b=y.Max(b,y.Abs(s));e=y.Abs(r);if(c){c=this.m_invMassA;g=this.m_invMassB;n=this.m_invIA;a=this.m_invIB;this.m_K.col1.x=c+g+n*this.m_s1*this.m_s1+a*this.m_s2*this.m_s2;this.m_K.col1.y=n*this.m_s1+
a*this.m_s2;this.m_K.col1.z=n*this.m_s1*this.m_a1+a*this.m_s2*this.m_a2;this.m_K.col2.x=this.m_K.col1.y;this.m_K.col2.y=n+a;this.m_K.col2.z=n*this.m_a1+a*this.m_a2;this.m_K.col3.x=this.m_K.col1.z;this.m_K.col3.y=this.m_K.col2.z;this.m_K.col3.z=c+g+n*this.m_a1*this.m_a1+a*this.m_a2*this.m_a2;this.m_K.Solve33(m,-s,-r,-f)}else{c=this.m_invMassA;g=this.m_invMassB;n=this.m_invIA;a=this.m_invIB;f=n*this.m_s1+a*this.m_s2;v=n+a;this.m_K.col1.Set(c+g+n*this.m_s1*this.m_s1+a*this.m_s2*this.m_s2,f,0);this.m_K.col2.Set(f,
v,0);f=this.m_K.Solve22(new w,-s,-r);m.x=f.x;m.y=f.y;m.z=0}f=m.x*this.m_perp.x+m.z*this.m_axis.x;c=m.x*this.m_perp.y+m.z*this.m_axis.y;s=m.x*this.m_s1+m.y+m.z*this.m_a1;m=m.x*this.m_s2+m.y+m.z*this.m_a2;l.x-=this.m_invMassA*f;l.y-=this.m_invMassA*c;j-=this.m_invIA*s;o.x+=this.m_invMassB*f;o.y+=this.m_invMassB*c;q+=this.m_invIB*m;d.m_sweep.a=j;h.m_sweep.a=q;d.SynchronizeTransform();h.SynchronizeTransform();return b<=F.b2_linearSlop&&e<=F.b2_angularSlop};Box2D.inherit(O,Box2D.Dynamics.Joints.b2JointDef);
O.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;O.b2PrismaticJointDef=function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,arguments);this.localAnchorA=new w;this.localAnchorB=new w;this.localAxisA=new w};O.prototype.b2PrismaticJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_prismaticJoint;this.localAxisA.Set(1,0);this.referenceAngle=0;this.enableLimit=false;this.upperTranslation=this.lowerTranslation=0;this.enableMotor=false;this.motorSpeed=this.maxMotorForce=
0};O.prototype.Initialize=function(d,h,l,j){this.bodyA=d;this.bodyB=h;this.localAnchorA=this.bodyA.GetLocalPoint(l);this.localAnchorB=this.bodyB.GetLocalPoint(l);this.localAxisA=this.bodyA.GetLocalVector(j);this.referenceAngle=this.bodyB.GetAngle()-this.bodyA.GetAngle()};Box2D.inherit(E,Box2D.Dynamics.Joints.b2Joint);E.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;E.b2PulleyJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.m_groundAnchor1=new w;this.m_groundAnchor2=
new w;this.m_localAnchor1=new w;this.m_localAnchor2=new w;this.m_u1=new w;this.m_u2=new w};E.prototype.GetAnchorA=function(){return this.m_bodyA.GetWorldPoint(this.m_localAnchor1)};E.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchor2)};E.prototype.GetReactionForce=function(d){if(d===undefined)d=0;return new w(d*this.m_impulse*this.m_u2.x,d*this.m_impulse*this.m_u2.y)};E.prototype.GetReactionTorque=function(){return 0};E.prototype.GetGroundAnchorA=function(){var d=
this.m_ground.m_xf.position.Copy();d.Add(this.m_groundAnchor1);return d};E.prototype.GetGroundAnchorB=function(){var d=this.m_ground.m_xf.position.Copy();d.Add(this.m_groundAnchor2);return d};E.prototype.GetLength1=function(){var d=this.m_bodyA.GetWorldPoint(this.m_localAnchor1),h=d.x-(this.m_ground.m_xf.position.x+this.m_groundAnchor1.x);d=d.y-(this.m_ground.m_xf.position.y+this.m_groundAnchor1.y);return Math.sqrt(h*h+d*d)};E.prototype.GetLength2=function(){var d=this.m_bodyB.GetWorldPoint(this.m_localAnchor2),
h=d.x-(this.m_ground.m_xf.position.x+this.m_groundAnchor2.x);d=d.y-(this.m_ground.m_xf.position.y+this.m_groundAnchor2.y);return Math.sqrt(h*h+d*d)};E.prototype.GetRatio=function(){return this.m_ratio};E.prototype.b2PulleyJoint=function(d){this.__super.b2Joint.call(this,d);this.m_ground=this.m_bodyA.m_world.m_groundBody;this.m_groundAnchor1.x=d.groundAnchorA.x-this.m_ground.m_xf.position.x;this.m_groundAnchor1.y=d.groundAnchorA.y-this.m_ground.m_xf.position.y;this.m_groundAnchor2.x=d.groundAnchorB.x-
this.m_ground.m_xf.position.x;this.m_groundAnchor2.y=d.groundAnchorB.y-this.m_ground.m_xf.position.y;this.m_localAnchor1.SetV(d.localAnchorA);this.m_localAnchor2.SetV(d.localAnchorB);this.m_ratio=d.ratio;this.m_constant=d.lengthA+this.m_ratio*d.lengthB;this.m_maxLength1=y.Min(d.maxLengthA,this.m_constant-this.m_ratio*E.b2_minPulleyLength);this.m_maxLength2=y.Min(d.maxLengthB,(this.m_constant-E.b2_minPulleyLength)/this.m_ratio);this.m_limitImpulse2=this.m_limitImpulse1=this.m_impulse=0};E.prototype.InitVelocityConstraints=
function(d){var h=this.m_bodyA,l=this.m_bodyB,j;j=h.m_xf.R;var o=this.m_localAnchor1.x-h.m_sweep.localCenter.x,q=this.m_localAnchor1.y-h.m_sweep.localCenter.y,n=j.col1.x*o+j.col2.x*q;q=j.col1.y*o+j.col2.y*q;o=n;j=l.m_xf.R;var a=this.m_localAnchor2.x-l.m_sweep.localCenter.x,c=this.m_localAnchor2.y-l.m_sweep.localCenter.y;n=j.col1.x*a+j.col2.x*c;c=j.col1.y*a+j.col2.y*c;a=n;j=l.m_sweep.c.x+a;n=l.m_sweep.c.y+c;var g=this.m_ground.m_xf.position.x+this.m_groundAnchor2.x,b=this.m_ground.m_xf.position.y+
this.m_groundAnchor2.y;this.m_u1.Set(h.m_sweep.c.x+o-(this.m_ground.m_xf.position.x+this.m_groundAnchor1.x),h.m_sweep.c.y+q-(this.m_ground.m_xf.position.y+this.m_groundAnchor1.y));this.m_u2.Set(j-g,n-b);j=this.m_u1.Length();n=this.m_u2.Length();j>F.b2_linearSlop?this.m_u1.Multiply(1/j):this.m_u1.SetZero();n>F.b2_linearSlop?this.m_u2.Multiply(1/n):this.m_u2.SetZero();if(this.m_constant-j-this.m_ratio*n>0){this.m_state=I.e_inactiveLimit;this.m_impulse=0}else this.m_state=I.e_atUpperLimit;if(j<this.m_maxLength1){this.m_limitState1=
I.e_inactiveLimit;this.m_limitImpulse1=0}else this.m_limitState1=I.e_atUpperLimit;if(n<this.m_maxLength2){this.m_limitState2=I.e_inactiveLimit;this.m_limitImpulse2=0}else this.m_limitState2=I.e_atUpperLimit;j=o*this.m_u1.y-q*this.m_u1.x;n=a*this.m_u2.y-c*this.m_u2.x;this.m_limitMass1=h.m_invMass+h.m_invI*j*j;this.m_limitMass2=l.m_invMass+l.m_invI*n*n;this.m_pulleyMass=this.m_limitMass1+this.m_ratio*this.m_ratio*this.m_limitMass2;this.m_limitMass1=1/this.m_limitMass1;this.m_limitMass2=1/this.m_limitMass2;
this.m_pulleyMass=1/this.m_pulleyMass;if(d.warmStarting){this.m_impulse*=d.dtRatio;this.m_limitImpulse1*=d.dtRatio;this.m_limitImpulse2*=d.dtRatio;d=(-this.m_impulse-this.m_limitImpulse1)*this.m_u1.x;j=(-this.m_impulse-this.m_limitImpulse1)*this.m_u1.y;n=(-this.m_ratio*this.m_impulse-this.m_limitImpulse2)*this.m_u2.x;g=(-this.m_ratio*this.m_impulse-this.m_limitImpulse2)*this.m_u2.y;h.m_linearVelocity.x+=h.m_invMass*d;h.m_linearVelocity.y+=h.m_invMass*j;h.m_angularVelocity+=h.m_invI*(o*j-q*d);l.m_linearVelocity.x+=
l.m_invMass*n;l.m_linearVelocity.y+=l.m_invMass*g;l.m_angularVelocity+=l.m_invI*(a*g-c*n)}else this.m_limitImpulse2=this.m_limitImpulse1=this.m_impulse=0};E.prototype.SolveVelocityConstraints=function(){var d=this.m_bodyA,h=this.m_bodyB,l;l=d.m_xf.R;var j=this.m_localAnchor1.x-d.m_sweep.localCenter.x,o=this.m_localAnchor1.y-d.m_sweep.localCenter.y,q=l.col1.x*j+l.col2.x*o;o=l.col1.y*j+l.col2.y*o;j=q;l=h.m_xf.R;var n=this.m_localAnchor2.x-h.m_sweep.localCenter.x,a=this.m_localAnchor2.y-h.m_sweep.localCenter.y;
q=l.col1.x*n+l.col2.x*a;a=l.col1.y*n+l.col2.y*a;n=q;var c=q=l=0,g=0;l=g=l=g=c=q=l=0;if(this.m_state==I.e_atUpperLimit){l=d.m_linearVelocity.x+-d.m_angularVelocity*o;q=d.m_linearVelocity.y+d.m_angularVelocity*j;c=h.m_linearVelocity.x+-h.m_angularVelocity*a;g=h.m_linearVelocity.y+h.m_angularVelocity*n;l=-(this.m_u1.x*l+this.m_u1.y*q)-this.m_ratio*(this.m_u2.x*c+this.m_u2.y*g);g=this.m_pulleyMass*-l;l=this.m_impulse;this.m_impulse=y.Max(0,this.m_impulse+g);g=this.m_impulse-l;l=-g*this.m_u1.x;q=-g*this.m_u1.y;
c=-this.m_ratio*g*this.m_u2.x;g=-this.m_ratio*g*this.m_u2.y;d.m_linearVelocity.x+=d.m_invMass*l;d.m_linearVelocity.y+=d.m_invMass*q;d.m_angularVelocity+=d.m_invI*(j*q-o*l);h.m_linearVelocity.x+=h.m_invMass*c;h.m_linearVelocity.y+=h.m_invMass*g;h.m_angularVelocity+=h.m_invI*(n*g-a*c)}if(this.m_limitState1==I.e_atUpperLimit){l=d.m_linearVelocity.x+-d.m_angularVelocity*o;q=d.m_linearVelocity.y+d.m_angularVelocity*j;l=-(this.m_u1.x*l+this.m_u1.y*q);g=-this.m_limitMass1*l;l=this.m_limitImpulse1;this.m_limitImpulse1=
y.Max(0,this.m_limitImpulse1+g);g=this.m_limitImpulse1-l;l=-g*this.m_u1.x;q=-g*this.m_u1.y;d.m_linearVelocity.x+=d.m_invMass*l;d.m_linearVelocity.y+=d.m_invMass*q;d.m_angularVelocity+=d.m_invI*(j*q-o*l)}if(this.m_limitState2==I.e_atUpperLimit){c=h.m_linearVelocity.x+-h.m_angularVelocity*a;g=h.m_linearVelocity.y+h.m_angularVelocity*n;l=-(this.m_u2.x*c+this.m_u2.y*g);g=-this.m_limitMass2*l;l=this.m_limitImpulse2;this.m_limitImpulse2=y.Max(0,this.m_limitImpulse2+g);g=this.m_limitImpulse2-l;c=-g*this.m_u2.x;
g=-g*this.m_u2.y;h.m_linearVelocity.x+=h.m_invMass*c;h.m_linearVelocity.y+=h.m_invMass*g;h.m_angularVelocity+=h.m_invI*(n*g-a*c)}};E.prototype.SolvePositionConstraints=function(){var d=this.m_bodyA,h=this.m_bodyB,l,j=this.m_ground.m_xf.position.x+this.m_groundAnchor1.x,o=this.m_ground.m_xf.position.y+this.m_groundAnchor1.y,q=this.m_ground.m_xf.position.x+this.m_groundAnchor2.x,n=this.m_ground.m_xf.position.y+this.m_groundAnchor2.y,a=0,c=0,g=0,b=0,e=l=0,f=0,m=0,r=e=m=l=e=l=0;if(this.m_state==I.e_atUpperLimit){l=
d.m_xf.R;a=this.m_localAnchor1.x-d.m_sweep.localCenter.x;c=this.m_localAnchor1.y-d.m_sweep.localCenter.y;e=l.col1.x*a+l.col2.x*c;c=l.col1.y*a+l.col2.y*c;a=e;l=h.m_xf.R;g=this.m_localAnchor2.x-h.m_sweep.localCenter.x;b=this.m_localAnchor2.y-h.m_sweep.localCenter.y;e=l.col1.x*g+l.col2.x*b;b=l.col1.y*g+l.col2.y*b;g=e;l=d.m_sweep.c.x+a;e=d.m_sweep.c.y+c;f=h.m_sweep.c.x+g;m=h.m_sweep.c.y+b;this.m_u1.Set(l-j,e-o);this.m_u2.Set(f-q,m-n);l=this.m_u1.Length();e=this.m_u2.Length();l>F.b2_linearSlop?this.m_u1.Multiply(1/
l):this.m_u1.SetZero();e>F.b2_linearSlop?this.m_u2.Multiply(1/e):this.m_u2.SetZero();l=this.m_constant-l-this.m_ratio*e;r=y.Max(r,-l);l=y.Clamp(l+F.b2_linearSlop,-F.b2_maxLinearCorrection,0);m=-this.m_pulleyMass*l;l=-m*this.m_u1.x;e=-m*this.m_u1.y;f=-this.m_ratio*m*this.m_u2.x;m=-this.m_ratio*m*this.m_u2.y;d.m_sweep.c.x+=d.m_invMass*l;d.m_sweep.c.y+=d.m_invMass*e;d.m_sweep.a+=d.m_invI*(a*e-c*l);h.m_sweep.c.x+=h.m_invMass*f;h.m_sweep.c.y+=h.m_invMass*m;h.m_sweep.a+=h.m_invI*(g*m-b*f);d.SynchronizeTransform();
h.SynchronizeTransform()}if(this.m_limitState1==I.e_atUpperLimit){l=d.m_xf.R;a=this.m_localAnchor1.x-d.m_sweep.localCenter.x;c=this.m_localAnchor1.y-d.m_sweep.localCenter.y;e=l.col1.x*a+l.col2.x*c;c=l.col1.y*a+l.col2.y*c;a=e;l=d.m_sweep.c.x+a;e=d.m_sweep.c.y+c;this.m_u1.Set(l-j,e-o);l=this.m_u1.Length();if(l>F.b2_linearSlop){this.m_u1.x*=1/l;this.m_u1.y*=1/l}else this.m_u1.SetZero();l=this.m_maxLength1-l;r=y.Max(r,-l);l=y.Clamp(l+F.b2_linearSlop,-F.b2_maxLinearCorrection,0);m=-this.m_limitMass1*l;
l=-m*this.m_u1.x;e=-m*this.m_u1.y;d.m_sweep.c.x+=d.m_invMass*l;d.m_sweep.c.y+=d.m_invMass*e;d.m_sweep.a+=d.m_invI*(a*e-c*l);d.SynchronizeTransform()}if(this.m_limitState2==I.e_atUpperLimit){l=h.m_xf.R;g=this.m_localAnchor2.x-h.m_sweep.localCenter.x;b=this.m_localAnchor2.y-h.m_sweep.localCenter.y;e=l.col1.x*g+l.col2.x*b;b=l.col1.y*g+l.col2.y*b;g=e;f=h.m_sweep.c.x+g;m=h.m_sweep.c.y+b;this.m_u2.Set(f-q,m-n);e=this.m_u2.Length();if(e>F.b2_linearSlop){this.m_u2.x*=1/e;this.m_u2.y*=1/e}else this.m_u2.SetZero();
l=this.m_maxLength2-e;r=y.Max(r,-l);l=y.Clamp(l+F.b2_linearSlop,-F.b2_maxLinearCorrection,0);m=-this.m_limitMass2*l;f=-m*this.m_u2.x;m=-m*this.m_u2.y;h.m_sweep.c.x+=h.m_invMass*f;h.m_sweep.c.y+=h.m_invMass*m;h.m_sweep.a+=h.m_invI*(g*m-b*f);h.SynchronizeTransform()}return r<F.b2_linearSlop};Box2D.postDefs.push(function(){Box2D.Dynamics.Joints.b2PulleyJoint.b2_minPulleyLength=2});Box2D.inherit(R,Box2D.Dynamics.Joints.b2JointDef);R.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;R.b2PulleyJointDef=
function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,arguments);this.groundAnchorA=new w;this.groundAnchorB=new w;this.localAnchorA=new w;this.localAnchorB=new w};R.prototype.b2PulleyJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_pulleyJoint;this.groundAnchorA.Set(-1,1);this.groundAnchorB.Set(1,1);this.localAnchorA.Set(-1,0);this.localAnchorB.Set(1,0);this.maxLengthB=this.lengthB=this.maxLengthA=this.lengthA=0;this.ratio=1;this.collideConnected=true};R.prototype.Initialize=
function(d,h,l,j,o,q,n){if(n===undefined)n=0;this.bodyA=d;this.bodyB=h;this.groundAnchorA.SetV(l);this.groundAnchorB.SetV(j);this.localAnchorA=this.bodyA.GetLocalPoint(o);this.localAnchorB=this.bodyB.GetLocalPoint(q);d=o.x-l.x;l=o.y-l.y;this.lengthA=Math.sqrt(d*d+l*l);l=q.x-j.x;j=q.y-j.y;this.lengthB=Math.sqrt(l*l+j*j);this.ratio=n;n=this.lengthA+this.ratio*this.lengthB;this.maxLengthA=n-this.ratio*E.b2_minPulleyLength;this.maxLengthB=(n-E.b2_minPulleyLength)/this.ratio};Box2D.inherit(N,Box2D.Dynamics.Joints.b2Joint);
N.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;N.b2RevoluteJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.K=new G;this.K1=new G;this.K2=new G;this.K3=new G;this.impulse3=new A;this.impulse2=new w;this.reduced=new w;this.m_localAnchor1=new w;this.m_localAnchor2=new w;this.m_impulse=new A;this.m_mass=new K};N.prototype.GetAnchorA=function(){return this.m_bodyA.GetWorldPoint(this.m_localAnchor1)};N.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchor2)};
N.prototype.GetReactionForce=function(d){if(d===undefined)d=0;return new w(d*this.m_impulse.x,d*this.m_impulse.y)};N.prototype.GetReactionTorque=function(d){if(d===undefined)d=0;return d*this.m_impulse.z};N.prototype.GetJointAngle=function(){return this.m_bodyB.m_sweep.a-this.m_bodyA.m_sweep.a-this.m_referenceAngle};N.prototype.GetJointSpeed=function(){return this.m_bodyB.m_angularVelocity-this.m_bodyA.m_angularVelocity};N.prototype.IsLimitEnabled=function(){return this.m_enableLimit};N.prototype.EnableLimit=
function(d){this.m_enableLimit=d};N.prototype.GetLowerLimit=function(){return this.m_lowerAngle};N.prototype.GetUpperLimit=function(){return this.m_upperAngle};N.prototype.SetLimits=function(d,h){if(d===undefined)d=0;if(h===undefined)h=0;this.m_lowerAngle=d;this.m_upperAngle=h};N.prototype.IsMotorEnabled=function(){this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);return this.m_enableMotor};N.prototype.EnableMotor=function(d){this.m_enableMotor=d};N.prototype.SetMotorSpeed=function(d){if(d===
undefined)d=0;this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_motorSpeed=d};N.prototype.GetMotorSpeed=function(){return this.m_motorSpeed};N.prototype.SetMaxMotorTorque=function(d){if(d===undefined)d=0;this.m_maxMotorTorque=d};N.prototype.GetMotorTorque=function(){return this.m_maxMotorTorque};N.prototype.b2RevoluteJoint=function(d){this.__super.b2Joint.call(this,d);this.m_localAnchor1.SetV(d.localAnchorA);this.m_localAnchor2.SetV(d.localAnchorB);this.m_referenceAngle=d.referenceAngle;
this.m_impulse.SetZero();this.m_motorImpulse=0;this.m_lowerAngle=d.lowerAngle;this.m_upperAngle=d.upperAngle;this.m_maxMotorTorque=d.maxMotorTorque;this.m_motorSpeed=d.motorSpeed;this.m_enableLimit=d.enableLimit;this.m_enableMotor=d.enableMotor;this.m_limitState=I.e_inactiveLimit};N.prototype.InitVelocityConstraints=function(d){var h=this.m_bodyA,l=this.m_bodyB,j,o=0;j=h.m_xf.R;var q=this.m_localAnchor1.x-h.m_sweep.localCenter.x,n=this.m_localAnchor1.y-h.m_sweep.localCenter.y;o=j.col1.x*q+j.col2.x*
n;n=j.col1.y*q+j.col2.y*n;q=o;j=l.m_xf.R;var a=this.m_localAnchor2.x-l.m_sweep.localCenter.x,c=this.m_localAnchor2.y-l.m_sweep.localCenter.y;o=j.col1.x*a+j.col2.x*c;c=j.col1.y*a+j.col2.y*c;a=o;j=h.m_invMass;o=l.m_invMass;var g=h.m_invI,b=l.m_invI;this.m_mass.col1.x=j+o+n*n*g+c*c*b;this.m_mass.col2.x=-n*q*g-c*a*b;this.m_mass.col3.x=-n*g-c*b;this.m_mass.col1.y=this.m_mass.col2.x;this.m_mass.col2.y=j+o+q*q*g+a*a*b;this.m_mass.col3.y=q*g+a*b;this.m_mass.col1.z=this.m_mass.col3.x;this.m_mass.col2.z=this.m_mass.col3.y;
this.m_mass.col3.z=g+b;this.m_motorMass=1/(g+b);if(this.m_enableMotor==false)this.m_motorImpulse=0;if(this.m_enableLimit){var e=l.m_sweep.a-h.m_sweep.a-this.m_referenceAngle;if(y.Abs(this.m_upperAngle-this.m_lowerAngle)<2*F.b2_angularSlop)this.m_limitState=I.e_equalLimits;else if(e<=this.m_lowerAngle){if(this.m_limitState!=I.e_atLowerLimit)this.m_impulse.z=0;this.m_limitState=I.e_atLowerLimit}else if(e>=this.m_upperAngle){if(this.m_limitState!=I.e_atUpperLimit)this.m_impulse.z=0;this.m_limitState=
I.e_atUpperLimit}else{this.m_limitState=I.e_inactiveLimit;this.m_impulse.z=0}}else this.m_limitState=I.e_inactiveLimit;if(d.warmStarting){this.m_impulse.x*=d.dtRatio;this.m_impulse.y*=d.dtRatio;this.m_motorImpulse*=d.dtRatio;d=this.m_impulse.x;e=this.m_impulse.y;h.m_linearVelocity.x-=j*d;h.m_linearVelocity.y-=j*e;h.m_angularVelocity-=g*(q*e-n*d+this.m_motorImpulse+this.m_impulse.z);l.m_linearVelocity.x+=o*d;l.m_linearVelocity.y+=o*e;l.m_angularVelocity+=b*(a*e-c*d+this.m_motorImpulse+this.m_impulse.z)}else{this.m_impulse.SetZero();
this.m_motorImpulse=0}};N.prototype.SolveVelocityConstraints=function(d){var h=this.m_bodyA,l=this.m_bodyB,j=0,o=j=0,q=0,n=0,a=0,c=h.m_linearVelocity,g=h.m_angularVelocity,b=l.m_linearVelocity,e=l.m_angularVelocity,f=h.m_invMass,m=l.m_invMass,r=h.m_invI,s=l.m_invI;if(this.m_enableMotor&&this.m_limitState!=I.e_equalLimits){o=this.m_motorMass*-(e-g-this.m_motorSpeed);q=this.m_motorImpulse;n=d.dt*this.m_maxMotorTorque;this.m_motorImpulse=y.Clamp(this.m_motorImpulse+o,-n,n);o=this.m_motorImpulse-q;g-=
r*o;e+=s*o}if(this.m_enableLimit&&this.m_limitState!=I.e_inactiveLimit){d=h.m_xf.R;o=this.m_localAnchor1.x-h.m_sweep.localCenter.x;q=this.m_localAnchor1.y-h.m_sweep.localCenter.y;j=d.col1.x*o+d.col2.x*q;q=d.col1.y*o+d.col2.y*q;o=j;d=l.m_xf.R;n=this.m_localAnchor2.x-l.m_sweep.localCenter.x;a=this.m_localAnchor2.y-l.m_sweep.localCenter.y;j=d.col1.x*n+d.col2.x*a;a=d.col1.y*n+d.col2.y*a;n=j;d=b.x+-e*a-c.x- -g*q;var v=b.y+e*n-c.y-g*o;this.m_mass.Solve33(this.impulse3,-d,-v,-(e-g));if(this.m_limitState==
I.e_equalLimits)this.m_impulse.Add(this.impulse3);else if(this.m_limitState==I.e_atLowerLimit){j=this.m_impulse.z+this.impulse3.z;if(j<0){this.m_mass.Solve22(this.reduced,-d,-v);this.impulse3.x=this.reduced.x;this.impulse3.y=this.reduced.y;this.impulse3.z=-this.m_impulse.z;this.m_impulse.x+=this.reduced.x;this.m_impulse.y+=this.reduced.y;this.m_impulse.z=0}}else if(this.m_limitState==I.e_atUpperLimit){j=this.m_impulse.z+this.impulse3.z;if(j>0){this.m_mass.Solve22(this.reduced,-d,-v);this.impulse3.x=
this.reduced.x;this.impulse3.y=this.reduced.y;this.impulse3.z=-this.m_impulse.z;this.m_impulse.x+=this.reduced.x;this.m_impulse.y+=this.reduced.y;this.m_impulse.z=0}}c.x-=f*this.impulse3.x;c.y-=f*this.impulse3.y;g-=r*(o*this.impulse3.y-q*this.impulse3.x+this.impulse3.z);b.x+=m*this.impulse3.x;b.y+=m*this.impulse3.y;e+=s*(n*this.impulse3.y-a*this.impulse3.x+this.impulse3.z)}else{d=h.m_xf.R;o=this.m_localAnchor1.x-h.m_sweep.localCenter.x;q=this.m_localAnchor1.y-h.m_sweep.localCenter.y;j=d.col1.x*o+
d.col2.x*q;q=d.col1.y*o+d.col2.y*q;o=j;d=l.m_xf.R;n=this.m_localAnchor2.x-l.m_sweep.localCenter.x;a=this.m_localAnchor2.y-l.m_sweep.localCenter.y;j=d.col1.x*n+d.col2.x*a;a=d.col1.y*n+d.col2.y*a;n=j;this.m_mass.Solve22(this.impulse2,-(b.x+-e*a-c.x- -g*q),-(b.y+e*n-c.y-g*o));this.m_impulse.x+=this.impulse2.x;this.m_impulse.y+=this.impulse2.y;c.x-=f*this.impulse2.x;c.y-=f*this.impulse2.y;g-=r*(o*this.impulse2.y-q*this.impulse2.x);b.x+=m*this.impulse2.x;b.y+=m*this.impulse2.y;e+=s*(n*this.impulse2.y-
a*this.impulse2.x)}h.m_linearVelocity.SetV(c);h.m_angularVelocity=g;l.m_linearVelocity.SetV(b);l.m_angularVelocity=e};N.prototype.SolvePositionConstraints=function(){var d=0,h,l=this.m_bodyA,j=this.m_bodyB,o=0,q=h=0,n=0,a=0;if(this.m_enableLimit&&this.m_limitState!=I.e_inactiveLimit){d=j.m_sweep.a-l.m_sweep.a-this.m_referenceAngle;var c=0;if(this.m_limitState==I.e_equalLimits){d=y.Clamp(d-this.m_lowerAngle,-F.b2_maxAngularCorrection,F.b2_maxAngularCorrection);c=-this.m_motorMass*d;o=y.Abs(d)}else if(this.m_limitState==
I.e_atLowerLimit){d=d-this.m_lowerAngle;o=-d;d=y.Clamp(d+F.b2_angularSlop,-F.b2_maxAngularCorrection,0);c=-this.m_motorMass*d}else if(this.m_limitState==I.e_atUpperLimit){o=d=d-this.m_upperAngle;d=y.Clamp(d-F.b2_angularSlop,0,F.b2_maxAngularCorrection);c=-this.m_motorMass*d}l.m_sweep.a-=l.m_invI*c;j.m_sweep.a+=j.m_invI*c;l.SynchronizeTransform();j.SynchronizeTransform()}h=l.m_xf.R;c=this.m_localAnchor1.x-l.m_sweep.localCenter.x;d=this.m_localAnchor1.y-l.m_sweep.localCenter.y;q=h.col1.x*c+h.col2.x*
d;d=h.col1.y*c+h.col2.y*d;c=q;h=j.m_xf.R;var g=this.m_localAnchor2.x-j.m_sweep.localCenter.x,b=this.m_localAnchor2.y-j.m_sweep.localCenter.y;q=h.col1.x*g+h.col2.x*b;b=h.col1.y*g+h.col2.y*b;g=q;n=j.m_sweep.c.x+g-l.m_sweep.c.x-c;a=j.m_sweep.c.y+b-l.m_sweep.c.y-d;var e=n*n+a*a;h=Math.sqrt(e);q=l.m_invMass;var f=j.m_invMass,m=l.m_invI,r=j.m_invI,s=10*F.b2_linearSlop;if(e>s*s){e=1/(q+f);n=e*-n;a=e*-a;l.m_sweep.c.x-=0.5*q*n;l.m_sweep.c.y-=0.5*q*a;j.m_sweep.c.x+=0.5*f*n;j.m_sweep.c.y+=0.5*f*a;n=j.m_sweep.c.x+
g-l.m_sweep.c.x-c;a=j.m_sweep.c.y+b-l.m_sweep.c.y-d}this.K1.col1.x=q+f;this.K1.col2.x=0;this.K1.col1.y=0;this.K1.col2.y=q+f;this.K2.col1.x=m*d*d;this.K2.col2.x=-m*c*d;this.K2.col1.y=-m*c*d;this.K2.col2.y=m*c*c;this.K3.col1.x=r*b*b;this.K3.col2.x=-r*g*b;this.K3.col1.y=-r*g*b;this.K3.col2.y=r*g*g;this.K.SetM(this.K1);this.K.AddM(this.K2);this.K.AddM(this.K3);this.K.Solve(N.tImpulse,-n,-a);n=N.tImpulse.x;a=N.tImpulse.y;l.m_sweep.c.x-=l.m_invMass*n;l.m_sweep.c.y-=l.m_invMass*a;l.m_sweep.a-=l.m_invI*(c*
a-d*n);j.m_sweep.c.x+=j.m_invMass*n;j.m_sweep.c.y+=j.m_invMass*a;j.m_sweep.a+=j.m_invI*(g*a-b*n);l.SynchronizeTransform();j.SynchronizeTransform();return h<=F.b2_linearSlop&&o<=F.b2_angularSlop};Box2D.postDefs.push(function(){Box2D.Dynamics.Joints.b2RevoluteJoint.tImpulse=new w});Box2D.inherit(S,Box2D.Dynamics.Joints.b2JointDef);S.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;S.b2RevoluteJointDef=function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,arguments);this.localAnchorA=
new w;this.localAnchorB=new w};S.prototype.b2RevoluteJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_revoluteJoint;this.localAnchorA.Set(0,0);this.localAnchorB.Set(0,0);this.motorSpeed=this.maxMotorTorque=this.upperAngle=this.lowerAngle=this.referenceAngle=0;this.enableMotor=this.enableLimit=false};S.prototype.Initialize=function(d,h,l){this.bodyA=d;this.bodyB=h;this.localAnchorA=this.bodyA.GetLocalPoint(l);this.localAnchorB=this.bodyB.GetLocalPoint(l);this.referenceAngle=this.bodyB.GetAngle()-
this.bodyA.GetAngle()};Box2D.inherit(aa,Box2D.Dynamics.Joints.b2Joint);aa.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;aa.b2WeldJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.m_localAnchorA=new w;this.m_localAnchorB=new w;this.m_impulse=new A;this.m_mass=new K};aa.prototype.GetAnchorA=function(){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA)};aa.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB)};aa.prototype.GetReactionForce=
function(d){if(d===undefined)d=0;return new w(d*this.m_impulse.x,d*this.m_impulse.y)};aa.prototype.GetReactionTorque=function(d){if(d===undefined)d=0;return d*this.m_impulse.z};aa.prototype.b2WeldJoint=function(d){this.__super.b2Joint.call(this,d);this.m_localAnchorA.SetV(d.localAnchorA);this.m_localAnchorB.SetV(d.localAnchorB);this.m_referenceAngle=d.referenceAngle;this.m_impulse.SetZero();this.m_mass=new K};aa.prototype.InitVelocityConstraints=function(d){var h,l=0,j=this.m_bodyA,o=this.m_bodyB;
h=j.m_xf.R;var q=this.m_localAnchorA.x-j.m_sweep.localCenter.x,n=this.m_localAnchorA.y-j.m_sweep.localCenter.y;l=h.col1.x*q+h.col2.x*n;n=h.col1.y*q+h.col2.y*n;q=l;h=o.m_xf.R;var a=this.m_localAnchorB.x-o.m_sweep.localCenter.x,c=this.m_localAnchorB.y-o.m_sweep.localCenter.y;l=h.col1.x*a+h.col2.x*c;c=h.col1.y*a+h.col2.y*c;a=l;h=j.m_invMass;l=o.m_invMass;var g=j.m_invI,b=o.m_invI;this.m_mass.col1.x=h+l+n*n*g+c*c*b;this.m_mass.col2.x=-n*q*g-c*a*b;this.m_mass.col3.x=-n*g-c*b;this.m_mass.col1.y=this.m_mass.col2.x;
this.m_mass.col2.y=h+l+q*q*g+a*a*b;this.m_mass.col3.y=q*g+a*b;this.m_mass.col1.z=this.m_mass.col3.x;this.m_mass.col2.z=this.m_mass.col3.y;this.m_mass.col3.z=g+b;if(d.warmStarting){this.m_impulse.x*=d.dtRatio;this.m_impulse.y*=d.dtRatio;this.m_impulse.z*=d.dtRatio;j.m_linearVelocity.x-=h*this.m_impulse.x;j.m_linearVelocity.y-=h*this.m_impulse.y;j.m_angularVelocity-=g*(q*this.m_impulse.y-n*this.m_impulse.x+this.m_impulse.z);o.m_linearVelocity.x+=l*this.m_impulse.x;o.m_linearVelocity.y+=l*this.m_impulse.y;
o.m_angularVelocity+=b*(a*this.m_impulse.y-c*this.m_impulse.x+this.m_impulse.z)}else this.m_impulse.SetZero()};aa.prototype.SolveVelocityConstraints=function(){var d,h=0,l=this.m_bodyA,j=this.m_bodyB,o=l.m_linearVelocity,q=l.m_angularVelocity,n=j.m_linearVelocity,a=j.m_angularVelocity,c=l.m_invMass,g=j.m_invMass,b=l.m_invI,e=j.m_invI;d=l.m_xf.R;var f=this.m_localAnchorA.x-l.m_sweep.localCenter.x,m=this.m_localAnchorA.y-l.m_sweep.localCenter.y;h=d.col1.x*f+d.col2.x*m;m=d.col1.y*f+d.col2.y*m;f=h;d=
j.m_xf.R;var r=this.m_localAnchorB.x-j.m_sweep.localCenter.x,s=this.m_localAnchorB.y-j.m_sweep.localCenter.y;h=d.col1.x*r+d.col2.x*s;s=d.col1.y*r+d.col2.y*s;r=h;d=n.x-a*s-o.x+q*m;h=n.y+a*r-o.y-q*f;var v=a-q,t=new A;this.m_mass.Solve33(t,-d,-h,-v);this.m_impulse.Add(t);o.x-=c*t.x;o.y-=c*t.y;q-=b*(f*t.y-m*t.x+t.z);n.x+=g*t.x;n.y+=g*t.y;a+=e*(r*t.y-s*t.x+t.z);l.m_angularVelocity=q;j.m_angularVelocity=a};aa.prototype.SolvePositionConstraints=function(){var d,h=0,l=this.m_bodyA,j=this.m_bodyB;d=l.m_xf.R;
var o=this.m_localAnchorA.x-l.m_sweep.localCenter.x,q=this.m_localAnchorA.y-l.m_sweep.localCenter.y;h=d.col1.x*o+d.col2.x*q;q=d.col1.y*o+d.col2.y*q;o=h;d=j.m_xf.R;var n=this.m_localAnchorB.x-j.m_sweep.localCenter.x,a=this.m_localAnchorB.y-j.m_sweep.localCenter.y;h=d.col1.x*n+d.col2.x*a;a=d.col1.y*n+d.col2.y*a;n=h;d=l.m_invMass;h=j.m_invMass;var c=l.m_invI,g=j.m_invI,b=j.m_sweep.c.x+n-l.m_sweep.c.x-o,e=j.m_sweep.c.y+a-l.m_sweep.c.y-q,f=j.m_sweep.a-l.m_sweep.a-this.m_referenceAngle,m=10*F.b2_linearSlop,
r=Math.sqrt(b*b+e*e),s=y.Abs(f);if(r>m){c*=1;g*=1}this.m_mass.col1.x=d+h+q*q*c+a*a*g;this.m_mass.col2.x=-q*o*c-a*n*g;this.m_mass.col3.x=-q*c-a*g;this.m_mass.col1.y=this.m_mass.col2.x;this.m_mass.col2.y=d+h+o*o*c+n*n*g;this.m_mass.col3.y=o*c+n*g;this.m_mass.col1.z=this.m_mass.col3.x;this.m_mass.col2.z=this.m_mass.col3.y;this.m_mass.col3.z=c+g;m=new A;this.m_mass.Solve33(m,-b,-e,-f);l.m_sweep.c.x-=d*m.x;l.m_sweep.c.y-=d*m.y;l.m_sweep.a-=c*(o*m.y-q*m.x+m.z);j.m_sweep.c.x+=h*m.x;j.m_sweep.c.y+=h*m.y;
j.m_sweep.a+=g*(n*m.y-a*m.x+m.z);l.SynchronizeTransform();j.SynchronizeTransform();return r<=F.b2_linearSlop&&s<=F.b2_angularSlop};Box2D.inherit(Z,Box2D.Dynamics.Joints.b2JointDef);Z.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;Z.b2WeldJointDef=function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,arguments);this.localAnchorA=new w;this.localAnchorB=new w};Z.prototype.b2WeldJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_weldJoint;this.referenceAngle=
0};Z.prototype.Initialize=function(d,h,l){this.bodyA=d;this.bodyB=h;this.localAnchorA.SetV(this.bodyA.GetLocalPoint(l));this.localAnchorB.SetV(this.bodyB.GetLocalPoint(l));this.referenceAngle=this.bodyB.GetAngle()-this.bodyA.GetAngle()}})();
(function(){var F=Box2D.Dynamics.b2DebugDraw;F.b2DebugDraw=function(){this.m_xformScale=this.m_fillAlpha=this.m_alpha=this.m_lineThickness=this.m_drawScale=1;var G=this;this.m_sprite={graphics:{clear:function(){G.m_ctx.clearRect(0,0,G.m_ctx.canvas.width,G.m_ctx.canvas.height)}}}};F.prototype._color=function(G,K){return"rgba("+((G&16711680)>>16)+","+((G&65280)>>8)+","+(G&255)+","+K+")"};F.prototype.b2DebugDraw=function(){this.m_drawFlags=0};F.prototype.SetFlags=function(G){if(G===undefined)G=0;this.m_drawFlags=
G};F.prototype.GetFlags=function(){return this.m_drawFlags};F.prototype.AppendFlags=function(G){if(G===undefined)G=0;this.m_drawFlags|=G};F.prototype.ClearFlags=function(G){if(G===undefined)G=0;this.m_drawFlags&=~G};F.prototype.SetSprite=function(G){this.m_ctx=G};F.prototype.GetSprite=function(){return this.m_ctx};F.prototype.SetDrawScale=function(G){if(G===undefined)G=0;this.m_drawScale=G};F.prototype.GetDrawScale=function(){return this.m_drawScale};F.prototype.SetLineThickness=function(G){if(G===
undefined)G=0;this.m_lineThickness=G;this.m_ctx.strokeWidth=G};F.prototype.GetLineThickness=function(){return this.m_lineThickness};F.prototype.SetAlpha=function(G){if(G===undefined)G=0;this.m_alpha=G};F.prototype.GetAlpha=function(){return this.m_alpha};F.prototype.SetFillAlpha=function(G){if(G===undefined)G=0;this.m_fillAlpha=G};F.prototype.GetFillAlpha=function(){return this.m_fillAlpha};F.prototype.SetXFormScale=function(G){if(G===undefined)G=0;this.m_xformScale=G};F.prototype.GetXFormScale=function(){return this.m_xformScale};
F.prototype.DrawPolygon=function(G,K,y){if(K){var w=this.m_ctx,A=this.m_drawScale;w.beginPath();w.strokeStyle=this._color(y.color,this.m_alpha);w.moveTo(G[0].x*A,G[0].y*A);for(y=1;y<K;y++)w.lineTo(G[y].x*A,G[y].y*A);w.lineTo(G[0].x*A,G[0].y*A);w.closePath();w.stroke()}};F.prototype.DrawSolidPolygon=function(G,K,y){if(K){var w=this.m_ctx,A=this.m_drawScale;w.beginPath();w.strokeStyle=this._color(y.color,this.m_alpha);w.fillStyle=this._color(y.color,this.m_fillAlpha);w.moveTo(G[0].x*A,G[0].y*A);for(y=
1;y<K;y++)w.lineTo(G[y].x*A,G[y].y*A);w.lineTo(G[0].x*A,G[0].y*A);w.closePath();w.fill();w.stroke()}};F.prototype.DrawCircle=function(G,K,y){if(K){var w=this.m_ctx,A=this.m_drawScale;w.beginPath();w.strokeStyle=this._color(y.color,this.m_alpha);w.arc(G.x*A,G.y*A,K*A,0,Math.PI*2,true);w.closePath();w.stroke()}};F.prototype.DrawSolidCircle=function(G,K,y,w){if(K){var A=this.m_ctx,U=this.m_drawScale,p=G.x*U,B=G.y*U;A.moveTo(0,0);A.beginPath();A.strokeStyle=this._color(w.color,this.m_alpha);A.fillStyle=
this._color(w.color,this.m_fillAlpha);A.arc(p,B,K*U,0,Math.PI*2,true);A.moveTo(p,B);A.lineTo((G.x+y.x*K)*U,(G.y+y.y*K)*U);A.closePath();A.fill();A.stroke()}};F.prototype.DrawSegment=function(G,K,y){var w=this.m_ctx,A=this.m_drawScale;w.strokeStyle=this._color(y.color,this.m_alpha);w.beginPath();w.moveTo(G.x*A,G.y*A);w.lineTo(K.x*A,K.y*A);w.closePath();w.stroke()};F.prototype.DrawTransform=function(G){var K=this.m_ctx,y=this.m_drawScale;K.beginPath();K.strokeStyle=this._color(16711680,this.m_alpha);
K.moveTo(G.position.x*y,G.position.y*y);K.lineTo((G.position.x+this.m_xformScale*G.R.col1.x)*y,(G.position.y+this.m_xformScale*G.R.col1.y)*y);K.strokeStyle=this._color(65280,this.m_alpha);K.moveTo(G.position.x*y,G.position.y*y);K.lineTo((G.position.x+this.m_xformScale*G.R.col2.x)*y,(G.position.y+this.m_xformScale*G.R.col2.y)*y);K.closePath();K.stroke()}})();var i;for(i=0;i<Box2D.postDefs.length;++i)Box2D.postDefs[i]();delete Box2D.postDefs;

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,12 @@
/*!
* @license EaselJS
* Visit http://createjs.com/ for documentation, updates and examples.
*
* Copyright (c) 2011-2013 gskinner.com, inc.
*
* Distributed under the terms of the MIT license.
* http://www.opensource.org/licenses/mit-license.html
*
* This notice shall be included in all copies or substantial portions of the Software.
*/
this.createjs=this.createjs||{},function(){"use strict";var a=function(a,b,c,d){this.initialize(a,b,c,d)},b=a.prototype=new createjs.Container;a.INDEPENDENT="independent",a.SINGLE_FRAME="single",a.SYNCHED="synched",b.mode,b.startPosition=0,b.loop=!0,b.currentFrame=0,b.timeline=null,b.paused=!1,b.actionsEnabled=!0,b.autoReset=!0,b.frameBounds=null,b._synchOffset=0,b._prevPos=-1,b._prevPosition=0,b._managed,b.Container_initialize=b.initialize,b.initialize=function(b,c,d,e){this.mode=b||a.INDEPENDENT,this.startPosition=c||0,this.loop=d;var f={paused:!0,position:c,useTicks:!0};this.Container_initialize(),this.timeline=new createjs.Timeline(null,e,f),this._managed={}},b.isVisible=function(){return!!(this.visible&&this.alpha>0&&0!=this.scaleX&&0!=this.scaleY)},b.Container_draw=b.draw,b.draw=function(a,b){return this.DisplayObject_draw(a,b)?!0:(this._updateTimeline(),this.Container_draw(a,b),!0)},b.play=function(){this.paused=!1},b.stop=function(){this.paused=!0},b.gotoAndPlay=function(a){this.paused=!1,this._goto(a)},b.gotoAndStop=function(a){this.paused=!0,this._goto(a)},b.getLabels=function(){return this.timeline.getLabels()},b.getCurrentLabel=function(){return this._updateTimeline(),this.timeline.getCurrentLabel()},b.clone=function(){throw"MovieClip cannot be cloned."},b.toString=function(){return"[MovieClip (name="+this.name+")]"},b.Container__tick=b._tick,b._tick=function(b){this.paused||this.mode!=a.INDEPENDENT||(this._prevPosition=this._prevPos<0?0:this._prevPosition+1,this._updateTimeline()),this.Container__tick(b)},b._goto=function(a){var b=this.timeline.resolve(a);null!=b&&(-1==this._prevPos&&(this._prevPos=0/0),this._prevPosition=b,this._updateTimeline())},b._reset=function(){this._prevPos=-1,this.currentFrame=0},b._updateTimeline=function(){var b=this.timeline,c=this.mode!=a.INDEPENDENT;if(b.loop=null==this.loop?!0:this.loop,c?b.setPosition(this.startPosition+(this.mode==a.SINGLE_FRAME?0:this._synchOffset),createjs.Tween.NONE):b.setPosition(this._prevPos<0?0:this._prevPosition,this.actionsEnabled?null:createjs.Tween.NONE),this._prevPosition=b._prevPosition,this._prevPos!=b._prevPos){this.currentFrame=this._prevPos=b._prevPos;for(var d in this._managed)this._managed[d]=1;for(var e=b._tweens,f=0,g=e.length;g>f;f++){var h=e[f],i=h._target;if(i!=this&&!h.passive){var j=h._stepPosition;i instanceof createjs.DisplayObject?this._addManagedChild(i,j):this._setState(i.state,j)}}var k=this.children;for(f=k.length-1;f>=0;f--){var l=k[f].id;1==this._managed[l]&&(this.removeChildAt(f),delete this._managed[l])}}},b._setState=function(a,b){if(a)for(var c=a.length-1;c>=0;c--){var d=a[c],e=d.t,f=d.p;for(var g in f)e[g]=f[g];this._addManagedChild(e,b)}},b._addManagedChild=function(b,c){b._off||(this.addChildAt(b,0),b instanceof a&&(b._synchOffset=c,b.mode==a.INDEPENDENT&&b.autoReset&&!this._managed[b.id]&&b._reset()),this._managed[b.id]=2)},b.Container__getBounds=b._getBounds,b._getBounds=function(a,b){var c=this.DisplayObject_getBounds();return c||(this._updateTimeline(),this.frameBounds&&(c=this._rectangle.copy(this.frameBounds[this.currentFrame]))),c?this._transformBounds(c,a,b):this.Container__getBounds(a,b)},createjs.MovieClip=a;var c=function(){throw"MovieClipPlugin cannot be instantiated."};c.priority=100,c.install=function(){createjs.Tween.installPlugin(c,["startPosition"])},c.init=function(a,b,c){return c},c.step=function(){},c.tween=function(b,c,d,e,f,g){return b.target instanceof a?1==g?f[c]:e[c]:d},c.install()}();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,91 @@
/*!
* Box2D Car Game Example
* http://42games.net/html5games/box2d-car-game/
*
* This is an example game for the book HTML5 Games Development: A Beginning Guide.
*
* Copyright 2010, Thomas Seng Hin Mak
* makzan@42games.net
*
* All Right Reserved.
*/
html, body{
background: url(../images/website_background.jpg);
font-family: 'Play', arial, serif;
}
em {
margin: 0 6px;
color: #006600;
}
.startscreen {
background: #eee url(../images/starting_screen.jpg);
}
.gamebg_level0 {
background: #eee url(../images/bg.jpg);
}
.gamebg_level1 {
background: #eee url(../images/bg2.jpg);
}
.gamebg_level2 {
background: #eee url(../images/bg3.jpg);
}
.gamebg_level3 {
background: #eee url(../images/bg4.jpg);
}
.gamebg_level4 {
background: #eee url(../images/bg5.jpg);
}
.gamebg_won {
background: #eee url(../images/game_completed_screen.jpg);
}
#game {
width: 1300px;
}
#asset {
position: absolute;
top: -99999px;
}
#game-container {
position: relative;
width: 1300px;
}
#level {
position: absolute;
top: 10px;
left: 10px;
}
.progressbar {
position: absolute;
top: 10px;
right: 10px;
width: 300px;
height:20px;
margin: 2px;
border: 1px solid #000;
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#8C906F), color-stop(48%,#8C906F), color-stop(51%,#323721), color-stop(54%,#55624F), color-stop(100%,#55624F)); /* webkit */
background: gradient(linear, left top, left bottom, color-stop(0%,#8C906F), color-stop(48%,#8C906F), color-stop(51%,#323721), color-stop(54%,#55624F), color-stop(100%,#55624F));
}
.progressbar .fuel-value {
height:20px;
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#A8D751), color-stop(48%,#A8D751), color-stop(51%,#275606), color-stop(54%,#4A8A49), color-stop(100%,#4A8A49)); /* webkit */
background: gradient(linear, left top, left bottom, color-stop(0%,#A8D751), color-stop(48%,#A8D751), color-stop(51%,#275606), color-stop(54%,#4A8A49), color-stop(100%,#4A8A49));
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,134 @@
<!DOCTYPE html>
<html lang=en>
<head>
<!--
Box2D Car Game
http://42games.net/html5games/box2d-car-game/
This is an example game for the book HTML5 Games Development: A Beginning Guide.
Copyright 2011, Thomas Seng Hin Mak
makzan@42games.net
All Right Reserved.
-->
<meta charset=utf-8>
<title>Box2D Car Game</title>
<link href='http://fonts.googleapis.com/css?family=Play&v1' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="css/cargame.css" />
</head>
<body>
<header>
<h1>Box2DJS Car Game</h1>
</header>
<section id="game-container">
<canvas id="game" width='1300' height='600' class="startscreen"></canvas>
<div id="fuel" class="progressbar">
<div class="fuel-value" style="width: 100%;"></div>
</div>
<div id="level"></div>
</section>
<div id="asset">
<img id="flag" src='images/flag.png'>
<img id="bus" src="images/bus.png">
<img id="wheel" src="images/wheel.png">
</div>
<p>Press <em>X</em> to move right. <em>Z</em> to move left. <em>R</em> to restart the game.</p>
<!--=============================-->
<!-- Copy this part to your app. -->
<!-- START -->
<!--=============================-->
<!-- libs -->
<!--[if IE]><script type="text/javascript" src="js/excanvas.js"></script><![endif]-->
<script src="js/protoclass.js"></script>
<script src="js/jquery-1.6.min.js"></script>
<!-- box2djs -->
<script src='js/box2d/common/b2Settings.js'></script>
<script src='js/box2d/common/math/b2Vec2.js'></script>
<script src='js/box2d/common/math/b2Mat22.js'></script>
<script src='js/box2d/common/math/b2Math.js'></script>
<script src='js/box2d/collision/b2AABB.js'></script>
<script src='js/box2d/collision/b2Bound.js'></script>
<script src='js/box2d/collision/b2BoundValues.js'></script>
<script src='js/box2d/collision/b2Pair.js'></script>
<script src='js/box2d/collision/b2PairCallback.js'></script>
<script src='js/box2d/collision/b2BufferedPair.js'></script>
<script src='js/box2d/collision/b2PairManager.js'></script>
<script src='js/box2d/collision/b2BroadPhase.js'></script>
<script src='js/box2d/collision/b2Collision.js'></script>
<script src='js/box2d/collision/Features.js'></script>
<script src='js/box2d/collision/b2ContactID.js'></script>
<script src='js/box2d/collision/b2ContactPoint.js'></script>
<script src='js/box2d/collision/b2Distance.js'></script>
<script src='js/box2d/collision/b2Manifold.js'></script>
<script src='js/box2d/collision/b2OBB.js'></script>
<script src='js/box2d/collision/b2Proxy.js'></script>
<script src='js/box2d/collision/ClipVertex.js'></script>
<script src='js/box2d/collision/shapes/b2Shape.js'></script>
<script src='js/box2d/collision/shapes/b2ShapeDef.js'></script>
<script src='js/box2d/collision/shapes/b2BoxDef.js'></script>
<script src='js/box2d/collision/shapes/b2CircleDef.js'></script>
<script src='js/box2d/collision/shapes/b2CircleShape.js'></script>
<script src='js/box2d/collision/shapes/b2MassData.js'></script>
<script src='js/box2d/collision/shapes/b2PolyDef.js'></script>
<script src='js/box2d/collision/shapes/b2PolyShape.js'></script>
<script src='js/box2d/dynamics/b2Body.js'></script>
<script src='js/box2d/dynamics/b2BodyDef.js'></script>
<script src='js/box2d/dynamics/b2CollisionFilter.js'></script>
<script src='js/box2d/dynamics/b2Island.js'></script>
<script src='js/box2d/dynamics/b2TimeStep.js'></script>
<script src='js/box2d/dynamics/contacts/b2ContactNode.js'></script>
<script src='js/box2d/dynamics/contacts/b2Contact.js'></script>
<script src='js/box2d/dynamics/contacts/b2ContactConstraint.js'></script>
<script src='js/box2d/dynamics/contacts/b2ContactConstraintPoint.js'></script>
<script src='js/box2d/dynamics/contacts/b2ContactRegister.js'></script>
<script src='js/box2d/dynamics/contacts/b2ContactSolver.js'></script>
<script src='js/box2d/dynamics/contacts/b2CircleContact.js'></script>
<script src='js/box2d/dynamics/contacts/b2Conservative.js'></script>
<script src='js/box2d/dynamics/contacts/b2NullContact.js'></script>
<script src='js/box2d/dynamics/contacts/b2PolyAndCircleContact.js'></script>
<script src='js/box2d/dynamics/contacts/b2PolyContact.js'></script>
<script src='js/box2d/dynamics/b2ContactManager.js'></script>
<script src='js/box2d/dynamics/b2World.js'></script>
<script src='js/box2d/dynamics/b2WorldListener.js'></script>
<script src='js/box2d/dynamics/joints/b2JointNode.js'></script>
<script src='js/box2d/dynamics/joints/b2Joint.js'></script>
<script src='js/box2d/dynamics/joints/b2JointDef.js'></script>
<script src='js/box2d/dynamics/joints/b2DistanceJoint.js'></script>
<script src='js/box2d/dynamics/joints/b2DistanceJointDef.js'></script>
<script src='js/box2d/dynamics/joints/b2Jacobian.js'></script>
<script src='js/box2d/dynamics/joints/b2GearJoint.js'></script>
<script src='js/box2d/dynamics/joints/b2GearJointDef.js'></script>
<script src='js/box2d/dynamics/joints/b2MouseJoint.js'></script>
<script src='js/box2d/dynamics/joints/b2MouseJointDef.js'></script>
<script src='js/box2d/dynamics/joints/b2PrismaticJoint.js'></script>
<script src='js/box2d/dynamics/joints/b2PrismaticJointDef.js'></script>
<script src='js/box2d/dynamics/joints/b2PulleyJoint.js'></script>
<script src='js/box2d/dynamics/joints/b2PulleyJointDef.js'></script>
<script src='js/box2d/dynamics/joints/b2RevoluteJoint.js'></script>
<script src='js/box2d/dynamics/joints/b2RevoluteJointDef.js'></script>
<!--=============================-->
<!-- Copy this part to your app. -->
<!-- END -->
<!--=============================-->
<script src='js/html5games.box2dcargame.js'></script>
</body>
</html>

View file

@ -0,0 +1,10 @@
ExplorerCanvas
Google Open Source:
<http://code.google.com>
<opensource@google.com>
Developers:
Emil A Eklund <emil@eae.net>
Erik Arvidsson <erik@eae.net>
Glen Murphy <glen@glenmurphy.com>

View file

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -0,0 +1,22 @@
ExplorerCanvas
Copyright 2006 Google Inc.
-------------------------------------------------------------------------------
DESCRIPTION
Firefox, Safari and Opera 9 support the canvas tag to allow 2D command-based
drawing operations. ExplorerCanvas brings the same functionality to Internet
Explorer; web developers only need to include a single script tag in their
existing canvas webpages to enable this support.
-------------------------------------------------------------------------------
INSTALLATION
Include the ExplorerCanvas tag in the same directory as your HTML files, and
add the following code to your page, preferably in the <head> tag.
<!--[if IE]><script type="text/javascript" src="excanvas.js"></script><![endif]-->
If you run into trouble, please look at the included example code to see how
to best implement this

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var ClipVertex = Class.create();
ClipVertex.prototype =
{
v: new b2Vec2(),
id: new b2ContactID(),
initialize: function() {
// initialize instance variables for references
this.v = new b2Vec2();
this.id = new b2ContactID();
//
}};

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
// We use contact ids to facilitate warm starting.
var Features = Class.create();
Features.prototype =
{
//
set_referenceFace: function(value){
this._referenceFace = value;
this._m_id._key = (this._m_id._key & 0xffffff00) | (this._referenceFace & 0x000000ff)
},
get_referenceFace: function(){
return this._referenceFace;
},
_referenceFace: 0,
//
set_incidentEdge: function(value){
this._incidentEdge = value;
this._m_id._key = (this._m_id._key & 0xffff00ff) | ((this._incidentEdge << 8) & 0x0000ff00)
},
get_incidentEdge: function(){
return this._incidentEdge;
},
_incidentEdge: 0,
//
set_incidentVertex: function(value){
this._incidentVertex = value;
this._m_id._key = (this._m_id._key & 0xff00ffff) | ((this._incidentVertex << 16) & 0x00ff0000)
},
get_incidentVertex: function(){
return this._incidentVertex;
},
_incidentVertex: 0,
//
set_flip: function(value){
this._flip = value;
this._m_id._key = (this._m_id._key & 0x00ffffff) | ((this._flip << 24) & 0xff000000)
},
get_flip: function(){
return this._flip;
},
_flip: 0,
_m_id: null,
initialize: function() {}};

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
// A manifold for two touching convex shapes.
var b2AABB = Class.create();
b2AABB.prototype =
{
IsValid: function(){
//var d = b2Math.SubtractVV(this.maxVertex, this.minVertex);
var dX = this.maxVertex.x;
var dY = this.maxVertex.y;
dX = this.maxVertex.x;
dY = this.maxVertex.y;
dX -= this.minVertex.x;
dY -= this.minVertex.y;
var valid = dX >= 0.0 && dY >= 0.0;
valid = valid && this.minVertex.IsValid() && this.maxVertex.IsValid();
return valid;
},
minVertex: new b2Vec2(),
maxVertex: new b2Vec2(),
initialize: function() {
// initialize instance variables for references
this.minVertex = new b2Vec2();
this.maxVertex = new b2Vec2();
//
}};

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2Bound = Class.create();
b2Bound.prototype = {
IsLower: function(){ return (this.value & 1) == 0; },
IsUpper: function(){ return (this.value & 1) == 1; },
Swap: function(b){
var tempValue = this.value;
var tempProxyId = this.proxyId;
var tempStabbingCount = this.stabbingCount;
this.value = b.value;
this.proxyId = b.proxyId;
this.stabbingCount = b.stabbingCount;
b.value = tempValue;
b.proxyId = tempProxyId;
b.stabbingCount = tempStabbingCount;
},
value: 0,
proxyId: 0,
stabbingCount: 0,
initialize: function() {}}

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2BoundValues = Class.create();
b2BoundValues.prototype = {
lowerValues: [0,0],
upperValues: [0,0],
initialize: function() {
// initialize instance variables for references
this.lowerValues = [0,0];
this.upperValues = [0,0];
//
}}

View file

@ -0,0 +1,898 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
/*
This broad phase uses the Sweep and Prune algorithm in:
Collision Detection in Interactive 3D Environments by Gino van den Bergen
Also, some ideas, such integral values for fast compares comes from
Bullet (http:/www.bulletphysics.com).
*/
// Notes:
// - we use bound arrays instead of linked lists for cache coherence.
// - we use quantized integral values for fast compares.
// - we use short indices rather than pointers to save memory.
// - we use a stabbing count for fast overlap queries (less than order N).
// - we also use a time stamp on each proxy to speed up the registration of
// overlap query results.
// - where possible, we compare bound indices instead of values to reduce
// cache misses (TODO_ERIN).
// - no broadphase is perfect and neither is this one: it is not great for huge
// worlds (use a multi-SAP instead), it is not great for large objects.
var b2BroadPhase = Class.create();
b2BroadPhase.prototype =
{
//public:
initialize: function(worldAABB, callback){
// initialize instance variables for references
this.m_pairManager = new b2PairManager();
this.m_proxyPool = new Array(b2Settings.b2_maxPairs);
this.m_bounds = new Array(2*b2Settings.b2_maxProxies);
this.m_queryResults = new Array(b2Settings.b2_maxProxies);
this.m_quantizationFactor = new b2Vec2();
//
//b2Settings.b2Assert(worldAABB.IsValid());
var i = 0;
this.m_pairManager.Initialize(this, callback);
this.m_worldAABB = worldAABB;
this.m_proxyCount = 0;
// query results
for (i = 0; i < b2Settings.b2_maxProxies; i++){
this.m_queryResults[i] = 0;
}
// bounds array
this.m_bounds = new Array(2);
for (i = 0; i < 2; i++){
this.m_bounds[i] = new Array(2*b2Settings.b2_maxProxies);
for (var j = 0; j < 2*b2Settings.b2_maxProxies; j++){
this.m_bounds[i][j] = new b2Bound();
}
}
//var d = b2Math.SubtractVV(worldAABB.maxVertex, worldAABB.minVertex);
var dX = worldAABB.maxVertex.x;
var dY = worldAABB.maxVertex.y;
dX -= worldAABB.minVertex.x;
dY -= worldAABB.minVertex.y;
this.m_quantizationFactor.x = b2Settings.USHRT_MAX / dX;
this.m_quantizationFactor.y = b2Settings.USHRT_MAX / dY;
var tProxy;
for (i = 0; i < b2Settings.b2_maxProxies - 1; ++i)
{
tProxy = new b2Proxy();
this.m_proxyPool[i] = tProxy;
tProxy.SetNext(i + 1);
tProxy.timeStamp = 0;
tProxy.overlapCount = b2BroadPhase.b2_invalid;
tProxy.userData = null;
}
tProxy = new b2Proxy();
this.m_proxyPool[b2Settings.b2_maxProxies-1] = tProxy;
tProxy.SetNext(b2Pair.b2_nullProxy);
tProxy.timeStamp = 0;
tProxy.overlapCount = b2BroadPhase.b2_invalid;
tProxy.userData = null;
this.m_freeProxy = 0;
this.m_timeStamp = 1;
this.m_queryResultCount = 0;
},
//~b2BroadPhase();
// Use this to see if your proxy is in range. If it is not in range,
// it should be destroyed. Otherwise you may get O(m^2) pairs, where m
// is the number of proxies that are out of range.
InRange: function(aabb){
//var d = b2Math.b2MaxV(b2Math.SubtractVV(aabb.minVertex, this.m_worldAABB.maxVertex), b2Math.SubtractVV(this.m_worldAABB.minVertex, aabb.maxVertex));
var dX;
var dY;
var d2X;
var d2Y;
dX = aabb.minVertex.x;
dY = aabb.minVertex.y;
dX -= this.m_worldAABB.maxVertex.x;
dY -= this.m_worldAABB.maxVertex.y;
d2X = this.m_worldAABB.minVertex.x;
d2Y = this.m_worldAABB.minVertex.y;
d2X -= aabb.maxVertex.x;
d2Y -= aabb.maxVertex.y;
dX = b2Math.b2Max(dX, d2X);
dY = b2Math.b2Max(dY, d2Y);
return b2Math.b2Max(dX, dY) < 0.0;
},
// Get a single proxy. Returns NULL if the id is invalid.
GetProxy: function(proxyId){
if (proxyId == b2Pair.b2_nullProxy || this.m_proxyPool[proxyId].IsValid() == false)
{
return null;
}
return this.m_proxyPool[ proxyId ];
},
// Create and destroy proxies. These call Flush first.
CreateProxy: function(aabb, userData){
var index = 0;
var proxy;
//b2Settings.b2Assert(this.m_proxyCount < b2_maxProxies);
//b2Settings.b2Assert(this.m_freeProxy != b2Pair.b2_nullProxy);
var proxyId = this.m_freeProxy;
proxy = this.m_proxyPool[ proxyId ];
this.m_freeProxy = proxy.GetNext();
proxy.overlapCount = 0;
proxy.userData = userData;
var boundCount = 2 * this.m_proxyCount;
var lowerValues = new Array();
var upperValues = new Array();
this.ComputeBounds(lowerValues, upperValues, aabb);
for (var axis = 0; axis < 2; ++axis)
{
var bounds = this.m_bounds[axis];
var lowerIndex = 0;
var upperIndex = 0;
var lowerIndexOut = [lowerIndex];
var upperIndexOut = [upperIndex];
this.Query(lowerIndexOut, upperIndexOut, lowerValues[axis], upperValues[axis], bounds, boundCount, axis);
lowerIndex = lowerIndexOut[0];
upperIndex = upperIndexOut[0];
// Replace memmove calls
//memmove(bounds + upperIndex + 2, bounds + upperIndex, (edgeCount - upperIndex) * sizeof(b2Bound));
var tArr = new Array();
var j = 0;
var tEnd = boundCount - upperIndex
var tBound1;
var tBound2;
// make temp array
for (j = 0; j < tEnd; j++){
tArr[j] = new b2Bound();
tBound1 = tArr[j];
tBound2 = bounds[upperIndex+j];
tBound1.value = tBound2.value;
tBound1.proxyId = tBound2.proxyId;
tBound1.stabbingCount = tBound2.stabbingCount;
}
// move temp array back in to bounds
tEnd = tArr.length;
var tIndex = upperIndex+2;
for (j = 0; j < tEnd; j++){
//bounds[tIndex+j] = tArr[j];
tBound2 = tArr[j];
tBound1 = bounds[tIndex+j]
tBound1.value = tBound2.value;
tBound1.proxyId = tBound2.proxyId;
tBound1.stabbingCount = tBound2.stabbingCount;
}
//memmove(bounds + lowerIndex + 1, bounds + lowerIndex, (upperIndex - lowerIndex) * sizeof(b2Bound));
// make temp array
tArr = new Array();
tEnd = upperIndex - lowerIndex;
for (j = 0; j < tEnd; j++){
tArr[j] = new b2Bound();
tBound1 = tArr[j];
tBound2 = bounds[lowerIndex+j];
tBound1.value = tBound2.value;
tBound1.proxyId = tBound2.proxyId;
tBound1.stabbingCount = tBound2.stabbingCount;
}
// move temp array back in to bounds
tEnd = tArr.length;
tIndex = lowerIndex+1;
for (j = 0; j < tEnd; j++){
//bounds[tIndex+j] = tArr[j];
tBound2 = tArr[j];
tBound1 = bounds[tIndex+j]
tBound1.value = tBound2.value;
tBound1.proxyId = tBound2.proxyId;
tBound1.stabbingCount = tBound2.stabbingCount;
}
// The upper index has increased because of the lower bound insertion.
++upperIndex;
// Copy in the new bounds.
bounds[lowerIndex].value = lowerValues[axis];
bounds[lowerIndex].proxyId = proxyId;
bounds[upperIndex].value = upperValues[axis];
bounds[upperIndex].proxyId = proxyId;
bounds[lowerIndex].stabbingCount = lowerIndex == 0 ? 0 : bounds[lowerIndex-1].stabbingCount;
bounds[upperIndex].stabbingCount = bounds[upperIndex-1].stabbingCount;
// Adjust the stabbing count between the new bounds.
for (index = lowerIndex; index < upperIndex; ++index)
{
bounds[index].stabbingCount++;
}
// Adjust the all the affected bound indices.
for (index = lowerIndex; index < boundCount + 2; ++index)
{
var proxy2 = this.m_proxyPool[ bounds[index].proxyId ];
if (bounds[index].IsLower())
{
proxy2.lowerBounds[axis] = index;
}
else
{
proxy2.upperBounds[axis] = index;
}
}
}
++this.m_proxyCount;
//b2Settings.b2Assert(this.m_queryResultCount < b2Settings.b2_maxProxies);
for (var i = 0; i < this.m_queryResultCount; ++i)
{
//b2Settings.b2Assert(this.m_queryResults[i] < b2_maxProxies);
//b2Settings.b2Assert(this.m_proxyPool[this.m_queryResults[i]].IsValid());
this.m_pairManager.AddBufferedPair(proxyId, this.m_queryResults[i]);
}
this.m_pairManager.Commit();
// Prepare for next query.
this.m_queryResultCount = 0;
this.IncrementTimeStamp();
return proxyId;
},
DestroyProxy: function(proxyId){
//b2Settings.b2Assert(0 < this.m_proxyCount && this.m_proxyCount <= b2_maxProxies);
var proxy = this.m_proxyPool[ proxyId ];
//b2Settings.b2Assert(proxy.IsValid());
var boundCount = 2 * this.m_proxyCount;
for (var axis = 0; axis < 2; ++axis)
{
var bounds = this.m_bounds[axis];
var lowerIndex = proxy.lowerBounds[axis];
var upperIndex = proxy.upperBounds[axis];
var lowerValue = bounds[lowerIndex].value;
var upperValue = bounds[upperIndex].value;
// replace memmove calls
//memmove(bounds + lowerIndex, bounds + lowerIndex + 1, (upperIndex - lowerIndex - 1) * sizeof(b2Bound));
var tArr = new Array();
var j = 0;
var tEnd = upperIndex - lowerIndex - 1;
var tBound1;
var tBound2;
// make temp array
for (j = 0; j < tEnd; j++){
tArr[j] = new b2Bound();
tBound1 = tArr[j];
tBound2 = bounds[lowerIndex+1+j];
tBound1.value = tBound2.value;
tBound1.proxyId = tBound2.proxyId;
tBound1.stabbingCount = tBound2.stabbingCount;
}
// move temp array back in to bounds
tEnd = tArr.length;
var tIndex = lowerIndex;
for (j = 0; j < tEnd; j++){
//bounds[tIndex+j] = tArr[j];
tBound2 = tArr[j];
tBound1 = bounds[tIndex+j]
tBound1.value = tBound2.value;
tBound1.proxyId = tBound2.proxyId;
tBound1.stabbingCount = tBound2.stabbingCount;
}
//memmove(bounds + upperIndex-1, bounds + upperIndex + 1, (edgeCount - upperIndex - 1) * sizeof(b2Bound));
// make temp array
tArr = new Array();
tEnd = boundCount - upperIndex - 1;
for (j = 0; j < tEnd; j++){
tArr[j] = new b2Bound();
tBound1 = tArr[j];
tBound2 = bounds[upperIndex+1+j];
tBound1.value = tBound2.value;
tBound1.proxyId = tBound2.proxyId;
tBound1.stabbingCount = tBound2.stabbingCount;
}
// move temp array back in to bounds
tEnd = tArr.length;
tIndex = upperIndex-1;
for (j = 0; j < tEnd; j++){
//bounds[tIndex+j] = tArr[j];
tBound2 = tArr[j];
tBound1 = bounds[tIndex+j]
tBound1.value = tBound2.value;
tBound1.proxyId = tBound2.proxyId;
tBound1.stabbingCount = tBound2.stabbingCount;
}
// Fix bound indices.
tEnd = boundCount - 2;
for (var index = lowerIndex; index < tEnd; ++index)
{
var proxy2 = this.m_proxyPool[ bounds[index].proxyId ];
if (bounds[index].IsLower())
{
proxy2.lowerBounds[axis] = index;
}
else
{
proxy2.upperBounds[axis] = index;
}
}
// Fix stabbing count.
tEnd = upperIndex - 1;
for (var index2 = lowerIndex; index2 < tEnd; ++index2)
{
bounds[index2].stabbingCount--;
}
// this.Query for pairs to be removed. lowerIndex and upperIndex are not needed.
// make lowerIndex and upper output using an array and do this for others if compiler doesn't pick them up
this.Query([0], [0], lowerValue, upperValue, bounds, boundCount - 2, axis);
}
//b2Settings.b2Assert(this.m_queryResultCount < b2Settings.b2_maxProxies);
for (var i = 0; i < this.m_queryResultCount; ++i)
{
//b2Settings.b2Assert(this.m_proxyPool[this.m_queryResults[i]].IsValid());
this.m_pairManager.RemoveBufferedPair(proxyId, this.m_queryResults[i]);
}
this.m_pairManager.Commit();
// Prepare for next query.
this.m_queryResultCount = 0;
this.IncrementTimeStamp();
// Return the proxy to the pool.
proxy.userData = null;
proxy.overlapCount = b2BroadPhase.b2_invalid;
proxy.lowerBounds[0] = b2BroadPhase.b2_invalid;
proxy.lowerBounds[1] = b2BroadPhase.b2_invalid;
proxy.upperBounds[0] = b2BroadPhase.b2_invalid;
proxy.upperBounds[1] = b2BroadPhase.b2_invalid;
proxy.SetNext(this.m_freeProxy);
this.m_freeProxy = proxyId;
--this.m_proxyCount;
},
// Call this.MoveProxy times like, then when you are done
// call this.Commit to finalized the proxy pairs (for your time step).
MoveProxy: function(proxyId, aabb){
var axis = 0;
var index = 0;
var bound;
var prevBound
var nextBound
var nextProxyId = 0;
var nextProxy;
if (proxyId == b2Pair.b2_nullProxy || b2Settings.b2_maxProxies <= proxyId)
{
//b2Settings.b2Assert(false);
return;
}
if (aabb.IsValid() == false)
{
//b2Settings.b2Assert(false);
return;
}
var boundCount = 2 * this.m_proxyCount;
var proxy = this.m_proxyPool[ proxyId ];
// Get new bound values
var newValues = new b2BoundValues();
this.ComputeBounds(newValues.lowerValues, newValues.upperValues, aabb);
// Get old bound values
var oldValues = new b2BoundValues();
for (axis = 0; axis < 2; ++axis)
{
oldValues.lowerValues[axis] = this.m_bounds[axis][proxy.lowerBounds[axis]].value;
oldValues.upperValues[axis] = this.m_bounds[axis][proxy.upperBounds[axis]].value;
}
for (axis = 0; axis < 2; ++axis)
{
var bounds = this.m_bounds[axis];
var lowerIndex = proxy.lowerBounds[axis];
var upperIndex = proxy.upperBounds[axis];
var lowerValue = newValues.lowerValues[axis];
var upperValue = newValues.upperValues[axis];
var deltaLower = lowerValue - bounds[lowerIndex].value;
var deltaUpper = upperValue - bounds[upperIndex].value;
bounds[lowerIndex].value = lowerValue;
bounds[upperIndex].value = upperValue;
//
// Expanding adds overlaps
//
// Should we move the lower bound down?
if (deltaLower < 0)
{
index = lowerIndex;
while (index > 0 && lowerValue < bounds[index-1].value)
{
bound = bounds[index];
prevBound = bounds[index - 1];
var prevProxyId = prevBound.proxyId;
var prevProxy = this.m_proxyPool[ prevBound.proxyId ];
prevBound.stabbingCount++;
if (prevBound.IsUpper() == true)
{
if (this.TestOverlap(newValues, prevProxy))
{
this.m_pairManager.AddBufferedPair(proxyId, prevProxyId);
}
prevProxy.upperBounds[axis]++;
bound.stabbingCount++;
}
else
{
prevProxy.lowerBounds[axis]++;
bound.stabbingCount--;
}
proxy.lowerBounds[axis]--;
// swap
//var temp = bound;
//bound = prevEdge;
//prevEdge = temp;
bound.Swap(prevBound);
//b2Math.b2Swap(bound, prevEdge);
--index;
}
}
// Should we move the upper bound up?
if (deltaUpper > 0)
{
index = upperIndex;
while (index < boundCount-1 && bounds[index+1].value <= upperValue)
{
bound = bounds[ index ];
nextBound = bounds[ index + 1 ];
nextProxyId = nextBound.proxyId;
nextProxy = this.m_proxyPool[ nextProxyId ];
nextBound.stabbingCount++;
if (nextBound.IsLower() == true)
{
if (this.TestOverlap(newValues, nextProxy))
{
this.m_pairManager.AddBufferedPair(proxyId, nextProxyId);
}
nextProxy.lowerBounds[axis]--;
bound.stabbingCount++;
}
else
{
nextProxy.upperBounds[axis]--;
bound.stabbingCount--;
}
proxy.upperBounds[axis]++;
// swap
//var temp = bound;
//bound = nextEdge;
//nextEdge = temp;
bound.Swap(nextBound);
//b2Math.b2Swap(bound, nextEdge);
index++;
}
}
//
// Shrinking removes overlaps
//
// Should we move the lower bound up?
if (deltaLower > 0)
{
index = lowerIndex;
while (index < boundCount-1 && bounds[index+1].value <= lowerValue)
{
bound = bounds[ index ];
nextBound = bounds[ index + 1 ];
nextProxyId = nextBound.proxyId;
nextProxy = this.m_proxyPool[ nextProxyId ];
nextBound.stabbingCount--;
if (nextBound.IsUpper())
{
if (this.TestOverlap(oldValues, nextProxy))
{
this.m_pairManager.RemoveBufferedPair(proxyId, nextProxyId);
}
nextProxy.upperBounds[axis]--;
bound.stabbingCount--;
}
else
{
nextProxy.lowerBounds[axis]--;
bound.stabbingCount++;
}
proxy.lowerBounds[axis]++;
// swap
//var temp = bound;
//bound = nextEdge;
//nextEdge = temp;
bound.Swap(nextBound);
//b2Math.b2Swap(bound, nextEdge);
index++;
}
}
// Should we move the upper bound down?
if (deltaUpper < 0)
{
index = upperIndex;
while (index > 0 && upperValue < bounds[index-1].value)
{
bound = bounds[index];
prevBound = bounds[index - 1];
prevProxyId = prevBound.proxyId;
prevProxy = this.m_proxyPool[ prevProxyId ];
prevBound.stabbingCount--;
if (prevBound.IsLower() == true)
{
if (this.TestOverlap(oldValues, prevProxy))
{
this.m_pairManager.RemoveBufferedPair(proxyId, prevProxyId);
}
prevProxy.lowerBounds[axis]++;
bound.stabbingCount--;
}
else
{
prevProxy.upperBounds[axis]++;
bound.stabbingCount++;
}
proxy.upperBounds[axis]--;
// swap
//var temp = bound;
//bound = prevEdge;
//prevEdge = temp;
bound.Swap(prevBound);
//b2Math.b2Swap(bound, prevEdge);
index--;
}
}
}
},
Commit: function(){
this.m_pairManager.Commit();
},
// this.Query an AABB for overlapping proxies, returns the user data and
// the count, up to the supplied maximum count.
QueryAABB: function(aabb, userData, maxCount){
var lowerValues = new Array();
var upperValues = new Array();
this.ComputeBounds(lowerValues, upperValues, aabb);
var lowerIndex = 0;
var upperIndex = 0;
var lowerIndexOut = [lowerIndex];
var upperIndexOut = [upperIndex];
this.Query(lowerIndexOut, upperIndexOut, lowerValues[0], upperValues[0], this.m_bounds[0], 2*this.m_proxyCount, 0);
this.Query(lowerIndexOut, upperIndexOut, lowerValues[1], upperValues[1], this.m_bounds[1], 2*this.m_proxyCount, 1);
//b2Settings.b2Assert(this.m_queryResultCount < b2Settings.b2_maxProxies);
var count = 0;
for (var i = 0; i < this.m_queryResultCount && count < maxCount; ++i, ++count)
{
//b2Settings.b2Assert(this.m_queryResults[i] < b2Settings.b2_maxProxies);
var proxy = this.m_proxyPool[ this.m_queryResults[i] ];
//b2Settings.b2Assert(proxy.IsValid());
userData[i] = proxy.userData;
}
// Prepare for next query.
this.m_queryResultCount = 0;
this.IncrementTimeStamp();
return count;
},
Validate: function(){
var pair;
var proxy1;
var proxy2;
var overlap;
for (var axis = 0; axis < 2; ++axis)
{
var bounds = this.m_bounds[axis];
var boundCount = 2 * this.m_proxyCount;
var stabbingCount = 0;
for (var i = 0; i < boundCount; ++i)
{
var bound = bounds[i];
//b2Settings.b2Assert(i == 0 || bounds[i-1].value <= bound->value);
//b2Settings.b2Assert(bound->proxyId != b2_nullProxy);
//b2Settings.b2Assert(this.m_proxyPool[bound->proxyId].IsValid());
if (bound.IsLower() == true)
{
//b2Settings.b2Assert(this.m_proxyPool[bound.proxyId].lowerBounds[axis] == i);
stabbingCount++;
}
else
{
//b2Settings.b2Assert(this.m_proxyPool[bound.proxyId].upperBounds[axis] == i);
stabbingCount--;
}
//b2Settings.b2Assert(bound.stabbingCount == stabbingCount);
}
}
},
//private:
ComputeBounds: function(lowerValues, upperValues, aabb)
{
//b2Settings.b2Assert(aabb.maxVertex.x > aabb.minVertex.x);
//b2Settings.b2Assert(aabb.maxVertex.y > aabb.minVertex.y);
//var minVertex = b2Math.b2ClampV(aabb.minVertex, this.m_worldAABB.minVertex, this.m_worldAABB.maxVertex);
var minVertexX = aabb.minVertex.x;
var minVertexY = aabb.minVertex.y;
minVertexX = b2Math.b2Min(minVertexX, this.m_worldAABB.maxVertex.x);
minVertexY = b2Math.b2Min(minVertexY, this.m_worldAABB.maxVertex.y);
minVertexX = b2Math.b2Max(minVertexX, this.m_worldAABB.minVertex.x);
minVertexY = b2Math.b2Max(minVertexY, this.m_worldAABB.minVertex.y);
//var maxVertex = b2Math.b2ClampV(aabb.maxVertex, this.m_worldAABB.minVertex, this.m_worldAABB.maxVertex);
var maxVertexX = aabb.maxVertex.x;
var maxVertexY = aabb.maxVertex.y;
maxVertexX = b2Math.b2Min(maxVertexX, this.m_worldAABB.maxVertex.x);
maxVertexY = b2Math.b2Min(maxVertexY, this.m_worldAABB.maxVertex.y);
maxVertexX = b2Math.b2Max(maxVertexX, this.m_worldAABB.minVertex.x);
maxVertexY = b2Math.b2Max(maxVertexY, this.m_worldAABB.minVertex.y);
// Bump lower bounds downs and upper bounds up. This ensures correct sorting of
// lower/upper bounds that would have equal values.
// TODO_ERIN implement fast float to uint16 conversion.
lowerValues[0] = /*uint*/(this.m_quantizationFactor.x * (minVertexX - this.m_worldAABB.minVertex.x)) & (b2Settings.USHRT_MAX - 1);
upperValues[0] = (/*uint*/(this.m_quantizationFactor.x * (maxVertexX - this.m_worldAABB.minVertex.x))& 0x0000ffff) | 1;
lowerValues[1] = /*uint*/(this.m_quantizationFactor.y * (minVertexY - this.m_worldAABB.minVertex.y)) & (b2Settings.USHRT_MAX - 1);
upperValues[1] = (/*uint*/(this.m_quantizationFactor.y * (maxVertexY - this.m_worldAABB.minVertex.y))& 0x0000ffff) | 1;
},
// This one is only used for validation.
TestOverlapValidate: function(p1, p2){
for (var axis = 0; axis < 2; ++axis)
{
var bounds = this.m_bounds[axis];
//b2Settings.b2Assert(p1.lowerBounds[axis] < 2 * this.m_proxyCount);
//b2Settings.b2Assert(p1.upperBounds[axis] < 2 * this.m_proxyCount);
//b2Settings.b2Assert(p2.lowerBounds[axis] < 2 * this.m_proxyCount);
//b2Settings.b2Assert(p2.upperBounds[axis] < 2 * this.m_proxyCount);
if (bounds[p1.lowerBounds[axis]].value > bounds[p2.upperBounds[axis]].value)
return false;
if (bounds[p1.upperBounds[axis]].value < bounds[p2.lowerBounds[axis]].value)
return false;
}
return true;
},
TestOverlap: function(b, p)
{
for (var axis = 0; axis < 2; ++axis)
{
var bounds = this.m_bounds[axis];
//b2Settings.b2Assert(p.lowerBounds[axis] < 2 * this.m_proxyCount);
//b2Settings.b2Assert(p.upperBounds[axis] < 2 * this.m_proxyCount);
if (b.lowerValues[axis] > bounds[p.upperBounds[axis]].value)
return false;
if (b.upperValues[axis] < bounds[p.lowerBounds[axis]].value)
return false;
}
return true;
},
Query: function(lowerQueryOut, upperQueryOut, lowerValue, upperValue, bounds, boundCount, axis){
var lowerQuery = b2BroadPhase.BinarySearch(bounds, boundCount, lowerValue);
var upperQuery = b2BroadPhase.BinarySearch(bounds, boundCount, upperValue);
// Easy case: lowerQuery <= lowerIndex(i) < upperQuery
// Solution: search query range for min bounds.
for (var j = lowerQuery; j < upperQuery; ++j)
{
if (bounds[j].IsLower())
{
this.IncrementOverlapCount(bounds[j].proxyId);
}
}
// Hard case: lowerIndex(i) < lowerQuery < upperIndex(i)
// Solution: use the stabbing count to search down the bound array.
if (lowerQuery > 0)
{
var i = lowerQuery - 1;
var s = bounds[i].stabbingCount;
// Find the s overlaps.
while (s)
{
//b2Settings.b2Assert(i >= 0);
if (bounds[i].IsLower())
{
var proxy = this.m_proxyPool[ bounds[i].proxyId ];
if (lowerQuery <= proxy.upperBounds[axis])
{
this.IncrementOverlapCount(bounds[i].proxyId);
--s;
}
}
--i;
}
}
lowerQueryOut[0] = lowerQuery;
upperQueryOut[0] = upperQuery;
},
IncrementOverlapCount: function(proxyId){
var proxy = this.m_proxyPool[ proxyId ];
if (proxy.timeStamp < this.m_timeStamp)
{
proxy.timeStamp = this.m_timeStamp;
proxy.overlapCount = 1;
}
else
{
proxy.overlapCount = 2;
//b2Settings.b2Assert(this.m_queryResultCount < b2Settings.b2_maxProxies);
this.m_queryResults[this.m_queryResultCount] = proxyId;
++this.m_queryResultCount;
}
},
IncrementTimeStamp: function(){
if (this.m_timeStamp == b2Settings.USHRT_MAX)
{
for (var i = 0; i < b2Settings.b2_maxProxies; ++i)
{
this.m_proxyPool[i].timeStamp = 0;
}
this.m_timeStamp = 1;
}
else
{
++this.m_timeStamp;
}
},
//public:
m_pairManager: new b2PairManager(),
m_proxyPool: new Array(b2Settings.b2_maxPairs),
m_freeProxy: 0,
m_bounds: new Array(2*b2Settings.b2_maxProxies),
m_queryResults: new Array(b2Settings.b2_maxProxies),
m_queryResultCount: 0,
m_worldAABB: null,
m_quantizationFactor: new b2Vec2(),
m_proxyCount: 0,
m_timeStamp: 0};
b2BroadPhase.s_validate = false;
b2BroadPhase.b2_invalid = b2Settings.USHRT_MAX;
b2BroadPhase.b2_nullEdge = b2Settings.USHRT_MAX;
b2BroadPhase.BinarySearch = function(bounds, count, value)
{
var low = 0;
var high = count - 1;
while (low <= high)
{
var mid = Math.floor((low + high) / 2);
if (bounds[mid].value > value)
{
high = mid - 1;
}
else if (bounds[mid].value < value)
{
low = mid + 1;
}
else
{
return /*uint*/(mid);
}
}
return /*uint*/(low);
};

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2BufferedPair = Class.create();
b2BufferedPair.prototype = {
proxyId1: 0,
proxyId2: 0,
initialize: function() {}}

View file

@ -0,0 +1,738 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2Collision = Class.create();
b2Collision.prototype = {
// Null feature
// Find the separation between poly1 and poly2 for a give edge normal on poly1.
// Find the max separation between poly1 and poly2 using edge normals
// from poly1.
// Find edge normal of max separation on A - return if separating axis is found
// Find edge normal of max separation on B - return if separation axis is found
// Choose reference edge(minA, minB)
// Find incident edge
// Clip
// The normal points from 1 to 2
initialize: function() {}}
b2Collision.b2_nullFeature = 0x000000ff;
b2Collision.ClipSegmentToLine = function(vOut, vIn, normal, offset)
{
// Start with no output points
var numOut = 0;
var vIn0 = vIn[0].v;
var vIn1 = vIn[1].v;
// Calculate the distance of end points to the line
var distance0 = b2Math.b2Dot(normal, vIn[0].v) - offset;
var distance1 = b2Math.b2Dot(normal, vIn[1].v) - offset;
// If the points are behind the plane
if (distance0 <= 0.0) vOut[numOut++] = vIn[0];
if (distance1 <= 0.0) vOut[numOut++] = vIn[1];
// If the points are on different sides of the plane
if (distance0 * distance1 < 0.0)
{
// Find intersection point of edge and plane
var interp = distance0 / (distance0 - distance1);
// expanded for performance
var tVec = vOut[numOut].v;
tVec.x = vIn0.x + interp * (vIn1.x - vIn0.x);
tVec.y = vIn0.y + interp * (vIn1.y - vIn0.y);
if (distance0 > 0.0)
{
vOut[numOut].id = vIn[0].id;
}
else
{
vOut[numOut].id = vIn[1].id;
}
++numOut;
}
return numOut;
};
b2Collision.EdgeSeparation = function(poly1, edge1, poly2)
{
var vert1s = poly1.m_vertices;
var count2 = poly2.m_vertexCount;
var vert2s = poly2.m_vertices;
// Convert normal from into poly2's frame.
//b2Settings.b2Assert(edge1 < poly1.m_vertexCount);
//var normal = b2Math.b2MulMV(poly1.m_R, poly1->m_normals[edge1]);
var normalX = poly1.m_normals[edge1].x;
var normalY = poly1.m_normals[edge1].y;
var tX = normalX;
var tMat = poly1.m_R;
normalX = tMat.col1.x * tX + tMat.col2.x * normalY;
normalY = tMat.col1.y * tX + tMat.col2.y * normalY;
// ^^^^^^^ normal.MulM(poly1.m_R);
//var normalLocal2 = b2Math.b2MulTMV(poly2.m_R, normal);
var normalLocal2X = normalX;
var normalLocal2Y = normalY;
tMat = poly2.m_R;
tX = normalLocal2X * tMat.col1.x + normalLocal2Y * tMat.col1.y;
normalLocal2Y = normalLocal2X * tMat.col2.x + normalLocal2Y * tMat.col2.y;
normalLocal2X = tX;
// ^^^^^ normalLocal2.MulTM(poly2.m_R);
// Find support vertex on poly2 for -normal.
var vertexIndex2 = 0;
var minDot = Number.MAX_VALUE;
for (var i = 0; i < count2; ++i)
{
//var dot = b2Math.b2Dot(vert2s[i], normalLocal2);
var tVec = vert2s[i];
var dot = tVec.x * normalLocal2X + tVec.y * normalLocal2Y;
if (dot < minDot)
{
minDot = dot;
vertexIndex2 = i;
}
}
//b2Vec2 v1 = poly1->m_position + b2Mul(poly1->m_R, vert1s[edge1]);
tMat = poly1.m_R;
var v1X = poly1.m_position.x + (tMat.col1.x * vert1s[edge1].x + tMat.col2.x * vert1s[edge1].y)
var v1Y = poly1.m_position.y + (tMat.col1.y * vert1s[edge1].x + tMat.col2.y * vert1s[edge1].y)
//b2Vec2 v2 = poly2->m_position + b2Mul(poly2->m_R, vert2s[vertexIndex2]);
tMat = poly2.m_R;
var v2X = poly2.m_position.x + (tMat.col1.x * vert2s[vertexIndex2].x + tMat.col2.x * vert2s[vertexIndex2].y)
var v2Y = poly2.m_position.y + (tMat.col1.y * vert2s[vertexIndex2].x + tMat.col2.y * vert2s[vertexIndex2].y)
//var separation = b2Math.b2Dot( b2Math.SubtractVV( v2, v1 ) , normal);
v2X -= v1X;
v2Y -= v1Y;
//var separation = b2Math.b2Dot( v2 , normal);
var separation = v2X * normalX + v2Y * normalY;
return separation;
};
b2Collision.FindMaxSeparation = function(edgeIndex /*int ptr*/, poly1, poly2, conservative)
{
var count1 = poly1.m_vertexCount;
// Vector pointing from the origin of poly1 to the origin of poly2.
//var d = b2Math.SubtractVV( poly2.m_position, poly1.m_position );
var dX = poly2.m_position.x - poly1.m_position.x;
var dY = poly2.m_position.y - poly1.m_position.y;
//var dLocal1 = b2Math.b2MulTMV(poly1.m_R, d);
var dLocal1X = (dX * poly1.m_R.col1.x + dY * poly1.m_R.col1.y);
var dLocal1Y = (dX * poly1.m_R.col2.x + dY * poly1.m_R.col2.y);
// Get support vertex hint for our search
var edge = 0;
var maxDot = -Number.MAX_VALUE;
for (var i = 0; i < count1; ++i)
{
//var dot = b2Math.b2Dot(poly.m_normals[i], dLocal1);
var dot = (poly1.m_normals[i].x * dLocal1X + poly1.m_normals[i].y * dLocal1Y);
if (dot > maxDot)
{
maxDot = dot;
edge = i;
}
}
// Get the separation for the edge normal.
var s = b2Collision.EdgeSeparation(poly1, edge, poly2);
if (s > 0.0 && conservative == false)
{
return s;
}
// Check the separation for the neighboring edges.
var prevEdge = edge - 1 >= 0 ? edge - 1 : count1 - 1;
var sPrev = b2Collision.EdgeSeparation(poly1, prevEdge, poly2);
if (sPrev > 0.0 && conservative == false)
{
return sPrev;
}
var nextEdge = edge + 1 < count1 ? edge + 1 : 0;
var sNext = b2Collision.EdgeSeparation(poly1, nextEdge, poly2);
if (sNext > 0.0 && conservative == false)
{
return sNext;
}
// Find the best edge and the search direction.
var bestEdge = 0;
var bestSeparation;
var increment = 0;
if (sPrev > s && sPrev > sNext)
{
increment = -1;
bestEdge = prevEdge;
bestSeparation = sPrev;
}
else if (sNext > s)
{
increment = 1;
bestEdge = nextEdge;
bestSeparation = sNext;
}
else
{
// pointer out
edgeIndex[0] = edge;
return s;
}
while (true)
{
if (increment == -1)
edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1;
else
edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0;
s = b2Collision.EdgeSeparation(poly1, edge, poly2);
if (s > 0.0 && conservative == false)
{
return s;
}
if (s > bestSeparation)
{
bestEdge = edge;
bestSeparation = s;
}
else
{
break;
}
}
// pointer out
edgeIndex[0] = bestEdge;
return bestSeparation;
};
b2Collision.FindIncidentEdge = function(c, poly1, edge1, poly2)
{
var count1 = poly1.m_vertexCount;
var vert1s = poly1.m_vertices;
var count2 = poly2.m_vertexCount;
var vert2s = poly2.m_vertices;
// Get the vertices associated with edge1.
var vertex11 = edge1;
var vertex12 = edge1 + 1 == count1 ? 0 : edge1 + 1;
// Get the normal of edge1.
var tVec = vert1s[vertex12];
//var normal1Local1 = b2Math.b2CrossVF( b2Math.SubtractVV( vert1s[vertex12], vert1s[vertex11] ), 1.0);
var normal1Local1X = tVec.x;
var normal1Local1Y = tVec.y;
tVec = vert1s[vertex11];
normal1Local1X -= tVec.x;
normal1Local1Y -= tVec.y;
var tX = normal1Local1X;
normal1Local1X = normal1Local1Y;
normal1Local1Y = -tX;
// ^^^^ normal1Local1.CrossVF(1.0);
var invLength = 1.0 / Math.sqrt(normal1Local1X*normal1Local1X + normal1Local1Y*normal1Local1Y);
normal1Local1X *= invLength;
normal1Local1Y *= invLength;
// ^^^^normal1Local1.Normalize();
//var normal1 = b2Math.b2MulMV(poly1.m_R, normal1Local1);
var normal1X = normal1Local1X;
var normal1Y = normal1Local1Y;
tX = normal1X;
var tMat = poly1.m_R;
normal1X = tMat.col1.x * tX + tMat.col2.x * normal1Y;
normal1Y = tMat.col1.y * tX + tMat.col2.y * normal1Y;
// ^^^^ normal1.MulM(poly1.m_R);
//var normal1Local2 = b2Math.b2MulTMV(poly2.m_R, normal1);
var normal1Local2X = normal1X;
var normal1Local2Y = normal1Y;
tMat = poly2.m_R;
tX = normal1Local2X * tMat.col1.x + normal1Local2Y * tMat.col1.y;
normal1Local2Y = normal1Local2X * tMat.col2.x + normal1Local2Y * tMat.col2.y;
normal1Local2X = tX;
// ^^^^ normal1Local2.MulTM(poly2.m_R);
// Find the incident edge on poly2.
var vertex21 = 0;
var vertex22 = 0;
var minDot = Number.MAX_VALUE;
for (var i = 0; i < count2; ++i)
{
var i1 = i;
var i2 = i + 1 < count2 ? i + 1 : 0;
//var normal2Local2 = b2Math.b2CrossVF( b2Math.SubtractVV( vert2s[i2], vert2s[i1] ), 1.0);
tVec = vert2s[i2];
var normal2Local2X = tVec.x;
var normal2Local2Y = tVec.y;
tVec = vert2s[i1];
normal2Local2X -= tVec.x;
normal2Local2Y -= tVec.y;
tX = normal2Local2X;
normal2Local2X = normal2Local2Y;
normal2Local2Y = -tX;
// ^^^^ normal2Local2.CrossVF(1.0);
invLength = 1.0 / Math.sqrt(normal2Local2X*normal2Local2X + normal2Local2Y*normal2Local2Y);
normal2Local2X *= invLength;
normal2Local2Y *= invLength;
// ^^^^ normal2Local2.Normalize();
//var dot = b2Math.b2Dot(normal2Local2, normal1Local2);
var dot = normal2Local2X * normal1Local2X + normal2Local2Y * normal1Local2Y;
if (dot < minDot)
{
minDot = dot;
vertex21 = i1;
vertex22 = i2;
}
}
var tClip;
// Build the clip vertices for the incident edge.
tClip = c[0];
//tClip.v = b2Math.AddVV(poly2.m_position, b2Math.b2MulMV(poly2.m_R, vert2s[vertex21]));
tVec = tClip.v;
tVec.SetV(vert2s[vertex21]);
tVec.MulM(poly2.m_R);
tVec.Add(poly2.m_position);
tClip.id.features.referenceFace = edge1;
tClip.id.features.incidentEdge = vertex21;
tClip.id.features.incidentVertex = vertex21;
tClip = c[1];
//tClip.v = b2Math.AddVV(poly2.m_position, b2Math.b2MulMV(poly2.m_R, vert2s[vertex22]));
tVec = tClip.v;
tVec.SetV(vert2s[vertex22]);
tVec.MulM(poly2.m_R);
tVec.Add(poly2.m_position);
tClip.id.features.referenceFace = edge1;
tClip.id.features.incidentEdge = vertex21;
tClip.id.features.incidentVertex = vertex22;
};
b2Collision.b2CollidePolyTempVec = new b2Vec2();
b2Collision.b2CollidePoly = function(manifold, polyA, polyB, conservative)
{
manifold.pointCount = 0;
var edgeA = 0;
var edgeAOut = [edgeA];
var separationA = b2Collision.FindMaxSeparation(edgeAOut, polyA, polyB, conservative);
edgeA = edgeAOut[0];
if (separationA > 0.0 && conservative == false)
return;
var edgeB = 0;
var edgeBOut = [edgeB];
var separationB = b2Collision.FindMaxSeparation(edgeBOut, polyB, polyA, conservative);
edgeB = edgeBOut[0];
if (separationB > 0.0 && conservative == false)
return;
var poly1;
var poly2;
var edge1 = 0;
var flip = 0;
var k_relativeTol = 0.98;
var k_absoluteTol = 0.001;
// TODO_ERIN use "radius" of poly for absolute tolerance.
if (separationB > k_relativeTol * separationA + k_absoluteTol)
{
poly1 = polyB;
poly2 = polyA;
edge1 = edgeB;
flip = 1;
}
else
{
poly1 = polyA;
poly2 = polyB;
edge1 = edgeA;
flip = 0;
}
var incidentEdge = [new ClipVertex(), new ClipVertex()];
b2Collision.FindIncidentEdge(incidentEdge, poly1, edge1, poly2);
var count1 = poly1.m_vertexCount;
var vert1s = poly1.m_vertices;
var v11 = vert1s[edge1];
var v12 = edge1 + 1 < count1 ? vert1s[edge1+1] : vert1s[0];
//var dv = b2Math.SubtractVV(v12, v11);
var dvX = v12.x - v11.x;
var dvY = v12.y - v11.y;
//var sideNormal = b2Math.b2MulMV(poly1.m_R, b2Math.SubtractVV(v12, v11));
var sideNormalX = v12.x - v11.x;
var sideNormalY = v12.y - v11.y;
var tX = sideNormalX;
var tMat = poly1.m_R;
sideNormalX = tMat.col1.x * tX + tMat.col2.x * sideNormalY;
sideNormalY = tMat.col1.y * tX + tMat.col2.y * sideNormalY;
// ^^^^ sideNormal.MulM(poly1.m_R);
var invLength = 1.0 / Math.sqrt(sideNormalX*sideNormalX + sideNormalY*sideNormalY);
sideNormalX *= invLength;
sideNormalY *= invLength;
// ^^^^ sideNormal.Normalize();
//var frontNormal = b2Math.b2CrossVF(sideNormal, 1.0);
var frontNormalX = sideNormalX;
var frontNormalY = sideNormalY;
tX = frontNormalX;
frontNormalX = frontNormalY;
frontNormalY = -tX;
// ^^^^ frontNormal.CrossVF(1.0);
// Expanded for performance
//v11 = b2Math.AddVV(poly1.m_position, b2Math.b2MulMV(poly1.m_R, v11));
var v11X = v11.x;
var v11Y = v11.y;
tX = v11X;
tMat = poly1.m_R;
v11X = tMat.col1.x * tX + tMat.col2.x * v11Y;
v11Y = tMat.col1.y * tX + tMat.col2.y * v11Y;
// ^^^^ v11.MulM(poly1.m_R);
v11X += poly1.m_position.x;
v11Y += poly1.m_position.y;
//v12 = b2Math.AddVV(poly1.m_position, b2Math.b2MulMV(poly1.m_R, v12));
var v12X = v12.x;
var v12Y = v12.y;
tX = v12X;
tMat = poly1.m_R;
v12X = tMat.col1.x * tX + tMat.col2.x * v12Y;
v12Y = tMat.col1.y * tX + tMat.col2.y * v12Y;
// ^^^^ v12.MulM(poly1.m_R);
v12X += poly1.m_position.x;
v12Y += poly1.m_position.y;
//var frontOffset = b2Math.b2Dot(frontNormal, v11);
var frontOffset = frontNormalX * v11X + frontNormalY * v11Y;
//var sideOffset1 = -b2Math.b2Dot(sideNormal, v11);
var sideOffset1 = -(sideNormalX * v11X + sideNormalY * v11Y);
//var sideOffset2 = b2Math.b2Dot(sideNormal, v12);
var sideOffset2 = sideNormalX * v12X + sideNormalY * v12Y;
// Clip incident edge against extruded edge1 side edges.
var clipPoints1 = [new ClipVertex(), new ClipVertex()];
var clipPoints2 = [new ClipVertex(), new ClipVertex()];
var np = 0;
// Clip to box side 1
b2Collision.b2CollidePolyTempVec.Set(-sideNormalX, -sideNormalY);
np = b2Collision.ClipSegmentToLine(clipPoints1, incidentEdge, b2Collision.b2CollidePolyTempVec, sideOffset1);
if (np < 2)
return;
// Clip to negative box side 1
b2Collision.b2CollidePolyTempVec.Set(sideNormalX, sideNormalY);
np = b2Collision.ClipSegmentToLine(clipPoints2, clipPoints1, b2Collision.b2CollidePolyTempVec, sideOffset2);
if (np < 2)
return;
// Now clipPoints2 contains the clipped points.
if (flip){
manifold.normal.Set(-frontNormalX, -frontNormalY);
}
else{
manifold.normal.Set(frontNormalX, frontNormalY);
}
// ^^^^ manifold.normal = flip ? frontNormal.Negative() : frontNormal;
var pointCount = 0;
for (var i = 0; i < b2Settings.b2_maxManifoldPoints; ++i)
{
//var separation = b2Math.b2Dot(frontNormal, clipPoints2[i].v) - frontOffset;
var tVec = clipPoints2[i].v;
var separation = (frontNormalX * tVec.x + frontNormalY * tVec.y) - frontOffset;
if (separation <= 0.0 || conservative == true)
{
var cp = manifold.points[ pointCount ];
cp.separation = separation;
cp.position.SetV( clipPoints2[i].v );
cp.id.Set( clipPoints2[i].id );
cp.id.features.flip = flip;
++pointCount;
}
}
manifold.pointCount = pointCount;
};
b2Collision.b2CollideCircle = function(manifold, circle1, circle2, conservative)
{
manifold.pointCount = 0;
//var d = b2Math.SubtractVV(circle2.m_position, circle1.m_position);
var dX = circle2.m_position.x - circle1.m_position.x;
var dY = circle2.m_position.y - circle1.m_position.y;
//var distSqr = b2Math.b2Dot(d, d);
var distSqr = dX * dX + dY * dY;
var radiusSum = circle1.m_radius + circle2.m_radius;
if (distSqr > radiusSum * radiusSum && conservative == false)
{
return;
}
var separation;
if (distSqr < Number.MIN_VALUE)
{
separation = -radiusSum;
manifold.normal.Set(0.0, 1.0);
}
else
{
var dist = Math.sqrt(distSqr);
separation = dist - radiusSum;
var a = 1.0 / dist;
manifold.normal.x = a * dX;
manifold.normal.y = a * dY;
}
manifold.pointCount = 1;
var tPoint = manifold.points[0];
tPoint.id.set_key(0);
tPoint.separation = separation;
//tPoint.position = b2Math.SubtractVV(circle2.m_position, b2Math.MulFV(circle2.m_radius, manifold.normal));
tPoint.position.x = circle2.m_position.x - (circle2.m_radius * manifold.normal.x);
tPoint.position.y = circle2.m_position.y - (circle2.m_radius * manifold.normal.y);
};
b2Collision.b2CollidePolyAndCircle = function(manifold, poly, circle, conservative)
{
manifold.pointCount = 0;
var tPoint;
var dX;
var dY;
// Compute circle position in the frame of the polygon.
//var xLocal = b2Math.b2MulTMV(poly.m_R, b2Math.SubtractVV(circle.m_position, poly.m_position));
var xLocalX = circle.m_position.x - poly.m_position.x;
var xLocalY = circle.m_position.y - poly.m_position.y;
var tMat = poly.m_R;
var tX = xLocalX * tMat.col1.x + xLocalY * tMat.col1.y;
xLocalY = xLocalX * tMat.col2.x + xLocalY * tMat.col2.y;
xLocalX = tX;
var dist;
// Find the min separating edge.
var normalIndex = 0;
var separation = -Number.MAX_VALUE;
var radius = circle.m_radius;
for (var i = 0; i < poly.m_vertexCount; ++i)
{
//var s = b2Math.b2Dot(poly.m_normals[i], b2Math.SubtractVV(xLocal, poly.m_vertices[i]));
var s = poly.m_normals[i].x * (xLocalX-poly.m_vertices[i].x) + poly.m_normals[i].y * (xLocalY-poly.m_vertices[i].y);
if (s > radius)
{
// Early out.
return;
}
if (s > separation)
{
separation = s;
normalIndex = i;
}
}
// If the center is inside the polygon ...
if (separation < Number.MIN_VALUE)
{
manifold.pointCount = 1;
//manifold.normal = b2Math.b2MulMV(poly.m_R, poly.m_normals[normalIndex]);
var tVec = poly.m_normals[normalIndex];
manifold.normal.x = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
manifold.normal.y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
tPoint = manifold.points[0];
tPoint.id.features.incidentEdge = normalIndex;
tPoint.id.features.incidentVertex = b2Collision.b2_nullFeature;
tPoint.id.features.referenceFace = b2Collision.b2_nullFeature;
tPoint.id.features.flip = 0;
tPoint.position.x = circle.m_position.x - radius * manifold.normal.x;
tPoint.position.y = circle.m_position.y - radius * manifold.normal.y;
//tPoint.position = b2Math.SubtractVV(circle.m_position , b2Math.MulFV(radius , manifold.normal));
tPoint.separation = separation - radius;
return;
}
// Project the circle center onto the edge segment.
var vertIndex1 = normalIndex;
var vertIndex2 = vertIndex1 + 1 < poly.m_vertexCount ? vertIndex1 + 1 : 0;
//var e = b2Math.SubtractVV(poly.m_vertices[vertIndex2] , poly.m_vertices[vertIndex1]);
var eX = poly.m_vertices[vertIndex2].x - poly.m_vertices[vertIndex1].x;
var eY = poly.m_vertices[vertIndex2].y - poly.m_vertices[vertIndex1].y;
//var length = e.Normalize();
var length = Math.sqrt(eX*eX + eY*eY);
eX /= length;
eY /= length;
// If the edge length is zero ...
if (length < Number.MIN_VALUE)
{
//d = b2Math.SubtractVV(xLocal , poly.m_vertices[vertIndex1]);
dX = xLocalX - poly.m_vertices[vertIndex1].x;
dY = xLocalY - poly.m_vertices[vertIndex1].y;
//dist = d.Normalize();
dist = Math.sqrt(dX*dX + dY*dY);
dX /= dist;
dY /= dist;
if (dist > radius)
{
return;
}
manifold.pointCount = 1;
//manifold.normal = b2Math.b2MulMV(poly.m_R, d);
manifold.normal.Set(tMat.col1.x * dX + tMat.col2.x * dY, tMat.col1.y * dX + tMat.col2.y * dY);
tPoint = manifold.points[0];
tPoint.id.features.incidentEdge = b2Collision.b2_nullFeature;
tPoint.id.features.incidentVertex = vertIndex1;
tPoint.id.features.referenceFace = b2Collision.b2_nullFeature;
tPoint.id.features.flip = 0;
//tPoint.position = b2Math.SubtractVV(circle.m_position , b2Math.MulFV(radius , manifold.normal));
tPoint.position.x = circle.m_position.x - radius * manifold.normal.x;
tPoint.position.y = circle.m_position.y - radius * manifold.normal.y;
tPoint.separation = dist - radius;
return;
}
// Project the center onto the edge.
//var u = b2Math.b2Dot(b2Math.SubtractVV(xLocal , poly.m_vertices[vertIndex1]) , e);
var u = (xLocalX-poly.m_vertices[vertIndex1].x) * eX + (xLocalY-poly.m_vertices[vertIndex1].y) * eY;
tPoint = manifold.points[0];
tPoint.id.features.incidentEdge = b2Collision.b2_nullFeature;
tPoint.id.features.incidentVertex = b2Collision.b2_nullFeature;
tPoint.id.features.referenceFace = b2Collision.b2_nullFeature;
tPoint.id.features.flip = 0;
var pX, pY;
if (u <= 0.0)
{
pX = poly.m_vertices[vertIndex1].x;
pY = poly.m_vertices[vertIndex1].y;
tPoint.id.features.incidentVertex = vertIndex1;
}
else if (u >= length)
{
pX = poly.m_vertices[vertIndex2].x;
pY = poly.m_vertices[vertIndex2].y;
tPoint.id.features.incidentVertex = vertIndex2;
}
else
{
//p = b2Math.AddVV(poly.m_vertices[vertIndex1] , b2Math.MulFV(u, e));
pX = eX * u + poly.m_vertices[vertIndex1].x;
pY = eY * u + poly.m_vertices[vertIndex1].y;
tPoint.id.features.incidentEdge = vertIndex1;
}
//d = b2Math.SubtractVV(xLocal , p);
dX = xLocalX - pX;
dY = xLocalY - pY;
//dist = d.Normalize();
dist = Math.sqrt(dX*dX + dY*dY);
dX /= dist;
dY /= dist;
if (dist > radius)
{
return;
}
manifold.pointCount = 1;
//manifold.normal = b2Math.b2MulMV(poly.m_R, d);
manifold.normal.Set(tMat.col1.x * dX + tMat.col2.x * dY, tMat.col1.y * dX + tMat.col2.y * dY);
//tPoint.position = b2Math.SubtractVV(circle.m_position , b2Math.MulFV(radius , manifold.normal));
tPoint.position.x = circle.m_position.x - radius * manifold.normal.x;
tPoint.position.y = circle.m_position.y - radius * manifold.normal.y;
tPoint.separation = dist - radius;
};
b2Collision.b2TestOverlap = function(a, b)
{
var t1 = b.minVertex;
var t2 = a.maxVertex;
//d1 = b2Math.SubtractVV(b.minVertex, a.maxVertex);
var d1X = t1.x - t2.x;
var d1Y = t1.y - t2.y;
//d2 = b2Math.SubtractVV(a.minVertex, b.maxVertex);
t1 = a.minVertex;
t2 = b.maxVertex;
var d2X = t1.x - t2.x;
var d2Y = t1.y - t2.y;
if (d1X > 0.0 || d1Y > 0.0)
return false;
if (d2X > 0.0 || d2Y > 0.0)
return false;
return true;
};

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
// We use contact ids to facilitate warm starting.
var b2ContactID = Class.create();
b2ContactID.prototype =
{
initialize: function(){
// initialize instance variables for references
this.features = new Features();
//
this.features._m_id = this;
},
Set: function(id){
this.set_key(id._key);
},
Copy: function(){
var id = new b2ContactID();
id.set_key(this._key);
return id;
},
get_key: function(){
return this._key;
},
set_key: function(value) {
this._key = value;
this.features._referenceFace = this._key & 0x000000ff;
this.features._incidentEdge = ((this._key & 0x0000ff00) >> 8) & 0x000000ff;
this.features._incidentVertex = ((this._key & 0x00ff0000) >> 16) & 0x000000ff;
this.features._flip = ((this._key & 0xff000000) >> 24) & 0x000000ff;
},
features: new Features(),
_key: 0};

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
// We use contact ids to facilitate warm starting.
var b2ContactPoint = Class.create();
b2ContactPoint.prototype =
{
position: new b2Vec2(),
separation: null,
normalImpulse: null,
tangentImpulse: null,
id: new b2ContactID(),
initialize: function() {
// initialize instance variables for references
this.position = new b2Vec2();
this.id = new b2ContactID();
//
}};

View file

@ -0,0 +1,333 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2Distance = Class.create();
b2Distance.prototype =
{
// GJK using Voronoi regions (Christer Ericson) and region selection
// optimizations (Casey Muratori).
// The origin is either in the region of points[1] or in the edge region. The origin is
// not in region of points[0] because that is the old point.
// Possible regions:
// - points[2]
// - edge points[0]-points[2]
// - edge points[1]-points[2]
// - inside the triangle
initialize: function() {}};
b2Distance.ProcessTwo = function(p1Out, p2Out, p1s, p2s, points)
{
// If in point[1] region
//b2Vec2 r = -points[1];
var rX = -points[1].x;
var rY = -points[1].y;
//b2Vec2 d = points[1] - points[0];
var dX = points[0].x - points[1].x;
var dY = points[0].y - points[1].y;
//float32 length = d.Normalize();
var length = Math.sqrt(dX*dX + dY*dY);
dX /= length;
dY /= length;
//float32 lambda = b2Dot(r, d);
var lambda = rX * dX + rY * dY;
if (lambda <= 0.0 || length < Number.MIN_VALUE)
{
// The simplex is reduced to a point.
//*p1Out = p1s[1];
p1Out.SetV(p1s[1]);
//*p2Out = p2s[1];
p2Out.SetV(p2s[1]);
//p1s[0] = p1s[1];
p1s[0].SetV(p1s[1]);
//p2s[0] = p2s[1];
p2s[0].SetV(p2s[1]);
points[0].SetV(points[1]);
return 1;
}
// Else in edge region
lambda /= length;
//*p1Out = p1s[1] + lambda * (p1s[0] - p1s[1]);
p1Out.x = p1s[1].x + lambda * (p1s[0].x - p1s[1].x);
p1Out.y = p1s[1].y + lambda * (p1s[0].y - p1s[1].y);
//*p2Out = p2s[1] + lambda * (p2s[0] - p2s[1]);
p2Out.x = p2s[1].x + lambda * (p2s[0].x - p2s[1].x);
p2Out.y = p2s[1].y + lambda * (p2s[0].y - p2s[1].y);
return 2;
};
b2Distance.ProcessThree = function(p1Out, p2Out, p1s, p2s, points)
{
//b2Vec2 a = points[0];
var aX = points[0].x;
var aY = points[0].y;
//b2Vec2 b = points[1];
var bX = points[1].x;
var bY = points[1].y;
//b2Vec2 c = points[2];
var cX = points[2].x;
var cY = points[2].y;
//b2Vec2 ab = b - a;
var abX = bX - aX;
var abY = bY - aY;
//b2Vec2 ac = c - a;
var acX = cX - aX;
var acY = cY - aY;
//b2Vec2 bc = c - b;
var bcX = cX - bX;
var bcY = cY - bY;
//float32 sn = -b2Dot(a, ab), sd = b2Dot(b, ab);
var sn = -(aX * abX + aY * abY);
var sd = (bX * abX + bY * abY);
//float32 tn = -b2Dot(a, ac), td = b2Dot(c, ac);
var tn = -(aX * acX + aY * acY);
var td = (cX * acX + cY * acY);
//float32 un = -b2Dot(b, bc), ud = b2Dot(c, bc);
var un = -(bX * bcX + bY * bcY);
var ud = (cX * bcX + cY * bcY);
// In vertex c region?
if (td <= 0.0 && ud <= 0.0)
{
// Single point
//*p1Out = p1s[2];
p1Out.SetV(p1s[2]);
//*p2Out = p2s[2];
p2Out.SetV(p2s[2]);
//p1s[0] = p1s[2];
p1s[0].SetV(p1s[2]);
//p2s[0] = p2s[2];
p2s[0].SetV(p2s[2]);
points[0].SetV(points[2]);
return 1;
}
// Should not be in vertex a or b region.
//b2Settings.b2Assert(sn > 0.0 || tn > 0.0);
//b2Settings.b2Assert(sd > 0.0 || un > 0.0);
//float32 n = b2Cross(ab, ac);
var n = abX * acY - abY * acX;
// Should not be in edge ab region.
//float32 vc = n * b2Cross(a, b);
var vc = n * (aX * bY - aY * bX);
//b2Settings.b2Assert(vc > 0.0 || sn > 0.0 || sd > 0.0);
// In edge bc region?
//float32 va = n * b2Cross(b, c);
var va = n * (bX * cY - bY * cX);
if (va <= 0.0 && un >= 0.0 && ud >= 0.0)
{
//b2Settings.b2Assert(un + ud > 0.0);
//float32 lambda = un / (un + ud);
var lambda = un / (un + ud);
//*p1Out = p1s[1] + lambda * (p1s[2] - p1s[1]);
p1Out.x = p1s[1].x + lambda * (p1s[2].x - p1s[1].x);
p1Out.y = p1s[1].y + lambda * (p1s[2].y - p1s[1].y);
//*p2Out = p2s[1] + lambda * (p2s[2] - p2s[1]);
p2Out.x = p2s[1].x + lambda * (p2s[2].x - p2s[1].x);
p2Out.y = p2s[1].y + lambda * (p2s[2].y - p2s[1].y);
//p1s[0] = p1s[2];
p1s[0].SetV(p1s[2]);
//p2s[0] = p2s[2];
p2s[0].SetV(p2s[2]);
//points[0] = points[2];
points[0].SetV(points[2]);
return 2;
}
// In edge ac region?
//float32 vb = n * b2Cross(c, a);
var vb = n * (cX * aY - cY * aX);
if (vb <= 0.0 && tn >= 0.0 && td >= 0.0)
{
//b2Settings.b2Assert(tn + td > 0.0);
//float32 lambda = tn / (tn + td);
var lambda = tn / (tn + td);
//*p1Out = p1s[0] + lambda * (p1s[2] - p1s[0]);
p1Out.x = p1s[0].x + lambda * (p1s[2].x - p1s[0].x);
p1Out.y = p1s[0].y + lambda * (p1s[2].y - p1s[0].y);
//*p2Out = p2s[0] + lambda * (p2s[2] - p2s[0]);
p2Out.x = p2s[0].x + lambda * (p2s[2].x - p2s[0].x);
p2Out.y = p2s[0].y + lambda * (p2s[2].y - p2s[0].y);
//p1s[1] = p1s[2];
p1s[1].SetV(p1s[2]);
//p2s[1] = p2s[2];
p2s[1].SetV(p2s[2]);
//points[1] = points[2];
points[1].SetV(points[2]);
return 2;
}
// Inside the triangle, compute barycentric coordinates
//float32 denom = va + vb + vc;
var denom = va + vb + vc;
//b2Settings.b2Assert(denom > 0.0);
denom = 1.0 / denom;
//float32 u = va * denom;
var u = va * denom;
//float32 v = vb * denom;
var v = vb * denom;
//float32 w = 1.0f - u - v;
var w = 1.0 - u - v;
//*p1Out = u * p1s[0] + v * p1s[1] + w * p1s[2];
p1Out.x = u * p1s[0].x + v * p1s[1].x + w * p1s[2].x;
p1Out.y = u * p1s[0].y + v * p1s[1].y + w * p1s[2].y;
//*p2Out = u * p2s[0] + v * p2s[1] + w * p2s[2];
p2Out.x = u * p2s[0].x + v * p2s[1].x + w * p2s[2].x;
p2Out.y = u * p2s[0].y + v * p2s[1].y + w * p2s[2].y;
return 3;
};
b2Distance.InPoinsts = function(w, points, pointCount)
{
for (var i = 0; i < pointCount; ++i)
{
if (w.x == points[i].x && w.y == points[i].y)
{
return true;
}
}
return false;
};
b2Distance.Distance = function(p1Out, p2Out, shape1, shape2)
{
//b2Vec2 p1s[3], p2s[3];
var p1s = new Array(3);
var p2s = new Array(3);
//b2Vec2 points[3];
var points = new Array(3);
//int32 pointCount = 0;
var pointCount = 0;
//*p1Out = shape1->m_position;
p1Out.SetV(shape1.m_position);
//*p2Out = shape2->m_position;
p2Out.SetV(shape2.m_position);
var vSqr = 0.0;
var maxIterations = 20;
for (var iter = 0; iter < maxIterations; ++iter)
{
//b2Vec2 v = *p2Out - *p1Out;
var vX = p2Out.x - p1Out.x;
var vY = p2Out.y - p1Out.y;
//b2Vec2 w1 = shape1->Support(v);
var w1 = shape1.Support(vX, vY);
//b2Vec2 w2 = shape2->Support(-v);
var w2 = shape2.Support(-vX, -vY);
//float32 vSqr = b2Dot(v, v);
vSqr = (vX*vX + vY*vY);
//b2Vec2 w = w2 - w1;
var wX = w2.x - w1.x;
var wY = w2.y - w1.y;
//float32 vw = b2Dot(v, w);
var vw = (vX*wX + vY*wY);
//if (vSqr - b2Dot(v, w) <= 0.01f * vSqr)
if (vSqr - b2Dot(vX * wX + vY * wY) <= 0.01 * vSqr)
{
if (pointCount == 0)
{
//*p1Out = w1;
p1Out.SetV(w1);
//*p2Out = w2;
p2Out.SetV(w2);
}
b2Distance.g_GJK_Iterations = iter;
return Math.sqrt(vSqr);
}
switch (pointCount)
{
case 0:
//p1s[0] = w1;
p1s[0].SetV(w1);
//p2s[0] = w2;
p2s[0].SetV(w2);
points[0] = w;
//*p1Out = p1s[0];
p1Out.SetV(p1s[0]);
//*p2Out = p2s[0];
p2Out.SetV(p2s[0]);
++pointCount;
break;
case 1:
//p1s[1] = w1;
p1s[1].SetV(w1);
//p2s[1] = w2;
p2s[1].SetV(w2);
//points[1] = w;
points[1].x = wX;
points[1].y = wY;
pointCount = b2Distance.ProcessTwo(p1Out, p2Out, p1s, p2s, points);
break;
case 2:
//p1s[2] = w1;
p1s[2].SetV(w1);
//p2s[2] = w2;
p2s[2].SetV(w2);
//points[2] = w;
points[2].x = wX;
points[2].y = wY;
pointCount = b2Distance.ProcessThree(p1Out, p2Out, p1s, p2s, points);
break;
}
// If we have three points, then the origin is in the corresponding triangle.
if (pointCount == 3)
{
b2Distance.g_GJK_Iterations = iter;
return 0.0;
}
//float32 maxSqr = -FLT_MAX;
var maxSqr = -Number.MAX_VALUE;
for (var i = 0; i < pointCount; ++i)
{
//maxSqr = b2Math.b2Max(maxSqr, b2Dot(points[i], points[i]));
maxSqr = b2Math.b2Max(maxSqr, (points[i].x*points[i].x + points[i].y*points[i].y));
}
if (pointCount == 3 || vSqr <= 100.0 * Number.MIN_VALUE * maxSqr)
{
b2Distance.g_GJK_Iterations = iter;
return Math.sqrt(vSqr);
}
}
b2Distance.g_GJK_Iterations = maxIterations;
return Math.sqrt(vSqr);
};
b2Distance.g_GJK_Iterations = 0;

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
// A manifold for two touching convex shapes.
var b2Manifold = Class.create();
b2Manifold.prototype =
{
initialize: function(){
this.points = new Array(b2Settings.b2_maxManifoldPoints);
for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++){
this.points[i] = new b2ContactPoint();
}
this.normal = new b2Vec2();
},
points: null,
normal: null,
pointCount: 0};

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
// A manifold for two touching convex shapes.
var b2OBB = Class.create();
b2OBB.prototype =
{
R: new b2Mat22(),
center: new b2Vec2(),
extents: new b2Vec2(),
initialize: function() {
// initialize instance variables for references
this.R = new b2Mat22();
this.center = new b2Vec2();
this.extents = new b2Vec2();
//
}};

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
// The pair manager is used by the broad-phase to quickly add/remove/find pairs
// of overlapping proxies. It is based closely on code provided by Pierre Terdiman.
// http:
var b2Pair = Class.create();
b2Pair.prototype =
{
SetBuffered: function() { this.status |= b2Pair.e_pairBuffered; },
ClearBuffered: function() { this.status &= ~b2Pair.e_pairBuffered; },
IsBuffered: function(){ return (this.status & b2Pair.e_pairBuffered) == b2Pair.e_pairBuffered; },
SetRemoved: function() { this.status |= b2Pair.e_pairRemoved; },
ClearRemoved: function() { this.status &= ~b2Pair.e_pairRemoved; },
IsRemoved: function(){ return (this.status & b2Pair.e_pairRemoved) == b2Pair.e_pairRemoved; },
SetFinal: function() { this.status |= b2Pair.e_pairFinal; },
IsFinal: function(){ return (this.status & b2Pair.e_pairFinal) == b2Pair.e_pairFinal; },
userData: null,
proxyId1: 0,
proxyId2: 0,
next: 0,
status: 0,
// STATIC
// enum
initialize: function() {}};
b2Pair.b2_nullPair = b2Settings.USHRT_MAX;
b2Pair.b2_nullProxy = b2Settings.USHRT_MAX;
b2Pair.b2_tableCapacity = b2Settings.b2_maxPairs;
b2Pair.b2_tableMask = b2Pair.b2_tableCapacity - 1;
b2Pair.e_pairBuffered = 0x0001;
b2Pair.e_pairRemoved = 0x0002;
b2Pair.e_pairFinal = 0x0004;

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2PairCallback = Class.create();
b2PairCallback.prototype =
{
//virtual ~b2PairCallback() {}
// This returns the new pair user data.
PairAdded: function(proxyUserData1, proxyUserData2){return null},
// This should free the pair's user data. In extreme circumstances, it is possible
// this will be called with null pairUserData because the pair never existed.
PairRemoved: function(proxyUserData1, proxyUserData2, pairUserData){},
initialize: function() {}};

View file

@ -0,0 +1,386 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
// The pair manager is used by the broad-phase to quickly add/remove/find pairs
// of overlapping proxies. It is based closely on code provided by Pierre Terdiman.
// http:
var b2PairManager = Class.create();
b2PairManager.prototype =
{
//public:
initialize: function(){
var i = 0;
//b2Settings.b2Assert(b2Math.b2IsPowerOfTwo(b2Pair.b2_tableCapacity) == true);
//b2Settings.b2Assert(b2Pair.b2_tableCapacity >= b2Settings.b2_maxPairs);
this.m_hashTable = new Array(b2Pair.b2_tableCapacity);
for (i = 0; i < b2Pair.b2_tableCapacity; ++i)
{
this.m_hashTable[i] = b2Pair.b2_nullPair;
}
this.m_pairs = new Array(b2Settings.b2_maxPairs);
for (i = 0; i < b2Settings.b2_maxPairs; ++i)
{
this.m_pairs[i] = new b2Pair();
}
this.m_pairBuffer = new Array(b2Settings.b2_maxPairs);
for (i = 0; i < b2Settings.b2_maxPairs; ++i)
{
this.m_pairBuffer[i] = new b2BufferedPair();
}
for (i = 0; i < b2Settings.b2_maxPairs; ++i)
{
this.m_pairs[i].proxyId1 = b2Pair.b2_nullProxy;
this.m_pairs[i].proxyId2 = b2Pair.b2_nullProxy;
this.m_pairs[i].userData = null;
this.m_pairs[i].status = 0;
this.m_pairs[i].next = (i + 1);
}
this.m_pairs[b2Settings.b2_maxPairs-1].next = b2Pair.b2_nullPair;
this.m_pairCount = 0;
},
//~b2PairManager();
Initialize: function(broadPhase, callback){
this.m_broadPhase = broadPhase;
this.m_callback = callback;
},
/*
As proxies are created and moved, many pairs are created and destroyed. Even worse, the same
pair may be added and removed multiple times in a single time step of the physics engine. To reduce
traffic in the pair manager, we try to avoid destroying pairs in the pair manager until the
end of the physics step. This is done by buffering all the this.RemovePair requests. this.AddPair
requests are processed immediately because we need the hash table entry for quick lookup.
All user user callbacks are delayed until the buffered pairs are confirmed in this.Commit.
This is very important because the user callbacks may be very expensive and client logic
may be harmed if pairs are added and removed within the same time step.
Buffer a pair for addition.
We may add a pair that is not in the pair manager or pair buffer.
We may add a pair that is already in the pair manager and pair buffer.
If the added pair is not a new pair, then it must be in the pair buffer (because this.RemovePair was called).
*/
AddBufferedPair: function(proxyId1, proxyId2){
//b2Settings.b2Assert(id1 != b2_nullProxy && id2 != b2_nullProxy);
//b2Settings.b2Assert(this.m_pairBufferCount < b2_maxPairs);
var pair = this.AddPair(proxyId1, proxyId2);
// If this pair is not in the pair buffer ...
if (pair.IsBuffered() == false)
{
// This must be a newly added pair.
//b2Settings.b2Assert(pair.IsFinal() == false);
// Add it to the pair buffer.
pair.SetBuffered();
this.m_pairBuffer[this.m_pairBufferCount].proxyId1 = pair.proxyId1;
this.m_pairBuffer[this.m_pairBufferCount].proxyId2 = pair.proxyId2;
++this.m_pairBufferCount;
//b2Settings.b2Assert(this.m_pairBufferCount <= this.m_pairCount);
}
// Confirm this pair for the subsequent call to this.Commit.
pair.ClearRemoved();
if (b2BroadPhase.s_validate)
{
this.ValidateBuffer();
}
},
// Buffer a pair for removal.
RemoveBufferedPair: function(proxyId1, proxyId2){
//b2Settings.b2Assert(id1 != b2_nullProxy && id2 != b2_nullProxy);
//b2Settings.b2Assert(this.m_pairBufferCount < b2_maxPairs);
var pair = this.Find(proxyId1, proxyId2);
if (pair == null)
{
// The pair never existed. This is legal (due to collision filtering).
return;
}
// If this pair is not in the pair buffer ...
if (pair.IsBuffered() == false)
{
// This must be an old pair.
//b2Settings.b2Assert(pair.IsFinal() == true);
pair.SetBuffered();
this.m_pairBuffer[this.m_pairBufferCount].proxyId1 = pair.proxyId1;
this.m_pairBuffer[this.m_pairBufferCount].proxyId2 = pair.proxyId2;
++this.m_pairBufferCount;
//b2Settings.b2Assert(this.m_pairBufferCount <= this.m_pairCount);
}
pair.SetRemoved();
if (b2BroadPhase.s_validate)
{
this.ValidateBuffer();
}
},
Commit: function(){
var i = 0;
var removeCount = 0;
var proxies = this.m_broadPhase.m_proxyPool;
for (i = 0; i < this.m_pairBufferCount; ++i)
{
var pair = this.Find(this.m_pairBuffer[i].proxyId1, this.m_pairBuffer[i].proxyId2);
//b2Settings.b2Assert(pair.IsBuffered());
pair.ClearBuffered();
//b2Settings.b2Assert(pair.proxyId1 < b2Settings.b2_maxProxies && pair.proxyId2 < b2Settings.b2_maxProxies);
var proxy1 = proxies[ pair.proxyId1 ];
var proxy2 = proxies[ pair.proxyId2 ];
//b2Settings.b2Assert(proxy1.IsValid());
//b2Settings.b2Assert(proxy2.IsValid());
if (pair.IsRemoved())
{
// It is possible a pair was added then removed before a commit. Therefore,
// we should be careful not to tell the user the pair was removed when the
// the user didn't receive a matching add.
if (pair.IsFinal() == true)
{
this.m_callback.PairRemoved(proxy1.userData, proxy2.userData, pair.userData);
}
// Store the ids so we can actually remove the pair below.
this.m_pairBuffer[removeCount].proxyId1 = pair.proxyId1;
this.m_pairBuffer[removeCount].proxyId2 = pair.proxyId2;
++removeCount;
}
else
{
//b2Settings.b2Assert(this.m_broadPhase.TestOverlap(proxy1, proxy2) == true);
if (pair.IsFinal() == false)
{
pair.userData = this.m_callback.PairAdded(proxy1.userData, proxy2.userData);
pair.SetFinal();
}
}
}
for (i = 0; i < removeCount; ++i)
{
this.RemovePair(this.m_pairBuffer[i].proxyId1, this.m_pairBuffer[i].proxyId2);
}
this.m_pairBufferCount = 0;
if (b2BroadPhase.s_validate)
{
this.ValidateTable();
}
},
//private:
// Add a pair and return the new pair. If the pair already exists,
// no new pair is created and the old one is returned.
AddPair: function(proxyId1, proxyId2){
if (proxyId1 > proxyId2){
var temp = proxyId1;
proxyId1 = proxyId2;
proxyId2 = temp;
//b2Math.b2Swap(p1, p2);
}
var hash = b2PairManager.Hash(proxyId1, proxyId2) & b2Pair.b2_tableMask;
//var pairIndex = this.FindHash(proxyId1, proxyId2, hash);
var pair = pair = this.FindHash(proxyId1, proxyId2, hash);
if (pair != null)
{
return pair;
}
//b2Settings.b2Assert(this.m_pairCount < b2Settings.b2_maxPairs && this.m_freePair != b2_nullPair);
var pIndex = this.m_freePair;
pair = this.m_pairs[pIndex];
this.m_freePair = pair.next;
pair.proxyId1 = proxyId1;
pair.proxyId2 = proxyId2;
pair.status = 0;
pair.userData = null;
pair.next = this.m_hashTable[hash];
this.m_hashTable[hash] = pIndex;
++this.m_pairCount;
return pair;
},
// Remove a pair, return the pair's userData.
RemovePair: function(proxyId1, proxyId2){
//b2Settings.b2Assert(this.m_pairCount > 0);
if (proxyId1 > proxyId2){
var temp = proxyId1;
proxyId1 = proxyId2;
proxyId2 = temp;
//b2Math.b2Swap(proxyId1, proxyId2);
}
var hash = b2PairManager.Hash(proxyId1, proxyId2) & b2Pair.b2_tableMask;
var node = this.m_hashTable[hash];
var pNode = null;
while (node != b2Pair.b2_nullPair)
{
if (b2PairManager.Equals(this.m_pairs[node], proxyId1, proxyId2))
{
var index = node;
//*node = this.m_pairs[*node].next;
if (pNode){
pNode.next = this.m_pairs[node].next;
}
else{
this.m_hashTable[hash] = this.m_pairs[node].next;
}
var pair = this.m_pairs[ index ];
var userData = pair.userData;
// Scrub
pair.next = this.m_freePair;
pair.proxyId1 = b2Pair.b2_nullProxy;
pair.proxyId2 = b2Pair.b2_nullProxy;
pair.userData = null;
pair.status = 0;
this.m_freePair = index;
--this.m_pairCount;
return userData;
}
else
{
//node = &this.m_pairs[*node].next;
pNode = this.m_pairs[node];
node = pNode.next;
}
}
//b2Settings.b2Assert(false);
return null;
},
Find: function(proxyId1, proxyId2){
if (proxyId1 > proxyId2){
var temp = proxyId1;
proxyId1 = proxyId2;
proxyId2 = temp;
//b2Math.b2Swap(proxyId1, proxyId2);
}
var hash = b2PairManager.Hash(proxyId1, proxyId2) & b2Pair.b2_tableMask;
return this.FindHash(proxyId1, proxyId2, hash);
},
FindHash: function(proxyId1, proxyId2, hash){
var index = this.m_hashTable[hash];
while( index != b2Pair.b2_nullPair && b2PairManager.Equals(this.m_pairs[index], proxyId1, proxyId2) == false)
{
index = this.m_pairs[index].next;
}
if ( index == b2Pair.b2_nullPair )
{
return null;
}
//b2Settings.b2Assert(index < b2_maxPairs);
return this.m_pairs[ index ];
},
ValidateBuffer: function(){
// DEBUG
},
ValidateTable: function(){
// DEBUG
},
//public:
m_broadPhase: null,
m_callback: null,
m_pairs: null,
m_freePair: 0,
m_pairCount: 0,
m_pairBuffer: null,
m_pairBufferCount: 0,
m_hashTable: null
// static
// Thomas Wang's hash, see: http:
};
b2PairManager.Hash = function(proxyId1, proxyId2)
{
var key = ((proxyId2 << 16) & 0xffff0000) | proxyId1;
key = ~key + ((key << 15) & 0xFFFF8000);
key = key ^ ((key >> 12) & 0x000fffff);
key = key + ((key << 2) & 0xFFFFFFFC);
key = key ^ ((key >> 4) & 0x0fffffff);
key = key * 2057;
key = key ^ ((key >> 16) & 0x0000ffff);
return key;
};
b2PairManager.Equals = function(pair, proxyId1, proxyId2)
{
return (pair.proxyId1 == proxyId1 && pair.proxyId2 == proxyId2);
};
b2PairManager.EqualsPair = function(pair1, pair2)
{
return pair1.proxyId1 == pair2.proxyId1 && pair1.proxyId2 == pair2.proxyId2;
};

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2Proxy = Class.create();
b2Proxy.prototype = {
GetNext: function(){ return this.lowerBounds[0]; },
SetNext: function(next) { this.lowerBounds[0] = next /*& 0x0000ffff*/; },
IsValid: function(){ return this.overlapCount != b2BroadPhase.b2_invalid; },
lowerBounds: [/*uint*/(0), /*uint*/(0)],
upperBounds: [/*uint*/(0), /*uint*/(0)],
overlapCount: 0,
timeStamp: 0,
userData: null,
initialize: function() {
// initialize instance variables for references
this.lowerBounds = [/*uint*/(0), /*uint*/(0)];
this.upperBounds = [/*uint*/(0), /*uint*/(0)];
//
}}

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2BoxDef = Class.create();
Object.extend(b2BoxDef.prototype, b2ShapeDef.prototype);
Object.extend(b2BoxDef.prototype,
{
initialize: function()
{
// The constructor for b2ShapeDef
this.type = b2Shape.e_unknownShape;
this.userData = null;
this.localPosition = new b2Vec2(0.0, 0.0);
this.localRotation = 0.0;
this.friction = 0.2;
this.restitution = 0.0;
this.density = 0.0;
this.categoryBits = 0x0001;
this.maskBits = 0xFFFF;
this.groupIndex = 0;
//
this.type = b2Shape.e_boxShape;
this.extents = new b2Vec2(1.0, 1.0);
},
extents: null});

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2CircleDef = Class.create();
Object.extend(b2CircleDef.prototype, b2ShapeDef.prototype);
Object.extend(b2CircleDef.prototype,
{
initialize: function()
{
// The constructor for b2ShapeDef
this.type = b2Shape.e_unknownShape;
this.userData = null;
this.localPosition = new b2Vec2(0.0, 0.0);
this.localRotation = 0.0;
this.friction = 0.2;
this.restitution = 0.0;
this.density = 0.0;
this.categoryBits = 0x0001;
this.maskBits = 0xFFFF;
this.groupIndex = 0;
//
this.type = b2Shape.e_circleShape;
this.radius = 1.0;
},
radius: null});

View file

@ -0,0 +1,198 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2CircleShape = Class.create();
Object.extend(b2CircleShape.prototype, b2Shape.prototype);
Object.extend(b2CircleShape.prototype,
{
TestPoint: function(p){
//var d = b2Math.SubtractVV(p, this.m_position);
var d = new b2Vec2();
d.SetV(p);
d.Subtract(this.m_position);
return b2Math.b2Dot(d, d) <= this.m_radius * this.m_radius;
},
//--------------- Internals Below -------------------
initialize: function(def, body, localCenter){
// initialize instance variables for references
this.m_R = new b2Mat22();
this.m_position = new b2Vec2();
//
// The constructor for b2Shape
this.m_userData = def.userData;
this.m_friction = def.friction;
this.m_restitution = def.restitution;
this.m_body = body;
this.m_proxyId = b2Pair.b2_nullProxy;
this.m_maxRadius = 0.0;
this.m_categoryBits = def.categoryBits;
this.m_maskBits = def.maskBits;
this.m_groupIndex = def.groupIndex;
//
// initialize instance variables for references
this.m_localPosition = new b2Vec2();
//
//super(def, body);
//b2Settings.b2Assert(def.type == b2Shape.e_circleShape);
var circle = def;
//this.m_localPosition = def.localPosition - localCenter;
this.m_localPosition.Set(def.localPosition.x - localCenter.x, def.localPosition.y - localCenter.y);
this.m_type = b2Shape.e_circleShape;
this.m_radius = circle.radius;
this.m_R.SetM(this.m_body.m_R);
//b2Vec2 r = b2Mul(this.m_body->this.m_R, this.m_localPosition);
var rX = this.m_R.col1.x * this.m_localPosition.x + this.m_R.col2.x * this.m_localPosition.y;
var rY = this.m_R.col1.y * this.m_localPosition.x + this.m_R.col2.y * this.m_localPosition.y;
//this.m_position = this.m_body->this.m_position + r;
this.m_position.x = this.m_body.m_position.x + rX;
this.m_position.y = this.m_body.m_position.y + rY;
//this.m_maxRadius = r.Length() + this.m_radius;
this.m_maxRadius = Math.sqrt(rX*rX+rY*rY) + this.m_radius;
var aabb = new b2AABB();
aabb.minVertex.Set(this.m_position.x - this.m_radius, this.m_position.y - this.m_radius);
aabb.maxVertex.Set(this.m_position.x + this.m_radius, this.m_position.y + this.m_radius);
var broadPhase = this.m_body.m_world.m_broadPhase;
if (broadPhase.InRange(aabb))
{
this.m_proxyId = broadPhase.CreateProxy(aabb, this);
}
else
{
this.m_proxyId = b2Pair.b2_nullProxy;
}
if (this.m_proxyId == b2Pair.b2_nullProxy)
{
this.m_body.Freeze();
}
},
Synchronize: function(position1, R1, position2, R2){
this.m_R.SetM(R2);
//this.m_position = position2 + b2Mul(R2, this.m_localPosition);
this.m_position.x = (R2.col1.x * this.m_localPosition.x + R2.col2.x * this.m_localPosition.y) + position2.x;
this.m_position.y = (R2.col1.y * this.m_localPosition.x + R2.col2.y * this.m_localPosition.y) + position2.y;
if (this.m_proxyId == b2Pair.b2_nullProxy)
{
return;
}
// Compute an AABB that covers the swept shape (may miss some rotation effect).
//b2Vec2 p1 = position1 + b2Mul(R1, this.m_localPosition);
var p1X = position1.x + (R1.col1.x * this.m_localPosition.x + R1.col2.x * this.m_localPosition.y);
var p1Y = position1.y + (R1.col1.y * this.m_localPosition.x + R1.col2.y * this.m_localPosition.y);
//b2Vec2 lower = b2Min(p1, this.m_position);
var lowerX = Math.min(p1X, this.m_position.x);
var lowerY = Math.min(p1Y, this.m_position.y);
//b2Vec2 upper = b2Max(p1, this.m_position);
var upperX = Math.max(p1X, this.m_position.x);
var upperY = Math.max(p1Y, this.m_position.y);
var aabb = new b2AABB();
aabb.minVertex.Set(lowerX - this.m_radius, lowerY - this.m_radius);
aabb.maxVertex.Set(upperX + this.m_radius, upperY + this.m_radius);
var broadPhase = this.m_body.m_world.m_broadPhase;
if (broadPhase.InRange(aabb))
{
broadPhase.MoveProxy(this.m_proxyId, aabb);
}
else
{
this.m_body.Freeze();
}
},
QuickSync: function(position, R){
this.m_R.SetM(R);
//this.m_position = position + b2Mul(R, this.m_localPosition);
this.m_position.x = (R.col1.x * this.m_localPosition.x + R.col2.x * this.m_localPosition.y) + position.x;
this.m_position.y = (R.col1.y * this.m_localPosition.x + R.col2.y * this.m_localPosition.y) + position.y;
},
ResetProxy: function(broadPhase)
{
if (this.m_proxyId == b2Pair.b2_nullProxy)
{
return;
}
var proxy = broadPhase.GetProxy(this.m_proxyId);
broadPhase.DestroyProxy(this.m_proxyId);
proxy = null;
var aabb = new b2AABB();
aabb.minVertex.Set(this.m_position.x - this.m_radius, this.m_position.y - this.m_radius);
aabb.maxVertex.Set(this.m_position.x + this.m_radius, this.m_position.y + this.m_radius);
if (broadPhase.InRange(aabb))
{
this.m_proxyId = broadPhase.CreateProxy(aabb, this);
}
else
{
this.m_proxyId = b2Pair.b2_nullProxy;
}
if (this.m_proxyId == b2Pair.b2_nullProxy)
{
this.m_body.Freeze();
}
},
Support: function(dX, dY, out)
{
//b2Vec2 u = d;
//u.Normalize();
var len = Math.sqrt(dX*dX + dY*dY);
dX /= len;
dY /= len;
//return this.m_position + this.m_radius * u;
out.Set( this.m_position.x + this.m_radius*dX,
this.m_position.y + this.m_radius*dY);
},
// Local position in parent body
m_localPosition: new b2Vec2(),
m_radius: null});

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2MassData = Class.create();
b2MassData.prototype =
{
mass: 0.0,
center: new b2Vec2(0,0),
I: 0.0,
initialize: function() {
// initialize instance variables for references
this.center = new b2Vec2(0,0);
//
}}

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2PolyDef = Class.create();
Object.extend(b2PolyDef.prototype, b2ShapeDef.prototype);
Object.extend(b2PolyDef.prototype,
{
initialize: function()
{
// The constructor for b2ShapeDef
this.type = b2Shape.e_unknownShape;
this.userData = null;
this.localPosition = new b2Vec2(0.0, 0.0);
this.localRotation = 0.0;
this.friction = 0.2;
this.restitution = 0.0;
this.density = 0.0;
this.categoryBits = 0x0001;
this.maskBits = 0xFFFF;
this.groupIndex = 0;
//
// initialize instance variables for references
this.vertices = new Array(b2Settings.b2_maxPolyVertices);
//
this.type = b2Shape.e_polyShape;
this.vertexCount = 0;
for (var i = 0; i < b2Settings.b2_maxPolyVertices; i++){
this.vertices[i] = new b2Vec2();
}
},
vertices: new Array(b2Settings.b2_maxPolyVertices),
vertexCount: 0});

View file

@ -0,0 +1,492 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
// A convex polygon. The position of the polygon (m_position) is the
// position of the centroid. The vertices of the incoming polygon are pre-rotated
// according to the local rotation. The vertices are also shifted to be centered
// on the centroid. Since the local rotation is absorbed into the vertex
// coordinates, the polygon rotation is equal to the body rotation. However,
// the polygon position is centered on the polygon centroid. This simplifies
// some collision algorithms.
var b2PolyShape = Class.create();
Object.extend(b2PolyShape.prototype, b2Shape.prototype);
Object.extend(b2PolyShape.prototype,
{
TestPoint: function(p){
//var pLocal = b2Math.b2MulTMV(this.m_R, b2Math.SubtractVV(p, this.m_position));
var pLocal = new b2Vec2();
pLocal.SetV(p);
pLocal.Subtract(this.m_position);
pLocal.MulTM(this.m_R);
for (var i = 0; i < this.m_vertexCount; ++i)
{
//var dot = b2Math.b2Dot(this.m_normals[i], b2Math.SubtractVV(pLocal, this.m_vertices[i]));
var tVec = new b2Vec2();
tVec.SetV(pLocal);
tVec.Subtract(this.m_vertices[i]);
var dot = b2Math.b2Dot(this.m_normals[i], tVec);
if (dot > 0.0)
{
return false;
}
}
return true;
},
//--------------- Internals Below -------------------
// Temp vec for b2Shape.PolyCentroid
initialize: function(def, body, newOrigin){
// initialize instance variables for references
this.m_R = new b2Mat22();
this.m_position = new b2Vec2();
//
// The constructor for b2Shape
this.m_userData = def.userData;
this.m_friction = def.friction;
this.m_restitution = def.restitution;
this.m_body = body;
this.m_proxyId = b2Pair.b2_nullProxy;
this.m_maxRadius = 0.0;
this.m_categoryBits = def.categoryBits;
this.m_maskBits = def.maskBits;
this.m_groupIndex = def.groupIndex;
//
// initialize instance variables for references
this.syncAABB = new b2AABB();
this.syncMat = new b2Mat22();
this.m_localCentroid = new b2Vec2();
this.m_localOBB = new b2OBB();
//
//super(def, body);
var i = 0;
var hX;
var hY;
var tVec;
var aabb = new b2AABB();
// Vertices
this.m_vertices = new Array(b2Settings.b2_maxPolyVertices);
this.m_coreVertices = new Array(b2Settings.b2_maxPolyVertices);
//for (i = 0; i < b2Settings.b2_maxPolyVertices; i++)
// this.m_vertices[i] = new b2Vec2();
// Normals
this.m_normals = new Array(b2Settings.b2_maxPolyVertices);
//for (i = 0; i < b2Settings.b2_maxPolyVertices; i++)
// this.m_normals[i] = new b2Vec2();
//b2Settings.b2Assert(def.type == b2Shape.e_boxShape || def.type == b2Shape.e_polyShape);
this.m_type = b2Shape.e_polyShape;
var localR = new b2Mat22(def.localRotation);
// Get the vertices transformed into the body frame.
if (def.type == b2Shape.e_boxShape)
{
//this.m_localCentroid = def.localPosition - newOrigin;
this.m_localCentroid.x = def.localPosition.x - newOrigin.x;
this.m_localCentroid.y = def.localPosition.y - newOrigin.y;
var box = def;
this.m_vertexCount = 4;
hX = box.extents.x;
hY = box.extents.y;
//hc.x = b2Max(0.0f, h.x - 2.0f * b2_linearSlop);
var hcX = Math.max(0.0, hX - 2.0 * b2Settings.b2_linearSlop);
//hc.y = b2Max(0.0f, h.y - 2.0f * b2_linearSlop);
var hcY = Math.max(0.0, hY - 2.0 * b2Settings.b2_linearSlop);
//this.m_vertices[0] = b2Mul(localR, b2Vec2(h.x, h.y));
tVec = this.m_vertices[0] = new b2Vec2();
tVec.x = localR.col1.x * hX + localR.col2.x * hY;
tVec.y = localR.col1.y * hX + localR.col2.y * hY;
//this.m_vertices[1] = b2Mul(localR, b2Vec2(-h.x, h.y));
tVec = this.m_vertices[1] = new b2Vec2();
tVec.x = localR.col1.x * -hX + localR.col2.x * hY;
tVec.y = localR.col1.y * -hX + localR.col2.y * hY;
//this.m_vertices[2] = b2Mul(localR, b2Vec2(-h.x, -h.y));
tVec = this.m_vertices[2] = new b2Vec2();
tVec.x = localR.col1.x * -hX + localR.col2.x * -hY;
tVec.y = localR.col1.y * -hX + localR.col2.y * -hY;
//this.m_vertices[3] = b2Mul(localR, b2Vec2(h.x, -h.y));
tVec = this.m_vertices[3] = new b2Vec2();
tVec.x = localR.col1.x * hX + localR.col2.x * -hY;
tVec.y = localR.col1.y * hX + localR.col2.y * -hY;
//this.m_coreVertices[0] = b2Mul(localR, b2Vec2(hc.x, hc.y));
tVec = this.m_coreVertices[0] = new b2Vec2();
tVec.x = localR.col1.x * hcX + localR.col2.x * hcY;
tVec.y = localR.col1.y * hcX + localR.col2.y * hcY;
//this.m_coreVertices[1] = b2Mul(localR, b2Vec2(-hc.x, hc.y));
tVec = this.m_coreVertices[1] = new b2Vec2();
tVec.x = localR.col1.x * -hcX + localR.col2.x * hcY;
tVec.y = localR.col1.y * -hcX + localR.col2.y * hcY;
//this.m_coreVertices[2] = b2Mul(localR, b2Vec2(-hc.x, -hc.y));
tVec = this.m_coreVertices[2] = new b2Vec2();
tVec.x = localR.col1.x * -hcX + localR.col2.x * -hcY;
tVec.y = localR.col1.y * -hcX + localR.col2.y * -hcY;
//this.m_coreVertices[3] = b2Mul(localR, b2Vec2(hc.x, -hc.y));
tVec = this.m_coreVertices[3] = new b2Vec2();
tVec.x = localR.col1.x * hcX + localR.col2.x * -hcY;
tVec.y = localR.col1.y * hcX + localR.col2.y * -hcY;
}
else
{
var poly = def;
this.m_vertexCount = poly.vertexCount;
//b2Settings.b2Assert(3 <= this.m_vertexCount && this.m_vertexCount <= b2Settings.b2_maxPolyVertices);
//b2Vec2 centroid = b2Shape.PolyCentroid(poly->vertices, poly->vertexCount);
b2Shape.PolyCentroid(poly.vertices, poly.vertexCount, b2PolyShape.tempVec);
var centroidX = b2PolyShape.tempVec.x;
var centroidY = b2PolyShape.tempVec.y;
//this.m_localCentroid = def->localPosition + b2Mul(localR, centroid) - newOrigin;
this.m_localCentroid.x = def.localPosition.x + (localR.col1.x * centroidX + localR.col2.x * centroidY) - newOrigin.x;
this.m_localCentroid.y = def.localPosition.y + (localR.col1.y * centroidX + localR.col2.y * centroidY) - newOrigin.y;
for (i = 0; i < this.m_vertexCount; ++i)
{
this.m_vertices[i] = new b2Vec2();
this.m_coreVertices[i] = new b2Vec2();
//this.m_vertices[i] = b2Mul(localR, poly->vertices[i] - centroid);
hX = poly.vertices[i].x - centroidX;
hY = poly.vertices[i].y - centroidY;
this.m_vertices[i].x = localR.col1.x * hX + localR.col2.x * hY;
this.m_vertices[i].y = localR.col1.y * hX + localR.col2.y * hY;
//b2Vec2 u = this.m_vertices[i];
var uX = this.m_vertices[i].x;
var uY = this.m_vertices[i].y;
//float32 length = u.Length();
var length = Math.sqrt(uX*uX + uY*uY);
if (length > Number.MIN_VALUE)
{
uX *= 1.0 / length;
uY *= 1.0 / length;
}
//this.m_coreVertices[i] = this.m_vertices[i] - 2.0f * b2_linearSlop * u;
this.m_coreVertices[i].x = this.m_vertices[i].x - 2.0 * b2Settings.b2_linearSlop * uX;
this.m_coreVertices[i].y = this.m_vertices[i].y - 2.0 * b2Settings.b2_linearSlop * uY;
}
}
// Compute bounding box. TODO_ERIN optimize OBB
//var minVertex = new b2Vec2(Number.MAX_VALUE, Number.MAX_VALUE);
var minVertexX = Number.MAX_VALUE;
var minVertexY = Number.MAX_VALUE;
var maxVertexX = -Number.MAX_VALUE;
var maxVertexY = -Number.MAX_VALUE;
this.m_maxRadius = 0.0;
for (i = 0; i < this.m_vertexCount; ++i)
{
var v = this.m_vertices[i];
//minVertex = b2Math.b2MinV(minVertex, this.m_vertices[i]);
minVertexX = Math.min(minVertexX, v.x);
minVertexY = Math.min(minVertexY, v.y);
//maxVertex = b2Math.b2MaxV(maxVertex, this.m_vertices[i]);
maxVertexX = Math.max(maxVertexX, v.x);
maxVertexY = Math.max(maxVertexY, v.y);
//this.m_maxRadius = b2Max(this.m_maxRadius, v.Length());
this.m_maxRadius = Math.max(this.m_maxRadius, v.Length());
}
this.m_localOBB.R.SetIdentity();
//this.m_localOBB.center = 0.5 * (minVertex + maxVertex);
this.m_localOBB.center.Set((minVertexX + maxVertexX) * 0.5, (minVertexY + maxVertexY) * 0.5);
//this.m_localOBB.extents = 0.5 * (maxVertex - minVertex);
this.m_localOBB.extents.Set((maxVertexX - minVertexX) * 0.5, (maxVertexY - minVertexY) * 0.5);
// Compute the edge normals and next index map.
var i1 = 0;
var i2 = 0;
for (i = 0; i < this.m_vertexCount; ++i)
{
this.m_normals[i] = new b2Vec2();
i1 = i;
i2 = i + 1 < this.m_vertexCount ? i + 1 : 0;
//b2Vec2 edge = this.m_vertices[i2] - this.m_vertices[i1];
//var edgeX = this.m_vertices[i2].x - this.m_vertices[i1].x;
//var edgeY = this.m_vertices[i2].y - this.m_vertices[i1].y;
//this.m_normals[i] = b2Cross(edge, 1.0f);
this.m_normals[i].x = this.m_vertices[i2].y - this.m_vertices[i1].y;
this.m_normals[i].y = -(this.m_vertices[i2].x - this.m_vertices[i1].x);
this.m_normals[i].Normalize();
}
// Ensure the polygon in convex. TODO_ERIN compute convex hull.
for (i = 0; i < this.m_vertexCount; ++i)
{
i1 = i;
i2 = i + 1 < this.m_vertexCount ? i + 1 : 0;
//b2Settings.b2Assert(b2Math.b2CrossVV(this.m_normals[i1], this.m_normals[i2]) > Number.MIN_VALUE);
}
this.m_R.SetM(this.m_body.m_R);
//this.m_position.SetV( this.m_body.m_position + b2Mul(this.m_body->this.m_R, this.m_localCentroid) );
this.m_position.x = this.m_body.m_position.x + (this.m_R.col1.x * this.m_localCentroid.x + this.m_R.col2.x * this.m_localCentroid.y);
this.m_position.y = this.m_body.m_position.y + (this.m_R.col1.y * this.m_localCentroid.x + this.m_R.col2.y * this.m_localCentroid.y);
//var R = b2Math.b2MulMM(this.m_R, this.m_localOBB.R);
//R.col1 = b2MulMV(this.m_R, this.m_localOBB.R.col1);
b2PolyShape.tAbsR.col1.x = this.m_R.col1.x * this.m_localOBB.R.col1.x + this.m_R.col2.x * this.m_localOBB.R.col1.y;
b2PolyShape.tAbsR.col1.y = this.m_R.col1.y * this.m_localOBB.R.col1.x + this.m_R.col2.y * this.m_localOBB.R.col1.y;
//R.col2 = b2MulMV(this.m_R, this.m_localOBB.R.col2)
b2PolyShape.tAbsR.col2.x = this.m_R.col1.x * this.m_localOBB.R.col2.x + this.m_R.col2.x * this.m_localOBB.R.col2.y;
b2PolyShape.tAbsR.col2.y = this.m_R.col1.y * this.m_localOBB.R.col2.x + this.m_R.col2.y * this.m_localOBB.R.col2.y;
//var absR = b2Math.b2AbsM(R);
b2PolyShape.tAbsR.Abs()
//h = b2Math.b2MulMV(b2PolyShape.tAbsR, this.m_localOBB.extents);
hX = b2PolyShape.tAbsR.col1.x * this.m_localOBB.extents.x + b2PolyShape.tAbsR.col2.x * this.m_localOBB.extents.y;
hY = b2PolyShape.tAbsR.col1.y * this.m_localOBB.extents.x + b2PolyShape.tAbsR.col2.y * this.m_localOBB.extents.y;
//var position = this.m_position + b2Mul(this.m_R, this.m_localOBB.center);
var positionX = this.m_position.x + (this.m_R.col1.x * this.m_localOBB.center.x + this.m_R.col2.x * this.m_localOBB.center.y);
var positionY = this.m_position.y + (this.m_R.col1.y * this.m_localOBB.center.x + this.m_R.col2.y * this.m_localOBB.center.y);
//aabb.minVertex = b2Math.SubtractVV(this.m_position, h);
aabb.minVertex.x = positionX - hX;
aabb.minVertex.y = positionY - hY;
//aabb.maxVertex = b2Math.AddVV(this.m_position, h);
aabb.maxVertex.x = positionX + hX;
aabb.maxVertex.y = positionY + hY;
var broadPhase = this.m_body.m_world.m_broadPhase;
if (broadPhase.InRange(aabb))
{
this.m_proxyId = broadPhase.CreateProxy(aabb, this);
}
else
{
this.m_proxyId = b2Pair.b2_nullProxy;
}
if (this.m_proxyId == b2Pair.b2_nullProxy)
{
this.m_body.Freeze();
}
},
// Temp AABB for Synch function
syncAABB: new b2AABB(),
syncMat: new b2Mat22(),
Synchronize: function(position1, R1, position2, R2){
// The body transform is copied for convenience.
this.m_R.SetM(R2);
//this.m_position = this.m_body->this.m_position + b2Mul(this.m_body->this.m_R, this.m_localCentroid)
this.m_position.x = this.m_body.m_position.x + (R2.col1.x * this.m_localCentroid.x + R2.col2.x * this.m_localCentroid.y);
this.m_position.y = this.m_body.m_position.y + (R2.col1.y * this.m_localCentroid.x + R2.col2.y * this.m_localCentroid.y);
if (this.m_proxyId == b2Pair.b2_nullProxy)
{
return;
}
//b2AABB aabb1, aabb2;
var hX;
var hY;
//b2Mat22 obbR = b2Mul(R1, this.m_localOBB.R);
var v1 = R1.col1;
var v2 = R1.col2;
var v3 = this.m_localOBB.R.col1;
var v4 = this.m_localOBB.R.col2;
//this.syncMat.col1 = b2MulMV(R1, this.m_localOBB.R.col1);
this.syncMat.col1.x = v1.x * v3.x + v2.x * v3.y;
this.syncMat.col1.y = v1.y * v3.x + v2.y * v3.y;
//this.syncMat.col2 = b2MulMV(R1, this.m_localOBB.R.col2);
this.syncMat.col2.x = v1.x * v4.x + v2.x * v4.y;
this.syncMat.col2.y = v1.y * v4.x + v2.y * v4.y;
//b2Mat22 absR = b2Abs(obbR);
this.syncMat.Abs();
//b2Vec2 center = position1 + b2Mul(R1, this.m_localCentroid + this.m_localOBB.center);
hX = this.m_localCentroid.x + this.m_localOBB.center.x;
hY = this.m_localCentroid.y + this.m_localOBB.center.y;
var centerX = position1.x + (R1.col1.x * hX + R1.col2.x * hY);
var centerY = position1.y + (R1.col1.y * hX + R1.col2.y * hY);
//b2Vec2 h = b2Mul(this.syncMat, this.m_localOBB.extents);
hX = this.syncMat.col1.x * this.m_localOBB.extents.x + this.syncMat.col2.x * this.m_localOBB.extents.y;
hY = this.syncMat.col1.y * this.m_localOBB.extents.x + this.syncMat.col2.y * this.m_localOBB.extents.y;
//aabb1.minVertex = center - h;
this.syncAABB.minVertex.x = centerX - hX;
this.syncAABB.minVertex.y = centerY - hY;
//aabb1.maxVertex = center + h;
this.syncAABB.maxVertex.x = centerX + hX;
this.syncAABB.maxVertex.y = centerY + hY;
//b2Mat22 obbR = b2Mul(R2, this.m_localOBB.R);
v1 = R2.col1;
v2 = R2.col2;
v3 = this.m_localOBB.R.col1;
v4 = this.m_localOBB.R.col2;
//this.syncMat.col1 = b2MulMV(R1, this.m_localOBB.R.col1);
this.syncMat.col1.x = v1.x * v3.x + v2.x * v3.y;
this.syncMat.col1.y = v1.y * v3.x + v2.y * v3.y;
//this.syncMat.col2 = b2MulMV(R1, this.m_localOBB.R.col2);
this.syncMat.col2.x = v1.x * v4.x + v2.x * v4.y;
this.syncMat.col2.y = v1.y * v4.x + v2.y * v4.y;
//b2Mat22 absR = b2Abs(obbR);
this.syncMat.Abs();
//b2Vec2 center = position2 + b2Mul(R2, this.m_localCentroid + this.m_localOBB.center);
hX = this.m_localCentroid.x + this.m_localOBB.center.x;
hY = this.m_localCentroid.y + this.m_localOBB.center.y;
centerX = position2.x + (R2.col1.x * hX + R2.col2.x * hY);
centerY = position2.y + (R2.col1.y * hX + R2.col2.y * hY);
//b2Vec2 h = b2Mul(absR, this.m_localOBB.extents);
hX = this.syncMat.col1.x * this.m_localOBB.extents.x + this.syncMat.col2.x * this.m_localOBB.extents.y;
hY = this.syncMat.col1.y * this.m_localOBB.extents.x + this.syncMat.col2.y * this.m_localOBB.extents.y;
//aabb2.minVertex = center - h;
//aabb2.maxVertex = center + h;
//aabb.minVertex = b2Min(aabb1.minVertex, aabb2.minVertex);
this.syncAABB.minVertex.x = Math.min(this.syncAABB.minVertex.x, centerX - hX);
this.syncAABB.minVertex.y = Math.min(this.syncAABB.minVertex.y, centerY - hY);
//aabb.maxVertex = b2Max(aabb1.maxVertex, aabb2.maxVertex);
this.syncAABB.maxVertex.x = Math.max(this.syncAABB.maxVertex.x, centerX + hX);
this.syncAABB.maxVertex.y = Math.max(this.syncAABB.maxVertex.y, centerY + hY);
var broadPhase = this.m_body.m_world.m_broadPhase;
if (broadPhase.InRange(this.syncAABB))
{
broadPhase.MoveProxy(this.m_proxyId, this.syncAABB);
}
else
{
this.m_body.Freeze();
}
},
QuickSync: function(position, R){
//this.m_R = R;
this.m_R.SetM(R);
//this.m_position = position + b2Mul(R, this.m_localCentroid);
this.m_position.x = position.x + (R.col1.x * this.m_localCentroid.x + R.col2.x * this.m_localCentroid.y);
this.m_position.y = position.y + (R.col1.y * this.m_localCentroid.x + R.col2.y * this.m_localCentroid.y);
},
ResetProxy: function(broadPhase){
if (this.m_proxyId == b2Pair.b2_nullProxy)
{
return;
}
var proxy = broadPhase.GetProxy(this.m_proxyId);
broadPhase.DestroyProxy(this.m_proxyId);
proxy = null;
var R = b2Math.b2MulMM(this.m_R, this.m_localOBB.R);
var absR = b2Math.b2AbsM(R);
var h = b2Math.b2MulMV(absR, this.m_localOBB.extents);
//var position = this.m_position + b2Mul(this.m_R, this.m_localOBB.center);
var position = b2Math.b2MulMV(this.m_R, this.m_localOBB.center);
position.Add(this.m_position);
var aabb = new b2AABB();
//aabb.minVertex = position - h;
aabb.minVertex.SetV(position);
aabb.minVertex.Subtract(h);
//aabb.maxVertex = position + h;
aabb.maxVertex.SetV(position);
aabb.maxVertex.Add(h);
if (broadPhase.InRange(aabb))
{
this.m_proxyId = broadPhase.CreateProxy(aabb, this);
}
else
{
this.m_proxyId = b2Pair.b2_nullProxy;
}
if (this.m_proxyId == b2Pair.b2_nullProxy)
{
this.m_body.Freeze();
}
},
Support: function(dX, dY, out)
{
//b2Vec2 dLocal = b2MulT(this.m_R, d);
var dLocalX = (dX*this.m_R.col1.x + dY*this.m_R.col1.y);
var dLocalY = (dX*this.m_R.col2.x + dY*this.m_R.col2.y);
var bestIndex = 0;
//float32 bestValue = b2Dot(this.m_vertices[0], dLocal);
var bestValue = (this.m_coreVertices[0].x * dLocalX + this.m_coreVertices[0].y * dLocalY);
for (var i = 1; i < this.m_vertexCount; ++i)
{
//float32 value = b2Dot(this.m_vertices[i], dLocal);
var value = (this.m_coreVertices[i].x * dLocalX + this.m_coreVertices[i].y * dLocalY);
if (value > bestValue)
{
bestIndex = i;
bestValue = value;
}
}
//return this.m_position + b2Mul(this.m_R, this.m_vertices[bestIndex]);
out.Set( this.m_position.x + (this.m_R.col1.x * this.m_coreVertices[bestIndex].x + this.m_R.col2.x * this.m_coreVertices[bestIndex].y),
this.m_position.y + (this.m_R.col1.y * this.m_coreVertices[bestIndex].x + this.m_R.col2.y * this.m_coreVertices[bestIndex].y));
},
// Local position of the shape centroid in parent body frame.
m_localCentroid: new b2Vec2(),
// Local position oriented bounding box. The OBB center is relative to
// shape centroid.
m_localOBB: new b2OBB(),
m_vertices: null,
m_coreVertices: null,
m_vertexCount: 0,
m_normals: null});
b2PolyShape.tempVec = new b2Vec2();
b2PolyShape.tAbsR = new b2Mat22();

View file

@ -0,0 +1,339 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
// Shapes are created automatically when a body is created.
// Client code does not normally interact with shapes.
var b2Shape = Class.create();
b2Shape.prototype =
{
TestPoint: function(p){return false},
GetUserData: function(){return this.m_userData;},
GetType: function(){
return this.m_type;
},
// Get the parent body of this shape.
GetBody: function(){
return this.m_body;
},
GetPosition: function(){
return this.m_position;
},
GetRotationMatrix: function(){
return this.m_R;
},
// Remove and then add proxy from the broad-phase.
// This is used to refresh the collision filters.
ResetProxy: function(broadPhase){},
// Get the next shape in the parent body's shape list.
GetNext: function(){
return this.m_next;
},
//--------------- Internals Below -------------------
initialize: function(def, body){
// initialize instance variables for references
this.m_R = new b2Mat22();
this.m_position = new b2Vec2();
//
this.m_userData = def.userData;
this.m_friction = def.friction;
this.m_restitution = def.restitution;
this.m_body = body;
this.m_proxyId = b2Pair.b2_nullProxy;
this.m_maxRadius = 0.0;
this.m_categoryBits = def.categoryBits;
this.m_maskBits = def.maskBits;
this.m_groupIndex = def.groupIndex;
},
// Internal use only. Do not call.
//b2Shape::~b2Shape()
//{
// this.m_body->m_world->m_broadPhase->this.DestroyProxy(this.m_proxyId);
//}
DestroyProxy: function()
{
if (this.m_proxyId != b2Pair.b2_nullProxy)
{
this.m_body.m_world.m_broadPhase.DestroyProxy(this.m_proxyId);
this.m_proxyId = b2Pair.b2_nullProxy;
}
},
// Internal use only. Do not call.
Synchronize: function(position1, R1, position2, R2){},
QuickSync: function(position, R){},
Support: function(dX, dY, out){},
GetMaxRadius: function(){
return this.m_maxRadius;
},
m_next: null,
m_R: new b2Mat22(),
m_position: new b2Vec2(),
m_type: 0,
m_userData: null,
m_body: null,
m_friction: null,
m_restitution: null,
m_maxRadius: null,
m_proxyId: 0,
m_categoryBits: 0,
m_maskBits: 0,
m_groupIndex: 0
// b2ShapeType
};
b2Shape.Create = function(def, body, center){
switch (def.type)
{
case b2Shape.e_circleShape:
{
//void* mem = body->m_world->m_blockAllocator.Allocate(sizeof(b2CircleShape));
return new b2CircleShape(def, body, center);
}
case b2Shape.e_boxShape:
case b2Shape.e_polyShape:
{
//void* mem = body->m_world->m_blockAllocator.Allocate(sizeof(b2PolyShape));
return new b2PolyShape(def, body, center);
}
}
//b2Settings.b2Assert(false);
return null;
};
b2Shape.Destroy = function(shape)
{
/*b2BlockAllocator& allocator = shape->m_body->m_world->m_blockAllocator;
switch (shape.m_type)
{
case b2Shape.e_circleShape:
shape->~b2Shape();
allocator.Free(shape, sizeof(b2CircleShape));
break;
case b2Shape.e_polyShape:
shape->~b2Shape();
allocator.Free(shape, sizeof(b2PolyShape));
break;
default:
b2Assert(false);
}
shape = NULL;*/
// FROM DESTRUCTOR
if (shape.m_proxyId != b2Pair.b2_nullProxy)
shape.m_body.m_world.m_broadPhase.DestroyProxy(shape.m_proxyId);
};
b2Shape.e_unknownShape = -1;
b2Shape.e_circleShape = 0;
b2Shape.e_boxShape = 1;
b2Shape.e_polyShape = 2;
b2Shape.e_meshShape = 3;
b2Shape.e_shapeTypeCount = 4;
b2Shape.PolyMass = function(massData, vs, count, rho)
{
//b2Settings.b2Assert(count >= 3);
//var center = new b2Vec2(0.0, 0.0);
var center = new b2Vec2();
center.SetZero();
var area = 0.0;
var I = 0.0;
// pRef is the reference point for forming triangles.
// It's location doesn't change the result (except for rounding error).
var pRef = new b2Vec2(0.0, 0.0);
var inv3 = 1.0 / 3.0;
for (var i = 0; i < count; ++i)
{
// Triangle vertices.
var p1 = pRef;
var p2 = vs[i];
var p3 = i + 1 < count ? vs[i+1] : vs[0];
var e1 = b2Math.SubtractVV(p2, p1);
var e2 = b2Math.SubtractVV(p3, p1);
var D = b2Math.b2CrossVV(e1, e2);
var triangleArea = 0.5 * D;
area += triangleArea;
// Area weighted centroid
// center += triangleArea * inv3 * (p1 + p2 + p3);
var tVec = new b2Vec2();
tVec.SetV(p1);
tVec.Add(p2);
tVec.Add(p3);
tVec.Multiply(inv3*triangleArea);
center.Add(tVec);
var px = p1.x;
var py = p1.y;
var ex1 = e1.x;
var ey1 = e1.y;
var ex2 = e2.x;
var ey2 = e2.y;
var intx2 = inv3 * (0.25 * (ex1*ex1 + ex2*ex1 + ex2*ex2) + (px*ex1 + px*ex2)) + 0.5*px*px;
var inty2 = inv3 * (0.25 * (ey1*ey1 + ey2*ey1 + ey2*ey2) + (py*ey1 + py*ey2)) + 0.5*py*py;
I += D * (intx2 + inty2);
}
// Total mass
massData.mass = rho * area;
// Center of mass
//b2Settings.b2Assert(area > Number.MIN_VALUE);
center.Multiply( 1.0 / area );
massData.center = center;
// Inertia tensor relative to the center.
I = rho * (I - area * b2Math.b2Dot(center, center));
massData.I = I;
};
b2Shape.PolyCentroid = function(vs, count, out)
{
//b2Settings.b2Assert(count >= 3);
//b2Vec2 c; c.Set(0.0f, 0.0f);
var cX = 0.0;
var cY = 0.0;
//float32 area = 0.0f;
var area = 0.0;
// pRef is the reference point for forming triangles.
// It's location doesn't change the result (except for rounding error).
//b2Vec2 pRef(0.0f, 0.0f);
var pRefX = 0.0;
var pRefY = 0.0;
/*
// This code would put the reference point inside the polygon.
for (var i = 0; i < count; ++i)
{
//pRef += vs[i];
pRef.x += vs[i].x;
pRef.y += vs[i].y;
}
pRef.x *= 1.0 / count;
pRef.y *= 1.0 / count;
*/
//const float32 inv3 = 1.0f / 3.0f;
var inv3 = 1.0 / 3.0;
for (var i = 0; i < count; ++i)
{
// Triangle vertices.
//b2Vec2 p1 = pRef;
var p1X = pRefX;
var p1Y = pRefY;
//b2Vec2 p2 = vs[i];
var p2X = vs[i].x;
var p2Y = vs[i].y;
//b2Vec2 p3 = i + 1 < count ? vs[i+1] : vs[0];
var p3X = i + 1 < count ? vs[i+1].x : vs[0].x;
var p3Y = i + 1 < count ? vs[i+1].y : vs[0].y;
//b2Vec2 e1 = p2 - p1;
var e1X = p2X - p1X;
var e1Y = p2Y - p1Y;
//b2Vec2 e2 = p3 - p1;
var e2X = p3X - p1X;
var e2Y = p3Y - p1Y;
//float32 D = b2Cross(e1, e2);
var D = (e1X * e2Y - e1Y * e2X);
//float32 triangleArea = 0.5f * D;
var triangleArea = 0.5 * D;
area += triangleArea;
// Area weighted centroid
//c += triangleArea * inv3 * (p1 + p2 + p3);
cX += triangleArea * inv3 * (p1X + p2X + p3X);
cY += triangleArea * inv3 * (p1Y + p2Y + p3Y);
}
// Centroid
//b2Settings.b2Assert(area > Number.MIN_VALUE);
cX *= 1.0 / area;
cY *= 1.0 / area;
// Replace return with 'out' vector
//return c;
out.Set(cX, cY);
};

View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2ShapeDef = Class.create();
b2ShapeDef.prototype =
{
initialize: function()
{
this.type = b2Shape.e_unknownShape;
this.userData = null;
this.localPosition = new b2Vec2(0.0, 0.0);
this.localRotation = 0.0;
this.friction = 0.2;
this.restitution = 0.0;
this.density = 0.0;
this.categoryBits = 0x0001;
this.maskBits = 0xFFFF;
this.groupIndex = 0;
},
//virtual ~b2ShapeDef() {}
ComputeMass: function(massData)
{
massData.center = new b2Vec2(0.0, 0.0)
if (this.density == 0.0)
{
massData.mass = 0.0;
massData.center.Set(0.0, 0.0);
massData.I = 0.0;
};
switch (this.type)
{
case b2Shape.e_circleShape:
{
var circle = this;
massData.mass = this.density * b2Settings.b2_pi * circle.radius * circle.radius;
massData.center.Set(0.0, 0.0);
massData.I = 0.5 * (massData.mass) * circle.radius * circle.radius;
}
break;
case b2Shape.e_boxShape:
{
var box = this;
massData.mass = 4.0 * this.density * box.extents.x * box.extents.y;
massData.center.Set(0.0, 0.0);
massData.I = massData.mass / 3.0 * b2Math.b2Dot(box.extents, box.extents);
}
break;
case b2Shape.e_polyShape:
{
var poly = this;
b2Shape.PolyMass(massData, poly.vertices, poly.vertexCount, this.density);
}
break;
default:
massData.mass = 0.0;
massData.center.Set(0.0, 0.0);
massData.I = 0.0;
break;
}
},
type: 0,
userData: null,
localPosition: null,
localRotation: null,
friction: null,
restitution: null,
density: null,
// The collision category bits. Normally you would just set one bit.
categoryBits: 0,
// The collision mask bits. This states the categories that this
// shape would accept for collision.
maskBits: 0,
// Collision groups allow a certain group of objects to never collide (negative)
// or always collide (positive). Zero means no collision group. Non-zero group
// filtering always wins against the mask bits.
groupIndex: 0};

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2Settings = Class.create();
b2Settings.prototype = {
// Define your unit system here. The default system is
// meters-kilograms-seconds. For the tuning to work well,
// your dynamic objects should be bigger than a pebble and smaller
// than a house.
//static public const b2Settings.b2_lengthUnitsPerMeter = 1.0;
// Use this for pixels:
// Global tuning constants based on MKS units.
// Collision
// Dynamics
// Sleep
// assert
initialize: function() {}}
b2Settings.USHRT_MAX = 0x0000ffff;
b2Settings.b2_pi = Math.PI;
b2Settings.b2_massUnitsPerKilogram = 1.0;
b2Settings.b2_timeUnitsPerSecond = 1.0;
b2Settings.b2_lengthUnitsPerMeter = 30.0;
b2Settings.b2_maxManifoldPoints = 2;
b2Settings.b2_maxShapesPerBody = 64;
b2Settings.b2_maxPolyVertices = 8;
b2Settings.b2_maxProxies = 1024;
b2Settings.b2_maxPairs = 8 * b2Settings.b2_maxProxies;
b2Settings.b2_linearSlop = 0.005 * b2Settings.b2_lengthUnitsPerMeter;
b2Settings.b2_angularSlop = 2.0 / 180.0 * b2Settings.b2_pi;
b2Settings.b2_velocityThreshold = 1.0 * b2Settings.b2_lengthUnitsPerMeter / b2Settings.b2_timeUnitsPerSecond;
b2Settings.b2_maxLinearCorrection = 0.2 * b2Settings.b2_lengthUnitsPerMeter;
b2Settings.b2_maxAngularCorrection = 8.0 / 180.0 * b2Settings.b2_pi;
b2Settings.b2_contactBaumgarte = 0.2;
b2Settings.b2_timeToSleep = 0.5 * b2Settings.b2_timeUnitsPerSecond;
b2Settings.b2_linearSleepTolerance = 0.01 * b2Settings.b2_lengthUnitsPerMeter / b2Settings.b2_timeUnitsPerSecond;
b2Settings.b2_angularSleepTolerance = 2.0 / 180.0 / b2Settings.b2_timeUnitsPerSecond;
b2Settings.b2Assert = function(a)
{
if (!a){
var nullVec;
nullVec.x++;
}
};

View file

@ -0,0 +1,130 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2Mat22 = Class.create();
b2Mat22.prototype =
{
initialize: function(angle, c1, c2)
{
if (angle==null) angle = 0;
// initialize instance variables for references
this.col1 = new b2Vec2();
this.col2 = new b2Vec2();
//
if (c1!=null && c2!=null){
this.col1.SetV(c1);
this.col2.SetV(c2);
}
else{
var c = Math.cos(angle);
var s = Math.sin(angle);
this.col1.x = c; this.col2.x = -s;
this.col1.y = s; this.col2.y = c;
}
},
Set: function(angle)
{
var c = Math.cos(angle);
var s = Math.sin(angle);
this.col1.x = c; this.col2.x = -s;
this.col1.y = s; this.col2.y = c;
},
SetVV: function(c1, c2)
{
this.col1.SetV(c1);
this.col2.SetV(c2);
},
Copy: function(){
return new b2Mat22(0, this.col1, this.col2);
},
SetM: function(m)
{
this.col1.SetV(m.col1);
this.col2.SetV(m.col2);
},
AddM: function(m)
{
this.col1.x += m.col1.x;
this.col1.y += m.col1.y;
this.col2.x += m.col2.x;
this.col2.y += m.col2.y;
},
SetIdentity: function()
{
this.col1.x = 1.0; this.col2.x = 0.0;
this.col1.y = 0.0; this.col2.y = 1.0;
},
SetZero: function()
{
this.col1.x = 0.0; this.col2.x = 0.0;
this.col1.y = 0.0; this.col2.y = 0.0;
},
Invert: function(out)
{
var a = this.col1.x;
var b = this.col2.x;
var c = this.col1.y;
var d = this.col2.y;
//var B = new b2Mat22();
var det = a * d - b * c;
//b2Settings.b2Assert(det != 0.0);
det = 1.0 / det;
out.col1.x = det * d; out.col2.x = -det * b;
out.col1.y = -det * c; out.col2.y = det * a;
return out;
},
// this.Solve A * x = b
Solve: function(out, bX, bY)
{
//float32 a11 = this.col1.x, a12 = this.col2.x, a21 = this.col1.y, a22 = this.col2.y;
var a11 = this.col1.x;
var a12 = this.col2.x;
var a21 = this.col1.y;
var a22 = this.col2.y;
//float32 det = a11 * a22 - a12 * a21;
var det = a11 * a22 - a12 * a21;
//b2Settings.b2Assert(det != 0.0);
det = 1.0 / det;
out.x = det * (a22 * bX - a12 * bY);
out.y = det * (a11 * bY - a21 * bX);
return out;
},
Abs: function()
{
this.col1.Abs();
this.col2.Abs();
},
col1: new b2Vec2(),
col2: new b2Vec2()};

View file

@ -0,0 +1,218 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2Math = Class.create();
b2Math.prototype = {
/*static public function b2InvSqrt(x)
{
float32 xhalf = 0.5f * x;
int32 i = *(int32*)&x;
i = 0x5f3759df - (i >> 1);
x = *(float32*)&i;
x = x * (1.5f - xhalf * x * x);
return x;
}*/
// A * B
// A^T * B
// b2Math.b2Random number in range [-1,1]
/*inline float32 b2Math.b2Random(float32 lo, float32 hi)
{
float32 r = (float32)rand();
r /= RAND_MAX;
r = (hi - lo) * r + lo;
return r;
}*/
// "Next Largest Power of 2
// Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
// that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
// the same most significant 1, but all 1's below it. Adding 1 to that value yields the next
// largest power of 2. For a 32-bit value:"
// Temp vector functions to reduce calls to 'new'
/*static public var tempVec = new b2Vec2();
static public var tempAABB = new b2AABB(); */
initialize: function() {}}
b2Math.b2IsValid = function(x)
{
return isFinite(x);
};
b2Math.b2Dot = function(a, b)
{
return a.x * b.x + a.y * b.y;
};
b2Math.b2CrossVV = function(a, b)
{
return a.x * b.y - a.y * b.x;
};
b2Math.b2CrossVF = function(a, s)
{
var v = new b2Vec2(s * a.y, -s * a.x);
return v;
};
b2Math.b2CrossFV = function(s, a)
{
var v = new b2Vec2(-s * a.y, s * a.x);
return v;
};
b2Math.b2MulMV = function(A, v)
{
var u = new b2Vec2(A.col1.x * v.x + A.col2.x * v.y, A.col1.y * v.x + A.col2.y * v.y);
return u;
};
b2Math.b2MulTMV = function(A, v)
{
var u = new b2Vec2(b2Math.b2Dot(v, A.col1), b2Math.b2Dot(v, A.col2));
return u;
};
b2Math.AddVV = function(a, b)
{
var v = new b2Vec2(a.x + b.x, a.y + b.y);
return v;
};
b2Math.SubtractVV = function(a, b)
{
var v = new b2Vec2(a.x - b.x, a.y - b.y);
return v;
};
b2Math.MulFV = function(s, a)
{
var v = new b2Vec2(s * a.x, s * a.y);
return v;
};
b2Math.AddMM = function(A, B)
{
var C = new b2Mat22(0, b2Math.AddVV(A.col1, B.col1), b2Math.AddVV(A.col2, B.col2));
return C;
};
b2Math.b2MulMM = function(A, B)
{
var C = new b2Mat22(0, b2Math.b2MulMV(A, B.col1), b2Math.b2MulMV(A, B.col2));
return C;
};
b2Math.b2MulTMM = function(A, B)
{
var c1 = new b2Vec2(b2Math.b2Dot(A.col1, B.col1), b2Math.b2Dot(A.col2, B.col1));
var c2 = new b2Vec2(b2Math.b2Dot(A.col1, B.col2), b2Math.b2Dot(A.col2, B.col2));
var C = new b2Mat22(0, c1, c2);
return C;
};
b2Math.b2Abs = function(a)
{
return a > 0.0 ? a : -a;
};
b2Math.b2AbsV = function(a)
{
var b = new b2Vec2(b2Math.b2Abs(a.x), b2Math.b2Abs(a.y));
return b;
};
b2Math.b2AbsM = function(A)
{
var B = new b2Mat22(0, b2Math.b2AbsV(A.col1), b2Math.b2AbsV(A.col2));
return B;
};
b2Math.b2Min = function(a, b)
{
return a < b ? a : b;
};
b2Math.b2MinV = function(a, b)
{
var c = new b2Vec2(b2Math.b2Min(a.x, b.x), b2Math.b2Min(a.y, b.y));
return c;
};
b2Math.b2Max = function(a, b)
{
return a > b ? a : b;
};
b2Math.b2MaxV = function(a, b)
{
var c = new b2Vec2(b2Math.b2Max(a.x, b.x), b2Math.b2Max(a.y, b.y));
return c;
};
b2Math.b2Clamp = function(a, low, high)
{
return b2Math.b2Max(low, b2Math.b2Min(a, high));
};
b2Math.b2ClampV = function(a, low, high)
{
return b2Math.b2MaxV(low, b2Math.b2MinV(a, high));
};
b2Math.b2Swap = function(a, b)
{
var tmp = a[0];
a[0] = b[0];
b[0] = tmp;
};
b2Math.b2Random = function()
{
return Math.random() * 2 - 1;
};
b2Math.b2NextPowerOfTwo = function(x)
{
x |= (x >> 1) & 0x7FFFFFFF;
x |= (x >> 2) & 0x3FFFFFFF;
x |= (x >> 4) & 0x0FFFFFFF;
x |= (x >> 8) & 0x00FFFFFF;
x |= (x >> 16)& 0x0000FFFF;
return x + 1;
};
b2Math.b2IsPowerOfTwo = function(x)
{
var result = x > 0 && (x & (x - 1)) == 0;
return result;
};
b2Math.tempVec2 = new b2Vec2();
b2Math.tempVec3 = new b2Vec2();
b2Math.tempVec4 = new b2Vec2();
b2Math.tempVec5 = new b2Vec2();
b2Math.tempMat = new b2Mat22();

View file

@ -0,0 +1,131 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
// b2Vec2 has no constructor so that it
// can be placed in a union.
var b2Vec2 = Class.create();
b2Vec2.prototype =
{
initialize: function(x_, y_) {this.x=x_; this.y=y_;},
SetZero: function() { this.x = 0.0; this.y = 0.0; },
Set: function(x_, y_) {this.x=x_; this.y=y_;},
SetV: function(v) {this.x=v.x; this.y=v.y;},
Negative: function(){ return new b2Vec2(-this.x, -this.y); },
Copy: function(){
return new b2Vec2(this.x,this.y);
},
Add: function(v)
{
this.x += v.x; this.y += v.y;
},
Subtract: function(v)
{
this.x -= v.x; this.y -= v.y;
},
Multiply: function(a)
{
this.x *= a; this.y *= a;
},
MulM: function(A)
{
var tX = this.x;
this.x = A.col1.x * tX + A.col2.x * this.y;
this.y = A.col1.y * tX + A.col2.y * this.y;
},
MulTM: function(A)
{
var tX = b2Math.b2Dot(this, A.col1);
this.y = b2Math.b2Dot(this, A.col2);
this.x = tX;
},
CrossVF: function(s)
{
var tX = this.x;
this.x = s * this.y;
this.y = -s * tX;
},
CrossFV: function(s)
{
var tX = this.x;
this.x = -s * this.y;
this.y = s * tX;
},
MinV: function(b)
{
this.x = this.x < b.x ? this.x : b.x;
this.y = this.y < b.y ? this.y : b.y;
},
MaxV: function(b)
{
this.x = this.x > b.x ? this.x : b.x;
this.y = this.y > b.y ? this.y : b.y;
},
Abs: function()
{
this.x = Math.abs(this.x);
this.y = Math.abs(this.y);
},
Length: function()
{
return Math.sqrt(this.x * this.x + this.y * this.y);
},
Normalize: function()
{
var length = this.Length();
if (length < Number.MIN_VALUE)
{
return 0.0;
}
var invLength = 1.0 / length;
this.x *= invLength;
this.y *= invLength;
return length;
},
IsValid: function()
{
return b2Math.b2IsValid(this.x) && b2Math.b2IsValid(this.y);
},
x: null,
y: null};
b2Vec2.Make = function(x_, y_)
{
return new b2Vec2(x_, y_);
};

View file

@ -0,0 +1,469 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
// A rigid body. Internal computation are done in terms
// of the center of mass position. The center of mass may
// be offset from the body's origin.
var b2Body = Class.create();
b2Body.prototype =
{
// Set the position of the body's origin and rotation (radians).
// This breaks any contacts and wakes the other bodies.
SetOriginPosition: function(position, rotation){
if (this.IsFrozen())
{
return;
}
this.m_rotation = rotation;
this.m_R.Set(this.m_rotation);
this.m_position = b2Math.AddVV(position , b2Math.b2MulMV(this.m_R, this.m_center));
this.m_position0.SetV(this.m_position);
this.m_rotation0 = this.m_rotation;
for (var s = this.m_shapeList; s != null; s = s.m_next)
{
s.Synchronize(this.m_position, this.m_R, this.m_position, this.m_R);
}
this.m_world.m_broadPhase.Commit();
},
// Get the position of the body's origin. The body's origin does not
// necessarily coincide with the center of mass. It depends on how the
// shapes are created.
GetOriginPosition: function(){
return b2Math.SubtractVV(this.m_position, b2Math.b2MulMV(this.m_R, this.m_center));
},
// Set the position of the body's center of mass and rotation (radians).
// This breaks any contacts and wakes the other bodies.
SetCenterPosition: function(position, rotation){
if (this.IsFrozen())
{
return;
}
this.m_rotation = rotation;
this.m_R.Set(this.m_rotation);
this.m_position.SetV( position );
this.m_position0.SetV(this.m_position);
this.m_rotation0 = this.m_rotation;
for (var s = this.m_shapeList; s != null; s = s.m_next)
{
s.Synchronize(this.m_position, this.m_R, this.m_position, this.m_R);
}
this.m_world.m_broadPhase.Commit();
},
// Get the position of the body's center of mass. The body's center of mass
// does not necessarily coincide with the body's origin. It depends on how the
// shapes are created.
GetCenterPosition: function(){
return this.m_position;
},
// Get the rotation in radians.
GetRotation: function(){
return this.m_rotation;
},
GetRotationMatrix: function(){
return this.m_R;
},
// Set/Get the linear velocity of the center of mass.
SetLinearVelocity: function(v){
this.m_linearVelocity.SetV(v);
},
GetLinearVelocity: function(){
return this.m_linearVelocity;
},
// Set/Get the angular velocity.
SetAngularVelocity: function(w){
this.m_angularVelocity = w;
},
GetAngularVelocity: function(){
return this.m_angularVelocity;
},
// Apply a force at a world point. Additive.
ApplyForce: function(force, point)
{
if (this.IsSleeping() == false)
{
this.m_force.Add( force );
this.m_torque += b2Math.b2CrossVV(b2Math.SubtractVV(point, this.m_position), force);
}
},
// Apply a torque. Additive.
ApplyTorque: function(torque)
{
if (this.IsSleeping() == false)
{
this.m_torque += torque;
}
},
// Apply an impulse at a point. This immediately modifies the velocity.
ApplyImpulse: function(impulse, point)
{
if (this.IsSleeping() == false)
{
this.m_linearVelocity.Add( b2Math.MulFV(this.m_invMass, impulse) );
this.m_angularVelocity += ( this.m_invI * b2Math.b2CrossVV( b2Math.SubtractVV(point, this.m_position), impulse) );
}
},
GetMass: function(){
return this.m_mass;
},
GetInertia: function(){
return this.m_I;
},
// Get the world coordinates of a point give the local coordinates
// relative to the body's center of mass.
GetWorldPoint: function(localPoint){
return b2Math.AddVV(this.m_position , b2Math.b2MulMV(this.m_R, localPoint));
},
// Get the world coordinates of a vector given the local coordinates.
GetWorldVector: function(localVector){
return b2Math.b2MulMV(this.m_R, localVector);
},
// Returns a local point relative to the center of mass given a world point.
GetLocalPoint: function(worldPoint){
return b2Math.b2MulTMV(this.m_R, b2Math.SubtractVV(worldPoint, this.m_position));
},
// Returns a local vector given a world vector.
GetLocalVector: function(worldVector){
return b2Math.b2MulTMV(this.m_R, worldVector);
},
// Is this body static (immovable)?
IsStatic: function(){
return (this.m_flags & b2Body.e_staticFlag) == b2Body.e_staticFlag;
},
IsFrozen: function()
{
return (this.m_flags & b2Body.e_frozenFlag) == b2Body.e_frozenFlag;
},
// Is this body sleeping (not simulating).
IsSleeping: function(){
return (this.m_flags & b2Body.e_sleepFlag) == b2Body.e_sleepFlag;
},
// You can disable sleeping on this particular body.
AllowSleeping: function(flag)
{
if (flag)
{
this.m_flags |= b2Body.e_allowSleepFlag;
}
else
{
this.m_flags &= ~b2Body.e_allowSleepFlag;
this.WakeUp();
}
},
// Wake up this body so it will begin simulating.
WakeUp: function(){
this.m_flags &= ~b2Body.e_sleepFlag;
this.m_sleepTime = 0.0;
},
// Get the list of all shapes attached to this body.
GetShapeList: function(){
return this.m_shapeList;
},
GetContactList: function()
{
return this.m_contactList;
},
GetJointList: function()
{
return this.m_jointList;
},
// Get the next body in the world's body list.
GetNext: function(){
return this.m_next;
},
GetUserData: function(){
return this.m_userData;
},
//--------------- Internals Below -------------------
initialize: function(bd, world){
// initialize instance variables for references
this.sMat0 = new b2Mat22();
this.m_position = new b2Vec2();
this.m_R = new b2Mat22(0);
this.m_position0 = new b2Vec2();
//
var i = 0;
var sd;
var massData;
this.m_flags = 0;
this.m_position.SetV( bd.position );
this.m_rotation = bd.rotation;
this.m_R.Set(this.m_rotation);
this.m_position0.SetV(this.m_position);
this.m_rotation0 = this.m_rotation;
this.m_world = world;
this.m_linearDamping = b2Math.b2Clamp(1.0 - bd.linearDamping, 0.0, 1.0);
this.m_angularDamping = b2Math.b2Clamp(1.0 - bd.angularDamping, 0.0, 1.0);
this.m_force = new b2Vec2(0.0, 0.0);
this.m_torque = 0.0;
this.m_mass = 0.0;
var massDatas = new Array(b2Settings.b2_maxShapesPerBody);
for (i = 0; i < b2Settings.b2_maxShapesPerBody; i++){
massDatas[i] = new b2MassData();
}
// Compute the shape mass properties, the bodies total mass and COM.
this.m_shapeCount = 0;
this.m_center = new b2Vec2(0.0, 0.0);
for (i = 0; i < b2Settings.b2_maxShapesPerBody; ++i)
{
sd = bd.shapes[i];
if (sd == null) break;
massData = massDatas[ i ];
sd.ComputeMass(massData);
this.m_mass += massData.mass;
//this.m_center += massData->mass * (sd->localPosition + massData->center);
this.m_center.x += massData.mass * (sd.localPosition.x + massData.center.x);
this.m_center.y += massData.mass * (sd.localPosition.y + massData.center.y);
++this.m_shapeCount;
}
// Compute center of mass, and shift the origin to the COM.
if (this.m_mass > 0.0)
{
this.m_center.Multiply( 1.0 / this.m_mass );
this.m_position.Add( b2Math.b2MulMV(this.m_R, this.m_center) );
}
else
{
this.m_flags |= b2Body.e_staticFlag;
}
// Compute the moment of inertia.
this.m_I = 0.0;
for (i = 0; i < this.m_shapeCount; ++i)
{
sd = bd.shapes[i];
massData = massDatas[ i ];
this.m_I += massData.I;
var r = b2Math.SubtractVV( b2Math.AddVV(sd.localPosition, massData.center), this.m_center );
this.m_I += massData.mass * b2Math.b2Dot(r, r);
}
if (this.m_mass > 0.0)
{
this.m_invMass = 1.0 / this.m_mass;
}
else
{
this.m_invMass = 0.0;
}
if (this.m_I > 0.0 && bd.preventRotation == false)
{
this.m_invI = 1.0 / this.m_I;
}
else
{
this.m_I = 0.0;
this.m_invI = 0.0;
}
// Compute the center of mass velocity.
this.m_linearVelocity = b2Math.AddVV(bd.linearVelocity, b2Math.b2CrossFV(bd.angularVelocity, this.m_center));
this.m_angularVelocity = bd.angularVelocity;
this.m_jointList = null;
this.m_contactList = null;
this.m_prev = null;
this.m_next = null;
// Create the shapes.
this.m_shapeList = null;
for (i = 0; i < this.m_shapeCount; ++i)
{
sd = bd.shapes[i];
var shape = b2Shape.Create(sd, this, this.m_center);
shape.m_next = this.m_shapeList;
this.m_shapeList = shape;
}
this.m_sleepTime = 0.0;
if (bd.allowSleep)
{
this.m_flags |= b2Body.e_allowSleepFlag;
}
if (bd.isSleeping)
{
this.m_flags |= b2Body.e_sleepFlag;
}
if ((this.m_flags & b2Body.e_sleepFlag) || this.m_invMass == 0.0)
{
this.m_linearVelocity.Set(0.0, 0.0);
this.m_angularVelocity = 0.0;
}
this.m_userData = bd.userData;
},
// does not support destructors
/*~b2Body(){
b2Shape* s = this.m_shapeList;
while (s)
{
b2Shape* s0 = s;
s = s->this.m_next;
b2Shape::this.Destroy(s0);
}
}*/
Destroy: function(){
var s = this.m_shapeList;
while (s)
{
var s0 = s;
s = s.m_next;
b2Shape.Destroy(s0);
}
},
// Temp mat
sMat0: new b2Mat22(),
SynchronizeShapes: function(){
//b2Mat22 R0(this.m_rotation0);
this.sMat0.Set(this.m_rotation0);
for (var s = this.m_shapeList; s != null; s = s.m_next)
{
s.Synchronize(this.m_position0, this.sMat0, this.m_position, this.m_R);
}
},
QuickSyncShapes: function(){
for (var s = this.m_shapeList; s != null; s = s.m_next)
{
s.QuickSync(this.m_position, this.m_R);
}
},
// This is used to prevent connected bodies from colliding.
// It may lie, depending on the collideConnected flag.
IsConnected: function(other){
for (var jn = this.m_jointList; jn != null; jn = jn.next)
{
if (jn.other == other)
return jn.joint.m_collideConnected == false;
}
return false;
},
Freeze: function(){
this.m_flags |= b2Body.e_frozenFlag;
this.m_linearVelocity.SetZero();
this.m_angularVelocity = 0.0;
for (var s = this.m_shapeList; s != null; s = s.m_next)
{
s.DestroyProxy();
}
},
m_flags: 0,
m_position: new b2Vec2(),
m_rotation: null,
m_R: new b2Mat22(0),
// Conservative advancement data.
m_position0: new b2Vec2(),
m_rotation0: null,
m_linearVelocity: null,
m_angularVelocity: null,
m_force: null,
m_torque: null,
m_center: null,
m_world: null,
m_prev: null,
m_next: null,
m_shapeList: null,
m_shapeCount: 0,
m_jointList: null,
m_contactList: null,
m_mass: null,
m_invMass: null,
m_I: null,
m_invI: null,
m_linearDamping: null,
m_angularDamping: null,
m_sleepTime: null,
m_userData: null};
b2Body.e_staticFlag = 0x0001;
b2Body.e_frozenFlag = 0x0002;
b2Body.e_islandFlag = 0x0004;
b2Body.e_sleepFlag = 0x0008;
b2Body.e_allowSleepFlag = 0x0010;
b2Body.e_destroyFlag = 0x0020;

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2BodyDef = Class.create();
b2BodyDef.prototype =
{
initialize: function()
{
// initialize instance variables for references
this.shapes = new Array();
//
this.userData = null;
for (var i = 0; i < b2Settings.b2_maxShapesPerBody; i++){
this.shapes[i] = null;
}
this.position = new b2Vec2(0.0, 0.0);
this.rotation = 0.0;
this.linearVelocity = new b2Vec2(0.0, 0.0);
this.angularVelocity = 0.0;
this.linearDamping = 0.0;
this.angularDamping = 0.0;
this.allowSleep = true;
this.isSleeping = false;
this.preventRotation = false;
},
userData: null,
shapes: new Array(),
position: null,
rotation: null,
linearVelocity: null,
angularVelocity: null,
linearDamping: null,
angularDamping: null,
allowSleep: null,
isSleeping: null,
preventRotation: null,
AddShape: function(shape)
{
for (var i = 0; i < b2Settings.b2_maxShapesPerBody; ++i)
{
if (this.shapes[i] == null)
{
this.shapes[i] = shape;
break;
}
}
}};

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2CollisionFilter = Class.create();
b2CollisionFilter.prototype =
{
// Return true if contact calculations should be performed between these two shapes.
ShouldCollide: function(shape1, shape2){
if (shape1.m_groupIndex == shape2.m_groupIndex && shape1.m_groupIndex != 0)
{
return shape1.m_groupIndex > 0;
}
var collide = (shape1.m_maskBits & shape2.m_categoryBits) != 0 && (shape1.m_categoryBits & shape2.m_maskBits) != 0;
return collide;
},
initialize: function() {}};
b2CollisionFilter.b2_defaultFilter = new b2CollisionFilter;

View file

@ -0,0 +1,337 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2ContactManager = Class.create();
Object.extend(b2ContactManager.prototype, b2PairCallback.prototype);
Object.extend(b2ContactManager.prototype,
{
initialize: function(){
// The constructor for b2PairCallback
//
// initialize instance variables for references
this.m_nullContact = new b2NullContact();
//
this.m_world = null;
this.m_destroyImmediate = false;
},
// This is a callback from the broadphase when two AABB proxies begin
// to overlap. We create a b2Contact to manage the narrow phase.
PairAdded: function(proxyUserData1, proxyUserData2){
var shape1 = proxyUserData1;
var shape2 = proxyUserData2;
var body1 = shape1.m_body;
var body2 = shape2.m_body;
if (body1.IsStatic() && body2.IsStatic())
{
return this.m_nullContact;
}
if (shape1.m_body == shape2.m_body)
{
return this.m_nullContact;
}
if (body2.IsConnected(body1))
{
return this.m_nullContact;
}
if (this.m_world.m_filter != null && this.m_world.m_filter.ShouldCollide(shape1, shape2) == false)
{
return this.m_nullContact;
}
// Ensure that body2 is dynamic (body1 is static or dynamic).
if (body2.m_invMass == 0.0)
{
var tempShape = shape1;
shape1 = shape2;
shape2 = tempShape;
//b2Math.b2Swap(shape1, shape2);
var tempBody = body1;
body1 = body2;
body2 = tempBody;
//b2Math.b2Swap(body1, body2);
}
// Call the factory.
var contact = b2Contact.Create(shape1, shape2, this.m_world.m_blockAllocator);
if (contact == null)
{
return this.m_nullContact;
}
else
{
// Insert into the world.
contact.m_prev = null;
contact.m_next = this.m_world.m_contactList;
if (this.m_world.m_contactList != null)
{
this.m_world.m_contactList.m_prev = contact;
}
this.m_world.m_contactList = contact;
this.m_world.m_contactCount++;
}
return contact;
},
// This is a callback from the broadphase when two AABB proxies cease
// to overlap. We destroy the b2Contact.
PairRemoved: function(proxyUserData1, proxyUserData2, pairUserData){
if (pairUserData == null)
{
return;
}
var c = pairUserData;
if (c != this.m_nullContact)
{
//b2Settings.b2Assert(this.m_world.m_contactCount > 0);
if (this.m_destroyImmediate == true)
{
this.DestroyContact(c);
c = null;
}
else
{
c.m_flags |= b2Contact.e_destroyFlag;
}
}
},
DestroyContact: function(c)
{
//b2Settings.b2Assert(this.m_world.m_contactCount > 0);
// Remove from the world.
if (c.m_prev)
{
c.m_prev.m_next = c.m_next;
}
if (c.m_next)
{
c.m_next.m_prev = c.m_prev;
}
if (c == this.m_world.m_contactList)
{
this.m_world.m_contactList = c.m_next;
}
// If there are contact points, then disconnect from the island graph.
if (c.GetManifoldCount() > 0)
{
var body1 = c.m_shape1.m_body;
var body2 = c.m_shape2.m_body;
var node1 = c.m_node1;
var node2 = c.m_node2;
// Wake up touching bodies.
body1.WakeUp();
body2.WakeUp();
// Remove from body 1
if (node1.prev)
{
node1.prev.next = node1.next;
}
if (node1.next)
{
node1.next.prev = node1.prev;
}
if (node1 == body1.m_contactList)
{
body1.m_contactList = node1.next;
}
node1.prev = null;
node1.next = null;
// Remove from body 2
if (node2.prev)
{
node2.prev.next = node2.next;
}
if (node2.next)
{
node2.next.prev = node2.prev;
}
if (node2 == body2.m_contactList)
{
body2.m_contactList = node2.next;
}
node2.prev = null;
node2.next = null;
}
// Call the factory.
b2Contact.Destroy(c, this.m_world.m_blockAllocator);
--this.m_world.m_contactCount;
},
// Destroy any contacts marked for deferred destruction.
CleanContactList: function()
{
var c = this.m_world.m_contactList;
while (c != null)
{
var c0 = c;
c = c.m_next;
if (c0.m_flags & b2Contact.e_destroyFlag)
{
this.DestroyContact(c0);
c0 = null;
}
}
},
// This is the top level collision call for the time step. Here
// all the narrow phase collision is processed for the world
// contact list.
Collide: function()
{
var body1;
var body2;
var node1;
var node2;
for (var c = this.m_world.m_contactList; c != null; c = c.m_next)
{
if (c.m_shape1.m_body.IsSleeping() &&
c.m_shape2.m_body.IsSleeping())
{
continue;
}
var oldCount = c.GetManifoldCount();
c.Evaluate();
var newCount = c.GetManifoldCount();
if (oldCount == 0 && newCount > 0)
{
//b2Settings.b2Assert(c.GetManifolds().pointCount > 0);
// Connect to island graph.
body1 = c.m_shape1.m_body;
body2 = c.m_shape2.m_body;
node1 = c.m_node1;
node2 = c.m_node2;
// Connect to body 1
node1.contact = c;
node1.other = body2;
node1.prev = null;
node1.next = body1.m_contactList;
if (node1.next != null)
{
node1.next.prev = c.m_node1;
}
body1.m_contactList = c.m_node1;
// Connect to body 2
node2.contact = c;
node2.other = body1;
node2.prev = null;
node2.next = body2.m_contactList;
if (node2.next != null)
{
node2.next.prev = node2;
}
body2.m_contactList = node2;
}
else if (oldCount > 0 && newCount == 0)
{
// Disconnect from island graph.
body1 = c.m_shape1.m_body;
body2 = c.m_shape2.m_body;
node1 = c.m_node1;
node2 = c.m_node2;
// Remove from body 1
if (node1.prev)
{
node1.prev.next = node1.next;
}
if (node1.next)
{
node1.next.prev = node1.prev;
}
if (node1 == body1.m_contactList)
{
body1.m_contactList = node1.next;
}
node1.prev = null;
node1.next = null;
// Remove from body 2
if (node2.prev)
{
node2.prev.next = node2.next;
}
if (node2.next)
{
node2.next.prev = node2.prev;
}
if (node2 == body2.m_contactList)
{
body2.m_contactList = node2.next;
}
node2.prev = null;
node2.next = null;
}
}
},
m_world: null,
// This lets us provide broadphase proxy pair user data for
// contacts that shouldn't exist.
m_nullContact: new b2NullContact(),
m_destroyImmediate: null});

View file

@ -0,0 +1,331 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
/*
Position Correction Notes
=========================
I tried the several algorithms for position correction of the 2D revolute joint.
I looked at these systems:
- simple pendulum (1m diameter sphere on massless 5m stick) with initial angular velocity of 100 rad/s.
- suspension bridge with 30 1m long planks of length 1m.
- multi-link chain with 30 1m long links.
Here are the algorithms:
Baumgarte - A fraction of the position error is added to the velocity error. There is no
separate position solver.
Pseudo Velocities - After the velocity solver and position integration,
the position error, Jacobian, and effective mass are recomputed. Then
the velocity constraints are solved with pseudo velocities and a fraction
of the position error is added to the pseudo velocity error. The pseudo
velocities are initialized to zero and there is no warm-starting. After
the position solver, the pseudo velocities are added to the positions.
This is also called the First Order World method or the Position LCP method.
Modified Nonlinear Gauss-Seidel (NGS) - Like Pseudo Velocities except the
position error is re-computed for each constraint and the positions are updated
after the constraint is solved. The radius vectors (aka Jacobians) are
re-computed too (otherwise the algorithm has horrible instability). The pseudo
velocity states are not needed because they are effectively zero at the beginning
of each iteration. Since we have the current position error, we allow the
iterations to terminate early if the error becomes smaller than b2_linearSlop.
Full NGS or just NGS - Like Modified NGS except the effective mass are re-computed
each time a constraint is solved.
Here are the results:
Baumgarte - this is the cheapest algorithm but it has some stability problems,
especially with the bridge. The chain links separate easily close to the root
and they jitter struggle to pull together. This is one of the most common
methods in the field. The big drawback is that the position correction artificially
affects the momentum, thus leading to instabilities and false bounce. I used a
bias factor of 0.2. A larger bias factor makes the bridge less stable, a smaller
factor makes joints and contacts more spongy.
Pseudo Velocities - the is more stable than the Baumgarte method. The bridge is
stable. However, joints still separate with large angular velocities. Drag the
simple pendulum in a circle quickly and the joint will separate. The chain separates
easily and does not recover. I used a bias factor of 0.2. A larger value lead to
the bridge collapsing when a heavy cube drops on it.
Modified NGS - this algorithm is better in some ways than Baumgarte and Pseudo
Velocities, but in other ways it is worse. The bridge and chain are much more
stable, but the simple pendulum goes unstable at high angular velocities.
Full NGS - stable in all tests. The joints display good stiffness. The bridge
still sags, but this is better than infinite forces.
Recommendations
Pseudo Velocities are not really worthwhile because the bridge and chain cannot
recover from joint separation. In other cases the benefit over Baumgarte is small.
Modified NGS is not a robust method for the revolute joint due to the violent
instability seen in the simple pendulum. Perhaps it is viable with other constraint
types, especially scalar constraints where the effective mass is a scalar.
This leaves Baumgarte and Full NGS. Baumgarte has small, but manageable instabilities
and is very fast. I don't think we can escape Baumgarte, especially in highly
demanding cases where high constraint fidelity is not needed.
Full NGS is robust and easy on the eyes. I recommend this option for
higher fidelity simulation and certainly for suspension bridges and long chains.
Full NGS might be a good choice for ragdolls, especially motorized ragdolls where
joint separation can be problematic. The number of NGS iterations can be reduced
for better performance without harming robustness much.
Each joint in a can be handled differently in the position solver. So I recommend
a system where the user can select the algorithm on a per joint basis. I would
probably default to the slower Full NGS and let the user select the faster
Baumgarte method in performance critical scenarios.
*/
var b2Island = Class.create();
b2Island.prototype =
{
initialize: function(bodyCapacity, contactCapacity, jointCapacity, allocator)
{
var i = 0;
this.m_bodyCapacity = bodyCapacity;
this.m_contactCapacity = contactCapacity;
this.m_jointCapacity = jointCapacity;
this.m_bodyCount = 0;
this.m_contactCount = 0;
this.m_jointCount = 0;
//this.m_bodies = (b2Body**)allocator->Allocate(bodyCapacity * sizeof(b2Body*));
this.m_bodies = new Array(bodyCapacity);
for (i = 0; i < bodyCapacity; i++)
this.m_bodies[i] = null;
//this.m_contacts = (b2Contact**)allocator->Allocate(contactCapacity * sizeof(b2Contact*));
this.m_contacts = new Array(contactCapacity);
for (i = 0; i < contactCapacity; i++)
this.m_contacts[i] = null;
//this.m_joints = (b2Joint**)allocator->Allocate(jointCapacity * sizeof(b2Joint*));
this.m_joints = new Array(jointCapacity);
for (i = 0; i < jointCapacity; i++)
this.m_joints[i] = null;
this.m_allocator = allocator;
},
//~b2Island();
Clear: function()
{
this.m_bodyCount = 0;
this.m_contactCount = 0;
this.m_jointCount = 0;
},
Solve: function(step, gravity)
{
var i = 0;
var b;
for (i = 0; i < this.m_bodyCount; ++i)
{
b = this.m_bodies[i];
if (b.m_invMass == 0.0)
continue;
b.m_linearVelocity.Add( b2Math.MulFV (step.dt, b2Math.AddVV(gravity, b2Math.MulFV( b.m_invMass, b.m_force ) ) ) );
b.m_angularVelocity += step.dt * b.m_invI * b.m_torque;
//b.m_linearVelocity *= b.m_linearDamping;
b.m_linearVelocity.Multiply(b.m_linearDamping);
b.m_angularVelocity *= b.m_angularDamping;
// Store positions for conservative advancement.
b.m_position0.SetV(b.m_position);
b.m_rotation0 = b.m_rotation;
}
var contactSolver = new b2ContactSolver(this.m_contacts, this.m_contactCount, this.m_allocator);
// Pre-solve
contactSolver.PreSolve();
for (i = 0; i < this.m_jointCount; ++i)
{
this.m_joints[i].PrepareVelocitySolver();
}
// this.Solve velocity constraints.
for (i = 0; i < step.iterations; ++i)
{
contactSolver.SolveVelocityConstraints();
for (var j = 0; j < this.m_jointCount; ++j)
{
this.m_joints[j].SolveVelocityConstraints(step);
}
}
// Integrate positions.
for (i = 0; i < this.m_bodyCount; ++i)
{
b = this.m_bodies[i];
if (b.m_invMass == 0.0)
continue;
//b.m_position.Add( b2Math.MulFV (step.dt, b.m_linearVelocity) );
b.m_position.x += step.dt * b.m_linearVelocity.x;
b.m_position.y += step.dt * b.m_linearVelocity.y;
b.m_rotation += step.dt * b.m_angularVelocity;
b.m_R.Set(b.m_rotation);
}
for (i = 0; i < this.m_jointCount; ++i)
{
this.m_joints[i].PreparePositionSolver();
}
// this.Solve position constraints.
if (b2World.s_enablePositionCorrection)
{
for (b2Island.m_positionIterationCount = 0; b2Island.m_positionIterationCount < step.iterations; ++b2Island.m_positionIterationCount)
{
var contactsOkay = contactSolver.SolvePositionConstraints(b2Settings.b2_contactBaumgarte);
var jointsOkay = true;
for (i = 0; i < this.m_jointCount; ++i)
{
var jointOkay = this.m_joints[i].SolvePositionConstraints();
jointsOkay = jointsOkay && jointOkay;
}
if (contactsOkay && jointsOkay)
{
break;
}
}
}
// Post-solve.
contactSolver.PostSolve();
// Synchronize shapes and reset forces.
for (i = 0; i < this.m_bodyCount; ++i)
{
b = this.m_bodies[i];
if (b.m_invMass == 0.0)
continue;
b.m_R.Set(b.m_rotation);
b.SynchronizeShapes();
b.m_force.Set(0.0, 0.0);
b.m_torque = 0.0;
}
},
UpdateSleep: function(dt)
{
var i = 0;
var b;
var minSleepTime = Number.MAX_VALUE;
var linTolSqr = b2Settings.b2_linearSleepTolerance * b2Settings.b2_linearSleepTolerance;
var angTolSqr = b2Settings.b2_angularSleepTolerance * b2Settings.b2_angularSleepTolerance;
for (i = 0; i < this.m_bodyCount; ++i)
{
b = this.m_bodies[i];
if (b.m_invMass == 0.0)
{
continue;
}
if ((b.m_flags & b2Body.e_allowSleepFlag) == 0)
{
b.m_sleepTime = 0.0;
minSleepTime = 0.0;
}
if ((b.m_flags & b2Body.e_allowSleepFlag) == 0 ||
b.m_angularVelocity * b.m_angularVelocity > angTolSqr ||
b2Math.b2Dot(b.m_linearVelocity, b.m_linearVelocity) > linTolSqr)
{
b.m_sleepTime = 0.0;
minSleepTime = 0.0;
}
else
{
b.m_sleepTime += dt;
minSleepTime = b2Math.b2Min(minSleepTime, b.m_sleepTime);
}
}
if (minSleepTime >= b2Settings.b2_timeToSleep)
{
for (i = 0; i < this.m_bodyCount; ++i)
{
b = this.m_bodies[i];
b.m_flags |= b2Body.e_sleepFlag;
}
}
},
AddBody: function(body)
{
//b2Settings.b2Assert(this.m_bodyCount < this.m_bodyCapacity);
this.m_bodies[this.m_bodyCount++] = body;
},
AddContact: function(contact)
{
//b2Settings.b2Assert(this.m_contactCount < this.m_contactCapacity);
this.m_contacts[this.m_contactCount++] = contact;
},
AddJoint: function(joint)
{
//b2Settings.b2Assert(this.m_jointCount < this.m_jointCapacity);
this.m_joints[this.m_jointCount++] = joint;
},
m_allocator: null,
m_bodies: null,
m_contacts: null,
m_joints: null,
m_bodyCount: 0,
m_jointCount: 0,
m_contactCount: 0,
m_bodyCapacity: 0,
m_contactCapacity: 0,
m_jointCapacity: 0,
m_positionError: null};
b2Island.m_positionIterationCount = 0;

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2TimeStep = Class.create();
b2TimeStep.prototype =
{
dt: null,
inv_dt: null,
iterations: 0,
initialize: function() {}};

View file

@ -0,0 +1,522 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2World = Class.create();
b2World.prototype =
{
initialize: function(worldAABB, gravity, doSleep){
// initialize instance variables for references
this.step = new b2TimeStep();
this.m_contactManager = new b2ContactManager();
//
this.m_listener = null;
this.m_filter = b2CollisionFilter.b2_defaultFilter;
this.m_bodyList = null;
this.m_contactList = null;
this.m_jointList = null;
this.m_bodyCount = 0;
this.m_contactCount = 0;
this.m_jointCount = 0;
this.m_bodyDestroyList = null;
this.m_allowSleep = doSleep;
this.m_gravity = gravity;
this.m_contactManager.m_world = this;
this.m_broadPhase = new b2BroadPhase(worldAABB, this.m_contactManager);
var bd = new b2BodyDef();
this.m_groundBody = this.CreateBody(bd);
},
//~b2World(){
// this.DestroyBody(this.m_groundBody);
// delete this.m_broadPhase;
//}
// Set a callback to notify you when a joint is implicitly destroyed
// when an attached body is destroyed.
SetListener: function(listener){
this.m_listener = listener;
},
// Register a collision filter to provide specific control over collision.
// Otherwise the default filter is used (b2CollisionFilter).
SetFilter: function(filter){
this.m_filter = filter;
},
// Create and destroy rigid bodies. Destruction is deferred until the
// the next call to this.Step. This is done so that bodies may be destroyed
// while you iterate through the contact list.
CreateBody: function(def){
//void* mem = this.m_blockAllocator.Allocate(sizeof(b2Body));
var b = new b2Body(def, this);
b.m_prev = null;
b.m_next = this.m_bodyList;
if (this.m_bodyList)
{
this.m_bodyList.m_prev = b;
}
this.m_bodyList = b;
++this.m_bodyCount;
return b;
},
// Body destruction is deferred to make contact processing more robust.
DestroyBody: function(b)
{
if (b.m_flags & b2Body.e_destroyFlag)
{
return;
}
// Remove from normal body list.
if (b.m_prev)
{
b.m_prev.m_next = b.m_next;
}
if (b.m_next)
{
b.m_next.m_prev = b.m_prev;
}
if (b == this.m_bodyList)
{
this.m_bodyList = b.m_next;
}
b.m_flags |= b2Body.e_destroyFlag;
//b2Settings.b2Assert(this.m_bodyCount > 0);
--this.m_bodyCount;
//b->~b2Body();
//b.Destroy();
// Add to the deferred destruction list.
b.m_prev = null;
b.m_next = this.m_bodyDestroyList;
this.m_bodyDestroyList = b;
},
CleanBodyList: function()
{
this.m_contactManager.m_destroyImmediate = true;
var b = this.m_bodyDestroyList;
while (b)
{
//b2Settings.b2Assert((b.m_flags & b2Body.e_destroyFlag) != 0);
// Preserve the next pointer.
var b0 = b;
b = b.m_next;
// Delete the attached joints
var jn = b0.m_jointList;
while (jn)
{
var jn0 = jn;
jn = jn.next;
if (this.m_listener)
{
this.m_listener.NotifyJointDestroyed(jn0.joint);
}
this.DestroyJoint(jn0.joint);
}
b0.Destroy();
//this.m_blockAllocator.Free(b0, sizeof(b2Body));
}
// Reset the list.
this.m_bodyDestroyList = null;
this.m_contactManager.m_destroyImmediate = false;
},
CreateJoint: function(def){
var j = b2Joint.Create(def, this.m_blockAllocator);
// Connect to the world list.
j.m_prev = null;
j.m_next = this.m_jointList;
if (this.m_jointList)
{
this.m_jointList.m_prev = j;
}
this.m_jointList = j;
++this.m_jointCount;
// Connect to the bodies
j.m_node1.joint = j;
j.m_node1.other = j.m_body2;
j.m_node1.prev = null;
j.m_node1.next = j.m_body1.m_jointList;
if (j.m_body1.m_jointList) j.m_body1.m_jointList.prev = j.m_node1;
j.m_body1.m_jointList = j.m_node1;
j.m_node2.joint = j;
j.m_node2.other = j.m_body1;
j.m_node2.prev = null;
j.m_node2.next = j.m_body2.m_jointList;
if (j.m_body2.m_jointList) j.m_body2.m_jointList.prev = j.m_node2;
j.m_body2.m_jointList = j.m_node2;
// If the joint prevents collisions, then reset collision filtering.
if (def.collideConnected == false)
{
// Reset the proxies on the body with the minimum number of shapes.
var b = def.body1.m_shapeCount < def.body2.m_shapeCount ? def.body1 : def.body2;
for (var s = b.m_shapeList; s; s = s.m_next)
{
s.ResetProxy(this.m_broadPhase);
}
}
return j;
},
DestroyJoint: function(j)
{
var collideConnected = j.m_collideConnected;
// Remove from the world.
if (j.m_prev)
{
j.m_prev.m_next = j.m_next;
}
if (j.m_next)
{
j.m_next.m_prev = j.m_prev;
}
if (j == this.m_jointList)
{
this.m_jointList = j.m_next;
}
// Disconnect from island graph.
var body1 = j.m_body1;
var body2 = j.m_body2;
// Wake up touching bodies.
body1.WakeUp();
body2.WakeUp();
// Remove from body 1
if (j.m_node1.prev)
{
j.m_node1.prev.next = j.m_node1.next;
}
if (j.m_node1.next)
{
j.m_node1.next.prev = j.m_node1.prev;
}
if (j.m_node1 == body1.m_jointList)
{
body1.m_jointList = j.m_node1.next;
}
j.m_node1.prev = null;
j.m_node1.next = null;
// Remove from body 2
if (j.m_node2.prev)
{
j.m_node2.prev.next = j.m_node2.next;
}
if (j.m_node2.next)
{
j.m_node2.next.prev = j.m_node2.prev;
}
if (j.m_node2 == body2.m_jointList)
{
body2.m_jointList = j.m_node2.next;
}
j.m_node2.prev = null;
j.m_node2.next = null;
b2Joint.Destroy(j, this.m_blockAllocator);
//b2Settings.b2Assert(this.m_jointCount > 0);
--this.m_jointCount;
// If the joint prevents collisions, then reset collision filtering.
if (collideConnected == false)
{
// Reset the proxies on the body with the minimum number of shapes.
var b = body1.m_shapeCount < body2.m_shapeCount ? body1 : body2;
for (var s = b.m_shapeList; s; s = s.m_next)
{
s.ResetProxy(this.m_broadPhase);
}
}
},
// The world provides a single ground body with no collision shapes. You
// can use this to simplify the creation of joints.
GetGroundBody: function(){
return this.m_groundBody;
},
step: new b2TimeStep(),
// this.Step
Step: function(dt, iterations){
var b;
var other;
this.step.dt = dt;
this.step.iterations = iterations;
if (dt > 0.0)
{
this.step.inv_dt = 1.0 / dt;
}
else
{
this.step.inv_dt = 0.0;
}
this.m_positionIterationCount = 0;
// Handle deferred contact destruction.
this.m_contactManager.CleanContactList();
// Handle deferred body destruction.
this.CleanBodyList();
// Update contacts.
this.m_contactManager.Collide();
// Size the island for the worst case.
var island = new b2Island(this.m_bodyCount, this.m_contactCount, this.m_jointCount, this.m_stackAllocator);
// Clear all the island flags.
for (b = this.m_bodyList; b != null; b = b.m_next)
{
b.m_flags &= ~b2Body.e_islandFlag;
}
for (var c = this.m_contactList; c != null; c = c.m_next)
{
c.m_flags &= ~b2Contact.e_islandFlag;
}
for (var j = this.m_jointList; j != null; j = j.m_next)
{
j.m_islandFlag = false;
}
// Build and simulate all awake islands.
var stackSize = this.m_bodyCount;
//var stack = (b2Body**)this.m_stackAllocator.Allocate(stackSize * sizeof(b2Body*));
var stack = new Array(this.m_bodyCount);
for (var k = 0; k < this.m_bodyCount; k++)
stack[k] = null;
for (var seed = this.m_bodyList; seed != null; seed = seed.m_next)
{
if (seed.m_flags & (b2Body.e_staticFlag | b2Body.e_islandFlag | b2Body.e_sleepFlag | b2Body.e_frozenFlag))
{
continue;
}
// Reset island and stack.
island.Clear();
var stackCount = 0;
stack[stackCount++] = seed;
seed.m_flags |= b2Body.e_islandFlag;;
// Perform a depth first search (DFS) on the constraint graph.
while (stackCount > 0)
{
// Grab the next body off the stack and add it to the island.
b = stack[--stackCount];
island.AddBody(b);
// Make sure the body is awake.
b.m_flags &= ~b2Body.e_sleepFlag;
// To keep islands, we don't
// propagate islands across static bodies.
if (b.m_flags & b2Body.e_staticFlag)
{
continue;
}
// Search all contacts connected to this body.
for (var cn = b.m_contactList; cn != null; cn = cn.next)
{
if (cn.contact.m_flags & b2Contact.e_islandFlag)
{
continue;
}
island.AddContact(cn.contact);
cn.contact.m_flags |= b2Contact.e_islandFlag;
other = cn.other;
if (other.m_flags & b2Body.e_islandFlag)
{
continue;
}
//b2Settings.b2Assert(stackCount < stackSize);
stack[stackCount++] = other;
other.m_flags |= b2Body.e_islandFlag;
}
// Search all joints connect to this body.
for (var jn = b.m_jointList; jn != null; jn = jn.next)
{
if (jn.joint.m_islandFlag == true)
{
continue;
}
island.AddJoint(jn.joint);
jn.joint.m_islandFlag = true;
other = jn.other;
if (other.m_flags & b2Body.e_islandFlag)
{
continue;
}
//b2Settings.b2Assert(stackCount < stackSize);
stack[stackCount++] = other;
other.m_flags |= b2Body.e_islandFlag;
}
}
island.Solve(this.step, this.m_gravity);
this.m_positionIterationCount = b2Math.b2Max(this.m_positionIterationCount, b2Island.m_positionIterationCount);
if (this.m_allowSleep)
{
island.UpdateSleep(dt);
}
// Post solve cleanup.
for (var i = 0; i < island.m_bodyCount; ++i)
{
// Allow static bodies to participate in other islands.
b = island.m_bodies[i];
if (b.m_flags & b2Body.e_staticFlag)
{
b.m_flags &= ~b2Body.e_islandFlag;
}
// Handle newly frozen bodies.
if (b.IsFrozen() && this.m_listener)
{
var response = this.m_listener.NotifyBoundaryViolated(b);
if (response == b2WorldListener.b2_destroyBody)
{
this.DestroyBody(b);
b = null;
island.m_bodies[i] = null;
}
}
}
}
this.m_broadPhase.Commit();
//this.m_stackAllocator.Free(stack);
},
// this.Query the world for all shapes that potentially overlap the
// provided AABB. You provide a shape pointer buffer of specified
// size. The number of shapes found is returned.
Query: function(aabb, shapes, maxCount){
//void** results = (void**)this.m_stackAllocator.Allocate(maxCount * sizeof(void*));
var results = new Array();
var count = this.m_broadPhase.QueryAABB(aabb, results, maxCount);
for (var i = 0; i < count; ++i)
{
shapes[i] = results[i];
}
//this.m_stackAllocator.Free(results);
return count;
},
// You can use these to iterate over all the bodies, joints, and contacts.
GetBodyList: function(){
return this.m_bodyList;
},
GetJointList: function(){
return this.m_jointList;
},
GetContactList: function(){
return this.m_contactList;
},
//--------------- Internals Below -------------------
m_blockAllocator: null,
m_stackAllocator: null,
m_broadPhase: null,
m_contactManager: new b2ContactManager(),
m_bodyList: null,
m_contactList: null,
m_jointList: null,
m_bodyCount: 0,
m_contactCount: 0,
m_jointCount: 0,
// These bodies will be destroyed at the next time this.step.
m_bodyDestroyList: null,
m_gravity: null,
m_allowSleep: null,
m_groundBody: null,
m_listener: null,
m_filter: null,
m_positionIterationCount: 0};
b2World.s_enablePositionCorrection = 1;
b2World.s_enableWarmStarting = 1;

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2WorldListener = Class.create();
b2WorldListener.prototype =
{
// If a body is destroyed, then any joints attached to it are also destroyed.
// This prevents memory leaks, but you may unexpectedly be left with an
// orphaned joint pointer.
// Box2D will notify you when a joint is implicitly destroyed.
// It is NOT called if you directly destroy a joint.
// Implement this abstract class and provide it to b2World via
// b2World::SetListener().
// DO NOT modify the Box2D world inside this callback.
NotifyJointDestroyed: function(joint){},
// This is called when a body's shape passes outside of the world boundary. If you
// override this and pass back e_destroyBody, you must nullify your copies of the
// body pointer.
NotifyBoundaryViolated: function(body)
{
//NOT_USED(body);
return b2WorldListener.b2_freezeBody;
},
initialize: function() {}};
b2WorldListener.b2_freezeBody = 0;
b2WorldListener.b2_destroyBody = 1;

View file

@ -0,0 +1,102 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2CircleContact = Class.create();
Object.extend(b2CircleContact.prototype, b2Contact.prototype);
Object.extend(b2CircleContact.prototype,
{
initialize: function(s1, s2) {
// The constructor for b2Contact
// initialize instance variables for references
this.m_node1 = new b2ContactNode();
this.m_node2 = new b2ContactNode();
//
this.m_flags = 0;
if (!s1 || !s2){
this.m_shape1 = null;
this.m_shape2 = null;
return;
}
this.m_shape1 = s1;
this.m_shape2 = s2;
this.m_manifoldCount = 0;
this.m_friction = Math.sqrt(this.m_shape1.m_friction * this.m_shape2.m_friction);
this.m_restitution = b2Math.b2Max(this.m_shape1.m_restitution, this.m_shape2.m_restitution);
this.m_prev = null;
this.m_next = null;
this.m_node1.contact = null;
this.m_node1.prev = null;
this.m_node1.next = null;
this.m_node1.other = null;
this.m_node2.contact = null;
this.m_node2.prev = null;
this.m_node2.next = null;
this.m_node2.other = null;
//
// initialize instance variables for references
this.m_manifold = [new b2Manifold()];
//
//super(shape1, shape2);
//b2Settings.b2Assert(this.m_shape1.m_type == b2Shape.e_circleShape);
//b2Settings.b2Assert(this.m_shape2.m_type == b2Shape.e_circleShape);
this.m_manifold[0].pointCount = 0;
this.m_manifold[0].points[0].normalImpulse = 0.0;
this.m_manifold[0].points[0].tangentImpulse = 0.0;
},
//~b2CircleContact() {}
Evaluate: function(){
b2Collision.b2CollideCircle(this.m_manifold[0], this.m_shape1, this.m_shape2, false);
if (this.m_manifold[0].pointCount > 0)
{
this.m_manifoldCount = 1;
}
else
{
this.m_manifoldCount = 0;
}
},
GetManifolds: function()
{
return this.m_manifold;
},
m_manifold: [new b2Manifold()]});
b2CircleContact.Create = function(shape1, shape2, allocator){
return new b2CircleContact(shape1, shape2);
};
b2CircleContact.Destroy = function(contact, allocator){
//
};

View file

@ -0,0 +1,228 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2Conservative = Class.create();
b2Conservative.prototype = {
// Temp vars
initialize: function() {}}
b2Conservative.R1 = new b2Mat22();
b2Conservative.R2 = new b2Mat22();
b2Conservative.x1 = new b2Vec2();
b2Conservative.x2 = new b2Vec2();
b2Conservative.Conservative = function(shape1, shape2){
var body1 = shape1.GetBody();
var body2 = shape2.GetBody();
//b2Vec2 v1 = body1->m_position - body1->m_position0;
var v1X = body1.m_position.x - body1.m_position0.x;
var v1Y = body1.m_position.y - body1.m_position0.y;
//float32 omega1 = body1->m_rotation - body1->m_rotation0;
var omega1 = body1.m_rotation - body1.m_rotation0;
//b2Vec2 v2 = body2->m_position - body2->m_position0;
var v2X = body2.m_position.x - body2.m_position0.x;
var v2Y = body2.m_position.y - body2.m_position0.y;
//float32 omega2 = body2->m_rotation - body2->m_rotation0;
var omega2 = body2.m_rotation - body2.m_rotation0;
//float32 r1 = shape1->GetMaxRadius();
var r1 = shape1.GetMaxRadius();
//float32 r2 = shape2->GetMaxRadius();
var r2 = shape2.GetMaxRadius();
//b2Vec2 p1Start = body1->m_position0;
var p1StartX = body1.m_position0.x;
var p1StartY = body1.m_position0.y;
//float32 a1Start = body1->m_rotation0;
var a1Start = body1.m_rotation0;
//b2Vec2 p2Start = body2->m_position0;
var p2StartX = body2.m_position0.x;
var p2StartY = body2.m_position0.y;
//float32 a2Start = body2->m_rotation0;
var a2Start = body2.m_rotation0;
//b2Vec2 p1 = p1Start;
var p1X = p1StartX;
var p1Y = p1StartY;
//float32 a1 = a1Start;
var a1 = a1Start;
//b2Vec2 p2 = p2Start;
var p2X = p2StartX;
var p2Y = p2StartY;
//float32 a2 = a2Start;
var a2 = a2Start;
//b2Mat22 b2Conservative.R1(a1), b2Conservative.R2(a2);
b2Conservative.R1.Set(a1);
b2Conservative.R2.Set(a2);
//shape1->QuickSync(p1, b2Conservative.R1);
shape1.QuickSync(p1, b2Conservative.R1);
//shape2->QuickSync(p2, b2Conservative.R2);
shape2.QuickSync(p2, b2Conservative.R2);
//float32 s1 = 0.0f;
var s1 = 0.0;
//const int32 maxIterations = 10;
var maxIterations = 10;
//b2Vec2 d;
var dX;
var dY;
//float32 invRelativeVelocity = 0.0f;
var invRelativeVelocity = 0.0;
//bool hit = true;
var hit = true;
//b2Vec2 b2Conservative.x1, b2Conservative.x2; moved to static var
for (var iter = 0; iter < maxIterations; ++iter)
{
// Get the accurate distance between shapes.
//float32 distance = b2Distance.Distance(&b2Conservative.x1, &b2Conservative.x2, shape1, shape2);
var distance = b2Distance.Distance(b2Conservative.x1, b2Conservative.x2, shape1, shape2);
if (distance < b2Settings.b2_linearSlop)
{
if (iter == 0)
{
hit = false;
}
else
{
hit = true;
}
break;
}
if (iter == 0)
{
//b2Vec2 d = b2Conservative.x2 - b2Conservative.x1;
dX = b2Conservative.x2.x - b2Conservative.x1.x;
dY = b2Conservative.x2.y - b2Conservative.x1.y;
//d.Normalize();
var dLen = Math.sqrt(dX*dX + dY*dY);
//float32 relativeVelocity = b2Dot(d, v1 - v2) + b2Abs(omega1) * r1 + b2Abs(omega2) * r2;
var relativeVelocity = (dX*(v1X-v2X) + dY*(v1Y - v2Y)) + Math.abs(omega1) * r1 + Math.abs(omega2) * r2;
if (Math.abs(relativeVelocity) < Number.MIN_VALUE)
{
hit = false;
break;
}
invRelativeVelocity = 1.0 / relativeVelocity;
}
// Get the conservative movement.
//float32 ds = distance * invRelativeVelocity;
var ds = distance * invRelativeVelocity;
//float32 s2 = s1 + ds;
var s2 = s1 + ds;
if (s2 < 0.0 || 1.0 < s2)
{
hit = false;
break;
}
if (s2 < (1.0 + 100.0 * Number.MIN_VALUE) * s1)
{
hit = true;
break;
}
s1 = s2;
// Move forward conservatively.
//p1 = p1Start + s1 * v1;
p1X = p1StartX + s1 * v1.x;
p1Y = p1StartY + s1 * v1.y;
//a1 = a1Start + s1 * omega1;
a1 = a1Start + s1 * omega1;
//p2 = p2Start + s1 * v2;
p2X = p2StartX + s1 * v2.x;
p2Y = p2StartY + s1 * v2.y;
//a2 = a2Start + s1 * omega2;
a2 = a2Start + s1 * omega2;
b2Conservative.R1.Set(a1);
b2Conservative.R2.Set(a2);
shape1.QuickSync(p1, b2Conservative.R1);
shape2.QuickSync(p2, b2Conservative.R2);
}
if (hit)
{
// Hit, move bodies to safe position and re-sync shapes.
//b2Vec2 d = b2Conservative.x2 - b2Conservative.x1;
dX = b2Conservative.x2.x - b2Conservative.x1.x;
dY = b2Conservative.x2.y - b2Conservative.x1.y;
//float32 length = d.Length();
var length = Math.sqrt(dX*dX + dY*dY);
if (length > FLT_EPSILON)
{
d *= b2_linearSlop / length;
}
if (body1.IsStatic())
{
//body1.m_position = p1;
body1.m_position.x = p1X;
body1.m_position.y = p1Y;
}
else
{
//body1.m_position = p1 - d;
body1.m_position.x = p1X - dX;
body1.m_position.y = p1Y - dY;
}
body1.m_rotation = a1;
body1.m_R.Set(a1);
body1.QuickSyncShapes();
if (body2.IsStatic())
{
//body2->m_position = p2;
body2.m_position.x = p2X;
body2.m_position.y = p2Y;
}
else
{
//body2->m_position = p2 + d;
body2.m_position.x = p2X + dX;
body2.m_position.y = p2Y + dY;
}
//body2.m_position = p2 + d;
body2.m_position.x = p2X + dX;
body2.m_position.y = p2Y + dY;
body2.m_rotation = a2;
body2.m_R.Set(a2);
body2.QuickSyncShapes();
return true;
}
// No hit, restore shapes.
shape1.QuickSync(body1.m_position, body1.m_R);
shape2.QuickSync(body2.m_position, body2.m_R);
return false;
};

View file

@ -0,0 +1,201 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
//typedef b2Contact* b2ContactCreateFcn(b2Shape* shape1, b2Shape* shape2, b2BlockAllocator* allocator);
//typedef void b2ContactDestroyFcn(b2Contact* contact, b2BlockAllocator* allocator);
var b2Contact = Class.create();
b2Contact.prototype =
{
GetManifolds: function(){return null},
GetManifoldCount: function()
{
return this.m_manifoldCount;
},
GetNext: function(){
return this.m_next;
},
GetShape1: function(){
return this.m_shape1;
},
GetShape2: function(){
return this.m_shape2;
},
//--------------- Internals Below -------------------
// this.m_flags
// enum
initialize: function(s1, s2)
{
// initialize instance variables for references
this.m_node1 = new b2ContactNode();
this.m_node2 = new b2ContactNode();
//
this.m_flags = 0;
if (!s1 || !s2){
this.m_shape1 = null;
this.m_shape2 = null;
return;
}
this.m_shape1 = s1;
this.m_shape2 = s2;
this.m_manifoldCount = 0;
this.m_friction = Math.sqrt(this.m_shape1.m_friction * this.m_shape2.m_friction);
this.m_restitution = b2Math.b2Max(this.m_shape1.m_restitution, this.m_shape2.m_restitution);
this.m_prev = null;
this.m_next = null;
this.m_node1.contact = null;
this.m_node1.prev = null;
this.m_node1.next = null;
this.m_node1.other = null;
this.m_node2.contact = null;
this.m_node2.prev = null;
this.m_node2.next = null;
this.m_node2.other = null;
},
//virtual ~b2Contact() {}
Evaluate: function(){},
m_flags: 0,
// World pool and list pointers.
m_prev: null,
m_next: null,
// Nodes for connecting bodies.
m_node1: new b2ContactNode(),
m_node2: new b2ContactNode(),
m_shape1: null,
m_shape2: null,
m_manifoldCount: 0,
// Combined friction
m_friction: null,
m_restitution: null};
b2Contact.e_islandFlag = 0x0001;
b2Contact.e_destroyFlag = 0x0002;
b2Contact.AddType = function(createFcn, destroyFcn, type1, type2)
{
//b2Settings.b2Assert(b2Shape.e_unknownShape < type1 && type1 < b2Shape.e_shapeTypeCount);
//b2Settings.b2Assert(b2Shape.e_unknownShape < type2 && type2 < b2Shape.e_shapeTypeCount);
b2Contact.s_registers[type1][type2].createFcn = createFcn;
b2Contact.s_registers[type1][type2].destroyFcn = destroyFcn;
b2Contact.s_registers[type1][type2].primary = true;
if (type1 != type2)
{
b2Contact.s_registers[type2][type1].createFcn = createFcn;
b2Contact.s_registers[type2][type1].destroyFcn = destroyFcn;
b2Contact.s_registers[type2][type1].primary = false;
}
};
b2Contact.InitializeRegisters = function(){
b2Contact.s_registers = new Array(b2Shape.e_shapeTypeCount);
for (var i = 0; i < b2Shape.e_shapeTypeCount; i++){
b2Contact.s_registers[i] = new Array(b2Shape.e_shapeTypeCount);
for (var j = 0; j < b2Shape.e_shapeTypeCount; j++){
b2Contact.s_registers[i][j] = new b2ContactRegister();
}
}
b2Contact.AddType(b2CircleContact.Create, b2CircleContact.Destroy, b2Shape.e_circleShape, b2Shape.e_circleShape);
b2Contact.AddType(b2PolyAndCircleContact.Create, b2PolyAndCircleContact.Destroy, b2Shape.e_polyShape, b2Shape.e_circleShape);
b2Contact.AddType(b2PolyContact.Create, b2PolyContact.Destroy, b2Shape.e_polyShape, b2Shape.e_polyShape);
};
b2Contact.Create = function(shape1, shape2, allocator){
if (b2Contact.s_initialized == false)
{
b2Contact.InitializeRegisters();
b2Contact.s_initialized = true;
}
var type1 = shape1.m_type;
var type2 = shape2.m_type;
//b2Settings.b2Assert(b2Shape.e_unknownShape < type1 && type1 < b2Shape.e_shapeTypeCount);
//b2Settings.b2Assert(b2Shape.e_unknownShape < type2 && type2 < b2Shape.e_shapeTypeCount);
var createFcn = b2Contact.s_registers[type1][type2].createFcn;
if (createFcn)
{
if (b2Contact.s_registers[type1][type2].primary)
{
return createFcn(shape1, shape2, allocator);
}
else
{
var c = createFcn(shape2, shape1, allocator);
for (var i = 0; i < c.GetManifoldCount(); ++i)
{
var m = c.GetManifolds()[ i ];
m.normal = m.normal.Negative();
}
return c;
}
}
else
{
return null;
}
};
b2Contact.Destroy = function(contact, allocator){
//b2Settings.b2Assert(b2Contact.s_initialized == true);
if (contact.GetManifoldCount() > 0)
{
contact.m_shape1.m_body.WakeUp();
contact.m_shape2.m_body.WakeUp();
}
var type1 = contact.m_shape1.m_type;
var type2 = contact.m_shape2.m_type;
//b2Settings.b2Assert(b2Shape.e_unknownShape < type1 && type1 < b2Shape.e_shapeTypeCount);
//b2Settings.b2Assert(b2Shape.e_unknownShape < type2 && type2 < b2Shape.e_shapeTypeCount);
var destroyFcn = b2Contact.s_registers[type1][type2].destroyFcn;
destroyFcn(contact, allocator);
};
b2Contact.s_registers = null;
b2Contact.s_initialized = false;

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2ContactConstraint = Class.create();
b2ContactConstraint.prototype =
{
initialize: function(){
// initialize instance variables for references
this.normal = new b2Vec2();
//
this.points = new Array(b2Settings.b2_maxManifoldPoints);
for (var i = 0; i < b2Settings.b2_maxManifoldPoints; i++){
this.points[i] = new b2ContactConstraintPoint();
}
},
points: null,
normal: new b2Vec2(),
manifold: null,
body1: null,
body2: null,
friction: null,
restitution: null,
pointCount: 0};

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2ContactConstraintPoint = Class.create();
b2ContactConstraintPoint.prototype =
{
localAnchor1: new b2Vec2(),
localAnchor2: new b2Vec2(),
normalImpulse: null,
tangentImpulse: null,
positionImpulse: null,
normalMass: null,
tangentMass: null,
separation: null,
velocityBias: null,
initialize: function() {
// initialize instance variables for references
this.localAnchor1 = new b2Vec2();
this.localAnchor2 = new b2Vec2();
//
}};

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2ContactNode = Class.create();
b2ContactNode.prototype =
{
other: null,
contact: null,
prev: null,
next: null,
initialize: function() {}};

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2ContactRegister = Class.create();
b2ContactRegister.prototype =
{
createFcn: null,
destroyFcn: null,
primary: null,
initialize: function() {}};

View file

@ -0,0 +1,537 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2ContactSolver = Class.create();
b2ContactSolver.prototype =
{
initialize: function(contacts, contactCount, allocator){
// initialize instance variables for references
this.m_constraints = new Array();
//
this.m_allocator = allocator;
var i = 0;
var tVec;
var tMat;
this.m_constraintCount = 0;
for (i = 0; i < contactCount; ++i)
{
this.m_constraintCount += contacts[i].GetManifoldCount();
}
// fill array
for (i = 0; i < this.m_constraintCount; i++){
this.m_constraints[i] = new b2ContactConstraint();
}
var count = 0;
for (i = 0; i < contactCount; ++i)
{
var contact = contacts[i];
var b1 = contact.m_shape1.m_body;
var b2 = contact.m_shape2.m_body;
var manifoldCount = contact.GetManifoldCount();
var manifolds = contact.GetManifolds();
var friction = contact.m_friction;
var restitution = contact.m_restitution;
//var v1 = b1.m_linearVelocity.Copy();
var v1X = b1.m_linearVelocity.x;
var v1Y = b1.m_linearVelocity.y;
//var v2 = b2.m_linearVelocity.Copy();
var v2X = b2.m_linearVelocity.x;
var v2Y = b2.m_linearVelocity.y;
var w1 = b1.m_angularVelocity;
var w2 = b2.m_angularVelocity;
for (var j = 0; j < manifoldCount; ++j)
{
var manifold = manifolds[ j ];
//b2Settings.b2Assert(manifold.pointCount > 0);
//var normal = manifold.normal.Copy();
var normalX = manifold.normal.x;
var normalY = manifold.normal.y;
//b2Settings.b2Assert(count < this.m_constraintCount);
var c = this.m_constraints[ count ];
c.body1 = b1;
c.body2 = b2;
c.manifold = manifold;
//c.normal = normal;
c.normal.x = normalX;
c.normal.y = normalY;
c.pointCount = manifold.pointCount;
c.friction = friction;
c.restitution = restitution;
for (var k = 0; k < c.pointCount; ++k)
{
var cp = manifold.points[ k ];
var ccp = c.points[ k ];
ccp.normalImpulse = cp.normalImpulse;
ccp.tangentImpulse = cp.tangentImpulse;
ccp.separation = cp.separation;
//var r1 = b2Math.SubtractVV( cp.position, b1.m_position );
var r1X = cp.position.x - b1.m_position.x;
var r1Y = cp.position.y - b1.m_position.y;
//var r2 = b2Math.SubtractVV( cp.position, b2.m_position );
var r2X = cp.position.x - b2.m_position.x;
var r2Y = cp.position.y - b2.m_position.y;
//ccp.localAnchor1 = b2Math.b2MulTMV(b1.m_R, r1);
tVec = ccp.localAnchor1;
tMat = b1.m_R;
tVec.x = r1X * tMat.col1.x + r1Y * tMat.col1.y;
tVec.y = r1X * tMat.col2.x + r1Y * tMat.col2.y;
//ccp.localAnchor2 = b2Math.b2MulTMV(b2.m_R, r2);
tVec = ccp.localAnchor2;
tMat = b2.m_R;
tVec.x = r2X * tMat.col1.x + r2Y * tMat.col1.y;
tVec.y = r2X * tMat.col2.x + r2Y * tMat.col2.y;
var r1Sqr = r1X * r1X + r1Y * r1Y;
var r2Sqr = r2X * r2X + r2Y * r2Y;
//var rn1 = b2Math.b2Dot(r1, normal);
var rn1 = r1X*normalX + r1Y*normalY;
//var rn2 = b2Math.b2Dot(r2, normal);
var rn2 = r2X*normalX + r2Y*normalY;
var kNormal = b1.m_invMass + b2.m_invMass;
kNormal += b1.m_invI * (r1Sqr - rn1 * rn1) + b2.m_invI * (r2Sqr - rn2 * rn2);
//b2Settings.b2Assert(kNormal > Number.MIN_VALUE);
ccp.normalMass = 1.0 / kNormal;
//var tangent = b2Math.b2CrossVF(normal, 1.0);
var tangentX = normalY
var tangentY = -normalX;
//var rt1 = b2Math.b2Dot(r1, tangent);
var rt1 = r1X*tangentX + r1Y*tangentY;
//var rt2 = b2Math.b2Dot(r2, tangent);
var rt2 = r2X*tangentX + r2Y*tangentY;
var kTangent = b1.m_invMass + b2.m_invMass;
kTangent += b1.m_invI * (r1Sqr - rt1 * rt1) + b2.m_invI * (r2Sqr - rt2 * rt2);
//b2Settings.b2Assert(kTangent > Number.MIN_VALUE);
ccp.tangentMass = 1.0 / kTangent;
// Setup a velocity bias for restitution.
ccp.velocityBias = 0.0;
if (ccp.separation > 0.0)
{
ccp.velocityBias = -60.0 * ccp.separation;
}
//var vRel = b2Math.b2Dot(c.normal, b2Math.SubtractVV( b2Math.SubtractVV( b2Math.AddVV( v2, b2Math.b2CrossFV(w2, r2)), v1 ), b2Math.b2CrossFV(w1, r1)));
var tX = v2X + (-w2*r2Y) - v1X - (-w1*r1Y);
var tY = v2Y + (w2*r2X) - v1Y - (w1*r1X);
//var vRel = b2Dot(c.normal, tX/Y);
var vRel = c.normal.x*tX + c.normal.y*tY;
if (vRel < -b2Settings.b2_velocityThreshold)
{
ccp.velocityBias += -c.restitution * vRel;
}
}
++count;
}
}
//b2Settings.b2Assert(count == this.m_constraintCount);
},
//~b2ContactSolver();
PreSolve: function(){
var tVec;
var tVec2;
var tMat;
// Warm start.
for (var i = 0; i < this.m_constraintCount; ++i)
{
var c = this.m_constraints[ i ];
var b1 = c.body1;
var b2 = c.body2;
var invMass1 = b1.m_invMass;
var invI1 = b1.m_invI;
var invMass2 = b2.m_invMass;
var invI2 = b2.m_invI;
//var normal = new b2Vec2(c.normal.x, c.normal.y);
var normalX = c.normal.x;
var normalY = c.normal.y;
//var tangent = b2Math.b2CrossVF(normal, 1.0);
var tangentX = normalY;
var tangentY = -normalX;
var j = 0;
var tCount = 0;
if (b2World.s_enableWarmStarting)
{
tCount = c.pointCount;
for (j = 0; j < tCount; ++j)
{
var ccp = c.points[ j ];
//var P = b2Math.AddVV( b2Math.MulFV(ccp.normalImpulse, normal), b2Math.MulFV(ccp.tangentImpulse, tangent));
var PX = ccp.normalImpulse*normalX + ccp.tangentImpulse*tangentX;
var PY = ccp.normalImpulse*normalY + ccp.tangentImpulse*tangentY;
//var r1 = b2Math.b2MulMV(b1.m_R, ccp.localAnchor1);
tMat = b1.m_R;
tVec = ccp.localAnchor1;
var r1X = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
var r1Y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
//var r2 = b2Math.b2MulMV(b2.m_R, ccp.localAnchor2);
tMat = b2.m_R;
tVec = ccp.localAnchor2;
var r2X = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
var r2Y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
//b1.m_angularVelocity -= invI1 * b2Math.b2CrossVV(r1, P);
b1.m_angularVelocity -= invI1 * (r1X * PY - r1Y * PX);
//b1.m_linearVelocity.Subtract( b2Math.MulFV(invMass1, P) );
b1.m_linearVelocity.x -= invMass1 * PX;
b1.m_linearVelocity.y -= invMass1 * PY;
//b2.m_angularVelocity += invI2 * b2Math.b2CrossVV(r2, P);
b2.m_angularVelocity += invI2 * (r2X * PY - r2Y * PX);
//b2.m_linearVelocity.Add( b2Math.MulFV(invMass2, P) );
b2.m_linearVelocity.x += invMass2 * PX;
b2.m_linearVelocity.y += invMass2 * PY;
ccp.positionImpulse = 0.0;
}
}
else{
tCount = c.pointCount;
for (j = 0; j < tCount; ++j)
{
var ccp2 = c.points[ j ];
ccp2.normalImpulse = 0.0;
ccp2.tangentImpulse = 0.0;
ccp2.positionImpulse = 0.0;
}
}
}
},
SolveVelocityConstraints: function(){
var j = 0;
var ccp;
var r1X;
var r1Y;
var r2X;
var r2Y;
var dvX;
var dvY;
var lambda;
var newImpulse;
var PX;
var PY;
var tMat;
var tVec;
for (var i = 0; i < this.m_constraintCount; ++i)
{
var c = this.m_constraints[ i ];
var b1 = c.body1;
var b2 = c.body2;
var b1_angularVelocity = b1.m_angularVelocity;
var b1_linearVelocity = b1.m_linearVelocity;
var b2_angularVelocity = b2.m_angularVelocity;
var b2_linearVelocity = b2.m_linearVelocity;
var invMass1 = b1.m_invMass;
var invI1 = b1.m_invI;
var invMass2 = b2.m_invMass;
var invI2 = b2.m_invI;
//var normal = new b2Vec2(c.normal.x, c.normal.y);
var normalX = c.normal.x;
var normalY = c.normal.y;
//var tangent = b2Math.b2CrossVF(normal, 1.0);
var tangentX = normalY;
var tangentY = -normalX;
// Solver normal constraints
var tCount = c.pointCount;
for (j = 0; j < tCount; ++j)
{
ccp = c.points[ j ];
//r1 = b2Math.b2MulMV(b1.m_R, ccp.localAnchor1);
tMat = b1.m_R;
tVec = ccp.localAnchor1;
r1X = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y
r1Y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y
//r2 = b2Math.b2MulMV(b2.m_R, ccp.localAnchor2);
tMat = b2.m_R;
tVec = ccp.localAnchor2;
r2X = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y
r2Y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y
// Relative velocity at contact
//var dv = b2Math.SubtractVV( b2Math.AddVV( b2.m_linearVelocity, b2Math.b2CrossFV(b2.m_angularVelocity, r2)), b2Math.SubtractVV(b1.m_linearVelocity, b2Math.b2CrossFV(b1.m_angularVelocity, r1)));
//dv = b2Math.SubtractVV(b2Math.SubtractVV( b2Math.AddVV( b2.m_linearVelocity, b2Math.b2CrossFV(b2.m_angularVelocity, r2)), b1.m_linearVelocity), b2Math.b2CrossFV(b1.m_angularVelocity, r1));
dvX = b2_linearVelocity.x + (-b2_angularVelocity * r2Y) - b1_linearVelocity.x - (-b1_angularVelocity * r1Y);
dvY = b2_linearVelocity.y + (b2_angularVelocity * r2X) - b1_linearVelocity.y - (b1_angularVelocity * r1X);
// Compute normal impulse
//var vn = b2Math.b2Dot(dv, normal);
var vn = dvX * normalX + dvY * normalY;
lambda = -ccp.normalMass * (vn - ccp.velocityBias);
// b2Clamp the accumulated impulse
newImpulse = b2Math.b2Max(ccp.normalImpulse + lambda, 0.0);
lambda = newImpulse - ccp.normalImpulse;
// Apply contact impulse
//P = b2Math.MulFV(lambda, normal);
PX = lambda * normalX;
PY = lambda * normalY;
//b1.m_linearVelocity.Subtract( b2Math.MulFV( invMass1, P ) );
b1_linearVelocity.x -= invMass1 * PX;
b1_linearVelocity.y -= invMass1 * PY;
b1_angularVelocity -= invI1 * (r1X * PY - r1Y * PX);
//b2.m_linearVelocity.Add( b2Math.MulFV( invMass2, P ) );
b2_linearVelocity.x += invMass2 * PX;
b2_linearVelocity.y += invMass2 * PY;
b2_angularVelocity += invI2 * (r2X * PY - r2Y * PX);
ccp.normalImpulse = newImpulse;
// MOVED FROM BELOW
// Relative velocity at contact
//var dv = b2.m_linearVelocity + b2Cross(b2.m_angularVelocity, r2) - b1.m_linearVelocity - b2Cross(b1.m_angularVelocity, r1);
//dv = b2Math.SubtractVV(b2Math.SubtractVV(b2Math.AddVV(b2.m_linearVelocity, b2Math.b2CrossFV(b2.m_angularVelocity, r2)), b1.m_linearVelocity), b2Math.b2CrossFV(b1.m_angularVelocity, r1));
dvX = b2_linearVelocity.x + (-b2_angularVelocity * r2Y) - b1_linearVelocity.x - (-b1_angularVelocity * r1Y);
dvY = b2_linearVelocity.y + (b2_angularVelocity * r2X) - b1_linearVelocity.y - (b1_angularVelocity * r1X);
// Compute tangent impulse
var vt = dvX*tangentX + dvY*tangentY;
lambda = ccp.tangentMass * (-vt);
// b2Clamp the accumulated impulse
var maxFriction = c.friction * ccp.normalImpulse;
newImpulse = b2Math.b2Clamp(ccp.tangentImpulse + lambda, -maxFriction, maxFriction);
lambda = newImpulse - ccp.tangentImpulse;
// Apply contact impulse
//P = b2Math.MulFV(lambda, tangent);
PX = lambda * tangentX;
PY = lambda * tangentY;
//b1.m_linearVelocity.Subtract( b2Math.MulFV( invMass1, P ) );
b1_linearVelocity.x -= invMass1 * PX;
b1_linearVelocity.y -= invMass1 * PY;
b1_angularVelocity -= invI1 * (r1X * PY - r1Y * PX);
//b2.m_linearVelocity.Add( b2Math.MulFV( invMass2, P ) );
b2_linearVelocity.x += invMass2 * PX;
b2_linearVelocity.y += invMass2 * PY;
b2_angularVelocity += invI2 * (r2X * PY - r2Y * PX);
ccp.tangentImpulse = newImpulse;
}
// Solver tangent constraints
// MOVED ABOVE FOR EFFICIENCY
/*for (j = 0; j < tCount; ++j)
{
ccp = c.points[ j ];
//r1 = b2Math.b2MulMV(b1.m_R, ccp.localAnchor1);
tMat = b1.m_R;
tVec = ccp.localAnchor1;
r1X = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y
r1Y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y
//r2 = b2Math.b2MulMV(b2.m_R, ccp.localAnchor2);
tMat = b2.m_R;
tVec = ccp.localAnchor2;
r2X = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y
r2Y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y
// Relative velocity at contact
//var dv = b2.m_linearVelocity + b2Cross(b2.m_angularVelocity, r2) - b1.m_linearVelocity - b2Cross(b1.m_angularVelocity, r1);
//dv = b2Math.SubtractVV(b2Math.SubtractVV(b2Math.AddVV(b2.m_linearVelocity, b2Math.b2CrossFV(b2.m_angularVelocity, r2)), b1.m_linearVelocity), b2Math.b2CrossFV(b1.m_angularVelocity, r1));
dvX = b2_linearVelocity.x + (-b2_angularVelocity * r2Y) - b1_linearVelocity.x - (-b1_angularVelocity * r1Y);
dvY = b2_linearVelocity.y + (b2_angularVelocity * r2X) - b1_linearVelocity.y - (b1_angularVelocity * r1X);
// Compute tangent impulse
var vt = dvX*tangentX + dvY*tangentY;
lambda = ccp.tangentMass * (-vt);
// b2Clamp the accumulated impulse
var maxFriction = c.friction * ccp.normalImpulse;
newImpulse = b2Math.b2Clamp(ccp.tangentImpulse + lambda, -maxFriction, maxFriction);
lambda = newImpulse - ccp.tangentImpulse;
// Apply contact impulse
//P = b2Math.MulFV(lambda, tangent);
PX = lambda * tangentX;
PY = lambda * tangentY;
//b1.m_linearVelocity.Subtract( b2Math.MulFV( invMass1, P ) );
b1_linearVelocity.x -= invMass1 * PX;
b1_linearVelocity.y -= invMass1 * PY;
b1_angularVelocity -= invI1 * (r1X * PY - r1Y * PX);
//b2.m_linearVelocity.Add( b2Math.MulFV( invMass2, P ) );
b2_linearVelocity.x += invMass2 * PX;
b2_linearVelocity.y += invMass2 * PY;
b2_angularVelocity += invI2 * (r2X * PY - r2Y * PX);
ccp.tangentImpulse = newImpulse;
}*/
// Update angular velocity
b1.m_angularVelocity = b1_angularVelocity;
b2.m_angularVelocity = b2_angularVelocity;
}
},
SolvePositionConstraints: function(beta){
var minSeparation = 0.0;
var tMat;
var tVec;
for (var i = 0; i < this.m_constraintCount; ++i)
{
var c = this.m_constraints[ i ];
var b1 = c.body1;
var b2 = c.body2;
var b1_position = b1.m_position;
var b1_rotation = b1.m_rotation;
var b2_position = b2.m_position;
var b2_rotation = b2.m_rotation;
var invMass1 = b1.m_invMass;
var invI1 = b1.m_invI;
var invMass2 = b2.m_invMass;
var invI2 = b2.m_invI;
//var normal = new b2Vec2(c.normal.x, c.normal.y);
var normalX = c.normal.x;
var normalY = c.normal.y;
//var tangent = b2Math.b2CrossVF(normal, 1.0);
var tangentX = normalY;
var tangentY = -normalX;
// Solver normal constraints
var tCount = c.pointCount;
for (var j = 0; j < tCount; ++j)
{
var ccp = c.points[ j ];
//r1 = b2Math.b2MulMV(b1.m_R, ccp.localAnchor1);
tMat = b1.m_R;
tVec = ccp.localAnchor1;
var r1X = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y
var r1Y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y
//r2 = b2Math.b2MulMV(b2.m_R, ccp.localAnchor2);
tMat = b2.m_R;
tVec = ccp.localAnchor2;
var r2X = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y
var r2Y = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y
//var p1 = b2Math.AddVV(b1.m_position, r1);
var p1X = b1_position.x + r1X;
var p1Y = b1_position.y + r1Y;
//var p2 = b2Math.AddVV(b2.m_position, r2);
var p2X = b2_position.x + r2X;
var p2Y = b2_position.y + r2Y;
//var dp = b2Math.SubtractVV(p2, p1);
var dpX = p2X - p1X;
var dpY = p2Y - p1Y;
// Approximate the current separation.
//var separation = b2Math.b2Dot(dp, normal) + ccp.separation;
var separation = (dpX*normalX + dpY*normalY) + ccp.separation;
// Track max constraint error.
minSeparation = b2Math.b2Min(minSeparation, separation);
// Prevent large corrections and allow slop.
var C = beta * b2Math.b2Clamp(separation + b2Settings.b2_linearSlop, -b2Settings.b2_maxLinearCorrection, 0.0);
// Compute normal impulse
var dImpulse = -ccp.normalMass * C;
// b2Clamp the accumulated impulse
var impulse0 = ccp.positionImpulse;
ccp.positionImpulse = b2Math.b2Max(impulse0 + dImpulse, 0.0);
dImpulse = ccp.positionImpulse - impulse0;
//var impulse = b2Math.MulFV( dImpulse, normal );
var impulseX = dImpulse * normalX;
var impulseY = dImpulse * normalY;
//b1.m_position.Subtract( b2Math.MulFV( invMass1, impulse ) );
b1_position.x -= invMass1 * impulseX;
b1_position.y -= invMass1 * impulseY;
b1_rotation -= invI1 * (r1X * impulseY - r1Y * impulseX);
b1.m_R.Set(b1_rotation);
//b2.m_position.Add( b2Math.MulFV( invMass2, impulse ) );
b2_position.x += invMass2 * impulseX;
b2_position.y += invMass2 * impulseY;
b2_rotation += invI2 * (r2X * impulseY - r2Y * impulseX);
b2.m_R.Set(b2_rotation);
}
// Update body rotations
b1.m_rotation = b1_rotation;
b2.m_rotation = b2_rotation;
}
return minSeparation >= -b2Settings.b2_linearSlop;
},
PostSolve: function(){
for (var i = 0; i < this.m_constraintCount; ++i)
{
var c = this.m_constraints[ i ];
var m = c.manifold;
for (var j = 0; j < c.pointCount; ++j)
{
var mPoint = m.points[j];
var cPoint = c.points[j];
mPoint.normalImpulse = cPoint.normalImpulse;
mPoint.tangentImpulse = cPoint.tangentImpulse;
}
}
},
m_allocator: null,
m_constraints: new Array(),
m_constraintCount: 0};

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2006-2007 Erin Catto http:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked, and must not be
* misrepresented the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
var b2NullContact = Class.create();
Object.extend(b2NullContact.prototype, b2Contact.prototype);
Object.extend(b2NullContact.prototype,
{
initialize: function(s1, s2) {
// The constructor for b2Contact
// initialize instance variables for references
this.m_node1 = new b2ContactNode();
this.m_node2 = new b2ContactNode();
//
this.m_flags = 0;
if (!s1 || !s2){
this.m_shape1 = null;
this.m_shape2 = null;
return;
}
this.m_shape1 = s1;
this.m_shape2 = s2;
this.m_manifoldCount = 0;
this.m_friction = Math.sqrt(this.m_shape1.m_friction * this.m_shape2.m_friction);
this.m_restitution = b2Math.b2Max(this.m_shape1.m_restitution, this.m_shape2.m_restitution);
this.m_prev = null;
this.m_next = null;
this.m_node1.contact = null;
this.m_node1.prev = null;
this.m_node1.next = null;
this.m_node1.other = null;
this.m_node2.contact = null;
this.m_node2.prev = null;
this.m_node2.next = null;
this.m_node2.other = null;
//
},
Evaluate: function() {},
GetManifolds: function(){ return null; }});

Some files were not shown because too many files have changed in this diff Show more