Compare commits
10 Commits
fb97114207
...
ad2dd979eb
| Author | SHA1 | Date | |
|---|---|---|---|
| ad2dd979eb | |||
| ada597137f | |||
| 218f4f31f0 | |||
| b70084acdb | |||
| a358340e2d | |||
| d0eb574f62 | |||
| 1f810ef5e2 | |||
| fed4277a7c | |||
| ebfa52b990 | |||
| c84bc60d8c |
2
.gitignore
vendored
2
.gitignore
vendored
@ -12,8 +12,6 @@ dist
|
|||||||
dist-ssr
|
dist-ssr
|
||||||
*.local
|
*.local
|
||||||
|
|
||||||
packages/examples
|
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
.vscode/*
|
.vscode/*
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
|
|||||||
49
.prettierrc.js
Normal file
49
.prettierrc.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/** @type {import("prettier").Config} */
|
||||||
|
module.exports = {
|
||||||
|
// 一行最多160字符
|
||||||
|
printWidth: 160,
|
||||||
|
// 指定一个制表符等于的空格数
|
||||||
|
tabWidth: 4,
|
||||||
|
// 使用制表符,而不使用空格
|
||||||
|
useTabs: true,
|
||||||
|
// 行尾需要有分号
|
||||||
|
semi: true,
|
||||||
|
// 使用单引号代替双引号
|
||||||
|
singleQuote: false,
|
||||||
|
// 默认值。因为使用了一些折行敏感型的渲染器(如GitHub comment)而按照markdown文本样式进行折行
|
||||||
|
proseWrap: "preserve",
|
||||||
|
// 对象的key仅在必要时用引号括起来
|
||||||
|
quoteProps: "as-needed",
|
||||||
|
// 尾逗号根据ES5规则使用
|
||||||
|
trailingComma: "es5",
|
||||||
|
// 在对象,数组括号与文字之间加空格 "{ foo: bar }"
|
||||||
|
bracketSpacing: true,
|
||||||
|
// (x) => {} 箭头函数参数只有一个时是否要有小括号。avoid:省略括号
|
||||||
|
arrowParens: "avoid",
|
||||||
|
// 指定 HTML 文件的空白字符敏感度
|
||||||
|
htmlWhitespaceSensitivity: "ignore",
|
||||||
|
// 缩进 Vue SFC 文件中的 <script> 和 <style> 标签
|
||||||
|
vueIndentScriptAndStyle: true,
|
||||||
|
// 结尾是 \n \r \n\r auto
|
||||||
|
endOfLine: "auto",
|
||||||
|
// 在jsx中使用单引号代替双引号
|
||||||
|
jsxSingleQuote: false,
|
||||||
|
// 在jsx中是否把'>' 单独放一行
|
||||||
|
bracketSameLine: false,
|
||||||
|
// === 不同文件的定制 ===
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: "*.md",
|
||||||
|
options: {
|
||||||
|
printWidth: 120,
|
||||||
|
proseWrap: "preserve",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: "*.json",
|
||||||
|
options: {
|
||||||
|
printWidth: 120,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
🌍 [简体中文](README.md) | English
|
🌍 [简体中文](README.md) | English
|
||||||
|
|
||||||
|
|
||||||
|
Link:
|
||||||
|
[](https://github.com/mlt131220/Astral3D)
|
||||||
|
[](https://gitee.com/mlt131220/Astral3D)
|
||||||
[](https://editor.astraljs.com)
|
[](https://editor.astraljs.com)
|
||||||
|
|
||||||
> Modern Web 3D editor based on Vue3 + Three.js
|
> Modern Web 3D editor based on Vue3 + Three.js
|
||||||
@ -17,7 +21,7 @@ Get the latest news and technical support in the following ways:
|
|||||||
|
|
||||||
|  | -07C160?logo=wechat&logoColor=white) |
|
|  | -07C160?logo=wechat&logoColor=white) |
|
||||||
|---------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|---------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| <img src="https://fs.mhbdng.cn/astral3d/4851677b-661d-4e60-884d-414316290425.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=NQQLQF1YWRT2TJD5FA27%2F20251004%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20251004T155028Z&X-Amz-Expires=3600&X-Amz-Security-Token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJwYXJlbnQiOiJtbHQxMzEyMjAiLCJleHAiOjE3NTk2MjQ5MTJ9.j5yb8tpX9-NR38EzzO3TCYKkTy8gvDMV8KaLNIsqMiHdxrIgmE8TKQspHvnRhRJPrcOMJyYGnT_4AVPlAdZLyw&X-Amz-Signature=3f3f323627ece52ddc5b47d05a673363b0403540edaf1cc9bf6a2ff225738ba0&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" width="200"> | <img src="https://fs.mhbdng.cn/astral3d/c1c7ecef-d655-4bb3-97e8-54402e3a48ef.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=NQQLQF1YWRT2TJD5FA27%2F20251004%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20251004T154710Z&X-Amz-Expires=3600&X-Amz-Security-Token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJwYXJlbnQiOiJtbHQxMzEyMjAiLCJleHAiOjE3NTk2MjQ5MTJ9.j5yb8tpX9-NR38EzzO3TCYKkTy8gvDMV8KaLNIsqMiHdxrIgmE8TKQspHvnRhRJPrcOMJyYGnT_4AVPlAdZLyw&X-Amz-Signature=88d0a04a67c06812258d6cd60bea6875b993008b859b51e6c0c83395ccf41aa1&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" width="200"> |
|
| <img src="https://fs.mhbdng.cn/temp/4851677b-661d-4e60-884d-414316290425.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=6TE7OKPZN15R380TGT1V%2F20260111%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260111T135452Z&X-Amz-Expires=3600&X-Amz-Security-Token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJwYXJlbnQiOiJtbHQxMzEyMjAiLCJleHAiOjE3NjgxODExNTV9.RAvlAnLKtG-9rNIZMrO5lrSJc_N1VqHf3yF3-slD59b-miNqdorqsI9Zmaz6_imBe_uw1u5KMt_OGE7No-vxfA&X-Amz-Signature=4868484133727ab3881d0f7eb65a52db07ee91bc154b4bf4b88d19a91446188e&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" width="200"> | <img src="https://fs.mhbdng.cn/temp/c1c7ecef-d655-4bb3-97e8-54402e3a48ef.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=6TE7OKPZN15R380TGT1V%2F20260111%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260111T135514Z&X-Amz-Expires=3600&X-Amz-Security-Token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJwYXJlbnQiOiJtbHQxMzEyMjAiLCJleHAiOjE3NjgxODExNTV9.RAvlAnLKtG-9rNIZMrO5lrSJc_N1VqHf3yF3-slD59b-miNqdorqsI9Zmaz6_imBe_uw1u5KMt_OGE7No-vxfA&X-Amz-Signature=7005038e2ded3dbad425f6a23341002bf79c3ffe9f2166af18348dcaeb61dca0&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" width="200"> |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
🌍 简体中文 | [English](README.en.md)
|
🌍 简体中文 | [English](README.en.md)
|
||||||
|
|
||||||
|
直达:
|
||||||
|
[](https://github.com/mlt131220/Astral3D)
|
||||||
|
[](https://gitee.com/mlt131220/Astral3D)
|
||||||
[](https://editor.astraljs.com)
|
[](https://editor.astraljs.com)
|
||||||
|
|
||||||
> 基于 Vue3 + Three.js 的现代 Web 3D 编辑器
|
> 基于 Vue3 + Three.js 的现代 Web 3D 编辑器
|
||||||
@ -15,9 +18,9 @@
|
|||||||
|
|
||||||
通过以下方式获取最新动态和技术支持:
|
通过以下方式获取最新动态和技术支持:
|
||||||
|
|
||||||
|  | -07C160?logo=wechat&logoColor=white) |
|
|  | -07C160?logo=wechat&logoColor=white)
|
||||||
|------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|---------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| <img src="https://fs.mhbdng.cn/astral3d/4851677b-661d-4e60-884d-414316290425.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=NQQLQF1YWRT2TJD5FA27%2F20251004%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20251004T155028Z&X-Amz-Expires=3600&X-Amz-Security-Token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJwYXJlbnQiOiJtbHQxMzEyMjAiLCJleHAiOjE3NTk2MjQ5MTJ9.j5yb8tpX9-NR38EzzO3TCYKkTy8gvDMV8KaLNIsqMiHdxrIgmE8TKQspHvnRhRJPrcOMJyYGnT_4AVPlAdZLyw&X-Amz-Signature=3f3f323627ece52ddc5b47d05a673363b0403540edaf1cc9bf6a2ff225738ba0&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" width="200"> | <img src="https://fs.mhbdng.cn/astral3d/c1c7ecef-d655-4bb3-97e8-54402e3a48ef.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=NQQLQF1YWRT2TJD5FA27%2F20251004%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20251004T154710Z&X-Amz-Expires=3600&X-Amz-Security-Token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJwYXJlbnQiOiJtbHQxMzEyMjAiLCJleHAiOjE3NTk2MjQ5MTJ9.j5yb8tpX9-NR38EzzO3TCYKkTy8gvDMV8KaLNIsqMiHdxrIgmE8TKQspHvnRhRJPrcOMJyYGnT_4AVPlAdZLyw&X-Amz-Signature=88d0a04a67c06812258d6cd60bea6875b993008b859b51e6c0c83395ccf41aa1&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" width="200"> |
|
| <img src="https://fs.mhbdng.cn/temp/4851677b-661d-4e60-884d-414316290425.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=6TE7OKPZN15R380TGT1V%2F20260111%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260111T135452Z&X-Amz-Expires=3600&X-Amz-Security-Token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJwYXJlbnQiOiJtbHQxMzEyMjAiLCJleHAiOjE3NjgxODExNTV9.RAvlAnLKtG-9rNIZMrO5lrSJc_N1VqHf3yF3-slD59b-miNqdorqsI9Zmaz6_imBe_uw1u5KMt_OGE7No-vxfA&X-Amz-Signature=4868484133727ab3881d0f7eb65a52db07ee91bc154b4bf4b88d19a91446188e&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" width="200"> | <img src="https://fs.mhbdng.cn/temp/c1c7ecef-d655-4bb3-97e8-54402e3a48ef.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=6TE7OKPZN15R380TGT1V%2F20260111%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260111T135514Z&X-Amz-Expires=3600&X-Amz-Security-Token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJwYXJlbnQiOiJtbHQxMzEyMjAiLCJleHAiOjE3NjgxODExNTV9.RAvlAnLKtG-9rNIZMrO5lrSJc_N1VqHf3yF3-slD59b-miNqdorqsI9Zmaz6_imBe_uw1u5KMt_OGE7No-vxfA&X-Amz-Signature=7005038e2ded3dbad425f6a23341002bf79c3ffe9f2166af18348dcaeb61dca0&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject" width="200">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
49
package.json
49
package.json
@ -1,25 +1,28 @@
|
|||||||
{
|
{
|
||||||
"name": "astral3d",
|
"name": "astral3d",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Astral3D Engine",
|
"description": "Astral3D Engine",
|
||||||
"author": "ErSan <mlt131220@163.com>",
|
"author": "ErSan <mlt131220@163.com>",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"docs:dev": "pnpm run -C packages/docs docs:dev",
|
"docs:dev": "pnpm run -C packages/docs docs:dev",
|
||||||
"docs:dev-clean": "pnpm run -C packages/docs docs:dev-clean",
|
"docs:dev-clean": "pnpm run -C packages/docs docs:dev-clean",
|
||||||
"docs:build": "pnpm run -C packages/docs docs:build",
|
"docs:build": "pnpm run -C packages/docs docs:build",
|
||||||
"docs:preview": "pnpm run -C packages/docs docs:preview",
|
"docs:preview": "pnpm run -C packages/docs docs:preview",
|
||||||
"editor:dev": "pnpm run -C packages/editor dev",
|
"editor:dev": "pnpm run -C packages/editor dev",
|
||||||
"editor:build": "pnpm run -C packages/editor build",
|
"editor:build": "pnpm run sdk:build && pnpm run -C packages/editor build",
|
||||||
"editor:tsc": "pnpm run -C packages/editor tsc",
|
"editor:tsc": "pnpm run -C packages/editor tsc",
|
||||||
"editor:preview": "pnpm run -C packages/editor preview",
|
"editor:preview": "pnpm run -C packages/editor preview",
|
||||||
"sdk:dev": "pnpm run -C packages/sdk dev",
|
"sdk:dev": "pnpm run -C packages/sdk dev",
|
||||||
"sdk:build": "pnpm run -C packages/sdk build",
|
"sdk:build": "pnpm run -C packages/sdk build",
|
||||||
"examples:dev": "pnpm run -C packages/examples dev",
|
"examples:dev": "pnpm run -C packages/examples dev",
|
||||||
"examples:build": "pnpm run -C packages/examples build"
|
"examples:build": "pnpm run -C packages/examples build"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=23.0.0"
|
"node": ">=23.0.0"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"packageManager": "pnpm@10.8.1"
|
"devDependencies": {
|
||||||
|
"prettier": "^3.7.4"
|
||||||
|
},
|
||||||
|
"packageManager": "pnpm@10.8.1"
|
||||||
}
|
}
|
||||||
@ -11,4 +11,4 @@ VITE_GLOB_AUTHOR='ErSan'
|
|||||||
VITE_GLOB_VERSION='1.0.0'
|
VITE_GLOB_VERSION='1.0.0'
|
||||||
|
|
||||||
# 备案号
|
# 备案号
|
||||||
VITE_GLOB_BEIAN='滇ICP备2022001592号-2'
|
VITE_GLOB_BEIAN='滇ICP备XXXXXX号'
|
||||||
@ -19,4 +19,4 @@ VITE_ENABLE_CONFIG_GENERATE=true
|
|||||||
VITE_GLOB_ORIGIN=https://editor.astraljs.com/
|
VITE_GLOB_ORIGIN=https://editor.astraljs.com/
|
||||||
|
|
||||||
#ws接口
|
#ws接口
|
||||||
VITE_GLOB_SOCKET_URL=wss://editor.astraljs.com/api/sys/ws
|
VITE_GLOB_SOCKET_URL=wss://editor.astraljs.com/socket
|
||||||
@ -15,9 +15,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/colors": "^7.0.2",
|
"@ant-design/colors": "^7.0.2",
|
||||||
"@astral3d/engine": "workspace:^",
|
"@astral3d/engine": "workspace:^",
|
||||||
"@gltf-transform/core": "^4.0.8",
|
"@gltf-transform/core": "^4.2.1",
|
||||||
"@gltf-transform/extensions": "^4.0.8",
|
"@gltf-transform/extensions": "^4.2.1",
|
||||||
"@gltf-transform/functions": "^4.0.8",
|
"@gltf-transform/functions": "^4.2.1",
|
||||||
"@vicons/carbon": "^0.12.0",
|
"@vicons/carbon": "^0.12.0",
|
||||||
"@vicons/ionicons5": "^0.12.0",
|
"@vicons/ionicons5": "^0.12.0",
|
||||||
"@vueuse/core": "^13.2.0",
|
"@vueuse/core": "^13.2.0",
|
||||||
|
|||||||
BIN
packages/editor/public/wasm/Astral3DEditor.wasm
Normal file
BIN
packages/editor/public/wasm/Astral3DEditor.wasm
Normal file
Binary file not shown.
BIN
packages/editor/public/wasm/Astral3DglTFHandler.wasm
Normal file
BIN
packages/editor/public/wasm/Astral3DglTFHandler.wasm
Normal file
Binary file not shown.
@ -1,138 +1,152 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-modal :show="visible" @update:show="emits('update:visible',$event)" display-directive="show"
|
<n-modal
|
||||||
class="w-66vw h-66vh min-w-1000px" @close="emits('update:visible',false)">
|
:show="visible"
|
||||||
<n-card :title="asset.name" embedded size="small" content-class="!p-0 flex gap-x-15px" closable
|
@update:show="emits('update:visible', $event)"
|
||||||
@close="handleClose">
|
display-directive="show"
|
||||||
<div ref="assetPreviewRef" id="assetPreview"></div>
|
class="w-66vw h-66vh min-w-1000px"
|
||||||
|
@close="emits('update:visible', false)"
|
||||||
|
>
|
||||||
|
<n-card
|
||||||
|
:title="asset.name"
|
||||||
|
embedded
|
||||||
|
size="small"
|
||||||
|
content-class="!p-0 flex gap-x-15px"
|
||||||
|
content-style="height: calc(100% - 48px);"
|
||||||
|
closable
|
||||||
|
@close="handleClose"
|
||||||
|
>
|
||||||
|
<div ref="assetPreviewRef" id="assetPreview"></div>
|
||||||
|
|
||||||
<div class="w-345px mr-15px h-full">
|
<div class="w-345px mr-15px h-full">
|
||||||
<n-descriptions label-placement="left" label-class="w-100px" bordered :column="1">
|
<n-descriptions label-placement="left" label-class="w-100px" bordered :column="1">
|
||||||
<n-descriptions-item :label="t('home.assets.Name')">
|
<n-descriptions-item :label="t('home.assets.Name')">
|
||||||
{{ asset.name }}
|
{{ asset.name }}
|
||||||
</n-descriptions-item>
|
</n-descriptions-item>
|
||||||
<n-descriptions-item :label="t('home.assets.Type')">
|
<n-descriptions-item :label="t('home.assets.Type')">
|
||||||
{{ t(`home.assets.${asset.type}`) }}
|
{{ t(`home.assets.${asset.type}`) }}
|
||||||
</n-descriptions-item>
|
</n-descriptions-item>
|
||||||
<n-descriptions-item :label="t('home.assets.Category')">
|
<n-descriptions-item :label="t('home.assets.Category')">
|
||||||
{{ asset.categoryName || asset.category }}
|
{{ asset.categoryName || asset.category }}
|
||||||
</n-descriptions-item>
|
</n-descriptions-item>
|
||||||
<n-descriptions-item :label="t('bim.Thumbnail')">
|
<n-descriptions-item :label="t('bim.Thumbnail')">
|
||||||
<n-image
|
<n-image width="120" :src="getServiceStaticFile(asset.thumbnail)" />
|
||||||
width="120"
|
{{}}
|
||||||
:src="getServiceStaticFile(asset.thumbnail)"
|
</n-descriptions-item>
|
||||||
/>
|
<n-descriptions-item :label="t('home.assets.Size')">
|
||||||
{{ }}
|
{{ filterSize(asset.size) }}
|
||||||
</n-descriptions-item>
|
</n-descriptions-item>
|
||||||
<n-descriptions-item :label="t('home.assets.Size')">
|
<n-descriptions-item :label="t('home.assets.Tags')">
|
||||||
{{ filterSize(asset.size) }}
|
<n-tag type="success" :bordered="false" class="ml-5px" v-for="tag in asset.tags ? asset.tags.split(',') : []" :key="tag">
|
||||||
</n-descriptions-item>
|
{{ tag }}
|
||||||
<n-descriptions-item :label="t('home.assets.Tags')">
|
</n-tag>
|
||||||
<n-tag type="success" :bordered="false" class="ml-5px"
|
</n-descriptions-item>
|
||||||
v-for="tag in (asset.tags ? asset.tags.split(',') : [])" :key="tag">
|
<n-descriptions-item :label="t('scene.Create time')">
|
||||||
{{ tag }}
|
{{ asset.createTime }}
|
||||||
</n-tag>
|
</n-descriptions-item>
|
||||||
</n-descriptions-item>
|
<n-descriptions-item :label="t('scene.Update time')">
|
||||||
<n-descriptions-item :label="t('scene.Create time')">
|
{{ asset.updateTime }}
|
||||||
{{ asset.createTime }}
|
</n-descriptions-item>
|
||||||
</n-descriptions-item>
|
</n-descriptions>
|
||||||
<n-descriptions-item :label="t('scene.Update time')">
|
|
||||||
{{ asset.updateTime }}
|
|
||||||
</n-descriptions-item>
|
|
||||||
</n-descriptions>
|
|
||||||
|
|
||||||
<n-button type="primary" class="w-full" :loading="downloadLoading" @click="handleDownload">
|
<n-button type="primary" class="w-full" :loading="downloadLoading" @click="handleDownload">
|
||||||
{{ t('plugin.gltfHandler.Download') }}
|
{{ t("plugin.gltfHandler.Download") }}
|
||||||
</n-button>
|
</n-button>
|
||||||
</div>
|
</div>
|
||||||
</n-card>
|
</n-card>
|
||||||
</n-modal>
|
</n-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, nextTick, watch, useTemplateRef, onBeforeUnmount} from "vue";
|
import { ref, nextTick, watch, useTemplateRef, onBeforeUnmount } from "vue";
|
||||||
import {Preview} from "@astral3d/engine";
|
import { Preview } from "@astral3d/engine";
|
||||||
import {t} from "@/language";
|
import { t } from "@/language";
|
||||||
import {downloadWithFetch, filterSize, getServiceStaticFile} from "@/utils/common/file";
|
import { downloadWithFetch, filterSize, getServiceStaticFile } from "@/utils/common/file";
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(
|
||||||
visible: boolean,
|
defineProps<{
|
||||||
asset: IAssets.Item
|
visible: boolean;
|
||||||
}>(), {
|
asset: IAssets.Item;
|
||||||
visible: false,
|
}>(),
|
||||||
asset: () => ({
|
{
|
||||||
name: "",
|
visible: false,
|
||||||
type: 'Model',
|
asset: () => ({
|
||||||
category: "",
|
name: "",
|
||||||
thumbnail: "",
|
type: "Model",
|
||||||
size: 0,
|
category: "",
|
||||||
file: '',
|
thumbnail: "",
|
||||||
createTime: "",
|
size: 0,
|
||||||
updateTime: ""
|
file: "",
|
||||||
})
|
createTime: "",
|
||||||
})
|
updateTime: "",
|
||||||
const emits = defineEmits(['update:visible'])
|
}),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const emits = defineEmits(["update:visible"]);
|
||||||
|
|
||||||
let previewer:Preview | null = null;
|
let previewer: Preview | null = null;
|
||||||
|
|
||||||
const assetPreviewRef = useTemplateRef("assetPreviewRef");
|
const assetPreviewRef = useTemplateRef("assetPreviewRef");
|
||||||
|
|
||||||
watch(() => props.visible, async (newVal) => {
|
watch(
|
||||||
if (newVal) {
|
() => props.visible,
|
||||||
if(!previewer){
|
async newVal => {
|
||||||
await nextTick();
|
if (newVal) {
|
||||||
|
if (!previewer) {
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
previewer = new Preview({
|
previewer = new Preview({
|
||||||
container: assetPreviewRef.value,
|
container: assetPreviewRef.value,
|
||||||
hdr: "/static/resource/hdr/cloudy.hdr",
|
hdr: "/static/resource/hdr/cloudy.hdr",
|
||||||
request: {
|
request: {
|
||||||
baseUrl:"/file/static/"
|
baseUrl: "/file/static/",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(props.asset.file){
|
if (props.asset.file) {
|
||||||
previewer.load(getServiceStaticFile(props.asset.file),props.asset.type);
|
previewer.load(getServiceStaticFile(props.asset.file), props.asset.type);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
disposePreviewer();
|
disposePreviewer();
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
);
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
disposePreviewer();
|
disposePreviewer();
|
||||||
})
|
});
|
||||||
|
|
||||||
function disposePreviewer() {
|
function disposePreviewer() {
|
||||||
if(previewer){
|
if (previewer) {
|
||||||
previewer.dispose();
|
previewer.dispose();
|
||||||
previewer = null;
|
previewer = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleClose() {
|
function handleClose() {
|
||||||
emits('update:visible', false);
|
emits("update:visible", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const downloadLoading = ref(false);
|
const downloadLoading = ref(false);
|
||||||
|
|
||||||
function handleDownload() {
|
function handleDownload() {
|
||||||
downloadLoading.value = true;
|
downloadLoading.value = true;
|
||||||
|
|
||||||
downloadWithFetch(getServiceStaticFile(props.asset.file)).finally(() => {
|
downloadWithFetch(getServiceStaticFile(props.asset.file)).finally(() => {
|
||||||
downloadLoading.value = false;
|
downloadLoading.value = false;
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
#assetPreview {
|
#assetPreview {
|
||||||
width: calc(100% - 360px);
|
width: calc(100% - 360px);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.n-descriptions {
|
.n-descriptions {
|
||||||
height: calc(100% - 65px);
|
height: calc(100% - 65px);
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -33,6 +33,7 @@ import {
|
|||||||
import { ALL_EXTENSIONS } from '@gltf-transform/extensions';
|
import { ALL_EXTENSIONS } from '@gltf-transform/extensions';
|
||||||
import {Session} from "./session";
|
import {Session} from "./session";
|
||||||
import {loadScript} from "@/utils/common/utils";
|
import {loadScript} from "@/utils/common/utils";
|
||||||
|
import { optimizePNG } from "@/plugin/glTFHandler/optimizePng";
|
||||||
|
|
||||||
//使用'micromatch',因为'contains: true'没有像预期的那样在minimatch中工作。需要确保'*'匹配的模式,如'image/png'。
|
//使用'micromatch',因为'contains: true'没有像预期的那样在minimatch中工作。需要确保'*'匹配的模式,如'image/png'。
|
||||||
export const MICROMATCH_OPTIONS = { nocase: true, contains: true };
|
export const MICROMATCH_OPTIONS = { nocase: true, contains: true };
|
||||||
@ -91,7 +92,6 @@ export default class GLTFHandler implements Plugin{
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.GLTFHandlerComponentRef = ref();
|
this.GLTFHandlerComponentRef = ref();
|
||||||
const finishFn = this.finish.bind(this);
|
|
||||||
this.modalInstance = window.$modal.create({
|
this.modalInstance = window.$modal.create({
|
||||||
title: this.name,
|
title: this.name,
|
||||||
preset:"card",
|
preset:"card",
|
||||||
@ -100,12 +100,12 @@ export default class GLTFHandler implements Plugin{
|
|||||||
width: '90%',
|
width: '90%',
|
||||||
maxWidth: '800px'
|
maxWidth: '800px'
|
||||||
},
|
},
|
||||||
onAfterLeave: finishFn,
|
onAfterLeave: () => this.finish(),
|
||||||
content: () => {
|
content: () => {
|
||||||
return h(GLTFHandlerComponent,{
|
return h(GLTFHandlerComponent,{
|
||||||
onOptimize:this.optimize.bind(this),
|
onOptimize: this.optimize.bind(this),
|
||||||
onFinish: finishFn,
|
onFinish: () => this.finish(),
|
||||||
ref:this.GLTFHandlerComponentRef
|
ref: this.GLTFHandlerComponentRef
|
||||||
},"")
|
},"")
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -137,7 +137,6 @@ export default class GLTFHandler implements Plugin{
|
|||||||
|
|
||||||
/* 下面是实现的自定义的处理器方法 */
|
/* 下面是实现的自定义的处理器方法 */
|
||||||
async optimize(opts:IPlugin.GLTFHandlerOptimizeModel,inputFile:File,outputFileName = ""){
|
async optimize(opts:IPlugin.GLTFHandlerOptimizeModel,inputFile:File,outputFileName = ""){
|
||||||
// console.log("调用优化处理器,",opts,inputFile)
|
|
||||||
this.setLogger(`Optimize ${inputFile.name}`);
|
this.setLogger(`Optimize ${inputFile.name}`);
|
||||||
|
|
||||||
if(this.dracoScript.failMsg){
|
if(this.dracoScript.failMsg){
|
||||||
@ -151,7 +150,10 @@ export default class GLTFHandler implements Plugin{
|
|||||||
|
|
||||||
/* 文件准备就绪,开始优化 */
|
/* 文件准备就绪,开始优化 */
|
||||||
|
|
||||||
const transforms: Transform[] = [dedup()];
|
const transforms: Transform[] = [
|
||||||
|
optimizePNG(),
|
||||||
|
dedup()
|
||||||
|
];
|
||||||
|
|
||||||
if (opts.instance) transforms.push(instance({ min: opts.instanceMin }));
|
if (opts.instance) transforms.push(instance({ min: opts.instanceMin }));
|
||||||
|
|
||||||
|
|||||||
26
packages/editor/src/plugin/glTFHandler/optimizePng.ts
Normal file
26
packages/editor/src/plugin/glTFHandler/optimizePng.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import type { Transform } from '@gltf-transform/core';
|
||||||
|
import { encodePNG } from './util';
|
||||||
|
|
||||||
|
function asUint8Array(data: unknown): Uint8Array {
|
||||||
|
if (data instanceof Uint8Array) return data;
|
||||||
|
if (data instanceof ArrayBuffer) return new Uint8Array(data);
|
||||||
|
throw new Error('Unsupported texture image type');
|
||||||
|
}
|
||||||
|
|
||||||
|
export const optimizePNG = (): Transform => async (doc) => {
|
||||||
|
const textures = doc.getRoot().listTextures();
|
||||||
|
for (const tex of textures) {
|
||||||
|
// 仅处理 PNG
|
||||||
|
if (tex.getMimeType() !== 'image/png') continue;
|
||||||
|
|
||||||
|
const image = tex.getImage();
|
||||||
|
if (!image || image.byteLength === 0) continue;
|
||||||
|
|
||||||
|
// 归一化为 Uint8Array
|
||||||
|
const imgU8 = asUint8Array(image);
|
||||||
|
|
||||||
|
const stamped = await encodePNG(imgU8);
|
||||||
|
tex.setImage(stamped);
|
||||||
|
tex.setMimeType('image/png');
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1,125 +1,136 @@
|
|||||||
import {Document, WebIO, FileUtils, Transform, Format, Logger} from '@gltf-transform/core';
|
import { Document, WebIO, FileUtils, Transform, Format, Logger } from '@gltf-transform/core';
|
||||||
import type { Packet, KHRXMP } from '@gltf-transform/extensions';
|
import type { Packet, KHRXMP } from '@gltf-transform/extensions';
|
||||||
import { unpartition } from '@gltf-transform/functions';
|
import { unpartition } from '@gltf-transform/functions';
|
||||||
import {Listr} from "./Listr";
|
import { Listr } from "./Listr";
|
||||||
import { formatBytes, XMPContext } from './util.js';
|
import { formatBytes, encodeGLB, XMPContext } from './util.js';
|
||||||
import GLTFHandler from "./glTFHandler";
|
import GLTFHandler from "./glTFHandler";
|
||||||
|
|
||||||
export class Session {
|
export class Session {
|
||||||
private _outputFormat: Format;
|
private _outputFormat: Format;
|
||||||
private _display = false;
|
private _display = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private _io: WebIO,
|
private _io: WebIO,
|
||||||
private _logger: Logger,
|
private _logger: Logger,
|
||||||
private setLogger: (log:string) => void,
|
private setLogger: (log: string) => void,
|
||||||
private _input: string,
|
private _input: string,
|
||||||
private _inputName: string,
|
private _inputName: string,
|
||||||
private _output: string,
|
private _output: string,
|
||||||
) {
|
) {
|
||||||
_io.setLogger(_logger);
|
_io.setLogger(_logger);
|
||||||
this._outputFormat = FileUtils.extension(_output) === 'glb' ? Format.GLB : Format.GLTF;
|
this._outputFormat = FileUtils.extension(_output) === 'glb' ? Format.GLB : Format.GLTF;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static create(handler:GLTFHandler, inputFileUrl: string,inputName:string, output: string): Session {
|
public static create(handler: GLTFHandler, inputFileUrl: string, inputName: string, output: string): Session {
|
||||||
return new Session(handler.io, handler.logger, handler.setLogger.bind(handler),inputFileUrl, inputName,output);
|
return new Session(handler.io, handler.logger, handler.setLogger.bind(handler), inputFileUrl, inputName, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
public setDisplay(display: boolean): this {
|
public setDisplay(display: boolean): this {
|
||||||
this._display = display;
|
this._display = display;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async transform(...transforms: Transform[]): Promise<File> {
|
public async transform(...transforms: Transform[]): Promise<File> {
|
||||||
this.setLogger("Start");
|
this.setLogger("Start");
|
||||||
|
|
||||||
let _document = this._input
|
let _document = this._input
|
||||||
? (await this._io.read(this._input)).setLogger(this._logger)
|
? (await this._io.read(this._input)).setLogger(this._logger)
|
||||||
: new Document().setLogger(this._logger);
|
: new Document().setLogger(this._logger);
|
||||||
|
|
||||||
// Warn and remove lossy compression, to avoid increasing loss on round trip.
|
// 警告和消除有损压缩,以避免增加往返的损失。
|
||||||
for (const extensionName of ['KHR_draco_mesh_compression', 'EXT_meshopt_compression']) {
|
for (const extensionName of ['KHR_draco_mesh_compression', 'EXT_meshopt_compression']) {
|
||||||
const extension = _document
|
const extension = _document
|
||||||
.getRoot()
|
.getRoot()
|
||||||
.listExtensionsUsed()
|
.listExtensionsUsed()
|
||||||
.find((extension) => extension.extensionName === extensionName);
|
.find((extension) => extension.extensionName === extensionName);
|
||||||
if (extension) {
|
if (extension) {
|
||||||
extension.dispose();
|
extension.dispose();
|
||||||
this._logger.warn(`Decoded ${extensionName}. Further compression will be lossy.`);
|
this._logger.warn(`Decoded ${extensionName}. Further compression will be lossy.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._display) {
|
if (this._display) {
|
||||||
const tasks = [] as { title:string,task:(task: any) => Promise<void> }[];
|
const tasks = [] as { title: string, task: (task: any) => Promise<void> }[];
|
||||||
for (const transform of transforms) {
|
for (const transform of transforms) {
|
||||||
tasks.push({
|
tasks.push({
|
||||||
title: transform.name,
|
title: transform.name,
|
||||||
task: async (task) => {
|
task: async (task) => {
|
||||||
try{
|
try {
|
||||||
this.setLogger(task.title)
|
this.setLogger(task.title)
|
||||||
let time = performance.now();
|
let time = performance.now();
|
||||||
_document = await _document.transform(transform);
|
_document = await _document.transform(transform);
|
||||||
time = Math.round(performance.now() - time);
|
time = Math.round(performance.now() - time);
|
||||||
this.setLogger(task.title.padEnd(20) + ` ${time}ms`)
|
this.setLogger(task.title.padEnd(20) + ` ${time}ms`)
|
||||||
}catch (error:unknown){
|
} catch (error: unknown) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.setLogger(`${task.title} run fail: ${error?.message || error}`)
|
this.setLogger(`${task.title} run fail: ${error?.message || error}`)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Listr(tasks).run();
|
await new Listr(tasks).run();
|
||||||
} else {
|
} else {
|
||||||
await _document.transform(...transforms);
|
await _document.transform(...transforms);
|
||||||
}
|
}
|
||||||
|
|
||||||
await _document.transform(updateMetadata);
|
await _document.transform(updateMetadata);
|
||||||
|
|
||||||
if (this._outputFormat === Format.GLB) {
|
if (this._outputFormat === Format.GLB) {
|
||||||
await _document.transform(unpartition());
|
await _document.transform(unpartition());
|
||||||
}
|
}
|
||||||
|
|
||||||
const outputUint8Array = await this._io.writeBinary(_document);
|
const rawU8 = await this._io.writeBinary(_document);
|
||||||
// Uint8Array转file
|
|
||||||
const mimeType = this._outputFormat === Format.GLB ? "model/gltf-binary" : "model/gltf+json";
|
|
||||||
const blob = new Blob([outputUint8Array], { type: mimeType});
|
|
||||||
const outputFile = new File([blob], this._output, { type: mimeType });
|
|
||||||
|
|
||||||
const { lastReadBytes, lastWriteBytes } = this._io;
|
// 插入 WASM 水印
|
||||||
if (!this._input) {
|
let outputUint8Array = rawU8;
|
||||||
const output = FileUtils.basename(this._output) + '.' + FileUtils.extension(this._output);
|
try {
|
||||||
this._logger.info(`${output} (${formatBytes(lastWriteBytes)})`);
|
outputUint8Array = await encodeGLB(rawU8, {});
|
||||||
} else {
|
} catch (e: any) {
|
||||||
const input = FileUtils.basename(this._inputName) + '.' + FileUtils.extension(this._inputName);
|
this._logger.warn('EncodeGLB skipped: ' + (e?.message || e));
|
||||||
const output = FileUtils.basename(this._output) + '.' + FileUtils.extension(this._output);
|
}
|
||||||
this._logger.info(
|
|
||||||
`${input} (${formatBytes(lastReadBytes)})` + ` → ${output} (${formatBytes(lastWriteBytes)})`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setLogger("Done")
|
// Uint8Array转file
|
||||||
|
const mimeType = this._outputFormat === Format.GLB ? "model/gltf-binary" : "model/gltf+json";
|
||||||
|
const blob = new Blob([outputUint8Array], { type: mimeType });
|
||||||
|
const outputFile = new File([blob], this._output, { type: mimeType });
|
||||||
|
|
||||||
return outputFile;
|
const { lastReadBytes } = this._io;
|
||||||
}
|
const lastWriteBytes = outputUint8Array.byteLength;
|
||||||
|
|
||||||
|
if (!this._input) {
|
||||||
|
const output = FileUtils.basename(this._output) + '.' + FileUtils.extension(this._output);
|
||||||
|
this._logger.info(`${output} (${formatBytes(lastWriteBytes)})`);
|
||||||
|
} else {
|
||||||
|
const input = FileUtils.basename(this._inputName) + '.' + FileUtils.extension(this._inputName);
|
||||||
|
const output = FileUtils.basename(this._output) + '.' + FileUtils.extension(this._output);
|
||||||
|
this._logger.info(
|
||||||
|
`${input} (${formatBytes(lastReadBytes)})` + ` → ${output} (${formatBytes(lastWriteBytes)})`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setLogger("Done")
|
||||||
|
|
||||||
|
return outputFile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateMetadata(_document: Document): void {
|
function updateMetadata(_document: Document): void {
|
||||||
const root = _document.getRoot();
|
const root = _document.getRoot();
|
||||||
const xmpExtension = root
|
const xmpExtension = root
|
||||||
.listExtensionsUsed()
|
.listExtensionsUsed()
|
||||||
.find((ext) => ext.extensionName === 'KHR_xmp_json_ld') as KHRXMP | null;
|
.find((ext) => ext.extensionName === 'KHR_xmp_json_ld') as KHRXMP | null;
|
||||||
|
|
||||||
// 不要将KHR_xmp_json_ld添加到尚未使用它的资产中。
|
// 不要将KHR_xmp_json_ld添加到尚未使用它的资产中。
|
||||||
if (!xmpExtension) return;
|
if (!xmpExtension) return;
|
||||||
|
|
||||||
const rootPacket = root.getExtension<Packet>('KHR_xmp_json_ld') || xmpExtension.createPacket();
|
const rootPacket = root.getExtension<Packet>('KHR_xmp_json_ld') || xmpExtension.createPacket();
|
||||||
|
|
||||||
// xmp:MetadataDate should be the same as, or more recent than, xmp:ModifyDate.
|
// xmp:MetadataDate should be the same as, or more recent than, xmp:ModifyDate.
|
||||||
// https://github.com/adobe/xmp-docs/blob/master/XMPNamespaces/xmp.md
|
// https://github.com/adobe/xmp-docs/blob/master/XMPNamespaces/xmp.md
|
||||||
const date = new Date().toISOString().substring(0, 10);
|
const date = new Date().toISOString().substring(0, 10);
|
||||||
rootPacket
|
rootPacket
|
||||||
.setContext({ ...rootPacket.getContext(), xmp: XMPContext.xmp })
|
.setContext({ ...rootPacket.getContext(), xmp: XMPContext.xmp })
|
||||||
.setProperty('xmp:ModifyDate', date)
|
.setProperty('xmp:ModifyDate', date)
|
||||||
.setProperty('xmp:MetadataDate', date);
|
.setProperty('xmp:MetadataDate', date);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +1,53 @@
|
|||||||
|
import { injectWasm } from "@/utils/wasm/inject";
|
||||||
|
|
||||||
export const XMPContext: Record<string, string> = {
|
export const XMPContext: Record<string, string> = {
|
||||||
dc: 'http://purl.org/dc/elements/1.1/',
|
dc: 'http://purl.org/dc/elements/1.1/',
|
||||||
model3d: 'https://schema.khronos.org/model3d/xsd/1.0/',
|
model3d: 'https://schema.khronos.org/model3d/xsd/1.0/',
|
||||||
rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
|
rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
|
||||||
xmp: 'http://ns.adobe.com/xap/1.0/',
|
xmp: 'http://ns.adobe.com/xap/1.0/',
|
||||||
xmpRights: 'http://ns.adobe.com/xap/1.0/rights/',
|
xmpRights: 'http://ns.adobe.com/xap/1.0/rights/',
|
||||||
};
|
};
|
||||||
|
|
||||||
export function formatLong(x: number): string {
|
export function formatLong(x: number): string {
|
||||||
return x.toString();
|
return x.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatBytes(bytes: number, decimals = 2): string {
|
export function formatBytes(bytes: number, decimals = 2): string {
|
||||||
if (bytes === 0) return '0 Bytes';
|
if (bytes === 0) return '0 Bytes';
|
||||||
|
|
||||||
const k = 1000;
|
const k = 1000;
|
||||||
const dm = decimals < 0 ? 0 : decimals;
|
const dm = decimals < 0 ? 0 : decimals;
|
||||||
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||||
|
|
||||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||||
|
|
||||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function dim(str: string): string {
|
export function dim(str: string): string {
|
||||||
return `\x1b[2m${str}\x1b[0m`;
|
return `\x1b[2m${str}\x1b[0m`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* wasm内优化处理 */
|
||||||
|
let wasmReady = false;
|
||||||
|
|
||||||
|
async function ensureWasmReady() {
|
||||||
|
if (wasmReady) return;
|
||||||
|
await injectWasm({ wasmUrl: "/wasm/Astral3DglTFHandler.wasm" });
|
||||||
|
wasmReady = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function encodeGLB(u8: Uint8Array, meta: Record<string, any> = {}) {
|
||||||
|
await ensureWasmReady();
|
||||||
|
|
||||||
|
const out = window.glTFHandlerEncodeGLB(u8, JSON.stringify(meta || {}));
|
||||||
|
return new Uint8Array(out.buffer, out.byteOffset, out.byteLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function encodePNG(png: Uint8Array) {
|
||||||
|
await ensureWasmReady();
|
||||||
|
|
||||||
|
const out = window.glTFHandlerEncodePNG(png);
|
||||||
|
return new Uint8Array(out.buffer, out.byteOffset, out.byteLength);
|
||||||
|
}
|
||||||
|
/* wasm内优化处理 End */
|
||||||
|
|||||||
39
packages/editor/src/utils/wasm/inject.ts
Normal file
39
packages/editor/src/utils/wasm/inject.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import "@/utils/wasm/wasm_exec.js";
|
||||||
|
|
||||||
|
// 20251112: 注入tinyGo编译的wasm
|
||||||
|
export function injectWasm(opts: {wasmUrl: string}):Promise<any> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if(!opts.wasmUrl){
|
||||||
|
reject("wasmUrl requires valid URL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const go = new Go();
|
||||||
|
|
||||||
|
const done = (obj) => {
|
||||||
|
const wasm = obj.instance;
|
||||||
|
go.run(wasm);
|
||||||
|
|
||||||
|
resolve(wasm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('instantiateStreaming' in WebAssembly) {
|
||||||
|
WebAssembly.instantiateStreaming(fetch(opts.wasmUrl), go.importObject).then(function (obj) {
|
||||||
|
done(obj);
|
||||||
|
}).catch(function (err) {
|
||||||
|
reject(err);
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
fetch(opts.wasmUrl).then(resp =>
|
||||||
|
resp.arrayBuffer()
|
||||||
|
).then(bytes =>
|
||||||
|
WebAssembly.instantiate(bytes, go.importObject).then(function (obj) {
|
||||||
|
done(obj);
|
||||||
|
}).catch(function (err) {
|
||||||
|
reject(err);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
8
packages/editor/src/utils/wasm/optimize.ts
Normal file
8
packages/editor/src/utils/wasm/optimize.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { injectWasm } from "@/utils/wasm/inject";
|
||||||
|
|
||||||
|
export function clearBuffer() {
|
||||||
|
injectWasm({ wasmUrl: "/wasm/Astral3DEditor.wasm" }).then(() => {
|
||||||
|
// 加载完wasm后自动注册了清除缓存的函数调用
|
||||||
|
window.clearBuffer();
|
||||||
|
});
|
||||||
|
}
|
||||||
403
packages/editor/src/utils/wasm/wasm_exec.js
Normal file
403
packages/editor/src/utils/wasm/wasm_exec.js
Normal file
@ -0,0 +1,403 @@
|
|||||||
|
(() => {
|
||||||
|
const global = window;
|
||||||
|
|
||||||
|
const encoder = new TextEncoder("utf-8");
|
||||||
|
const decoder = new TextDecoder("utf-8");
|
||||||
|
let reinterpretBuf = new DataView(new ArrayBuffer(8));
|
||||||
|
let logLine = [];
|
||||||
|
const wasmExit = {}; // thrown to exit via proc_exit (not an error)
|
||||||
|
|
||||||
|
global.Go = class {
|
||||||
|
constructor() {
|
||||||
|
this._callbackTimeouts = new Map();
|
||||||
|
this._nextCallbackTimeoutID = 1;
|
||||||
|
|
||||||
|
const mem = () => {
|
||||||
|
// The buffer may change when requesting more memory.
|
||||||
|
return new DataView(this._inst.exports.memory.buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
const unboxValue = (v_ref) => {
|
||||||
|
reinterpretBuf.setBigInt64(0, v_ref, true);
|
||||||
|
const f = reinterpretBuf.getFloat64(0, true);
|
||||||
|
if (f === 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (!isNaN(f)) {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = v_ref & 0xffffffffn;
|
||||||
|
return this._values[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const loadValue = (addr) => {
|
||||||
|
let v_ref = mem().getBigUint64(addr, true);
|
||||||
|
return unboxValue(v_ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
const boxValue = (v) => {
|
||||||
|
const nanHead = 0x7FF80000n;
|
||||||
|
|
||||||
|
if (typeof v === "number") {
|
||||||
|
if (isNaN(v)) {
|
||||||
|
return nanHead << 32n;
|
||||||
|
}
|
||||||
|
if (v === 0) {
|
||||||
|
return (nanHead << 32n) | 1n;
|
||||||
|
}
|
||||||
|
reinterpretBuf.setFloat64(0, v, true);
|
||||||
|
return reinterpretBuf.getBigInt64(0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (v) {
|
||||||
|
case undefined:
|
||||||
|
return 0n;
|
||||||
|
case null:
|
||||||
|
return (nanHead << 32n) | 2n;
|
||||||
|
case true:
|
||||||
|
return (nanHead << 32n) | 3n;
|
||||||
|
case false:
|
||||||
|
return (nanHead << 32n) | 4n;
|
||||||
|
}
|
||||||
|
|
||||||
|
let id = this._ids.get(v);
|
||||||
|
if (id === undefined) {
|
||||||
|
id = this._idPool.pop();
|
||||||
|
if (id === undefined) {
|
||||||
|
id = BigInt(this._values.length);
|
||||||
|
}
|
||||||
|
this._values[id] = v;
|
||||||
|
this._goRefCounts[id] = 0;
|
||||||
|
this._ids.set(v, id);
|
||||||
|
}
|
||||||
|
this._goRefCounts[id]++;
|
||||||
|
let typeFlag = 1n;
|
||||||
|
switch (typeof v) {
|
||||||
|
case "string":
|
||||||
|
typeFlag = 2n;
|
||||||
|
break;
|
||||||
|
case "symbol":
|
||||||
|
typeFlag = 3n;
|
||||||
|
break;
|
||||||
|
case "function":
|
||||||
|
typeFlag = 4n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return id | ((nanHead | typeFlag) << 32n);
|
||||||
|
}
|
||||||
|
|
||||||
|
const storeValue = (addr, v) => {
|
||||||
|
let v_ref = boxValue(v);
|
||||||
|
mem().setBigUint64(addr, v_ref, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadSlice = (array, len, cap) => {
|
||||||
|
return new Uint8Array(this._inst.exports.memory.buffer, array, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadSliceOfValues = (array, len, cap) => {
|
||||||
|
const a = new Array(len);
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
a[i] = loadValue(array + i * 8);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadString = (ptr, len) => {
|
||||||
|
return decoder.decode(new DataView(this._inst.exports.memory.buffer, ptr, len));
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeOrigin = Date.now() - performance.now();
|
||||||
|
this.importObject = {
|
||||||
|
wasi_snapshot_preview1: {
|
||||||
|
fd_write: function(fd, iovs_ptr, iovs_len, nwritten_ptr) {
|
||||||
|
let nwritten = 0;
|
||||||
|
if (fd == 1) {
|
||||||
|
for (let iovs_i=0; iovs_i<iovs_len;iovs_i++) {
|
||||||
|
let iov_ptr = iovs_ptr+iovs_i*8; // assuming wasm32
|
||||||
|
let ptr = mem().getUint32(iov_ptr + 0, true);
|
||||||
|
let len = mem().getUint32(iov_ptr + 4, true);
|
||||||
|
nwritten += len;
|
||||||
|
for (let i=0; i<len; i++) {
|
||||||
|
let c = mem().getUint8(ptr+i);
|
||||||
|
if (c == 13) { // CR
|
||||||
|
// ignore
|
||||||
|
} else if (c == 10) { // LF
|
||||||
|
// write line
|
||||||
|
let line = decoder.decode(new Uint8Array(logLine));
|
||||||
|
logLine = [];
|
||||||
|
console.log(line);
|
||||||
|
} else {
|
||||||
|
logLine.push(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('invalid file descriptor:', fd);
|
||||||
|
}
|
||||||
|
mem().setUint32(nwritten_ptr, nwritten, true);
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
fd_close: () => 0, // dummy
|
||||||
|
fd_fdstat_get: () => 0, // dummy
|
||||||
|
fd_seek: () => 0, // dummy
|
||||||
|
proc_exit: (code) => {
|
||||||
|
this.exited = true;
|
||||||
|
this.exitCode = code;
|
||||||
|
this._resolveExitPromise();
|
||||||
|
throw wasmExit;
|
||||||
|
},
|
||||||
|
random_get: (bufPtr, bufLen) => {
|
||||||
|
crypto.getRandomValues(loadSlice(bufPtr, bufLen));
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
gojs: {
|
||||||
|
// func ticks() float64
|
||||||
|
"runtime.ticks": () => {
|
||||||
|
return timeOrigin + performance.now();
|
||||||
|
},
|
||||||
|
|
||||||
|
// func sleepTicks(timeout float64)
|
||||||
|
"runtime.sleepTicks": (timeout) => {
|
||||||
|
// Do not sleep, only reactivate scheduler after the given timeout.
|
||||||
|
setTimeout(() => {
|
||||||
|
if (this.exited) return;
|
||||||
|
try {
|
||||||
|
this._inst.exports.go_scheduler();
|
||||||
|
} catch (e) {
|
||||||
|
if (e !== wasmExit) throw e;
|
||||||
|
}
|
||||||
|
}, timeout);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func finalizeRef(v ref)
|
||||||
|
"syscall/js.finalizeRef": (v_ref) => {
|
||||||
|
// Note: TinyGo does not support finalizers so this is only called
|
||||||
|
// for one specific case, by js.go:jsString. and can/might leak memory.
|
||||||
|
const id = v_ref & 0xffffffffn;
|
||||||
|
if (this._goRefCounts?.[id] !== undefined) {
|
||||||
|
this._goRefCounts[id]--;
|
||||||
|
if (this._goRefCounts[id] === 0) {
|
||||||
|
const v = this._values[id];
|
||||||
|
this._values[id] = null;
|
||||||
|
this._ids.delete(v);
|
||||||
|
this._idPool.push(id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error("syscall/js.finalizeRef: unknown id", id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// func stringVal(value string) ref
|
||||||
|
"syscall/js.stringVal": (value_ptr, value_len) => {
|
||||||
|
value_ptr >>>= 0;
|
||||||
|
const s = loadString(value_ptr, value_len);
|
||||||
|
return boxValue(s);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueGet(v ref, p string) ref
|
||||||
|
"syscall/js.valueGet": (v_ref, p_ptr, p_len) => {
|
||||||
|
let prop = loadString(p_ptr, p_len);
|
||||||
|
let v = unboxValue(v_ref);
|
||||||
|
let result = Reflect.get(v, prop);
|
||||||
|
return boxValue(result);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueSet(v ref, p string, x ref)
|
||||||
|
"syscall/js.valueSet": (v_ref, p_ptr, p_len, x_ref) => {
|
||||||
|
const v = unboxValue(v_ref);
|
||||||
|
const p = loadString(p_ptr, p_len);
|
||||||
|
const x = unboxValue(x_ref);
|
||||||
|
Reflect.set(v, p, x);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueDelete(v ref, p string)
|
||||||
|
"syscall/js.valueDelete": (v_ref, p_ptr, p_len) => {
|
||||||
|
const v = unboxValue(v_ref);
|
||||||
|
const p = loadString(p_ptr, p_len);
|
||||||
|
Reflect.deleteProperty(v, p);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueIndex(v ref, i int) ref
|
||||||
|
"syscall/js.valueIndex": (v_ref, i) => {
|
||||||
|
return boxValue(Reflect.get(unboxValue(v_ref), i));
|
||||||
|
},
|
||||||
|
|
||||||
|
// valueSetIndex(v ref, i int, x ref)
|
||||||
|
"syscall/js.valueSetIndex": (v_ref, i, x_ref) => {
|
||||||
|
Reflect.set(unboxValue(v_ref), i, unboxValue(x_ref));
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueCall(v ref, m string, args []ref) (ref, bool)
|
||||||
|
"syscall/js.valueCall": (ret_addr, v_ref, m_ptr, m_len, args_ptr, args_len, args_cap) => {
|
||||||
|
const v = unboxValue(v_ref);
|
||||||
|
const name = loadString(m_ptr, m_len);
|
||||||
|
const args = loadSliceOfValues(args_ptr, args_len, args_cap);
|
||||||
|
try {
|
||||||
|
const m = Reflect.get(v, name);
|
||||||
|
storeValue(ret_addr, Reflect.apply(m, v, args));
|
||||||
|
mem().setUint8(ret_addr + 8, 1);
|
||||||
|
} catch (err) {
|
||||||
|
storeValue(ret_addr, err);
|
||||||
|
mem().setUint8(ret_addr + 8, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueInvoke(v ref, args []ref) (ref, bool)
|
||||||
|
"syscall/js.valueInvoke": (ret_addr, v_ref, args_ptr, args_len, args_cap) => {
|
||||||
|
try {
|
||||||
|
const v = unboxValue(v_ref);
|
||||||
|
const args = loadSliceOfValues(args_ptr, args_len, args_cap);
|
||||||
|
storeValue(ret_addr, Reflect.apply(v, undefined, args));
|
||||||
|
mem().setUint8(ret_addr + 8, 1);
|
||||||
|
} catch (err) {
|
||||||
|
storeValue(ret_addr, err);
|
||||||
|
mem().setUint8(ret_addr + 8, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueNew(v ref, args []ref) (ref, bool)
|
||||||
|
"syscall/js.valueNew": (ret_addr, v_ref, args_ptr, args_len, args_cap) => {
|
||||||
|
const v = unboxValue(v_ref);
|
||||||
|
const args = loadSliceOfValues(args_ptr, args_len, args_cap);
|
||||||
|
try {
|
||||||
|
storeValue(ret_addr, Reflect.construct(v, args));
|
||||||
|
mem().setUint8(ret_addr + 8, 1);
|
||||||
|
} catch (err) {
|
||||||
|
storeValue(ret_addr, err);
|
||||||
|
mem().setUint8(ret_addr+ 8, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueLength(v ref) int
|
||||||
|
"syscall/js.valueLength": (v_ref) => {
|
||||||
|
return unboxValue(v_ref).length;
|
||||||
|
},
|
||||||
|
|
||||||
|
// valuePrepareString(v ref) (ref, int)
|
||||||
|
"syscall/js.valuePrepareString": (ret_addr, v_ref) => {
|
||||||
|
const s = String(unboxValue(v_ref));
|
||||||
|
const str = encoder.encode(s);
|
||||||
|
storeValue(ret_addr, str);
|
||||||
|
mem().setInt32(ret_addr + 8, str.length, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
// valueLoadString(v ref, b []byte)
|
||||||
|
"syscall/js.valueLoadString": (v_ref, slice_ptr, slice_len, slice_cap) => {
|
||||||
|
const str = unboxValue(v_ref);
|
||||||
|
loadSlice(slice_ptr, slice_len, slice_cap).set(str);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func valueInstanceOf(v ref, t ref) bool
|
||||||
|
"syscall/js.valueInstanceOf": (v_ref, t_ref) => {
|
||||||
|
return unboxValue(v_ref) instanceof unboxValue(t_ref);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func copyBytesToGo(dst []byte, src ref) (int, bool)
|
||||||
|
"syscall/js.copyBytesToGo": (ret_addr, dest_addr, dest_len, dest_cap, src_ref) => {
|
||||||
|
let num_bytes_copied_addr = ret_addr;
|
||||||
|
let returned_status_addr = ret_addr + 4; // Address of returned boolean status variable
|
||||||
|
|
||||||
|
const dst = loadSlice(dest_addr, dest_len);
|
||||||
|
const src = unboxValue(src_ref);
|
||||||
|
if (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) {
|
||||||
|
mem().setUint8(returned_status_addr, 0); // Return "not ok" status
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const toCopy = src.subarray(0, dst.length);
|
||||||
|
dst.set(toCopy);
|
||||||
|
mem().setUint32(num_bytes_copied_addr, toCopy.length, true);
|
||||||
|
mem().setUint8(returned_status_addr, 1); // Return "ok" status
|
||||||
|
},
|
||||||
|
|
||||||
|
// copyBytesToJS(dst ref, src []byte) (int, bool)
|
||||||
|
// Originally copied from upstream Go project, then modified:
|
||||||
|
// https://github.com/golang/go/blob/3f995c3f3b43033013013e6c7ccc93a9b1411ca9/misc/wasm/wasm_exec.js#L404-L416
|
||||||
|
"syscall/js.copyBytesToJS": (ret_addr, dst_ref, src_addr, src_len, src_cap) => {
|
||||||
|
let num_bytes_copied_addr = ret_addr;
|
||||||
|
let returned_status_addr = ret_addr + 4; // Address of returned boolean status variable
|
||||||
|
|
||||||
|
const dst = unboxValue(dst_ref);
|
||||||
|
const src = loadSlice(src_addr, src_len);
|
||||||
|
if (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) {
|
||||||
|
mem().setUint8(returned_status_addr, 0); // Return "not ok" status
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const toCopy = src.subarray(0, dst.length);
|
||||||
|
dst.set(toCopy);
|
||||||
|
mem().setUint32(num_bytes_copied_addr, toCopy.length, true);
|
||||||
|
mem().setUint8(returned_status_addr, 1); // Return "ok" status
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Go 1.20 uses 'env'. Go 1.21 uses 'gojs'.
|
||||||
|
// 开启 env 映射
|
||||||
|
this.importObject.env = this.importObject.gojs;
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(instance) {
|
||||||
|
this._inst = instance;
|
||||||
|
this._values = [ // JS values that Go currently has references to, indexed by reference id
|
||||||
|
NaN,
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
global,
|
||||||
|
this,
|
||||||
|
];
|
||||||
|
this._goRefCounts = []; // number of references that Go has to a JS value, indexed by reference id
|
||||||
|
this._ids = new Map(); // mapping from JS values to reference ids
|
||||||
|
this._idPool = []; // unused ids that have been garbage collected
|
||||||
|
this.exited = false; // whether the Go program has exited
|
||||||
|
this.exitCode = 0;
|
||||||
|
|
||||||
|
if (this._inst.exports._start) {
|
||||||
|
let exitPromise = new Promise((resolve, reject) => {
|
||||||
|
this._resolveExitPromise = resolve;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Run program, but catch the wasmExit exception that's thrown
|
||||||
|
// to return back here.
|
||||||
|
try {
|
||||||
|
this._inst.exports._start();
|
||||||
|
} catch (e) {
|
||||||
|
if (e !== wasmExit) throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
await exitPromise;
|
||||||
|
return this.exitCode;
|
||||||
|
} else {
|
||||||
|
this._inst.exports._initialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_resume() {
|
||||||
|
if (this.exited) {
|
||||||
|
throw new Error("Go program has already exited");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this._inst.exports.resume();
|
||||||
|
} catch (e) {
|
||||||
|
if (e !== wasmExit) throw e;
|
||||||
|
}
|
||||||
|
if (this.exited) {
|
||||||
|
this._resolveExitPromise();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_makeFuncWrapper(id) {
|
||||||
|
const go = this;
|
||||||
|
return function () {
|
||||||
|
const event = { id: id, this: this, args: arguments };
|
||||||
|
go._pendingEvent = event;
|
||||||
|
go._resume();
|
||||||
|
return event.result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
@ -42,7 +42,8 @@ const filteredList = computed(() => {
|
|||||||
|
|
||||||
//双击添加至场景
|
//双击添加至场景
|
||||||
function addToScene(key) {
|
function addToScene(key) {
|
||||||
const obj = Astral3D[key];
|
const obj = Astral3D[key]();
|
||||||
|
|
||||||
Astral3D.App.execute(new Astral3D.AddObjectCommand(obj));
|
Astral3D.App.execute(new Astral3D.AddObjectCommand(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -58,7 +58,7 @@ const filteredList = computed(() => {
|
|||||||
|
|
||||||
//双击添加至场景
|
//双击添加至场景
|
||||||
function addToScene(key) {
|
function addToScene(key) {
|
||||||
const obj = Astral3D[key];
|
const obj = Astral3D[key]();
|
||||||
|
|
||||||
Astral3D.App.execute(new Astral3D.AddObjectCommand(obj));
|
Astral3D.App.execute(new Astral3D.AddObjectCommand(obj));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,12 +18,13 @@
|
|||||||
import {onMounted, ref, nextTick, onBeforeUnmount} from 'vue';
|
import {onMounted, ref, nextTick, onBeforeUnmount} from 'vue';
|
||||||
import {App,Viewer,Hooks} from "@astral3d/engine";
|
import {App,Viewer,Hooks} from "@astral3d/engine";
|
||||||
import Toolbar from "./Toolbar.vue";
|
import Toolbar from "./Toolbar.vue";
|
||||||
import ViewportInfo from "./ViewportInfo.vue";
|
|
||||||
import BIMProperties from "./BIMProperties.vue";
|
|
||||||
import IFCProperties from "./IFCProperties.vue";
|
|
||||||
import {useGlobalConfigStore} from "@/store/modules/globalConfig";
|
import {useGlobalConfigStore} from "@/store/modules/globalConfig";
|
||||||
import {usePluginStore} from "@/store/modules/plugin";
|
import {usePluginStore} from "@/store/modules/plugin";
|
||||||
import {installBuiltinPlugin} from "@/plugin";
|
import {installBuiltinPlugin} from "@/plugin";
|
||||||
|
import { clearBuffer } from "@/utils/wasm/optimize";
|
||||||
|
import ViewportInfo from "./ViewportInfo.vue";
|
||||||
|
import BIMProperties from "./BIMProperties.vue";
|
||||||
|
import IFCProperties from "./IFCProperties.vue";
|
||||||
|
|
||||||
const globalStore = useGlobalConfigStore();
|
const globalStore = useGlobalConfigStore();
|
||||||
const pluginStore = usePluginStore();
|
const pluginStore = usePluginStore();
|
||||||
@ -55,6 +56,9 @@ onMounted(async () => {
|
|||||||
|
|
||||||
// 注册astral editor内置插件
|
// 注册astral editor内置插件
|
||||||
installBuiltinPlugin(window.viewer);
|
installBuiltinPlugin(window.viewer);
|
||||||
|
|
||||||
|
// 清理wasm缓存
|
||||||
|
clearBuffer();
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
|
|||||||
@ -216,7 +216,7 @@ onMounted(() => {
|
|||||||
<n-divider vertical class="!h-auto"/>
|
<n-divider vertical class="!h-auto"/>
|
||||||
|
|
||||||
<div class="h-full w-320px flex flex-col justify-start ml-10px">
|
<div class="h-full w-320px flex flex-col justify-start ml-10px">
|
||||||
<img :src="currentExample?.coverPicture || '/static/images/carousel/Astral3DEditor.jpg'" class="w-full">
|
<img :src="getServiceStaticFile(currentExample?.coverPicture || '') || '/static/images/carousel/Astral3DEditor.jpg'" class="w-full">
|
||||||
|
|
||||||
<h3 class="mt-10px mb-8px">{{ currentExample?.sceneName || t("home.Empty project") }}</h3>
|
<h3 class="mt-10px mb-8px">{{ currentExample?.sceneName || t("home.Empty project") }}</h3>
|
||||||
<p class="h-100px overflow-y-auto">
|
<p class="h-100px overflow-y-auto">
|
||||||
|
|||||||
17
packages/editor/types/window.d.ts
vendored
17
packages/editor/types/window.d.ts
vendored
@ -1,13 +1,3 @@
|
|||||||
declare interface IAstralEditorWasm {
|
|
||||||
exports:{
|
|
||||||
computedStyle:()=>void
|
|
||||||
}
|
|
||||||
}
|
|
||||||
declare interface IAstralEngineWasm {
|
|
||||||
exports: {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declare interface Window {
|
declare interface Window {
|
||||||
$t:(s: string)=>string;
|
$t:(s: string)=>string;
|
||||||
$cpt:(s: string)=>ComputedRef<string>;
|
$cpt:(s: string)=>ComputedRef<string>;
|
||||||
@ -21,9 +11,10 @@ declare interface Window {
|
|||||||
CesiumApp:any;
|
CesiumApp:any;
|
||||||
VRButton: any;
|
VRButton: any;
|
||||||
log: import('loglevel').RootLogger;
|
log: import('loglevel').RootLogger;
|
||||||
// 在wasm中注册
|
// wasm
|
||||||
AstralEditorWasm: IAstralEditorWasm;
|
clearBuffer: () => void
|
||||||
AstralEngineWasm: IAstralEngineWasm;
|
glTFHandlerEncodeGLB: (u: Uint8Array, jsonStr: string) => Uint8Array
|
||||||
|
glTFHandlerEncodePNG: (png: Uint8Array) => Uint8Array
|
||||||
}
|
}
|
||||||
|
|
||||||
declare interface Number{
|
declare interface Number{
|
||||||
|
|||||||
@ -8,11 +8,11 @@ import * as THREE from 'three';
|
|||||||
// 原生three的扩展
|
// 原生three的扩展
|
||||||
import '../expansion';
|
import '../expansion';
|
||||||
import Logger from "@/utils/log/Logger";
|
import Logger from "@/utils/log/Logger";
|
||||||
import {Config,Storage,Project,Selector,History as _History,Resource,CSM} from "./modules";
|
import { Config, Storage, Project, Selector, History as _History, Resource, CSM } from "./modules";
|
||||||
import { AnimationManager } from "../animation/AnimationManager";
|
import { AnimationManager } from "../animation/AnimationManager";
|
||||||
import {useAddSignal, useDispatchSignal, useSetSignalActive} from '@/hooks';
|
import { useAddSignal, useDispatchSignal, useSetSignalActive } from '@/hooks';
|
||||||
import Loader from "@/core/loader/Loader.ts";
|
import Loader from "@/core/loader/Loader.ts";
|
||||||
import {AddScriptCommand,RemoveScriptCommand} from "@/core/commands/Commands.ts";
|
import { AddScriptCommand, RemoveScriptCommand } from "@/core/commands/Commands.ts";
|
||||||
import Viewer from "@/core/viewer/Viewer.ts";
|
import Viewer from "@/core/viewer/Viewer.ts";
|
||||||
|
|
||||||
const _DEFAULT_CAMERA = new THREE.PerspectiveCamera(45, 1, 0.01, 100 * 1000);
|
const _DEFAULT_CAMERA = new THREE.PerspectiveCamera(45, 1, 0.01, 100 * 1000);
|
||||||
@ -49,27 +49,27 @@ export class App {
|
|||||||
/**
|
/**
|
||||||
* 场景中的几何数据集合
|
* 场景中的几何数据集合
|
||||||
*/
|
*/
|
||||||
public geometries:{[uuid:string]:THREE.BufferGeometry}= {};
|
public geometries: { [uuid: string]: THREE.BufferGeometry } = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 场景中的材质集合
|
* 场景中的材质集合
|
||||||
*/
|
*/
|
||||||
public materials:{[uuid:string]:THREE.Material} = {};
|
public materials: { [uuid: string]: THREE.Material } = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 场景中的贴图集合
|
* 场景中的贴图集合
|
||||||
*/
|
*/
|
||||||
public textures:{[uuid:string]:THREE.Texture} = {};
|
public textures: { [uuid: string]: THREE.Texture } = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 场景中的脚本集合
|
* 场景中的脚本集合
|
||||||
*/
|
*/
|
||||||
public scripts:ISceneJson['scripts'] = {};
|
public scripts: ISceneJson['scripts'] = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 场景中的辅助集合
|
* 场景中的辅助集合
|
||||||
*/
|
*/
|
||||||
public helpers:Record<number, THREE.Object3D> = {};
|
public helpers: Record<number, THREE.Object3D> = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 场景中的相机集合
|
* 场景中的相机集合
|
||||||
@ -89,12 +89,12 @@ export class App {
|
|||||||
/**
|
/**
|
||||||
* 场景选中的模型
|
* 场景选中的模型
|
||||||
*/
|
*/
|
||||||
public selected:THREE.Object3D | null = null;
|
public selected: THREE.Object3D | null = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 场景锁定的模型
|
* 场景锁定的模型
|
||||||
*/
|
*/
|
||||||
public locked:THREE.Object3D | null = null;
|
public locked: THREE.Object3D | null = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日志记录
|
* 日志记录
|
||||||
@ -144,14 +144,14 @@ export class App {
|
|||||||
/**
|
/**
|
||||||
* 间隔多长时间渲染渲染一次,用于固定fps上限(单位秒)
|
* 间隔多长时间渲染渲染一次,用于固定fps上限(单位秒)
|
||||||
*/
|
*/
|
||||||
public singleFrameTime:number = 1 / this.FPS;
|
public singleFrameTime: number = 1 / this.FPS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前视口示例,实例化视口时赋值
|
* 当前视口示例,实例化视口时赋值
|
||||||
*/
|
*/
|
||||||
public viewer:Viewer | null = null;
|
public viewer: Viewer | null = null;
|
||||||
|
|
||||||
constructor(){
|
constructor() {
|
||||||
this.scene.name = "默认场景";
|
this.scene.name = "默认场景";
|
||||||
|
|
||||||
this.addCamera(this.camera);
|
this.addCamera(this.camera);
|
||||||
@ -162,7 +162,7 @@ export class App {
|
|||||||
/**
|
/**
|
||||||
* 获取渲染帧率上限
|
* 获取渲染帧率上限
|
||||||
*/
|
*/
|
||||||
get FPS():number{
|
get FPS(): number {
|
||||||
return this.project.getKey("renderer.fps");
|
return this.project.getKey("renderer.fps");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,8 +170,8 @@ export class App {
|
|||||||
* 设置渲染帧率上限
|
* 设置渲染帧率上限
|
||||||
* @param fps
|
* @param fps
|
||||||
*/
|
*/
|
||||||
set FPS(fps:number){
|
set FPS(fps: number) {
|
||||||
this.project.setKey("renderer.fps",fps,false);
|
this.project.setKey("renderer.fps", fps, false);
|
||||||
|
|
||||||
this.singleFrameTime = fps ? (1 / fps) : 0;
|
this.singleFrameTime = fps ? (1 / fps) : 0;
|
||||||
}
|
}
|
||||||
@ -179,7 +179,7 @@ export class App {
|
|||||||
/**
|
/**
|
||||||
* 设置初始配置
|
* 设置初始配置
|
||||||
*/
|
*/
|
||||||
setConfig(_config:Record<string, any>){
|
setConfig(_config: Record<string, any>) {
|
||||||
this.config.setConfig(_config);
|
this.config.setConfig(_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,8 +187,8 @@ export class App {
|
|||||||
* 生成场景
|
* 生成场景
|
||||||
* @param scene
|
* @param scene
|
||||||
*/
|
*/
|
||||||
setScene(scene:THREE.Scene) {
|
setScene(scene: THREE.Scene) {
|
||||||
this.scene.copy(scene,false)
|
this.scene.copy(scene, false)
|
||||||
// copy方法不会复制uuid,需要手动赋值
|
// copy方法不会复制uuid,需要手动赋值
|
||||||
this.scene.uuid = scene.uuid;
|
this.scene.uuid = scene.uuid;
|
||||||
if (this.scene.animations && this.scene.animations.length > 0) this.clipAction(this.scene);
|
if (this.scene.animations && this.scene.animations.length > 0) this.clipAction(this.scene);
|
||||||
@ -210,24 +210,24 @@ export class App {
|
|||||||
* 剪辑动画
|
* 剪辑动画
|
||||||
* @param object
|
* @param object
|
||||||
*/
|
*/
|
||||||
clipAction(object:THREE.Object3D){
|
clipAction(object: THREE.Object3D) {
|
||||||
if (!object.animations || !object.animations.length) return;
|
if (!object.animations || !object.animations.length) return;
|
||||||
|
|
||||||
// 每个包含动画的模型都会有自己的混合器,因为如果采用共用scene混合器方案会造成全场景动画播放进度统一的情况
|
// 每个包含动画的模型都会有自己的混合器,因为如果采用共用scene混合器方案会造成全场景动画播放进度统一的情况
|
||||||
let mixer = this.animationManager.mixerMap.get(object.uuid);
|
let mixer = this.animationManager.mixerMap.get(object.uuid);
|
||||||
if(!mixer){
|
if (!mixer) {
|
||||||
mixer = new THREE.AnimationMixer(object);
|
mixer = new THREE.AnimationMixer(object);
|
||||||
this.animationManager.mixerMap.set(object.uuid, mixer);
|
this.animationManager.mixerMap.set(object.uuid, mixer);
|
||||||
}
|
}
|
||||||
|
|
||||||
object.animations.forEach((animation,index) => {
|
object.animations.forEach((animation, index) => {
|
||||||
if ((animation instanceof THREE.AnimationAction) && animation.getClip()) {
|
if ((animation instanceof THREE.AnimationAction) && animation.getClip()) {
|
||||||
this.animationManager.actionMap.set(animation.getClip().uuid, animation)
|
this.animationManager.actionMap.set(animation.getClip().uuid, animation)
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(animation instanceof THREE.AnimationClip)) return;
|
if (!(animation instanceof THREE.AnimationClip)) return;
|
||||||
|
|
||||||
const action = (<THREE.AnimationMixer>mixer).clipAction(animation, object);
|
const action = (<THREE.AnimationMixer>mixer).clipAction(animation, object);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@ -243,7 +243,17 @@ export class App {
|
|||||||
* @param parent
|
* @param parent
|
||||||
* @param index
|
* @param index
|
||||||
*/
|
*/
|
||||||
addObject(object:THREE.Object3D, parent?:THREE.Object3D, index?:number) {
|
addObject(object: THREE.Object3D, parent?: THREE.Object3D, index?: number) {
|
||||||
|
// 使用自己版本threejs(比如插件)创建的物体调用此方法时需要递归修复原型链
|
||||||
|
const fixPrototypeChain = (obj: THREE.Object3D) => {
|
||||||
|
if (!obj.traverseByCondition) {
|
||||||
|
Object.setPrototypeOf(obj, THREE.Object3D.prototype);
|
||||||
|
}
|
||||||
|
obj.children.forEach(child => child.traverse(c => fixPrototypeChain(c)));
|
||||||
|
};
|
||||||
|
|
||||||
|
fixPrototypeChain(object);
|
||||||
|
|
||||||
object.traverseByCondition((child) => {
|
object.traverseByCondition((child) => {
|
||||||
if (child.animations && child.animations.length > 0) this.clipAction(child);
|
if (child.animations && child.animations.length > 0) this.clipAction(child);
|
||||||
if (child.geometry !== undefined) this.addGeometry(child.geometry);
|
if (child.geometry !== undefined) this.addGeometry(child.geometry);
|
||||||
@ -275,7 +285,7 @@ export class App {
|
|||||||
* @param parent
|
* @param parent
|
||||||
* @param before
|
* @param before
|
||||||
*/
|
*/
|
||||||
moveObject(object:THREE.Object3D, parent:THREE.Object3D, before:THREE.Object3D) {
|
moveObject(object: THREE.Object3D, parent: THREE.Object3D, before: THREE.Object3D) {
|
||||||
if (parent === undefined) {
|
if (parent === undefined) {
|
||||||
parent = this.scene;
|
parent = this.scene;
|
||||||
}
|
}
|
||||||
@ -297,7 +307,7 @@ export class App {
|
|||||||
* @param object
|
* @param object
|
||||||
* @param name
|
* @param name
|
||||||
*/
|
*/
|
||||||
nameObject(object:THREE.Object3D, name:string) {
|
nameObject(object: THREE.Object3D, name: string) {
|
||||||
object.name = name;
|
object.name = name;
|
||||||
useDispatchSignal('sceneGraphChanged');
|
useDispatchSignal('sceneGraphChanged');
|
||||||
}
|
}
|
||||||
@ -306,16 +316,16 @@ export class App {
|
|||||||
* 移除模型
|
* 移除模型
|
||||||
* @param object
|
* @param object
|
||||||
*/
|
*/
|
||||||
removeObject(object:THREE.Object3D) {
|
removeObject(object: THREE.Object3D) {
|
||||||
// 由于含有ignore属性的对象与业务关联,不受scene管控
|
// 由于含有ignore属性的对象与业务关联,不受scene管控
|
||||||
// object.parent === null避免删除相机或场景
|
// object.parent === null避免删除相机或场景
|
||||||
if (object.parent === null || object.ignore) return;
|
if (object.parent === null || object.ignore) return;
|
||||||
|
|
||||||
object.traverseByCondition((child:THREE.Object3D) => {
|
object.traverseByCondition((child: THREE.Object3D) => {
|
||||||
this.removeCamera(child);
|
this.removeCamera(child);
|
||||||
this.removeHelper(child);
|
this.removeHelper(child);
|
||||||
if (child.material !== undefined) this.removeMaterial(child.material);
|
if (child.material !== undefined) this.removeMaterial(child.material);
|
||||||
}, (child:THREE.Object3D) => !child.ignore);
|
}, (child: THREE.Object3D) => !child.ignore);
|
||||||
|
|
||||||
object.parent.remove(object);
|
object.parent.remove(object);
|
||||||
|
|
||||||
@ -327,7 +337,7 @@ export class App {
|
|||||||
* 添加几何数据
|
* 添加几何数据
|
||||||
* @param geometry
|
* @param geometry
|
||||||
*/
|
*/
|
||||||
addGeometry(geometry:THREE.BufferGeometry) {
|
addGeometry(geometry: THREE.BufferGeometry) {
|
||||||
this.geometries[geometry.uuid] = geometry;
|
this.geometries[geometry.uuid] = geometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,7 +346,7 @@ export class App {
|
|||||||
* @param geometry
|
* @param geometry
|
||||||
* @param name
|
* @param name
|
||||||
*/
|
*/
|
||||||
setGeometryName(geometry:THREE.BufferGeometry, name:string) {
|
setGeometryName(geometry: THREE.BufferGeometry, name: string) {
|
||||||
geometry.name = name;
|
geometry.name = name;
|
||||||
useDispatchSignal('sceneGraphChanged');
|
useDispatchSignal('sceneGraphChanged');
|
||||||
}
|
}
|
||||||
@ -345,7 +355,7 @@ export class App {
|
|||||||
* 场景中新增材质
|
* 场景中新增材质
|
||||||
* @param material
|
* @param material
|
||||||
*/
|
*/
|
||||||
addMaterial(material:THREE.Material | THREE.Material[]) {
|
addMaterial(material: THREE.Material | THREE.Material[]) {
|
||||||
if (Array.isArray(material)) {
|
if (Array.isArray(material)) {
|
||||||
for (let i = 0, l = material.length; i < l; i++) {
|
for (let i = 0, l = material.length; i < l; i++) {
|
||||||
this.addMaterialToRefCounter(material[i]);
|
this.addMaterialToRefCounter(material[i]);
|
||||||
@ -361,7 +371,7 @@ export class App {
|
|||||||
* 新增材质的使用计数
|
* 新增材质的使用计数
|
||||||
* @param material
|
* @param material
|
||||||
*/
|
*/
|
||||||
addMaterialToRefCounter(material:THREE.Material) {
|
addMaterialToRefCounter(material: THREE.Material) {
|
||||||
let materialsRefCounter = this.materialsRefCounter;
|
let materialsRefCounter = this.materialsRefCounter;
|
||||||
let count = materialsRefCounter.get(material);
|
let count = materialsRefCounter.get(material);
|
||||||
|
|
||||||
@ -382,7 +392,7 @@ export class App {
|
|||||||
* 场景中移除材质
|
* 场景中移除材质
|
||||||
* @param material
|
* @param material
|
||||||
*/
|
*/
|
||||||
removeMaterial(material:THREE.Material | THREE.Material[]) {
|
removeMaterial(material: THREE.Material | THREE.Material[]) {
|
||||||
if (Array.isArray(material)) {
|
if (Array.isArray(material)) {
|
||||||
for (let i = 0, l = material.length; i < l; i++) {
|
for (let i = 0, l = material.length; i < l; i++) {
|
||||||
this.removeMaterialFromRefCounter(material[i]);
|
this.removeMaterialFromRefCounter(material[i]);
|
||||||
@ -398,7 +408,7 @@ export class App {
|
|||||||
* 移除材质时减少对应材质使用计数
|
* 移除材质时减少对应材质使用计数
|
||||||
* @param material
|
* @param material
|
||||||
*/
|
*/
|
||||||
removeMaterialFromRefCounter(material:THREE.Material) {
|
removeMaterialFromRefCounter(material: THREE.Material) {
|
||||||
let materialsRefCounter = this.materialsRefCounter;
|
let materialsRefCounter = this.materialsRefCounter;
|
||||||
let count = materialsRefCounter.get(material) as number;
|
let count = materialsRefCounter.get(material) as number;
|
||||||
count--;
|
count--;
|
||||||
@ -415,7 +425,7 @@ export class App {
|
|||||||
* 通过材质uuid获取材质
|
* 通过材质uuid获取材质
|
||||||
* @param uuid
|
* @param uuid
|
||||||
*/
|
*/
|
||||||
getMaterialByUuid(uuid:string) {
|
getMaterialByUuid(uuid: string) {
|
||||||
return this.materials[uuid];
|
return this.materials[uuid];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,7 +434,7 @@ export class App {
|
|||||||
* @param material
|
* @param material
|
||||||
* @param name
|
* @param name
|
||||||
*/
|
*/
|
||||||
setMaterialName(material:THREE.Material, name:string) {
|
setMaterialName(material: THREE.Material, name: string) {
|
||||||
material.name = name;
|
material.name = name;
|
||||||
useDispatchSignal('sceneGraphChanged');
|
useDispatchSignal('sceneGraphChanged');
|
||||||
}
|
}
|
||||||
@ -433,7 +443,7 @@ export class App {
|
|||||||
* 场景中新增贴图
|
* 场景中新增贴图
|
||||||
* @param texture
|
* @param texture
|
||||||
*/
|
*/
|
||||||
addTexture(texture:THREE.Texture) {
|
addTexture(texture: THREE.Texture) {
|
||||||
this.textures[texture.uuid] = texture;
|
this.textures[texture.uuid] = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,7 +451,7 @@ export class App {
|
|||||||
* 场景中新增相机
|
* 场景中新增相机
|
||||||
* @param camera
|
* @param camera
|
||||||
*/
|
*/
|
||||||
addCamera(camera:THREE.Camera) {
|
addCamera(camera: THREE.Camera) {
|
||||||
if (camera.isCamera) {
|
if (camera.isCamera) {
|
||||||
this.cameras[camera.uuid] = camera;
|
this.cameras[camera.uuid] = camera;
|
||||||
useDispatchSignal('cameraAdded', camera);
|
useDispatchSignal('cameraAdded', camera);
|
||||||
@ -452,7 +462,7 @@ export class App {
|
|||||||
* 场景中移除相机
|
* 场景中移除相机
|
||||||
* @param camera
|
* @param camera
|
||||||
*/
|
*/
|
||||||
removeCamera(camera:THREE.Camera | THREE.Object3D) {
|
removeCamera(camera: THREE.Camera | THREE.Object3D) {
|
||||||
if (this.cameras[camera.uuid] !== undefined) {
|
if (this.cameras[camera.uuid] !== undefined) {
|
||||||
delete this.cameras[camera.uuid];
|
delete this.cameras[camera.uuid];
|
||||||
useDispatchSignal('cameraRemoved', camera);
|
useDispatchSignal('cameraRemoved', camera);
|
||||||
@ -464,7 +474,7 @@ export class App {
|
|||||||
* @param object
|
* @param object
|
||||||
* @param helper
|
* @param helper
|
||||||
*/
|
*/
|
||||||
addHelper(object:any, helper?:THREE.Object3D) {
|
addHelper(object: any, helper?: THREE.Object3D) {
|
||||||
if (helper === undefined) {
|
if (helper === undefined) {
|
||||||
if (object.isCamera) {
|
if (object.isCamera) {
|
||||||
helper = new THREE.CameraHelper(object);
|
helper = new THREE.CameraHelper(object);
|
||||||
@ -486,7 +496,7 @@ export class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let geometry = new THREE.SphereGeometry(2, 4, 2);
|
let geometry = new THREE.SphereGeometry(2, 4, 2);
|
||||||
let material = new THREE.MeshBasicMaterial({color: 0xff0000, visible: false});
|
let material = new THREE.MeshBasicMaterial({ color: 0xff0000, visible: false });
|
||||||
const picker = new THREE.Mesh(geometry, material);
|
const picker = new THREE.Mesh(geometry, material);
|
||||||
picker.name = 'picker';
|
picker.name = 'picker';
|
||||||
picker.proxy = object;
|
picker.proxy = object;
|
||||||
@ -501,7 +511,7 @@ export class App {
|
|||||||
* 移除某个模型上的三维辅助工具
|
* 移除某个模型上的三维辅助工具
|
||||||
* @param object
|
* @param object
|
||||||
*/
|
*/
|
||||||
removeHelper(object:THREE.Object3D) {
|
removeHelper(object: THREE.Object3D) {
|
||||||
if (this.helpers[object.id] !== undefined) {
|
if (this.helpers[object.id] !== undefined) {
|
||||||
const helper = this.helpers[object.id];
|
const helper = this.helpers[object.id];
|
||||||
helper.parent?.remove(helper);
|
helper.parent?.remove(helper);
|
||||||
@ -514,8 +524,8 @@ export class App {
|
|||||||
* @param object
|
* @param object
|
||||||
* @param script
|
* @param script
|
||||||
*/
|
*/
|
||||||
addScript(object:THREE.Object3D, script:ISceneScript) {
|
addScript(object: THREE.Object3D, script: ISceneScript) {
|
||||||
this.execute(new AddScriptCommand(object,script));
|
this.execute(new AddScriptCommand(object, script));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -523,8 +533,8 @@ export class App {
|
|||||||
* @param object
|
* @param object
|
||||||
* @param script
|
* @param script
|
||||||
*/
|
*/
|
||||||
removeScript(object:THREE.Object3D, script:ISceneScript) {
|
removeScript(object: THREE.Object3D, script: ISceneScript) {
|
||||||
this.execute(new RemoveScriptCommand(object,script));
|
this.execute(new RemoveScriptCommand(object, script));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -532,7 +542,7 @@ export class App {
|
|||||||
* @param object
|
* @param object
|
||||||
* @param slot
|
* @param slot
|
||||||
*/
|
*/
|
||||||
getObjectMaterial(object:THREE.Object3D, slot:number) {
|
getObjectMaterial(object: THREE.Object3D, slot: number) {
|
||||||
let material = object.material;
|
let material = object.material;
|
||||||
|
|
||||||
if (Array.isArray(material) && slot !== undefined) {
|
if (Array.isArray(material) && slot !== undefined) {
|
||||||
@ -547,7 +557,7 @@ export class App {
|
|||||||
* @param slot
|
* @param slot
|
||||||
* @param newMaterial
|
* @param newMaterial
|
||||||
*/
|
*/
|
||||||
setObjectMaterial(object:THREE.Object3D, slot:number | undefined, newMaterial:THREE.Material) {
|
setObjectMaterial(object: THREE.Object3D, slot: number | undefined, newMaterial: THREE.Material) {
|
||||||
if (Array.isArray(object.material) && slot !== undefined) {
|
if (Array.isArray(object.material) && slot !== undefined) {
|
||||||
object.material[slot] = newMaterial;
|
object.material[slot] = newMaterial;
|
||||||
} else {
|
} else {
|
||||||
@ -577,7 +587,7 @@ export class App {
|
|||||||
* 选中模型
|
* 选中模型
|
||||||
* @param object
|
* @param object
|
||||||
*/
|
*/
|
||||||
select(object:THREE.Object3D) {
|
select(object: THREE.Object3D) {
|
||||||
this.selector.select(object);
|
this.selector.select(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,7 +595,7 @@ export class App {
|
|||||||
* 通过模型id选中模型
|
* 通过模型id选中模型
|
||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
selectById(id:number) {
|
selectById(id: number) {
|
||||||
if (id === this.camera.id) {
|
if (id === this.camera.id) {
|
||||||
this.select(this.camera);
|
this.select(this.camera);
|
||||||
return;
|
return;
|
||||||
@ -600,9 +610,9 @@ export class App {
|
|||||||
* 通过模型uuid选中模型
|
* 通过模型uuid选中模型
|
||||||
* @param uuid
|
* @param uuid
|
||||||
*/
|
*/
|
||||||
selectByUuid(uuid:string) {
|
selectByUuid(uuid: string) {
|
||||||
const scope = this;
|
const scope = this;
|
||||||
this.scene.traverse(function (child:THREE.Object3D) {
|
this.scene.traverse(function (child: THREE.Object3D) {
|
||||||
if (child.uuid === uuid) {
|
if (child.uuid === uuid) {
|
||||||
scope.select(child);
|
scope.select(child);
|
||||||
}
|
}
|
||||||
@ -620,8 +630,8 @@ export class App {
|
|||||||
* 锁定模型
|
* 锁定模型
|
||||||
* @param object
|
* @param object
|
||||||
*/
|
*/
|
||||||
lock(object?:THREE.Object3D | null){
|
lock(object?: THREE.Object3D | null) {
|
||||||
if(!object){
|
if (!object) {
|
||||||
object = this.selected;
|
object = this.selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -634,7 +644,7 @@ export class App {
|
|||||||
/**
|
/**
|
||||||
* 取消模型锁定状态
|
* 取消模型锁定状态
|
||||||
*/
|
*/
|
||||||
unlock(){
|
unlock() {
|
||||||
this.locked = null;
|
this.locked = null;
|
||||||
useDispatchSignal('objectUnlocked');
|
useDispatchSignal('objectUnlocked');
|
||||||
}
|
}
|
||||||
@ -643,7 +653,7 @@ export class App {
|
|||||||
* 相机聚焦模型
|
* 相机聚焦模型
|
||||||
* @param object
|
* @param object
|
||||||
*/
|
*/
|
||||||
focus(object:THREE.Object3D) {
|
focus(object: THREE.Object3D) {
|
||||||
if (object !== undefined) {
|
if (object !== undefined) {
|
||||||
useDispatchSignal('objectFocused', object);
|
useDispatchSignal('objectFocused', object);
|
||||||
}
|
}
|
||||||
@ -653,7 +663,7 @@ export class App {
|
|||||||
* 通过id聚焦模型
|
* 通过id聚焦模型
|
||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
focusById(id:number) {
|
focusById(id: number) {
|
||||||
const obj = this.scene.getObjectById(id);
|
const obj = this.scene.getObjectById(id);
|
||||||
|
|
||||||
obj && this.focus(obj);
|
obj && this.focus(obj);
|
||||||
@ -663,7 +673,7 @@ export class App {
|
|||||||
* 通过uuid聚焦模型
|
* 通过uuid聚焦模型
|
||||||
* @param uuid
|
* @param uuid
|
||||||
*/
|
*/
|
||||||
focusByUuid(uuid:string) {
|
focusByUuid(uuid: string) {
|
||||||
if (uuid === undefined) {
|
if (uuid === undefined) {
|
||||||
this.deselect();
|
this.deselect();
|
||||||
return;
|
return;
|
||||||
@ -677,7 +687,7 @@ export class App {
|
|||||||
* 通过uuid获取模型
|
* 通过uuid获取模型
|
||||||
* @param uuid
|
* @param uuid
|
||||||
*/
|
*/
|
||||||
getObjectByUuid(uuid:string) {
|
getObjectByUuid(uuid: string) {
|
||||||
return this.scene.getObjectByProperty('uuid', uuid);
|
return this.scene.getObjectByProperty('uuid', uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -685,7 +695,7 @@ export class App {
|
|||||||
* 遍历平铺所有子级mesh
|
* 遍历平铺所有子级mesh
|
||||||
* @param object
|
* @param object
|
||||||
*/
|
*/
|
||||||
traverseMeshToArr(object:THREE.Object3D) {
|
traverseMeshToArr(object: THREE.Object3D) {
|
||||||
if (object.isMesh) return [object];
|
if (object.isMesh) return [object];
|
||||||
|
|
||||||
const arr: THREE.Mesh[] = [];
|
const arr: THREE.Mesh[] = [];
|
||||||
@ -720,7 +730,7 @@ export class App {
|
|||||||
* @param textures
|
* @param textures
|
||||||
* @param properties
|
* @param properties
|
||||||
*/
|
*/
|
||||||
createPBRMaterial(textures: { [type: string]:string | THREE.Texture } = {},properties:any = {}):Promise<THREE.MeshStandardMaterial> {
|
createPBRMaterial(textures: { [type: string]: string | THREE.Texture } = {}, properties: any = {}): Promise<THREE.MeshStandardMaterial> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const material = new THREE.MeshStandardMaterial({
|
const material = new THREE.MeshStandardMaterial({
|
||||||
// 位移贴图对网格的影响程度默认设置为0
|
// 位移贴图对网格的影响程度默认设置为0
|
||||||
@ -731,10 +741,10 @@ export class App {
|
|||||||
material[key] = properties[key];
|
material[key] = properties[key];
|
||||||
});
|
});
|
||||||
|
|
||||||
const num = new Proxy({value: 10},{
|
const num = new Proxy({ value: 10 }, {
|
||||||
set(target: { value: number }, p: string | symbol, newValue: any): boolean {
|
set(target: { value: number }, p: string | symbol, newValue: any): boolean {
|
||||||
target[p] = newValue;
|
target[p] = newValue;
|
||||||
if(p === 'value' && newValue === 0){
|
if (p === 'value' && newValue === 0) {
|
||||||
resolve(material);
|
resolve(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -743,141 +753,141 @@ export class App {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 基础颜色贴图(高光反射/光泽度工作流:diffuse, 金属/粗糙度工作流:baseColor)
|
// 基础颜色贴图(高光反射/光泽度工作流:diffuse, 金属/粗糙度工作流:baseColor)
|
||||||
if(textures.baseColor){
|
if (textures.baseColor) {
|
||||||
this.resource.loadURLTexture(textures.baseColor,(texture => {
|
this.resource.loadURLTexture(textures.baseColor, (texture => {
|
||||||
material.map = texture;
|
material.map = texture;
|
||||||
|
|
||||||
num.value--;
|
num.value--;
|
||||||
}),err => {
|
}), err => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
num.value--;
|
num.value--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 法线贴图
|
// 法线贴图
|
||||||
if(textures.normal){
|
if (textures.normal) {
|
||||||
this.resource.loadURLTexture(textures.normal,(texture => {
|
this.resource.loadURLTexture(textures.normal, (texture => {
|
||||||
material.normalMap = texture;
|
material.normalMap = texture;
|
||||||
|
|
||||||
num.value--;
|
num.value--;
|
||||||
}),err => {
|
}), err => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
}else if(textures.bump){
|
} else if (textures.bump) {
|
||||||
// 凹凸贴图(如果定义了法线贴图,则将忽略该贴图)
|
// 凹凸贴图(如果定义了法线贴图,则将忽略该贴图)
|
||||||
this.resource.loadURLTexture(textures.bump,(texture => {
|
this.resource.loadURLTexture(textures.bump, (texture => {
|
||||||
material.bumpMap = texture;
|
material.bumpMap = texture;
|
||||||
|
|
||||||
num.value--;
|
num.value--;
|
||||||
}),err => {
|
}), err => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
num.value--;
|
num.value--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 置换贴图(位移贴图)
|
// 置换贴图(位移贴图)
|
||||||
if(textures.displacement){
|
if (textures.displacement) {
|
||||||
this.resource.loadURLTexture(textures.displacement,(texture => {
|
this.resource.loadURLTexture(textures.displacement, (texture => {
|
||||||
material.displacementMap = texture;
|
material.displacementMap = texture;
|
||||||
|
|
||||||
num.value--;
|
num.value--;
|
||||||
}),err => {
|
}), err => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
num.value--;
|
num.value--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 粗糙度贴图
|
// 粗糙度贴图
|
||||||
if(textures.roughness){
|
if (textures.roughness) {
|
||||||
this.resource.loadURLTexture(textures.roughness,(texture => {
|
this.resource.loadURLTexture(textures.roughness, (texture => {
|
||||||
material.roughnessMap = texture;
|
material.roughnessMap = texture;
|
||||||
|
|
||||||
num.value--;
|
num.value--;
|
||||||
}),err => {
|
}), err => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
num.value--;
|
num.value--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 金属度贴图
|
// 金属度贴图
|
||||||
if(textures.metalness){
|
if (textures.metalness) {
|
||||||
this.resource.loadURLTexture(textures.metalness,(texture => {
|
this.resource.loadURLTexture(textures.metalness, (texture => {
|
||||||
material.metalnessMap = texture;
|
material.metalnessMap = texture;
|
||||||
|
|
||||||
num.value--;
|
num.value--;
|
||||||
}),err => {
|
}), err => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
num.value--;
|
num.value--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 环境遮挡贴图
|
// 环境遮挡贴图
|
||||||
if(textures.ao){
|
if (textures.ao) {
|
||||||
this.resource.loadURLTexture(textures.ao,(texture => {
|
this.resource.loadURLTexture(textures.ao, (texture => {
|
||||||
material.aoMap = texture;
|
material.aoMap = texture;
|
||||||
|
|
||||||
num.value--;
|
num.value--;
|
||||||
}),err => {
|
}), err => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
num.value--;
|
num.value--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自发光贴图
|
// 自发光贴图
|
||||||
if(textures.emissive){
|
if (textures.emissive) {
|
||||||
this.resource.loadURLTexture(textures.emissive,(texture => {
|
this.resource.loadURLTexture(textures.emissive, (texture => {
|
||||||
material.emissiveMap = texture;
|
material.emissiveMap = texture;
|
||||||
|
|
||||||
num.value--;
|
num.value--;
|
||||||
}),err => {
|
}), err => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
num.value--;
|
num.value--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 透明贴图
|
// 透明贴图
|
||||||
if(textures.alpha){
|
if (textures.alpha) {
|
||||||
this.resource.loadURLTexture(textures.alpha,(texture => {
|
this.resource.loadURLTexture(textures.alpha, (texture => {
|
||||||
material.alphaMap = texture;
|
material.alphaMap = texture;
|
||||||
|
|
||||||
num.value--;
|
num.value--;
|
||||||
}),err => {
|
}), err => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
num.value--;
|
num.value--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 环境贴图(一般不会设置,因为会使用scene.environment)
|
// 环境贴图(一般不会设置,因为会使用scene.environment)
|
||||||
if(textures.env){
|
if (textures.env) {
|
||||||
this.resource.loadURLTexture(textures.env,(texture => {
|
this.resource.loadURLTexture(textures.env, (texture => {
|
||||||
material.envMap = texture;
|
material.envMap = texture;
|
||||||
|
|
||||||
num.value--;
|
num.value--;
|
||||||
}),err => {
|
}), err => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
num.value--;
|
num.value--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 光照贴图
|
// 光照贴图
|
||||||
if(textures.light){
|
if (textures.light) {
|
||||||
this.resource.loadURLTexture(textures.light,(texture => {
|
this.resource.loadURLTexture(textures.light, (texture => {
|
||||||
material.lightMap = texture;
|
material.lightMap = texture;
|
||||||
|
|
||||||
num.value--;
|
num.value--;
|
||||||
}),err => {
|
}), err => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
num.value--;
|
num.value--;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -898,7 +908,7 @@ export class App {
|
|||||||
this.scene.environment = null;
|
this.scene.environment = null;
|
||||||
this.scene.fog = null;
|
this.scene.fog = null;
|
||||||
|
|
||||||
for(let i = this.scene.children.length - 1; i >= 0; i--){
|
for (let i = this.scene.children.length - 1; i >= 0; i--) {
|
||||||
this.removeObject(this.scene.children[i]);
|
this.removeObject(this.scene.children[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,9 +952,9 @@ export class App {
|
|||||||
const scene = this.setScene(await loader.parseAsync(sceneJson.scene) as THREE.Scene);
|
const scene = this.setScene(await loader.parseAsync(sceneJson.scene) as THREE.Scene);
|
||||||
|
|
||||||
// 20250718: 环境类型是ModelViewer时需要手动设置,因为scene.toJSON()不会处理renderTargetTexture
|
// 20250718: 环境类型是ModelViewer时需要手动设置,因为scene.toJSON()不会处理renderTargetTexture
|
||||||
switch(sceneJson.scene.object.environmentType){
|
switch (sceneJson.scene.object.environmentType) {
|
||||||
case "ModelViewer":
|
case "ModelViewer":
|
||||||
useDispatchSignal("sceneEnvironmentChanged",'ModelViewer');
|
useDispatchSignal("sceneEnvironmentChanged", 'ModelViewer');
|
||||||
useDispatchSignal("sceneGraphChanged");
|
useDispatchSignal("sceneGraphChanged");
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -990,7 +1000,7 @@ export class App {
|
|||||||
* @param cmd
|
* @param cmd
|
||||||
* @param optionalName
|
* @param optionalName
|
||||||
*/
|
*/
|
||||||
execute(cmd, optionalName?:string) {
|
execute(cmd, optionalName?: string) {
|
||||||
this.history.execute(cmd, optionalName);
|
this.history.execute(cmd, optionalName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,15 +5,29 @@ import * as THREE from "three";
|
|||||||
* @param callback - 以一个object3D对象作为第一个参数的函数。
|
* @param callback - 以一个object3D对象作为第一个参数的函数。
|
||||||
* @param condition - 需要满足该条件才继续后续回调的条件函数
|
* @param condition - 需要满足该条件才继续后续回调的条件函数
|
||||||
*/
|
*/
|
||||||
THREE.Object3D.prototype.traverseByCondition = function(callback, condition){
|
THREE.Object3D.prototype.traverseByCondition = function (callback, condition) {
|
||||||
if (!condition(this)) return;
|
if (!condition(this)) return;
|
||||||
|
|
||||||
callback(this);
|
callback(this);
|
||||||
|
|
||||||
const children = this.children;
|
const children = this.children;
|
||||||
|
|
||||||
|
// 优先使用子对象的traverseByCondition方法,如果没有则降级兜底
|
||||||
|
const fallbackFn = (child) => {
|
||||||
|
if (condition(child)) {
|
||||||
|
callback(child);
|
||||||
|
}
|
||||||
|
child.children.forEach(grandChild => fallbackFn(grandChild));
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 0, l = children.length; i < l; i++) {
|
for (let i = 0, l = children.length; i < l; i++) {
|
||||||
children[i].traverseByCondition(callback, condition);
|
// @ts-ignore
|
||||||
|
if (children[i].traverseByCondition) {
|
||||||
|
children[i].traverseByCondition(callback, condition);
|
||||||
|
} else {
|
||||||
|
// 降级兜底
|
||||||
|
fallbackFn(children[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,8 +35,8 @@ THREE.Object3D.prototype.traverseByCondition = function(callback, condition){
|
|||||||
* 判断 parentObj 是否是 当前对象 的任意层级祖先(包括祖父、曾祖父等)
|
* 判断 parentObj 是否是 当前对象 的任意层级祖先(包括祖父、曾祖父等)
|
||||||
* @param parentObj - 可能是祖先的对象
|
* @param parentObj - 可能是祖先的对象
|
||||||
*/
|
*/
|
||||||
THREE.Object3D.prototype.isAncestor = function(parentObj) {
|
THREE.Object3D.prototype.isAncestor = function (parentObj) {
|
||||||
let current:THREE.Object3D | null = this;
|
let current: THREE.Object3D | null = this;
|
||||||
while (current) {
|
while (current) {
|
||||||
if (current === parentObj) return true;
|
if (current === parentObj) return true;
|
||||||
current = current.parent;
|
current = current.parent;
|
||||||
@ -33,7 +47,7 @@ THREE.Object3D.prototype.isAncestor = function(parentObj) {
|
|||||||
/**
|
/**
|
||||||
* 重写toJSON方法
|
* 重写toJSON方法
|
||||||
*/
|
*/
|
||||||
THREE.Object3D.prototype.toJSON = function(meta:any) {
|
THREE.Object3D.prototype.toJSON = function (meta: any) {
|
||||||
// 当从JSON.stringify调用时,meta是一个字符串
|
// 当从JSON.stringify调用时,meta是一个字符串
|
||||||
const isRootObject = (meta === undefined || typeof meta === 'string');
|
const isRootObject = (meta === undefined || typeof meta === 'string');
|
||||||
|
|
||||||
@ -60,7 +74,7 @@ THREE.Object3D.prototype.toJSON = function(meta:any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 标准Object3D序列化
|
// 标准Object3D序列化
|
||||||
const object:any = {
|
const object: any = {
|
||||||
uuid: this.uuid,
|
uuid: this.uuid,
|
||||||
type: this.type
|
type: this.type
|
||||||
};
|
};
|
||||||
@ -184,14 +198,14 @@ THREE.Object3D.prototype.toJSON = function(meta:any) {
|
|||||||
// 判断元数据是否含有材质
|
// 判断元数据是否含有材质
|
||||||
// 创建新变量替代,不然正在使用的材质被还原回this.metaData.material会造成播放异常
|
// 创建新变量替代,不然正在使用的材质被还原回this.metaData.material会造成播放异常
|
||||||
let _material = this.material;
|
let _material = this.material;
|
||||||
if(this.metaData?.material){
|
if (this.metaData?.material) {
|
||||||
if (this.metaData.material instanceof THREE.Material){
|
if (this.metaData.material instanceof THREE.Material) {
|
||||||
_material = this.metaData.material;
|
_material = this.metaData.material;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Array.isArray(_material)) {
|
if (Array.isArray(_material)) {
|
||||||
const uuids:string[] = [];
|
const uuids: string[] = [];
|
||||||
|
|
||||||
for (let i = 0, l = _material.length; i < l; i++) {
|
for (let i = 0, l = _material.length; i < l; i++) {
|
||||||
uuids.push(serialize(meta.materials, _material[i]));
|
uuids.push(serialize(meta.materials, _material[i]));
|
||||||
@ -217,10 +231,10 @@ THREE.Object3D.prototype.toJSON = function(meta:any) {
|
|||||||
for (let i = 0; i < this.animations.length; i++) {
|
for (let i = 0; i < this.animations.length; i++) {
|
||||||
let animation = this.animations[i];
|
let animation = this.animations[i];
|
||||||
// 20250306 修复动画导出问题(代码中处理了object3D.animations,此属性下是AnimationAction数组)
|
// 20250306 修复动画导出问题(代码中处理了object3D.animations,此属性下是AnimationAction数组)
|
||||||
if(animation instanceof THREE.AnimationAction){
|
if (animation instanceof THREE.AnimationAction) {
|
||||||
animation = animation.getClip();
|
animation = animation.getClip();
|
||||||
}
|
}
|
||||||
if(!animation) continue;
|
if (!animation) continue;
|
||||||
object.animations.push(serialize(meta.animations, animation));
|
object.animations.push(serialize(meta.animations, animation));
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -244,7 +258,7 @@ THREE.Object3D.prototype.toJSON = function(meta:any) {
|
|||||||
if (skeletons.length > 0) output.skeletons = skeletons;
|
if (skeletons.length > 0) output.skeletons = skeletons;
|
||||||
if (animations.length > 0) output.animations = animations.map(animation => {
|
if (animations.length > 0) output.animations = animations.map(animation => {
|
||||||
animation.tracks = animation.tracks.map(track => {
|
animation.tracks = animation.tracks.map(track => {
|
||||||
if(!track.type){
|
if (!track.type) {
|
||||||
track.type = 'vector';
|
track.type = 'vector';
|
||||||
}
|
}
|
||||||
return track;
|
return track;
|
||||||
@ -261,7 +275,7 @@ THREE.Object3D.prototype.toJSON = function(meta:any) {
|
|||||||
|
|
||||||
// 从缓存哈希中提取数据,删除每个项目上的元数据并作为数组返回
|
// 从缓存哈希中提取数据,删除每个项目上的元数据并作为数组返回
|
||||||
function extractFromCache(cache) {
|
function extractFromCache(cache) {
|
||||||
const values:any = [];
|
const values: any = [];
|
||||||
for (const key in cache) {
|
for (const key in cache) {
|
||||||
const data = cache[key];
|
const data = cache[key];
|
||||||
delete data.metadata;
|
delete data.metadata;
|
||||||
|
|||||||
@ -39,6 +39,8 @@ class Measure extends THREE.EventDispatcher<MeasureEventMap>{
|
|||||||
depthWrite: false,
|
depthWrite: false,
|
||||||
depthTest: false
|
depthTest: false
|
||||||
});
|
});
|
||||||
|
// 标记点图片
|
||||||
|
static MARKER_TEXTURE = new URL(import.meta.env.BASE_URL + 'static/images/logo.png', import.meta.url).href;
|
||||||
static MAX_DISTANCE = 500; //当相交物体的距离太远时,忽略它
|
static MAX_DISTANCE = 500; //当相交物体的距离太远时,忽略它
|
||||||
static OBJ_NAME = "object_for_measure";
|
static OBJ_NAME = "object_for_measure";
|
||||||
static LABEL_NAME = "label_for_measure";
|
static LABEL_NAME = "label_for_measure";
|
||||||
@ -69,12 +71,13 @@ class Measure extends THREE.EventDispatcher<MeasureEventMap>{
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
this.scene = viewer.sceneHelpers;
|
this.scene = viewer.scene;
|
||||||
this.viewer = viewer;
|
this.viewer = viewer;
|
||||||
|
|
||||||
// 初始化group
|
// 初始化group
|
||||||
this.measureGroup = new THREE.Group();
|
this.measureGroup = new THREE.Group();
|
||||||
this.measureGroup.name = `measure_group`;
|
this.measureGroup.name = `measure_group`;
|
||||||
|
this.measureGroup.ignore = true;
|
||||||
|
|
||||||
this.group = new THREE.Group();
|
this.group = new THREE.Group();
|
||||||
|
|
||||||
@ -239,7 +242,7 @@ class Measure extends THREE.EventDispatcher<MeasureEventMap>{
|
|||||||
* 初始化点标记材料
|
* 初始化点标记材料
|
||||||
*/
|
*/
|
||||||
initPointMarkerMaterial() {
|
initPointMarkerMaterial() {
|
||||||
const markerTexture = new THREE.TextureLoader().load("/static/images/logo/logo.png");
|
const markerTexture = new THREE.TextureLoader().load(Measure.MARKER_TEXTURE);
|
||||||
this.spriteMaterial = new THREE.SpriteMaterial({
|
this.spriteMaterial = new THREE.SpriteMaterial({
|
||||||
map: markerTexture,
|
map: markerTexture,
|
||||||
depthTest: false, // 深度测试
|
depthTest: false, // 深度测试
|
||||||
|
|||||||
@ -1103,9 +1103,7 @@ export default class Viewer extends THREE.EventDispatcher<ViewerEventMap> {
|
|||||||
if (this.options.edit?.enabled) this.renderer.render(this.sceneHelpers, this.camera);
|
if (this.options.edit?.enabled) this.renderer.render(this.sceneHelpers, this.camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
// css2d 在sceneHelpers内
|
this.css2DRenderer.render(this.scene, App.viewportCamera);
|
||||||
this.css2DRenderer.render(this.sceneHelpers, App.viewportCamera);
|
|
||||||
|
|
||||||
this.css3DRenderer.render(this.scene, App.viewportCamera);
|
this.css3DRenderer.render(this.scene, App.viewportCamera);
|
||||||
|
|
||||||
this.modules.viewHelper.render();
|
this.modules.viewHelper.render();
|
||||||
|
|||||||
@ -1,12 +1,49 @@
|
|||||||
import {Object3D,Box3,Vector3} from "three";
|
import {Object3D,Box3,Sphere,Vector3} from "three";
|
||||||
import CameraControls from "camera-controls";
|
import CameraControls from "camera-controls";
|
||||||
|
|
||||||
export function focusObject(object:Object3D,controls:CameraControls,enableTransition: boolean = true){
|
function getObjectBox3(object:Object3D){
|
||||||
const box3 = new Box3();
|
const box3 = new Box3();
|
||||||
box3.setFromObject(object);
|
box3.setFromObject(object);
|
||||||
|
|
||||||
if(box3.isEmpty()){
|
if(box3.isEmpty()){
|
||||||
box3.set(new Vector3(object.position.x-1, object.position.y-1, object.position.z-1), new Vector3(object.position.x+1, object.position.y+1, object.position.z+1));
|
box3.set(new Vector3(object.position.x-1, object.position.y-1, object.position.z-1), new Vector3(object.position.x+1, object.position.y+1, object.position.z+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return box3;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function focusObject(object:Object3D,controls:CameraControls,enableTransition: boolean = true){
|
||||||
|
const box3 = getObjectBox3(object);
|
||||||
|
|
||||||
return controls.fitToBox(box3,enableTransition);
|
return controls.fitToBox(box3,enableTransition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function focusObjectByDistance(object:Object3D,controls:CameraControls,distance:number,enableTransition: boolean = true){
|
||||||
|
const box3 = getObjectBox3(object);
|
||||||
|
const sphere = box3.getBoundingSphere(new Sphere());
|
||||||
|
|
||||||
|
const center = sphere.center.clone();
|
||||||
|
const radius = Number.isFinite(sphere.radius) ? sphere.radius : 1;
|
||||||
|
const toSurfaceDistance = Math.max(distance, 0);
|
||||||
|
const toCenterDistance = Math.max(radius + toSurfaceDistance, 0.01);
|
||||||
|
|
||||||
|
const currentPosition = controls.getPosition(new Vector3());
|
||||||
|
const currentTarget = controls.getTarget(new Vector3());
|
||||||
|
const direction = currentPosition.sub(currentTarget);
|
||||||
|
if(direction.lengthSq() < 1e-6){
|
||||||
|
direction.set(0, 0, 1);
|
||||||
|
}
|
||||||
|
direction.normalize();
|
||||||
|
|
||||||
|
const nextPosition = center.clone().addScaledVector(direction, toCenterDistance);
|
||||||
|
|
||||||
|
return controls.setLookAt(
|
||||||
|
nextPosition.x,
|
||||||
|
nextPosition.y,
|
||||||
|
nextPosition.z,
|
||||||
|
center.x,
|
||||||
|
center.y,
|
||||||
|
center.z,
|
||||||
|
enableTransition
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
BIN
packages/sdk/public/static/images/logo.png
Normal file
BIN
packages/sdk/public/static/images/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
401
pnpm-lock.yaml
401
pnpm-lock.yaml
@ -39,7 +39,11 @@ catalogs:
|
|||||||
|
|
||||||
importers:
|
importers:
|
||||||
|
|
||||||
.: {}
|
.:
|
||||||
|
devDependencies:
|
||||||
|
prettier:
|
||||||
|
specifier: ^3.7.4
|
||||||
|
version: 3.8.1
|
||||||
|
|
||||||
common/build:
|
common/build:
|
||||||
devDependencies:
|
devDependencies:
|
||||||
@ -107,14 +111,14 @@ importers:
|
|||||||
specifier: workspace:^
|
specifier: workspace:^
|
||||||
version: link:../sdk
|
version: link:../sdk
|
||||||
'@gltf-transform/core':
|
'@gltf-transform/core':
|
||||||
specifier: ^4.0.8
|
specifier: ^4.2.1
|
||||||
version: 4.1.3
|
version: 4.3.0
|
||||||
'@gltf-transform/extensions':
|
'@gltf-transform/extensions':
|
||||||
specifier: ^4.0.8
|
specifier: ^4.2.1
|
||||||
version: 4.1.3
|
version: 4.3.0
|
||||||
'@gltf-transform/functions':
|
'@gltf-transform/functions':
|
||||||
specifier: ^4.0.8
|
specifier: ^4.2.1
|
||||||
version: 4.1.3
|
version: 4.3.0
|
||||||
'@vicons/carbon':
|
'@vicons/carbon':
|
||||||
specifier: ^0.12.0
|
specifier: ^0.12.0
|
||||||
version: 0.12.0
|
version: 0.12.0
|
||||||
@ -1044,8 +1048,8 @@ packages:
|
|||||||
'@dxfom/mtext@0.3.2':
|
'@dxfom/mtext@0.3.2':
|
||||||
resolution: {integrity: sha512-QL2XYBiAidjKYe0W04Icz051P9V0EBh6H7R0rcrvcUEPGr7PzLBYRt+f9X4WOnBGuoGlTKJ/7NKPRYUCCSkVYg==}
|
resolution: {integrity: sha512-QL2XYBiAidjKYe0W04Icz051P9V0EBh6H7R0rcrvcUEPGr7PzLBYRt+f9X4WOnBGuoGlTKJ/7NKPRYUCCSkVYg==}
|
||||||
|
|
||||||
'@emnapi/runtime@1.4.3':
|
'@emnapi/runtime@1.8.1':
|
||||||
resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==}
|
resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==}
|
||||||
|
|
||||||
'@emotion/hash@0.8.0':
|
'@emotion/hash@0.8.0':
|
||||||
resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==}
|
resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==}
|
||||||
@ -1206,14 +1210,14 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@gltf-transform/core@4.1.3':
|
'@gltf-transform/core@4.3.0':
|
||||||
resolution: {integrity: sha512-N+73Vo9DTXV2QmsnetLRY4q3z0Q0oyH0i/ymvzEkgpgNEAq+RP73ZLY0HK+Ia0rTUMgFwQHFNyHDyFiENToBZA==}
|
resolution: {integrity: sha512-ZeaQfszGJ9LYwELszu45CuDQCsE26lJNNe36FVmN8xclaT6WDdCj7fwGpQXo0/l/YgAVAHX+uO7YNBW75/SRYw==}
|
||||||
|
|
||||||
'@gltf-transform/extensions@4.1.3':
|
'@gltf-transform/extensions@4.3.0':
|
||||||
resolution: {integrity: sha512-RcjA6UfBqOQPMqYhY/ftHAjrO1mnGLxUIXwErrH8qBoMprgkfLmi3fZuNL1tgZXlSPTjYdMCd7zEOc707F8Ekg==}
|
resolution: {integrity: sha512-XDAjQPYVMHa/VDpSbfCBwI+/1muwRJCaXhUpLgnUzAjn0D//PgvIAcbNm1EwBl3LIWBSwjDUCn2LiMAjp+aXVw==}
|
||||||
|
|
||||||
'@gltf-transform/functions@4.1.3':
|
'@gltf-transform/functions@4.3.0':
|
||||||
resolution: {integrity: sha512-SS0WH43lA/ttysXB0DovwhKF5yuAXOW/BWUqFlQPCX/NDqt+7qMDqGYL7zCB24NdUh43ipd4k/7QRVMwyrBZUA==}
|
resolution: {integrity: sha512-FZggHVgt3DHOezgESBrf2vDzuD2FYQYaNT2sT/aP316SIwhuiIwby3z7rhV9joDvWqqUaPkf1UmkjlOaY9riSQ==}
|
||||||
|
|
||||||
'@iconify/types@2.0.0':
|
'@iconify/types@2.0.0':
|
||||||
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
|
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
|
||||||
@ -1229,107 +1233,155 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
vue: '>=3'
|
vue: '>=3'
|
||||||
|
|
||||||
'@img/sharp-darwin-arm64@0.33.5':
|
'@img/colour@1.1.0':
|
||||||
resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==}
|
resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
'@img/sharp-darwin-arm64@0.34.5':
|
||||||
|
resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
|
||||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
'@img/sharp-darwin-x64@0.33.5':
|
'@img/sharp-darwin-x64@0.34.5':
|
||||||
resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==}
|
resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
|
||||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
'@img/sharp-libvips-darwin-arm64@1.0.4':
|
'@img/sharp-libvips-darwin-arm64@1.2.4':
|
||||||
resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==}
|
resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
'@img/sharp-libvips-darwin-x64@1.0.4':
|
'@img/sharp-libvips-darwin-x64@1.2.4':
|
||||||
resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==}
|
resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
'@img/sharp-libvips-linux-arm64@1.0.4':
|
'@img/sharp-libvips-linux-arm64@1.2.4':
|
||||||
resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==}
|
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@img/sharp-libvips-linux-arm@1.0.5':
|
'@img/sharp-libvips-linux-arm@1.2.4':
|
||||||
resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==}
|
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@img/sharp-libvips-linux-s390x@1.0.4':
|
'@img/sharp-libvips-linux-ppc64@1.2.4':
|
||||||
resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==}
|
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
|
||||||
|
cpu: [ppc64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-riscv64@1.2.4':
|
||||||
|
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
|
||||||
|
cpu: [riscv64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linux-s390x@1.2.4':
|
||||||
|
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
|
||||||
cpu: [s390x]
|
cpu: [s390x]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@img/sharp-libvips-linux-x64@1.0.4':
|
'@img/sharp-libvips-linux-x64@1.2.4':
|
||||||
resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==}
|
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@img/sharp-libvips-linuxmusl-arm64@1.0.4':
|
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
|
||||||
resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==}
|
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@img/sharp-libvips-linuxmusl-x64@1.0.4':
|
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
|
||||||
resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==}
|
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@img/sharp-linux-arm64@0.33.5':
|
'@img/sharp-linux-arm64@0.34.5':
|
||||||
resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==}
|
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
|
||||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@img/sharp-linux-arm@0.33.5':
|
'@img/sharp-linux-arm@0.34.5':
|
||||||
resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==}
|
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
|
||||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@img/sharp-linux-s390x@0.33.5':
|
'@img/sharp-linux-ppc64@0.34.5':
|
||||||
resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==}
|
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
|
||||||
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
|
cpu: [ppc64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-linux-riscv64@0.34.5':
|
||||||
|
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
|
||||||
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
|
cpu: [riscv64]
|
||||||
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
|
'@img/sharp-linux-s390x@0.34.5':
|
||||||
|
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
|
||||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
cpu: [s390x]
|
cpu: [s390x]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@img/sharp-linux-x64@0.33.5':
|
'@img/sharp-linux-x64@0.34.5':
|
||||||
resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==}
|
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
|
||||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@img/sharp-linuxmusl-arm64@0.33.5':
|
'@img/sharp-linuxmusl-arm64@0.34.5':
|
||||||
resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==}
|
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
|
||||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@img/sharp-linuxmusl-x64@0.33.5':
|
'@img/sharp-linuxmusl-x64@0.34.5':
|
||||||
resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==}
|
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
|
||||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@img/sharp-wasm32@0.33.5':
|
'@img/sharp-wasm32@0.34.5':
|
||||||
resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==}
|
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
|
||||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
cpu: [wasm32]
|
cpu: [wasm32]
|
||||||
|
|
||||||
'@img/sharp-win32-ia32@0.33.5':
|
'@img/sharp-win32-arm64@0.34.5':
|
||||||
resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==}
|
resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
|
||||||
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
|
'@img/sharp-win32-ia32@0.34.5':
|
||||||
|
resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
|
||||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
cpu: [ia32]
|
cpu: [ia32]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@img/sharp-win32-x64@0.33.5':
|
'@img/sharp-win32-x64@0.34.5':
|
||||||
resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==}
|
resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
|
||||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
@ -1683,36 +1735,42 @@ packages:
|
|||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@parcel/watcher-linux-arm-musl@2.5.1':
|
'@parcel/watcher-linux-arm-musl@2.5.1':
|
||||||
resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==}
|
resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@parcel/watcher-linux-arm64-glibc@2.5.1':
|
'@parcel/watcher-linux-arm64-glibc@2.5.1':
|
||||||
resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==}
|
resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@parcel/watcher-linux-arm64-musl@2.5.1':
|
'@parcel/watcher-linux-arm64-musl@2.5.1':
|
||||||
resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==}
|
resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@parcel/watcher-linux-x64-glibc@2.5.1':
|
'@parcel/watcher-linux-x64-glibc@2.5.1':
|
||||||
resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==}
|
resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@parcel/watcher-linux-x64-musl@2.5.1':
|
'@parcel/watcher-linux-x64-musl@2.5.1':
|
||||||
resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==}
|
resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@parcel/watcher-win32-arm64@2.5.1':
|
'@parcel/watcher-win32-arm64@2.5.1':
|
||||||
resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==}
|
resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==}
|
||||||
@ -1911,56 +1969,67 @@ packages:
|
|||||||
resolution: {integrity: sha512-+xmiDGGaSfIIOXMzkhJ++Oa0Gwvl9oXUeIiwarsdRXSe27HUIvjbSIpPxvnNsRebsNdUo7uAiQVgBD1hVriwSQ==}
|
resolution: {integrity: sha512-+xmiDGGaSfIIOXMzkhJ++Oa0Gwvl9oXUeIiwarsdRXSe27HUIvjbSIpPxvnNsRebsNdUo7uAiQVgBD1hVriwSQ==}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm-musleabihf@4.44.2':
|
'@rollup/rollup-linux-arm-musleabihf@4.44.2':
|
||||||
resolution: {integrity: sha512-bDHvhzOfORk3wt8yxIra8N4k/N0MnKInCW5OGZaeDYa/hMrdPaJzo7CSkjKZqX4JFUWjUGm88lI6QJLCM7lDrA==}
|
resolution: {integrity: sha512-bDHvhzOfORk3wt8yxIra8N4k/N0MnKInCW5OGZaeDYa/hMrdPaJzo7CSkjKZqX4JFUWjUGm88lI6QJLCM7lDrA==}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm64-gnu@4.44.2':
|
'@rollup/rollup-linux-arm64-gnu@4.44.2':
|
||||||
resolution: {integrity: sha512-NMsDEsDiYghTbeZWEGnNi4F0hSbGnsuOG+VnNvxkKg0IGDvFh7UVpM/14mnMwxRxUf9AdAVJgHPvKXf6FpMB7A==}
|
resolution: {integrity: sha512-NMsDEsDiYghTbeZWEGnNi4F0hSbGnsuOG+VnNvxkKg0IGDvFh7UVpM/14mnMwxRxUf9AdAVJgHPvKXf6FpMB7A==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm64-musl@4.44.2':
|
'@rollup/rollup-linux-arm64-musl@4.44.2':
|
||||||
resolution: {integrity: sha512-lb5bxXnxXglVq+7imxykIp5xMq+idehfl+wOgiiix0191av84OqbjUED+PRC5OA8eFJYj5xAGcpAZ0pF2MnW+A==}
|
resolution: {integrity: sha512-lb5bxXnxXglVq+7imxykIp5xMq+idehfl+wOgiiix0191av84OqbjUED+PRC5OA8eFJYj5xAGcpAZ0pF2MnW+A==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@rollup/rollup-linux-loongarch64-gnu@4.44.2':
|
'@rollup/rollup-linux-loongarch64-gnu@4.44.2':
|
||||||
resolution: {integrity: sha512-Yl5Rdpf9pIc4GW1PmkUGHdMtbx0fBLE1//SxDmuf3X0dUC57+zMepow2LK0V21661cjXdTn8hO2tXDdAWAqE5g==}
|
resolution: {integrity: sha512-Yl5Rdpf9pIc4GW1PmkUGHdMtbx0fBLE1//SxDmuf3X0dUC57+zMepow2LK0V21661cjXdTn8hO2tXDdAWAqE5g==}
|
||||||
cpu: [loong64]
|
cpu: [loong64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@rollup/rollup-linux-powerpc64le-gnu@4.44.2':
|
'@rollup/rollup-linux-powerpc64le-gnu@4.44.2':
|
||||||
resolution: {integrity: sha512-03vUDH+w55s680YYryyr78jsO1RWU9ocRMaeV2vMniJJW/6HhoTBwyyiiTPVHNWLnhsnwcQ0oH3S9JSBEKuyqw==}
|
resolution: {integrity: sha512-03vUDH+w55s680YYryyr78jsO1RWU9ocRMaeV2vMniJJW/6HhoTBwyyiiTPVHNWLnhsnwcQ0oH3S9JSBEKuyqw==}
|
||||||
cpu: [ppc64]
|
cpu: [ppc64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@rollup/rollup-linux-riscv64-gnu@4.44.2':
|
'@rollup/rollup-linux-riscv64-gnu@4.44.2':
|
||||||
resolution: {integrity: sha512-iYtAqBg5eEMG4dEfVlkqo05xMOk6y/JXIToRca2bAWuqjrJYJlx/I7+Z+4hSrsWU8GdJDFPL4ktV3dy4yBSrzg==}
|
resolution: {integrity: sha512-iYtAqBg5eEMG4dEfVlkqo05xMOk6y/JXIToRca2bAWuqjrJYJlx/I7+Z+4hSrsWU8GdJDFPL4ktV3dy4yBSrzg==}
|
||||||
cpu: [riscv64]
|
cpu: [riscv64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@rollup/rollup-linux-riscv64-musl@4.44.2':
|
'@rollup/rollup-linux-riscv64-musl@4.44.2':
|
||||||
resolution: {integrity: sha512-e6vEbgaaqz2yEHqtkPXa28fFuBGmUJ0N2dOJK8YUfijejInt9gfCSA7YDdJ4nYlv67JfP3+PSWFX4IVw/xRIPg==}
|
resolution: {integrity: sha512-e6vEbgaaqz2yEHqtkPXa28fFuBGmUJ0N2dOJK8YUfijejInt9gfCSA7YDdJ4nYlv67JfP3+PSWFX4IVw/xRIPg==}
|
||||||
cpu: [riscv64]
|
cpu: [riscv64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@rollup/rollup-linux-s390x-gnu@4.44.2':
|
'@rollup/rollup-linux-s390x-gnu@4.44.2':
|
||||||
resolution: {integrity: sha512-evFOtkmVdY3udE+0QKrV5wBx7bKI0iHz5yEVx5WqDJkxp9YQefy4Mpx3RajIVcM6o7jxTvVd/qpC1IXUhGc1Mw==}
|
resolution: {integrity: sha512-evFOtkmVdY3udE+0QKrV5wBx7bKI0iHz5yEVx5WqDJkxp9YQefy4Mpx3RajIVcM6o7jxTvVd/qpC1IXUhGc1Mw==}
|
||||||
cpu: [s390x]
|
cpu: [s390x]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@rollup/rollup-linux-x64-gnu@4.44.2':
|
'@rollup/rollup-linux-x64-gnu@4.44.2':
|
||||||
resolution: {integrity: sha512-/bXb0bEsWMyEkIsUL2Yt5nFB5naLAwyOWMEviQfQY1x3l5WsLKgvZf66TM7UTfED6erckUVUJQ/jJ1FSpm3pRQ==}
|
resolution: {integrity: sha512-/bXb0bEsWMyEkIsUL2Yt5nFB5naLAwyOWMEviQfQY1x3l5WsLKgvZf66TM7UTfED6erckUVUJQ/jJ1FSpm3pRQ==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@rollup/rollup-linux-x64-musl@4.44.2':
|
'@rollup/rollup-linux-x64-musl@4.44.2':
|
||||||
resolution: {integrity: sha512-3D3OB1vSSBXmkGEZR27uiMRNiwN08/RVAcBKwhUYPaiZ8bcvdeEwWPvbnXvvXHY+A/7xluzcN+kaiOFNiOZwWg==}
|
resolution: {integrity: sha512-3D3OB1vSSBXmkGEZR27uiMRNiwN08/RVAcBKwhUYPaiZ8bcvdeEwWPvbnXvvXHY+A/7xluzcN+kaiOFNiOZwWg==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@rollup/rollup-win32-arm64-msvc@4.44.2':
|
'@rollup/rollup-win32-arm64-msvc@4.44.2':
|
||||||
resolution: {integrity: sha512-VfU0fsMK+rwdK8mwODqYeM2hDrF2WiHaSmCBrS7gColkQft95/8tphyzv2EupVxn3iE0FI78wzffoULH1G+dkw==}
|
resolution: {integrity: sha512-VfU0fsMK+rwdK8mwODqYeM2hDrF2WiHaSmCBrS7gColkQft95/8tphyzv2EupVxn3iE0FI78wzffoULH1G+dkw==}
|
||||||
@ -2053,24 +2122,28 @@ packages:
|
|||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@swc/core-linux-arm64-musl@1.11.21':
|
'@swc/core-linux-arm64-musl@1.11.21':
|
||||||
resolution: {integrity: sha512-y1L49+snt1a1gLTYPY641slqy55QotPdtRK9Y6jMi4JBQyZwxC8swWYlQWb+MyILwxA614fi62SCNZNznB3XSA==}
|
resolution: {integrity: sha512-y1L49+snt1a1gLTYPY641slqy55QotPdtRK9Y6jMi4JBQyZwxC8swWYlQWb+MyILwxA614fi62SCNZNznB3XSA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@swc/core-linux-x64-gnu@1.11.21':
|
'@swc/core-linux-x64-gnu@1.11.21':
|
||||||
resolution: {integrity: sha512-NesdBXv4CvVEaFUlqKj+GA4jJMNUzK2NtKOrUNEtTbXaVyNiXjFCSaDajMTedEB0jTAd9ybB0aBvwhgkJUWkWA==}
|
resolution: {integrity: sha512-NesdBXv4CvVEaFUlqKj+GA4jJMNUzK2NtKOrUNEtTbXaVyNiXjFCSaDajMTedEB0jTAd9ybB0aBvwhgkJUWkWA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@swc/core-linux-x64-musl@1.11.21':
|
'@swc/core-linux-x64-musl@1.11.21':
|
||||||
resolution: {integrity: sha512-qFV60pwpKVOdmX67wqQzgtSrUGWX9Cibnp1CXyqZ9Mmt8UyYGvmGu7p6PMbTyX7vdpVUvWVRf8DzrW2//wmVHg==}
|
resolution: {integrity: sha512-qFV60pwpKVOdmX67wqQzgtSrUGWX9Cibnp1CXyqZ9Mmt8UyYGvmGu7p6PMbTyX7vdpVUvWVRf8DzrW2//wmVHg==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@swc/core-win32-arm64-msvc@1.11.21':
|
'@swc/core-win32-arm64-msvc@1.11.21':
|
||||||
resolution: {integrity: sha512-DJJe9k6gXR/15ZZVLv1SKhXkFst8lYCeZRNHH99SlBodvu4slhh/MKQ6YCixINRhCwliHrpXPym8/5fOq8b7Ig==}
|
resolution: {integrity: sha512-DJJe9k6gXR/15ZZVLv1SKhXkFst8lYCeZRNHH99SlBodvu4slhh/MKQ6YCixINRhCwliHrpXPym8/5fOq8b7Ig==}
|
||||||
@ -2974,13 +3047,6 @@ packages:
|
|||||||
color-name@1.1.4:
|
color-name@1.1.4:
|
||||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||||
|
|
||||||
color-string@1.9.1:
|
|
||||||
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
|
|
||||||
|
|
||||||
color@4.2.3:
|
|
||||||
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
|
|
||||||
engines: {node: '>=12.5.0'}
|
|
||||||
|
|
||||||
colorette@2.0.20:
|
colorette@2.0.20:
|
||||||
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
|
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
|
||||||
|
|
||||||
@ -3188,8 +3254,8 @@ packages:
|
|||||||
engines: {node: '>=0.10'}
|
engines: {node: '>=0.10'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
detect-libc@2.0.3:
|
detect-libc@2.1.2:
|
||||||
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
|
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
devlop@1.1.0:
|
devlop@1.1.0:
|
||||||
@ -3699,9 +3765,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
|
resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
is-arrayish@0.3.2:
|
|
||||||
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
|
|
||||||
|
|
||||||
is-async-function@2.1.1:
|
is-async-function@2.1.1:
|
||||||
resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==}
|
resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@ -3972,6 +4035,9 @@ packages:
|
|||||||
ktx-parse@1.0.0:
|
ktx-parse@1.0.0:
|
||||||
resolution: {integrity: sha512-Z31kVizz4DF/6vo9YiSYVBhuXAfyQy9bGxlW3+mB5OELoZjfXVZQpRoctsx8IEDKxBd6SagXKo7qRvu38i8Jfg==}
|
resolution: {integrity: sha512-Z31kVizz4DF/6vo9YiSYVBhuXAfyQy9bGxlW3+mB5OELoZjfXVZQpRoctsx8IEDKxBd6SagXKo7qRvu38i8Jfg==}
|
||||||
|
|
||||||
|
ktx-parse@1.1.0:
|
||||||
|
resolution: {integrity: sha512-mKp3y+FaYgR7mXWAbyyzpa/r1zDWeaunH+INJO4fou3hb45XuNSwar+7llrRyvpMWafxSIi99RNFJ05MHedaJQ==}
|
||||||
|
|
||||||
lerc@2.0.0:
|
lerc@2.0.0:
|
||||||
resolution: {integrity: sha512-7qo1Mq8ZNmaR4USHHm615nEW2lPeeWJ3bTyoqFbd35DLx0LUH7C6ptt5FDCTAlbIzs3+WKrk5SkJvw8AFDE2hg==}
|
resolution: {integrity: sha512-7qo1Mq8ZNmaR4USHHm615nEW2lPeeWJ3bTyoqFbd35DLx0LUH7C6ptt5FDCTAlbIzs3+WKrk5SkJvw8AFDE2hg==}
|
||||||
|
|
||||||
@ -4223,8 +4289,8 @@ packages:
|
|||||||
ndarray-ops@1.2.2:
|
ndarray-ops@1.2.2:
|
||||||
resolution: {integrity: sha512-BppWAFRjMYF7N/r6Ie51q6D4fs0iiGmeXIACKY66fLpnwIui3Wc3CXiD/30mgLbDjPpSLrsqcp3Z62+IcHZsDw==}
|
resolution: {integrity: sha512-BppWAFRjMYF7N/r6Ie51q6D4fs0iiGmeXIACKY66fLpnwIui3Wc3CXiD/30mgLbDjPpSLrsqcp3Z62+IcHZsDw==}
|
||||||
|
|
||||||
ndarray-pixels@4.1.0:
|
ndarray-pixels@5.0.1:
|
||||||
resolution: {integrity: sha512-xKPI4zXJ2pkUcVX24zIN1AWqqPWvRWWhRuO6PlY4EdB2VNRauNwA6rDdsAQG/ldQp0sU7nTXgPR/io1duy3Zyg==}
|
resolution: {integrity: sha512-IBtrpefpqlI8SPDCGjXk4v5NV5z7r3JSuCbfuEEXaM0vrOJtNGgYUa4C3Lt5H+qWdYF4BCPVFsnXhNC7QvZwkw==}
|
||||||
|
|
||||||
ndarray@1.0.19:
|
ndarray@1.0.19:
|
||||||
resolution: {integrity: sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==}
|
resolution: {integrity: sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==}
|
||||||
@ -4455,6 +4521,11 @@ packages:
|
|||||||
preact@10.26.5:
|
preact@10.26.5:
|
||||||
resolution: {integrity: sha512-fmpDkgfGU6JYux9teDWLhj9mKN55tyepwYbxHgQuIxbWQzgFg5vk7Mrrtfx7xRxq798ynkY4DDDxZr235Kk+4w==}
|
resolution: {integrity: sha512-fmpDkgfGU6JYux9teDWLhj9mKN55tyepwYbxHgQuIxbWQzgFg5vk7Mrrtfx7xRxq798ynkY4DDDxZr235Kk+4w==}
|
||||||
|
|
||||||
|
prettier@3.8.1:
|
||||||
|
resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==}
|
||||||
|
engines: {node: '>=14'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
pretty-bytes@5.6.0:
|
pretty-bytes@5.6.0:
|
||||||
resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==}
|
resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@ -4466,8 +4537,8 @@ packages:
|
|||||||
process-nextick-args@2.0.1:
|
process-nextick-args@2.0.1:
|
||||||
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
|
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
|
||||||
|
|
||||||
property-graph@3.0.0:
|
property-graph@4.0.0:
|
||||||
resolution: {integrity: sha512-TnzxUsttmGtw+OiU0LDw+0FlMbJ8vV8pOjyDI7+Kdni4Tj0hW5BFh7TatQu7Y68hcvvFmiFOHilKShsA4R82fA==}
|
resolution: {integrity: sha512-I0hojAJfTbSCZy3y6xyK29eayxo14v1bj1VPiDkHjTdz33SV6RdfMz2AHnf4ai62Vng2mN5GkaKahkooBIo9gA==}
|
||||||
|
|
||||||
property-information@7.0.0:
|
property-information@7.0.0:
|
||||||
resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==}
|
resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==}
|
||||||
@ -4869,6 +4940,11 @@ packages:
|
|||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
semver@7.7.4:
|
||||||
|
resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
send@0.19.0:
|
send@0.19.0:
|
||||||
resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==}
|
resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
@ -4898,8 +4974,8 @@ packages:
|
|||||||
setprototypeof@1.2.0:
|
setprototypeof@1.2.0:
|
||||||
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
|
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
|
||||||
|
|
||||||
sharp@0.33.5:
|
sharp@0.34.5:
|
||||||
resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==}
|
resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
|
||||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||||
|
|
||||||
shebang-command@2.0.0:
|
shebang-command@2.0.0:
|
||||||
@ -4936,9 +5012,6 @@ packages:
|
|||||||
signals@1.0.0:
|
signals@1.0.0:
|
||||||
resolution: {integrity: sha512-dE3lBiqgrgIvpGHYBy6/kiYKfh0HXRmbg0ocakBKiOefbal6ZeTtNlQlxsu9ADkNzv5OmRwRKu+IaTPSqJdZDg==}
|
resolution: {integrity: sha512-dE3lBiqgrgIvpGHYBy6/kiYKfh0HXRmbg0ocakBKiOefbal6ZeTtNlQlxsu9ADkNzv5OmRwRKu+IaTPSqJdZDg==}
|
||||||
|
|
||||||
simple-swizzle@0.2.2:
|
|
||||||
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
|
||||||
|
|
||||||
sirv@3.0.1:
|
sirv@3.0.1:
|
||||||
resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==}
|
resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@ -6814,7 +6887,7 @@ snapshots:
|
|||||||
|
|
||||||
'@dxfom/mtext@0.3.2': {}
|
'@dxfom/mtext@0.3.2': {}
|
||||||
|
|
||||||
'@emnapi/runtime@1.4.3':
|
'@emnapi/runtime@1.8.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
optional: true
|
optional: true
|
||||||
@ -6899,23 +6972,23 @@ snapshots:
|
|||||||
'@esbuild/win32-x64@0.25.10':
|
'@esbuild/win32-x64@0.25.10':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@gltf-transform/core@4.1.3':
|
'@gltf-transform/core@4.3.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
property-graph: 3.0.0
|
property-graph: 4.0.0
|
||||||
|
|
||||||
'@gltf-transform/extensions@4.1.3':
|
'@gltf-transform/extensions@4.3.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@gltf-transform/core': 4.1.3
|
'@gltf-transform/core': 4.3.0
|
||||||
ktx-parse: 1.0.0
|
ktx-parse: 1.1.0
|
||||||
|
|
||||||
'@gltf-transform/functions@4.1.3':
|
'@gltf-transform/functions@4.3.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@gltf-transform/core': 4.1.3
|
'@gltf-transform/core': 4.3.0
|
||||||
'@gltf-transform/extensions': 4.1.3
|
'@gltf-transform/extensions': 4.3.0
|
||||||
ktx-parse: 1.0.0
|
ktx-parse: 1.1.0
|
||||||
ndarray: 1.0.19
|
ndarray: 1.0.19
|
||||||
ndarray-lanczos: 0.3.0
|
ndarray-lanczos: 0.3.0
|
||||||
ndarray-pixels: 4.1.0
|
ndarray-pixels: 5.0.1
|
||||||
|
|
||||||
'@iconify/types@2.0.0': {}
|
'@iconify/types@2.0.0': {}
|
||||||
|
|
||||||
@ -6950,79 +7023,100 @@ snapshots:
|
|||||||
'@iconify/types': 2.0.0
|
'@iconify/types': 2.0.0
|
||||||
vue: 3.5.22(typescript@5.8.3)
|
vue: 3.5.22(typescript@5.8.3)
|
||||||
|
|
||||||
'@img/sharp-darwin-arm64@0.33.5':
|
'@img/colour@1.1.0': {}
|
||||||
|
|
||||||
|
'@img/sharp-darwin-arm64@0.34.5':
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@img/sharp-libvips-darwin-arm64': 1.0.4
|
'@img/sharp-libvips-darwin-arm64': 1.2.4
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-darwin-x64@0.33.5':
|
'@img/sharp-darwin-x64@0.34.5':
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@img/sharp-libvips-darwin-x64': 1.0.4
|
'@img/sharp-libvips-darwin-x64': 1.2.4
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-libvips-darwin-arm64@1.0.4':
|
'@img/sharp-libvips-darwin-arm64@1.2.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-libvips-darwin-x64@1.0.4':
|
'@img/sharp-libvips-darwin-x64@1.2.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-libvips-linux-arm64@1.0.4':
|
'@img/sharp-libvips-linux-arm64@1.2.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-libvips-linux-arm@1.0.5':
|
'@img/sharp-libvips-linux-arm@1.2.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-libvips-linux-s390x@1.0.4':
|
'@img/sharp-libvips-linux-ppc64@1.2.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-libvips-linux-x64@1.0.4':
|
'@img/sharp-libvips-linux-riscv64@1.2.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-libvips-linuxmusl-arm64@1.0.4':
|
'@img/sharp-libvips-linux-s390x@1.2.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-libvips-linuxmusl-x64@1.0.4':
|
'@img/sharp-libvips-linux-x64@1.2.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-linux-arm64@0.33.5':
|
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-linux-arm64@0.34.5':
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@img/sharp-libvips-linux-arm64': 1.0.4
|
'@img/sharp-libvips-linux-arm64': 1.2.4
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-linux-arm@0.33.5':
|
'@img/sharp-linux-arm@0.34.5':
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@img/sharp-libvips-linux-arm': 1.0.5
|
'@img/sharp-libvips-linux-arm': 1.2.4
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-linux-s390x@0.33.5':
|
'@img/sharp-linux-ppc64@0.34.5':
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@img/sharp-libvips-linux-s390x': 1.0.4
|
'@img/sharp-libvips-linux-ppc64': 1.2.4
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-linux-x64@0.33.5':
|
'@img/sharp-linux-riscv64@0.34.5':
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@img/sharp-libvips-linux-x64': 1.0.4
|
'@img/sharp-libvips-linux-riscv64': 1.2.4
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-linuxmusl-arm64@0.33.5':
|
'@img/sharp-linux-s390x@0.34.5':
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@img/sharp-libvips-linuxmusl-arm64': 1.0.4
|
'@img/sharp-libvips-linux-s390x': 1.2.4
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-linuxmusl-x64@0.33.5':
|
'@img/sharp-linux-x64@0.34.5':
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@img/sharp-libvips-linuxmusl-x64': 1.0.4
|
'@img/sharp-libvips-linux-x64': 1.2.4
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-wasm32@0.33.5':
|
'@img/sharp-linuxmusl-arm64@0.34.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-linuxmusl-arm64': 1.2.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-linuxmusl-x64@0.34.5':
|
||||||
|
optionalDependencies:
|
||||||
|
'@img/sharp-libvips-linuxmusl-x64': 1.2.4
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-wasm32@0.34.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@emnapi/runtime': 1.4.3
|
'@emnapi/runtime': 1.8.1
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-win32-ia32@0.33.5':
|
'@img/sharp-win32-arm64@0.34.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@img/sharp-win32-x64@0.33.5':
|
'@img/sharp-win32-ia32@0.34.5':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@img/sharp-win32-x64@0.34.5':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@intlify/core-base@11.1.3':
|
'@intlify/core-base@11.1.3':
|
||||||
@ -8949,16 +9043,6 @@ snapshots:
|
|||||||
|
|
||||||
color-name@1.1.4: {}
|
color-name@1.1.4: {}
|
||||||
|
|
||||||
color-string@1.9.1:
|
|
||||||
dependencies:
|
|
||||||
color-name: 1.1.4
|
|
||||||
simple-swizzle: 0.2.2
|
|
||||||
|
|
||||||
color@4.2.3:
|
|
||||||
dependencies:
|
|
||||||
color-convert: 2.0.1
|
|
||||||
color-string: 1.9.1
|
|
||||||
|
|
||||||
colorette@2.0.20: {}
|
colorette@2.0.20: {}
|
||||||
|
|
||||||
colorjs.io@0.5.2: {}
|
colorjs.io@0.5.2: {}
|
||||||
@ -9131,7 +9215,7 @@ snapshots:
|
|||||||
detect-libc@1.0.3:
|
detect-libc@1.0.3:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
detect-libc@2.0.3: {}
|
detect-libc@2.1.2: {}
|
||||||
|
|
||||||
devlop@1.1.0:
|
devlop@1.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -9752,8 +9836,6 @@ snapshots:
|
|||||||
call-bound: 1.0.4
|
call-bound: 1.0.4
|
||||||
get-intrinsic: 1.3.0
|
get-intrinsic: 1.3.0
|
||||||
|
|
||||||
is-arrayish@0.3.2: {}
|
|
||||||
|
|
||||||
is-async-function@2.1.1:
|
is-async-function@2.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
async-function: 1.0.0
|
async-function: 1.0.0
|
||||||
@ -10014,6 +10096,8 @@ snapshots:
|
|||||||
|
|
||||||
ktx-parse@1.0.0: {}
|
ktx-parse@1.0.0: {}
|
||||||
|
|
||||||
|
ktx-parse@1.1.0: {}
|
||||||
|
|
||||||
lerc@2.0.0: {}
|
lerc@2.0.0: {}
|
||||||
|
|
||||||
less@4.3.0:
|
less@4.3.0:
|
||||||
@ -10291,12 +10375,12 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
cwise-compiler: 1.1.3
|
cwise-compiler: 1.1.3
|
||||||
|
|
||||||
ndarray-pixels@4.1.0:
|
ndarray-pixels@5.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/ndarray': 1.0.14
|
'@types/ndarray': 1.0.14
|
||||||
ndarray: 1.0.19
|
ndarray: 1.0.19
|
||||||
ndarray-ops: 1.2.2
|
ndarray-ops: 1.2.2
|
||||||
sharp: 0.33.5
|
sharp: 0.34.5
|
||||||
|
|
||||||
ndarray@1.0.19:
|
ndarray@1.0.19:
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -10519,13 +10603,15 @@ snapshots:
|
|||||||
|
|
||||||
preact@10.26.5: {}
|
preact@10.26.5: {}
|
||||||
|
|
||||||
|
prettier@3.8.1: {}
|
||||||
|
|
||||||
pretty-bytes@5.6.0: {}
|
pretty-bytes@5.6.0: {}
|
||||||
|
|
||||||
pretty-bytes@6.1.1: {}
|
pretty-bytes@6.1.1: {}
|
||||||
|
|
||||||
process-nextick-args@2.0.1: {}
|
process-nextick-args@2.0.1: {}
|
||||||
|
|
||||||
property-graph@3.0.0: {}
|
property-graph@4.0.0: {}
|
||||||
|
|
||||||
property-information@7.0.0: {}
|
property-information@7.0.0: {}
|
||||||
|
|
||||||
@ -10941,6 +11027,8 @@ snapshots:
|
|||||||
|
|
||||||
semver@7.7.1: {}
|
semver@7.7.1: {}
|
||||||
|
|
||||||
|
semver@7.7.4: {}
|
||||||
|
|
||||||
send@0.19.0:
|
send@0.19.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 2.6.9
|
debug: 2.6.9
|
||||||
@ -10998,31 +11086,36 @@ snapshots:
|
|||||||
|
|
||||||
setprototypeof@1.2.0: {}
|
setprototypeof@1.2.0: {}
|
||||||
|
|
||||||
sharp@0.33.5:
|
sharp@0.34.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
color: 4.2.3
|
'@img/colour': 1.1.0
|
||||||
detect-libc: 2.0.3
|
detect-libc: 2.1.2
|
||||||
semver: 7.7.1
|
semver: 7.7.4
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@img/sharp-darwin-arm64': 0.33.5
|
'@img/sharp-darwin-arm64': 0.34.5
|
||||||
'@img/sharp-darwin-x64': 0.33.5
|
'@img/sharp-darwin-x64': 0.34.5
|
||||||
'@img/sharp-libvips-darwin-arm64': 1.0.4
|
'@img/sharp-libvips-darwin-arm64': 1.2.4
|
||||||
'@img/sharp-libvips-darwin-x64': 1.0.4
|
'@img/sharp-libvips-darwin-x64': 1.2.4
|
||||||
'@img/sharp-libvips-linux-arm': 1.0.5
|
'@img/sharp-libvips-linux-arm': 1.2.4
|
||||||
'@img/sharp-libvips-linux-arm64': 1.0.4
|
'@img/sharp-libvips-linux-arm64': 1.2.4
|
||||||
'@img/sharp-libvips-linux-s390x': 1.0.4
|
'@img/sharp-libvips-linux-ppc64': 1.2.4
|
||||||
'@img/sharp-libvips-linux-x64': 1.0.4
|
'@img/sharp-libvips-linux-riscv64': 1.2.4
|
||||||
'@img/sharp-libvips-linuxmusl-arm64': 1.0.4
|
'@img/sharp-libvips-linux-s390x': 1.2.4
|
||||||
'@img/sharp-libvips-linuxmusl-x64': 1.0.4
|
'@img/sharp-libvips-linux-x64': 1.2.4
|
||||||
'@img/sharp-linux-arm': 0.33.5
|
'@img/sharp-libvips-linuxmusl-arm64': 1.2.4
|
||||||
'@img/sharp-linux-arm64': 0.33.5
|
'@img/sharp-libvips-linuxmusl-x64': 1.2.4
|
||||||
'@img/sharp-linux-s390x': 0.33.5
|
'@img/sharp-linux-arm': 0.34.5
|
||||||
'@img/sharp-linux-x64': 0.33.5
|
'@img/sharp-linux-arm64': 0.34.5
|
||||||
'@img/sharp-linuxmusl-arm64': 0.33.5
|
'@img/sharp-linux-ppc64': 0.34.5
|
||||||
'@img/sharp-linuxmusl-x64': 0.33.5
|
'@img/sharp-linux-riscv64': 0.34.5
|
||||||
'@img/sharp-wasm32': 0.33.5
|
'@img/sharp-linux-s390x': 0.34.5
|
||||||
'@img/sharp-win32-ia32': 0.33.5
|
'@img/sharp-linux-x64': 0.34.5
|
||||||
'@img/sharp-win32-x64': 0.33.5
|
'@img/sharp-linuxmusl-arm64': 0.34.5
|
||||||
|
'@img/sharp-linuxmusl-x64': 0.34.5
|
||||||
|
'@img/sharp-wasm32': 0.34.5
|
||||||
|
'@img/sharp-win32-arm64': 0.34.5
|
||||||
|
'@img/sharp-win32-ia32': 0.34.5
|
||||||
|
'@img/sharp-win32-x64': 0.34.5
|
||||||
|
|
||||||
shebang-command@2.0.0:
|
shebang-command@2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -11075,10 +11168,6 @@ snapshots:
|
|||||||
|
|
||||||
signals@1.0.0: {}
|
signals@1.0.0: {}
|
||||||
|
|
||||||
simple-swizzle@0.2.2:
|
|
||||||
dependencies:
|
|
||||||
is-arrayish: 0.3.2
|
|
||||||
|
|
||||||
sirv@3.0.1:
|
sirv@3.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@polka/url': 1.0.0-next.29
|
'@polka/url': 1.0.0-next.29
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user