@jfk-solutions/demo3d-file-format 1.7.0 → 1.9.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 +289 -1
- package/dist/examples/export-embedded-viewer-standalone.html +193 -0
- package/dist/examples/three-render-smoke-standalone.html +4997 -0
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/model.d.ts +20 -3
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +89 -11
- package/dist/model.js.map +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +135 -9
- package/dist/parser.js.map +1 -1
- package/dist/raw3d-animation.d.ts +63 -0
- package/dist/raw3d-animation.d.ts.map +1 -0
- package/dist/raw3d-animation.js +200 -0
- package/dist/raw3d-animation.js.map +1 -0
- package/dist/raw3d-effects.d.ts +66 -0
- package/dist/raw3d-effects.d.ts.map +1 -0
- package/dist/raw3d-effects.js +172 -0
- package/dist/raw3d-effects.js.map +1 -0
- package/dist/raw3d-skinning.d.ts +8 -0
- package/dist/raw3d-skinning.d.ts.map +1 -0
- package/dist/raw3d-skinning.js +37 -0
- package/dist/raw3d-skinning.js.map +1 -0
- package/dist/raw3d.d.ts +84 -4
- package/dist/raw3d.d.ts.map +1 -1
- package/dist/raw3d.js +111 -9
- package/dist/raw3d.js.map +1 -1
- package/dist/rigid-interpolation.d.ts +16 -0
- package/dist/rigid-interpolation.d.ts.map +1 -0
- package/dist/rigid-interpolation.js +52 -0
- package/dist/rigid-interpolation.js.map +1 -0
- package/dist/three/backend.d.ts +13 -0
- package/dist/three/backend.d.ts.map +1 -0
- package/dist/three/backend.js +9 -0
- package/dist/three/backend.js.map +1 -0
- package/dist/three/effects.d.ts +7 -0
- package/dist/three/effects.d.ts.map +1 -0
- package/dist/three/effects.js +127 -0
- package/dist/three/effects.js.map +1 -0
- package/dist/three/index.d.ts +5 -1
- package/dist/three/index.d.ts.map +1 -1
- package/dist/three/index.js +35 -1
- package/dist/three/index.js.map +1 -1
- package/dist/three/native-lighting.d.ts +5 -0
- package/dist/three/native-lighting.d.ts.map +1 -0
- package/dist/three/native-lighting.js +86 -0
- package/dist/three/native-lighting.js.map +1 -0
- package/dist/three/parallax.d.ts +5 -0
- package/dist/three/parallax.d.ts.map +1 -0
- package/dist/three/parallax.js +63 -0
- package/dist/three/parallax.js.map +1 -0
- package/dist/three/presentation.d.ts +31 -0
- package/dist/three/presentation.d.ts.map +1 -0
- package/dist/three/presentation.js +137 -0
- package/dist/three/presentation.js.map +1 -0
- package/dist/three/raw3d.d.ts +27 -0
- package/dist/three/raw3d.d.ts.map +1 -1
- package/dist/three/raw3d.js +536 -25
- package/dist/three/raw3d.js.map +1 -1
- package/dist/three/renderer.d.ts.map +1 -1
- package/dist/three/renderer.js +3 -0
- package/dist/three/renderer.js.map +1 -1
- package/dist/three/skinning.d.ts +11 -0
- package/dist/three/skinning.d.ts.map +1 -0
- package/dist/three/skinning.js +92 -0
- package/dist/three/skinning.js.map +1 -0
- package/dist/three/tsl.d.ts +60 -0
- package/dist/three/tsl.d.ts.map +1 -0
- package/dist/three/tsl.js +3 -0
- package/dist/three/tsl.js.map +1 -0
- package/dist/three/webgpu-native.d.ts +3 -0
- package/dist/three/webgpu-native.d.ts.map +1 -0
- package/dist/three/webgpu-native.js +58 -0
- package/dist/three/webgpu-native.js.map +1 -0
- package/dist/three/webgpu-relief.d.ts +3 -0
- package/dist/three/webgpu-relief.d.ts.map +1 -0
- package/dist/three/webgpu-relief.js +61 -0
- package/dist/three/webgpu-relief.js.map +1 -0
- package/dist/xml.d.ts +4 -1
- package/dist/xml.d.ts.map +1 -1
- package/dist/xml.js +14 -3
- package/dist/xml.js.map +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
Browser-first TypeScript parser and Three.js adapter for Demo3D/Emulate3D
|
|
4
4
|
`.demo3d` project files and render-ready `.raw3d` scene files.
|
|
5
5
|
|
|
6
|
-
The parser accepts an `ArrayBuffer`, `Uint8Array`, or `DataView`, reads the outer
|
|
6
|
+
The parser accepts an `ArrayBuffer`, `Uint8Array`, or `DataView`, reads the outer
|
|
7
|
+
ZIP package, extracts either the traditional nested XML model document or the
|
|
8
|
+
Demo3D 2026 `Model.xml`, and returns a lossless object structure with typed
|
|
9
|
+
helpers for the pieces most useful to rendering adapters. Demo3D 2026 external
|
|
10
|
+
geometry caches (`meshes/map.xml` with `v*.dat`, `i*.dat`, and `s*.dat`
|
|
11
|
+
buffers) are decoded automatically.
|
|
7
12
|
|
|
8
13
|
## Install
|
|
9
14
|
|
|
@@ -25,6 +30,12 @@ console.log(parsed.model.meshes.length);
|
|
|
25
30
|
console.log(parsed.model.visuals.length);
|
|
26
31
|
```
|
|
27
32
|
|
|
33
|
+
Saved project views are available through `parsed.model.views`; the name stored
|
|
34
|
+
in `parsed.model.defaultView` identifies the project's default view. Each view
|
|
35
|
+
contains its Demo3D `position` and `target` vectors. The included Three.js
|
|
36
|
+
viewer exposes these from its **Saved views** menu and opens the default view
|
|
37
|
+
automatically. RAW3D saved views are exposed as `parsed.model.views` as well.
|
|
38
|
+
|
|
28
39
|
RAW3D scenes use a separate, strongly typed API because their `Model.xml`, flat
|
|
29
40
|
node hierarchy, and external vertex/index buffers differ from the editable
|
|
30
41
|
Demo3D project schema:
|
|
@@ -47,6 +58,217 @@ submeshes, and shadow flags.
|
|
|
47
58
|
|
|
48
59
|
Runtime code has no production dependencies and uses browser APIs only. ZIP method `8` entries are decompressed with `DecompressionStream("deflate-raw")`.
|
|
49
60
|
|
|
61
|
+
## RAW3D animation without a renderer
|
|
62
|
+
|
|
63
|
+
The root package has no Three.js dependency. It reads animation channels and
|
|
64
|
+
samples native node state independently of any renderer, UI, or playback clock:
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import { parseRaw3D } from "@jfk-solutions/demo3d-file-format";
|
|
68
|
+
|
|
69
|
+
const parsed = await parseRaw3D(await file.arrayBuffer());
|
|
70
|
+
const animation = parsed.model.animation; // Lazy, cached typed Updates parser.
|
|
71
|
+
console.log(animation.duration, animation.tracks, animation.warnings);
|
|
72
|
+
const states = animation.sample(1.25); // Absolute simulation seconds.
|
|
73
|
+
const node = animation.sampleNode(0, 1.25);
|
|
74
|
+
console.log(node.location, node.quaternion, node.layerIndex);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Supported tracks include position, rotation, scale, own-geometry visibility,
|
|
78
|
+
deletion, parent, mesh, layer, interaction mode, highlight, optimization metadata,
|
|
79
|
+
and material diffuse ARGB, texture offsets/scales, reflectivity, transparency,
|
|
80
|
+
luminosity, normal scale, and point size. Unknown tracks remain available through
|
|
81
|
+
their original XML and produce warnings; their timestamps still contribute to
|
|
82
|
+
the clip duration. Reading metadata does not execute its native behavior.
|
|
83
|
+
Invalid supported tracks fail explicitly. Duplicate key times select the last
|
|
84
|
+
value, and seeking before a first key restores the node's initial state.
|
|
85
|
+
|
|
86
|
+
`Raw3DInterpolationMode` matches the Emulate3D 2026 enum: `Default=0`, `None=1`,
|
|
87
|
+
`Linear=2`, `DualQuaternion=3`. `None` holds the previous key; `Linear` interpolates
|
|
88
|
+
numeric channels, with shortest-path angle interpolation. This library treats
|
|
89
|
+
`Default` as linear. Discrete properties and ARGB colors switch at key times.
|
|
90
|
+
|
|
91
|
+
`DualQuaternion` couples position and orientation using normalized dual-quaternion
|
|
92
|
+
linear blending (DLB). Scale stays separate. `quaternion` and `rotation` describe
|
|
93
|
+
the same sampled orientation in native coordinates. Transform keys are evaluated
|
|
94
|
+
on the union of the node's position/rotation key times. This original implementation
|
|
95
|
+
is derived from the mathematical representation and normalization in
|
|
96
|
+
[Kavan et al., Dual Quaternions for Rigid Transformation Blending (2006)](https://users.cs.utah.edu/~ladislav/kavan06dual/kavan06dual.pdf).
|
|
97
|
+
DLB follows a rigid screw path but is not constant-speed ScLERP. Exact parity
|
|
98
|
+
with Demo3D's interpolation variant/default policy has not yet been established.
|
|
99
|
+
No vendor or paper implementation code is copied.
|
|
100
|
+
|
|
101
|
+
Native node visibility, interpolation mode, highlight, user data, owner,
|
|
102
|
+
decal/billboard flags, material luminosity/offsets/point size, and scene floor,
|
|
103
|
+
lighting, ambient color and quality properties have typed accessors. Unknown XML
|
|
104
|
+
is still retained; these accessors do not imply full native shader, billboard,
|
|
105
|
+
decal, floor, interaction, or scripting behavior.
|
|
106
|
+
|
|
107
|
+
### Optional Three.js playback
|
|
108
|
+
|
|
109
|
+
Only the `/three` entry point binds the sampled state to Three.js objects:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { createRaw3DThreePlayback } from "@jfk-solutions/demo3d-file-format/three";
|
|
113
|
+
|
|
114
|
+
const playback = await createRaw3DThreePlayback(parsed, { three: THREE });
|
|
115
|
+
scene.add(playback.group);
|
|
116
|
+
playback.seek(1.25);
|
|
117
|
+
renderer.render(scene, camera);
|
|
118
|
+
// The application owns its animation clock, play/pause, speed and looping.
|
|
119
|
+
scene.remove(playback.group);
|
|
120
|
+
playback.dispose();
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The binding applies transforms, visibility, deletion, parenting, mesh swaps,
|
|
124
|
+
layer-material fallback, and supported material changes. It preserves explicit
|
|
125
|
+
node materials when a layer changes and isolates animated materials between
|
|
126
|
+
nodes. Structural groups stay enabled when only their own geometry is hidden.
|
|
127
|
+
Retired mesh samples are released, and `dispose()` releases owned GPU resources.
|
|
128
|
+
Playback does not run simulation scripts, physics, or PLC connections. Both
|
|
129
|
+
native bone/weight buffers and baked deforming mesh updates are supported.
|
|
130
|
+
|
|
131
|
+
The demo and generated standalone viewer offer Play/Pause and an absolute-time
|
|
132
|
+
slider for animated RAW3D files. Embedding the original RAW3D retains animation;
|
|
133
|
+
the source-protected Three.js snapshot export remains a static snapshot.
|
|
134
|
+
|
|
135
|
+
### Native effects, surfaces and skinning
|
|
136
|
+
|
|
137
|
+
Use `animation.sampleFrame(time)` for a complete renderer-independent frame:
|
|
138
|
+
`nodes`, `lights`, `buttons`, and `scene`. The same current frame is available as
|
|
139
|
+
`playback.state` after `seek()`. Extended tracks and original XML are exposed by
|
|
140
|
+
`animation.effects.tracks`.
|
|
141
|
+
|
|
142
|
+
- Material `Texture`, `NormalMap`/`NormalTexture` references switch discretely,
|
|
143
|
+
including clearing a texture with a negative index. Referenced archive textures
|
|
144
|
+
are preloaded even when they are only used by later animation keys. Color and
|
|
145
|
+
normal textures are isolated per animated node and restored on backward seeks.
|
|
146
|
+
- Native light channels include `LightType`, `LightEnabled`, `LightMaterial`,
|
|
147
|
+
`LightAR`, `LightAC`, `LightAL`, `LightAQ`, `LightSF`, `LightSIA`, `LightSOA`, and
|
|
148
|
+
`LightCS`. Range, constant/linear/quadratic attenuation, total inner/outer cone
|
|
149
|
+
angles, falloff and shadow flags are applied. WebGL hooks and the TSL node backend implement
|
|
150
|
+
the distance/cone equations described in [Microsoft's Direct3D lighting
|
|
151
|
+
documentation](https://learn.microsoft.com/en-us/windows/win32/direct3d9/attenuation-and-spotlight-factor).
|
|
152
|
+
`evaluateRaw3DLightAttenuation()` exposes the same calculation without Three.js.
|
|
153
|
+
Shadow rendering still requires the host renderer's shadow map to be enabled.
|
|
154
|
+
- `SceneShowDefaultFloor`, `SceneAllowTeleportOnDefaultFloor`,
|
|
155
|
+
`SceneUseDefaultLighting`, and `ALR`/`ALG`/`ALB` update the sampled scene.
|
|
156
|
+
The Three binding provides ambient/default light and a finite floor preview on
|
|
157
|
+
the recorded plane. Teleport permission is metadata; browser navigation is a
|
|
158
|
+
host concern. Host-added lighting remains under host control.
|
|
159
|
+
- Native button visibility and checked-state channels are sampled and displayed
|
|
160
|
+
by the demo. Their original native serializer names `UpdateUIVisible` and
|
|
161
|
+
`UpdateUIChecked`, as well as `UIVisible`/`UIChecked`, are accepted. Displayed
|
|
162
|
+
buttons are read-only; the library does not execute their model actions.
|
|
163
|
+
- Unambiguous `UserData`/`ClientOwner` string keys are sampled as metadata. The
|
|
164
|
+
native serializer joins string arrays with spaces without escaping boundaries.
|
|
165
|
+
A single key may contain spaces; multi-key values with ambiguous boundaries
|
|
166
|
+
remain in XML with `RAW3D_STRING_KEYS_AMBIGUOUS` instead of being guessed.
|
|
167
|
+
- The native `Default`, `FlatText`, and `PointCloud` material shader modes map to
|
|
168
|
+
lit, unlit, and vertex-colored point rendering. Packed ARGB/byte/short vertex
|
|
169
|
+
attributes retain their native strides. RAW3D material `A` is opacity; the
|
|
170
|
+
public `transparency` property is its complement. This corrects older builds
|
|
171
|
+
which inverted partially transparent native materials.
|
|
172
|
+
- Billboards orient their own drawable toward the render camera while leaving
|
|
173
|
+
the node hierarchy intact. Decal flags apply depth bias and suppress depth
|
|
174
|
+
writes on the provided surface geometry; no projection onto an unrelated mesh
|
|
175
|
+
is invented.
|
|
176
|
+
- Mesh `Bones` expose driving scene-node references, bind offsets and native
|
|
177
|
+
skin index/weight buffer references. `decodeRaw3DSkinInfluences()` validates and
|
|
178
|
+
normalizes weights without a renderer. The Three adapter constructs GPU
|
|
179
|
+
`SkinnedMesh`/`Skeleton` bindings for up to four influences per vertex. Larger
|
|
180
|
+
influence sets use CPU skinning with positions, normals and tangents; no
|
|
181
|
+
weights are discarded. Unweighted vertices retain their mesh position.
|
|
182
|
+
|
|
183
|
+
Native channel names, bone fields and shader enums have a checked-in fixture
|
|
184
|
+
generated by the installed Emulate3D 2026 SDK serializer. To regenerate it on
|
|
185
|
+
Windows, run `./scripts/generate-native-feature-fixture.ps1`; other platforms can
|
|
186
|
+
run the tests using the existing fixture without that proprietary SDK.
|
|
187
|
+
Synthetic rigs exercise GPU/CPU deformation, bind offsets and reversible seeks.
|
|
188
|
+
Comparison against a captured native skinned person remains a separate parity
|
|
189
|
+
check; the current Bauhaus recording contains baked human geometry.
|
|
190
|
+
|
|
191
|
+
### Lossless strings and external resources
|
|
192
|
+
|
|
193
|
+
Native string arrays lose their boundaries when values containing spaces are
|
|
194
|
+
joined into a single attribute. Supply authoritative keys from a sidecar through
|
|
195
|
+
the renderer-independent parser option:
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
const parsed = await parseRaw3D(bytes, {
|
|
199
|
+
resolveStringKeys: ({ nodeIndex, property, times, encoded, xml }) => {
|
|
200
|
+
return sidecar.lookup(nodeIndex, property, times); // string[] or undefined
|
|
201
|
+
},
|
|
202
|
+
resolveResource: async path => resources.get(path) // Uint8Array or undefined
|
|
203
|
+
});
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The resolver runs for string tracks and must return one string per timestamp,
|
|
207
|
+
including empty values. Incorrect lengths/types fail explicitly. Archive entries
|
|
208
|
+
take precedence over `resolveResource`; no filesystem/network request is made
|
|
209
|
+
automatically. A library-side extension also accepts `<Values><Value>...</Value>
|
|
210
|
+
...</Values>` children, or `ValueEncoding="json"` with a JSON array in `Value`.
|
|
211
|
+
These extensions are explicit conventions for this reader, not a claim that the
|
|
212
|
+
native serializer emits them. The original XML stays available. Missing
|
|
213
|
+
authoritative data still produces `RAW3D_STRING_KEYS_AMBIGUOUS`; impossible
|
|
214
|
+
boundaries are not guessed.
|
|
215
|
+
|
|
216
|
+
`parsed.model.streamableTextures` exposes native index, ID, name, dimensions,
|
|
217
|
+
path and any archived/resolved image bytes. Material `StreamableTexture` selects
|
|
218
|
+
the corresponding image. For video, a live camera or a recorded frame sequence,
|
|
219
|
+
provide Three.js textures and use asynchronous seeking:
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
const playback = await createRaw3DThreePlayback(parsed, {
|
|
223
|
+
three: THREE,
|
|
224
|
+
resolveStreamTexture: async ({ index, time, source, signal }) => {
|
|
225
|
+
return frames.textureAt(index, time, signal); // Texture or undefined
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
await playback.seekAsync(2.5); // false if superseded by a newer seek
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Resolvers receive clip time, stream metadata and an abort signal. A newer seek,
|
|
232
|
+
synchronous seek, or disposal cancels pending requests; stale responses never
|
|
233
|
+
replace newer imagery. Returned textures remain caller-owned. The player owns
|
|
234
|
+
only its clones. Returning `undefined` restores the archived fallback or clears
|
|
235
|
+
the unavailable frame and reports a warning. A synchronous `seek()` retains the
|
|
236
|
+
currently resolved stream image; use `seekAsync()` for frame-accurate seeking.
|
|
237
|
+
Missing video frames still need an external source; a file reader cannot
|
|
238
|
+
reconstruct imagery that was never recorded. No URL or camera is opened without
|
|
239
|
+
an explicit host resolver.
|
|
240
|
+
|
|
241
|
+
### Relief shading and the node renderer
|
|
242
|
+
|
|
243
|
+
`NormalDepth` drives layered parallax/relief UV ray marching with 32 layers and
|
|
244
|
+
five binary refinements in both the WebGL shader and TSL material paths. Heights
|
|
245
|
+
are read from the normal image's alpha channel by default; select a different
|
|
246
|
+
packed channel with `parallaxHeightChannel: "r" | "g" | "b" | "a"`. Opaque alpha
|
|
247
|
+
represents a flat top surface. Color and normal samples share the relief offset,
|
|
248
|
+
and animated depth updates are reversible. Depth controls texture-coordinate
|
|
249
|
+
displacement; this does not add geometry or alter silhouettes. A normal image
|
|
250
|
+
without height data cannot supply missing surface depth by itself. The height
|
|
251
|
+
packing and scale may need adjustment for a particular native export.
|
|
252
|
+
|
|
253
|
+
The renderer factory automatically registers native point/spot light nodes and
|
|
254
|
+
node materials with `WebGPURenderer`. Native attenuation, range and cone falloff
|
|
255
|
+
are calculated through TSL, which supports both the WebGPU and node-renderer
|
|
256
|
+
WebGL backends. Existing lights and materials outside the native binding keep
|
|
257
|
+
their standard behavior. For a manually constructed renderer, configure it
|
|
258
|
+
before creating RAW3D groups:
|
|
259
|
+
|
|
260
|
+
```ts
|
|
261
|
+
import * as THREE from "three/webgpu";
|
|
262
|
+
import { configureRaw3DWebGPURenderer } from "@jfk-solutions/demo3d-file-format/three";
|
|
263
|
+
await configureRaw3DWebGPURenderer(renderer, THREE);
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Unbundled hosts must map `three/tsl` alongside `three/webgpu` to their matching
|
|
267
|
+
Three.js release. Node rendering code is loaded on demand; importing the parser
|
|
268
|
+
still loads no renderer. Browser tests compare visible relief and attenuation
|
|
269
|
+
changes plus backward restoration under WebGL and the TSL WebGL backend. The
|
|
270
|
+
hardware WebGPU case runs only when an adapter is available.
|
|
271
|
+
|
|
50
272
|
The default single-pass XML parser builds the Demo3D object tree directly, avoiding the time and memory cost of an intermediate browser DOM. For unusual XML inputs, callers can opt into the browser parser or inject another DOM implementation:
|
|
51
273
|
|
|
52
274
|
```ts
|
|
@@ -66,6 +288,46 @@ npm run demo:three
|
|
|
66
288
|
|
|
67
289
|
Then open the printed `http://127.0.0.1:.../examples/three-render-smoke.html` URL and choose a `.demo3d` or `.raw3d` file.
|
|
68
290
|
|
|
291
|
+
To create a single-file version that can be opened directly from the file
|
|
292
|
+
system without a server, run:
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
npm run build:test-page
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Open `dist/examples/three-render-smoke-standalone.html`. Three.js,
|
|
299
|
+
OrbitControls, and the Demo3D parser/renderer are bundled into that HTML file;
|
|
300
|
+
only the `.demo3d` or `.raw3d` file selected by the user remains external. The
|
|
301
|
+
normal `npm run build` command also generates this standalone page.
|
|
302
|
+
|
|
303
|
+
### Export an Embedded Viewer
|
|
304
|
+
|
|
305
|
+
To create a standalone HTML viewer with one model embedded inside it, run:
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
npm run demo:export
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Open the printed URL, choose either a `.demo3d` or `.raw3d` file, and select
|
|
312
|
+
an export mode:
|
|
313
|
+
|
|
314
|
+
- **Generated Three.js objects and cameras (source-protected)** is the default.
|
|
315
|
+
It converts the
|
|
316
|
+
model first and creates `<model>-three-viewer.html` containing only serialized
|
|
317
|
+
Three.js objects, materials, geometry, textures, layer visibility, and
|
|
318
|
+
cameras. The original archive, `Model.xml`, and other Demo3D project data are
|
|
319
|
+
not included, so the source `.demo3d` file cannot be extracted from the
|
|
320
|
+
exported viewer. Rendered mesh data necessarily remains inspectable in any
|
|
321
|
+
browser-based viewer.
|
|
322
|
+
- **Original Demo3D/RAW3D file (lossless)** creates `<model>-viewer.html` with
|
|
323
|
+
the original file embedded.
|
|
324
|
+
|
|
325
|
+
Select **Download viewer HTML** after choosing the mode. The downloaded page can
|
|
326
|
+
be opened directly with `file://` and presents the model immediately without a
|
|
327
|
+
file-open control. The exporter itself is also available as
|
|
328
|
+
`dist/examples/export-embedded-viewer-standalone.html` and can be opened
|
|
329
|
+
directly from the file system.
|
|
330
|
+
|
|
69
331
|
The parser root remains independent of Three.js. Renderer features that require
|
|
70
332
|
procedural reconstruction are opt-in through the `demo3d-file-format/three`
|
|
71
333
|
subpath:
|
|
@@ -160,6 +422,31 @@ lights come from the same Three.js module as the renderer. Set
|
|
|
160
422
|
WebGPU can improve repeated rendering of complex scenes, but it does not speed
|
|
161
423
|
up archive/XML parsing and may have higher first-frame shader compilation cost.
|
|
162
424
|
|
|
425
|
+
### Enhanced Render Mode
|
|
426
|
+
|
|
427
|
+
For a more presentation-ready view, apply the optional enhanced preset after
|
|
428
|
+
adding the parsed group to a scene. It enables soft shadows, marks opaque model
|
|
429
|
+
meshes as shadow casters/receivers, adds fitted key and fill lighting, and puts
|
|
430
|
+
a matte contact floor below the model:
|
|
431
|
+
|
|
432
|
+
```ts
|
|
433
|
+
import { applyDemo3DThreeRenderMode } from "demo3d-file-format/three";
|
|
434
|
+
|
|
435
|
+
const presentation = applyDemo3DThreeRenderMode({
|
|
436
|
+
three: selected.three,
|
|
437
|
+
renderer: selected.renderer,
|
|
438
|
+
scene,
|
|
439
|
+
object: group,
|
|
440
|
+
mode: "enhanced"
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
// Remove the preset and restore the previous renderer and mesh settings.
|
|
444
|
+
presentation.dispose();
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
Use `mode: "standard"` for the lighter-weight lighting preset. The browser
|
|
448
|
+
smoke-test page includes a **Better render** switch for comparing both modes.
|
|
449
|
+
|
|
163
450
|
## Current Scope
|
|
164
451
|
|
|
165
452
|
- Read-only parser.
|
|
@@ -167,6 +454,7 @@ up archive/XML parsing and may have higher first-frame shader compilation cost.
|
|
|
167
454
|
- Stored and DEFLATE ZIP entries.
|
|
168
455
|
- Full XML tree preservation.
|
|
169
456
|
- Core typed classes for project header, visuals, meshes, materials, resources, and unknown typed entries.
|
|
457
|
+
- Demo3D 2026 `Model.xml`, flat visual hierarchies, and external mesh caches.
|
|
170
458
|
- Vendor-specific object types are preserved as `Demo3DUnknownObject` until explicit classes are added.
|
|
171
459
|
- RAW3D `Model.xml` scene metadata and external geometry/texture resources.
|
|
172
460
|
- RAW3D Three.js rendering with source geometry shared across scene nodes.
|