mirror of
https://github.com/liabru/matter-js.git
synced 2025-01-21 17:14:38 -05:00
add test capture sort to improve comparison
This commit is contained in:
parent
de04c00278
commit
ea3c11b1fe
2 changed files with 111 additions and 106 deletions
|
@ -3,10 +3,27 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const mock = require('mock-require');
|
const mock = require('mock-require');
|
||||||
const { requireUncached, engineCapture } = require('./TestTools');
|
|
||||||
const Example = require('../examples/index');
|
const Example = require('../examples/index');
|
||||||
|
const { requireUncached } = require('./TestTools');
|
||||||
const consoleOriginal = global.console;
|
const consoleOriginal = global.console;
|
||||||
|
|
||||||
|
const intrinsicProps = [
|
||||||
|
// Common
|
||||||
|
'id', 'label',
|
||||||
|
|
||||||
|
// Constraint
|
||||||
|
'angularStiffness', 'bodyA', 'bodyB', 'damping', 'length', 'stiffness',
|
||||||
|
|
||||||
|
// Body
|
||||||
|
'area', 'axes', 'collisionFilter', 'category', 'mask',
|
||||||
|
'group', 'density', 'friction', 'frictionAir', 'frictionStatic', 'inertia', 'inverseInertia', 'inverseMass', 'isSensor',
|
||||||
|
'isSleeping', 'isStatic', 'mass', 'parent', 'parts', 'restitution', 'sleepThreshold', 'slop',
|
||||||
|
'timeScale', 'vertices',
|
||||||
|
|
||||||
|
// Composite
|
||||||
|
'bodies', 'constraints', 'composites'
|
||||||
|
];
|
||||||
|
|
||||||
const prepareMatter = (options) => {
|
const prepareMatter = (options) => {
|
||||||
const Matter = requireUncached(options.useDev ? '../build/matter.dev' : '../build/matter');
|
const Matter = requireUncached(options.useDev ? '../build/matter.dev' : '../build/matter');
|
||||||
|
|
||||||
|
@ -48,6 +65,97 @@ const resetEnvironment = () => {
|
||||||
mock.stopAll();
|
mock.stopAll();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const limitPrecision = (val, precision=3) => parseFloat(val.toPrecision(precision));
|
||||||
|
|
||||||
|
const sortById = (objs) => {
|
||||||
|
objs.sort((objA, objB) => objA.id - objB.id);
|
||||||
|
return objs;
|
||||||
|
};
|
||||||
|
|
||||||
|
const engineCapture = (engine, Matter) => ({
|
||||||
|
timestamp: limitPrecision(engine.timing.timestamp),
|
||||||
|
extrinsic: worldCaptureExtrinsic(engine.world, Matter),
|
||||||
|
intrinsic: worldCaptureIntrinsic(engine.world, Matter)
|
||||||
|
});
|
||||||
|
|
||||||
|
const worldCaptureExtrinsic = (world, Matter) => ({
|
||||||
|
bodies: sortById(Matter.Composite.allBodies(world)).reduce((bodies, body) => {
|
||||||
|
bodies[body.id] = [
|
||||||
|
body.position.x,
|
||||||
|
body.position.y,
|
||||||
|
body.positionPrev.x,
|
||||||
|
body.positionPrev.y,
|
||||||
|
body.angle,
|
||||||
|
body.anglePrev,
|
||||||
|
...body.vertices.reduce((flat, vertex) => (flat.push(vertex.x, vertex.y), flat), [])
|
||||||
|
];
|
||||||
|
|
||||||
|
return bodies;
|
||||||
|
}, {}),
|
||||||
|
constraints: sortById(Matter.Composite.allConstraints(world)).reduce((constraints, constraint) => {
|
||||||
|
const positionA = Matter.Constraint.pointAWorld(constraint);
|
||||||
|
const positionB = Matter.Constraint.pointBWorld(constraint);
|
||||||
|
|
||||||
|
constraints[constraint.id] = [
|
||||||
|
positionA.x,
|
||||||
|
positionA.y,
|
||||||
|
positionB.x,
|
||||||
|
positionB.y
|
||||||
|
];
|
||||||
|
|
||||||
|
return constraints;
|
||||||
|
}, {})
|
||||||
|
});
|
||||||
|
|
||||||
|
const worldCaptureIntrinsic = (world, Matter) => worldCaptureIntrinsicBase({
|
||||||
|
bodies: sortById(Matter.Composite.allBodies(world)).reduce((bodies, body) => {
|
||||||
|
bodies[body.id] = body;
|
||||||
|
return bodies;
|
||||||
|
}, {}),
|
||||||
|
constraints: sortById(Matter.Composite.allConstraints(world)).reduce((constraints, constraint) => {
|
||||||
|
constraints[constraint.id] = constraint;
|
||||||
|
return constraints;
|
||||||
|
}, {}),
|
||||||
|
composites: sortById(Matter.Composite.allComposites(world)).reduce((composites, composite) => {
|
||||||
|
composites[composite.id] = {
|
||||||
|
bodies: sortById(Matter.Composite.allBodies(composite)).map(body => body.id),
|
||||||
|
constraints: sortById(Matter.Composite.allConstraints(composite)).map(constraint => constraint.id),
|
||||||
|
composites: sortById(Matter.Composite.allComposites(composite)).map(composite => composite.id)
|
||||||
|
};
|
||||||
|
return composites;
|
||||||
|
}, {})
|
||||||
|
});
|
||||||
|
|
||||||
|
const worldCaptureIntrinsicBase = (obj, depth=0) => {
|
||||||
|
if (obj === Infinity) {
|
||||||
|
return 'Infinity';
|
||||||
|
} else if (typeof obj === 'number') {
|
||||||
|
return limitPrecision(obj);
|
||||||
|
} else if (Array.isArray(obj)) {
|
||||||
|
return obj.map(item => worldCaptureIntrinsicBase(item, depth + 1));
|
||||||
|
} else if (typeof obj !== 'object') {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = Object.entries(obj)
|
||||||
|
.filter(([key]) => depth <= 1 || intrinsicProps.includes(key))
|
||||||
|
.reduce((cleaned, [key, val]) => {
|
||||||
|
if (val && val.id && String(val.id) !== key) {
|
||||||
|
val = val.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(val) && !['composites', 'constraints', 'bodies'].includes(key)) {
|
||||||
|
val = `[${val.length}]`;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleaned[key] = worldCaptureIntrinsicBase(val, depth + 1);
|
||||||
|
return cleaned;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
return Object.keys(result).sort()
|
||||||
|
.reduce((sorted, key) => (sorted[key] = result[key], sorted), {});
|
||||||
|
};
|
||||||
|
|
||||||
const runExample = options => {
|
const runExample = options => {
|
||||||
const Matter = prepareMatter(options);
|
const Matter = prepareMatter(options);
|
||||||
const logs = prepareEnvironment(Matter);
|
const logs = prepareEnvironment(Matter);
|
||||||
|
@ -107,7 +215,7 @@ const runExample = options => {
|
||||||
overlap: overlapTotal / (overlapCount || 1),
|
overlap: overlapTotal / (overlapCount || 1),
|
||||||
memory: totalMemory,
|
memory: totalMemory,
|
||||||
logs,
|
logs,
|
||||||
...engineCapture(engine)
|
...engineCapture(engine, Matter)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const compactStringify = require('json-stringify-pretty-compact');
|
const compactStringify = require('json-stringify-pretty-compact');
|
||||||
const { Composite, Constraint } = require('../src/module/main');
|
|
||||||
|
|
||||||
const comparePath = './test/__compare__';
|
const comparePath = './test/__compare__';
|
||||||
const compareCommand = 'open http://localhost:8000/?compare';
|
const compareCommand = 'open http://localhost:8000/?compare';
|
||||||
|
@ -11,26 +10,8 @@ const diffSaveCommand = 'npm run test-save';
|
||||||
const diffCommand = 'code -n -d test/__compare__/examples-build.json test/__compare__/examples-dev.json';
|
const diffCommand = 'code -n -d test/__compare__/examples-build.json test/__compare__/examples-dev.json';
|
||||||
const equalityThreshold = 0.99999;
|
const equalityThreshold = 0.99999;
|
||||||
|
|
||||||
const intrinsicProps = [
|
|
||||||
// Common
|
|
||||||
'id', 'label',
|
|
||||||
|
|
||||||
// Constraint
|
|
||||||
'angularStiffness', 'bodyA', 'bodyB', 'damping', 'length', 'stiffness',
|
|
||||||
|
|
||||||
// Body
|
|
||||||
'area', 'axes', 'collisionFilter', 'category', 'mask',
|
|
||||||
'group', 'density', 'friction', 'frictionAir', 'frictionStatic', 'inertia', 'inverseInertia', 'inverseMass', 'isSensor',
|
|
||||||
'isSleeping', 'isStatic', 'mass', 'parent', 'parts', 'restitution', 'sleepThreshold', 'slop',
|
|
||||||
'timeScale', 'vertices',
|
|
||||||
|
|
||||||
// Composite
|
|
||||||
'bodies', 'constraints', 'composites'
|
|
||||||
];
|
|
||||||
|
|
||||||
const colors = { Red: 31, Green: 32, Yellow: 33, White: 37, BrightWhite: 90, BrightCyan: 36 };
|
const colors = { Red: 31, Green: 32, Yellow: 33, White: 37, BrightWhite: 90, BrightCyan: 36 };
|
||||||
const color = (text, number) => number ? `\x1b[${number}m${text}\x1b[0m` : text;
|
const color = (text, number) => number ? `\x1b[${number}m${text}\x1b[0m` : text;
|
||||||
const limit = (val, precision=3) => parseFloat(val.toPrecision(precision));
|
|
||||||
const toPercent = val => (100 * val).toFixed(3);
|
const toPercent = val => (100 * val).toFixed(3);
|
||||||
const toPercentRound = val => Math.round(100 * val);
|
const toPercentRound = val => Math.round(100 * val);
|
||||||
|
|
||||||
|
@ -47,90 +28,6 @@ const noiseThreshold = (val, threshold) => {
|
||||||
return sign * Math.max(0, magnitude - threshold) / (1 - threshold);
|
return sign * Math.max(0, magnitude - threshold) / (1 - threshold);
|
||||||
};
|
};
|
||||||
|
|
||||||
const engineCapture = (engine) => ({
|
|
||||||
timestamp: limit(engine.timing.timestamp),
|
|
||||||
extrinsic: worldCaptureExtrinsic(engine.world),
|
|
||||||
intrinsic: worldCaptureIntrinsic(engine.world)
|
|
||||||
});
|
|
||||||
|
|
||||||
const worldCaptureExtrinsic = world => ({
|
|
||||||
bodies: Composite.allBodies(world).reduce((bodies, body) => {
|
|
||||||
bodies[body.id] = [
|
|
||||||
body.position.x,
|
|
||||||
body.position.y,
|
|
||||||
body.positionPrev.x,
|
|
||||||
body.positionPrev.y,
|
|
||||||
body.angle,
|
|
||||||
body.anglePrev,
|
|
||||||
...body.vertices.reduce((flat, vertex) => (flat.push(vertex.x, vertex.y), flat), [])
|
|
||||||
];
|
|
||||||
|
|
||||||
return bodies;
|
|
||||||
}, {}),
|
|
||||||
constraints: Composite.allConstraints(world).reduce((constraints, constraint) => {
|
|
||||||
const positionA = Constraint.pointAWorld(constraint);
|
|
||||||
const positionB = Constraint.pointBWorld(constraint);
|
|
||||||
|
|
||||||
constraints[constraint.id] = [
|
|
||||||
positionA.x,
|
|
||||||
positionA.y,
|
|
||||||
positionB.x,
|
|
||||||
positionB.y
|
|
||||||
];
|
|
||||||
|
|
||||||
return constraints;
|
|
||||||
}, {})
|
|
||||||
});
|
|
||||||
|
|
||||||
const worldCaptureIntrinsic = world => worldCaptureIntrinsicBase({
|
|
||||||
bodies: Composite.allBodies(world).reduce((bodies, body) => {
|
|
||||||
bodies[body.id] = body;
|
|
||||||
return bodies;
|
|
||||||
}, {}),
|
|
||||||
constraints: Composite.allConstraints(world).reduce((constraints, constraint) => {
|
|
||||||
constraints[constraint.id] = constraint;
|
|
||||||
return constraints;
|
|
||||||
}, {}),
|
|
||||||
composites: Composite.allComposites(world).reduce((composites, composite) => {
|
|
||||||
composites[composite.id] = {
|
|
||||||
bodies: Composite.allBodies(composite).map(body => body.id),
|
|
||||||
constraints: Composite.allConstraints(composite).map(constraint => constraint.id),
|
|
||||||
composites: Composite.allComposites(composite).map(composite => composite.id)
|
|
||||||
};
|
|
||||||
return composites;
|
|
||||||
}, {})
|
|
||||||
});
|
|
||||||
|
|
||||||
const worldCaptureIntrinsicBase = (obj, depth=0) => {
|
|
||||||
if (obj === Infinity) {
|
|
||||||
return 'Infinity';
|
|
||||||
} else if (typeof obj === 'number') {
|
|
||||||
return limit(obj);
|
|
||||||
} else if (Array.isArray(obj)) {
|
|
||||||
return obj.map(item => worldCaptureIntrinsicBase(item, depth + 1));
|
|
||||||
} else if (typeof obj !== 'object') {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = Object.entries(obj)
|
|
||||||
.filter(([key]) => depth <= 1 || intrinsicProps.includes(key))
|
|
||||||
.reduce((cleaned, [key, val]) => {
|
|
||||||
if (val && val.id && String(val.id) !== key) {
|
|
||||||
val = val.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(val) && !['composites', 'constraints', 'bodies'].includes(key)) {
|
|
||||||
val = `[${val.length}]`;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleaned[key] = worldCaptureIntrinsicBase(val, depth + 1);
|
|
||||||
return cleaned;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
return Object.keys(result).sort()
|
|
||||||
.reduce((sorted, key) => (sorted[key] = result[key], sorted), {});
|
|
||||||
};
|
|
||||||
|
|
||||||
const similarity = (a, b) => {
|
const similarity = (a, b) => {
|
||||||
const distance = Math.sqrt(a.reduce(
|
const distance = Math.sqrt(a.reduce(
|
||||||
(sum, _val, i) => sum + Math.pow((a[i] || 0) - (b[i] || 0), 2), 0)
|
(sum, _val, i) => sum + Math.pow((a[i] || 0) - (b[i] || 0), 2), 0)
|
||||||
|
@ -325,6 +222,6 @@ const comparisonReport = (capturesDev, capturesBuild, devSize, buildSize, buildV
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
requireUncached, engineCapture, comparisonReport, logReport,
|
requireUncached, comparisonReport, logReport,
|
||||||
toMatchExtrinsics, toMatchIntrinsics
|
toMatchExtrinsics, toMatchIntrinsics
|
||||||
};
|
};
|
Loading…
Add table
Reference in a new issue