@haiyue/extensions 0.1.0 → 0.2.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 +25 -0
- package/dist/animation/Animation2DComponent.d.ts +18 -0
- package/dist/animation/Animation2DExtensionRegistry.d.ts +7 -0
- package/dist/animation/Animation2DRenderSystem.d.ts +6 -0
- package/dist/animation/Animation2DRuntime.d.ts +6 -2
- package/dist/animation/AnimationTextRasterizer.d.ts +4 -0
- package/dist/animation/AnimationVisual2D.d.ts +58 -2
- package/dist/animation/interaction/InteractionRuntime.d.ts +83 -0
- package/dist/animation/interaction/runtime-types.d.ts +257 -0
- package/dist/animation.d.ts +3 -1
- package/dist/animation.js +551 -59
- package/dist/animation3d.js +1 -1
- package/dist/canvas-text.js +1 -1
- package/dist/chunks/2d-ui-animation-2d.generated-FpziAeGJ.js +4 -0
- package/dist/chunks/2d-ui-indexed-sprite.generated-DmKR0CC3.js +4 -0
- package/dist/chunks/Animation2DStateMachine-BHcA6Cu3.js +18212 -0
- package/dist/chunks/{AnimationStateMachineController-BIcAh-sT.js → AnimationStateMachineController-4sKaqh9E.js} +2 -2
- package/dist/chunks/AnimationVisual2D-8y3qp0_U.js +230 -0
- package/dist/chunks/{RenderSystem2DBase-DDT61dAu.js → RenderSystem2DBase-CF2s00vg.js} +2 -2
- package/dist/controls/VirtualJoystickControls.d.ts +46 -0
- package/dist/controls/contracts.d.ts +91 -0
- package/dist/controls.d.ts +2 -0
- package/dist/controls.js +358 -0
- package/dist/deformable-animation/runtime/DeformableMesh2DRuntimeExtension.d.ts +11 -0
- package/dist/deformable-animation/runtime/DeformableMesh2DSampler.d.ts +11 -0
- package/dist/deformable-animation.d.ts +5 -0
- package/dist/deformable-animation.js +316 -0
- package/dist/experimental-indexed-sprite.d.ts +5 -0
- package/dist/experimental-indexed-sprite.js +482 -0
- package/dist/gltf-worker-runtime.js +9 -9
- package/dist/hya-state-machine.js +3 -2
- package/dist/index.js +1 -1
- package/dist/indexed-sprite/AtlasLayout.d.ts +2 -0
- package/dist/indexed-sprite/IndexedSpriteRenderer.d.ts +23 -0
- package/dist/indexed-sprite/contracts.d.ts +89 -0
- package/dist/internal/2d-ui-shader-artifact.js +232 -23
- package/dist/ray-tracing/acceleration/bvh.d.ts +37 -0
- package/dist/ray-tracing/acceleration/index.d.ts +6 -0
- package/dist/ray-tracing/acceleration/pack.d.ts +152 -0
- package/dist/ray-tracing/acceleration/query.d.ts +4 -0
- package/dist/ray-tracing/acceleration/runtime.d.ts +30 -0
- package/dist/ray-tracing/acceleration/tlas.d.ts +4 -0
- package/dist/ray-tracing/acceleration/types.d.ts +165 -0
- package/dist/ray-tracing/denoise/index.d.ts +3 -0
- package/dist/ray-tracing/denoise/layout.d.ts +9 -0
- package/dist/ray-tracing/denoise/runtime.d.ts +23 -0
- package/dist/ray-tracing/denoise/types.d.ts +28 -0
- package/dist/ray-tracing/hybrid/contract.d.ts +2 -0
- package/dist/ray-tracing/hybrid/index.d.ts +5 -0
- package/dist/ray-tracing/hybrid/layout.d.ts +17 -0
- package/dist/ray-tracing/hybrid/plan.d.ts +2 -0
- package/dist/ray-tracing/hybrid/runtime.d.ts +31 -0
- package/dist/ray-tracing/hybrid/shaders/hybrid-artifact.generated.d.ts +625 -0
- package/dist/ray-tracing/hybrid/types.d.ts +144 -0
- package/dist/ray-tracing/lifecycle/device-recovery.d.ts +31 -0
- package/dist/ray-tracing/lifecycle/index.d.ts +2 -0
- package/dist/ray-tracing/lifecycle/types.d.ts +37 -0
- package/dist/ray-tracing/material/index.d.ts +2 -0
- package/dist/ray-tracing/material/pack.d.ts +5 -0
- package/dist/ray-tracing/material/types.d.ts +63 -0
- package/dist/ray-tracing/reference/index.d.ts +122 -0
- package/dist/ray-tracing/renderer/index.d.ts +7 -0
- package/dist/ray-tracing/renderer/layout.d.ts +20 -0
- package/dist/ray-tracing/renderer/plan.d.ts +2 -0
- package/dist/ray-tracing/renderer/reference.d.ts +17 -0
- package/dist/ray-tracing/renderer/runtime.d.ts +39 -0
- package/dist/ray-tracing/renderer/scene.d.ts +4 -0
- package/dist/ray-tracing/renderer/types.d.ts +115 -0
- package/dist/ray-tracing/sampling/index.d.ts +8 -0
- package/dist/ray-tracing/sampling/layout.d.ts +12 -0
- package/dist/ray-tracing/sampling/plan.d.ts +5 -0
- package/dist/ray-tracing/sampling/revision.d.ts +15 -0
- package/dist/ray-tracing/sampling/runtime.d.ts +44 -0
- package/dist/ray-tracing/sampling/sequence.d.ts +2 -0
- package/dist/ray-tracing/sampling/types.d.ts +96 -0
- package/dist/ray-tracing/scene/index.d.ts +41 -0
- package/dist/ray-tracing/traversal/index.d.ts +4 -0
- package/dist/ray-tracing/traversal/layout.d.ts +16 -0
- package/dist/ray-tracing/traversal/plan.d.ts +2 -0
- package/dist/ray-tracing/traversal/runtime.d.ts +25 -0
- package/dist/ray-tracing/traversal/types.d.ts +79 -0
- package/dist/ray-tracing/worker/client.d.ts +25 -0
- package/dist/ray-tracing/worker/index.d.ts +5 -0
- package/dist/ray-tracing/worker/runtime.d.ts +11 -0
- package/dist/ray-tracing/worker/serialization.d.ts +16 -0
- package/dist/ray-tracing/worker/source.d.ts +1 -0
- package/dist/ray-tracing/worker/types.d.ts +91 -0
- package/dist/ray-tracing.d.ts +17 -0
- package/dist/ray-tracing.js +7666 -0
- package/dist/spine.js +1 -1
- package/dist/tilemap.js +1 -1
- package/package.json +26 -23
- package/dist/animation/Animation2DStateMachineVisualRuntime.d.ts +0 -27
- package/dist/animation/Particle2DDescriptorAdapter.d.ts +0 -5
- package/dist/animation3d/Animation3DResource.d.ts +0 -28
- package/dist/animation3d/hya/HyaAnimation3DStateMachineRuntime.d.ts +0 -65
- package/dist/animation3d/hya/index.d.ts +0 -4
- package/dist/animation3d/runtime/integration/Animation3DStateMachineMixerAdapter.d.ts +0 -81
- package/dist/animation3d/runtime/integration/Animation3DStateMachineMixerIntegration.d.ts +0 -39
- package/dist/animation3d/runtime/integration/index.d.ts +0 -2
- package/dist/animation3d/runtime/mixer/Action.d.ts +0 -150
- package/dist/animation3d/runtime/mixer/Animation3DMixerRuntimeStore.d.ts +0 -6
- package/dist/animation3d/runtime/mixer/Mixer.d.ts +0 -59
- package/dist/animation3d/runtime/mixer/PoseBuffer.d.ts +0 -1
- package/dist/animation3d/runtime/mixer/TrackSampler.d.ts +0 -24
- package/dist/animation3d/runtime/mixer/index.d.ts +0 -4
- package/dist/animation3d/runtime/state-machine/Animation3DBlendTreeWeights.d.ts +0 -1
- package/dist/animation3d/runtime/state-machine/Animation3DStateMachineCompiler.d.ts +0 -1
- package/dist/animation3d/runtime/state-machine/Animation3DStateMachineController.d.ts +0 -1
- package/dist/animation3d/runtime/state-machine/Animation3DStateMachineMixerPort.d.ts +0 -1
- package/dist/animation3d/runtime/state-machine/index.d.ts +0 -6
- package/dist/benchmark.d.ts +0 -30
- package/dist/chunks/2d-ui-animation-2d.generated-D4aHzFU2.js +0 -4
- package/dist/chunks/Animation2DStateMachine-9IonguNa.js +0 -3245
- package/dist/gltf/GltfAccessorReader.d.ts +0 -7
- package/dist/gltf/GltfDracoDecoder.d.ts +0 -4
- package/dist/gltf/GltfLoaderErrors.d.ts +0 -4
- package/dist/gltf/GltfMaterialDescriptor.d.ts +0 -23
- package/dist/gltf/GltfMaterialLoader.d.ts +0 -6
- package/dist/gltf-worker-runtime.d.ts +0 -7
- package/dist/plugins/pluginUtils.d.ts +0 -20
- package/dist/plugins.d.ts +0 -6
- package/dist/shaders/generated/2d-ui-artifact.generated.d.ts +0 -658
- package/dist/spine/Spine2DGpuRenderer.d.ts +0 -65
- package/dist/spine/Spine2DRuntime.d.ts +0 -103
- package/dist/spine/SpineAnimationBoneTimelines.d.ts +0 -8
- package/dist/spine/SpineFloatBuilder.d.ts +0 -15
- package/dist/spine/SpinePathConstraintSolver.d.ts +0 -32
- package/dist/spine/SpineSkeletonRuntime.d.ts +0 -185
- package/dist/spine/SpineSlotAnimation.d.ts +0 -17
- package/dist/spine/SpineTimelineRuntime.d.ts +0 -25
- package/dist/spine/SpineVertexBuilder.d.ts +0 -61
- package/dist/tilemap/Tilemap2DRenderer.d.ts +0 -24
- package/dist/utils/arrayAccess.d.ts +0 -4
- package/dist/utils/camera2d.d.ts +0 -12
- package/src/animation/Animation2DComponent.ts +0 -135
- package/src/animation/Animation2DExtensionRegistry.ts +0 -52
- package/src/animation/Animation2DRenderSystem.ts +0 -1026
- package/src/animation/Animation2DRuntime.ts +0 -1326
- package/src/animation/Animation2DStateMachine.ts +0 -39
- package/src/animation/Animation2DStateMachineComponent.ts +0 -228
- package/src/animation/Animation2DStateMachineRuntime.ts +0 -141
- package/src/animation/Animation2DStateMachineSystem.ts +0 -60
- package/src/animation/Animation2DStateMachineVisualRuntime.ts +0 -282
- package/src/animation/Animation2DSystem.ts +0 -72
- package/src/animation/AnimationAssetLoader.ts +0 -84
- package/src/animation/AnimationAudioClip.ts +0 -140
- package/src/animation/AnimationPathTessellator.ts +0 -691
- package/src/animation/AnimationTextRasterizer.ts +0 -340
- package/src/animation/AnimationVisual2D.ts +0 -153
- package/src/animation/HyaAnimation2DClipAdapter.ts +0 -845
- package/src/animation/Particle2DDescriptorAdapter.ts +0 -35
- package/src/animation/runtime/mixer/Action.ts +0 -876
- package/src/animation/runtime/mixer/Mixer.ts +0 -505
- package/src/animation/runtime/mixer/PoseBuffer.ts +0 -105
- package/src/animation/runtime/mixer/Sampler.ts +0 -252
- package/src/animation/runtime/mixer/Types.ts +0 -138
- package/src/animation/runtime/mixer/index.ts +0 -31
- package/src/animation-state-machine/AnimationStateMachine.ts +0 -146
- package/src/animation-state-machine/AnimationStateMachineChannels.ts +0 -116
- package/src/animation-state-machine/runtime/Animation2DStateMachineMixerAdapter.ts +0 -197
- package/src/animation-state-machine/runtime/AnimationStateMachineBlendTreeWeights.ts +0 -503
- package/src/animation-state-machine/runtime/AnimationStateMachineCompiler.ts +0 -763
- package/src/animation-state-machine/runtime/AnimationStateMachineController.ts +0 -987
- package/src/animation-state-machine/runtime/AnimationStateMachineMixerPort.ts +0 -54
- package/src/animation-state-machine/runtime/index.ts +0 -47
- package/src/animation.ts +0 -33
- package/src/animation3d/Animation3DAction.ts +0 -73
- package/src/animation3d/Animation3DBinding.ts +0 -116
- package/src/animation3d/Animation3DClip.ts +0 -22
- package/src/animation3d/Animation3DError.ts +0 -34
- package/src/animation3d/Animation3DMixer.ts +0 -82
- package/src/animation3d/Animation3DPose.ts +0 -100
- package/src/animation3d/Animation3DPoseBuffer.ts +0 -85
- package/src/animation3d/Animation3DResource.ts +0 -49
- package/src/animation3d/Animation3DStateMachine.ts +0 -126
- package/src/animation3d/Animation3DStateMachineRuntime.ts +0 -191
- package/src/animation3d/Animation3DTrack.ts +0 -29
- package/src/animation3d/hya/HyaAnimation3DRuntime.ts +0 -756
- package/src/animation3d/hya/HyaAnimation3DStateMachineRuntime.ts +0 -618
- package/src/animation3d/hya/HyaAnimation3DTypes.ts +0 -168
- package/src/animation3d/hya/index.ts +0 -10
- package/src/animation3d/index.ts +0 -76
- package/src/animation3d/runtime/integration/Animation3DStateMachineMixerAdapter.ts +0 -325
- package/src/animation3d/runtime/integration/Animation3DStateMachineMixerIntegration.ts +0 -158
- package/src/animation3d/runtime/integration/index.ts +0 -9
- package/src/animation3d/runtime/mixer/Action.ts +0 -833
- package/src/animation3d/runtime/mixer/Animation3DMixerRuntimeStore.ts +0 -26
- package/src/animation3d/runtime/mixer/Mixer.ts +0 -562
- package/src/animation3d/runtime/mixer/PoseBuffer.ts +0 -1
- package/src/animation3d/runtime/mixer/TrackSampler.ts +0 -399
- package/src/animation3d/runtime/mixer/index.ts +0 -8
- package/src/animation3d/runtime/state-machine/Animation3DBlendTreeWeights.ts +0 -4
- package/src/animation3d/runtime/state-machine/Animation3DStateMachineCompiler.ts +0 -1
- package/src/animation3d/runtime/state-machine/Animation3DStateMachineController.ts +0 -1
- package/src/animation3d/runtime/state-machine/Animation3DStateMachineMixerPort.ts +0 -1
- package/src/animation3d/runtime/state-machine/index.ts +0 -45
- package/src/animation3d.ts +0 -5
- package/src/benchmark.ts +0 -168
- package/src/canvas-text/CanvasText2DRenderSystem.ts +0 -292
- package/src/canvas-text/CanvasTextComponent.ts +0 -47
- package/src/canvas-text.ts +0 -4
- package/src/experimental-gltf-worker.ts +0 -18
- package/src/experimental-spine-worker.ts +0 -9
- package/src/gltf/GltfAccessorReader.ts +0 -271
- package/src/gltf/GltfAnimation3DAdapter.ts +0 -680
- package/src/gltf/GltfAnimationRuntime.ts +0 -392
- package/src/gltf/GltfAssetWorkerClient.ts +0 -136
- package/src/gltf/GltfCompatibilityReport.ts +0 -214
- package/src/gltf/GltfConservativeBounds.ts +0 -219
- package/src/gltf/GltfDracoDecoder.ts +0 -251
- package/src/gltf/GltfExtensionAdapter.ts +0 -340
- package/src/gltf/GltfLoaderContract.ts +0 -333
- package/src/gltf/GltfLoaderErrors.ts +0 -59
- package/src/gltf/GltfMaterialDescriptor.ts +0 -134
- package/src/gltf/GltfMaterialEncoder.ts +0 -173
- package/src/gltf/GltfMaterialLoader.ts +0 -293
- package/src/gltf/GltfModelComponent.ts +0 -115
- package/src/gltf/GltfModelSystem.ts +0 -208
- package/src/gltf/GltfPlugin.ts +0 -84
- package/src/gltf/GltfSchema.ts +0 -229
- package/src/gltf/GltfUvSemanticPlanner.ts +0 -166
- package/src/gltf/gltfLoader.ts +0 -910
- package/src/gltf-animation3d.ts +0 -10
- package/src/gltf-worker-runtime.ts +0 -10
- package/src/gltf.ts +0 -56
- package/src/grid/Grid2DComponent.ts +0 -69
- package/src/grid.ts +0 -2
- package/src/hya-state-machine.ts +0 -19
- package/src/index.ts +0 -2
- package/src/plugins/pluginUtils.ts +0 -50
- package/src/plugins.ts +0 -6
- package/src/shaders/generated/2d-ui-animation-2d.generated.wgsl +0 -242
- package/src/shaders/generated/2d-ui-artifact.generated.ts +0 -867
- package/src/shaders/generated/2d-ui-canvas-text-2d.generated.wgsl +0 -38
- package/src/shaders/generated/2d-ui-spine2d.generated.wgsl +0 -41
- package/src/shaders/generated/2d-ui-tilemap2d.generated.wgsl +0 -36
- package/src/spine/Spine2DComponent.ts +0 -168
- package/src/spine/Spine2DGpuRenderer.ts +0 -449
- package/src/spine/Spine2DRenderSystem.ts +0 -199
- package/src/spine/Spine2DRuntime.ts +0 -1529
- package/src/spine/SpineAnimationBoneTimelines.ts +0 -30
- package/src/spine/SpineAssetParser.ts +0 -20
- package/src/spine/SpineAssetWorkerClient.ts +0 -112
- package/src/spine/SpineAssetWorkerContract.ts +0 -4
- package/src/spine/SpineAtlasParser.ts +0 -127
- package/src/spine/SpineFloatBuilder.ts +0 -66
- package/src/spine/SpinePathConstraintSolver.ts +0 -582
- package/src/spine/SpinePlugin.ts +0 -76
- package/src/spine/SpineSkeletonRuntime.ts +0 -521
- package/src/spine/SpineSlotAnimation.ts +0 -195
- package/src/spine/SpineTimelineRuntime.ts +0 -453
- package/src/spine/SpineVertexBuilder.ts +0 -686
- package/src/spine.ts +0 -7
- package/src/tilemap/Tilemap2DComponent.ts +0 -232
- package/src/tilemap/Tilemap2DRenderSystem.ts +0 -58
- package/src/tilemap/Tilemap2DRenderer.ts +0 -289
- package/src/tilemap/TilemapPlugin.ts +0 -75
- package/src/tilemap.ts +0 -6
- package/src/tween/Tween2DComponent.ts +0 -83
- package/src/tween/Tween2DSystem.ts +0 -78
- package/src/tween.ts +0 -4
- package/src/types/earcut.d.ts +0 -7
- package/src/types/wgsl.d.ts +0 -4
- package/src/utils/RenderSystem2DBase.ts +0 -164
- package/src/utils/arrayAccess.ts +0 -17
- package/src/utils/camera2d.ts +0 -68
- package/src/utils/render2dGpu.ts +0 -132
- package/test/fixtures/gltf/animation-characterization.gltf +0 -344
|
@@ -1,392 +0,0 @@
|
|
|
1
|
-
import { Entity, Geometry3D } from '@haiyue/engine';
|
|
2
|
-
import { Transform3D } from '@haiyue/engine/components';
|
|
3
|
-
import { mat4 } from 'wgpu-matrix';
|
|
4
|
-
import { GltfConservativeBounds } from './GltfConservativeBounds';
|
|
5
|
-
import { readAccessorFloat, requiredFiniteArrayValue } from './GltfAccessorReader';
|
|
6
|
-
import { gltfDataError } from './GltfLoaderErrors';
|
|
7
|
-
import type { GltfAsset } from './GltfSchema';
|
|
8
|
-
import type {
|
|
9
|
-
GltfAnimationChannelRuntime,
|
|
10
|
-
GltfAnimationClip,
|
|
11
|
-
GltfAnimationPath,
|
|
12
|
-
GltfAnimationTarget,
|
|
13
|
-
GltfSkinnedPrimitiveRuntime,
|
|
14
|
-
} from './GltfLoaderContract';
|
|
15
|
-
|
|
16
|
-
const conservativeBoundsByGeometry = new WeakMap<Geometry3D, GltfConservativeBounds>();
|
|
17
|
-
|
|
18
|
-
export function registerGltfConservativeBounds(
|
|
19
|
-
geometry: Geometry3D,
|
|
20
|
-
bounds: GltfConservativeBounds,
|
|
21
|
-
): void {
|
|
22
|
-
conservativeBoundsByGeometry.set(geometry, bounds);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function createAnimationClips(
|
|
26
|
-
gltf: GltfAsset,
|
|
27
|
-
buffers: ArrayBuffer[],
|
|
28
|
-
targets: Map<number, GltfAnimationTarget>,
|
|
29
|
-
skinnedPrimitives: GltfSkinnedPrimitiveRuntime[],
|
|
30
|
-
): GltfAnimationClip[] {
|
|
31
|
-
return (gltf.animations ?? []).map((animation, index) => {
|
|
32
|
-
const channels: GltfAnimationChannelRuntime[] = [];
|
|
33
|
-
let duration = 0;
|
|
34
|
-
for (const channel of animation.channels ?? []) {
|
|
35
|
-
const sampler = animation.samplers?.[channel.sampler];
|
|
36
|
-
const nodeIndex = channel.target.node;
|
|
37
|
-
const path = channel.target.path;
|
|
38
|
-
if (!sampler || nodeIndex === undefined || !isAnimationPath(path)) continue;
|
|
39
|
-
const target = targets.get(nodeIndex);
|
|
40
|
-
if (!target) continue;
|
|
41
|
-
const input = readAccessorFloat(gltf, buffers, sampler.input, 1);
|
|
42
|
-
const outputSize = path === 'weights' ? Math.max(target.weights.length, target.morphPrimitives[0]?.positionTargets.length ?? 0, 1) : path === 'rotation' ? 4 : 3;
|
|
43
|
-
const output = path === 'weights'
|
|
44
|
-
? readAccessorFloat(gltf, buffers, sampler.output, 1)
|
|
45
|
-
: readAccessorFloat(gltf, buffers, sampler.output, outputSize);
|
|
46
|
-
duration = Math.max(duration, input[input.length - 1] ?? 0);
|
|
47
|
-
channels.push({
|
|
48
|
-
target,
|
|
49
|
-
path,
|
|
50
|
-
interpolation: sampler.interpolation ?? 'LINEAR',
|
|
51
|
-
valueSize: outputSize,
|
|
52
|
-
input,
|
|
53
|
-
output,
|
|
54
|
-
sampleA: new Float32Array(outputSize),
|
|
55
|
-
sampleB: new Float32Array(outputSize),
|
|
56
|
-
sampleOut: new Float32Array(outputSize),
|
|
57
|
-
quatScratch: new Float32Array(4),
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
name: animation.name || `Animation ${index + 1}`,
|
|
62
|
-
duration,
|
|
63
|
-
channels,
|
|
64
|
-
skinnedPrimitives,
|
|
65
|
-
stateCache: new Map(),
|
|
66
|
-
activeStates: [],
|
|
67
|
-
};
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function isAnimationPath(path: string | undefined): path is GltfAnimationPath {
|
|
72
|
-
return path === 'translation' || path === 'rotation' || path === 'scale' || path === 'weights';
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export function applyGltfAnimationClip(clip: GltfAnimationClip, time: number): void {
|
|
76
|
-
if (clip.duration <= 0) return;
|
|
77
|
-
const localTime = ((time % clip.duration) + clip.duration) % clip.duration;
|
|
78
|
-
const states = clip.stateCache;
|
|
79
|
-
const activeStates = clip.activeStates;
|
|
80
|
-
activeStates.length = 0;
|
|
81
|
-
for (const channel of clip.channels) {
|
|
82
|
-
const value = sampleAnimationChannel(channel, localTime, channel.sampleOut);
|
|
83
|
-
if (channel.path === 'weights') {
|
|
84
|
-
applyMorphWeights(channel.target, value);
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
let state = states.get(channel.target);
|
|
88
|
-
if (!state) {
|
|
89
|
-
state = {
|
|
90
|
-
target: channel.target,
|
|
91
|
-
translation: new Float32Array(3),
|
|
92
|
-
rotation: new Float32Array(4),
|
|
93
|
-
scale: new Float32Array(3),
|
|
94
|
-
matrix: new Float32Array(16),
|
|
95
|
-
active: false,
|
|
96
|
-
};
|
|
97
|
-
states.set(channel.target, state);
|
|
98
|
-
}
|
|
99
|
-
if (!state.active) {
|
|
100
|
-
state.translation.set(channel.target.translation);
|
|
101
|
-
state.rotation.set(channel.target.rotation);
|
|
102
|
-
state.scale.set(channel.target.scale);
|
|
103
|
-
state.active = true;
|
|
104
|
-
activeStates.push(state);
|
|
105
|
-
}
|
|
106
|
-
if (channel.path === 'translation') copyComponents(value, state.translation, 3);
|
|
107
|
-
else if (channel.path === 'scale') copyComponents(value, state.scale, 3);
|
|
108
|
-
else normalizeQuat(value, state.rotation);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
for (const state of activeStates) {
|
|
112
|
-
state.target.transform.localMatrix = composeTrsMatrix(state.translation, state.rotation, state.scale, state.matrix);
|
|
113
|
-
state.active = false;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
for (const skinnedPrimitive of clip.skinnedPrimitives) {
|
|
117
|
-
updateSkinnedPrimitive(skinnedPrimitive);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function sampleAnimationChannel(channel: GltfAnimationChannelRuntime, time: number, out: Float32Array): Float32Array {
|
|
122
|
-
const times = channel.input;
|
|
123
|
-
const count = times.length;
|
|
124
|
-
const componentCount = channel.valueSize;
|
|
125
|
-
if (count === 0) {
|
|
126
|
-
fillDefaultAnimationValue(out, componentCount);
|
|
127
|
-
return out;
|
|
128
|
-
}
|
|
129
|
-
const firstTime = requiredFiniteArrayValue(times, 0, 'animation input');
|
|
130
|
-
const lastTime = requiredFiniteArrayValue(times, count - 1, 'animation input');
|
|
131
|
-
if (time <= firstTime) return readAnimationValue(channel, 0, componentCount, out);
|
|
132
|
-
if (time >= lastTime) return readAnimationValue(channel, count - 1, componentCount, out);
|
|
133
|
-
let frame = 0;
|
|
134
|
-
while (frame + 1 < count && requiredFiniteArrayValue(times, frame + 1, 'animation input') < time) frame++;
|
|
135
|
-
const t0 = requiredFiniteArrayValue(times, frame, 'animation input');
|
|
136
|
-
const t1 = requiredFiniteArrayValue(times, frame + 1, 'animation input');
|
|
137
|
-
const alpha = channel.interpolation === 'STEP' ? 0 : (time - t0) / Math.max(0.000001, t1 - t0);
|
|
138
|
-
const a = readAnimationValue(channel, frame, componentCount, channel.sampleA);
|
|
139
|
-
if (channel.interpolation === 'STEP') {
|
|
140
|
-
copyComponents(a, out, componentCount);
|
|
141
|
-
return out;
|
|
142
|
-
}
|
|
143
|
-
const b = readAnimationValue(channel, frame + 1, componentCount, channel.sampleB);
|
|
144
|
-
if (channel.path === 'rotation') return slerpQuat(a, b, alpha, out, channel.quatScratch);
|
|
145
|
-
return lerpArray(a, b, alpha, out, componentCount);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function readAnimationValue(channel: GltfAnimationChannelRuntime, frame: number, componentCount: number, out: Float32Array): Float32Array {
|
|
149
|
-
const cubic = channel.interpolation === 'CUBICSPLINE';
|
|
150
|
-
const stride = cubic ? componentCount * 3 : componentCount;
|
|
151
|
-
const offset = frame * stride + (cubic ? componentCount : 0);
|
|
152
|
-
for (let i = 0; i < componentCount; i++) out[i] = channel.output[offset + i] ?? (i === 3 ? 1 : 0);
|
|
153
|
-
return out;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function fillDefaultAnimationValue(out: Float32Array, componentCount: number): void {
|
|
157
|
-
for (let i = 0; i < componentCount; i++) out[i] = i === 3 ? 1 : 0;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function copyComponents(source: ArrayLike<number>, target: Float32Array, count: number): void {
|
|
161
|
-
for (let i = 0; i < count; i++) target[i] = source[i] ?? 0;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
function lerpArray(a: ArrayLike<number>, b: ArrayLike<number>, alpha: number, out: Float32Array, componentCount: number): Float32Array {
|
|
165
|
-
for (let i = 0; i < componentCount; i++) {
|
|
166
|
-
const value = a[i] ?? 0;
|
|
167
|
-
out[i] = value + ((b[i] ?? value) - value) * alpha;
|
|
168
|
-
}
|
|
169
|
-
return out;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
function normalizeQuat(q: ArrayLike<number>, out: Float32Array): Float32Array {
|
|
173
|
-
const qx = q[0] ?? 0;
|
|
174
|
-
const qy = q[1] ?? 0;
|
|
175
|
-
const qz = q[2] ?? 0;
|
|
176
|
-
const qw = q[3] ?? 1;
|
|
177
|
-
const len = Math.hypot(qx, qy, qz, qw) || 1;
|
|
178
|
-
out[0] = qx / len;
|
|
179
|
-
out[1] = qy / len;
|
|
180
|
-
out[2] = qz / len;
|
|
181
|
-
out[3] = qw / len;
|
|
182
|
-
return out;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
function slerpQuat(aRaw: ArrayLike<number>, bRaw: ArrayLike<number>, alpha: number, out: Float32Array, scratch: Float32Array): Float32Array {
|
|
186
|
-
const a = normalizeQuat(aRaw, out);
|
|
187
|
-
const b = normalizeQuat(bRaw, scratch);
|
|
188
|
-
let bx = b[0] ?? 0;
|
|
189
|
-
let by = b[1] ?? 0;
|
|
190
|
-
let bz = b[2] ?? 0;
|
|
191
|
-
let bw = b[3] ?? 1;
|
|
192
|
-
const ax = a[0] ?? 0;
|
|
193
|
-
const ay = a[1] ?? 0;
|
|
194
|
-
const az = a[2] ?? 0;
|
|
195
|
-
const aw = a[3] ?? 1;
|
|
196
|
-
let dot = ax * bx + ay * by + az * bz + aw * bw;
|
|
197
|
-
|
|
198
|
-
if (dot < 0) {
|
|
199
|
-
dot = -dot;
|
|
200
|
-
bx = -bx;
|
|
201
|
-
by = -by;
|
|
202
|
-
bz = -bz;
|
|
203
|
-
bw = -bw;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if (dot > 0.9995) {
|
|
207
|
-
out[0] = ax + (bx - ax) * alpha;
|
|
208
|
-
out[1] = ay + (by - ay) * alpha;
|
|
209
|
-
out[2] = az + (bz - az) * alpha;
|
|
210
|
-
out[3] = aw + (bw - aw) * alpha;
|
|
211
|
-
return normalizeQuat(out, out);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
const theta0 = Math.acos(Math.min(1, Math.max(-1, dot)));
|
|
215
|
-
const sinTheta0 = Math.sin(theta0);
|
|
216
|
-
const theta = theta0 * alpha;
|
|
217
|
-
const sinTheta = Math.sin(theta);
|
|
218
|
-
const s0 = Math.cos(theta) - dot * sinTheta / sinTheta0;
|
|
219
|
-
const s1 = sinTheta / sinTheta0;
|
|
220
|
-
out[0] = ax * s0 + bx * s1;
|
|
221
|
-
out[1] = ay * s0 + by * s1;
|
|
222
|
-
out[2] = az * s0 + bz * s1;
|
|
223
|
-
out[3] = aw * s0 + bw * s1;
|
|
224
|
-
return normalizeQuat(out, out);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
export function composeTrsMatrix(
|
|
228
|
-
translation: ArrayLike<number>,
|
|
229
|
-
rotation: ArrayLike<number>,
|
|
230
|
-
scale: ArrayLike<number>,
|
|
231
|
-
out = new Float32Array(16),
|
|
232
|
-
): Float32Array {
|
|
233
|
-
const rx = rotation[0] ?? 0;
|
|
234
|
-
const ry = rotation[1] ?? 0;
|
|
235
|
-
const rz = rotation[2] ?? 0;
|
|
236
|
-
const rw = rotation[3] ?? 1;
|
|
237
|
-
const len = Math.hypot(rx, ry, rz, rw) || 1;
|
|
238
|
-
const x = rx / len;
|
|
239
|
-
const y = ry / len;
|
|
240
|
-
const z = rz / len;
|
|
241
|
-
const w = rw / len;
|
|
242
|
-
const sx = scale[0] ?? 1;
|
|
243
|
-
const sy = scale[1] ?? 1;
|
|
244
|
-
const sz = scale[2] ?? 1;
|
|
245
|
-
const x2 = x + x;
|
|
246
|
-
const y2 = y + y;
|
|
247
|
-
const z2 = z + z;
|
|
248
|
-
const xx = x * x2;
|
|
249
|
-
const xy = x * y2;
|
|
250
|
-
const xz = x * z2;
|
|
251
|
-
const yy = y * y2;
|
|
252
|
-
const yz = y * z2;
|
|
253
|
-
const zz = z * z2;
|
|
254
|
-
const wx = w * x2;
|
|
255
|
-
const wy = w * y2;
|
|
256
|
-
const wz = w * z2;
|
|
257
|
-
|
|
258
|
-
out[0] = (1 - (yy + zz)) * sx;
|
|
259
|
-
out[1] = (xy + wz) * sx;
|
|
260
|
-
out[2] = (xz - wy) * sx;
|
|
261
|
-
out[3] = 0;
|
|
262
|
-
out[4] = (xy - wz) * sy;
|
|
263
|
-
out[5] = (1 - (xx + zz)) * sy;
|
|
264
|
-
out[6] = (yz + wx) * sy;
|
|
265
|
-
out[7] = 0;
|
|
266
|
-
out[8] = (xz + wy) * sz;
|
|
267
|
-
out[9] = (yz - wx) * sz;
|
|
268
|
-
out[10] = (1 - (xx + yy)) * sz;
|
|
269
|
-
out[11] = 0;
|
|
270
|
-
out[12] = translation[0] ?? 0;
|
|
271
|
-
out[13] = translation[1] ?? 0;
|
|
272
|
-
out[14] = translation[2] ?? 0;
|
|
273
|
-
out[15] = 1;
|
|
274
|
-
return out;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
export function applyMorphWeights(target: GltfAnimationTarget, weights: ArrayLike<number>): void {
|
|
278
|
-
if (target.morphPrimitives.length === 0) return;
|
|
279
|
-
target.weights.length = weights.length;
|
|
280
|
-
for (let i = 0; i < weights.length; i++) target.weights[i] = weights[i] ?? 0;
|
|
281
|
-
for (const morph of target.morphPrimitives) {
|
|
282
|
-
morph.geometry.setMorphWeights(target.weights);
|
|
283
|
-
updateConservativeMorphBounds(morph.geometry, target.weights);
|
|
284
|
-
if (morph.geometry.morphUseGpu) continue;
|
|
285
|
-
const positions = morph.geometry.positions;
|
|
286
|
-
positions.set(morph.geometry.morphBasePositions ?? morph.basePositions);
|
|
287
|
-
for (let targetIndex = 0; targetIndex < morph.positionTargets.length; targetIndex++) {
|
|
288
|
-
const weight = weights[targetIndex] ?? 0;
|
|
289
|
-
if (weight === 0) continue;
|
|
290
|
-
const delta = morph.positionTargets[targetIndex];
|
|
291
|
-
if (!delta || delta.length !== positions.length) {
|
|
292
|
-
throw gltfDataError('Morph POSITION target does not match the base position count.');
|
|
293
|
-
}
|
|
294
|
-
for (let i = 0; i < positions.length; i++) {
|
|
295
|
-
positions[i] = requiredFiniteArrayValue(positions, i, 'morph positions')
|
|
296
|
-
+ requiredFiniteArrayValue(delta, i, 'morph POSITION target') * weight;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
const normals = morph.geometry.normals;
|
|
301
|
-
const baseNormals = morph.geometry.morphBaseNormals ?? morph.baseNormals;
|
|
302
|
-
if (normals && baseNormals) {
|
|
303
|
-
normals.set(baseNormals);
|
|
304
|
-
for (let targetIndex = 0; targetIndex < morph.normalTargets.length; targetIndex++) {
|
|
305
|
-
const weight = weights[targetIndex] ?? 0;
|
|
306
|
-
if (weight === 0) continue;
|
|
307
|
-
const delta = morph.normalTargets[targetIndex];
|
|
308
|
-
if (!delta || delta.length !== normals.length) {
|
|
309
|
-
throw gltfDataError('Morph NORMAL target does not match the base normal count.');
|
|
310
|
-
}
|
|
311
|
-
for (let i = 0; i < normals.length; i++) {
|
|
312
|
-
normals[i] = requiredFiniteArrayValue(normals, i, 'morph normals')
|
|
313
|
-
+ requiredFiniteArrayValue(delta, i, 'morph NORMAL target') * weight;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
morph.geometry.markDirty();
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
export function updateSkinnedPrimitive(runtime: GltfSkinnedPrimitiveRuntime): void {
|
|
323
|
-
const meshWorldMatrix = updateEntityWorldMatrix(runtime.meshEntity);
|
|
324
|
-
const meshTransform = runtime.meshEntity.getComponent(Transform3D);
|
|
325
|
-
let dirty = runtime.lastMeshWorldVersion !== (meshTransform?.worldVersion ?? 0)
|
|
326
|
-
|| runtime.lastGeometryVersion !== runtime.geometry.version;
|
|
327
|
-
for (let jointIndex = 0; jointIndex < runtime.jointTargets.length; jointIndex++) {
|
|
328
|
-
const target = runtime.jointTargets[jointIndex];
|
|
329
|
-
if (!target) continue;
|
|
330
|
-
updateEntityWorldMatrix(target.entity);
|
|
331
|
-
const worldVersion = target.transform.worldVersion;
|
|
332
|
-
if (runtime.lastJointWorldVersions[jointIndex] !== worldVersion) dirty = true;
|
|
333
|
-
}
|
|
334
|
-
if (!dirty) return;
|
|
335
|
-
|
|
336
|
-
const inverseMeshWorld = mat4.inverse(meshWorldMatrix, runtime.inverseMeshWorldScratch) as Float32Array;
|
|
337
|
-
for (let jointIndex = 0; jointIndex < runtime.jointTargets.length; jointIndex++) {
|
|
338
|
-
const jointTarget = runtime.jointTargets[jointIndex];
|
|
339
|
-
const inverseBind = runtime.inverseBindMatrices[jointIndex];
|
|
340
|
-
if (!jointTarget || !inverseBind) {
|
|
341
|
-
runtime.jointMatrices.set(IDENTITY_MATRIX, jointIndex * 16);
|
|
342
|
-
continue;
|
|
343
|
-
}
|
|
344
|
-
mat4.multiply(jointTarget.transform.worldMatrix, inverseBind, runtime.jointMatrixScratch);
|
|
345
|
-
mat4.multiply(inverseMeshWorld, runtime.jointMatrixScratch, runtime.skinMatrixScratch);
|
|
346
|
-
runtime.jointMatrices.set(runtime.skinMatrixScratch, jointIndex * 16);
|
|
347
|
-
}
|
|
348
|
-
runtime.geometry.updateSkinningMatrices(runtime.jointMatrices);
|
|
349
|
-
updateConservativeSkinBounds(runtime.geometry);
|
|
350
|
-
runtime.lastMeshWorldVersion = meshTransform?.worldVersion ?? 0;
|
|
351
|
-
runtime.lastGeometryVersion = runtime.geometry.version;
|
|
352
|
-
for (let jointIndex = 0; jointIndex < runtime.jointTargets.length; jointIndex++) {
|
|
353
|
-
runtime.lastJointWorldVersions[jointIndex] = runtime.jointTargets[jointIndex]?.transform.worldVersion ?? -1;
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
function updateConservativeMorphBounds(geometry: Geometry3D, weights: ArrayLike<number>): void {
|
|
358
|
-
const bounds = conservativeBoundsByGeometry.get(geometry);
|
|
359
|
-
if (!bounds) return;
|
|
360
|
-
bounds.updateMorphWeights(weights);
|
|
361
|
-
geometry.setLocalBounds(geometry.skinning
|
|
362
|
-
? bounds.getSkinnedBounds(geometry.skinning.jointMatrices, geometry.skinning.joints, geometry.skinning.weights)
|
|
363
|
-
: bounds.getSourceBounds());
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
function updateConservativeSkinBounds(geometry: Geometry3D): void {
|
|
367
|
-
const bounds = conservativeBoundsByGeometry.get(geometry);
|
|
368
|
-
if (!bounds || !geometry.skinning) return;
|
|
369
|
-
geometry.setLocalBounds(bounds.getSkinnedBounds(
|
|
370
|
-
geometry.skinning.jointMatrices,
|
|
371
|
-
geometry.skinning.joints,
|
|
372
|
-
geometry.skinning.weights,
|
|
373
|
-
));
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
const IDENTITY_MATRIX = mat4.identity() as Float32Array;
|
|
377
|
-
|
|
378
|
-
function updateEntityWorldMatrix(entity: Entity): Float32Array {
|
|
379
|
-
const transform = entity.getComponent(Transform3D);
|
|
380
|
-
const parent = entity.parent as Entity | null;
|
|
381
|
-
const parentWorld = parent ? updateEntityWorldMatrix(parent) : null;
|
|
382
|
-
if (transform) {
|
|
383
|
-
if (parent) {
|
|
384
|
-
const parentTransform = parent.getComponent(Transform3D);
|
|
385
|
-
transform.updateWorldMatrix(parentTransform?.worldMatrix ?? parentWorld ?? undefined, parentTransform?.worldVersion ?? 0);
|
|
386
|
-
} else {
|
|
387
|
-
transform.updateWorldMatrix(undefined, 0);
|
|
388
|
-
}
|
|
389
|
-
return transform.worldMatrix;
|
|
390
|
-
}
|
|
391
|
-
return parentWorld ?? IDENTITY_MATRIX;
|
|
392
|
-
}
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import { WorkerChannel, type WorkerChannelLike } from '@haiyue/engine/experimental/async';
|
|
2
|
-
import { isGltfParsedAsset, type DracoDecoderConfig, type GltfAssetWorker } from './GltfLoaderContract';
|
|
3
|
-
|
|
4
|
-
type GltfAssetWorkerLike = WorkerChannelLike;
|
|
5
|
-
|
|
6
|
-
export class GltfAssetWorkerClient implements GltfAssetWorker {
|
|
7
|
-
private readonly channel: WorkerChannel;
|
|
8
|
-
|
|
9
|
-
constructor(worker: GltfAssetWorkerLike, private readonly objectUrl: string | null = null) {
|
|
10
|
-
this.channel = new WorkerChannel(worker, {
|
|
11
|
-
label: 'glTF asset worker',
|
|
12
|
-
path: 'gltf.worker',
|
|
13
|
-
context: { resourceType: 'model/gltf' },
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
loadParsedAsset(
|
|
18
|
-
src: string,
|
|
19
|
-
options: { signal?: AbortSignal; dracoDecoderConfig?: DracoDecoderConfig } = {},
|
|
20
|
-
): Promise<Awaited<ReturnType<GltfAssetWorker['loadParsedAsset']>>> {
|
|
21
|
-
return this.channel.request('loadParsedGltfAsset', {
|
|
22
|
-
src,
|
|
23
|
-
dracoDecoderConfig: toWorkerDracoDecoderConfig(options.dracoDecoderConfig),
|
|
24
|
-
}, {
|
|
25
|
-
...(options.signal ? { signal: options.signal } : {}),
|
|
26
|
-
context: { url: src },
|
|
27
|
-
abortMessage: 'glTF load aborted.',
|
|
28
|
-
validate: isGltfParsedAsset,
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
dispose(options: { terminate?: boolean } = {}): void {
|
|
33
|
-
const alreadyDisposed = this.channel.isDisposed;
|
|
34
|
-
this.channel.dispose(options);
|
|
35
|
-
if (!alreadyDisposed && this.objectUrl) URL.revokeObjectURL(this.objectUrl);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function toWorkerDracoDecoderConfig(config: DracoDecoderConfig | undefined): Pick<DracoDecoderConfig, 'scriptUrl' | 'wasmBinary'> | undefined {
|
|
40
|
-
if (!config) return undefined;
|
|
41
|
-
return {
|
|
42
|
-
...(config.scriptUrl === undefined ? {} : { scriptUrl: config.scriptUrl }),
|
|
43
|
-
...(config.wasmBinary === undefined ? {} : { wasmBinary: config.wasmBinary }),
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/** The worker imports the same production parser used by the main-thread fallback. */
|
|
48
|
-
export function createGltfAssetWorkerSource(extensionGltfModuleUrl: string): string {
|
|
49
|
-
return `
|
|
50
|
-
const parserModulePromise = import(${JSON.stringify(extensionGltfModuleUrl)});
|
|
51
|
-
const requests = new Map();
|
|
52
|
-
self.addEventListener('message', async event => {
|
|
53
|
-
const request = event.data;
|
|
54
|
-
if (!request || request.version !== 1 || typeof request.id !== 'number') return;
|
|
55
|
-
if (request.type === 'cancel') {
|
|
56
|
-
requests.get(request.id)?.abort('cancelled');
|
|
57
|
-
requests.delete(request.id);
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
if (request.type !== 'loadParsedGltfAsset') return;
|
|
61
|
-
const controller = new AbortController();
|
|
62
|
-
requests.set(request.id, controller);
|
|
63
|
-
try {
|
|
64
|
-
const parser = await parserModulePromise;
|
|
65
|
-
const value = await parser.loadParsedGltfAsset(request.src, controller.signal);
|
|
66
|
-
const geometryStartedAt = performance.now();
|
|
67
|
-
let dracoDecodeMs = 0;
|
|
68
|
-
value.geometryPayloads = await parser.prepareGltfGeometryPayloads(value.gltf, value.buffers, {
|
|
69
|
-
signal: controller.signal,
|
|
70
|
-
dracoDecoderConfig: request.dracoDecoderConfig,
|
|
71
|
-
diagnostics: {
|
|
72
|
-
onDracoDecode(durationMs) { dracoDecodeMs += durationMs; },
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
const geometryPreparationMs = performance.now() - geometryStartedAt;
|
|
76
|
-
if (!requiresRuntimeSourceBuffers(value.gltf)) {
|
|
77
|
-
value.binaryChunk = null;
|
|
78
|
-
value.buffers = [];
|
|
79
|
-
}
|
|
80
|
-
const transfer = [];
|
|
81
|
-
const seen = new Set();
|
|
82
|
-
const add = buffer => { if (buffer && !seen.has(buffer)) { seen.add(buffer); transfer.push(buffer); } };
|
|
83
|
-
add(value.binaryChunk);
|
|
84
|
-
for (const buffer of value.buffers || []) add(buffer);
|
|
85
|
-
for (const mesh of value.geometryPayloads || []) for (const payload of mesh || []) if (payload) {
|
|
86
|
-
for (const array of [payload.positions, payload.indices, payload.normals, payload.joints, payload.weights]) add(array && array.buffer);
|
|
87
|
-
for (const entry of payload.textureCoordinates || []) add(entry.data && entry.data.buffer);
|
|
88
|
-
for (const array of payload.positionTargets || []) add(array.buffer);
|
|
89
|
-
for (const array of payload.normalTargets || []) add(array.buffer);
|
|
90
|
-
}
|
|
91
|
-
const workerTransferBytes = transfer.reduce((total, buffer) => total + buffer.byteLength, 0);
|
|
92
|
-
const baseMetrics = value.metrics || {};
|
|
93
|
-
value.metrics = {
|
|
94
|
-
fetchMs: baseMetrics.fetchMs || 0,
|
|
95
|
-
parseMs: baseMetrics.parseMs || 0,
|
|
96
|
-
workerParseMs: (baseMetrics.parseMs || 0) + Math.max(0, geometryPreparationMs - dracoDecodeMs),
|
|
97
|
-
dracoDecodeMs,
|
|
98
|
-
geometryPreparationMs,
|
|
99
|
-
sourceBytes: baseMetrics.sourceBytes || 0,
|
|
100
|
-
workerTransferBytes,
|
|
101
|
-
workerTransferBufferCount: transfer.length,
|
|
102
|
-
};
|
|
103
|
-
self.postMessage({ version: 1, id: request.id, ok: true, value }, transfer);
|
|
104
|
-
} catch (error) {
|
|
105
|
-
if (controller.signal.aborted) return;
|
|
106
|
-
const serialized = error && typeof error.toJSON === 'function' ? error.toJSON() : {
|
|
107
|
-
name: 'EngineError', domain: 'asset', code: 'E_ASSET_INVALID_DATA',
|
|
108
|
-
message: error instanceof Error ? error.message : String(error), recoverable: false,
|
|
109
|
-
recovery: 'release-resource', context: { url: request.src, resourceType: 'model/gltf' },
|
|
110
|
-
path: error && error.path || 'gltf.parse',
|
|
111
|
-
cause: error instanceof Error ? { name: error.name, message: error.message, stack: error.stack } : undefined,
|
|
112
|
-
};
|
|
113
|
-
self.postMessage({ version: 1, id: request.id, ok: false, error: serialized });
|
|
114
|
-
} finally {
|
|
115
|
-
requests.delete(request.id);
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
function requiresRuntimeSourceBuffers(gltf) {
|
|
120
|
-
if ((gltf.animations || []).length > 0) return true;
|
|
121
|
-
if ((gltf.images || []).some(image => image.bufferView !== undefined)) return true;
|
|
122
|
-
return (gltf.skins || []).some(skin => skin.inverseBindMatrices !== undefined);
|
|
123
|
-
}
|
|
124
|
-
`.trim();
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export function createGltfAssetWorkerClientFromUrl(url: string | URL, options?: WorkerOptions): GltfAssetWorkerClient {
|
|
128
|
-
return new GltfAssetWorkerClient(new Worker(url, options));
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export function createInlineGltfAssetWorkerClient(extensionGltfModuleUrl: string, options?: WorkerOptions): GltfAssetWorkerClient {
|
|
132
|
-
const blob = new Blob([createGltfAssetWorkerSource(extensionGltfModuleUrl)], { type: 'text/javascript' });
|
|
133
|
-
const url = URL.createObjectURL(blob);
|
|
134
|
-
const worker = new Worker(url, { type: 'module', ...options });
|
|
135
|
-
return new GltfAssetWorkerClient(worker, url);
|
|
136
|
-
}
|