web打包更新
This commit is contained in:
parent
ab6d543dc0
commit
bab5a9bb27
28
imgui.ini
28
imgui.ini
@ -31,19 +31,19 @@ DockId=0x0000000D,0
|
||||
|
||||
[Window][场景树]
|
||||
Pos=0,20
|
||||
Size=339,1008
|
||||
Size=339,996
|
||||
Collapsed=0
|
||||
DockId=0x00000007,0
|
||||
|
||||
[Window][属性面板]
|
||||
Pos=1506,20
|
||||
Size=346,1008
|
||||
Pos=1502,20
|
||||
Size=346,996
|
||||
Collapsed=0
|
||||
DockId=0x00000002,0
|
||||
|
||||
[Window][控制台]
|
||||
Pos=341,629
|
||||
Size=1163,399
|
||||
Pos=341,617
|
||||
Size=1159,399
|
||||
Collapsed=0
|
||||
DockId=0x00000006,1
|
||||
|
||||
@ -59,7 +59,7 @@ Collapsed=0
|
||||
|
||||
[Window][WindowOverViewport_11111111]
|
||||
Pos=0,20
|
||||
Size=1852,1008
|
||||
Size=1848,996
|
||||
Collapsed=0
|
||||
|
||||
[Window][测试窗口1]
|
||||
@ -78,17 +78,17 @@ Size=93,65
|
||||
Collapsed=0
|
||||
|
||||
[Window][新建项目]
|
||||
Pos=824,402
|
||||
Pos=724,358
|
||||
Size=400,300
|
||||
Collapsed=0
|
||||
|
||||
[Window][选择路径]
|
||||
Pos=626,264
|
||||
Pos=624,258
|
||||
Size=600,500
|
||||
Collapsed=0
|
||||
|
||||
[Window][打开项目]
|
||||
Pos=676,314
|
||||
Pos=674,308
|
||||
Size=500,400
|
||||
Collapsed=0
|
||||
|
||||
@ -98,8 +98,8 @@ Size=600,500
|
||||
Collapsed=0
|
||||
|
||||
[Window][资源管理器]
|
||||
Pos=341,629
|
||||
Size=1163,399
|
||||
Pos=341,617
|
||||
Size=1159,399
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
@ -226,13 +226,13 @@ Size=460,260
|
||||
Collapsed=0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,20 Size=1852,1008 Split=X
|
||||
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,20 Size=1848,996 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x08BD597D SizeRef=2212,1012 Split=X
|
||||
DockNode ID=0x00000007 Parent=0x00000001 SizeRef=339,1084 Selected=0xE0015051
|
||||
DockNode ID=0x00000008 Parent=0x00000001 SizeRef=1871,1084 Split=Y
|
||||
DockNode ID=0x00000005 Parent=0x00000008 SizeRef=2048,683 Split=Y
|
||||
DockNode ID=0x00000005 Parent=0x00000008 SizeRef=2048,595 Split=Y
|
||||
DockNode ID=0x0000000D Parent=0x00000005 SizeRef=1318,383 HiddenTabBar=1 Selected=0x43A39006
|
||||
DockNode ID=0x0000000E Parent=0x00000005 SizeRef=1318,363 CentralNode=1 Selected=0xE0015051
|
||||
DockNode ID=0x00000006 Parent=0x00000008 SizeRef=2048,399 Selected=0x3A2E05C3
|
||||
DockNode ID=0x00000006 Parent=0x00000008 SizeRef=2048,399 Selected=0x5428E753
|
||||
DockNode ID=0x00000002 Parent=0x08BD597D SizeRef=346,1012 Selected=0x5DB6FF37
|
||||
|
||||
|
||||
@ -32,6 +32,7 @@ from project.scene_description import (
|
||||
normalize_scene_description,
|
||||
save_json,
|
||||
)
|
||||
from project.webgl_packager import WebGLPackager
|
||||
|
||||
class ProjectManager:
|
||||
|
||||
@ -41,6 +42,7 @@ class ProjectManager:
|
||||
self.project_config = None
|
||||
self.current_scene_guid = None
|
||||
self._asset_database = None
|
||||
self.last_webgl_export_report = None
|
||||
|
||||
print("✓ 项目管理系统初始化完成")
|
||||
|
||||
@ -2091,6 +2093,55 @@ class ProjectManager:
|
||||
)
|
||||
return manifest
|
||||
|
||||
def buildWebGLPackage(self, output_dir):
|
||||
"""将当前项目导出为 WebGL 静态站点目录。"""
|
||||
try:
|
||||
if not self.current_project_path:
|
||||
print("错误: 请先创建或打开一个项目!")
|
||||
return False
|
||||
|
||||
if not output_dir:
|
||||
print("错误: 请指定 WebGL 打包输出目录!")
|
||||
return False
|
||||
|
||||
project_path = normalize_path(self.current_project_path)
|
||||
ensure_project_directories(ProjectLayout(project_path))
|
||||
|
||||
if hasattr(self.world, "selection") and self.world.selection:
|
||||
self.world.selection.clearSelection()
|
||||
print("已取消场景中的物体选中状态")
|
||||
|
||||
if not self.saveProject():
|
||||
print("错误: WebGL 打包前保存场景失败!")
|
||||
return False
|
||||
|
||||
output_dir = normalize_path(output_dir)
|
||||
|
||||
packager = WebGLPackager(self.world)
|
||||
report = packager.package(project_path, output_dir)
|
||||
self.last_webgl_export_report = report
|
||||
|
||||
status = str(report.get("status", "failed") or "failed")
|
||||
report_path = os.path.join(
|
||||
str(report.get("output_dir", "") or ""),
|
||||
"reports",
|
||||
"export_report.json",
|
||||
)
|
||||
|
||||
if status in ("success", "partial"):
|
||||
print(f"WebGL打包完成: {status}")
|
||||
print(f"输出目录: {report.get('output_dir', '')}")
|
||||
print(f"报告路径: {report_path}")
|
||||
return True
|
||||
|
||||
print("WebGL打包失败")
|
||||
if report_path:
|
||||
print(f"报告路径: {report_path}")
|
||||
return False
|
||||
except Exception as exc:
|
||||
print(f"WebGL打包过程出错: {exc}")
|
||||
return False
|
||||
|
||||
def buildPackage(self, build_dir):
|
||||
"""将当前项目打包为最终运行程序。"""
|
||||
try:
|
||||
@ -2707,4 +2758,3 @@ class ProjectManager:
|
||||
"""更新窗口标题(保留方法以兼容旧代码)"""
|
||||
# 这个方法现在不需要做任何事情,因为我们不再处理UI
|
||||
pass
|
||||
|
||||
|
||||
2405
project/webgl_packager.py
Normal file
2405
project/webgl_packager.py
Normal file
File diff suppressed because it is too large
Load Diff
16
templates/webgl/index.html
Normal file
16
templates/webgl/index.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>EG WebGL Scene</title>
|
||||
<link rel="stylesheet" href="./style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<canvas id="scene-canvas"></canvas>
|
||||
<div id="status" class="status">Loading scene...</div>
|
||||
</div>
|
||||
<script type="module" src="./js/viewer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
61
templates/webgl/style.css
Normal file
61
templates/webgl/style.css
Normal file
@ -0,0 +1,61 @@
|
||||
:root {
|
||||
--bg: #0f1115;
|
||||
--panel: rgba(16, 20, 28, 0.88);
|
||||
--text: #d6dde9;
|
||||
--ok: #77d0b9;
|
||||
--warn: #e2b272;
|
||||
--err: #f27878;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
#app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background: radial-gradient(circle at 20% 20%, #1b2230 0%, var(--bg) 50%, #090b10 100%);
|
||||
color: var(--text);
|
||||
font-family: "Segoe UI", "SF Pro Text", "PingFang SC", sans-serif;
|
||||
}
|
||||
|
||||
#scene-canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.status {
|
||||
position: fixed;
|
||||
left: 16px;
|
||||
bottom: 16px;
|
||||
max-width: min(640px, calc(100vw - 32px));
|
||||
padding: 10px 12px;
|
||||
background: var(--panel);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
border-radius: 8px;
|
||||
backdrop-filter: blur(4px);
|
||||
line-height: 1.45;
|
||||
white-space: pre-wrap;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.status.ok {
|
||||
border-color: rgba(119, 208, 185, 0.5);
|
||||
color: var(--ok);
|
||||
}
|
||||
|
||||
.status.warn {
|
||||
border-color: rgba(226, 178, 114, 0.55);
|
||||
color: var(--warn);
|
||||
}
|
||||
|
||||
.status.error {
|
||||
border-color: rgba(242, 120, 120, 0.65);
|
||||
color: var(--err);
|
||||
}
|
||||
3923
templates/webgl/vendor/GLTFLoader.js
vendored
Normal file
3923
templates/webgl/vendor/GLTFLoader.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1229
templates/webgl/vendor/OrbitControls.js
vendored
Normal file
1229
templates/webgl/vendor/OrbitControls.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8
templates/webgl/vendor/three.module.min.js
vendored
Normal file
8
templates/webgl/vendor/three.module.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2085
templates/webgl/viewer.js
Normal file
2085
templates/webgl/viewer.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -309,6 +309,95 @@ class AppActions:
|
||||
self.add_info_message("打开打包项目对话框")
|
||||
self.show_build_project_dialog = True
|
||||
|
||||
def _on_build_webgl_package(self):
|
||||
"""处理“打包为 WebGL”菜单项。"""
|
||||
project_manager = getattr(self, "project_manager", None)
|
||||
if not project_manager:
|
||||
self.add_error_message("项目管理器未初始化")
|
||||
return
|
||||
|
||||
current_project_path = getattr(project_manager, "current_project_path", None)
|
||||
if not current_project_path:
|
||||
self.add_warning_message("请先创建或打开项目,再进行WebGL打包")
|
||||
return
|
||||
|
||||
if not self._save_project_impl():
|
||||
self.add_error_message("打包前自动保存失败,已取消WebGL打包")
|
||||
return
|
||||
|
||||
initial_dir = os.path.dirname(current_project_path) if current_project_path else os.getcwd()
|
||||
selected_dir = self._select_directory_system_dialog("选择 WebGL 打包输出目录", initial_dir)
|
||||
if not selected_dir:
|
||||
dialog_error = getattr(self, "_last_directory_dialog_error", "")
|
||||
if dialog_error:
|
||||
self.add_warning_message(f"系统目录选择器不可用: {dialog_error}")
|
||||
self.path_browser_mode = "webgl_build"
|
||||
self.path_browser_current_path = initial_dir if os.path.isdir(initial_dir) else os.getcwd()
|
||||
self.path_browser_selected_path = self.path_browser_current_path
|
||||
self.show_path_browser = True
|
||||
self._pending_webgl_package = True
|
||||
self._refresh_path_browser()
|
||||
self.add_info_message("已切换到内置路径浏览器,请选择输出目录并点击确定")
|
||||
else:
|
||||
self.add_info_message("已取消WebGL打包")
|
||||
return
|
||||
|
||||
self._execute_webgl_package(selected_dir)
|
||||
|
||||
def _execute_webgl_package(self, selected_dir):
|
||||
"""执行 WebGL 打包并反馈结果。"""
|
||||
ok = self.project_manager.buildWebGLPackage(selected_dir)
|
||||
report = getattr(self.project_manager, "last_webgl_export_report", None) or {}
|
||||
status = str(report.get("status", "failed") or "failed")
|
||||
out_dir = str(report.get("output_dir", "") or "")
|
||||
report_path = os.path.join(out_dir, "reports", "export_report.json") if out_dir else ""
|
||||
|
||||
if ok:
|
||||
missing_count = len(report.get("missing_assets", []) or [])
|
||||
unsupported_count = len(report.get("unsupported_assets", []) or [])
|
||||
if status == "partial":
|
||||
self.add_warning_message(
|
||||
f"WebGL打包部分成功: 缺失资源 {missing_count},不支持资源 {unsupported_count}"
|
||||
)
|
||||
else:
|
||||
self.add_success_message("WebGL打包成功")
|
||||
|
||||
if out_dir:
|
||||
self.add_info_message(f"输出目录: {out_dir}")
|
||||
if report_path:
|
||||
self.add_info_message(f"报告: {report_path}")
|
||||
return True
|
||||
|
||||
self.add_error_message("WebGL打包失败")
|
||||
if report_path:
|
||||
self.add_warning_message(f"请检查报告: {report_path}")
|
||||
return False
|
||||
|
||||
def _select_directory_system_dialog(self, title, initial_dir=""):
|
||||
"""打开系统目录选择器并返回目录路径。"""
|
||||
self._last_directory_dialog_error = ""
|
||||
try:
|
||||
import tkinter as tk
|
||||
from tkinter import filedialog
|
||||
|
||||
if not initial_dir or not os.path.isdir(initial_dir):
|
||||
initial_dir = os.getcwd()
|
||||
|
||||
root = tk.Tk()
|
||||
root.withdraw()
|
||||
root.attributes("-topmost", True)
|
||||
selected_dir = filedialog.askdirectory(
|
||||
title=title,
|
||||
initialdir=initial_dir,
|
||||
mustexist=False,
|
||||
parent=root,
|
||||
)
|
||||
root.destroy()
|
||||
return os.path.normpath(selected_dir) if selected_dir else ""
|
||||
except Exception as exc:
|
||||
self._last_directory_dialog_error = str(exc)
|
||||
return ""
|
||||
|
||||
def _build_project_impl(self, output_path):
|
||||
"""执行项目打包。"""
|
||||
if not hasattr(self, "project_manager") or not self.project_manager:
|
||||
|
||||
@ -627,6 +627,13 @@ class DialogPanels:
|
||||
elif self.path_browser_mode == "build_project":
|
||||
self.build_output_path = self.path_browser_current_path
|
||||
self.add_info_message(f"已选择打包位置: {self.build_output_path}")
|
||||
elif self.path_browser_mode == "webgl_build":
|
||||
output_dir = self.path_browser_current_path
|
||||
self.add_info_message(f"已选择WebGL输出目录: {output_dir}")
|
||||
if getattr(self, "_pending_webgl_package", False):
|
||||
self._pending_webgl_package = False
|
||||
if hasattr(self, "_execute_webgl_package"):
|
||||
self._execute_webgl_package(output_dir)
|
||||
elif self.path_browser_mode == "import_model":
|
||||
# 导入模型模式:使用选择的文件路径
|
||||
self.import_file_path = self.path_browser_selected_path
|
||||
|
||||
@ -189,6 +189,8 @@ class EditorPanelsTopMixin:
|
||||
self.app._on_save_as_project()
|
||||
if imgui.menu_item("打包项目", "", False, True)[1]:
|
||||
self.app._on_build_project()
|
||||
if imgui.menu_item("打包为 WebGL", "", False, True)[1]:
|
||||
self.app._on_build_webgl_package()
|
||||
imgui.separator()
|
||||
if imgui.menu_item("退出", "Alt+F4", False, True)[1]:
|
||||
self.app._on_exit()
|
||||
@ -544,4 +546,3 @@ class EditorPanelsTopMixin:
|
||||
)
|
||||
|
||||
imgui.pop_style_var(2)
|
||||
|
||||
|
||||
@ -540,6 +540,12 @@ class PanelDelegates:
|
||||
def _on_build_project(self, *args, **kwargs):
|
||||
return self.app_actions._on_build_project(*args, **kwargs)
|
||||
|
||||
def _on_build_webgl_package(self, *args, **kwargs):
|
||||
return self.app_actions._on_build_webgl_package(*args, **kwargs)
|
||||
|
||||
def _execute_webgl_package(self, *args, **kwargs):
|
||||
return self.app_actions._execute_webgl_package(*args, **kwargs)
|
||||
|
||||
def _build_project_impl(self, *args, **kwargs):
|
||||
return self.app_actions._build_project_impl(*args, **kwargs)
|
||||
|
||||
@ -954,4 +960,3 @@ class PanelDelegates:
|
||||
|
||||
def loadScript(self, script_path):
|
||||
return self.runtime_actions.loadScript(script_path)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user