@gg-web-engine/core 0.0.1 → 0.0.3

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 (103) hide show
  1. package/dist/2d/entities/controllers/entity-2d-positioning.animator.d.ts +16 -0
  2. package/dist/2d/entities/controllers/entity-2d-positioning.animator.js +26 -0
  3. package/dist/2d/entities/gg-2d-entity.d.ts +9 -1
  4. package/dist/2d/entities/gg-2d-entity.js +50 -17
  5. package/dist/2d/gg-2d-world.d.ts +3 -0
  6. package/dist/2d/gg-2d-world.js +11 -0
  7. package/dist/3d/controllers/car-keyboard.controller.d.ts +10 -10
  8. package/dist/3d/controllers/car-keyboard.controller.js +21 -20
  9. package/dist/3d/controllers/free-camera.controller.d.ts +8 -8
  10. package/dist/3d/entities/controllers/camera-3d.animator.d.ts +17 -0
  11. package/dist/3d/entities/controllers/camera-3d.animator.js +32 -0
  12. package/dist/3d/entities/controllers/entity-3d-positioning.animator.d.ts +16 -0
  13. package/dist/3d/entities/controllers/entity-3d-positioning.animator.js +26 -0
  14. package/dist/3d/entities/gg-3d-camera.entity.d.ts +2 -0
  15. package/dist/3d/entities/gg-3d-camera.entity.js +6 -0
  16. package/dist/3d/entities/gg-3d-entity.d.ts +4 -1
  17. package/dist/3d/entities/gg-3d-entity.js +19 -10
  18. package/dist/3d/entities/gg-3d-map-graph.entity.d.ts +7 -5
  19. package/dist/3d/entities/gg-3d-map-graph.entity.js +1 -1
  20. package/dist/3d/entities/gg-3d-raycast-vehicle.entity.d.ts +6 -5
  21. package/dist/3d/gg-3d-world.d.ts +3 -0
  22. package/dist/3d/gg-3d-world.js +12 -0
  23. package/dist/base/clock/clock.d.ts +25 -0
  24. package/dist/base/clock/clock.js +79 -0
  25. package/dist/base/clock/global-clock.d.ts +15 -0
  26. package/dist/base/clock/global-clock.js +36 -0
  27. package/dist/base/entities/controllers/animation-mixer.d.ts +83 -0
  28. package/dist/base/entities/controllers/animation-mixer.js +152 -0
  29. package/dist/base/entities/gg-entity.d.ts +4 -1
  30. package/dist/base/entities/gg-entity.js +7 -0
  31. package/dist/base/entities/inline-controller.js +0 -1
  32. package/dist/base/gg-viewport-manager.d.ts +4 -0
  33. package/dist/base/gg-world.d.ts +3 -1
  34. package/dist/base/gg-world.js +6 -5
  35. package/dist/base/math/matrix4.js +3 -3
  36. package/dist/base/math/point2.js +1 -1
  37. package/dist/base/math/point3.js +1 -1
  38. package/dist/base/math/quaternion.d.ts +83 -9
  39. package/dist/base/math/quaternion.js +93 -10
  40. package/dist/base/models/points.d.ts +9 -9
  41. package/dist/index.d.ts +6 -2
  42. package/dist/index.js +6 -2
  43. package/package.json +1 -1
  44. package/.prettierrc +0 -8
  45. package/src/2d/entities/gg-2d-entity.ts +0 -86
  46. package/src/2d/entities/gg-2d-trigger.entity.ts +0 -17
  47. package/src/2d/entities/gg-positionable-2d-entity.ts +0 -16
  48. package/src/2d/factories.ts +0 -20
  49. package/src/2d/gg-2d-world.ts +0 -32
  50. package/src/2d/interfaces.ts +0 -31
  51. package/src/2d/models/body-options.ts +0 -3
  52. package/src/2d/models/shapes.ts +0 -7
  53. package/src/3d/controllers/car-keyboard.controller.ts +0 -128
  54. package/src/3d/controllers/free-camera.controller.ts +0 -86
  55. package/src/3d/entities/controllers/entity-motion.controller.ts +0 -122
  56. package/src/3d/entities/gg-3d-camera.entity.ts +0 -8
  57. package/src/3d/entities/gg-3d-entity.ts +0 -116
  58. package/src/3d/entities/gg-3d-map-graph.entity.ts +0 -204
  59. package/src/3d/entities/gg-3d-raycast-vehicle.entity.ts +0 -468
  60. package/src/3d/entities/gg-3d-trigger.entity.ts +0 -22
  61. package/src/3d/entities/gg-positionable-3d-entity.ts +0 -31
  62. package/src/3d/factories.ts +0 -29
  63. package/src/3d/gg-3d-world.ts +0 -36
  64. package/src/3d/interfaces.ts +0 -96
  65. package/src/3d/loader.ts +0 -165
  66. package/src/3d/models/body-options.ts +0 -3
  67. package/src/3d/models/gg-meta.ts +0 -12
  68. package/src/3d/models/shapes.ts +0 -13
  69. package/src/base/clock.ts +0 -97
  70. package/src/base/controllers/common.ts +0 -37
  71. package/src/base/controllers/i-controller.ts +0 -5
  72. package/src/base/controllers/keyboard.controller.ts +0 -109
  73. package/src/base/controllers/mouse.controller.ts +0 -73
  74. package/src/base/data-structures/graph.ts +0 -125
  75. package/src/base/entities/base-gg-renderer.ts +0 -77
  76. package/src/base/entities/gg-entity.ts +0 -61
  77. package/src/base/entities/gg-positionable-entity.ts +0 -64
  78. package/src/base/entities/inline-controller.ts +0 -31
  79. package/src/base/entities/interfaces/i-tick-listener.ts +0 -15
  80. package/src/base/gg-static.ts +0 -30
  81. package/src/base/gg-viewport-manager.ts +0 -122
  82. package/src/base/gg-viewport.ts +0 -159
  83. package/src/base/gg-world.ts +0 -198
  84. package/src/base/interfaces/gg-body.ts +0 -23
  85. package/src/base/interfaces/gg-debug-physics-drawer.ts +0 -10
  86. package/src/base/interfaces/gg-object.ts +0 -26
  87. package/src/base/interfaces/gg-physics-world.ts +0 -24
  88. package/src/base/interfaces/gg-trigger.ts +0 -10
  89. package/src/base/interfaces/gg-visual-scene.ts +0 -11
  90. package/src/base/math/box.ts +0 -19
  91. package/src/base/math/matrix4.ts +0 -29
  92. package/src/base/math/numbers.ts +0 -10
  93. package/src/base/math/point2.ts +0 -43
  94. package/src/base/math/point3.ts +0 -119
  95. package/src/base/math/quaternion.ts +0 -172
  96. package/src/base/models/axis-directions.ts +0 -3
  97. package/src/base/models/body-options.ts +0 -6
  98. package/src/base/models/geometry-nodes.ts +0 -5
  99. package/src/base/models/points.ts +0 -3
  100. package/src/base/ui/gg-console.ui.ts +0 -165
  101. package/src/base/ui/gg-debugger.ui.ts +0 -69
  102. package/src/index.ts +0 -53
  103. package/test/base/data-structures/graph.spec.ts +0 -76
