@chromatic-coherence/generative-engine 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/dist/world.d.ts +9 -1
- package/dist/world.js +41 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -143,9 +143,14 @@ Bones, grown from code like everything else — no asset pipeline. `humanoid()`
|
|
|
143
143
|
in the vertex stage — scene, shadows and water reflections alike. `walkPose` / `trotPose`
|
|
144
144
|
ship as procedural cycles; `composePose` takes any per-joint rotations you write.
|
|
145
145
|
|
|
146
|
+
## Fly controls (v1.7)
|
|
147
|
+
|
|
148
|
+
`controls: "fly"` — free flight: drag to look, wheel to fly along your gaze, W/A/S/D to
|
|
149
|
+
move (shift for speed), `w.flySpeed` to tune. The pitch clamp opens to near-vertical.
|
|
150
|
+
|
|
146
151
|
## Roadmap
|
|
147
152
|
|
|
148
|
-
The engine's
|
|
153
|
+
The engine's founding frontiers are landed. What comes next, the scenes will ask for. The chart editions stay lean.
|
|
149
154
|
|
|
150
155
|
## Licence
|
|
151
156
|
|
package/dist/world.d.ts
CHANGED
|
@@ -52,7 +52,9 @@ export type WorldOpts = {
|
|
|
52
52
|
maxDpr?: number;
|
|
53
53
|
drift?: number;
|
|
54
54
|
parallax?: number;
|
|
55
|
-
|
|
55
|
+
/** true = orbit (drag + ctrl-wheel zoom). "fly" (W13) = free flight: drag to look,
|
|
56
|
+
* wheel to fly forward/back, W/A/S/D to move, shift for speed. */
|
|
57
|
+
controls?: boolean | "fly";
|
|
56
58
|
/** shadow maps — lights[0] casts. true, or { size (px, default 2048), softness, bias } */
|
|
57
59
|
shadows?: boolean | {
|
|
58
60
|
size?: number;
|
|
@@ -84,6 +86,12 @@ export declare class World {
|
|
|
84
86
|
private overlay;
|
|
85
87
|
private og;
|
|
86
88
|
private opts;
|
|
89
|
+
private flyMode;
|
|
90
|
+
private pitchMin;
|
|
91
|
+
private pitchMax;
|
|
92
|
+
private keys;
|
|
93
|
+
/** W13 fly speed, units/second (shift = 3x). */
|
|
94
|
+
flySpeed: number;
|
|
87
95
|
private pFace;
|
|
88
96
|
private pLine;
|
|
89
97
|
private pPt;
|
package/dist/world.js
CHANGED
|
@@ -34,6 +34,12 @@ export class World {
|
|
|
34
34
|
this.groupNM.set(normalMat3(mat), i * 9);
|
|
35
35
|
}
|
|
36
36
|
constructor(o) {
|
|
37
|
+
this.flyMode = false;
|
|
38
|
+
this.pitchMin = 0.18;
|
|
39
|
+
this.pitchMax = 0.95;
|
|
40
|
+
this.keys = new Set();
|
|
41
|
+
/** W13 fly speed, units/second (shift = 3x). */
|
|
42
|
+
this.flySpeed = 420;
|
|
37
43
|
this.instanced = [];
|
|
38
44
|
/** W9 — the one wind that blows through every swaying instanced batch */
|
|
39
45
|
this.wind = { dir: v3(1, 0, 0.35), speed: 1 };
|
|
@@ -159,8 +165,13 @@ export class World {
|
|
|
159
165
|
maxDpr: o.maxDpr ?? 2,
|
|
160
166
|
drift: o.drift ?? 0.045,
|
|
161
167
|
parallax: o.parallax ?? 0.3,
|
|
162
|
-
controls: o.controls
|
|
168
|
+
controls: !!o.controls,
|
|
163
169
|
};
|
|
170
|
+
this.flyMode = o.controls === "fly";
|
|
171
|
+
if (this.flyMode) {
|
|
172
|
+
this.pitchMin = -1.15;
|
|
173
|
+
this.pitchMax = 1.15;
|
|
174
|
+
}
|
|
164
175
|
if (o.camera) {
|
|
165
176
|
if (o.camera.target)
|
|
166
177
|
this.cam.target = o.camera.target;
|
|
@@ -264,11 +275,26 @@ export class World {
|
|
|
264
275
|
};
|
|
265
276
|
const upFn = () => { dragging = false; cv.style.cursor = "grab"; };
|
|
266
277
|
const wheel = (e) => {
|
|
278
|
+
if (this.flyMode) {
|
|
279
|
+
e.preventDefault();
|
|
280
|
+
// fly: the wheel moves the camera along its own gaze
|
|
281
|
+
const d = -e.deltaY * this.flySpeed * 0.004;
|
|
282
|
+
this.cam.target = add(this.cam.target, scale(this.fw, d));
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
267
285
|
if (!e.ctrlKey && !e.metaKey)
|
|
268
286
|
return;
|
|
269
287
|
e.preventDefault();
|
|
270
288
|
this.cam.distT = clamp(this.cam.distT + e.deltaY * 0.6, 120, 2200);
|
|
271
289
|
};
|
|
290
|
+
const kdown = (e) => { if (this.flyMode)
|
|
291
|
+
this.keys.add(e.key.toLowerCase()); };
|
|
292
|
+
const kup = (e) => { this.keys.delete(e.key.toLowerCase()); };
|
|
293
|
+
if (this.flyMode) {
|
|
294
|
+
window.addEventListener("keydown", kdown);
|
|
295
|
+
window.addEventListener("keyup", kup);
|
|
296
|
+
this.cleanup.push(() => { window.removeEventListener("keydown", kdown); window.removeEventListener("keyup", kup); });
|
|
297
|
+
}
|
|
272
298
|
cv.addEventListener("pointerdown", down);
|
|
273
299
|
cv.addEventListener("pointermove", move);
|
|
274
300
|
cv.addEventListener("pointerup", upFn);
|
|
@@ -462,13 +488,26 @@ export class World {
|
|
|
462
488
|
overlay2d(cb) { cb(this.og, this); }
|
|
463
489
|
// ── camera + CPU projection for pick/labels ──
|
|
464
490
|
setupCamera(t, dt) {
|
|
491
|
+
if (this.flyMode && this.keys.size && dt > 0) { // W13: keys fly the camera
|
|
492
|
+
const sp = this.flySpeed * (this.keys.has("shift") ? 3 : 1) * dt;
|
|
493
|
+
let m = v3();
|
|
494
|
+
if (this.keys.has("w"))
|
|
495
|
+
m = add(m, scale(this.fw, sp));
|
|
496
|
+
if (this.keys.has("s"))
|
|
497
|
+
m = add(m, scale(this.fw, -sp));
|
|
498
|
+
if (this.keys.has("a"))
|
|
499
|
+
m = add(m, scale(this.rt, -sp));
|
|
500
|
+
if (this.keys.has("d"))
|
|
501
|
+
m = add(m, scale(this.rt, sp));
|
|
502
|
+
this.cam.target = add(this.cam.target, m);
|
|
503
|
+
}
|
|
465
504
|
this.mx += (this.mxT - this.mx) * Math.min(1, dt * 3);
|
|
466
505
|
this.my += (this.myT - this.my) * Math.min(1, dt * 3);
|
|
467
506
|
this.cam.yawUser += (this.yawUserT - this.cam.yawUser) * Math.min(1, dt * 5);
|
|
468
507
|
this.cam.pitchUser += (this.pitchUserT - this.cam.pitchUser) * Math.min(1, dt * 5);
|
|
469
508
|
this.cam.dist += (this.cam.distT - this.cam.dist) * Math.min(1, dt * 4);
|
|
470
509
|
const yaw = this.cam.yawBase + t * this.opts.drift + this.cam.yawUser + this.mx * this.opts.parallax;
|
|
471
|
-
const pitch = clamp(this.cam.pitch + this.cam.pitchUser + this.my * this.opts.parallax * 0.5,
|
|
510
|
+
const pitch = clamp(this.cam.pitch + this.cam.pitchUser + this.my * this.opts.parallax * 0.5, this.pitchMin, this.pitchMax);
|
|
472
511
|
const cp = Math.cos(pitch), sp = Math.sin(pitch);
|
|
473
512
|
this.cx = add(this.cam.target, scale(v3(cp * Math.cos(yaw), sp, cp * Math.sin(yaw)), this.cam.dist));
|
|
474
513
|
this.fw = norm(sub(this.cam.target, this.cx));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chromatic-coherence/generative-engine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "THE THIRD ENGINE — a zero-dependency WebGL2 graphics engine grown from generative-charts-3d: HDR + bloom + SSAO post chain, hardware-PCF shadow maps, a geometry stdlib, ribbon strokes, group transforms and morph targets. The charts API rides on top unchanged.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|