diff --git a/dist/base-system.d.ts b/dist/base-system.d.ts index 029c44e..3ea4671 100644 --- a/dist/base-system.d.ts +++ b/dist/base-system.d.ts @@ -1,10 +1,10 @@ import { Body, BodyOptions, ChildrenData, Data, InTest, Leaf, PotentialVector, RBush, TraverseFunction, Vector } from "./model"; -import { Box } from "./bodies/box"; -import { Circle } from "./bodies/circle"; -import { Ellipse } from "./bodies/ellipse"; -import { Line } from "./bodies/line"; -import { Point } from "./bodies/point"; -import { Polygon } from "./bodies/polygon"; +import { Box, BoxConstructor } from "./bodies/box"; +import { Circle, CircleConstructor } from "./bodies/circle"; +import { Ellipse, EllipseConstructor } from "./bodies/ellipse"; +import { Line, LineConstructor } from "./bodies/line"; +import { Point, PointConstructor } from "./bodies/point"; +import { Polygon, PolygonConstructor } from "./bodies/polygon"; /** * very base collision system (create, insert, update, draw, remove) */ @@ -13,27 +13,27 @@ export declare class BaseSystem extends RBush impleme /** * create point at position with options and add to system */ - createPoint(position: PotentialVector, options?: BodyOptions): TPoint; + createPoint(position: PotentialVector, options?: BodyOptions, Class?: PointConstructor): TPoint | Point; /** * create line at position with options and add to system */ - createLine(start: Vector, end: Vector, options?: BodyOptions): TLine; + createLine(start: Vector, end: Vector, options?: BodyOptions, Class?: LineConstructor): TLine | Line; /** * create circle at position with options and add to system */ - createCircle(position: PotentialVector, radius: number, options?: BodyOptions): TCircle; + createCircle(position: PotentialVector, radius: number, options?: BodyOptions, Class?: CircleConstructor): TCircle | Circle; /** * create box at position with options and add to system */ - createBox(position: PotentialVector, width: number, height: number, options?: BodyOptions): TBox; + createBox(position: PotentialVector, width: number, height: number, options?: BodyOptions, Class?: BoxConstructor): TBox | Box; /** * create ellipse at position with options and add to system */ - createEllipse(position: PotentialVector, radiusX: number, radiusY?: number, step?: number, options?: BodyOptions): TEllipse; + createEllipse(position: PotentialVector, radiusX: number, radiusY?: number, step?: number, options?: BodyOptions, Class?: EllipseConstructor): TEllipse | Ellipse; /** * create polygon at position with options and add to system */ - createPolygon(position: PotentialVector, points: PotentialVector[], options?: BodyOptions): TPolygon; + createPolygon(position: PotentialVector, points: PotentialVector[], options?: BodyOptions, Class?: PolygonConstructor): TPolygon | Polygon; /** * re-insert body into collision tree and update its bbox * every body can be part of only one system diff --git a/dist/base-system.js b/dist/base-system.js index 19be1f0..79bbb36 100644 --- a/dist/base-system.js +++ b/dist/base-system.js @@ -17,48 +17,54 @@ class BaseSystem extends model_1.RBush { /** * create point at position with options and add to system */ - createPoint(position, options) { - const point = new point_1.Point(position, options); + createPoint(position, options, Class) { + const PointClass = Class || point_1.Point; + const point = new PointClass(position, options); this.insert(point); return point; } /** * create line at position with options and add to system */ - createLine(start, end, options) { - const line = new line_1.Line(start, end, options); + createLine(start, end, options, Class) { + const LineClass = Class || line_1.Line; + const line = new LineClass(start, end, options); this.insert(line); return line; } /** * create circle at position with options and add to system */ - createCircle(position, radius, options) { - const circle = new circle_1.Circle(position, radius, options); + createCircle(position, radius, options, Class) { + const CircleClass = Class || circle_1.Circle; + const circle = new CircleClass(position, radius, options); this.insert(circle); return circle; } /** * create box at position with options and add to system */ - createBox(position, width, height, options) { - const box = new box_1.Box(position, width, height, options); + createBox(position, width, height, options, Class) { + const BoxClass = Class || box_1.Box; + const box = new BoxClass(position, width, height, options); this.insert(box); return box; } /** * create ellipse at position with options and add to system */ - createEllipse(position, radiusX, radiusY = radiusX, step, options) { - const ellipse = new ellipse_1.Ellipse(position, radiusX, radiusY, step, options); + createEllipse(position, radiusX, radiusY = radiusX, step, options, Class) { + const EllipseClass = Class || ellipse_1.Ellipse; + const ellipse = new EllipseClass(position, radiusX, radiusY, step, options); this.insert(ellipse); return ellipse; } /** * create polygon at position with options and add to system */ - createPolygon(position, points, options) { - const polygon = new polygon_1.Polygon(position, points, options); + createPolygon(position, points, options, Class) { + const PolygonClass = Class || polygon_1.Polygon; + const polygon = new PolygonClass(position, points, options); this.insert(polygon); return polygon; } diff --git a/dist/bodies/box.d.ts b/dist/bodies/box.d.ts index 8467a4b..e8689bb 100644 --- a/dist/bodies/box.d.ts +++ b/dist/bodies/box.d.ts @@ -1,5 +1,8 @@ import { BodyGroup, BodyOptions, BodyType, PotentialVector } from "../model"; import { Polygon } from "./polygon"; +export interface BoxConstructor { + new (position: PotentialVector, width: number, height: number, options?: BodyOptions): TBox; +} /** * collider - box */ diff --git a/dist/bodies/circle.d.ts b/dist/bodies/circle.d.ts index 8e550e1..bb9b1dd 100644 --- a/dist/bodies/circle.d.ts +++ b/dist/bodies/circle.d.ts @@ -1,6 +1,9 @@ import { BBox, BodyGroup, BodyOptions, BodyProps, BodyType, PotentialVector, SATVector, Vector } from "../model"; import { Circle as SATCircle } from "sat"; import { System } from "../system"; +export interface CircleConstructor { + new (position: PotentialVector, radius: number, options?: BodyOptions): TCircle; +} /** * collider - circle */ diff --git a/dist/bodies/ellipse.d.ts b/dist/bodies/ellipse.d.ts index 871f3c1..4389f24 100644 --- a/dist/bodies/ellipse.d.ts +++ b/dist/bodies/ellipse.d.ts @@ -1,5 +1,8 @@ import { BodyGroup, BodyOptions, BodyType, PotentialVector } from "../model"; import { Polygon } from "./polygon"; +export interface EllipseConstructor { + new (position: PotentialVector, radiusX: number, radiusY?: number, step?: number, options?: BodyOptions): TEllipse; +} /** * collider - ellipse */ diff --git a/dist/bodies/line.d.ts b/dist/bodies/line.d.ts index 4a2f9ac..fa6c83c 100644 --- a/dist/bodies/line.d.ts +++ b/dist/bodies/line.d.ts @@ -1,6 +1,9 @@ import { BodyGroup, BodyOptions, BodyType, Vector } from "../model"; import { Vector as SATVector } from "sat"; import { Polygon } from "./polygon"; +export interface LineConstructor { + new (start: Vector, end: Vector, options?: BodyOptions): TLine; +} /** * collider - line */ diff --git a/dist/bodies/point.d.ts b/dist/bodies/point.d.ts index ed1621a..aece8ae 100644 --- a/dist/bodies/point.d.ts +++ b/dist/bodies/point.d.ts @@ -1,5 +1,8 @@ import { BodyGroup, BodyOptions, BodyType, PotentialVector } from "../model"; import { Box } from "./box"; +export interface PointConstructor { + new (position: PotentialVector, options?: BodyOptions): TPoint; +} /** * collider - point (very tiny box) */ diff --git a/dist/bodies/polygon.d.ts b/dist/bodies/polygon.d.ts index 2dbd5d1..f4120b6 100644 --- a/dist/bodies/polygon.d.ts +++ b/dist/bodies/polygon.d.ts @@ -1,8 +1,9 @@ -import { isSimple } from "poly-decomp-es"; import { BBox, BodyGroup, BodyOptions, BodyProps, BodyType, DecompPolygon, PotentialVector, SATVector, Vector } from "../model"; import { Polygon as SATPolygon } from "sat"; import { System } from "../system"; -export { isSimple }; +export interface PolygonConstructor { + new (position: PotentialVector, points: PotentialVector[], options?: BodyOptions): TPolygon; +} /** * collider - polygon */ diff --git a/dist/bodies/polygon.js b/dist/bodies/polygon.js index 3daf476..5d8ced8 100644 --- a/dist/bodies/polygon.js +++ b/dist/bodies/polygon.js @@ -1,8 +1,7 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.Polygon = exports.isSimple = void 0; +exports.Polygon = void 0; const poly_decomp_es_1 = require("poly-decomp-es"); -Object.defineProperty(exports, "isSimple", { enumerable: true, get: function () { return poly_decomp_es_1.isSimple; } }); const model_1 = require("../model"); const optimized_1 = require("../optimized"); const utils_1 = require("../utils"); diff --git a/dist/demo/demo.js b/dist/demo/demo.js index 9d5e33d..d8b609c 100644 --- a/dist/demo/demo.js +++ b/dist/demo/demo.js @@ -2067,48 +2067,54 @@ class BaseSystem extends model_1.RBush { /** * create point at position with options and add to system */ - createPoint(position, options) { - const point = new point_1.Point(position, options); + createPoint(position, options, Class) { + const PointClass = Class || point_1.Point; + const point = new PointClass(position, options); this.insert(point); return point; } /** * create line at position with options and add to system */ - createLine(start, end, options) { - const line = new line_1.Line(start, end, options); + createLine(start, end, options, Class) { + const LineClass = Class || line_1.Line; + const line = new LineClass(start, end, options); this.insert(line); return line; } /** * create circle at position with options and add to system */ - createCircle(position, radius, options) { - const circle = new circle_1.Circle(position, radius, options); + createCircle(position, radius, options, Class) { + const CircleClass = Class || circle_1.Circle; + const circle = new CircleClass(position, radius, options); this.insert(circle); return circle; } /** * create box at position with options and add to system */ - createBox(position, width, height, options) { - const box = new box_1.Box(position, width, height, options); + createBox(position, width, height, options, Class) { + const BoxClass = Class || box_1.Box; + const box = new BoxClass(position, width, height, options); this.insert(box); return box; } /** * create ellipse at position with options and add to system */ - createEllipse(position, radiusX, radiusY = radiusX, step, options) { - const ellipse = new ellipse_1.Ellipse(position, radiusX, radiusY, step, options); + createEllipse(position, radiusX, radiusY = radiusX, step, options, Class) { + const EllipseClass = Class || ellipse_1.Ellipse; + const ellipse = new EllipseClass(position, radiusX, radiusY, step, options); this.insert(ellipse); return ellipse; } /** * create polygon at position with options and add to system */ - createPolygon(position, points, options) { - const polygon = new polygon_1.Polygon(position, points, options); + createPolygon(position, points, options, Class) { + const PolygonClass = Class || polygon_1.Polygon; + const polygon = new PolygonClass(position, points, options); this.insert(polygon); return polygon; } @@ -2769,9 +2775,8 @@ exports.Point = Point; "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.Polygon = exports.isSimple = void 0; +exports.Polygon = void 0; const poly_decomp_es_1 = __webpack_require__(/*! poly-decomp-es */ "./node_modules/poly-decomp-es/dist/poly-decomp-es.js"); -Object.defineProperty(exports, "isSimple", ({ enumerable: true, get: function () { return poly_decomp_es_1.isSimple; } })); const model_1 = __webpack_require__(/*! ../model */ "./src/model.ts"); const optimized_1 = __webpack_require__(/*! ../optimized */ "./src/optimized.ts"); const utils_1 = __webpack_require__(/*! ../utils */ "./src/utils.ts"); diff --git a/docs/assets/navigation.js b/docs/assets/navigation.js index 5f20d31..8f9d2af 100644 --- a/docs/assets/navigation.js +++ b/docs/assets/navigation.js @@ -1 +1 @@ -window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAA52XS3PaMBSF/4vXpGlok7bsbEgIM2mTSTzZdLoQ9g1oMJJHkilMp/+94wfYkq+vaLY653x6WdL1zz+Bgb0JJkEk08NcySIPRkHOzDqYBCCKrb48CR/WZpsFo2DDRRpMvv4dWdn4kAMWLdup5L4NJRnTGsrY3k5cjbuZKVdJBv1Y3U4lb7OM5xqJNgKVfeACCZatVOpJcmH6saqZzmWHlRRYshKo7HNU6HU/WTWTOdC5FNjyHJVeelRbgklgdHrB9QXsDSjBsqDDfQnjoS07Se8mDy5Uq72b/QqJkQpF19I7yQdtYItgq3ZqhyLruHBhQL2xpDwxvSMzvr5xDuhjbrgUGs+3ug/zpGQ+DKlUCjFd8yxVIGbMMJTSNVCgQYAvOAcThlEU6qHF7Boo0JM0IAxnmfuddFiOh8I9s0PCtLnnBiW1MgUhhuIfQbmBbdQc8mZTnczHb1+ursfdPZVZxjWXYsqybMmSjQvpGXzEGSRymzuXZ83qSCjlrCN4hDh3h90Dcnn8Tx8LEYPuDb9u9c3/AdibmyzbfLmXMMY6bZp96VixHSgNd4VIyrvAxbi6dxdv5+PncNZidkxxtszKNa4lm/CpG34OZ+PZ7RwLNxIRXnIxTiFpw2/NkPVlI9nhm8/dsEwP3+UOUjR+FAlAwsSiPHcsMRiiI1OQNSSbcCEiFHEUKUD1sC6E+/Z2KJbjDFTvwPRZ6LFBYI+F0TwFL9H2UdhMJpvfXOMzPYo0QEB1r+hQKXYY4FgeH65fUjksvLKyQQqYAeux6kCOohfQq31dCFoDW6CU6XVZ8MYSo7QqhYDVWDH0ZDXSxRUV59owkaCzOGpUXLHf0es9mq4lT5j4XDsyAQGhCwVTKXaA7mdX92J+FNslqGFMrXsxzajrz3qYZtm80LracF5wF9kxUcC9AZHaxUmHdFIJxApMJAuRwIwrcN62FtV30Ujnd9kCIX/Mbrz3WFsA9M22EWUXEcf37CQSgKo41JBU5S4GsQzngMrzP/zeILZzofbf9wCy/zNOA+8Yvvqo8VwwcUVgPgqrX/g2H1jKRnPjZ1WmW5ZXr1cs3d+FtgPXQ4xzy/LaE8vBh9P1UDi5Q6dcthMxIc3C9z27HgKXl5cSWfHYDh/qkajDLAMJqrqiSjrHcg6MnKLtIXCKpeMUVhilkciHXYEplIhVgc6qVXuIX/8AfjD0VsIUAAA=" \ No newline at end of file +window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAA52YT1PbMBDFv4vPUEpaaJubTSBkhpYOeLh0ehD2QjRxJI8kh2Q6/e4d/0lsSetVylXvvZ8l29Ku/etPZGBrommUyHw3V7Iqo5OoZGYZTSMQ1VqfHYQPS7MuopNoxUUeTb/+PbGy6a4ELFqPU8ltH8oKpjXUsa2dOJ8MM1dcZQX4sXacSl4XBS81Eu0EKnvHBRKsR6nUT8mF8WPNMJ0rdq9SYMlGoLIPSaWXfrIZJnOgSymw27NXvPRJa4mmkdH5KdensDWgBCuiAfcxTsce2UF6N3n0RvXau9lPkBmpUHQrvZO80wbWCLYZp55QYm0XLgyoF5bVO8bbMpOLS2eD3peGS6HxfK+HMD+VLMchjUojtldSaKMq+95anKGFgl0teZErEDNmGIoaGkhQ8xKGJua5KOTonEJz6c6i0GR8GwWdg4njJIn12Bs0NFCg+sALTc3xULjmIAzxXBMNbPZ8GOnaaKgBYTgr3BPBIloeCvfAdhnT5pYblNTLFISYSngG9Vbto2ZXdtvXyXz89uX8YjLcJ7IouOZSXLGieGbZyoV4hhBxBplcl06ZbFkDCaUcddjuIU6VsK+AlIn/ucZCpKC96bejofXfAXtxk/VYKPcYp9hFu+FQOlVsA0rDTSWy+tR3Ma4efIrX88lDPOsxG6Y4ey7qe9xKNuHTMPwQzyaz6zkW7iQi/MzFJIesD790U9ZnnWSHLz8PwzLffZcbyNH4XiQAGROLet+xzGCIgUxBlpCt4oVIUMRepABNXVoIt8saUCzHEShvw/gsdNsgsPvKaJ5DkGj7KGwhs9Ub1/hK9yINENCcKzpWiu1GOJYnhPObZ4eF99A2SAEzYFXoAWQvBgHeV44LQb92LFDO9LKu4qnEKL1KIeB1ohi6szrp9JyKc22YyNBV7DUqrthb8nSLplspECZe14FMQEDoStVt0AbQ5znUg5gf1foZ1Dim1YOYbtbtaz1Os2xBaNttOBXcRQ5MFHBrQOR2czIgHVQC8QomkZXIYMYVOLWtR/kuGun8GLFAyL8RN+4VawuA1mwbUV8i4fgzO4gEoGkONWRNj49BLMMxoKbHH603iO1YqP2fZQTp/3ahgTcMv/uo8VgwcURgPgqrH/m6HLmVnebGj+pM16xsqlcq3c+F/gKuh5jnmpWtJ5WjhdP1UDi5QZdcjxMxIc0i9D67HgJX1ocS2fHYjhDqnujDLAMJai5FtXSO5RgYuUTbQ+AUyyc5vGKUTiILuwJTKZGqCl1Vr3qI3/8A8K+b+KwWAAA=" \ No newline at end of file diff --git a/docs/assets/search.js b/docs/assets/search.js index 9056917..85708e0 100644 --- a/docs/assets/search.js +++ b/docs/assets/search.js @@ -1 +1 @@ -window.searchData = "data:application/octet-stream;base64,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"; \ No newline at end of file +window.searchData = "data:application/octet-stream;base64,H4sIAAAAAAAAA72db5PbNrKvv8qtydtZR0ADpOR3drInm1O7J6k4d+/dcqVcHIkec6ORpkiOY5+t/e63CAoS0PzhDymd+2Ir3hHYDYINoLufBvmvu/b4R3f3+v2/7n5vDru711IX93eH6qm+e3339u3xy9393Uu7v3t91xz6uv1Ybevu2+Hvrz71T/u7+7vtvuq6urt7fXf373srRKykOkt5ag7/Nyrlm1MLR9T93XPV1ofediIs+h9J0f9YJrr6kur12GKR6FSvxxZ5ouX6LPmXty/dp7Po0+Xfmr9Gn5cW8ixjezx0ffuy7Y9tRNI3fjPc07E7gVH48FR9+fOhb5u6i+nxmy3S0xyy9LjN8vTIlbqMfbXfx+SPPy+Q29VVu4091G/OLRZI3x73+2YXHxqnzQIN+2O1i0k//b7gye6qvopJPv2+oM/NoavbPib73GLJmO/rKj63Tg0WyG7rp+PnOib83GKB9P7obQlA+rnFIlt8Ghr+zd0voDm6za7S8488PeG1ODFa//nup/+Kj9apxQLpH9vjU0q+02aBhg+JJe3D4jXtw8NLs4+uCucWedILrenit3z40H99jk6CUfyr8T9/Eq/OV0TUvfIuCi1K20/NftfWh/naXzmXZnfD9jzQm0918/gpupAF+nK+8FY92dfVxwX9OF12q148JdaWQC+iDuqiXkRXnnAvEivRvF64Hu6MXsTc3kW9WDQWMQ85qxf+grT9dDx29buXh76t4ysHb7lk+Uv7Fx+ucTA+dM/7Ji7etlgs/ZfjMUPDqdUSLadxHqT8eNjVUa8DNb5S55svTTxemLZduMV+33T936r2sYnvGbzlIm27f750/c+m8eCnJUIi2HzRuB4Pu/rQJSbWpVGujk0p9CVy/W6IU7rmePiu2u8fqu3vZ3XD1O++nfwejYmjLkVM4DcJZ2LazYvSy5i9Pe6+/uqqrA8vT9239s/x9Mul33/e75vnLirlm0ubQMLBdgVq+K5pt/u4gnOTJfJ/Pu6/Ph4PUQWXNks0uCENkh4LaOKS/9oc4iNzarBsXJpDnxiVsUW2dN/6fmiPL89Agfn79fZ3EZNlgGNv5lmgoyLDBCMawjboqMgxwogObIWO/JQZRmQH7NARnjTE6OhgS/TGJmWKXD5f3P/qxg/j8jv8KWqHbi77u1Nw9b2bNHKSr+7v+bntSbQXk/hNMsDzOonvI9T/ef3epaTEk2eR/g3P8qfnvjkeOqTA+Tm/t033rq/6Zpsj8BuncdjabA+DCn9tm8fHus3UeGl9hcrv6kFHvcvU6TRfrLQ6PDoLZ0yfbblY1XO12zWHxyxll7aL1T16m1dMmW25WNVLV7ehWTnR5jSeo9CdYb9UX7dV1//FifAcjZdf8+fXs7eAh4V98xxdxp2OBRQ9HHdfc/Sc2s1Q4w7Qz8e+PvRNtf977VEsRyFrkj9UkIciad+EN2vev4AqOFJQVXiswqrcAQuP002GJ29UFgxG3hhEb/2Hun/z5u3bN10Adbu/x30NN+B9nCv1G3YFvhOvs5mRarbWV+7/SafEfwhd6v2f8IoDvYMlPXw1yrqml4kU5R836+of/7Md/XSzjoZp8tKOcn/+rbsVjP788Kdsf35o/HN7fA56mebH/JUrNGl8Ud9E58SlTxElP8Q8E6bph6RvElXXdN8dD59rXMPja3OaLlT28BAoFvIVnZotVHL8+LGroavC1JwbLlTUfe36+ilD0bnhQkW7pu3h5sb02Hb5amQhhXLuaFvta1zSxO7INrxOFS5xAqoilU5IlbvPerUOYTXRgoekkq7ufz52zeCS59yS13q5ynfD0OTps02XK3sTiwN9ZW+SgWBK2U+5c9htu1Ddrq3+ePv3v+TMr3PLK1Rl6lmu5LLHhkozfW28/eKNJJ6A8TYSkH7pu92fmu5PzeFT3Ta9yVnMUZ5IxnjaUSrmSvWpxIy/jaK0zFUdiCZpHN3TFM1VahMJG0cxStdcpTqavHGte+IeXaU2lchxNMM0zlzl3CV+9+bXX+uuZ17x6a/XskpXTIpQ2o6Eu/rjAfR0/OO1HXWkpPp56kW4m7+21ee67er/eDlsvf17VMV/vrbrUF7qJiZ9DPALA7C+A8XZLnLgja6q+k4KzioCn3Yc164zimcrBMY/36R63RE1o+ezSslcFdGisYRsVJrlyY4VYSX7PS24Yv0Ou+TJfidkx8q24rK9+BLJjkaWcdksrETSEwFljvzvjs9fM3Scmi3Rw/dspCQFV+IafGcEyY+Torj0iZ+JFCQBX0oHdyexkhTTi2th+QOkIpE5iMv30wZIfDxhEJc+8YSQgiTKSj0HlpzCjyGRlorrgGXgrvx4oVZStp/LCymIZ/GSo8Sjj8A4pXBwXM+Hx+StfAi628/tsa+3zONNWNjB5H52v1S75mVahejZGW+6UD9LUsUNb4bFMbnxWTljRqKkWnxBieaBsuTHvY5EZjBLQ9w/SCQEUxrSRhyn/VP5wWwj9G5ieca4bJRkhAOUkV5ManqXNqVUVjGp403SUUgmE5M6fkq7bekcYlwLTrhBy8pKtcW1eTlEuKnHsodp2W4qNCQ+lgSNa3h53lV97YE9uJ67zRbNw6r9/U33fdID8tst3TWYNYzW9H+a/lPawmHzpf3Qk6LaRDJg2upW2YCA5KygGvQd5wN45bAd4NPfb5IRcGXN6f0sf9NTEnU4M6Rjj3OiIu5yJvQEPXNPTdI1T2j50Bp/bupxeFqcVnkTJ0/r1AtBWv9xM61dXyeemm2yVB/zhCJxA3+KqcAhqSt9c5N7myU/y1CQnSzQkjAMZBcJLd7JczPWiWXItlmkYdxcf8yawZO2N7F1mBf19E4SozFwktKGMqW+Np4qvUYbyp3ye4OrxsJ7S2nj6dQrtMH8qqdtkmC9QtvW2NzpyMw0/ucbs9/2Jj0I5Uo91XPRZnJnDeQ32Zo8E6EntYYynkztXHae0BvIgfo7wzQJeoVGnBX1FE7TolfoC+ZJ/XV2LixOWe5Qhd+9rba/p1xB1jK8vv+va6ZylqOxjdRF3KQbgQym72SlU5jXdMFkr1gxPbZ6r+HNOpPMcHqduGYtT+Y8PU3XzLe8LOV0dK/Z8/PyllOd1+zFWdneqcrbacyYPvPqbRKeKsym+t4NT6deoS2WX/VHNZBgvU43zrhyxdOU63VacYaKaw0mphZqDWRluVqQlr1CbzxP61txMFF7hX6YufUdD566vVIbyuVOFPJk7nUjPKQK2mOzG9KZx5f+l+PgpqYmVPS6283twdHJmNmnZjfR27fVodtXfSrl5zS7id52GL+E0nObm2hsunfN03NqLXFa3URrhCeAPMYEKFwzwnXms/Ub3s6Ry8UdLBuQxzuu6cw41t+5EbndLhPTL3Hl/0x3h8UnIxPmNvv/Nm7zx+u246Qn7zdJAKVpq1sBpYDkLCQD+o6BEn+Jix31099vApRcWXN6PyuZ6imJVpmmpKPkqS89Vmea7vs0aOJ9D6fS031PSY/Vmiakw2SoJz1abZqQHgRsnoYkYEtoSaRYuamGlpkZGkMpVU9Vqv40OXaBFCobu0SNaFJLKGXK1KSqRBN6AilST0miTjShAadEPQXxStGE/GAK1FORrBVNaIFg3dMQBesZ0jFYn6iIg/XU/Iglbv1Jkpu4nbMehPK0/kqQk6edoTWQlvV0zqwsTc2pSBbWn1iZWdi47nzwzlf3FHhP6kpsIHN2jmRC15M8Z7XIS+BOH8wcvyMvYTvVMcc/yErQTlUs15AxceLVrEBDMgHre1CxetaE9FjC1R+ljIrWtC6cYOWK4jWtaS04ocq1xKta01oCCVSuJlHXmtATT5j6VpZV2ZrQBxOkvhsSq23NkI4SohMFserW9IjlJkD58OUkQOfOLZjwnM6sScJzhp5wEsz3i2AKbIaeQELTUwISmjM0BBOYPGqYJjBnaIkkLH1vOF0BnRqxSILSH7bMBOWcfSOSj2QB+Pz666wRzkw/gjFfkH6cuUJkBPZ52cbrRmX+aNxsFBIliKAfs0sQQQ+8V4N9SWQy/Ra3ymICqVk5QNZfnL1Eu3TqnYS5Wcvzm+EyezsrSj8LT7w6LSoVR+ee6NS70oLyg9m4s/iMl6MFpX/4o9n108+3nWWff8+z/JimwMd+LqrAR33ydbHoJHFb07vKlpy6jcSniZhs7xN9H/u6/d9myXnX/HfEVKcNF43YjFXxrHrhihj/SOY03g5/ezP+Fpu872VOtcwpws794Ce6l/wSrNwPdKJ7uYkWyBjOWmYVW0e0JCiAu/QvKbKOveM1QAPOKue/NyqyhgeogLOGz34vWURbiA446ua/iCyoL0AJzspmFlFHNGFacFY0r3g6oidIDS7r4Pw3bEXeNhzJu1/M8SbF0rGpGEoMXybh1UXSMf8AJxQv7sGVxdExA46k5C9WfIui6KhnEcnNu77e/Df4RXRGlvil63syV3/WsHSu5uXs/Se3dH/Py937upbuv1k5fF/VbTQlpt7cFxkGvUyY0794LnMKqiNaYrn9y+gtKKSO68Q5flfhvALquDac63e1zSucjmsL5PxddTMLpiP64rl/8J74OYXSEb2QAVycizkF0gktiAV4iuYURsdHMpcJuMN6bUF0am5CNuDPzFmF0BF94Tz0JTszuwA6oi/ACs7KZhY+RzQFmYEbU8wreE7mByA7YLmBWYXOsZGMMITLcN6iwDm2YUVgghNx36CwOTn2mVSBPY1bFzQnFptE9ugGhczzxmne+NxuXDT7/GCydNlvc7vCZSA3s/CX9TpUtOx+muvCUJpD/EXL+QXLVlJ+r2cW6Z0VJEr0EpJDBXqe+FR5XkRHpCj3rAKCgJjVRjUG0ICjLwMORCdNXH0g0e7qzyAGszqQBRGcDgTvf4m29P2GbzdP3xzY4KidgxvmDfcsLnvuzwwGsdz8Akcbzp2YBSbimvAxh4umOXAidU+o7NC9p/zUReqe4prmQIqopsBRiLOmWaAiqil5YMHdqpbAiqj28OGFs9q5wCKx3wQPMjj7zUxokdAYPtTgqJwLLqI6gwcczgpnwouottBhh7OyeQAjqity8OGykM6FGHELjR8fuJjpTUBGfKqGa9wvk/RqmBF3X0L10Rfv5UqgETfs6CmDi3XfAmok/JrokQPXd50LNhJ6o9vC8j0h4yjCWcvyuZx7LMF/ksv9hNwjCr6+5Xt45nEFX92ttCWn5jzgEXVrA8cYLp7QHOgR1RQ/0nAZyQXgI6U3dLzBVToPfqQ0ho46uBrnAZCUxuCxB1flTAgS1Zk6AnGx1kUgJKo7cBzi4qjMgSFJTfhohKdsDhBJjWr+MQl3iK+FIum5Gzgy4c/cWWAkqjNWon/JWs2GI1GdwaMUZ4UzAUlUW+RYhRvDzIMkGUmMwBELlsCYBUrioxo9bnEZ2lvAkvhmFz174UT/NwAmGc8h+yAGezK3hibJBSmZ8roBOJk7XnPH6Zbj4+CTvzaH1JcEWJNbwRMkNotC8C5jdDK0mgzx8MebgJOzoOwez8ImF/FRapKSi6GJLzzOTGIagsjkoiB5dILJn7xavmqnLuFFvP19iez6MI2XL5LHX/PkBtyfiHS/1XwtiVz+RdHC4wSxpw4T9xeNs/L2UT0obe/omZO1T9zPNBD37ic/Ck/cT1TPnIx9TA9M2F/0zMrXx/Qk0vXeArkkWx/THUrWX5TOzdXH17lAqt5d52Zm6uP6Qol6V+HcPH1MYyBN7yy087L0MV04SX9RNS9HH9MUTNE76+PcDH3UKmMJesc0b5Kfj07NUD7YmZRXZ+djHQgk5y/qr83NR405kpp3LPoWmfm4hxFJzHse0ty8fFxrbPFfvPInk/IXHYvnbl5Knj3BxT5AXkKeaVu8Q2el45myG+lKTcV5ufiYVwpT8Y6HMycTH9MTS8Q7Y7ggD5/QitPwnsp5WfiEPpyE9/TNy8En9AVS8J7CmRn4RKwUScB70dKC/HtMM0y/Oy7InOx7Sg9Kvvuq5uTeM2PPVOodhqJLM+/JuQoT72ymzsq7xzSGU7VO3mN21j2mMZB0v6ibmXOP6Qqm3L1YZF7GPZ1pgAl3nmWYlW+Pjmck3e4M6i2y7dHtLJJsd+P2G+Ta008gM9XOn8mtM+2p5SeVj7pBnn3mWM0co9uNjZuLfofj6/HPN8lHO6KyMtKnHgVCqLbuno8H8PVdV43TaJGOajqtPPFV/mvDJpr8NfPQ1SCN7Co7N8m8E7bHPVctWqxcDU6ja3TAlRjpib5eLq5r+6ne/v4ToCeekV0aLdbxpq2nyZmJklOr5Vr2+wwl+/01Or477vdNhzytiSa36RJ9bfV1W3Vxc760WTIzdyhn5orfzcmYJUavrau+xsecvKHz2t1OM6SEU8WnZrfTe/rAe1rzueHtdKNoa6p4TqyVozX0Qfep5kvLW1oY/voHsjHb8hbaI/6zq3qBB52jN0PnjfTBiNpbM+bE1GldKKrm6ubE1Yk1t4a5Ld8bmpXfiut7HCLivj70TbWfOrCuWt7yFtr7tvpct4mp6jRaqNMnBk/Vlz8f+rap4/frt7uN5uaQp9ltd4txrhKOScV8kuWaurpqt9OTlr7feGpykzV38HF2iQF1Gt1C5/5YTTmLq+/U4Cb3t6+rRAx2anGT+XiECVJvNh5n5UZTT+9paPk3VOjhP0C33W01T1EM1pxPZFJj/J/vfvqvxBifmtxC38f2+JTU6DS6hc4PqQXnw+1WnA8PL80+Ph/PTRbqK7SmSx3jhw+wkG6q8NX4nz+JV+dLYkHSK++qIHH/1Ox3bR33L7H+V861+R2xnQ/0J3DWPaM3idfrLujLvq4+LunJ6bqb9QMWrmX0I/qJvWX9iK9u4X6EP1izpB+owC6nH7GPAi7rx7LxiH3gL68f/pK1/XQ8dvW7l4e+rRMrCW96kyUzI0/5ASQqr9DYPe+bhELb5Hb6fjkec3Semt1E7+lxDWJ/POwAoUAP12196168+dIkoo1p41u5AN83Xf+3qn1sErsVb3ob/bt/vnT9z6b14LKmgi7Y/jZP43jY1SnG4bZa6qY4idX6UbZOlPLx5bA1QO7b0y9/ElEYVLj0ZCd39SMQdfolXxROz10Eer/PE+qGLVxg6usVjrD60L20p2I9P1V8ETppM0/4GZF6tQpcvNcqV8Gu6frqsEVDa3/KHtX9cfv7Hw1+TPa37Bv/0teHnZeadO73/GOuuIfj7uvfjp9rZN7n33KFHY79j0NVZFdvTe0PkMmb5IpuEnKbJUK31cF0ptoi23R+zRZooNSPB9TD828zzOYwspPuTetyV896vCa5op+q53HO/XoMieZNZog27X89smJeT7TXJFf0Y92/Pb4ctvX3TVtvvQqpi/Bpoxni37359de6Q8Zw+TF7Aam6TwOA+vWIlpDzj9ni2uoPjkMceZdf5wh08/G+sLd//8ssO/2F1x4wI7W/Z++Udf/SHn5tX5DEy48znq1/qs57suan7BWzOchdvUXr5fjLvC3sv16eHmo0S9yfs29zuJG3DdwLz79lz2QXnjiz9/g5Pux0qX35/s8/yF/efH+W8rlqm+phX3ffnn7JFfTLm+/l93/+AQg6/TJv0FnFEx/08edckc/jvPvxwOjwRSprkS+4OfQ/HsKz3m8wu78xwX6TWT3+KTYQzu/Z64tpHRlev8FcseFRYC3mCf7ppe+a3YRgc+l+s9nekDlUHRoX0GqRguF//1HBbRG2W6wkR8Ei4eGngJohFb/d3zUmq/D6X3cDQR2cj9d38hW92tzd331s6v2uu3v9ftR+PyCRp9pEPLvj9sX887dTs9HnGRqPrb9d3d2/X90r8YpWm99+u39vLzY/mD9YGZe/mAvF3f17ca9Wr8Sm9C4UkwuFd6G8u38v0YVycqH0LqS7+/eELqTJheRdqO7u3yt0oZpcqLwL9d39e32v168Krb0L9eRC7V1Y3N2/L+5Jv9oUa+/CYnJh4V1Y3t2/L+81vdLK72o5ubD0Llzf3b9fowvXkwvX3oWbu/v3G3ThZnLhxjeAwR7ECl0qpsYjmPUY8xHwYmBAvgWJwS6EhBdPjUj4ViQG2xB0r8pXReGbvJgakvAtSQz2IRTUPDUm4VuTGGxEaHjx1KCEb1FisBNRwIunRiV8qxKDrQhoV2JqWMK3LDHYi4C2JabGJXzrEoPNCGhfYmpgwrcwOdiMhBYmpxYmfQuTg81IaGFyamGSrVFmkYIWJsEy5VuYHGxGErx4amHStzA52IxU90q+0oXwL55amPQtTA42I/W9Xr0Sa+lfPLUw6VuYHGxGFmhiyKmFSd/C5GAzsoSapxYmfQuT69BeIqcGJn0Dk5vgdjK1L+nbF62CO8rUvMg3LxKhTYWm1kW+dZGxLjijaGpdxHZBY11wRhHYCH3rosFeCM4omloX+dZFg70QnFE0tS7yrYsGeyE4o2hqXeRbFw32QnBG0dS6yLcuGgyG4JpNU/Mi37xosBiCazZN7Yt8+1LGvuCaraYGpnwDU4PNUIm8DzW1MOVbmJLBVURNLUz5FqaMo7WGmqcWppivZSxsgxYCBdwt38LUYDNqBS+eWpjyLUwNNqMEvHhqYcq3MDXYjJLw4qmFKd/C1GAziuDFUwtTvoWpwWaUQsuumlqY8i1MDzajsIs6tTDtW5gWwUelpxamfQvTMvio9NTCtG9hmoKPSk8tTPsWplXwUemphWnm0evgo9LAqfctTBfBR6WnFqZ9C9PhHVJPLUz7FqaNhRXwOU8tTPsWpjdBr0BPLUz7Flasgu5yMbWwwrewQoQvnlpY4VtYYSwMLoDF1MIK38IKY2FrFNgWUwsrfAsrjIVt4MVTCyt8CytM0AhD6mJqYQWLGweb0XBiFCB09C2sGGxGS6h5amGFb2HFYDOa4MVTCyt8CysGm9EKXjy1sMK3sHKwGQ3XsHJqYaVvYaUITslyamGlb2HlYDMa7s/l1MJK38LKwWY0NM9yamGlb2HlYDMammc5tbDSt7DSWBg0z3JqYaVvYaVJTaxgt6cWVrLsRBnuNkhQ+BZWrsPdnlpY6VtYOdhMAX3PcmphpW9h61Xw4vXUwta+ha1F0JVaTy1s7VvYerCZQqLRXk8tbO1b2HqwmYLgxVMLW/sWth5splDw4qmFrX0LW+vgxFhPLWztW9jaWBicz+upha19C1sPNlMUcLSnFrZmObDBZooSXgzSYL6FrY2FreHFUwtb+xa2CaZRN1MD2/gGthlMpsApuKmBbXwD2wwmU2LNUwPb+Aa2GUymFOiWN1MD2/gGthlMppTw4qmBbXwD2wwmUxK8eGpgG9/ANoPJlHC32UwNbOMb2MZkWDXUPDWwjW9gm8FkSmidm6mBbViidTCZElrnBuRaebJ1MJoSmuf4m3+587fT9YPdlBuYsF+BjOuKpVxXg+msoaGNv/HrWdZ1NVjPGtra+Bu/niVeVyro0I2/8etZ7nWlgz7d+Bu/nqVfV0XQrRt/49ezDOyqDHp242/8epaEXa2Dzt34G7+e5WFXm6B/N/7Gr2f2Z/L32MUTKN0/yfcP9rSGO6GAGX9mfyKc0RAo6c+z/iaRv4abqUB5f574F+G8rECpf577N+n8NdyPBcr+8/S/yeiH9AP74wTAJPXXcFcWiAFwCGDy+hBpCUQBOAYwmX2cLhAIBDASIExyH6sHKEAwFiBkmFYCGCAYDRAmwQ8TxQLgAMF4gBiBAL4cmB4jAkIG+aUASEAwJiBMmh8vXAAKCEYFhEn0Y/dEAC4gGBgQJte/hqkLAdCAYGxAyMjCB/CAYHxAmJx/YOEFiEAwRiBM3j+w8QBMIBgnECMowBsPQAWCsQJBYQ9PAFogGC4QFHbyBAAGghEDYSBAYOEHzEAwaCAMB8B+tQDYQDBuIAwKwBGBAORAMHQgDA3AQYEA8EAweiAMEAhs/IAfCAYQhGEC6/Je0avNhtkfQAiCMQRhsMAaZuMFoAiCYQRhyACO2QUACYKRBGHgAA7bBWAJgsEEYfjAegPvH+AEwXiCUOE4QwCiIBhSECocaggAFQSjCsKAgoDjBLiCYGBBGFaAoxUB0IJgbEEYXIADFgHogmB4QRhigGMWAQCDYIRBGGiAwxYBGINgkEEYbhAIXABmEIwzCIMOAoEDIA2CoQZh6EEgcAGwQTDaIAxACAROgDcIBhyEYQibFe4/Kvtg9mcwwkbA+QOog2DYQRiSsMGONwAPgpEHYWDCBjvOgD0IBh+E4QnYcwP0QTD8IAxRwJBKAAAhGIEQBipg9QBBCMYghMEKgd0HUAjBMIQwZCGw+wAQIRiJEAYuBHZPwCIEgxHC8IUNDjsAjhCMRwiDGDY4bABEQjAkIQxl2GDvD0AJwaiEKCK7L+ASgoEJYVjDBmbpBUATgrEJYXDDBu++gE4IhieEIQ6bDb4e2B8jFMJAB7GC+XoBIIVglEIY8CBW4l7pV0XBJhAAFYKRCmHgAw6dAKoQjFUIgx9w6ARghWC0QhgAgUMngCsE4xXCIAgcOgFgIRixEAZCYOMDyEIwZiEMhhAricceWB/jFsKgiEDsA8iFYOhCGBoRiF0AvBCMXggDJAKxC+AXggEMYZhEIHYBCEMwhiEMlgjELoBiCIYxxMgxsO8FQIZgJEMYOCFWBB8ggBmC0QxhAIVYKSwAWCAjGsJAikD0AJiGYFBDrEcT1LgDwAQZ2BAGVgTCB8A2BIMbwvCKQPgA8IZgfEOMgAO7/4BwCIY4xMg4sPsPIIdglEMYcBEIXwDnEAx0CMMuAuEDQB2CsQ4RgR0C0A7BcIeI8A4BgIdgxENEkIcAzEMw6CEi1EMA7CEY95AR7iEB95CMe0jDMXD4IAH3kIx7yAj3kIB7SMY9pOEYOHyQgHtIxj2k4RhiVaAJLAH4kAx8SAMyxKrEAkBVMCMfcjUugmssAFQGM/QhV+MiuMECQHUwYx/SsAwhVlgAKBFm8EMamIFjMAngh2TwQ45HHQR0oiSgH5LRD2loBg7iJKAfktEPOZ54ENCTkAB/SIY/5HjqQcCdTAL+IRn/kOPJBwF3MgkAiGQARI6nHwQMJSQgIJIRECmCh2okACCSARBpgAauOZQAgEgGQGQYgEgAQCQDIHI8CAGXAcA/JD8JIYOl6hIdheBnIcbDEPhyYH6T0xAy5EZLeByCGZ8BGngJRQci+IkIGY6BJToTwQ9FSB12wyU6F8EPRhikgd1wiY5G8LMRBmlgN1yi0xH8eIRBGtgNl+iEBD8iYZAGdsMlOiXBEIg0SAO74RIgEMkQiDRIA7vhEiAQyRCIpHASRgIEIhkCkRROwkiAQCRDIJJUOAyQgIFIxkAk6XAYIAEEkQyCSAM1cBggAQSRDIJIKsNhgAQURDIKIiMURAIKIhkFkYZq4DBCAgoiGQWRhmrgMEICCiIZBZGGauAwQgIKIhkFkYZq4DBCAgoiGQWREQoiAQWRjIJIQzVwGCEBBZGMgsiRguApCCiIZBREGqqBwwgJKIhkFESOFARPYUBBJKMgcqQgeAoDCiIZBZEjBcF7CKAgklEQaahGIIwAFEQyCiIN1QiEEYCCSEZBpKEagTACUBDJKIjUFAkjAAaRDINIrSJhBOAgknEQqXUkjAAgRDIQInURCSMACZGMhEhDNkJhBEAhkqEQOaIQHEYAFCIZCpGGbYTCCABDJIMh0sCNQBgBYIhkMESO5zECYQTAIZLhEFnISBgBeIhkPEQWFAkjABCRDIjIQoXz2RIQEcmIiCzGOAQiCQmQiGRIRBbhOAQQEcmIiCzCJ80kICKSERFZhOMQAEQkAyLSAI6ALwWAiGRARBrAEfClABCRDIhIAzgCzjwAIpIBETkCEXyWXQIgIhkQkSMQwefZJQAikgEROQIRfKZdAiQiGRKRhnEEDloDJiIZE5EGcojAuXhARSSjIrIsI3MIcBHJuIgswwe2AReRjItIgzlwMAuoiGRURBrKgYNZAEUkgyJyHTy5LQETkYyJSMM48EYOkIhkSESuKRKMAiYiGRORhnEEglHARCRjItIwjkAwCpiIZExEGsQRCEYBEpEMiUhDOALBKCAikhERaQhHIBgFREQyIiLX4bNqEgARyYCI3KwiwSAgIpIREWkIRygYBEhEMiQiDeIIBIMAiUiGROSGIsEgYCKSMRFpGEcgGARMRDImIkcmgk0QMBHJmIg0jCMQDAImIhkTkSMTwcEgYCKSMRE5MhEcDAImIhkTkYZxBIJBwEQkYyJkGAcOBgkwEWJMhMazIHAKEGAixJgIGcaBg0ECTIQYE6GRiUAfhAATIcZEyCAOHAwSQCLEkAgZwoGDQQJEhBgRIQM4cDBIAIgQAyJk+AYOBgnwEGI8hAzewMEgARxCDIfQahMOBgnwEGI8hE6vfoLBIAEeQoyH0Pj6JxwMEgAixIAIjUAEB4MEgAgxIEInIAKDQQJAhBgQIcM3cDBIgIcQ4yF04iHQCSPAQ4jxEBLhwkACQIQYEKHxpVA4GCRARIgRERpfDIWDQQJMhBgToZGJ4GCQABUhRkXIYA4xvORpGssR4CLEuAjJYHUgAS5CjIvQyEXg6XMCYIQYGCFDOgLqgQkyMEIjGMHrKAAjxMAIGc6BYzkCXIQYF6HxaAheRwEXIcZFSJbhWI4AGCEGRmh8cRSO5QiQEWJkhOQmHMsRQCPE3yBlUAeO5Qi9RIq/RcqgjkAsR+hNUvxVUiTDsRyht0lNXidFoViO4PukmA2Ob5TClwMT5K+UMqADxnKE3inFXyplOAd+Cxd6qxR/rZShHHgfRu+V4i+WMpAjEMsRercUf7nUSEVgLEfo9VKMipAKn00iQEWIURFS4bNJBKgIMSpCKnw2iQAVIUZFSIXPJhGgIsSoCKnw2SQCVIQYFSGlw7EcASxCDIuQKsKxHAEuQoyLkOEcOJYjwEWIcRFS63AsRwCMEAMjZEAHjuUIgBFiYIR0uD6QABghBkZIh+sDCYARYmCEdLg+kAAYIQZGSIfrAwlwEWJchHS4PpAAFiGGRUiH6wMJUBFiVIR0uD6QABQhBkVIh+sDCTARYkyEdLg+kAATIcZESIfrAwkgEWJIhIpwfSABJEIMiVARrg8kQESIEREqwvWBBIAIMSBCRbg+kAAPIcZDqIjUBxLgIcR4CBWR+kACPIQYD6EiUh9IgIgQIyJUROoDCSARYkiEikh9IAEoQgyKUBGuDyQARYhBESoj9YEEqAgxKkJluD6QABUhRkWojNQHEqAixKgIlZH6QAJUhBgVoTJSH0iAihCjImQoh5DwoBoBLEIMi1AZ5HIEoAgxKELjURH4ZkACTIQYE6EyyOUIMBFiTITKMJcjAEWIQRFah7kcASpCjIrQOszlCGARYliE1uM7ueE5QQJghBgYoRGMSHhUjQAYIQZGyIAOIWGBKQEyQoyM0FpHQimARoihERqPi8ClHJARYmSEDOnAoRQAI8TACBnQgUMpwEWIcREynAOHUgCLEMMiFH4DFgEoQgyK0AmK4AUMQBFiUIQM5AiEUgCKEIMitAm/MJIAEyHGRGgTfmckASZCjInQ+EaswAAC22NMhMZzItiPAUyEGBMhwzgCoRRgIsSYCG3WkVAKQBFiUIQ2m0goBagIMSqiDOXAoZQCVEQxKqJWIhxKKYBFFMMiymAOHEopgEUUwyLKYA4cSimARRTDIspgDhxKKYBFFMMiasQiMJRSAIsohkWUwRw4lFIAiyiGRdSIRWAopQAWUQyLqFX4FaYKYBHFsIgylAOHUgpQEcWoiDKQA4dSCkARxaCIMowDh1IKMBHFmIgyiAOHUgogEcWQiDKEA4dSChARxYiIMoQDh1IKEBHFiIgaX5GF5w8AIooBEWUABw6lFAAiigERNQIRHEopAEQUAyJqBCI4lFIAiCgGRNQIRHAopQAQUQyIqBGI4FBKASCiGBBR44uycCilABJRDIkogzhwKKUAElEMiShJ4VBKASiiGBRRBnLgUEoBKKIYFFHjaREcSilARRSjIspQjkAopQAWUQyLqBMWgTuhAlhEMSyiDOXAvoQCVEQxKqJk8JUdCjARxZiIopHKwQpLBaCIYlBEnaAI/vYBgCKKQRE1QhH4yQcFmIhiTESNTEQGPoGAvoHAjHA8MSLhex8U4CKKcRE1nhgh+N4HBciIYmREGdQhCKJRBdiIYmxEjUdGCMbjCtARxeiIGukIwYhQATqiGB1RhnYIghGhAnhE8c9vqPC76xX6AAf/AocaX18PI0qFPsLBv8JheIcgPBPQhzj4lzgM8BCBr4Cgj3FMvsZhDJEgIVXwgxzMEEdEQpCQKvRRDv5VjhGRKGzJ6MMc/MscBnkEdhT0bQ7+cY4RkSg8E9D3OfgHOgzyCPgl6BMdDJGo8Q1a2C8BiEQxRKIM8sCf/lIAkSiGSJQeV0M8kwEjUYyRqPHwiMIzGUASxSCJGt+hhW8A2CBjJMowD2zCAJEohkjU+AYtfDmwP0ZI1HhsBBJ6BQiJYoRE6XXwU3cKEBLFCIkaT43ALycpQEgUIyRq/IIH/ISRAoREMUKixkMj+OkBQqIYIVHjmRH8+AAhUYyQqPHICH5+gJAoRkiUAR64wkIBQKIYIFGGd+APySnARxTjI8rgDvwtOQXwiGJ4RBnagT8npwAdUYyOKAM7At+CAnBEMTiiivDnYxSAI4rBEVWGS2QUYCOKsRFlWAf+cI4CbEQxNqJGNgJXX0BGFCMjqgy+vFcBLqIYF1FlsD5GASqiGBVRBnLgb5cCJqIYE1Hj67Pw3ANQRDEoogzkwB+bUwCKKAZFlKEc+HtzClARxaiIGk+K4LkHqIhiVEQZyoG/OqcAFVGMiihDOfCH5xSgIopREWUgB/72nAJQRDEoogzjwJ+fU4CJKMZElEEcgS/QASSiGBJRIxJRgRsABsiQiBqRiArcAbBABkXU+AatgP8JsIhiWESt1xEPGIARxcCIGl+hhT++pQAaUQyNqPHECP6SlQJwRDE4okY4onA4CuCIYnBEbUYPEIejgI4oRkfUeGREYyce4BHF8IgyuENo7IQDPqIYH1GGdwiNnVgASBQDJMoAD6GxEwsIiWKERBniITQORwEiUQyRqBGR4C9dKYBIFEMkakQkGlsiQCSKIRK9Gl1BaIkaMBLNGIkeGYmGlqgBI9GMkWjDPISGlqgBJNEMkmgDPQT+gJUGlEQzSqLHF2oV0BI1wCSaYRI9vlALf9RJA06iGSfRq3CeWgNOohkn0eP7tPCHoTQAJZqBEj2+Twt/HEoDUqIZKdHjARL8jScNUIlmqESPB0gK/EFDwEo0YyV6PEBSYEsGsEQzWKLHAyQFtmRASzSjJXqkJZAWaUBLNKMl+vQpcbi1aoBLNMMlejxAgrdWDXiJZrxEnz4pjuciACaaARN9+qw4nosAmGgGTPQITEo8FwEw0QyY6BGYlHguAmCiGTDRIzAp8VwCwEQzYKJHYFLiuQSAiWbARBsAIko8lwAx0YyY6JGYlHguAWKiGTHRhoCIEs8lgEw0QyZ6RCYlnksAmWiGTPSITEpsiQCZaIZM9IhM1tgSATKxf/vt/q45fK7bvt79eNjVX+5ev39/9+FD//W5vrv/192HZvyjVPdG0d3rf91Jdff6X/++v1Ny/O9ajP8dvjh0+oey/yhOTYv18I9/39s+jX+2vTG/Dd37UO3++dL1z1VbH/qHh+OXunN7QfrSC9qcRK8pU/R+792RdO5I2m4W2bJ2Tdc/Ve1jc/B66IwTrW0PZZ7Uh5dmv/P6SE4fyfaxzJO2/XQ8dnX3vG/66kvjj6Mjl0rbSzFb7ijOFewMKtlnv17NEvzy0Le1b3xrR6p9VGXmo9oeD7v60HkCqbgIVCvbTZUn8LE9vjy70tblRZqwZjm8h9j8Q9pxGE6hm38MRxhGlavMkflUN4+felfncOTrYhrlyTaG011ZAptDV7eeQLlxxtiaWplpak/Vl/rQt40/W51hsTesM8f4qTkAgc4t26mldZ7Atto1L51nqxtnqg5v/Z8h56snR7tyMq3STB/PJFfO+NsFtsx8nEZaezz6EoUjUVuJm0yJfe3Z+KZwbzLTLP5odv0n32pL12rtfJB58qqPfd2+PO+qvu6a//Ym9HB+0BF8mnHDUcEswf7O4MwEu8fovMdaHR73Xr+08wyKU6+GDxuO/5B5D2PYB12hzq2e1q7Nyko8PWdR2tXHbhtybUfbLvi0yVt9HpqD3NVbb7gLxxyGyCRLznHnzRvtyLCmsM6bhoOoyTKsnHmo87v0dPxce5uucB/akIXJlXR87pvjwVuxlGPvRZ4XMEh6bo/PnpzCubd1ni0OcrgXR84KqvLcJmZ7ytng7TamT8uVzFwXHo5ftsdD17cv2/7Y+uuDYxMyc03eVofm0NdttfV3SK3cx5jXtW09SPLErJzpJsq8ZziKYWa1cvebdWm9A229A2G9A7t6bfKWh+2nevt71Rwe/LvX7t3n7SOjJH8xFK5LpyhzGI2gtq58Se68ojwrNpK2x/2+6ZrjwRdHrrgZd3g8+HuHu/UqyjS6T81+19Zej6Qz5HYh1nYHKXIf5ih3V/Xe4Cl3wc2816bd+ruRcm/UdvAcs2V20EgNzN+16wqJTFsxApvDtLtDTuFy0zJvL7fino/7r4/MYkp3h5CZU9nIO770XbOroVD3yci8RXW7ryt/lXEHzvpqRd4mtt0ft7//0fgRzoA6nPmfea/746F+PjaHvqvatvrq99CNmXKXpkFgW3fPRxaADblbZ7POtJRhGdj5IYEQrsVZby1zgthlZVvt9w/V9ndvq3R2bpVpesenIXHx1By8LdON1ISNWzKdgYtI/2E4D1ecV5hM28NT13m61k+1nR2+JTz+w65mw0fixl3LJnikbSytmyuL019I2p3N+qJ0dtCtm6oyXeHt8fC5/nKahr4hrKS7T586Ku06LNdWt83K0CbzqbZ11dfMDRKeJ6VsvLbONDwjEix4ntFlOmijsHq/b57ZHCN3CbDrvVpnTjYjdt/wvdJdBVSmERtRZl3xZbkuSu4cO8marsPe5qbyvItd1X0abrE/+ouTcBenvACAb9jCWeDEyfaK0zyys0epvBV+Vz/KtvK9SeV6t2u7mYvMzjZt7y0opXPHm1NvhU0DibV18GllZ5OdRMpOq03miDddXx22bK9yJ1PmtNy11R+e6+G66Svr1Ggb/dq/DK8VHztso3AqbEbxvPGqvMVo6MLDZy/BUboL88rmxc8B0sp2x3pdw4vpTr2wObdzylyfBnugn7ndQROjkK4157m3YDnxVxNrb3Y/yDPkk9jAFrRxp0zmHl4f/Gkhvfx73gpaH7qXth63Fn/knFvWIu8pjMIOL08PLI4sSldYnpGPwk4PdXTM/Inj7heZ6ZxR5ud6GP3pmuzGGUMZT5bEL3192PH0zlAr43Qu71F8bI9P/+x8A5bO2mRdCZWZG3is+6p6eKg6nkNbu36jnZbCTktpp660k5BW1mU5L96Za+2lC34P3E3GuiuZpOSx7h+OL4dtvWvaetvzwFi7ZrvK26Mf635IWrTHhs0nl7hlEhJH1h9N/+n40rfHvpp0c+XmelZ2ibQr9vDGzdOAW+8qM6Ac1E/nsrsfS7shS7v2k3VfyaKU4UxaprZJJlIUXioybxY91v3x48eu7ocxmySSN653q7MH4vnY14e+qfZs3XBzOjrbQrqq7+vOXzCKlXurebN8MmDaeTg2bBDWAIRNiA1fhhwfm91/aGWnp7Z79ypv3zBdeGjYelqs3TU6b1y8/b9wtp/M2TJle9JLgp5uuTzdIFkfbKgSz5E/RX3CTUTayUV5d2syrV29NWuav+q46bhMb/AsbXDCUQLI3TNl3nh6Mifxi+ug6cwpPpH4sWKToHTtRuZtTZ5U5Le5Hq3ORGSDUL9va9epEnnzs+lQAtvdzwvLmey2KGxYLYoz97b/2NjZqmyqInNTarrpQu5O0bVdIWwSXdi9QtoaleHrGafkg93AM+scmq5rnp6ZQQoXM1rfXWobSth9hYpzXiNb2bBDepDNjYpsdCDsPinsMiBs9Y2UFinYaJBsaQNlel9N17fN46PvuLqJRDu8YmUHnGwEYPGilHZU1nbAlX0EmSxtX1cfvfXQg8bjRXbIVZk3wHwhUO5qdeqx3UMos+zBLFoBkOVWF1GZtyLsjyzGd/d8G6TqPG/iqXo2Kdz+OHr6/lLtLlervAF8qp5HSf0R5IbddTqzqOWpan+vukkmYuM65vqcXbRGblMoJM4pROuPZ+4PT9UXv2TJeVDWqzjZtC0LE3bzlTYTKq3HTrZWg9Zni8zuh3fjbj7H3qPth512pZ3itmfSzn6i8/JmF9lMq5ukq53xt0psP2yHSru62uSztIlcskkjstNfZTJTnuN2y/PsRmL7YVdDm0eW8txVax92SyCbqlJl3iI41AN4KR3nwWzsbmfRt7B/kTa/SjZ0JGu8yjqyOnP7PRz7iJvluu6bvEc8xhXeLurWuJzNLM8dGqVtj8/e41q7BUKZ3spztds1h0fPyXBur7CDvDoboP2Hfczy7B/bHCXZAjzKhF6THIiXWbWP7qTm4k3MEB7cI9wCLZm3ahqBAbrpZq1FXhhkxB0he3UB3ZzOdQNJY/HwynVC7cIg7dIpbfkSnSdRZsECGAblFhmcNJ2zwJkZhJPYYJGKy/lF3hQ8icSY23X053UxYAluxjeT6z8f/YIjR0Rm+fI51zD1OFz/IHMZbqud3NXe2iDcCi9lzUhnPgFUAeqS2cxwGhWAukn/TH+Ue1Cuj6syyxbb6uuWR6Ju/bmivEd/kvPJL0h1C4hyx+bhpfPSIW4aLE9Czbdf4RWennZUnTlAqPLAza4oyryxum+rQ7evehYOeqlpuydZSk7iHFDYnE1mfUhb9y/toW9f2FC49TCZiS6TevXFrBx7lRaDSbvFkQ01yO6/KnP5B+nBtRvCZEKPblv5C+TanV8WOAqbVZD2L3Jjx93yNpVZWGI0gjhp5VblWL9a2vpZaUEp2QBSZcZSRp+3Erkrtr0xYbOcwh4ckDaSlhubcbDEQmWCPaPaR7/O3mwTrMJuxMLeo1RnJ9x6+nZXVZl8squrduuXg3vM1s7tzGdWP1ctt2zp1bfmzTUraMKv3BMRivKCuq7uJ6l7N4lpTVRYriTsX6Q1IrIpHjrXDmZmojtLEDzt7h63OhfyWEOyf5HW0yWb2iEbaqvMsKUbcMMEUa7c5I2VLfU5xLWun80oqkzP1WjrGk6V3BI/O0mEHVph/yLPNba2LoDOCaXMavau7icLlVsKaKeJsAMr7F+kDR7JckfSdgHJXSL7iqX03ZNilOmwTc54uOeYMutVu69dXz95g+BMartwCXtqS9gyLGmDeWnzJmRXGLKrkMo8zdQfOd11j5kI+2CLvLHtjxMA7SV9rbS8BQH7DSv38JZNoctz/tFmu8jW0qlMJ75vq89D3sD3mt1Up86by1bQx5fDhC+vXXyU6Xzzgwju+RFrAMKmsISlstKajSzs6mRTYZR5kGlQPMGNbimGTQ8Ju60Lm2uXNpUlrftG8pxUylskXg5mjdiNQYM3iO6ynFkGNh598p+tG+2qvOkyiuHb3cbdi60lSpu6knaFIgsMyT4SdT48q/J27lG/V8lpV3JW2uumAMXZFOzksBOb7OEhlUneQAeYYvews71hae2CbNKTbBpUZea7RsWIag3fXHBWrHN5wpli2Xu1M4IyT0q9dHXLSxPdgzH2KQq7EQublREWI0k6J1ftjZ/5e+axmqlv7ZYNZJ7k9cr93PrxzDIvcBrRDYTsw6TMUmTv+blExQoqz+6HTbDaPJe0OUpptzqy/qDKLKHwT9I592FRRXn2P+zWa/O80mJBaZPXZN1BlVPs+tv93XPzPKL11+9/+/e//x/uf1Z+D6MBAA=="; \ No newline at end of file diff --git a/docs/classes/Box.html b/docs/classes/Box.html index c08fefa..bf49da3 100644 --- a/docs/classes/Box.html +++ b/docs/classes/Box.html @@ -1,5 +1,5 @@ Box | Detect-Collisions

Class Box<UserDataType>

collider - box

-

Type Parameters

  • UserDataType = any

Hierarchy (view full)

Constructors

Type Parameters

  • UserDataType = any

Hierarchy (view full)

Constructors

Properties

Constructors

Properties

_group: number

group for collision filtering

-
_height: number

inner height

-
_width: number

inner width

-
angle: number

body angle in radians use deg2rad to convert +

Type Parameters

  • UserDataType = any

Parameters

Returns Box<UserDataType>

Properties

_group: number

group for collision filtering

+
_height: number

inner height

+
_width: number

inner width

+
angle: number

body angle in radians use deg2rad to convert move(speed) moves at 1 speed = 1px towards angle

bbox: BBox

bounding box cache, without padding

-
calcPoints: SATVector[]
centered: boolean = false

is body centered

-
convexPolygons: SATPolygon[]

optimization for convex polygons

-
dirty: boolean = false

was the polygon modified and needs update in the next checkCollision

-
edges: SATVector[]
isConvex = true

boxes are convex

-
isStatic: boolean

static bodies don't move but they collide

-
isTrigger: boolean

trigger bodies move but are like ghosts

-
maxX: number

maximum x bound of body

-
maxY: number

maximum y bound of body

-
minX: number

minimum x bound of body

-
minY: number

minimum y bound of body

-
normals: SATVector[]
offset: SATVector

each body may have offset from center

+
calcPoints: SATVector[]
centered: boolean = false

is body centered

+
convexPolygons: SATPolygon[]

optimization for convex polygons

+
dirty: boolean = false

was the polygon modified and needs update in the next checkCollision

+
edges: SATVector[]
isConvex = true

boxes are convex

+
isStatic: boolean

static bodies don't move but they collide

+
isTrigger: boolean

trigger bodies move but are like ghosts

+
maxX: number

maximum x bound of body

+
maxY: number

maximum y bound of body

+
minX: number

minimum x bound of body

+
minY: number

minimum y bound of body

+
normals: SATVector[]
offset: SATVector

each body may have offset from center

padding: number

bodies are not reinserted during update if their bbox didnt move outside bbox + padding

-
points: SATVector[]
pointsBackup: Vector[]

backup of points used for scaling

-
scaleVector: Vector = ...

scale Vector of body

-
system?: System<Body>

reference to collision system

-
type: Box | Point = BodyType.Box

type of body

-
typeGroup: Box | Point = BodyGroup.Box

faster than type

-
userData?: any

allows the user to set any misc data for client use

-

Accessors

points: SATVector[]
pointsBackup: Vector[]

backup of points used for scaling

+
scaleVector: Vector = ...

scale Vector of body

+
system?: System<Body>

reference to collision system

+
type: Box | Point = BodyType.Box

type of body

+
typeGroup: Box | Point = BodyGroup.Box

faster than type

+
userData?: any

allows the user to set any misc data for client use

+

Accessors

  • get group(): number
  • group for collision filtering

    Based on Box2D (tutorial)

    Values in BodyGroup are predefined and used each the body type and @@ -95,7 +95,7 @@

    0x7fffffff // member of all groups (can interact with everyting)
     
    -
  • set group(group): void
  • group for collision filtering

    +
  • set group(group): void
  • group for collision filtering

    Based on Box2D (tutorial)

    Values in BodyGroup are predefined and used each the body type and @@ -105,38 +105,38 @@

    0x7fffffff // member of all groups (can interact with everyting)
     
    -
    • get height(): number
    • get box height

      -

      Returns number

    • set height(height): void
    • set box height, update points

      -

      Parameters

      • height: number

      Returns void

    • get isCentered(): boolean
    • is polygon centered?

      -

      Returns boolean

    • set isCentered(isCentered): void
    • flag to set is polygon centered

      -

      Parameters

      • isCentered: boolean

      Returns void

    • get scale(): number
    • allow approx getting of scale

      -

      Returns number

    • set scale(scale): void
    • allow easier setting of scale

      -

      Parameters

      • scale: number

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      -

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      -

      Returns number

    Methods

    • after setting width/height update translate +

    • get height(): number
    • get box height

      +

      Returns number

    • set height(height): void
    • set box height, update points

      +

      Parameters

      • height: number

      Returns void

    • get isCentered(): boolean
    • is polygon centered?

      +

      Returns boolean

    • set isCentered(isCentered): void
    • flag to set is polygon centered

      +

      Parameters

      • isCentered: boolean

      Returns void

    • get scale(): number
    • allow approx getting of scale

      +

      Returns number

    • set scale(scale): void
    • allow easier setting of scale

      +

      Parameters

      • scale: number

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      +

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      +

      Returns number

    Methods

    • inner function for after position change update aabb in system and convex inner polygons

      -

      Parameters

      • updateNow: boolean = ...

      Returns void

    • update the position of the decomposed convex polygons (if any), called +

      Returns void

    • inner function for after position change update aabb in system and convex inner polygons

      +

      Parameters

      • updateNow: boolean = ...

      Returns void

    +

    Returns void

    diff --git a/docs/classes/Circle.html b/docs/classes/Circle.html index 8d77616..2880444 100644 --- a/docs/classes/Circle.html +++ b/docs/classes/Circle.html @@ -1,5 +1,5 @@ Circle | Detect-Collisions

    Class Circle<UserDataType>

    collider - circle

    -

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Implements

    Constructors

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Implements

    Constructors

    Properties

    _group angle bbox @@ -40,27 +40,27 @@ setScale updateBody

    Constructors

    Properties

    _group: number

    group for collision filtering

    -
    angle: number

    for compatibility reasons circle has angle

    -
    bbox: BBox

    bounding box cache, without padding

    -
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    -
    isCentered = true

    always centered

    -
    isConvex = true

    flag to show is it a convex body or non convex polygon

    -
    isStatic: boolean

    static bodies don't move but they collide

    -
    isTrigger: boolean

    trigger bodies move but are like ghosts

    -
    maxX: number

    maximum x bound of body

    -
    maxY: number

    maximum y bound of body

    -
    minX: number

    minimum x bound of body

    -
    minY: number

    minimum y bound of body

    -
    offset: SATVector

    offset

    -
    offsetCopy: Vector = ...

    offset copy without angle applied

    -
    padding: number

    bodies are not reinserted during update if their bbox didnt move outside bbox + padding

    -
    r: number
    system?: System<Body>

    reference to collision system

    -
    type: Circle = BodyType.Circle

    circle type

    -
    typeGroup: Circle = BodyGroup.Circle

    faster than type

    -
    unscaledRadius: number

    saved initial radius - internal

    -
    userData?: any

    allows the user to set any misc data for client use

    -

    Accessors

    Properties

    _group: number

    group for collision filtering

    +
    angle: number

    for compatibility reasons circle has angle

    +
    bbox: BBox

    bounding box cache, without padding

    +
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    +
    isCentered = true

    always centered

    +
    isConvex = true

    flag to show is it a convex body or non convex polygon

    +
    isStatic: boolean

    static bodies don't move but they collide

    +
    isTrigger: boolean

    trigger bodies move but are like ghosts

    +
    maxX: number

    maximum x bound of body

    +
    maxY: number

    maximum y bound of body

    +
    minX: number

    minimum x bound of body

    +
    minY: number

    minimum y bound of body

    +
    offset: SATVector

    offset

    +
    offsetCopy: Vector = ...

    offset copy without angle applied

    +
    padding: number

    bodies are not reinserted during update if their bbox didnt move outside bbox + padding

    +
    r: number
    system?: System<Body>

    reference to collision system

    +
    type: Circle = BodyType.Circle

    circle type

    +
    typeGroup: Circle = BodyGroup.Circle

    faster than type

    +
    unscaledRadius: number

    saved initial radius - internal

    +
    userData?: any

    allows the user to set any misc data for client use

    +

    Accessors

    • get group(): number
    • group for collision filtering

      Based on Box2D (tutorial)

      Values in BodyGroup are predefined and used each the body type and @@ -70,7 +70,7 @@

      0x7fffffff // member of all groups (can interact with everyting)
       
      -
  • set group(group): void
  • group for collision filtering

    +
  • set group(group): void
  • group for collision filtering

    Based on Box2D (tutorial)

    Values in BodyGroup are predefined and used each the body type and @@ -80,23 +80,23 @@

    0x7fffffff // member of all groups (can interact with everyting)
     
    -
    • get scaleX(): number
    • scaleX = scale in case of Circles

      -

      Returns number

    • get scaleY(): number
    • scaleY = scale in case of Circles

      -

      Returns number

    Methods

    • Draws collider on a CanvasRenderingContext2D's current path

      -

      Parameters

      • context: CanvasRenderingContext2D

      Returns void

    • update instantly or mark as dirty

      -

      Parameters

      • updateNow: boolean = false

      Returns void

    • inner function for after position change update aabb in system

      -

      Parameters

      • updateNow: boolean = ...

      Returns void

    +
    • get scaleX(): number
    • scaleX = scale in case of Circles

      +

      Returns number

    • get scaleY(): number
    • scaleY = scale in case of Circles

      +

      Returns number

    Methods

    • Draws collider on a CanvasRenderingContext2D's current path

      +

      Parameters

      • context: CanvasRenderingContext2D

      Returns void

    • update instantly or mark as dirty

      +

      Parameters

      • updateNow: boolean = false

      Returns void

    • inner function for after position change update aabb in system

      +

      Parameters

      • updateNow: boolean = ...

      Returns void

    diff --git a/docs/classes/Ellipse.html b/docs/classes/Ellipse.html index 5d50639..dd623a7 100644 --- a/docs/classes/Ellipse.html +++ b/docs/classes/Ellipse.html @@ -1,5 +1,5 @@ Ellipse | Detect-Collisions

    Class Ellipse<UserDataType>

    collider - ellipse

    -

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Constructors

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Constructors

    Properties

    Constructors

    Properties

    _group: number

    group for collision filtering

    -
    _radiusX: number

    inner initial params save

    -
    _radiusY: number
    _step: number
    angle: number

    body angle in radians use deg2rad to convert +

    Type Parameters

    • UserDataType = any

    Parameters

    Returns Ellipse<UserDataType>

    Properties

    _group: number

    group for collision filtering

    +
    _radiusX: number

    inner initial params save

    +
    _radiusY: number
    _step: number
    angle: number

    body angle in radians use deg2rad to convert move(speed) moves at 1 speed = 1px towards angle

    bbox: BBox

    bounding box cache, without padding

    -
    calcPoints: SATVector[]
    centered: boolean = false

    is body centered

    -
    convexPolygons: SATPolygon[]

    optimization for convex polygons

    -
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    -
    edges: SATVector[]
    isConvex = true

    ellipses are convex

    -
    isStatic: boolean

    static bodies don't move but they collide

    -
    isTrigger: boolean

    trigger bodies move but are like ghosts

    -
    maxX: number

    maximum x bound of body

    -
    maxY: number

    maximum y bound of body

    -
    minX: number

    minimum x bound of body

    -
    minY: number

    minimum y bound of body

    -
    normals: SATVector[]
    offset: SATVector

    each body may have offset from center

    +
    calcPoints: SATVector[]
    centered: boolean = false

    is body centered

    +
    convexPolygons: SATPolygon[]

    optimization for convex polygons

    +
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    +
    edges: SATVector[]
    isConvex = true

    ellipses are convex

    +
    isStatic: boolean

    static bodies don't move but they collide

    +
    isTrigger: boolean

    trigger bodies move but are like ghosts

    +
    maxX: number

    maximum x bound of body

    +
    maxY: number

    maximum y bound of body

    +
    minX: number

    minimum x bound of body

    +
    minY: number

    minimum y bound of body

    +
    normals: SATVector[]
    offset: SATVector

    each body may have offset from center

    padding: number

    bodies are not reinserted during update if their bbox didnt move outside bbox + padding

    -
    points: SATVector[]
    pointsBackup: Vector[]

    backup of points used for scaling

    -
    scaleVector: Vector = ...

    scale Vector of body

    -
    system?: System<Body>

    reference to collision system

    -
    type: Ellipse = BodyType.Ellipse

    ellipse type

    -
    typeGroup: Ellipse = BodyGroup.Ellipse

    faster than type

    -
    userData?: any

    allows the user to set any misc data for client use

    -

    Accessors

    points: SATVector[]
    pointsBackup: Vector[]

    backup of points used for scaling

    +
    scaleVector: Vector = ...

    scale Vector of body

    +
    system?: System<Body>

    reference to collision system

    +
    type: Ellipse = BodyType.Ellipse

    ellipse type

    +
    typeGroup: Ellipse = BodyGroup.Ellipse

    faster than type

    +
    userData?: any

    allows the user to set any misc data for client use

    +

    Accessors

    • get group(): number
    • group for collision filtering

      Based on Box2D (tutorial)

      Values in BodyGroup are predefined and used each the body type and @@ -96,7 +96,7 @@

      0x7fffffff // member of all groups (can interact with everyting)
       
      -
  • set group(group): void
  • group for collision filtering

    +
  • set group(group): void
  • group for collision filtering

    Based on Box2D (tutorial)

    Values in BodyGroup are predefined and used each the body type and @@ -106,39 +106,39 @@

    0x7fffffff // member of all groups (can interact with everyting)
     
    -
    • get isCentered(): boolean
    • is body centered?

      -

      Returns boolean

    • set isCentered(_isCentered): void
    • flag to set is body centered

      -

      Parameters

      • _isCentered: boolean

      Returns void

    • get scale(): number
    • allow approx getting of scale

      -

      Returns number

    • set scale(scale): void
    • allow easier setting of scale

      -

      Parameters

      • scale: number

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      -

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      -

      Returns number

    Methods

    • inner function for after position change update aabb in system and convex inner polygons

      -

      Parameters

      • updateNow: boolean = ...

      Returns void

    • update the position of the decomposed convex polygons (if any), called +

    • get isCentered(): boolean
    • is body centered?

      +

      Returns boolean

    • set isCentered(_isCentered): void
    • flag to set is body centered

      +

      Parameters

      • _isCentered: boolean

      Returns void

    • get scale(): number
    • allow approx getting of scale

      +

      Returns number

    • set scale(scale): void
    • allow easier setting of scale

      +

      Parameters

      • scale: number

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      +

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      +

      Returns number

    Methods

    • inner function for after position change update aabb in system and convex inner polygons

      +

      Parameters

      • updateNow: boolean = ...

      Returns void

    +

    Returns void

    diff --git a/docs/classes/Line.html b/docs/classes/Line.html index 4a7c11a..691a803 100644 --- a/docs/classes/Line.html +++ b/docs/classes/Line.html @@ -1,5 +1,5 @@ Line | Detect-Collisions

    Class Line<UserDataType>

    collider - line

    -

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Constructors

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Constructors

    Properties

    Constructors

    Properties

    _group: number

    group for collision filtering

    -
    angle: number

    body angle in radians use deg2rad to convert +

    Type Parameters

    • UserDataType = any

    Parameters

    Returns Line<UserDataType>

    Properties

    _group: number

    group for collision filtering

    +
    angle: number

    body angle in radians use deg2rad to convert move(speed) moves at 1 speed = 1px towards angle

    bbox: BBox

    bounding box cache, without padding

    -
    calcPoints: SATVector[]
    centered: boolean = false

    is body centered

    -
    convexPolygons: SATPolygon[]

    optimization for convex polygons

    -
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    -
    edges: SATVector[]
    isConvex = true

    line is convex

    -
    isStatic: boolean

    static bodies don't move but they collide

    -
    isTrigger: boolean

    trigger bodies move but are like ghosts

    -
    maxX: number

    maximum x bound of body

    -
    maxY: number

    maximum y bound of body

    -
    minX: number

    minimum x bound of body

    -
    minY: number

    minimum y bound of body

    -
    normals: SATVector[]
    offset: SATVector

    each body may have offset from center

    +
    calcPoints: SATVector[]
    centered: boolean = false

    is body centered

    +
    convexPolygons: SATPolygon[]

    optimization for convex polygons

    +
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    +
    edges: SATVector[]
    isConvex = true

    line is convex

    +
    isStatic: boolean

    static bodies don't move but they collide

    +
    isTrigger: boolean

    trigger bodies move but are like ghosts

    +
    maxX: number

    maximum x bound of body

    +
    maxY: number

    maximum y bound of body

    +
    minX: number

    minimum x bound of body

    +
    minY: number

    minimum y bound of body

    +
    normals: SATVector[]
    offset: SATVector

    each body may have offset from center

    padding: number

    bodies are not reinserted during update if their bbox didnt move outside bbox + padding

    -
    points: SATVector[]
    pointsBackup: Vector[]

    backup of points used for scaling

    -
    scaleVector: Vector = ...

    scale Vector of body

    -
    system?: System<Body>

    reference to collision system

    -
    type: Line = BodyType.Line

    line type

    -
    typeGroup: Line = BodyGroup.Line

    faster than type

    -
    userData?: any

    allows the user to set any misc data for client use

    -

    Accessors

    points: SATVector[]
    pointsBackup: Vector[]

    backup of points used for scaling

    +
    scaleVector: Vector = ...

    scale Vector of body

    +
    system?: System<Body>

    reference to collision system

    +
    type: Line = BodyType.Line

    line type

    +
    typeGroup: Line = BodyGroup.Line

    faster than type

    +
    userData?: any

    allows the user to set any misc data for client use

    +

    Accessors

    • get group(): number
    • group for collision filtering

      Based on Box2D (tutorial)

      Values in BodyGroup are predefined and used each the body type and @@ -90,7 +90,7 @@

      0x7fffffff // member of all groups (can interact with everyting)
       
      -
  • set group(group): void
  • group for collision filtering

    +
  • set group(group): void
  • group for collision filtering

    Based on Box2D (tutorial)

    Values in BodyGroup are predefined and used each the body type and @@ -100,32 +100,32 @@

    0x7fffffff // member of all groups (can interact with everyting)
     
    -
    • get isCentered(): boolean
    • is polygon centered?

      -

      Returns boolean

    • set isCentered(isCentered): void
    • flag to set is polygon centered

      -

      Parameters

      • isCentered: boolean

      Returns void

    • get scale(): number
    • allow approx getting of scale

      -

      Returns number

    • set scale(scale): void
    • allow easier setting of scale

      -

      Parameters

      • scale: number

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      -

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      -

      Returns number

    Methods

    • inner function for after position change update aabb in system and convex inner polygons

      -

      Parameters

      • updateNow: boolean = ...

      Returns void

    • update the position of the decomposed convex polygons (if any), called +

    • get isCentered(): boolean
    • is polygon centered?

      +

      Returns boolean

    • set isCentered(isCentered): void
    • flag to set is polygon centered

      +

      Parameters

      • isCentered: boolean

      Returns void

    • get scale(): number
    • allow approx getting of scale

      +

      Returns number

    • set scale(scale): void
    • allow easier setting of scale

      +

      Parameters

      • scale: number

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      +

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      +

      Returns number

    Methods

    • inner function for after position change update aabb in system and convex inner polygons

      +

      Parameters

      • updateNow: boolean = ...

      Returns void

    +

    Returns void

    diff --git a/docs/classes/Point.html b/docs/classes/Point.html index 60181aa..6219b79 100644 --- a/docs/classes/Point.html +++ b/docs/classes/Point.html @@ -1,5 +1,5 @@ Point | Detect-Collisions

    Class Point<UserDataType>

    collider - point (very tiny box)

    -

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Constructors

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Constructors

    Properties

    Constructors

    Properties

    _group: number

    group for collision filtering

    -
    _height: number

    inner height

    -
    _width: number

    inner width

    -
    angle: number

    body angle in radians use deg2rad to convert +

    Type Parameters

    • UserDataType = any

    Parameters

    Returns Point<UserDataType>

    Properties

    _group: number

    group for collision filtering

    +
    _height: number

    inner height

    +
    _width: number

    inner width

    +
    angle: number

    body angle in radians use deg2rad to convert move(speed) moves at 1 speed = 1px towards angle

    bbox: BBox

    bounding box cache, without padding

    -
    calcPoints: SATVector[]
    centered: boolean = false

    is body centered

    -
    convexPolygons: SATPolygon[]

    optimization for convex polygons

    -
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    -
    edges: SATVector[]
    isConvex = true

    boxes are convex

    -
    isStatic: boolean

    static bodies don't move but they collide

    -
    isTrigger: boolean

    trigger bodies move but are like ghosts

    -
    maxX: number

    maximum x bound of body

    -
    maxY: number

    maximum y bound of body

    -
    minX: number

    minimum x bound of body

    -
    minY: number

    minimum y bound of body

    -
    normals: SATVector[]
    offset: SATVector

    each body may have offset from center

    +
    calcPoints: SATVector[]
    centered: boolean = false

    is body centered

    +
    convexPolygons: SATPolygon[]

    optimization for convex polygons

    +
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    +
    edges: SATVector[]
    isConvex = true

    boxes are convex

    +
    isStatic: boolean

    static bodies don't move but they collide

    +
    isTrigger: boolean

    trigger bodies move but are like ghosts

    +
    maxX: number

    maximum x bound of body

    +
    maxY: number

    maximum y bound of body

    +
    minX: number

    minimum x bound of body

    +
    minY: number

    minimum y bound of body

    +
    normals: SATVector[]
    offset: SATVector

    each body may have offset from center

    padding: number

    bodies are not reinserted during update if their bbox didnt move outside bbox + padding

    -
    points: SATVector[]
    pointsBackup: Vector[]

    backup of points used for scaling

    -
    scaleVector: Vector = ...

    scale Vector of body

    -
    system?: System<Body>

    reference to collision system

    -
    type: Point = BodyType.Point

    point type

    -
    typeGroup: Point = BodyGroup.Point

    faster than type

    -
    userData?: any

    allows the user to set any misc data for client use

    -

    Accessors

    points: SATVector[]
    pointsBackup: Vector[]

    backup of points used for scaling

    +
    scaleVector: Vector = ...

    scale Vector of body

    +
    system?: System<Body>

    reference to collision system

    +
    type: Point = BodyType.Point

    point type

    +
    typeGroup: Point = BodyGroup.Point

    faster than type

    +
    userData?: any

    allows the user to set any misc data for client use

    +

    Accessors

    • get group(): number
    • group for collision filtering

      Based on Box2D (tutorial)

      Values in BodyGroup are predefined and used each the body type and @@ -95,7 +95,7 @@

      0x7fffffff // member of all groups (can interact with everyting)
       
      -
  • set group(group): void
  • group for collision filtering

    +
  • set group(group): void
  • group for collision filtering

    Based on Box2D (tutorial)

    Values in BodyGroup are predefined and used each the body type and @@ -105,38 +105,38 @@

    0x7fffffff // member of all groups (can interact with everyting)
     
    -
    • get height(): number
    • get box height

      -

      Returns number

    • set height(height): void
    • set box height, update points

      -

      Parameters

      • height: number

      Returns void

    • get isCentered(): boolean
    • is polygon centered?

      -

      Returns boolean

    • set isCentered(isCentered): void
    • flag to set is polygon centered

      -

      Parameters

      • isCentered: boolean

      Returns void

    • get scale(): number
    • allow approx getting of scale

      -

      Returns number

    • set scale(scale): void
    • allow easier setting of scale

      -

      Parameters

      • scale: number

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      -

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      -

      Returns number

    • get width(): number
    • get box width

      -

      Returns number

    • set width(width): void
    • set box width, update points

      -

      Parameters

      • width: number

      Returns void

    Methods

    • after setting width/height update translate +

    • get height(): number
    • get box height

      +

      Returns number

    • set height(height): void
    • set box height, update points

      +

      Parameters

      • height: number

      Returns void

    • get isCentered(): boolean
    • is polygon centered?

      +

      Returns boolean

    • set isCentered(isCentered): void
    • flag to set is polygon centered

      +

      Parameters

      • isCentered: boolean

      Returns void

    • get scale(): number
    • allow approx getting of scale

      +

      Returns number

    • set scale(scale): void
    • allow easier setting of scale

      +

      Parameters

      • scale: number

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      +

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      +

      Returns number

    • get width(): number
    • get box width

      +

      Returns number

    • set width(width): void
    • set box width, update points

      +

      Parameters

      • width: number

      Returns void

    Methods

    • Draws exact collider on canvas context

      -

      Parameters

      • context: CanvasRenderingContext2D

      Returns void

    • Draws Bounding Box on canvas context

      -

      Parameters

      • context: CanvasRenderingContext2D

      Returns void

    • inner function for after position change update aabb in system and convex inner polygons

      -

      Parameters

      • updateNow: boolean = ...

      Returns void

    • Draws exact collider on canvas context

      +

      Parameters

      • context: CanvasRenderingContext2D

      Returns void

    • Draws Bounding Box on canvas context

      +

      Parameters

      • context: CanvasRenderingContext2D

      Returns void

    • inner function for after position change update aabb in system and convex inner polygons

      +

      Parameters

      • updateNow: boolean = ...

      Returns void

    +

    Returns void

    diff --git a/docs/classes/Polygon.html b/docs/classes/Polygon.html index edf0948..77e1707 100644 --- a/docs/classes/Polygon.html +++ b/docs/classes/Polygon.html @@ -1,5 +1,5 @@ Polygon | Detect-Collisions

    Class Polygon<UserDataType>

    collider - polygon

    -

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Implements

    Constructors

    Type Parameters

    • UserDataType = any

    Hierarchy (view full)

    Implements

    Constructors

    Properties

    Constructors

    Properties

    _group: number

    group for collision filtering

    -
    angle: number

    body angle in radians use deg2rad to convert +

    Type Parameters

    • UserDataType = any

    Parameters

    Returns Polygon<UserDataType>

    Properties

    _group: number

    group for collision filtering

    +
    angle: number

    body angle in radians use deg2rad to convert move(speed) moves at 1 speed = 1px towards angle

    bbox: BBox

    bounding box cache, without padding

    -
    calcPoints: SATVector[]
    centered: boolean = false

    is body centered

    -
    convexPolygons: SATPolygon[]

    optimization for convex polygons

    -
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    -
    edges: SATVector[]
    isConvex: boolean

    is it a convex polgyon as opposed to a hollow inside (concave) polygon

    -
    isStatic: boolean

    static bodies don't move but they collide

    -
    isTrigger: boolean

    trigger bodies move but are like ghosts

    -
    maxX: number

    maximum x bound of body

    -
    maxY: number

    maximum y bound of body

    -
    minX: number

    minimum x bound of body

    -
    minY: number

    minimum y bound of body

    -
    normals: SATVector[]
    offset: SATVector

    each body may have offset from center

    +
    calcPoints: SATVector[]
    centered: boolean = false

    is body centered

    +
    convexPolygons: SATPolygon[]

    optimization for convex polygons

    +
    dirty: boolean = false

    was the polygon modified and needs update in the next checkCollision

    +
    edges: SATVector[]
    isConvex: boolean

    is it a convex polgyon as opposed to a hollow inside (concave) polygon

    +
    isStatic: boolean

    static bodies don't move but they collide

    +
    isTrigger: boolean

    trigger bodies move but are like ghosts

    +
    maxX: number

    maximum x bound of body

    +
    maxY: number

    maximum y bound of body

    +
    minX: number

    minimum x bound of body

    +
    minY: number

    minimum y bound of body

    +
    normals: SATVector[]
    offset: SATVector

    each body may have offset from center

    padding: number

    bodies are not reinserted during update if their bbox didnt move outside bbox + padding

    -
    points: SATVector[]
    pointsBackup: Vector[]

    backup of points used for scaling

    -
    scaleVector: Vector = ...

    scale Vector of body

    -
    system?: System<Body>

    reference to collision system

    -
    type:
        | Ellipse
        | Polygon
        | Box
        | Line
        | Point = BodyType.Polygon

    type of body

    -
    typeGroup:
        | Ellipse
        | Polygon
        | Box
        | Line
        | Point = BodyGroup.Polygon

    faster than type

    -
    userData?: any

    allows the user to set any misc data for client use

    -

    Accessors

    points: SATVector[]
    pointsBackup: Vector[]

    backup of points used for scaling

    +
    scaleVector: Vector = ...

    scale Vector of body

    +
    system?: System<Body>

    reference to collision system

    +
    type:
        | Ellipse
        | Polygon
        | Box
        | Line
        | Point = BodyType.Polygon

    type of body

    +
    typeGroup:
        | Ellipse
        | Polygon
        | Box
        | Line
        | Point = BodyGroup.Polygon

    faster than type

    +
    userData?: any

    allows the user to set any misc data for client use

    +

    Accessors

    • get group(): number
    • group for collision filtering

      Based on Box2D (tutorial)

      Values in BodyGroup are predefined and used each the body type and @@ -88,7 +88,7 @@

      0x7fffffff // member of all groups (can interact with everyting)
       
      -
  • set group(group): void
  • group for collision filtering

    +
  • set group(group): void
  • group for collision filtering

    Based on Box2D (tutorial)

    Values in BodyGroup are predefined and used each the body type and @@ -98,32 +98,32 @@

    0x7fffffff // member of all groups (can interact with everyting)
     
    -
    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      -

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      -

      Returns number

    Methods

    • if true, polygon is not an invalid, self-crossing polygon

      -

      Returns boolean

    • update instantly or mark as dirty

      -

      Parameters

      • updateNow: boolean = false

      Returns void

    • inner function for after position change update aabb in system and convex inner polygons

      -

      Parameters

      • updateNow: boolean = ...

      Returns void

    • get scaleX(): number
    • allow exact getting of scale x - use setScale(x, y) to set

      +

      Returns number

    • get scaleY(): number
    • allow exact getting of scale y - use setScale(x, y) to set

      +

      Returns number

    Methods

    • if true, polygon is not an invalid, self-crossing polygon

      +

      Returns boolean

    • update instantly or mark as dirty

      +

      Parameters

      • updateNow: boolean = false

      Returns void

    • inner function for after position change update aabb in system and convex inner polygons

      +

      Parameters

      • updateNow: boolean = ...

      Returns void

    • update the position of the decomposed convex polygons (if any), called after the position of the body has changed

      -

      Returns void

    +

    Returns void

    diff --git a/docs/classes/System.html b/docs/classes/System.html index fe206f3..0d4ef3f 100644 --- a/docs/classes/System.html +++ b/docs/classes/System.html @@ -47,29 +47,29 @@ traverse update updateBody -

    Constructors

    Properties

    _maxEntries: number
    _minEntries: number
    ray: Line<any>

    for raycasting

    +

    Constructors

    Properties

    _maxEntries: number
    _minEntries: number
    ray: Line<any>

    for raycasting

    response: Response = ...

    the last collision result

    Methods

    • Parameters

      • bbox: any
      • path: any
      • level: any

      Returns void

    • Parameters

      • node: any
      • result: any

      Returns any

    • Parameters

      • node: any
      • m: any
      • M: any
      • compare: any

      Returns number

    • Parameters

      • items: any
      • left: any
      • right: any
      • height: any

      Returns {
          children: any;
          height: number;
          leaf: boolean;
          maxX: number;
          maxY: number;
          minX: number;
          minY: number;
      }

      • children: any
      • height: number
      • leaf: boolean
      • maxX: number
      • maxY: number
      • minX: number
      • minY: number
    • Parameters

      • node: any
      • m: any
      • M: any

      Returns void

    • Parameters

      • node: any
      • m: any
      • M: any

      Returns any

    • Parameters

      • bbox: any
      • node: any
      • level: any
      • path: any

      Returns any

    • Parameters

      • item: any
      • level: any
      • isNode: any

      Returns void

    • Parameters

      • insertPath: any
      • level: any

      Returns void

    • Parameters

      • node: any
      • newNode: any

      Returns void

    • check do 2 objects collide

      Parameters

      Returns boolean

    • Parameters

      • bbox: any

      Returns boolean

    • Parameters

      • a: any
      • b: any

      Returns number

    • Parameters

      • a: any
      • b: any

      Returns number

    • create box at position with options and add to system

      -

      Type Parameters

      • TBox extends Box<any>

      Parameters

      Returns TBox

    • create ellipse at position with options and add to system

      -

      Type Parameters

      Parameters

      Returns TEllipse

    • draw exact bodies colliders outline

      -

      Parameters

      • context: CanvasRenderingContext2D

      Returns void

    • draw bounding boxes hierarchy outline

      -

      Parameters

      • context: CanvasRenderingContext2D
      • isTrigger: boolean = true

      Returns void

    • Parameters

      • bbox: any

      Returns boolean

    • Parameters

      • a: any
      • b: any

      Returns number

    • Parameters

      • a: any
      • b: any

      Returns number

    • draw exact bodies colliders outline

      +

      Parameters

      • context: CanvasRenderingContext2D

      Returns void

    • draw bounding boxes hierarchy outline

      +

      Parameters

      • context: CanvasRenderingContext2D
      • isTrigger: boolean = true

      Returns void

    • get object potential colliders

      Parameters

      Returns TBody[]

      because it's slower to use than checkOne() or checkAll()

      -
    • re-insert body into collision tree and update its bbox +

    • re-insert body into collision tree and update its bbox every body can be part of only one system

      Parameters

      Returns this

    • remove body aabb from collision tree

      -

      Parameters

      Returns this

    • separate (move away) bodies

      +

      Parameters

      Returns this

    • separate (move away) 1 body, with optional callback before collision

      Parameters

      Returns void

    • used to find body deep inside data with finder function returning boolean found or not

      -

      Parameters

      Returns undefined | TBody

    • update all bodies aabb

      -

      Returns void

    • updates body in collision tree

      -

      Parameters

      Returns void

    +

    Parameters

    Returns undefined | TBody

    • update all bodies aabb

      +

      Returns void

    • updates body in collision tree

      +

      Parameters

      Returns void

    diff --git a/docs/demo/demo.js b/docs/demo/demo.js index 9d5e33d..d8b609c 100644 --- a/docs/demo/demo.js +++ b/docs/demo/demo.js @@ -2067,48 +2067,54 @@ class BaseSystem extends model_1.RBush { /** * create point at position with options and add to system */ - createPoint(position, options) { - const point = new point_1.Point(position, options); + createPoint(position, options, Class) { + const PointClass = Class || point_1.Point; + const point = new PointClass(position, options); this.insert(point); return point; } /** * create line at position with options and add to system */ - createLine(start, end, options) { - const line = new line_1.Line(start, end, options); + createLine(start, end, options, Class) { + const LineClass = Class || line_1.Line; + const line = new LineClass(start, end, options); this.insert(line); return line; } /** * create circle at position with options and add to system */ - createCircle(position, radius, options) { - const circle = new circle_1.Circle(position, radius, options); + createCircle(position, radius, options, Class) { + const CircleClass = Class || circle_1.Circle; + const circle = new CircleClass(position, radius, options); this.insert(circle); return circle; } /** * create box at position with options and add to system */ - createBox(position, width, height, options) { - const box = new box_1.Box(position, width, height, options); + createBox(position, width, height, options, Class) { + const BoxClass = Class || box_1.Box; + const box = new BoxClass(position, width, height, options); this.insert(box); return box; } /** * create ellipse at position with options and add to system */ - createEllipse(position, radiusX, radiusY = radiusX, step, options) { - const ellipse = new ellipse_1.Ellipse(position, radiusX, radiusY, step, options); + createEllipse(position, radiusX, radiusY = radiusX, step, options, Class) { + const EllipseClass = Class || ellipse_1.Ellipse; + const ellipse = new EllipseClass(position, radiusX, radiusY, step, options); this.insert(ellipse); return ellipse; } /** * create polygon at position with options and add to system */ - createPolygon(position, points, options) { - const polygon = new polygon_1.Polygon(position, points, options); + createPolygon(position, points, options, Class) { + const PolygonClass = Class || polygon_1.Polygon; + const polygon = new PolygonClass(position, points, options); this.insert(polygon); return polygon; } @@ -2769,9 +2775,8 @@ exports.Point = Point; "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.Polygon = exports.isSimple = void 0; +exports.Polygon = void 0; const poly_decomp_es_1 = __webpack_require__(/*! poly-decomp-es */ "./node_modules/poly-decomp-es/dist/poly-decomp-es.js"); -Object.defineProperty(exports, "isSimple", ({ enumerable: true, get: function () { return poly_decomp_es_1.isSimple; } })); const model_1 = __webpack_require__(/*! ../model */ "./src/model.ts"); const optimized_1 = __webpack_require__(/*! ../optimized */ "./src/optimized.ts"); const utils_1 = __webpack_require__(/*! ../utils */ "./src/utils.ts"); diff --git a/docs/interfaces/BoxConstructor.html b/docs/interfaces/BoxConstructor.html new file mode 100644 index 0000000..5ffb331 --- /dev/null +++ b/docs/interfaces/BoxConstructor.html @@ -0,0 +1,2 @@ +BoxConstructor | Detect-Collisions

    Interface BoxConstructor<TBox>

    interface BoxConstructor<TBox> {
        new BoxConstructornew (position: PotentialVector, width: number, height: number, options?: BodyOptions<any>): TBox;
    }

    Type Parameters

    • TBox extends Box

    Constructors

    Constructors

    diff --git a/docs/interfaces/CircleConstructor.html b/docs/interfaces/CircleConstructor.html new file mode 100644 index 0000000..0ecfd83 --- /dev/null +++ b/docs/interfaces/CircleConstructor.html @@ -0,0 +1,2 @@ +CircleConstructor | Detect-Collisions

    Interface CircleConstructor<TCircle>

    interface CircleConstructor<TCircle> {
        new CircleConstructornew (position: PotentialVector, radius: number, options?: BodyOptions<any>): TCircle;
    }

    Type Parameters

    Constructors

    Constructors

    diff --git a/docs/interfaces/EllipseConstructor.html b/docs/interfaces/EllipseConstructor.html new file mode 100644 index 0000000..c668d3e --- /dev/null +++ b/docs/interfaces/EllipseConstructor.html @@ -0,0 +1,2 @@ +EllipseConstructor | Detect-Collisions

    Interface EllipseConstructor<TEllipse>

    interface EllipseConstructor<TEllipse> {
        new EllipseConstructornew (position: PotentialVector, radiusX: number, radiusY?: number, step?: number, options?: BodyOptions<any>): TEllipse;
    }

    Type Parameters

    Constructors

    Constructors

    diff --git a/docs/interfaces/LineConstructor.html b/docs/interfaces/LineConstructor.html new file mode 100644 index 0000000..11aefac --- /dev/null +++ b/docs/interfaces/LineConstructor.html @@ -0,0 +1,2 @@ +LineConstructor | Detect-Collisions

    Interface LineConstructor<TLine>

    interface LineConstructor<TLine> {
        new LineConstructornew (start: Vector, end: Vector, options?: BodyOptions<any>): TLine;
    }

    Type Parameters

    Constructors

    Constructors

    diff --git a/docs/interfaces/PointConstructor.html b/docs/interfaces/PointConstructor.html new file mode 100644 index 0000000..0fbd4ae --- /dev/null +++ b/docs/interfaces/PointConstructor.html @@ -0,0 +1,2 @@ +PointConstructor | Detect-Collisions

    Interface PointConstructor<TPoint>

    interface PointConstructor<TPoint> {
        new PointConstructornew (position: PotentialVector, options?: BodyOptions<any>): TPoint;
    }

    Type Parameters

    Constructors

    Constructors

    diff --git a/docs/interfaces/PolygonConstructor.html b/docs/interfaces/PolygonConstructor.html new file mode 100644 index 0000000..a078e91 --- /dev/null +++ b/docs/interfaces/PolygonConstructor.html @@ -0,0 +1,2 @@ +PolygonConstructor | Detect-Collisions

    Interface PolygonConstructor<TPolygon>

    interface PolygonConstructor<TPolygon> {
        new PolygonConstructornew (position: PotentialVector, points: PotentialVector[], options?: BodyOptions<any>): TPolygon;
    }

    Type Parameters

    Constructors

    Constructors

    diff --git a/docs/modules.html b/docs/modules.html index ba2ebba..ee99e01 100644 --- a/docs/modules.html +++ b/docs/modules.html @@ -15,9 +15,15 @@

    Interfaces

    BBox BodyOptions BodyProps +BoxConstructor ChildrenData +CircleConstructor Data +EllipseConstructor GetAABBAsBox +LineConstructor +PointConstructor +PolygonConstructor PotentialVector RaycastHit Vector diff --git a/package.json b/package.json index 52255f6..b98034d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "detect-collisions", - "version": "9.19.1", + "version": "9.20.0", "description": "Detect collisions between different shapes such as Points, Lines, Boxes, Polygons (including concave), Ellipses, and Circles. Features include RayCasting and support for offsets, rotation, scaling, bounding box padding, with options for static and trigger bodies (non-colliding).", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/base-system.ts b/src/base-system.ts index f951659..ca51bf3 100644 --- a/src/base-system.ts +++ b/src/base-system.ts @@ -13,19 +13,20 @@ import { import { filter, forEach } from "./optimized"; import { bodyMoved, drawBVH } from "./utils"; -import { Box } from "./bodies/box"; -import { Circle } from "./bodies/circle"; -import { Ellipse } from "./bodies/ellipse"; -import { Line } from "./bodies/line"; -import { Point } from "./bodies/point"; -import { Polygon } from "./bodies/polygon"; +import { Box, BoxConstructor } from "./bodies/box"; +import { Circle, CircleConstructor } from "./bodies/circle"; +import { Ellipse, EllipseConstructor } from "./bodies/ellipse"; +import { Line, LineConstructor } from "./bodies/line"; +import { Point, PointConstructor } from "./bodies/point"; +import { Polygon, PolygonConstructor } from "./bodies/polygon"; /** * very base collision system (create, insert, update, draw, remove) */ export class BaseSystem extends RBush - implements Data { + implements Data +{ data!: ChildrenData; /** @@ -33,13 +34,15 @@ export class BaseSystem */ createPoint( position: PotentialVector, - options?: BodyOptions - ): TPoint { - const point = new Point(position, options); + options?: BodyOptions, + Class?: PointConstructor + ): TPoint | Point { + const PointClass = Class || Point; + const point = new PointClass(position, options); this.insert(point as TBody); - return point as TPoint; + return point; } /** @@ -48,13 +51,15 @@ export class BaseSystem createLine( start: Vector, end: Vector, - options?: BodyOptions - ): TLine { - const line = new Line(start, end, options); + options?: BodyOptions, + Class?: LineConstructor + ): TLine | Line { + const LineClass = Class || Line; + const line = new LineClass(start, end, options); this.insert(line as TBody); - return line as TLine; + return line; } /** @@ -63,13 +68,15 @@ export class BaseSystem createCircle( position: PotentialVector, radius: number, - options?: BodyOptions - ): TCircle { - const circle = new Circle(position, radius, options); + options?: BodyOptions, + Class?: CircleConstructor + ): TCircle | Circle { + const CircleClass = Class || Circle; + const circle = new CircleClass(position, radius, options); this.insert(circle as TBody); - return circle as TCircle; + return circle; } /** @@ -79,13 +86,15 @@ export class BaseSystem position: PotentialVector, width: number, height: number, - options?: BodyOptions - ): TBox { - const box = new Box(position, width, height, options); + options?: BodyOptions, + Class?: BoxConstructor + ): TBox | Box { + const BoxClass = Class || Box; + const box = new BoxClass(position, width, height, options); this.insert(box as TBody); - return box as TBox; + return box; } /** @@ -96,13 +105,15 @@ export class BaseSystem radiusX: number, radiusY: number = radiusX, step?: number, - options?: BodyOptions - ): TEllipse { - const ellipse = new Ellipse(position, radiusX, radiusY, step, options); + options?: BodyOptions, + Class?: EllipseConstructor + ): TEllipse | Ellipse { + const EllipseClass = Class || Ellipse; + const ellipse = new EllipseClass(position, radiusX, radiusY, step, options); this.insert(ellipse as TBody); - return ellipse as TEllipse; + return ellipse; } /** @@ -111,13 +122,15 @@ export class BaseSystem createPolygon( position: PotentialVector, points: PotentialVector[], - options?: BodyOptions - ): TPolygon { - const polygon = new Polygon(position, points, options); + options?: BodyOptions, + Class?: PolygonConstructor + ): TPolygon | Polygon { + const PolygonClass = Class || Polygon; + const polygon = new PolygonClass(position, points, options); this.insert(polygon as TBody); - return polygon as TPolygon; + return polygon; } /** diff --git a/src/bodies/box.ts b/src/bodies/box.ts index e277c90..a56d39f 100644 --- a/src/bodies/box.ts +++ b/src/bodies/box.ts @@ -3,6 +3,15 @@ import { BodyGroup, BodyOptions, BodyType, PotentialVector } from "../model"; import { createBox } from "../utils"; import { Polygon } from "./polygon"; +export interface BoxConstructor { + new ( + position: PotentialVector, + width: number, + height: number, + options?: BodyOptions + ): TBox; +} + /** * collider - box */ @@ -39,7 +48,7 @@ export class Box extends Polygon { position: PotentialVector, width: number, height: number, - options?: BodyOptions, + options?: BodyOptions ) { super(position, createBox(width, height), options); diff --git a/src/bodies/circle.ts b/src/bodies/circle.ts index 428c967..3e44db9 100644 --- a/src/bodies/circle.ts +++ b/src/bodies/circle.ts @@ -20,12 +20,21 @@ import { import { Circle as SATCircle } from "sat"; import { System } from "../system"; +export interface CircleConstructor { + new ( + position: PotentialVector, + radius: number, + options?: BodyOptions + ): TCircle; +} + /** * collider - circle */ export class Circle extends SATCircle - implements BBox, BodyProps { + implements BBox, BodyProps +{ /** * minimum x bound of body */ @@ -132,7 +141,7 @@ export class Circle constructor( position: PotentialVector, radius: number, - options?: BodyOptions, + options?: BodyOptions ) { super(ensureVectorPoint(position), radius); diff --git a/src/bodies/ellipse.ts b/src/bodies/ellipse.ts index 7009e49..fac59e3 100644 --- a/src/bodies/ellipse.ts +++ b/src/bodies/ellipse.ts @@ -3,6 +3,16 @@ import { BodyGroup, BodyOptions, BodyType, PotentialVector } from "../model"; import { createEllipse } from "../utils"; import { Polygon } from "./polygon"; +export interface EllipseConstructor { + new ( + position: PotentialVector, + radiusX: number, + radiusY?: number, + step?: number, + options?: BodyOptions + ): TEllipse; +} + /** * collider - ellipse */ @@ -37,7 +47,7 @@ export class Ellipse extends Polygon { radiusX: number, radiusY: number = radiusX, step: number = (radiusX + radiusY) / Math.PI, - options?: BodyOptions, + options?: BodyOptions ) { super(position, createEllipse(radiusX, radiusY, step), options); diff --git a/src/bodies/line.ts b/src/bodies/line.ts index 3776339..dcbab9c 100644 --- a/src/bodies/line.ts +++ b/src/bodies/line.ts @@ -3,6 +3,10 @@ import { BodyGroup, BodyOptions, BodyType, Vector } from "../model"; import { Vector as SATVector } from "sat"; import { Polygon } from "./polygon"; +export interface LineConstructor { + new (start: Vector, end: Vector, options?: BodyOptions): TLine; +} + /** * collider - line */ @@ -32,7 +36,7 @@ export class Line extends Polygon { { x: 0, y: 0 }, { x: end.x - start.x, y: end.y - start.y }, ], - options, + options ); if (this.calcPoints.length === 1 || !end) { @@ -76,7 +80,7 @@ export class Line extends Polygon { getCentroid(): SATVector { return new SATVector( (this.end.x - this.start.x) / 2, - (this.end.y - this.start.y) / 2, + (this.end.y - this.start.y) / 2 ); } diff --git a/src/bodies/point.ts b/src/bodies/point.ts index 5c16426..260b3ef 100644 --- a/src/bodies/point.ts +++ b/src/bodies/point.ts @@ -3,6 +3,10 @@ import { BodyGroup, BodyOptions, BodyType, PotentialVector } from "../model"; import { ensureVectorPoint } from "../utils"; import { Box } from "./box"; +export interface PointConstructor { + new (position: PotentialVector, options?: BodyOptions): TPoint; +} + /** * collider - point (very tiny box) */ diff --git a/src/bodies/polygon.ts b/src/bodies/polygon.ts index ffa5208..1c51571 100644 --- a/src/bodies/polygon.ts +++ b/src/bodies/polygon.ts @@ -28,7 +28,13 @@ import { import { Polygon as SATPolygon } from "sat"; import { System } from "../system"; -export { isSimple }; +export interface PolygonConstructor { + new ( + position: PotentialVector, + points: PotentialVector[], + options?: BodyOptions, + ): TPolygon; +} /** * collider - polygon diff --git a/src/system.spec.js b/src/system.spec.js index dc0c905..935667b 100644 --- a/src/system.spec.js +++ b/src/system.spec.js @@ -184,4 +184,21 @@ describe("GIVEN System", () => { expectToBeNear(hit.point.y, 70, 10); }); }); + + it("THEN I can provide custom class to body create functions", () => { + const { System, Polygon } = require("."); + const physics = new System(); + + class MyPolygon extends Polygon { + constructor(position, points, options) { + super(position, points, options); + this.foo = "bar"; + } + } + + // create minimal MyPolygon and insert to system + const myPolygon = physics.createPolygon({}, [{}], {}, MyPolygon); + + expect(myPolygon.foo).toBe("bar"); + }); });