@gg-web-engine/core 0.0.57 → 0.0.59
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/dist/2d/components/physics/i-physics-world-2d.component.d.ts +1 -1
- package/dist/2d/components/physics/i-rigid-body-2d.component.d.ts +1 -1
- package/dist/2d/components/physics/i-trigger-2d.component.d.ts +3 -3
- package/dist/2d/components/rendering/i-camera-2d.component.d.ts +5 -0
- package/dist/2d/components/rendering/i-display-object-2d.component.d.ts +1 -1
- package/dist/2d/components/rendering/i-renderer-2d.component.d.ts +1 -1
- package/dist/2d/components/rendering/i-visual-scene-2d.component.d.ts +2 -3
- package/dist/2d/entities/controllers/entity-2d-positioning.animator.d.ts +2 -2
- package/dist/2d/entities/entity-2d.d.ts +7 -7
- package/dist/2d/entities/i-renderable-2d.entity.d.ts +4 -4
- package/dist/2d/entities/renderer-2d.entity.d.ts +2 -1
- package/dist/2d/entities/trigger-2d.entity.d.ts +8 -4
- package/dist/2d/factories.d.ts +7 -7
- package/dist/2d/gg-2d-world.d.ts +38 -6
- package/dist/2d/gg-2d-world.js +27 -21
- package/dist/2d/index.d.ts +3 -0
- package/dist/2d/index.js +3 -0
- package/dist/2d/level-loader.d.ts +101 -0
- package/dist/2d/level-loader.js +88 -0
- package/dist/2d/loader.d.ts +11 -0
- package/dist/2d/loader.js +10 -0
- package/dist/3d/components/physics/i-physics-world-3d.component.d.ts +5 -5
- package/dist/3d/components/physics/i-raycast-vehicle.component.d.ts +1 -1
- package/dist/3d/components/physics/i-rigid-body-3d.component.d.ts +1 -1
- package/dist/3d/components/physics/i-trigger-3d.component.d.ts +3 -3
- package/dist/3d/components/rendering/{i-camera.component.d.ts → i-camera-3d.component.d.ts} +1 -1
- package/dist/3d/components/rendering/i-camera-3d.component.js +1 -0
- package/dist/3d/components/rendering/i-display-object-3d.component.d.ts +1 -1
- package/dist/3d/components/rendering/i-renderer-3d.component.d.ts +1 -2
- package/dist/3d/components/rendering/i-visual-scene-3d.component.d.ts +3 -4
- package/dist/3d/entities/camera-3d.entity.d.ts +24 -0
- package/dist/3d/entities/camera-3d.entity.js +35 -0
- package/dist/3d/entities/controllers/animators/camera-3d.animator.d.ts +3 -3
- package/dist/3d/entities/controllers/animators/entity-3d-positioning.animator.d.ts +2 -2
- package/dist/3d/entities/entity-3d.d.ts +6 -6
- package/dist/3d/entities/gg-car/gg-car.entity.d.ts +5 -5
- package/dist/3d/entities/i-renderable-3d.entity.d.ts +4 -4
- package/dist/3d/entities/map-graph-3d.entity.d.ts +6 -6
- package/dist/3d/entities/raycast-vehicle-3d.entity.d.ts +3 -3
- package/dist/3d/entities/renderer-3d.entity.d.ts +1 -6
- package/dist/3d/entities/renderer-3d.entity.js +0 -15
- package/dist/3d/entities/surface-following.entity.d.ts +3 -3
- package/dist/3d/entities/surface-following.entity.js +3 -0
- package/dist/3d/entities/trigger-3d.entity.d.ts +8 -4
- package/dist/3d/factories.d.ts +14 -14
- package/dist/3d/gg-3d-world.d.ts +37 -9
- package/dist/3d/gg-3d-world.js +23 -19
- package/dist/3d/index.d.ts +3 -1
- package/dist/3d/index.js +3 -1
- package/dist/3d/level-loader.d.ts +300 -0
- package/dist/3d/level-loader.js +267 -0
- package/dist/3d/loader.d.ts +55 -14
- package/dist/3d/loader.js +37 -8
- package/dist/3d/loaders.d.ts +4 -4
- package/dist/base/blueprint/blueprint-node.d.ts +75 -0
- package/dist/base/blueprint/blueprint-node.js +51 -0
- package/dist/base/blueprint/blueprint.d.ts +123 -0
- package/dist/base/blueprint/blueprint.js +86 -0
- package/dist/base/blueprint/nodes/remove-entity.node.d.ts +26 -0
- package/dist/base/blueprint/nodes/remove-entity.node.js +29 -0
- package/dist/base/components/i-world-component.d.ts +5 -5
- package/dist/base/components/physics/i-body.component.d.ts +5 -5
- package/dist/base/components/physics/i-physics-world.component.d.ts +13 -5
- package/dist/base/components/physics/i-rigid-body.component.d.ts +2 -2
- package/dist/base/components/physics/i-trigger.component.d.ts +4 -4
- package/dist/base/components/rendering/i-display-object.component.d.ts +6 -6
- package/dist/base/components/rendering/i-renderer.component.d.ts +5 -4
- package/dist/base/components/rendering/i-visual-scene.component.d.ts +4 -2
- package/dist/base/entities/controllers/animation-mixer.d.ts +3 -3
- package/dist/base/entities/group.entity.d.ts +17 -0
- package/dist/base/entities/group.entity.js +19 -0
- package/dist/base/entities/i-entity.d.ts +19 -8
- package/dist/base/entities/i-entity.js +28 -0
- package/dist/base/entities/i-renderable.entity.d.ts +2 -2
- package/dist/base/entities/i-renderer.entity.d.ts +11 -5
- package/dist/base/entities/i-renderer.entity.js +15 -0
- package/dist/base/gg-world.d.ts +42 -5
- package/dist/base/gg-world.js +45 -10
- package/dist/base/index.d.ts +6 -0
- package/dist/base/index.js +6 -0
- package/dist/base/inputs/mouse.input.js +1 -0
- package/dist/base/level-loader.d.ts +217 -0
- package/dist/base/level-loader.js +258 -0
- package/dist/base/math/numbers.d.ts +2 -1
- package/dist/base/math/numbers.js +7 -1
- package/dist/base/math/point2.d.ts +17 -1
- package/dist/base/math/point2.js +35 -0
- package/dist/base/math/point3.d.ts +2 -0
- package/dist/base/math/point3.js +15 -1
- package/dist/base/models/points.d.ts +20 -16
- package/dist/base/models/raycasting.d.ts +52 -0
- package/dist/base/models/raycasting.js +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/tsconfig.json +3 -1
- /package/dist/{3d/components/rendering/i-camera.component.js → 2d/components/rendering/i-camera-2d.component.js} +0 -0
package/dist/3d/loader.js
CHANGED
|
@@ -8,7 +8,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { Entity3d } from './entities/entity-3d';
|
|
11
|
-
import { Pnt3, Qtrn } from '../base';
|
|
11
|
+
import { GroupEntity, Pnt3, Qtrn } from '../base';
|
|
12
|
+
import { Gg3dLevelLoader } from './level-loader';
|
|
12
13
|
export var CachingStrategy;
|
|
13
14
|
(function (CachingStrategy) {
|
|
14
15
|
CachingStrategy[CachingStrategy["Nothing"] = 0] = "Nothing";
|
|
@@ -28,11 +29,38 @@ const cloneLoadResourcesResult = (loadResult) => ({
|
|
|
28
29
|
body: body && body.clone(),
|
|
29
30
|
})),
|
|
30
31
|
});
|
|
31
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Flatten a `LoadResultWithProps` (and its recursively-nested `props`) into one flat list of every
|
|
34
|
+
* `Entity3d` it produced, for the built-in `"Glb"` level entity class to parent under a single
|
|
35
|
+
* `GroupEntity`.
|
|
36
|
+
*/
|
|
37
|
+
function flattenGlbEntities(result) {
|
|
38
|
+
var _a;
|
|
39
|
+
return [...result.entities, ...((_a = result.props) !== null && _a !== void 0 ? _a : []).flatMap(prop => flattenGlbEntities(prop))];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Full 3D loader exposed as `Gg3dWorld.loader`: GLB+meta asset loading (`loadGgGlb` and friends)
|
|
43
|
+
* layered on top of `Gg3dLevelLoader`, so `registerClass`/`loadLevel`/`loadLevelFromUrl`/
|
|
44
|
+
* `getEntityByName` are all available directly on `world.loader`. Also registers a `"Glb"` level
|
|
45
|
+
* entity class (see `Glb3DSettings`) so a level JSON can place a GLB model declaratively, the same
|
|
46
|
+
* way it places primitives/triggers/cameras.
|
|
47
|
+
* @template TypeDoc - The type document repository
|
|
48
|
+
*/
|
|
49
|
+
export class Gg3dLoader extends Gg3dLevelLoader {
|
|
32
50
|
constructor(world) {
|
|
33
|
-
|
|
51
|
+
super(world);
|
|
34
52
|
this.filesCache = new Map();
|
|
35
53
|
this.loadResultCache = new Map();
|
|
54
|
+
this.registerClass('Glb', (w, settings) => __awaiter(this, void 0, void 0, function* () {
|
|
55
|
+
if (!settings.path) {
|
|
56
|
+
throw new Error('Path is required for Glb class');
|
|
57
|
+
}
|
|
58
|
+
const { path, position, rotation, cachingStrategy, loadProps, propsPath } = settings;
|
|
59
|
+
const result = yield this.loadGgGlb(path, Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (position !== undefined ? { position } : {})), (rotation !== undefined ? { rotation } : {})), (cachingStrategy !== undefined ? { cachingStrategy } : {})), (loadProps !== undefined ? { loadProps } : {})), (propsPath !== undefined ? { propsPath } : {})));
|
|
60
|
+
const group = new GroupEntity();
|
|
61
|
+
group.addChildren(...flattenGlbEntities(result));
|
|
62
|
+
return group;
|
|
63
|
+
}));
|
|
36
64
|
}
|
|
37
65
|
loadGgGlbFiles(path_1) {
|
|
38
66
|
return __awaiter(this, arguments, void 0, function* (path, useCache = false) {
|
|
@@ -57,6 +85,7 @@ export class Gg3dLoader {
|
|
|
57
85
|
}
|
|
58
86
|
loadGgGlbResources(path_1) {
|
|
59
87
|
return __awaiter(this, arguments, void 0, function* (path, cachingStrategy = CachingStrategy.Nothing) {
|
|
88
|
+
var _a, _b;
|
|
60
89
|
if (cachingStrategy == CachingStrategy.Entities && this.loadResultCache.has(path)) {
|
|
61
90
|
const cached = this.loadResultCache.get(path);
|
|
62
91
|
const cachedResult = cached instanceof Promise ? yield cached : cached;
|
|
@@ -67,21 +96,21 @@ export class Gg3dLoader {
|
|
|
67
96
|
throw new Error('GLB not found');
|
|
68
97
|
}
|
|
69
98
|
const [object, bodies] = yield Promise.all([
|
|
70
|
-
this.world.visualScene.loader.loadFromGgGlb(glb, meta),
|
|
71
|
-
this.world.physicsWorld.loader.loadFromGgGlb(glb, meta),
|
|
99
|
+
(_a = this.world.visualScene) === null || _a === void 0 ? void 0 : _a.loader.loadFromGgGlb(glb, meta),
|
|
100
|
+
(_b = this.world.physicsWorld) === null || _b === void 0 ? void 0 : _b.loader.loadFromGgGlb(glb, meta),
|
|
72
101
|
]);
|
|
73
102
|
const result = { resources: [], meta };
|
|
74
103
|
if (!object) {
|
|
75
104
|
return result;
|
|
76
105
|
}
|
|
77
|
-
if (bodies.length == 0) {
|
|
106
|
+
if ((bodies === null || bodies === void 0 ? void 0 : bodies.length) == 0) {
|
|
78
107
|
result.resources.push({ object3D: object, body: null });
|
|
79
108
|
}
|
|
80
|
-
else if (bodies.length == 1) {
|
|
109
|
+
else if ((bodies === null || bodies === void 0 ? void 0 : bodies.length) == 1) {
|
|
81
110
|
result.resources.push({ object3D: object, body: bodies[0] });
|
|
82
111
|
}
|
|
83
112
|
else {
|
|
84
|
-
for (const body of bodies) {
|
|
113
|
+
for (const body of bodies || []) {
|
|
85
114
|
result.resources.push({ object3D: object.popChild(body.name), body });
|
|
86
115
|
}
|
|
87
116
|
if (!object.isEmpty()) {
|
package/dist/3d/loaders.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { GgMeta } from './models/gg-meta';
|
|
2
2
|
import { IPhysicsWorld3dComponent } from './components/physics/i-physics-world-3d.component';
|
|
3
3
|
import { PhysicsTypeDocRepo3D, VisualTypeDocRepo3D } from './gg-3d-world';
|
|
4
|
-
export declare abstract class IPhysicsBody3dComponentLoader<
|
|
4
|
+
export declare abstract class IPhysicsBody3dComponentLoader<PTypeDoc extends PhysicsTypeDocRepo3D = PhysicsTypeDocRepo3D> {
|
|
5
5
|
protected readonly world: IPhysicsWorld3dComponent;
|
|
6
6
|
protected constructor(world: IPhysicsWorld3dComponent);
|
|
7
|
-
loadFromGgGlb(glbFile: ArrayBuffer, meta: GgMeta): Promise<
|
|
7
|
+
loadFromGgGlb(glbFile: ArrayBuffer, meta: GgMeta): Promise<PTypeDoc['rigidBody'][]>;
|
|
8
8
|
}
|
|
9
|
-
export interface IDisplayObject3dComponentLoader<
|
|
10
|
-
loadFromGgGlb(glbFile: ArrayBuffer, meta: GgMeta): Promise<
|
|
9
|
+
export interface IDisplayObject3dComponentLoader<VTypeDoc extends VisualTypeDocRepo3D = VisualTypeDocRepo3D> {
|
|
10
|
+
loadFromGgGlb(glbFile: ArrayBuffer, meta: GgMeta): Promise<VTypeDoc['displayObject'] | null>;
|
|
11
11
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import { GgWorld, GgWorldTypeDocRepo } from '../gg-world';
|
|
3
|
+
/**
|
|
4
|
+
* Whether a {@link BlueprintNode} pin carries an execution pulse ("do this now", no meaningful
|
|
5
|
+
* payload - e.g. Unreal's white exec pins) or a data value ("here's a value", not itself a
|
|
6
|
+
* trigger - e.g. Unreal's colored data pins). Purely descriptive for now (introspection/future
|
|
7
|
+
* editor tooling) - {@link BlueprintNode.trigger} treats every input pin the same way at runtime,
|
|
8
|
+
* since a node is free to both react to and read a value from the same pin (see
|
|
9
|
+
* {@link RemoveEntityBlueprintNode}, whose single `"entity"` pin is a data pin that also triggers
|
|
10
|
+
* the node when fed a value - the same way an Unreal event node's payload pins double as the
|
|
11
|
+
* thing that fires the node).
|
|
12
|
+
*/
|
|
13
|
+
export type BlueprintPinKind = 'exec' | 'data';
|
|
14
|
+
/**
|
|
15
|
+
* Declares one named pin a {@link BlueprintNode} exposes - either an input (fed a value via
|
|
16
|
+
* {@link BlueprintNode.trigger}) or an output (fired via {@link BlueprintNode.output}).
|
|
17
|
+
*/
|
|
18
|
+
export interface BlueprintPinDefinition {
|
|
19
|
+
name: string;
|
|
20
|
+
kind: BlueprintPinKind;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* One node in a {@link Blueprint} graph - the engine's analogue of a single Unreal Blueprint graph
|
|
24
|
+
* node: a small unit of behavior with named input pins that trigger it, named output pins it can
|
|
25
|
+
* fire in response, and a `settings` bag of static (non-pin) configuration baked in from its
|
|
26
|
+
* {@link BlueprintNodeJson} (e.g. `RemoveEntity`'s `dispose` flag). Register a concrete subclass's
|
|
27
|
+
* factory against a type alias via `LevelLoader.registerBlueprintNode` so `Blueprint` can
|
|
28
|
+
* instantiate it from JSON, the same way `LevelLoader.registerClass` works for entity classes.
|
|
29
|
+
* @template D - The position type
|
|
30
|
+
* @template R - The rotation type
|
|
31
|
+
* @template TypeDoc - The type document repository
|
|
32
|
+
*/
|
|
33
|
+
export declare abstract class BlueprintNode<D = any, R = any, TypeDoc extends GgWorldTypeDocRepo<D, R> = GgWorldTypeDocRepo<D, R>> {
|
|
34
|
+
protected readonly world: GgWorld<D, R, TypeDoc>;
|
|
35
|
+
protected readonly settings: Record<string, any>;
|
|
36
|
+
/**
|
|
37
|
+
* This node's input pins - see {@link trigger} for how they're fed.
|
|
38
|
+
*/
|
|
39
|
+
abstract readonly inputs: readonly BlueprintPinDefinition[];
|
|
40
|
+
/**
|
|
41
|
+
* This node's output pins - see {@link output} for how to observe them.
|
|
42
|
+
*/
|
|
43
|
+
abstract readonly outputs: readonly BlueprintPinDefinition[];
|
|
44
|
+
private readonly outputSubjects;
|
|
45
|
+
constructor(world: GgWorld<D, R, TypeDoc>, settings: Record<string, any>);
|
|
46
|
+
private subjectFor;
|
|
47
|
+
/**
|
|
48
|
+
* Observe one of this node's output pins firing - what a {@link BlueprintLinkJson} subscribes
|
|
49
|
+
* to in order to feed a downstream node's input, or what an embedding `Blueprint`'s own
|
|
50
|
+
* `outputs` entry bubbles up to whatever triggered the blueprint.
|
|
51
|
+
* @param name - The output pin's name, per {@link outputs}
|
|
52
|
+
*/
|
|
53
|
+
output(name: string): Observable<unknown>;
|
|
54
|
+
/**
|
|
55
|
+
* Fire one of this node's output pins - call from within {@link trigger} once the node has done
|
|
56
|
+
* whatever that output represents. A no-op if nothing is subscribed.
|
|
57
|
+
* @param name - The output pin's name, per {@link outputs}
|
|
58
|
+
* @param value - Payload for a data output pin; omit for a bare exec pulse
|
|
59
|
+
*/
|
|
60
|
+
protected emit(name: string, value?: unknown): void;
|
|
61
|
+
/**
|
|
62
|
+
* Feed a value/pulse into one of this node's input pins (per {@link inputs}), running whatever
|
|
63
|
+
* behavior that pin represents. Called by `Blueprint` both for external triggers (via its own
|
|
64
|
+
* `inputs` aliasing) and for links from another node's output pin.
|
|
65
|
+
* @param inputName - The input pin's name, per {@link inputs}
|
|
66
|
+
* @param value - Payload carried in on a data pin, if any
|
|
67
|
+
*/
|
|
68
|
+
abstract trigger(inputName: string, value?: unknown): void;
|
|
69
|
+
/**
|
|
70
|
+
* Release anything this node set up outside of its output subjects (timers, subscriptions,
|
|
71
|
+
* etc). Default no-op - override when a node needs it. `Blueprint.dispose` calls this on every
|
|
72
|
+
* node in its graph.
|
|
73
|
+
*/
|
|
74
|
+
dispose(): void;
|
|
75
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Subject } from 'rxjs';
|
|
2
|
+
/**
|
|
3
|
+
* One node in a {@link Blueprint} graph - the engine's analogue of a single Unreal Blueprint graph
|
|
4
|
+
* node: a small unit of behavior with named input pins that trigger it, named output pins it can
|
|
5
|
+
* fire in response, and a `settings` bag of static (non-pin) configuration baked in from its
|
|
6
|
+
* {@link BlueprintNodeJson} (e.g. `RemoveEntity`'s `dispose` flag). Register a concrete subclass's
|
|
7
|
+
* factory against a type alias via `LevelLoader.registerBlueprintNode` so `Blueprint` can
|
|
8
|
+
* instantiate it from JSON, the same way `LevelLoader.registerClass` works for entity classes.
|
|
9
|
+
* @template D - The position type
|
|
10
|
+
* @template R - The rotation type
|
|
11
|
+
* @template TypeDoc - The type document repository
|
|
12
|
+
*/
|
|
13
|
+
export class BlueprintNode {
|
|
14
|
+
constructor(world, settings) {
|
|
15
|
+
this.world = world;
|
|
16
|
+
this.settings = settings;
|
|
17
|
+
this.outputSubjects = new Map();
|
|
18
|
+
}
|
|
19
|
+
subjectFor(name) {
|
|
20
|
+
let subject = this.outputSubjects.get(name);
|
|
21
|
+
if (!subject) {
|
|
22
|
+
subject = new Subject();
|
|
23
|
+
this.outputSubjects.set(name, subject);
|
|
24
|
+
}
|
|
25
|
+
return subject;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Observe one of this node's output pins firing - what a {@link BlueprintLinkJson} subscribes
|
|
29
|
+
* to in order to feed a downstream node's input, or what an embedding `Blueprint`'s own
|
|
30
|
+
* `outputs` entry bubbles up to whatever triggered the blueprint.
|
|
31
|
+
* @param name - The output pin's name, per {@link outputs}
|
|
32
|
+
*/
|
|
33
|
+
output(name) {
|
|
34
|
+
return this.subjectFor(name).asObservable();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Fire one of this node's output pins - call from within {@link trigger} once the node has done
|
|
38
|
+
* whatever that output represents. A no-op if nothing is subscribed.
|
|
39
|
+
* @param name - The output pin's name, per {@link outputs}
|
|
40
|
+
* @param value - Payload for a data output pin; omit for a bare exec pulse
|
|
41
|
+
*/
|
|
42
|
+
emit(name, value) {
|
|
43
|
+
this.subjectFor(name).next(value);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Release anything this node set up outside of its output subjects (timers, subscriptions,
|
|
47
|
+
* etc). Default no-op - override when a node needs it. `Blueprint.dispose` calls this on every
|
|
48
|
+
* node in its graph.
|
|
49
|
+
*/
|
|
50
|
+
dispose() { }
|
|
51
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import { GgWorld, GgWorldTypeDocRepo } from '../gg-world';
|
|
3
|
+
import { BlueprintNode } from './blueprint-node';
|
|
4
|
+
/**
|
|
5
|
+
* A function that builds a {@link BlueprintNode} instance from its baked-in settings. Registered
|
|
6
|
+
* against a node type alias via `LevelLoader.registerBlueprintNode`, the same way
|
|
7
|
+
* {@link EntityGenerator} is registered against an entity class alias via `registerClass`.
|
|
8
|
+
* @template D - The position type
|
|
9
|
+
* @template R - The rotation type
|
|
10
|
+
* @template TypeDoc - The type document repository
|
|
11
|
+
*/
|
|
12
|
+
export type BlueprintNodeFactory<D, R, TypeDoc extends GgWorldTypeDocRepo<D, R>> = (world: GgWorld<D, R, TypeDoc>, settings: Record<string, any>) => BlueprintNode<D, R, TypeDoc>;
|
|
13
|
+
/**
|
|
14
|
+
* A reference to one named pin on one node within a {@link BlueprintJson} graph - either end of a
|
|
15
|
+
* {@link BlueprintLinkJson}, or what a graph's own `inputs`/`outputs` entry aliases.
|
|
16
|
+
*/
|
|
17
|
+
export interface BlueprintPinRef {
|
|
18
|
+
/**
|
|
19
|
+
* `id` of the node within the same `BlueprintJson.nodes` array
|
|
20
|
+
*/
|
|
21
|
+
node: string;
|
|
22
|
+
/**
|
|
23
|
+
* Pin name on that node, per its `BlueprintNode.inputs`/`outputs`
|
|
24
|
+
*/
|
|
25
|
+
pin: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* JSON description of a single node instance within a {@link BlueprintJson} graph.
|
|
29
|
+
*/
|
|
30
|
+
export interface BlueprintNodeJson {
|
|
31
|
+
/**
|
|
32
|
+
* Identifier for this node instance, unique within the same graph - referenced by
|
|
33
|
+
* `BlueprintLinkJson`/`BlueprintJson.inputs`/`BlueprintJson.outputs`.
|
|
34
|
+
*/
|
|
35
|
+
id: string;
|
|
36
|
+
/**
|
|
37
|
+
* Node type alias, matching a type registered via `LevelLoader.registerBlueprintNode` (e.g. the
|
|
38
|
+
* built-in `"RemoveEntity"`).
|
|
39
|
+
*/
|
|
40
|
+
type: string;
|
|
41
|
+
/**
|
|
42
|
+
* Static settings baked into the node (e.g. `RemoveEntity`'s `dispose` flag) - not wired at
|
|
43
|
+
* runtime, unlike a pin.
|
|
44
|
+
*/
|
|
45
|
+
settings?: Record<string, any>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* JSON description of one wire connecting one node's output pin to another node's input pin
|
|
49
|
+
* within the same {@link BlueprintJson} graph. Whenever `from` fires, `to` is triggered with
|
|
50
|
+
* whatever value (if any) `from` fired with.
|
|
51
|
+
*/
|
|
52
|
+
export interface BlueprintLinkJson {
|
|
53
|
+
from: BlueprintPinRef;
|
|
54
|
+
to: BlueprintPinRef;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A blueprint graph, serializable as a single JSON document - the engine's analogue of an Unreal
|
|
58
|
+
* Blueprint event graph. `nodes` are node instances (see {@link BlueprintNodeJson}), `links` wire
|
|
59
|
+
* one node's output pin to another's input pin, and `inputs`/`outputs` expose named entry/exit
|
|
60
|
+
* points at the graph's own boundary - each aliasing one node's pin - so embedding code (or, in
|
|
61
|
+
* the future, another blueprint nesting this one) doesn't need to know internal node ids. A level
|
|
62
|
+
* JSON references a `BlueprintJson` by name via its top-level `blueprints` map and an entity's
|
|
63
|
+
* `events` mapping - see `gg-engine-level-json`.
|
|
64
|
+
*/
|
|
65
|
+
export interface BlueprintJson {
|
|
66
|
+
/**
|
|
67
|
+
* Node instances in this graph
|
|
68
|
+
*/
|
|
69
|
+
nodes: BlueprintNodeJson[];
|
|
70
|
+
/**
|
|
71
|
+
* Wires wiring one node's output pin to another node's input pin
|
|
72
|
+
*/
|
|
73
|
+
links?: BlueprintLinkJson[];
|
|
74
|
+
/**
|
|
75
|
+
* Named entry points into this graph, each aliasing one node's input pin - e.g.
|
|
76
|
+
* `{ "in": { "node": "n1", "pin": "entity" } }` lets external code trigger `"n1"`'s `"entity"`
|
|
77
|
+
* pin by calling `blueprint.trigger("in", value)` without knowing the internal node id. A
|
|
78
|
+
* blueprint bound to a level JSON entity event is always triggered through the entry named
|
|
79
|
+
* `"in"` - see `gg-engine-level-json`.
|
|
80
|
+
*/
|
|
81
|
+
inputs?: Record<string, BlueprintPinRef>;
|
|
82
|
+
/**
|
|
83
|
+
* Named exit points out of this graph, each aliasing one node's output pin - for a future
|
|
84
|
+
* blueprint nested inside a larger graph to bubble one of its own nodes' outputs back out.
|
|
85
|
+
*/
|
|
86
|
+
outputs?: Record<string, BlueprintPinRef>;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Runtime instance of a {@link BlueprintJson} graph: builds one {@link BlueprintNode} per
|
|
90
|
+
* `nodes` entry (via the node type registry passed in), wires every `links` entry as a live
|
|
91
|
+
* subscription from the source node's output pin to the target node's input pin, and exposes the
|
|
92
|
+
* graph's own `inputs`/`outputs` boundary. Each binding of a blueprint (e.g. one level JSON entity
|
|
93
|
+
* event) gets its own `Blueprint` instance - and therefore its own node instances - even when
|
|
94
|
+
* multiple bindings reference the same `BlueprintJson` by name, so per-node state (a future timer
|
|
95
|
+
* node's countdown, etc) is never accidentally shared between unrelated bindings.
|
|
96
|
+
* @template D - The position type
|
|
97
|
+
* @template R - The rotation type
|
|
98
|
+
* @template TypeDoc - The type document repository
|
|
99
|
+
*/
|
|
100
|
+
export declare class Blueprint<D = any, R = any, TypeDoc extends GgWorldTypeDocRepo<D, R> = GgWorldTypeDocRepo<D, R>> {
|
|
101
|
+
private readonly json;
|
|
102
|
+
private readonly nodes;
|
|
103
|
+
private readonly linkSubscriptions;
|
|
104
|
+
constructor(world: GgWorld<D, R, TypeDoc>, json: BlueprintJson, registry: ReadonlyMap<string, BlueprintNodeFactory<D, R, TypeDoc>>);
|
|
105
|
+
/**
|
|
106
|
+
* Feed a value/pulse into one of this graph's named entry points (per `BlueprintJson.inputs`).
|
|
107
|
+
* A no-op (with a console warning) if no such input, or the node it aliases failed to build.
|
|
108
|
+
* @param inputName - Entry point name, per `BlueprintJson.inputs`
|
|
109
|
+
* @param value - Payload to hand to the aliased node's input pin, if any
|
|
110
|
+
*/
|
|
111
|
+
trigger(inputName: string, value?: unknown): void;
|
|
112
|
+
/**
|
|
113
|
+
* Observe one of this graph's named exit points (per `BlueprintJson.outputs`) firing.
|
|
114
|
+
* @param outputName - Exit point name, per `BlueprintJson.outputs`
|
|
115
|
+
* @throws if no such output is declared, or the node it aliases failed to build
|
|
116
|
+
*/
|
|
117
|
+
output(outputName: string): Observable<unknown>;
|
|
118
|
+
/**
|
|
119
|
+
* Unwire every link and dispose every node in this graph. Idempotent-ish - safe to call once
|
|
120
|
+
* per `Blueprint` instance, same lifetime contract as `IEntity.dispose`.
|
|
121
|
+
*/
|
|
122
|
+
dispose(): void;
|
|
123
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime instance of a {@link BlueprintJson} graph: builds one {@link BlueprintNode} per
|
|
3
|
+
* `nodes` entry (via the node type registry passed in), wires every `links` entry as a live
|
|
4
|
+
* subscription from the source node's output pin to the target node's input pin, and exposes the
|
|
5
|
+
* graph's own `inputs`/`outputs` boundary. Each binding of a blueprint (e.g. one level JSON entity
|
|
6
|
+
* event) gets its own `Blueprint` instance - and therefore its own node instances - even when
|
|
7
|
+
* multiple bindings reference the same `BlueprintJson` by name, so per-node state (a future timer
|
|
8
|
+
* node's countdown, etc) is never accidentally shared between unrelated bindings.
|
|
9
|
+
* @template D - The position type
|
|
10
|
+
* @template R - The rotation type
|
|
11
|
+
* @template TypeDoc - The type document repository
|
|
12
|
+
*/
|
|
13
|
+
export class Blueprint {
|
|
14
|
+
constructor(world, json, registry) {
|
|
15
|
+
var _a, _b;
|
|
16
|
+
this.json = json;
|
|
17
|
+
this.nodes = new Map();
|
|
18
|
+
this.linkSubscriptions = [];
|
|
19
|
+
for (const nodeJson of json.nodes) {
|
|
20
|
+
const factory = registry.get(nodeJson.type);
|
|
21
|
+
if (!factory) {
|
|
22
|
+
console.warn(`No blueprint node type registered for "${nodeJson.type}" - skipping node "${nodeJson.id}"`);
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
this.nodes.set(nodeJson.id, factory(world, (_a = nodeJson.settings) !== null && _a !== void 0 ? _a : {}));
|
|
26
|
+
}
|
|
27
|
+
for (const link of (_b = json.links) !== null && _b !== void 0 ? _b : []) {
|
|
28
|
+
const source = this.nodes.get(link.from.node);
|
|
29
|
+
const target = this.nodes.get(link.to.node);
|
|
30
|
+
if (!source || !target) {
|
|
31
|
+
console.warn(`Blueprint link references an unknown node ("${link.from.node}" -> "${link.to.node}") - skipping`);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
this.linkSubscriptions.push(source.output(link.from.pin).subscribe(value => target.trigger(link.to.pin, value)));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Feed a value/pulse into one of this graph's named entry points (per `BlueprintJson.inputs`).
|
|
39
|
+
* A no-op (with a console warning) if no such input, or the node it aliases failed to build.
|
|
40
|
+
* @param inputName - Entry point name, per `BlueprintJson.inputs`
|
|
41
|
+
* @param value - Payload to hand to the aliased node's input pin, if any
|
|
42
|
+
*/
|
|
43
|
+
trigger(inputName, value) {
|
|
44
|
+
var _a;
|
|
45
|
+
const ref = (_a = this.json.inputs) === null || _a === void 0 ? void 0 : _a[inputName];
|
|
46
|
+
if (!ref) {
|
|
47
|
+
console.warn(`Blueprint has no declared input named "${inputName}" - ignoring trigger`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const node = this.nodes.get(ref.node);
|
|
51
|
+
if (!node) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
node.trigger(ref.pin, value);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Observe one of this graph's named exit points (per `BlueprintJson.outputs`) firing.
|
|
58
|
+
* @param outputName - Exit point name, per `BlueprintJson.outputs`
|
|
59
|
+
* @throws if no such output is declared, or the node it aliases failed to build
|
|
60
|
+
*/
|
|
61
|
+
output(outputName) {
|
|
62
|
+
var _a;
|
|
63
|
+
const ref = (_a = this.json.outputs) === null || _a === void 0 ? void 0 : _a[outputName];
|
|
64
|
+
if (!ref) {
|
|
65
|
+
throw new Error(`Blueprint has no declared output named "${outputName}"`);
|
|
66
|
+
}
|
|
67
|
+
const node = this.nodes.get(ref.node);
|
|
68
|
+
if (!node) {
|
|
69
|
+
throw new Error(`Blueprint output "${outputName}" references unknown node "${ref.node}"`);
|
|
70
|
+
}
|
|
71
|
+
return node.output(ref.pin);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Unwire every link and dispose every node in this graph. Idempotent-ish - safe to call once
|
|
75
|
+
* per `Blueprint` instance, same lifetime contract as `IEntity.dispose`.
|
|
76
|
+
*/
|
|
77
|
+
dispose() {
|
|
78
|
+
for (const sub of this.linkSubscriptions) {
|
|
79
|
+
sub.unsubscribe();
|
|
80
|
+
}
|
|
81
|
+
this.linkSubscriptions.splice(0, this.linkSubscriptions.length);
|
|
82
|
+
for (const node of this.nodes.values()) {
|
|
83
|
+
node.dispose();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { GgWorldTypeDocRepo } from '../../gg-world';
|
|
2
|
+
import { BlueprintNode, BlueprintPinDefinition } from '../blueprint-node';
|
|
3
|
+
/**
|
|
4
|
+
* Settings for the built-in `"RemoveEntity"` blueprint node - baked in from its
|
|
5
|
+
* {@link BlueprintNodeJson.settings}, not wired at runtime.
|
|
6
|
+
*/
|
|
7
|
+
export interface RemoveEntityNodeSettings {
|
|
8
|
+
/**
|
|
9
|
+
* Whether to dispose the entity (release its components/children) as well as remove it from
|
|
10
|
+
* the world, same as the `dispose` argument of `GgWorld.removeEntity`. Defaults to `false`.
|
|
11
|
+
*/
|
|
12
|
+
dispose?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Built-in blueprint node: removes an entity from the world - the blueprint analogue of calling
|
|
16
|
+
* `world.removeEntity(entity, dispose)` directly. Has one input pin, `"entity"` (a data pin that
|
|
17
|
+
* also acts as this node's trigger - feeding it a value runs the node, same as an Unreal event
|
|
18
|
+
* node's payload pin doubling as its exec pulse) and no output pins. Whether the removal also
|
|
19
|
+
* disposes the entity is controlled by the static `dispose` setting, not a pin - see
|
|
20
|
+
* {@link RemoveEntityNodeSettings}.
|
|
21
|
+
*/
|
|
22
|
+
export declare class RemoveEntityBlueprintNode<D = any, R = any, TypeDoc extends GgWorldTypeDocRepo<D, R> = GgWorldTypeDocRepo<D, R>> extends BlueprintNode<D, R, TypeDoc> {
|
|
23
|
+
readonly inputs: readonly BlueprintPinDefinition[];
|
|
24
|
+
readonly outputs: readonly BlueprintPinDefinition[];
|
|
25
|
+
trigger(inputName: string, value?: unknown): void;
|
|
26
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { IEntity } from '../../entities/i-entity';
|
|
2
|
+
import { BlueprintNode } from '../blueprint-node';
|
|
3
|
+
/**
|
|
4
|
+
* Built-in blueprint node: removes an entity from the world - the blueprint analogue of calling
|
|
5
|
+
* `world.removeEntity(entity, dispose)` directly. Has one input pin, `"entity"` (a data pin that
|
|
6
|
+
* also acts as this node's trigger - feeding it a value runs the node, same as an Unreal event
|
|
7
|
+
* node's payload pin doubling as its exec pulse) and no output pins. Whether the removal also
|
|
8
|
+
* disposes the entity is controlled by the static `dispose` setting, not a pin - see
|
|
9
|
+
* {@link RemoveEntityNodeSettings}.
|
|
10
|
+
*/
|
|
11
|
+
export class RemoveEntityBlueprintNode extends BlueprintNode {
|
|
12
|
+
constructor() {
|
|
13
|
+
super(...arguments);
|
|
14
|
+
this.inputs = [{ name: 'entity', kind: 'data' }];
|
|
15
|
+
this.outputs = [];
|
|
16
|
+
}
|
|
17
|
+
trigger(inputName, value) {
|
|
18
|
+
var _a;
|
|
19
|
+
if (inputName !== 'entity') {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (!(value instanceof IEntity)) {
|
|
23
|
+
console.warn('RemoveEntity blueprint node triggered without a valid entity reference - ignoring');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const settings = this.settings;
|
|
27
|
+
this.world.removeEntity(value, (_a = settings.dispose) !== null && _a !== void 0 ? _a : false);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { IEntity } from '../entities/i-entity';
|
|
2
|
-
import { GgWorld,
|
|
3
|
-
|
|
2
|
+
import { GgWorld, GgWorldTypeDocRepo } from '../gg-world';
|
|
3
|
+
import { IComponent } from './i-component';
|
|
4
|
+
export interface IWorldComponent<D, R, TypeDoc extends GgWorldTypeDocRepo<D, R> = GgWorldTypeDocRepo<D, R>> extends IComponent {
|
|
4
5
|
entity: IEntity | null;
|
|
5
|
-
addToWorld(world: GgWorld<D, R,
|
|
6
|
-
removeFromWorld(world: GgWorld<D, R,
|
|
7
|
-
dispose(): void;
|
|
6
|
+
addToWorld(world: GgWorld<D, R, TypeDoc>): void;
|
|
7
|
+
removeFromWorld(world: GgWorld<D, R, TypeDoc>, dispose?: boolean): void;
|
|
8
8
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { IEntity } from '../../entities/i-entity';
|
|
2
2
|
import { IWorldComponent } from '../i-world-component';
|
|
3
|
-
import { GgWorld,
|
|
3
|
+
import { GgWorld, GgWorldTypeDocPPatch, PhysicsTypeDocRepo } from '../../gg-world';
|
|
4
4
|
import { CollisionGroup, DebugBodySettings } from '../../models/body-options';
|
|
5
|
-
export interface IBodyComponent<D, R,
|
|
5
|
+
export interface IBodyComponent<D, R, PTypeDoc extends PhysicsTypeDocRepo<D, R> = PhysicsTypeDocRepo<D, R>> extends IWorldComponent<D, R, GgWorldTypeDocPPatch<D, R, PTypeDoc>> {
|
|
6
6
|
entity: IEntity | null;
|
|
7
7
|
position: D;
|
|
8
8
|
rotation: R;
|
|
@@ -13,7 +13,7 @@ export interface IBodyComponent<D, R, TypeDoc extends PhysicsTypeDocRepo<D, R> =
|
|
|
13
13
|
set interactWithCollisionGroups(value: ReadonlyArray<CollisionGroup> | 'all');
|
|
14
14
|
/** body info for physics debugger view */
|
|
15
15
|
readonly debugBodySettings: DebugBodySettings<any>;
|
|
16
|
-
clone(): IBodyComponent<D, R,
|
|
17
|
-
addToWorld(world: GgWorld<D, R,
|
|
18
|
-
removeFromWorld(world: GgWorld<D, R,
|
|
16
|
+
clone(): IBodyComponent<D, R, PTypeDoc>;
|
|
17
|
+
addToWorld(world: GgWorld<D, R, GgWorldTypeDocPPatch<D, R, PTypeDoc>>): void;
|
|
18
|
+
removeFromWorld(world: GgWorld<D, R, GgWorldTypeDocPPatch<D, R, PTypeDoc>>): void;
|
|
19
19
|
}
|
|
@@ -2,6 +2,7 @@ import { PhysicsTypeDocRepo } from '../../gg-world';
|
|
|
2
2
|
import { IComponent } from '../i-component';
|
|
3
3
|
import { CollisionGroup } from '../../models/body-options';
|
|
4
4
|
import { Subject } from 'rxjs';
|
|
5
|
+
import { RaycastOptions, RaycastResult } from '../../models/raycasting';
|
|
5
6
|
/**
|
|
6
7
|
* Interface representing a physics world component.
|
|
7
8
|
*
|
|
@@ -9,11 +10,11 @@ import { Subject } from 'rxjs';
|
|
|
9
10
|
* @template R - Type representing the physics engine's rigid body.
|
|
10
11
|
* @template TypeDoc - Physics typings repository.
|
|
11
12
|
*/
|
|
12
|
-
export interface IPhysicsWorldComponent<D, R,
|
|
13
|
+
export interface IPhysicsWorldComponent<D, R, PTypeDoc extends PhysicsTypeDocRepo<D, R> = PhysicsTypeDocRepo<D, R>> extends IComponent {
|
|
13
14
|
/**
|
|
14
15
|
* Factory function for creating physics-related objects.
|
|
15
16
|
*/
|
|
16
|
-
readonly factory:
|
|
17
|
+
readonly factory: PTypeDoc['factory'];
|
|
17
18
|
/**
|
|
18
19
|
* The gravity vector affecting the physics world.
|
|
19
20
|
*/
|
|
@@ -21,15 +22,15 @@ export interface IPhysicsWorldComponent<D, R, TypeDoc extends PhysicsTypeDocRepo
|
|
|
21
22
|
/**
|
|
22
23
|
* Event emitter that emits newly added physics components.
|
|
23
24
|
*/
|
|
24
|
-
readonly added$: Subject<
|
|
25
|
+
readonly added$: Subject<PTypeDoc['rigidBody'] | PTypeDoc['trigger'] | any>;
|
|
25
26
|
/**
|
|
26
27
|
* Event emitter that emits just removed physics components.
|
|
27
28
|
*/
|
|
28
|
-
readonly removed$: Subject<
|
|
29
|
+
readonly removed$: Subject<PTypeDoc['rigidBody'] | PTypeDoc['trigger'] | any>;
|
|
29
30
|
/**
|
|
30
31
|
* List of currently added physics components in the world.
|
|
31
32
|
*/
|
|
32
|
-
readonly children: (
|
|
33
|
+
readonly children: (PTypeDoc['rigidBody'] | PTypeDoc['trigger'] | any)[];
|
|
33
34
|
/**
|
|
34
35
|
* The main collision group. All physics bodies have this collision group set by default.
|
|
35
36
|
*/
|
|
@@ -58,4 +59,11 @@ export interface IPhysicsWorldComponent<D, R, TypeDoc extends PhysicsTypeDocRepo
|
|
|
58
59
|
* @param group - The collision group to be removed.
|
|
59
60
|
*/
|
|
60
61
|
deregisterCollisionGroup(group: CollisionGroup): void;
|
|
62
|
+
/**
|
|
63
|
+
* Performs a raycast in the physics world.
|
|
64
|
+
*
|
|
65
|
+
* @param options - The options for the raycast.
|
|
66
|
+
* @returns The result of the raycast.
|
|
67
|
+
*/
|
|
68
|
+
raycast(options: RaycastOptions<D>): RaycastResult<D, PTypeDoc['rigidBody'] | PTypeDoc['trigger']>;
|
|
61
69
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { IBodyComponent } from './i-body.component';
|
|
2
2
|
import { PhysicsTypeDocRepo } from '../../gg-world';
|
|
3
|
-
export interface IRigidBodyComponent<D, R,
|
|
3
|
+
export interface IRigidBodyComponent<D, R, PTypeDoc extends PhysicsTypeDocRepo<D, R> = PhysicsTypeDocRepo<D, R>> extends IBodyComponent<D, R, PTypeDoc> {
|
|
4
4
|
linearVelocity: D;
|
|
5
5
|
angularVelocity: R | D;
|
|
6
|
-
clone(): IRigidBodyComponent<D, R,
|
|
6
|
+
clone(): IRigidBodyComponent<D, R, PTypeDoc>;
|
|
7
7
|
/** clear velocities etc. */
|
|
8
8
|
resetMotion(): void;
|
|
9
9
|
}
|
|
@@ -2,9 +2,9 @@ import { Observable } from 'rxjs';
|
|
|
2
2
|
import { IRigidBodyComponent } from './i-rigid-body.component';
|
|
3
3
|
import { IBodyComponent } from './i-body.component';
|
|
4
4
|
import { PhysicsTypeDocRepo } from '../../gg-world';
|
|
5
|
-
export interface ITriggerComponent<D, R,
|
|
6
|
-
get onEntityEntered(): Observable<IRigidBodyComponent<D, R,
|
|
7
|
-
get onEntityLeft(): Observable<IRigidBodyComponent<D, R,
|
|
8
|
-
clone(): ITriggerComponent<D, R,
|
|
5
|
+
export interface ITriggerComponent<D, R, PTypeDoc extends PhysicsTypeDocRepo<D, R> = PhysicsTypeDocRepo<D, R>> extends IBodyComponent<D, R, PTypeDoc> {
|
|
6
|
+
get onEntityEntered(): Observable<IRigidBodyComponent<D, R, PTypeDoc>>;
|
|
7
|
+
get onEntityLeft(): Observable<IRigidBodyComponent<D, R, PTypeDoc> | null>;
|
|
8
|
+
clone(): ITriggerComponent<D, R, PTypeDoc>;
|
|
9
9
|
checkOverlaps(): void;
|
|
10
10
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { GgBox, GgWorld, VisualTypeDocRepo } from '../../../base';
|
|
1
|
+
import { GgBox, GgWorld, GgWorldTypeDocVPatch, VisualTypeDocRepo } from '../../../base';
|
|
2
2
|
import { IWorldComponent } from '../i-world-component';
|
|
3
|
-
export interface IDisplayObjectComponent<D, R,
|
|
3
|
+
export interface IDisplayObjectComponent<D, R, VTypeDoc extends VisualTypeDocRepo<D, R> = VisualTypeDocRepo<D, R>> extends IWorldComponent<D, R, GgWorldTypeDocVPatch<D, R, VTypeDoc>> {
|
|
4
4
|
position: D;
|
|
5
5
|
rotation: R;
|
|
6
6
|
scale: D;
|
|
7
7
|
visible: boolean;
|
|
8
8
|
name: string;
|
|
9
9
|
isEmpty(): boolean;
|
|
10
|
-
popChild(name: string): IDisplayObjectComponent<D, R,
|
|
10
|
+
popChild(name: string): IDisplayObjectComponent<D, R, VTypeDoc> | null;
|
|
11
11
|
getBoundings(): GgBox<D>;
|
|
12
|
-
clone(): IDisplayObjectComponent<D, R,
|
|
13
|
-
addToWorld(world: GgWorld<D, R,
|
|
14
|
-
removeFromWorld(world: GgWorld<D, R,
|
|
12
|
+
clone(): IDisplayObjectComponent<D, R, VTypeDoc>;
|
|
13
|
+
addToWorld(world: GgWorld<D, R, GgWorldTypeDocVPatch<D, R, VTypeDoc>>): void;
|
|
14
|
+
removeFromWorld(world: GgWorld<D, R, GgWorldTypeDocVPatch<D, R, VTypeDoc>>): void;
|
|
15
15
|
}
|