@es3d/es3d 1.0.0 → 1.0.2
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/LICENSE +201 -201
- package/README.md +95 -86
- package/docs/SPEC.md +426 -417
- package/package.json +1 -1
- package/scripts/es3d-cli.mjs +390 -377
- package/src/cache/geometry-store.js +392 -392
- package/src/cache/mesh-bundle.js +123 -123
- package/src/cache/sha256.js +73 -73
- package/src/format/ast.js +238 -238
- package/src/format/colors.js +93 -93
- package/src/format/compact-parser.js +171 -171
- package/src/format/compact-tokenizer.js +165 -165
- package/src/format/errors.js +247 -247
- package/src/format/json.js +55 -55
- package/src/format/limits.js +14 -14
- package/src/format/parse.js +132 -92
- package/src/format/schema.js +617 -617
- package/src/format/serializer.js +333 -333
- package/src/format/validator.js +330 -330
- package/src/format/value-error.js +12 -12
- package/src/format/value-format.js +314 -314
- package/src/format/values.js +459 -459
- package/src/format/xml-parser.js +136 -136
- package/src/format/xml-tokenizer.js +237 -237
- package/src/geometry/contour.js +86 -86
- package/src/geometry/extrude.js +175 -175
- package/src/geometry/gear.js +85 -85
- package/src/geometry/geometry-cache.js +159 -159
- package/src/geometry/lod-error.js +178 -178
- package/src/geometry/mesh.js +458 -458
- package/src/geometry/primitives.js +299 -299
- package/src/geometry/registry.js +645 -645
- package/src/geometry/revolve.js +136 -136
- package/src/geometry/sweep.js +441 -441
- package/src/index.js +47 -47
- package/src/io/compression.js +67 -67
- package/src/io/convert.js +236 -236
- package/src/io/download.js +13 -13
- package/src/io/external-scene.js +127 -127
- package/src/io/file-loader.js +28 -28
- package/src/io/gltf-pack.js +1461 -0
- package/src/io/gltf.js +630 -630
- package/src/io/mesh-import.js +104 -104
- package/src/io/obj.js +352 -352
- package/src/io/step-brep.js +439 -439
- package/src/io/step-exact.js +1149 -1149
- package/src/io/step.js +1418 -1418
- package/src/io/stl.js +193 -193
- package/src/io/svg-import.js +787 -787
- package/src/material/materials.js +154 -154
- package/src/math/mat4.js +475 -475
- package/src/math/random.js +30 -30
- package/src/math/trig.js +65 -65
- package/src/math/vec3.js +81 -81
- package/src/optimize/optimizer.js +604 -579
- package/src/path/path-flatten.js +322 -322
- package/src/path/path-parser.js +332 -332
- package/src/path/shapes.js +129 -129
- package/src/path/triangulate.js +517 -517
- package/src/pipeline.js +74 -74
- package/src/render/camera.js +168 -168
- package/src/render/frame-builder.js +362 -362
- package/src/render/geometry-pool.js +149 -149
- package/src/render/lighting.js +149 -149
- package/src/render/orbit-controls.js +237 -237
- package/src/render/renderer.js +258 -249
- package/src/render/scroll-timeline.js +104 -104
- package/src/render/shaders/glsl.js +285 -285
- package/src/render/shaders/wgsl.js +252 -252
- package/src/render/stage.js +365 -352
- package/src/render/texture-cache.js +40 -40
- package/src/render/textures.js +223 -223
- package/src/render/webgl2/webgl2-backend.js +586 -532
- package/src/render/webgpu/webgpu-backend.js +482 -480
- package/src/scene/flatten.js +754 -754
- package/src/scene/picking.js +161 -161
- package/src/scene/scene-graph.js +320 -320
- package/src/transform/transform.js +211 -211
- package/src/wasm/kernels-binary.js +3 -3
- package/src/wasm/kernels.js +385 -385
|
@@ -1,154 +1,154 @@
|
|
|
1
|
-
// Material system: a deliberately small metallic/roughness model.
|
|
2
|
-
//
|
|
3
|
-
// <material> elements define named parameter sets. Shapes reference them by
|
|
4
|
-
// id, and `material` / `color` are inherited down the tree like SVG's fill.
|
|
5
|
-
// The effective material of a shape is (inherited material, inherited color
|
|
6
|
-
// override); identical parameter sets are deduplicated into one Material, so
|
|
7
|
-
// the renderer binds each distinct material exactly once.
|
|
8
|
-
|
|
9
|
-
import { colorToLinear, colorToHex } from '../format/colors.js';
|
|
10
|
-
import { valueOf } from '../format/schema.js';
|
|
11
|
-
|
|
12
|
-
export const DEFAULT_MATERIAL_PARAMS = {
|
|
13
|
-
color: [0.8, 0.8, 0.8, 1],
|
|
14
|
-
metallic: 0,
|
|
15
|
-
roughness: 0.5,
|
|
16
|
-
opacity: 1,
|
|
17
|
-
emissive: [0, 0, 0, 1],
|
|
18
|
-
emissiveIntensity: 1,
|
|
19
|
-
map: null,
|
|
20
|
-
normalMap: null,
|
|
21
|
-
normalScale: 1,
|
|
22
|
-
occlusionMap: null,
|
|
23
|
-
occlusionStrength: 1,
|
|
24
|
-
metallicRoughnessMap: null,
|
|
25
|
-
emissiveMap: null,
|
|
26
|
-
alphaMode: 'auto',
|
|
27
|
-
alphaCutoff: 0.5,
|
|
28
|
-
uvScale: [1, 1],
|
|
29
|
-
doubleSided: false,
|
|
30
|
-
unlit: false,
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export class Material {
|
|
34
|
-
constructor(params, index, name = null) {
|
|
35
|
-
this.index = index;
|
|
36
|
-
this.name = name;
|
|
37
|
-
this.params = params;
|
|
38
|
-
this.baseColor = colorToLinear(params.color);
|
|
39
|
-
this.baseColorSrgb = params.color;
|
|
40
|
-
this.metallic = params.metallic;
|
|
41
|
-
this.roughness = params.roughness;
|
|
42
|
-
this.opacity = params.opacity * params.color[3];
|
|
43
|
-
const e = colorToLinear(params.emissive);
|
|
44
|
-
this.emissive = [e[0] * params.emissiveIntensity, e[1] * params.emissiveIntensity, e[2] * params.emissiveIntensity];
|
|
45
|
-
this.map = params.map;
|
|
46
|
-
this.normalMap = params.normalMap;
|
|
47
|
-
this.normalScale = params.normalScale;
|
|
48
|
-
this.occlusionMap = params.occlusionMap;
|
|
49
|
-
this.occlusionStrength = params.occlusionStrength;
|
|
50
|
-
this.metallicRoughnessMap = params.metallicRoughnessMap;
|
|
51
|
-
this.emissiveMap = params.emissiveMap;
|
|
52
|
-
this.alphaCutoff = params.alphaCutoff;
|
|
53
|
-
const coverage = params.opacity * params.color[3];
|
|
54
|
-
const requested = params.alphaMode || 'auto';
|
|
55
|
-
this.alphaMode = requested === 'auto' ? (coverage < 0.999 ? 'blend' : 'opaque') : requested;
|
|
56
|
-
this.uvScale = params.uvScale;
|
|
57
|
-
this.doubleSided = params.doubleSided;
|
|
58
|
-
this.unlit = params.unlit;
|
|
59
|
-
this.key = materialKey(params);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
get transparent() {
|
|
63
|
-
return this.alphaMode === 'blend' && this.opacity < 0.999;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export function materialKey(p) {
|
|
68
|
-
return [
|
|
69
|
-
colorToHex(p.color),
|
|
70
|
-
p.metallic,
|
|
71
|
-
p.roughness,
|
|
72
|
-
p.opacity,
|
|
73
|
-
colorToHex(p.emissive),
|
|
74
|
-
p.emissiveIntensity,
|
|
75
|
-
p.map ? p.map.key : '',
|
|
76
|
-
p.normalMap ? p.normalMap.key : '',
|
|
77
|
-
p.normalScale,
|
|
78
|
-
p.occlusionMap ? p.occlusionMap.key : '',
|
|
79
|
-
p.occlusionStrength,
|
|
80
|
-
p.metallicRoughnessMap ? p.metallicRoughnessMap.key : '',
|
|
81
|
-
p.emissiveMap ? p.emissiveMap.key : '',
|
|
82
|
-
p.alphaMode,
|
|
83
|
-
p.alphaCutoff,
|
|
84
|
-
p.uvScale.join(','),
|
|
85
|
-
p.doubleSided ? 1 : 0,
|
|
86
|
-
p.unlit ? 1 : 0,
|
|
87
|
-
].join('|');
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/** Parameters of a <material> element with schema defaults applied. */
|
|
91
|
-
export function paramsFromElement(el) {
|
|
92
|
-
const p = {};
|
|
93
|
-
for (const k of Object.keys(DEFAULT_MATERIAL_PARAMS)) {
|
|
94
|
-
const v = valueOf(el, k);
|
|
95
|
-
p[k] = v === undefined ? DEFAULT_MATERIAL_PARAMS[k] : v;
|
|
96
|
-
}
|
|
97
|
-
return p;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export class MaterialTable {
|
|
101
|
-
constructor() {
|
|
102
|
-
/** @type {Material[]} */
|
|
103
|
-
this.list = [];
|
|
104
|
-
this.byKey = new Map();
|
|
105
|
-
this.defs = new Map(); // material id -> params
|
|
106
|
-
this.resolved = new Map(); // "id|color" -> index
|
|
107
|
-
this.fast = new Map(); // id -> Map(color array object -> index), identity cache for hot loops
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
define(id, params) {
|
|
111
|
-
this.defs.set(id, params);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
intern(params, name) {
|
|
115
|
-
const key = materialKey(params);
|
|
116
|
-
let idx = this.byKey.get(key);
|
|
117
|
-
if (idx === undefined) {
|
|
118
|
-
idx = this.list.length;
|
|
119
|
-
this.list.push(new Material(params, idx, name));
|
|
120
|
-
this.byKey.set(key, idx);
|
|
121
|
-
}
|
|
122
|
-
return idx;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Effective material index for an inherited (material id, color override) pair.
|
|
127
|
-
* @param {string|null} id
|
|
128
|
-
* @param {number[]|null} color sRGB rgba
|
|
129
|
-
*/
|
|
130
|
-
resolve(id, color) {
|
|
131
|
-
let byColor = this.fast.get(id);
|
|
132
|
-
if (byColor === undefined) {
|
|
133
|
-
byColor = new Map();
|
|
134
|
-
this.fast.set(id, byColor);
|
|
135
|
-
}
|
|
136
|
-
let fast = byColor.get(color);
|
|
137
|
-
if (fast !== undefined) return fast;
|
|
138
|
-
fast = this.resolveSlow(id, color);
|
|
139
|
-
byColor.set(color, fast);
|
|
140
|
-
return fast;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
resolveSlow(id, color) {
|
|
144
|
-
const ck = color ? colorToHex(color) : '';
|
|
145
|
-
const rk = (id || '') + '|' + ck;
|
|
146
|
-
let idx = this.resolved.get(rk);
|
|
147
|
-
if (idx !== undefined) return idx;
|
|
148
|
-
const base = (id && this.defs.get(id)) || DEFAULT_MATERIAL_PARAMS;
|
|
149
|
-
const params = color ? { ...base, color } : base;
|
|
150
|
-
idx = this.intern(params, id || (color ? ck : 'default'));
|
|
151
|
-
this.resolved.set(rk, idx);
|
|
152
|
-
return idx;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
1
|
+
// Material system: a deliberately small metallic/roughness model.
|
|
2
|
+
//
|
|
3
|
+
// <material> elements define named parameter sets. Shapes reference them by
|
|
4
|
+
// id, and `material` / `color` are inherited down the tree like SVG's fill.
|
|
5
|
+
// The effective material of a shape is (inherited material, inherited color
|
|
6
|
+
// override); identical parameter sets are deduplicated into one Material, so
|
|
7
|
+
// the renderer binds each distinct material exactly once.
|
|
8
|
+
|
|
9
|
+
import { colorToLinear, colorToHex } from '../format/colors.js';
|
|
10
|
+
import { valueOf } from '../format/schema.js';
|
|
11
|
+
|
|
12
|
+
export const DEFAULT_MATERIAL_PARAMS = {
|
|
13
|
+
color: [0.8, 0.8, 0.8, 1],
|
|
14
|
+
metallic: 0,
|
|
15
|
+
roughness: 0.5,
|
|
16
|
+
opacity: 1,
|
|
17
|
+
emissive: [0, 0, 0, 1],
|
|
18
|
+
emissiveIntensity: 1,
|
|
19
|
+
map: null,
|
|
20
|
+
normalMap: null,
|
|
21
|
+
normalScale: 1,
|
|
22
|
+
occlusionMap: null,
|
|
23
|
+
occlusionStrength: 1,
|
|
24
|
+
metallicRoughnessMap: null,
|
|
25
|
+
emissiveMap: null,
|
|
26
|
+
alphaMode: 'auto',
|
|
27
|
+
alphaCutoff: 0.5,
|
|
28
|
+
uvScale: [1, 1],
|
|
29
|
+
doubleSided: false,
|
|
30
|
+
unlit: false,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export class Material {
|
|
34
|
+
constructor(params, index, name = null) {
|
|
35
|
+
this.index = index;
|
|
36
|
+
this.name = name;
|
|
37
|
+
this.params = params;
|
|
38
|
+
this.baseColor = colorToLinear(params.color);
|
|
39
|
+
this.baseColorSrgb = params.color;
|
|
40
|
+
this.metallic = params.metallic;
|
|
41
|
+
this.roughness = params.roughness;
|
|
42
|
+
this.opacity = params.opacity * params.color[3];
|
|
43
|
+
const e = colorToLinear(params.emissive);
|
|
44
|
+
this.emissive = [e[0] * params.emissiveIntensity, e[1] * params.emissiveIntensity, e[2] * params.emissiveIntensity];
|
|
45
|
+
this.map = params.map;
|
|
46
|
+
this.normalMap = params.normalMap;
|
|
47
|
+
this.normalScale = params.normalScale;
|
|
48
|
+
this.occlusionMap = params.occlusionMap;
|
|
49
|
+
this.occlusionStrength = params.occlusionStrength;
|
|
50
|
+
this.metallicRoughnessMap = params.metallicRoughnessMap;
|
|
51
|
+
this.emissiveMap = params.emissiveMap;
|
|
52
|
+
this.alphaCutoff = params.alphaCutoff;
|
|
53
|
+
const coverage = params.opacity * params.color[3];
|
|
54
|
+
const requested = params.alphaMode || 'auto';
|
|
55
|
+
this.alphaMode = requested === 'auto' ? (coverage < 0.999 ? 'blend' : 'opaque') : requested;
|
|
56
|
+
this.uvScale = params.uvScale;
|
|
57
|
+
this.doubleSided = params.doubleSided;
|
|
58
|
+
this.unlit = params.unlit;
|
|
59
|
+
this.key = materialKey(params);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get transparent() {
|
|
63
|
+
return this.alphaMode === 'blend' && this.opacity < 0.999;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function materialKey(p) {
|
|
68
|
+
return [
|
|
69
|
+
colorToHex(p.color),
|
|
70
|
+
p.metallic,
|
|
71
|
+
p.roughness,
|
|
72
|
+
p.opacity,
|
|
73
|
+
colorToHex(p.emissive),
|
|
74
|
+
p.emissiveIntensity,
|
|
75
|
+
p.map ? p.map.key : '',
|
|
76
|
+
p.normalMap ? p.normalMap.key : '',
|
|
77
|
+
p.normalScale,
|
|
78
|
+
p.occlusionMap ? p.occlusionMap.key : '',
|
|
79
|
+
p.occlusionStrength,
|
|
80
|
+
p.metallicRoughnessMap ? p.metallicRoughnessMap.key : '',
|
|
81
|
+
p.emissiveMap ? p.emissiveMap.key : '',
|
|
82
|
+
p.alphaMode,
|
|
83
|
+
p.alphaCutoff,
|
|
84
|
+
p.uvScale.join(','),
|
|
85
|
+
p.doubleSided ? 1 : 0,
|
|
86
|
+
p.unlit ? 1 : 0,
|
|
87
|
+
].join('|');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Parameters of a <material> element with schema defaults applied. */
|
|
91
|
+
export function paramsFromElement(el) {
|
|
92
|
+
const p = {};
|
|
93
|
+
for (const k of Object.keys(DEFAULT_MATERIAL_PARAMS)) {
|
|
94
|
+
const v = valueOf(el, k);
|
|
95
|
+
p[k] = v === undefined ? DEFAULT_MATERIAL_PARAMS[k] : v;
|
|
96
|
+
}
|
|
97
|
+
return p;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export class MaterialTable {
|
|
101
|
+
constructor() {
|
|
102
|
+
/** @type {Material[]} */
|
|
103
|
+
this.list = [];
|
|
104
|
+
this.byKey = new Map();
|
|
105
|
+
this.defs = new Map(); // material id -> params
|
|
106
|
+
this.resolved = new Map(); // "id|color" -> index
|
|
107
|
+
this.fast = new Map(); // id -> Map(color array object -> index), identity cache for hot loops
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
define(id, params) {
|
|
111
|
+
this.defs.set(id, params);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
intern(params, name) {
|
|
115
|
+
const key = materialKey(params);
|
|
116
|
+
let idx = this.byKey.get(key);
|
|
117
|
+
if (idx === undefined) {
|
|
118
|
+
idx = this.list.length;
|
|
119
|
+
this.list.push(new Material(params, idx, name));
|
|
120
|
+
this.byKey.set(key, idx);
|
|
121
|
+
}
|
|
122
|
+
return idx;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Effective material index for an inherited (material id, color override) pair.
|
|
127
|
+
* @param {string|null} id
|
|
128
|
+
* @param {number[]|null} color sRGB rgba
|
|
129
|
+
*/
|
|
130
|
+
resolve(id, color) {
|
|
131
|
+
let byColor = this.fast.get(id);
|
|
132
|
+
if (byColor === undefined) {
|
|
133
|
+
byColor = new Map();
|
|
134
|
+
this.fast.set(id, byColor);
|
|
135
|
+
}
|
|
136
|
+
let fast = byColor.get(color);
|
|
137
|
+
if (fast !== undefined) return fast;
|
|
138
|
+
fast = this.resolveSlow(id, color);
|
|
139
|
+
byColor.set(color, fast);
|
|
140
|
+
return fast;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
resolveSlow(id, color) {
|
|
144
|
+
const ck = color ? colorToHex(color) : '';
|
|
145
|
+
const rk = (id || '') + '|' + ck;
|
|
146
|
+
let idx = this.resolved.get(rk);
|
|
147
|
+
if (idx !== undefined) return idx;
|
|
148
|
+
const base = (id && this.defs.get(id)) || DEFAULT_MATERIAL_PARAMS;
|
|
149
|
+
const params = color ? { ...base, color } : base;
|
|
150
|
+
idx = this.intern(params, id || (color ? ck : 'default'));
|
|
151
|
+
this.resolved.set(rk, idx);
|
|
152
|
+
return idx;
|
|
153
|
+
}
|
|
154
|
+
}
|