@gg-web-engine/core 0.0.1
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/.prettierrc +8 -0
- package/README.md +8 -0
- package/blender_exporter/build_blender_scene.py +180 -0
- package/blender_exporter/spherical_to_cube_texture.py +116 -0
- package/dist/2d/entities/gg-2d-entity.d.ts +20 -0
- package/dist/2d/entities/gg-2d-entity.js +84 -0
- package/dist/2d/entities/gg-2d-trigger.entity.d.ts +10 -0
- package/dist/2d/entities/gg-2d-trigger.entity.js +17 -0
- package/dist/2d/entities/gg-positionable-2d-entity.d.ts +7 -0
- package/dist/2d/entities/gg-positionable-2d-entity.js +16 -0
- package/dist/2d/factories.d.ts +18 -0
- package/dist/2d/factories.js +13 -0
- package/dist/2d/gg-2d-world.d.ts +9 -0
- package/dist/2d/gg-2d-world.js +34 -0
- package/dist/2d/interfaces.d.ts +26 -0
- package/dist/2d/interfaces.js +7 -0
- package/dist/2d/models/body-options.d.ts +3 -0
- package/dist/2d/models/body-options.js +2 -0
- package/dist/2d/models/shapes.d.ts +13 -0
- package/dist/2d/models/shapes.js +2 -0
- package/dist/3d/controllers/car-keyboard.controller.d.ts +25 -0
- package/dist/3d/controllers/car-keyboard.controller.js +98 -0
- package/dist/3d/controllers/free-camera.controller.d.ts +23 -0
- package/dist/3d/controllers/free-camera.controller.js +79 -0
- package/dist/3d/entities/controllers/entity-motion.controller.d.ts +32 -0
- package/dist/3d/entities/controllers/entity-motion.controller.js +100 -0
- package/dist/3d/entities/gg-3d-camera.entity.d.ts +7 -0
- package/dist/3d/entities/gg-3d-camera.entity.js +12 -0
- package/dist/3d/entities/gg-3d-entity.d.ts +25 -0
- package/dist/3d/entities/gg-3d-entity.js +108 -0
- package/dist/3d/entities/gg-3d-map-graph.entity.d.ts +51 -0
- package/dist/3d/entities/gg-3d-map-graph.entity.js +164 -0
- package/dist/3d/entities/gg-3d-raycast-vehicle.entity.d.ts +107 -0
- package/dist/3d/entities/gg-3d-raycast-vehicle.entity.js +372 -0
- package/dist/3d/entities/gg-3d-trigger.entity.d.ts +10 -0
- package/dist/3d/entities/gg-3d-trigger.entity.js +21 -0
- package/dist/3d/entities/gg-positionable-3d-entity.d.ts +11 -0
- package/dist/3d/entities/gg-positionable-3d-entity.js +27 -0
- package/dist/3d/factories.d.ts +21 -0
- package/dist/3d/factories.js +22 -0
- package/dist/3d/gg-3d-world.d.ts +11 -0
- package/dist/3d/gg-3d-world.js +36 -0
- package/dist/3d/interfaces.d.ts +65 -0
- package/dist/3d/interfaces.js +40 -0
- package/dist/3d/loader.d.ts +40 -0
- package/dist/3d/loader.js +129 -0
- package/dist/3d/models/body-options.d.ts +3 -0
- package/dist/3d/models/body-options.js +2 -0
- package/dist/3d/models/gg-meta.d.ts +22 -0
- package/dist/3d/models/gg-meta.js +2 -0
- package/dist/3d/models/shapes.d.ts +35 -0
- package/dist/3d/models/shapes.js +2 -0
- package/dist/base/clock.d.ts +26 -0
- package/dist/base/clock.js +82 -0
- package/dist/base/controllers/common.d.ts +8 -0
- package/dist/base/controllers/common.js +32 -0
- package/dist/base/controllers/i-controller.d.ts +4 -0
- package/dist/base/controllers/i-controller.js +2 -0
- package/dist/base/controllers/keyboard.controller.d.ts +16 -0
- package/dist/base/controllers/keyboard.controller.js +109 -0
- package/dist/base/controllers/mouse.controller.d.ts +24 -0
- package/dist/base/controllers/mouse.controller.js +68 -0
- package/dist/base/data-structures/graph.d.ts +20 -0
- package/dist/base/data-structures/graph.js +118 -0
- package/dist/base/entities/base-gg-renderer.d.ts +28 -0
- package/dist/base/entities/base-gg-renderer.js +49 -0
- package/dist/base/entities/gg-entity.d.ts +14 -0
- package/dist/base/entities/gg-entity.js +55 -0
- package/dist/base/entities/gg-positionable-entity.d.ts +23 -0
- package/dist/base/entities/gg-positionable-entity.js +47 -0
- package/dist/base/entities/inline-controller.d.ts +3 -0
- package/dist/base/entities/inline-controller.js +25 -0
- package/dist/base/entities/interfaces/i-tick-listener.d.ts +7 -0
- package/dist/base/entities/interfaces/i-tick-listener.js +6 -0
- package/dist/base/gg-static.d.ts +9 -0
- package/dist/base/gg-static.js +40 -0
- package/dist/base/gg-viewport-manager.d.ts +14 -0
- package/dist/base/gg-viewport-manager.js +125 -0
- package/dist/base/gg-viewport.d.ts +23 -0
- package/dist/base/gg-viewport.js +123 -0
- package/dist/base/gg-world.d.ts +32 -0
- package/dist/base/gg-world.js +172 -0
- package/dist/base/interfaces/gg-body.d.ts +15 -0
- package/dist/base/interfaces/gg-body.js +2 -0
- package/dist/base/interfaces/gg-debug-physics-drawer.d.ts +7 -0
- package/dist/base/interfaces/gg-debug-physics-drawer.js +2 -0
- package/dist/base/interfaces/gg-object.d.ts +16 -0
- package/dist/base/interfaces/gg-object.js +2 -0
- package/dist/base/interfaces/gg-physics-world.d.ts +18 -0
- package/dist/base/interfaces/gg-physics-world.js +2 -0
- package/dist/base/interfaces/gg-trigger.d.ts +8 -0
- package/dist/base/interfaces/gg-trigger.js +2 -0
- package/dist/base/interfaces/gg-visual-scene.d.ts +9 -0
- package/dist/base/interfaces/gg-visual-scene.js +2 -0
- package/dist/base/math/box.d.ts +5 -0
- package/dist/base/math/box.js +21 -0
- package/dist/base/math/matrix4.d.ts +5 -0
- package/dist/base/math/matrix4.js +33 -0
- package/dist/base/math/numbers.d.ts +2 -0
- package/dist/base/math/numbers.js +14 -0
- package/dist/base/math/point2.d.ts +15 -0
- package/dist/base/math/point2.js +40 -0
- package/dist/base/math/point3.d.ts +25 -0
- package/dist/base/math/point3.js +104 -0
- package/dist/base/math/quaternion.d.ts +28 -0
- package/dist/base/math/quaternion.js +145 -0
- package/dist/base/models/axis-directions.d.ts +3 -0
- package/dist/base/models/axis-directions.js +2 -0
- package/dist/base/models/body-options.d.ts +6 -0
- package/dist/base/models/body-options.js +2 -0
- package/dist/base/models/geometry-nodes.d.ts +7 -0
- package/dist/base/models/geometry-nodes.js +2 -0
- package/dist/base/models/points.d.ts +15 -0
- package/dist/base/models/points.js +2 -0
- package/dist/base/ui/gg-console.ui.d.ts +21 -0
- package/dist/base/ui/gg-console.ui.js +162 -0
- package/dist/base/ui/gg-debugger.ui.d.ts +10 -0
- package/dist/base/ui/gg-debugger.ui.js +68 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.js +67 -0
- package/package.json +64 -0
- package/src/2d/entities/gg-2d-entity.ts +86 -0
- package/src/2d/entities/gg-2d-trigger.entity.ts +17 -0
- package/src/2d/entities/gg-positionable-2d-entity.ts +16 -0
- package/src/2d/factories.ts +20 -0
- package/src/2d/gg-2d-world.ts +32 -0
- package/src/2d/interfaces.ts +31 -0
- package/src/2d/models/body-options.ts +3 -0
- package/src/2d/models/shapes.ts +7 -0
- package/src/3d/controllers/car-keyboard.controller.ts +128 -0
- package/src/3d/controllers/free-camera.controller.ts +86 -0
- package/src/3d/entities/controllers/entity-motion.controller.ts +122 -0
- package/src/3d/entities/gg-3d-camera.entity.ts +8 -0
- package/src/3d/entities/gg-3d-entity.ts +116 -0
- package/src/3d/entities/gg-3d-map-graph.entity.ts +204 -0
- package/src/3d/entities/gg-3d-raycast-vehicle.entity.ts +468 -0
- package/src/3d/entities/gg-3d-trigger.entity.ts +22 -0
- package/src/3d/entities/gg-positionable-3d-entity.ts +31 -0
- package/src/3d/factories.ts +29 -0
- package/src/3d/gg-3d-world.ts +36 -0
- package/src/3d/interfaces.ts +96 -0
- package/src/3d/loader.ts +165 -0
- package/src/3d/models/body-options.ts +3 -0
- package/src/3d/models/gg-meta.ts +12 -0
- package/src/3d/models/shapes.ts +13 -0
- package/src/base/clock.ts +97 -0
- package/src/base/controllers/common.ts +37 -0
- package/src/base/controllers/i-controller.ts +5 -0
- package/src/base/controllers/keyboard.controller.ts +109 -0
- package/src/base/controllers/mouse.controller.ts +73 -0
- package/src/base/data-structures/graph.ts +125 -0
- package/src/base/entities/base-gg-renderer.ts +77 -0
- package/src/base/entities/gg-entity.ts +61 -0
- package/src/base/entities/gg-positionable-entity.ts +64 -0
- package/src/base/entities/inline-controller.ts +31 -0
- package/src/base/entities/interfaces/i-tick-listener.ts +15 -0
- package/src/base/gg-static.ts +30 -0
- package/src/base/gg-viewport-manager.ts +122 -0
- package/src/base/gg-viewport.ts +159 -0
- package/src/base/gg-world.ts +198 -0
- package/src/base/interfaces/gg-body.ts +23 -0
- package/src/base/interfaces/gg-debug-physics-drawer.ts +10 -0
- package/src/base/interfaces/gg-object.ts +26 -0
- package/src/base/interfaces/gg-physics-world.ts +24 -0
- package/src/base/interfaces/gg-trigger.ts +10 -0
- package/src/base/interfaces/gg-visual-scene.ts +11 -0
- package/src/base/math/box.ts +19 -0
- package/src/base/math/matrix4.ts +29 -0
- package/src/base/math/numbers.ts +10 -0
- package/src/base/math/point2.ts +43 -0
- package/src/base/math/point3.ts +119 -0
- package/src/base/math/quaternion.ts +172 -0
- package/src/base/models/axis-directions.ts +3 -0
- package/src/base/models/body-options.ts +6 -0
- package/src/base/models/geometry-nodes.ts +5 -0
- package/src/base/models/points.ts +3 -0
- package/src/base/ui/gg-console.ui.ts +165 -0
- package/src/base/ui/gg-debugger.ui.ts +69 -0
- package/src/index.ts +53 -0
- package/test/base/data-structures/graph.spec.ts +76 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { Point3, Point4 } from '../models/points';
|
|
2
|
+
import { Pnt3 } from './point3';
|
|
3
|
+
import { Mtrx4 } from './matrix4';
|
|
4
|
+
|
|
5
|
+
export class Qtrn {
|
|
6
|
+
/** clone quaternion */
|
|
7
|
+
static clone(q: Point4): Point4 {
|
|
8
|
+
return { ...q };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** add quaternion b to quaternion a */
|
|
12
|
+
static add(a: Point4, b: Point4): Point4 {
|
|
13
|
+
const w = a.w + b.w;
|
|
14
|
+
const x = a.x + b.x;
|
|
15
|
+
const y = a.y + b.y;
|
|
16
|
+
const z = a.z + b.z;
|
|
17
|
+
const magnitude = Math.sqrt(w * w + x * x + y * y + z * z);
|
|
18
|
+
return { w: w / magnitude, x: x / magnitude, y: y / magnitude, z: z / magnitude };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static mult(a: Point4, b: Point4): Point4 {
|
|
22
|
+
return {
|
|
23
|
+
w: a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z,
|
|
24
|
+
x: a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y,
|
|
25
|
+
y: a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x,
|
|
26
|
+
z: a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static combineRotations(...quaternions: Point4[]): Point4 {
|
|
31
|
+
let result = { w: 1, x: 0, y: 0, z: 0 };
|
|
32
|
+
for (const quat of quaternions) {
|
|
33
|
+
result = this.mult(result, quat);
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** linear interpolation */
|
|
39
|
+
static lerp(a: Point4, b: Point4, t: number): Point4 {
|
|
40
|
+
return {
|
|
41
|
+
x: a.x + t * (b.x - a.x),
|
|
42
|
+
y: a.y + t * (b.y - a.y),
|
|
43
|
+
z: a.z + t * (b.z - a.z),
|
|
44
|
+
w: a.w + t * (b.w - a.w),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** spherical interpolation */
|
|
49
|
+
static slerp(a: Point4, b: Point4, t: number): Point4 {
|
|
50
|
+
let dot = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
|
|
51
|
+
let theta = Math.acos(dot);
|
|
52
|
+
let sinTheta = Math.sin(theta);
|
|
53
|
+
|
|
54
|
+
let x = (a.x * Math.sin((1 - t) * theta)) / sinTheta + (b.x * Math.sin(t * theta)) / sinTheta;
|
|
55
|
+
let y = (a.y * Math.sin((1 - t) * theta)) / sinTheta + (b.y * Math.sin(t * theta)) / sinTheta;
|
|
56
|
+
let z = (a.z * Math.sin((1 - t) * theta)) / sinTheta + (b.z * Math.sin(t * theta)) / sinTheta;
|
|
57
|
+
let w = (a.w * Math.sin((1 - t) * theta)) / sinTheta + (b.w * Math.sin(t * theta)) / sinTheta;
|
|
58
|
+
|
|
59
|
+
if (isNaN(x) || isNaN(y) || isNaN(z) || isNaN(w)) {
|
|
60
|
+
// happens when they are equal
|
|
61
|
+
return Qtrn.clone(a);
|
|
62
|
+
}
|
|
63
|
+
return { x, y, z, w };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** creates quaternion from simple angle around axis. Assumes that axis vector is normalized */
|
|
67
|
+
static fromAngle(axis: Point3, angle: number) {
|
|
68
|
+
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
|
|
69
|
+
const halfAngle = angle / 2,
|
|
70
|
+
s = Math.sin(halfAngle);
|
|
71
|
+
return {
|
|
72
|
+
...Pnt3.scalarMult(axis, s),
|
|
73
|
+
w: Math.cos(halfAngle),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** creates quaternion from 4-dimension rotation matrix */
|
|
78
|
+
static fromMatrix4(m: number[]): Point4 {
|
|
79
|
+
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
|
|
80
|
+
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
|
|
81
|
+
const m11 = m[0],
|
|
82
|
+
m12 = m[4],
|
|
83
|
+
m13 = m[8],
|
|
84
|
+
m21 = m[1],
|
|
85
|
+
m22 = m[5],
|
|
86
|
+
m23 = m[9],
|
|
87
|
+
m31 = m[2],
|
|
88
|
+
m32 = m[6],
|
|
89
|
+
m33 = m[10],
|
|
90
|
+
trace = m11 + m22 + m33;
|
|
91
|
+
if (trace > 0) {
|
|
92
|
+
const s = 0.5 / Math.sqrt(trace + 1.0);
|
|
93
|
+
return {
|
|
94
|
+
x: (m32 - m23) * s,
|
|
95
|
+
y: (m13 - m31) * s,
|
|
96
|
+
z: (m21 - m12) * s,
|
|
97
|
+
w: 0.25 / s,
|
|
98
|
+
};
|
|
99
|
+
} else if (m11 > m22 && m11 > m33) {
|
|
100
|
+
const s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);
|
|
101
|
+
return {
|
|
102
|
+
x: 0.25 * s,
|
|
103
|
+
y: (m12 + m21) / s,
|
|
104
|
+
z: (m13 + m31) / s,
|
|
105
|
+
w: (m32 - m23) / s,
|
|
106
|
+
};
|
|
107
|
+
} else if (m22 > m33) {
|
|
108
|
+
const s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);
|
|
109
|
+
return {
|
|
110
|
+
x: (m12 + m21) / s,
|
|
111
|
+
y: 0.25 * s,
|
|
112
|
+
z: (m23 + m32) / s,
|
|
113
|
+
w: (m13 - m31) / s,
|
|
114
|
+
};
|
|
115
|
+
} else {
|
|
116
|
+
const s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);
|
|
117
|
+
return {
|
|
118
|
+
x: (m13 + m31) / s,
|
|
119
|
+
y: (m23 + m32) / s,
|
|
120
|
+
z: 0.25 * s,
|
|
121
|
+
w: (m21 - m12) / s,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** creates a quaternion from euler */
|
|
127
|
+
static fromEuler(e: Point3): Point4 {
|
|
128
|
+
const roll = e.x;
|
|
129
|
+
const pitch = e.y;
|
|
130
|
+
const yaw = e.z;
|
|
131
|
+
|
|
132
|
+
const cy = Math.cos(yaw * 0.5);
|
|
133
|
+
const sy = Math.sin(yaw * 0.5);
|
|
134
|
+
const cp = Math.cos(pitch * 0.5);
|
|
135
|
+
const sp = Math.sin(pitch * 0.5);
|
|
136
|
+
const cr = Math.cos(roll * 0.5);
|
|
137
|
+
const sr = Math.sin(roll * 0.5);
|
|
138
|
+
|
|
139
|
+
const qw = cr * cp * cy + sr * sp * sy;
|
|
140
|
+
const qx = sr * cp * cy - cr * sp * sy;
|
|
141
|
+
const qy = cr * sp * cy + sr * cp * sy;
|
|
142
|
+
const qz = cr * cp * sy - sr * sp * cy;
|
|
143
|
+
|
|
144
|
+
return { w: qw, x: qx, y: qy, z: qz };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** converts a quaternion to euler */
|
|
148
|
+
static toEuler(q: Point4): Point3 {
|
|
149
|
+
const qw = q.w;
|
|
150
|
+
const qx = q.x;
|
|
151
|
+
const qy = q.y;
|
|
152
|
+
const qz = q.z;
|
|
153
|
+
|
|
154
|
+
const sinr_cosp = 2 * (qw * qx + qy * qz);
|
|
155
|
+
const cosr_cosp = 1 - 2 * (qx * qx + qy * qy);
|
|
156
|
+
const roll = Math.atan2(sinr_cosp, cosr_cosp);
|
|
157
|
+
|
|
158
|
+
const sinp = 2 * (qw * qy - qz * qx);
|
|
159
|
+
const pitch = Math.abs(sinp) >= 1 ? (Math.sign(sinp) * Math.PI) / 2 : Math.asin(sinp);
|
|
160
|
+
|
|
161
|
+
const siny_cosp = 2 * (qw * qz + qx * qy);
|
|
162
|
+
const cosy_cosp = 1 - 2 * (qy * qy + qz * qz);
|
|
163
|
+
const yaw = Math.atan2(siny_cosp, cosy_cosp);
|
|
164
|
+
|
|
165
|
+
return { x: roll, y: pitch, z: yaw };
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** creates a rotation for object, so it will look at some point in space */
|
|
169
|
+
static lookAt(eye: Point3, target: Point3, up: Point3): Point4 {
|
|
170
|
+
return this.fromMatrix4(Mtrx4.lookAt(eye, target, up));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { GgStatic } from '../gg-static';
|
|
2
|
+
|
|
3
|
+
export class GgConsoleUI {
|
|
4
|
+
private static _instance: GgConsoleUI | null;
|
|
5
|
+
static get instance(): GgConsoleUI {
|
|
6
|
+
if (!this._instance) {
|
|
7
|
+
this._instance = new GgConsoleUI();
|
|
8
|
+
}
|
|
9
|
+
return this._instance;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
private constructor() {}
|
|
13
|
+
|
|
14
|
+
private output: string = `
|
|
15
|
+
▄████ ▄████ █ █░▓█████ ▄▄▄▄
|
|
16
|
+
██▒ ▀█▒ ██▒ ▀█▒ ▓█░ █ ░█░▓█ ▀ ▓█████▄
|
|
17
|
+
▒██░▄▄▄░▒██░▄▄▄░ ▒█░ █ ░█ ▒███ ▒██▒ ▄██
|
|
18
|
+
░▓█ ██▓░▓█ ██▓ ░█░ █ ░█ ▒▓█ ▄ ▒██░█▀
|
|
19
|
+
░▒▓███▀▒░▒▓███▀▒ ░░██▒██▓ ░▒████▒░▓█ ▀█▓
|
|
20
|
+
░▒ ▒ ░▒ ▒ ░ ▓░▒ ▒ ░░ ▒░ ░░▒▓███▀▒
|
|
21
|
+
░ ░ ░ ░ ▒ ░ ░ ░ ░ ░▒░▒ ░
|
|
22
|
+
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
|
|
23
|
+
░ ░ ░ ░ ░ ░
|
|
24
|
+
░
|
|
25
|
+
>>> https://github.com/AndyGura/gg-web-engine <<<
|
|
26
|
+
Welcome to GG web engine UI console.
|
|
27
|
+
Enter command in input below.
|
|
28
|
+
|
|
29
|
+
List of available commands: commandslist
|
|
30
|
+
`;
|
|
31
|
+
|
|
32
|
+
private commandHistory: string[] = [];
|
|
33
|
+
private currentCommandIndex = 0; // for repeating command using up/down arrow keys
|
|
34
|
+
|
|
35
|
+
elements: {
|
|
36
|
+
main: HTMLDivElement;
|
|
37
|
+
input: HTMLInputElement;
|
|
38
|
+
output: HTMLTextAreaElement;
|
|
39
|
+
} | null = null;
|
|
40
|
+
|
|
41
|
+
public get isUIShown(): boolean {
|
|
42
|
+
return !!this.elements;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public createUI() {
|
|
46
|
+
if (this.elements) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const main: HTMLDivElement = document.createElement('div');
|
|
50
|
+
main.innerHTML = `
|
|
51
|
+
<div id="gg-console-header" style="padding: 10px; cursor: move; z-index: 10; background-color: #054a81; border: 1px solid white; font-size: large;">GG web engine UI console</div>
|
|
52
|
+
<textarea id="gg-console-output" disabled style="resize: none; flex-grow: 1; background: #555555; border: 1px solid white; color: white; font-family: monospace;" ></textarea>
|
|
53
|
+
<input id="gg-console-input" style="background: #555555; border: 1px solid white; color: white; font-family: monospace;"/>`;
|
|
54
|
+
main.style.position = 'absolute';
|
|
55
|
+
main.style.zIndex = '1000';
|
|
56
|
+
main.style.backgroundColor = '#222222';
|
|
57
|
+
main.style.border = '1px solid white';
|
|
58
|
+
main.style.width = '640px';
|
|
59
|
+
main.style.height = '480px';
|
|
60
|
+
main.style.display = 'flex';
|
|
61
|
+
main.style.flexDirection = 'column';
|
|
62
|
+
main.style.alignItems = 'stretch';
|
|
63
|
+
main.style.padding = '3px';
|
|
64
|
+
main.style.rowGap = '3px';
|
|
65
|
+
main.style.fontFamily = 'monospace';
|
|
66
|
+
main.style.color = 'white';
|
|
67
|
+
document.body.append(main);
|
|
68
|
+
this.elements = {
|
|
69
|
+
main,
|
|
70
|
+
input: document.getElementById('gg-console-input')! as HTMLInputElement,
|
|
71
|
+
output: document.getElementById('gg-console-output')! as HTMLTextAreaElement,
|
|
72
|
+
};
|
|
73
|
+
this.elements.input.onkeydown = event => {
|
|
74
|
+
if (event?.keyCode === 13) {
|
|
75
|
+
event.preventDefault();
|
|
76
|
+
this.onInput().then();
|
|
77
|
+
} else if (event?.keyCode === 38) {
|
|
78
|
+
event.preventDefault();
|
|
79
|
+
this.onUsePreviousCommand();
|
|
80
|
+
} else if (event?.keyCode === 40) {
|
|
81
|
+
event.preventDefault();
|
|
82
|
+
this.onUseNextCommand();
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
this.stdout();
|
|
86
|
+
this.setupDragging();
|
|
87
|
+
setTimeout(() => this.elements!.input.focus(), 20);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public destroyUI() {
|
|
91
|
+
if (!this.elements) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
document.body.removeChild(this.elements.main);
|
|
95
|
+
this.elements = null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
onUsePreviousCommand() {
|
|
99
|
+
if (this.commandHistory.length === 0) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
this.currentCommandIndex--;
|
|
103
|
+
if (this.currentCommandIndex < 0) {
|
|
104
|
+
this.currentCommandIndex += this.commandHistory.length;
|
|
105
|
+
}
|
|
106
|
+
this.elements!.input.value = this.commandHistory[this.currentCommandIndex % this.commandHistory.length];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
onUseNextCommand() {
|
|
110
|
+
if (this.commandHistory.length === 0) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
this.currentCommandIndex++;
|
|
114
|
+
this.elements!.input.value = this.commandHistory[this.currentCommandIndex % this.commandHistory.length];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async onInput() {
|
|
118
|
+
const command = this.elements!.input.value;
|
|
119
|
+
this.elements!.input.value = '';
|
|
120
|
+
this.stdout('\n> ' + command);
|
|
121
|
+
this.stdout('\n' + (await GgStatic.instance.console(command)));
|
|
122
|
+
this.commandHistory.push(command);
|
|
123
|
+
this.currentCommandIndex = this.commandHistory.length;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
private stdout(s: string = ''): void {
|
|
127
|
+
this.output += s;
|
|
128
|
+
this.elements!.output.value = this.output;
|
|
129
|
+
this.elements!.output.scrollTop = this.elements!.output.scrollHeight;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
setupDragging() {
|
|
133
|
+
let x = 0,
|
|
134
|
+
y = 0;
|
|
135
|
+
const dragMouseDown = (e: MouseEvent) => {
|
|
136
|
+
e = e || window.event;
|
|
137
|
+
e.preventDefault();
|
|
138
|
+
// get the mouse cursor position at startup:
|
|
139
|
+
x = e.clientX;
|
|
140
|
+
y = e.clientY;
|
|
141
|
+
document.onmouseup = closeDragElement;
|
|
142
|
+
// call a function whenever the cursor moves:
|
|
143
|
+
document.onmousemove = elementDrag;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const elementDrag = (e: MouseEvent) => {
|
|
147
|
+
e.preventDefault();
|
|
148
|
+
// calculate the new cursor position:
|
|
149
|
+
const curX = x - e.clientX;
|
|
150
|
+
const curY = y - e.clientY;
|
|
151
|
+
x = e.clientX;
|
|
152
|
+
y = e.clientY;
|
|
153
|
+
// set the element's new position:
|
|
154
|
+
this.elements!.main.style.left = this.elements!.main.offsetLeft - curX + 'px';
|
|
155
|
+
this.elements!.main.style.top = this.elements!.main.offsetTop - curY + 'px';
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const closeDragElement = () => {
|
|
159
|
+
// stop moving when mouse button is released:
|
|
160
|
+
document.onmouseup = null;
|
|
161
|
+
document.onmousemove = null;
|
|
162
|
+
};
|
|
163
|
+
document.getElementById('gg-console-header')!.onmousedown = dragMouseDown;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { GgStatic } from '../gg-static';
|
|
2
|
+
import { createInlineTickController } from '../entities/inline-controller';
|
|
3
|
+
import { fromEvent, Subject, takeUntil } from 'rxjs';
|
|
4
|
+
import Stats from 'stats.js';
|
|
5
|
+
|
|
6
|
+
export class GgDebuggerUI {
|
|
7
|
+
private static _instance: GgDebuggerUI | null;
|
|
8
|
+
static get instance(): GgDebuggerUI {
|
|
9
|
+
if (!this._instance) {
|
|
10
|
+
this._instance = new GgDebuggerUI();
|
|
11
|
+
}
|
|
12
|
+
return this._instance;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
private ui: { stats: Stats; customContainer: HTMLDivElement } | null = null;
|
|
16
|
+
|
|
17
|
+
private removed$: Subject<void> = new Subject<void>();
|
|
18
|
+
|
|
19
|
+
private constructor() {}
|
|
20
|
+
|
|
21
|
+
public get isUIShown(): boolean {
|
|
22
|
+
return !!this.ui;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public createUI() {
|
|
26
|
+
const stats = new Stats();
|
|
27
|
+
stats.dom.style.left = 'unset';
|
|
28
|
+
stats.dom.style.right = '0';
|
|
29
|
+
stats.showPanel(0); // 0: fps, 1: ms, 2: mb
|
|
30
|
+
document.body.appendChild(stats.dom);
|
|
31
|
+
createInlineTickController(GgStatic.instance.selectedWorld!, -1)
|
|
32
|
+
.pipe(takeUntil(this.removed$))
|
|
33
|
+
.subscribe(() => {
|
|
34
|
+
stats?.begin();
|
|
35
|
+
});
|
|
36
|
+
createInlineTickController(GgStatic.instance.selectedWorld!, 10000)
|
|
37
|
+
.pipe(takeUntil(this.removed$))
|
|
38
|
+
.subscribe(() => {
|
|
39
|
+
stats?.end();
|
|
40
|
+
});
|
|
41
|
+
const customContainer: HTMLDivElement = document.createElement('div');
|
|
42
|
+
customContainer.style.cssText =
|
|
43
|
+
'position:fixed;top:48px;right:0;opacity:0.9;z-index:9999;background-color:#333;color:white';
|
|
44
|
+
customContainer.innerHTML = `<input type="checkbox" name="checkbox" id="physics_debugger_checkbox_id" value="1"${
|
|
45
|
+
GgStatic.instance.selectedWorld?.physicsWorld.physicsDebugViewActive ? ' checked' : ''
|
|
46
|
+
}>
|
|
47
|
+
<label for="physics_debugger_checkbox_id" style="user-select: none;">Show physics bodies in scene</label>`;
|
|
48
|
+
document.body.appendChild(customContainer);
|
|
49
|
+
fromEvent(document.getElementById('physics_debugger_checkbox_id')! as HTMLInputElement, 'change')
|
|
50
|
+
.pipe(takeUntil(this.removed$))
|
|
51
|
+
.subscribe(e => {
|
|
52
|
+
GgStatic.instance.console('dr_drawphysics ' + (e.target as HTMLInputElement).checked).then();
|
|
53
|
+
});
|
|
54
|
+
this.ui = {
|
|
55
|
+
stats,
|
|
56
|
+
customContainer,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public destroyUI() {
|
|
61
|
+
if (this.ui) {
|
|
62
|
+
document.body.removeChild(this.ui.stats.dom);
|
|
63
|
+
document.body.removeChild(this.ui.customContainer);
|
|
64
|
+
this.ui.stats.end();
|
|
65
|
+
this.ui = null;
|
|
66
|
+
}
|
|
67
|
+
this.removed$.next();
|
|
68
|
+
}
|
|
69
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export * from './base/clock';
|
|
2
|
+
export * from './base/gg-viewport';
|
|
3
|
+
export * from './base/gg-viewport-manager';
|
|
4
|
+
export * from './base/entities/interfaces/i-tick-listener';
|
|
5
|
+
export * from './base/entities/gg-entity';
|
|
6
|
+
export * from './base/entities/base-gg-renderer';
|
|
7
|
+
export * from './base/entities/inline-controller';
|
|
8
|
+
export * from './base/interfaces/gg-body';
|
|
9
|
+
export * from './base/interfaces/gg-debug-physics-drawer';
|
|
10
|
+
export * from './base/interfaces/gg-object';
|
|
11
|
+
export * from './base/interfaces/gg-physics-world';
|
|
12
|
+
export * from './base/interfaces/gg-trigger';
|
|
13
|
+
export * from './base/interfaces/gg-visual-scene';
|
|
14
|
+
export * from './base/models/axis-directions';
|
|
15
|
+
export * from './base/models/body-options';
|
|
16
|
+
export * from './base/models/geometry-nodes';
|
|
17
|
+
export * from './base/models/points';
|
|
18
|
+
export * from './base/math/box';
|
|
19
|
+
export * from './base/math/point2';
|
|
20
|
+
export * from './base/math/point3';
|
|
21
|
+
export * from './base/math/quaternion';
|
|
22
|
+
export * from './base/math/numbers';
|
|
23
|
+
export * from './base/math/matrix4';
|
|
24
|
+
export * from './base/controllers/common';
|
|
25
|
+
export * from './base/controllers/i-controller';
|
|
26
|
+
export * from './base/controllers/keyboard.controller';
|
|
27
|
+
export * from './base/controllers/mouse.controller';
|
|
28
|
+
|
|
29
|
+
export * from './2d/entities/gg-2d-entity';
|
|
30
|
+
export * from './2d/entities/gg-positionable-2d-entity';
|
|
31
|
+
export * from './2d/entities/gg-2d-trigger.entity';
|
|
32
|
+
export * from './2d/models/body-options';
|
|
33
|
+
export * from './2d/models/shapes';
|
|
34
|
+
export * from './2d/interfaces';
|
|
35
|
+
export * from './2d/factories';
|
|
36
|
+
export * from './2d/gg-2d-world';
|
|
37
|
+
|
|
38
|
+
export * from './3d/controllers/car-keyboard.controller';
|
|
39
|
+
export * from './3d/controllers/free-camera.controller';
|
|
40
|
+
export * from './3d/entities/controllers/entity-motion.controller';
|
|
41
|
+
export * from './3d/entities/gg-3d-entity';
|
|
42
|
+
export * from './3d/entities/gg-positionable-3d-entity';
|
|
43
|
+
export * from './3d/entities/gg-3d-camera.entity';
|
|
44
|
+
export * from './3d/entities/gg-3d-map-graph.entity';
|
|
45
|
+
export * from './3d/entities/gg-3d-raycast-vehicle.entity';
|
|
46
|
+
export * from './3d/entities/gg-3d-trigger.entity';
|
|
47
|
+
export * from './3d/models/body-options';
|
|
48
|
+
export * from './3d/models/gg-meta';
|
|
49
|
+
export * from './3d/models/shapes';
|
|
50
|
+
export * from './3d/interfaces';
|
|
51
|
+
export * from './3d/factories';
|
|
52
|
+
export * from './3d/gg-3d-world';
|
|
53
|
+
export * from './3d/loader';
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Graph } from '../../../src/base/data-structures/graph';
|
|
2
|
+
|
|
3
|
+
describe(`Graph<T>`, () => {
|
|
4
|
+
|
|
5
|
+
const testGrid = Array(150).fill(null).map((_, i) => (
|
|
6
|
+
Array(151).fill(null).map((_, j) => ({ i, j }))
|
|
7
|
+
));
|
|
8
|
+
const testGridGraph = Graph.fromSquareGrid(testGrid);
|
|
9
|
+
const nodesArray: Graph<{ i: number, j: number }>[][] = Array(150).fill(null).map((_, i) => (
|
|
10
|
+
Array(151).fill(null).map((_, j) => null!)
|
|
11
|
+
));
|
|
12
|
+
for (const node of testGridGraph.nodes()) {
|
|
13
|
+
nodesArray[node.data.i][node.data.j] = node;
|
|
14
|
+
}
|
|
15
|
+
const middleNode = nodesArray[75][75];
|
|
16
|
+
|
|
17
|
+
describe(`walkRead`, () => {
|
|
18
|
+
it('should return correct amount for depth 0', () => {
|
|
19
|
+
const result = middleNode.walkRead(0);
|
|
20
|
+
expect(result.size).toBe(1);
|
|
21
|
+
expect(result.has(middleNode)).toBe(true);
|
|
22
|
+
});
|
|
23
|
+
it('should return correct amount for depth 4', () => {
|
|
24
|
+
const result = middleNode.walkRead(4);
|
|
25
|
+
expect(result.size).toBe(41);
|
|
26
|
+
});
|
|
27
|
+
it('should return correct amount for depth 5', () => {
|
|
28
|
+
const result = middleNode.walkRead(5);
|
|
29
|
+
expect(result.size).toBe(61);
|
|
30
|
+
});
|
|
31
|
+
it('should return correct amount for depth 6', () => {
|
|
32
|
+
const result = middleNode.walkRead(6);
|
|
33
|
+
expect(result.size).toBe(85);
|
|
34
|
+
});
|
|
35
|
+
it('should return correct amount for depth 7', () => {
|
|
36
|
+
const result = middleNode.walkRead(7);
|
|
37
|
+
expect(result.size).toBe(113);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
describe(`walkReadPreserveDepth`, () => {
|
|
41
|
+
it('should return correct amounts for depth 0', () => {
|
|
42
|
+
const result = middleNode.walkReadPreserveDepth(0);
|
|
43
|
+
expect(result.length).toBe(1);
|
|
44
|
+
expect(result[0].size).toBe(1);
|
|
45
|
+
expect(result[0].has(middleNode)).toBe(true);
|
|
46
|
+
});
|
|
47
|
+
it('should return correct amount for depth 4', () => {
|
|
48
|
+
const result = middleNode.walkReadPreserveDepth(4);
|
|
49
|
+
expect(result.length).toBe(5);
|
|
50
|
+
for (let i = 0; i < result.length; i++) {
|
|
51
|
+
expect(result[i].size).toBe(i > 0 ? i * 4 : 1);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
it('should return correct amount for depth 5', () => {
|
|
55
|
+
const result = middleNode.walkReadPreserveDepth(5);
|
|
56
|
+
expect(result.length).toBe(6);
|
|
57
|
+
for (let i = 0; i < result.length; i++) {
|
|
58
|
+
expect(result[i].size).toBe(i > 0 ? i * 4 : 1);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
it('should return correct amount for depth 6', () => {
|
|
62
|
+
const result = middleNode.walkReadPreserveDepth(6);
|
|
63
|
+
expect(result.length).toBe(7);
|
|
64
|
+
for (let i = 0; i < result.length; i++) {
|
|
65
|
+
expect(result[i].size).toBe(i > 0 ? i * 4 : 1);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
it('should return correct amount for depth 7', () => {
|
|
69
|
+
const result = middleNode.walkReadPreserveDepth(7);
|
|
70
|
+
expect(result.length).toBe(8);
|
|
71
|
+
for (let i = 0; i < result.length; i++) {
|
|
72
|
+
expect(result[i].size).toBe(i > 0 ? i * 4 : 1);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
});
|