@@ -1,198 +0,0 @@
1
- import { Clock } from './clock';
2
- import { GgEntity } from './entities/gg-entity';
3
- import { isITickListener, ITickListener } from './entities/interfaces/i-tick-listener';
4
- import { GgPhysicsWorld } from './interfaces/gg-physics-world';
5
- import { GgVisualScene } from './interfaces/gg-visual-scene';
6
- import { GgStatic } from './gg-static';
7
- import { KeyboardController } from './controllers/keyboard.controller';
8
- import { filter } from 'rxjs';
9
- import { GgConsoleUI } from './ui/gg-console.ui';
10
- import { GgDebuggerUI } from './ui/gg-debugger.ui';
11
-
12
- export abstract class GgWorld<
13
- D,
14
- R,
15
- V extends GgVisualScene<D, R> = GgVisualScene<D, R>,
16
- P extends GgPhysicsWorld<D, R> = GgPhysicsWorld<D, R>,
17
- > {
18
- // inner clock, runs constantly
19
- private readonly animationFrameClock: Clock = Clock.animationFrameClock;
20
- // world clock, can be paused/resumed. Stops when disposing world
21
- private readonly worldClock: Clock = new Clock(this.animationFrameClock.tick$);
22
-
23
- // TODO consider adding mouse controller
24
- public readonly keyboardController: KeyboardController = new KeyboardController();
25
-
26
- readonly children: GgEntity[] = [];
27
- protected readonly tickListeners: ITickListener[] = [];
28
-
29
- constructor(
30
- public readonly visualScene: V,
31
- public readonly physicsWorld: P,
32
- protected readonly consoleEnabled: boolean = false,
33
- ) {
34
- GgStatic.instance.worlds.push(this);
35
- GgStatic.instance.selectedWorld = this;
36
- this.keyboardController.start().then();
37
- if (consoleEnabled) {
38
- this.keyboardController
39
- .bind('Backquote')
40
- .pipe(filter(x => x))
41
- .subscribe(() => {
42
- // open console UI
43
- if (GgConsoleUI.instance.isUIShown) {
44
- GgConsoleUI.instance.destroyUI();
45
- } else {
46
- GgConsoleUI.instance.createUI();
47
- }
48
- });
49
- this.registerConsoleCommand(
50
- 'commandslist',
51
- async () => {
52
- return Object.entries(this.commands)
53
- .map(([key, value]) => `${key}${value.doc ? '\t// ' + value.doc : ''}`)
54
- .sort()
55
- .join('\n\n');
56
- },
57
- 'no args; print all available commands',
58
- );
59
- this.registerConsoleCommand(
60
- 'debugger',
61
- async (...args: string[]) => {
62
- const shouldDraw = ['1', 'true', '+'].includes(args[0]);
63
- if (shouldDraw != GgDebuggerUI.instance.isUIShown) {
64
- if (GgDebuggerUI.instance.isUIShown) {
65
- GgDebuggerUI.instance.destroyUI();
66
- } else {
67
- GgDebuggerUI.instance.createUI();
68
- }
69
- }
70
- return '' + GgDebuggerUI.instance.isUIShown;
71
- },
72
- 'args: [0 or 1]; turn on/off debug panel. Default value is 0',
73
- );
74
- this.registerConsoleCommand(
75
- 'ph_timescale',
76
- async (...args: string[]) => {
77
- this.physicsWorld.timeScale = +args[0];
78
- return JSON.stringify(this.physicsWorld.timeScale);
79
- },
80
- 'args: [float]; change time scale of physics engine. Default value is 1.0',
81
- );
82
- this.registerConsoleCommand(
83
- 'dr_drawphysics',
84
- async (...args: string[]) => {
85
- const shouldDraw = ['1', 'true', '+'].includes(args[0]);
86
- if (shouldDraw != this.physicsWorld.physicsDebugViewActive) {
87
- this.triggerPhysicsDebugView();
88
- }
89
- return '' + this.physicsWorld.physicsDebugViewActive;
90
- },
91
- 'args: [0 or 1]; turn on/off physics debug view. Default value is 0',
92
- );
93
- }
94
- }
95
-
96
- public async init() {
97
- await Promise.all([this.physicsWorld.init(), this.visualScene.init()]);
98
- this.worldClock.tick$.subscribe(([elapsed, delta]) => {
99
- let physicsTickPerformed = false;
100
- for (let i = 0; i < this.tickListeners.length; i++) {
101
- if (!physicsTickPerformed && this.tickListeners[i].tickOrder >= 500) {
102
- this.physicsWorld.simulate(delta);
103
- physicsTickPerformed = true;
104
- }
105
- this.tickListeners[i].tick$.next([elapsed, delta]);
106
- }
107
- if (!physicsTickPerformed) {
108
- this.physicsWorld.simulate(delta);
109
- }
110
- });
111
- }
112
-
113
- public start() {
114
- this.worldClock.start();
115
- }
116
-
117
- public pauseWorld() {
118
- this.worldClock.pause();
119
- }
120
-
121
- public resumeWorld() {
122
- this.worldClock.pause();
123
- }
124
-
125
- public dispose(): void {
126
- this.worldClock.stop();
127
- for (let i = 0; i < this.children.length; i++) {
128
- this.children[i].dispose();
129
- }
130
- this.children.splice(0, this.children.length);
131
- this.tickListeners.splice(0, this.tickListeners.length);
132
- this.physicsWorld.dispose();
133
- this.visualScene.dispose();
134
- }
135
-
136
- public addEntity(entity: GgEntity): void {
137
- if (!!entity.world) {
138
- throw new Error('Entity already spawned');
139
- }
140
- this.children.push(entity);
141
- if (isITickListener(entity)) {
142
- this.tickListeners.push(entity as any as ITickListener);
143
- this.tickListeners.sort((l1, l2) => l1.tickOrder - l2.tickOrder);
144
- }
145
- entity.onSpawned(this);
146
- }
147
-
148
- public removeEntity(entity: GgEntity, dispose = true): void {
149
- if (entity.world !== this) {
150
- throw new Error('Entity is not a part of this world');
151
- }
152
- this.children.splice(
153
- this.children.findIndex(x => x === entity),
154
- 1,
155
- );
156
- if (isITickListener(entity)) {
157
- this.tickListeners.splice(
158
- this.tickListeners.findIndex(x => (x as any) === entity),
159
- 1,
160
- );
161
- }
162
- entity.onRemoved();
163
- if (dispose) {
164
- entity.dispose();
165
- }
166
- }
167
-
168
- protected commands: { [key: string]: { handler: (...args: string[]) => Promise<string>; doc?: string } } = {};
169
-
170
- public registerConsoleCommand(command: string, handler: (...args: string[]) => Promise<string>, doc?: string): void {
171
- if (!this.consoleEnabled) {
172
- throw new Error('Console not enabled for this world');
173
- }
174
- this.commands[command] = { handler, doc };
175
- }
176
-
177
- public async runConsoleCommand(command: string, args: string[]): Promise<string> {
178
- if (!this.consoleEnabled) {
179
- throw new Error('Console not enabled for this world');
180
- }
181
- if (!this.commands[command]) {
182
- return 'Unrecognized command: ' + command;
183
- }
184
- return this.commands[command].handler(...args);
185
- }
186
-
187
- public triggerPhysicsDebugView() {
188
- if (this.physicsWorld.physicsDebugViewActive) {
189
- this.physicsWorld.stopDebugger(this);
190
- } else {
191
- const cls = this.visualScene.debugPhysicsDrawerClass;
192
- if (!cls) {
193
- throw new Error('Debug drawer is not available');
194
- }
195
- this.physicsWorld.startDebugger(this, new cls());
196
- }
197
- }
198
- }
@@ -1,23 +0,0 @@
1
- import { GgPhysicsWorld } from './gg-physics-world';
2
- import { GgEntity } from '../entities/gg-entity';
3
-
4
- export interface GgBody<D, R> {
5
- position: D;
6
- rotation: R;
7
- scale: D;
8
-
9
- name: string;
10
-
11
- entity: GgEntity | null;
12
-
13
- clone(): GgBody<D, R>;
14
-
15
- addToWorld(world: GgPhysicsWorld<D, R>): void;
16
-
17
- removeFromWorld(world: GgPhysicsWorld<D, R>): void;
18
-
19
- dispose(): void;
20
-
21
- /** clear velocities etc. */
22
- resetMotion(): void;
23
- }
@@ -1,10 +0,0 @@
1
- import { Point3 } from '../models/points';
2
- import { GgObject } from './gg-object';
3
-
4
- export interface GgDebugPhysicsDrawer<D, R> extends GgObject<D, R> {
5
- drawContactPoint(point: D, normal: D, color?: Point3): void;
6
-
7
- drawLine(from: D, to: D, color?: Point3): void;
8
-
9
- update(): void;
10
- }
@@ -1,26 +0,0 @@
1
- import { GgVisualScene } from './gg-visual-scene';
2
- import { GgBox } from '../models/geometry-nodes';
3
-
4
- export interface GgObject<D, R> {
5
- position: D;
6
- rotation: R;
7
- scale: D;
8
-
9
- visible: boolean;
10
-
11
- name: string;
12
-
13
- isEmpty(): boolean;
14
-
15
- popChild(name: string): GgObject<D, R> | null;
16
-
17
- getBoundings(): GgBox<D>;
18
-
19
- clone(): GgObject<D, R>;
20
-
21
- addToWorld(world: GgVisualScene<D, R>): void;
22
-
23
- removeFromWorld(world: GgVisualScene<D, R>): void;
24
-
25
- dispose(): void;
26
- }
@@ -1,24 +0,0 @@
1
- import { GgDebugPhysicsDrawer } from './gg-debug-physics-drawer';
2
- import { GgWorld } from '../gg-world';
3
-
4
- export interface GgPhysicsWorld<D, R> {
5
- readonly factory: any; // type defined in sub-interfaces
6
- gravity: D;
7
- timeScale: number;
8
- get physicsDebugViewActive(): boolean;
9
-
10
- init(): Promise<void>;
11
-
12
- /**
13
- * Runs simulation of the physics world.
14
- *
15
- * @param delta delta time from last tick in milliseconds.
16
- */
17
- simulate(delta: number): void;
18
-
19
- startDebugger(world: GgWorld<D, R>, drawer: GgDebugPhysicsDrawer<D, R>): void;
20
-
21
- stopDebugger(world: GgWorld<D, R>): void;
22
-
23
- dispose(): void;
24
- }
@@ -1,10 +0,0 @@
1
- import { GgBody } from './gg-body';
2
- import { GgPositionableEntity } from '../entities/gg-positionable-entity';
3
- import { Observable } from 'rxjs';
4
-
5
- export interface GgTrigger<D, R> extends GgBody<D, R> {
6
- get onEntityEntered(): Observable<GgPositionableEntity<D, R>>;
7
- get onEntityLeft(): Observable<GgPositionableEntity<D, R> | null>;
8
-
9
- checkOverlaps(): void;
10
- }
@@ -1,11 +0,0 @@
1
- import { GgDebugPhysicsDrawer } from './gg-debug-physics-drawer';
2
-
3
- export interface GgVisualScene<D, R> {
4
- readonly factory: any; // type defined in sub-interfaces
5
-
6
- readonly debugPhysicsDrawerClass?: { new (): GgDebugPhysicsDrawer<D, R> };
7
-
8
- init(): Promise<void>;
9
-
10
- dispose(): void;
11
- }
@@ -1,19 +0,0 @@
1
- import { GgBox } from '../models/geometry-nodes';
2
-
3
- export class Box {
4
- static clone<T>(box: GgBox<T>): GgBox<T> {
5
- return { min: { ...box.min }, max: { ...box.max } };
6
- }
7
- static expandByPoint<T>(box: GgBox<T>, point: T): GgBox<T> {
8
- const res: GgBox<T> = Box.clone(box);
9
- for (const c in point) {
10
- if (res.min[c] > point[c]) {
11
- res.min[c] = point[c];
12
- }
13
- if (res.max[c] < point[c]) {
14
- res.max[c] = point[c];
15
- }
16
- }
17
- return res;
18
- }
19
- }
@@ -1,29 +0,0 @@
1
- import { Point3, Point4 } from '../models/points';
2
- import { Pnt3 } from './point3';
3
-
4
- export class Mtrx4 {
5
- /** creates a rotation matrix for object, so it will look at some point in space */
6
- static lookAt(eye: Point3, target: Point3, up: Point3): number[] {
7
- let z: Point3 = Pnt3.sub(eye, target);
8
- if (Pnt3.lenSq(z) === 0) {
9
- // same position
10
- z.z = 1;
11
- } else {
12
- z = Pnt3.norm(z);
13
- }
14
- let x = Pnt3.cross(up, z);
15
- if (Pnt3.lenSq(x) === 0) {
16
- // up and z are parallel
17
- if (Math.abs(up.z) === 1) {
18
- z.x += 0.0001;
19
- } else {
20
- z.z += 0.0001;
21
- }
22
- z = Pnt3.norm(z);
23
- x = Pnt3.cross(up, z);
24
- }
25
- x = Pnt3.norm(x);
26
- let y = Pnt3.cross(z, x);
27
- return [x.x, x.y, x.z, 0, y.x, y.y, y.z, 0, z.x, z.y, z.z, 0];
28
- }
29
- }
@@ -1,10 +0,0 @@
1
- export const averageAngle = (angleA: number, angleB: number, factor: number = 0.5) => {
2
- while (Math.abs(angleA - angleB) > Math.PI) {
3
- angleB += Math.PI * (angleA > angleB ? 2 : -2);
4
- }
5
- return angleA * (1 - factor) + angleB * factor;
6
- };
7
-
8
- export const lerpNumber = (a: number, b: number, t: number) => {
9
- return a + t * (b - a);
10
- };
@@ -1,43 +0,0 @@
1
- import { Point2 } from '../models/points';
2
-
3
- export class Pnt2 {
4
- /** clone point */
5
- static clone(p: Point2): Point2 {
6
- return { ...p };
7
- }
8
-
9
- /** add point b to point a */
10
- static add(a: Point2, b: Point2): Point2 {
11
- return { x: a.x + b.x, y: a.y + b.y };
12
- }
13
-
14
- /** subtract point b from point a */
15
- static sub(a: Point2, b: Point2): Point2 {
16
- return { x: a.x - b.x, y: a.y - b.y };
17
- }
18
-
19
- /** normalize */
20
- static norm(p: Point2): Point2 {
21
- const length = Math.sqrt(p.x ** 2 + p.y ** 2);
22
- return {
23
- x: p.x / length,
24
- y: p.y / length,
25
- };
26
- }
27
-
28
- /** scalar multiplication */
29
- static scalarMult(p: Point2, m: number): Point2 {
30
- return {
31
- x: p.x * m,
32
- y: p.y * m,
33
- };
34
- }
35
-
36
- /** linear interpolation */
37
- static lerp(a: Point2, b: Point2, t: number): Point2 {
38
- return {
39
- x: a.x + t * (b.x - a.x),
40
- y: a.y + t * (b.y - a.y),
41
- };
42
- }
43
- }
@@ -1,119 +0,0 @@
1
- import { Point3, Point4 } from '../models/points';
2
- import { Qtrn } from './quaternion';
3
-
4
- export class Pnt3 {
5
- /** clone point */
6
- static clone(p: Point3): Point3 {
7
- return { ...p };
8
- }
9
-
10
- /** add point b to point a */
11
- static add(a: Point3, b: Point3): Point3 {
12
- return { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
13
- }
14
-
15
- /** subtract point b from point a */
16
- static sub(a: Point3, b: Point3): Point3 {
17
- return { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z };
18
- }
19
-
20
- /** calculate vector length (squared) */
21
- static lenSq(v: Point3) {
22
- return v.x * v.x + v.y * v.y + v.z * v.z;
23
- }
24
-
25
- /** calculate vector length */
26
- static len(v: Point3) {
27
- return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
28
- }
29
-
30
- /** cross vectors */
31
- static cross(a: Point3, b: Point3): Point3 {
32
- const ax = a.x,
33
- ay = a.y,
34
- az = a.z;
35
- const bx = b.x,
36
- by = b.y,
37
- bz = b.z;
38
- return {
39
- x: ay * bz - az * by,
40
- y: az * bx - ax * bz,
41
- z: ax * by - ay * bx,
42
- };
43
- }
44
-
45
- /** normalize */
46
- static norm(p: Point3): Point3 {
47
- const length = Math.sqrt(p.x ** 2 + p.y ** 2 + p.z ** 2);
48
- if (length === 0) {
49
- return p;
50
- }
51
- return {
52
- x: p.x / length,
53
- y: p.y / length,
54
- z: p.z / length,
55
- };
56
- }
57
-
58
- /** scalar multiplication */
59
- static scalarMult(p: Point3, m: number): Point3 {
60
- return {
61
- x: p.x * m,
62
- y: p.y * m,
63
- z: p.z * m,
64
- };
65
- }
66
-
67
- /** linear interpolation */
68
- static lerp(a: Point3, b: Point3, t: number): Point3 {
69
- return {
70
- x: a.x + t * (b.x - a.x),
71
- y: a.y + t * (b.y - a.y),
72
- z: a.z + t * (b.z - a.z),
73
- };
74
- }
75
-
76
- /** rotate point a with quaternion q */
77
- static rot(p: Point3, q: Point4): Point3 {
78
- // faster version of:
79
- // let qvec: Point4 = {x: v.x, y: v.y, z: v.z, w: 0};
80
- // let qinv: Point4 = {x: -q.x, y: -q.y, z: -q.z, w: q.w};
81
- // let res = Qtrn.mult(q, Qtrn.mult(qvec, qinv));
82
- // return {x: res.x, y: res.y, z: res.z};
83
- const { x, y, z } = p;
84
- return {
85
- x:
86
- q.w * q.w * x +
87
- 2 * q.y * q.w * z -
88
- 2 * q.z * q.w * y +
89
- q.x * q.x * x +
90
- 2 * q.y * q.x * y +
91
- 2 * q.z * q.x * z -
92
- q.y * q.y * x -
93
- q.z * q.z * x,
94
- y:
95
- 2 * q.x * q.y * x +
96
- q.y * q.y * y +
97
- 2 * q.z * q.y * z +
98
- 2 * q.w * q.z * x -
99
- q.z * q.z * y +
100
- q.w * q.w * y -
101
- 2 * q.x * q.w * z -
102
- q.x * q.x * y,
103
- z:
104
- 2 * q.x * q.z * x +
105
- 2 * q.y * q.z * y +
106
- q.z * q.z * z -
107
- 2 * q.w * q.y * x -
108
- q.y * q.y * z +
109
- 2 * q.w * q.x * y -
110
- q.x * q.x * z +
111
- q.w * q.w * z,
112
- };
113
- }
114
-
115
- /** rotate point around axis a (normalized vector) */
116
- static rotAround(p: Point3, axis: Point3, angle: number): Point3 {
117
- return this.rot(p, Qtrn.fromAngle(axis, angle));
118
- }
119
- }