mirror of
https://github.com/liabru/matter-js.git
synced 2024-12-26 13:49:01 -05:00
Merge branch 'runner-improve' into browserify
This commit is contained in:
commit
9e3438f359
99 changed files with 1404935 additions and 534 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -6,3 +6,4 @@ matter-doc-theme
|
||||||
build/matter-dev.js
|
build/matter-dev.js
|
||||||
build/matter-dev.min.js
|
build/matter-dev.min.js
|
||||||
demo/js/lib/matter-dev.js
|
demo/js/lib/matter-dev.js
|
||||||
|
test/browser/diffs
|
15
.jshintrc
15
.jshintrc
|
@ -25,5 +25,18 @@
|
||||||
"sub" : false, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`.
|
"sub" : false, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`.
|
||||||
"trailing" : false, // Prohibit trailing whitespaces.
|
"trailing" : false, // Prohibit trailing whitespaces.
|
||||||
"white" : false, // Check against strict whitespace and indentation rules.
|
"white" : false, // Check against strict whitespace and indentation rules.
|
||||||
"indent" : 4 // Specify indentation spacing
|
"indent" : 4, // Specify indentation spacing
|
||||||
|
|
||||||
|
// variables
|
||||||
|
"undef": true,
|
||||||
|
"-W079": true, // Silence redefinition errors (they are false positives).
|
||||||
|
"predef": [
|
||||||
|
"Matter", "window", "document", "Element", "MatterTools", "PIXI", "phantom", "module",
|
||||||
|
"$", "Image", "navigator", "setTimeout", "decomp", "HTMLElement", "require",
|
||||||
|
"Body", "Composite", "World", "Contact", "Detector", "Grid",
|
||||||
|
"Pairs", "Pair", "Resolver", "SAT", "Constraint", "MouseConstraint",
|
||||||
|
"Common", "Engine", "Mouse", "Sleeping", "Bodies", "Composites",
|
||||||
|
"Axes", "Bounds", "Vector", "Vertices", "Render", "RenderPixi",
|
||||||
|
"Events", "Query", "Runner", "Svg", "Metrics"
|
||||||
|
]
|
||||||
}
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
|
.idea
|
||||||
node_modules
|
node_modules
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
doc
|
doc
|
||||||
matter-doc-theme
|
matter-doc-theme
|
||||||
build/matter-dev.js
|
build/matter-dev.js
|
||||||
build/matter-dev.min.js
|
build/matter-dev.min.js
|
||||||
demo/js/lib/matter-dev.js
|
demo/js/lib/matter-dev.js
|
||||||
|
test/browser/diffs
|
11
.travis.yml
11
.travis.yml
|
@ -1,6 +1,11 @@
|
||||||
language: node_js
|
language: node_js
|
||||||
|
sudo: false
|
||||||
node_js:
|
node_js:
|
||||||
- "0.10"
|
- "0.10"
|
||||||
before_install: npm install -g grunt-cli
|
before_install:
|
||||||
install: npm install
|
- npm install -g grunt-cli
|
||||||
before_script: grunt
|
- mkdir travis-phantomjs
|
||||||
|
- wget https://s3.amazonaws.com/travis-phantomjs/phantomjs-2.0.0-ubuntu-12.04.tar.bz2 -O $PWD/travis-phantomjs/phantomjs-2.0.0-ubuntu-12.04.tar.bz2
|
||||||
|
- tar -xvf $PWD/travis-phantomjs/phantomjs-2.0.0-ubuntu-12.04.tar.bz2 -C $PWD/travis-phantomjs
|
||||||
|
- export PATH=$PWD/travis-phantomjs:$PATH
|
||||||
|
install: npm install
|
36
Gruntfile.js
36
Gruntfile.js
|
@ -45,7 +45,7 @@ module.exports = function(grunt) {
|
||||||
options: {
|
options: {
|
||||||
jshintrc: '.jshintrc'
|
jshintrc: '.jshintrc'
|
||||||
},
|
},
|
||||||
all: ['src/**/*.js', 'demo/js/*.js', '!src/module/*']
|
all: ['src/**/*.js', 'demo/js/*.js', 'test/browser/TestDemo.js', '!src/module/*']
|
||||||
},
|
},
|
||||||
connect: {
|
connect: {
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -54,6 +54,11 @@ module.exports = function(grunt) {
|
||||||
open: 'http://localhost:9000/demo/dev.html',
|
open: 'http://localhost:9000/demo/dev.html',
|
||||||
livereload: 9001
|
livereload: 9001
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
serve: {
|
||||||
|
options: {
|
||||||
|
port: 8000
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -95,6 +100,19 @@ module.exports = function(grunt) {
|
||||||
src: 'build/<%= buildName %>.js',
|
src: 'build/<%= buildName %>.js',
|
||||||
dest: 'build/<%= buildName %>.js'
|
dest: 'build/<%= buildName %>.js'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
shell: {
|
||||||
|
testDemo: {
|
||||||
|
command: function(arg) {
|
||||||
|
arg = arg ? ' --' + arg : '';
|
||||||
|
return 'phantomjs test/browser/TestDemo.js' + arg;
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
execOptions: {
|
||||||
|
timeout: 1000 * 60
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -106,11 +124,25 @@ module.exports = function(grunt) {
|
||||||
grunt.loadNpmTasks('grunt-contrib-copy');
|
grunt.loadNpmTasks('grunt-contrib-copy');
|
||||||
grunt.loadNpmTasks('grunt-contrib-yuidoc');
|
grunt.loadNpmTasks('grunt-contrib-yuidoc');
|
||||||
grunt.loadNpmTasks('grunt-preprocess');
|
grunt.loadNpmTasks('grunt-preprocess');
|
||||||
|
grunt.loadNpmTasks('grunt-shell');
|
||||||
|
|
||||||
grunt.registerTask('default', ['test', 'build']);
|
grunt.registerTask('default', ['test', 'build']);
|
||||||
grunt.registerTask('test', ['jshint']);
|
grunt.registerTask('test', ['build:dev', 'connect:serve', 'jshint', 'test:demo']);
|
||||||
grunt.registerTask('dev', ['build:dev', 'connect:watch', 'watch']);
|
grunt.registerTask('dev', ['build:dev', 'connect:watch', 'watch']);
|
||||||
|
|
||||||
|
grunt.registerTask('test:demo', function() {
|
||||||
|
var updateAll = grunt.option('updateAll'),
|
||||||
|
diff = grunt.option('diff');
|
||||||
|
|
||||||
|
if (updateAll) {
|
||||||
|
grunt.task.run('shell:testDemo:updateAll');
|
||||||
|
} else if (diff) {
|
||||||
|
grunt.task.run('shell:testDemo:diff');
|
||||||
|
} else {
|
||||||
|
grunt.task.run('shell:testDemo');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
grunt.registerTask('build', function(mode) {
|
grunt.registerTask('build', function(mode) {
|
||||||
var isDev = (mode === 'dev'),
|
var isDev = (mode === 'dev'),
|
||||||
isRelease = (mode === 'release'),
|
isRelease = (mode === 'release'),
|
||||||
|
|
668
build/matter.js
668
build/matter.js
File diff suppressed because it is too large
Load diff
8
build/matter.min.js
vendored
8
build/matter.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -25,15 +25,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
var Demo = {};
|
var Demo = {};
|
||||||
|
Matter.Demo = Demo;
|
||||||
|
|
||||||
var _engine,
|
var _engine,
|
||||||
|
_runner,
|
||||||
_gui,
|
_gui,
|
||||||
_inspector,
|
_inspector,
|
||||||
_sceneName,
|
_sceneName,
|
||||||
_mouseConstraint,
|
_mouseConstraint,
|
||||||
_sceneEvents = [],
|
_sceneEvents = [],
|
||||||
_useInspector = window.location.hash.indexOf('-inspect') !== -1,
|
_useInspector = window.location.hash.indexOf('-inspect') !== -1,
|
||||||
_isMobile = /(ipad|iphone|ipod|android)/gi.test(navigator.userAgent);
|
_isMobile = /(ipad|iphone|ipod|android)/gi.test(navigator.userAgent),
|
||||||
|
_isAutomatedTest = window._phantom ? true : false;
|
||||||
|
|
||||||
// initialise the demo
|
// initialise the demo
|
||||||
|
|
||||||
|
@ -56,8 +59,14 @@
|
||||||
_mouseConstraint = MouseConstraint.create(_engine);
|
_mouseConstraint = MouseConstraint.create(_engine);
|
||||||
World.add(_engine.world, _mouseConstraint);
|
World.add(_engine.world, _mouseConstraint);
|
||||||
|
|
||||||
|
// engine reference for external use
|
||||||
|
Matter.Demo._engine = _engine;
|
||||||
|
|
||||||
|
// skip runner when performing automated tests
|
||||||
|
if (_isAutomatedTest) return;
|
||||||
|
|
||||||
// run the engine
|
// run the engine
|
||||||
Engine.run(_engine);
|
_runner = Engine.run(_engine);
|
||||||
|
|
||||||
// default scene function name
|
// default scene function name
|
||||||
_sceneName = 'mixed';
|
_sceneName = 'mixed';
|
||||||
|
@ -344,7 +353,7 @@
|
||||||
|
|
||||||
World.add(_engine.world, [ground, pyramid, ground2, pyramid2, rock, elastic]);
|
World.add(_engine.world, [ground, pyramid, ground2, pyramid2, rock, elastic]);
|
||||||
|
|
||||||
Events.on(_engine, 'tick', function() {
|
Events.on(_engine, 'afterUpdate', function() {
|
||||||
if (_mouseConstraint.mouse.button === -1 && (rock.position.x > 190 || rock.position.y < 430)) {
|
if (_mouseConstraint.mouse.button === -1 && (rock.position.x > 190 || rock.position.y < 430)) {
|
||||||
rock = Bodies.polygon(170, 450, 7, 20, rockOptions);
|
rock = Bodies.polygon(170, 450, 7, 20, rockOptions);
|
||||||
World.add(_engine.world, rock);
|
World.add(_engine.world, rock);
|
||||||
|
@ -491,7 +500,7 @@
|
||||||
_world.gravity.y = 0;
|
_world.gravity.y = 0;
|
||||||
|
|
||||||
_sceneEvents.push(
|
_sceneEvents.push(
|
||||||
Events.on(_engine, 'tick', function(event) {
|
Events.on(_engine, 'afterUpdate', function(event) {
|
||||||
var time = _engine.timing.timestamp;
|
var time = _engine.timing.timestamp;
|
||||||
|
|
||||||
Composite.translate(stack, {
|
Composite.translate(stack, {
|
||||||
|
@ -986,7 +995,7 @@
|
||||||
counter = 0;
|
counter = 0;
|
||||||
|
|
||||||
_sceneEvents.push(
|
_sceneEvents.push(
|
||||||
Events.on(_engine, 'tick', function(event) {
|
Events.on(_engine, 'afterUpdate', function(event) {
|
||||||
// tween the timescale for bullet time slow-mo
|
// tween the timescale for bullet time slow-mo
|
||||||
_engine.timing.timeScale += (timeScaleTarget - _engine.timing.timeScale) * 0.05;
|
_engine.timing.timeScale += (timeScaleTarget - _engine.timing.timeScale) * 0.05;
|
||||||
|
|
||||||
|
@ -1482,7 +1491,7 @@
|
||||||
World.add(_world, [stack, concave]);
|
World.add(_world, [stack, concave]);
|
||||||
|
|
||||||
_sceneEvents.push(
|
_sceneEvents.push(
|
||||||
Events.on(_engine, 'afterRender', function() {
|
Events.on(_engine.render, 'afterRender', function() {
|
||||||
var mouse = _mouseConstraint.mouse,
|
var mouse = _mouseConstraint.mouse,
|
||||||
context = _engine.render.context,
|
context = _engine.render.context,
|
||||||
bodies = Composite.allBodies(_engine.world),
|
bodies = Composite.allBodies(_engine.world),
|
||||||
|
@ -1610,7 +1619,7 @@
|
||||||
|
|
||||||
// create a Matter.Gui
|
// create a Matter.Gui
|
||||||
if (!_isMobile && Gui) {
|
if (!_isMobile && Gui) {
|
||||||
_gui = Gui.create(_engine);
|
_gui = Gui.create(_engine, _runner);
|
||||||
|
|
||||||
// need to add mouse constraint back in after gui clear or load is pressed
|
// need to add mouse constraint back in after gui clear or load is pressed
|
||||||
Events.on(_gui, 'clear load', function() {
|
Events.on(_gui, 'clear load', function() {
|
||||||
|
@ -1626,7 +1635,7 @@
|
||||||
|
|
||||||
// create a Matter.Inspector
|
// create a Matter.Inspector
|
||||||
if (!_isMobile && Inspector && _useInspector) {
|
if (!_isMobile && Inspector && _useInspector) {
|
||||||
_inspector = Inspector.create(_engine);
|
_inspector = Inspector.create(_engine, _runner);
|
||||||
|
|
||||||
Events.on(_inspector, 'import', function() {
|
Events.on(_inspector, 'import', function() {
|
||||||
_mouseConstraint = MouseConstraint.create(_engine);
|
_mouseConstraint = MouseConstraint.create(_engine);
|
||||||
|
@ -1729,6 +1738,16 @@
|
||||||
Events.off(_world, _sceneEvents[i]);
|
Events.off(_world, _sceneEvents[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_runner && _runner.events) {
|
||||||
|
for (i = 0; i < _sceneEvents.length; i++)
|
||||||
|
Events.off(_runner, _sceneEvents[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_engine.render.events) {
|
||||||
|
for (i = 0; i < _sceneEvents.length; i++)
|
||||||
|
Events.off(_engine.render, _sceneEvents[i]);
|
||||||
|
}
|
||||||
|
|
||||||
_sceneEvents = [];
|
_sceneEvents = [];
|
||||||
|
|
||||||
// reset id pool
|
// reset id pool
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
var _engine,
|
var _engine,
|
||||||
_sceneName = 'mixed',
|
_sceneName = 'mixed',
|
||||||
_sceneWidth,
|
_sceneWidth,
|
||||||
_sceneHeight;
|
_sceneHeight,
|
||||||
|
_deviceOrientationEvent;
|
||||||
|
|
||||||
Demo.init = function() {
|
Demo.init = function() {
|
||||||
var canvasContainer = document.getElementById('canvas-container'),
|
var canvasContainer = document.getElementById('canvas-container'),
|
||||||
|
@ -44,10 +45,15 @@
|
||||||
}, 800);
|
}, 800);
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('deviceorientation', Demo.updateGravity, true);
|
window.addEventListener('deviceorientation', function(event) {
|
||||||
|
_deviceOrientationEvent = event;
|
||||||
|
Demo.updateGravity(event);
|
||||||
|
}, true);
|
||||||
|
|
||||||
window.addEventListener('touchstart', Demo.fullscreen);
|
window.addEventListener('touchstart', Demo.fullscreen);
|
||||||
|
|
||||||
window.addEventListener('orientationchange', function() {
|
window.addEventListener('orientationchange', function() {
|
||||||
Demo.updateGravity();
|
Demo.updateGravity(_deviceOrientationEvent);
|
||||||
Demo.updateScene();
|
Demo.updateScene();
|
||||||
Demo.fullscreen();
|
Demo.fullscreen();
|
||||||
}, false);
|
}, false);
|
||||||
|
@ -101,7 +107,7 @@
|
||||||
Demo[_sceneName]();
|
Demo[_sceneName]();
|
||||||
};
|
};
|
||||||
|
|
||||||
Demo.updateGravity = function () {
|
Demo.updateGravity = function(event) {
|
||||||
if (!_engine)
|
if (!_engine)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* matter-tools-dev.min.js 0.5.0-dev 2015-05-24
|
* matter-tools-dev.min.js 0.5.0-dev 2015-07-27
|
||||||
* https://github.com/liabru/matter-tools
|
* https://github.com/liabru/matter-tools
|
||||||
* License: MIT
|
* License: MIT
|
||||||
*/
|
*/
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
var Gui = {};
|
var Gui = {};
|
||||||
(function() {
|
(function() {
|
||||||
var _isWebkit = "WebkitAppearance" in document.documentElement.style;
|
var _isWebkit = "WebkitAppearance" in document.documentElement.style;
|
||||||
Gui.create = function(engine, options) {
|
Gui.create = function(engine, runner, options) {
|
||||||
var _datGuiSupported = window.dat && window.localStorage;
|
var _datGuiSupported = window.dat && window.localStorage;
|
||||||
if (!_datGuiSupported) {
|
if (!_datGuiSupported) {
|
||||||
console.log("Could not create GUI. Check dat.gui library is loaded first.");
|
console.log("Could not create GUI. Check dat.gui library is loaded first.");
|
||||||
|
@ -19,6 +19,7 @@
|
||||||
var datGui = new dat.GUI(options);
|
var datGui = new dat.GUI(options);
|
||||||
var gui = {
|
var gui = {
|
||||||
engine:engine,
|
engine:engine,
|
||||||
|
runner:runner,
|
||||||
datGui:datGui,
|
datGui:datGui,
|
||||||
broadphase:"grid",
|
broadphase:"grid",
|
||||||
broadphaseCache:{
|
broadphaseCache:{
|
||||||
|
@ -98,7 +99,7 @@
|
||||||
return clone;
|
return clone;
|
||||||
};
|
};
|
||||||
var _initDatGui = function(gui) {
|
var _initDatGui = function(gui) {
|
||||||
var engine = gui.engine, datGui = gui.datGui;
|
var engine = gui.engine, runner = gui.runner, datGui = gui.datGui;
|
||||||
var funcs = {
|
var funcs = {
|
||||||
addBody:function() {
|
addBody:function() {
|
||||||
_addBody(gui);
|
_addBody(gui);
|
||||||
|
@ -115,7 +116,7 @@
|
||||||
Events.trigger(gui, "load");
|
Events.trigger(gui, "load");
|
||||||
},
|
},
|
||||||
inspect:function() {
|
inspect:function() {
|
||||||
if (!Inspector.instance) gui.inspector = Inspector.create(gui.engine);
|
if (!Inspector.instance) gui.inspector = Inspector.create(gui.engine, gui.runner);
|
||||||
},
|
},
|
||||||
recordGif:function() {
|
recordGif:function() {
|
||||||
if (!gui.isRecording) {
|
if (!gui.isRecording) {
|
||||||
|
@ -152,10 +153,10 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var metrics = datGui.addFolder("Metrics");
|
var metrics = datGui.addFolder("Metrics");
|
||||||
metrics.add(engine.timing, "fps").listen();
|
metrics.add(runner, "fps").listen();
|
||||||
if (engine.metrics.extended) {
|
if (engine.metrics.extended) {
|
||||||
metrics.add(engine.timing, "delta").listen();
|
metrics.add(runner, "delta").listen();
|
||||||
metrics.add(engine.timing, "correction").listen();
|
metrics.add(runner, "correction").listen();
|
||||||
metrics.add(engine.metrics, "bodies").listen();
|
metrics.add(engine.metrics, "bodies").listen();
|
||||||
metrics.add(engine.metrics, "collisions").listen();
|
metrics.add(engine.metrics, "collisions").listen();
|
||||||
metrics.add(engine.metrics, "pairs").listen();
|
metrics.add(engine.metrics, "pairs").listen();
|
||||||
|
@ -201,7 +202,7 @@
|
||||||
physics.add(engine.timing, "timeScale", 0, 1.2).step(.05).listen();
|
physics.add(engine.timing, "timeScale", 0, 1.2).step(.05).listen();
|
||||||
physics.add(engine, "velocityIterations", 1, 10).step(1);
|
physics.add(engine, "velocityIterations", 1, 10).step(1);
|
||||||
physics.add(engine, "positionIterations", 1, 10).step(1);
|
physics.add(engine, "positionIterations", 1, 10).step(1);
|
||||||
physics.add(engine, "enabled");
|
physics.add(runner, "enabled");
|
||||||
physics.open();
|
physics.open();
|
||||||
var render = datGui.addFolder("Render");
|
var render = datGui.addFolder("Render");
|
||||||
render.add(gui, "renderer", [ "canvas", "webgl" ]).onFinishChange(function(value) {
|
render.add(gui, "renderer", [ "canvas", "webgl" ]).onFinishChange(function(value) {
|
||||||
|
@ -269,7 +270,7 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var engine = gui.engine, skipFrame = false;
|
var engine = gui.engine, skipFrame = false;
|
||||||
Matter.Events.on(engine, "beforeTick", function(event) {
|
Matter.Events.on(gui.runner, "beforeTick", function(event) {
|
||||||
if (gui.isRecording && !skipFrame) {
|
if (gui.isRecording && !skipFrame) {
|
||||||
gui.gif.addFrame(engine.render.context, {
|
gui.gif.addFrame(engine.render.context, {
|
||||||
copy:true,
|
copy:true,
|
||||||
|
@ -283,13 +284,14 @@
|
||||||
var Inspector = {};
|
var Inspector = {};
|
||||||
(function() {
|
(function() {
|
||||||
var _key, _isWebkit = "WebkitAppearance" in document.documentElement.style, $body;
|
var _key, _isWebkit = "WebkitAppearance" in document.documentElement.style, $body;
|
||||||
Inspector.create = function(engine, options) {
|
Inspector.create = function(engine, runner, options) {
|
||||||
if (!jQuery || !$.fn.jstree || !window.key) {
|
if (!jQuery || !$.fn.jstree || !window.key) {
|
||||||
console.log("Could not create inspector. Check keymaster, jQuery, jsTree libraries are loaded first.");
|
console.log("Could not create inspector. Check keymaster, jQuery, jsTree libraries are loaded first.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var inspector = {
|
var inspector = {
|
||||||
engine:engine,
|
engine:engine,
|
||||||
|
runner:runner,
|
||||||
isPaused:false,
|
isPaused:false,
|
||||||
selected:[],
|
selected:[],
|
||||||
selectStart:null,
|
selectStart:null,
|
||||||
|
@ -566,7 +568,7 @@
|
||||||
};
|
};
|
||||||
var _initEngineEvents = function(inspector) {
|
var _initEngineEvents = function(inspector) {
|
||||||
var engine = inspector.engine, mouse = inspector.mouse, mousePosition = _getMousePosition(inspector), controls = inspector.controls;
|
var engine = inspector.engine, mouse = inspector.mouse, mousePosition = _getMousePosition(inspector), controls = inspector.controls;
|
||||||
Events.on(engine, "tick", function() {
|
Events.on(inspector.engine, "beforeUpdate", function() {
|
||||||
mousePosition = _getMousePosition(inspector);
|
mousePosition = _getMousePosition(inspector);
|
||||||
var mouseDelta = mousePosition.x - inspector.mousePrevPosition.x, keyDelta = _key.isPressed("up") + _key.isPressed("right") - _key.isPressed("down") - _key.isPressed("left"), delta = mouseDelta + keyDelta;
|
var mouseDelta = mousePosition.x - inspector.mousePrevPosition.x, keyDelta = _key.isPressed("up") + _key.isPressed("right") - _key.isPressed("down") - _key.isPressed("left"), delta = mouseDelta + keyDelta;
|
||||||
if (engine.world.isModified) {
|
if (engine.world.isModified) {
|
||||||
|
@ -672,7 +674,7 @@
|
||||||
_updateSelectedMouseDownOffset(inspector);
|
_updateSelectedMouseDownOffset(inspector);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Events.on(engine, "afterRender", function() {
|
Events.on(inspector.engine.render, "afterRender", function() {
|
||||||
var renderController = engine.render.controller, context = engine.render.context;
|
var renderController = engine.render.controller, context = engine.render.context;
|
||||||
if (renderController.inspector) renderController.inspector(inspector, context);
|
if (renderController.inspector) renderController.inspector(inspector, context);
|
||||||
});
|
});
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
"rigid body physics"
|
"rigid body physics"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"fast-json-patch": "^0.5.4",
|
||||||
"grunt": "~0.4.2",
|
"grunt": "~0.4.2",
|
||||||
"grunt-browserify": "~3.7.0",
|
"grunt-browserify": "~3.7.0",
|
||||||
"grunt-contrib-connect": "~0.6.0",
|
"grunt-contrib-connect": "~0.6.0",
|
||||||
|
@ -28,7 +29,8 @@
|
||||||
"grunt-contrib-uglify": "~0.2.7",
|
"grunt-contrib-uglify": "~0.2.7",
|
||||||
"grunt-contrib-watch": "~0.5.3",
|
"grunt-contrib-watch": "~0.5.3",
|
||||||
"grunt-contrib-yuidoc": "~0.5.1",
|
"grunt-contrib-yuidoc": "~0.5.1",
|
||||||
"grunt-preprocess": "^4.1.0"
|
"grunt-preprocess": "^4.1.0",
|
||||||
|
"grunt-shell": "^1.1.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "npm install && grunt dev",
|
"dev": "npm install && grunt dev",
|
||||||
|
|
|
@ -58,6 +58,7 @@ module.exports = Resolver;
|
||||||
normal,
|
normal,
|
||||||
bodyBtoA,
|
bodyBtoA,
|
||||||
contactShare,
|
contactShare,
|
||||||
|
positionImpulse,
|
||||||
contactCount = {},
|
contactCount = {},
|
||||||
tempA = Vector._temp[0],
|
tempA = Vector._temp[0],
|
||||||
tempB = Vector._temp[1],
|
tempB = Vector._temp[1],
|
||||||
|
|
|
@ -13,7 +13,7 @@ var Body = require('../body/Body');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `Matter.Engine` module contains methods for creating and manipulating engines.
|
* The `Matter.Engine` module contains methods for creating and manipulating engines.
|
||||||
* An engine is a controller that manages updating and rendering the simulation of the world.
|
* An engine is a controller that manages updating the simulation of the world.
|
||||||
* See `Matter.Runner` for an optional game loop utility.
|
* See `Matter.Runner` for an optional game loop utility.
|
||||||
*
|
*
|
||||||
* See [Demo.js](https://github.com/liabru/matter-js/blob/master/demo/js/Demo.js)
|
* See [Demo.js](https://github.com/liabru/matter-js/blob/master/demo/js/Demo.js)
|
||||||
|
@ -28,9 +28,6 @@ module.exports = Engine;
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var _fps = 60,
|
|
||||||
_delta = 1000 / _fps;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new engine. The options parameter is an object that specifies any properties you wish to override the defaults.
|
* Creates a new engine. The options parameter is an object that specifies any properties you wish to override the defaults.
|
||||||
* All properties have default values, and many are pre-calculated automatically based on other properties.
|
* All properties have default values, and many are pre-calculated automatically based on other properties.
|
||||||
|
@ -47,49 +44,55 @@ module.exports = Engine;
|
||||||
element = Common.isElement(element) ? element : null;
|
element = Common.isElement(element) ? element : null;
|
||||||
|
|
||||||
var defaults = {
|
var defaults = {
|
||||||
enabled: true,
|
|
||||||
positionIterations: 6,
|
positionIterations: 6,
|
||||||
velocityIterations: 4,
|
velocityIterations: 4,
|
||||||
constraintIterations: 2,
|
constraintIterations: 2,
|
||||||
enableSleeping: false,
|
enableSleeping: false,
|
||||||
events: [],
|
events: [],
|
||||||
timing: {
|
timing: {
|
||||||
fps: _fps,
|
|
||||||
timestamp: 0,
|
timestamp: 0,
|
||||||
delta: _delta,
|
timeScale: 1
|
||||||
correction: 1,
|
|
||||||
deltaMin: 1000 / _fps,
|
|
||||||
deltaMax: 1000 / (_fps * 0.5),
|
|
||||||
timeScale: 1,
|
|
||||||
isFixed: false,
|
|
||||||
frameRequestId: 0
|
|
||||||
},
|
|
||||||
render: {
|
|
||||||
element: element,
|
|
||||||
controller: Render
|
|
||||||
},
|
},
|
||||||
broadphase: {
|
broadphase: {
|
||||||
controller: Grid
|
controller: Grid
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var engine = Common.extend(defaults, options);
|
var engine = Common.extend(defaults, options);
|
||||||
|
|
||||||
engine.render = engine.render.controller.create(engine.render);
|
if (element || engine.render) {
|
||||||
|
var renderDefaults = {
|
||||||
|
element: element,
|
||||||
|
controller: Render
|
||||||
|
};
|
||||||
|
|
||||||
|
engine.render = Common.extend(renderDefaults, engine.render);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine.render && engine.render.controller) {
|
||||||
|
engine.render = engine.render.controller.create(engine.render);
|
||||||
|
}
|
||||||
|
|
||||||
engine.world = World.create(engine.world);
|
engine.world = World.create(engine.world);
|
||||||
engine.pairs = Pairs.create();
|
engine.pairs = Pairs.create();
|
||||||
engine.broadphase = engine.broadphase.controller.create(engine.broadphase);
|
engine.broadphase = engine.broadphase.controller.create(engine.broadphase);
|
||||||
engine.metrics = engine.metrics || { extended: false };
|
engine.metrics = engine.metrics || { extended: false };
|
||||||
|
|
||||||
// @if DEBUG
|
// @if DEBUG
|
||||||
engine.metrics = engine.metrics || Metrics.create();
|
engine.metrics = Metrics.create(engine.metrics);
|
||||||
// @endif
|
// @endif
|
||||||
|
|
||||||
return engine;
|
return engine;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the simulation forward in time by `delta` ms.
|
* Moves the simulation forward in time by `delta` ms.
|
||||||
|
* The `correction` argument is an optional `Number` that specifies the time correction factor to apply to the update.
|
||||||
|
* This can help improve the accuracy of the simulation in cases where `delta` is changing between updates.
|
||||||
|
* The value of `correction` is defined as `delta / lastDelta`, i.e. the percentage change of `delta` over the last step.
|
||||||
|
* Therefore the value is always `1` (no correction) when `delta` constant (or when no correction is desired, which is the default).
|
||||||
|
* See the paper on <a href="http://lonesock.net/article/verlet.html">Time Corrected Verlet</a> for more information.
|
||||||
|
*
|
||||||
* Triggers `beforeUpdate` and `afterUpdate` events.
|
* Triggers `beforeUpdate` and `afterUpdate` events.
|
||||||
* Triggers `collisionStart`, `collisionActive` and `collisionEnd` events.
|
* Triggers `collisionStart`, `collisionActive` and `collisionEnd` events.
|
||||||
* @method update
|
* @method update
|
||||||
|
@ -108,11 +111,10 @@ module.exports = Engine;
|
||||||
|
|
||||||
// increment timestamp
|
// increment timestamp
|
||||||
timing.timestamp += delta * timing.timeScale;
|
timing.timestamp += delta * timing.timeScale;
|
||||||
timing.correction = correction;
|
|
||||||
|
|
||||||
// create an event object
|
// create an event object
|
||||||
var event = {
|
var event = {
|
||||||
timestamp: engine.timing.timestamp
|
timestamp: timing.timestamp
|
||||||
};
|
};
|
||||||
|
|
||||||
Events.trigger(engine, 'beforeUpdate', event);
|
Events.trigger(engine, 'beforeUpdate', event);
|
||||||
|
@ -211,22 +213,6 @@ module.exports = Engine;
|
||||||
|
|
||||||
return engine;
|
return engine;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the world by calling its defined renderer `engine.render.controller`. Triggers `beforeRender` and `afterRender` events.
|
|
||||||
* @method render
|
|
||||||
* @param {engine} engine
|
|
||||||
*/
|
|
||||||
Engine.render = function(engine) {
|
|
||||||
// create an event object
|
|
||||||
var event = {
|
|
||||||
timestamp: engine.timing.timestamp
|
|
||||||
};
|
|
||||||
|
|
||||||
Events.trigger(engine, 'beforeRender', event);
|
|
||||||
engine.render.controller.world(engine);
|
|
||||||
Events.trigger(engine, 'afterRender', event);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merges two engines by keeping the configuration of `engineA` but replacing the world with the one from `engineB`.
|
* Merges two engines by keeping the configuration of `engineA` but replacing the world with the one from `engineB`.
|
||||||
|
@ -336,38 +322,12 @@ module.exports = Engine;
|
||||||
* @param {engine} engine
|
* @param {engine} engine
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Events Documentation
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fired at the start of a tick, before any updates to the engine or timing
|
|
||||||
*
|
|
||||||
* @event beforeTick
|
|
||||||
* @param {} event An event object
|
|
||||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
|
||||||
* @param {} event.source The source object of the event
|
|
||||||
* @param {} event.name The name of the event
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fired after engine timing updated, but just before engine state updated
|
|
||||||
*
|
|
||||||
* @event tick
|
|
||||||
* @param {} event An event object
|
|
||||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
|
||||||
* @param {} event.source The source object of the event
|
|
||||||
* @param {} event.name The name of the event
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fired just before an update
|
* Fired just before an update
|
||||||
*
|
*
|
||||||
* @event beforeUpdate
|
* @event beforeUpdate
|
||||||
* @param {} event An event object
|
* @param {} event An event object
|
||||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
* @param {} event.source The source object of the event
|
* @param {} event.source The source object of the event
|
||||||
* @param {} event.name The name of the event
|
* @param {} event.name The name of the event
|
||||||
*/
|
*/
|
||||||
|
@ -377,37 +337,7 @@ module.exports = Engine;
|
||||||
*
|
*
|
||||||
* @event afterUpdate
|
* @event afterUpdate
|
||||||
* @param {} event An event object
|
* @param {} event An event object
|
||||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
* @param {} event.source The source object of the event
|
|
||||||
* @param {} event.name The name of the event
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fired just before rendering
|
|
||||||
*
|
|
||||||
* @event beforeRender
|
|
||||||
* @param {} event An event object
|
|
||||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
|
||||||
* @param {} event.source The source object of the event
|
|
||||||
* @param {} event.name The name of the event
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fired after rendering
|
|
||||||
*
|
|
||||||
* @event afterRender
|
|
||||||
* @param {} event An event object
|
|
||||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
|
||||||
* @param {} event.source The source object of the event
|
|
||||||
* @param {} event.name The name of the event
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fired after engine update and after rendering
|
|
||||||
*
|
|
||||||
* @event afterTick
|
|
||||||
* @param {} event An event object
|
|
||||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
|
||||||
* @param {} event.source The source object of the event
|
* @param {} event.source The source object of the event
|
||||||
* @param {} event.name The name of the event
|
* @param {} event.name The name of the event
|
||||||
*/
|
*/
|
||||||
|
@ -418,7 +348,7 @@ module.exports = Engine;
|
||||||
* @event collisionStart
|
* @event collisionStart
|
||||||
* @param {} event An event object
|
* @param {} event An event object
|
||||||
* @param {} event.pairs List of affected pairs
|
* @param {} event.pairs List of affected pairs
|
||||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
* @param {} event.source The source object of the event
|
* @param {} event.source The source object of the event
|
||||||
* @param {} event.name The name of the event
|
* @param {} event.name The name of the event
|
||||||
*/
|
*/
|
||||||
|
@ -429,7 +359,7 @@ module.exports = Engine;
|
||||||
* @event collisionActive
|
* @event collisionActive
|
||||||
* @param {} event An event object
|
* @param {} event An event object
|
||||||
* @param {} event.pairs List of affected pairs
|
* @param {} event.pairs List of affected pairs
|
||||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
* @param {} event.source The source object of the event
|
* @param {} event.source The source object of the event
|
||||||
* @param {} event.name The name of the event
|
* @param {} event.name The name of the event
|
||||||
*/
|
*/
|
||||||
|
@ -440,7 +370,7 @@ module.exports = Engine;
|
||||||
* @event collisionEnd
|
* @event collisionEnd
|
||||||
* @param {} event An event object
|
* @param {} event An event object
|
||||||
* @param {} event.pairs List of affected pairs
|
* @param {} event.pairs List of affected pairs
|
||||||
* @param {DOMHighResTimeStamp} event.timestamp The timestamp of the current tick
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
* @param {} event.source The source object of the event
|
* @param {} event.source The source object of the event
|
||||||
* @param {} event.name The name of the event
|
* @param {} event.name The name of the event
|
||||||
*/
|
*/
|
||||||
|
@ -451,14 +381,6 @@ module.exports = Engine;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* A flag that specifies whether the engine is running or not.
|
|
||||||
*
|
|
||||||
* @property enabled
|
|
||||||
* @type boolean
|
|
||||||
* @default true
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An integer `Number` that specifies the number of position iterations to perform each update.
|
* An integer `Number` that specifies the number of position iterations to perform each update.
|
||||||
* The higher the value, the higher quality the simulation will be at the expense of performance.
|
* The higher the value, the higher quality the simulation will be at the expense of performance.
|
||||||
|
@ -516,46 +438,13 @@ module.exports = Engine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `Number` that specifies the current simulation-time in milliseconds starting from `0`.
|
* A `Number` that specifies the current simulation-time in milliseconds starting from `0`.
|
||||||
* It is incremented on every `Engine.update` by the `timing.delta`.
|
* It is incremented on every `Engine.update` by the given `delta` argument.
|
||||||
*
|
*
|
||||||
* @property timing.timestamp
|
* @property timing.timestamp
|
||||||
* @type number
|
* @type number
|
||||||
* @default 0
|
* @default 0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* A `Boolean` that specifies if the `Engine.run` game loop should use a fixed timestep (otherwise it is variable).
|
|
||||||
* If timing is fixed, then the apparent simulation speed will change depending on the frame rate (but behaviour will be deterministic).
|
|
||||||
* If the timing is variable, then the apparent simulation speed will be constant (approximately, but at the cost of determininism).
|
|
||||||
*
|
|
||||||
* @property timing.isFixed
|
|
||||||
* @type boolean
|
|
||||||
* @default false
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A `Number` that specifies the time step between updates in milliseconds.
|
|
||||||
* If `engine.timing.isFixed` is set to `true`, then `delta` is fixed.
|
|
||||||
* If it is `false`, then `delta` can dynamically change to maintain the correct apparent simulation speed.
|
|
||||||
*
|
|
||||||
* @property timing.delta
|
|
||||||
* @type number
|
|
||||||
* @default 1000 / 60
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A `Number` that specifies the time correction factor to apply to the current timestep.
|
|
||||||
* It is automatically handled when using `Engine.run`, but is also only optional even if you use your own game loop.
|
|
||||||
* The value is defined as `delta / lastDelta`, i.e. the percentage change of `delta` between steps.
|
|
||||||
* This value is always `1` (no correction) when frame rate is constant or `engine.timing.isFixed` is `true`.
|
|
||||||
* If the framerate and hence `delta` are changing, then correction should be applied to the current update to account for the change.
|
|
||||||
* See the paper on <a href="http://lonesock.net/article/verlet.html">Time Corrected Verlet</a> for more information.
|
|
||||||
*
|
|
||||||
* @property timing.correction
|
|
||||||
* @type number
|
|
||||||
* @default 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An instance of a `Render` controller. The default value is a `Matter.Render` instance created by `Engine.create`.
|
* An instance of a `Render` controller. The default value is a `Matter.Render` instance created by `Engine.create`.
|
||||||
* One may also develop a custom renderer module based on `Matter.Render` and pass an instance of it to `Engine.create` via `options.render`.
|
* One may also develop a custom renderer module based on `Matter.Render` and pass an instance of it to `Engine.create` via `options.render`.
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// @if DEBUG
|
// @if DEBUG
|
||||||
var Composite = require('../body/Composite');
|
var Composite = require('../body/Composite');
|
||||||
|
var Common = require('./Common');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _Internal Class_, not generally used outside of the engine's internals.
|
* _Internal Class_, not generally used outside of the engine's internals.
|
||||||
|
@ -18,8 +19,8 @@ module.exports = Metrics;
|
||||||
* @private
|
* @private
|
||||||
* @return {metrics} A new metrics
|
* @return {metrics} A new metrics
|
||||||
*/
|
*/
|
||||||
Metrics.create = function() {
|
Metrics.create = function(options) {
|
||||||
return {
|
var defaults = {
|
||||||
extended: false,
|
extended: false,
|
||||||
narrowDetections: 0,
|
narrowDetections: 0,
|
||||||
narrowphaseTests: 0,
|
narrowphaseTests: 0,
|
||||||
|
@ -35,6 +36,8 @@ module.exports = Metrics;
|
||||||
bodies: 0,
|
bodies: 0,
|
||||||
pairs: 0
|
pairs: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return Common.extend(defaults, false, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,6 +5,9 @@ var Common = require('./Common');
|
||||||
/**
|
/**
|
||||||
* The `Matter.Runner` module is an optional utility which provides a game loop,
|
* The `Matter.Runner` module is an optional utility which provides a game loop,
|
||||||
* that handles updating and rendering a `Matter.Engine` for you within a browser.
|
* that handles updating and rendering a `Matter.Engine` for you within a browser.
|
||||||
|
* It is intended for demo and testing purposes, but may be adequate for simple games.
|
||||||
|
* If you are using your own game loop instead, then you do not need the `Matter.Runner` module.
|
||||||
|
* Instead just call `Engine.update(engine, delta)` in your own loop.
|
||||||
* Note that the method `Engine.run` is an alias for `Runner.run`.
|
* Note that the method `Engine.run` is an alias for `Runner.run`.
|
||||||
*
|
*
|
||||||
* See [Demo.js](https://github.com/liabru/matter-js/blob/master/demo/js/Demo.js)
|
* See [Demo.js](https://github.com/liabru/matter-js/blob/master/demo/js/Demo.js)
|
||||||
|
@ -19,114 +22,285 @@ module.exports = Runner;
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var _fps = 60,
|
if (typeof window === 'undefined') {
|
||||||
_deltaSampleSize = _fps,
|
// TODO: support Runner on non-browser environments.
|
||||||
_delta = 1000 / _fps;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var _requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame
|
var _requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame
|
||||||
|| window.mozRequestAnimationFrame || window.msRequestAnimationFrame
|
|| window.mozRequestAnimationFrame || window.msRequestAnimationFrame
|
||||||
|| function(callback){ window.setTimeout(function() { callback(Common.now()); }, _delta); };
|
|| function(callback){ window.setTimeout(function() { callback(Common.now()); }, 1000 / 60); };
|
||||||
|
|
||||||
var _cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame
|
var _cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame
|
||||||
|| window.webkitCancelAnimationFrame || window.msCancelAnimationFrame;
|
|| window.webkitCancelAnimationFrame || window.msCancelAnimationFrame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a basic game loop that handles updating the engine for you.
|
* Creates a new Runner. The options parameter is an object that specifies any properties you wish to override the defaults.
|
||||||
* Calls `Engine.update` and `Engine.render` on the `requestAnimationFrame` event automatically.
|
* @method create
|
||||||
* Handles time correction and non-fixed dynamic timing (if enabled).
|
* @param {} options
|
||||||
* Triggers `beforeTick`, `tick` and `afterTick` events.
|
|
||||||
* @method run
|
|
||||||
* @param {engine} engine
|
|
||||||
*/
|
*/
|
||||||
Runner.run = function(engine) {
|
Runner.create = function(options) {
|
||||||
var counterTimestamp = 0,
|
var defaults = {
|
||||||
frameCounter = 0,
|
fps: 60,
|
||||||
deltaHistory = [],
|
correction: 1,
|
||||||
timePrev,
|
deltaSampleSize: 60,
|
||||||
timeScalePrev = 1;
|
counterTimestamp: 0,
|
||||||
|
frameCounter: 0,
|
||||||
|
deltaHistory: [],
|
||||||
|
timePrev: null,
|
||||||
|
timeScalePrev: 1,
|
||||||
|
frameRequestId: null,
|
||||||
|
isFixed: false,
|
||||||
|
enabled: true
|
||||||
|
};
|
||||||
|
|
||||||
(function render(time){
|
var runner = Common.extend(defaults, options);
|
||||||
var timing = engine.timing,
|
|
||||||
delta,
|
|
||||||
correction = 1;
|
|
||||||
|
|
||||||
timing.frameRequestId = _requestAnimationFrame(render);
|
runner.delta = runner.delta || 1000 / runner.fps;
|
||||||
|
runner.deltaMin = runner.deltaMin || 1000 / runner.fps;
|
||||||
|
runner.deltaMax = runner.deltaMax || 1000 / (runner.fps * 0.5);
|
||||||
|
runner.fps = 1000 / runner.delta;
|
||||||
|
|
||||||
if (!engine.enabled)
|
return runner;
|
||||||
return;
|
|
||||||
|
|
||||||
// create an event object
|
|
||||||
var event = {
|
|
||||||
timestamp: time
|
|
||||||
};
|
|
||||||
|
|
||||||
Events.trigger(engine, 'beforeTick', event);
|
|
||||||
|
|
||||||
if (timing.isFixed) {
|
|
||||||
// fixed timestep
|
|
||||||
delta = timing.delta;
|
|
||||||
} else {
|
|
||||||
// dynamic timestep based on wall clock between calls
|
|
||||||
delta = (time - timePrev) || timing.delta;
|
|
||||||
timePrev = time;
|
|
||||||
|
|
||||||
// optimistically filter delta over a few frames, to improve stability
|
|
||||||
deltaHistory.push(delta);
|
|
||||||
deltaHistory = deltaHistory.slice(-_deltaSampleSize);
|
|
||||||
delta = Math.min.apply(null, deltaHistory);
|
|
||||||
|
|
||||||
// limit delta
|
|
||||||
delta = delta < timing.deltaMin ? timing.deltaMin : delta;
|
|
||||||
delta = delta > timing.deltaMax ? timing.deltaMax : delta;
|
|
||||||
|
|
||||||
// time correction for delta
|
|
||||||
correction = delta / timing.delta;
|
|
||||||
|
|
||||||
// update engine timing object
|
|
||||||
timing.delta = delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
// time correction for time scaling
|
|
||||||
if (timeScalePrev !== 0)
|
|
||||||
correction *= timing.timeScale / timeScalePrev;
|
|
||||||
|
|
||||||
if (timing.timeScale === 0)
|
|
||||||
correction = 0;
|
|
||||||
|
|
||||||
timeScalePrev = timing.timeScale;
|
|
||||||
|
|
||||||
// fps counter
|
|
||||||
frameCounter += 1;
|
|
||||||
if (time - counterTimestamp >= 1000) {
|
|
||||||
timing.fps = frameCounter * ((time - counterTimestamp) / 1000);
|
|
||||||
counterTimestamp = time;
|
|
||||||
frameCounter = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Events.trigger(engine, 'tick', event);
|
|
||||||
|
|
||||||
// if world has been modified, clear the render scene graph
|
|
||||||
if (engine.world.isModified && engine.render.controller.clear)
|
|
||||||
engine.render.controller.clear(engine.render);
|
|
||||||
|
|
||||||
// update
|
|
||||||
Engine.update(engine, delta, correction);
|
|
||||||
|
|
||||||
// render
|
|
||||||
Engine.render(engine);
|
|
||||||
|
|
||||||
Events.trigger(engine, 'afterTick', event);
|
|
||||||
})();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ends execution of `Runner.run` on the given `engine`, by canceling the animation frame request event loop.
|
* Continuously ticks a `Matter.Engine` by calling `Runner.tick` on the `requestAnimationFrame` event.
|
||||||
* If you wish to only temporarily pause the engine, see `engine.enabled` instead.
|
* @method run
|
||||||
* @method stop
|
|
||||||
* @param {engine} engine
|
* @param {engine} engine
|
||||||
*/
|
*/
|
||||||
Runner.stop = function(engine) {
|
Runner.run = function(runner, engine) {
|
||||||
_cancelAnimationFrame(engine.timing.frameRequestId);
|
// create runner if engine is first argument
|
||||||
|
if (typeof runner.positionIterations !== 'undefined') {
|
||||||
|
engine = runner;
|
||||||
|
runner = Runner.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
(function render(time){
|
||||||
|
runner.frameRequestId = _requestAnimationFrame(render);
|
||||||
|
|
||||||
|
if (time && runner.enabled) {
|
||||||
|
Runner.tick(runner, engine, time);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
return runner;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A game loop utility that updates the engine and renderer by one step (a 'tick').
|
||||||
|
* Features delta smoothing, time correction and fixed or dynamic timing.
|
||||||
|
* Triggers `beforeTick`, `tick` and `afterTick` events on the engine.
|
||||||
|
* Consider just `Engine.update(engine, delta)` if you're using your own loop.
|
||||||
|
* @method tick
|
||||||
|
* @param {runner} runner
|
||||||
|
* @param {engine} engine
|
||||||
|
* @param {number} time
|
||||||
|
*/
|
||||||
|
Runner.tick = function(runner, engine, time) {
|
||||||
|
var timing = engine.timing,
|
||||||
|
correction = 1,
|
||||||
|
delta;
|
||||||
|
|
||||||
|
// create an event object
|
||||||
|
var event = {
|
||||||
|
timestamp: timing.timestamp
|
||||||
|
};
|
||||||
|
|
||||||
|
Events.trigger(runner, 'beforeTick', event);
|
||||||
|
Events.trigger(engine, 'beforeTick', event); // @deprecated
|
||||||
|
|
||||||
|
if (runner.isFixed) {
|
||||||
|
// fixed timestep
|
||||||
|
delta = runner.delta;
|
||||||
|
} else {
|
||||||
|
// dynamic timestep based on wall clock between calls
|
||||||
|
delta = (time - runner.timePrev) || runner.delta;
|
||||||
|
runner.timePrev = time;
|
||||||
|
|
||||||
|
// optimistically filter delta over a few frames, to improve stability
|
||||||
|
runner.deltaHistory.push(delta);
|
||||||
|
runner.deltaHistory = runner.deltaHistory.slice(-runner.deltaSampleSize);
|
||||||
|
delta = Math.min.apply(null, runner.deltaHistory);
|
||||||
|
|
||||||
|
// limit delta
|
||||||
|
delta = delta < runner.deltaMin ? runner.deltaMin : delta;
|
||||||
|
delta = delta > runner.deltaMax ? runner.deltaMax : delta;
|
||||||
|
|
||||||
|
// correction for delta
|
||||||
|
correction = delta / runner.delta;
|
||||||
|
|
||||||
|
// update engine timing object
|
||||||
|
runner.delta = delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
// time correction for time scaling
|
||||||
|
if (runner.timeScalePrev !== 0)
|
||||||
|
correction *= timing.timeScale / runner.timeScalePrev;
|
||||||
|
|
||||||
|
if (timing.timeScale === 0)
|
||||||
|
correction = 0;
|
||||||
|
|
||||||
|
runner.timeScalePrev = timing.timeScale;
|
||||||
|
runner.correction = correction;
|
||||||
|
|
||||||
|
// fps counter
|
||||||
|
runner.frameCounter += 1;
|
||||||
|
if (time - runner.counterTimestamp >= 1000) {
|
||||||
|
runner.fps = runner.frameCounter * ((time - runner.counterTimestamp) / 1000);
|
||||||
|
runner.counterTimestamp = time;
|
||||||
|
runner.frameCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Events.trigger(runner, 'tick', event);
|
||||||
|
Events.trigger(engine, 'tick', event); // @deprecated
|
||||||
|
|
||||||
|
// if world has been modified, clear the render scene graph
|
||||||
|
if (engine.world.isModified
|
||||||
|
&& engine.render
|
||||||
|
&& engine.render.controller
|
||||||
|
&& engine.render.controller.clear) {
|
||||||
|
engine.render.controller.clear(engine.render);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update
|
||||||
|
Events.trigger(runner, 'beforeUpdate', event);
|
||||||
|
Engine.update(engine, delta, correction);
|
||||||
|
Events.trigger(runner, 'afterUpdate', event);
|
||||||
|
|
||||||
|
// render
|
||||||
|
if (engine.render) {
|
||||||
|
Events.trigger(runner, 'beforeRender', event);
|
||||||
|
Events.trigger(engine, 'beforeRender', event); // @deprecated
|
||||||
|
|
||||||
|
engine.render.controller.world(engine);
|
||||||
|
|
||||||
|
Events.trigger(runner, 'afterRender', event);
|
||||||
|
Events.trigger(engine, 'afterRender', event); // @deprecated
|
||||||
|
}
|
||||||
|
|
||||||
|
Events.trigger(runner, 'afterTick', event);
|
||||||
|
Events.trigger(engine, 'afterTick', event); // @deprecated
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends execution of `Runner.run` on the given `runner`, by canceling the animation frame request event loop.
|
||||||
|
* If you wish to only temporarily pause the engine, see `engine.enabled` instead.
|
||||||
|
* @method stop
|
||||||
|
* @param {runner} runner
|
||||||
|
*/
|
||||||
|
Runner.stop = function(runner) {
|
||||||
|
_cancelAnimationFrame(runner.frameRequestId);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Events Documentation
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired at the start of a tick, before any updates to the engine or timing
|
||||||
|
*
|
||||||
|
* @event beforeTick
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired after engine timing updated, but just before update
|
||||||
|
*
|
||||||
|
* @event tick
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired at the end of a tick, after engine update and after rendering
|
||||||
|
*
|
||||||
|
* @event afterTick
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired before update
|
||||||
|
*
|
||||||
|
* @event beforeUpdate
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired after update
|
||||||
|
*
|
||||||
|
* @event afterUpdate
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired before rendering
|
||||||
|
*
|
||||||
|
* @event beforeRender
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired after rendering
|
||||||
|
*
|
||||||
|
* @event afterRender
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Properties Documentation
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag that specifies whether the runner is running or not.
|
||||||
|
*
|
||||||
|
* @property enabled
|
||||||
|
* @type boolean
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `Boolean` that specifies if the runner should use a fixed timestep (otherwise it is variable).
|
||||||
|
* If timing is fixed, then the apparent simulation speed will change depending on the frame rate (but behaviour will be deterministic).
|
||||||
|
* If the timing is variable, then the apparent simulation speed will be constant (approximately, but at the cost of determininism).
|
||||||
|
*
|
||||||
|
* @property isFixed
|
||||||
|
* @type boolean
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `Number` that specifies the time step between updates in milliseconds.
|
||||||
|
* If `engine.timing.isFixed` is set to `true`, then `delta` is fixed.
|
||||||
|
* If it is `false`, then `delta` can dynamically change to maintain the correct apparent simulation speed.
|
||||||
|
*
|
||||||
|
* @property delta
|
||||||
|
* @type number
|
||||||
|
* @default 1000 / 60
|
||||||
|
*/
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -30,7 +30,7 @@ module.exports = Svg;
|
||||||
var i, il, total, point, segment, segments,
|
var i, il, total, point, segment, segments,
|
||||||
segmentsQueue, lastSegment,
|
segmentsQueue, lastSegment,
|
||||||
lastPoint, segmentIndex, points = [],
|
lastPoint, segmentIndex, points = [],
|
||||||
length = 0, x = 0, y = 0;
|
lx, ly, length = 0, x = 0, y = 0;
|
||||||
|
|
||||||
sampleLength = sampleLength || 15;
|
sampleLength = sampleLength || 15;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
var Common = require('../core/Common');
|
var Common = require('../core/Common');
|
||||||
var Composite = require('../body/Composite');
|
var Composite = require('../body/Composite');
|
||||||
var Bounds = require('../geometry/Bounds');
|
var Bounds = require('../geometry/Bounds');
|
||||||
|
var Events = require('../core/Events');
|
||||||
var Grid = require('../collision/Grid');
|
var Grid = require('../collision/Grid');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,6 +135,12 @@ module.exports = Render;
|
||||||
constraints = [],
|
constraints = [],
|
||||||
i;
|
i;
|
||||||
|
|
||||||
|
var event = {
|
||||||
|
timestamp: engine.timing.timestamp
|
||||||
|
};
|
||||||
|
|
||||||
|
Events.trigger(render, 'beforeRender', event);
|
||||||
|
|
||||||
// apply background if it has changed
|
// apply background if it has changed
|
||||||
if (render.currentBackground !== background)
|
if (render.currentBackground !== background)
|
||||||
_applyBackground(render, background);
|
_applyBackground(render, background);
|
||||||
|
@ -231,6 +238,8 @@ module.exports = Render;
|
||||||
// revert view transforms
|
// revert view transforms
|
||||||
context.setTransform(options.pixelRatio, 0, 0, options.pixelRatio, 0, 0);
|
context.setTransform(options.pixelRatio, 0, 0, options.pixelRatio, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Events.trigger(render, 'afterRender', event);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -394,7 +403,8 @@ module.exports = Render;
|
||||||
options = render.options,
|
options = render.options,
|
||||||
body,
|
body,
|
||||||
part,
|
part,
|
||||||
i;
|
i,
|
||||||
|
k;
|
||||||
|
|
||||||
for (i = 0; i < bodies.length; i++) {
|
for (i = 0; i < bodies.length; i++) {
|
||||||
body = bodies[i];
|
body = bodies[i];
|
||||||
|
@ -691,7 +701,8 @@ module.exports = Render;
|
||||||
options = render.options,
|
options = render.options,
|
||||||
body,
|
body,
|
||||||
part,
|
part,
|
||||||
i;
|
i,
|
||||||
|
k;
|
||||||
|
|
||||||
c.beginPath();
|
c.beginPath();
|
||||||
|
|
||||||
|
@ -1027,7 +1038,7 @@ module.exports = Render;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context.setLineDash([0]);
|
context.setLineDash([]);
|
||||||
context.translate(-0.5, -0.5);
|
context.translate(-0.5, -0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1123,6 +1134,32 @@ module.exports = Render;
|
||||||
render.currentBackground = background;
|
render.currentBackground = background;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Events Documentation
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired before rendering
|
||||||
|
*
|
||||||
|
* @event beforeRender
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired after rendering
|
||||||
|
*
|
||||||
|
* @event afterRender
|
||||||
|
* @param {} event An event object
|
||||||
|
* @param {number} event.timestamp The engine.timing.timestamp of the event
|
||||||
|
* @param {} event.source The source object of the event
|
||||||
|
* @param {} event.name The name of the event
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Properties Documentation
|
* Properties Documentation
|
||||||
|
|
192
test/browser/TestDemo.js
Normal file
192
test/browser/TestDemo.js
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
var page = require('webpage').create();
|
||||||
|
var fs = require('fs');
|
||||||
|
var Resurrect = require('./lib/resurrect');
|
||||||
|
var compare = require('fast-json-patch').compare;
|
||||||
|
var system = require('system');
|
||||||
|
|
||||||
|
var demo,
|
||||||
|
frames = 10,
|
||||||
|
testUrl = 'http://localhost:8000/demo/dev.html',
|
||||||
|
refsPath = 'test/browser/refs',
|
||||||
|
diffsPath = 'test/browser/diffs';
|
||||||
|
|
||||||
|
var update = arg('--update'),
|
||||||
|
updateAll = typeof arg('--updateAll') !== 'undefined',
|
||||||
|
diff = arg('--diff');
|
||||||
|
|
||||||
|
var resurrect = new Resurrect({ cleanup: true, revive: false }),
|
||||||
|
created = [],
|
||||||
|
changed = [];
|
||||||
|
|
||||||
|
var test = function(status) {
|
||||||
|
if (status === 'fail') {
|
||||||
|
console.log('failed to load', testUrl);
|
||||||
|
console.log('check dev server is running!');
|
||||||
|
console.log('use `grunt dev`');
|
||||||
|
phantom.exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var demos = page.evaluate(function() {
|
||||||
|
var demoSelect = document.getElementById('demo-select'),
|
||||||
|
options = Array.prototype.slice.call(demoSelect);
|
||||||
|
return options.map(function(o) { return o.value; });
|
||||||
|
});
|
||||||
|
|
||||||
|
fs.removeTree(diffsPath);
|
||||||
|
|
||||||
|
if (diff) {
|
||||||
|
fs.makeDirectory(diffsPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < demos.length; i += 1) {
|
||||||
|
demo = demos[i];
|
||||||
|
|
||||||
|
var hasChanged = false,
|
||||||
|
hasCreated = false,
|
||||||
|
forceUpdate = update === demo || updateAll,
|
||||||
|
worldStartPath = refsPath + '/' + demo + '/' + demo + '-0.json',
|
||||||
|
worldEndPath = refsPath + '/' + demo + '/' + demo + '-' + frames + '.json',
|
||||||
|
worldStartDiffPath = diffsPath + '/' + demo + '/' + demo + '-0.json',
|
||||||
|
worldEndDiffPath = diffsPath + '/' + demo + '/' + demo + '-' + frames + '.json';
|
||||||
|
|
||||||
|
var worldStart = page.evaluate(function(demo) {
|
||||||
|
var engine = Matter.Demo._engine;
|
||||||
|
if (!(demo in Matter.Demo)) {
|
||||||
|
throw '\'' + demo + '\' is not defined in Matter.Demo';
|
||||||
|
}
|
||||||
|
Matter.Demo[demo]();
|
||||||
|
return engine.world;
|
||||||
|
}, demo);
|
||||||
|
|
||||||
|
var worldEnd = page.evaluate(function(demo, frames) {
|
||||||
|
var engine = Matter.Demo._engine,
|
||||||
|
runner = Matter.Runner.create();
|
||||||
|
|
||||||
|
for (var j = 0; j <= frames; j += 1) {
|
||||||
|
Matter.Runner.tick(runner, engine, j * runner.delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
return engine.world;
|
||||||
|
}, demo, frames);
|
||||||
|
|
||||||
|
worldEnd = resurrect.resurrect(resurrect.stringify(worldEnd, precisionLimiter));
|
||||||
|
worldStart = resurrect.resurrect(resurrect.stringify(worldStart, precisionLimiter));
|
||||||
|
|
||||||
|
if (fs.exists(worldStartPath)) {
|
||||||
|
var worldStartRef = resurrect.resurrect(fs.read(worldStartPath));
|
||||||
|
var worldStartDiff = compare(worldStartRef, worldStart);
|
||||||
|
|
||||||
|
if (worldStartDiff.length !== 0) {
|
||||||
|
if (diff) {
|
||||||
|
fs.write(worldStartDiffPath, JSON.stringify(worldStartDiff, precisionLimiter, 2), 'w');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forceUpdate) {
|
||||||
|
hasCreated = true;
|
||||||
|
fs.write(worldStartPath, resurrect.stringify(worldStart, precisionLimiter, 2), 'w');
|
||||||
|
} else {
|
||||||
|
hasChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasCreated = true;
|
||||||
|
fs.write(worldStartPath, resurrect.stringify(worldStart, precisionLimiter, 2), 'w');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs.exists(worldEndPath)) {
|
||||||
|
var worldEndRef = resurrect.resurrect(fs.read(worldEndPath));
|
||||||
|
var worldEndDiff = compare(worldEndRef, worldEnd);
|
||||||
|
|
||||||
|
if (worldEndDiff.length !== 0) {
|
||||||
|
if (diff) {
|
||||||
|
fs.write(worldEndDiffPath, JSON.stringify(worldEndDiff, precisionLimiter, 2), 'w');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forceUpdate) {
|
||||||
|
hasCreated = true;
|
||||||
|
fs.write(worldEndPath, resurrect.stringify(worldEnd, precisionLimiter, 2), 'w');
|
||||||
|
} else {
|
||||||
|
hasChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasCreated = true;
|
||||||
|
fs.write(worldEndPath, resurrect.stringify(worldEnd, precisionLimiter, 2), 'w');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasChanged) {
|
||||||
|
changed.push("'" + demo + "'");
|
||||||
|
system.stdout.write('x');
|
||||||
|
} else if (hasCreated) {
|
||||||
|
created.push("'" + demo + "'");
|
||||||
|
system.stdout.write('+');
|
||||||
|
} else {
|
||||||
|
system.stdout.write('.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (created.length > 0) {
|
||||||
|
console.log('\nupdated', created.join(', '));
|
||||||
|
}
|
||||||
|
|
||||||
|
var isOk = changed.length === 0 ? 1 : 0;
|
||||||
|
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
if (isOk) {
|
||||||
|
console.log('ok');
|
||||||
|
} else {
|
||||||
|
console.log('\nchanges detected on:');
|
||||||
|
console.log(changed.join(', '));
|
||||||
|
console.log('\nreview, then --update [name] or --updateAll');
|
||||||
|
console.log('use --diff for diff log');
|
||||||
|
}
|
||||||
|
|
||||||
|
phantom.exit(!isOk);
|
||||||
|
};
|
||||||
|
|
||||||
|
var precisionLimiter = function(key, value) {
|
||||||
|
if (typeof value === 'number') {
|
||||||
|
return parseFloat(value.toFixed(5));
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
function arg(name) {
|
||||||
|
var index = system.args.indexOf(name);
|
||||||
|
if (index >= 0) {
|
||||||
|
return system.args[index + 1] || true;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
page.onError = function(msg, trace) {
|
||||||
|
setTimeout(function() {
|
||||||
|
var msgStack = ['testing \'' + demo + '\'', msg];
|
||||||
|
|
||||||
|
if (trace && trace.length) {
|
||||||
|
trace.forEach(function(t) {
|
||||||
|
msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (fn: ' + t.function +')' : ''));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(msgStack.join('\n'));
|
||||||
|
phantom.exit(1);
|
||||||
|
}, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
page.onResourceReceived = function(res) {
|
||||||
|
setTimeout(function() {
|
||||||
|
if (res.stage === 'end'
|
||||||
|
&& (res.status !== 304 && res.status !== 200 && res.status !== null)) {
|
||||||
|
console.log('error', res.status, res.url);
|
||||||
|
phantom.exit(1);
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
phantom.onError = page.onError;
|
||||||
|
|
||||||
|
page.open(testUrl, test);
|
542
test/browser/lib/resurrect.js
Normal file
542
test/browser/lib/resurrect.js
Normal file
|
@ -0,0 +1,542 @@
|
||||||
|
/**
|
||||||
|
* # ResurrectJS
|
||||||
|
* @version 1.0.3
|
||||||
|
* @license Public Domain
|
||||||
|
*
|
||||||
|
* ResurrectJS preserves object behavior (prototypes) and reference
|
||||||
|
* circularity with a special JSON encoding. Unlike regular JSON,
|
||||||
|
* Date, RegExp, DOM objects, and `undefined` are also properly
|
||||||
|
* preserved.
|
||||||
|
*
|
||||||
|
* ## Examples
|
||||||
|
*
|
||||||
|
* function Foo() {}
|
||||||
|
* Foo.prototype.greet = function() { return "hello"; };
|
||||||
|
*
|
||||||
|
* // Behavior is preserved:
|
||||||
|
* var necromancer = new Resurrect();
|
||||||
|
* var json = necromancer.stringify(new Foo());
|
||||||
|
* var foo = necromancer.resurrect(json);
|
||||||
|
* foo.greet(); // => "hello"
|
||||||
|
*
|
||||||
|
* // References to the same object are preserved:
|
||||||
|
* json = necromancer.stringify([foo, foo]);
|
||||||
|
* var array = necromancer.resurrect(json);
|
||||||
|
* array[0] === array[1]; // => true
|
||||||
|
* array[1].greet(); // => "hello"
|
||||||
|
*
|
||||||
|
* // Dates are restored properly
|
||||||
|
* json = necromancer.stringify(new Date());
|
||||||
|
* var date = necromancer.resurrect(json);
|
||||||
|
* Object.prototype.toString.call(date); // => "[object Date]"
|
||||||
|
*
|
||||||
|
* ## Options
|
||||||
|
*
|
||||||
|
* Options are provided to the constructor as an object with these
|
||||||
|
* properties:
|
||||||
|
*
|
||||||
|
* prefix ('#'): A prefix string used for temporary properties added
|
||||||
|
* to objects during serialization and deserialization. It is
|
||||||
|
* important that you don't use any properties beginning with this
|
||||||
|
* string. This option must be consistent between both
|
||||||
|
* serialization and deserialization.
|
||||||
|
*
|
||||||
|
* cleanup (false): Perform full property cleanup after both
|
||||||
|
* serialization and deserialization using the `delete`
|
||||||
|
* operator. This may cause performance penalties (breaking hidden
|
||||||
|
* classes in V8) on objects that ResurrectJS touches, so enable
|
||||||
|
* with care.
|
||||||
|
*
|
||||||
|
* revive (true): Restore behavior (__proto__) to objects that have
|
||||||
|
* been resurrected. If this is set to false during serialization,
|
||||||
|
* resurrection information will not be encoded. You still get
|
||||||
|
* circularity and Date support.
|
||||||
|
*
|
||||||
|
* resolver (Resurrect.NamespaceResolver(window)): Converts between
|
||||||
|
* a name and a prototype. Create a custom resolver if your
|
||||||
|
* constructors are not stored in global variables. The resolver
|
||||||
|
* has two methods: getName(object) and getPrototype(string).
|
||||||
|
*
|
||||||
|
* For example,
|
||||||
|
*
|
||||||
|
* var necromancer = new Resurrect({
|
||||||
|
* prefix: '__#',
|
||||||
|
* cleanup: true
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* ## Caveats
|
||||||
|
*
|
||||||
|
* * With the default resolver, all constructors must be named and
|
||||||
|
* stored in the global variable under that name. This is required
|
||||||
|
* so that the prototypes can be looked up and reconnected at
|
||||||
|
* resurrection time.
|
||||||
|
*
|
||||||
|
* * The wrapper objects Boolean, String, and Number will be
|
||||||
|
* unwrapped. This means extra properties added to these objects
|
||||||
|
* will not be preserved.
|
||||||
|
*
|
||||||
|
* * Functions cannot ever be serialized. Resurrect will throw an
|
||||||
|
* error if a function is found when traversing a data structure.
|
||||||
|
*
|
||||||
|
* @see http://nullprogram.com/blog/2013/03/28/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} [options] See options documentation.
|
||||||
|
* @namespace
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function Resurrect(options) {
|
||||||
|
this.table = null;
|
||||||
|
this.prefix = '#';
|
||||||
|
this.cleanup = false;
|
||||||
|
this.revive = true;
|
||||||
|
for (var option in options) {
|
||||||
|
if (options.hasOwnProperty(option)) {
|
||||||
|
this[option] = options[option];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.refcode = this.prefix + 'id';
|
||||||
|
this.origcode = this.prefix + 'original';
|
||||||
|
this.buildcode = this.prefix + '.';
|
||||||
|
this.valuecode = this.prefix + 'v';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (module)
|
||||||
|
module.exports = Resurrect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Portable access to the global object (window, global).
|
||||||
|
* Uses indirect eval.
|
||||||
|
* @constant
|
||||||
|
*/
|
||||||
|
Resurrect.GLOBAL = (0, eval)('this');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape special regular expression characters in a string.
|
||||||
|
* @param {string} string
|
||||||
|
* @returns {string} The string escaped for exact matches.
|
||||||
|
* @see http://stackoverflow.com/a/6969486
|
||||||
|
*/
|
||||||
|
Resurrect.escapeRegExp = function (string) {
|
||||||
|
return string.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Helper Objects */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} [message]
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
Resurrect.prototype.Error = function ResurrectError(message) {
|
||||||
|
this.message = message || '';
|
||||||
|
this.stack = new Error().stack;
|
||||||
|
};
|
||||||
|
Resurrect.prototype.Error.prototype = Object.create(Error.prototype);
|
||||||
|
Resurrect.prototype.Error.prototype.name = 'ResurrectError';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves prototypes through the properties on an object and
|
||||||
|
* constructor names.
|
||||||
|
* @param {Object} scope
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
Resurrect.NamespaceResolver = function(scope) {
|
||||||
|
this.scope = scope;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the prototype of the given property name from an object. If
|
||||||
|
* not found, it throws an error.
|
||||||
|
* @param {string} name
|
||||||
|
* @returns {Object}
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
Resurrect.NamespaceResolver.prototype.getPrototype = function(name) {
|
||||||
|
var constructor = this.scope[name];
|
||||||
|
if (constructor) {
|
||||||
|
return constructor.prototype;
|
||||||
|
} else {
|
||||||
|
throw new Resurrect.prototype.Error('Unknown constructor: ' + name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the prototype name for an object, to be fetched later with getPrototype.
|
||||||
|
* @param {Object} object
|
||||||
|
* @returns {?string} Null if the constructor is Object.
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
Resurrect.NamespaceResolver.prototype.getName = function(object) {
|
||||||
|
var constructor = object.constructor.name;
|
||||||
|
if (constructor == null) { // IE
|
||||||
|
var funcPattern = /^\s*function\s*([A-Za-z0-9_$]*)/;
|
||||||
|
constructor = funcPattern.exec(object.constructor)[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (constructor === '') {
|
||||||
|
var msg = "Can't serialize objects with anonymous constructors.";
|
||||||
|
throw new Resurrect.prototype.Error(msg);
|
||||||
|
} else if (constructor === 'Object' || constructor === 'Array') {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return constructor;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Set the default resolver searches the global object. */
|
||||||
|
Resurrect.prototype.resolver =
|
||||||
|
new Resurrect.NamespaceResolver(Resurrect.GLOBAL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a DOM node from HTML source; behaves like a constructor.
|
||||||
|
* @param {string} html
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
Resurrect.Node = function(html) {
|
||||||
|
var div = document.createElement('div');
|
||||||
|
div.innerHTML = html;
|
||||||
|
return div.firstChild;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Type Tests */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} type
|
||||||
|
* @returns {Function} A function that tests for type.
|
||||||
|
*/
|
||||||
|
Resurrect.is = function(type) {
|
||||||
|
var string = '[object ' + type + ']';
|
||||||
|
return function(object) {
|
||||||
|
return Object.prototype.toString.call(object) === string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Resurrect.isArray = Resurrect.is('Array');
|
||||||
|
Resurrect.isString = Resurrect.is('String');
|
||||||
|
Resurrect.isBoolean = Resurrect.is('Boolean');
|
||||||
|
Resurrect.isNumber = Resurrect.is('Number');
|
||||||
|
Resurrect.isFunction = Resurrect.is('Function');
|
||||||
|
Resurrect.isDate = Resurrect.is('Date');
|
||||||
|
Resurrect.isRegExp = Resurrect.is('RegExp');
|
||||||
|
Resurrect.isObject = Resurrect.is('Object');
|
||||||
|
|
||||||
|
Resurrect.isAtom = function(object) {
|
||||||
|
return !Resurrect.isObject(object) && !Resurrect.isArray(object);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {*} object
|
||||||
|
* @returns {boolean} True if object is a primitive or a primitive wrapper.
|
||||||
|
*/
|
||||||
|
Resurrect.isPrimitive = function(object) {
|
||||||
|
return object == null ||
|
||||||
|
Resurrect.isNumber(object) ||
|
||||||
|
Resurrect.isString(object) ||
|
||||||
|
Resurrect.isBoolean(object);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Methods */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a reference (encoding) to an object.
|
||||||
|
* @param {(Object|undefined)} object
|
||||||
|
* @returns {Object}
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
Resurrect.prototype.ref = function(object) {
|
||||||
|
var ref = {};
|
||||||
|
if (object === undefined) {
|
||||||
|
ref[this.prefix] = -1;
|
||||||
|
} else {
|
||||||
|
ref[this.prefix] = object[this.refcode];
|
||||||
|
}
|
||||||
|
return ref;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup an object in the table by reference object.
|
||||||
|
* @param {Object} ref
|
||||||
|
* @returns {(Object|undefined)}
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
Resurrect.prototype.deref = function(ref) {
|
||||||
|
return this.table[ref[this.prefix]];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put a temporary identifier on an object and store it in the table.
|
||||||
|
* @param {Object} object
|
||||||
|
* @returns {number} The unique identifier number.
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
Resurrect.prototype.tag = function(object) {
|
||||||
|
if (this.revive) {
|
||||||
|
var constructor = this.resolver.getName(object);
|
||||||
|
if (constructor) {
|
||||||
|
var proto = Object.getPrototypeOf(object);
|
||||||
|
if (this.resolver.getPrototype(constructor) !== proto) {
|
||||||
|
throw new this.Error('Constructor mismatch!');
|
||||||
|
} else {
|
||||||
|
object[this.prefix] = constructor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object[this.refcode] = this.table.length;
|
||||||
|
this.table.push(object);
|
||||||
|
return object[this.refcode];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a builder object (encoding) for serialization.
|
||||||
|
* @param {string} name The name of the constructor.
|
||||||
|
* @param value The value to pass to the constructor.
|
||||||
|
* @returns {Object}
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
Resurrect.prototype.builder = function(name, value) {
|
||||||
|
var builder = {};
|
||||||
|
builder[this.buildcode] = name;
|
||||||
|
builder[this.valuecode] = value;
|
||||||
|
return builder;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a value from a deserialized builder.
|
||||||
|
* @param {Object} ref
|
||||||
|
* @returns {Object}
|
||||||
|
* @method
|
||||||
|
* @see http://stackoverflow.com/a/14378462
|
||||||
|
* @see http://nullprogram.com/blog/2013/03/24/
|
||||||
|
*/
|
||||||
|
Resurrect.prototype.build = function(ref) {
|
||||||
|
var type = ref[this.buildcode].split(/\./).reduce(function(object, name) {
|
||||||
|
return object[name];
|
||||||
|
}, Resurrect.GLOBAL);
|
||||||
|
/* Brilliant hack by kybernetikos: */
|
||||||
|
var args = [null].concat(ref[this.valuecode]);
|
||||||
|
var factory = type.bind.apply(type, args);
|
||||||
|
var result = new factory();
|
||||||
|
if (Resurrect.isPrimitive(result)) {
|
||||||
|
return result.valueOf(); // unwrap
|
||||||
|
} else {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dereference or build an object or value from an encoding.
|
||||||
|
* @param {Object} ref
|
||||||
|
* @returns {(Object|undefined)}
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
Resurrect.prototype.decode = function(ref) {
|
||||||
|
if (this.prefix in ref) {
|
||||||
|
return this.deref(ref);
|
||||||
|
} else if (this.buildcode in ref) {
|
||||||
|
return this.build(ref);
|
||||||
|
} else {
|
||||||
|
throw new this.Error('Unknown encoding.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} object
|
||||||
|
* @returns {boolean} True if the provided object is tagged for serialization.
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
Resurrect.prototype.isTagged = function(object) {
|
||||||
|
return (this.refcode in object) && (object[this.refcode] != null);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visit root and all its ancestors, visiting atoms with f.
|
||||||
|
* @param {*} root
|
||||||
|
* @param {Function} f
|
||||||
|
* @param {Function} replacer
|
||||||
|
* @returns {*} A fresh copy of root to be serialized.
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
Resurrect.prototype.visit = function(root, f, replacer) {
|
||||||
|
if (Resurrect.isAtom(root)) {
|
||||||
|
return f(root);
|
||||||
|
} else if (!this.isTagged(root)) {
|
||||||
|
var copy = null;
|
||||||
|
if (Resurrect.isArray(root)) {
|
||||||
|
copy = [];
|
||||||
|
root[this.refcode] = this.tag(copy);
|
||||||
|
for (var i = 0; i < root.length; i++) {
|
||||||
|
copy.push(this.visit(root[i], f, replacer));
|
||||||
|
}
|
||||||
|
} else { /* Object */
|
||||||
|
copy = Object.create(Object.getPrototypeOf(root));
|
||||||
|
root[this.refcode] = this.tag(copy);
|
||||||
|
for (var key in root) {
|
||||||
|
var value = root[key];
|
||||||
|
if (root.hasOwnProperty(key)) {
|
||||||
|
if (replacer && value !== undefined) {
|
||||||
|
// Call replacer like JSON.stringify's replacer
|
||||||
|
value = replacer.call(root, key, root[key]);
|
||||||
|
if (value === undefined) {
|
||||||
|
continue; // Omit from result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
copy[key] = this.visit(value, f, replacer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
copy[this.origcode] = root;
|
||||||
|
return this.ref(copy);
|
||||||
|
} else {
|
||||||
|
return this.ref(root);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage special atom values, possibly returning an encoding.
|
||||||
|
* @param {*} atom
|
||||||
|
* @returns {*}
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
Resurrect.prototype.handleAtom = function(atom) {
|
||||||
|
var Node = Resurrect.GLOBAL.Node || function() {};
|
||||||
|
if (Resurrect.isFunction(atom)) {
|
||||||
|
throw new this.Error("Can't serialize functions.");
|
||||||
|
} else if (atom instanceof Node) {
|
||||||
|
var xmls = new XMLSerializer();
|
||||||
|
return this.builder('Resurrect.Node', [xmls.serializeToString(atom)]);
|
||||||
|
} else if (Resurrect.isDate(atom)) {
|
||||||
|
return this.builder('Date', [atom.toISOString()]);
|
||||||
|
} else if (Resurrect.isRegExp(atom)) {
|
||||||
|
var args = atom.toString().match(/\/(.+)\/([gimy]*)/).slice(1);
|
||||||
|
return this.builder('RegExp', args);
|
||||||
|
} else if (atom === undefined) {
|
||||||
|
return this.ref(undefined);
|
||||||
|
} else if (Resurrect.isNumber(atom) && (isNaN(atom) || !isFinite(atom))) {
|
||||||
|
return this.builder('Number', [atom.toString()]);
|
||||||
|
} else {
|
||||||
|
return atom;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides intrusive keys from a user-supplied replacer.
|
||||||
|
* @param {Function} replacer function of two arguments (key, value)
|
||||||
|
* @returns {Function} A function that skips the replacer for intrusive keys.
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
Resurrect.prototype.replacerWrapper = function(replacer) {
|
||||||
|
var skip = new RegExp('^' + Resurrect.escapeRegExp(this.prefix));
|
||||||
|
return function(k, v) {
|
||||||
|
if (skip.test(k)) {
|
||||||
|
return v;
|
||||||
|
} else {
|
||||||
|
return replacer(k, v);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize an arbitrary JavaScript object, carefully preserving it.
|
||||||
|
* @param {*} object
|
||||||
|
* @param {(Function|Array)} replacer
|
||||||
|
* @param {string} space
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
Resurrect.prototype.stringify = function(object, replacer, space) {
|
||||||
|
if (Resurrect.isFunction(replacer)) {
|
||||||
|
replacer = this.replacerWrapper(replacer);
|
||||||
|
} else if (Resurrect.isArray(replacer)) {
|
||||||
|
var acceptKeys = replacer;
|
||||||
|
replacer = function(k, v) {
|
||||||
|
return acceptKeys.indexOf(k) >= 0 ? v : undefined;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (Resurrect.isAtom(object)) {
|
||||||
|
return JSON.stringify(this.handleAtom(object), replacer, space);
|
||||||
|
} else {
|
||||||
|
this.table = [];
|
||||||
|
this.visit(object, this.handleAtom.bind(this), replacer);
|
||||||
|
for (var i = 0; i < this.table.length; i++) {
|
||||||
|
if (this.cleanup) {
|
||||||
|
delete this.table[i][this.origcode][this.refcode];
|
||||||
|
} else {
|
||||||
|
this.table[i][this.origcode][this.refcode] = null;
|
||||||
|
}
|
||||||
|
delete this.table[i][this.refcode];
|
||||||
|
delete this.table[i][this.origcode];
|
||||||
|
}
|
||||||
|
var table = this.table;
|
||||||
|
this.table = null;
|
||||||
|
return JSON.stringify(table, null, space);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the __proto__ of the given object to the proper value.
|
||||||
|
* @param {Object} object
|
||||||
|
* @returns {Object} Its argument, or a copy, with the prototype restored.
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
Resurrect.prototype.fixPrototype = function(object) {
|
||||||
|
if (this.prefix in object) {
|
||||||
|
var name = object[this.prefix];
|
||||||
|
var prototype = this.resolver.getPrototype(name);
|
||||||
|
if ('__proto__' in object) {
|
||||||
|
object.__proto__ = prototype;
|
||||||
|
if (this.cleanup) {
|
||||||
|
delete object[this.prefix];
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
} else { // IE
|
||||||
|
var copy = Object.create(prototype);
|
||||||
|
for (var key in object) {
|
||||||
|
if (object.hasOwnProperty(key) && key !== this.prefix) {
|
||||||
|
copy[key] = object[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize an encoded object, restoring circularity and behavior.
|
||||||
|
* @param {string} string
|
||||||
|
* @returns {*} The decoded object or value.
|
||||||
|
* @method
|
||||||
|
*/
|
||||||
|
Resurrect.prototype.resurrect = function(string) {
|
||||||
|
var result = null;
|
||||||
|
var data = JSON.parse(string);
|
||||||
|
if (Resurrect.isArray(data)) {
|
||||||
|
this.table = data;
|
||||||
|
/* Restore __proto__. */
|
||||||
|
if (this.revive) {
|
||||||
|
for (var i = 0; i < this.table.length; i++) {
|
||||||
|
this.table[i] = this.fixPrototype(this.table[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Re-establish object references and construct atoms. */
|
||||||
|
for (i = 0; i < this.table.length; i++) {
|
||||||
|
var object = this.table[i];
|
||||||
|
for (var key in object) {
|
||||||
|
if (object.hasOwnProperty(key)) {
|
||||||
|
if (!(Resurrect.isAtom(object[key]))) {
|
||||||
|
object[key] = this.decode(object[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = this.table[0];
|
||||||
|
} else if (Resurrect.isObject(data)) {
|
||||||
|
this.table = [];
|
||||||
|
result = this.decode(data);
|
||||||
|
} else {
|
||||||
|
result = data;
|
||||||
|
}
|
||||||
|
this.table = null;
|
||||||
|
return result;
|
||||||
|
};
|
1427
test/browser/refs/airFriction/airFriction-0.json
Normal file
1427
test/browser/refs/airFriction/airFriction-0.json
Normal file
File diff suppressed because it is too large
Load diff
1497
test/browser/refs/airFriction/airFriction-10.json
Normal file
1497
test/browser/refs/airFriction/airFriction-10.json
Normal file
File diff suppressed because it is too large
Load diff
36249
test/browser/refs/avalanche/avalanche-0.json
Normal file
36249
test/browser/refs/avalanche/avalanche-0.json
Normal file
File diff suppressed because it is too large
Load diff
37319
test/browser/refs/avalanche/avalanche-10.json
Normal file
37319
test/browser/refs/avalanche/avalanche-10.json
Normal file
File diff suppressed because it is too large
Load diff
66852
test/browser/refs/ballPool/ballPool-0.json
Normal file
66852
test/browser/refs/ballPool/ballPool-0.json
Normal file
File diff suppressed because it is too large
Load diff
68422
test/browser/refs/ballPool/ballPool-10.json
Normal file
68422
test/browser/refs/ballPool/ballPool-10.json
Normal file
File diff suppressed because it is too large
Load diff
3307
test/browser/refs/beachBalls/beachBalls-0.json
Normal file
3307
test/browser/refs/beachBalls/beachBalls-0.json
Normal file
File diff suppressed because it is too large
Load diff
3397
test/browser/refs/beachBalls/beachBalls-10.json
Normal file
3397
test/browser/refs/beachBalls/beachBalls-10.json
Normal file
File diff suppressed because it is too large
Load diff
8066
test/browser/refs/bridge/bridge-0.json
Normal file
8066
test/browser/refs/bridge/bridge-0.json
Normal file
File diff suppressed because it is too large
Load diff
8396
test/browser/refs/bridge/bridge-10.json
Normal file
8396
test/browser/refs/bridge/bridge-10.json
Normal file
File diff suppressed because it is too large
Load diff
22924
test/browser/refs/broadphase/broadphase-0.json
Normal file
22924
test/browser/refs/broadphase/broadphase-0.json
Normal file
File diff suppressed because it is too large
Load diff
23964
test/browser/refs/broadphase/broadphase-10.json
Normal file
23964
test/browser/refs/broadphase/broadphase-10.json
Normal file
File diff suppressed because it is too large
Load diff
4332
test/browser/refs/car/car-0.json
Normal file
4332
test/browser/refs/car/car-0.json
Normal file
File diff suppressed because it is too large
Load diff
4462
test/browser/refs/car/car-10.json
Normal file
4462
test/browser/refs/car/car-10.json
Normal file
File diff suppressed because it is too large
Load diff
2923
test/browser/refs/catapult/catapult-0.json
Normal file
2923
test/browser/refs/catapult/catapult-0.json
Normal file
File diff suppressed because it is too large
Load diff
3053
test/browser/refs/catapult/catapult-10.json
Normal file
3053
test/browser/refs/catapult/catapult-10.json
Normal file
File diff suppressed because it is too large
Load diff
7493
test/browser/refs/chains/chains-0.json
Normal file
7493
test/browser/refs/chains/chains-0.json
Normal file
File diff suppressed because it is too large
Load diff
7733
test/browser/refs/chains/chains-10.json
Normal file
7733
test/browser/refs/chains/chains-10.json
Normal file
File diff suppressed because it is too large
Load diff
40902
test/browser/refs/circleStack/circleStack-0.json
Normal file
40902
test/browser/refs/circleStack/circleStack-0.json
Normal file
File diff suppressed because it is too large
Load diff
41942
test/browser/refs/circleStack/circleStack-10.json
Normal file
41942
test/browser/refs/circleStack/circleStack-10.json
Normal file
File diff suppressed because it is too large
Load diff
82964
test/browser/refs/cloth/cloth-0.json
Normal file
82964
test/browser/refs/cloth/cloth-0.json
Normal file
File diff suppressed because it is too large
Load diff
85424
test/browser/refs/cloth/cloth-10.json
Normal file
85424
test/browser/refs/cloth/cloth-10.json
Normal file
File diff suppressed because it is too large
Load diff
22345
test/browser/refs/collisionFiltering/collisionFiltering-0.json
Normal file
22345
test/browser/refs/collisionFiltering/collisionFiltering-0.json
Normal file
File diff suppressed because it is too large
Load diff
22915
test/browser/refs/collisionFiltering/collisionFiltering-10.json
Normal file
22915
test/browser/refs/collisionFiltering/collisionFiltering-10.json
Normal file
File diff suppressed because it is too large
Load diff
3821
test/browser/refs/compositeManipulation/compositeManipulation-0.json
Normal file
3821
test/browser/refs/compositeManipulation/compositeManipulation-0.json
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
1668
test/browser/refs/compound/compound-0.json
Normal file
1668
test/browser/refs/compound/compound-0.json
Normal file
File diff suppressed because it is too large
Load diff
1728
test/browser/refs/compound/compound-10.json
Normal file
1728
test/browser/refs/compound/compound-10.json
Normal file
File diff suppressed because it is too large
Load diff
17966
test/browser/refs/compoundStack/compoundStack-0.json
Normal file
17966
test/browser/refs/compoundStack/compoundStack-0.json
Normal file
File diff suppressed because it is too large
Load diff
18726
test/browser/refs/compoundStack/compoundStack-10.json
Normal file
18726
test/browser/refs/compoundStack/compoundStack-10.json
Normal file
File diff suppressed because it is too large
Load diff
6237
test/browser/refs/concave/concave-0.json
Normal file
6237
test/browser/refs/concave/concave-0.json
Normal file
File diff suppressed because it is too large
Load diff
6517
test/browser/refs/concave/concave-10.json
Normal file
6517
test/browser/refs/concave/concave-10.json
Normal file
File diff suppressed because it is too large
Load diff
11979
test/browser/refs/events/events-0.json
Normal file
11979
test/browser/refs/events/events-0.json
Normal file
File diff suppressed because it is too large
Load diff
12339
test/browser/refs/events/events-10.json
Normal file
12339
test/browser/refs/events/events-10.json
Normal file
File diff suppressed because it is too large
Load diff
2021
test/browser/refs/friction/friction-0.json
Normal file
2021
test/browser/refs/friction/friction-0.json
Normal file
File diff suppressed because it is too large
Load diff
2121
test/browser/refs/friction/friction-10.json
Normal file
2121
test/browser/refs/friction/friction-10.json
Normal file
File diff suppressed because it is too large
Load diff
22915
test/browser/refs/gravity/gravity-0.json
Normal file
22915
test/browser/refs/gravity/gravity-0.json
Normal file
File diff suppressed because it is too large
Load diff
23955
test/browser/refs/gravity/gravity-10.json
Normal file
23955
test/browser/refs/gravity/gravity-10.json
Normal file
File diff suppressed because it is too large
Load diff
2695
test/browser/refs/manipulation/manipulation-0.json
Normal file
2695
test/browser/refs/manipulation/manipulation-0.json
Normal file
File diff suppressed because it is too large
Load diff
2829
test/browser/refs/manipulation/manipulation-10.json
Normal file
2829
test/browser/refs/manipulation/manipulation-10.json
Normal file
File diff suppressed because it is too large
Load diff
17880
test/browser/refs/mixed/mixed-0.json
Normal file
17880
test/browser/refs/mixed/mixed-0.json
Normal file
File diff suppressed because it is too large
Load diff
18515
test/browser/refs/mixed/mixed-10.json
Normal file
18515
test/browser/refs/mixed/mixed-10.json
Normal file
File diff suppressed because it is too large
Load diff
8705
test/browser/refs/mixedSolid/mixedSolid-0.json
Normal file
8705
test/browser/refs/mixedSolid/mixedSolid-0.json
Normal file
File diff suppressed because it is too large
Load diff
9105
test/browser/refs/mixedSolid/mixedSolid-10.json
Normal file
9105
test/browser/refs/mixedSolid/mixedSolid-10.json
Normal file
File diff suppressed because it is too large
Load diff
6563
test/browser/refs/newtonsCradle/newtonsCradle-0.json
Normal file
6563
test/browser/refs/newtonsCradle/newtonsCradle-0.json
Normal file
File diff suppressed because it is too large
Load diff
6723
test/browser/refs/newtonsCradle/newtonsCradle-10.json
Normal file
6723
test/browser/refs/newtonsCradle/newtonsCradle-10.json
Normal file
File diff suppressed because it is too large
Load diff
12605
test/browser/refs/pyramid/pyramid-0.json
Normal file
12605
test/browser/refs/pyramid/pyramid-0.json
Normal file
File diff suppressed because it is too large
Load diff
13285
test/browser/refs/pyramid/pyramid-10.json
Normal file
13285
test/browser/refs/pyramid/pyramid-10.json
Normal file
File diff suppressed because it is too large
Load diff
14451
test/browser/refs/raycasting/raycasting-0.json
Normal file
14451
test/browser/refs/raycasting/raycasting-0.json
Normal file
File diff suppressed because it is too large
Load diff
15101
test/browser/refs/raycasting/raycasting-10.json
Normal file
15101
test/browser/refs/raycasting/raycasting-10.json
Normal file
File diff suppressed because it is too large
Load diff
2091
test/browser/refs/restitution/restitution-0.json
Normal file
2091
test/browser/refs/restitution/restitution-0.json
Normal file
File diff suppressed because it is too large
Load diff
2181
test/browser/refs/restitution/restitution-10.json
Normal file
2181
test/browser/refs/restitution/restitution-10.json
Normal file
File diff suppressed because it is too large
Load diff
4610
test/browser/refs/rounded/rounded-0.json
Normal file
4610
test/browser/refs/rounded/rounded-0.json
Normal file
File diff suppressed because it is too large
Load diff
4730
test/browser/refs/rounded/rounded-10.json
Normal file
4730
test/browser/refs/rounded/rounded-10.json
Normal file
File diff suppressed because it is too large
Load diff
9198
test/browser/refs/sleeping/sleeping-0.json
Normal file
9198
test/browser/refs/sleeping/sleeping-0.json
Normal file
File diff suppressed because it is too large
Load diff
9598
test/browser/refs/sleeping/sleeping-10.json
Normal file
9598
test/browser/refs/sleeping/sleeping-10.json
Normal file
File diff suppressed because it is too large
Load diff
7069
test/browser/refs/slingshot/slingshot-0.json
Normal file
7069
test/browser/refs/slingshot/slingshot-0.json
Normal file
File diff suppressed because it is too large
Load diff
7439
test/browser/refs/slingshot/slingshot-10.json
Normal file
7439
test/browser/refs/slingshot/slingshot-10.json
Normal file
File diff suppressed because it is too large
Load diff
31055
test/browser/refs/softBody/softBody-0.json
Normal file
31055
test/browser/refs/softBody/softBody-0.json
Normal file
File diff suppressed because it is too large
Load diff
31745
test/browser/refs/softBody/softBody-10.json
Normal file
31745
test/browser/refs/softBody/softBody-10.json
Normal file
File diff suppressed because it is too large
Load diff
11829
test/browser/refs/sprites/sprites-0.json
Normal file
11829
test/browser/refs/sprites/sprites-0.json
Normal file
File diff suppressed because it is too large
Load diff
12269
test/browser/refs/sprites/sprites-10.json
Normal file
12269
test/browser/refs/sprites/sprites-10.json
Normal file
File diff suppressed because it is too large
Load diff
10052
test/browser/refs/stack/stack-0.json
Normal file
10052
test/browser/refs/stack/stack-0.json
Normal file
File diff suppressed because it is too large
Load diff
10592
test/browser/refs/stack/stack-10.json
Normal file
10592
test/browser/refs/stack/stack-10.json
Normal file
File diff suppressed because it is too large
Load diff
2390
test/browser/refs/staticFriction/staticFriction-0.json
Normal file
2390
test/browser/refs/staticFriction/staticFriction-0.json
Normal file
File diff suppressed because it is too large
Load diff
2500
test/browser/refs/staticFriction/staticFriction-10.json
Normal file
2500
test/browser/refs/staticFriction/staticFriction-10.json
Normal file
File diff suppressed because it is too large
Load diff
50312
test/browser/refs/stress/stress-0.json
Normal file
50312
test/browser/refs/stress/stress-0.json
Normal file
File diff suppressed because it is too large
Load diff
53052
test/browser/refs/stress/stress-10.json
Normal file
53052
test/browser/refs/stress/stress-10.json
Normal file
File diff suppressed because it is too large
Load diff
83252
test/browser/refs/stress2/stress2-0.json
Normal file
83252
test/browser/refs/stress2/stress2-0.json
Normal file
File diff suppressed because it is too large
Load diff
87792
test/browser/refs/stress2/stress2-10.json
Normal file
87792
test/browser/refs/stress2/stress2-10.json
Normal file
File diff suppressed because it is too large
Load diff
889
test/browser/refs/svg/svg-0.json
Normal file
889
test/browser/refs/svg/svg-0.json
Normal file
|
@ -0,0 +1,889 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"bodies": {
|
||||||
|
"#": 1
|
||||||
|
},
|
||||||
|
"bounds": {
|
||||||
|
"#": 86
|
||||||
|
},
|
||||||
|
"composites": {
|
||||||
|
"#": 89
|
||||||
|
},
|
||||||
|
"constraints": {
|
||||||
|
"#": 90
|
||||||
|
},
|
||||||
|
"gravity": {
|
||||||
|
"#": 94
|
||||||
|
},
|
||||||
|
"id": 0,
|
||||||
|
"isModified": true,
|
||||||
|
"label": "World",
|
||||||
|
"parent": "",
|
||||||
|
"type": "composite"
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 23
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 44
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 65
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"angle": 0,
|
||||||
|
"anglePrev": 0,
|
||||||
|
"angularSpeed": 0,
|
||||||
|
"angularVelocity": 0,
|
||||||
|
"area": 40930.25,
|
||||||
|
"axes": {
|
||||||
|
"#": 3
|
||||||
|
},
|
||||||
|
"bounds": {
|
||||||
|
"#": 6
|
||||||
|
},
|
||||||
|
"collisionFilter": {
|
||||||
|
"#": 9
|
||||||
|
},
|
||||||
|
"constraintImpulse": {
|
||||||
|
"#": 10
|
||||||
|
},
|
||||||
|
"density": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"force": {
|
||||||
|
"#": 11
|
||||||
|
},
|
||||||
|
"friction": 1,
|
||||||
|
"frictionAir": 0.01,
|
||||||
|
"frictionStatic": 0.5,
|
||||||
|
"id": 0,
|
||||||
|
"inertia": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"inverseInertia": 0,
|
||||||
|
"inverseMass": 0,
|
||||||
|
"isSleeping": false,
|
||||||
|
"isStatic": true,
|
||||||
|
"label": "Rectangle Body",
|
||||||
|
"mass": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"motion": 0,
|
||||||
|
"parent": null,
|
||||||
|
"position": {
|
||||||
|
"#": 12
|
||||||
|
},
|
||||||
|
"positionImpulse": {
|
||||||
|
"#": 13
|
||||||
|
},
|
||||||
|
"positionPrev": {
|
||||||
|
"#": 14
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"#": 15
|
||||||
|
},
|
||||||
|
"restitution": 0,
|
||||||
|
"sleepCounter": 0,
|
||||||
|
"sleepThreshold": 60,
|
||||||
|
"slop": 0.05,
|
||||||
|
"speed": 0,
|
||||||
|
"timeScale": 1,
|
||||||
|
"torque": 0,
|
||||||
|
"totalContacts": 0,
|
||||||
|
"type": "body",
|
||||||
|
"velocity": {
|
||||||
|
"#": 17
|
||||||
|
},
|
||||||
|
"vertices": {
|
||||||
|
"#": 18
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -1,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"max": {
|
||||||
|
"#": 7
|
||||||
|
},
|
||||||
|
"min": {
|
||||||
|
"#": 8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 805.25,
|
||||||
|
"y": 20.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -5.25,
|
||||||
|
"y": -30.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": 1,
|
||||||
|
"group": 0,
|
||||||
|
"mask": 4294967295
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"angle": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 400,
|
||||||
|
"y": -5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 400,
|
||||||
|
"y": -5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fillStyle": "#eeeeee",
|
||||||
|
"lineWidth": 1.5,
|
||||||
|
"sprite": {
|
||||||
|
"#": 16
|
||||||
|
},
|
||||||
|
"strokeStyle": "#bbbbbb",
|
||||||
|
"visible": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"xScale": 1,
|
||||||
|
"yScale": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 19
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 21
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 22
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 0,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": -5.25,
|
||||||
|
"y": -30.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 1,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 805.25,
|
||||||
|
"y": -30.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 2,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 805.25,
|
||||||
|
"y": 20.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 3,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": -5.25,
|
||||||
|
"y": 20.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"angle": 0,
|
||||||
|
"anglePrev": 0,
|
||||||
|
"angularSpeed": 0,
|
||||||
|
"angularVelocity": 0,
|
||||||
|
"area": 40930.25,
|
||||||
|
"axes": {
|
||||||
|
"#": 24
|
||||||
|
},
|
||||||
|
"bounds": {
|
||||||
|
"#": 27
|
||||||
|
},
|
||||||
|
"collisionFilter": {
|
||||||
|
"#": 30
|
||||||
|
},
|
||||||
|
"constraintImpulse": {
|
||||||
|
"#": 31
|
||||||
|
},
|
||||||
|
"density": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"force": {
|
||||||
|
"#": 32
|
||||||
|
},
|
||||||
|
"friction": 1,
|
||||||
|
"frictionAir": 0.01,
|
||||||
|
"frictionStatic": 0.5,
|
||||||
|
"id": 1,
|
||||||
|
"inertia": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"inverseInertia": 0,
|
||||||
|
"inverseMass": 0,
|
||||||
|
"isSleeping": false,
|
||||||
|
"isStatic": true,
|
||||||
|
"label": "Rectangle Body",
|
||||||
|
"mass": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"motion": 0,
|
||||||
|
"parent": null,
|
||||||
|
"position": {
|
||||||
|
"#": 33
|
||||||
|
},
|
||||||
|
"positionImpulse": {
|
||||||
|
"#": 34
|
||||||
|
},
|
||||||
|
"positionPrev": {
|
||||||
|
"#": 35
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"#": 36
|
||||||
|
},
|
||||||
|
"restitution": 0,
|
||||||
|
"sleepCounter": 0,
|
||||||
|
"sleepThreshold": 60,
|
||||||
|
"slop": 0.05,
|
||||||
|
"speed": 0,
|
||||||
|
"timeScale": 1,
|
||||||
|
"torque": 0,
|
||||||
|
"totalContacts": 0,
|
||||||
|
"type": "body",
|
||||||
|
"velocity": {
|
||||||
|
"#": 38
|
||||||
|
},
|
||||||
|
"vertices": {
|
||||||
|
"#": 39
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 26
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -1,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"max": {
|
||||||
|
"#": 28
|
||||||
|
},
|
||||||
|
"min": {
|
||||||
|
"#": 29
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 805.25,
|
||||||
|
"y": 630.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -5.25,
|
||||||
|
"y": 579.75
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": 1,
|
||||||
|
"group": 0,
|
||||||
|
"mask": 4294967295
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"angle": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 400,
|
||||||
|
"y": 605
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 400,
|
||||||
|
"y": 605
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fillStyle": "#eeeeee",
|
||||||
|
"lineWidth": 1.5,
|
||||||
|
"sprite": {
|
||||||
|
"#": 37
|
||||||
|
},
|
||||||
|
"strokeStyle": "#bbbbbb",
|
||||||
|
"visible": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"xScale": 1,
|
||||||
|
"yScale": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 41
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 42
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 43
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 0,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": -5.25,
|
||||||
|
"y": 579.75
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 1,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 805.25,
|
||||||
|
"y": 579.75
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 2,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 805.25,
|
||||||
|
"y": 630.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 3,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": -5.25,
|
||||||
|
"y": 630.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"angle": 0,
|
||||||
|
"anglePrev": 0,
|
||||||
|
"angularSpeed": 0,
|
||||||
|
"angularVelocity": 0,
|
||||||
|
"area": 30830.25,
|
||||||
|
"axes": {
|
||||||
|
"#": 45
|
||||||
|
},
|
||||||
|
"bounds": {
|
||||||
|
"#": 48
|
||||||
|
},
|
||||||
|
"collisionFilter": {
|
||||||
|
"#": 51
|
||||||
|
},
|
||||||
|
"constraintImpulse": {
|
||||||
|
"#": 52
|
||||||
|
},
|
||||||
|
"density": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"force": {
|
||||||
|
"#": 53
|
||||||
|
},
|
||||||
|
"friction": 1,
|
||||||
|
"frictionAir": 0.01,
|
||||||
|
"frictionStatic": 0.5,
|
||||||
|
"id": 2,
|
||||||
|
"inertia": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"inverseInertia": 0,
|
||||||
|
"inverseMass": 0,
|
||||||
|
"isSleeping": false,
|
||||||
|
"isStatic": true,
|
||||||
|
"label": "Rectangle Body",
|
||||||
|
"mass": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"motion": 0,
|
||||||
|
"parent": null,
|
||||||
|
"position": {
|
||||||
|
"#": 54
|
||||||
|
},
|
||||||
|
"positionImpulse": {
|
||||||
|
"#": 55
|
||||||
|
},
|
||||||
|
"positionPrev": {
|
||||||
|
"#": 56
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"#": 57
|
||||||
|
},
|
||||||
|
"restitution": 0,
|
||||||
|
"sleepCounter": 0,
|
||||||
|
"sleepThreshold": 60,
|
||||||
|
"slop": 0.05,
|
||||||
|
"speed": 0,
|
||||||
|
"timeScale": 1,
|
||||||
|
"torque": 0,
|
||||||
|
"totalContacts": 0,
|
||||||
|
"type": "body",
|
||||||
|
"velocity": {
|
||||||
|
"#": 59
|
||||||
|
},
|
||||||
|
"vertices": {
|
||||||
|
"#": 60
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 46
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 47
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -1,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"max": {
|
||||||
|
"#": 49
|
||||||
|
},
|
||||||
|
"min": {
|
||||||
|
"#": 50
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 830.25,
|
||||||
|
"y": 605.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 779.75,
|
||||||
|
"y": -5.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": 1,
|
||||||
|
"group": 0,
|
||||||
|
"mask": 4294967295
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"angle": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 805,
|
||||||
|
"y": 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 805,
|
||||||
|
"y": 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fillStyle": "#eeeeee",
|
||||||
|
"lineWidth": 1.5,
|
||||||
|
"sprite": {
|
||||||
|
"#": 58
|
||||||
|
},
|
||||||
|
"strokeStyle": "#bbbbbb",
|
||||||
|
"visible": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"xScale": 1,
|
||||||
|
"yScale": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 61
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 62
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 63
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 64
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 0,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 779.75,
|
||||||
|
"y": -5.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 1,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 830.25,
|
||||||
|
"y": -5.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 2,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 830.25,
|
||||||
|
"y": 605.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 3,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 779.75,
|
||||||
|
"y": 605.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"angle": 0,
|
||||||
|
"anglePrev": 0,
|
||||||
|
"angularSpeed": 0,
|
||||||
|
"angularVelocity": 0,
|
||||||
|
"area": 30830.25,
|
||||||
|
"axes": {
|
||||||
|
"#": 66
|
||||||
|
},
|
||||||
|
"bounds": {
|
||||||
|
"#": 69
|
||||||
|
},
|
||||||
|
"collisionFilter": {
|
||||||
|
"#": 72
|
||||||
|
},
|
||||||
|
"constraintImpulse": {
|
||||||
|
"#": 73
|
||||||
|
},
|
||||||
|
"density": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"force": {
|
||||||
|
"#": 74
|
||||||
|
},
|
||||||
|
"friction": 1,
|
||||||
|
"frictionAir": 0.01,
|
||||||
|
"frictionStatic": 0.5,
|
||||||
|
"id": 3,
|
||||||
|
"inertia": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"inverseInertia": 0,
|
||||||
|
"inverseMass": 0,
|
||||||
|
"isSleeping": false,
|
||||||
|
"isStatic": true,
|
||||||
|
"label": "Rectangle Body",
|
||||||
|
"mass": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"motion": 0,
|
||||||
|
"parent": null,
|
||||||
|
"position": {
|
||||||
|
"#": 75
|
||||||
|
},
|
||||||
|
"positionImpulse": {
|
||||||
|
"#": 76
|
||||||
|
},
|
||||||
|
"positionPrev": {
|
||||||
|
"#": 77
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"#": 78
|
||||||
|
},
|
||||||
|
"restitution": 0,
|
||||||
|
"sleepCounter": 0,
|
||||||
|
"sleepThreshold": 60,
|
||||||
|
"slop": 0.05,
|
||||||
|
"speed": 0,
|
||||||
|
"timeScale": 1,
|
||||||
|
"torque": 0,
|
||||||
|
"totalContacts": 0,
|
||||||
|
"type": "body",
|
||||||
|
"velocity": {
|
||||||
|
"#": 80
|
||||||
|
},
|
||||||
|
"vertices": {
|
||||||
|
"#": 81
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 67
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 68
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -1,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"max": {
|
||||||
|
"#": 70
|
||||||
|
},
|
||||||
|
"min": {
|
||||||
|
"#": 71
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 20.25,
|
||||||
|
"y": 605.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -30.25,
|
||||||
|
"y": -5.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": 1,
|
||||||
|
"group": 0,
|
||||||
|
"mask": 4294967295
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"angle": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -5,
|
||||||
|
"y": 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -5,
|
||||||
|
"y": 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fillStyle": "#eeeeee",
|
||||||
|
"lineWidth": 1.5,
|
||||||
|
"sprite": {
|
||||||
|
"#": 79
|
||||||
|
},
|
||||||
|
"strokeStyle": "#bbbbbb",
|
||||||
|
"visible": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"xScale": 1,
|
||||||
|
"yScale": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 82
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 83
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 84
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 85
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 0,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": -30.25,
|
||||||
|
"y": -5.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 1,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 20.25,
|
||||||
|
"y": -5.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 2,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 20.25,
|
||||||
|
"y": 605.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 3,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": -30.25,
|
||||||
|
"y": 605.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"max": {
|
||||||
|
"#": 87
|
||||||
|
},
|
||||||
|
"min": {
|
||||||
|
"#": 88
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"y": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"-Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"y": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"-Infinity"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 91
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"angularStiffness": 1,
|
||||||
|
"bodyB": "",
|
||||||
|
"id": 1,
|
||||||
|
"label": "Mouse Constraint",
|
||||||
|
"length": 0.01,
|
||||||
|
"pointA": {
|
||||||
|
"#": 92
|
||||||
|
},
|
||||||
|
"pointB": "",
|
||||||
|
"render": {
|
||||||
|
"#": 93
|
||||||
|
},
|
||||||
|
"stiffness": 0.1,
|
||||||
|
"type": "constraint"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lineWidth": 3,
|
||||||
|
"strokeStyle": "#90EE90",
|
||||||
|
"visible": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 1
|
||||||
|
}
|
||||||
|
]
|
929
test/browser/refs/svg/svg-10.json
Normal file
929
test/browser/refs/svg/svg-10.json
Normal file
|
@ -0,0 +1,929 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"bodies": {
|
||||||
|
"#": 1
|
||||||
|
},
|
||||||
|
"bounds": {
|
||||||
|
"#": 90
|
||||||
|
},
|
||||||
|
"composites": {
|
||||||
|
"#": 93
|
||||||
|
},
|
||||||
|
"constraints": {
|
||||||
|
"#": 94
|
||||||
|
},
|
||||||
|
"gravity": {
|
||||||
|
"#": 98
|
||||||
|
},
|
||||||
|
"id": 0,
|
||||||
|
"isModified": false,
|
||||||
|
"label": "World",
|
||||||
|
"parent": "",
|
||||||
|
"type": "composite"
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 24
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 46
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 68
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"angle": 0,
|
||||||
|
"anglePrev": 0,
|
||||||
|
"angularSpeed": 0,
|
||||||
|
"angularVelocity": 0,
|
||||||
|
"area": 40930.25,
|
||||||
|
"axes": {
|
||||||
|
"#": 3
|
||||||
|
},
|
||||||
|
"bounds": {
|
||||||
|
"#": 6
|
||||||
|
},
|
||||||
|
"collisionFilter": {
|
||||||
|
"#": 9
|
||||||
|
},
|
||||||
|
"constraintImpulse": {
|
||||||
|
"#": 10
|
||||||
|
},
|
||||||
|
"density": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"force": {
|
||||||
|
"#": 11
|
||||||
|
},
|
||||||
|
"friction": 1,
|
||||||
|
"frictionAir": 0.01,
|
||||||
|
"frictionStatic": 0.5,
|
||||||
|
"id": 0,
|
||||||
|
"inertia": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"inverseInertia": 0,
|
||||||
|
"inverseMass": 0,
|
||||||
|
"isSleeping": false,
|
||||||
|
"isStatic": true,
|
||||||
|
"label": "Rectangle Body",
|
||||||
|
"mass": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"motion": 0,
|
||||||
|
"parent": null,
|
||||||
|
"position": {
|
||||||
|
"#": 12
|
||||||
|
},
|
||||||
|
"positionImpulse": {
|
||||||
|
"#": 13
|
||||||
|
},
|
||||||
|
"positionPrev": {
|
||||||
|
"#": 14
|
||||||
|
},
|
||||||
|
"region": {
|
||||||
|
"#": 15
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"#": 16
|
||||||
|
},
|
||||||
|
"restitution": 0,
|
||||||
|
"sleepCounter": 0,
|
||||||
|
"sleepThreshold": 60,
|
||||||
|
"slop": 0.05,
|
||||||
|
"speed": 0,
|
||||||
|
"timeScale": 1,
|
||||||
|
"torque": 0,
|
||||||
|
"totalContacts": 0,
|
||||||
|
"type": "body",
|
||||||
|
"velocity": {
|
||||||
|
"#": 18
|
||||||
|
},
|
||||||
|
"vertices": {
|
||||||
|
"#": 19
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -1,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"max": {
|
||||||
|
"#": 7
|
||||||
|
},
|
||||||
|
"min": {
|
||||||
|
"#": 8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 805.25,
|
||||||
|
"y": 20.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -5.25,
|
||||||
|
"y": -30.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": 1,
|
||||||
|
"group": 0,
|
||||||
|
"mask": 4294967295
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"angle": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 400,
|
||||||
|
"y": -5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 400,
|
||||||
|
"y": -5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"endCol": 16,
|
||||||
|
"endRow": 0,
|
||||||
|
"id": "-1,16,-1,0",
|
||||||
|
"startCol": -1,
|
||||||
|
"startRow": -1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fillStyle": "#eeeeee",
|
||||||
|
"lineWidth": 1.5,
|
||||||
|
"sprite": {
|
||||||
|
"#": 17
|
||||||
|
},
|
||||||
|
"strokeStyle": "#bbbbbb",
|
||||||
|
"visible": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"xScale": 1,
|
||||||
|
"yScale": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 21
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 22
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 23
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 0,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": -5.25,
|
||||||
|
"y": -30.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 1,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 805.25,
|
||||||
|
"y": -30.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 2,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 805.25,
|
||||||
|
"y": 20.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 3,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": -5.25,
|
||||||
|
"y": 20.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"angle": 0,
|
||||||
|
"anglePrev": 0,
|
||||||
|
"angularSpeed": 0,
|
||||||
|
"angularVelocity": 0,
|
||||||
|
"area": 40930.25,
|
||||||
|
"axes": {
|
||||||
|
"#": 25
|
||||||
|
},
|
||||||
|
"bounds": {
|
||||||
|
"#": 28
|
||||||
|
},
|
||||||
|
"collisionFilter": {
|
||||||
|
"#": 31
|
||||||
|
},
|
||||||
|
"constraintImpulse": {
|
||||||
|
"#": 32
|
||||||
|
},
|
||||||
|
"density": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"force": {
|
||||||
|
"#": 33
|
||||||
|
},
|
||||||
|
"friction": 1,
|
||||||
|
"frictionAir": 0.01,
|
||||||
|
"frictionStatic": 0.5,
|
||||||
|
"id": 1,
|
||||||
|
"inertia": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"inverseInertia": 0,
|
||||||
|
"inverseMass": 0,
|
||||||
|
"isSleeping": false,
|
||||||
|
"isStatic": true,
|
||||||
|
"label": "Rectangle Body",
|
||||||
|
"mass": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"motion": 0,
|
||||||
|
"parent": null,
|
||||||
|
"position": {
|
||||||
|
"#": 34
|
||||||
|
},
|
||||||
|
"positionImpulse": {
|
||||||
|
"#": 35
|
||||||
|
},
|
||||||
|
"positionPrev": {
|
||||||
|
"#": 36
|
||||||
|
},
|
||||||
|
"region": {
|
||||||
|
"#": 37
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"#": 38
|
||||||
|
},
|
||||||
|
"restitution": 0,
|
||||||
|
"sleepCounter": 0,
|
||||||
|
"sleepThreshold": 60,
|
||||||
|
"slop": 0.05,
|
||||||
|
"speed": 0,
|
||||||
|
"timeScale": 1,
|
||||||
|
"torque": 0,
|
||||||
|
"totalContacts": 0,
|
||||||
|
"type": "body",
|
||||||
|
"velocity": {
|
||||||
|
"#": 40
|
||||||
|
},
|
||||||
|
"vertices": {
|
||||||
|
"#": 41
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 26
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 27
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -1,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"max": {
|
||||||
|
"#": 29
|
||||||
|
},
|
||||||
|
"min": {
|
||||||
|
"#": 30
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 805.25,
|
||||||
|
"y": 630.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -5.25,
|
||||||
|
"y": 579.75
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": 1,
|
||||||
|
"group": 0,
|
||||||
|
"mask": 4294967295
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"angle": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 400,
|
||||||
|
"y": 605
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 400,
|
||||||
|
"y": 605
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"endCol": 16,
|
||||||
|
"endRow": 13,
|
||||||
|
"id": "-1,16,12,13",
|
||||||
|
"startCol": -1,
|
||||||
|
"startRow": 12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fillStyle": "#eeeeee",
|
||||||
|
"lineWidth": 1.5,
|
||||||
|
"sprite": {
|
||||||
|
"#": 39
|
||||||
|
},
|
||||||
|
"strokeStyle": "#bbbbbb",
|
||||||
|
"visible": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"xScale": 1,
|
||||||
|
"yScale": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 42
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 43
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 44
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 45
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 0,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": -5.25,
|
||||||
|
"y": 579.75
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 1,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 805.25,
|
||||||
|
"y": 579.75
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 2,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 805.25,
|
||||||
|
"y": 630.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 3,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": -5.25,
|
||||||
|
"y": 630.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"angle": 0,
|
||||||
|
"anglePrev": 0,
|
||||||
|
"angularSpeed": 0,
|
||||||
|
"angularVelocity": 0,
|
||||||
|
"area": 30830.25,
|
||||||
|
"axes": {
|
||||||
|
"#": 47
|
||||||
|
},
|
||||||
|
"bounds": {
|
||||||
|
"#": 50
|
||||||
|
},
|
||||||
|
"collisionFilter": {
|
||||||
|
"#": 53
|
||||||
|
},
|
||||||
|
"constraintImpulse": {
|
||||||
|
"#": 54
|
||||||
|
},
|
||||||
|
"density": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"force": {
|
||||||
|
"#": 55
|
||||||
|
},
|
||||||
|
"friction": 1,
|
||||||
|
"frictionAir": 0.01,
|
||||||
|
"frictionStatic": 0.5,
|
||||||
|
"id": 2,
|
||||||
|
"inertia": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"inverseInertia": 0,
|
||||||
|
"inverseMass": 0,
|
||||||
|
"isSleeping": false,
|
||||||
|
"isStatic": true,
|
||||||
|
"label": "Rectangle Body",
|
||||||
|
"mass": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"motion": 0,
|
||||||
|
"parent": null,
|
||||||
|
"position": {
|
||||||
|
"#": 56
|
||||||
|
},
|
||||||
|
"positionImpulse": {
|
||||||
|
"#": 57
|
||||||
|
},
|
||||||
|
"positionPrev": {
|
||||||
|
"#": 58
|
||||||
|
},
|
||||||
|
"region": {
|
||||||
|
"#": 59
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"#": 60
|
||||||
|
},
|
||||||
|
"restitution": 0,
|
||||||
|
"sleepCounter": 0,
|
||||||
|
"sleepThreshold": 60,
|
||||||
|
"slop": 0.05,
|
||||||
|
"speed": 0,
|
||||||
|
"timeScale": 1,
|
||||||
|
"torque": 0,
|
||||||
|
"totalContacts": 0,
|
||||||
|
"type": "body",
|
||||||
|
"velocity": {
|
||||||
|
"#": 62
|
||||||
|
},
|
||||||
|
"vertices": {
|
||||||
|
"#": 63
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 48
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 49
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -1,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"max": {
|
||||||
|
"#": 51
|
||||||
|
},
|
||||||
|
"min": {
|
||||||
|
"#": 52
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 830.25,
|
||||||
|
"y": 605.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 779.75,
|
||||||
|
"y": -5.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": 1,
|
||||||
|
"group": 0,
|
||||||
|
"mask": 4294967295
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"angle": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 805,
|
||||||
|
"y": 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 805,
|
||||||
|
"y": 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"endCol": 17,
|
||||||
|
"endRow": 12,
|
||||||
|
"id": "16,17,-1,12",
|
||||||
|
"startCol": 16,
|
||||||
|
"startRow": -1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fillStyle": "#eeeeee",
|
||||||
|
"lineWidth": 1.5,
|
||||||
|
"sprite": {
|
||||||
|
"#": 61
|
||||||
|
},
|
||||||
|
"strokeStyle": "#bbbbbb",
|
||||||
|
"visible": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"xScale": 1,
|
||||||
|
"yScale": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 64
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 65
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 66
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 67
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 0,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 779.75,
|
||||||
|
"y": -5.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 1,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 830.25,
|
||||||
|
"y": -5.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 2,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 830.25,
|
||||||
|
"y": 605.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 3,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 779.75,
|
||||||
|
"y": 605.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"angle": 0,
|
||||||
|
"anglePrev": 0,
|
||||||
|
"angularSpeed": 0,
|
||||||
|
"angularVelocity": 0,
|
||||||
|
"area": 30830.25,
|
||||||
|
"axes": {
|
||||||
|
"#": 69
|
||||||
|
},
|
||||||
|
"bounds": {
|
||||||
|
"#": 72
|
||||||
|
},
|
||||||
|
"collisionFilter": {
|
||||||
|
"#": 75
|
||||||
|
},
|
||||||
|
"constraintImpulse": {
|
||||||
|
"#": 76
|
||||||
|
},
|
||||||
|
"density": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"force": {
|
||||||
|
"#": 77
|
||||||
|
},
|
||||||
|
"friction": 1,
|
||||||
|
"frictionAir": 0.01,
|
||||||
|
"frictionStatic": 0.5,
|
||||||
|
"id": 3,
|
||||||
|
"inertia": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"inverseInertia": 0,
|
||||||
|
"inverseMass": 0,
|
||||||
|
"isSleeping": false,
|
||||||
|
"isStatic": true,
|
||||||
|
"label": "Rectangle Body",
|
||||||
|
"mass": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"motion": 0,
|
||||||
|
"parent": null,
|
||||||
|
"position": {
|
||||||
|
"#": 78
|
||||||
|
},
|
||||||
|
"positionImpulse": {
|
||||||
|
"#": 79
|
||||||
|
},
|
||||||
|
"positionPrev": {
|
||||||
|
"#": 80
|
||||||
|
},
|
||||||
|
"region": {
|
||||||
|
"#": 81
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"#": 82
|
||||||
|
},
|
||||||
|
"restitution": 0,
|
||||||
|
"sleepCounter": 0,
|
||||||
|
"sleepThreshold": 60,
|
||||||
|
"slop": 0.05,
|
||||||
|
"speed": 0,
|
||||||
|
"timeScale": 1,
|
||||||
|
"torque": 0,
|
||||||
|
"totalContacts": 0,
|
||||||
|
"type": "body",
|
||||||
|
"velocity": {
|
||||||
|
"#": 84
|
||||||
|
},
|
||||||
|
"vertices": {
|
||||||
|
"#": 85
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 71
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -1,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"max": {
|
||||||
|
"#": 73
|
||||||
|
},
|
||||||
|
"min": {
|
||||||
|
"#": 74
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 20.25,
|
||||||
|
"y": 605.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -30.25,
|
||||||
|
"y": -5.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": 1,
|
||||||
|
"group": 0,
|
||||||
|
"mask": 4294967295
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"angle": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -5,
|
||||||
|
"y": 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": -5,
|
||||||
|
"y": 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"endCol": 0,
|
||||||
|
"endRow": 12,
|
||||||
|
"id": "-1,0,-1,12",
|
||||||
|
"startCol": -1,
|
||||||
|
"startRow": -1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fillStyle": "#eeeeee",
|
||||||
|
"lineWidth": 1.5,
|
||||||
|
"sprite": {
|
||||||
|
"#": 83
|
||||||
|
},
|
||||||
|
"strokeStyle": "#bbbbbb",
|
||||||
|
"visible": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"xScale": 1,
|
||||||
|
"yScale": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 86
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 87
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 88
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"#": 89
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 0,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": -30.25,
|
||||||
|
"y": -5.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 1,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 20.25,
|
||||||
|
"y": -5.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 2,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": 20.25,
|
||||||
|
"y": 605.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"body": null,
|
||||||
|
"index": 3,
|
||||||
|
"isInternal": false,
|
||||||
|
"x": -30.25,
|
||||||
|
"y": 605.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"max": {
|
||||||
|
"#": 91
|
||||||
|
},
|
||||||
|
"min": {
|
||||||
|
"#": 92
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"y": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"-Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"y": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"-Infinity"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 95
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"angularStiffness": 1,
|
||||||
|
"bodyB": "",
|
||||||
|
"id": 1,
|
||||||
|
"label": "Mouse Constraint",
|
||||||
|
"length": 0.01,
|
||||||
|
"pointA": {
|
||||||
|
"#": 96
|
||||||
|
},
|
||||||
|
"pointB": "",
|
||||||
|
"render": {
|
||||||
|
"#": 97
|
||||||
|
},
|
||||||
|
"stiffness": 0.1,
|
||||||
|
"type": "constraint"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lineWidth": 3,
|
||||||
|
"strokeStyle": "#90EE90",
|
||||||
|
"visible": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 1
|
||||||
|
}
|
||||||
|
]
|
96
test/browser/refs/terrain/terrain-0.json
Normal file
96
test/browser/refs/terrain/terrain-0.json
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"bodies": {
|
||||||
|
"#": 1
|
||||||
|
},
|
||||||
|
"bounds": {
|
||||||
|
"#": 2
|
||||||
|
},
|
||||||
|
"composites": {
|
||||||
|
"#": 5
|
||||||
|
},
|
||||||
|
"constraints": {
|
||||||
|
"#": 6
|
||||||
|
},
|
||||||
|
"gravity": {
|
||||||
|
"#": 10
|
||||||
|
},
|
||||||
|
"id": 0,
|
||||||
|
"isModified": true,
|
||||||
|
"label": "World",
|
||||||
|
"parent": "",
|
||||||
|
"type": "composite"
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
{
|
||||||
|
"max": {
|
||||||
|
"#": 3
|
||||||
|
},
|
||||||
|
"min": {
|
||||||
|
"#": 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"y": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"-Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"y": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"-Infinity"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 7
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"angularStiffness": 1,
|
||||||
|
"bodyB": "",
|
||||||
|
"id": 1,
|
||||||
|
"label": "Mouse Constraint",
|
||||||
|
"length": 0.01,
|
||||||
|
"pointA": {
|
||||||
|
"#": 8
|
||||||
|
},
|
||||||
|
"pointB": "",
|
||||||
|
"render": {
|
||||||
|
"#": 9
|
||||||
|
},
|
||||||
|
"stiffness": 0.1,
|
||||||
|
"type": "constraint"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lineWidth": 3,
|
||||||
|
"strokeStyle": "#90EE90",
|
||||||
|
"visible": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 1
|
||||||
|
}
|
||||||
|
]
|
96
test/browser/refs/terrain/terrain-10.json
Normal file
96
test/browser/refs/terrain/terrain-10.json
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"bodies": {
|
||||||
|
"#": 1
|
||||||
|
},
|
||||||
|
"bounds": {
|
||||||
|
"#": 2
|
||||||
|
},
|
||||||
|
"composites": {
|
||||||
|
"#": 5
|
||||||
|
},
|
||||||
|
"constraints": {
|
||||||
|
"#": 6
|
||||||
|
},
|
||||||
|
"gravity": {
|
||||||
|
"#": 10
|
||||||
|
},
|
||||||
|
"id": 0,
|
||||||
|
"isModified": false,
|
||||||
|
"label": "World",
|
||||||
|
"parent": "",
|
||||||
|
"type": "composite"
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
{
|
||||||
|
"max": {
|
||||||
|
"#": 3
|
||||||
|
},
|
||||||
|
"min": {
|
||||||
|
"#": 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"y": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"Infinity"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"-Infinity"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"y": {
|
||||||
|
"#.": "Number",
|
||||||
|
"#v": [
|
||||||
|
"-Infinity"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"#": 7
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
"angularStiffness": 1,
|
||||||
|
"bodyB": "",
|
||||||
|
"id": 1,
|
||||||
|
"label": "Mouse Constraint",
|
||||||
|
"length": 0.01,
|
||||||
|
"pointA": {
|
||||||
|
"#": 8
|
||||||
|
},
|
||||||
|
"pointB": "",
|
||||||
|
"render": {
|
||||||
|
"#": 9
|
||||||
|
},
|
||||||
|
"stiffness": 0.1,
|
||||||
|
"type": "constraint"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lineWidth": 3,
|
||||||
|
"strokeStyle": "#90EE90",
|
||||||
|
"visible": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 1
|
||||||
|
}
|
||||||
|
]
|
21617
test/browser/refs/timescale/timescale-0.json
Normal file
21617
test/browser/refs/timescale/timescale-0.json
Normal file
File diff suppressed because it is too large
Load diff
22347
test/browser/refs/timescale/timescale-10.json
Normal file
22347
test/browser/refs/timescale/timescale-10.json
Normal file
File diff suppressed because it is too large
Load diff
14237
test/browser/refs/views/views-0.json
Normal file
14237
test/browser/refs/views/views-0.json
Normal file
File diff suppressed because it is too large
Load diff
14877
test/browser/refs/views/views-10.json
Normal file
14877
test/browser/refs/views/views-10.json
Normal file
File diff suppressed because it is too large
Load diff
10579
test/browser/refs/wreckingBall/wreckingBall-0.json
Normal file
10579
test/browser/refs/wreckingBall/wreckingBall-0.json
Normal file
File diff suppressed because it is too large
Load diff
11129
test/browser/refs/wreckingBall/wreckingBall-10.json
Normal file
11129
test/browser/refs/wreckingBall/wreckingBall-10.json
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue