From cda4999325d8856436aec16d10bf246222d7b21d Mon Sep 17 00:00:00 2001 From: lyf <2514544224@qq.com> Date: Sat, 14 Mar 2026 00:26:51 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E9=A1=B9=E7=9B=AE=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E5=92=8CSDK=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新 README 文档和许可证文件 - 完善编辑器使用手册,包括BIM浏览、CAD查看等功能说明 - 更新文档配置和首页内容 - 优化编辑器环境配置 - 完善 WebSocket 通信和 API 接口 - 增强 glTF 处理器和点云重建功能 - 优化 SDK 核心模块: - 更新 App 和 Config 配置 - 添加 Billboard、HtmlPanel 等对象支持 - 完善粒子系统和天气效果 - 优化相机管理和漫游工具 - 改进材质着色器效果 - 更新服务层 README 文档 Made-with: Cursor --- Astral3D/LEGAL.md | 2 +- Astral3D/LICENSE | 2 +- Astral3D/README.en.md | 170 +++-- Astral3D/README.md | 170 +++-- Astral3D/common/build/package.json | 44 +- Astral3D/package.json | 2 +- Astral3D/packages/docs/package.json | 48 +- .../packages/docs/src/.vuepress/_bulletin.md | 2 +- .../packages/docs/src/.vuepress/config.ts | 2 +- .../docs/src/.vuepress/plume.config.ts | 4 +- Astral3D/packages/docs/src/README.md | 4 +- .../guide/manual/editor/extras/资源中心.md | 2 +- .../manual/editor/leftSidebar/BIM轻量化.md | 6 +- .../manual/editor/leftSidebar/CAD解析预览.md | 6 +- .../guide/manual/editor/leftSidebar/场景树.md | 4 +- .../guide/manual/editor/rightSidebar/脚本.md | 2 +- .../guide/manual/editor/viewport/2D图纸.md | 4 +- .../guide/manual/editor/viewport/3D场景.md | 8 +- .../src/notes/guide/manual/editor/界面.md | 2 +- .../src/notes/guide/manual/editor/顶栏.md | 8 +- .../src/notes/guide/manual/home/资源中心.md | 10 +- .../docs/src/notes/guide/manual/home/项目.md | 4 +- Astral3D/packages/editor/.env | 4 +- Astral3D/packages/editor/.env.production | 4 +- Astral3D/packages/editor/package.json | 2 +- .../packages/editor/src/hooks/useWebSocket.ts | 5 +- .../editor/src/http/api/sceneExample.ts | 5 +- .../editor/src/plugin/glTFHandler/Listr.ts | 88 ++- .../src/plugin/glTFHandler/glTFHandler.ts | 494 ++++++------ .../PointCloudReconstructor.ts | 106 ++- .../editor/src/store/modules/plugin.ts | 104 ++- .../editor/src/utils/common/constant.ts | 130 ++-- .../editor/src/utils/preview/menuOperation.ts | 712 +++++++++--------- .../extraPane/resource/builtin/Billboard.vue | 2 +- Astral3D/packages/sdk/.env | 2 +- Astral3D/packages/sdk/.env.production | 2 +- Astral3D/packages/sdk/lib/core/app/App.ts | 4 +- .../sdk/lib/core/app/modules/Config.ts | 3 +- .../sdk/lib/core/app/modules/Project.ts | 4 +- .../packages/sdk/lib/core/expansion/index.ts | 3 +- .../sdk/lib/core/geometries/TeapotGeometry.ts | 3 +- .../sdk/lib/core/loader/ObjectLoader.js | 2 +- .../sdk/lib/core/loader/Package.Skeleton.ts | 4 +- .../sdk/lib/core/objects/Billboard.ts | 3 +- .../sdk/lib/core/objects/HtmlPanel.ts | 3 +- .../packages/sdk/lib/core/objects/LineMesh.ts | 3 +- .../sdk/lib/core/objects/ParticleEmitter.ts | 3 +- .../core/objects/texture/BillboardTexture.ts | 3 +- .../sdk/lib/core/objects/weather/Rain.ts | 3 +- .../sdk/lib/core/objects/weather/Snow.ts | 3 +- .../sdk/lib/core/plugin/builtin/builtin.ts | 3 +- .../sdk/lib/core/plugin/pluginLoader.ts | 3 +- .../core/points/PointCloudReconstructor.ts | 3 +- .../packages/sdk/lib/core/preview/Preview.ts | 3 +- .../packages/sdk/lib/core/script/Helper.ts | 3 +- .../modules/CircleGridShaderMaterial.ts | 3 +- .../DynamicCheckerboardShaderMaterial.ts | 3 +- .../modules/FlickerShaderMaterial.ts | 3 +- .../modules/SlowSmokeShaderMaterial.ts | 3 +- .../modules/SnowingShaderMaterial.ts | 3 +- .../modules/StreamerWallShaderMaterial.ts | 3 +- .../packages/sdk/lib/core/tools/Roaming.ts | 3 +- .../sdk/lib/core/tools/RoamingStatus.ts | 3 +- .../lib/core/viewer/modules/CameraManage.ts | 3 +- .../sdk/lib/core/viewer/modules/Effect.ts | 3 +- .../lib/core/viewer/modules/TilesManage.ts | 4 +- .../sdk/lib/core/viewer/modules/Weather.ts | 4 +- Astral3D/packages/sdk/lib/utils/log/Logger.ts | 236 +++--- README.md | 339 +++++---- astral-service/README.md | 127 ++-- 70 files changed, 1510 insertions(+), 1455 deletions(-) diff --git a/Astral3D/LEGAL.md b/Astral3D/LEGAL.md index decf6b9..30827a8 100644 --- a/Astral3D/LEGAL.md +++ b/Astral3D/LEGAL.md @@ -36,7 +36,7 @@ - 暗示与官方项目的关联性 ## ©️ 版权声明 -2019-2025 © ErSan. All rights reserved. +Copyright © 2026 . All rights reserved. diff --git a/Astral3D/LICENSE b/Astral3D/LICENSE index 20a0810..12c39fd 100644 --- a/Astral3D/LICENSE +++ b/Astral3D/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2024 ErSan + Copyright 2026 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Astral3D/README.en.md b/Astral3D/README.en.md index 1a0505a..3daeede 100644 --- a/Astral3D/README.en.md +++ b/Astral3D/README.en.md @@ -1,65 +1,105 @@ -# NeonVision 3D Editor - -[简体中文](README.md) | English - -## Core Features - -- Multi-format support: 30+ model formats (GLTF/OBJ/FBX/GLB/RVT/IFC, etc.) -- BIM Model Lightweight Display (RVT/IFC) -- CAD Drawing Analysis (DWG/DXF) -- Scene Subpackage Storage and Loading -- Animation Editor - -## Extended Capabilities - -- Plugin System -- Script Runtime -- Particle System -- Weather System -- Cloud Storage Integration -- Resource Center - -## Technology Stack - -- Vue 3.5+ -- Three.js r176+ -- Cesium 1.107+ -- Naive UI 2.43+ -- UnoCSS 0.46+ - -## Quick Start - -### Prerequisites - -- Node.js ≥ 20.x -- PNPM - -### Local Development - -```bash -# Clone the project -git clone - -# Install dependencies -pnpm install - -# Build SDK -pnpm run sdk:build - -# Start dev server -pnpm run editor:dev -``` - -### Production Build - -```bash -pnpm run editor:build -``` - -## License - -Open source under Apache 2.0 License. - ---- - -*More content to be added* +# NeonVision 3D Editor + +[简体中文](README.md) | English + +## Overview + +NeonVision 3D Editor (Art Museum Digital Cockpit) is a professional Web-based 3D scene editor built on WebGL/Three.js technology. It supports multi-format 3D model import, scene editing, animation production, BIM/CAD parsing and other professional features. + +## Core Features + +- **Multi-format Support**: Supports 30+ 3D model formats including GLTF, GLB, OBJ, FBX, RVT, IFC +- **BIM Model Lightweight**: Lightweight display of Revit (RVT) and IFC format models +- **CAD Drawing Analysis**: DWG/DXF format 2D drawing parsing with 3D linkage +- **Scene Subpackage Storage**: Scene subpackage packaging and incremental loading for large-scale scenes +- **Animation Editor**: Keyframe animation, timeline editing, skeletal animation support +- **Real-time Preview**: Instant rendering preview, WYSIWYG + +## Extended Capabilities + +- **Plugin System**: Plugin extension support for customization +- **Script Runtime**: JavaScript script injection for business logic +- **Particle System**: Rich particle effect editor +- **Weather System**: Fog, rain, snow and other weather effects +- **Cloud Storage Integration**: Local storage and UpYun object storage support +- **Asset Center**: Unified asset management for models, materials, textures, etc. + +## Technology Stack + +| Category | Technology | +|----------|------------| +| Frontend Framework | Vue 3.5+ / Vue Router / Pinia | +| 3D Engine | Three.js r176+ | +| GIS Engine | Cesium 1.107+ | +| UI Components | Naive UI | +| CSS Framework | UnoCSS / Tailwind CSS | +| Build Tool | Vite | +| Editor | Monaco Editor | + +## Project Structure + +``` +Astral3D/ +├── packages/ +│ ├── editor/ # Web editor +│ ├── sdk/ # 3D engine SDK +│ ├── examples/ # Example projects +│ └── docs/ # Documentation site +├── common/ # Shared build config +└── astral-service/ # Backend service (Java/SpringBoot) +``` + +## Quick Start + +### Prerequisites + +- Node.js ≥ 23.0.0 +- PNPM ≥ 10.8.1 +- Java 8+ (for backend) +- MySQL 5.7+ (for backend) + +### Local Development + +```bash +# Clone the project +git clone http://code-server:3000/lyf/Astral3D.git +cd Astral3D + +# Install dependencies +pnpm install + +# Build SDK +pnpm run sdk:build + +# Start dev server +pnpm run editor:dev +``` + +Visit http://localhost:5173 + +### Production Build + +```bash +pnpm run editor:build +``` + +### Backend Service (Optional) + +```bash +# Enter backend directory +cd ../astral-service + +# Configure database +# Edit astral-web/src/main/resources/application-dev.yml + +# Start service +mvn spring-boot:run +``` + +## License + +Open source under Apache 2.0 License. + +## Contributing + +Issues and Pull Requests are welcome. diff --git a/Astral3D/README.md b/Astral3D/README.md index 10ee14b..638917d 100644 --- a/Astral3D/README.md +++ b/Astral3D/README.md @@ -1,65 +1,105 @@ -# NeonVision 3D Editor - -简体中文 | [English](README.en.md) - -## 核心功能 - -- 多格式支持:30+ 模型格式(GLTF/OBJ/FBX/GLB/RVT/IFC等) -- BIM模型轻量化展示(RVT/IFC) -- CAD图纸解析(DWG/DXF) -- 场景分包存储与加载 -- 动画编辑器 - -## 扩展能力 - -- 插件系统 -- 脚本运行时 -- 粒子系统 -- 天气系统 -- 云存储集成 -- 资源中心 - -## 技术栈 - -- Vue 3.5+ -- Three.js r176+ -- Cesium 1.107+ -- Naive UI 2.43+ -- UnoCSS 0.46+ - -## 快速开始 - -### 前置需求 - -- Node.js ≥ 20.x -- PNPM - -### 本地运行 - -```bash -# 克隆项目 -git clone - -# 安装依赖 -pnpm install - -# 构建 SDK -pnpm run sdk:build - -# 启动开发服务器 -pnpm run editor:dev -``` - -### 生产构建 - -```bash -pnpm run editor:build -``` - -## 许可协议 - -基于 Apache 2.0 许可证开源。 - ---- - -*更多内容待补充* +# NeonVision 3D Editor + +简体中文 | [English](README.en.md) + +## 概述 + +NeonVision 3D Editor(美术馆数字驾驶舱)是一款专业的 Web 端三维场景编辑器,基于 WebGL/Three.js 技术构建,支持多格式三维模型导入、场景编辑、动画制作、BIM/CAD 解析等专业功能。 + +## 核心功能 + +- **多格式支持**:支持 GLTF、GLB、OBJ、FBX、RVT、IFC 等 30+ 三维模型格式 +- **BIM 模型轻量化**:支持 Revit(RVT) 和 IFC 格式的轻量化展示 +- **CAD 图纸解析**:支持 DWG/DXF 格式的二维图纸解析与三维联动 +- **场景分包存储**:支持场景分包打包、增量加载,提升大规模场景性能 +- **动画编辑器**:支持关键帧动画、时间轴编辑、骨骼动画 +- **实时预览**:即时渲染预览,所见即所得 + +## 扩展能力 + +- **插件系统**:支持插件扩展,满足定制化需求 +- **脚本运行时**:支持 JavaScript 脚本注入,实现业务逻辑 +- **粒子系统**:丰富的粒子效果编辑器 +- **天气系统**:雾、雨、雪等天气效果模拟 +- **云存储集成**:支持本地存储和又拍云对象存储 +- **资源中心**:统一资产管理,支持模型、材质、纹理等 + +## 技术栈 + +| 类别 | 技术 | +|------|------| +| 前端框架 | Vue 3.5+ / Vue Router / Pinia | +| 3D 引擎 | Three.js r176+ | +| GIS 引擎 | Cesium 1.107+ | +| UI 组件库 | Naive UI | +| CSS 框架 | UnoCSS / Tailwind CSS | +| 构建工具 | Vite | +| 编辑器 | Monaco Editor | + +## 项目结构 + +``` +Astral3D/ +├── packages/ +│ ├── editor/ # Web 编辑器 +│ ├── sdk/ # 3D 引擎 SDK +│ ├── examples/ # 示例项目 +│ └── docs/ # 文档站点 +├── common/ # 公共构建配置 +└── astral-service/ # 后端服务 (Java/SpringBoot) +``` + +## 快速开始 + +### 前置需求 + +- Node.js ≥ 23.0.0 +- PNPM ≥ 10.8.1 +- Java 8+ (后端服务) +- MySQL 5.7+ (后端服务) + +### 本地运行 + +```bash +# 克隆项目 +git clone http://code-server:3000/lyf/Astral3D.git +cd Astral3D + +# 安装依赖 +pnpm install + +# 构建 SDK +pnpm run sdk:build + +# 启动开发服务器 +pnpm run editor:dev +``` + +访问 http://localhost:5173 + +### 生产构建 + +```bash +pnpm run editor:build +``` + +### 后端服务(可选) + +```bash +# 进入后端目录 +cd ../astral-service + +# 配置数据库 +# 修改 astral-web/src/main/resources/application-dev.yml + +# 启动服务 +mvn spring-boot:run +``` + +## 许可协议 + +基于 Apache 2.0 许可证开源。 + +## 贡献指南 + +欢迎提交 Issue 和 Pull Request。 diff --git a/Astral3D/common/build/package.json b/Astral3D/common/build/package.json index 5b6b64a..83dad32 100644 --- a/Astral3D/common/build/package.json +++ b/Astral3D/common/build/package.json @@ -1,22 +1,22 @@ -{ - "name": "@astral3d/build-vite-plugins", - "author": "ErSan", - "private": true, - "version": "1.0.0", - "type": "module", - "main": "./src/index.ts", - "dependencies": { - }, - "devDependencies": { - "@types/fs-extra": "^11.0.3", - "dotenv": "16.3.1", - "fs-extra": "^11.1.1", - "rollup-plugin-visualizer": "catalog:", - "typescript": "catalog:", - "unplugin-config": "^0.1.5", - "vite": "catalog:", - "vite-plugin-compression": "^0.5.1", - "vite-plugin-enhance-log": "^0.6.2", - "vite-plugin-top-level-await": "^1.3.1" - } -} +{ + "name": "@astral3d/build-vite-plugins", + "author": "", + "private": true, + "version": "1.0.0", + "type": "module", + "main": "./src/index.ts", + "dependencies": { + }, + "devDependencies": { + "@types/fs-extra": "^11.0.3", + "dotenv": "16.3.1", + "fs-extra": "^11.1.1", + "rollup-plugin-visualizer": "catalog:", + "typescript": "catalog:", + "unplugin-config": "^0.1.5", + "vite": "catalog:", + "vite-plugin-compression": "^0.5.1", + "vite-plugin-enhance-log": "^0.6.2", + "vite-plugin-top-level-await": "^1.3.1" + } +} diff --git a/Astral3D/package.json b/Astral3D/package.json index cfd2b83..7913f64 100644 --- a/Astral3D/package.json +++ b/Astral3D/package.json @@ -2,7 +2,7 @@ "name": "astral3d", "version": "1.0.0", "description": "Astral3D Engine", - "author": "ErSan ", + "author": "", "scripts": { "docs:dev": "pnpm run -C packages/docs docs:dev", "docs:dev-clean": "pnpm run -C packages/docs docs:dev-clean", diff --git a/Astral3D/packages/docs/package.json b/Astral3D/packages/docs/package.json index c1d4e2f..c8307f5 100644 --- a/Astral3D/packages/docs/package.json +++ b/Astral3D/packages/docs/package.json @@ -1,24 +1,24 @@ -{ - "name": "@astral3d/docs", - "type": "module", - "version": "1.0.0", - "description": "Astral3D 文档", - "packageManager": "pnpm@10.8.1", - "author": "ErSan ", - "scripts": { - "docs:dev": "vuepress dev src", - "docs:dev-clean": "vuepress dev src --clean-cache --clean-temp", - "docs:build": "vuepress build src --clean-cache --clean-temp", - "docs:preview": "http-server src/.vuepress/dist", - "vp-update": "pnpm dlx vp-update" - }, - "devDependencies": { - "@vuepress/bundler-vite": "^2.0.0-rc.24", - "http-server": "^14.1.1", - "sass-embedded": "^1.85.0", - "typescript": "catalog:", - "vue": "catalog:", - "vuepress": "^2.0.0-rc.24", - "vuepress-theme-plume": "^1.0.0-rc.164" - } -} +{ + "name": "@astral3d/docs", + "type": "module", + "version": "1.0.0", + "description": "Astral3D 文档", + "packageManager": "pnpm@10.8.1", + "author": "", + "scripts": { + "docs:dev": "vuepress dev src", + "docs:dev-clean": "vuepress dev src --clean-cache --clean-temp", + "docs:build": "vuepress build src --clean-cache --clean-temp", + "docs:preview": "http-server src/.vuepress/dist", + "vp-update": "pnpm dlx vp-update" + }, + "devDependencies": { + "@vuepress/bundler-vite": "^2.0.0-rc.24", + "http-server": "^14.1.1", + "sass-embedded": "^1.85.0", + "typescript": "catalog:", + "vue": "catalog:", + "vuepress": "^2.0.0-rc.24", + "vuepress-theme-plume": "^1.0.0-rc.164" + } +} diff --git a/Astral3D/packages/docs/src/.vuepress/_bulletin.md b/Astral3D/packages/docs/src/.vuepress/_bulletin.md index 0018f55..b495e08 100644 --- a/Astral3D/packages/docs/src/.vuepress/_bulletin.md +++ b/Astral3D/packages/docs/src/.vuepress/_bulletin.md @@ -9,7 +9,7 @@ permalink: /astral/ib77r5fd/ ![QQ qr_code](/images/qq_qrcode.jpg){width="618" height="616" style="width: 200px"} -您在使用过程中遇到任何问题,欢迎通过 [issue](https://github.com/mlt131220/Astral3D/issues/new) 反馈。也欢迎加入我们的 QQ 交流群一起讨论。 +您在使用过程中遇到任何问题,欢迎通过项目仓库反馈。也欢迎加入我们的 QQ 交流群一起讨论。 > :fire: 4核8G 200兆服务器,仅需49元/月,[点击这里购买](https://www.rainyun.com/Astral3D_) > 专属优惠码:Astral3D diff --git a/Astral3D/packages/docs/src/.vuepress/config.ts b/Astral3D/packages/docs/src/.vuepress/config.ts index a524f63..33371f1 100644 --- a/Astral3D/packages/docs/src/.vuepress/config.ts +++ b/Astral3D/packages/docs/src/.vuepress/config.ts @@ -176,7 +176,7 @@ export default defineUserConfig({ comment: { provider: 'Giscus', // "Artalk" | "Giscus" | "Twikoo" | "Waline" comment: true, - repo: 'mlt131220/Astral3D-Docs', + repo: 'Astral3D/Docs', repoId: 'R_kgDOLuBMGg', category: 'Announcements', categoryId: 'DIC_kwDOLuBMGs4Cero3', diff --git a/Astral3D/packages/docs/src/.vuepress/plume.config.ts b/Astral3D/packages/docs/src/.vuepress/plume.config.ts index 76d5711..2f2c708 100644 --- a/Astral3D/packages/docs/src/.vuepress/plume.config.ts +++ b/Astral3D/packages/docs/src/.vuepress/plume.config.ts @@ -11,7 +11,7 @@ export default defineThemeConfig({ appearance: true, // 配置 深色模式 social: [ - { icon: 'github', link: 'https://github.com/mlt131220/Astral3D' }, + { icon: 'github', link: 'http://code-server:3000/lyf/Astral3D.git' }, ], // navbarSocialInclude: ['github'], // 允许显示在导航栏的 social 社交链接 // aside: true, // 页内侧边栏, 默认显示在右侧 @@ -30,7 +30,7 @@ export default defineThemeConfig({ /* 站点页脚 */ footer: { message: '', - copyright: 'Copyright © 2023-present ErSan ', + copyright: 'Copyright © 2026', }, /** diff --git a/Astral3D/packages/docs/src/README.md b/Astral3D/packages/docs/src/README.md index fde75a4..2f0f4b3 100644 --- a/Astral3D/packages/docs/src/README.md +++ b/Astral3D/packages/docs/src/README.md @@ -18,11 +18,11 @@ config: - theme: alt text: Demo - link: https://editor.astraljs.com/#/ + link: - theme: alt text: Github - link: https://github.com/mlt131220/Astral3D + link: - type: features features: diff --git a/Astral3D/packages/docs/src/notes/guide/manual/editor/extras/资源中心.md b/Astral3D/packages/docs/src/notes/guide/manual/editor/extras/资源中心.md index de42aa2..3c0decf 100644 --- a/Astral3D/packages/docs/src/notes/guide/manual/editor/extras/资源中心.md +++ b/Astral3D/packages/docs/src/notes/guide/manual/editor/extras/资源中心.md @@ -8,7 +8,7 @@ permalink: /guide/dju4ekca/ ::: diff --git a/Astral3D/packages/docs/src/notes/guide/manual/editor/leftSidebar/BIM轻量化.md b/Astral3D/packages/docs/src/notes/guide/manual/editor/leftSidebar/BIM轻量化.md index f1fe688..4d21370 100644 --- a/Astral3D/packages/docs/src/notes/guide/manual/editor/leftSidebar/BIM轻量化.md +++ b/Astral3D/packages/docs/src/notes/guide/manual/editor/leftSidebar/BIM轻量化.md @@ -10,7 +10,7 @@ permalink: /guide/rf1xgf4z/ title="BIM" description="通过将BIM工程文件(.rvt)转换为glTF文件,在保留BIM构件属性的同时压缩优化模型,以达到web端解析BIM并且轻量化的目的。" width="300" - author="ErSan" + author="" date="2025/04/15" /> @@ -41,7 +41,7 @@ permalink: /guide/rf1xgf4z/ image="/images/manual/editor/leftSidebar/bimUpload.png" title="上传模型" width="400" - author="ErSan" + author="" date="2025/04/15" /> @@ -62,7 +62,7 @@ permalink: /guide/rf1xgf4z/ ::: diff --git a/Astral3D/packages/docs/src/notes/guide/manual/editor/leftSidebar/CAD解析预览.md b/Astral3D/packages/docs/src/notes/guide/manual/editor/leftSidebar/CAD解析预览.md index db20a00..6d3e815 100644 --- a/Astral3D/packages/docs/src/notes/guide/manual/editor/leftSidebar/CAD解析预览.md +++ b/Astral3D/packages/docs/src/notes/guide/manual/editor/leftSidebar/CAD解析预览.md @@ -10,7 +10,7 @@ permalink: /guide/u1631nwk/ title="CAD" description="编辑器支持用户上传CAD图纸(.dwg、.dxf)进行解析预览" width="300" - author="ErSan" + author="" date="2025/04/15" /> @@ -43,7 +43,7 @@ permalink: /guide/u1631nwk/ ::: @@ -59,7 +59,7 @@ permalink: /guide/u1631nwk/ ::: diff --git a/Astral3D/packages/docs/src/notes/guide/manual/editor/leftSidebar/场景树.md b/Astral3D/packages/docs/src/notes/guide/manual/editor/leftSidebar/场景树.md index 6e15160..a283c90 100644 --- a/Astral3D/packages/docs/src/notes/guide/manual/editor/leftSidebar/场景树.md +++ b/Astral3D/packages/docs/src/notes/guide/manual/editor/leftSidebar/场景树.md @@ -9,14 +9,14 @@ permalink: /guide/rzqb0h0l/ image="/images/manual/editor/leftSidebar/sceneTree.png" title="场景树" description="场景树是 Astral3D 编辑器中用于管理场景中所有对象的工具。它以树状结构展示场景中的层级关系,便于用户快速定位和操作对象" - author="ErSan" + author="" date="2025/04/14" /> diff --git a/Astral3D/packages/docs/src/notes/guide/manual/editor/rightSidebar/脚本.md b/Astral3D/packages/docs/src/notes/guide/manual/editor/rightSidebar/脚本.md index e801f29..6456e9a 100644 --- a/Astral3D/packages/docs/src/notes/guide/manual/editor/rightSidebar/脚本.md +++ b/Astral3D/packages/docs/src/notes/guide/manual/editor/rightSidebar/脚本.md @@ -278,4 +278,4 @@ function beforeDestroy() { ::: - \ No newline at end of file + \ No newline at end of file diff --git a/Astral3D/packages/docs/src/notes/guide/manual/editor/viewport/2D图纸.md b/Astral3D/packages/docs/src/notes/guide/manual/editor/viewport/2D图纸.md index 5923cea..a9ad033 100644 --- a/Astral3D/packages/docs/src/notes/guide/manual/editor/viewport/2D图纸.md +++ b/Astral3D/packages/docs/src/notes/guide/manual/editor/viewport/2D图纸.md @@ -9,7 +9,7 @@ permalink: /guide/7eo51kfy/ image="/images/manual/editor/viewport/drawing.png" title="2D图纸" description="拖入(双击)添加至场景中的图纸会自动占据中心视口一半的位置,其与3D视图中间的垂直分割线可以左右拖动以改变占据视口的大小" - author="ErSan" + author="" date="2025/04/16" /> ::: @@ -53,7 +53,7 @@ permalink: /guide/7eo51kfy/ ::: diff --git a/Astral3D/packages/docs/src/notes/guide/manual/editor/viewport/3D场景.md b/Astral3D/packages/docs/src/notes/guide/manual/editor/viewport/3D场景.md index f7c54fe..cd2d741 100644 --- a/Astral3D/packages/docs/src/notes/guide/manual/editor/viewport/3D场景.md +++ b/Astral3D/packages/docs/src/notes/guide/manual/editor/viewport/3D场景.md @@ -9,7 +9,7 @@ permalink: /guide/jkg3yahd/ image="/images/manual/editor/viewport/viewer.png" title="3D场景" description="编辑器的核心视口,展示用户所编辑的场景内容。" - author="ErSan" + author="" date="2025/04/16" /> ::: @@ -38,7 +38,7 @@ permalink: /guide/jkg3yahd/ ::: @@ -49,7 +49,7 @@ permalink: /guide/jkg3yahd/ image="/images/manual/editor/viewport/viewerRenderMode.png" title="渲染模式" width="400" - author="ErSan" + author="" date="2025/04/16" /> @@ -66,7 +66,7 @@ permalink: /guide/jkg3yahd/ image="/images/manual/editor/viewport/viewerTransform.png" title="变换控制" width="400" - author="ErSan" + author="" date="2025/04/16" /> diff --git a/Astral3D/packages/docs/src/notes/guide/manual/editor/界面.md b/Astral3D/packages/docs/src/notes/guide/manual/editor/界面.md index d3908da..b5457ad 100644 --- a/Astral3D/packages/docs/src/notes/guide/manual/editor/界面.md +++ b/Astral3D/packages/docs/src/notes/guide/manual/editor/界面.md @@ -9,7 +9,7 @@ permalink: /guide/swepocsg/ image="/images/manual/editor/page.png" title="编辑器" description="整个编辑界面分为 `顶栏`,`左侧边栏`,`场景视口`,`扩展栏`,`右侧边栏` 五个区域" - author="ErSan" + author="" date="2025/04/14" /> ::: diff --git a/Astral3D/packages/docs/src/notes/guide/manual/editor/顶栏.md b/Astral3D/packages/docs/src/notes/guide/manual/editor/顶栏.md index d242bc4..879b365 100644 --- a/Astral3D/packages/docs/src/notes/guide/manual/editor/顶栏.md +++ b/Astral3D/packages/docs/src/notes/guide/manual/editor/顶栏.md @@ -42,13 +42,13 @@ permalink: /guide/f7smai4w/ @@ -121,7 +121,7 @@ permalink: /guide/f7smai4w/ image="/images/manual/editor/header/mainColor.png" title="主色调" description="调整编辑器的主色,系统会自动生成相应的浅色、深色色阶,用于鼠标经过以及选中等效果" - author="ErSan" + author="" date="2025/04/14" /> @@ -132,7 +132,7 @@ permalink: /guide/f7smai4w/ diff --git a/Astral3D/packages/docs/src/notes/guide/manual/home/资源中心.md b/Astral3D/packages/docs/src/notes/guide/manual/home/资源中心.md index 14eb1c3..d2ca698 100644 --- a/Astral3D/packages/docs/src/notes/guide/manual/home/资源中心.md +++ b/Astral3D/packages/docs/src/notes/guide/manual/home/资源中心.md @@ -9,7 +9,7 @@ permalink: /guide/4tirtbsc/ image="/images/manual/home/assets/assets-page.jpg" title="资源中心" description="多级分类,精细控制" -author="ErSan" +author="" date="2025/08/01" /> ::: @@ -20,7 +20,7 @@ date="2025/08/01" image="/images/manual/home/assets/asset-upload.png" title="上传资源" description="多级分类,精细控制" -author="ErSan" +author="" date="2025/08/01" /> ::: @@ -37,7 +37,7 @@ date="2025/08/01" image="/images/manual/home/assets/asset-preview-screenshot.png" title="通过预览截图" description="点击截图按钮,将自动截取当前画布填充至表单缩略图字段,并关闭此预览弹窗" -author="ErSan" +author="" date="2025/08/01" /> ::: @@ -123,7 +123,7 @@ date="2025/08/01" image="/images/manual/home/assets/asset-preview.png" title="预览资源" description="点击资源卡片/资源卡片操作栏的预览按钮进行资源预览。 预览弹窗左侧为可操作画布,右侧为资源详情及操作。" -author="ErSan" +author="" date="2025/08/01" /> ::: @@ -134,7 +134,7 @@ date="2025/08/01" image="/images/manual/home/assets/asset-edit.png" title="编辑资源" description="点击资源卡片操作栏的编辑选项进行资源编辑。 编辑时无法修改资源类型和资源文件。" -author="ErSan" +author="" date="2025/08/01" /> ::: diff --git a/Astral3D/packages/docs/src/notes/guide/manual/home/项目.md b/Astral3D/packages/docs/src/notes/guide/manual/home/项目.md index e7b7925..f59f8e8 100644 --- a/Astral3D/packages/docs/src/notes/guide/manual/home/项目.md +++ b/Astral3D/packages/docs/src/notes/guide/manual/home/项目.md @@ -9,7 +9,7 @@ permalink: /guide/dbd366ps/ image="/images/manual/home/project/project-page.png" title="项目" description="" -author="ErSan" +author="" date="2025/08/01" /> ::: @@ -23,7 +23,7 @@ date="2025/08/01" image="/images/manual/home/project/new-project.png" title="新建项目" description="可以选择新建一个空项目或者依据内置模板创建" -author="ErSan" +author="" date="2025/08/01" /> ::: diff --git a/Astral3D/packages/editor/.env b/Astral3D/packages/editor/.env index b9dddb8..078a72e 100644 --- a/Astral3D/packages/editor/.env +++ b/Astral3D/packages/editor/.env @@ -5,10 +5,10 @@ VITE_PORT=8090 VITE_GLOB_APP_TITLE='Astral3D Editor' # 作者 -VITE_GLOB_AUTHOR='ErSan' +VITE_GLOB_AUTHOR='' # 当前版本 VITE_GLOB_VERSION='1.0.0' # 备案号 -VITE_GLOB_BEIAN='滇ICP备XXXXXX号' \ No newline at end of file +VITE_GLOB_BEIAN='' \ No newline at end of file diff --git a/Astral3D/packages/editor/.env.production b/Astral3D/packages/editor/.env.production index c65c321..b39c5eb 100644 --- a/Astral3D/packages/editor/.env.production +++ b/Astral3D/packages/editor/.env.production @@ -16,7 +16,7 @@ VITE_ENABLE_ANALYZE=true VITE_ENABLE_CONFIG_GENERATE=true # 当前站点URL -VITE_GLOB_ORIGIN=https://editor.astraljs.com/ +VITE_GLOB_ORIGIN= #ws接口 -VITE_GLOB_SOCKET_URL=wss://editor.astraljs.com/socket \ No newline at end of file +VITE_GLOB_SOCKET_URL= \ No newline at end of file diff --git a/Astral3D/packages/editor/package.json b/Astral3D/packages/editor/package.json index be3ce18..80ec41b 100644 --- a/Astral3D/packages/editor/package.json +++ b/Astral3D/packages/editor/package.json @@ -1,6 +1,6 @@ { "name": "@astral3d/editor", - "author": "ErSan", + "author": "", "version": "1.0.0", "type": "module", "scripts": { diff --git a/Astral3D/packages/editor/src/hooks/useWebSocket.ts b/Astral3D/packages/editor/src/hooks/useWebSocket.ts index 0b4733e..18db65e 100644 --- a/Astral3D/packages/editor/src/hooks/useWebSocket.ts +++ b/Astral3D/packages/editor/src/hooks/useWebSocket.ts @@ -1,7 +1,6 @@ /** - * @author MaHaiBing - * @email mlt131220@163.com - * @date 2023/11/29 10:10 + * @author + * @date 2026/3/13 * @description websocket hook;使用store管理websocket保证全局唯一性 */ import {unref} from 'vue'; diff --git a/Astral3D/packages/editor/src/http/api/sceneExample.ts b/Astral3D/packages/editor/src/http/api/sceneExample.ts index b734361..116c862 100644 --- a/Astral3D/packages/editor/src/http/api/sceneExample.ts +++ b/Astral3D/packages/editor/src/http/api/sceneExample.ts @@ -1,7 +1,6 @@ /** - * @author MaHaiBing - * @email mlt131220@163.com - * @date 2024/7/28 14:54 + * @author + * @date 2026/3/13 * @description 示例场景 */ import {request} from "@/http/request"; diff --git a/Astral3D/packages/editor/src/plugin/glTFHandler/Listr.ts b/Astral3D/packages/editor/src/plugin/glTFHandler/Listr.ts index 0cda96e..333af36 100644 --- a/Astral3D/packages/editor/src/plugin/glTFHandler/Listr.ts +++ b/Astral3D/packages/editor/src/plugin/glTFHandler/Listr.ts @@ -1,46 +1,44 @@ -/** - * @author ErSan - * @email mlt131220@163.com - * @date 2024/9/18 22:24 - * @description - */ - -export class ListrTask { - // @ts-ignore - private title: any; - private taskFn: any; - isFailed: boolean; - - constructor(title, taskFn) { - this.title = title; - this.taskFn = taskFn; - this.isFailed = false; - } - - async run() { - try { - await this.taskFn(this); - } catch (error) { - this.isFailed = true; - - throw error; - } - } -} - -export class Listr { - private tasks: ListrTask[]; - - constructor(tasks: { title:string,task:(task: any) => Promise }[]) { - this.tasks = tasks.map(task => new ListrTask(task.title, task.task)); - } - - async run() { - for (const task of this.tasks) { - await task.run(); - if (task.isFailed) { - break; // 如果任务失败,停止执行后续任务 - } - } - } +/** + * @date 2026/3/13 + * @description + */ + +export class ListrTask { + // @ts-ignore + private title: any; + private taskFn: any; + isFailed: boolean; + + constructor(title, taskFn) { + this.title = title; + this.taskFn = taskFn; + this.isFailed = false; + } + + async run() { + try { + await this.taskFn(this); + } catch (error) { + this.isFailed = true; + + throw error; + } + } +} + +export class Listr { + private tasks: ListrTask[]; + + constructor(tasks: { title:string,task:(task: any) => Promise }[]) { + this.tasks = tasks.map(task => new ListrTask(task.title, task.task)); + } + + async run() { + for (const task of this.tasks) { + await task.run(); + if (task.isFailed) { + break; // 如果任务失败,停止执行后续任务 + } + } + } } \ No newline at end of file diff --git a/Astral3D/packages/editor/src/plugin/glTFHandler/glTFHandler.ts b/Astral3D/packages/editor/src/plugin/glTFHandler/glTFHandler.ts index 74d081d..1693322 100644 --- a/Astral3D/packages/editor/src/plugin/glTFHandler/glTFHandler.ts +++ b/Astral3D/packages/editor/src/plugin/glTFHandler/glTFHandler.ts @@ -1,249 +1,247 @@ -/** - * @author ErSan - * @email mlt131220@163.com - * @date 2024/9/16 23:19 - * @description glTF处理器插件 - */ -import {h, ref} from "vue"; -import type {ModalReactive} from "naive-ui"; -import {t} from "@/language"; -import type {Plugin} from "@astral3d/engine"; -import GLTFHandlerComponent from "@/components/es/plugin/builtin/GLTFHandler.vue"; - -import { MeshoptEncoder, MeshoptSimplifier } from 'meshoptimizer'; -// @ts-ignore -import { ready as resampleReady, resample as resampleWASM } from 'keyframe-resample'; -import { Logger,WebIO, Transform } from '@gltf-transform/core'; -import { - dedup, - instance, - prune, - quantize, - resample, - weld, - meshopt, - draco, - simplify, - textureCompress, - flatten, - join, - sparse, - palette, -} from '@gltf-transform/functions'; -import { ALL_EXTENSIONS } from '@gltf-transform/extensions'; -import {Session} from "./session"; -import {loadScript} from "@/utils/common/utils"; -import { optimizePNG } from "@/plugin/glTFHandler/optimizePng"; - -//使用'micromatch',因为'contains: true'没有像预期的那样在minimatch中工作。需要确保'*'匹配的模式,如'image/png'。 -export const MICROMATCH_OPTIONS = { nocase: true, contains: true }; - -export default class GLTFHandler implements Plugin{ - icon= ""; - name = "glTF处理器"; - version = 1; - - logger = new Logger(Logger.Verbosity.INFO); - io = new WebIO({credentials: 'include'}).registerExtensions(ALL_EXTENSIONS); - - modalInstance:ModalReactive | undefined = undefined; - GLTFHandlerComponentRef = ref(); - dracoScript = new Proxy({ - encoder:false, - decoder:false, - failMsg:"" - },{ - set:(target: {decoder: boolean;encoder: boolean;failMsg: string;}, p: string | symbol, newValue: any): boolean => { - target[p] = newValue; - - if(p === "failMsg"){ - window.$message?.error(newValue) - return true; - } - - if(target.encoder && target.decoder){ - this.registerDependencies() - } - - return true; - } - }) - - async install() { - // console.log(`%c glTF处理器 %c 版本:1.0.0`, 'background: #35495e; padding: 4px; border-radius: 3px 0 0 3px; color: #fff', - // 'background: #41b883; padding: 4px; border-radius: 0 3px 3px 0; color: #fff'); - } - - async run() { - // 运行时再加载draco相关js - if(!this.dracoScript.encoder){ - loadScript("/libs/draco/draco_encoder.js",false).then(() => { - this.dracoScript.encoder = true; - }).catch(() => { - this.dracoScript.failMsg = t("plugin.gltfHandler['Draco encoder load fail,Refresh the page and try again.']"); - }) - } - if(!this.dracoScript.decoder) { - loadScript("/libs/draco/draco_decoder.js", false).then(() => { - this.dracoScript.decoder = true; - }).catch(() => { - this.dracoScript.failMsg = t("plugin.gltfHandler['Draco decoder load fail,Refresh the page and try again.']"); - }) - } - - this.GLTFHandlerComponentRef = ref(); - this.modalInstance = window.$modal.create({ - title: this.name, - preset:"card", - maskClosable:false, - style: { - width: '90%', - maxWidth: '800px' - }, - onAfterLeave: () => this.finish(), - content: () => { - return h(GLTFHandlerComponent,{ - onOptimize: this.optimize.bind(this), - onFinish: () => this.finish(), - ref: this.GLTFHandlerComponentRef - },"") - }, - }) - } - - // 关闭插件 - finish(){ - this.modalInstance && this.modalInstance.destroy(); - - this.GLTFHandlerComponentRef = ref(); - } - - uninstall(): void {} - - setLogger(log:string){ - if(!this.GLTFHandlerComponentRef.value) return; - - this.GLTFHandlerComponentRef.value.addLog(log); - } - - async registerDependencies(){ - this.io.registerDependencies({ - // @ts-ignore - 'draco3d.encoder': await new DracoEncoderModule(), - // @ts-ignore - 'draco3d.decoder': await new DracoDecoderModule(), - }) - } - - /* 下面是实现的自定义的处理器方法 */ - async optimize(opts:IPlugin.GLTFHandlerOptimizeModel,inputFile:File,outputFileName = ""){ - this.setLogger(`Optimize ${inputFile.name}`); - - if(this.dracoScript.failMsg){ - window.$message?.error(this.dracoScript.failMsg); - return; - } - if(!this.dracoScript.encoder || !this.dracoScript.decoder){ - setTimeout(()=>this.optimize(opts,inputFile,outputFileName),1000) - return; - } - - /* 文件准备就绪,开始优化 */ - - const transforms: Transform[] = [ - optimizePNG(), - dedup() - ]; - - if (opts.instance) transforms.push(instance({ min: opts.instanceMin })); - - if (opts.palette) { - transforms.push( - palette({ - min: opts.paletteMin, - keepAttributes: !opts.prune || !opts.pruneAttributes, - }), - ); - } - - if (opts.flatten) transforms.push(flatten()); - if (opts.join) transforms.push(join()); - if (opts.weld) transforms.push(weld()); - - if (opts.simplify) { - transforms.push( - simplify({ - simplifier: MeshoptSimplifier, - // simplifyError 用%显示时扩大了100倍,需要高精度计算减小100倍 - error: opts.simplifyError / 100, - ratio: opts.simplifyRatio, - lockBorder: opts.simplifyLockBorder, - }), - ); - } - - // 重新采样动画通道,无损地删除重复的关键帧以减小文件大小。重复的关键帧通常出现在由创作软件“烘焙”的动画中,以应用 IK 约束或其他软件特定功能。 - transforms.push(resample({ ready: resampleReady, resample: resampleWASM })); - - if (opts.prune) { - transforms.push( - prune({ - keepAttributes: !opts.pruneAttributes, - keepIndices: false, - keepLeaves: !opts.pruneLeaves, - keepSolidTextures: !opts.pruneSolidTextures, - }), - ); - } - - transforms.push(sparse()); - - if (opts.textureCompress !== 'none') { - transforms.push( - textureCompress({ - resize: [opts.textureSize, opts.textureSize], - targetFormat: opts.textureCompress === 'auto' ? undefined : opts.textureCompress, - // limitInputPixels: options.limitInputPixels as boolean, - limitInputPixels: false, - }), - ); - } - - // 最后进行网格压缩 - if (opts.compress === 'draco') { - transforms.push(draco()); - } else if (opts.compress === 'meshopt') { - transforms.push(meshopt({ encoder: MeshoptEncoder, level: opts.meshoptLevel })); - } else if (opts.compress === 'quantize') { - transforms.push(quantize()); - } - - // 设置输出文件名 - if(!outputFileName){ - const format = inputFile.name.split(".").pop(); - outputFileName = inputFile.name.replace(`.${format}`,`_astral3d.optimize.${format}`) - } - - // 生成临时 URL - const inputFileUrl = URL.createObjectURL(inputFile); - - let outputFile:File | undefined = undefined - try { - outputFile = await Session.create(this,inputFileUrl, inputFile.name, outputFileName) - .setDisplay(true) - .transform(...transforms); - - this.setLogger(`Optimize ${inputFile.name} success!`); - }catch (e:unknown){ - if (e instanceof Error) { - window.$message?.error(e.message); - this.setLogger(`Optimize ${inputFile.name} error: ${e.message}`); - } else { - window.$message?.error(e as string); - this.setLogger(`Optimize ${inputFile.name} error: ${e}`); - } - } - - return outputFile; - } +/** + * @date 2026/3/13 + * @description glTF处理器插件 + */ +import {h, ref} from "vue"; +import type {ModalReactive} from "naive-ui"; +import {t} from "@/language"; +import type {Plugin} from "@astral3d/engine"; +import GLTFHandlerComponent from "@/components/es/plugin/builtin/GLTFHandler.vue"; + +import { MeshoptEncoder, MeshoptSimplifier } from 'meshoptimizer'; +// @ts-ignore +import { ready as resampleReady, resample as resampleWASM } from 'keyframe-resample'; +import { Logger,WebIO, Transform } from '@gltf-transform/core'; +import { + dedup, + instance, + prune, + quantize, + resample, + weld, + meshopt, + draco, + simplify, + textureCompress, + flatten, + join, + sparse, + palette, +} from '@gltf-transform/functions'; +import { ALL_EXTENSIONS } from '@gltf-transform/extensions'; +import {Session} from "./session"; +import {loadScript} from "@/utils/common/utils"; +import { optimizePNG } from "@/plugin/glTFHandler/optimizePng"; + +//使用'micromatch',因为'contains: true'没有像预期的那样在minimatch中工作。需要确保'*'匹配的模式,如'image/png'。 +export const MICROMATCH_OPTIONS = { nocase: true, contains: true }; + +export default class GLTFHandler implements Plugin{ + icon= ""; + name = "glTF处理器"; + version = 1; + + logger = new Logger(Logger.Verbosity.INFO); + io = new WebIO({credentials: 'include'}).registerExtensions(ALL_EXTENSIONS); + + modalInstance:ModalReactive | undefined = undefined; + GLTFHandlerComponentRef = ref(); + dracoScript = new Proxy({ + encoder:false, + decoder:false, + failMsg:"" + },{ + set:(target: {decoder: boolean;encoder: boolean;failMsg: string;}, p: string | symbol, newValue: any): boolean => { + target[p] = newValue; + + if(p === "failMsg"){ + window.$message?.error(newValue) + return true; + } + + if(target.encoder && target.decoder){ + this.registerDependencies() + } + + return true; + } + }) + + async install() { + // console.log(`%c glTF处理器 %c 版本:1.0.0`, 'background: #35495e; padding: 4px; border-radius: 3px 0 0 3px; color: #fff', + // 'background: #41b883; padding: 4px; border-radius: 0 3px 3px 0; color: #fff'); + } + + async run() { + // 运行时再加载draco相关js + if(!this.dracoScript.encoder){ + loadScript("/libs/draco/draco_encoder.js",false).then(() => { + this.dracoScript.encoder = true; + }).catch(() => { + this.dracoScript.failMsg = t("plugin.gltfHandler['Draco encoder load fail,Refresh the page and try again.']"); + }) + } + if(!this.dracoScript.decoder) { + loadScript("/libs/draco/draco_decoder.js", false).then(() => { + this.dracoScript.decoder = true; + }).catch(() => { + this.dracoScript.failMsg = t("plugin.gltfHandler['Draco decoder load fail,Refresh the page and try again.']"); + }) + } + + this.GLTFHandlerComponentRef = ref(); + this.modalInstance = window.$modal.create({ + title: this.name, + preset:"card", + maskClosable:false, + style: { + width: '90%', + maxWidth: '800px' + }, + onAfterLeave: () => this.finish(), + content: () => { + return h(GLTFHandlerComponent,{ + onOptimize: this.optimize.bind(this), + onFinish: () => this.finish(), + ref: this.GLTFHandlerComponentRef + },"") + }, + }) + } + + // 关闭插件 + finish(){ + this.modalInstance && this.modalInstance.destroy(); + + this.GLTFHandlerComponentRef = ref(); + } + + uninstall(): void {} + + setLogger(log:string){ + if(!this.GLTFHandlerComponentRef.value) return; + + this.GLTFHandlerComponentRef.value.addLog(log); + } + + async registerDependencies(){ + this.io.registerDependencies({ + // @ts-ignore + 'draco3d.encoder': await new DracoEncoderModule(), + // @ts-ignore + 'draco3d.decoder': await new DracoDecoderModule(), + }) + } + + /* 下面是实现的自定义的处理器方法 */ + async optimize(opts:IPlugin.GLTFHandlerOptimizeModel,inputFile:File,outputFileName = ""){ + this.setLogger(`Optimize ${inputFile.name}`); + + if(this.dracoScript.failMsg){ + window.$message?.error(this.dracoScript.failMsg); + return; + } + if(!this.dracoScript.encoder || !this.dracoScript.decoder){ + setTimeout(()=>this.optimize(opts,inputFile,outputFileName),1000) + return; + } + + /* 文件准备就绪,开始优化 */ + + const transforms: Transform[] = [ + optimizePNG(), + dedup() + ]; + + if (opts.instance) transforms.push(instance({ min: opts.instanceMin })); + + if (opts.palette) { + transforms.push( + palette({ + min: opts.paletteMin, + keepAttributes: !opts.prune || !opts.pruneAttributes, + }), + ); + } + + if (opts.flatten) transforms.push(flatten()); + if (opts.join) transforms.push(join()); + if (opts.weld) transforms.push(weld()); + + if (opts.simplify) { + transforms.push( + simplify({ + simplifier: MeshoptSimplifier, + // simplifyError 用%显示时扩大了100倍,需要高精度计算减小100倍 + error: opts.simplifyError / 100, + ratio: opts.simplifyRatio, + lockBorder: opts.simplifyLockBorder, + }), + ); + } + + // 重新采样动画通道,无损地删除重复的关键帧以减小文件大小。重复的关键帧通常出现在由创作软件“烘焙”的动画中,以应用 IK 约束或其他软件特定功能。 + transforms.push(resample({ ready: resampleReady, resample: resampleWASM })); + + if (opts.prune) { + transforms.push( + prune({ + keepAttributes: !opts.pruneAttributes, + keepIndices: false, + keepLeaves: !opts.pruneLeaves, + keepSolidTextures: !opts.pruneSolidTextures, + }), + ); + } + + transforms.push(sparse()); + + if (opts.textureCompress !== 'none') { + transforms.push( + textureCompress({ + resize: [opts.textureSize, opts.textureSize], + targetFormat: opts.textureCompress === 'auto' ? undefined : opts.textureCompress, + // limitInputPixels: options.limitInputPixels as boolean, + limitInputPixels: false, + }), + ); + } + + // 最后进行网格压缩 + if (opts.compress === 'draco') { + transforms.push(draco()); + } else if (opts.compress === 'meshopt') { + transforms.push(meshopt({ encoder: MeshoptEncoder, level: opts.meshoptLevel })); + } else if (opts.compress === 'quantize') { + transforms.push(quantize()); + } + + // 设置输出文件名 + if(!outputFileName){ + const format = inputFile.name.split(".").pop(); + outputFileName = inputFile.name.replace(`.${format}`,`_astral3d.optimize.${format}`) + } + + // 生成临时 URL + const inputFileUrl = URL.createObjectURL(inputFile); + + let outputFile:File | undefined = undefined + try { + outputFile = await Session.create(this,inputFileUrl, inputFile.name, outputFileName) + .setDisplay(true) + .transform(...transforms); + + this.setLogger(`Optimize ${inputFile.name} success!`); + }catch (e:unknown){ + if (e instanceof Error) { + window.$message?.error(e.message); + this.setLogger(`Optimize ${inputFile.name} error: ${e.message}`); + } else { + window.$message?.error(e as string); + this.setLogger(`Optimize ${inputFile.name} error: ${e}`); + } + } + + return outputFile; + } } \ No newline at end of file diff --git a/Astral3D/packages/editor/src/plugin/pointCloudReconstructor/PointCloudReconstructor.ts b/Astral3D/packages/editor/src/plugin/pointCloudReconstructor/PointCloudReconstructor.ts index 28fb2d8..7f3ca01 100644 --- a/Astral3D/packages/editor/src/plugin/pointCloudReconstructor/PointCloudReconstructor.ts +++ b/Astral3D/packages/editor/src/plugin/pointCloudReconstructor/PointCloudReconstructor.ts @@ -1,55 +1,53 @@ -/** - * @author ErSan - * @email mlt131220@163.com - * @date 2025/07/03 14:20 - * @description 语义化点云重建 - */ -import { h, ref } from "vue"; -import type { ModalReactive } from "naive-ui"; -import type { Plugin } from "@astral3d/engine"; -import PointCloudReconstructorComponent from "@/components/es/plugin/builtin/PointCloudReconstructor.vue"; - -export default class PointCloudReconstructor implements Plugin { - icon = ""; - name = "语义化点云重建"; - version = 0.1; - - modalInstance: ModalReactive | undefined = undefined; - componentRef = ref(); - - async install() { - // console.log(`%c 语义化点云重建 %c 版本:0.1.0`, 'background: #35495e; padding: 4px; border-radius: 3px 0 0 3px; color: #fff', - // 'background: #41b883; padding: 4px; border-radius: 0 3px 3px 0; color: #fff'); - } - - async run() { - this.componentRef = ref(); - this.modalInstance = window.$modal.create({ - title: this.name, - preset: "card", - maskClosable: false, - style: { - width: '90%', - maxWidth: '800px' - }, - onAfterLeave: () => { - this.componentRef.value.handleClose(); - this.finish(); - }, - content: () => { - return h(PointCloudReconstructorComponent, { - ref: this.componentRef - }, "") - }, - }) - } - - // 关闭插件 - finish() { - this.modalInstance && this.modalInstance.destroy(); - - this.componentRef = ref(); - } - - uninstall(): void { } +/** + * @date 2026/3/13 + * @description 语义化点云重建 + */ +import { h, ref } from "vue"; +import type { ModalReactive } from "naive-ui"; +import type { Plugin } from "@astral3d/engine"; +import PointCloudReconstructorComponent from "@/components/es/plugin/builtin/PointCloudReconstructor.vue"; + +export default class PointCloudReconstructor implements Plugin { + icon = ""; + name = "语义化点云重建"; + version = 0.1; + + modalInstance: ModalReactive | undefined = undefined; + componentRef = ref(); + + async install() { + // console.log(`%c 语义化点云重建 %c 版本:0.1.0`, 'background: #35495e; padding: 4px; border-radius: 3px 0 0 3px; color: #fff', + // 'background: #41b883; padding: 4px; border-radius: 0 3px 3px 0; color: #fff'); + } + + async run() { + this.componentRef = ref(); + this.modalInstance = window.$modal.create({ + title: this.name, + preset: "card", + maskClosable: false, + style: { + width: '90%', + maxWidth: '800px' + }, + onAfterLeave: () => { + this.componentRef.value.handleClose(); + this.finish(); + }, + content: () => { + return h(PointCloudReconstructorComponent, { + ref: this.componentRef + }, "") + }, + }) + } + + // 关闭插件 + finish() { + this.modalInstance && this.modalInstance.destroy(); + + this.componentRef = ref(); + } + + uninstall(): void { } } \ No newline at end of file diff --git a/Astral3D/packages/editor/src/store/modules/plugin.ts b/Astral3D/packages/editor/src/store/modules/plugin.ts index 2b1ef85..3db0884 100644 --- a/Astral3D/packages/editor/src/store/modules/plugin.ts +++ b/Astral3D/packages/editor/src/store/modules/plugin.ts @@ -1,54 +1,52 @@ -/** - * @author ErSan - * @email mlt131220@163.com - * @date 2024/9/16 0:36 - * @description - */ -import { defineStore } from 'pinia'; -import { store } from '@/store'; -import {computed, reactive, toRefs} from "vue"; - -interface IPluginState { - // 已安装(可用)插件的列表 - plugins:{[name:string]:IPlugin.Item} -} - -export const usePluginStore = defineStore("plugin",() => { - const state = reactive({ - plugins:{} - }) - - const getPluginsList = () => computed(() => Object.values(state.plugins)); - const setPlugins = (_plugins:IPlugin.Item[]) => { - state.plugins = {}; - - _plugins.forEach(plugin => { - state.plugins[plugin.name] = { - name:plugin.name, - icon:plugin.icon - } - }) - - } - const addPlugin = (plugin:IPlugin.Item) => { - state.plugins[plugin.name] = { - name:plugin.name, - icon:plugin.icon - } - } - const removePlugin = (pluginName:string) => { - delete state.plugins[pluginName]; - } - - return { - ...toRefs(state), - getPluginsList, - setPlugins, - addPlugin, - removePlugin - } -}) - -export function usePluginStoreWithOut() { - return usePluginStore(store); +/** + * @date 2026/3/13 + * @description + */ +import { defineStore } from 'pinia'; +import { store } from '@/store'; +import {computed, reactive, toRefs} from "vue"; + +interface IPluginState { + // 已安装(可用)插件的列表 + plugins:{[name:string]:IPlugin.Item} +} + +export const usePluginStore = defineStore("plugin",() => { + const state = reactive({ + plugins:{} + }) + + const getPluginsList = () => computed(() => Object.values(state.plugins)); + const setPlugins = (_plugins:IPlugin.Item[]) => { + state.plugins = {}; + + _plugins.forEach(plugin => { + state.plugins[plugin.name] = { + name:plugin.name, + icon:plugin.icon + } + }) + + } + const addPlugin = (plugin:IPlugin.Item) => { + state.plugins[plugin.name] = { + name:plugin.name, + icon:plugin.icon + } + } + const removePlugin = (pluginName:string) => { + delete state.plugins[pluginName]; + } + + return { + ...toRefs(state), + getPluginsList, + setPlugins, + addPlugin, + removePlugin + } +}) + +export function usePluginStoreWithOut() { + return usePluginStore(store); } \ No newline at end of file diff --git a/Astral3D/packages/editor/src/utils/common/constant.ts b/Astral3D/packages/editor/src/utils/common/constant.ts index b42acc0..9e80124 100644 --- a/Astral3D/packages/editor/src/utils/common/constant.ts +++ b/Astral3D/packages/editor/src/utils/common/constant.ts @@ -1,66 +1,64 @@ -/** - * @author ErSan - * @email mlt131220@163.com - * @date 2024/3/26 9:57 - * @description 全局常量 - */ -// 支持的模型格式 -export const MODEL_SUPPORT_TYPE = [ - // 普通模型格式 - "gltf","glb","fbx","obj","mtl", - "3dm","3ds", - "3mf","amf", - "dae","drc", - "kmz","ldr", - "mpd","md2", - "pcd","ply", - "stl","svg", - "usdz","vox","vtk","vtp", - "wrl", - "xyz", - "json","zip", - // 自解析格式 - "rvt","rfa","ifc", - "3DTiles", - //"osgb", - // "rvm", - // "dgn", - /*"jt"*/ - // "shp", - // "stp","step" -]; - -// 资源中心支持上传的格式 -export const ASSET_UPLOAD_SUPPORT_TYPE = { - 'Model': ['glb','gltf','fbx','obj'], - 'Material': ['zip'], - 'Texture': ['png','jpg','jpeg','webp'], - 'Billboard': ['png','jpg','jpeg','webp','svg'], - 'HDR': ['hdr','exr'], - 'Tiles': ['zip'], -} - -// 需要转换的BIM模型格式 -export const NEED_CONVERT_BIM_MODEL = ["rvt", "rfa"]; - -// 支持的图纸文件类型 -export const DRAWING_SUPPORT_TYPE = ["dwg", "dxf", "png", "jpg", "jpeg"]; - -// 需要转换的图纸格式 -export const NEED_CONVERT_DRAWING = ["dwg"]; - -// 支持的文档类型 -export const DOC_SUPPORT_TYPE = ["doc","docx","xls","xlsx","xlsm","ppt",'pptx',"pdf","txt"]; - -export const SCENE_TYPE = [ - {label:"城市",value:"城市"}, - {label:"园区",value:"园区"}, - {label:"工厂",value:"工厂"}, - {label:"楼宇",value:"楼宇"}, - {label:"设备",value:"设备"}, - {label:"其他",value:"其他"}, -] - -// 截屏占位图 -export const DefaultScreenshot = "/static/images/placeholder/截屏占位图.png"; - +/** + * @date 2026/3/13 + * @description 全局常量 + */ +// 支持的模型格式 +export const MODEL_SUPPORT_TYPE = [ + // 普通模型格式 + "gltf","glb","fbx","obj","mtl", + "3dm","3ds", + "3mf","amf", + "dae","drc", + "kmz","ldr", + "mpd","md2", + "pcd","ply", + "stl","svg", + "usdz","vox","vtk","vtp", + "wrl", + "xyz", + "json","zip", + // 自解析格式 + "rvt","rfa","ifc", + "3DTiles", + //"osgb", + // "rvm", + // "dgn", + /*"jt"*/ + // "shp", + // "stp","step" +]; + +// 资源中心支持上传的格式 +export const ASSET_UPLOAD_SUPPORT_TYPE = { + 'Model': ['glb','gltf','fbx','obj'], + 'Material': ['zip'], + 'Texture': ['png','jpg','jpeg','webp'], + 'Billboard': ['png','jpg','jpeg','webp','svg'], + 'HDR': ['hdr','exr'], + 'Tiles': ['zip'], +} + +// 需要转换的BIM模型格式 +export const NEED_CONVERT_BIM_MODEL = ["rvt", "rfa"]; + +// 支持的图纸文件类型 +export const DRAWING_SUPPORT_TYPE = ["dwg", "dxf", "png", "jpg", "jpeg"]; + +// 需要转换的图纸格式 +export const NEED_CONVERT_DRAWING = ["dwg"]; + +// 支持的文档类型 +export const DOC_SUPPORT_TYPE = ["doc","docx","xls","xlsx","xlsm","ppt",'pptx',"pdf","txt"]; + +export const SCENE_TYPE = [ + {label:"城市",value:"城市"}, + {label:"园区",value:"园区"}, + {label:"工厂",value:"工厂"}, + {label:"楼宇",value:"楼宇"}, + {label:"设备",value:"设备"}, + {label:"其他",value:"其他"}, +] + +// 截屏占位图 +export const DefaultScreenshot = "/static/images/placeholder/截屏占位图.png"; + diff --git a/Astral3D/packages/editor/src/utils/preview/menuOperation.ts b/Astral3D/packages/editor/src/utils/preview/menuOperation.ts index a56c742..2fcfd9d 100644 --- a/Astral3D/packages/editor/src/utils/preview/menuOperation.ts +++ b/Astral3D/packages/editor/src/utils/preview/menuOperation.ts @@ -1,358 +1,356 @@ -/** - * @author ErSan - * @email mlt131220@163.com - * @date 2024/8/22 - * @description 预览菜单操作 - */ -import { useFullscreen } from '@vueuse/core' -import { - IPreviewOperation, - usePreviewOperationStoreWithOut -} from "@/store/modules/previewOperation"; -import * as THREE from 'three'; -import { App,Hooks,ClippedEdgesBox,Measure,MeasureMode,ModelExplode,Roaming,MiniMap } from "@astral3d/engine"; -import { t } from "@/language"; - -const operationStore = usePreviewOperationStoreWithOut(); - -const { enter:enterFullscreen,exit:exitFullscreen } = useFullscreen(); - -let roamPdFn, pointerlockFn; - -export class MenuOperation { - // 初始化控制器状态 - static InitControlsState: string = "{}"; - - // 开始漫游前的相机位置 - static lastRoadCameraPos = new THREE.Vector3(); - - // 开始漫游前的相机目标位置 - static lastRoadCameraTarget = new THREE.Vector3(); - - // 模型爆炸专用图层 - static explodeLayer = 10; - - // 当前爆炸的模型 - static explodeModel:THREE.Object3D | null = null; - - // 剖切盒子 - static _clippedEdgesBox:ClippedEdgesBox | null = null; - - // 测量类 - static _measure:Measure | null = null; - - // 爆炸类 - static _explode:ModelExplode | null = null; - - // 漫游类 - static _roaming:Roaming | null = null; - - // 小地图 - static _miniMap:MiniMap | null = null; - - static Init(key: string) { - if (MenuOperation[key]) { - MenuOperation[key](); - } else { - window.$message?.warning("相关模块正在开发中...") - } - } - - static get ClippedEdgesBox(){ - if(!MenuOperation._clippedEdgesBox){ - MenuOperation._clippedEdgesBox = new ClippedEdgesBox(window.viewer); - } - - return MenuOperation._clippedEdgesBox; - } - - static get Measure():Measure{ - if(!MenuOperation._measure){ - MenuOperation._measure = new Measure(window.viewer,MeasureMode.Distance); - - MenuOperation._measure.addEventListener("complete",() => { - if(!MenuOperation._measure) return; - - // 激活清除测量按钮 - if (!MenuOperation._measure.isClose && MenuOperation._measure.measureGroup.children.length > 0) { - (<{ [key: string]: IPreviewOperation }>operationStore.menuList.measure.children).clearMeasure.disabled = false; - } - }) - } - - return MenuOperation._measure; - } - - static get Explode():ModelExplode{ - if(!MenuOperation._explode){ - MenuOperation._explode = new ModelExplode(); - } - - return MenuOperation._explode; - } - - static get Roaming():Roaming{ - if(!MenuOperation._roaming){ - MenuOperation._roaming = new Roaming(window.viewer); - } - - return MenuOperation._roaming; - } - - static get MiniMap():MiniMap{ - if(!MenuOperation._miniMap){ - MenuOperation._miniMap = new MiniMap(window.viewer,{ - mapSize: 100, - mapRenderSize: 350, - followTarget: window.viewer.camera, - isShow: false, - }); - } - - return MenuOperation._miniMap; - } - - /** - * 还原视角 - */ - static toHome() { - if (MenuOperation.InitControlsState === "{}") { - window.$message?.warning("缺失初始视角信息") - return; - } - - window.viewer.modules.controls.fromJSON(MenuOperation.InitControlsState, true); - } - - /** - * 自动旋转 - */ - static autoRotate() { - operationStore.menuList.autoRotate.active = !operationStore.menuList.autoRotate.active; - } - - /** - * 剖切 - */ - static cutting() { - operationStore.menuList.cutting.active = !operationStore.menuList.cutting.active; - - if (operationStore.menuList.cutting.active) { - MenuOperation.ClippedEdgesBox.open(); - } else { - MenuOperation.ClippedEdgesBox.close(); - } - } - - // 测距 - static distance() { - // 上一个测量也许未完成 - if (!MenuOperation.Measure.isCompleted) { - MenuOperation.Measure.complete(); - } - - window.$message?.info(t("prompt['Left click to confirm the drawing point, and right click to complete the drawing.']"),{ - duration: 1500 - }) - - MenuOperation.Measure.mode = MeasureMode.Distance; - MenuOperation.Measure.open(); - - operationStore.menuList.measure.active = true; - } - - // 测角度 - static angle() { - if (!MenuOperation.Measure.isCompleted) { - MenuOperation.Measure.complete(); - } - - window.$message?.info(t("prompt['Left click to confirm the drawing point, and right click to complete the drawing.']"),{ - duration: 1500 - }) - - MenuOperation.Measure.mode = MeasureMode.Angle; - MenuOperation.Measure.open(); - - operationStore.menuList.measure.active = true; - } - - // 测面积 - static area() { - if (!MenuOperation.Measure.isCompleted) { - MenuOperation.Measure.complete(); - } - - window.$message?.info(t("prompt['Left click to confirm the drawing point, and right click to complete the drawing.']"),{ - duration: 1500 - }) - - MenuOperation.Measure.mode = MeasureMode.Area; - MenuOperation.Measure.open(); - - operationStore.menuList.measure.active = true; - } - - // 清除测量结果 - static clearMeasure() { - (<{ [key: string]: IPreviewOperation }>operationStore.menuList.measure.children).clearMeasure.disabled = true; - - MenuOperation.Measure.clear(); - - operationStore.menuList.measure.active = false; - } - - // 爆炸 - static explode(){ - if(!App.selected && !MenuOperation.explodeModel){ - window.$message?.warning(t("prompt['No object selected.']")); - return; - } - - operationStore.menuList.explode.active = !operationStore.menuList.explode.active; - - if (operationStore.menuList.explode.active){ - if(!App.selected) return; - - App.selected.traverse(obj => obj.layers.set(MenuOperation.explodeLayer)); - window.viewer.camera.layers.set(MenuOperation.explodeLayer); - - MenuOperation.Explode.explodeModel(App.selected,operationStore.explodeScalar); - MenuOperation.explodeModel = App.selected; - }else{ - if(!MenuOperation.explodeModel) return; - - MenuOperation.explodeModel.traverse(obj => obj.layers.set(0)); - window.viewer.camera.layers.set(0); - - MenuOperation.Explode.restore(); - - MenuOperation.explodeModel = null; - } - } - - // 漫游 - static roaming() { - if (!MenuOperation.Roaming) return; - - operationStore.menuList.roaming.active = !operationStore.menuList.roaming.active; - - if (operationStore.menuList.roaming.active) { - MenuOperation.enterRoaming(); - } else { - MenuOperation.leaveRoaming(); - } - } - - // 选点进入漫游 - static enterRoaming() { - window.$message?.info(t("preview.Please select initial position")); - - const canvas = window.viewer.renderer.domElement; - - const handlePointerDown = (e: MouseEvent) => { - const raycaster = new THREE.Raycaster(); - - const x = e.offsetX; - const y = e.offsetY; - const mouse = new THREE.Vector2(); - mouse.x = (x / canvas.offsetWidth) * 2 - 1; - mouse.y = -(y / canvas.offsetHeight) * 2 + 1; - - raycaster.setFromCamera(mouse, window.viewer.camera); - raycaster.firstHitOnly = true; - - const intersectObjects:THREE.Object3D[] = [MenuOperation.Roaming.group]; - if(window.viewer.modules.tilesManage.mergeMesh){ - intersectObjects.push(window.viewer.modules.tilesManage.mergeMesh); - } - let intersects = raycaster.intersectObjects(intersectObjects, true) || []; - if (intersects && intersects.length > 0) { - const intersect = intersects[0]; - - // 锁定鼠标指针 - window.viewer.modules.controls.lockPointer(); - - canvas.removeEventListener("pointerdown", roamPdFn); - roamPdFn = undefined; - - window.viewer.modules.controls.getTarget(MenuOperation.lastRoadCameraTarget); - window.viewer.modules.controls.getPosition(MenuOperation.lastRoadCameraPos); - - const point = new THREE.Vector3(intersect.point.x, intersect.point.y + 2, intersect.point.z); - MenuOperation.Roaming.playerInitPos.copy(point); - - MenuOperation.Roaming.startRoaming(); - - // 第三人称 - window.viewer.modules.controls.maxPolarAngle = Math.PI / 2; - window.viewer.modules.controls.minDistance = 0.8; - window.viewer.modules.controls.maxDistance = 0.8; - window.viewer.modules.controls.distance = 0.8; - - Hooks.useDispatchSignal("sceneGraphChanged"); - } - return null; - } - - pointerlockFn = () => { - if (document.pointerLockElement) { - // console.log("指针被锁定到:", document.pointerLockElement); - } else { - // console.log("指针锁定状态现已解锁"); - MenuOperation.roaming(); - } - } - // 监听鼠标锁定取消 - document.addEventListener("pointerlockchange", pointerlockFn); - - // 监听选取初始位置 - roamPdFn = handlePointerDown.bind(this); - canvas.addEventListener("pointerdown", roamPdFn); - } - - // 退出漫游 - static leaveRoaming() { - MenuOperation.Roaming.exitRoaming(MenuOperation.lastRoadCameraPos,MenuOperation.lastRoadCameraTarget); - - if (roamPdFn) { - window.viewer.renderer.domElement.removeEventListener("pointerdown", roamPdFn); - roamPdFn = null; - } - - if (pointerlockFn) { - document.removeEventListener("pointerlockchange", pointerlockFn); - pointerlockFn = null; - } - } - - // 小地图 - static miniMap() { - if (MenuOperation.MiniMap.isShow) { - operationStore.menuList.miniMap.active = false; - MenuOperation.MiniMap.close(); - } else { - operationStore.menuList.miniMap.active = true; - MenuOperation.MiniMap.open(); - } - } - - // 设置 - static settings(){ - operationStore.menuList.settings.active = !operationStore.menuList.settings.active; - } - - static fullscreen() { - operationStore.menuList.fullscreen.show = false; - operationStore.menuList.exitFullscreen.show = true; - - enterFullscreen(); - } - - static exitFullscreen() { - operationStore.menuList.fullscreen.show = true; - operationStore.menuList.exitFullscreen.show = false; - - exitFullscreen(); - } +/** + * @date 2026/3/13 + * @description 预览菜单操作 + */ +import { useFullscreen } from '@vueuse/core' +import { + IPreviewOperation, + usePreviewOperationStoreWithOut +} from "@/store/modules/previewOperation"; +import * as THREE from 'three'; +import { App,Hooks,ClippedEdgesBox,Measure,MeasureMode,ModelExplode,Roaming,MiniMap } from "@astral3d/engine"; +import { t } from "@/language"; + +const operationStore = usePreviewOperationStoreWithOut(); + +const { enter:enterFullscreen,exit:exitFullscreen } = useFullscreen(); + +let roamPdFn, pointerlockFn; + +export class MenuOperation { + // 初始化控制器状态 + static InitControlsState: string = "{}"; + + // 开始漫游前的相机位置 + static lastRoadCameraPos = new THREE.Vector3(); + + // 开始漫游前的相机目标位置 + static lastRoadCameraTarget = new THREE.Vector3(); + + // 模型爆炸专用图层 + static explodeLayer = 10; + + // 当前爆炸的模型 + static explodeModel:THREE.Object3D | null = null; + + // 剖切盒子 + static _clippedEdgesBox:ClippedEdgesBox | null = null; + + // 测量类 + static _measure:Measure | null = null; + + // 爆炸类 + static _explode:ModelExplode | null = null; + + // 漫游类 + static _roaming:Roaming | null = null; + + // 小地图 + static _miniMap:MiniMap | null = null; + + static Init(key: string) { + if (MenuOperation[key]) { + MenuOperation[key](); + } else { + window.$message?.warning("相关模块正在开发中...") + } + } + + static get ClippedEdgesBox(){ + if(!MenuOperation._clippedEdgesBox){ + MenuOperation._clippedEdgesBox = new ClippedEdgesBox(window.viewer); + } + + return MenuOperation._clippedEdgesBox; + } + + static get Measure():Measure{ + if(!MenuOperation._measure){ + MenuOperation._measure = new Measure(window.viewer,MeasureMode.Distance); + + MenuOperation._measure.addEventListener("complete",() => { + if(!MenuOperation._measure) return; + + // 激活清除测量按钮 + if (!MenuOperation._measure.isClose && MenuOperation._measure.measureGroup.children.length > 0) { + (<{ [key: string]: IPreviewOperation }>operationStore.menuList.measure.children).clearMeasure.disabled = false; + } + }) + } + + return MenuOperation._measure; + } + + static get Explode():ModelExplode{ + if(!MenuOperation._explode){ + MenuOperation._explode = new ModelExplode(); + } + + return MenuOperation._explode; + } + + static get Roaming():Roaming{ + if(!MenuOperation._roaming){ + MenuOperation._roaming = new Roaming(window.viewer); + } + + return MenuOperation._roaming; + } + + static get MiniMap():MiniMap{ + if(!MenuOperation._miniMap){ + MenuOperation._miniMap = new MiniMap(window.viewer,{ + mapSize: 100, + mapRenderSize: 350, + followTarget: window.viewer.camera, + isShow: false, + }); + } + + return MenuOperation._miniMap; + } + + /** + * 还原视角 + */ + static toHome() { + if (MenuOperation.InitControlsState === "{}") { + window.$message?.warning("缺失初始视角信息") + return; + } + + window.viewer.modules.controls.fromJSON(MenuOperation.InitControlsState, true); + } + + /** + * 自动旋转 + */ + static autoRotate() { + operationStore.menuList.autoRotate.active = !operationStore.menuList.autoRotate.active; + } + + /** + * 剖切 + */ + static cutting() { + operationStore.menuList.cutting.active = !operationStore.menuList.cutting.active; + + if (operationStore.menuList.cutting.active) { + MenuOperation.ClippedEdgesBox.open(); + } else { + MenuOperation.ClippedEdgesBox.close(); + } + } + + // 测距 + static distance() { + // 上一个测量也许未完成 + if (!MenuOperation.Measure.isCompleted) { + MenuOperation.Measure.complete(); + } + + window.$message?.info(t("prompt['Left click to confirm the drawing point, and right click to complete the drawing.']"),{ + duration: 1500 + }) + + MenuOperation.Measure.mode = MeasureMode.Distance; + MenuOperation.Measure.open(); + + operationStore.menuList.measure.active = true; + } + + // 测角度 + static angle() { + if (!MenuOperation.Measure.isCompleted) { + MenuOperation.Measure.complete(); + } + + window.$message?.info(t("prompt['Left click to confirm the drawing point, and right click to complete the drawing.']"),{ + duration: 1500 + }) + + MenuOperation.Measure.mode = MeasureMode.Angle; + MenuOperation.Measure.open(); + + operationStore.menuList.measure.active = true; + } + + // 测面积 + static area() { + if (!MenuOperation.Measure.isCompleted) { + MenuOperation.Measure.complete(); + } + + window.$message?.info(t("prompt['Left click to confirm the drawing point, and right click to complete the drawing.']"),{ + duration: 1500 + }) + + MenuOperation.Measure.mode = MeasureMode.Area; + MenuOperation.Measure.open(); + + operationStore.menuList.measure.active = true; + } + + // 清除测量结果 + static clearMeasure() { + (<{ [key: string]: IPreviewOperation }>operationStore.menuList.measure.children).clearMeasure.disabled = true; + + MenuOperation.Measure.clear(); + + operationStore.menuList.measure.active = false; + } + + // 爆炸 + static explode(){ + if(!App.selected && !MenuOperation.explodeModel){ + window.$message?.warning(t("prompt['No object selected.']")); + return; + } + + operationStore.menuList.explode.active = !operationStore.menuList.explode.active; + + if (operationStore.menuList.explode.active){ + if(!App.selected) return; + + App.selected.traverse(obj => obj.layers.set(MenuOperation.explodeLayer)); + window.viewer.camera.layers.set(MenuOperation.explodeLayer); + + MenuOperation.Explode.explodeModel(App.selected,operationStore.explodeScalar); + MenuOperation.explodeModel = App.selected; + }else{ + if(!MenuOperation.explodeModel) return; + + MenuOperation.explodeModel.traverse(obj => obj.layers.set(0)); + window.viewer.camera.layers.set(0); + + MenuOperation.Explode.restore(); + + MenuOperation.explodeModel = null; + } + } + + // 漫游 + static roaming() { + if (!MenuOperation.Roaming) return; + + operationStore.menuList.roaming.active = !operationStore.menuList.roaming.active; + + if (operationStore.menuList.roaming.active) { + MenuOperation.enterRoaming(); + } else { + MenuOperation.leaveRoaming(); + } + } + + // 选点进入漫游 + static enterRoaming() { + window.$message?.info(t("preview.Please select initial position")); + + const canvas = window.viewer.renderer.domElement; + + const handlePointerDown = (e: MouseEvent) => { + const raycaster = new THREE.Raycaster(); + + const x = e.offsetX; + const y = e.offsetY; + const mouse = new THREE.Vector2(); + mouse.x = (x / canvas.offsetWidth) * 2 - 1; + mouse.y = -(y / canvas.offsetHeight) * 2 + 1; + + raycaster.setFromCamera(mouse, window.viewer.camera); + raycaster.firstHitOnly = true; + + const intersectObjects:THREE.Object3D[] = [MenuOperation.Roaming.group]; + if(window.viewer.modules.tilesManage.mergeMesh){ + intersectObjects.push(window.viewer.modules.tilesManage.mergeMesh); + } + let intersects = raycaster.intersectObjects(intersectObjects, true) || []; + if (intersects && intersects.length > 0) { + const intersect = intersects[0]; + + // 锁定鼠标指针 + window.viewer.modules.controls.lockPointer(); + + canvas.removeEventListener("pointerdown", roamPdFn); + roamPdFn = undefined; + + window.viewer.modules.controls.getTarget(MenuOperation.lastRoadCameraTarget); + window.viewer.modules.controls.getPosition(MenuOperation.lastRoadCameraPos); + + const point = new THREE.Vector3(intersect.point.x, intersect.point.y + 2, intersect.point.z); + MenuOperation.Roaming.playerInitPos.copy(point); + + MenuOperation.Roaming.startRoaming(); + + // 第三人称 + window.viewer.modules.controls.maxPolarAngle = Math.PI / 2; + window.viewer.modules.controls.minDistance = 0.8; + window.viewer.modules.controls.maxDistance = 0.8; + window.viewer.modules.controls.distance = 0.8; + + Hooks.useDispatchSignal("sceneGraphChanged"); + } + return null; + } + + pointerlockFn = () => { + if (document.pointerLockElement) { + // console.log("指针被锁定到:", document.pointerLockElement); + } else { + // console.log("指针锁定状态现已解锁"); + MenuOperation.roaming(); + } + } + // 监听鼠标锁定取消 + document.addEventListener("pointerlockchange", pointerlockFn); + + // 监听选取初始位置 + roamPdFn = handlePointerDown.bind(this); + canvas.addEventListener("pointerdown", roamPdFn); + } + + // 退出漫游 + static leaveRoaming() { + MenuOperation.Roaming.exitRoaming(MenuOperation.lastRoadCameraPos,MenuOperation.lastRoadCameraTarget); + + if (roamPdFn) { + window.viewer.renderer.domElement.removeEventListener("pointerdown", roamPdFn); + roamPdFn = null; + } + + if (pointerlockFn) { + document.removeEventListener("pointerlockchange", pointerlockFn); + pointerlockFn = null; + } + } + + // 小地图 + static miniMap() { + if (MenuOperation.MiniMap.isShow) { + operationStore.menuList.miniMap.active = false; + MenuOperation.MiniMap.close(); + } else { + operationStore.menuList.miniMap.active = true; + MenuOperation.MiniMap.open(); + } + } + + // 设置 + static settings(){ + operationStore.menuList.settings.active = !operationStore.menuList.settings.active; + } + + static fullscreen() { + operationStore.menuList.fullscreen.show = false; + operationStore.menuList.exitFullscreen.show = true; + + enterFullscreen(); + } + + static exitFullscreen() { + operationStore.menuList.fullscreen.show = true; + operationStore.menuList.exitFullscreen.show = false; + + exitFullscreen(); + } } \ No newline at end of file diff --git a/Astral3D/packages/editor/src/views/editor/components/extraPane/resource/builtin/Billboard.vue b/Astral3D/packages/editor/src/views/editor/components/extraPane/resource/builtin/Billboard.vue index f22d2c5..c46060b 100644 --- a/Astral3D/packages/editor/src/views/editor/components/extraPane/resource/builtin/Billboard.vue +++ b/Astral3D/packages/editor/src/views/editor/components/extraPane/resource/builtin/Billboard.vue @@ -343,7 +343,7 @@ const allList = { image: "/static/resource/billboard/icon/no-entry.svg", name: cpt("extra.resource.billboard.No entry") }, - {key: "clown", image: "/static/resource/billboard/icon/clown.svg", name: cpt("ErSan")}, + {key: "clown", image: "/static/resource/billboard/icon/clown.svg", name: cpt("")}, ], "text": [ { diff --git a/Astral3D/packages/sdk/.env b/Astral3D/packages/sdk/.env index 61b5189..d8ed026 100644 --- a/Astral3D/packages/sdk/.env +++ b/Astral3D/packages/sdk/.env @@ -2,4 +2,4 @@ VITE_PORT=8091 # 作者 -VITE_GLOB_AUTHOR='ErSan' \ No newline at end of file +VITE_GLOB_AUTHOR='' \ No newline at end of file diff --git a/Astral3D/packages/sdk/.env.production b/Astral3D/packages/sdk/.env.production index a766d3c..e80010f 100644 --- a/Astral3D/packages/sdk/.env.production +++ b/Astral3D/packages/sdk/.env.production @@ -16,4 +16,4 @@ VITE_ENABLE_ANALYZE=false VITE_ENABLE_CONFIG_GENERATE=false # 当前站点URL -VITE_GLOB_ORIGIN=https://editor.astraljs.com/ \ No newline at end of file +VITE_GLOB_ORIGIN= \ No newline at end of file diff --git a/Astral3D/packages/sdk/lib/core/app/App.ts b/Astral3D/packages/sdk/lib/core/app/App.ts index 3c57a5a..104627d 100644 --- a/Astral3D/packages/sdk/lib/core/app/App.ts +++ b/Astral3D/packages/sdk/lib/core/app/App.ts @@ -1,7 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com - * @date 2025/4/22 10:16 + * @date 2026/3/13 * @description 静态类,全局场景管理 */ import * as THREE from 'three'; diff --git a/Astral3D/packages/sdk/lib/core/app/modules/Config.ts b/Astral3D/packages/sdk/lib/core/app/modules/Config.ts index 3ec50ce..a1ffd56 100644 --- a/Astral3D/packages/sdk/lib/core/app/modules/Config.ts +++ b/Astral3D/packages/sdk/lib/core/app/modules/Config.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2025/4/26 13:59 * @description 应用的全局配置,会存储在本地缓存 */ diff --git a/Astral3D/packages/sdk/lib/core/app/modules/Project.ts b/Astral3D/packages/sdk/lib/core/app/modules/Project.ts index cbeaacd..140cb80 100644 --- a/Astral3D/packages/sdk/lib/core/app/modules/Project.ts +++ b/Astral3D/packages/sdk/lib/core/app/modules/Project.ts @@ -1,7 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com - * @date 2025/4/26 13:59 + * @date 2026/3/13 * @description 当前项目相关信息 */ import * as THREE from 'three'; diff --git a/Astral3D/packages/sdk/lib/core/expansion/index.ts b/Astral3D/packages/sdk/lib/core/expansion/index.ts index b3abb14..79134bd 100644 --- a/Astral3D/packages/sdk/lib/core/expansion/index.ts +++ b/Astral3D/packages/sdk/lib/core/expansion/index.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2025/01/08 * @description 从原型链扩充原threejs对象方法 */ diff --git a/Astral3D/packages/sdk/lib/core/geometries/TeapotGeometry.ts b/Astral3D/packages/sdk/lib/core/geometries/TeapotGeometry.ts index 08075db..768721b 100644 --- a/Astral3D/packages/sdk/lib/core/geometries/TeapotGeometry.ts +++ b/Astral3D/packages/sdk/lib/core/geometries/TeapotGeometry.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2024/3/11 10:18 * @description 茶壶几何,修改于 three/examples/jsm/geometries/TeapotGeometry.js */ diff --git a/Astral3D/packages/sdk/lib/core/loader/ObjectLoader.js b/Astral3D/packages/sdk/lib/core/loader/ObjectLoader.js index 96ec6bc..123002c 100644 --- a/Astral3D/packages/sdk/lib/core/loader/ObjectLoader.js +++ b/Astral3D/packages/sdk/lib/core/loader/ObjectLoader.js @@ -1,6 +1,6 @@ /** * THREE JSON 解析器 - * @author ErSan + * @date 2026/3/13 * @version 2.0.0 * @description 来自于THREE.ObjectLoader,修改了部分代码,添加了部分功能 */ diff --git a/Astral3D/packages/sdk/lib/core/loader/Package.Skeleton.ts b/Astral3D/packages/sdk/lib/core/loader/Package.Skeleton.ts index 5531cb8..5a36137 100644 --- a/Astral3D/packages/sdk/lib/core/loader/Package.Skeleton.ts +++ b/Astral3D/packages/sdk/lib/core/loader/Package.Skeleton.ts @@ -1,7 +1,5 @@ /** - * @author MaHaiBing - * @email mlt131220@163.com - * @date 2024/8/3 22:49 + * @date 2026/3/13 * @description 包 骨骼处理 */ import {Skeleton, Bone, Object3D } from "three"; diff --git a/Astral3D/packages/sdk/lib/core/objects/Billboard.ts b/Astral3D/packages/sdk/lib/core/objects/Billboard.ts index 89e24ad..96ba81e 100644 --- a/Astral3D/packages/sdk/lib/core/objects/Billboard.ts +++ b/Astral3D/packages/sdk/lib/core/objects/Billboard.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2025/4/6 12:02 * @description 广告牌对象 */ diff --git a/Astral3D/packages/sdk/lib/core/objects/HtmlPanel.ts b/Astral3D/packages/sdk/lib/core/objects/HtmlPanel.ts index ce2932e..2f149b6 100644 --- a/Astral3D/packages/sdk/lib/core/objects/HtmlPanel.ts +++ b/Astral3D/packages/sdk/lib/core/objects/HtmlPanel.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2025/4/10 0:29 * @description html面板 */ diff --git a/Astral3D/packages/sdk/lib/core/objects/LineMesh.ts b/Astral3D/packages/sdk/lib/core/objects/LineMesh.ts index d2c288c..767ef43 100644 --- a/Astral3D/packages/sdk/lib/core/objects/LineMesh.ts +++ b/Astral3D/packages/sdk/lib/core/objects/LineMesh.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2024/5/21 22:08 * @description 带线框子模型的Mesh对象 */ diff --git a/Astral3D/packages/sdk/lib/core/objects/ParticleEmitter.ts b/Astral3D/packages/sdk/lib/core/objects/ParticleEmitter.ts index fdd2358..e9d1b38 100644 --- a/Astral3D/packages/sdk/lib/core/objects/ParticleEmitter.ts +++ b/Astral3D/packages/sdk/lib/core/objects/ParticleEmitter.ts @@ -1,7 +1,6 @@ /** * 用于代理粒子发射器的空对象,以便于进行场景树显示及控制操作 - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2025-02-14 16:00:00 */ import * as THREE from 'three'; diff --git a/Astral3D/packages/sdk/lib/core/objects/texture/BillboardTexture.ts b/Astral3D/packages/sdk/lib/core/objects/texture/BillboardTexture.ts index a288626..00c96bd 100644 --- a/Astral3D/packages/sdk/lib/core/objects/texture/BillboardTexture.ts +++ b/Astral3D/packages/sdk/lib/core/objects/texture/BillboardTexture.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2025/4/6 13:07 * @description 广告牌map */ diff --git a/Astral3D/packages/sdk/lib/core/objects/weather/Rain.ts b/Astral3D/packages/sdk/lib/core/objects/weather/Rain.ts index e5f7cb9..fbce3e8 100644 --- a/Astral3D/packages/sdk/lib/core/objects/weather/Rain.ts +++ b/Astral3D/packages/sdk/lib/core/objects/weather/Rain.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2025/01/07 * @description 贴相机的下雨效果 */ diff --git a/Astral3D/packages/sdk/lib/core/objects/weather/Snow.ts b/Astral3D/packages/sdk/lib/core/objects/weather/Snow.ts index 1170651..e1d2a66 100644 --- a/Astral3D/packages/sdk/lib/core/objects/weather/Snow.ts +++ b/Astral3D/packages/sdk/lib/core/objects/weather/Snow.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2025/01/08 * @description 贴相机的下雪效果 */ diff --git a/Astral3D/packages/sdk/lib/core/plugin/builtin/builtin.ts b/Astral3D/packages/sdk/lib/core/plugin/builtin/builtin.ts index 3ca949c..4e9b056 100644 --- a/Astral3D/packages/sdk/lib/core/plugin/builtin/builtin.ts +++ b/Astral3D/packages/sdk/lib/core/plugin/builtin/builtin.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2024/9/16 23:18 * @description 在此处注册内置插件 */ diff --git a/Astral3D/packages/sdk/lib/core/plugin/pluginLoader.ts b/Astral3D/packages/sdk/lib/core/plugin/pluginLoader.ts index 47cfe5f..4b49583 100644 --- a/Astral3D/packages/sdk/lib/core/plugin/pluginLoader.ts +++ b/Astral3D/packages/sdk/lib/core/plugin/pluginLoader.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2024/9/16 2:57 * @description 插件加载 */ diff --git a/Astral3D/packages/sdk/lib/core/points/PointCloudReconstructor.ts b/Astral3D/packages/sdk/lib/core/points/PointCloudReconstructor.ts index 8c1f84b..34f07ed 100644 --- a/Astral3D/packages/sdk/lib/core/points/PointCloudReconstructor.ts +++ b/Astral3D/packages/sdk/lib/core/points/PointCloudReconstructor.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2025/07/03 19:38 * @description 点云语义重建 */ diff --git a/Astral3D/packages/sdk/lib/core/preview/Preview.ts b/Astral3D/packages/sdk/lib/core/preview/Preview.ts index 2ab08cf..5a6d2f7 100644 --- a/Astral3D/packages/sdk/lib/core/preview/Preview.ts +++ b/Astral3D/packages/sdk/lib/core/preview/Preview.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2025/7/30 18:49 * @description 资源预览类 */ diff --git a/Astral3D/packages/sdk/lib/core/script/Helper.ts b/Astral3D/packages/sdk/lib/core/script/Helper.ts index 08da4f5..bc028d1 100644 --- a/Astral3D/packages/sdk/lib/core/script/Helper.ts +++ b/Astral3D/packages/sdk/lib/core/script/Helper.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2024/4/24 10:39 * @description 迁移App.ts中的一些方法(也有新增)提供脚本使用,因为脚本在运行态时执行,应该与原环境隔离 */ diff --git a/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/CircleGridShaderMaterial.ts b/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/CircleGridShaderMaterial.ts index ab91cc2..1800058 100644 --- a/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/CircleGridShaderMaterial.ts +++ b/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/CircleGridShaderMaterial.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2024/5/18 13:49 * @description 圆网格着色器材质 * @from https://www.shadertoy.com/view/7dG3zy diff --git a/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/DynamicCheckerboardShaderMaterial.ts b/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/DynamicCheckerboardShaderMaterial.ts index fc72c6e..17e4507 100644 --- a/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/DynamicCheckerboardShaderMaterial.ts +++ b/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/DynamicCheckerboardShaderMaterial.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2024/5/18 13:49 * @description 动态棋盘着色器材质 * @from https://glslsandbox.com/e#109552.0 diff --git a/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/FlickerShaderMaterial.ts b/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/FlickerShaderMaterial.ts index 03bca92..e730a70 100644 --- a/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/FlickerShaderMaterial.ts +++ b/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/FlickerShaderMaterial.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2024/5/18 13:49 * @description 闪烁着色器材质 */ diff --git a/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/SlowSmokeShaderMaterial.ts b/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/SlowSmokeShaderMaterial.ts index d782558..759e6ad 100644 --- a/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/SlowSmokeShaderMaterial.ts +++ b/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/SlowSmokeShaderMaterial.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2024/5/18 13:49 * @description 动态烟着色器材质 * @from https://glslsandbox.com/e#109550.0 diff --git a/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/SnowingShaderMaterial.ts b/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/SnowingShaderMaterial.ts index 038337c..80fa92f 100644 --- a/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/SnowingShaderMaterial.ts +++ b/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/SnowingShaderMaterial.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @description 下雪特效着色器 */ import { ShaderChunk, ShaderMaterial, Vector2, Vector4, TextureLoader, RepeatWrapping, DoubleSide } from "three"; diff --git a/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/StreamerWallShaderMaterial.ts b/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/StreamerWallShaderMaterial.ts index eb2a248..2186965 100644 --- a/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/StreamerWallShaderMaterial.ts +++ b/Astral3D/packages/sdk/lib/core/shaderMaterial/modules/StreamerWallShaderMaterial.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2024/5/18 13:49 * @description 流光墙着色器材质 * @from http://t.csdnimg.cn/zSxq0 diff --git a/Astral3D/packages/sdk/lib/core/tools/Roaming.ts b/Astral3D/packages/sdk/lib/core/tools/Roaming.ts index 466ebcc..605ee86 100644 --- a/Astral3D/packages/sdk/lib/core/tools/Roaming.ts +++ b/Astral3D/packages/sdk/lib/core/tools/Roaming.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2024/08/28 * @description 漫游类,使用BVH检测碰撞,人物模型必须包含动画:Enter,Idle, Walking, WalkingBackward,Jumping */ diff --git a/Astral3D/packages/sdk/lib/core/tools/RoamingStatus.ts b/Astral3D/packages/sdk/lib/core/tools/RoamingStatus.ts index cb324d0..8771944 100644 --- a/Astral3D/packages/sdk/lib/core/tools/RoamingStatus.ts +++ b/Astral3D/packages/sdk/lib/core/tools/RoamingStatus.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2024/8/29 22:10 * @description 漫游的人物动画状态机 */ diff --git a/Astral3D/packages/sdk/lib/core/viewer/modules/CameraManage.ts b/Astral3D/packages/sdk/lib/core/viewer/modules/CameraManage.ts index b0ab0cf..388b357 100644 --- a/Astral3D/packages/sdk/lib/core/viewer/modules/CameraManage.ts +++ b/Astral3D/packages/sdk/lib/core/viewer/modules/CameraManage.ts @@ -3,8 +3,7 @@ import CameraControls from "camera-controls"; import Viewer from "../Viewer" /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2024/10/21 21:16 * @description 场景相机管理器。 TODO: 后续应把viewport.camera也管理进来 */ diff --git a/Astral3D/packages/sdk/lib/core/viewer/modules/Effect.ts b/Astral3D/packages/sdk/lib/core/viewer/modules/Effect.ts index 2be9a22..04ce924 100644 --- a/Astral3D/packages/sdk/lib/core/viewer/modules/Effect.ts +++ b/Astral3D/packages/sdk/lib/core/viewer/modules/Effect.ts @@ -1,6 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com + * @date 2026/3/13 * @date 2024/10/26 18:27 * @description 后处理 */ diff --git a/Astral3D/packages/sdk/lib/core/viewer/modules/TilesManage.ts b/Astral3D/packages/sdk/lib/core/viewer/modules/TilesManage.ts index 84ad943..ce87e75 100644 --- a/Astral3D/packages/sdk/lib/core/viewer/modules/TilesManage.ts +++ b/Astral3D/packages/sdk/lib/core/viewer/modules/TilesManage.ts @@ -1,7 +1,5 @@ /** - * @author ErSan - * @email mlt131220@163.com - * @date 2025/9/23 21:31 + * @date 2026/3/13 * @description 3d tiles加载管理 */ import {TilesRenderer} from "3d-tiles-renderer"; diff --git a/Astral3D/packages/sdk/lib/core/viewer/modules/Weather.ts b/Astral3D/packages/sdk/lib/core/viewer/modules/Weather.ts index 6182d30..6bdf5d2 100644 --- a/Astral3D/packages/sdk/lib/core/viewer/modules/Weather.ts +++ b/Astral3D/packages/sdk/lib/core/viewer/modules/Weather.ts @@ -1,7 +1,5 @@ /* - * @author ErSan - * @email mlt131220@163.com - * @date 2024/12/23 19:27 + * @date 2026/3/13 * @description 天气系统 */ import * as THREE from "three"; diff --git a/Astral3D/packages/sdk/lib/utils/log/Logger.ts b/Astral3D/packages/sdk/lib/utils/log/Logger.ts index 460a927..d6b9992 100644 --- a/Astral3D/packages/sdk/lib/utils/log/Logger.ts +++ b/Astral3D/packages/sdk/lib/utils/log/Logger.ts @@ -1,120 +1,118 @@ -/** - * @author ErSan - * @email mlt131220@163.com - * @date 2025/2/24 下午2:21 - * @description 日志记录器 - */ -import {useAddSignal, useDispatchSignal,useRemoveSignal} from '@/hooks'; - -export interface ILog { - id: number; - message: string; - time: string; - level: string; -} - -let _delLogFn,_clearLogFn,_historyChangedFn; -class Logger { - static Enum = Object.freeze({ - TRACE: "trace", - DEBUG: "debug", - INFO: "info", - WARN: "warn", - ERROR: "error" - }); - - // 是否启用日志 - enabled: boolean = true; - - // 日志信息 - logs: ILog[] = []; - - constructor() { - _delLogFn = this.delLog.bind(this); - useAddSignal("deleteLog",_delLogFn); - _clearLogFn = this.clearLogs.bind(this); - useAddSignal("clearLogs",_clearLogFn); - _historyChangedFn = this.historyChanged.bind(this); - useAddSignal("historyChanged",_historyChangedFn); - } - - log(methodName:string,message:string){ - if(!this.enabled) return; - - const _log = { - id: this.logs.length, - message, - level: methodName, - time: new Date().toLocaleString() - } - - this.logs.unshift(_log); - - useDispatchSignal("addLog", _log, this.logs); - } - - trace(message:string) { this.log(Logger.Enum.TRACE, message); } - debug(message:string) { this.log(Logger.Enum.DEBUG, message); } - info(message:string) { this.log(Logger.Enum.INFO, message); } - warn(message:string) { this.log(Logger.Enum.WARN, message); } - error(message:string) { this.log(Logger.Enum.ERROR, message); } - - /** - * 删除日志 - * @param _log - */ - delLog(_log: ILog) { - this.logs = this.logs.filter(log => log.id!== _log.id); - } - - /** - * 清空日志 - */ - clearLogs() { - this.logs = []; - } - - /** - * 历史记录变化回调 - * @param cmd - */ - historyChanged(cmd){ - if(!cmd?.name) return; - - let msg = cmd.name; - const postposition = ['AddObjectCommand','RemoveObjectCommand','MoveObjectCommand']; - if(postposition.includes(cmd.type)){ - msg = `${msg}: ${cmd.object.name} `; - }else if(cmd.object){ - msg = `${cmd.object.name} ${msg.toLowerCase()}`; - } - - if(cmd.newValue !== undefined && cmd.oldValue !== undefined){ - let newValue = cmd.newValue; - let oldValue = cmd.oldValue; - if(typeof newValue === 'object'){ - newValue = JSON.stringify(newValue); - } - if(typeof oldValue === 'object'){ - oldValue = JSON.stringify(oldValue); - } - - msg = `${msg}: ${oldValue} ⇒ ${newValue}`; - } - - this.info(msg); - } - - dispose() { - useRemoveSignal("deleteLog",_delLogFn) - _delLogFn = null; - useRemoveSignal("clearLogs",_clearLogFn) - _clearLogFn = null; - useRemoveSignal("historyChanged",_historyChangedFn) - _historyChangedFn = null; - } -} - -export const logger = new Logger(); - +/** + * @date 2026/3/13 + * @description 日志记录器 + */ +import {useAddSignal, useDispatchSignal,useRemoveSignal} from '@/hooks'; + +export interface ILog { + id: number; + message: string; + time: string; + level: string; +} + +let _delLogFn,_clearLogFn,_historyChangedFn; +class Logger { + static Enum = Object.freeze({ + TRACE: "trace", + DEBUG: "debug", + INFO: "info", + WARN: "warn", + ERROR: "error" + }); + + // 是否启用日志 + enabled: boolean = true; + + // 日志信息 + logs: ILog[] = []; + + constructor() { + _delLogFn = this.delLog.bind(this); + useAddSignal("deleteLog",_delLogFn); + _clearLogFn = this.clearLogs.bind(this); + useAddSignal("clearLogs",_clearLogFn); + _historyChangedFn = this.historyChanged.bind(this); + useAddSignal("historyChanged",_historyChangedFn); + } + + log(methodName:string,message:string){ + if(!this.enabled) return; + + const _log = { + id: this.logs.length, + message, + level: methodName, + time: new Date().toLocaleString() + } + + this.logs.unshift(_log); + + useDispatchSignal("addLog", _log, this.logs); + } + + trace(message:string) { this.log(Logger.Enum.TRACE, message); } + debug(message:string) { this.log(Logger.Enum.DEBUG, message); } + info(message:string) { this.log(Logger.Enum.INFO, message); } + warn(message:string) { this.log(Logger.Enum.WARN, message); } + error(message:string) { this.log(Logger.Enum.ERROR, message); } + + /** + * 删除日志 + * @param _log + */ + delLog(_log: ILog) { + this.logs = this.logs.filter(log => log.id!== _log.id); + } + + /** + * 清空日志 + */ + clearLogs() { + this.logs = []; + } + + /** + * 历史记录变化回调 + * @param cmd + */ + historyChanged(cmd){ + if(!cmd?.name) return; + + let msg = cmd.name; + const postposition = ['AddObjectCommand','RemoveObjectCommand','MoveObjectCommand']; + if(postposition.includes(cmd.type)){ + msg = `${msg}: ${cmd.object.name} `; + }else if(cmd.object){ + msg = `${cmd.object.name} ${msg.toLowerCase()}`; + } + + if(cmd.newValue !== undefined && cmd.oldValue !== undefined){ + let newValue = cmd.newValue; + let oldValue = cmd.oldValue; + if(typeof newValue === 'object'){ + newValue = JSON.stringify(newValue); + } + if(typeof oldValue === 'object'){ + oldValue = JSON.stringify(oldValue); + } + + msg = `${msg}: ${oldValue} ⇒ ${newValue}`; + } + + this.info(msg); + } + + dispose() { + useRemoveSignal("deleteLog",_delLogFn) + _delLogFn = null; + useRemoveSignal("clearLogs",_clearLogFn) + _clearLogFn = null; + useRemoveSignal("historyChanged",_historyChangedFn) + _historyChangedFn = null; + } +} + +export const logger = new Logger(); + export default logger; \ No newline at end of file diff --git a/README.md b/README.md index a05837f..6cb6d06 100644 --- a/README.md +++ b/README.md @@ -1,170 +1,169 @@ -# Astral3D 项目说明 - -## 项目简介 - -Astral3D 是一个基于 Vue3 + Three.js 的现代 Web 3D 编辑器,同时包含配套的 Java 后端服务。项目旨在提供一站式 3D 场景创建、管理和展示解决方案。 - -**在线演示**: [Astral 3D Editor](https://editor.astraljs.com) - ---- - -## 项目结构 - -``` -Astral3D-Projects/ -├── Astral3D/ # 前端编辑器项目 (Vue3 + Three.js) -│ ├── packages/ # 子包 -│ ├── common/ # 公共模块 -│ └── node_modules/ # 依赖 -│ -├── astral-service/ # 后端服务项目 (Java + SpringBoot) -│ ├── astral-common/ # 公共模块 -│ ├── astral-core/ # 核心配置 -│ ├── astral-business/ # 业务模块 -│ ├── astral-system/ # 系统模块 -│ ├── astral-web/ # Web 层 -│ └── static/ # 静态资源 -│ -└── docs/ # 文档目录 -``` - ---- - -## 技术栈 - -### 前端 (Astral3D) - -| 技术 | 版本 | 说明 | -|------|------|------| -| Vue | 3.5.22 | 渐进式前端框架 | -| Three.js | r176 | 3D 渲染引擎 | -| Cesium | 1.107.0 | 地理信息系统 | -| Naive UI | 2.43.1 | UI 组件库 | -| UnoCSS | 0.46.5 | 原子化 CSS | - -### 后端 (AstralService) - -| 技术 | 版本 | 说明 | -|------|------|------| -| Java | 8 | 编程语言 | -| Spring Boot | 2.7.18 | Web 框架 | -| MyBatis Plus | - | ORM 框架 | -| MySQL | - | 数据库 | -| WebSocket | - | 实时通信 | - ---- - -## 核心功能 - -### 前端功能 - -- **多格式模型支持**: 30+ 模型格式(GLTF/OBJ/FBX/GLB/RVT/IFC 等) -- **BIM 模型轻量化**: RVT/IFC 文件浏览器端展示 -- **CAD 图纸解析**: DWG/DXF 文件解析和展示 -- **场景管理**: 分包存储与动态加载 -- **动画编辑器**: 内置动画制作工具 -- **插件系统**: 扩展能力支持 -- **脚本运行时**: 脚本化业务逻辑 -- **粒子系统**: 视觉效果增强 -- **天气系统**: 场景环境模拟 -- **云存储集成**: 又拍云 USS 支持 -- **资源中心**: 统一资源管理 - -### 后端功能 - -- **用户认证**: 用户注册登录 -- **场景管理**: 场景 CRUD 操作 -- **资产管理**: 资源上传、存储、加载 -- **文件转换**: CAD DWG 转 DXF -- **WebSocket**: 实时通信支持 - ---- - -## 快速开始 - -### 前端开发 - -```bash -# 进入前端项目 -cd Astral3D - -# 使用 nvm 切换 Node 版本 -nvm use 23.11.0 - -# 安装依赖 -pnpm install - -# 构建 SDK -pnpm run sdk:build - -# 启动开发服务器 -pnpm run editor:dev -``` - -### 后端服务 - -```bash -# 进入后端项目 -cd astral-service - -# 配置数据库 -# 修改 astral-web/src/main/resources/application-dev.yml - -# 方式一:IDEA 直接运行 -# 运行 AstralWebApplication 类 - -# 方式二:Maven 运行 -mvn spring-boot:run - -# 方式三:打包运行 -mvn clean package -cd astral-web/target -java -jar astral-web-exec.jar -``` - ---- - -## 数据库配置 - -1. 创建 MySQL 数据库 -2. 导入表结构:`static/sql/astral_3d.sql` -3. 修改配置文件中的数据库连接信息 - ---- - -## 文件存储配置 - -支持两种存储方式: - -- **本地存储 (local)**: 保存在项目 static 文件夹 -- **又拍云存储 (upyun)**: 云端存储 - ---- - -## 文档目录 - -| 文档 | 说明 | -|------|------| -| [GIT_TUTORIAL.md](../GIT_TUTORIAL.md) | Git 操作教程 | - ---- - -## 许可证 - -本项目基于 Apache 2.0 许可证开源,详细内容请参阅 [LICENSE](../Astral3D/LICENSE) 文件。 - ---- - -## 相关链接 - -- [在线演示](https://editor.astraljs.com) -- [文档中心](http://editor-doc.astraljs.com/) -- [后端仓库](https://github.com/yx8663/astral-service) -- [前端仓库](https://github.com/mlt131220/Astral3D) - ---- - -## 交流社区 - -- QQ 交流群:1040320579 -- 微信:联系开发者(仅限商务) +# Astral3D 项目说明 + +## 项目简介 + +Astral3D 是一个基于 Vue3 + Three.js 的现代 Web 3D 编辑器,同时包含配套的 Java 后端服务。项目旨在提供一站式 3D 场景创建、管理和展示解决方案。 + +**在线演示**: [Astral 3D Editor](https://editor.astraljs.com) + +--- + +## 项目结构 + +``` +Astral3D-Projects/ +├── Astral3D/ # 前端编辑器项目 (Vue3 + Three.js) +│ ├── packages/ # 子包 +│ ├── common/ # 公共模块 +│ └── node_modules/ # 依赖 +│ +├── astral-service/ # 后端服务项目 (Java + SpringBoot) +│ ├── astral-common/ # 公共模块 +│ ├── astral-core/ # 核心配置 +│ ├── astral-business/ # 业务模块 +│ ├── astral-system/ # 系统模块 +│ ├── astral-web/ # Web 层 +│ └── static/ # 静态资源 +│ +└── docs/ # 文档目录 +``` + +--- + +## 技术栈 + +### 前端 (Astral3D) + +| 技术 | 版本 | 说明 | +|------|------|------| +| Vue | 3.5.22 | 渐进式前端框架 | +| Three.js | r176 | 3D 渲染引擎 | +| Cesium | 1.107.0 | 地理信息系统 | +| Naive UI | 2.43.1 | UI 组件库 | +| UnoCSS | 0.46.5 | 原子化 CSS | + +### 后端 (AstralService) + +| 技术 | 版本 | 说明 | +|------|------|------| +| Java | 8 | 编程语言 | +| Spring Boot | 2.7.18 | Web 框架 | +| MyBatis Plus | - | ORM 框架 | +| MySQL | - | 数据库 | +| WebSocket | - | 实时通信 | + +--- + +## 核心功能 + +### 前端功能 + +- **多格式模型支持**: 30+ 模型格式(GLTF/OBJ/FBX/GLB/RVT/IFC 等) +- **BIM 模型轻量化**: RVT/IFC 文件浏览器端展示 +- **CAD 图纸解析**: DWG/DXF 文件解析和展示 +- **场景管理**: 分包存储与动态加载 +- **动画编辑器**: 内置动画制作工具 +- **插件系统**: 扩展能力支持 +- **脚本运行时**: 脚本化业务逻辑 +- **粒子系统**: 视觉效果增强 +- **天气系统**: 场景环境模拟 +- **云存储集成**: 又拍云 USS 支持 +- **资源中心**: 统一资源管理 + +### 后端功能 + +- **用户认证**: 用户注册登录 +- **场景管理**: 场景 CRUD 操作 +- **资产管理**: 资源上传、存储、加载 +- **文件转换**: CAD DWG 转 DXF +- **WebSocket**: 实时通信支持 + +--- + +## 快速开始 + +### 前端开发 + +```bash +# 进入前端项目 +cd Astral3D + +# 使用 nvm 切换 Node 版本 +nvm use 23.11.0 + +# 安装依赖 +pnpm install + +# 构建 SDK +pnpm run sdk:build + +# 启动开发服务器 +pnpm run editor:dev +``` + +### 后端服务 + +```bash +# 进入后端项目 +cd astral-service + +# 配置数据库 +# 修改 astral-web/src/main/resources/application-dev.yml + +# 方式一:IDEA 直接运行 +# 运行 AstralWebApplication 类 + +# 方式二:Maven 运行 +mvn spring-boot:run + +# 方式三:打包运行 +mvn clean package +cd astral-web/target +java -jar astral-web-exec.jar +``` + +--- + +## 数据库配置 + +1. 创建 MySQL 数据库 +2. 导入表结构:`static/sql/astral_3d.sql` +3. 修改配置文件中的数据库连接信息 + +--- + +## 文件存储配置 + +支持两种存储方式: + +- **本地存储 (local)**: 保存在项目 static 文件夹 +- **又拍云存储 (upyun)**: 云端存储 + +--- + +## 文档目录 + +| 文档 | 说明 | +|------|------| +| [二开改造方案.md](docs/二开改造方案.md) | 二次开发视觉改造方案(新品牌 Logo、配色、UI 风格) | +| [digital-atelier-philosophy.md](docs/digital-atelier-philosophy.md) | 设计哲学:Digital Atelier 理念 | +| [ui-migration-todo.md](docs/ui-migration-todo.md) | UI 迁移待办:NaiveUI → Shadcn UI | +| [css-migration-spec.md](docs/css-migration-spec.md) | CSS 样式迁移规范 | +| [GIT_TUTORIAL.md](docs/GIT_TUTORIAL.md) | Git 操作教程 | + +--- + +## 许可证 + +本项目基于 Apache 2.0 许可证开源,详细内容请参阅 [LICENSE](../Astral3D/LICENSE) 文件。 + +--- + +## 相关链接 + +- [在线演示](https://editor.astraljs.com) +- [文档中心](http://editor-doc.astraljs.com/) +- [代码仓库](http://code-server:3000/lyf/Astral3D.git) + +--- + diff --git a/astral-service/README.md b/astral-service/README.md index 1338a3c..5928892 100644 --- a/astral-service/README.md +++ b/astral-service/README.md @@ -1,50 +1,77 @@ -# AstralService - -🌍 -*[简体中文](README.md)* - -基于`Java:8`和`SpringBoot:2.7.18`的 [Astral3D](https://github.com/mlt131220/Astral3D) 项目后端代码. - -![Static Badge](https://img.shields.io/badge/Java-8-green) -![Static Badge](https://img.shields.io/badge/SpringBoot-2.7.18-8732D7) -![Static Badge](https://img.shields.io/badge/license-MIT-blue) - -## 快速开始 -```shell - git clone https://github.com/yx8663/astral-service.git -``` -### 配置 -* 数据库使用 MySQL,表结构数据文件位于: `static/sql/astral_3d.sql`; -* 配置文件路径: `astral-web/src/main/resources/application-dev.yml`; -* 修改配置文件下 `spring.datasource` 项为自己的数据库连接; -* 修改配置文件下 `astral.uploadType` 项为自己使用的文件存储方式:`本地-local 又拍云-upyun`; -* 修改配置文件下 `astral.uploadDir` 项为自己使用的文件存储方式对应的存储目录: - * `本地-local`存储推荐修改为此项目下的`static`文件夹; - * `又拍云-upyun`存储按需配置存储路径; -* 如果使用`又拍云-upyun`存储,还需修改配置文件下 `upyun`项配置: - * `bucket` 为对应存储桶名; - * `operator` 为在又拍云为该桶配置的操作员账号; - * `password` 为对应操作员密码; - * `domain` 为该存储使用的加速域名(为保证又拍云信息不在前端泄露,故不使用在`HTTP Header`/`HTTP Body`签名认证的方式鉴权,而是配置对应存储的加速域名,将前端请求重定向来通过该加速域名获取资源); -* 修改配置文件下 `dev` 项配置: - * `currentAbPath` 为本项目绝对路径地址; - * `cadDwgConverterAbPath` 为本地CAD Dwg转换器执行程序文件夹绝对路径,转换程序使用 libreDWG(已包含在项目static/lib/libredwg文件夹); - * `temporaryFolder` 为临时文件夹地址,推荐配置为本项目地址下的`static/tmp`文件夹; - -## 运行 - -### 方式一 -> IDEA中直接运行@SpringBootApplication注解的类的main方法:
-> `astral-web/src/main/java/com.astral.web/AstralWebApplication/AstralWebApplication` - -### 方式二 -> cmd中执行命令 `mvn spring-boot:run` - -### 方式三(打包) -> cmd中执行命令: -> * 生成jar包: mvn clean package -> * 进入生成的jar包目录:cd astral-web/target -> * 运行项目:java -jar astral-web-exec.jar - -## Star History -[![Star History Chart](https://api.star-history.com/svg?repos=yx8663/astral-service&type=Date)](https://star-history.com/#yx8663/astral-service&Date) \ No newline at end of file +# AstralService + +🌍 *[简体中文](README.md)* | English + +Backend service for NeonVision 3D Editor. + +Based on `Java 8` and `SpringBoot 2.7.18`. + +![Static Badge](https://img.shields.io/badge/Java-8-green) +![Static Badge](https://img.shields.io/badge/SpringBoot-2.7.18-8732D7) +![Static Badge](https://img.shields.io/badge/license-MIT-blue) + +## Prerequisites + +- Java 8+ +- Maven 3.6+ +- MySQL 5.7+ + +## Quick Start + +```shell +git clone http://code-server:3000/lyf/Astral3D.git +cd astral-service +``` + +### Database Setup + +1. Create database and import schema: + ```sql + mysql -u root -p < static/sql/astral_3d.sql + ``` + +2. Configure database connection in: + ``` + astral-web/src/main/resources/application-dev.yml + ``` + +### Configuration + +Edit `astral-web/src/main/resources/application-dev.yml`: + +| Property | Description | +|----------|-------------| +| `spring.datasource` | Your MySQL connection settings | +| `astral.uploadType` | Storage type: `local` or `upyun` | +| `astral.uploadDir` | Storage directory path | +| `upyun.bucket` | UpYun bucket name (if using UpYun) | +| `upyun.operator` | UpYun operator account | +| `upyun.password` | UpYun operator password | +| `upyun.domain` | UpYun CDN domain | +| `dev.currentAbPath` | Project absolute path | +| `dev.cadDwgConverterAbPath` | CAD DWG converter path (libreDWG) | +| `dev.temporaryFolder` | Temporary folder path | + +### Running + +**Option 1: IDEA** +Run the main class: +``` +astral-web/src/main/java/com.astral.web/AstralWebApplication/AstralWebApplication +``` + +**Option 2: Maven** +```bash +mvn spring-boot:run +``` + +**Option 3: JAR Package** +```bash +mvn clean package +cd astral-web/target +java -jar astral-web-exec.jar +``` + +## License + +Open source under MIT License.