@zylem/game-lib 0.3.15 → 0.3.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -13
- package/dist/.vite/manifest.json +665 -2
- package/dist/actions.d.ts +4 -0
- package/dist/actions.js +10 -0
- package/dist/behaviors.d.ts +3 -0
- package/dist/behaviors.js +8 -0
- package/dist/camera.d.ts +3 -0
- package/dist/camera.js +6 -0
- package/dist/core.d.ts +5 -0
- package/dist/core.js +11 -0
- package/dist/entities.d.ts +8 -0
- package/dist/entities.js +19 -0
- package/dist/lib/actions/behaviors/actions.js +35 -0
- package/dist/lib/actions/behaviors/boundaries/boundary.d.ts +1 -1
- package/dist/lib/actions/behaviors/boundaries/boundary.js +40 -0
- package/dist/lib/actions/behaviors/ricochet/ricochet-2d-collision.js +100 -0
- package/dist/lib/actions/behaviors/ricochet/ricochet-2d-in-bounds.js +37 -0
- package/dist/lib/actions/behaviors/ricochet/ricochet.d.ts +2 -0
- package/dist/lib/actions/behaviors/ricochet/ricochet.js +6 -0
- package/dist/lib/actions/capabilities/moveable.js +108 -0
- package/dist/lib/actions/capabilities/rotatable.js +82 -0
- package/dist/lib/actions/capabilities/transformable.js +9 -0
- package/dist/lib/actions/global-change.js +40 -0
- package/dist/lib/camera/camera.js +19 -0
- package/dist/lib/camera/fixed-2d.js +30 -0
- package/dist/lib/camera/perspective.js +10 -0
- package/dist/lib/camera/third-person.js +42 -0
- package/dist/lib/camera/zylem-camera.js +145 -0
- package/dist/lib/collision/collision-builder.js +46 -0
- package/dist/lib/collision/collision-delegate.js +6 -0
- package/dist/lib/collision/utils.js +24 -0
- package/dist/lib/collision/world.js +77 -0
- package/dist/lib/core/base-node-life-cycle.d.ts +14 -0
- package/dist/lib/core/base-node.d.ts +6 -2
- package/dist/lib/core/base-node.js +62 -0
- package/dist/lib/core/entity-asset-loader.js +57 -0
- package/dist/lib/core/lazy-loader.d.ts +2 -2
- package/dist/lib/core/lifecycle-base.js +20 -0
- package/dist/lib/core/preset-shader.js +30 -0
- package/dist/lib/core/three-addons/Timer.js +103 -0
- package/dist/lib/core/utility/nodes.d.ts +11 -0
- package/dist/lib/core/utility/nodes.js +27 -0
- package/dist/lib/core/utility/strings.d.ts +2 -0
- package/dist/lib/core/utility/strings.js +14 -0
- package/dist/lib/core/{utility.d.ts → utility/vector.d.ts} +0 -2
- package/dist/lib/core/utility/vector.js +8 -0
- package/dist/lib/core/vessel.d.ts +3 -1
- package/dist/lib/core/vessel.js +27 -0
- package/dist/lib/debug/console/console-state.js +11 -0
- package/dist/lib/debug/debug-state.js +40 -0
- package/dist/lib/device/aspect-ratio.d.ts +37 -0
- package/dist/lib/device/aspect-ratio.js +44 -0
- package/dist/lib/entities/actor.js +125 -0
- package/dist/lib/entities/box.js +68 -0
- package/dist/lib/entities/builder.js +79 -0
- package/dist/lib/entities/create.js +31 -0
- package/dist/lib/entities/delegates/animation.js +58 -0
- package/dist/lib/entities/delegates/debug.js +72 -0
- package/dist/lib/entities/delegates/loader.js +19 -0
- package/dist/lib/entities/destroy.js +15 -0
- package/dist/lib/entities/entity.d.ts +3 -1
- package/dist/lib/entities/entity.js +120 -0
- package/dist/lib/entities/plane.js +81 -0
- package/dist/lib/entities/rect.js +160 -0
- package/dist/lib/entities/sphere.js +68 -0
- package/dist/lib/entities/sprite.js +118 -0
- package/dist/lib/entities/text.js +111 -0
- package/dist/lib/entities/zone.js +103 -0
- package/dist/lib/game/game-blueprint.d.ts +44 -0
- package/dist/lib/game/game-canvas.d.ts +34 -0
- package/dist/lib/game/game-canvas.js +57 -0
- package/dist/lib/game/game-config.d.ts +47 -0
- package/dist/lib/game/game-config.js +53 -0
- package/dist/lib/game/game-default.d.ts +18 -0
- package/dist/lib/game/game-default.js +24 -0
- package/dist/lib/game/game-state.js +17 -0
- package/dist/lib/game/game.d.ts +2 -5
- package/dist/lib/game/game.js +133 -0
- package/dist/lib/game/zylem-game.d.ts +12 -1
- package/dist/lib/game/zylem-game.js +133 -0
- package/dist/lib/graphics/geometries/XZPlaneGeometry.js +34 -0
- package/dist/lib/graphics/material.d.ts +1 -1
- package/dist/lib/graphics/material.js +64 -0
- package/dist/lib/graphics/mesh.js +14 -0
- package/dist/lib/graphics/render-pass.js +56 -0
- package/dist/lib/graphics/shaders/fragment/debug.glsl.js +23 -0
- package/dist/lib/graphics/shaders/fragment/fire.glsl.js +52 -0
- package/dist/lib/graphics/shaders/fragment/standard.glsl.js +11 -0
- package/dist/lib/graphics/shaders/fragment/stars.glsl.js +44 -0
- package/dist/lib/graphics/shaders/vertex/debug.glsl.js +15 -0
- package/dist/lib/graphics/shaders/vertex/object-shader.glsl.js +11 -0
- package/dist/lib/graphics/shaders/vertex/standard.glsl.js +9 -0
- package/dist/lib/graphics/zylem-scene.d.ts +7 -7
- package/dist/lib/graphics/zylem-scene.js +75 -0
- package/dist/lib/input/gamepad-provider.js +58 -0
- package/dist/lib/input/input-manager.js +70 -0
- package/dist/lib/input/keyboard-provider.js +120 -0
- package/dist/lib/stage/debug-entity-cursor.js +53 -0
- package/dist/lib/stage/entity-spawner.js +27 -0
- package/dist/lib/stage/stage-blueprint.d.ts +44 -0
- package/dist/lib/stage/stage-blueprint.js +56 -0
- package/dist/lib/stage/stage-debug-delegate.js +100 -0
- package/dist/lib/stage/stage-default.d.ts +9 -0
- package/dist/lib/stage/stage-default.js +42 -0
- package/dist/lib/stage/stage-state.js +36 -0
- package/dist/lib/stage/stage.d.ts +2 -2
- package/dist/lib/stage/stage.js +60 -0
- package/dist/lib/stage/zylem-stage.d.ts +4 -3
- package/dist/lib/stage/zylem-stage.js +268 -0
- package/dist/lib/systems/transformable.system.js +43 -0
- package/dist/main.d.ts +6 -15
- package/dist/main.js +56 -45933
- package/dist/stage.d.ts +6 -0
- package/dist/stage.js +22 -0
- package/dist/tests/stage/stage-blueprint.spec.d.ts +1 -0
- package/package.json +35 -1
- package/dist/lib/actions/behaviors/index.d.ts +0 -1
- package/dist/lib/core/game-canvas.d.ts +0 -4
- package/dist/main.cjs +0 -4023
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BaseNode as f } from "../base-node.js";
|
|
2
|
+
import { Stage as r } from "../../stage/stage.js";
|
|
3
|
+
import { GameEntity as g } from "../../entities/entity.js";
|
|
4
|
+
async function h(c) {
|
|
5
|
+
const { getGameDefaultConfig: a } = await import("../../game/game-default.js");
|
|
6
|
+
let s = { ...a() };
|
|
7
|
+
const o = [], e = [], i = [];
|
|
8
|
+
return Object.values(c).forEach((t) => {
|
|
9
|
+
if (t instanceof r)
|
|
10
|
+
e.push(t);
|
|
11
|
+
else if (t instanceof g)
|
|
12
|
+
i.push(t);
|
|
13
|
+
else if (t instanceof f)
|
|
14
|
+
i.push(t);
|
|
15
|
+
else if (t?.constructor?.name === "Object" && typeof t == "object") {
|
|
16
|
+
const n = Object.assign({ ...a() }, { ...t });
|
|
17
|
+
o.push(n);
|
|
18
|
+
}
|
|
19
|
+
}), o.forEach((t) => {
|
|
20
|
+
s = Object.assign(s, { ...t });
|
|
21
|
+
}), e.forEach((t) => {
|
|
22
|
+
t.addEntities(i);
|
|
23
|
+
}), e.length ? s.stages = e : s.stages[0].addEntities(i), s;
|
|
24
|
+
}
|
|
25
|
+
export {
|
|
26
|
+
h as convertNodes
|
|
27
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
function o(r) {
|
|
2
|
+
const e = Object.keys(r).sort().reduce((t, n) => (t[n] = r[n], t), {});
|
|
3
|
+
return JSON.stringify(e);
|
|
4
|
+
}
|
|
5
|
+
function s(r) {
|
|
6
|
+
let e = 0;
|
|
7
|
+
for (let t = 0; t < r.length; t++)
|
|
8
|
+
e = Math.imul(31, e) + r.charCodeAt(t) | 0;
|
|
9
|
+
return e.toString(36);
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
s as shortHash,
|
|
13
|
+
o as sortedStringify
|
|
14
|
+
};
|
|
@@ -9,7 +9,5 @@ export declare const ZylemBlue = "#0333EC";
|
|
|
9
9
|
export declare const ZylemBlueTransparent = "#0333ECA0";
|
|
10
10
|
export declare const ZylemGoldText = "#DAA420";
|
|
11
11
|
export type SizeVector = Vect3 | null;
|
|
12
|
-
export declare function sortedStringify(obj: Record<string, any>): string;
|
|
13
|
-
export declare function shortHash(objString: string): string;
|
|
14
12
|
export declare const Vec0: Vector3;
|
|
15
13
|
export declare const Vec1: Vector3;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { BaseNode } from './base-node';
|
|
2
|
-
import { SetupContext, UpdateContext, DestroyContext } from './base-node-life-cycle';
|
|
2
|
+
import { SetupContext, UpdateContext, DestroyContext, LoadedContext, CleanupContext } from './base-node-life-cycle';
|
|
3
3
|
export declare const VESSEL_TYPE: unique symbol;
|
|
4
4
|
export declare class Vessel extends BaseNode<{}, Vessel> {
|
|
5
5
|
static type: symbol;
|
|
6
6
|
protected _setup(_params: SetupContext<this>): void;
|
|
7
|
+
protected _loaded(_params: LoadedContext<this>): Promise<void>;
|
|
7
8
|
protected _update(_params: UpdateContext<this>): void;
|
|
8
9
|
protected _destroy(_params: DestroyContext<this>): void;
|
|
10
|
+
protected _cleanup(_params: CleanupContext<this>): Promise<void>;
|
|
9
11
|
create(): this;
|
|
10
12
|
}
|
|
11
13
|
export declare function vessel(...args: Array<BaseNode>): BaseNode<{}, Vessel>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BaseNode as t } from "./base-node.js";
|
|
2
|
+
const r = Symbol("vessel");
|
|
3
|
+
class n extends t {
|
|
4
|
+
static type = r;
|
|
5
|
+
_setup(s) {
|
|
6
|
+
}
|
|
7
|
+
async _loaded(s) {
|
|
8
|
+
}
|
|
9
|
+
_update(s) {
|
|
10
|
+
}
|
|
11
|
+
_destroy(s) {
|
|
12
|
+
}
|
|
13
|
+
async _cleanup(s) {
|
|
14
|
+
}
|
|
15
|
+
create() {
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function o(...e) {
|
|
20
|
+
const s = new n();
|
|
21
|
+
return e.forEach((a) => s.add(a)), s;
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
r as VESSEL_TYPE,
|
|
25
|
+
n as Vessel,
|
|
26
|
+
o as vessel
|
|
27
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { proxy as s } from "valtio/vanilla";
|
|
2
|
+
import { printToConsole as t } from "./console/console-state.js";
|
|
3
|
+
const n = {
|
|
4
|
+
NONE: "NONE",
|
|
5
|
+
SELECT: "SELECT",
|
|
6
|
+
DELETE: "DELETE"
|
|
7
|
+
}, o = s({
|
|
8
|
+
on: !1,
|
|
9
|
+
paused: !1,
|
|
10
|
+
configuration: {
|
|
11
|
+
showCollisionBounds: !1,
|
|
12
|
+
showModelBounds: !1,
|
|
13
|
+
showSpriteBounds: !1
|
|
14
|
+
},
|
|
15
|
+
hovered: null,
|
|
16
|
+
selected: [],
|
|
17
|
+
tool: n.NONE
|
|
18
|
+
}), r = (e = !1) => {
|
|
19
|
+
o.on = e;
|
|
20
|
+
}, u = (e) => {
|
|
21
|
+
o.selected.push(e);
|
|
22
|
+
}, E = () => o.tool, a = (e) => {
|
|
23
|
+
o.hovered = e;
|
|
24
|
+
}, c = () => {
|
|
25
|
+
o.hovered = null;
|
|
26
|
+
}, i = () => o.hovered, f = (e) => {
|
|
27
|
+
o.paused = e, t(e ? "Paused" : "Resumed");
|
|
28
|
+
}, p = () => o.paused;
|
|
29
|
+
export {
|
|
30
|
+
n as DebugTools,
|
|
31
|
+
o as debugState,
|
|
32
|
+
E as getDebugTool,
|
|
33
|
+
i as getHoveredEntity,
|
|
34
|
+
p as isPaused,
|
|
35
|
+
c as resetHoveredEntity,
|
|
36
|
+
r as setDebugFlag,
|
|
37
|
+
a as setHoveredEntity,
|
|
38
|
+
f as setPaused,
|
|
39
|
+
u as setSelectedEntity
|
|
40
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export declare const AspectRatio: {
|
|
2
|
+
readonly FourByThree: number;
|
|
3
|
+
readonly SixteenByNine: number;
|
|
4
|
+
readonly TwentyOneByNine: number;
|
|
5
|
+
readonly OneByOne: number;
|
|
6
|
+
};
|
|
7
|
+
export type AspectRatioValue = (typeof AspectRatio)[keyof typeof AspectRatio] | number;
|
|
8
|
+
/**
|
|
9
|
+
* AspectRatioDelegate manages sizing a canvas to fit within a container
|
|
10
|
+
* while preserving a target aspect ratio. It notifies a consumer via
|
|
11
|
+
* onResize when the final width/height are applied so renderers/cameras
|
|
12
|
+
* can update their viewports.
|
|
13
|
+
*/
|
|
14
|
+
export declare class AspectRatioDelegate {
|
|
15
|
+
container: HTMLElement;
|
|
16
|
+
canvas: HTMLCanvasElement;
|
|
17
|
+
aspectRatio: number;
|
|
18
|
+
onResize?: (width: number, height: number) => void;
|
|
19
|
+
private handleResizeBound;
|
|
20
|
+
constructor(params: {
|
|
21
|
+
container: HTMLElement;
|
|
22
|
+
canvas: HTMLCanvasElement;
|
|
23
|
+
aspectRatio: AspectRatioValue;
|
|
24
|
+
onResize?: (width: number, height: number) => void;
|
|
25
|
+
});
|
|
26
|
+
/** Attach window resize listener and apply once. */
|
|
27
|
+
attach(): void;
|
|
28
|
+
/** Detach window resize listener. */
|
|
29
|
+
detach(): void;
|
|
30
|
+
/** Compute the largest size that fits container while preserving aspect. */
|
|
31
|
+
measure(): {
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
};
|
|
35
|
+
/** Apply measured size to canvas and notify. */
|
|
36
|
+
apply(): void;
|
|
37
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const h = {
|
|
2
|
+
FourByThree: 1.3333333333333333,
|
|
3
|
+
SixteenByNine: 1.7777777777777777,
|
|
4
|
+
TwentyOneByNine: 2.3333333333333335,
|
|
5
|
+
OneByOne: 1
|
|
6
|
+
};
|
|
7
|
+
class a {
|
|
8
|
+
container;
|
|
9
|
+
canvas;
|
|
10
|
+
aspectRatio;
|
|
11
|
+
onResize;
|
|
12
|
+
handleResizeBound;
|
|
13
|
+
constructor(t) {
|
|
14
|
+
this.container = t.container, this.canvas = t.canvas, this.aspectRatio = (typeof t.aspectRatio == "number", t.aspectRatio), this.onResize = t.onResize, this.handleResizeBound = this.apply.bind(this);
|
|
15
|
+
}
|
|
16
|
+
/** Attach window resize listener and apply once. */
|
|
17
|
+
attach() {
|
|
18
|
+
window.addEventListener("resize", this.handleResizeBound), this.apply();
|
|
19
|
+
}
|
|
20
|
+
/** Detach window resize listener. */
|
|
21
|
+
detach() {
|
|
22
|
+
window.removeEventListener("resize", this.handleResizeBound);
|
|
23
|
+
}
|
|
24
|
+
/** Compute the largest size that fits container while preserving aspect. */
|
|
25
|
+
measure() {
|
|
26
|
+
const t = this.container.clientWidth || window.innerWidth, e = this.container.clientHeight || window.innerHeight;
|
|
27
|
+
if (t / e > this.aspectRatio) {
|
|
28
|
+
const i = e;
|
|
29
|
+
return { width: Math.round(i * this.aspectRatio), height: i };
|
|
30
|
+
} else {
|
|
31
|
+
const i = t, n = Math.round(i / this.aspectRatio);
|
|
32
|
+
return { width: i, height: n };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Apply measured size to canvas and notify. */
|
|
36
|
+
apply() {
|
|
37
|
+
const { width: t, height: e } = this.measure();
|
|
38
|
+
this.canvas.style.width = `${t}px`, this.canvas.style.height = `${e}px`, this.onResize?.(t, e);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export {
|
|
42
|
+
h as AspectRatio,
|
|
43
|
+
a as AspectRatioDelegate
|
|
44
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { ColliderDesc as l, ActiveCollisionTypes as m } from "@dimforge/rapier3d-compat";
|
|
2
|
+
import { Vector3 as r, Group as d, SkinnedMesh as u } from "three";
|
|
3
|
+
import { GameEntity as p } from "./entity.js";
|
|
4
|
+
import { createEntity as g } from "./create.js";
|
|
5
|
+
import { EntityAssetLoader as y } from "../core/entity-asset-loader.js";
|
|
6
|
+
import { AnimationDelegate as f } from "./delegates/animation.js";
|
|
7
|
+
import { EntityCollisionBuilder as b, EntityBuilder as _ } from "./builder.js";
|
|
8
|
+
const c = {
|
|
9
|
+
position: { x: 0, y: 0, z: 0 },
|
|
10
|
+
collision: {
|
|
11
|
+
static: !1,
|
|
12
|
+
size: new r(0.5, 0.5, 0.5),
|
|
13
|
+
position: new r(0, 0, 0)
|
|
14
|
+
},
|
|
15
|
+
material: {
|
|
16
|
+
shader: "standard"
|
|
17
|
+
},
|
|
18
|
+
animations: [],
|
|
19
|
+
models: []
|
|
20
|
+
};
|
|
21
|
+
class j extends b {
|
|
22
|
+
height = 1;
|
|
23
|
+
objectModel = null;
|
|
24
|
+
constructor(t) {
|
|
25
|
+
super(), this.objectModel = t.objectModel;
|
|
26
|
+
}
|
|
27
|
+
createColliderFromObjectModel(t) {
|
|
28
|
+
if (!t)
|
|
29
|
+
return l.capsule(1, 1);
|
|
30
|
+
const e = t.children.find((s) => s instanceof u).geometry;
|
|
31
|
+
if (e && (e.computeBoundingBox(), e.boundingBox)) {
|
|
32
|
+
const s = e.boundingBox.max.y, h = e.boundingBox.min.y;
|
|
33
|
+
this.height = s - h;
|
|
34
|
+
}
|
|
35
|
+
this.height = 1;
|
|
36
|
+
let o = l.capsule(this.height / 2, 1);
|
|
37
|
+
return o.setSensor(!1), o.setTranslation(0, this.height + 0.5, 0), o.activeCollisionTypes = m.DEFAULT, o;
|
|
38
|
+
}
|
|
39
|
+
collider(t) {
|
|
40
|
+
return this.createColliderFromObjectModel(this.objectModel);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
class C extends _ {
|
|
44
|
+
createEntity(t) {
|
|
45
|
+
return new a(t);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const D = Symbol("Actor");
|
|
49
|
+
class a extends p {
|
|
50
|
+
static type = D;
|
|
51
|
+
_object = null;
|
|
52
|
+
_animationDelegate = null;
|
|
53
|
+
_modelFileNames = [];
|
|
54
|
+
_assetLoader = new y();
|
|
55
|
+
controlledRotation = !1;
|
|
56
|
+
constructor(t) {
|
|
57
|
+
super(), this.options = { ...c, ...t }, this.lifeCycleDelegate = {
|
|
58
|
+
update: [this.actorUpdate.bind(this)]
|
|
59
|
+
}, this.controlledRotation = !0;
|
|
60
|
+
}
|
|
61
|
+
async load() {
|
|
62
|
+
this._modelFileNames = this.options.models || [], await this.loadModels(), this._object && (this._animationDelegate = new f(this._object), await this._animationDelegate.loadAnimations(this.options.animations || []));
|
|
63
|
+
}
|
|
64
|
+
async data() {
|
|
65
|
+
return {
|
|
66
|
+
animations: this._animationDelegate?.animations,
|
|
67
|
+
objectModel: this._object
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
async actorUpdate(t) {
|
|
71
|
+
this._animationDelegate?.update(t.delta);
|
|
72
|
+
}
|
|
73
|
+
async loadModels() {
|
|
74
|
+
if (this._modelFileNames.length === 0)
|
|
75
|
+
return;
|
|
76
|
+
const t = this._modelFileNames.map((e) => this._assetLoader.loadFile(e)), i = await Promise.all(t);
|
|
77
|
+
i[0]?.object && (this._object = i[0].object), this._object && (this.group = new d(), this.group.attach(this._object), this.group.scale.set(this.options.scale?.x || 1, this.options.scale?.y || 1, this.options.scale?.z || 1));
|
|
78
|
+
}
|
|
79
|
+
playAnimation(t) {
|
|
80
|
+
this._animationDelegate?.playAnimation(t);
|
|
81
|
+
}
|
|
82
|
+
get object() {
|
|
83
|
+
return this._object;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Provide custom debug information for the actor
|
|
87
|
+
* This will be merged with the default debug information
|
|
88
|
+
*/
|
|
89
|
+
getDebugInfo() {
|
|
90
|
+
const t = {
|
|
91
|
+
type: "Actor",
|
|
92
|
+
models: this._modelFileNames.length > 0 ? this._modelFileNames : "none",
|
|
93
|
+
modelLoaded: !!this._object,
|
|
94
|
+
scale: this.options.scale ? `${this.options.scale.x}, ${this.options.scale.y}, ${this.options.scale.z}` : "1, 1, 1"
|
|
95
|
+
};
|
|
96
|
+
if (this._animationDelegate && (t.currentAnimation = this._animationDelegate.currentAnimationKey || "none", t.animationsCount = this.options.animations?.length || 0), this._object) {
|
|
97
|
+
let i = 0, e = 0;
|
|
98
|
+
this._object.traverse((o) => {
|
|
99
|
+
if (o.isMesh) {
|
|
100
|
+
i++;
|
|
101
|
+
const s = o.geometry;
|
|
102
|
+
s && s.attributes.position && (e += s.attributes.position.count);
|
|
103
|
+
}
|
|
104
|
+
}), t.meshCount = i, t.vertexCount = e;
|
|
105
|
+
}
|
|
106
|
+
return t;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async function T(...n) {
|
|
110
|
+
return await g({
|
|
111
|
+
args: n,
|
|
112
|
+
defaultConfig: c,
|
|
113
|
+
EntityClass: a,
|
|
114
|
+
BuilderClass: C,
|
|
115
|
+
CollisionBuilderClass: j,
|
|
116
|
+
entityType: a.type
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
export {
|
|
120
|
+
D as ACTOR_TYPE,
|
|
121
|
+
C as ActorBuilder,
|
|
122
|
+
j as ActorCollisionBuilder,
|
|
123
|
+
a as ZylemActor,
|
|
124
|
+
T as actor
|
|
125
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ColliderDesc as a } from "@dimforge/rapier3d-compat";
|
|
2
|
+
import { Color as d, Vector3 as n, BoxGeometry as u } from "three";
|
|
3
|
+
import { GameEntity as y } from "./entity.js";
|
|
4
|
+
import { EntityCollisionBuilder as f, EntityBuilder as x, EntityMeshBuilder as m } from "./builder.js";
|
|
5
|
+
import { DebugDelegate as p } from "./delegates/debug.js";
|
|
6
|
+
import { createEntity as z } from "./create.js";
|
|
7
|
+
const l = {
|
|
8
|
+
size: new n(1, 1, 1),
|
|
9
|
+
position: new n(0, 0, 0),
|
|
10
|
+
collision: {
|
|
11
|
+
static: !1
|
|
12
|
+
},
|
|
13
|
+
material: {
|
|
14
|
+
color: new d("#ffffff"),
|
|
15
|
+
shader: "standard"
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
class B extends f {
|
|
19
|
+
collider(t) {
|
|
20
|
+
const e = t.size || new n(1, 1, 1), s = { x: e.x / 2, y: e.y / 2, z: e.z / 2 };
|
|
21
|
+
return a.cuboid(s.x, s.y, s.z);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
class b extends m {
|
|
25
|
+
build(t) {
|
|
26
|
+
const e = t.size ?? new n(1, 1, 1);
|
|
27
|
+
return new u(e.x, e.y, e.z);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
class C extends x {
|
|
31
|
+
createEntity(t) {
|
|
32
|
+
return new i(t);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const h = Symbol("Box");
|
|
36
|
+
class i extends y {
|
|
37
|
+
static type = h;
|
|
38
|
+
constructor(t) {
|
|
39
|
+
super(), this.options = { ...l, ...t };
|
|
40
|
+
}
|
|
41
|
+
buildInfo() {
|
|
42
|
+
const e = new p(this).buildDebugInfo(), { x: s, y: r, z: c } = this.options.size ?? { x: 1, y: 1, z: 1 };
|
|
43
|
+
return {
|
|
44
|
+
...e,
|
|
45
|
+
type: String(i.type),
|
|
46
|
+
size: `${s}, ${r}, ${c}`
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async function $(...o) {
|
|
51
|
+
return z({
|
|
52
|
+
args: o,
|
|
53
|
+
defaultConfig: l,
|
|
54
|
+
EntityClass: i,
|
|
55
|
+
BuilderClass: C,
|
|
56
|
+
MeshBuilderClass: b,
|
|
57
|
+
CollisionBuilderClass: B,
|
|
58
|
+
entityType: i.type
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
export {
|
|
62
|
+
h as BOX_TYPE,
|
|
63
|
+
C as BoxBuilder,
|
|
64
|
+
B as BoxCollisionBuilder,
|
|
65
|
+
b as BoxMeshBuilder,
|
|
66
|
+
i as ZylemBox,
|
|
67
|
+
$ as box
|
|
68
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Mesh as l, Color as n, BufferGeometry as u } from "three";
|
|
2
|
+
import { CollisionBuilder as h } from "../collision/collision-builder.js";
|
|
3
|
+
import { MeshBuilder as m } from "../graphics/mesh.js";
|
|
4
|
+
import { MaterialBuilder as d } from "../graphics/material.js";
|
|
5
|
+
class y extends h {
|
|
6
|
+
}
|
|
7
|
+
class b extends m {
|
|
8
|
+
build(i) {
|
|
9
|
+
return new u();
|
|
10
|
+
}
|
|
11
|
+
postBuild() {
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
class M {
|
|
15
|
+
meshBuilder;
|
|
16
|
+
collisionBuilder;
|
|
17
|
+
materialBuilder;
|
|
18
|
+
options;
|
|
19
|
+
entity;
|
|
20
|
+
constructor(i, s, t, e) {
|
|
21
|
+
this.options = i, this.entity = s, this.meshBuilder = t, this.collisionBuilder = e, this.materialBuilder = new d();
|
|
22
|
+
const o = {
|
|
23
|
+
meshBuilder: this.meshBuilder,
|
|
24
|
+
collisionBuilder: this.collisionBuilder,
|
|
25
|
+
materialBuilder: this.materialBuilder
|
|
26
|
+
};
|
|
27
|
+
this.options._builders = o;
|
|
28
|
+
}
|
|
29
|
+
withPosition(i) {
|
|
30
|
+
return this.options.position = i, this;
|
|
31
|
+
}
|
|
32
|
+
async withMaterial(i, s) {
|
|
33
|
+
return this.materialBuilder && await this.materialBuilder.build(i, s), this;
|
|
34
|
+
}
|
|
35
|
+
applyMaterialToGroup(i, s) {
|
|
36
|
+
i.traverse((t) => {
|
|
37
|
+
t instanceof l && t.type === "SkinnedMesh" && s[0] && !t.material.map && (t.material = s[0]), t.castShadow = !0, t.receiveShadow = !0;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
async build() {
|
|
41
|
+
const i = this.entity;
|
|
42
|
+
if (this.materialBuilder && (i.materials = this.materialBuilder.materials), this.meshBuilder && i.materials) {
|
|
43
|
+
const s = this.meshBuilder.build(this.options);
|
|
44
|
+
i.mesh = this.meshBuilder._build(this.options, s, i.materials), this.meshBuilder.postBuild();
|
|
45
|
+
}
|
|
46
|
+
if (i.group && i.materials && this.applyMaterialToGroup(i.group, i.materials), this.collisionBuilder) {
|
|
47
|
+
this.collisionBuilder.withCollision(this.options?.collision || {});
|
|
48
|
+
const [s, t] = this.collisionBuilder.build(this.options);
|
|
49
|
+
i.bodyDesc = s, i.colliderDesc = t;
|
|
50
|
+
const { x: e, y: o, z: a } = this.options.position || { x: 0, y: 0, z: 0 };
|
|
51
|
+
i.bodyDesc.setTranslation(e, o, a);
|
|
52
|
+
}
|
|
53
|
+
if (this.options.collisionType && (i.collisionType = this.options.collisionType), this.options.color instanceof n) {
|
|
54
|
+
const s = (t) => {
|
|
55
|
+
const e = t;
|
|
56
|
+
e && e.color && e.color.set && e.color.set(this.options.color);
|
|
57
|
+
};
|
|
58
|
+
if (i.materials?.length)
|
|
59
|
+
for (const t of i.materials)
|
|
60
|
+
s(t);
|
|
61
|
+
if (i.mesh && i.mesh.material) {
|
|
62
|
+
const t = i.mesh.material;
|
|
63
|
+
Array.isArray(t) ? t.forEach(s) : s(t);
|
|
64
|
+
}
|
|
65
|
+
i.group && i.group.traverse((t) => {
|
|
66
|
+
if (t instanceof l && t.material) {
|
|
67
|
+
const e = t.material;
|
|
68
|
+
Array.isArray(e) ? e.forEach(s) : s(e);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return i;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export {
|
|
76
|
+
M as EntityBuilder,
|
|
77
|
+
y as EntityCollisionBuilder,
|
|
78
|
+
b as EntityMeshBuilder
|
|
79
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { BaseNode as s } from "../core/base-node.js";
|
|
2
|
+
import { isLoadable as p, EntityLoader as C } from "./delegates/loader.js";
|
|
3
|
+
async function E(w) {
|
|
4
|
+
const { args: n, defaultConfig: l, EntityClass: g, BuilderClass: y, entityType: c, MeshBuilderClass: f, CollisionBuilderClass: d } = w;
|
|
5
|
+
let e = null, r;
|
|
6
|
+
const u = n.findIndex((i) => !(i instanceof s));
|
|
7
|
+
u !== -1 && (r = n.splice(u, 1).find((t) => !(t instanceof s)));
|
|
8
|
+
const m = r ? { ...l, ...r } : l;
|
|
9
|
+
n.push(m);
|
|
10
|
+
for (const i of n) {
|
|
11
|
+
if (i instanceof s)
|
|
12
|
+
continue;
|
|
13
|
+
let t = null;
|
|
14
|
+
const a = new g(i);
|
|
15
|
+
try {
|
|
16
|
+
if (p(a)) {
|
|
17
|
+
const o = new C(a);
|
|
18
|
+
await o.load(), t = await o.data();
|
|
19
|
+
}
|
|
20
|
+
} catch (o) {
|
|
21
|
+
console.error("Error creating entity with loader:", o);
|
|
22
|
+
}
|
|
23
|
+
e = new y(i, a, f ? new f(t) : null, d ? new d(t) : null), i.material && await e.withMaterial(i.material, c);
|
|
24
|
+
}
|
|
25
|
+
if (!e)
|
|
26
|
+
throw new Error(`missing options for ${String(c)}, builder is not initialized.`);
|
|
27
|
+
return await e.build();
|
|
28
|
+
}
|
|
29
|
+
export {
|
|
30
|
+
E as createEntity
|
|
31
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { AnimationMixer as u, LoopOnce as c, LoopRepeat as h } from "three";
|
|
2
|
+
import { EntityAssetLoader as _ } from "../../core/entity-asset-loader.js";
|
|
3
|
+
class d {
|
|
4
|
+
target;
|
|
5
|
+
_mixer = null;
|
|
6
|
+
_actions = {};
|
|
7
|
+
_animations = [];
|
|
8
|
+
_currentAction = null;
|
|
9
|
+
_pauseAtPercentage = 0;
|
|
10
|
+
_isPaused = !1;
|
|
11
|
+
_queuedKey = null;
|
|
12
|
+
_fadeDuration = 0.5;
|
|
13
|
+
_currentKey = "";
|
|
14
|
+
_assetLoader = new _();
|
|
15
|
+
constructor(e) {
|
|
16
|
+
this.target = e;
|
|
17
|
+
}
|
|
18
|
+
async loadAnimations(e) {
|
|
19
|
+
if (!e.length)
|
|
20
|
+
return;
|
|
21
|
+
const i = await Promise.all(e.map((t) => this._assetLoader.loadFile(t.path)));
|
|
22
|
+
this._animations = i.filter((t) => !!t.animation).map((t) => t.animation), this._animations.length && (this._mixer = new u(this.target), this._animations.forEach((t, n) => {
|
|
23
|
+
const a = e[n].key || n.toString();
|
|
24
|
+
this._actions[a] = this._mixer.clipAction(t);
|
|
25
|
+
}), this.playAnimation({ key: Object.keys(this._actions)[0] }));
|
|
26
|
+
}
|
|
27
|
+
update(e) {
|
|
28
|
+
if (!this._mixer || !this._currentAction)
|
|
29
|
+
return;
|
|
30
|
+
this._mixer.update(e);
|
|
31
|
+
const i = this._currentAction.getClip().duration * (this._pauseAtPercentage / 100);
|
|
32
|
+
if (!this._isPaused && this._pauseAtPercentage > 0 && this._currentAction.time >= i && (this._currentAction.time = i, this._currentAction.paused = !0, this._isPaused = !0, this._queuedKey !== null)) {
|
|
33
|
+
const t = this._actions[this._queuedKey];
|
|
34
|
+
t.reset().play(), this._currentAction.crossFadeTo(t, this._fadeDuration, !1), this._currentAction = t, this._currentKey = this._queuedKey, this._queuedKey = null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
playAnimation(e) {
|
|
38
|
+
if (!this._mixer)
|
|
39
|
+
return;
|
|
40
|
+
const { key: i, pauseAtPercentage: t = 0, pauseAtEnd: n = !1, fadeToKey: a, fadeDuration: o = 0.5 } = e;
|
|
41
|
+
if (i === this._currentKey)
|
|
42
|
+
return;
|
|
43
|
+
this._queuedKey = a || null, this._fadeDuration = o, this._pauseAtPercentage = n ? 100 : t, this._isPaused = !1;
|
|
44
|
+
const r = this._currentAction;
|
|
45
|
+
r && r.stop();
|
|
46
|
+
const s = this._actions[i];
|
|
47
|
+
s && (this._pauseAtPercentage > 0 ? (s.setLoop(c, 1 / 0), s.clampWhenFinished = !0) : (s.setLoop(h, 1 / 0), s.clampWhenFinished = !1), r && r.crossFadeTo(s, o, !1), s.reset().play(), this._currentAction = s, this._currentKey = i);
|
|
48
|
+
}
|
|
49
|
+
get currentAnimationKey() {
|
|
50
|
+
return this._currentKey;
|
|
51
|
+
}
|
|
52
|
+
get animations() {
|
|
53
|
+
return this._animations;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
d as AnimationDelegate
|
|
58
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { MeshStandardMaterial as c, MeshBasicMaterial as u, MeshPhongMaterial as f } from "three";
|
|
2
|
+
function g(o) {
|
|
3
|
+
return o && typeof o.getDebugInfo == "function";
|
|
4
|
+
}
|
|
5
|
+
class d {
|
|
6
|
+
entity;
|
|
7
|
+
constructor(t) {
|
|
8
|
+
this.entity = t;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Get formatted position string
|
|
12
|
+
*/
|
|
13
|
+
getPositionString() {
|
|
14
|
+
if (this.entity.mesh) {
|
|
15
|
+
const { x: n, y: s, z: r } = this.entity.mesh.position;
|
|
16
|
+
return `${n.toFixed(2)}, ${s.toFixed(2)}, ${r.toFixed(2)}`;
|
|
17
|
+
}
|
|
18
|
+
const { x: t, y: i, z: e } = this.entity.options.position || { x: 0, y: 0, z: 0 };
|
|
19
|
+
return `${t.toFixed(2)}, ${i.toFixed(2)}, ${e.toFixed(2)}`;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get formatted rotation string (in degrees)
|
|
23
|
+
*/
|
|
24
|
+
getRotationString() {
|
|
25
|
+
if (this.entity.mesh) {
|
|
26
|
+
const { x: s, y: r, z: y } = this.entity.mesh.rotation, a = (h) => (h * 180 / Math.PI).toFixed(1);
|
|
27
|
+
return `${a(s)}°, ${a(r)}°, ${a(y)}°`;
|
|
28
|
+
}
|
|
29
|
+
const { x: t, y: i, z: e } = this.entity.options.rotation || { x: 0, y: 0, z: 0 }, n = (s) => (s * 180 / Math.PI).toFixed(1);
|
|
30
|
+
return `${n(t)}°, ${n(i)}°, ${n(e)}°`;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get material information
|
|
34
|
+
*/
|
|
35
|
+
getMaterialInfo() {
|
|
36
|
+
if (!this.entity.mesh || !this.entity.mesh.material)
|
|
37
|
+
return { type: "none" };
|
|
38
|
+
const t = Array.isArray(this.entity.mesh.material) ? this.entity.mesh.material[0] : this.entity.mesh.material, i = {
|
|
39
|
+
type: t.type
|
|
40
|
+
};
|
|
41
|
+
return (t instanceof c || t instanceof u || t instanceof f) && (i.color = `#${t.color.getHexString()}`, i.opacity = t.opacity, i.transparent = t.transparent), "roughness" in t && (i.roughness = t.roughness), "metalness" in t && (i.metalness = t.metalness), i;
|
|
42
|
+
}
|
|
43
|
+
getPhysicsInfo() {
|
|
44
|
+
if (!this.entity.body)
|
|
45
|
+
return null;
|
|
46
|
+
const t = {
|
|
47
|
+
type: this.entity.body.bodyType(),
|
|
48
|
+
mass: this.entity.body.mass(),
|
|
49
|
+
isEnabled: this.entity.body.isEnabled(),
|
|
50
|
+
isSleeping: this.entity.body.isSleeping()
|
|
51
|
+
}, i = this.entity.body.linvel();
|
|
52
|
+
return t.velocity = `${i.x.toFixed(2)}, ${i.y.toFixed(2)}, ${i.z.toFixed(2)}`, t;
|
|
53
|
+
}
|
|
54
|
+
buildDebugInfo() {
|
|
55
|
+
const t = {
|
|
56
|
+
name: this.entity.name || this.entity.uuid,
|
|
57
|
+
uuid: this.entity.uuid,
|
|
58
|
+
position: this.getPositionString(),
|
|
59
|
+
rotation: this.getRotationString(),
|
|
60
|
+
material: this.getMaterialInfo()
|
|
61
|
+
}, i = this.getPhysicsInfo();
|
|
62
|
+
if (i && (t.physics = i), this.entity.behaviors.length > 0 && (t.behaviors = this.entity.behaviors.map((e) => e.constructor.name)), g(this.entity)) {
|
|
63
|
+
const e = this.entity.getDebugInfo();
|
|
64
|
+
return { ...t, ...e };
|
|
65
|
+
}
|
|
66
|
+
return t;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export {
|
|
70
|
+
d as DebugDelegate,
|
|
71
|
+
g as hasDebugInfo
|
|
72
|
+
};
|