@volter/blender-engine 0.1.148 → 0.1.150
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 +22 -5
- package/README.md +4 -11
- package/browser/addons/vrm/LICENSE_(OPTION1)_MIT.txt +22 -0
- package/browser/addons/vrm/LICENSE_(OPTION2)_GPL-3_0.txt +674 -0
- package/browser/addons/vrm/LICENSE_MAIN.txt +1 -0
- package/browser/addons/vrm/README.txt +3 -0
- package/browser/addons/vrm/__init__.py +41 -0
- package/browser/addons/vrm/blender_manifest.toml +16 -0
- package/browser/addons/vrm/common/__init__.py +1 -0
- package/browser/addons/vrm/common/animation.py +58 -0
- package/browser/addons/vrm/common/blender_manifest.py +82 -0
- package/browser/addons/vrm/common/char.py +16 -0
- package/browser/addons/vrm/common/convert.py +287 -0
- package/browser/addons/vrm/common/convert_any.py +48 -0
- package/browser/addons/vrm/common/debug.py +40 -0
- package/browser/addons/vrm/common/deep.py +162 -0
- package/browser/addons/vrm/common/error_dialog.py +274 -0
- package/browser/addons/vrm/common/fs.py +71 -0
- package/browser/addons/vrm/common/gl.py +20 -0
- package/browser/addons/vrm/common/gltf.py +1149 -0
- package/browser/addons/vrm/common/human_bone_mapper/__init__.py +1 -0
- package/browser/addons/vrm/common/human_bone_mapper/biped_mapping.py +84 -0
- package/browser/addons/vrm/common/human_bone_mapper/cats_blender_plugin_fix_model_mapping.py +63 -0
- package/browser/addons/vrm/common/human_bone_mapper/human_bone_mapper.py +203 -0
- package/browser/addons/vrm/common/human_bone_mapper/microsoft_rocketbox_mapping.py +69 -0
- package/browser/addons/vrm/common/human_bone_mapper/mixamo_mapping.py +62 -0
- package/browser/addons/vrm/common/human_bone_mapper/mmd_mapping.py +115 -0
- package/browser/addons/vrm/common/human_bone_mapper/mpfb_mapping.py +120 -0
- package/browser/addons/vrm/common/human_bone_mapper/ready_player_me_mapping.py +65 -0
- package/browser/addons/vrm/common/human_bone_mapper/reallusion_mapping.py +94 -0
- package/browser/addons/vrm/common/human_bone_mapper/rigify_meta_rig_mapping.py +65 -0
- package/browser/addons/vrm/common/human_bone_mapper/structure_based_mapping.py +891 -0
- package/browser/addons/vrm/common/human_bone_mapper/unreal_mapping.py +62 -0
- package/browser/addons/vrm/common/human_bone_mapper/vrm_addon_mapping.py +112 -0
- package/browser/addons/vrm/common/human_bone_mapper/vroid_mapping.py +89 -0
- package/browser/addons/vrm/common/legacy_gltf.py +16 -0
- package/browser/addons/vrm/common/logger.py +84 -0
- package/browser/addons/vrm/common/mtoon0.blend +0 -0
- package/browser/addons/vrm/common/mtoon1.blend +0 -0
- package/browser/addons/vrm/common/mtoon1_outline.blend +0 -0
- package/browser/addons/vrm/common/mtoon_auto_setup.blend +0 -0
- package/browser/addons/vrm/common/mtoon_unversioned.py +62 -0
- package/browser/addons/vrm/common/ops/__init__.py +10 -0
- package/browser/addons/vrm/common/ops/export_scene.py +67 -0
- package/browser/addons/vrm/common/ops/icyp.py +53 -0
- package/browser/addons/vrm/common/ops/import_scene.py +57 -0
- package/browser/addons/vrm/common/ops/vrm.py +2380 -0
- package/browser/addons/vrm/common/ops/wm.py +167 -0
- package/browser/addons/vrm/common/preferences.py +362 -0
- package/browser/addons/vrm/common/progress.py +87 -0
- package/browser/addons/vrm/common/rotation.py +89 -0
- package/browser/addons/vrm/common/safe_removal.py +46 -0
- package/browser/addons/vrm/common/scene_watcher.py +230 -0
- package/browser/addons/vrm/common/shader.py +2243 -0
- package/browser/addons/vrm/common/shape_key_mapper/__init__.py +1 -0
- package/browser/addons/vrm/common/shape_key_mapper/arkit_mapping.py +168 -0
- package/browser/addons/vrm/common/shape_key_mapper/mmd_mapping.py +62 -0
- package/browser/addons/vrm/common/shape_key_mapper/ready_player_me_mapping.py +52 -0
- package/browser/addons/vrm/common/shape_key_mapper/vrchat_mapping.py +17 -0
- package/browser/addons/vrm/common/third_party_user_extension.py +214 -0
- package/browser/addons/vrm/common/transparent_z_write.blend +0 -0
- package/browser/addons/vrm/common/version.py +161 -0
- package/browser/addons/vrm/common/vrm0/__init__.py +1 -0
- package/browser/addons/vrm/common/vrm0/human_bone.py +662 -0
- package/browser/addons/vrm/common/vrm0/material_property.py +346 -0
- package/browser/addons/vrm/common/vrm1/__init__.py +1 -0
- package/browser/addons/vrm/common/vrm1/expression_preset.py +207 -0
- package/browser/addons/vrm/common/vrm1/human_bone.py +822 -0
- package/browser/addons/vrm/common/workspace.py +227 -0
- package/browser/addons/vrm/common/writable_context.py +77 -0
- package/browser/addons/vrm/documentation/en-us/animation/index.md +63 -0
- package/browser/addons/vrm/documentation/en-us/create-humanoid-vrm-from-scratch/index.md +131 -0
- package/browser/addons/vrm/documentation/en-us/create-simple-vrm-from-scratch/index.md +30 -0
- package/browser/addons/vrm/documentation/en-us/development/index.md +136 -0
- package/browser/addons/vrm/documentation/en-us/index.md +41 -0
- package/browser/addons/vrm/documentation/en-us/installation/index.md +152 -0
- package/browser/addons/vrm/documentation/en-us/material-mtoon/index.md +122 -0
- package/browser/addons/vrm/documentation/en-us/material-pbr/index.md +94 -0
- package/browser/addons/vrm/documentation/en-us/scripting-api/index.md +391 -0
- package/browser/addons/vrm/documentation/en-us/ui/export_scene.vrm/index.md +57 -0
- package/browser/addons/vrm/documentation/en-us/ui/export_scene.vrma/index.md +17 -0
- package/browser/addons/vrm/documentation/en-us/ui/import_scene.vrm/index.md +61 -0
- package/browser/addons/vrm/documentation/en-us/ui/import_scene.vrma/index.md +13 -0
- package/browser/addons/vrm/documentation/ja-jp/animation/index.md +57 -0
- package/browser/addons/vrm/documentation/ja-jp/create-humanoid-vrm-from-scratch/index.md +129 -0
- package/browser/addons/vrm/documentation/ja-jp/create-simple-vrm-from-scratch/index.md +29 -0
- package/browser/addons/vrm/documentation/ja-jp/development/index.md +137 -0
- package/browser/addons/vrm/documentation/ja-jp/index.md +37 -0
- package/browser/addons/vrm/documentation/ja-jp/installation/index.md +150 -0
- package/browser/addons/vrm/documentation/ja-jp/material-mtoon/index.md +113 -0
- package/browser/addons/vrm/documentation/ja-jp/material-pbr/index.md +90 -0
- package/browser/addons/vrm/documentation/ja-jp/scripting-api/index.md +389 -0
- package/browser/addons/vrm/documentation/ja-jp/ui/export_scene.vrm/index.md +55 -0
- package/browser/addons/vrm/documentation/ja-jp/ui/export_scene.vrma/index.md +19 -0
- package/browser/addons/vrm/documentation/ja-jp/ui/import_scene.vrm/index.md +56 -0
- package/browser/addons/vrm/documentation/ja-jp/ui/import_scene.vrma/index.md +14 -0
- package/browser/addons/vrm/editor/__init__.py +1 -0
- package/browser/addons/vrm/editor/extension.py +425 -0
- package/browser/addons/vrm/editor/extension_accessor.py +75 -0
- package/browser/addons/vrm/editor/handler.py +84 -0
- package/browser/addons/vrm/editor/khr_character/__init__.py +1 -0
- package/browser/addons/vrm/editor/khr_character/panel.py +69 -0
- package/browser/addons/vrm/editor/khr_character/property_group.py +27 -0
- package/browser/addons/vrm/editor/khr_xmp_json_ld/__init__.py +1 -0
- package/browser/addons/vrm/editor/khr_xmp_json_ld/ops.py +464 -0
- package/browser/addons/vrm/editor/khr_xmp_json_ld/panel.py +136 -0
- package/browser/addons/vrm/editor/khr_xmp_json_ld/property_group.py +83 -0
- package/browser/addons/vrm/editor/khr_xmp_json_ld/ui_list.py +198 -0
- package/browser/addons/vrm/editor/make_armature.py +709 -0
- package/browser/addons/vrm/editor/menu.py +147 -0
- package/browser/addons/vrm/editor/migration.py +297 -0
- package/browser/addons/vrm/editor/mtoon1/__init__.py +1 -0
- package/browser/addons/vrm/editor/mtoon1/handler.py +20 -0
- package/browser/addons/vrm/editor/mtoon1/migration.py +536 -0
- package/browser/addons/vrm/editor/mtoon1/ops.py +304 -0
- package/browser/addons/vrm/editor/mtoon1/panel.py +442 -0
- package/browser/addons/vrm/editor/mtoon1/property_group.py +4977 -0
- package/browser/addons/vrm/editor/mtoon1/scene_watcher.py +381 -0
- package/browser/addons/vrm/editor/node_constraint1/__init__.py +1 -0
- package/browser/addons/vrm/editor/node_constraint1/panel.py +317 -0
- package/browser/addons/vrm/editor/node_constraint1/property_group.py +25 -0
- package/browser/addons/vrm/editor/ops.py +471 -0
- package/browser/addons/vrm/editor/panel.py +315 -0
- package/browser/addons/vrm/editor/property_group.py +888 -0
- package/browser/addons/vrm/editor/search.py +682 -0
- package/browser/addons/vrm/editor/spring_bone1/__init__.py +1 -0
- package/browser/addons/vrm/editor/spring_bone1/handler.py +994 -0
- package/browser/addons/vrm/editor/spring_bone1/menu.py +246 -0
- package/browser/addons/vrm/editor/spring_bone1/migration.py +86 -0
- package/browser/addons/vrm/editor/spring_bone1/ops.py +1679 -0
- package/browser/addons/vrm/editor/spring_bone1/panel.py +605 -0
- package/browser/addons/vrm/editor/spring_bone1/property_group.py +1457 -0
- package/browser/addons/vrm/editor/spring_bone1/ui_list.py +408 -0
- package/browser/addons/vrm/editor/subscription.py +123 -0
- package/browser/addons/vrm/editor/t_pose.py +713 -0
- package/browser/addons/vrm/editor/validation.py +1271 -0
- package/browser/addons/vrm/editor/vrm0/__init__.py +1 -0
- package/browser/addons/vrm/editor/vrm0/gizmo_group.py +63 -0
- package/browser/addons/vrm/editor/vrm0/handler.py +23 -0
- package/browser/addons/vrm/editor/vrm0/menu.py +145 -0
- package/browser/addons/vrm/editor/vrm0/migration.py +761 -0
- package/browser/addons/vrm/editor/vrm0/ops.py +2145 -0
- package/browser/addons/vrm/editor/vrm0/panel.py +1333 -0
- package/browser/addons/vrm/editor/vrm0/property_group.py +1818 -0
- package/browser/addons/vrm/editor/vrm0/ui_list.py +688 -0
- package/browser/addons/vrm/editor/vrm1/__init__.py +1 -0
- package/browser/addons/vrm/editor/vrm1/handler.py +28 -0
- package/browser/addons/vrm/editor/vrm1/menu.py +76 -0
- package/browser/addons/vrm/editor/vrm1/migration.py +321 -0
- package/browser/addons/vrm/editor/vrm1/ops.py +2679 -0
- package/browser/addons/vrm/editor/vrm1/panel.py +1243 -0
- package/browser/addons/vrm/editor/vrm1/property_group.py +2087 -0
- package/browser/addons/vrm/editor/vrm1/scene_watcher.py +90 -0
- package/browser/addons/vrm/editor/vrm1/ui_list.py +533 -0
- package/browser/addons/vrm/exporter/__init__.py +1 -0
- package/browser/addons/vrm/exporter/abstract_base_vrm_exporter.py +628 -0
- package/browser/addons/vrm/exporter/export_scene.py +930 -0
- package/browser/addons/vrm/exporter/gltf2_export_user_extension.py +45 -0
- package/browser/addons/vrm/exporter/khr_character_exporter.py +34 -0
- package/browser/addons/vrm/exporter/vrm0_exporter.py +4020 -0
- package/browser/addons/vrm/exporter/vrm1_exporter.py +3682 -0
- package/browser/addons/vrm/exporter/vrm_animation_exporter.py +1035 -0
- package/browser/addons/vrm/external/__init__.py +1 -0
- package/browser/addons/vrm/external/auto_rig_pro_support.py +3 -0
- package/browser/addons/vrm/external/io_scene_gltf2_support.py +418 -0
- package/browser/addons/vrm/external/rigify_support.py +1 -0
- package/browser/addons/vrm/importer/__init__.py +1 -0
- package/browser/addons/vrm/importer/abstract_base_vrm_importer.py +1548 -0
- package/browser/addons/vrm/importer/file_handler.py +34 -0
- package/browser/addons/vrm/importer/gltf2_import_user_extension.py +268 -0
- package/browser/addons/vrm/importer/import_scene.py +646 -0
- package/browser/addons/vrm/importer/license_validation.py +198 -0
- package/browser/addons/vrm/importer/vrm0_importer.py +1723 -0
- package/browser/addons/vrm/importer/vrm1_importer.py +2014 -0
- package/browser/addons/vrm/importer/vrm_animation_importer.py +763 -0
- package/browser/addons/vrm/importer/vrm_diff.py +316 -0
- package/browser/addons/vrm/locale/__init__.py +1 -0
- package/browser/addons/vrm/locale/ja_jp.py +826 -0
- package/browser/addons/vrm/locale/ruff.toml +8 -0
- package/browser/addons/vrm/locale/translation_dictionary.py +10 -0
- package/browser/addons/vrm/locale/zh_hans.py +928 -0
- package/browser/addons/vrm/registration.py +670 -0
- package/browser/addons/vrm.json +18 -0
- package/browser/blender-emscripten-engine.mts +66 -129
- package/browser/blender-engine.mts +20 -186
- package/browser/blender-wali-engine.mts +37 -81
- package/browser/describe-thrown.mts +3 -6
- package/browser/document-chunks.mts +4 -16
- package/browser/gltf_export.py +3161 -0
- package/browser/heap-growth.mts +23 -0
- package/browser/index.ts +3 -0
- package/browser/protocol.ts +130 -43
- package/browser/pull-job.mts +2 -10
- package/browser/rna.ts +190 -73
- package/browser/runtime.ts +271 -106
- package/browser/session-addons.mts +33 -0
- package/browser/session-frame.mts +5 -24
- package/browser/session.py +1389 -1446
- package/browser/three/attach-presenter.ts +11 -39
- package/browser/three/blender-base64.ts +1 -36
- package/browser/three/blender-corner-normals.ts +1 -23
- package/browser/three/blender-display-shaders.json +1 -1
- package/browser/three/blender-display-shaders.lut +0 -0
- package/browser/three/blender-display-transform.ts +2 -1
- package/browser/three/blender-frame-columns.ts +5 -13
- package/browser/three/blender-graph-material.ts +18 -3
- package/browser/three/blender-node-graph.ts +10 -34
- package/browser/three/blender-physical-material.ts +2 -31
- package/browser/three/blender-runtime-armature.ts +7 -60
- package/browser/three/blender-runtime-frame.ts +9 -23
- package/browser/three/blender-runtime-geometry.ts +22 -26
- package/browser/three/blender-runtime-lighting.ts +48 -178
- package/browser/three/blender-runtime-shadows.ts +187 -1
- package/browser/three/blender-runtime-skeleton.ts +53 -1
- package/browser/three/blender-runtime-view.ts +492 -306
- package/browser/three/blender-runtime-weights.ts +9 -72
- package/browser/three/blender-sky.ts +13 -33
- package/browser/three/blender-triangulate.ts +7 -35
- package/browser/three/blender-viewport-sampling.ts +235 -0
- package/browser/three/blender-workbench-material.ts +25 -29
- package/browser/three/blender-workbench-outline.ts +199 -0
- package/browser/three/blender-world-volume.ts +62 -10
- package/browser/three/presenter.ts +10 -26
- package/browser/three/release.ts +5 -21
- package/browser/three/sky-precompute-worker.ts +1 -18
- package/browser/three/sky-worker.ts +5 -23
- package/browser/three/world-field-sampler.ts +12 -26
- package/browser/volter_three.py +9 -105
- package/browser/worker.ts +195 -180
- package/package.json +5 -2
- package/wasm/BUNDLE.json +17 -17
- package/wasm/DEPENDENCY-LICENSES.txt +14 -0
- package/wasm/blender_browser.data.br +0 -0
- package/wasm/blender_browser.js +1 -1
- package/wasm/blender_browser.wasm.br +0 -0
- package/browser/frame-transfer.mts +0 -19
- package/browser/three/agx-base-srgb.lut +0 -0
- package/browser/three/agx-look-medium-high-contrast.lut +0 -0
- package/browser/three/agx-look-punchy.lut +0 -0
- package/browser/three/blender-agx.ts +0 -235
- package/browser/three/blender-display-lut.ts +0 -145
- package/browser/three/blender-filmic.ts +0 -49
- package/browser/three/blender-standard.ts +0 -68
- package/browser/three/blender-world-visibility.ts +0 -278
- package/browser/three/filmic-srgb.lut +0 -0
|
@@ -1,25 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* other half, for a host that holds that directory as a filesystem in its own
|
|
7
|
-
* realm. It is the whole of what a host must do: hand it the filesystem, the
|
|
8
|
-
* root the program was told to ask at, and a presenter
|
|
9
|
-
* (`./presenter`'s `createPresenter()`, or the editor's own document wrapped
|
|
10
|
-
* around the same translation).
|
|
11
|
-
*
|
|
12
|
-
* ONE WRITER PER DIRECTORY, which is the channel's single structural rule:
|
|
13
|
-
* the guest writes and unlinks `ask/<n>.*`, this file writes and unlinks
|
|
14
|
-
* `reply/<n>.*`, and neither ever touches the other's. Under a snapshot-backed
|
|
15
|
-
* skew (WALI) a crossing edit is not a race but a terminated program -- the
|
|
16
|
-
* host refuses a patch whose base moved under it.
|
|
17
|
-
*
|
|
18
|
-
* THE TRIGGER IS THE GUEST'S OWN `.done` FILE, never a timer: the filesystem
|
|
19
|
-
* announces the write, this serves the ask, and the guest's removal of its
|
|
20
|
-
* `ask/<n>.json` is the acknowledgement that lets the reply be retired.
|
|
2
|
+
* Attach a presenter to the filesystem channel used by volter_three.py’s render override. The guest
|
|
3
|
+
* owns ask/<n>.*, the host owns reply/<n>.*, and each creates, writes and removes only its own
|
|
4
|
+
* files. A guest .done write triggers an answer; removal of the ask JSON acknowledges it and
|
|
5
|
+
* permits reply cleanup. Snapshot-backed filesystems require this single-writer ownership.
|
|
21
6
|
*/
|
|
22
7
|
import { columnsToTypedArrays, describeFrame } from '../session-frame.mts';
|
|
8
|
+
import type { PresentAnswer } from '../runtime';
|
|
23
9
|
|
|
24
10
|
/** The host filesystem seam, in exactly the shape this file uses. */
|
|
25
11
|
export interface PresenterFileSystem {
|
|
@@ -34,7 +20,7 @@ export interface PresenterFileSystem {
|
|
|
34
20
|
|
|
35
21
|
/** What `createPresenter()` returns, in the part this file uses. */
|
|
36
22
|
export interface AttachablePresenter {
|
|
37
|
-
present(frame: unknown, description: unknown, capture?: unknown): Promise<
|
|
23
|
+
present(frame: unknown, description: unknown, capture?: unknown): Promise<PresentAnswer>;
|
|
38
24
|
}
|
|
39
25
|
|
|
40
26
|
export function attachPresenter(
|
|
@@ -44,21 +30,7 @@ export function attachPresenter(
|
|
|
44
30
|
): () => void {
|
|
45
31
|
const askDirectory = `${root}/ask`;
|
|
46
32
|
const decoder = new TextDecoder();
|
|
47
|
-
/**
|
|
48
|
-
* Asks answered and not yet acknowledged -- this is also the "already
|
|
49
|
-
* served" test, and it may not be replaced by a highest-id watermark or a
|
|
50
|
-
* set that outlives an ask.
|
|
51
|
-
*
|
|
52
|
-
* ONE PRESENTER SERVES MANY PROCESSES, and every process starts its ask
|
|
53
|
-
* sequence at 0 again: the numbers are a conversation's, not a page's.
|
|
54
|
-
* MEASURED 2026-09-20 in the substrate tab with a page-lifetime `served`
|
|
55
|
-
* set: the first `blender -b … -a` photographed twelve frames at ~0.30 s,
|
|
56
|
-
* and every later one had its `ask/0` ("hello") skipped as already served,
|
|
57
|
-
* printed the no-presenter line and path traced with Cycles at ~1.40 s a
|
|
58
|
-
* frame -- a fallback that looked like a slow success. The ack is what
|
|
59
|
-
* closes an ask: the guest removes `ask/<n>.*` once it has read the reply,
|
|
60
|
-
* and this set is emptied by that.
|
|
61
|
-
*/
|
|
33
|
+
/** Track answered asks until acknowledgement. Each process restarts its ask sequence, so ids cannot be deduplicated across processes or retained after their ask files disappear. */
|
|
62
34
|
const replied = new Set<string>();
|
|
63
35
|
let attached = true;
|
|
64
36
|
let pumping: Promise<void> = Promise.resolve();
|
|
@@ -72,19 +44,19 @@ export function attachPresenter(
|
|
|
72
44
|
};
|
|
73
45
|
if (payload.op === 'hello') return { ok: true };
|
|
74
46
|
const arena = await filesystem.readFile(payload.arena ?? `${root}/arena.bin`);
|
|
75
|
-
const answered =
|
|
47
|
+
const answered = await presenter.present(
|
|
76
48
|
columnsToTypedArrays(arena, payload.frame),
|
|
77
49
|
await describeFrame(arena, payload.frame),
|
|
78
50
|
payload.capture,
|
|
79
|
-
)
|
|
51
|
+
);
|
|
80
52
|
// THE CAPTURE IS THE ANSWER'S BODY and `held` rides beside it, exactly as
|
|
81
53
|
// the editor's worker composes it: the guest reads a photograph's own
|
|
82
54
|
// fields off this object.
|
|
83
55
|
const body =
|
|
84
|
-
typeof answered
|
|
56
|
+
typeof answered.capture === 'object' && answered.capture !== null
|
|
85
57
|
? (answered.capture as Record<string, unknown>)
|
|
86
58
|
: {};
|
|
87
|
-
return { ...body, ...(
|
|
59
|
+
return { ...body, ...('held' in answered ? { held: answered.held } : {}) };
|
|
88
60
|
}
|
|
89
61
|
|
|
90
62
|
async function pump(): Promise<void> {
|
|
@@ -1,42 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Base64 → bytes, as a PLAIN LOOP.
|
|
3
|
-
*
|
|
4
|
-
* `Uint8Array.from(atob(text), (c) => c.charCodeAt(0))` is the obvious form and
|
|
5
|
-
* it is a trap: the mapping callback is invoked ONCE PER CHARACTER, so decoding
|
|
6
|
-
* scales with call overhead rather than with a memory copy. Measured against
|
|
7
|
-
* the loop below, byte-identical output throughout: 1MB 63ms vs 4ms (16.9x),
|
|
8
|
-
* 3MB 224ms vs 8ms (27.7x), 8MB 545ms vs 19ms (28.9x). Textures and EXR frames
|
|
9
|
-
* are routinely multi-megabyte and one of these decodes runs on the page's main
|
|
10
|
-
* thread, so the callback form is never the right one here.
|
|
11
|
-
*/
|
|
1
|
+
/** Decode base64 with a plain loop to avoid one callback invocation per byte. */
|
|
12
2
|
export function bytesFromBase64(text: string): Uint8Array<ArrayBuffer> {
|
|
13
3
|
const binary = atob(text);
|
|
14
4
|
const out = new Uint8Array(binary.length);
|
|
15
5
|
for (let i = 0; i < binary.length; i++) out[i] = binary.charCodeAt(i);
|
|
16
6
|
return out;
|
|
17
7
|
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Bytes → base64, the way back.
|
|
21
|
-
*
|
|
22
|
-
* `String.fromCharCode(...bytes)` in one call overflows the argument stack on
|
|
23
|
-
* anything megabyte-sized, so the string is built in 32K spreads. Extracted
|
|
24
|
-
* from the Blender worker's `encode_image`, which had exactly this
|
|
25
|
-
* loop; a frame's JSON channel needs the same conversion for a raster that has
|
|
26
|
-
* no transferable buffer to travel in.
|
|
27
|
-
*/
|
|
28
|
-
export function base64FromBytes(bytes: Uint8Array): string {
|
|
29
|
-
let binary = '';
|
|
30
|
-
for (let i = 0; i < bytes.length; i += 0x8000)
|
|
31
|
-
binary += String.fromCharCode(...bytes.subarray(i, i + 0x8000));
|
|
32
|
-
return btoa(binary);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/** {@link bytesFromBase64} for callers that want an 8-bit RGBA raster's own
|
|
36
|
-
* element type (`ImageData.data`'s), rather than a plain byte array. */
|
|
37
|
-
export function clampedBytesFromBase64(text: string): Uint8ClampedArray<ArrayBuffer> {
|
|
38
|
-
const binary = atob(text);
|
|
39
|
-
const out = new Uint8ClampedArray(binary.length);
|
|
40
|
-
for (let i = 0; i < binary.length; i++) out[i] = binary.charCodeAt(i);
|
|
41
|
-
return out;
|
|
42
|
-
}
|
|
@@ -7,9 +7,7 @@
|
|
|
7
7
|
export type Normal = [number, number, number];
|
|
8
8
|
|
|
9
9
|
/** `normalize_v3` (`blenlib/intern/math_vector.cc`), returning the length it
|
|
10
|
-
* divided by; a zero-length vector stays zero.
|
|
11
|
-
* `face-interpolation.ts` when this file became `@volter/editor-blender`'s — it is the
|
|
12
|
-
* one function of that module this drawing path used. Float width is part of
|
|
10
|
+
* divided by; a zero-length vector stays zero. Float width is part of
|
|
13
11
|
* the answer: native computes it in `float`, so every step is `Math.fround`. */
|
|
14
12
|
function normalize3(n: Normal): { unit: Normal; length: number } {
|
|
15
13
|
const w = Math.fround;
|
|
@@ -367,26 +365,6 @@ export function setCustomNormals(
|
|
|
367
365
|
return { customNormal, sharpEdge: Uint8Array.from(sharp, (x) => (x ? 1 : 0)) };
|
|
368
366
|
}
|
|
369
367
|
|
|
370
|
-
/**
|
|
371
|
-
* `Mesh::corner_normals`: one normal per corner, whatever the mesh carries.
|
|
372
|
-
*
|
|
373
|
-
* The decoded custom normals where a `custom_normal` layer exists, and the
|
|
374
|
-
* smooth fans' own auto normals where it does not — the split-normal answer,
|
|
375
|
-
* with sharp edges and flat faces already respected because they are what
|
|
376
|
-
* `normalFans` splits the fans on. ONE function so a reader of corner normals
|
|
377
|
-
* never has to know which of the two it is looking at; both halves are the
|
|
378
|
-
* same fans, computed once.
|
|
379
|
-
*/
|
|
380
|
-
export function cornerNormals(
|
|
381
|
-
mesh: NormalMesh,
|
|
382
|
-
attribute?: Parameters<typeof customCornerNormals>[1],
|
|
383
|
-
): Normal[] {
|
|
384
|
-
const custom = customCornerNormals(mesh, attribute);
|
|
385
|
-
if (custom) return custom;
|
|
386
|
-
const { corners, fanOf, fanNormals } = normalFans(mesh);
|
|
387
|
-
return corners.map((_, c) => fanNormals[fanOf[c]!]!);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
368
|
/** Read custom attributes at the geometry boundary, preserving corner splits. */
|
|
391
369
|
export function customCornerNormals(
|
|
392
370
|
mesh: NormalMesh,
|