@melonjs/matter-adapter 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../node_modules/.pnpm/poly-decomp@0.3.0/node_modules/poly-decomp/src/index.js", "../src/index.ts"],
4
+ "sourcesContent": ["module.exports = {\n decomp: polygonDecomp,\n quickDecomp: polygonQuickDecomp,\n isSimple: polygonIsSimple,\n removeCollinearPoints: polygonRemoveCollinearPoints,\n removeDuplicatePoints: polygonRemoveDuplicatePoints,\n makeCCW: polygonMakeCCW\n};\n\n/**\n * Compute the intersection between two lines.\n * @static\n * @method lineInt\n * @param {Array} l1 Line vector 1\n * @param {Array} l2 Line vector 2\n * @param {Number} precision Precision to use when checking if the lines are parallel\n * @return {Array} The intersection point.\n */\nfunction lineInt(l1,l2,precision){\n precision = precision || 0;\n var i = [0,0]; // point\n var a1, b1, c1, a2, b2, c2, det; // scalars\n a1 = l1[1][1] - l1[0][1];\n b1 = l1[0][0] - l1[1][0];\n c1 = a1 * l1[0][0] + b1 * l1[0][1];\n a2 = l2[1][1] - l2[0][1];\n b2 = l2[0][0] - l2[1][0];\n c2 = a2 * l2[0][0] + b2 * l2[0][1];\n det = a1 * b2 - a2*b1;\n if (!scalar_eq(det, 0, precision)) { // lines are not parallel\n i[0] = (b2 * c1 - b1 * c2) / det;\n i[1] = (a1 * c2 - a2 * c1) / det;\n }\n return i;\n}\n\n/**\n * Checks if two line segments intersects.\n * @method segmentsIntersect\n * @param {Array} p1 The start vertex of the first line segment.\n * @param {Array} p2 The end vertex of the first line segment.\n * @param {Array} q1 The start vertex of the second line segment.\n * @param {Array} q2 The end vertex of the second line segment.\n * @return {Boolean} True if the two line segments intersect\n */\nfunction lineSegmentsIntersect(p1, p2, q1, q2){\n\tvar dx = p2[0] - p1[0];\n\tvar dy = p2[1] - p1[1];\n\tvar da = q2[0] - q1[0];\n\tvar db = q2[1] - q1[1];\n\n\t// segments are parallel\n\tif((da*dy - db*dx) === 0){\n\t\treturn false;\n\t}\n\n\tvar s = (dx * (q1[1] - p1[1]) + dy * (p1[0] - q1[0])) / (da * dy - db * dx);\n\tvar t = (da * (p1[1] - q1[1]) + db * (q1[0] - p1[0])) / (db * dx - da * dy);\n\n\treturn (s>=0 && s<=1 && t>=0 && t<=1);\n}\n\n/**\n * Get the area of a triangle spanned by the three given points. Note that the area will be negative if the points are not given in counter-clockwise order.\n * @static\n * @method area\n * @param {Array} a\n * @param {Array} b\n * @param {Array} c\n * @return {Number}\n */\nfunction triangleArea(a,b,c){\n return (((b[0] - a[0])*(c[1] - a[1]))-((c[0] - a[0])*(b[1] - a[1])));\n}\n\nfunction isLeft(a,b,c){\n return triangleArea(a,b,c) > 0;\n}\n\nfunction isLeftOn(a,b,c) {\n return triangleArea(a, b, c) >= 0;\n}\n\nfunction isRight(a,b,c) {\n return triangleArea(a, b, c) < 0;\n}\n\nfunction isRightOn(a,b,c) {\n return triangleArea(a, b, c) <= 0;\n}\n\nvar tmpPoint1 = [],\n tmpPoint2 = [];\n\n/**\n * Check if three points are collinear\n * @method collinear\n * @param {Array} a\n * @param {Array} b\n * @param {Array} c\n * @param {Number} [thresholdAngle=0] Threshold angle to use when comparing the vectors. The function will return true if the angle between the resulting vectors is less than this value. Use zero for max precision.\n * @return {Boolean}\n */\nfunction collinear(a,b,c,thresholdAngle) {\n if(!thresholdAngle){\n return triangleArea(a, b, c) === 0;\n } else {\n var ab = tmpPoint1,\n bc = tmpPoint2;\n\n ab[0] = b[0]-a[0];\n ab[1] = b[1]-a[1];\n bc[0] = c[0]-b[0];\n bc[1] = c[1]-b[1];\n\n var dot = ab[0]*bc[0] + ab[1]*bc[1],\n magA = Math.sqrt(ab[0]*ab[0] + ab[1]*ab[1]),\n magB = Math.sqrt(bc[0]*bc[0] + bc[1]*bc[1]),\n angle = Math.acos(dot/(magA*magB));\n return angle < thresholdAngle;\n }\n}\n\nfunction sqdist(a,b){\n var dx = b[0] - a[0];\n var dy = b[1] - a[1];\n return dx * dx + dy * dy;\n}\n\n/**\n * Get a vertex at position i. It does not matter if i is out of bounds, this function will just cycle.\n * @method at\n * @param {Number} i\n * @return {Array}\n */\nfunction polygonAt(polygon, i){\n var s = polygon.length;\n return polygon[i < 0 ? i % s + s : i % s];\n}\n\n/**\n * Clear the polygon data\n * @method clear\n * @return {Array}\n */\nfunction polygonClear(polygon){\n polygon.length = 0;\n}\n\n/**\n * Append points \"from\" to \"to\"-1 from an other polygon \"poly\" onto this one.\n * @method append\n * @param {Polygon} poly The polygon to get points from.\n * @param {Number} from The vertex index in \"poly\".\n * @param {Number} to The end vertex index in \"poly\". Note that this vertex is NOT included when appending.\n * @return {Array}\n */\nfunction polygonAppend(polygon, poly, from, to){\n for(var i=from; i<to; i++){\n polygon.push(poly[i]);\n }\n}\n\n/**\n * Make sure that the polygon vertices are ordered counter-clockwise.\n * @method makeCCW\n */\nfunction polygonMakeCCW(polygon){\n var br = 0,\n v = polygon;\n\n // find bottom right point\n for (var i = 1; i < polygon.length; ++i) {\n if (v[i][1] < v[br][1] || (v[i][1] === v[br][1] && v[i][0] > v[br][0])) {\n br = i;\n }\n }\n\n // reverse poly if clockwise\n if (!isLeft(polygonAt(polygon, br - 1), polygonAt(polygon, br), polygonAt(polygon, br + 1))) {\n polygonReverse(polygon);\n return true;\n } else {\n return false;\n }\n}\n\n/**\n * Reverse the vertices in the polygon\n * @method reverse\n */\nfunction polygonReverse(polygon){\n var tmp = [];\n var N = polygon.length;\n for(var i=0; i!==N; i++){\n tmp.push(polygon.pop());\n }\n for(var i=0; i!==N; i++){\n\t\tpolygon[i] = tmp[i];\n }\n}\n\n/**\n * Check if a point in the polygon is a reflex point\n * @method isReflex\n * @param {Number} i\n * @return {Boolean}\n */\nfunction polygonIsReflex(polygon, i){\n return isRight(polygonAt(polygon, i - 1), polygonAt(polygon, i), polygonAt(polygon, i + 1));\n}\n\nvar tmpLine1=[],\n tmpLine2=[];\n\n/**\n * Check if two vertices in the polygon can see each other\n * @method canSee\n * @param {Number} a Vertex index 1\n * @param {Number} b Vertex index 2\n * @return {Boolean}\n */\nfunction polygonCanSee(polygon, a,b) {\n var p, dist, l1=tmpLine1, l2=tmpLine2;\n\n if (isLeftOn(polygonAt(polygon, a + 1), polygonAt(polygon, a), polygonAt(polygon, b)) && isRightOn(polygonAt(polygon, a - 1), polygonAt(polygon, a), polygonAt(polygon, b))) {\n return false;\n }\n dist = sqdist(polygonAt(polygon, a), polygonAt(polygon, b));\n for (var i = 0; i !== polygon.length; ++i) { // for each edge\n if ((i + 1) % polygon.length === a || i === a){ // ignore incident edges\n continue;\n }\n if (isLeftOn(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i + 1)) && isRightOn(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i))) { // if diag intersects an edge\n l1[0] = polygonAt(polygon, a);\n l1[1] = polygonAt(polygon, b);\n l2[0] = polygonAt(polygon, i);\n l2[1] = polygonAt(polygon, i + 1);\n p = lineInt(l1,l2);\n if (sqdist(polygonAt(polygon, a), p) < dist) { // if edge is blocking visibility to b\n return false;\n }\n }\n }\n\n return true;\n}\n\n/**\n * Check if two vertices in the polygon can see each other\n * @method canSee2\n * @param {Number} a Vertex index 1\n * @param {Number} b Vertex index 2\n * @return {Boolean}\n */\nfunction polygonCanSee2(polygon, a,b) {\n // for each edge\n for (var i = 0; i !== polygon.length; ++i) {\n // ignore incident edges\n if (i === a || i === b || (i + 1) % polygon.length === a || (i + 1) % polygon.length === b){\n continue;\n }\n if( lineSegmentsIntersect(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i), polygonAt(polygon, i+1)) ){\n return false;\n }\n }\n return true;\n}\n\n/**\n * Copy the polygon from vertex i to vertex j.\n * @method copy\n * @param {Number} i\n * @param {Number} j\n * @param {Polygon} [targetPoly] Optional target polygon to save in.\n * @return {Polygon} The resulting copy.\n */\nfunction polygonCopy(polygon, i,j,targetPoly){\n var p = targetPoly || [];\n polygonClear(p);\n if (i < j) {\n // Insert all vertices from i to j\n for(var k=i; k<=j; k++){\n p.push(polygon[k]);\n }\n\n } else {\n\n // Insert vertices 0 to j\n for(var k=0; k<=j; k++){\n p.push(polygon[k]);\n }\n\n // Insert vertices i to end\n for(var k=i; k<polygon.length; k++){\n p.push(polygon[k]);\n }\n }\n\n return p;\n}\n\n/**\n * Decomposes the polygon into convex pieces. Returns a list of edges [[p1,p2],[p2,p3],...] that cuts the polygon.\n * Note that this algorithm has complexity O(N^4) and will be very slow for polygons with many vertices.\n * @method getCutEdges\n * @return {Array}\n */\nfunction polygonGetCutEdges(polygon) {\n var min=[], tmp1=[], tmp2=[], tmpPoly = [];\n var nDiags = Number.MAX_VALUE;\n\n for (var i = 0; i < polygon.length; ++i) {\n if (polygonIsReflex(polygon, i)) {\n for (var j = 0; j < polygon.length; ++j) {\n if (polygonCanSee(polygon, i, j)) {\n tmp1 = polygonGetCutEdges(polygonCopy(polygon, i, j, tmpPoly));\n tmp2 = polygonGetCutEdges(polygonCopy(polygon, j, i, tmpPoly));\n\n for(var k=0; k<tmp2.length; k++){\n tmp1.push(tmp2[k]);\n }\n\n if (tmp1.length < nDiags) {\n min = tmp1;\n nDiags = tmp1.length;\n min.push([polygonAt(polygon, i), polygonAt(polygon, j)]);\n }\n }\n }\n }\n }\n\n return min;\n}\n\n/**\n * Decomposes the polygon into one or more convex sub-Polygons.\n * @method decomp\n * @return {Array} An array or Polygon objects.\n */\nfunction polygonDecomp(polygon){\n var edges = polygonGetCutEdges(polygon);\n if(edges.length > 0){\n return polygonSlice(polygon, edges);\n } else {\n return [polygon];\n }\n}\n\n/**\n * Slices the polygon given one or more cut edges. If given one, this function will return two polygons (false on failure). If many, an array of polygons.\n * @method slice\n * @param {Array} cutEdges A list of edges, as returned by .getCutEdges()\n * @return {Array}\n */\nfunction polygonSlice(polygon, cutEdges){\n if(cutEdges.length === 0){\n\t\treturn [polygon];\n }\n if(cutEdges instanceof Array && cutEdges.length && cutEdges[0] instanceof Array && cutEdges[0].length===2 && cutEdges[0][0] instanceof Array){\n\n var polys = [polygon];\n\n for(var i=0; i<cutEdges.length; i++){\n var cutEdge = cutEdges[i];\n // Cut all polys\n for(var j=0; j<polys.length; j++){\n var poly = polys[j];\n var result = polygonSlice(poly, cutEdge);\n if(result){\n // Found poly! Cut and quit\n polys.splice(j,1);\n polys.push(result[0],result[1]);\n break;\n }\n }\n }\n\n return polys;\n } else {\n\n // Was given one edge\n var cutEdge = cutEdges;\n var i = polygon.indexOf(cutEdge[0]);\n var j = polygon.indexOf(cutEdge[1]);\n\n if(i !== -1 && j !== -1){\n return [polygonCopy(polygon, i,j),\n polygonCopy(polygon, j,i)];\n } else {\n return false;\n }\n }\n}\n\n/**\n * Checks that the line segments of this polygon do not intersect each other.\n * @method isSimple\n * @param {Array} path An array of vertices e.g. [[0,0],[0,1],...]\n * @return {Boolean}\n * @todo Should it check all segments with all others?\n */\nfunction polygonIsSimple(polygon){\n var path = polygon, i;\n // Check\n for(i=0; i<path.length-1; i++){\n for(var j=0; j<i-1; j++){\n if(lineSegmentsIntersect(path[i], path[i+1], path[j], path[j+1] )){\n return false;\n }\n }\n }\n\n // Check the segment between the last and the first point to all others\n for(i=1; i<path.length-2; i++){\n if(lineSegmentsIntersect(path[0], path[path.length-1], path[i], path[i+1] )){\n return false;\n }\n }\n\n return true;\n}\n\nfunction getIntersectionPoint(p1, p2, q1, q2, delta){\n\tdelta = delta || 0;\n\tvar a1 = p2[1] - p1[1];\n\tvar b1 = p1[0] - p2[0];\n\tvar c1 = (a1 * p1[0]) + (b1 * p1[1]);\n\tvar a2 = q2[1] - q1[1];\n\tvar b2 = q1[0] - q2[0];\n\tvar c2 = (a2 * q1[0]) + (b2 * q1[1]);\n\tvar det = (a1 * b2) - (a2 * b1);\n\n\tif(!scalar_eq(det,0,delta)){\n\t\treturn [((b2 * c1) - (b1 * c2)) / det, ((a1 * c2) - (a2 * c1)) / det];\n\t} else {\n\t\treturn [0,0];\n }\n}\n\n/**\n * Quickly decompose the Polygon into convex sub-polygons.\n * @method quickDecomp\n * @param {Array} result\n * @param {Array} [reflexVertices]\n * @param {Array} [steinerPoints]\n * @param {Number} [delta]\n * @param {Number} [maxlevel]\n * @param {Number} [level]\n * @return {Array}\n */\nfunction polygonQuickDecomp(polygon, result,reflexVertices,steinerPoints,delta,maxlevel,level){\n maxlevel = maxlevel || 100;\n level = level || 0;\n delta = delta || 25;\n result = typeof(result)!==\"undefined\" ? result : [];\n reflexVertices = reflexVertices || [];\n steinerPoints = steinerPoints || [];\n\n var upperInt=[0,0], lowerInt=[0,0], p=[0,0]; // Points\n var upperDist=0, lowerDist=0, d=0, closestDist=0; // scalars\n var upperIndex=0, lowerIndex=0, closestIndex=0; // Integers\n var lowerPoly=[], upperPoly=[]; // polygons\n var poly = polygon,\n v = polygon;\n\n if(v.length < 3){\n\t\treturn result;\n }\n\n level++;\n if(level > maxlevel){\n console.warn(\"quickDecomp: max level (\"+maxlevel+\") reached.\");\n return result;\n }\n\n for (var i = 0; i < polygon.length; ++i) {\n if (polygonIsReflex(poly, i)) {\n reflexVertices.push(poly[i]);\n upperDist = lowerDist = Number.MAX_VALUE;\n\n\n for (var j = 0; j < polygon.length; ++j) {\n if (isLeft(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j)) && isRightOn(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j - 1))) { // if line intersects with an edge\n p = getIntersectionPoint(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j), polygonAt(poly, j - 1)); // find the point of intersection\n if (isRight(polygonAt(poly, i + 1), polygonAt(poly, i), p)) { // make sure it's inside the poly\n d = sqdist(poly[i], p);\n if (d < lowerDist) { // keep only the closest intersection\n lowerDist = d;\n lowerInt = p;\n lowerIndex = j;\n }\n }\n }\n if (isLeft(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j + 1)) && isRightOn(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j))) {\n p = getIntersectionPoint(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j), polygonAt(poly, j + 1));\n if (isLeft(polygonAt(poly, i - 1), polygonAt(poly, i), p)) {\n d = sqdist(poly[i], p);\n if (d < upperDist) {\n upperDist = d;\n upperInt = p;\n upperIndex = j;\n }\n }\n }\n }\n\n // if there are no vertices to connect to, choose a point in the middle\n if (lowerIndex === (upperIndex + 1) % polygon.length) {\n //console.log(\"Case 1: Vertex(\"+i+\"), lowerIndex(\"+lowerIndex+\"), upperIndex(\"+upperIndex+\"), poly.size(\"+polygon.length+\")\");\n p[0] = (lowerInt[0] + upperInt[0]) / 2;\n p[1] = (lowerInt[1] + upperInt[1]) / 2;\n steinerPoints.push(p);\n\n if (i < upperIndex) {\n //lowerPoly.insert(lowerPoly.end(), poly.begin() + i, poly.begin() + upperIndex + 1);\n polygonAppend(lowerPoly, poly, i, upperIndex+1);\n lowerPoly.push(p);\n upperPoly.push(p);\n if (lowerIndex !== 0){\n //upperPoly.insert(upperPoly.end(), poly.begin() + lowerIndex, poly.end());\n polygonAppend(upperPoly, poly,lowerIndex,poly.length);\n }\n //upperPoly.insert(upperPoly.end(), poly.begin(), poly.begin() + i + 1);\n polygonAppend(upperPoly, poly,0,i+1);\n } else {\n if (i !== 0){\n //lowerPoly.insert(lowerPoly.end(), poly.begin() + i, poly.end());\n polygonAppend(lowerPoly, poly,i,poly.length);\n }\n //lowerPoly.insert(lowerPoly.end(), poly.begin(), poly.begin() + upperIndex + 1);\n polygonAppend(lowerPoly, poly,0,upperIndex+1);\n lowerPoly.push(p);\n upperPoly.push(p);\n //upperPoly.insert(upperPoly.end(), poly.begin() + lowerIndex, poly.begin() + i + 1);\n polygonAppend(upperPoly, poly,lowerIndex,i+1);\n }\n } else {\n // connect to the closest point within the triangle\n //console.log(\"Case 2: Vertex(\"+i+\"), closestIndex(\"+closestIndex+\"), poly.size(\"+polygon.length+\")\\n\");\n\n if (lowerIndex > upperIndex) {\n upperIndex += polygon.length;\n }\n closestDist = Number.MAX_VALUE;\n\n if(upperIndex < lowerIndex){\n return result;\n }\n\n for (var j = lowerIndex; j <= upperIndex; ++j) {\n if (\n isLeftOn(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j)) &&\n isRightOn(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j))\n ) {\n d = sqdist(polygonAt(poly, i), polygonAt(poly, j));\n if (d < closestDist && polygonCanSee2(poly, i, j)) {\n closestDist = d;\n closestIndex = j % polygon.length;\n }\n }\n }\n\n if (i < closestIndex) {\n polygonAppend(lowerPoly, poly,i,closestIndex+1);\n if (closestIndex !== 0){\n polygonAppend(upperPoly, poly,closestIndex,v.length);\n }\n polygonAppend(upperPoly, poly,0,i+1);\n } else {\n if (i !== 0){\n polygonAppend(lowerPoly, poly,i,v.length);\n }\n polygonAppend(lowerPoly, poly,0,closestIndex+1);\n polygonAppend(upperPoly, poly,closestIndex,i+1);\n }\n }\n\n // solve smallest poly first\n if (lowerPoly.length < upperPoly.length) {\n polygonQuickDecomp(lowerPoly,result,reflexVertices,steinerPoints,delta,maxlevel,level);\n polygonQuickDecomp(upperPoly,result,reflexVertices,steinerPoints,delta,maxlevel,level);\n } else {\n polygonQuickDecomp(upperPoly,result,reflexVertices,steinerPoints,delta,maxlevel,level);\n polygonQuickDecomp(lowerPoly,result,reflexVertices,steinerPoints,delta,maxlevel,level);\n }\n\n return result;\n }\n }\n result.push(polygon);\n\n return result;\n}\n\n/**\n * Remove collinear points in the polygon.\n * @method removeCollinearPoints\n * @param {Number} [precision] The threshold angle to use when determining whether two edges are collinear. Use zero for finest precision.\n * @return {Number} The number of points removed\n */\nfunction polygonRemoveCollinearPoints(polygon, precision){\n var num = 0;\n for(var i=polygon.length-1; polygon.length>3 && i>=0; --i){\n if(collinear(polygonAt(polygon, i-1),polygonAt(polygon, i),polygonAt(polygon, i+1),precision)){\n // Remove the middle point\n polygon.splice(i%polygon.length,1);\n num++;\n }\n }\n return num;\n}\n\n/**\n * Remove duplicate points in the polygon.\n * @method removeDuplicatePoints\n * @param {Number} [precision] The threshold to use when determining whether two points are the same. Use zero for best precision.\n */\nfunction polygonRemoveDuplicatePoints(polygon, precision){\n for(var i=polygon.length-1; i>=1; --i){\n var pi = polygon[i];\n for(var j=i-1; j>=0; --j){\n if(points_eq(pi, polygon[j], precision)){\n polygon.splice(i,1);\n continue;\n }\n }\n }\n}\n\n/**\n * Check if two scalars are equal\n * @static\n * @method eq\n * @param {Number} a\n * @param {Number} b\n * @param {Number} [precision]\n * @return {Boolean}\n */\nfunction scalar_eq(a,b,precision){\n precision = precision || 0;\n return Math.abs(a-b) <= precision;\n}\n\n/**\n * Check if two points are equal\n * @static\n * @method points_eq\n * @param {Array} a\n * @param {Array} b\n * @param {Number} [precision]\n * @return {Boolean}\n */\nfunction points_eq(a,b,precision){\n return scalar_eq(a[0],b[0],precision) && scalar_eq(a[1],b[1],precision);\n}\n", "import * as Matter from \"matter-js\";\n// @ts-expect-error \u2014 poly-decomp has no published types; only used to\n// register a global decomposer with matter-js below.\nimport * as decomp from \"poly-decomp\";\n\n// Matter.js calls `decomp` internally via `Common.setDecomp(...)` to\n// break concave polygons (common in Tiled collision groups) into convex\n// pieces. Registering it once up-front saves users from having to wire\n// the global themselves.\nMatter.Common.setDecomp(decomp);\n\nimport {\n\ttype AdapterCapabilities,\n\ttype BodyDefinition,\n\ttype BodyShape,\n\ttype Bounds,\n\tEllipse,\n\tversion as melonjsVersion,\n\ttype PhysicsAdapter,\n\ttype PhysicsBody,\n\tPolygon,\n\ttype RaycastHit,\n\tRect,\n\ttype Renderable,\n\tstate,\n\tutils,\n\tVector2d,\n\ttype World,\n} from \"melonjs\";\n\ndeclare const __VERSION__: string;\n\n/**\n * Minimum melonJS version this adapter requires. The PhysicsAdapter\n * interface, `bodyDef` auto-registration, and the resolver in\n * `Application` are part of the 19.5 work \u2014 older releases don't have\n * the plumbing for instance-based adapters. Tracks the engine version\n * actually shipping these APIs (will be bumped to \"19.5.0\" once the\n * engine release is cut).\n */\nexport const REQUIRED_MELONJS_VERSION = \"19.5.0\";\n\n/**\n * Options accepted by the {@link MatterAdapter} constructor.\n */\nexport interface MatterAdapterOptions {\n\t/** initial world gravity, default `{x: 0, y: 1}` (matter-js convention) */\n\tgravity?: { x: number; y: number };\n\t/**\n\t * Number of physics substeps per engine frame. Each call to\n\t * {@link MatterAdapter.step} runs `Engine.update(engine, dt / N)`\n\t * `N` times instead of one full-dt step. Increases narrow-phase\n\t * accuracy at high relative velocities (break shots, projectiles)\n\t * at the cost of ~N\u00D7 physics CPU. Default `1` matches the legacy\n\t * single-step behaviour. Values < 1 are clamped to 1.\n\t */\n\tsubSteps?: number;\n\t/**\n\t * raw matter-js engine options forwarded to `Matter.Engine.create()`.\n\t * Use this to tweak solver iterations, constraint accuracy, etc.\n\t */\n\tmatterEngineOptions?: Matter.IEngineDefinition;\n}\n\n/**\n * melonJS physics adapter wrapping matter-js (https://brm.io/matter-js/).\n *\n * Implements the full {@link PhysicsAdapter} interface so the same game\n * code that runs on the built-in SAT physics also runs under Matter \u2014\n * with the upgrade in capabilities Matter brings (real rotational\n * dynamics, restitution-based stacking, constraints, sleeping bodies,\n * native raycasts).\n * @example\n * import { Application } from \"melonjs\";\n * import { MatterAdapter } from \"@melonjs/matter-adapter\";\n *\n * const app = new Application(800, 600, {\n * parent: \"screen\",\n * physic: new MatterAdapter(),\n * });\n */\nexport class MatterAdapter implements PhysicsAdapter {\n\treadonly physicLabel = \"matter\";\n\treadonly name = \"@melonjs/matter-adapter\";\n\treadonly version = __VERSION__;\n\treadonly url = \"https://www.npmjs.com/package/@melonjs/matter-adapter\";\n\n\treadonly capabilities: AdapterCapabilities = {\n\t\tconstraints: true,\n\t\tcontinuousCollisionDetection: true,\n\t\tsleepingBodies: true,\n\t\traycasts: true,\n\t\tvelocityLimit: true,\n\t\tisGrounded: true,\n\t};\n\n\tgravity: Vector2d;\n\n\t/**\n\t * Raw matter-js namespace \u2014 escape hatch for matter-specific features\n\t * the portable `PhysicsAdapter` interface doesn't cover (constraints,\n\t * compound bodies, events on the Matter engine, queries, etc.).\n\t *\n\t * Saves you from adding a transitive `import * as Matter from \"matter-js\"`\n\t * just to reach the factories you need. The Matter modules are accessed\n\t * by the same names matter's own docs use, so examples from the\n\t * matter-js docs copy-paste without renaming:\n\t *\n\t * ```ts\n\t * const spring = adapter.matter.Constraint.create({\n\t * bodyA: a.body, bodyB: b.body, stiffness: 0.04, length: 80,\n\t * });\n\t * adapter.matter.Composite.add(adapter.engine.world, spring);\n\t * ```\n\t *\n\t * Game code that touches `adapter.matter.*` is matter-only \u2014 it will\n\t * not work under any other physics adapter. Use the\n\t * `PhysicsAdapter` methods for anything that should stay portable.\n\t * @see {@link https://brm.io/matter-js/docs/ Official matter-js documentation}\n\t * for the full module reference (`Matter.Constraint`, `Matter.Composite`,\n\t * `Matter.Bodies`, `Matter.Events`, `Matter.Query`, `Matter.Vector`, \u2026).\n\t */\n\treadonly matter: typeof Matter = Matter;\n\n\t/** the underlying Matter engine; exposed for advanced use cases. */\n\tengine!: Matter.Engine;\n\n\t/** back-reference to the owning melonJS world (set in {@link init}). */\n\tworld!: World;\n\n\t/** renderable \u2192 its matter-js body */\n\tprivate readonly bodyMap = new Map<Renderable, Matter.Body>();\n\t/** matter-js body \u2192 its renderable (for collision / sync) */\n\tprivate readonly renderableMap = new Map<Matter.Body, Renderable>();\n\t/** per-body velocity cap (Matter has no native equivalent) */\n\tprivate readonly velocityLimits = new Map<\n\t\tRenderable,\n\t\t{ x: number; y: number }\n\t>();\n\t/** per-body bodyDef hash kept for shape introspection / removeBody */\n\tprivate readonly defMap = new Map<Renderable, BodyDefinition>();\n\t/**\n\t * Per-body gravity multiplier. matter-js 0.20 doesn't honor a\n\t * body-level gravityScale, so we emulate it by applying a counter-\n\t * force each step (see {@link init} `beforeUpdate`). Only stored for\n\t * bodies with scale \u2260 1; the default-1 case is the hot path and we\n\t * skip the map lookup entirely for it.\n\t */\n\tprivate readonly bodyGravityScale = new Map<Matter.Body, number>();\n\t/**\n\t * Offset between `renderable.pos` (top-left in melonJS convention)\n\t * and `Matter.Body.position` (centroid in Matter's convention). Stored\n\t * at addBody time so syncFromPhysics can place the sprite correctly.\n\t */\n\tprivate readonly posOffsets = new Map<Renderable, { x: number; y: number }>();\n\n\tprivate readonly matterOptions: Matter.IEngineDefinition | undefined;\n\n\tprivate readonly subSteps: number;\n\n\tconstructor(options: MatterAdapterOptions = {}) {\n\t\t// Mirror the BasePlugin version-check pattern: refuse to construct\n\t\t// against a melonJS that's too old to support the PhysicsAdapter\n\t\t// surface this adapter expects. Throwing here is loud and early \u2014\n\t\t// the error names the required version so users know what to upgrade.\n\t\tif (utils.checkVersion(REQUIRED_MELONJS_VERSION, melonjsVersion) > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`@melonjs/matter-adapter requires melonJS >= ${REQUIRED_MELONJS_VERSION}, ` +\n\t\t\t\t\t`but the loaded melonJS is ${melonjsVersion}.`,\n\t\t\t);\n\t\t}\n\t\tthis.matterOptions = options.matterEngineOptions;\n\t\tthis.subSteps = Math.max(1, Math.floor(options.subSteps ?? 1));\n\t\t// Default to matter-js native gravity: `(0, 1)` with the internal\n\t\t// `gravity.scale = 0.001`. This is intentionally NOT tuned to\n\t\t// match BuiltinAdapter's per-frame integration feel \u2014 the whole\n\t\t// point of running on Matter is to get Matter's real-physics\n\t\t// feel. Game code that wants legacy-style \"fast arcade gravity\"\n\t\t// should bump these values explicitly via the constructor option.\n\t\tconst g = options.gravity ?? { x: 0, y: 1 };\n\t\tthis.gravity = new Vector2d(g.x, g.y);\n\t}\n\n\t/**\n\t * Stored references to the listeners registered in {@link init}, so\n\t * {@link destroy} can `Matter.Events.off` them. Without these stored\n\t * refs, a destroy/re-init cycle would leak the old listeners and\n\t * dispatch every event twice on the second cycle.\n\t */\n\tprivate _matterListeners: Array<{\n\t\tname: string;\n\t\tfn: (e: unknown) => void;\n\t}> = [];\n\n\tinit(world: World): void {\n\t\tthis.world = world;\n\t\tthis.engine = Matter.Engine.create(this.matterOptions);\n\t\t// reflect our gravity vector onto the Matter engine\n\t\tthis.engine.gravity.x = this.gravity.x;\n\t\tthis.engine.gravity.y = this.gravity.y;\n\t\t// matter-js's internal `gravity.scale` defaults to 0.001 \u2014 left\n\t\t// untouched so this adapter behaves like a vanilla matter-js\n\t\t// engine. Game code that wants stronger gravity should pass a\n\t\t// larger `options.gravity` value, or mutate `adapter.gravity`\n\t\t// after construction.\n\t\tconst on = (name: string, fn: (e: unknown) => void) => {\n\t\t\tMatter.Events.on(\n\t\t\t\tthis.engine,\n\t\t\t\tname,\n\t\t\t\tfn as Parameters<typeof Matter.Events.on>[2],\n\t\t\t);\n\t\t\tthis._matterListeners.push({ name, fn });\n\t\t};\n\t\t// Emulate per-body gravityScale: matter-js 0.20 only honors the\n\t\t// engine-level `gravity.scale`, so we add a counter-force to each\n\t\t// non-default-scale body before integration. Net effect after\n\t\t// matter's own gravity step = mass * gravity * scale * gravityScale.\n\t\ton(\"beforeUpdate\", () => {\n\t\t\tif (this.bodyGravityScale.size === 0) return;\n\t\t\tconst gx = this.engine.gravity.x;\n\t\t\tconst gy = this.engine.gravity.y;\n\t\t\tconst gs = (this.engine.gravity as { scale?: number }).scale ?? 0.001;\n\t\t\tfor (const [body, scale] of this.bodyGravityScale) {\n\t\t\t\tif (body.isStatic || body.isSleeping) continue;\n\t\t\t\tconst k = (scale - 1) * body.mass * gs;\n\t\t\t\tbody.force.x += k * gx;\n\t\t\t\tbody.force.y += k * gy;\n\t\t\t}\n\t\t});\n\t\t// after each step, clamp velocities to maxVelocity (Matter has no\n\t\t// native cap) and copy positions back to the renderables\n\t\ton(\"afterUpdate\", () => {\n\t\t\tthis._clampVelocities();\n\t\t\tthis.syncFromPhysics();\n\t\t});\n\t\t// Route matter's three collision events to the renderable hooks.\n\t\t// `onCollision` is the legacy alias \u2014 same firing as `onCollisionStart`\n\t\t// (one-shot when contact begins). For frame-by-frame \"still in contact\"\n\t\t// semantics use `onCollisionActive`; for \"contact just broke\" use\n\t\t// `onCollisionEnd`.\n\t\ton(\"collisionStart\", (e) => {\n\t\t\tthis._dispatchCollisions((e as { pairs: Matter.Pair[] }).pairs, \"start\");\n\t\t});\n\t\ton(\"collisionActive\", (e) => {\n\t\t\tthis._dispatchCollisions((e as { pairs: Matter.Pair[] }).pairs, \"active\");\n\t\t});\n\t\ton(\"collisionEnd\", (e) => {\n\t\t\tthis._dispatchCollisions((e as { pairs: Matter.Pair[] }).pairs, \"end\");\n\t\t});\n\t}\n\n\tdestroy(): void {\n\t\t// Unregister listeners first so any matter events fired during the\n\t\t// teardown don't re-enter our dispatchers with already-cleared state.\n\t\tfor (const { name, fn } of this._matterListeners) {\n\t\t\tMatter.Events.off(\n\t\t\t\tthis.engine,\n\t\t\t\tname,\n\t\t\t\tfn as Parameters<typeof Matter.Events.off>[2],\n\t\t\t);\n\t\t}\n\t\tthis._matterListeners = [];\n\t\tMatter.Composite.clear(this.engine.world, false, true);\n\t\tMatter.Engine.clear(this.engine);\n\t\tthis.bodyMap.clear();\n\t\tthis.renderableMap.clear();\n\t\tthis.velocityLimits.clear();\n\t\tthis.defMap.clear();\n\t\tthis.bodyGravityScale.clear();\n\t\tthis.posOffsets.clear();\n\t}\n\n\tstep(dt: number): void {\n\t\t// Mirror BuiltinAdapter's pause behavior: when the engine is\n\t\t// paused (browser loses focus, state.pause(), etc.) skip the\n\t\t// physics step entirely. Matter has no per-body pause control,\n\t\t// so we pause the whole simulation rather than individual bodies\n\t\t// \u2014 bodies with `updateWhenPaused = true` are not preserved here,\n\t\t// which is a documented difference from BuiltinAdapter.\n\t\tif (state.isPaused()) {\n\t\t\treturn;\n\t\t}\n\t\t// mirror gravity (user may have mutated this.gravity since init)\n\t\tthis.engine.gravity.x = this.gravity.x;\n\t\tthis.engine.gravity.y = this.gravity.y;\n\t\t// matter-js takes delta in ms \u2014 exactly what World.update passes.\n\t\t// Substepping: run N engine ticks of `dt/N` instead of one of `dt`.\n\t\t// The narrow phase is discrete (no swept tests), so a body moving\n\t\t// faster than ~1 radius per tick can tunnel through another body\n\t\t// or a thin wall. Smaller per-tick deltas keep the inter-body\n\t\t// motion under that threshold; default `subSteps=1` reproduces\n\t\t// the previous single-step behaviour exactly.\n\t\tif (this.subSteps === 1) {\n\t\t\tMatter.Engine.update(this.engine, dt);\n\t\t} else {\n\t\t\tconst sub = dt / this.subSteps;\n\t\t\tfor (let i = 0; i < this.subSteps; i++) {\n\t\t\t\tMatter.Engine.update(this.engine, sub);\n\t\t\t}\n\t\t}\n\t}\n\n\tsyncFromPhysics(): void {\n\t\tfor (const [body, renderable] of this.renderableMap) {\n\t\t\t// Renderables can be destroyed mid-step (level reset, pool\n\t\t\t// recycle, removeChild) \u2014 their pooled `pos` vector gets\n\t\t\t// released and becomes undefined, but the body may still be\n\t\t\t// in matter's engine for one more frame. Skip those instead\n\t\t\t// of crashing; the body will be unregistered shortly.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- runtime guard: pos is typed non-null but the pool releases it on recycle\n\t\t\tif (!renderable.pos) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// melonJS renderable.pos is top-left (anchor 0,0 default);\n\t\t\t// Matter body.position is the centroid. Apply the stored\n\t\t\t// offset to translate back into renderable space.\n\t\t\tconst off = this.posOffsets.get(renderable);\n\t\t\tif (off) {\n\t\t\t\trenderable.pos.x = body.position.x + off.x;\n\t\t\t\trenderable.pos.y = body.position.y + off.y;\n\t\t\t} else {\n\t\t\t\trenderable.pos.x = body.position.x;\n\t\t\t\trenderable.pos.y = body.position.y;\n\t\t\t}\n\t\t\t// Mirror body angle onto the renderable's transform. melonJS\n\t\t\t// renderables expose `currentTransform` as a Matrix3d.\n\t\t\t// `Renderable.preDraw` applies the transform with the pivot at\n\t\t\t// `renderable.pos`, but matter rotates the body around its\n\t\t\t// centroid. For renderables whose `pos` is the top-left\n\t\t\t// (anchor 0,0) with a body shape centered inside the bounds,\n\t\t\t// the two pivots differ by `-posOffset` \u2014 rotating around\n\t\t\t// `pos` would spin the sprite around its corner. Pre-translate\n\t\t\t// by the centroid-relative offset so the rotation lands on\n\t\t\t// the visible center regardless of anchor.\n\t\t\tconst t = renderable.currentTransform;\n\t\t\tconst off2 = this.posOffsets.get(renderable);\n\t\t\tconst cx = off2 ? -off2.x : 0;\n\t\t\tconst cy = off2 ? -off2.y : 0;\n\t\t\tt.identity();\n\t\t\tif (cx !== 0 || cy !== 0) {\n\t\t\t\tt.translate(cx, cy);\n\t\t\t\tt.rotate(body.angle);\n\t\t\t\tt.translate(-cx, -cy);\n\t\t\t} else {\n\t\t\t\tt.rotate(body.angle);\n\t\t\t}\n\t\t}\n\t}\n\n\taddBody(renderable: Renderable, def: BodyDefinition): MatterAdapter.Body {\n\t\t// translate shapes into matter bodies. Multi-shape defs become a\n\t\t// matter compound body (Matter.Body.create with parts).\n\t\tconst baseX = renderable.pos.x;\n\t\tconst baseY = renderable.pos.y;\n\t\tconst parts = def.shapes.map((s) => this._shapeToMatter(s, baseX, baseY));\n\t\tlet body: Matter.Body;\n\t\tif (parts.length === 1) {\n\t\t\tbody = parts[0];\n\t\t} else {\n\t\t\tbody = Matter.Body.create({ parts });\n\t\t}\n\n\t\t// apply portable BodyDefinition fields onto the matter body\n\t\tif (def.type === \"static\") {\n\t\t\tMatter.Body.setStatic(body, true);\n\t\t}\n\t\tif (typeof def.density === \"number\") {\n\t\t\tMatter.Body.setDensity(body, def.density);\n\t\t}\n\t\tif (def.frictionAir !== undefined) {\n\t\t\t// Matter only supports scalar frictionAir; melonJS defs can be\n\t\t\t// {x, y} \u2014 average the two so the simulation feels close even\n\t\t\t// when the user passes per-axis values (rare).\n\t\t\tbody.frictionAir =\n\t\t\t\ttypeof def.frictionAir === \"number\"\n\t\t\t\t\t? def.frictionAir\n\t\t\t\t\t: (def.frictionAir.x + def.frictionAir.y) / 2;\n\t\t}\n\t\tif (typeof def.restitution === \"number\") {\n\t\t\tbody.restitution = def.restitution;\n\t\t}\n\t\tif (typeof def.friction === \"number\") {\n\t\t\tbody.friction = def.friction;\n\t\t}\n\t\tif (typeof def.gravityScale === \"number\" && def.gravityScale !== 1) {\n\t\t\t// matter-js 0.20 has no per-body gravityScale \u2014 store it and\n\t\t\t// apply a counter-force each step in the beforeUpdate handler.\n\t\t\tthis.bodyGravityScale.set(body, def.gravityScale);\n\t\t}\n\t\tif (def.maxVelocity) {\n\t\t\tthis.velocityLimits.set(renderable, {\n\t\t\t\tx: def.maxVelocity.x,\n\t\t\t\ty: def.maxVelocity.y,\n\t\t\t});\n\t\t}\n\t\t// Install live getter/setter aliases so the matter-native form\n\t\t// (`body.collisionFilter.category` / `body.collisionFilter.mask`)\n\t\t// and the legacy melonJS form (`body.collisionType` /\n\t\t// `body.collisionMask`) read and write the same underlying state.\n\t\t// Either API works; matter users don't have to learn melonJS's\n\t\t// names, and legacy melonJS handlers don't have to know about\n\t\t// collisionFilter.\n\t\tObject.defineProperties(body, {\n\t\t\tcollisionType: {\n\t\t\t\tget(this: Matter.Body) {\n\t\t\t\t\treturn this.collisionFilter.category;\n\t\t\t\t},\n\t\t\t\tset(this: Matter.Body, v: number) {\n\t\t\t\t\tthis.collisionFilter.category = v;\n\t\t\t\t},\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: true,\n\t\t\t},\n\t\t\tcollisionMask: {\n\t\t\t\tget(this: Matter.Body) {\n\t\t\t\t\treturn this.collisionFilter.mask;\n\t\t\t\t},\n\t\t\t\tset(this: Matter.Body, v: number) {\n\t\t\t\t\tthis.collisionFilter.mask = v;\n\t\t\t\t},\n\t\t\t\tconfigurable: true,\n\t\t\t\tenumerable: true,\n\t\t\t},\n\t\t});\n\t\tif (typeof def.collisionType === \"number\") {\n\t\t\tbody.collisionFilter.category = def.collisionType;\n\t\t}\n\t\tif (typeof def.collisionMask === \"number\") {\n\t\t\tbody.collisionFilter.mask = def.collisionMask;\n\t\t}\n\t\tif (def.isSensor) {\n\t\t\tbody.isSensor = true;\n\t\t}\n\t\t// Default to fixed rotation. Matter has full rotational dynamics\n\t\t// while SAT didn't; existing platformer-style game code assumes\n\t\t// bodies stay axis-aligned. Users that genuinely want rotation\n\t\t// (a rolling barrel, a rag-doll, etc.) opt out via\n\t\t// `fixedRotation: false`.\n\t\tif (def.fixedRotation !== false) {\n\t\t\tMatter.Body.setInertia(body, Number.POSITIVE_INFINITY);\n\t\t}\n\n\t\tMatter.Composite.add(this.engine.world, body);\n\t\tthis.bodyMap.set(renderable, body);\n\t\tthis.renderableMap.set(body, renderable);\n\t\tthis.defMap.set(renderable, def);\n\t\t// Track the offset between renderable.pos (top-left) and the\n\t\t// matter body's centroid so syncFromPhysics places the sprite\n\t\t// correctly.\n\t\tthis.posOffsets.set(renderable, {\n\t\t\tx: baseX - body.position.x,\n\t\t\ty: baseY - body.position.y,\n\t\t});\n\t\t// Debug-plugin compatibility is provided via the adapter-side\n\t\t// `getBodyAABB` / `getBodyShapes` methods (see below). No\n\t\t// foreign methods are attached to the matter Body itself \u2014 it\n\t\t// stays a pure `Matter.Body`, with adapter-owned coordinate-\n\t\t// system translation living on the adapter where it belongs.\n\t\t// melonJS Body convention: attach legacy-shaped helper methods so\n\t\t// `renderable.body.setVelocity(x, y)` / `applyForce(x, y)` etc.\n\t\t// work identically under either adapter. The body is still a real\n\t\t// `Matter.Body` \u2014 these are additive convenience methods that\n\t\t// delegate to matter's free functions. Users who want raw matter\n\t\t// access can keep calling `Matter.Body.setVelocity(body, v)`.\n\t\t//\n\t\t// `helpers` is typed as the portable {@link PhysicsBody} interface\n\t\t// (minus the `collisionType`/`collisionMask` data fields, which\n\t\t// are installed as live getter/setter aliases on the body itself\n\t\t// just below). If a method is added to or removed from PhysicsBody\n\t\t// in melonJS, this object fails to type-check until updated \u2014\n\t\t// keeps the matter helpers in lockstep with the portable contract.\n\t\tconst helpers: Omit<PhysicsBody, \"collisionType\" | \"collisionMask\"> = {\n\t\t\tsetVelocity(x: number, y: number) {\n\t\t\t\tMatter.Body.setVelocity(body, { x, y });\n\t\t\t},\n\t\t\tgetVelocity(out?: Vector2d): Vector2d {\n\t\t\t\treturn (out ?? new Vector2d()).set(body.velocity.x, body.velocity.y);\n\t\t\t},\n\t\t\tapplyForce(x: number, y: number, pointX?: number, pointY?: number) {\n\t\t\t\t// Matter's `applyForce` is inherently lever-arm-aware: a\n\t\t\t\t// force applied at a point != centroid generates a torque\n\t\t\t\t// automatically as part of matter's integration. Pass the\n\t\t\t\t// point through when provided, otherwise default to the\n\t\t\t\t// body's centroid (pure linear, matching the 2-arg call).\n\t\t\t\tconst point =\n\t\t\t\t\ttypeof pointX === \"number\" && typeof pointY === \"number\"\n\t\t\t\t\t\t? { x: pointX, y: pointY }\n\t\t\t\t\t\t: body.position;\n\t\t\t\tMatter.Body.applyForce(body, point, { x, y });\n\t\t\t},\n\t\t\tapplyImpulse(x: number, y: number) {\n\t\t\t\t// matter has no applyImpulse \u2014 convert via dv = J / m\n\t\t\t\tconst invMass = body.mass > 0 ? 1 / body.mass : 0;\n\t\t\t\tMatter.Body.setVelocity(body, {\n\t\t\t\t\tx: body.velocity.x + x * invMass,\n\t\t\t\t\ty: body.velocity.y + y * invMass,\n\t\t\t\t});\n\t\t\t},\n\t\t\tsetSensor(isSensor = true) {\n\t\t\t\tbody.isSensor = isSensor;\n\t\t\t},\n\t\t\tsetStatic(isStatic = true) {\n\t\t\t\tMatter.Body.setStatic(body, isStatic);\n\t\t\t},\n\t\t\tsetCollisionMask(mask: number) {\n\t\t\t\t// `body.collisionMask` is a live alias of\n\t\t\t\t// `body.collisionFilter.mask` (see the property descriptor\n\t\t\t\t// installed below), so writing either form propagates.\n\t\t\t\tbody.collisionFilter.mask = mask;\n\t\t\t},\n\t\t\tsetCollisionType(type: number) {\n\t\t\t\tbody.collisionFilter.category = type;\n\t\t\t},\n\t\t\tsetMass: (m: number) => {\n\t\t\t\tMatter.Body.setMass(body, m);\n\t\t\t},\n\t\t\tsetBounce(r: number) {\n\t\t\t\t// matter's body property is `restitution`; expose `setBounce`\n\t\t\t\t// to match the legacy melonJS API while writing the\n\t\t\t\t// matter-native field.\n\t\t\t\tbody.restitution = r;\n\t\t\t},\n\t\t\tsetGravityScale: (scale: number) => {\n\t\t\t\t// matter-js 0.20 has no native per-body gravity scale \u2014\n\t\t\t\t// the adapter emulates it via `bodyGravityScale` map +\n\t\t\t\t// per-frame counter-force. Update the map directly here.\n\t\t\t\tif (scale === 1) {\n\t\t\t\t\tthis.bodyGravityScale.delete(body);\n\t\t\t\t} else {\n\t\t\t\t\tthis.bodyGravityScale.set(body, scale);\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetAngularVelocity(omega: number) {\n\t\t\t\tMatter.Body.setAngularVelocity(body, omega);\n\t\t\t},\n\t\t\tgetAngularVelocity(): number {\n\t\t\t\treturn body.angularVelocity;\n\t\t\t},\n\t\t\tsetAngle(rad: number) {\n\t\t\t\tMatter.Body.setAngle(body, rad);\n\t\t\t},\n\t\t\tgetAngle(): number {\n\t\t\t\treturn body.angle;\n\t\t\t},\n\t\t\tapplyTorque(t: number) {\n\t\t\t\t// matter-js accumulates `body.torque` for the next step;\n\t\t\t\t// adding to it is the documented way to apply an angular\n\t\t\t\t// impulse without going through the force/lever-arm path.\n\t\t\t\tbody.torque += t;\n\t\t\t},\n\t\t};\n\t\tObject.assign(body, helpers);\n\t\t// After Object.assign the runtime body satisfies both the\n\t\t// matter-js `Body` interface AND the portable `PhysicsBody`\n\t\t// (plus the live `collisionType` / `collisionMask` aliases\n\t\t// installed via Object.defineProperties above). TypeScript can't\n\t\t// see the spliced helpers, so cast explicitly \u2014 this is the one\n\t\t// spot where the adapter promises the body conforms to its\n\t\t// published `MatterAdapter.Body` type.\n\t\tconst adapterBody = body as MatterAdapter.Body;\n\t\t// Convention: `renderable.body` is the adapter's body handle.\n\t\t// Stored as the portable `PhysicsBody` on the Renderable; matter-\n\t\t// specific code casts to `MatterAdapter.Body` to reach native\n\t\t// fields (frictionAir, angle, \u2026).\n\t\trenderable.body = adapterBody;\n\t\treturn adapterBody;\n\t}\n\n\tremoveBody(renderable: Renderable): void {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tif (body) {\n\t\t\tMatter.Composite.remove(this.engine.world, body);\n\t\t\tthis.bodyMap.delete(renderable);\n\t\t\tthis.renderableMap.delete(body);\n\t\t\tthis.velocityLimits.delete(renderable);\n\t\t\tthis.defMap.delete(renderable);\n\t\t\tthis.posOffsets.delete(renderable);\n\t\t\tthis.bodyGravityScale.delete(body);\n\t\t}\n\t}\n\n\tupdateShape(renderable: Renderable, shapes: BodyShape[]): void {\n\t\t// matter-js doesn't support live shape mutation cleanly \u2014 the\n\t\t// pragmatic approach is to rebuild the body. Preserve the prior\n\t\t// def, swap shapes, re-register \u2014 AND carry forward the velocity\n\t\t// state (linear + angular) so a moving body whose shape changes\n\t\t// mid-flight doesn't stop dead.\n\t\tconst oldDef = this.defMap.get(renderable);\n\t\tif (!oldDef) {\n\t\t\treturn;\n\t\t}\n\t\tconst oldBody = this.bodyMap.get(renderable);\n\t\tconst savedVel = oldBody\n\t\t\t? { x: oldBody.velocity.x, y: oldBody.velocity.y }\n\t\t\t: undefined;\n\t\tconst savedAngVel = oldBody?.angularVelocity ?? 0;\n\t\tthis.removeBody(renderable);\n\t\tconst newBody = this.addBody(renderable, { ...oldDef, shapes });\n\t\tif (savedVel) {\n\t\t\tMatter.Body.setVelocity(newBody, savedVel);\n\t\t\tMatter.Body.setAngularVelocity(newBody, savedAngVel);\n\t\t}\n\t}\n\n\tgetVelocity(renderable: Renderable, out?: Vector2d): Vector2d {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tconst target = out ?? new Vector2d();\n\t\tif (body) {\n\t\t\treturn target.set(body.velocity.x, body.velocity.y);\n\t\t}\n\t\treturn target.set(0, 0);\n\t}\n\n\tsetVelocity(renderable: Renderable, v: Vector2d): void {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tif (body) {\n\t\t\tMatter.Body.setVelocity(body, { x: v.x, y: v.y });\n\t\t}\n\t}\n\n\tapplyForce(renderable: Renderable, force: Vector2d, point?: Vector2d): void {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tif (!body) return;\n\t\t// True Newtonian force application \u2014 Matter integrates this as\n\t\t// `force / mass * dt\u00B2` per step. Game code that wants the legacy\n\t\t// \"set velocity to this value each frame\" pattern (what\n\t\t// BuiltinAdapter's force-accumulator gave you under the hood)\n\t\t// should use `setVelocity` instead.\n\t\tMatter.Body.applyForce(body, point ?? body.position, {\n\t\t\tx: force.x,\n\t\t\ty: force.y,\n\t\t});\n\t}\n\n\tapplyImpulse(renderable: Renderable, impulse: Vector2d): void {\n\t\t// Matter has no applyImpulse \u2014 convert via dv = J / m and update vel.\n\t\t// (interface `point?` is accepted in the call site but matter has no\n\t\t// off-center impulse equivalent, so we ignore it.)\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tif (!body) return;\n\t\tconst invMass = body.mass > 0 ? 1 / body.mass : 0;\n\t\tMatter.Body.setVelocity(body, {\n\t\t\tx: body.velocity.x + impulse.x * invMass,\n\t\t\ty: body.velocity.y + impulse.y * invMass,\n\t\t});\n\t}\n\n\tsetPosition(renderable: Renderable, p: Vector2d): void {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tif (body) {\n\t\t\t// `p` is in renderable.pos space (typically top-left). Matter's\n\t\t\t// body.position is the centroid \u2014 convert via the offset stored\n\t\t\t// at addBody time so syncFromPhysics keeps renderable.pos at the\n\t\t\t// requested value.\n\t\t\tconst off = this.posOffsets.get(renderable);\n\t\t\tMatter.Body.setPosition(body, {\n\t\t\t\tx: p.x - (off?.x ?? 0),\n\t\t\t\ty: p.y - (off?.y ?? 0),\n\t\t\t});\n\t\t\t// Matter caches contact pairs across steps for solver continuity.\n\t\t\t// After a discontinuous teleport the cached pair still holds the\n\t\t\t// previous penetration depth + normal, and matter's Baumgarte\n\t\t\t// position-correction phase applies that on the next step before\n\t\t\t// narrow-phase invalidates the pair \u2014 yanking the body back\n\t\t\t// toward the old contact point by \u2248 penetration depth. Builtin\n\t\t\t// and planck handle this natively (planck's `b2Body::SetTransform`\n\t\t\t// documents \"contacts are updated on the next call to\n\t\t\t// b2World::Step\"); matter doesn't, so do it ourselves.\n\t\t\tthis.invalidateContactsFor(body);\n\t\t}\n\t\trenderable.pos.x = p.x;\n\t\trenderable.pos.y = p.y;\n\t}\n\n\tprivate invalidateContactsFor(body: Matter.Body): void {\n\t\t// Flush the per-body cached position-correction impulse so matter's\n\t\t// position-warming mechanism doesn't reapply stale penetration\n\t\t// data on the next step. Used by setPosition to keep a\n\t\t// discontinuous teleport from being undone by the solver.\n\t\t// Zero the per-body cached position-correction impulse. Matter's\n\t\t// `Resolver.postSolvePosition` applies `body.positionImpulse` to\n\t\t// the body every step via the position-warming mechanism (for\n\t\t// solver continuity across frames), independently of whether\n\t\t// `pairs.list` still has an active contact. After a discontinuous\n\t\t// teleport that cached impulse contains the OLD penetration\n\t\t// vector, and reapplying it yanks the body back toward the old\n\t\t// contact point by \u2248 penetration depth. Zeroing it disables the\n\t\t// warming for one frame \u2014 matter will rebuild a fresh impulse\n\t\t// from genuine contacts on the next step if any exist.\n\t\t// Note: engine.pairs is left alone deliberately so matter's\n\t\t// natural pair-lifecycle (Pairs.update marking the stale pair\n\t\t// as inactive on the next step, then moving it to collisionEnd\n\t\t// and firing the event) still works.\n\t\t// `positionImpulse` is a real per-body field but isn't in\n\t\t// `@types/matter-js` (matter exposes it as a solver internal);\n\t\t// intersect the public Body type with the field we touch rather\n\t\t// than discarding the type entirely.\n\t\tconst impulse = (body as Matter.Body & { positionImpulse: Matter.Vector })\n\t\t\t.positionImpulse;\n\t\timpulse.x = 0;\n\t\timpulse.y = 0;\n\t}\n\n\tsetAngle(renderable: Renderable, angle: number): void {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tif (body) {\n\t\t\tMatter.Body.setAngle(body, angle);\n\t\t}\n\t}\n\n\tgetAngle(renderable: Renderable): number {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\treturn body ? body.angle : 0;\n\t}\n\n\tsetAngularVelocity(renderable: Renderable, omega: number): void {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tif (body) {\n\t\t\tMatter.Body.setAngularVelocity(body, omega);\n\t\t}\n\t}\n\n\tgetAngularVelocity(renderable: Renderable): number {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\treturn body ? body.angularVelocity : 0;\n\t}\n\n\tapplyTorque(renderable: Renderable, torque: number): void {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tif (body) {\n\t\t\tbody.torque += torque;\n\t\t}\n\t}\n\n\tsetStatic(renderable: Renderable, isStatic: boolean): void {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tif (body) {\n\t\t\tMatter.Body.setStatic(body, isStatic);\n\t\t}\n\t}\n\n\tsetGravityScale(renderable: Renderable, scale: number): void {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tif (!body) return;\n\t\t// matter-js 0.20 doesn't read body.gravityScale \u2014 track our own\n\t\t// counter-force map (cleared on scale=1 to keep the hot path fast).\n\t\tif (scale === 1) {\n\t\t\tthis.bodyGravityScale.delete(body);\n\t\t} else {\n\t\t\tthis.bodyGravityScale.set(body, scale);\n\t\t}\n\t}\n\n\tsetSensor(renderable: Renderable, isSensor: boolean): void {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tif (body) {\n\t\t\tbody.isSensor = isSensor;\n\t\t}\n\t}\n\n\tsetFrictionAir(\n\t\trenderable: Renderable,\n\t\tfriction: number | { x: number; y: number },\n\t): void {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tif (body) {\n\t\t\tbody.frictionAir =\n\t\t\t\ttypeof friction === \"number\" ? friction : (friction.x + friction.y) / 2;\n\t\t}\n\t}\n\n\tsetMaxVelocity(\n\t\trenderable: Renderable,\n\t\tlimit: { x: number; y: number },\n\t): void {\n\t\tthis.velocityLimits.set(renderable, { x: limit.x, y: limit.y });\n\t}\n\n\tgetMaxVelocity(renderable: Renderable): { x: number; y: number } {\n\t\treturn this.velocityLimits.get(renderable) ?? { x: 0, y: 0 };\n\t}\n\n\tsetCollisionType(renderable: Renderable, type: number): void {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tif (body) {\n\t\t\t// either name works (alias installed in addBody); the matter-\n\t\t\t// native one is the canonical write\n\t\t\tbody.collisionFilter.category = type;\n\t\t}\n\t}\n\n\tsetCollisionMask(renderable: Renderable, mask: number): void {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tif (body) {\n\t\t\tbody.collisionFilter.mask = mask;\n\t\t}\n\t}\n\n\t/**\n\t * Adapter-side debug surface: the body's AABB in renderable-local\n\t * coordinates. Matter tracks `body.bounds` in WORLD space; we\n\t * subtract `renderable.pos` so the result matches melonJS's local-\n\t * space convention (the debug plugin translates to the renderable\n\t * origin before drawing, and would otherwise see the bounds drawn\n\t * offset by the renderable's world position).\n\t * @param renderable - the renderable whose body bounds to read\n\t * @param out - destination `Bounds` (filled in place, also returned)\n\t */\n\tgetBodyAABB(renderable: Renderable, out: Bounds): Bounds | undefined {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tif (!body) return undefined;\n\t\tconst b = body.bounds;\n\t\tconst rp = renderable.pos;\n\t\tout.setMinMax(\n\t\t\tb.min.x - rp.x,\n\t\t\tb.min.y - rp.y,\n\t\t\tb.max.x - rp.x,\n\t\t\tb.max.y - rp.y,\n\t\t);\n\t\treturn out;\n\t}\n\n\t/**\n\t * Adapter-side debug surface: the body's collision shapes in\n\t * renderable-local coordinates. We return the original `def.shapes`\n\t * array \u2014 those are the input shape definitions in local space,\n\t * unchanged by matter's body transformation (rotation is baked into\n\t * matter's vertices, not into our local-space defs). Read-only.\n\t * @param renderable - the renderable whose body shapes to read\n\t */\n\tgetBodyShapes(renderable: Renderable): readonly BodyShape[] {\n\t\treturn this.defMap.get(renderable)?.shapes ?? [];\n\t}\n\n\tisGrounded(renderable: Renderable): boolean {\n\t\tconst body = this.bodyMap.get(renderable);\n\t\tif (!body) return false;\n\t\t// \"Grounded\" = at least one active contact with a body whose center\n\t\t// is below us. Matter's `pair.collision.normal` direction depends\n\t\t// on which body was the SAT reference (it's not stably \"from A to\n\t\t// B\"), so comparing the other body's vertical position is more\n\t\t// robust than reading the normal sign.\n\t\tfor (const pair of this.engine.pairs.list) {\n\t\t\tif (!pair.isActive) continue;\n\t\t\tconst isA = pair.bodyA === body;\n\t\t\tconst isB = pair.bodyB === body;\n\t\t\tif (!isA && !isB) continue;\n\t\t\tconst other = isA ? pair.bodyB : pair.bodyA;\n\t\t\tif (other.position.y > body.position.y) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\traycast(from: Vector2d, to: Vector2d): RaycastHit | null {\n\t\tconst dx = to.x - from.x;\n\t\tconst dy = to.y - from.y;\n\t\tif (Math.abs(dx) < 1e-9 && Math.abs(dy) < 1e-9) return null;\n\n\t\t// Use `Matter.Query.ray` as a coarse AABB-broadphase filter, then\n\t\t// do precise segment-vs-edge intersection per body to find the\n\t\t// actual entry point + surface normal (matter only gives us a\n\t\t// collision pair, not a parametric hit, so we compute it\n\t\t// ourselves). Matches the precision BuiltinAdapter provides.\n\t\tconst bodies = Matter.Composite.allBodies(this.engine.world);\n\t\tconst collisions = Matter.Query.ray(bodies, from, to);\n\t\tif (collisions.length === 0) return null;\n\n\t\t// Inner-loop hot path. Keep only the edge vector for the winning\n\t\t// edge (`bestEdgeX/Y`) \u2014 defer the unit-vector normalise + flip\n\t\t// to the single survivor after the loop, instead of running them\n\t\t// for every edge that briefly held bestT.\n\t\tlet bestT = Infinity;\n\t\tlet bestEdgeX = 0;\n\t\tlet bestEdgeY = 0;\n\t\tlet bestBody: Matter.Body | null = null;\n\n\t\tfor (const collision of collisions) {\n\t\t\tconst candidate = collision.bodyA;\n\t\t\t// Compound bodies expose actual collision shapes in\n\t\t\t// `parts[1..N]`; `parts[0]` is the parent wrapper whose\n\t\t\t// vertices are the convex hull, not the per-part shapes. For\n\t\t\t// simple bodies `parts.length === 1` and parts[0] IS the body.\n\t\t\tconst parts = candidate.parts;\n\t\t\tconst startIdx = parts.length > 1 ? 1 : 0;\n\t\t\tfor (let p = startIdx; p < parts.length; p++) {\n\t\t\t\tconst vertices = parts[p].vertices;\n\t\t\t\tconst vlen = vertices.length;\n\t\t\t\tfor (let i = 0; i < vlen; i++) {\n\t\t\t\t\tconst a = vertices[i];\n\t\t\t\t\t// `i + 1 === vlen ? 0 : i + 1` avoids the modulo\n\t\t\t\t\t// (~2\u00D7 faster than `(i + 1) % vlen` in V8).\n\t\t\t\t\tconst b = vertices[i + 1 === vlen ? 0 : i + 1];\n\t\t\t\t\tconst ex = b.x - a.x;\n\t\t\t\t\tconst ey = b.y - a.y;\n\t\t\t\t\tconst denom = dx * ey - dy * ex;\n\t\t\t\t\t// Inline `|denom| < eps` without the Math.abs call.\n\t\t\t\t\tif (denom > -1e-9 && denom < 1e-9) continue;\n\t\t\t\t\tconst fx = a.x - from.x;\n\t\t\t\t\tconst fy = a.y - from.y;\n\t\t\t\t\tconst t = (fx * ey - fy * ex) / denom;\n\t\t\t\t\t// Early reject on t before computing s \u2014 most edges\n\t\t\t\t\t// fail this check, so skipping s saves a divide.\n\t\t\t\t\tif (t < 0 || t > 1 || t >= bestT) continue;\n\t\t\t\t\tconst s = (fx * dy - fy * dx) / denom;\n\t\t\t\t\tif (s < 0 || s > 1) continue;\n\t\t\t\t\tbestT = t;\n\t\t\t\t\tbestEdgeX = ex;\n\t\t\t\t\tbestEdgeY = ey;\n\t\t\t\t\tbestBody = candidate;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (bestBody === null) return null;\n\t\tconst renderable = this.renderableMap.get(bestBody);\n\t\tif (!renderable) return null;\n\n\t\t// Edge outward normal \u2014 perpendicular to the winning edge,\n\t\t// flipped to point back toward the ray origin (Box2D convention).\n\t\tlet nx = bestEdgeY;\n\t\tlet ny = -bestEdgeX;\n\t\tconst nLen = Math.sqrt(nx * nx + ny * ny);\n\t\tif (nLen > 0) {\n\t\t\tnx /= nLen;\n\t\t\tny /= nLen;\n\t\t}\n\t\tif (nx * dx + ny * dy > 0) {\n\t\t\tnx = -nx;\n\t\t\tny = -ny;\n\t\t}\n\n\t\treturn {\n\t\t\trenderable,\n\t\t\tpoint: new Vector2d(from.x + dx * bestT, from.y + dy * bestT),\n\t\t\tnormal: new Vector2d(nx, ny),\n\t\t\tfraction: bestT,\n\t\t};\n\t}\n\n\tqueryAABB(rect: Rect): Renderable[] {\n\t\tconst bodies = Matter.Composite.allBodies(this.engine.world);\n\t\tconst matched = Matter.Query.region(bodies, {\n\t\t\tmin: { x: rect.pos.x, y: rect.pos.y },\n\t\t\tmax: { x: rect.pos.x + rect.width, y: rect.pos.y + rect.height },\n\t\t});\n\t\tconst result: Renderable[] = [];\n\t\tfor (const b of matched) {\n\t\t\tconst r = this.renderableMap.get(b);\n\t\t\tif (r) result.push(r);\n\t\t}\n\t\treturn result;\n\t}\n\n\t// ---------------------------------------------------------------------\n\t// Internal helpers\n\t// ---------------------------------------------------------------------\n\n\tprivate _clampVelocities(): void {\n\t\tfor (const [renderable, limit] of this.velocityLimits) {\n\t\t\tconst body = this.bodyMap.get(renderable);\n\t\t\tif (!body) continue;\n\t\t\tconst vx = Math.max(-limit.x, Math.min(limit.x, body.velocity.x));\n\t\t\tconst vy = Math.max(-limit.y, Math.min(limit.y, body.velocity.y));\n\t\t\tif (vx !== body.velocity.x || vy !== body.velocity.y) {\n\t\t\t\tMatter.Body.setVelocity(body, { x: vx, y: vy });\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _dispatchCollisions(\n\t\tpairs: Matter.Pair[],\n\t\tphase: \"start\" | \"active\" | \"end\",\n\t): void {\n\t\t// Pick the single handler to dispatch for each side per pair.\n\t\t// The supersedes rule (modern `onCollisionActive` wins over legacy\n\t\t// `onCollision` when both are defined) is baked into the picker,\n\t\t// so the per-pair loop becomes a straight dispatch with no\n\t\t// skip-flag bookkeeping.\n\t\t//\n\t\t// `onCollision` is the legacy every-frame alias; legacy melonJS\n\t\t// SAT fires it every frame two bodies overlap, which maps to\n\t\t// matter's `collisionActive`. Routing it there preserves legacy\n\t\t// semantics for code that never migrated to the modern hooks.\n\t\tconst methodForSide = (receiver: Renderable): string => {\n\t\t\tif (phase === \"start\") return \"onCollisionStart\";\n\t\t\tif (phase === \"end\") return \"onCollisionEnd\";\n\t\t\t// active: modern handler wins if defined, else fall back to legacy\n\t\t\treturn typeof (receiver as Renderable & { onCollisionActive?: unknown })\n\t\t\t\t.onCollisionActive === \"function\"\n\t\t\t\t? \"onCollisionActive\"\n\t\t\t\t: \"onCollision\";\n\t\t};\n\t\tfor (const pair of pairs) {\n\t\t\tconst rA = this.renderableMap.get(pair.bodyA);\n\t\t\tconst rB = this.renderableMap.get(pair.bodyB);\n\t\t\tif (!rA || !rB) continue;\n\t\t\t// Detachment handling. `ancestor === null` means the renderable\n\t\t\t// was attached to a container and later detached (removeChild,\n\t\t\t// mid-step level reload). `ancestor === undefined` means it was\n\t\t\t// never in a tree at all (unit tests adding bodies directly to\n\t\t\t// the adapter) \u2014 leave those alone.\n\t\t\t//\n\t\t\t// For START / ACTIVE phases: if either partner is detached the\n\t\t\t// pair is stale, skip the whole dispatch.\n\t\t\t//\n\t\t\t// For END phase: dispatch to whichever partner is still attached\n\t\t\t// \u2014 they want to know their neighbor just left. Skip only when\n\t\t\t// both are gone.\n\t\t\tconst ancA = (rA as Renderable & { ancestor?: object | null }).ancestor;\n\t\t\tconst ancB = (rB as Renderable & { ancestor?: object | null }).ancestor;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- runtime guard: ancestor is set to null by Container on removeChild; TS narrows it away on the cast\n\t\t\tconst aDetached = ancA === null;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- runtime guard: ancestor is set to null by Container on removeChild; TS narrows it away on the cast\n\t\t\tconst bDetached = ancB === null;\n\t\t\tif (phase === \"end\") {\n\t\t\t\tif (aDetached && bDetached) continue;\n\t\t\t} else if (aDetached || bDetached) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// Matter-native response shape passed to user handlers.\n\t\t\t//\n\t\t\t// - `a` / `b` \u2014 receiver and partner renderables. We dispatch\n\t\t\t// once per side, so each side sees itself as `a`.\n\t\t\t// - `normal` \u2014 unit MTV (minimum translation vector) for the\n\t\t\t// receiver. Direction `this` must move to separate from\n\t\t\t// `other`. Matter's `pair.collision.normal` is already the\n\t\t\t// MTV of `bodyA`; for the B-side dispatch we negate so each\n\t\t\t// handler sees the normal from its own perspective.\n\t\t\t// `normal.y < -0.7` \u2192 push me up to escape (I'm on top \u2192 stomp)\n\t\t\t// `normal.y > 0.7` \u2192 push me down to escape (I'm below \u2192 being stomped on)\n\t\t\t// - `depth` \u2014 penetration depth (matter native name).\n\t\t\t// - `pair` \u2014 raw `Matter.Pair`, exposed for advanced use\n\t\t\t// (supports, tangent, body refs, etc.).\n\t\t\tconst collision = pair.collision;\n\t\t\tconst depth = collision.depth;\n\t\t\tconst normal = collision.normal;\n\t\t\tconst responseAB = {\n\t\t\t\ta: rA,\n\t\t\t\tb: rB,\n\t\t\t\tnormal: { x: normal.x, y: normal.y },\n\t\t\t\tdepth,\n\t\t\t\tpair,\n\t\t\t};\n\t\t\tconst responseBA = {\n\t\t\t\ta: rB,\n\t\t\t\tb: rA,\n\t\t\t\tnormal: { x: -normal.x, y: -normal.y },\n\t\t\t\tdepth,\n\t\t\t\tpair,\n\t\t\t};\n\t\t\tif (!aDetached) {\n\t\t\t\tconst mA = methodForSide(rA);\n\t\t\t\tconst fnA = (rA as Renderable & Record<string, unknown>)[mA];\n\t\t\t\tif (typeof fnA === \"function\") {\n\t\t\t\t\t(fnA as (response: unknown, other: Renderable) => unknown).call(\n\t\t\t\t\t\trA,\n\t\t\t\t\t\tresponseAB,\n\t\t\t\t\t\trB,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!bDetached) {\n\t\t\t\tconst mB = methodForSide(rB);\n\t\t\t\tconst fnB = (rB as Renderable & Record<string, unknown>)[mB];\n\t\t\t\tif (typeof fnB === \"function\") {\n\t\t\t\t\t(fnB as (response: unknown, other: Renderable) => unknown).call(\n\t\t\t\t\t\trB,\n\t\t\t\t\t\tresponseBA,\n\t\t\t\t\t\trA,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _shapeToMatter(\n\t\tshape: BodyShape,\n\t\tbaseX: number,\n\t\tbaseY: number,\n\t): Matter.Body {\n\t\tif (shape instanceof Rect) {\n\t\t\t// melonJS Rect: pos is top-left in shape-local space. Matter\n\t\t\t// rectangles are centered, so we shift by half-width/half-height.\n\t\t\tconst w = shape.width;\n\t\t\tconst h = shape.height;\n\t\t\treturn Matter.Bodies.rectangle(\n\t\t\t\tbaseX + shape.pos.x + w / 2,\n\t\t\t\tbaseY + shape.pos.y + h / 2,\n\t\t\t\tw,\n\t\t\t\th,\n\t\t\t);\n\t\t}\n\t\tif (shape instanceof Ellipse) {\n\t\t\t// Matter has no native ellipse \u2014 approximate as a circle with the\n\t\t\t// average radius. For tall/narrow ellipses this is a poor fit;\n\t\t\t// a future improvement could synthesize a polygon hull.\n\t\t\tconst radius = (shape.radiusV.x + shape.radiusV.y) / 2;\n\t\t\treturn Matter.Bodies.circle(\n\t\t\t\tbaseX + shape.pos.x,\n\t\t\t\tbaseY + shape.pos.y,\n\t\t\t\tradius,\n\t\t\t);\n\t\t}\n\t\tif (shape instanceof Polygon) {\n\t\t\t// translate polygon vertices into world-space, then let Matter\n\t\t\t// recompute its own center / vertex list\n\t\t\tconst points = shape.points.map((p) => ({\n\t\t\t\tx: baseX + shape.pos.x + p.x,\n\t\t\t\ty: baseY + shape.pos.y + p.y,\n\t\t\t}));\n\t\t\t// average the points to get an initial center for Bodies.fromVertices\n\t\t\tconst cx =\n\t\t\t\tpoints.reduce((s, p) => s + p.x, 0) / Math.max(1, points.length);\n\t\t\tconst cy =\n\t\t\t\tpoints.reduce((s, p) => s + p.y, 0) / Math.max(1, points.length);\n\t\t\tconst body = Matter.Bodies.fromVertices(cx, cy, [points]);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- runtime guard: matter-js types claim non-null, but fromVertices returns undefined for degenerate polygons (collinear / zero-area)\n\t\t\tif (body) {\n\t\t\t\treturn body;\n\t\t\t}\n\t\t\t// Bodies.fromVertices returns undefined when the vertices form\n\t\t\t// a degenerate (collinear, zero-area, etc.) polygon. Fall back\n\t\t\t// to an axis-aligned bounding box so the body still exists in\n\t\t\t// the simulation rather than disappearing silently.\n\t\t\tlet minX = Number.POSITIVE_INFINITY;\n\t\t\tlet minY = Number.POSITIVE_INFINITY;\n\t\t\tlet maxX = Number.NEGATIVE_INFINITY;\n\t\t\tlet maxY = Number.NEGATIVE_INFINITY;\n\t\t\tfor (const p of points) {\n\t\t\t\tif (p.x < minX) minX = p.x;\n\t\t\t\tif (p.y < minY) minY = p.y;\n\t\t\t\tif (p.x > maxX) maxX = p.x;\n\t\t\t\tif (p.y > maxY) maxY = p.y;\n\t\t\t}\n\t\t\tconst w = Math.max(1, maxX - minX);\n\t\t\tconst h = Math.max(1, maxY - minY);\n\t\t\treturn Matter.Bodies.rectangle(minX + w / 2, minY + h / 2, w, h);\n\t\t}\n\t\tthrow new Error(\n\t\t\t`MatterAdapter: unsupported shape type ${\n\t\t\t\t(shape as { constructor: { name: string } }).constructor.name\n\t\t\t}`,\n\t\t);\n\t}\n}\n\n/**\n * Namespace-merged with the {@link MatterAdapter} class to expose\n * adapter-owned types alongside the runtime API. Access via\n * `MatterAdapter.Body`, etc.\n */\n// biome-ignore lint/style/useNamingConvention: namespace must match the class it merges with\n// eslint-disable-next-line @typescript-eslint/no-namespace -- intentional class+namespace declaration merge so adapter-owned types (`MatterAdapter.Body`) are reachable alongside the runtime class; cannot be expressed as a separate ES2015 module export\nexport namespace MatterAdapter {\n\t/**\n\t * The concrete body handle attached to `renderable.body` under\n\t * {@link MatterAdapter}. Combines the raw `Matter.Body` (with all\n\t * native fields \u2014 `frictionAir`, `restitution`, `friction`, `angle`,\n\t * `angularVelocity`, \u2026) with the portable melonJS helper methods\n\t * (`setVelocity`, `applyImpulse`, `setStatic`, etc.) spliced on at\n\t * `addBody` time.\n\t *\n\t * Type it explicitly when reaching for matter-native fields:\n\t *\n\t * ```ts\n\t * (this.body as MatterAdapter.Body).frictionAir = 0.02;\n\t * ```\n\t *\n\t * Keeps user code free of a direct `matter-js` import \u2014 the matter\n\t * dependency stays behind the adapter boundary.\n\t */\n\texport type Body = ReturnType<typeof Matter.Body.create> & PhysicsBody;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "@melonjs/matter-adapter",
3
+ "version": "1.0.0",
4
+ "description": "melonJS physics adapter for matter-js",
5
+ "homepage": "https://www.npmjs.com/package/@melonjs/matter-adapter",
6
+ "type": "module",
7
+ "keywords": [
8
+ "2D",
9
+ "HTML5",
10
+ "javascript",
11
+ "TypeScript",
12
+ "es6",
13
+ "Canvas",
14
+ "WebGL",
15
+ "game",
16
+ "engine",
17
+ "physics",
18
+ "matter-js",
19
+ "browser"
20
+ ],
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/melonjs/melonJS.git",
24
+ "directory": "packages/matter-adapter"
25
+ },
26
+ "bugs": {
27
+ "url": "https://github.com/melonjs/melonJS/issues"
28
+ },
29
+ "license": "MIT",
30
+ "author": "Olivier Biot (AltByte Pte Ltd)",
31
+ "funding": "https://github.com/sponsors/melonjs",
32
+ "engines": {
33
+ "node": ">=24.0.0"
34
+ },
35
+ "types": "./build/index.d.ts",
36
+ "exports": {
37
+ ".": "./build/index.js"
38
+ },
39
+ "files": [
40
+ "build/",
41
+ "package.json",
42
+ "README.md",
43
+ "LICENSE",
44
+ "CHANGELOG.md"
45
+ ],
46
+ "peerDependencies": {
47
+ "melonjs": ">=19.5.0"
48
+ },
49
+ "dependencies": {
50
+ "matter-js": "^0.20.0",
51
+ "poly-decomp": "^0.3.0"
52
+ },
53
+ "devDependencies": {
54
+ "@types/matter-js": "^0.20.0",
55
+ "concurrently": "^9.2.1",
56
+ "esbuild": "^0.27.3",
57
+ "melonjs": "workspace:*",
58
+ "tsconfig": "workspace:*",
59
+ "tsx": "^4.21.0",
60
+ "typescript": "^6.0.2",
61
+ "vitest": "^4.1.5"
62
+ },
63
+ "scripts": {
64
+ "dev": "concurrently --raw \"pnpm build:watch\" \"pnpm tsc:watch\"",
65
+ "build": "tsx scripts/build.ts && pnpm types",
66
+ "build:watch": "tsx scripts/build.ts watch",
67
+ "lint": "eslint src/**.ts",
68
+ "prepublishOnly": "pnpm clean && pnpm build",
69
+ "clean": "tsx scripts/clean.ts",
70
+ "types": "tsc --project tsconfig.build.json",
71
+ "tsc:watch": "tsc --project tsconfig.build.json --watch --noUnusedParameters false --noUnusedLocals false --preserveWatchOutput",
72
+ "test": "vitest run"
73
+ }
74
+ }