@driftengine/core 4.7.3 → 4.7.4
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/CHANGELOG.json +26 -0
- package/dist/geometry/meshBuilder.js +3 -2
- package/dist/math/exact.js +3 -3
- package/dist/render/mesh.js +0 -2
- package/dist/render/plumeRenderer.js +0 -29
- package/dist/scene/node.js +1 -1
- package/package.json +6 -6
- package/src/geometry/meshBuilder.ts +3 -2
- package/src/math/exact.ts +3 -3
- package/src/render/backend/webgpu/linePass.ts +0 -1
- package/src/render/mesh.ts +0 -2
- package/src/render/plumeRenderer.ts +0 -30
- package/src/scene/node.ts +1 -1
package/CHANGELOG.json
CHANGED
|
@@ -1,4 +1,30 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "4.7.4",
|
|
4
|
+
"date": "2026-10-02",
|
|
5
|
+
"entries": [
|
|
6
|
+
{
|
|
7
|
+
"kind": "fixed",
|
|
8
|
+
"short": "A component's declared field values fill every field an entity is not given: an add with some fields, a prefab that leaves one out, a script's instantiate, a save from before the field.",
|
|
9
|
+
"text": "**`driftscript` moves to 1.14.0**, whose compiler now carries the value each component field was declared with (`seed: u32 = 7`). Before, the value was parsed and dropped, so every entity started at zero and nothing said so. A component type has `defaults`, and `defineComponent(schema, defaults)` refuses one that names no field or does not fit its column. The store fills an omitted field from them, so `world.add` with some of the fields, a prefab that leaves one out and a script's `ecs.instantiate` all start at the declared values; a `null` given for an optional field is still its absence. `deserializeWorld` gives a field the saved scene does not have its declared value, so a save loads across an added field with what the component says. DriftScript 1.14.0 also type-checks a component's defaults, which nothing did before, and refuses one that is computed (DS0275)."
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"kind": "added",
|
|
13
|
+
"short": "The manual gains XR, and a Systems section that opens with saves and preferences, each chapter built on an example that runs live and keeps its behaviour in DriftScript.",
|
|
14
|
+
"text": "**XR** covers asking a browser what it can present, entering a session, and reading the head, the controllers and a tracked hand, from TypeScript and from `drift/xr`, through the simulated runtime the package tests against. It says plainly that the renderer cannot draw into a headset yet, and the xr README's sample, which called `renderer.setViewport` and `renderer.draw`, now stops where the renderer does. **Saves and preferences** covers the synchronous store and why it is synchronous, preferences checked field by field, `RemoteSaveStore` over a backend that answers later, `serializeWorld` and `deserializeWorld` with a save read back across an added field, and `drift/persistence`, around a garden bed that saves to a server the page can make slow or take offline."
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"kind": "fixed",
|
|
18
|
+
"short": "Four examples behave on any machine: the vehicle starts clear of the cones, readouts fit a small frame, chemistry holds 60 fps, and DriftLight starts smoothly on a slow CPU.",
|
|
19
|
+
"text": "The vehicle spawned overlapping a cone and came to rest on it with two wheels in the air; it starts on the ramp's line. A readout is sized to the frame it is in, so the manual's 768 by 432 frames no longer cut lines off, and it can keep clear of a panel. Chemistry stepped a quarter second sixty times a second and drew 3 fps once smoke filled the air; it steps a sixteenth, about four times the clock, at 60 fps, and `stage.run` takes loop options so a slow frame catches up two ticks at most. DriftLight baked 64 bricks a frame and ran at 1 to 8 fps for its first ten seconds on a CPU three times slower; it bakes for four milliseconds a frame and stays above 18. Under that throttling 44 of the 46 examples hold 57 to 60 fps, and chemistry 16."
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"kind": "changed",
|
|
23
|
+
"short": "The repository lints without a warning: oxlint's 170 are fixed, one of them a test that divided its fallback where it meant to check a length.",
|
|
24
|
+
"text": "Unused imports, constants, functions, variables and parameters are gone, products by zero are written as the terms that remain, and optional chains in tests stay optional to the end. Inside the native host, the window, the document and the canvas take their `on<type>` attributes from a base class that declares them, in place of an interface merged into each class, and fdlibm's constants are spelled with the digits a double holds, each parsing to the same value."
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
},
|
|
2
28
|
{
|
|
3
29
|
"version": "4.7.3",
|
|
4
30
|
"date": "2026-10-02",
|
|
@@ -812,8 +812,9 @@ export class MeshBuilder {
|
|
|
812
812
|
// later one is transported from it, so the choice never shows.
|
|
813
813
|
const ax = Math.abs(tx) < 0.9 ? 1 : 0;
|
|
814
814
|
const ay = Math.abs(tx) < 0.9 ? 0 : 1;
|
|
815
|
-
|
|
816
|
-
|
|
815
|
+
// (ax, ay, 0) x tangent, with the terms the zero removes left out.
|
|
816
|
+
ux = ay * tz;
|
|
817
|
+
uy = -ax * tz;
|
|
817
818
|
uz = ax * ty - ay * tx;
|
|
818
819
|
seeded = true;
|
|
819
820
|
}
|
package/dist/math/exact.js
CHANGED
|
@@ -66,14 +66,14 @@ const HALF_PI = 1.5707963267948966;
|
|
|
66
66
|
const PI = 3.141592653589793;
|
|
67
67
|
/* fdlibm's `__kernel_sin` coefficients. */
|
|
68
68
|
const S1 = -1.6666666666666632e-1;
|
|
69
|
-
const S2 = 8.
|
|
69
|
+
const S2 = 8.33333333332249e-3;
|
|
70
70
|
const S3 = -1.984126982985795e-4;
|
|
71
71
|
const S4 = 2.7557313707070068e-6;
|
|
72
72
|
const S5 = -2.5050760253406863e-8;
|
|
73
73
|
const S6 = 1.5896909952115501e-10;
|
|
74
74
|
/* fdlibm's `__kernel_cos` coefficients. */
|
|
75
75
|
const C1 = 4.1666666666666602e-2;
|
|
76
|
-
const C2 = -1.
|
|
76
|
+
const C2 = -1.388888888887411e-3;
|
|
77
77
|
const C3 = 2.480158728947673e-5;
|
|
78
78
|
const C4 = -2.7557314351390663e-7;
|
|
79
79
|
const C5 = 2.0875723212981748e-9;
|
|
@@ -273,7 +273,7 @@ export function exactLog(x) {
|
|
|
273
273
|
/* |f| < 2^-20: two terms of the series are the whole answer. */
|
|
274
274
|
if (f === 0)
|
|
275
275
|
return k === 0 ? 0 : k * LN2_HI + k * LN2_LO;
|
|
276
|
-
const r = f * f * (0.5 - 0.
|
|
276
|
+
const r = f * f * (0.5 - 0.3333333333333333 * f);
|
|
277
277
|
return k === 0 ? f - r : k * LN2_HI - (r - k * LN2_LO - f);
|
|
278
278
|
}
|
|
279
279
|
const s = f / (2 + f);
|
package/dist/render/mesh.js
CHANGED
|
@@ -23,8 +23,6 @@ import { validateMeshData } from '@driftengine/drft';
|
|
|
23
23
|
* well. Both halves are fixed — `flat.ts` normalises the lobe, and this is the width that
|
|
24
24
|
* actually matches.
|
|
25
25
|
*/
|
|
26
|
-
/* The engine's fixed lobe, stated once in `vertexDefaults.ts` so both backends read one number. */
|
|
27
|
-
const DEFAULT_ROUGHNESS = ABSENT_ATTRIBUTE['roughness']?.[0] ?? 0.4277;
|
|
28
26
|
/** Attribute locations are fixed engine-wide (`layout(location = n)` in GLSL). */
|
|
29
27
|
const ATTR_POSITION = 0;
|
|
30
28
|
const ATTR_NORMAL = 1;
|
|
@@ -3,37 +3,8 @@ import { compileProgram, uniformLocations } from './shader.js';
|
|
|
3
3
|
import { bindAtmosphere } from './atmosphere.js';
|
|
4
4
|
import { plumeShaders } from './plumeMaterial.js';
|
|
5
5
|
import { buildPlumeGeometry } from './plumeGeometry.js';
|
|
6
|
-
/**
|
|
7
|
-
* Blades in each plume's cross, and the vertices that costs.
|
|
8
|
-
*
|
|
9
|
-
* **Two, crossed at 90°, instead of one card turned to face the viewer.** A single
|
|
10
|
-
* billboard has no three-dimensional structure to see: orbiting a fire showed the
|
|
11
|
-
* identical silhouette from every angle, because every card shared one camera-derived
|
|
12
|
-
* axis and the whole plume swivelled as a sheet. Reported twice: the fire did not read
|
|
13
|
-
* as three-dimensional, it read as something that moved with the camera — and after a
|
|
14
|
-
* first attempt that only *leaned* edge-on cards toward the viewer, it still did,
|
|
15
|
-
* correctly, because leaning still rotates whichever cards are edge-on, so the ensemble
|
|
16
|
-
* still tracks the viewer.
|
|
17
|
-
*
|
|
18
|
-
* A cross cannot track anything: both blades are fixed in world space, so turning
|
|
19
|
-
* around a fire genuinely brings one broadside as the other goes edge-on, which is
|
|
20
|
-
* the parallax a volume has. It also removes the reason billboarding existed — a
|
|
21
|
-
* blade going edge-on no longer vanishes, because its partner is square-on at that
|
|
22
|
-
* exact moment.
|
|
23
|
-
*
|
|
24
|
-
* Two rather than three because the plumes blend additively and are drawn in
|
|
25
|
-
* quantity: the third blade costs 50% more geometry for a difference the eye does not
|
|
26
|
-
* separate at the sizes these are drawn.
|
|
27
|
-
*/
|
|
28
|
-
const BLADES = 2;
|
|
29
6
|
/* The shared count, so both backends step a plume's vertices the same way. */
|
|
30
7
|
const VERTS_PER_PLUME = PLUME_VERTS;
|
|
31
|
-
const CORNERS = [
|
|
32
|
-
[-1, -1],
|
|
33
|
-
[1, -1],
|
|
34
|
-
[1, 1],
|
|
35
|
-
[-1, 1],
|
|
36
|
-
];
|
|
37
8
|
export class PlumeRenderer {
|
|
38
9
|
program;
|
|
39
10
|
uniforms;
|
package/dist/scene/node.js
CHANGED
|
@@ -122,7 +122,7 @@ export class SceneNode {
|
|
|
122
122
|
attachChild(child) {
|
|
123
123
|
if (child === this)
|
|
124
124
|
throw new Error('SceneNode: a node cannot be its own child (cycle)');
|
|
125
|
-
for (let at = this; at !== null; at = at.parent) {
|
|
125
|
+
for (let at = this.parent; at !== null; at = at.parent) {
|
|
126
126
|
if (at === child)
|
|
127
127
|
throw new Error('SceneNode: that would make a cycle');
|
|
128
128
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@driftengine/core",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.4",
|
|
4
4
|
"description": "The runtime of DriftEngine, a WebGPU game engine with a WebGL2 fallback: renderer, loop, input, cameras, scene graph and physics",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
],
|
|
30
30
|
"sideEffects": false,
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@driftengine/drft": "4.7.
|
|
33
|
-
"@driftengine/physics": "4.7.
|
|
32
|
+
"@driftengine/drft": "4.7.4",
|
|
33
|
+
"@driftengine/physics": "4.7.4",
|
|
34
34
|
"gl-matrix": "^3.4.3"
|
|
35
35
|
},
|
|
36
36
|
"author": "Drift Technologies",
|
|
@@ -67,8 +67,8 @@
|
|
|
67
67
|
"prepack": "node ../../scripts/build.mjs @driftengine/core"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
|
-
"@driftengine/nav": "4.7.
|
|
71
|
-
"@driftengine/network": "4.7.
|
|
72
|
-
"@driftengine/texture": "4.7.
|
|
70
|
+
"@driftengine/nav": "4.7.4",
|
|
71
|
+
"@driftengine/network": "4.7.4",
|
|
72
|
+
"@driftengine/texture": "4.7.4"
|
|
73
73
|
}
|
|
74
74
|
}
|
|
@@ -969,8 +969,9 @@ export class MeshBuilder {
|
|
|
969
969
|
// later one is transported from it, so the choice never shows.
|
|
970
970
|
const ax = Math.abs(tx) < 0.9 ? 1 : 0;
|
|
971
971
|
const ay = Math.abs(tx) < 0.9 ? 0 : 1;
|
|
972
|
-
|
|
973
|
-
|
|
972
|
+
// (ax, ay, 0) x tangent, with the terms the zero removes left out.
|
|
973
|
+
ux = ay * tz;
|
|
974
|
+
uy = -ax * tz;
|
|
974
975
|
uz = ax * ty - ay * tx;
|
|
975
976
|
seeded = true;
|
|
976
977
|
}
|
package/src/math/exact.ts
CHANGED
|
@@ -69,7 +69,7 @@ const PI = 3.141592653589793;
|
|
|
69
69
|
|
|
70
70
|
/* fdlibm's `__kernel_sin` coefficients. */
|
|
71
71
|
const S1 = -1.6666666666666632e-1;
|
|
72
|
-
const S2 = 8.
|
|
72
|
+
const S2 = 8.33333333332249e-3;
|
|
73
73
|
const S3 = -1.984126982985795e-4;
|
|
74
74
|
const S4 = 2.7557313707070068e-6;
|
|
75
75
|
const S5 = -2.5050760253406863e-8;
|
|
@@ -77,7 +77,7 @@ const S6 = 1.5896909952115501e-10;
|
|
|
77
77
|
|
|
78
78
|
/* fdlibm's `__kernel_cos` coefficients. */
|
|
79
79
|
const C1 = 4.1666666666666602e-2;
|
|
80
|
-
const C2 = -1.
|
|
80
|
+
const C2 = -1.388888888887411e-3;
|
|
81
81
|
const C3 = 2.480158728947673e-5;
|
|
82
82
|
const C4 = -2.7557314351390663e-7;
|
|
83
83
|
const C5 = 2.0875723212981748e-9;
|
|
@@ -286,7 +286,7 @@ export function exactLog(x: number): number {
|
|
|
286
286
|
if ((0x000fffff & (2 + hx)) < 3) {
|
|
287
287
|
/* |f| < 2^-20: two terms of the series are the whole answer. */
|
|
288
288
|
if (f === 0) return k === 0 ? 0 : k * LN2_HI + k * LN2_LO;
|
|
289
|
-
const r = f * f * (0.5 - 0.
|
|
289
|
+
const r = f * f * (0.5 - 0.3333333333333333 * f);
|
|
290
290
|
return k === 0 ? f - r : k * LN2_HI - (r - k * LN2_LO - f);
|
|
291
291
|
}
|
|
292
292
|
const s = f / (2 + f);
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
LINE_VERT_WGSL,
|
|
6
6
|
} from '../../shaders/generated/line.wgsl.ts';
|
|
7
7
|
import { buildSegmentQuads } from '../../segmentQuads.ts';
|
|
8
|
-
import type { LineSegments } from '../../linePoints.ts';
|
|
9
8
|
import type { UniformFields } from './scatterPass.ts';
|
|
10
9
|
import { DEPTH_FORMAT } from './flatPass.ts';
|
|
11
10
|
import type { PipelineCache } from './pipelineCache.ts';
|
package/src/render/mesh.ts
CHANGED
|
@@ -30,8 +30,6 @@ import { validateMeshData } from '@driftengine/drft';
|
|
|
30
30
|
* well. Both halves are fixed — `flat.ts` normalises the lobe, and this is the width that
|
|
31
31
|
* actually matches.
|
|
32
32
|
*/
|
|
33
|
-
/* The engine's fixed lobe, stated once in `vertexDefaults.ts` so both backends read one number. */
|
|
34
|
-
const DEFAULT_ROUGHNESS = ABSENT_ATTRIBUTE['roughness']?.[0] ?? 0.4277;
|
|
35
33
|
|
|
36
34
|
/** Attribute locations are fixed engine-wide (`layout(location = n)` in GLSL). */
|
|
37
35
|
const ATTR_POSITION = 0;
|
|
@@ -62,39 +62,9 @@ export interface PlumeOptions {
|
|
|
62
62
|
tint?: Vec3;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
/**
|
|
66
|
-
* Blades in each plume's cross, and the vertices that costs.
|
|
67
|
-
*
|
|
68
|
-
* **Two, crossed at 90°, instead of one card turned to face the viewer.** A single
|
|
69
|
-
* billboard has no three-dimensional structure to see: orbiting a fire showed the
|
|
70
|
-
* identical silhouette from every angle, because every card shared one camera-derived
|
|
71
|
-
* axis and the whole plume swivelled as a sheet. Reported twice: the fire did not read
|
|
72
|
-
* as three-dimensional, it read as something that moved with the camera — and after a
|
|
73
|
-
* first attempt that only *leaned* edge-on cards toward the viewer, it still did,
|
|
74
|
-
* correctly, because leaning still rotates whichever cards are edge-on, so the ensemble
|
|
75
|
-
* still tracks the viewer.
|
|
76
|
-
*
|
|
77
|
-
* A cross cannot track anything: both blades are fixed in world space, so turning
|
|
78
|
-
* around a fire genuinely brings one broadside as the other goes edge-on, which is
|
|
79
|
-
* the parallax a volume has. It also removes the reason billboarding existed — a
|
|
80
|
-
* blade going edge-on no longer vanishes, because its partner is square-on at that
|
|
81
|
-
* exact moment.
|
|
82
|
-
*
|
|
83
|
-
* Two rather than three because the plumes blend additively and are drawn in
|
|
84
|
-
* quantity: the third blade costs 50% more geometry for a difference the eye does not
|
|
85
|
-
* separate at the sizes these are drawn.
|
|
86
|
-
*/
|
|
87
|
-
const BLADES = 2;
|
|
88
65
|
/* The shared count, so both backends step a plume's vertices the same way. */
|
|
89
66
|
const VERTS_PER_PLUME = PLUME_VERTS;
|
|
90
67
|
|
|
91
|
-
const CORNERS = [
|
|
92
|
-
[-1, -1],
|
|
93
|
-
[1, -1],
|
|
94
|
-
[1, 1],
|
|
95
|
-
[-1, 1],
|
|
96
|
-
] as const;
|
|
97
|
-
|
|
98
68
|
export class PlumeRenderer {
|
|
99
69
|
private readonly program: WebGLProgram;
|
|
100
70
|
private readonly uniforms: Record<string, WebGLUniformLocation>;
|
package/src/scene/node.ts
CHANGED
|
@@ -140,7 +140,7 @@ export class SceneNode {
|
|
|
140
140
|
*/
|
|
141
141
|
attachChild(child: SceneNode): void {
|
|
142
142
|
if (child === this) throw new Error('SceneNode: a node cannot be its own child (cycle)');
|
|
143
|
-
for (let at
|
|
143
|
+
for (let at = this.parent; at !== null; at = at.parent) {
|
|
144
144
|
if (at === child) throw new Error('SceneNode: that would make a cycle');
|
|
145
145
|
}
|
|
146
146
|
if (child.parent === this) return;
|