@gg-web-engine/core 0.0.58 → 0.0.60

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.
Files changed (59) hide show
  1. package/dist/2d/components/rendering/i-camera-2d.component.d.ts +5 -0
  2. package/dist/2d/components/rendering/i-visual-scene-2d.component.d.ts +1 -2
  3. package/dist/2d/entities/renderer-2d.entity.d.ts +2 -1
  4. package/dist/2d/gg-2d-world.d.ts +5 -1
  5. package/dist/2d/gg-2d-world.js +57 -2
  6. package/dist/2d/index.d.ts +3 -0
  7. package/dist/2d/index.js +3 -0
  8. package/dist/2d/level-loader.d.ts +101 -0
  9. package/dist/2d/level-loader.js +88 -0
  10. package/dist/2d/loader.d.ts +11 -0
  11. package/dist/2d/loader.js +10 -0
  12. package/dist/3d/components/rendering/{i-camera.component.d.ts → i-camera-3d.component.d.ts} +1 -1
  13. package/dist/3d/components/rendering/i-camera-3d.component.js +1 -0
  14. package/dist/3d/components/rendering/i-renderer-3d.component.d.ts +0 -1
  15. package/dist/3d/components/rendering/i-visual-scene-3d.component.d.ts +1 -2
  16. package/dist/3d/entities/camera-3d.entity.d.ts +24 -0
  17. package/dist/3d/entities/camera-3d.entity.js +35 -0
  18. package/dist/3d/entities/renderer-3d.entity.d.ts +0 -5
  19. package/dist/3d/entities/renderer-3d.entity.js +0 -15
  20. package/dist/3d/gg-3d-world.d.ts +2 -2
  21. package/dist/3d/gg-3d-world.js +73 -0
  22. package/dist/3d/index.d.ts +3 -1
  23. package/dist/3d/index.js +3 -1
  24. package/dist/3d/level-loader.d.ts +300 -0
  25. package/dist/3d/level-loader.js +267 -0
  26. package/dist/3d/loader.d.ts +44 -3
  27. package/dist/3d/loader.js +41 -4
  28. package/dist/3d/models/gg-meta.d.ts +10 -0
  29. package/dist/3d/models/gg-meta.js +2 -1
  30. package/dist/base/blueprint/blueprint-node.d.ts +75 -0
  31. package/dist/base/blueprint/blueprint-node.js +51 -0
  32. package/dist/base/blueprint/blueprint.d.ts +123 -0
  33. package/dist/base/blueprint/blueprint.js +86 -0
  34. package/dist/base/blueprint/nodes/remove-entity.node.d.ts +26 -0
  35. package/dist/base/blueprint/nodes/remove-entity.node.js +29 -0
  36. package/dist/base/clock/pausable-clock.d.ts +12 -0
  37. package/dist/base/clock/pausable-clock.js +24 -0
  38. package/dist/base/components/rendering/i-renderer.component.d.ts +1 -0
  39. package/dist/base/components/rendering/i-visual-scene.component.d.ts +2 -0
  40. package/dist/base/entities/group.entity.d.ts +17 -0
  41. package/dist/base/entities/group.entity.js +19 -0
  42. package/dist/base/entities/i-entity.d.ts +11 -0
  43. package/dist/base/entities/i-entity.js +28 -0
  44. package/dist/base/entities/i-renderer.entity.d.ts +7 -1
  45. package/dist/base/entities/i-renderer.entity.js +15 -0
  46. package/dist/base/gg-world.d.ts +13 -0
  47. package/dist/base/gg-world.js +83 -1
  48. package/dist/base/index.d.ts +5 -0
  49. package/dist/base/index.js +5 -0
  50. package/dist/base/inputs/mouse.input.js +1 -0
  51. package/dist/base/level-loader.d.ts +217 -0
  52. package/dist/base/level-loader.js +258 -0
  53. package/dist/version.d.ts +1 -1
  54. package/dist/version.js +1 -1
  55. package/package.json +10 -9
  56. package/tsconfig.json +4 -1
  57. package/blender_exporter/build_blender_scene.py +0 -179
  58. package/blender_exporter/spherical_to_cube_texture.py +0 -116
  59. /package/dist/{3d/components/rendering/i-camera.component.js → 2d/components/rendering/i-camera-2d.component.js} +0 -0
@@ -0,0 +1,5 @@
1
+ import { IDisplayObject2dComponent } from './i-display-object-2d.component';
2
+ import { VisualTypeDocRepo2D } from '../../gg-2d-world';
3
+ export interface ICamera2dComponent<VTypeDoc extends VisualTypeDocRepo2D = VisualTypeDocRepo2D> extends IDisplayObject2dComponent<VTypeDoc> {
4
+ zoom: number;
5
+ }
@@ -1,5 +1,4 @@
1
- import { IVisualSceneComponent, Point2, RendererOptions } from '../../../base';
1
+ import { IVisualSceneComponent, Point2 } from '../../../base';
2
2
  import { VisualTypeDocRepo2D } from '../../gg-2d-world';
3
3
  export interface IVisualScene2dComponent<VTypeDoc extends VisualTypeDocRepo2D = VisualTypeDocRepo2D> extends IVisualSceneComponent<Point2, number, VTypeDoc> {
4
- createRenderer(canvas?: HTMLCanvasElement, rendererOptions?: Partial<RendererOptions & VTypeDoc['rendererExtraOpts']>): VTypeDoc['renderer'];
5
4
  }
@@ -1,4 +1,5 @@
1
1
  import { IRendererEntity, Point2 } from '../../base';
2
2
  import { VisualTypeDocRepo2D } from '../gg-2d-world';
3
- export declare class Renderer2dEntity<VTypeDoc extends VisualTypeDocRepo2D = VisualTypeDocRepo2D> extends IRendererEntity<Point2, number, VTypeDoc> {
3
+ import { IPositionable2d } from '../interfaces/i-positionable-2d';
4
+ export declare class Renderer2dEntity<VTypeDoc extends VisualTypeDocRepo2D = VisualTypeDocRepo2D> extends IRendererEntity<Point2, number, VTypeDoc> implements IPositionable2d {
4
5
  }
@@ -1,4 +1,5 @@
1
1
  import { GgWorld, Point2, RendererOptions } from '../base';
2
+ import { Gg2dLoader } from './loader';
2
3
  import { BodyShape2DDescriptor } from './models/shapes';
3
4
  import { Entity2d } from './entities/entity-2d';
4
5
  import { IPhysicsWorld2dComponent } from './components/physics/i-physics-world-2d.component';
@@ -7,6 +8,7 @@ import { Renderer2dEntity } from './entities/renderer-2d.entity';
7
8
  import { DisplayObject2dOpts, IDisplayObject2dComponentFactory, IPhysicsBody2dComponentFactory } from './factories';
8
9
  import { IRenderer2dComponent } from './components/rendering/i-renderer-2d.component';
9
10
  import { IDisplayObject2dComponent } from './components/rendering/i-display-object-2d.component';
11
+ import { ICamera2dComponent } from './components/rendering/i-camera-2d.component';
10
12
  import { ITrigger2dComponent } from './components/physics/i-trigger-2d.component';
11
13
  import { IRigidBody2dComponent } from './components/physics/i-rigid-body-2d.component';
12
14
  export type VisualTypeDocRepo2D = {
@@ -14,6 +16,7 @@ export type VisualTypeDocRepo2D = {
14
16
  displayObject: IDisplayObject2dComponent;
15
17
  renderer: IRenderer2dComponent;
16
18
  rendererExtraOpts: {};
19
+ camera: ICamera2dComponent;
17
20
  texture: unknown;
18
21
  };
19
22
  export type PhysicsTypeDocRepo2D = {
@@ -49,12 +52,13 @@ export type TypedGg2dWorld<VW extends Gg2dWorld<any> | null, PW extends Gg2dWorl
49
52
  physicsWorld: PSTD['physicsWorld'];
50
53
  }> : never : never;
51
54
  export declare class Gg2dWorld<TypeDoc extends Gg2dWorldTypeDocRepo = Gg2dWorldTypeDocRepo, SceneTypeDoc extends Gg2dWorldSceneTypeRepo<TypeDoc> = Gg2dWorldSceneTypeRepo<TypeDoc>> extends GgWorld<Point2, number, TypeDoc, SceneTypeDoc> {
55
+ readonly loader: Gg2dLoader<TypeDoc>;
52
56
  constructor(args: {
53
57
  visualScene?: SceneTypeDoc['visualScene'];
54
58
  physicsWorld?: SceneTypeDoc['physicsWorld'];
55
59
  });
56
60
  addPrimitiveRigidBody(descr: BodyShape2DDescriptor, position?: Point2, rotation?: number, material?: DisplayObject2dOpts<TypeDoc['vTypeDoc']['texture']>): Entity2d<TypeDoc>;
57
- addRenderer(canvas?: HTMLCanvasElement, rendererOptions?: Partial<RendererOptions & TypeDoc['vTypeDoc']['rendererExtraOpts']>): Renderer2dEntity<TypeDoc['vTypeDoc']>;
61
+ addRenderer(camera: TypeDoc['vTypeDoc']['camera'], canvas?: HTMLCanvasElement, rendererOptions?: Partial<RendererOptions & TypeDoc['vTypeDoc']['rendererExtraOpts']>): Renderer2dEntity<TypeDoc['vTypeDoc']>;
58
62
  protected registerConsoleCommands(ggstatic: {
59
63
  registerConsoleCommand: (world: GgWorld<any, any> | null, command: string, handler: (...args: string[]) => Promise<string>, doc?: string) => void;
60
64
  }): void;
@@ -8,11 +8,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { GgWorld, Pnt2 } from '../base';
11
+ import { Gg2dLoader } from './loader';
11
12
  import { Entity2d } from './entities/entity-2d';
12
13
  import { Renderer2dEntity } from './entities/renderer-2d.entity';
13
14
  export class Gg2dWorld extends GgWorld {
14
15
  constructor(args) {
15
16
  super(args);
17
+ this.loader = new Gg2dLoader(this);
16
18
  }
17
19
  addPrimitiveRigidBody(descr, position = Pnt2.O, rotation = 0, material = {}) {
18
20
  var _a, _b;
@@ -25,16 +27,69 @@ export class Gg2dWorld extends GgWorld {
25
27
  this.addEntity(entity);
26
28
  return entity;
27
29
  }
28
- addRenderer(canvas, rendererOptions) {
30
+ addRenderer(camera, canvas, rendererOptions) {
29
31
  if (!this.visualScene) {
30
32
  throw new Error('Cannot add renderer to the world without visual scene');
31
33
  }
32
- const entity = new Renderer2dEntity(this.visualScene.createRenderer(canvas, rendererOptions));
34
+ const entity = new Renderer2dEntity(this.visualScene.createRenderer(camera, canvas, rendererOptions));
33
35
  this.addEntity(entity);
34
36
  return entity;
35
37
  }
36
38
  registerConsoleCommands(ggstatic) {
37
39
  super.registerConsoleCommands(ggstatic);
40
+ ggstatic.registerConsoleCommand(this, 'set_position', (...args) => __awaiter(this, void 0, void 0, function* () {
41
+ const [name, x, y] = args;
42
+ if (!name) {
43
+ throw new Error('usage: set_position <name> <x> <y>');
44
+ }
45
+ const entity = this.getEntityByName(name);
46
+ if (!('position' in entity)) {
47
+ throw new Error(`Entity "${name}" (${entity.constructor.name}) has no position`);
48
+ }
49
+ if ([x, y].some(v => v === undefined || isNaN(+v))) {
50
+ throw new Error('usage: set_position <name> <x> <y>');
51
+ }
52
+ entity.position = { x: +x, y: +y };
53
+ return JSON.stringify(entity.position);
54
+ }), 'args: [ string, float, float ]; Teleport a named entity to world-space coordinates. Use ' +
55
+ '"entities"/"entity <name>" to find entity names and their current position');
56
+ ggstatic.registerConsoleCommand(this, 'set_rotation', (...args) => __awaiter(this, void 0, void 0, function* () {
57
+ const [name, angle] = args;
58
+ if (!name) {
59
+ throw new Error('usage: set_rotation <name> <angleRadians>');
60
+ }
61
+ const entity = this.getEntityByName(name);
62
+ if (!('rotation' in entity)) {
63
+ throw new Error(`Entity "${name}" (${entity.constructor.name}) has no rotation`);
64
+ }
65
+ if (angle === undefined || isNaN(+angle)) {
66
+ throw new Error('usage: set_rotation <name> <angleRadians>');
67
+ }
68
+ entity.rotation = +angle;
69
+ return JSON.stringify(entity.rotation);
70
+ }), 'args: [ string, float ]; Rotate a named entity to the given angle, in radians');
71
+ ggstatic.registerConsoleCommand(this, 'spawn', (...args) => __awaiter(this, void 0, void 0, function* () {
72
+ const [shapeArg, x, y, dynamicArg] = args;
73
+ if ([x, y].some(v => v === undefined || isNaN(+v))) {
74
+ throw new Error('usage: spawn <SQUARE|CIRCLE> <x> <y> [dynamic=0|1]');
75
+ }
76
+ const dynamic = dynamicArg === undefined ? true : dynamicArg === '1';
77
+ let shape;
78
+ switch ((shapeArg || '').toUpperCase()) {
79
+ case 'SQUARE':
80
+ shape = { shape: 'SQUARE', dimensions: { x: 1, y: 1 } };
81
+ break;
82
+ case 'CIRCLE':
83
+ shape = { shape: 'CIRCLE', radius: 0.5 };
84
+ break;
85
+ default:
86
+ throw new Error(`Unknown shape "${shapeArg}". Use SQUARE|CIRCLE`);
87
+ }
88
+ const entity = this.addPrimitiveRigidBody({ shape, body: { dynamic } }, { x: +x, y: +y });
89
+ return `spawned "${entity.name}" (${shape.shape}) at ${JSON.stringify(entity.position)}`;
90
+ }), 'args: [ SQUARE|CIRCLE, float, float, 0|1? ]; Spawn a default-sized primitive rigid body at ' +
91
+ 'world-space coordinates, for probing physics. dynamic (last arg) defaults to 1 (falls ' +
92
+ 'under gravity); pass 0 for a static prop');
38
93
  if (this.physicsWorld) {
39
94
  ggstatic.registerConsoleCommand(this, 'gravity', (...args) => __awaiter(this, void 0, void 0, function* () {
40
95
  if (args.length == 1) {
@@ -1,6 +1,7 @@
1
1
  export * from './components/physics/i-rigid-body-2d.component';
2
2
  export * from './components/physics/i-trigger-2d.component';
3
3
  export * from './components/physics/i-physics-world-2d.component';
4
+ export * from './components/rendering/i-camera-2d.component';
4
5
  export * from './components/rendering/i-display-object-2d.component';
5
6
  export * from './components/rendering/i-renderer-2d.component';
6
7
  export * from './components/rendering/i-visual-scene-2d.component';
@@ -14,3 +15,5 @@ export * from './models/body-options';
14
15
  export * from './models/shapes';
15
16
  export * from './factories';
16
17
  export * from './gg-2d-world';
18
+ export * from './loader';
19
+ export * from './level-loader';
package/dist/2d/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './components/physics/i-rigid-body-2d.component';
2
2
  export * from './components/physics/i-trigger-2d.component';
3
3
  export * from './components/physics/i-physics-world-2d.component';
4
+ export * from './components/rendering/i-camera-2d.component';
4
5
  export * from './components/rendering/i-display-object-2d.component';
5
6
  export * from './components/rendering/i-renderer-2d.component';
6
7
  export * from './components/rendering/i-visual-scene-2d.component';
@@ -14,3 +15,5 @@ export * from './models/body-options';
14
15
  export * from './models/shapes';
15
16
  export * from './factories';
16
17
  export * from './gg-2d-world';
18
+ export * from './loader';
19
+ export * from './level-loader';
@@ -0,0 +1,101 @@
1
+ import { LevelLoader } from '../base/level-loader';
2
+ import { Gg2dWorld, Gg2dWorldTypeDocRepo } from './gg-2d-world';
3
+ import { Point2 } from '../base';
4
+ import { DisplayObject2dOpts } from './factories';
5
+ import { Body2DOptions } from './models/body-options';
6
+ import { Shape2DDescriptor } from './models/shapes';
7
+ /**
8
+ * Shape names accepted by the built-in `"Primitive"` entity class in a 2D level JSON, via the
9
+ * sibling `shape` field on the entity (e.g. `{ class: "Primitive", shape: "SQUARE" }`) - the same
10
+ * `Shape2DDescriptor['shape']` values used at the engine API level, so no translation is needed
11
+ * between a level JSON and `Gg2dWorld.addPrimitiveRigidBody`.
12
+ */
13
+ export type Primitive2DShapeName = Shape2DDescriptor['shape'];
14
+ /**
15
+ * Settings shared by every primitive entity (Square, Circle, ...)
16
+ */
17
+ export interface PrimitiveSettings {
18
+ /**
19
+ * Which primitive shape to construct
20
+ */
21
+ shape: Primitive2DShapeName;
22
+ /**
23
+ * Position of the primitive
24
+ */
25
+ position?: Point2;
26
+ /**
27
+ * Rotation of the primitive in radians
28
+ */
29
+ rotation?: number;
30
+ /**
31
+ * Dimensions of the primitive (for Square)
32
+ */
33
+ dimensions?: Point2;
34
+ /**
35
+ * Radius of the primitive (for Circle)
36
+ */
37
+ radius?: number;
38
+ /**
39
+ * Material options for the primitive
40
+ */
41
+ material?: DisplayObject2dOpts<any>;
42
+ /**
43
+ * Physics body options, merged over sensible defaults
44
+ */
45
+ body?: Partial<Body2DOptions>;
46
+ }
47
+ /**
48
+ * Settings for a trigger entity
49
+ */
50
+ export interface TriggerSettings {
51
+ /**
52
+ * Position of the trigger
53
+ */
54
+ position?: Point2;
55
+ /**
56
+ * Rotation of the trigger in radians
57
+ */
58
+ rotation?: number;
59
+ /**
60
+ * Dimensions of the trigger
61
+ */
62
+ dimensions: Point2;
63
+ }
64
+ /**
65
+ * 2D level loader: registers the built-in primitive/trigger entity classes and dispatches
66
+ * `LevelJson` entities to them (or to custom classes registered via `registerClass`).
67
+ * @template TypeDoc - The type document repository
68
+ */
69
+ export declare class Gg2dLevelLoader<TypeDoc extends Gg2dWorldTypeDocRepo = Gg2dWorldTypeDocRepo> extends LevelLoader<Point2, number, TypeDoc> {
70
+ protected readonly world: Gg2dWorld<TypeDoc>;
71
+ constructor(world: Gg2dWorld<TypeDoc>);
72
+ /**
73
+ * Register the built-in classes for primitives and triggers
74
+ */
75
+ private registerDefaultClasses;
76
+ /**
77
+ * Turn a `PrimitiveSettings` (`shape` plus shape-specific fields) into the `Shape2DDescriptor`
78
+ * consumed by `Gg2dWorld.addPrimitiveRigidBody`.
79
+ * @param settings - The primitive settings, as parsed from a `"Primitive"` entity's `shape` +
80
+ * `config`
81
+ * @returns The shape descriptor
82
+ */
83
+ private buildShapeDescriptor;
84
+ /**
85
+ * Create a primitive entity (both display object and physics body) from a shape descriptor
86
+ * @param world - The world instance
87
+ * @param shape - The shape descriptor
88
+ * @param settings - Position/rotation/material/body settings shared by all primitives
89
+ * @returns The created entity
90
+ */
91
+ private createPrimitive;
92
+ /**
93
+ * Create a trigger entity: a `Trigger2dEntity` wrapping the raw physics trigger component, so
94
+ * the app can subscribe to `onEntityEntered`/`onEntityLeft` without any extra wiring - see the
95
+ * base `LevelLoader` docs for how it's parented for level-lifecycle cleanup.
96
+ * @param world - The world instance
97
+ * @param settings - The trigger settings
98
+ * @returns The created trigger entity
99
+ */
100
+ private createTrigger;
101
+ }
@@ -0,0 +1,88 @@
1
+ import { LevelLoader } from '../base/level-loader';
2
+ import { Trigger2dEntity } from './entities/trigger-2d.entity';
3
+ const defaultBodyOptions = {
4
+ dynamic: true,
5
+ mass: 1,
6
+ restitution: 0.2,
7
+ friction: 0.5,
8
+ ownCollisionGroups: 'all',
9
+ interactWithCollisionGroups: 'all',
10
+ };
11
+ /**
12
+ * 2D level loader: registers the built-in primitive/trigger entity classes and dispatches
13
+ * `LevelJson` entities to them (or to custom classes registered via `registerClass`).
14
+ * @template TypeDoc - The type document repository
15
+ */
16
+ export class Gg2dLevelLoader extends LevelLoader {
17
+ constructor(world) {
18
+ super(world);
19
+ this.world = world;
20
+ this.registerDefaultClasses();
21
+ }
22
+ /**
23
+ * Register the built-in classes for primitives and triggers
24
+ */
25
+ registerDefaultClasses() {
26
+ this.registerClass('Primitive', (world, settings) => this.createPrimitive(world, this.buildShapeDescriptor(settings), settings));
27
+ this.registerClass('Trigger', this.createTrigger.bind(this));
28
+ }
29
+ /**
30
+ * Turn a `PrimitiveSettings` (`shape` plus shape-specific fields) into the `Shape2DDescriptor`
31
+ * consumed by `Gg2dWorld.addPrimitiveRigidBody`.
32
+ * @param settings - The primitive settings, as parsed from a `"Primitive"` entity's `shape` +
33
+ * `config`
34
+ * @returns The shape descriptor
35
+ */
36
+ buildShapeDescriptor(settings) {
37
+ switch (settings.shape) {
38
+ case 'SQUARE':
39
+ if (!settings.dimensions) {
40
+ throw new Error('Dimensions are required for SQUARE primitive');
41
+ }
42
+ return { shape: 'SQUARE', dimensions: settings.dimensions };
43
+ case 'CIRCLE':
44
+ if (settings.radius === undefined) {
45
+ throw new Error('Radius is required for CIRCLE primitive');
46
+ }
47
+ return { shape: 'CIRCLE', radius: settings.radius };
48
+ default:
49
+ throw new Error(`Unknown primitive shape "${settings.shape}"`);
50
+ }
51
+ }
52
+ /**
53
+ * Create a primitive entity (both display object and physics body) from a shape descriptor
54
+ * @param world - The world instance
55
+ * @param shape - The shape descriptor
56
+ * @param settings - Position/rotation/material/body settings shared by all primitives
57
+ * @returns The created entity
58
+ */
59
+ createPrimitive(world, shape, settings) {
60
+ const { position, rotation, material, body } = settings;
61
+ return world.addPrimitiveRigidBody({ shape, body: Object.assign(Object.assign({}, defaultBodyOptions), body) }, position, rotation, material);
62
+ }
63
+ /**
64
+ * Create a trigger entity: a `Trigger2dEntity` wrapping the raw physics trigger component, so
65
+ * the app can subscribe to `onEntityEntered`/`onEntityLeft` without any extra wiring - see the
66
+ * base `LevelLoader` docs for how it's parented for level-lifecycle cleanup.
67
+ * @param world - The world instance
68
+ * @param settings - The trigger settings
69
+ * @returns The created trigger entity
70
+ */
71
+ createTrigger(world, settings) {
72
+ var _a;
73
+ const { position, rotation, dimensions } = settings;
74
+ const shape = { shape: 'SQUARE', dimensions };
75
+ const trigger = (_a = world.physicsWorld) === null || _a === void 0 ? void 0 : _a.factory.createTrigger(shape, { position, rotation });
76
+ if (!trigger) {
77
+ return undefined;
78
+ }
79
+ const entity = new Trigger2dEntity(trigger);
80
+ if (position !== undefined) {
81
+ entity.position = position;
82
+ }
83
+ if (rotation !== undefined) {
84
+ entity.rotation = rotation;
85
+ }
86
+ return entity;
87
+ }
88
+ }
@@ -0,0 +1,11 @@
1
+ import { Gg2dWorldTypeDocRepo } from './gg-2d-world';
2
+ import { Gg2dLevelLoader } from './level-loader';
3
+ /**
4
+ * Full loader exposed as `Gg2dWorld.loader`, extending `Gg2dLevelLoader` (so
5
+ * `registerClass`/`loadLevel`/`loadLevelFromUrl`/`getEntityByName` are all available directly on
6
+ * `world.loader`) - kept as its own class/type so 2D can grow other loading capabilities (the way
7
+ * `Gg3dLoader` has GLB loading) without a breaking rename.
8
+ * @template TypeDoc - The type document repository
9
+ */
10
+ export declare class Gg2dLoader<TypeDoc extends Gg2dWorldTypeDocRepo = Gg2dWorldTypeDocRepo> extends Gg2dLevelLoader<TypeDoc> {
11
+ }
@@ -0,0 +1,10 @@
1
+ import { Gg2dLevelLoader } from './level-loader';
2
+ /**
3
+ * Full loader exposed as `Gg2dWorld.loader`, extending `Gg2dLevelLoader` (so
4
+ * `registerClass`/`loadLevel`/`loadLevelFromUrl`/`getEntityByName` are all available directly on
5
+ * `world.loader`) - kept as its own class/type so 2D can grow other loading capabilities (the way
6
+ * `Gg3dLoader` has GLB loading) without a breaking rename.
7
+ * @template TypeDoc - The type document repository
8
+ */
9
+ export class Gg2dLoader extends Gg2dLevelLoader {
10
+ }
@@ -1,6 +1,6 @@
1
1
  import { IDisplayObject3dComponent } from './i-display-object-3d.component';
2
2
  import { VisualTypeDocRepo3D } from '../../gg-3d-world';
3
- export interface ICameraComponent<VTypeDoc extends VisualTypeDocRepo3D = VisualTypeDocRepo3D> extends IDisplayObject3dComponent<VTypeDoc> {
3
+ export interface ICamera3dComponent<VTypeDoc extends VisualTypeDocRepo3D = VisualTypeDocRepo3D> extends IDisplayObject3dComponent<VTypeDoc> {
4
4
  get supportsFov(): boolean;
5
5
  get fov(): number;
6
6
  set fov(f: number);
@@ -1,5 +1,4 @@
1
1
  import { IRendererComponent, Point3, Point4 } from '../../../base';
2
2
  import { VisualTypeDocRepo3D } from '../../gg-3d-world';
3
3
  export declare abstract class IRenderer3dComponent<VTypeDoc extends VisualTypeDocRepo3D = VisualTypeDocRepo3D> extends IRendererComponent<Point3, Point4, VTypeDoc> {
4
- abstract camera: VTypeDoc['camera'];
5
4
  }
@@ -1,6 +1,5 @@
1
- import { IVisualSceneComponent, Point3, Point4, RendererOptions } from '../../../base';
1
+ import { IVisualSceneComponent, Point3, Point4 } from '../../../base';
2
2
  import { VisualTypeDocRepo3D } from '../../gg-3d-world';
3
3
  export interface IVisualScene3dComponent<VTypeDoc extends VisualTypeDocRepo3D = VisualTypeDocRepo3D> extends IVisualSceneComponent<Point3, Point4, VTypeDoc> {
4
4
  readonly loader: VTypeDoc['loader'];
5
- createRenderer(camera: VTypeDoc['camera'], canvas?: HTMLCanvasElement, rendererOptions?: Partial<RendererOptions & VTypeDoc['rendererExtraOpts']>): VTypeDoc['renderer'];
6
5
  }
@@ -0,0 +1,24 @@
1
+ import { IPositionable3d } from '../interfaces/i-positionable-3d';
2
+ import { IEntity, Point3, Point4, TickOrder } from '../../base';
3
+ import { Gg3dWorldTypeDocVPatch, VisualTypeDocRepo3D } from '../gg-3d-world';
4
+ /**
5
+ * A positioned entity wrapping a camera component (`VTypeDoc['camera']`, e.g. the adapter-specific
6
+ * camera type an app's `TypedGg3dWorld` uses) - not attached to any renderer/canvas itself (pass
7
+ * `.camera` to `Gg3dWorld.addRenderer` for that), but addressable in the world/entity trees like
8
+ * any other entity: `world.addEntity`/`getEntityByName`, `IEntity.getChildEntityByName`,
9
+ * `removeEntity`.
10
+ * @template VTypeDoc - The visual type document repository (parametrize this the same way an
11
+ * app's world type is, e.g. `Camera3dEntity<ThreeVisualTypeDocRepo>`, so `.camera` comes back as
12
+ * the adapter-specific camera type rather than the unbound base `ICamera3dComponent`)
13
+ */
14
+ export declare class Camera3dEntity<VTypeDoc extends VisualTypeDocRepo3D = VisualTypeDocRepo3D> extends IEntity<Point3, Point4, Gg3dWorldTypeDocVPatch<VTypeDoc>> implements IPositionable3d {
15
+ readonly camera: VTypeDoc['camera'];
16
+ readonly tickOrder = TickOrder.OBJECTS_BINDING;
17
+ private _position;
18
+ get position(): Point3;
19
+ set position(value: Point3);
20
+ private _rotation;
21
+ get rotation(): Point4;
22
+ set rotation(value: Point4);
23
+ constructor(camera: VTypeDoc['camera']);
24
+ }
@@ -0,0 +1,35 @@
1
+ import { IEntity, Pnt3, Qtrn, TickOrder } from '../../base';
2
+ /**
3
+ * A positioned entity wrapping a camera component (`VTypeDoc['camera']`, e.g. the adapter-specific
4
+ * camera type an app's `TypedGg3dWorld` uses) - not attached to any renderer/canvas itself (pass
5
+ * `.camera` to `Gg3dWorld.addRenderer` for that), but addressable in the world/entity trees like
6
+ * any other entity: `world.addEntity`/`getEntityByName`, `IEntity.getChildEntityByName`,
7
+ * `removeEntity`.
8
+ * @template VTypeDoc - The visual type document repository (parametrize this the same way an
9
+ * app's world type is, e.g. `Camera3dEntity<ThreeVisualTypeDocRepo>`, so `.camera` comes back as
10
+ * the adapter-specific camera type rather than the unbound base `ICamera3dComponent`)
11
+ */
12
+ export class Camera3dEntity extends IEntity {
13
+ get position() {
14
+ return this._position;
15
+ }
16
+ set position(value) {
17
+ this.camera.position = value;
18
+ this._position = value;
19
+ }
20
+ get rotation() {
21
+ return this._rotation;
22
+ }
23
+ set rotation(value) {
24
+ this.camera.rotation = value;
25
+ this._rotation = value;
26
+ }
27
+ constructor(camera) {
28
+ super();
29
+ this.camera = camera;
30
+ this.tickOrder = TickOrder.OBJECTS_BINDING;
31
+ this._position = Pnt3.O;
32
+ this._rotation = Qtrn.O;
33
+ this.addComponents(this.camera);
34
+ }
35
+ }
@@ -2,9 +2,4 @@ import { IRendererEntity, Point3, Point4 } from '../../base';
2
2
  import { IPositionable3d } from '../interfaces/i-positionable-3d';
3
3
  import { VisualTypeDocRepo3D } from '../gg-3d-world';
4
4
  export declare class Renderer3dEntity<VTypeDoc extends VisualTypeDocRepo3D = VisualTypeDocRepo3D> extends IRendererEntity<Point3, Point4, VTypeDoc> implements IPositionable3d {
5
- get position(): Point3;
6
- set position(value: Point3);
7
- get rotation(): Point4;
8
- set rotation(value: Point4);
9
- get camera(): VTypeDoc['camera'];
10
5
  }
@@ -1,18 +1,3 @@
1
1
  import { IRendererEntity } from '../../base';
2
2
  export class Renderer3dEntity extends IRendererEntity {
3
- get position() {
4
- return this.renderer.camera.position;
5
- }
6
- set position(value) {
7
- this.renderer.camera.position = value;
8
- }
9
- get rotation() {
10
- return this.renderer.camera.rotation;
11
- }
12
- set rotation(value) {
13
- this.renderer.camera.rotation = value;
14
- }
15
- get camera() {
16
- return this.renderer.camera;
17
- }
18
3
  }
@@ -4,7 +4,7 @@ import { Entity3d } from './entities/entity-3d';
4
4
  import { BodyShape3DDescriptor } from './models/shapes';
5
5
  import { IVisualScene3dComponent } from './components/rendering/i-visual-scene-3d.component';
6
6
  import { Renderer3dEntity } from './entities/renderer-3d.entity';
7
- import { ICameraComponent } from './components/rendering/i-camera.component';
7
+ import { ICamera3dComponent } from './components/rendering/i-camera-3d.component';
8
8
  import { IRenderer3dComponent } from './components/rendering/i-renderer-3d.component';
9
9
  import { IPhysicsWorld3dComponent } from './components/physics/i-physics-world-3d.component';
10
10
  import { DisplayObject3dOpts, IDisplayObject3dComponentFactory, IPhysicsBody3dComponentFactory } from './factories';
@@ -19,7 +19,7 @@ export type VisualTypeDocRepo3D = {
19
19
  displayObject: IDisplayObject3dComponent;
20
20
  renderer: IRenderer3dComponent;
21
21
  rendererExtraOpts: {};
22
- camera: ICameraComponent;
22
+ camera: ICamera3dComponent;
23
23
  texture: unknown;
24
24
  };
25
25
  export type PhysicsTypeDocRepo3D = {
@@ -37,6 +37,79 @@ export class Gg3dWorld extends GgWorld {
37
37
  }
38
38
  registerConsoleCommands(ggstatic) {
39
39
  super.registerConsoleCommands(ggstatic);
40
+ ggstatic.registerConsoleCommand(this, 'set_position', (...args) => __awaiter(this, void 0, void 0, function* () {
41
+ const [name, x, y, z] = args;
42
+ if (!name) {
43
+ throw new Error('usage: set_position <name> <x> <y> <z>');
44
+ }
45
+ const entity = this.getEntityByName(name);
46
+ if (!('position' in entity)) {
47
+ throw new Error(`Entity "${name}" (${entity.constructor.name}) has no position`);
48
+ }
49
+ if ([x, y, z].some(v => v === undefined || isNaN(+v))) {
50
+ throw new Error('usage: set_position <name> <x> <y> <z>');
51
+ }
52
+ entity.position = { x: +x, y: +y, z: +z };
53
+ return JSON.stringify(entity.position);
54
+ }), 'args: [ string, float, float, float ]; Teleport a named entity to world-space coordinates. ' +
55
+ 'Use "entities"/"entity <name>" to find entity names and their current position');
56
+ ggstatic.registerConsoleCommand(this, 'set_rotation', (...args) => __awaiter(this, void 0, void 0, function* () {
57
+ const [name, ...rest] = args;
58
+ if (!name) {
59
+ throw new Error('usage: set_rotation <name> <x> <y> <z> [w]');
60
+ }
61
+ const entity = this.getEntityByName(name);
62
+ if (!('rotation' in entity)) {
63
+ throw new Error(`Entity "${name}" (${entity.constructor.name}) has no rotation`);
64
+ }
65
+ const nums = rest.map(Number);
66
+ if (nums.length !== 3 && nums.length !== 4) {
67
+ throw new Error('usage: set_rotation <name> <x> <y> <z> (euler, radians) OR set_rotation <name> <x> <y> <z> <w> (quaternion)');
68
+ }
69
+ if (nums.some(Number.isNaN)) {
70
+ throw new Error('Wrong arguments');
71
+ }
72
+ const rotation = nums.length === 4
73
+ ? { x: nums[0], y: nums[1], z: nums[2], w: nums[3] }
74
+ : Qtrn.fromEuler({ x: nums[0], y: nums[1], z: nums[2] });
75
+ entity.rotation = rotation;
76
+ return JSON.stringify(entity.rotation);
77
+ }), 'args: [ string, float, float, float, float? ]; Rotate a named entity. 3 numbers are euler ' +
78
+ 'angles in radians, 4 numbers are a raw quaternion (x y z w)');
79
+ ggstatic.registerConsoleCommand(this, 'spawn', (...args) => __awaiter(this, void 0, void 0, function* () {
80
+ const [shapeArg, x, y, z, dynamicArg] = args;
81
+ if ([x, y, z].some(v => v === undefined || isNaN(+v))) {
82
+ throw new Error('usage: spawn <BOX|SPHERE|CYLINDER|CONE|CAPSULE|PLANE> <x> <y> <z> [dynamic=0|1]');
83
+ }
84
+ const dynamic = dynamicArg === undefined ? true : dynamicArg === '1';
85
+ let shape;
86
+ switch ((shapeArg || '').toUpperCase()) {
87
+ case 'BOX':
88
+ shape = { shape: 'BOX', dimensions: { x: 1, y: 1, z: 1 } };
89
+ break;
90
+ case 'SPHERE':
91
+ shape = { shape: 'SPHERE', radius: 0.5 };
92
+ break;
93
+ case 'CYLINDER':
94
+ shape = { shape: 'CYLINDER', radius: 0.5, height: 1 };
95
+ break;
96
+ case 'CONE':
97
+ shape = { shape: 'CONE', radius: 0.5, height: 1 };
98
+ break;
99
+ case 'CAPSULE':
100
+ shape = { shape: 'CAPSULE', radius: 0.5, centersDistance: 1 };
101
+ break;
102
+ case 'PLANE':
103
+ shape = { shape: 'PLANE' };
104
+ break;
105
+ default:
106
+ throw new Error(`Unknown shape "${shapeArg}". Use BOX|SPHERE|CYLINDER|CONE|CAPSULE|PLANE`);
107
+ }
108
+ const entity = this.addPrimitiveRigidBody({ shape, body: { dynamic } }, { x: +x, y: +y, z: +z });
109
+ return `spawned "${entity.name}" (${shape.shape}) at ${JSON.stringify(entity.position)}`;
110
+ }), 'args: [ BOX|SPHERE|CYLINDER|CONE|CAPSULE|PLANE, float, float, float, 0|1? ]; Spawn a ' +
111
+ 'default-sized primitive rigid body at world-space coordinates, for probing physics. ' +
112
+ 'dynamic (last arg) defaults to 1 (falls under gravity); pass 0 for a static prop');
40
113
  if (this.physicsWorld) {
41
114
  ggstatic.registerConsoleCommand(this, 'gravity', (...args) => __awaiter(this, void 0, void 0, function* () {
42
115
  if (args.length == 1) {
@@ -3,10 +3,11 @@ export * from './components/physics/i-rigid-body-3d.component';
3
3
  export * from './components/physics/i-trigger-3d.component';
4
4
  export * from './components/physics/i-physics-world-3d.component';
5
5
  export * from './components/rendering/i-display-object-3d.component';
6
- export * from './components/rendering/i-camera.component';
6
+ export * from './components/rendering/i-camera-3d.component';
7
7
  export * from './components/rendering/i-renderer-3d.component';
8
8
  export * from './components/rendering/i-visual-scene-3d.component';
9
9
  export * from './entities/gg-car/gg-car.entity';
10
+ export * from './entities/camera-3d.entity';
10
11
  export * from './entities/controllers/animators/camera-3d.animator';
11
12
  export * from './entities/controllers/animators/entity-3d-positioning.animator';
12
13
  export * from './entities/entity-3d';
@@ -28,3 +29,4 @@ export * from './loaders';
28
29
  export * from './factories';
29
30
  export * from './gg-3d-world';
30
31
  export * from './loader';
32
+ export * from './level-loader';
package/dist/3d/index.js CHANGED
@@ -3,10 +3,11 @@ export * from './components/physics/i-rigid-body-3d.component';
3
3
  export * from './components/physics/i-trigger-3d.component';
4
4
  export * from './components/physics/i-physics-world-3d.component';
5
5
  export * from './components/rendering/i-display-object-3d.component';
6
- export * from './components/rendering/i-camera.component';
6
+ export * from './components/rendering/i-camera-3d.component';
7
7
  export * from './components/rendering/i-renderer-3d.component';
8
8
  export * from './components/rendering/i-visual-scene-3d.component';
9
9
  export * from './entities/gg-car/gg-car.entity';
10
+ export * from './entities/camera-3d.entity';
10
11
  export * from './entities/controllers/animators/camera-3d.animator';
11
12
  export * from './entities/controllers/animators/entity-3d-positioning.animator';
12
13
  export * from './entities/entity-3d';
@@ -28,3 +29,4 @@ export * from './loaders';
28
29
  export * from './factories';
29
30
  export * from './gg-3d-world';
30
31
  export * from './loader';
32
+ export * from './level-loader';