Compare commits
69 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3d758a3e3 | ||
|
|
79b9aa44dc | ||
|
|
fe373c0e5d | ||
|
|
19235ca43a | ||
|
|
405e8a9ad3 | ||
|
|
eeb5dd193b | ||
|
|
0fa75b7937 | ||
|
|
69d83c6ab5 | ||
|
|
2766fb9faa | ||
|
|
f26b14cb40 | ||
|
|
35a75bba29 | ||
|
|
a00b276233 | ||
|
|
b7abab4f93 | ||
|
|
26b8e0d93f | ||
|
|
ae0df4ca3b | ||
|
|
62fe0628d8 | ||
| 73e6e64a2e | |||
| 3b1b547ed8 | |||
| 8b6b8daf9b | |||
| 33e62bd1e4 | |||
| f07a394d9f | |||
| a167767890 | |||
| ced0eedc7a | |||
| 887737f139 | |||
| 2124de7de5 | |||
| cbbbf065ac | |||
| 058cfe454d | |||
| e42d3cfa30 | |||
| 403c4d34f8 | |||
| 385103e252 | |||
| 99d4979af8 | |||
| fbf71fd6a2 | |||
| bde899a04f | |||
| 35d28f4e2b | |||
| 30a5669bc5 | |||
| 99ef5c0253 | |||
| ef9fabd43d | |||
| d7a5f420c4 | |||
| ae6395b88e | |||
| 52b07aa64f | |||
| 497ecc8608 | |||
| 0860182b11 | |||
| 35cecd6008 | |||
| 9424ddd0c2 | |||
| 6a7b6b6959 | |||
| 3f6ae9185e | |||
| 1ad2086525 | |||
| 1fc3e154d1 | |||
|
|
69e2bda47e | ||
| e2e432d52d | |||
| d7d7cc0cbb | |||
| ddb4fd9527 | |||
| 5e255e7c88 | |||
| 7a3fbfeb91 | |||
|
|
79e21d572d | ||
| 0a1abebe24 | |||
| 1a92f12dfd | |||
|
|
2776c587c1 | ||
|
|
ee63a10c19 | ||
|
|
32a6cb65e1 | ||
|
|
7570ce8242 | ||
| 0623908db0 | |||
|
|
d75d21f0f3 | ||
|
|
7270031f25 | ||
|
|
176995652b | ||
| 5882ac4716 | |||
| 3d5356a594 | |||
| a3711c57ea | |||
| 6cf616d1bb |
117
.gitignore
vendored
117
.gitignore
vendored
@ -1,57 +1,60 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.idea/
|
||||
【模板】模型及算法与功能对应清单.docx
|
||||
【模板】GY知识-产品模块架构及功能清单和主要应用场景说明.docx
|
||||
1.json
|
||||
2.json
|
||||
3.json
|
||||
4.json
|
||||
6.json
|
||||
功能清单.md
|
||||
模型及算法与功能对应清单(完整版).md
|
||||
维修系统使用说明.md
|
||||
audio_demo_config.json
|
||||
create_test_audio.py
|
||||
demo_universal_dialog.py
|
||||
Dock按钮样式统一说明.md
|
||||
Dock面板标题样式线完成说明.md
|
||||
exam_result_20250926_004454.json
|
||||
exam_result_20250926_010628.json
|
||||
exam_result_20250926_011746.json
|
||||
exam_result_20250926_090330.json
|
||||
exam_result_20250926_111756.json
|
||||
exam_test_config.json
|
||||
Figma布局优化说明.md
|
||||
Figma设计分析与菜单栏优化文档.md
|
||||
Figma样式优化完成说明.md
|
||||
manual_tools_config.json
|
||||
pm.txt
|
||||
simple_menubar_test.py
|
||||
test_audio.py
|
||||
test_basic_audio.py
|
||||
test_exam_tool_error.py
|
||||
test_full_audio_playback.py
|
||||
test_menu_visibility.py
|
||||
test_mode_selection.py
|
||||
test_mp3_audio.py
|
||||
test_pygame_audio.py
|
||||
test_score_config.py
|
||||
test_simple_audio.py
|
||||
tool_test_config.json
|
||||
UI设计文档.md
|
||||
UniversalMessageDialog使用说明.md
|
||||
.codex/settings/kiroCodex-settings.json
|
||||
data/projects.json
|
||||
RenderPipelineFile/config/daytime.yaml
|
||||
Resources/audio/README.md
|
||||
Resources/model/a.glb
|
||||
Resources/model/b.glb
|
||||
Resources/model/c.glb
|
||||
Resources/model/JQB_auto_converted.glb
|
||||
Resources/model/Untitled.glb
|
||||
Resources/models/Women_1.glb
|
||||
Subjects/test_maintenance_config.json
|
||||
Resources/models/Women_1.glb
|
||||
Resources/models/Women_1.glb
|
||||
Resources/models/Women_1.glb
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.idea/
|
||||
【模板】模型及算法与功能对应清单.docx
|
||||
【模板】GY知识-产品模块架构及功能清单和主要应用场景说明.docx
|
||||
1.json
|
||||
2.json
|
||||
3.json
|
||||
4.json
|
||||
6.json
|
||||
功能清单.md
|
||||
模型及算法与功能对应清单(完整版).md
|
||||
维修系统使用说明.md
|
||||
audio_demo_config.json
|
||||
create_test_audio.py
|
||||
demo_universal_dialog.py
|
||||
Dock按钮样式统一说明.md
|
||||
Dock面板标题样式线完成说明.md
|
||||
exam_result_20250926_004454.json
|
||||
exam_result_20250926_010628.json
|
||||
exam_result_20250926_011746.json
|
||||
exam_result_20250926_090330.json
|
||||
exam_result_20250926_111756.json
|
||||
exam_test_config.json
|
||||
Figma布局优化说明.md
|
||||
Figma设计分析与菜单栏优化文档.md
|
||||
Figma样式优化完成说明.md
|
||||
manual_tools_config.json
|
||||
pm.txt
|
||||
simple_menubar_test.py
|
||||
test_audio.py
|
||||
test_basic_audio.py
|
||||
test_exam_tool_error.py
|
||||
test_full_audio_playback.py
|
||||
test_menu_visibility.py
|
||||
test_mode_selection.py
|
||||
test_mp3_audio.py
|
||||
test_pygame_audio.py
|
||||
test_score_config.py
|
||||
test_simple_audio.py
|
||||
tool_test_config.json
|
||||
UI设计文档.md
|
||||
UniversalMessageDialog使用说明.md
|
||||
.codex/settings/kiroCodex-settings.json
|
||||
data/projects.json
|
||||
RenderPipelineFile/config/daytime.yaml
|
||||
Resources/audio/README.md
|
||||
Resources/model/a.glb
|
||||
Resources/model/b.glb
|
||||
Resources/model/c.glb
|
||||
Resources/model/JQB_auto_converted.glb
|
||||
Resources/model/Untitled.glb
|
||||
Resources/models/Women_1.glb
|
||||
Subjects/test_maintenance_config.json
|
||||
Resources/models/Women_1.glb
|
||||
Resources/models/Women_1.glb
|
||||
Resources/models/Women_1.glb
|
||||
/venv/
|
||||
/engine/
|
||||
/panda3d_imgui-1.1.0-py3-none-any.whl
|
||||
|
||||
28
.idea/EG.iml
generated
28
.idea/EG.iml
generated
@ -1,15 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.10 (eg)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="PyDocumentationSettings">
|
||||
<option name="format" value="PLAIN" />
|
||||
<option name="myDocStringFormat" value="Plain" />
|
||||
</component>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.10 (eg)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="PyDocumentationSettings">
|
||||
<option name="format" value="PLAIN" />
|
||||
<option name="myDocStringFormat" value="Plain" />
|
||||
</component>
|
||||
</module>
|
||||
12
.idea/misc.xml
generated
12
.idea/misc.xml
generated
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.12 (PythonProject)" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (EG)" project-jdk-type="Python SDK" />
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.12 (PythonProject)" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10" project-jdk-type="Python SDK" />
|
||||
</project>
|
||||
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@ -1,4 +1,4 @@
|
||||
{
|
||||
"python-envs.pythonProjects": [],
|
||||
"kiroAgent.configureMCP": "Disabled"
|
||||
{
|
||||
"python-envs.pythonProjects": [],
|
||||
"kiroAgent.configureMCP": "Disabled"
|
||||
}
|
||||
219
AGENTS.md
Normal file
219
AGENTS.md
Normal file
@ -0,0 +1,219 @@
|
||||
# EG 项目概览与开发指南
|
||||
|
||||
## 项目简介
|
||||
|
||||
EG 是一个基于 Panda3D 引擎开发的 3D 编辑器和游戏引擎,集成了高级渲染管线、VR 支持、物理模拟、脚本系统等功能。该项目主要用于创建 3D 场景、游戏开发和交互式应用程序。
|
||||
|
||||
## 核心技术栈
|
||||
|
||||
- **渲染引擎**: Panda3D 1.10.15 + RenderPipeline (延迟渲染、PBR材质)
|
||||
- **GUI框架**: PyQt5 + imgui_bundle (用于编辑器界面)
|
||||
- **VR支持**: OpenVR 2.2.0
|
||||
- **脚本系统**: Python 3.10.12
|
||||
- **其他依赖**: PyQt5-WebEngine, assimp, pillow 等
|
||||
|
||||
## 项目架构
|
||||
|
||||
### 核心模块
|
||||
|
||||
- **main.py** - 应用程序入口点,初始化所有系统
|
||||
- **Start_Run.py** - 启动脚本,设置环境变量和路径
|
||||
- **core/** - 核心功能模块
|
||||
- `world.py` - 世界管理器,处理场景渲染和更新
|
||||
- `selection.py` - 选择系统,处理对象选择
|
||||
- `event_handler.py` - 事件处理系统
|
||||
- `tool_manager.py` - 工具管理器
|
||||
- `script_system.py` - 脚本系统
|
||||
- `patrol_system.py` - 巡逻系统
|
||||
- `Command_System.py` - 命令系统
|
||||
- `terrain_manager.py` - 地形管理
|
||||
- `vr_manager.py` - VR 功能管理
|
||||
- `collision_manager.py` - 碰撞检测管理
|
||||
- `resource_manager.py` - 资源管理
|
||||
- `assembly_interaction.py` - 装配交互
|
||||
- `maintenance_gui.py` - 维护界面
|
||||
- `render_pipeline_utils.py` - 渲染管线工具
|
||||
- `InfoPanelManager.py` - 信息面板管理
|
||||
- `CustomMouseController.py` - 自定义鼠标控制器
|
||||
|
||||
### GUI 系统
|
||||
|
||||
- **gui/gui_manager.py** - GUI管理器,处理2D/3D界面元素
|
||||
- **ui/icon_manager.py** - 图标管理器
|
||||
|
||||
### 场景管理
|
||||
|
||||
- **scene/scene_manager.py** - 场景管理器,处理模型导入、场景树构建
|
||||
- **scene/util.py** - 场景工具函数
|
||||
|
||||
### 项目管理
|
||||
|
||||
- **project/project_manager.py** - 项目管理器,处理项目创建、保存、加载
|
||||
|
||||
### 脚本系统
|
||||
|
||||
- **scripts/** - 包含各种预定义脚本
|
||||
- `MoverScript.py` - 移动脚本
|
||||
- `RotatorScript.py` - 旋转脚本
|
||||
- `ScalerScript.py` - 缩放脚本
|
||||
- `ColorChangerScript.py` - 颜色变化脚本
|
||||
- `FollowerScript.py` - 跟随脚本
|
||||
- `BouncerScript.py` - 弹跳脚本
|
||||
- `ComboAnimatorScript.py` - 组合动画脚本
|
||||
|
||||
### VR 系统
|
||||
|
||||
- **vr_actions/** - VR动作配置
|
||||
- `actions.json` - VR动作定义
|
||||
- `bindings_*.json` - 不同VR设备的绑定配置
|
||||
|
||||
### 资源管理
|
||||
|
||||
- **Resources/** - 资源目录
|
||||
- `models/` - 3D模型
|
||||
- `textures/` - 纹理贴图
|
||||
- `materials/` - 材质文件
|
||||
- `animations/` - 动画文件
|
||||
- `icons/` - 图标资源
|
||||
|
||||
### 渲染管线
|
||||
|
||||
- **RenderPipelineFile/** - 高级渲染管线
|
||||
- `rpcore/` - 渲染管线核心
|
||||
- `rpplugins/` - 渲染插件
|
||||
- `effects/` - 后处理效果
|
||||
- `config/` - 渲染配置
|
||||
|
||||
## 启动和运行
|
||||
|
||||
### 环境要求
|
||||
|
||||
- Python 3.10.12
|
||||
- Panda3D 1.10.15
|
||||
- PyQt5 5.15.9
|
||||
- OpenVR 2.2.0 (VR功能)
|
||||
|
||||
### 运行方式
|
||||
|
||||
1. **直接运行主程序**:
|
||||
```bash
|
||||
python Start_Run.py
|
||||
```
|
||||
|
||||
2. **带项目路径运行**:
|
||||
```bash
|
||||
python Start_Run.py /path/to/project
|
||||
```
|
||||
|
||||
3. **从main.py运行**:
|
||||
```bash
|
||||
python main.py
|
||||
```
|
||||
|
||||
### 配置文件
|
||||
|
||||
- **config/vr_settings.json** - VR渲染配置
|
||||
- **imgui.ini** - ImGui界面配置
|
||||
- **.gitignore** - Git忽略文件配置
|
||||
|
||||
## 开发约定
|
||||
|
||||
### 代码风格
|
||||
|
||||
- 使用UTF-8编码
|
||||
- 遵循PEP 8代码规范
|
||||
- 类名使用驼峰命名法
|
||||
- 函数和变量使用下划线命名法
|
||||
- 文件头部包含模块说明和导入信息
|
||||
|
||||
### 脚本开发
|
||||
|
||||
- 所有用户脚本应继承 `ScriptBase` 类
|
||||
- 脚本文件放在 `scripts/` 目录下
|
||||
- 使用 `ScriptManager` 管理脚本生命周期
|
||||
- 脚本API通过 `world` 对象提供
|
||||
|
||||
### 插件开发
|
||||
|
||||
- 插件系统支持动态加载
|
||||
- 插件配置文件使用JSON格式
|
||||
- 插件应实现标准接口
|
||||
|
||||
### VR开发
|
||||
|
||||
- VR动作配置在 `vr_actions/actions.json` 中定义
|
||||
- 支持多种VR设备(Vive、Oculus、Index)
|
||||
- VR渲染配置在 `config/vr_settings.json` 中
|
||||
|
||||
## 构建和部署
|
||||
|
||||
### 依赖安装
|
||||
|
||||
```bash
|
||||
pip install -r requirements/requirements.txt
|
||||
```
|
||||
|
||||
### 测试
|
||||
|
||||
项目包含多个测试脚本:
|
||||
- `test_quick_script.py` - 快速测试脚本
|
||||
- `TestMover.py` - 移动测试
|
||||
- `TestRotator.py` - 旋转测试
|
||||
- `TestScaler.py` - 缩放测试
|
||||
|
||||
### 项目文件
|
||||
|
||||
- 项目配置使用JSON格式
|
||||
- 项目文件包含场景、资源、脚本等信息
|
||||
- 使用 `ProjectManager` 管理项目生命周期
|
||||
|
||||
## 常见问题
|
||||
|
||||
### VR相关问题
|
||||
|
||||
1. 确保VR设备已正确连接
|
||||
2. 检查OpenVR运行时是否安装
|
||||
3. 验证VR动作配置是否正确
|
||||
|
||||
### 渲染问题
|
||||
|
||||
1. 检查显卡驱动是否最新
|
||||
2. 确认RenderPipeline配置正确
|
||||
3. 验证材质和纹理路径
|
||||
|
||||
### 性能优化
|
||||
|
||||
1. 使用合适的LOD设置
|
||||
2. 优化场景复杂度
|
||||
3. 调整渲染质量设置
|
||||
|
||||
## 扩展开发
|
||||
|
||||
### 添加新脚本
|
||||
|
||||
1. 在 `scripts/` 目录创建新脚本文件
|
||||
2. 继承 `ScriptBase` 类
|
||||
3. 实现必要的方法
|
||||
4. 通过 `ScriptManager` 注册脚本
|
||||
|
||||
### 添加新工具
|
||||
|
||||
1. 在 `core/tool_manager.py` 中注册新工具
|
||||
2. 实现工具逻辑
|
||||
3. 添加GUI界面元素
|
||||
|
||||
### 添加新渲染效果
|
||||
|
||||
1. 在 `RenderPipelineFile/rpplugins/` 目录创建插件
|
||||
2. 实现渲染逻辑
|
||||
3. 添加配置选项
|
||||
|
||||
## 联系和支持
|
||||
|
||||
- 项目Git仓库: http://10.0.0.99:4000/Rowland/EG.git
|
||||
- 当前分支: imgui
|
||||
- 最新提交: 移除qt依赖 (33e62bd1e4c2c8d3aac15e045b419edb8992d7ff)
|
||||
|
||||
---
|
||||
|
||||
*该文档由iFlow CLI自动生成,最后更新时间: 2026年1月28日*
|
||||
1
EG
Submodule
1
EG
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 69e2bda47e9713705ad5c45a08b6fc643a2b51f6
|
||||
179
IFLOW.md
179
IFLOW.md
@ -1,179 +0,0 @@
|
||||
# iFlow 上下文文档
|
||||
|
||||
## 项目概述
|
||||
|
||||
这是一个基于 Panda3D 和 PyQt5 的 3D 虚拟现实 (VR) 应用程序框架。该项目旨在提供一个功能齐全、模块化的 3D 环境,支持 VR 设备(如 HTC Vive, Oculus Rift)的集成,包含场景管理、模型导入、GUI 系统、脚本系统、地形系统、碰撞检测以及完整的 VR 交互功能。
|
||||
|
||||
核心架构围绕 `MyWorld` 类构建,该类继承自 `CoreWorld`,并集成了各种管理器模块,如选择系统、工具管理器、脚本管理器、GUI 管理器、场景管理器、项目管理器、地形管理器、碰撞管理器和 VR 管理器。
|
||||
|
||||
## 核心技术栈
|
||||
|
||||
- **核心引擎**: Panda3D
|
||||
- **图形渲染**: 可选择普通渲染或 RenderPipeline 高级渲染管线
|
||||
- **VR 支持**: OpenVR/SteamVR
|
||||
- **用户界面**: PyQt5
|
||||
- **3D 模型格式**: 支持 glTF, FBX (需转换), BAM 等
|
||||
- **脚本语言**: Python (内嵌脚本系统)
|
||||
- **物理/碰撞**: Panda3D 内置碰撞系统
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
.
|
||||
├── core/ # 核心模块
|
||||
│ ├── world.py # CoreWorld 基础世界类
|
||||
│ ├── vr/ # VR 子模块 (完整模块化结构)
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── config/ # VR 配置管理
|
||||
│ │ ├── interaction/ # VR 交互系统 (动作、抓取、摇杆、传送)
|
||||
│ │ ├── performance/ # VR 性能监控
|
||||
│ │ ├── rendering/ # VR 渲染相关 (RenderPipeline 集成)
|
||||
│ │ ├── testing/ # VR 测试模式
|
||||
│ │ ├── tracking/ # VR 设备跟踪
|
||||
│ │ └── visualization/ # VR 可视化 (控制器模型)
|
||||
│ ├── vr_manager.py # VR 管理器主文件 (待拆分)
|
||||
│ ├── selection.py # 选择系统
|
||||
│ ├── tool_manager.py # 工具管理器
|
||||
│ ├── script_system.py # 脚本系统
|
||||
│ ├── gui_manager.py # GUI 管理器
|
||||
│ ├── terrain_manager.py # 地形管理器
|
||||
│ ├── collision_manager.py # 碰撞管理器
|
||||
│ ├── event_handler.py # 事件处理器
|
||||
│ ├── patrol_system.py # 巡检系统
|
||||
│ ├── Command_System.py # 命令系统
|
||||
│ └── InfoPanelManager.py # 信息面板管理器
|
||||
├── demo/ # 示例和测试文件
|
||||
├── gui/ # GUI 相关模块
|
||||
├── project/ # 项目管理模块
|
||||
├── scene/ # 场景管理模块 (部分代码在 core/)
|
||||
├── scripts/ # 脚本文件目录
|
||||
├── ui/ # UI 组件和主窗口
|
||||
├── QPanda3D/ # Panda3D 与 PyQt 集成库
|
||||
├── Resources/ # 资源文件 (模型、纹理等)
|
||||
├── config/ # 配置文件
|
||||
│ └── vr_settings.json # VR 配置文件
|
||||
├── main.py # 程序入口点
|
||||
└── Start_Run.py # 启动脚本
|
||||
```
|
||||
|
||||
## 核心功能模块
|
||||
|
||||
### 1. World (core/world.py, main.py)
|
||||
|
||||
- `CoreWorld`: 基础 3D 世界设置,包括相机、光照、地面、资源路径。
|
||||
- `MyWorld`: 扩展的主世界类,整合所有管理器和功能模块。
|
||||
- **初始化**: 设置资源路径、相机、光照、地面,加载中文字体。
|
||||
- **兼容性**: 提供旧版属性访问接口。
|
||||
- **功能代理**: 将大量功能委托给专门的管理器。
|
||||
|
||||
### 2. VR 系统 (core/vr/)
|
||||
|
||||
这是一个高度模块化的 VR 子系统,核心是 `VRManager` (core/vr_manager.py)。
|
||||
|
||||
- **VRManager**:
|
||||
- **初始化与状态管理**: 检查 VR 可用性、初始化 OpenVR、管理启用/禁用状态。
|
||||
- **渲染系统**:
|
||||
- 支持普通渲染和 RenderPipeline 高级渲染两种模式。
|
||||
- 创建和管理左右眼的渲染缓冲区和相机。
|
||||
- 实现高效的纹理提交到 OpenVR Compositor。
|
||||
- 支持动态分辨率缩放和质量预设。
|
||||
- **跟踪系统**:
|
||||
- 通过 OpenVR 获取 HMD 和控制器的姿态。
|
||||
- 使用锚点层级系统 (`tracking_space`, `hmd_anchor` 等) 管理设备位置。
|
||||
- 坐标系转换 (OpenVR 到 Panda3D)。
|
||||
- **控制器**:
|
||||
- `LeftController`, `RightController`: 管理具体的手柄输入和可视化。
|
||||
- 支持动作系统 (VRActionManager) 或直接输入读取。
|
||||
- **交互系统**:
|
||||
- **VRInteractionManager**: 对象抓取和交互。
|
||||
- **VRTeleportSystem**: 传送功能。
|
||||
- **VRJoystickManager**: 摇杆移动控制。
|
||||
- **性能优化**:
|
||||
- 对象池 (Mat4) 减少 GC 压力。
|
||||
- 纹理 ID 缓存避免重复 prepare。
|
||||
- 智能 GPU 同步策略。
|
||||
- 性能模式自动切换。
|
||||
- **配置管理**:
|
||||
- `VRConfigManager`: 从 `config/vr_settings.json` 加载/保存配置。
|
||||
- **测试与调试**:
|
||||
- `VRTestMode`: 提供不同的测试显示模式和功能开关。
|
||||
- `VRPerformanceMonitor`: 性能监控和报告。
|
||||
|
||||
### 3. GUI 系统 (core/gui_manager.py, gui/)
|
||||
|
||||
- **GUIManager**: 管理 2D 和 3D GUI 元素的创建、编辑、删除。
|
||||
- **功能**:
|
||||
- 创建按钮、标签、输入框、2D/3D 图像、视频屏幕等。
|
||||
- GUI 编辑模式,支持拖拽创建和属性编辑。
|
||||
- 与场景树和属性面板集成。
|
||||
- 独立的 GUI 预览窗口。
|
||||
|
||||
### 4. 场景与模型管理 (core/scene_manager.py)
|
||||
|
||||
- **SceneManager**: 管理 3D 场景中的所有模型。
|
||||
- **功能**:
|
||||
- 模型导入 (支持 glTF, FBX 转换)。
|
||||
- 材质和几何体处理。
|
||||
- 碰撞体设置。
|
||||
- 场景保存/加载 (BAM 格式)。
|
||||
- 场景树更新。
|
||||
|
||||
### 5. 脚本系统 (core/script_system.py)
|
||||
|
||||
- **ScriptManager**: 嵌入式 Python 脚本系统。
|
||||
- **功能**:
|
||||
- 脚本文件的创建、加载、重载。
|
||||
- 为游戏对象挂载/卸载脚本。
|
||||
- 热重载支持。
|
||||
- 脚本信息查询。
|
||||
|
||||
### 6. 地形系统 (core/terrain_manager.py)
|
||||
|
||||
- **TerrainManager**: 管理 3D 地形。
|
||||
- **功能**:
|
||||
- 从高度图或创建平面地形。
|
||||
- 地形 LOD 更新。
|
||||
- 地形高度查询和编辑。
|
||||
|
||||
### 7. 碰撞系统 (core/collision_manager.py)
|
||||
|
||||
- **CollisionManager**: 处理场景中的碰撞检测。
|
||||
- **功能**:
|
||||
- 模型间碰撞检测。
|
||||
- 碰撞历史和统计。
|
||||
|
||||
### 8. 工具与选择系统 (core/tool_manager.py, core/selection.py)
|
||||
|
||||
- **ToolManager**: 管理当前使用的工具 (选择、移动、旋转、缩放)。
|
||||
- **SelectionSystem**: 处理对象选择逻辑和相机聚焦。
|
||||
|
||||
## 构建与运行
|
||||
|
||||
### 入口点
|
||||
|
||||
- `main.py`: 主程序入口,创建 `MyWorld` 实例并启动 PyQt5 主窗口。
|
||||
- `Start_Run.py`: 可能的启动脚本。
|
||||
|
||||
### 运行方式
|
||||
|
||||
1. 确保已安装所有依赖项(Panda3D, PyQt5, OpenVR 等)。
|
||||
2. 运行 `python main.py` 启动应用程序。
|
||||
3. 如果连接了 VR 设备并安装了 SteamVR,可以在应用内启用 VR 模式。
|
||||
|
||||
### 依赖项
|
||||
|
||||
项目未提供 `requirements.txt` 文件,但根据代码分析,主要依赖包括:
|
||||
|
||||
- `panda3d`
|
||||
- `PyQt5`
|
||||
- `openvr` (用于 VR 功能)
|
||||
- `numpy` (在 VR 模块中使用)
|
||||
|
||||
## 开发约定
|
||||
|
||||
- **模块化设计**: 功能被分解到不同的管理器类中,`MyWorld` 主要起到集成和代理的作用。
|
||||
- **VR 子模块化**: VR 功能被组织在 `core/vr/` 目录下,具有清晰的子模块划分。
|
||||
- **配置驱动**: VR 设置通过 `config/vr_settings.json` 文件进行管理。
|
||||
- **性能意识**: VR 模块包含大量性能优化措施,如对象池、缓存、智能同步等。
|
||||
- **向后兼容**: `MyWorld` 通过属性代理保持与旧代码的兼容性。
|
||||
- **测试模式**: VR 系统包含专门的测试模式,便于调试和验证不同功能。
|
||||
@ -1,271 +0,0 @@
|
||||
from panda3d.core import *
|
||||
from direct.interval.IntervalGlobal import *
|
||||
|
||||
class Env_Grid_Maker:
|
||||
def __init__(self, XYPlaneShow = True, XZPlaneShow = False, YZPlaneShow = False, endCapLinesShow = True, XSize = 50, YSize = 50, ZSize = 50, gridStep = 10, subdiv = 10):
|
||||
#Create line objects
|
||||
self.axisLines = LineSegs()
|
||||
self.gridLines = LineSegs()
|
||||
self.subdivLines = LineSegs()
|
||||
|
||||
#Init passed variables
|
||||
self.XSize = XSize
|
||||
self.YSize = YSize
|
||||
self.ZSize = ZSize
|
||||
self.gridStep = gridStep
|
||||
self.subdiv = subdiv
|
||||
|
||||
#Init default variables
|
||||
|
||||
#Plane and end cap line visibility (1 is show, 0 is hide)
|
||||
self.XYPlaneShow = XYPlaneShow
|
||||
self.XZPlaneShow = XZPlaneShow
|
||||
self.YZPlaneShow = YZPlaneShow
|
||||
self.endCapLinesShow = endCapLinesShow
|
||||
|
||||
#Alpha variables for each plane
|
||||
#self.XYPlaneAlpha = 1
|
||||
#self.XZPlaneAlpha = 1
|
||||
#self.YZPlaneAlpha = 1
|
||||
|
||||
#Colors (RGBA passed as a VBase4 object)
|
||||
self.XAxisColor = VBase4(1, 0, 0, 1)
|
||||
self.YAxisColor = VBase4(0, 1, 0, 1)
|
||||
self.ZAxisColor = VBase4(0, 0, 1, 1)
|
||||
self.gridColor = VBase4(1, 1, 1, 1)
|
||||
self.subdivColor = VBase4(.35, .35, .35, 1)
|
||||
|
||||
#Line thicknesses (in pixels)
|
||||
self.axisThickness = 3
|
||||
self.gridThickness = 1
|
||||
self.subdivThickness = 1
|
||||
|
||||
|
||||
def create(self):
|
||||
#Set line thicknesses
|
||||
self.axisLines.setThickness(self.axisThickness)
|
||||
self.gridLines.setThickness(self.gridThickness)
|
||||
self.subdivLines.setThickness(self.subdivThickness)
|
||||
|
||||
if(self.XSize != 0):
|
||||
#Draw X axis line
|
||||
self.axisLines.setColor(self.XAxisColor)
|
||||
self.axisLines.moveTo(-(self.XSize), 0, 0)
|
||||
self.axisLines.drawTo(self.XSize, 0, 0)
|
||||
|
||||
if(self.YSize != 0):
|
||||
#Draw Y axis line
|
||||
self.axisLines.setColor(self.YAxisColor)
|
||||
self.axisLines.moveTo(0, -(self.YSize), 0)
|
||||
self.axisLines.drawTo(0, self.YSize, 0)
|
||||
|
||||
if(self.ZSize != 0):
|
||||
#Draw Z axis line
|
||||
self.axisLines.setColor(self.ZAxisColor)
|
||||
self.axisLines.moveTo(0, 0, -(self.ZSize))
|
||||
self.axisLines.drawTo(0, 0, self.ZSize)
|
||||
|
||||
#Check to see if primary grid lines should be drawn at all
|
||||
if(self.gridStep != 0):
|
||||
|
||||
#Draw primary grid lines
|
||||
self.gridLines.setColor(self.gridColor)
|
||||
|
||||
#Draw primary grid lines metering x axis if any x-length
|
||||
if(self.XSize != 0):
|
||||
if((self.YSize != 0) and (self.XYPlaneShow)):
|
||||
#Draw y lines across x axis starting from center moving out
|
||||
#XY Plane
|
||||
for x in self.myfrange(0, self.XSize, self.gridStep):
|
||||
self.gridLines.moveTo(x, -(self.YSize), 0)
|
||||
self.gridLines.drawTo(x, self.YSize, 0)
|
||||
self.gridLines.moveTo(-x, -(self.YSize), 0)
|
||||
self.gridLines.drawTo(-x, self.YSize, 0)
|
||||
|
||||
if(self.endCapLinesShow):
|
||||
#Draw endcap lines
|
||||
self.gridLines.moveTo(self.XSize, -(self.YSize), 0)
|
||||
self.gridLines.drawTo(self.XSize, self.YSize, 0)
|
||||
self.gridLines.moveTo(-(self.XSize), -(self.YSize), 0)
|
||||
self.gridLines.drawTo(-(self.XSize), self.YSize, 0)
|
||||
|
||||
if((self.ZSize != 0) and (self.XZPlaneShow)):
|
||||
#Draw z lines across x axis starting from center moving out
|
||||
#XZ Plane
|
||||
for x in self.myfrange(0, self.XSize, self.gridStep):
|
||||
self.gridLines.moveTo(x, 0, -(self.ZSize))
|
||||
self.gridLines.drawTo(x, 0, self.ZSize)
|
||||
self.gridLines.moveTo(-x, 0, -(self.ZSize))
|
||||
self.gridLines.drawTo(-x, 0, self.ZSize)
|
||||
|
||||
if(self.endCapLinesShow):
|
||||
#Draw endcap lines
|
||||
self.gridLines.moveTo(self.XSize, 0, -(self.ZSize))
|
||||
self.gridLines.drawTo(self.XSize, 0, self.ZSize)
|
||||
self.gridLines.moveTo(-(self.XSize), 0, -(self.ZSize))
|
||||
self.gridLines.drawTo(-(self.XSize), 0, self.ZSize)
|
||||
|
||||
#Draw primary grid lines metering y axis if any y-length
|
||||
if(self.YSize != 0):
|
||||
|
||||
if((self.YSize != 0) and (self.XYPlaneShow)):
|
||||
#Draw x lines across y axis
|
||||
#XY Plane
|
||||
for y in self.myfrange(0, self.YSize, self.gridStep):
|
||||
self.gridLines.moveTo(-(self.XSize), y, 0)
|
||||
self.gridLines.drawTo(self.XSize, y, 0)
|
||||
self.gridLines.moveTo(-(self.XSize), -y, 0)
|
||||
self.gridLines.drawTo(self.XSize, -y, 0)
|
||||
|
||||
if(self.endCapLinesShow):
|
||||
#Draw endcap lines
|
||||
self.gridLines.moveTo(-(self.XSize), self.YSize, 0)
|
||||
self.gridLines.drawTo(self.XSize, self.YSize, 0)
|
||||
self.gridLines.moveTo(-(self.XSize), -(self.YSize), 0)
|
||||
self.gridLines.drawTo(self.XSize, -(self.YSize), 0)
|
||||
|
||||
if((self.ZSize != 0) and (self.YZPlaneShow)):
|
||||
#Draw z lines across y axis
|
||||
#YZ Plane
|
||||
for y in self.myfrange(0, self.YSize, self.gridStep):
|
||||
self.gridLines.moveTo(0, y, -(self.ZSize))
|
||||
self.gridLines.drawTo(0, y, self.ZSize)
|
||||
self.gridLines.moveTo(0, -y, -(self.ZSize))
|
||||
self.gridLines.drawTo(0, -y, self.ZSize)
|
||||
|
||||
if(self.endCapLinesShow):
|
||||
#Draw endcap lines
|
||||
self.gridLines.moveTo(0, self.YSize, -(self.ZSize))
|
||||
self.gridLines.drawTo(0, self.YSize, self.ZSize)
|
||||
self.gridLines.moveTo(0, -(self.YSize), -(self.ZSize))
|
||||
self.gridLines.drawTo(0, -(self.YSize), self.ZSize)
|
||||
|
||||
#Draw primary grid lines metering z axis if any z-length
|
||||
if(self.ZSize != 0):
|
||||
if((self.XSize != 0) and (self.XZPlaneShow)):
|
||||
#Draw x lines across z axis
|
||||
#XZ Plane
|
||||
for z in self.myfrange(0, self.ZSize, self.gridStep):
|
||||
self.gridLines.moveTo(-(self.XSize), 0, z)
|
||||
self.gridLines.drawTo(self.XSize, 0, z)
|
||||
self.gridLines.moveTo(-(self.XSize), 0, -z)
|
||||
self.gridLines.drawTo(self.XSize, 0, -z)
|
||||
|
||||
if(self.endCapLinesShow):
|
||||
#Draw endcap lines
|
||||
self.gridLines.moveTo(-(self.XSize), 0, self.ZSize)
|
||||
self.gridLines.drawTo(self.XSize, 0, self.ZSize)
|
||||
self.gridLines.moveTo(-(self.XSize), 0, -(self.ZSize))
|
||||
self.gridLines.drawTo(self.XSize, 0, -(self.ZSize))
|
||||
|
||||
if((self.YSize != 0) and (self.YZPlaneShow)):
|
||||
#Draw y lines across z axis
|
||||
#YZ Plane
|
||||
for z in self.myfrange(0, self.ZSize, self.gridStep):
|
||||
self.gridLines.moveTo(0, -(self.YSize), z)
|
||||
self.gridLines.drawTo(0, self.YSize, z)
|
||||
self.gridLines.moveTo(0, -(self.YSize), -z)
|
||||
self.gridLines.drawTo(0, self.YSize, -z)
|
||||
|
||||
if(self.endCapLinesShow):
|
||||
#Draw endcap lines
|
||||
self.gridLines.moveTo(0, -(self.YSize), self.ZSize)
|
||||
self.gridLines.drawTo(0, self.YSize, self.ZSize)
|
||||
self.gridLines.moveTo(0, -(self.YSize), -(self.ZSize))
|
||||
self.gridLines.drawTo(0, self.YSize, -(self.ZSize))
|
||||
|
||||
#Check to see if secondary grid lines should be drawn
|
||||
if(self.subdiv != 0):
|
||||
|
||||
#Draw secondary grid lines
|
||||
self.subdivLines.setColor(self.subdivColor)
|
||||
|
||||
if(self.XSize != 0):
|
||||
adjustedstep = self.gridStep / self.subdiv
|
||||
if((self.YSize != 0) and (self.XYPlaneShow)):
|
||||
#Draw y lines across x axis starting from center moving out
|
||||
#XY
|
||||
for x in self.myfrange(0, self.XSize, adjustedstep):
|
||||
self.subdivLines.moveTo(x, -(self.YSize), 0)
|
||||
self.subdivLines.drawTo(x, self.YSize, 0)
|
||||
self.subdivLines.moveTo(-x, -(self.YSize), 0)
|
||||
self.subdivLines.drawTo(-x, self.YSize, 0)
|
||||
|
||||
if((self.ZSize != 0) and (self.XZPlaneShow)):
|
||||
#Draw z lines across x axis starting from center moving out
|
||||
#XZ
|
||||
for x in self.myfrange(0, self.XSize, adjustedstep):
|
||||
self.subdivLines.moveTo(x, 0, -(self.ZSize))
|
||||
self.subdivLines.drawTo(x, 0, self.ZSize)
|
||||
self.subdivLines.moveTo(-x, 0, -(self.ZSize))
|
||||
self.subdivLines.drawTo(-x, 0, self.ZSize)
|
||||
|
||||
if(self.YSize != 0):
|
||||
if((self.YSize != 0) and (self.XYPlaneShow)):
|
||||
#Draw x lines across y axis
|
||||
#XY
|
||||
for y in self.myfrange(0, self.YSize, adjustedstep):
|
||||
self.subdivLines.moveTo(-(self.XSize), y, 0)
|
||||
self.subdivLines.drawTo(self.XSize, y, 0)
|
||||
self.subdivLines.moveTo(-(self.XSize), -y, 0)
|
||||
self.subdivLines.drawTo(self.XSize, -y, 0)
|
||||
if((self.ZSize != 0) and (self.YZPlaneShow)):
|
||||
#Draw z lines across y axis
|
||||
#YZ
|
||||
for y in self.myfrange(0, self.YSize, adjustedstep):
|
||||
self.subdivLines.moveTo(0, y, -(self.ZSize))
|
||||
self.subdivLines.drawTo(0, y, self.ZSize)
|
||||
self.subdivLines.moveTo(0, -y, -(self.ZSize))
|
||||
self.subdivLines.drawTo(0, -y, self.ZSize)
|
||||
|
||||
if(self.ZSize != 0):
|
||||
|
||||
if((self.XSize != 0) and (self.XZPlaneShow)):
|
||||
#Draw x lines across z axis
|
||||
#XZ
|
||||
for z in self.myfrange(0, self.ZSize, adjustedstep):
|
||||
self.subdivLines.moveTo(-(self.XSize), 0, z)
|
||||
self.subdivLines.drawTo(self.XSize, 0, z)
|
||||
self.subdivLines.moveTo(-(self.XSize), 0, -z)
|
||||
self.subdivLines.drawTo(self.XSize, 0, -z)
|
||||
|
||||
if((self.YSize != 0) and (self.YZPlaneShow)):
|
||||
#Draw y lines across z axis
|
||||
#YZ
|
||||
for z in self.myfrange(0, self.ZSize, adjustedstep):
|
||||
self.subdivLines.moveTo(0, -(self.YSize), z)
|
||||
self.subdivLines.drawTo(0, self.YSize, z)
|
||||
self.subdivLines.moveTo(0, -(self.YSize), -z)
|
||||
self.subdivLines.drawTo(0, self.YSize, -z)
|
||||
|
||||
#Create ThreeAxisGrid nodes and nodepaths
|
||||
#Create parent node and path
|
||||
self.parentNode = PandaNode('threeaxisgrid-parentnode')
|
||||
self.parentNodePath = NodePath(self.parentNode)
|
||||
|
||||
#Create axis lines node and path, then reparent
|
||||
self.axisLinesNode = self.axisLines.create()
|
||||
self.axisLinesNodePath = NodePath(self.axisLinesNode)
|
||||
self.axisLinesNodePath.reparentTo(self.parentNodePath)
|
||||
|
||||
#Create grid lines node and path, then reparent
|
||||
self.gridLinesNode = self.gridLines.create()
|
||||
self.gridLinesNodePath = NodePath(self.gridLinesNode)
|
||||
self.gridLinesNodePath.reparentTo(self.parentNodePath)
|
||||
|
||||
#Create subdivision lines node and path then reparent
|
||||
self.subdivLinesNode = self.subdivLines.create()
|
||||
self.subdivLinesNodePath = NodePath(self.subdivLinesNode)
|
||||
self.subdivLinesNodePath.reparentTo(self.parentNodePath)
|
||||
|
||||
return self.parentNodePath
|
||||
def myfrange(self, start, stop=None, step=None):
|
||||
if stop is None:
|
||||
stop = float(start)
|
||||
start = 0.0
|
||||
if step is None:
|
||||
step = 1.0
|
||||
cur = float(start)
|
||||
while cur < stop:
|
||||
yield cur
|
||||
cur += step
|
||||
@ -1,2 +0,0 @@
|
||||
name="QMeta3D"
|
||||
__all__ = ["Env_Grid_Maker"]
|
||||
@ -1,192 +0,0 @@
|
||||
import sys
|
||||
import os
|
||||
|
||||
from core.CustomMouseController import CustomMouseController
|
||||
|
||||
# 获取 RenderPipelineFile 的路径
|
||||
render_pipeline_path = './RenderPipelineFile'
|
||||
# 将该路径添加到 sys.path 中,确保 Python 能够找到它
|
||||
project_root = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, project_root)
|
||||
sys.path.insert(0, render_pipeline_path)
|
||||
|
||||
from RenderPipelineFile.rpcore import RenderPipeline
|
||||
_global_render_pipeline = None
|
||||
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtWidgets import *
|
||||
|
||||
from panda3d.core import *
|
||||
from panda3d.core import GraphicsOutput, Texture, ConfigVariableManager, WindowProperties
|
||||
|
||||
from direct.showbase.ShowBase import ShowBase
|
||||
import platform
|
||||
|
||||
from QMeta3D.QMouseWatcherNode import QMouseWatcherNode
|
||||
|
||||
from RenderPipelineFile.rpcore.render_target import RenderTarget
|
||||
__all__ = ["Meta3DWorld"]
|
||||
|
||||
_global_world_instance=None
|
||||
import builtins
|
||||
|
||||
|
||||
class Meta3DWorld(ShowBase):
|
||||
def __init__(self, width=1380, height=750, is_fullscreen=False, size=1.0, clear_color=LVecBase4f(0, 0.5, 0, 1),
|
||||
name="qMeta3D"):
|
||||
|
||||
global _global_world_instance
|
||||
global _global_render_pipeline
|
||||
|
||||
_global_world_instance = self
|
||||
|
||||
sort = -100
|
||||
self.parent = None
|
||||
|
||||
# 设置基本配置
|
||||
loadPrcFileData("", "show-frame-rate-meter 0")
|
||||
loadPrcFileData("", "window-type offscreen") # 设置为离屏渲染
|
||||
loadPrcFileData("", f"win-size {width} {height}")
|
||||
loadPrcFileData("", "win-fixed-size #f") # 允许窗口调整大小
|
||||
|
||||
# 🚀 VR性能优化配置
|
||||
loadPrcFileData("", "prefer-single-buffer true") # 减少缓冲区交换开销
|
||||
loadPrcFileData("", "gl-force-flush false") # 避免强制glFlush导致的性能损失
|
||||
loadPrcFileData("", "sync-video false") # 禁用默认VSync,让OpenVR控制
|
||||
loadPrcFileData("", "support-stencil false") # 禁用不必要的模板缓冲区
|
||||
loadPrcFileData("", "clock-mode non-real-time")
|
||||
# loadPrcFileData("", "gl-debug true")
|
||||
|
||||
if (is_fullscreen):
|
||||
loadPrcFileData("", "fullscreen #t")
|
||||
|
||||
self.render_pipeline = RenderPipeline()
|
||||
self.render_pipeline.pre_showbase_init()
|
||||
|
||||
ShowBase.__init__(self)
|
||||
|
||||
# 初始化渲染管线并设置可调整大小的标志
|
||||
self.render_pipeline.create(self)
|
||||
_global_render_pipeline = self.render_pipeline
|
||||
|
||||
# 创建 Qt 能读的 RGBA8 贴图
|
||||
self.qt_output_tex = Texture("qt_output_tex")
|
||||
self.qt_output_tex.set_format(Texture.F_rgba8)
|
||||
self.qt_output_tex.set_component_type(Texture.T_unsigned_byte)
|
||||
|
||||
# # 获取图形管线对象
|
||||
# gsg = self.win.getGsg()
|
||||
# host = gsg.getEngine().getHost()
|
||||
|
||||
self.win.add_render_texture(self.qt_output_tex, GraphicsOutput.RTM_copy_ram)
|
||||
|
||||
#self.screenTexture = Texture()
|
||||
#self.screenTexture.setMinfilter(Texture.FTLinear)
|
||||
#self.screenTexture.setFormat(Texture.FRgba32)
|
||||
#self.screenTexture.set_wrap_u(Texture.WM_clamp)
|
||||
#self.screenTexture.set_wrap_v(Texture.WM_clamp)
|
||||
|
||||
# buff_size_x = int(self.win.get_x_size() * size)
|
||||
# buff_size_y = int(self.win.get_y_size() * size)
|
||||
# winprops = WindowProperties()
|
||||
# winprops.set_size(buff_size_x, buff_size_y)
|
||||
#
|
||||
#
|
||||
# props = FrameBufferProperties()
|
||||
# props.set_rgb_color(True)
|
||||
# props.set_rgba_bits(8, 8, 8, 8)
|
||||
# props.set_depth_bits(8)
|
||||
|
||||
# self.buff = self.graphicsEngine.make_output(
|
||||
# self.pipe, name, sort,
|
||||
# props, winprops,
|
||||
# GraphicsPipe.BF_resizeable,
|
||||
# self.win.get_gsg(), self.win)
|
||||
|
||||
#self.screenTexture = render_pipeline._final_stage.target.color_tex
|
||||
|
||||
#self.buff.addRenderTexture(self.screenTexture, GraphicsOutput.RTMCopyRam)
|
||||
# self.buff.set_sort(sort)
|
||||
|
||||
|
||||
|
||||
#self.cam = self.makeCamera(self.buff)
|
||||
#self.render_pipeline._showbase.cam=self.makeCamera(self.buff)
|
||||
|
||||
#self.render_pipeline._showbase.cam=self.makeCamera(self.buff)
|
||||
|
||||
#self.render_pipeline._showbase.camera.reparentTo(self.render)
|
||||
#base.camera.reparentTo(self.render)
|
||||
#self.cam.reparentTo(self.render) # 可选同步
|
||||
|
||||
#render_pipeline.set_camera(self.cam)
|
||||
|
||||
#添加渲染效果
|
||||
#self.cam = self.render_pipeline._showbase.cam
|
||||
#self.camNode = self.cam.node()
|
||||
#self.camLens = self.camNode.get_lens()
|
||||
self.render_pipeline._showbase.camera = self.render_pipeline._showbase.cam
|
||||
#self.render_pipeline.daytime_mgr.update()
|
||||
|
||||
|
||||
# if clear_color is None:
|
||||
# self.buff.set_clear_active(GraphicsOutput.RTPColor, False)
|
||||
# else:
|
||||
# self.buff.set_clear_color(clear_color)
|
||||
# self.buff.set_clear_active(GraphicsOutput.RTPColor, True)
|
||||
|
||||
# self.disableMouse()
|
||||
self.mouse_controller = CustomMouseController(self)
|
||||
self.mouse_controller.setUp()
|
||||
|
||||
# 添加错误处理钩子
|
||||
self.accept("transform_state_error", self._handle_transform_error)
|
||||
|
||||
def _handle_transform_error(self):
|
||||
"""处理TransformState相关的错误"""
|
||||
try:
|
||||
from panda3d.core import TransformState, RenderState
|
||||
TransformState.clear_cache()
|
||||
RenderState.clear_cache()
|
||||
print("已清理TransformState和RenderState缓存")
|
||||
except Exception as e:
|
||||
print(f"清理缓存时出错: {e}")
|
||||
|
||||
def render_pipeline(self):
|
||||
"""获取 RenderPipeline 实例"""
|
||||
return self._render_pipeline
|
||||
|
||||
|
||||
def set_parent(self, parent: QWidget):
|
||||
self.parent = parent
|
||||
self.mouseWatcherNode = QMouseWatcherNode(parent)
|
||||
|
||||
def getAspectRatio(self, win = None):
|
||||
if win is None and self.parent is not None:
|
||||
return float(self.parent.width()) / float(self.parent.height())
|
||||
else:
|
||||
return super().getAspectRatio(win)
|
||||
|
||||
def get_render_pipeline():
|
||||
"""获取全局 RenderPipeline 单例"""
|
||||
if _global_render_pipeline is None:
|
||||
raise RuntimeError(
|
||||
"RenderPipeline has not been initialized yet. Please create a 3DWorld instance first.")
|
||||
return _global_render_pipeline
|
||||
|
||||
def resize_buffer(self, width: int, height: int):
|
||||
props = WindowProperties()
|
||||
props.set_size(width, height)
|
||||
self.win.request_properties(props)
|
||||
|
||||
# 重新分配输出贴图的大小
|
||||
self.qt_output_tex.set_x_size(width)
|
||||
self.qt_output_tex.set_y_size(height)
|
||||
|
||||
# 更新 lens 的 aspect ratio
|
||||
if self.camLens:
|
||||
self.camLens.set_film_size(width, height) # 或 set_aspect_ratio(width / height)
|
||||
|
||||
# 强制更新窗口(有时在 Qt 内嵌时需要)
|
||||
self.graphicsEngine.open_windows()
|
||||
@ -1,252 +0,0 @@
|
||||
from PyQt5 import QtWidgets, QtGui
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtWidgets import *
|
||||
from direct.task.TaskManagerGlobal import taskMgr
|
||||
|
||||
from QMeta3D.QMeta3D_Buttons_Translation import QMeta3D_Button_translation
|
||||
from QMeta3D.QMeta3D_Keys_Translation import QMeta3D_Key_translation
|
||||
from QMeta3D.QMeta3D_Modifiers_Translation import QMeta3D_Modifier_translation
|
||||
|
||||
__all__ = ["QMeta3DWidget"]
|
||||
|
||||
|
||||
class QMeta3DSynchronizer(QTimer):
|
||||
def __init__(self, qMeta3DWidget, FPS=60):
|
||||
QTimer.__init__(self)
|
||||
self.qMeta3DWidget = qMeta3DWidget
|
||||
dt = 1000 / FPS
|
||||
self.setInterval(int(dt))
|
||||
self.timeout.connect(self.tick)
|
||||
|
||||
def tick(self):
|
||||
try:
|
||||
# 在渲染前清理可能损坏的TransformState对象
|
||||
from panda3d.core import TransformState
|
||||
TransformState.clear_cache()
|
||||
|
||||
taskMgr.step()
|
||||
self.qMeta3DWidget.update()
|
||||
except AssertionError as e:
|
||||
# 专门处理 TransformState has_mat() 断言错误
|
||||
if "has_mat" in str(e):
|
||||
print(f"警告: 检测到TransformState断言错误,已静默处理: {e}")
|
||||
# 尝试恢复渲染状态
|
||||
try:
|
||||
# 强制清理缓存并重试
|
||||
from panda3d.core import TransformState, RenderState
|
||||
TransformState.clear_cache()
|
||||
RenderState.clear_cache()
|
||||
taskMgr.step()
|
||||
self.qMeta3DWidget.update()
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
# 重新抛出其他断言错误
|
||||
raise
|
||||
except Exception as e:
|
||||
# 静默处理其他所有异常
|
||||
print(f"警告: 检测到异常,已静默处理: {e}")
|
||||
|
||||
|
||||
def get_panda_key_modifiers(evt):
|
||||
panda_mods = []
|
||||
qt_mods = evt.modifiers()
|
||||
for qt_mod, panda_mod in QMeta3D_Modifier_translation.items():
|
||||
if (qt_mods & qt_mod) == qt_mod:
|
||||
panda_mods.append(panda_mod)
|
||||
return panda_mods
|
||||
|
||||
|
||||
def get_panda_key_modifiers_prefix(evt):
|
||||
# join all modifiers (except NoModifier, which is None) with '-'
|
||||
prefix = "-".join([mod for mod in get_panda_key_modifiers(evt) if mod is not None])
|
||||
|
||||
# if the prefix is not empty, append a '-'
|
||||
if prefix:
|
||||
prefix += '-'
|
||||
|
||||
return prefix
|
||||
|
||||
|
||||
class QMeta3DWidget(QWidget):
|
||||
def __init__(self, Meta3DWorld, parent=None, FPS=60, debug=False):
|
||||
QWidget.__init__(self, parent)
|
||||
self.rp_sync_requested = False
|
||||
# set fixed geometry
|
||||
self.Meta3DWorld = Meta3DWorld
|
||||
self.Meta3DWorld.set_parent(self)
|
||||
# Setup a timer in Qt that runs taskMgr.step() to simulate Panda's own main loop
|
||||
# pandaTimer = QTimer(self)
|
||||
# pandaTimer.timeout.connect()
|
||||
# pandaTimer.start(0)
|
||||
|
||||
self.setFocusPolicy(Qt.StrongFocus)
|
||||
|
||||
# Setup another timer that redraws this widget in a specific FPS
|
||||
# redrawTimer = QTimer(self)
|
||||
# redrawTimer.timeout.connect(self.update)
|
||||
# redrawTimer.start(1000/FPS)
|
||||
|
||||
self.paintSurface = QPainter()
|
||||
self.rotate = QTransform()
|
||||
self.rotate.rotate(180)
|
||||
self.out_image = QImage()
|
||||
|
||||
size = self.Meta3DWorld.cam.node().get_lens().get_film_size()
|
||||
self.initial_film_size = QSizeF(size.x, size.y)
|
||||
self.initial_size = self.size()
|
||||
|
||||
self.synchronizer = QMeta3DSynchronizer(self, FPS)
|
||||
self.synchronizer.start()
|
||||
|
||||
self.debug = debug
|
||||
|
||||
def mousePressEvent(self, evt):
|
||||
button = evt.button()
|
||||
try:
|
||||
b = "{}{}".format(get_panda_key_modifiers_prefix(evt), QMeta3D_Button_translation[button])
|
||||
if self.debug:
|
||||
print(b)
|
||||
messenger.send(b,[{"x":evt.x(),"y":evt.y()}])
|
||||
except:
|
||||
print("Unimplemented button. Please send an issue on github to fix this problem")
|
||||
|
||||
def mouseMoveEvent(self, evt:QtGui.QMouseEvent):
|
||||
button = evt.button()
|
||||
try:
|
||||
b = "mouse-move"
|
||||
if self.debug:
|
||||
print(b)
|
||||
messenger.send(b,[{"x":evt.x(),"y":evt.y()}])
|
||||
except:
|
||||
print("Unimplemented button. Please send an issue on github to fix this problem")
|
||||
|
||||
|
||||
def mouseReleaseEvent(self, evt):
|
||||
button = evt.button()
|
||||
try:
|
||||
b = "{}{}-up".format(get_panda_key_modifiers_prefix(evt), QMeta3D_Button_translation[button])
|
||||
if self.debug:
|
||||
print(b)
|
||||
messenger.send(b,[{"x":evt.x(),"y":evt.y()}])
|
||||
except:
|
||||
print("Unimplemented button. Please send an issue on github to fix this problem")
|
||||
|
||||
def wheelEvent(self, evt):
|
||||
delta = evt.angleDelta().y()
|
||||
try:
|
||||
if self.debug:
|
||||
print(f"wheel {delta}")
|
||||
messenger.send('wheel',[{"delta":delta}])
|
||||
except:
|
||||
print("Unimplemented button. Please send an issue on github to fix this problem")
|
||||
|
||||
def keyPressEvent(self, evt):
|
||||
key = evt.key()
|
||||
try:
|
||||
k = "{}{}".format(get_panda_key_modifiers_prefix(evt), QMeta3D_Key_translation[key])
|
||||
if self.debug:
|
||||
print(k)
|
||||
messenger.send(k)
|
||||
except:
|
||||
print("Unimplemented key. Please send an issue on github to fix this problem")
|
||||
|
||||
def keyReleaseEvent(self, evt):
|
||||
key = evt.key()
|
||||
try:
|
||||
k = "{}{}-up".format(get_panda_key_modifiers_prefix(evt), QMeta3D_Key_translation[key])
|
||||
if self.debug:
|
||||
print(k)
|
||||
messenger.send(k)
|
||||
except:
|
||||
print("Unimplemented key. Please send an issue on github to fix this problem")
|
||||
|
||||
def resizeEvent(self, evt):
|
||||
width = evt.size().width()
|
||||
height = evt.size().height()
|
||||
#print(f"width:{width}")
|
||||
#print(f"height:{height}")
|
||||
|
||||
from Meta3DWorld import resize_buffer
|
||||
|
||||
lens = self.Meta3DWorld.cam.node().get_lens()
|
||||
|
||||
def minimumSizeHint(self):
|
||||
return QSize(400, 300)
|
||||
|
||||
def paintEvent(self, event):
|
||||
tex = self.Meta3DWorld.qt_output_tex
|
||||
gsg = base.win.getGsg()
|
||||
|
||||
if not gsg:
|
||||
self.update()
|
||||
return
|
||||
|
||||
if not tex.hasRamImage():
|
||||
base.graphicsEngine.extractTextureData(tex, gsg)
|
||||
self.update()
|
||||
return
|
||||
|
||||
data = tex.getRamImage().getData()
|
||||
tex_width = tex.getXSize()
|
||||
tex_height = tex.getYSize()
|
||||
expected_len = tex_width * tex_height * 4
|
||||
|
||||
if len(data) != expected_len:
|
||||
print(f"⚠️ 像素数据长度异常({len(data)} != {expected_len}),跳过绘制")
|
||||
self.update()
|
||||
return
|
||||
|
||||
img = QImage(data, tex_width, tex_height, QImage.Format_ARGB32).mirrored()
|
||||
|
||||
widget_width = self.width()
|
||||
widget_height = self.height()
|
||||
|
||||
painter = QPainter(self)
|
||||
|
||||
# 【保持宽高比的缩放】
|
||||
scaled_img = img.scaled(widget_width, widget_height, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
||||
|
||||
# 居中绘制
|
||||
x_offset = (widget_width - scaled_img.width()) // 2
|
||||
y_offset = (widget_height - scaled_img.height()) // 2
|
||||
|
||||
painter.drawImage(x_offset, y_offset, scaled_img)
|
||||
painter.end()
|
||||
|
||||
def sync_Meta3d_window_size(self, width, height):
|
||||
try:
|
||||
from panda3d.core import WindowProperties, LVecBase2i
|
||||
|
||||
# 确保尺寸是4的倍数(RenderPipeline 要求)
|
||||
adjusted_width = width - width % 4
|
||||
adjusted_height = height - height % 4
|
||||
|
||||
# 更新窗口属性
|
||||
props = WindowProperties()
|
||||
props.setSize(adjusted_width, adjusted_height)
|
||||
|
||||
# 对于 offscreen 渲染,直接更新窗口属性
|
||||
if self.Meta3DWorld.win:
|
||||
self.Meta3DWorld.win.request_properties(props)
|
||||
|
||||
# 手动触发 RenderPipeline 的尺寸更新逻辑
|
||||
if hasattr(self.Meta3DWorld, 'render_pipeline'):
|
||||
# 更新全局分辨率
|
||||
from RenderPipelineFile.rpcore.globals import Globals
|
||||
Globals.native_resolution = LVecBase2i(adjusted_width, adjusted_height)
|
||||
|
||||
# 重新计算渲染分辨率
|
||||
self.Meta3DWorld.render_pipeline._compute_render_resolution()
|
||||
|
||||
# 通知各个管理器处理尺寸变化
|
||||
self.Meta3DWorld.render_pipeline.light_mgr.compute_tile_size()
|
||||
self.Meta3DWorld.render_pipeline.stage_mgr.handle_window_resize()
|
||||
if hasattr(self.Meta3DWorld.render_pipeline, 'debugger'):
|
||||
self.Meta3DWorld.render_pipeline.debugger.handle_window_resize()
|
||||
|
||||
# 触发插件的窗口尺寸变化钩子
|
||||
self.Meta3DWorld.render_pipeline.plugin_mgr.trigger_hook("window_resized")
|
||||
except Exception as e:
|
||||
print(f"同步 Meta3D 窗口尺寸失败: {str(e)}")
|
||||
@ -1,43 +0,0 @@
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtWidgets import *
|
||||
import sys
|
||||
__all__ = ["QMeta3D_Keys_Translation.py"]
|
||||
|
||||
QMeta3D_Button_translation ={
|
||||
Qt.NoButton:'',
|
||||
Qt.AllButtons:'unknown',
|
||||
Qt.LeftButton:'mouse1',
|
||||
Qt.RightButton:'mouse2',
|
||||
Qt.MidButton:'mouse3',
|
||||
Qt.MiddleButton:'mouse3',
|
||||
Qt.BackButton:'unknown',
|
||||
Qt.XButton1:'unknown',
|
||||
Qt.ExtraButton1:'unknown',
|
||||
Qt.ForwardButton:'unknown',
|
||||
Qt.XButton2:'unknown',
|
||||
Qt.ExtraButton2:'unknown',
|
||||
Qt.TaskButton:'unknown',
|
||||
Qt.ExtraButton3:'unknown',
|
||||
Qt.ExtraButton4:'unknown',
|
||||
Qt.ExtraButton5:'unknown',
|
||||
Qt.ExtraButton6:'unknown',
|
||||
Qt.ExtraButton7:'unknown',
|
||||
Qt.ExtraButton8:'unknown',
|
||||
Qt.ExtraButton9:'unknown',
|
||||
Qt.ExtraButton10:'unknown',
|
||||
Qt.ExtraButton11:'unknown',
|
||||
Qt.ExtraButton12:'unknown',
|
||||
Qt.ExtraButton13:'unknown',
|
||||
Qt.ExtraButton14:'unknown',
|
||||
Qt.ExtraButton15:'unknown',
|
||||
Qt.ExtraButton16:'unknown',
|
||||
Qt.ExtraButton17:'unknown',
|
||||
Qt.ExtraButton18:'unknown',
|
||||
Qt.ExtraButton19:'unknown',
|
||||
Qt.ExtraButton20:'unknown',
|
||||
Qt.ExtraButton21:'unknown',
|
||||
Qt.ExtraButton22:'unknown',
|
||||
Qt.ExtraButton23:'unknown',
|
||||
Qt.ExtraButton24:'unknown',
|
||||
}
|
||||
@ -1,477 +0,0 @@
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtWidgets import *
|
||||
import sys
|
||||
__all__ = ["QMeta3D_Keys_Translation.py"]
|
||||
|
||||
QMeta3D_Key_translation ={
|
||||
Qt.Key_0:'0',
|
||||
Qt.Key_1:'1',
|
||||
Qt.Key_2:'2',
|
||||
Qt.Key_3:'3',
|
||||
Qt.Key_4:'4',
|
||||
Qt.Key_5:'5',
|
||||
Qt.Key_6:'6',
|
||||
Qt.Key_7:'7',
|
||||
Qt.Key_8:'8',
|
||||
Qt.Key_9:'9',
|
||||
Qt.Key_A:'a',
|
||||
Qt.Key_AE:'ae',
|
||||
Qt.Key_Aacute:'unknown',
|
||||
Qt.Key_Acircumflex:'unknown',
|
||||
Qt.Key_AddFavorite:'unknown',
|
||||
Qt.Key_Adiaeresis:'unknown',
|
||||
Qt.Key_Agrave:'unknown',
|
||||
Qt.Key_Alt:'lalt',
|
||||
Qt.Key_AltGr:'unknown',
|
||||
Qt.Key_Ampersand:'unknown',
|
||||
Qt.Key_Any:'unknown',
|
||||
Qt.Key_Apostrophe:'unknown',
|
||||
Qt.Key_ApplicationLeft:'unknown',
|
||||
Qt.Key_ApplicationRight:'unknown',
|
||||
Qt.Key_Aring:'unknown',
|
||||
Qt.Key_AsciiCircum:'unknown',
|
||||
Qt.Key_AsciiTilde:'unknown',
|
||||
Qt.Key_Asterisk:'unknown',
|
||||
Qt.Key_At:'unknown',
|
||||
Qt.Key_Atilde:'unknown',
|
||||
Qt.Key_AudioCycleTrack:'unknown',
|
||||
Qt.Key_AudioForward:'unknown',
|
||||
Qt.Key_AudioRandomPlay:'unknown',
|
||||
Qt.Key_AudioRepeat:'unknown',
|
||||
Qt.Key_AudioRewind:'unknown',
|
||||
Qt.Key_Away:'unknown',
|
||||
Qt.Key_B:'b',
|
||||
Qt.Key_Back:'unknown',
|
||||
Qt.Key_BackForward:'unknown',
|
||||
Qt.Key_Backslash:'unknown',
|
||||
Qt.Key_Backspace:'unknown',
|
||||
Qt.Key_Backtab:'unknown',
|
||||
Qt.Key_Bar:'unknown',
|
||||
Qt.Key_BassBoost:'unknown',
|
||||
Qt.Key_BassDown:'unknown',
|
||||
Qt.Key_BassUp:'unknown',
|
||||
Qt.Key_Battery:'unknown',
|
||||
Qt.Key_Blue:'unknown',
|
||||
Qt.Key_Bluetooth:'unknown',
|
||||
Qt.Key_Book:'unknown',
|
||||
Qt.Key_BraceLeft:'unknown',
|
||||
Qt.Key_BraceRight:'unknown',
|
||||
Qt.Key_BracketLeft:'unknown',
|
||||
Qt.Key_BracketRight:'unknown',
|
||||
Qt.Key_BrightnessAdjust:'unknown',
|
||||
Qt.Key_C:'c',
|
||||
Qt.Key_CD:'unknown',
|
||||
Qt.Key_Calculator:'unknown',
|
||||
Qt.Key_Calendar:'unknown',
|
||||
Qt.Key_Call:'unknown',
|
||||
Qt.Key_Camera:'unknown',
|
||||
Qt.Key_CameraFocus:'unknown',
|
||||
Qt.Key_Cancel:'unknown',
|
||||
Qt.Key_CapsLock:'unknown',
|
||||
Qt.Key_Ccedilla:'unknown',
|
||||
Qt.Key_ChannelDown:'unknown',
|
||||
Qt.Key_ChannelUp:'unknown',
|
||||
Qt.Key_Clear:'unknown',
|
||||
Qt.Key_ClearGrab:'unknown',
|
||||
Qt.Key_Close:'unknown',
|
||||
Qt.Key_Codeinput:'unknown',
|
||||
Qt.Key_Colon:'unknown',
|
||||
Qt.Key_Comma:'unknown',
|
||||
Qt.Key_Community:'unknown',
|
||||
Qt.Key_Context1:'unknown',
|
||||
Qt.Key_Context2:'unknown',
|
||||
Qt.Key_Context3:'unknown',
|
||||
Qt.Key_Context4:'unknown',
|
||||
Qt.Key_ContrastAdjust:'unknown',
|
||||
Qt.Key_Control:'control',
|
||||
Qt.Key_Copy:'unknown',
|
||||
Qt.Key_Cut:'unknown',
|
||||
Qt.Key_D:'d',
|
||||
Qt.Key_DOS:'unknown',
|
||||
Qt.Key_Dead_A:'unknown',
|
||||
Qt.Key_Dead_Abovecomma:'unknown',
|
||||
Qt.Key_Dead_Abovedot:'unknown',
|
||||
Qt.Key_Dead_Abovereversedcomma:'unknown',
|
||||
Qt.Key_Dead_Abovering:'unknown',
|
||||
Qt.Key_Dead_Aboveverticalline:'unknown',
|
||||
Qt.Key_Dead_Acute:'unknown',
|
||||
Qt.Key_Dead_Belowbreve:'unknown',
|
||||
Qt.Key_Dead_Belowcircumflex:'unknown',
|
||||
Qt.Key_Dead_Belowcomma:'unknown',
|
||||
Qt.Key_Dead_Belowdiaeresis:'unknown',
|
||||
Qt.Key_Dead_Belowdot:'unknown',
|
||||
Qt.Key_Dead_Belowmacron:'unknown',
|
||||
Qt.Key_Dead_Belowring:'unknown',
|
||||
Qt.Key_Dead_Belowtilde:'unknown',
|
||||
Qt.Key_Dead_Belowverticalline:'unknown',
|
||||
Qt.Key_Dead_Breve:'unknown',
|
||||
Qt.Key_Dead_Capital_Schwa:'unknown',
|
||||
Qt.Key_Dead_Caron:'unknown',
|
||||
Qt.Key_Dead_Cedilla:'unknown',
|
||||
Qt.Key_Dead_Circumflex:'unknown',
|
||||
Qt.Key_Dead_Currency:'unknown',
|
||||
Qt.Key_Dead_Diaeresis:'unknown',
|
||||
Qt.Key_Dead_Doubleacute:'unknown',
|
||||
Qt.Key_Dead_Doublegrave:'unknown',
|
||||
Qt.Key_Dead_E:'unknown',
|
||||
Qt.Key_Dead_Grave:'unknown',
|
||||
Qt.Key_Dead_Greek:'unknown',
|
||||
Qt.Key_Dead_Hook:'unknown',
|
||||
Qt.Key_Dead_Horn:'unknown',
|
||||
Qt.Key_Dead_I:'unknown',
|
||||
Qt.Key_Dead_Invertedbreve:'unknown',
|
||||
Qt.Key_Dead_Iota:'unknown',
|
||||
Qt.Key_Dead_Longsolidusoverlay:'unknown',
|
||||
Qt.Key_Dead_Lowline:'unknown',
|
||||
Qt.Key_Dead_Macron:'unknown',
|
||||
Qt.Key_Dead_O:'unknown',
|
||||
Qt.Key_Dead_Ogonek:'unknown',
|
||||
Qt.Key_Dead_Semivoiced_Sound:'unknown',
|
||||
Qt.Key_Dead_Small_Schwa:'unknown',
|
||||
Qt.Key_Dead_Stroke:'unknown',
|
||||
Qt.Key_Dead_Tilde:'unknown',
|
||||
Qt.Key_Dead_U:'unknown',
|
||||
Qt.Key_Dead_Voiced_Sound:'unknown',
|
||||
Qt.Key_Dead_a:'unknown',
|
||||
Qt.Key_Dead_e:'unknown',
|
||||
Qt.Key_Dead_i:'unknown',
|
||||
Qt.Key_Dead_o:'unknown',
|
||||
Qt.Key_Dead_u:'unknown',
|
||||
Qt.Key_Delete:'delete',
|
||||
Qt.Key_Direction_L:'unknown',
|
||||
Qt.Key_Direction_R:'unknown',
|
||||
Qt.Key_Display:'unknown',
|
||||
Qt.Key_Documents:'unknown',
|
||||
Qt.Key_Dollar:'unknown',
|
||||
Qt.Key_Down:'arrow_down',
|
||||
Qt.Key_E:'e',
|
||||
Qt.Key_ETH:'unknown',
|
||||
Qt.Key_Eacute:'unknown',
|
||||
Qt.Key_Ecircumflex:'unknown',
|
||||
Qt.Key_Ediaeresis:'unknown',
|
||||
Qt.Key_Egrave:'unknown',
|
||||
Qt.Key_Eisu_Shift:'unknown',
|
||||
Qt.Key_Eisu_toggle:'unknown',
|
||||
Qt.Key_Eject:'unknown',
|
||||
Qt.Key_End:'unknown',
|
||||
Qt.Key_Enter:'unknown',
|
||||
Qt.Key_Equal:'unknown',
|
||||
Qt.Key_Escape:'escape',
|
||||
Qt.Key_Excel:'unknown',
|
||||
Qt.Key_Exclam:'unknown',
|
||||
Qt.Key_Execute:'unknown',
|
||||
Qt.Key_Exit:'unknown',
|
||||
Qt.Key_Explorer:'unknown',
|
||||
Qt.Key_F:'f',
|
||||
Qt.Key_F1:'f1',
|
||||
Qt.Key_F10:'f10',
|
||||
Qt.Key_F11:'f11',
|
||||
Qt.Key_F12:'f12',
|
||||
Qt.Key_F13:'f13',
|
||||
Qt.Key_F14:'f14',
|
||||
Qt.Key_F15:'f15',
|
||||
Qt.Key_F16:'f16',
|
||||
Qt.Key_F17:'f17',
|
||||
Qt.Key_F18:'f18',
|
||||
Qt.Key_F19:'unknown',
|
||||
Qt.Key_F2:'unknown',
|
||||
Qt.Key_F20:'unknown',
|
||||
Qt.Key_F21:'unknown',
|
||||
Qt.Key_F22:'unknown',
|
||||
Qt.Key_F23:'unknown',
|
||||
Qt.Key_F24:'unknown',
|
||||
Qt.Key_F25:'unknown',
|
||||
Qt.Key_F26:'unknown',
|
||||
Qt.Key_F27:'unknown',
|
||||
Qt.Key_F28:'unknown',
|
||||
Qt.Key_F29:'unknown',
|
||||
Qt.Key_F3:'f3',
|
||||
Qt.Key_F30:'unknown',
|
||||
Qt.Key_F31:'unknown',
|
||||
Qt.Key_F32:'unknown',
|
||||
Qt.Key_F33:'unknown',
|
||||
Qt.Key_F34:'unknown',
|
||||
Qt.Key_F35:'unknown',
|
||||
Qt.Key_F4:'f4',
|
||||
Qt.Key_F5:'f5',
|
||||
Qt.Key_F6:'f6',
|
||||
Qt.Key_F7:'f7',
|
||||
Qt.Key_F8:'f8',
|
||||
Qt.Key_F9:'f9',
|
||||
Qt.Key_Favorites:'unknown',
|
||||
Qt.Key_Finance:'unknown',
|
||||
Qt.Key_Find:'unknown',
|
||||
Qt.Key_Flip:'unknown',
|
||||
Qt.Key_Forward:'unknown',
|
||||
Qt.Key_G:'g',
|
||||
Qt.Key_Game:'unknown',
|
||||
Qt.Key_Go:'unknown',
|
||||
Qt.Key_Greater:'unknown',
|
||||
Qt.Key_Green:'unknown',
|
||||
Qt.Key_Guide:'unknown',
|
||||
Qt.Key_H:'h',
|
||||
Qt.Key_Hangul:'unknown',
|
||||
Qt.Key_Hangul_Banja:'unknown',
|
||||
Qt.Key_Hangul_End:'unknown',
|
||||
Qt.Key_Hangul_Hanja:'unknown',
|
||||
Qt.Key_Hangul_Jamo:'unknown',
|
||||
Qt.Key_Hangul_Jeonja:'unknown',
|
||||
Qt.Key_Hangul_PostHanja:'unknown',
|
||||
Qt.Key_Hangul_PreHanja:'unknown',
|
||||
Qt.Key_Hangul_Romaja:'unknown',
|
||||
Qt.Key_Hangul_Special:'unknown',
|
||||
Qt.Key_Hangul_Start:'unknown',
|
||||
Qt.Key_Hangup:'unknown',
|
||||
Qt.Key_Hankaku:'unknown',
|
||||
Qt.Key_Help:'unknown',
|
||||
Qt.Key_Henkan:'unknown',
|
||||
Qt.Key_Hibernate:'unknown',
|
||||
Qt.Key_Hiragana:'unknown',
|
||||
Qt.Key_Hiragana_Katakana:'unknown',
|
||||
Qt.Key_History:'unknown',
|
||||
Qt.Key_Home:'home',
|
||||
Qt.Key_HomePage:'unknown',
|
||||
Qt.Key_HotLinks:'unknown',
|
||||
Qt.Key_Hyper_L:'unknown',
|
||||
Qt.Key_Hyper_R:'unknown',
|
||||
Qt.Key_I:'i',
|
||||
Qt.Key_Iacute:'unknown',
|
||||
Qt.Key_Icircumflex:'unknown',
|
||||
Qt.Key_Idiaeresis:'unknown',
|
||||
Qt.Key_Igrave:'unknown',
|
||||
Qt.Key_Info:'unknown',
|
||||
Qt.Key_Insert:'unknown',
|
||||
Qt.Key_J:'j',
|
||||
Qt.Key_K:'k',
|
||||
Qt.Key_Kana_Lock:'unknown',
|
||||
Qt.Key_Kana_Shift:'unknown',
|
||||
Qt.Key_Kanji:'unknown',
|
||||
Qt.Key_Katakana:'unknown',
|
||||
Qt.Key_KeyboardBrightnessDown:'unknown',
|
||||
Qt.Key_KeyboardBrightnessUp:'unknown',
|
||||
Qt.Key_KeyboardLightOnOff:'unknown',
|
||||
Qt.Key_L:'l',
|
||||
Qt.Key_LastNumberRedial:'unknown',
|
||||
Qt.Key_Launch0:'unknown',
|
||||
Qt.Key_Launch1:'unknown',
|
||||
Qt.Key_Launch2:'unknown',
|
||||
Qt.Key_Launch3:'unknown',
|
||||
Qt.Key_Launch4:'unknown',
|
||||
Qt.Key_Launch5:'unknown',
|
||||
Qt.Key_Launch6:'unknown',
|
||||
Qt.Key_Launch7:'unknown',
|
||||
Qt.Key_Launch8:'unknown',
|
||||
Qt.Key_Launch9:'unknown',
|
||||
Qt.Key_LaunchA:'unknown',
|
||||
Qt.Key_LaunchB:'unknown',
|
||||
Qt.Key_LaunchC:'unknown',
|
||||
Qt.Key_LaunchD:'unknown',
|
||||
Qt.Key_LaunchE:'unknown',
|
||||
Qt.Key_LaunchF:'unknown',
|
||||
Qt.Key_LaunchG:'unknown',
|
||||
Qt.Key_LaunchH:'unknown',
|
||||
Qt.Key_LaunchMail:'unknown',
|
||||
Qt.Key_LaunchMedia:'unknown',
|
||||
Qt.Key_Left:'arrow_left',
|
||||
Qt.Key_Less:'unknown',
|
||||
Qt.Key_LightBulb:'unknown',
|
||||
Qt.Key_LogOff:'unknown',
|
||||
Qt.Key_M:'m',
|
||||
Qt.Key_MailForward:'unknown',
|
||||
Qt.Key_Market:'unknown',
|
||||
Qt.Key_Massyo:'unknown',
|
||||
Qt.Key_MediaLast:'unknown',
|
||||
Qt.Key_MediaNext:'unknown',
|
||||
Qt.Key_MediaPause:'unknown',
|
||||
Qt.Key_MediaPlay:'unknown',
|
||||
Qt.Key_MediaPrevious:'unknown',
|
||||
Qt.Key_MediaRecord:'unknown',
|
||||
Qt.Key_MediaStop:'unknown',
|
||||
Qt.Key_MediaTogglePlayPause:'unknown',
|
||||
Qt.Key_Meeting:'unknown',
|
||||
Qt.Key_Memo:'unknown',
|
||||
Qt.Key_Menu:'unknown',
|
||||
Qt.Key_MenuKB:'unknown',
|
||||
Qt.Key_MenuPB:'unknown',
|
||||
Qt.Key_Messenger:'unknown',
|
||||
Qt.Key_Meta:'unknown',
|
||||
Qt.Key_MicMute:'unknown',
|
||||
Qt.Key_MicVolumeDown:'unknown',
|
||||
Qt.Key_MicVolumeUp:'unknown',
|
||||
Qt.Key_Minus:'unknown',
|
||||
Qt.Key_Mode_switch:'unknown',
|
||||
Qt.Key_MonBrightnessDown:'unknown',
|
||||
Qt.Key_MonBrightnessUp:'unknown',
|
||||
Qt.Key_Muhenkan:'unknown',
|
||||
Qt.Key_Multi_key:'unknown',
|
||||
Qt.Key_MultipleCandidate:'unknown',
|
||||
Qt.Key_Music:'unknown',
|
||||
Qt.Key_MySites:'unknown',
|
||||
Qt.Key_N:'n',
|
||||
Qt.Key_New:'unknown',
|
||||
Qt.Key_News:'unknown',
|
||||
Qt.Key_No:'unknown',
|
||||
Qt.Key_Ntilde:'unknown',
|
||||
Qt.Key_NumLock:'unknown',
|
||||
Qt.Key_NumberSign:'unknown',
|
||||
Qt.Key_O:'o',
|
||||
Qt.Key_Oacute:'unknown',
|
||||
Qt.Key_Ocircumflex:'unknown',
|
||||
Qt.Key_Odiaeresis:'unknown',
|
||||
Qt.Key_OfficeHome:'unknown',
|
||||
Qt.Key_Ograve:'unknown',
|
||||
Qt.Key_Ooblique:'unknown',
|
||||
Qt.Key_Open:'unknown',
|
||||
Qt.Key_OpenUrl:'unknown',
|
||||
Qt.Key_Option:'unknown',
|
||||
Qt.Key_Otilde:'unknown',
|
||||
Qt.Key_P:'p',
|
||||
Qt.Key_PageDown:'unknown',
|
||||
Qt.Key_PageUp:'unknown',
|
||||
Qt.Key_ParenLeft:'unknown',
|
||||
Qt.Key_ParenRight:'unknown',
|
||||
Qt.Key_Paste:'unknown',
|
||||
Qt.Key_Pause:'unknown',
|
||||
Qt.Key_Percent:'unknown',
|
||||
Qt.Key_Period:'unknown',
|
||||
Qt.Key_Phone:'unknown',
|
||||
Qt.Key_Pictures:'unknown',
|
||||
Qt.Key_Play:'unknown',
|
||||
Qt.Key_Plus:'unknown',
|
||||
Qt.Key_PowerDown:'unknown',
|
||||
Qt.Key_PowerOff:'unknown',
|
||||
Qt.Key_PreviousCandidate:'unknown',
|
||||
Qt.Key_Print:'unknown',
|
||||
Qt.Key_Printer:'unknown',
|
||||
Qt.Key_Q:'q',
|
||||
Qt.Key_Question:'unknown',
|
||||
Qt.Key_QuoteDbl:'unknown',
|
||||
Qt.Key_QuoteLeft:'unknown',
|
||||
Qt.Key_R:'r',
|
||||
Qt.Key_Red:'unknown',
|
||||
Qt.Key_Redo:'unknown',
|
||||
Qt.Key_Refresh:'unknown',
|
||||
Qt.Key_Reload:'unknown',
|
||||
Qt.Key_Reply:'unknown',
|
||||
Qt.Key_Return:'unknown',
|
||||
Qt.Key_Right:'arrow_right',
|
||||
Qt.Key_Romaji:'unknown',
|
||||
Qt.Key_RotateWindows:'unknown',
|
||||
Qt.Key_RotationKB:'unknown',
|
||||
Qt.Key_RotationPB:'unknown',
|
||||
Qt.Key_S:'s',
|
||||
Qt.Key_Save:'unknown',
|
||||
Qt.Key_ScreenSaver:'unknown',
|
||||
Qt.Key_ScrollLock:'unknown',
|
||||
Qt.Key_Search:'unknown',
|
||||
Qt.Key_Select:'unknown',
|
||||
Qt.Key_Semicolon:'unknown',
|
||||
Qt.Key_Send:'unknown',
|
||||
Qt.Key_Settings:'unknown',
|
||||
Qt.Key_Shift:'unknown',
|
||||
Qt.Key_Shop:'unknown',
|
||||
Qt.Key_SingleCandidate:'unknown',
|
||||
Qt.Key_Slash:'unknown',
|
||||
Qt.Key_Sleep:'unknown',
|
||||
Qt.Key_Space:'space',
|
||||
Qt.Key_Spell:'unknown',
|
||||
Qt.Key_SplitScreen:'unknown',
|
||||
Qt.Key_Standby:'unknown',
|
||||
Qt.Key_Stop:'unknown',
|
||||
Qt.Key_Subtitle:'unknown',
|
||||
Qt.Key_Super_L:'unknown',
|
||||
Qt.Key_Super_R:'unknown',
|
||||
Qt.Key_Support:'unknown',
|
||||
Qt.Key_Suspend:'unknown',
|
||||
Qt.Key_SysReq:'unknown',
|
||||
Qt.Key_T:'t',
|
||||
Qt.Key_THORN:'unknown',
|
||||
Qt.Key_Tab:'unknown',
|
||||
Qt.Key_TaskPane:'unknown',
|
||||
Qt.Key_Terminal:'unknown',
|
||||
Qt.Key_Time:'unknown',
|
||||
Qt.Key_ToDoList:'unknown',
|
||||
Qt.Key_ToggleCallHangup:'unknown',
|
||||
Qt.Key_Tools:'unknown',
|
||||
Qt.Key_TopMenu:'unknown',
|
||||
Qt.Key_TouchpadOff:'unknown',
|
||||
Qt.Key_TouchpadOn:'unknown',
|
||||
Qt.Key_TouchpadToggle:'unknown',
|
||||
Qt.Key_Touroku:'unknown',
|
||||
Qt.Key_Travel:'unknown',
|
||||
Qt.Key_TrebleDown:'unknown',
|
||||
Qt.Key_TrebleUp:'unknown',
|
||||
Qt.Key_U:'u',
|
||||
Qt.Key_UWB:'unknown',
|
||||
Qt.Key_Uacute:'unknown',
|
||||
Qt.Key_Ucircumflex:'unknown',
|
||||
Qt.Key_Udiaeresis:'unknown',
|
||||
Qt.Key_Ugrave:'unknown',
|
||||
Qt.Key_Underscore:'unknown',
|
||||
Qt.Key_Undo:'unknown',
|
||||
Qt.Key_Up:'arrow_up',
|
||||
Qt.Key_V:'v',
|
||||
Qt.Key_Video:'unknown',
|
||||
Qt.Key_View:'unknown',
|
||||
Qt.Key_VoiceDial:'unknown',
|
||||
Qt.Key_VolumeDown:'unknown',
|
||||
Qt.Key_VolumeMute:'unknown',
|
||||
Qt.Key_VolumeUp:'unknown',
|
||||
Qt.Key_W:'w',
|
||||
Qt.Key_WLAN:'unknown',
|
||||
Qt.Key_WWW:'unknown',
|
||||
Qt.Key_WakeUp:'unknown',
|
||||
Qt.Key_WebCam:'unknown',
|
||||
Qt.Key_Word:'unknown',
|
||||
Qt.Key_X:'x',
|
||||
Qt.Key_Xfer:'unknown',
|
||||
Qt.Key_Y:'y',
|
||||
Qt.Key_Yacute:'unknown',
|
||||
Qt.Key_Yellow:'unknown',
|
||||
Qt.Key_Yes:'unknown',
|
||||
Qt.Key_Z:'z',
|
||||
Qt.Key_Zenkaku:'unknown',
|
||||
Qt.Key_Zenkaku_Hankaku:'unknown',
|
||||
Qt.Key_Zoom:'unknown',
|
||||
Qt.Key_ZoomIn:'unknown',
|
||||
Qt.Key_ZoomOut:'unknown',
|
||||
Qt.Key_acute:'unknown',
|
||||
Qt.Key_brokenbar:'unknown',
|
||||
Qt.Key_cedilla:'unknown',
|
||||
Qt.Key_cent:'unknown',
|
||||
Qt.Key_copyright:'unknown',
|
||||
Qt.Key_currency:'unknown',
|
||||
Qt.Key_degree:'unknown',
|
||||
Qt.Key_diaeresis:'unknown',
|
||||
Qt.Key_division:'unknown',
|
||||
Qt.Key_exclamdown:'unknown',
|
||||
Qt.Key_guillemotleft:'unknown',
|
||||
Qt.Key_guillemotright:'unknown',
|
||||
Qt.Key_hyphen:'unknown',
|
||||
Qt.Key_iTouch:'unknown',
|
||||
Qt.Key_macron:'unknown',
|
||||
Qt.Key_masculine:'unknown',
|
||||
Qt.Key_mu:'unknown',
|
||||
Qt.Key_multiply:'unknown',
|
||||
Qt.Key_nobreakspace:'unknown',
|
||||
Qt.Key_notsign:'unknown',
|
||||
Qt.Key_onehalf:'unknown',
|
||||
Qt.Key_onequarter:'unknown',
|
||||
Qt.Key_onesuperior:'unknown',
|
||||
Qt.Key_ordfeminine:'unknown',
|
||||
Qt.Key_paragraph:'unknown',
|
||||
Qt.Key_periodcentered:'unknown',
|
||||
Qt.Key_plusminus:'unknown',
|
||||
Qt.Key_questiondown:'unknown',
|
||||
Qt.Key_registered:'unknown',
|
||||
Qt.Key_section:'unknown',
|
||||
Qt.Key_ssharp:'unknown',
|
||||
Qt.Key_sterling:'unknown',
|
||||
Qt.Key_threequarters:'unknown',
|
||||
Qt.Key_threesuperior:'unknown',
|
||||
Qt.Key_twosuperior:'unknown',
|
||||
Qt.Key_unknown:'unknown',
|
||||
Qt.Key_ydiaeresis:'unknown',
|
||||
Qt.Key_yen:'unknown',
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtWidgets import *
|
||||
import sys
|
||||
__all__ = ["QMeta3D_Modifiers_Translation.py"]
|
||||
|
||||
QMeta3D_Modifier_translation ={
|
||||
Qt.NoModifier:None,
|
||||
Qt.ShiftModifier:'shift',
|
||||
Qt.ControlModifier:'control',
|
||||
Qt.AltModifier:'alt',
|
||||
Qt.MetaModifier:'unknown',
|
||||
Qt.KeypadModifier:'unknown',
|
||||
Qt.GroupSwitchModifier:'unknown',
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtWidgets import *
|
||||
|
||||
from panda3d.core import *
|
||||
|
||||
__all__ = ["QMouseWatcherNode"]
|
||||
|
||||
|
||||
class QMouseWatcherNode(MouseWatcher):
|
||||
def __init__(self, parent):
|
||||
super().__init__()
|
||||
|
||||
self.parent = parent
|
||||
|
||||
def getMouse(self, *args, **kwargs):
|
||||
pos = self.parent.mapFromGlobal(QCursor.pos())
|
||||
|
||||
rel_x = -1 + 2 * pos.x() / self.parent.width()
|
||||
rel_y = -1 + 2 * pos.y() / self.parent.height()
|
||||
|
||||
rel_y = -rel_y
|
||||
|
||||
return LPoint2(rel_x, rel_y)
|
||||
|
||||
def hasMouse(self):
|
||||
return isinstance(self.parent, QWidget)
|
||||
@ -1,2 +0,0 @@
|
||||
name="QMeta3D"
|
||||
__all__ = ["generate_qt_to_pd3d_translator"]
|
||||
@ -1,11 +0,0 @@
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtWidgets import *
|
||||
|
||||
H=Qt.__dict__
|
||||
lst = [a for a in H if a.startswith("Key_")]
|
||||
QMeta3D_Key_translation = "QMeta3D_Key_translation ={"
|
||||
for i in range(len(lst)):
|
||||
QMeta3D_Key_translation += "Qt.{}:'unknown',\n".format(lst[i])
|
||||
QMeta3D_Key_translation += "}"
|
||||
print(QMeta3D_Key_translation)
|
||||
@ -1,2 +0,0 @@
|
||||
name="QMeta3D"
|
||||
__all__ = ["QMeta3DWidget.py", "Meta3DWorld.py", "QMeta3D_Keys_Translation.py"]
|
||||
@ -1,12 +1,12 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PyStubPackagesAdvertiser" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredPackages">
|
||||
<list>
|
||||
<option value="PyQt5-stubs==5.15.6.0" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PyStubPackagesAdvertiser" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredPackages">
|
||||
<list>
|
||||
<option value="PyQt5-stubs==5.15.6.0" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
@ -1,6 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
||||
174
RenderPipelineFile/config/Meta3d-config.prc
Normal file
174
RenderPipelineFile/config/Meta3d-config.prc
Normal file
@ -0,0 +1,174 @@
|
||||
|
||||
|
||||
# This is the config file used to configure basic settings for Panda3D.
|
||||
# The pipeline loads it at startup to ensure the environment is setup properly.
|
||||
|
||||
# -------------- Development options --------------
|
||||
|
||||
pstats-gpu-timing #t
|
||||
gl-debug #t
|
||||
gl-debug-object-labels #t
|
||||
|
||||
# -------------- Production options ---------------
|
||||
|
||||
# pstats-gpu-timing #f
|
||||
# gl-debug #f
|
||||
# gl-debug-object-labels #f
|
||||
|
||||
# ----------------- Misc Settings -----------------
|
||||
|
||||
# Disable V-Sync
|
||||
sync-video #f
|
||||
|
||||
# Limit the pstats-rate. This causes huge lag on windows 10.
|
||||
pstats-max-rate 200
|
||||
|
||||
# No stack trace on assertion, set this to true to make panda crash on assertions
|
||||
# (which will allow to debug it)
|
||||
# assert-abort #t
|
||||
# show-dll-error-dialog #f
|
||||
|
||||
# File system should be case sensitive
|
||||
# NOTICE: Set this to #f if you are using tempfile, since it returns
|
||||
# wrong cased directory paths
|
||||
vfs-case-sensitive #t
|
||||
|
||||
# Enable state cache, this seems to actually help the performance by a lot
|
||||
state-cache #t
|
||||
transform-cache #t
|
||||
|
||||
# Hide frame rate meter (we have our own)
|
||||
show-frame-rate-meter #f
|
||||
|
||||
# Set text settings
|
||||
text-minfilter linear
|
||||
text-magfilter linear
|
||||
text-page-size 512 512
|
||||
text-rwap-mode WM_border_clor
|
||||
|
||||
# Better text performance since rdb's patch
|
||||
text-flatten 0
|
||||
text-dynamic-merge 1
|
||||
|
||||
# For smoother animations
|
||||
# even-animation #t
|
||||
|
||||
# Threading, really buggy!
|
||||
#threading-model App/Cull/Draw
|
||||
|
||||
# Disable stencil, not supported/required
|
||||
support-stencil #f
|
||||
framebuffer-stencil #f
|
||||
|
||||
# Don't use srgb correction, we do that in the final shader
|
||||
framebuffer-srgb #f
|
||||
|
||||
# Don't use multisamples
|
||||
framebuffer-multisample #f
|
||||
multisamples 0
|
||||
|
||||
# Don't rescale textures which are no power-of-2
|
||||
textures-power-2 none
|
||||
|
||||
# Set default texture filters
|
||||
texture-anisotropic-degree 16
|
||||
texture-magfilter linear
|
||||
texture-minfilter linear
|
||||
texture-quality-level fastest
|
||||
|
||||
# Enable seamless cubemap filtering, important for environment filtering
|
||||
gl-cube-map-seamless #t
|
||||
|
||||
# Disable caching of textures
|
||||
model-cache-textures #f
|
||||
|
||||
# Disable the annoying SRGB warning from pnmimage
|
||||
notify-level-pnmimage error
|
||||
|
||||
# Disable the buffer viewer, we have our own
|
||||
show-buffers #f
|
||||
|
||||
# Use the default coordinate system, this makes our matrix transformations
|
||||
# faster because we don't have have to transform them to a different coordinate
|
||||
# system before
|
||||
gl-coordinate-system default
|
||||
|
||||
# This makes animations smoother, especially if they were exported at 30 FPS
|
||||
# and are played at 60 FPS
|
||||
interpolate-frames #t
|
||||
|
||||
# Disable workarround in panda which causes our shadow atlas to take twice
|
||||
# the amount of vram it should, due to an intel driver bug.
|
||||
gl-force-fbo-color #f
|
||||
|
||||
# ----------- OpenGL / Performance Settings ------------
|
||||
|
||||
# Require OpenGL 4.3 at least, necessary for Intel drivers on Linux
|
||||
gl-version 4 3
|
||||
|
||||
# Animations on the gpu. The default shader has to get adjusted to support this
|
||||
# feature before this option can be turned on.
|
||||
# hardware-animated-vertices #t
|
||||
|
||||
# Try this options for performance
|
||||
# uniquify-matrix #t
|
||||
# uniquify-transforms #t
|
||||
# uniquify-states #t
|
||||
# uniquify-attribs #f
|
||||
|
||||
# Enable garbarge collection
|
||||
garbage-collect-states #t
|
||||
# garbage-collect-states-rate 0.2
|
||||
|
||||
# Compress textures on the drivers?
|
||||
# driver-compress-textures #t
|
||||
|
||||
# Faster animations? (Have to test)
|
||||
# matrix-palette #t
|
||||
# display-list-animation #t
|
||||
|
||||
# Better GL performance by not using gl-finish and so on
|
||||
gl-finish #f
|
||||
gl-force-no-error #t
|
||||
gl-check-errors #f
|
||||
gl-force-no-flush #t
|
||||
gl-force-no-scissor #t
|
||||
|
||||
# Eventually disable memory barriers, have to check if this is faster
|
||||
gl-enable-memory-barriers #f
|
||||
|
||||
# Disable threading
|
||||
lock-to-one-cpu #t
|
||||
support-threads #f
|
||||
|
||||
# Let the driver generate the mipmaps
|
||||
driver-generate-mipmaps #t
|
||||
|
||||
# Use immutable texture storage, it is *supposed* to be faster, but might not be
|
||||
# XXX: Seems to produce an GL_INVALID_VALUE when disabled
|
||||
gl-immutable-texture-storage #t
|
||||
|
||||
# Default window settings
|
||||
# depth-bits 0
|
||||
color-bits 0
|
||||
framebuffer-depth #f
|
||||
|
||||
# Small performance gain by specifying fixed vertex attribute locations.
|
||||
# Might cause issues with some (incorrectly converted/loaded) meshes though
|
||||
gl-fixed-vertex-attrib-locations #f
|
||||
|
||||
# Disable the fragment shader performance warning
|
||||
gl-validate-shaders #f
|
||||
gl-skip-shader-recompilation-warnings #t
|
||||
|
||||
alpha-scale-via-texture #f
|
||||
pstats-name Render Pipeline Stats
|
||||
rescale-normals #f
|
||||
screenshot-extension png
|
||||
|
||||
# Required for correct velocity
|
||||
always-store-prev-transform #t
|
||||
allow-incomplete-render #t
|
||||
|
||||
|
||||
no-singular-invert #f
|
||||
File diff suppressed because one or more lines are too long
@ -1,3 +1,5 @@
|
||||
|
||||
|
||||
# This file stores internal settings of the pipeline. It does not contain the
|
||||
# plugin settings, but just the basic settings of the internal pipeline components.
|
||||
pipeline:
|
||||
@ -6,12 +8,12 @@ pipeline:
|
||||
# it will also disable the hotkeys, and give a small performance boost.
|
||||
# Most likely you also don't want to show it in your own game, so set
|
||||
# it to false in that case.
|
||||
display_debugger: False
|
||||
display_debugger: true
|
||||
|
||||
# Affects which debugging information is displayed. If this is set to false,
|
||||
# only frame time is displayed, otherwise much more information is visible.
|
||||
# Has no effect when display_debugger is set to false.
|
||||
advanced_debugging_info: False
|
||||
advanced_debugging_info: true
|
||||
|
||||
# Whether to use the GL_R11F_G11F_B10F texture format to save memory
|
||||
# and bandwidth. Usually you want to enable this, however it can
|
||||
@ -75,8 +77,8 @@ shadows:
|
||||
# getting updated fast enough. However, this also affects the performance
|
||||
# quite a bit, since for every shadow map a part of the scene has
|
||||
# to get re-rendered.
|
||||
max_updates: 16
|
||||
max_updates: 8
|
||||
|
||||
# Sets the maximum distance until which shadows are updated. If a shadow
|
||||
# source is further away, it will no longer recieve updates
|
||||
max_update_distance: 300.0
|
||||
max_update_distance: 150.0
|
||||
|
||||
@ -7,7 +7,6 @@ enabled:
|
||||
- ao
|
||||
- bloom
|
||||
- color_correction
|
||||
- env_probes
|
||||
- forward_shading
|
||||
- motion_blur
|
||||
- pssm
|
||||
@ -16,16 +15,17 @@ enabled:
|
||||
- sky_ao
|
||||
- smaa
|
||||
- ssr
|
||||
- clouds
|
||||
#- dof
|
||||
#- fxaa
|
||||
#- volumetrics
|
||||
#- vxgi
|
||||
# - clouds
|
||||
# - dof
|
||||
- env_probes
|
||||
# - fxaa
|
||||
# - volumetrics
|
||||
# - vxgi
|
||||
|
||||
|
||||
overrides:
|
||||
ao:
|
||||
blur_quality: LOW
|
||||
blur_quality: MEDIUM
|
||||
blur_normal_factor: 2.97
|
||||
blur_depth_factor: 0.88158
|
||||
occlusion_strength: 2.19
|
||||
@ -87,10 +87,10 @@ overrides:
|
||||
sharpen_twice: False
|
||||
|
||||
dof:
|
||||
focal_point: 5
|
||||
focal_size: 1
|
||||
blur_strength: 1
|
||||
near_blur_strength: 1
|
||||
focal_point: 1000.0
|
||||
focal_size: 994.0
|
||||
blur_strength: 0.0
|
||||
near_blur_strength: 0.4286
|
||||
|
||||
env_probes:
|
||||
probe_resolution: 128
|
||||
|
||||
BIN
RenderPipelineFile/core/RotationHandleQuarter.fbx
Executable file
BIN
RenderPipelineFile/core/RotationHandleQuarter.fbx
Executable file
Binary file not shown.
BIN
RenderPipelineFile/core/TranslateArrowHandle.fbx
Executable file
BIN
RenderPipelineFile/core/TranslateArrowHandle.fbx
Executable file
Binary file not shown.
BIN
RenderPipelineFile/core/UniformScaleHandle.fbx
Executable file
BIN
RenderPipelineFile/core/UniformScaleHandle.fbx
Executable file
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
material:
|
||||
name: GroundMaterial
|
||||
base_color: "../Textures/ground_diffuse.png"
|
||||
normal: "../Textures/ground_normal.png"
|
||||
roughness: 0.8
|
||||
metallic: 0.0
|
||||
two_sided: true
|
||||
material:
|
||||
name: GroundMaterial
|
||||
base_color: "../Textures/ground_diffuse.png"
|
||||
normal: "../Textures/ground_normal.png"
|
||||
roughness: 0.8
|
||||
metallic: 0.0
|
||||
two_sided: true
|
||||
|
||||
@ -1,47 +1,47 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
示例脚本 - 演示如何编写脚本
|
||||
"""
|
||||
|
||||
from core.script_system import ScriptBase
|
||||
|
||||
class ExampleScript(ScriptBase):
|
||||
"""示例脚本类"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.counter = 0
|
||||
self.rotation_speed = 30.0 # 度/秒
|
||||
|
||||
def start(self):
|
||||
"""脚本开始时调用"""
|
||||
self.log("示例脚本开始运行!")
|
||||
self.log(f"挂载到对象: {self.gameObject.getName()}")
|
||||
|
||||
def update(self, dt):
|
||||
"""每帧更新"""
|
||||
self.counter += 1
|
||||
|
||||
# 每60帧输出一次信息
|
||||
if self.counter % 60 == 0:
|
||||
self.log(f"运行了 {self.counter} 帧")
|
||||
|
||||
# 让对象旋转
|
||||
if self.transform:
|
||||
current_h = self.transform.getH()
|
||||
new_h = current_h + self.rotation_speed * dt
|
||||
self.transform.setH(new_h)
|
||||
|
||||
def on_destroy(self):
|
||||
"""脚本销毁时调用"""
|
||||
self.log("示例脚本被销毁")
|
||||
|
||||
def on_enable(self):
|
||||
"""脚本启用时调用"""
|
||||
self.log("示例脚本被启用")
|
||||
|
||||
def on_disable(self):
|
||||
"""脚本禁用时调用"""
|
||||
self.log("示例脚本被禁用")
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
示例脚本 - 演示如何编写脚本
|
||||
"""
|
||||
|
||||
from core.script_system import ScriptBase
|
||||
|
||||
class ExampleScript(ScriptBase):
|
||||
"""示例脚本类"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.counter = 0
|
||||
self.rotation_speed = 30.0 # 度/秒
|
||||
|
||||
def start(self):
|
||||
"""脚本开始时调用"""
|
||||
self.log("示例脚本开始运行!")
|
||||
self.log(f"挂载到对象: {self.gameObject.getName()}")
|
||||
|
||||
def update(self, dt):
|
||||
"""每帧更新"""
|
||||
self.counter += 1
|
||||
|
||||
# 每60帧输出一次信息
|
||||
if self.counter % 60 == 0:
|
||||
self.log(f"运行了 {self.counter} 帧")
|
||||
|
||||
# 让对象旋转
|
||||
if self.transform:
|
||||
current_h = self.transform.getH()
|
||||
new_h = current_h + self.rotation_speed * dt
|
||||
self.transform.setH(new_h)
|
||||
|
||||
def on_destroy(self):
|
||||
"""脚本销毁时调用"""
|
||||
self.log("示例脚本被销毁")
|
||||
|
||||
def on_enable(self):
|
||||
"""脚本启用时调用"""
|
||||
self.log("示例脚本被启用")
|
||||
|
||||
def on_disable(self):
|
||||
"""脚本禁用时调用"""
|
||||
self.log("示例脚本被禁用")
|
||||
|
||||
@ -1,35 +1,35 @@
|
||||
# Debug metallic texture effect
|
||||
# This effect visualizes metallic texture directly for debugging
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define DEBUG_METALLIC_TEXTURE 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture5; // Metallic texture
|
||||
|
||||
material: |
|
||||
// Debug: Show metallic texture directly
|
||||
#if DEBUG_METALLIC_TEXTURE
|
||||
// Sample metallic from texture
|
||||
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
|
||||
|
||||
// For debugging: show texture value as colored visualization
|
||||
// Blue tint for non-metallic, yellow tint for metallic
|
||||
vec3 debug_color = mix(vec3(0.2, 0.2, 1.0), vec3(1.0, 1.0, 0.2), sampled_metallic);
|
||||
|
||||
// Apply to material
|
||||
m.basecolor = debug_color; // Show texture as color for debugging
|
||||
m.roughness = 0.5; // Fixed roughness for clear visualization
|
||||
m.metallic = sampled_metallic; // Also apply to metallic
|
||||
m.specular_ior = 1.5;
|
||||
m.shading_model_param0 = 0.0;
|
||||
|
||||
#else
|
||||
// Fallback
|
||||
m.basecolor = mInput.color;
|
||||
m.roughness = mInput.roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
#endif
|
||||
# Debug metallic texture effect
|
||||
# This effect visualizes metallic texture directly for debugging
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define DEBUG_METALLIC_TEXTURE 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture5; // Metallic texture
|
||||
|
||||
material: |
|
||||
// Debug: Show metallic texture directly
|
||||
#if DEBUG_METALLIC_TEXTURE
|
||||
// Sample metallic from texture
|
||||
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
|
||||
|
||||
// For debugging: show texture value as colored visualization
|
||||
// Blue tint for non-metallic, yellow tint for metallic
|
||||
vec3 debug_color = mix(vec3(0.2, 0.2, 1.0), vec3(1.0, 1.0, 0.2), sampled_metallic);
|
||||
|
||||
// Apply to material
|
||||
m.basecolor = debug_color; // Show texture as color for debugging
|
||||
m.roughness = 0.5; // Fixed roughness for clear visualization
|
||||
m.metallic = sampled_metallic; // Also apply to metallic
|
||||
m.specular_ior = 1.5;
|
||||
m.shading_model_param0 = 0.0;
|
||||
|
||||
#else
|
||||
// Fallback
|
||||
m.basecolor = mInput.color;
|
||||
m.roughness = mInput.roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
#endif
|
||||
|
||||
@ -1,35 +1,35 @@
|
||||
# Debug roughness texture effect
|
||||
# This effect visualizes roughness texture directly for debugging
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define DEBUG_ROUGHNESS_TEXTURE 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture3; // Roughness texture
|
||||
|
||||
material: |
|
||||
// Debug: Show roughness texture directly
|
||||
#if DEBUG_ROUGHNESS_TEXTURE
|
||||
// Sample roughness from texture
|
||||
float sampled_roughness = texture(p3d_Texture3, texcoord).x;
|
||||
|
||||
// For debugging: show texture value as grayscale color
|
||||
// This helps verify the texture is being read correctly
|
||||
vec3 debug_color = vec3(sampled_roughness);
|
||||
|
||||
// Apply to material
|
||||
m.basecolor = debug_color; // Show texture as color for debugging
|
||||
m.roughness = sampled_roughness; // Also apply to roughness
|
||||
m.metallic = 0.0; // Keep metallic low for clear visualization
|
||||
m.specular_ior = 1.5;
|
||||
m.shading_model_param0 = 0.0;
|
||||
|
||||
#else
|
||||
// Fallback
|
||||
m.basecolor = mInput.color;
|
||||
m.roughness = mInput.roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
#endif
|
||||
# Debug roughness texture effect
|
||||
# This effect visualizes roughness texture directly for debugging
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define DEBUG_ROUGHNESS_TEXTURE 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture3; // Roughness texture
|
||||
|
||||
material: |
|
||||
// Debug: Show roughness texture directly
|
||||
#if DEBUG_ROUGHNESS_TEXTURE
|
||||
// Sample roughness from texture
|
||||
float sampled_roughness = texture(p3d_Texture3, texcoord).x;
|
||||
|
||||
// For debugging: show texture value as grayscale color
|
||||
// This helps verify the texture is being read correctly
|
||||
vec3 debug_color = vec3(sampled_roughness);
|
||||
|
||||
// Apply to material
|
||||
m.basecolor = debug_color; // Show texture as color for debugging
|
||||
m.roughness = sampled_roughness; // Also apply to roughness
|
||||
m.metallic = 0.0; // Keep metallic low for clear visualization
|
||||
m.specular_ior = 1.5;
|
||||
m.shading_model_param0 = 0.0;
|
||||
|
||||
#else
|
||||
// Fallback
|
||||
m.basecolor = mInput.color;
|
||||
m.roughness = mInput.roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
#endif
|
||||
|
||||
@ -1,39 +1,39 @@
|
||||
# Metallic-only PBR effect
|
||||
# This effect specifically handles metallic textures correctly
|
||||
# Ensures metallic texture is not confused with diffuse texture
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_METALLIC_TEXTURE_ONLY 1
|
||||
#define DONT_FETCH_DEFAULT_TEXTURES 0
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture5; // Metallic texture only
|
||||
|
||||
material: |
|
||||
// Only handle metallic texture, ignore others to avoid confusion
|
||||
#if USE_METALLIC_TEXTURE_ONLY
|
||||
// Sample metallic from p3d_Texture5
|
||||
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
|
||||
|
||||
// Direct control: texture value directly controls metallic
|
||||
// This gives Blender-like behavior where texture has full control
|
||||
m.metallic = sampled_metallic;
|
||||
|
||||
// Clamp to valid range
|
||||
m.metallic = clamp(m.metallic, 0.0, 1.0);
|
||||
|
||||
// Keep other properties from material (no texture interference)
|
||||
m.basecolor = mInput.color; // Use material color, not texture
|
||||
m.roughness = mInput.roughness;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
|
||||
#else
|
||||
// Fallback to material values only
|
||||
m.basecolor = mInput.color;
|
||||
m.roughness = mInput.roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
#endif
|
||||
# Metallic-only PBR effect
|
||||
# This effect specifically handles metallic textures correctly
|
||||
# Ensures metallic texture is not confused with diffuse texture
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_METALLIC_TEXTURE_ONLY 1
|
||||
#define DONT_FETCH_DEFAULT_TEXTURES 0
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture5; // Metallic texture only
|
||||
|
||||
material: |
|
||||
// Only handle metallic texture, ignore others to avoid confusion
|
||||
#if USE_METALLIC_TEXTURE_ONLY
|
||||
// Sample metallic from p3d_Texture5
|
||||
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
|
||||
|
||||
// Direct control: texture value directly controls metallic
|
||||
// This gives Blender-like behavior where texture has full control
|
||||
m.metallic = sampled_metallic;
|
||||
|
||||
// Clamp to valid range
|
||||
m.metallic = clamp(m.metallic, 0.0, 1.0);
|
||||
|
||||
// Keep other properties from material (no texture interference)
|
||||
m.basecolor = mInput.color; // Use material color, not texture
|
||||
m.roughness = mInput.roughness;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
|
||||
#else
|
||||
// Fallback to material values only
|
||||
m.basecolor = mInput.color;
|
||||
m.roughness = mInput.roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
#endif
|
||||
|
||||
@ -1,29 +1,29 @@
|
||||
# PBR effect with additive metallic texture control
|
||||
# This effect adds metallic texture values to material metallic values
|
||||
# Final metallic = material_metallic + texture_value (clamped to 0-1)
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_ADDITIVE_METALLIC_TEXTURE 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture5; // Metallic texture (additive control)
|
||||
|
||||
material: |
|
||||
// Additive metallic texture control
|
||||
#if USE_ADDITIVE_METALLIC_TEXTURE
|
||||
// Sample metallic value from texture
|
||||
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
|
||||
|
||||
// Add texture value to material metallic value
|
||||
// This allows enhancing existing metallic areas
|
||||
m.metallic = clamp(mInput.metallic + sampled_metallic, 0.0, 1.0);
|
||||
|
||||
// Debug: This mode is useful for:
|
||||
// - Adding metallic details to non-metallic materials
|
||||
// - Enhancing existing metallic areas
|
||||
// - Creating metallic highlights on top of base material
|
||||
#else
|
||||
// Fallback to material metallic value
|
||||
m.metallic = mInput.metallic;
|
||||
#endif
|
||||
# PBR effect with additive metallic texture control
|
||||
# This effect adds metallic texture values to material metallic values
|
||||
# Final metallic = material_metallic + texture_value (clamped to 0-1)
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_ADDITIVE_METALLIC_TEXTURE 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture5; // Metallic texture (additive control)
|
||||
|
||||
material: |
|
||||
// Additive metallic texture control
|
||||
#if USE_ADDITIVE_METALLIC_TEXTURE
|
||||
// Sample metallic value from texture
|
||||
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
|
||||
|
||||
// Add texture value to material metallic value
|
||||
// This allows enhancing existing metallic areas
|
||||
m.metallic = clamp(mInput.metallic + sampled_metallic, 0.0, 1.0);
|
||||
|
||||
// Debug: This mode is useful for:
|
||||
// - Adding metallic details to non-metallic materials
|
||||
// - Enhancing existing metallic areas
|
||||
// - Creating metallic highlights on top of base material
|
||||
#else
|
||||
// Fallback to material metallic value
|
||||
m.metallic = mInput.metallic;
|
||||
#endif
|
||||
|
||||
@ -1,29 +1,29 @@
|
||||
# PBR effect with direct metallic texture control
|
||||
# This effect allows metallic textures to directly control metallic values
|
||||
# instead of multiplying with material metallic value
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_DIRECT_METALLIC_TEXTURE 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture5; // Metallic texture (direct control)
|
||||
|
||||
material: |
|
||||
// Direct metallic texture control
|
||||
#if USE_DIRECT_METALLIC_TEXTURE
|
||||
// Sample metallic value directly from texture
|
||||
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
|
||||
|
||||
// Use texture value directly instead of multiplying
|
||||
// This allows the texture to have full control over metallic values
|
||||
m.metallic = sampled_metallic;
|
||||
|
||||
// Debug: Ensure we're using the texture value
|
||||
// White areas = 1.0 (fully metallic)
|
||||
// Gray areas = 0.5 (semi-metallic)
|
||||
// Black areas = 0.0 (non-metallic)
|
||||
#else
|
||||
// Fallback to material metallic value
|
||||
m.metallic = mInput.metallic;
|
||||
#endif
|
||||
# PBR effect with direct metallic texture control
|
||||
# This effect allows metallic textures to directly control metallic values
|
||||
# instead of multiplying with material metallic value
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_DIRECT_METALLIC_TEXTURE 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture5; // Metallic texture (direct control)
|
||||
|
||||
material: |
|
||||
// Direct metallic texture control
|
||||
#if USE_DIRECT_METALLIC_TEXTURE
|
||||
// Sample metallic value directly from texture
|
||||
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
|
||||
|
||||
// Use texture value directly instead of multiplying
|
||||
// This allows the texture to have full control over metallic values
|
||||
m.metallic = sampled_metallic;
|
||||
|
||||
// Debug: Ensure we're using the texture value
|
||||
// White areas = 1.0 (fully metallic)
|
||||
// Gray areas = 0.5 (semi-metallic)
|
||||
// Black areas = 0.0 (non-metallic)
|
||||
#else
|
||||
// Fallback to material metallic value
|
||||
m.metallic = mInput.metallic;
|
||||
#endif
|
||||
|
||||
@ -1,38 +1,38 @@
|
||||
# PBR effect with direct roughness texture control
|
||||
# This effect allows roughness textures to directly control roughness values
|
||||
# instead of multiplying with material roughness value
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_DIRECT_ROUGHNESS_TEXTURE 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture3; // Roughness texture (direct control)
|
||||
|
||||
material: |
|
||||
// Direct roughness texture control
|
||||
#if USE_DIRECT_ROUGHNESS_TEXTURE
|
||||
// Sample roughness value directly from texture
|
||||
float sampled_roughness = texture(p3d_Texture3, texcoord).x;
|
||||
|
||||
// Use texture value directly instead of multiplying
|
||||
// This allows the texture to have full control over roughness values
|
||||
m.roughness = sampled_roughness;
|
||||
|
||||
// Ensure minimum roughness to avoid rendering issues
|
||||
m.roughness = max(m.roughness, 0.01);
|
||||
|
||||
// Debug: Ensure we're using the texture value
|
||||
// White areas = 1.0 (fully rough)
|
||||
// Gray areas = 0.5 (semi-rough)
|
||||
// Black areas = 0.01 (smooth, but not zero to avoid issues)
|
||||
#else
|
||||
// Fallback to material roughness value
|
||||
m.roughness = mInput.roughness;
|
||||
#endif
|
||||
|
||||
// Keep all other properties unchanged for stability
|
||||
m.basecolor = mInput.color;
|
||||
m.metallic = mInput.metallic;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
# PBR effect with direct roughness texture control
|
||||
# This effect allows roughness textures to directly control roughness values
|
||||
# instead of multiplying with material roughness value
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_DIRECT_ROUGHNESS_TEXTURE 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture3; // Roughness texture (direct control)
|
||||
|
||||
material: |
|
||||
// Direct roughness texture control
|
||||
#if USE_DIRECT_ROUGHNESS_TEXTURE
|
||||
// Sample roughness value directly from texture
|
||||
float sampled_roughness = texture(p3d_Texture3, texcoord).x;
|
||||
|
||||
// Use texture value directly instead of multiplying
|
||||
// This allows the texture to have full control over roughness values
|
||||
m.roughness = sampled_roughness;
|
||||
|
||||
// Ensure minimum roughness to avoid rendering issues
|
||||
m.roughness = max(m.roughness, 0.01);
|
||||
|
||||
// Debug: Ensure we're using the texture value
|
||||
// White areas = 1.0 (fully rough)
|
||||
// Gray areas = 0.5 (semi-rough)
|
||||
// Black areas = 0.01 (smooth, but not zero to avoid issues)
|
||||
#else
|
||||
// Fallback to material roughness value
|
||||
m.roughness = mInput.roughness;
|
||||
#endif
|
||||
|
||||
// Keep all other properties unchanged for stability
|
||||
m.basecolor = mInput.color;
|
||||
m.metallic = mInput.metallic;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
|
||||
@ -1,51 +1,51 @@
|
||||
# Extended PBR effect with support for additional texture types
|
||||
# This effect supports metallic, emission, AO, detail, and gloss textures
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_EXTENDED_TEXTURES 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture5; // Metallic texture
|
||||
uniform sampler2D p3d_Texture6; // Emission texture
|
||||
uniform sampler2D p3d_Texture7; // AO texture
|
||||
uniform sampler2D p3d_Texture8; // Alpha texture
|
||||
uniform sampler2D p3d_Texture9; // Detail texture
|
||||
uniform sampler2D p3d_Texture10; // Gloss texture
|
||||
|
||||
material: |
|
||||
#if USE_EXTENDED_TEXTURES
|
||||
|
||||
// Metallic texture (p3d_Texture5)
|
||||
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
|
||||
m.metallic = mInput.metallic * sampled_metallic;
|
||||
|
||||
// Emission texture (p3d_Texture6)
|
||||
vec3 sampled_emission = texture(p3d_Texture6, texcoord).xyz;
|
||||
if (mInput.shading_model == SHADING_MODEL_EMISSIVE) {
|
||||
m.basecolor += sampled_emission * 2.0; // Boost emission intensity
|
||||
}
|
||||
|
||||
// AO texture (p3d_Texture7) - multiply with base color
|
||||
float sampled_ao = texture(p3d_Texture7, texcoord).x;
|
||||
m.basecolor *= sampled_ao;
|
||||
|
||||
// Alpha texture (p3d_Texture8) - for transparency
|
||||
float sampled_alpha = texture(p3d_Texture8, texcoord).x;
|
||||
if (mInput.shading_model == SHADING_MODEL_TRANSPARENT) {
|
||||
// Apply alpha testing
|
||||
if (sampled_alpha < 0.5) discard;
|
||||
}
|
||||
|
||||
// Detail texture (p3d_Texture9) - blend with base color
|
||||
vec3 sampled_detail = texture(p3d_Texture9, texcoord * 4.0).xyz; // Tiled detail
|
||||
m.basecolor = mix(m.basecolor, m.basecolor * sampled_detail, 0.5);
|
||||
|
||||
// Gloss texture (p3d_Texture10) - affects roughness
|
||||
float sampled_gloss = texture(p3d_Texture10, texcoord).x;
|
||||
m.roughness = m.roughness * (1.0 - sampled_gloss); // Gloss is inverse of roughness
|
||||
|
||||
#else
|
||||
// Standard behavior when extended textures are not used
|
||||
m.metallic = mInput.metallic;
|
||||
#endif
|
||||
# Extended PBR effect with support for additional texture types
|
||||
# This effect supports metallic, emission, AO, detail, and gloss textures
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_EXTENDED_TEXTURES 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture5; // Metallic texture
|
||||
uniform sampler2D p3d_Texture6; // Emission texture
|
||||
uniform sampler2D p3d_Texture7; // AO texture
|
||||
uniform sampler2D p3d_Texture8; // Alpha texture
|
||||
uniform sampler2D p3d_Texture9; // Detail texture
|
||||
uniform sampler2D p3d_Texture10; // Gloss texture
|
||||
|
||||
material: |
|
||||
#if USE_EXTENDED_TEXTURES
|
||||
|
||||
// Metallic texture (p3d_Texture5)
|
||||
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
|
||||
m.metallic = mInput.metallic * sampled_metallic;
|
||||
|
||||
// Emission texture (p3d_Texture6)
|
||||
vec3 sampled_emission = texture(p3d_Texture6, texcoord).xyz;
|
||||
if (mInput.shading_model == SHADING_MODEL_EMISSIVE) {
|
||||
m.basecolor += sampled_emission * 2.0; // Boost emission intensity
|
||||
}
|
||||
|
||||
// AO texture (p3d_Texture7) - multiply with base color
|
||||
float sampled_ao = texture(p3d_Texture7, texcoord).x;
|
||||
m.basecolor *= sampled_ao;
|
||||
|
||||
// Alpha texture (p3d_Texture8) - for transparency
|
||||
float sampled_alpha = texture(p3d_Texture8, texcoord).x;
|
||||
if (mInput.shading_model == SHADING_MODEL_TRANSPARENT) {
|
||||
// Apply alpha testing
|
||||
if (sampled_alpha < 0.5) discard;
|
||||
}
|
||||
|
||||
// Detail texture (p3d_Texture9) - blend with base color
|
||||
vec3 sampled_detail = texture(p3d_Texture9, texcoord * 4.0).xyz; // Tiled detail
|
||||
m.basecolor = mix(m.basecolor, m.basecolor * sampled_detail, 0.5);
|
||||
|
||||
// Gloss texture (p3d_Texture10) - affects roughness
|
||||
float sampled_gloss = texture(p3d_Texture10, texcoord).x;
|
||||
m.roughness = m.roughness * (1.0 - sampled_gloss); // Gloss is inverse of roughness
|
||||
|
||||
#else
|
||||
// Standard behavior when extended textures are not used
|
||||
m.metallic = mInput.metallic;
|
||||
#endif
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
# PBR effect with emission texture support
|
||||
# This effect extends the default PBR pipeline to support emission textures
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_EMISSION_TEXTURE 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture6; // Emission texture
|
||||
|
||||
material: |
|
||||
// Fetch emission value from texture if available
|
||||
#if USE_EMISSION_TEXTURE
|
||||
vec3 sampled_emission = texture(p3d_Texture6, texcoord).xyz;
|
||||
// For emissive materials, add the texture emission to the base color
|
||||
if (mInput.shading_model == SHADING_MODEL_EMISSIVE) {
|
||||
m.basecolor += sampled_emission * 2.0; // Boost emission intensity
|
||||
}
|
||||
#endif
|
||||
# PBR effect with emission texture support
|
||||
# This effect extends the default PBR pipeline to support emission textures
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_EMISSION_TEXTURE 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture6; // Emission texture
|
||||
|
||||
material: |
|
||||
// Fetch emission value from texture if available
|
||||
#if USE_EMISSION_TEXTURE
|
||||
vec3 sampled_emission = texture(p3d_Texture6, texcoord).xyz;
|
||||
// For emissive materials, add the texture emission to the base color
|
||||
if (mInput.shading_model == SHADING_MODEL_EMISSIVE) {
|
||||
m.basecolor += sampled_emission * 2.0; // Boost emission intensity
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1,40 +1,40 @@
|
||||
# PBR effect with metallic texture support
|
||||
# This effect extends the default PBR pipeline to support metallic textures
|
||||
# Provides both multiplicative and direct control modes
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_METALLIC_TEXTURE 1
|
||||
#define METALLIC_CONTROL_MODE 0 // 0=multiply, 1=direct, 2=additive
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture5; // Metallic texture
|
||||
|
||||
material: |
|
||||
// Add metallic texture support to the default material processing
|
||||
// Note: Don't override the default material processing, just extend it
|
||||
#if USE_METALLIC_TEXTURE
|
||||
// Sample metallic texture
|
||||
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
|
||||
|
||||
// Apply metallic texture based on control mode
|
||||
#if METALLIC_CONTROL_MODE == 0
|
||||
// Multiplicative mode (original behavior)
|
||||
m.metallic = mInput.metallic * sampled_metallic;
|
||||
#elif METALLIC_CONTROL_MODE == 1
|
||||
// Direct control mode
|
||||
m.metallic = sampled_metallic;
|
||||
#elif METALLIC_CONTROL_MODE == 2
|
||||
// Additive mode
|
||||
m.metallic = clamp(mInput.metallic + sampled_metallic, 0.0, 1.0);
|
||||
#else
|
||||
// Fallback to multiplicative
|
||||
m.metallic = mInput.metallic * sampled_metallic;
|
||||
#endif
|
||||
|
||||
// Ensure valid range
|
||||
m.metallic = clamp(m.metallic, 0.0, 1.0);
|
||||
#endif
|
||||
|
||||
// Note: Other material properties (basecolor, roughness, etc.) are handled by the default template
|
||||
// We don't override them here to avoid conflicts
|
||||
# PBR effect with metallic texture support
|
||||
# This effect extends the default PBR pipeline to support metallic textures
|
||||
# Provides both multiplicative and direct control modes
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_METALLIC_TEXTURE 1
|
||||
#define METALLIC_CONTROL_MODE 0 // 0=multiply, 1=direct, 2=additive
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture5; // Metallic texture
|
||||
|
||||
material: |
|
||||
// Add metallic texture support to the default material processing
|
||||
// Note: Don't override the default material processing, just extend it
|
||||
#if USE_METALLIC_TEXTURE
|
||||
// Sample metallic texture
|
||||
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
|
||||
|
||||
// Apply metallic texture based on control mode
|
||||
#if METALLIC_CONTROL_MODE == 0
|
||||
// Multiplicative mode (original behavior)
|
||||
m.metallic = mInput.metallic * sampled_metallic;
|
||||
#elif METALLIC_CONTROL_MODE == 1
|
||||
// Direct control mode
|
||||
m.metallic = sampled_metallic;
|
||||
#elif METALLIC_CONTROL_MODE == 2
|
||||
// Additive mode
|
||||
m.metallic = clamp(mInput.metallic + sampled_metallic, 0.0, 1.0);
|
||||
#else
|
||||
// Fallback to multiplicative
|
||||
m.metallic = mInput.metallic * sampled_metallic;
|
||||
#endif
|
||||
|
||||
// Ensure valid range
|
||||
m.metallic = clamp(m.metallic, 0.0, 1.0);
|
||||
#endif
|
||||
|
||||
// Note: Other material properties (basecolor, roughness, etc.) are handled by the default template
|
||||
// We don't override them here to avoid conflicts
|
||||
|
||||
@ -1,31 +1,31 @@
|
||||
# PBR effect with normal mapping support
|
||||
# This effect ensures proper material color handling when only normal maps are applied
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_NORMAL_MAPPING_ONLY 1
|
||||
|
||||
material: |
|
||||
// Handle normal mapping without requiring diffuse texture
|
||||
#if USE_NORMAL_MAPPING_ONLY
|
||||
// Use material color directly, don't multiply with sampled_diffuse
|
||||
// This prevents the black color issue when no diffuse texture is present
|
||||
m.basecolor = mInput.color;
|
||||
|
||||
// Handle other textures normally if they exist
|
||||
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
|
||||
m.roughness = mInput.roughness * sampled_roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
|
||||
// Ensure minimum roughness
|
||||
m.roughness = max(m.roughness, 0.01);
|
||||
|
||||
#else
|
||||
// Standard material processing
|
||||
m.basecolor = mInput.color * sampled_diffuse.xyz;
|
||||
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
|
||||
m.roughness = mInput.roughness * sampled_roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
#endif
|
||||
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
# PBR effect with normal mapping support
|
||||
# This effect ensures proper material color handling when only normal maps are applied
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_NORMAL_MAPPING_ONLY 1
|
||||
|
||||
material: |
|
||||
// Handle normal mapping without requiring diffuse texture
|
||||
#if USE_NORMAL_MAPPING_ONLY
|
||||
// Use material color directly, don't multiply with sampled_diffuse
|
||||
// This prevents the black color issue when no diffuse texture is present
|
||||
m.basecolor = mInput.color;
|
||||
|
||||
// Handle other textures normally if they exist
|
||||
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
|
||||
m.roughness = mInput.roughness * sampled_roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
|
||||
// Ensure minimum roughness
|
||||
m.roughness = max(m.roughness, 0.01);
|
||||
|
||||
#else
|
||||
// Standard material processing
|
||||
m.basecolor = mInput.color * sampled_diffuse.xyz;
|
||||
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
|
||||
m.roughness = mInput.roughness * sampled_roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
#endif
|
||||
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
|
||||
@ -1,33 +1,33 @@
|
||||
# Stable PBR effect with roughness texture support
|
||||
# Simplified version to avoid rendering issues and flickering
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_STABLE_ROUGHNESS_TEXTURE 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture3; // Roughness texture only
|
||||
|
||||
material: |
|
||||
// Simple and stable roughness texture handling
|
||||
#if USE_STABLE_ROUGHNESS_TEXTURE
|
||||
// Sample roughness from texture
|
||||
float sampled_roughness = texture(p3d_Texture3, texcoord).x;
|
||||
|
||||
// Use simple multiplication - stable and predictable
|
||||
// This ensures the texture effect is always visible
|
||||
m.roughness = mInput.roughness * sampled_roughness;
|
||||
|
||||
// Ensure minimum roughness to avoid rendering issues
|
||||
m.roughness = max(m.roughness, 0.01);
|
||||
|
||||
#else
|
||||
// Fallback to material roughness
|
||||
m.roughness = mInput.roughness;
|
||||
#endif
|
||||
|
||||
// Keep all other properties unchanged for stability
|
||||
m.basecolor = mInput.color;
|
||||
m.metallic = mInput.metallic;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
# Stable PBR effect with roughness texture support
|
||||
# Simplified version to avoid rendering issues and flickering
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_STABLE_ROUGHNESS_TEXTURE 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture3; // Roughness texture only
|
||||
|
||||
material: |
|
||||
// Simple and stable roughness texture handling
|
||||
#if USE_STABLE_ROUGHNESS_TEXTURE
|
||||
// Sample roughness from texture
|
||||
float sampled_roughness = texture(p3d_Texture3, texcoord).x;
|
||||
|
||||
// Use simple multiplication - stable and predictable
|
||||
// This ensures the texture effect is always visible
|
||||
m.roughness = mInput.roughness * sampled_roughness;
|
||||
|
||||
// Ensure minimum roughness to avoid rendering issues
|
||||
m.roughness = max(m.roughness, 0.01);
|
||||
|
||||
#else
|
||||
// Fallback to material roughness
|
||||
m.roughness = mInput.roughness;
|
||||
#endif
|
||||
|
||||
// Keep all other properties unchanged for stability
|
||||
m.basecolor = mInput.color;
|
||||
m.metallic = mInput.metallic;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
|
||||
@ -1,37 +1,37 @@
|
||||
# Enhanced PBR effect with metallic texture support
|
||||
# This effect extends the default PBR to support metallic textures
|
||||
# Avoids redeclaring textures that are already in the base template
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_METALLIC_TEXTURE 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture5; // Metallic texture (not in default template)
|
||||
|
||||
material: |
|
||||
// Enhanced material with metallic texture support
|
||||
#if USE_METALLIC_TEXTURE
|
||||
// Sample metallic texture
|
||||
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
|
||||
|
||||
// Apply all material properties
|
||||
// Use the sampled values from the base template for other textures
|
||||
m.basecolor = mInput.color * sampled_diffuse.xyz;
|
||||
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
|
||||
m.roughness = mInput.roughness * sampled_roughness;
|
||||
m.metallic = mInput.metallic * sampled_metallic; // Now with metallic texture support!
|
||||
|
||||
// Ensure valid ranges
|
||||
m.roughness = max(m.roughness, 0.01);
|
||||
m.metallic = clamp(m.metallic, 0.0, 1.0);
|
||||
|
||||
#else
|
||||
// Fallback to standard material processing
|
||||
m.basecolor = mInput.color * sampled_diffuse.xyz;
|
||||
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
|
||||
m.roughness = mInput.roughness * sampled_roughness;
|
||||
m.metallic = mInput.metallic; // No metallic texture
|
||||
#endif
|
||||
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
# Enhanced PBR effect with metallic texture support
|
||||
# This effect extends the default PBR to support metallic textures
|
||||
# Avoids redeclaring textures that are already in the base template
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_METALLIC_TEXTURE 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture5; // Metallic texture (not in default template)
|
||||
|
||||
material: |
|
||||
// Enhanced material with metallic texture support
|
||||
#if USE_METALLIC_TEXTURE
|
||||
// Sample metallic texture
|
||||
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
|
||||
|
||||
// Apply all material properties
|
||||
// Use the sampled values from the base template for other textures
|
||||
m.basecolor = mInput.color * sampled_diffuse.xyz;
|
||||
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
|
||||
m.roughness = mInput.roughness * sampled_roughness;
|
||||
m.metallic = mInput.metallic * sampled_metallic; // Now with metallic texture support!
|
||||
|
||||
// Ensure valid ranges
|
||||
m.roughness = max(m.roughness, 0.01);
|
||||
m.metallic = clamp(m.metallic, 0.0, 1.0);
|
||||
|
||||
#else
|
||||
// Fallback to standard material processing
|
||||
m.basecolor = mInput.color * sampled_diffuse.xyz;
|
||||
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
|
||||
m.roughness = mInput.roughness * sampled_roughness;
|
||||
m.metallic = mInput.metallic; // No metallic texture
|
||||
#endif
|
||||
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
|
||||
@ -1,39 +1,39 @@
|
||||
# Roughness-only PBR effect
|
||||
# This effect specifically handles roughness textures correctly
|
||||
# Ensures roughness texture is not confused with diffuse texture
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_ROUGHNESS_TEXTURE_ONLY 1
|
||||
#define DONT_FETCH_DEFAULT_TEXTURES 0
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture3; // Roughness texture only
|
||||
|
||||
material: |
|
||||
// Only handle roughness texture, ignore others to avoid confusion
|
||||
#if USE_ROUGHNESS_TEXTURE_ONLY
|
||||
// Sample roughness from p3d_Texture3
|
||||
float sampled_roughness = texture(p3d_Texture3, texcoord).x;
|
||||
|
||||
// Apply roughness: material_roughness * texture_value
|
||||
// This gives Blender-like behavior
|
||||
m.roughness = mInput.roughness * sampled_roughness;
|
||||
|
||||
// Ensure minimum roughness to avoid rendering issues
|
||||
m.roughness = max(m.roughness, 0.01);
|
||||
|
||||
// Keep other properties from material (no texture interference)
|
||||
m.basecolor = mInput.color; // Use material color, not texture
|
||||
m.metallic = mInput.metallic;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
|
||||
#else
|
||||
// Fallback to material values only
|
||||
m.basecolor = mInput.color;
|
||||
m.roughness = mInput.roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
#endif
|
||||
# Roughness-only PBR effect
|
||||
# This effect specifically handles roughness textures correctly
|
||||
# Ensures roughness texture is not confused with diffuse texture
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define USE_ROUGHNESS_TEXTURE_ONLY 1
|
||||
#define DONT_FETCH_DEFAULT_TEXTURES 0
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture3; // Roughness texture only
|
||||
|
||||
material: |
|
||||
// Only handle roughness texture, ignore others to avoid confusion
|
||||
#if USE_ROUGHNESS_TEXTURE_ONLY
|
||||
// Sample roughness from p3d_Texture3
|
||||
float sampled_roughness = texture(p3d_Texture3, texcoord).x;
|
||||
|
||||
// Apply roughness: material_roughness * texture_value
|
||||
// This gives Blender-like behavior
|
||||
m.roughness = mInput.roughness * sampled_roughness;
|
||||
|
||||
// Ensure minimum roughness to avoid rendering issues
|
||||
m.roughness = max(m.roughness, 0.01);
|
||||
|
||||
// Keep other properties from material (no texture interference)
|
||||
m.basecolor = mInput.color; // Use material color, not texture
|
||||
m.metallic = mInput.metallic;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
|
||||
#else
|
||||
// Fallback to material values only
|
||||
m.basecolor = mInput.color;
|
||||
m.roughness = mInput.roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
#endif
|
||||
|
||||
@ -1,31 +1,31 @@
|
||||
# 最简单的纹理测试效果
|
||||
# 直接将纹理显示为颜色,验证纹理是否被正确读取
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define SIMPLE_TEXTURE_TEST 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture3; // 粗糙度纹理槽
|
||||
|
||||
material: |
|
||||
// 最简单的测试:直接显示纹理
|
||||
#if SIMPLE_TEXTURE_TEST
|
||||
// 尝试读取纹理
|
||||
vec4 texture_sample = texture(p3d_Texture3, texcoord);
|
||||
float texture_value = texture_sample.r; // 读取红色通道
|
||||
|
||||
// 直接将纹理值显示为颜色
|
||||
m.basecolor = vec3(texture_value); // 灰度显示
|
||||
m.roughness = 0.5; // 固定粗糙度
|
||||
m.metallic = 0.0; // 非金属
|
||||
m.specular_ior = 1.5;
|
||||
m.shading_model_param0 = 0.0;
|
||||
#else
|
||||
// 正常材质
|
||||
m.basecolor = mInput.color;
|
||||
m.roughness = mInput.roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
#endif
|
||||
# 最简单的纹理测试效果
|
||||
# 直接将纹理显示为颜色,验证纹理是否被正确读取
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define SIMPLE_TEXTURE_TEST 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture3; // 粗糙度纹理槽
|
||||
|
||||
material: |
|
||||
// 最简单的测试:直接显示纹理
|
||||
#if SIMPLE_TEXTURE_TEST
|
||||
// 尝试读取纹理
|
||||
vec4 texture_sample = texture(p3d_Texture3, texcoord);
|
||||
float texture_value = texture_sample.r; // 读取红色通道
|
||||
|
||||
// 直接将纹理值显示为颜色
|
||||
m.basecolor = vec3(texture_value); // 灰度显示
|
||||
m.roughness = 0.5; // 固定粗糙度
|
||||
m.metallic = 0.0; // 非金属
|
||||
m.specular_ior = 1.5;
|
||||
m.shading_model_param0 = 0.0;
|
||||
#else
|
||||
// 正常材质
|
||||
m.basecolor = mInput.color;
|
||||
m.roughness = mInput.roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
m.specular_ior = mInput.specular_ior;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
#endif
|
||||
|
||||
@ -1,26 +1,26 @@
|
||||
# simple_transparent.yaml
|
||||
vertex_shader: |
|
||||
#version 330
|
||||
uniform mat4 p3d_ModelViewProjectionMatrix;
|
||||
in vec4 p3d_Vertex;
|
||||
in vec2 p3d_MultiTexCoord0;
|
||||
out vec2 texcoord;
|
||||
void main() {
|
||||
gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;
|
||||
texcoord = p3d_MultiTexCoord0;
|
||||
}
|
||||
|
||||
fragment_shader: |
|
||||
#version 330
|
||||
uniform sampler2D p3d_Texture0;
|
||||
uniform float material_opacity = 1.0;
|
||||
in vec2 texcoord;
|
||||
out vec4 o_color;
|
||||
void main() {
|
||||
vec4 c = texture(p3d_Texture0, texcoord);
|
||||
o_color = vec4(c.rgb, c.a * material_opacity);
|
||||
}
|
||||
|
||||
render_states:
|
||||
TransparencyAttrib: M_alpha
|
||||
# simple_transparent.yaml
|
||||
vertex_shader: |
|
||||
#version 330
|
||||
uniform mat4 p3d_ModelViewProjectionMatrix;
|
||||
in vec4 p3d_Vertex;
|
||||
in vec2 p3d_MultiTexCoord0;
|
||||
out vec2 texcoord;
|
||||
void main() {
|
||||
gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;
|
||||
texcoord = p3d_MultiTexCoord0;
|
||||
}
|
||||
|
||||
fragment_shader: |
|
||||
#version 330
|
||||
uniform sampler2D p3d_Texture0;
|
||||
uniform float material_opacity = 1.0;
|
||||
in vec2 texcoord;
|
||||
out vec4 o_color;
|
||||
void main() {
|
||||
vec4 c = texture(p3d_Texture0, texcoord);
|
||||
o_color = vec4(c.rgb, c.a * material_opacity);
|
||||
}
|
||||
|
||||
render_states:
|
||||
TransparencyAttrib: M_alpha
|
||||
DepthWriteAttrib: 0
|
||||
21
RenderPipelineFile/effects/ssbo_instancing.yaml
Normal file
21
RenderPipelineFile/effects/ssbo_instancing.yaml
Normal file
@ -0,0 +1,21 @@
|
||||
# SSBO Instancing Effect
|
||||
|
||||
vertex:
|
||||
includes: |
|
||||
struct Transform {
|
||||
mat4 model_mat;
|
||||
};
|
||||
#extension GL_ARB_shader_storage_buffer_object : enable
|
||||
layout(std430, binding = 10) buffer ShaderBuffer {
|
||||
Transform transforms[];
|
||||
};
|
||||
|
||||
transform: |
|
||||
// Overwrite position and normal using SSBO data
|
||||
mat4 model_matrix = transforms[gl_InstanceID].model_mat;
|
||||
vOutput.position = (model_matrix * p3d_Vertex).xyz;
|
||||
|
||||
// Transform normal (approximation assuming uniform scale for performance, otherwise use inverse transpose)
|
||||
mat3 normal_matrix = mat3(model_matrix);
|
||||
vOutput.normal = normalize(normal_matrix * p3d_Normal);
|
||||
|
||||
@ -1,34 +1,34 @@
|
||||
# Test metallic texture debug effect
|
||||
# This effect shows the metallic texture directly as color to verify it's working
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define TEST_METALLIC_DEBUG 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture5; // Metallic texture
|
||||
|
||||
material: |
|
||||
// Debug: Show metallic texture directly as color
|
||||
#if TEST_METALLIC_DEBUG
|
||||
// Sample metallic texture
|
||||
float metallic_value = texture(p3d_Texture5, texcoord).x;
|
||||
|
||||
// Show metallic as blue-to-yellow gradient for debugging
|
||||
vec3 debug_color = mix(vec3(0.2, 0.2, 1.0), vec3(1.0, 1.0, 0.2), metallic_value);
|
||||
|
||||
// Apply debug visualization
|
||||
m.basecolor = debug_color; // Show texture as blue-yellow gradient
|
||||
m.roughness = 0.5; // Fixed roughness for consistent lighting
|
||||
m.metallic = 0.0; // Non-metallic for clear visualization
|
||||
m.specular_ior = 1.5;
|
||||
m.shading_model_param0 = 0.0;
|
||||
|
||||
#else
|
||||
// Normal material processing
|
||||
m.basecolor = mInput.color * sampled_diffuse.xyz;
|
||||
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
|
||||
m.roughness = mInput.roughness * sampled_roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
#endif
|
||||
# Test metallic texture debug effect
|
||||
# This effect shows the metallic texture directly as color to verify it's working
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define TEST_METALLIC_DEBUG 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture5; // Metallic texture
|
||||
|
||||
material: |
|
||||
// Debug: Show metallic texture directly as color
|
||||
#if TEST_METALLIC_DEBUG
|
||||
// Sample metallic texture
|
||||
float metallic_value = texture(p3d_Texture5, texcoord).x;
|
||||
|
||||
// Show metallic as blue-to-yellow gradient for debugging
|
||||
vec3 debug_color = mix(vec3(0.2, 0.2, 1.0), vec3(1.0, 1.0, 0.2), metallic_value);
|
||||
|
||||
// Apply debug visualization
|
||||
m.basecolor = debug_color; // Show texture as blue-yellow gradient
|
||||
m.roughness = 0.5; // Fixed roughness for consistent lighting
|
||||
m.metallic = 0.0; // Non-metallic for clear visualization
|
||||
m.specular_ior = 1.5;
|
||||
m.shading_model_param0 = 0.0;
|
||||
|
||||
#else
|
||||
// Normal material processing
|
||||
m.basecolor = mInput.color * sampled_diffuse.xyz;
|
||||
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
|
||||
m.roughness = mInput.roughness * sampled_roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
#endif
|
||||
|
||||
@ -1,34 +1,34 @@
|
||||
# Test roughness texture debug effect
|
||||
# This effect shows the roughness texture directly as color to verify it's working
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define TEST_ROUGHNESS_DEBUG 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture3; // Roughness texture
|
||||
|
||||
material: |
|
||||
// Debug: Show roughness texture directly as color
|
||||
#if TEST_ROUGHNESS_DEBUG
|
||||
// Sample roughness texture
|
||||
float roughness_value = texture(p3d_Texture3, texcoord).x;
|
||||
|
||||
// Show roughness as grayscale color for debugging
|
||||
vec3 debug_color = vec3(roughness_value);
|
||||
|
||||
// Apply debug visualization
|
||||
m.basecolor = debug_color; // Show texture as grayscale
|
||||
m.roughness = 0.5; // Fixed roughness for consistent lighting
|
||||
m.metallic = 0.0; // Non-metallic for clear visualization
|
||||
m.specular_ior = 1.5;
|
||||
m.shading_model_param0 = 0.0;
|
||||
|
||||
#else
|
||||
// Normal material processing
|
||||
m.basecolor = mInput.color * sampled_diffuse.xyz;
|
||||
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
|
||||
m.roughness = mInput.roughness * sampled_roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
#endif
|
||||
# Test roughness texture debug effect
|
||||
# This effect shows the roughness texture directly as color to verify it's working
|
||||
|
||||
fragment:
|
||||
defines: |
|
||||
#define TEST_ROUGHNESS_DEBUG 1
|
||||
|
||||
inout: |
|
||||
uniform sampler2D p3d_Texture3; // Roughness texture
|
||||
|
||||
material: |
|
||||
// Debug: Show roughness texture directly as color
|
||||
#if TEST_ROUGHNESS_DEBUG
|
||||
// Sample roughness texture
|
||||
float roughness_value = texture(p3d_Texture3, texcoord).x;
|
||||
|
||||
// Show roughness as grayscale color for debugging
|
||||
vec3 debug_color = vec3(roughness_value);
|
||||
|
||||
// Apply debug visualization
|
||||
m.basecolor = debug_color; // Show texture as grayscale
|
||||
m.roughness = 0.5; // Fixed roughness for consistent lighting
|
||||
m.metallic = 0.0; // Non-metallic for clear visualization
|
||||
m.specular_ior = 1.5;
|
||||
m.shading_model_param0 = 0.0;
|
||||
|
||||
#else
|
||||
// Normal material processing
|
||||
m.basecolor = mInput.color * sampled_diffuse.xyz;
|
||||
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
|
||||
m.roughness = mInput.roughness * sampled_roughness;
|
||||
m.metallic = mInput.metallic;
|
||||
m.shading_model_param0 = mInput.arbitrary0;
|
||||
#endif
|
||||
|
||||
BIN
RenderPipelineFile/rp/core/RotationHandleFull.fbx
Executable file
BIN
RenderPipelineFile/rp/core/RotationHandleFull.fbx
Executable file
Binary file not shown.
BIN
RenderPipelineFile/rp/core/RotationHandleQuarter.fbx
Executable file
BIN
RenderPipelineFile/rp/core/RotationHandleQuarter.fbx
Executable file
Binary file not shown.
BIN
RenderPipelineFile/rp/core/TranslateArrowHandle.fbx
Executable file
BIN
RenderPipelineFile/rp/core/TranslateArrowHandle.fbx
Executable file
Binary file not shown.
BIN
RenderPipelineFile/rp/core/UniformScaleHandle.fbx
Executable file
BIN
RenderPipelineFile/rp/core/UniformScaleHandle.fbx
Executable file
Binary file not shown.
BIN
RenderPipelineFile/rp/shader/core/RotationHandleFull.fbx
Executable file
BIN
RenderPipelineFile/rp/shader/core/RotationHandleFull.fbx
Executable file
Binary file not shown.
BIN
RenderPipelineFile/rp/shader/core/RotationHandleQuarter.fbx
Executable file
BIN
RenderPipelineFile/rp/shader/core/RotationHandleQuarter.fbx
Executable file
Binary file not shown.
BIN
RenderPipelineFile/rp/shader/core/TranslateArrowHandle.fbx
Executable file
BIN
RenderPipelineFile/rp/shader/core/TranslateArrowHandle.fbx
Executable file
Binary file not shown.
BIN
RenderPipelineFile/rp/shader/core/UniformScaleHandle.fbx
Executable file
BIN
RenderPipelineFile/rp/shader/core/UniformScaleHandle.fbx
Executable file
Binary file not shown.
@ -30,7 +30,7 @@ import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
from six.moves import range # pylint: disable=import-error
|
||||
from rplibs.six.moves import range # pylint: disable=import-error
|
||||
|
||||
from panda3d.core import Vec4, Vec3, Vec2, RenderState, TransformState
|
||||
from panda3d.core import TexturePool, SceneGraphAnalyzer
|
||||
@ -75,7 +75,6 @@ class Debugger(RPObject):
|
||||
|
||||
Globals.base.doMethodLater(0.1, self.update_stats, "RPDebugger_updateStats")
|
||||
|
||||
|
||||
@property
|
||||
def advanced_info(self):
|
||||
return self.pipeline.settings["pipeline.advanced_debugging_info"]
|
||||
@ -225,11 +224,6 @@ class Debugger(RPObject):
|
||||
self.overlay_node.show()
|
||||
self.error_msg_handler.show()
|
||||
|
||||
def hide_gui(self):
|
||||
self.fullscreen_node.hide()
|
||||
self.overlay_node.hide()
|
||||
self.error_msg_handler.hide()
|
||||
|
||||
def toggle_keybindings_visible(self):
|
||||
""" Shows / Hides the FPS graph """
|
||||
if not self.keybinding_instructions.is_hidden():
|
||||
|
||||
@ -25,7 +25,7 @@ THE SOFTWARE.
|
||||
"""
|
||||
from __future__ import division
|
||||
|
||||
from six.moves import range # pylint: disable=import-error
|
||||
from rplibs.six.moves import range # pylint: disable=import-error
|
||||
|
||||
from rpcore.gui.sprite import Sprite
|
||||
from rpcore.rpobject import RPObject
|
||||
|
||||
@ -90,10 +90,6 @@ class LightManager(RPObject):
|
||||
|
||||
def remove_light(self, light):
|
||||
""" Removes a light """
|
||||
print(f'333333333333333333333333333333,{light.casts_shadows}')
|
||||
# from RenderPipelineFile.rpcore.pynative.internal_light_manager import InternalLightManager
|
||||
# inter = InternalLightManager()
|
||||
# inter.remove_light(light)
|
||||
self.internal_mgr.remove_light(light)
|
||||
self.pta_max_light_index[0] = self.internal_mgr.max_light_index
|
||||
|
||||
|
||||
@ -80,7 +80,6 @@ if NATIVE_CXX_LOADED:
|
||||
RPObject.global_debug("CORE", "Using native core module")
|
||||
from rpcore.native import native_ as _native_module # pylint: disable=wrong-import-position
|
||||
else:
|
||||
print(f'343434343434343434343434343')
|
||||
from rpcore import pynative as _native_module # pylint: disable=wrong-import-position
|
||||
RPObject.global_debug("CORE", "Using simulated python-wrapper module")
|
||||
|
||||
|
||||
@ -161,12 +161,7 @@ public:
|
||||
|
||||
// Update maximum index
|
||||
if (slot == _max_index) {
|
||||
while (_max_index >= 0 && !_data[_max_index--]);
|
||||
// 正确的修复代码
|
||||
// while (_max_index >= 0 && _data[_max_index] == NULL) {
|
||||
// _max_index--;
|
||||
// }
|
||||
}
|
||||
while (_max_index >= 0 && !_data[_max_index--]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -24,14 +24,11 @@ THE SOFTWARE.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
|
||||
from __future__ import division, print_function
|
||||
from math import exp, log
|
||||
|
||||
from panda3d.core import PTAFloat, PTALVecBase3f
|
||||
|
||||
|
||||
from rpcore.rpobject import RPObject
|
||||
from rpcore.util.smooth_connected_curve import SmoothConnectedCurve
|
||||
from rpcore.pluginbase.setting_types import make_setting_from_factory
|
||||
|
||||
@ -116,70 +116,30 @@ class InternalLightManager(object):
|
||||
source.set_slot(slot)
|
||||
|
||||
def remove_light(self, light):
|
||||
print(f'44444444444444444444444444')
|
||||
print("\n" + "=" * 50)
|
||||
print(f"DEBUG: Entering remove_light for light object: {light.casts_shadows}")
|
||||
if light:
|
||||
print(f" - Light's Slot: {light.get_slot() if light.has_slot() else 'No Slot'}")
|
||||
print(f" - Does it cast shadows? light.get_casts_shadows() -> {light.get_casts_shadows()}")
|
||||
else:
|
||||
print(" - Light object is None!")
|
||||
|
||||
print("\n --- State of Light System BEFORE removal ---")
|
||||
if hasattr(self, '_lights') and hasattr(self._lights, '_data'):
|
||||
# 打印出当前所有灯光对象,看看有没有异常
|
||||
print(f" - Light Data Array (_data):")
|
||||
for i, l_obj in enumerate(self._lights._data):
|
||||
print(f" [{i}]: {l_obj}")
|
||||
|
||||
print(f"\n - Max Index (_max_index): {self._lights._max_index}")
|
||||
print(f" - Num Entries (_num_entries): {self._lights._num_entries}")
|
||||
print("=" * 50 + "\n")
|
||||
assert light is not None
|
||||
if not light.has_slot():
|
||||
print("ERROR: Could not detach light, light was not attached!")
|
||||
return
|
||||
|
||||
# 保存必要信息,避免过早清理
|
||||
light_slot = light.get_slot()
|
||||
has_shadows = light.get_casts_shadows()
|
||||
|
||||
# 处理shadow sources(如果有的话)
|
||||
if has_shadows:
|
||||
num_sources = light.get_num_shadow_sources()
|
||||
if num_sources > 0:
|
||||
# 关键修复:先保存第一个source的slot,再清理
|
||||
first_source = light.get_shadow_source(0)
|
||||
first_source_slot = first_source.get_slot() # 保存slot值
|
||||
|
||||
# --- 在这里加上打印语句 ---
|
||||
print(f"DEBUG: Removing shadow sources. Start Slot: {first_source_slot}, Count: {num_sources}")
|
||||
|
||||
# 先发送GPU移除命令(在清理之前)
|
||||
cmd_remove = GPUCommand(GPUCommand.CMD_remove_sources)
|
||||
cmd_remove.push_int(first_source_slot) # 使用保存的slot值
|
||||
cmd_remove.push_int(num_sources)
|
||||
self._cmd_list.add_command(cmd_remove)
|
||||
|
||||
# 然后清理所有shadow sources
|
||||
for i in range(num_sources):
|
||||
source = light.get_shadow_source(i)
|
||||
if source.has_slot():
|
||||
self._shadow_sources.free_slot(source.get_slot())
|
||||
if source.has_region():
|
||||
self._shadow_manager.get_atlas().free_region(source.get_region())
|
||||
source.clear_region()
|
||||
|
||||
# 清理light的shadow sources
|
||||
light.clear_shadow_sources()
|
||||
|
||||
# 发送GPU移除light命令
|
||||
self._lights.free_slot(light.get_slot())
|
||||
self.gpu_remove_light(light)
|
||||
|
||||
# 最后释放light slot和清理light信息
|
||||
self._lights.free_slot(light_slot)
|
||||
light.remove_slot()
|
||||
|
||||
if light.get_casts_shadows():
|
||||
|
||||
for i in range(light.get_num_shadow_sources()):
|
||||
source = light.get_shadow_source(i)
|
||||
if source.has_slot():
|
||||
self._shadow_sources.free_slot(source.get_slot())
|
||||
if source.has_region():
|
||||
self._shadow_manager.get_atlas().free_region(source.get_region())
|
||||
source.clear_region()
|
||||
|
||||
self.gpu_remove_consecutive_sources(
|
||||
light.get_shadow_source(0), light.get_num_shadow_sources())
|
||||
|
||||
light.clear_shadow_sources()
|
||||
|
||||
def gpu_remove_consecutive_sources(self, first_source, num_sources):
|
||||
cmd_remove = GPUCommand(GPUCommand.CMD_remove_sources)
|
||||
cmd_remove.push_int(first_source.get_slot())
|
||||
|
||||
@ -38,7 +38,7 @@ from direct.showbase.ShowBase import ShowBase
|
||||
from direct.stdpy.file import isfile
|
||||
|
||||
from rplibs.yaml import load_yaml_file_flat
|
||||
from six.moves import range # pylint: disable=import-error
|
||||
from rplibs.six.moves import range # pylint: disable=import-error
|
||||
|
||||
from rpcore.globals import Globals
|
||||
from rpcore.effect import Effect
|
||||
@ -86,8 +86,7 @@ class RenderPipeline(RPObject):
|
||||
self._applied_effects = []
|
||||
self._pre_showbase_initialized = False
|
||||
self._first_frame = None
|
||||
#self.set_loading_screen_image("/$$rp/data/gui/loading_screen_bg.txo")
|
||||
self.set_loading_screen_image("/$$rp/data/gui/Default_Rough.png")
|
||||
self.set_loading_screen_image("/$$rp/data/gui/loading_screen_bg.txo")
|
||||
|
||||
def load_settings(self, path):
|
||||
""" Loads the pipeline configuration from a given filename. Usually
|
||||
@ -208,7 +207,6 @@ class RenderPipeline(RPObject):
|
||||
def remove_light(self, light):
|
||||
""" Removes a previously attached light, check out the LightManager
|
||||
remove_light documentation for further information. """
|
||||
print(f'222222222222222222222222222,{light.casts_shadows}')
|
||||
self.light_mgr.remove_light(light)
|
||||
|
||||
def load_ies_profile(self, filename):
|
||||
@ -351,11 +349,7 @@ class RenderPipeline(RPObject):
|
||||
continue
|
||||
|
||||
material = state.get_attrib(MaterialAttrib).get_material()
|
||||
if material.emission is not None:
|
||||
shading_model = material.emission.x
|
||||
else:
|
||||
shading_model = 0.0
|
||||
|
||||
shading_model = material.emission.x
|
||||
|
||||
# SHADING_MODEL_TRANSPARENT
|
||||
if shading_model == 3:
|
||||
|
||||
@ -31,7 +31,7 @@ from panda3d.core import Vec4, TransparencyAttrib, ColorWriteAttrib, SamplerStat
|
||||
from panda3d.core import WindowProperties, FrameBufferProperties, GraphicsPipe
|
||||
from panda3d.core import LVecBase2i
|
||||
|
||||
from six.moves import range # pylint: disable=import-error
|
||||
from rplibs.six.moves import range # pylint: disable=import-error
|
||||
from rplibs.six import iterkeys, itervalues
|
||||
|
||||
from rpcore.globals import Globals
|
||||
|
||||
@ -71,8 +71,8 @@ class DisplayShaderBuilder(object): # pylint: disable=too-few-public-methods
|
||||
# Build actual shader
|
||||
built = """
|
||||
#version 400
|
||||
#pragma include "render_pipeline_base.inc.glsl"
|
||||
#extension GL_ARB_shading_language_420pack : enable
|
||||
#pragma include "render_pipeline_base.inc.glsl"
|
||||
in vec2 texcoord;
|
||||
out vec3 result;
|
||||
uniform int mipmap;
|
||||
|
||||
@ -36,7 +36,7 @@ from panda3d.core import PTAFloat, Filename, SamplerState, VirtualFileSystem
|
||||
from panda3d.core import get_model_path
|
||||
from direct.stdpy.file import open, join, isfile
|
||||
|
||||
from six.moves import range # pylint: disable=import-error
|
||||
from rplibs.six.moves import range # pylint: disable=import-error
|
||||
|
||||
from rpcore.native import IESDataset
|
||||
from rpcore.image import Image
|
||||
|
||||
@ -60,7 +60,7 @@ class MovementController(object):
|
||||
self.keyboard_hpr_speed = 0.4
|
||||
self.use_hpr = False
|
||||
self.smoothness = 6.0
|
||||
self.bobbing_amount = 0.0
|
||||
self.bobbing_amount = 1.5
|
||||
self.bobbing_speed = 0.5
|
||||
|
||||
def set_initial_position(self, pos, target):
|
||||
@ -138,8 +138,8 @@ class MovementController(object):
|
||||
self.showbase.accept("j", self.print_position)
|
||||
|
||||
# mouse
|
||||
self.showbase.accept("mouse3", self.set_mouse_enabled, [True])
|
||||
self.showbase.accept("mouse3-up", self.set_mouse_enabled, [False])
|
||||
self.showbase.accept("mouse1", self.set_mouse_enabled, [True])
|
||||
self.showbase.accept("mouse1-up", self.set_mouse_enabled, [False])
|
||||
|
||||
# arrow mouse navigation
|
||||
self.showbase.accept("arrow_up", self.set_hpr_movement, [1, 1])
|
||||
|
||||
@ -127,20 +127,9 @@ class NetworkCommunication(RPObject):
|
||||
be an update of a plugin setting """
|
||||
if cmd.startswith("setval "):
|
||||
parts = cmd.split()
|
||||
if len(parts) < 3:
|
||||
self.warn("Invalid setval command format. Expected: setval plugin.setting value")
|
||||
return
|
||||
|
||||
setting_parts = parts[1].split(".")
|
||||
if len(setting_parts) < 2:
|
||||
self.warn("Invalid setting format. Expected: plugin.setting")
|
||||
return
|
||||
|
||||
try:
|
||||
self._pipeline.plugin_mgr.on_setting_changed(
|
||||
setting_parts[0], setting_parts[1], parts[2])
|
||||
except Exception as e:
|
||||
self.warn("Error handling setting change:", str(e))
|
||||
self._pipeline.plugin_mgr.on_setting_changed(
|
||||
setting_parts[0], setting_parts[1], parts[2])
|
||||
else:
|
||||
self.warn("Recieved unkown plugin command:", cmd)
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ THE SOFTWARE.
|
||||
|
||||
"""
|
||||
|
||||
from six.moves import range # pylint: disable=import-error
|
||||
from rplibs.six.moves import range # pylint: disable=import-error
|
||||
|
||||
from panda3d.core import Vec3, CurveFitter
|
||||
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
"""Utilities for writing code that runs on Python 2 and 3"""
|
||||
|
||||
# Copyright (c) 2010-2015 Benjamin Peterson
|
||||
# Copyright (c) 2010-2020 Benjamin Peterson
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
@ -20,6 +18,8 @@
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
"""Utilities for writing code that runs on Python 2 and 3"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import functools
|
||||
@ -29,7 +29,7 @@ import sys
|
||||
import types
|
||||
|
||||
__author__ = "Benjamin Peterson <benjamin@python.org>"
|
||||
__version__ = "1.10.0"
|
||||
__version__ = "1.16.0"
|
||||
|
||||
|
||||
# Useful for very coarse version differentiation.
|
||||
@ -71,6 +71,11 @@ else:
|
||||
MAXSIZE = int((1 << 63) - 1)
|
||||
del X
|
||||
|
||||
if PY34:
|
||||
from importlib.util import spec_from_loader
|
||||
else:
|
||||
spec_from_loader = None
|
||||
|
||||
|
||||
def _add_doc(func, doc):
|
||||
"""Add documentation to a function."""
|
||||
@ -186,6 +191,11 @@ class _SixMetaPathImporter(object):
|
||||
return self
|
||||
return None
|
||||
|
||||
def find_spec(self, fullname, path, target=None):
|
||||
if fullname in self.known_modules:
|
||||
return spec_from_loader(fullname, self)
|
||||
return None
|
||||
|
||||
def __get_module(self, fullname):
|
||||
try:
|
||||
return self.known_modules[fullname]
|
||||
@ -223,6 +233,12 @@ class _SixMetaPathImporter(object):
|
||||
return None
|
||||
get_source = get_code # same as get_code
|
||||
|
||||
def create_module(self, spec):
|
||||
return self.load_module(spec.name)
|
||||
|
||||
def exec_module(self, module):
|
||||
pass
|
||||
|
||||
_importer = _SixMetaPathImporter(__name__)
|
||||
|
||||
|
||||
@ -241,6 +257,7 @@ _moved_attributes = [
|
||||
MovedAttribute("map", "itertools", "builtins", "imap", "map"),
|
||||
MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
|
||||
MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
|
||||
MovedAttribute("getoutput", "commands", "subprocess"),
|
||||
MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
|
||||
MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
|
||||
MovedAttribute("reduce", "__builtin__", "functools"),
|
||||
@ -254,18 +271,21 @@ _moved_attributes = [
|
||||
MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
|
||||
MovedModule("builtins", "__builtin__"),
|
||||
MovedModule("configparser", "ConfigParser"),
|
||||
MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"),
|
||||
MovedModule("copyreg", "copy_reg"),
|
||||
MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
|
||||
MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"),
|
||||
MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"),
|
||||
MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread" if sys.version_info < (3, 9) else "_thread"),
|
||||
MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
|
||||
MovedModule("http_cookies", "Cookie", "http.cookies"),
|
||||
MovedModule("html_entities", "htmlentitydefs", "html.entities"),
|
||||
MovedModule("html_parser", "HTMLParser", "html.parser"),
|
||||
MovedModule("http_client", "httplib", "http.client"),
|
||||
MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
|
||||
MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"),
|
||||
MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
|
||||
MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
|
||||
MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
|
||||
MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
|
||||
MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
|
||||
MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
|
||||
MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
|
||||
@ -337,10 +357,12 @@ _urllib_parse_moved_attributes = [
|
||||
MovedAttribute("quote_plus", "urllib", "urllib.parse"),
|
||||
MovedAttribute("unquote", "urllib", "urllib.parse"),
|
||||
MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
|
||||
MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"),
|
||||
MovedAttribute("urlencode", "urllib", "urllib.parse"),
|
||||
MovedAttribute("splitquery", "urllib", "urllib.parse"),
|
||||
MovedAttribute("splittag", "urllib", "urllib.parse"),
|
||||
MovedAttribute("splituser", "urllib", "urllib.parse"),
|
||||
MovedAttribute("splitvalue", "urllib", "urllib.parse"),
|
||||
MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
|
||||
MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
|
||||
MovedAttribute("uses_params", "urlparse", "urllib.parse"),
|
||||
@ -416,6 +438,8 @@ _urllib_request_moved_attributes = [
|
||||
MovedAttribute("URLopener", "urllib", "urllib.request"),
|
||||
MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
|
||||
MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
|
||||
MovedAttribute("parse_http_list", "urllib2", "urllib.request"),
|
||||
MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"),
|
||||
]
|
||||
for attr in _urllib_request_moved_attributes:
|
||||
setattr(Module_six_moves_urllib_request, attr.name, attr)
|
||||
@ -631,13 +655,16 @@ if PY3:
|
||||
import io
|
||||
StringIO = io.StringIO
|
||||
BytesIO = io.BytesIO
|
||||
del io
|
||||
_assertCountEqual = "assertCountEqual"
|
||||
if sys.version_info[1] <= 1:
|
||||
_assertRaisesRegex = "assertRaisesRegexp"
|
||||
_assertRegex = "assertRegexpMatches"
|
||||
_assertNotRegex = "assertNotRegexpMatches"
|
||||
else:
|
||||
_assertRaisesRegex = "assertRaisesRegex"
|
||||
_assertRegex = "assertRegex"
|
||||
_assertNotRegex = "assertNotRegex"
|
||||
else:
|
||||
def b(s):
|
||||
return s
|
||||
@ -659,6 +686,7 @@ else:
|
||||
_assertCountEqual = "assertItemsEqual"
|
||||
_assertRaisesRegex = "assertRaisesRegexp"
|
||||
_assertRegex = "assertRegexpMatches"
|
||||
_assertNotRegex = "assertNotRegexpMatches"
|
||||
_add_doc(b, """Byte literal""")
|
||||
_add_doc(u, """Text literal""")
|
||||
|
||||
@ -675,15 +703,23 @@ def assertRegex(self, *args, **kwargs):
|
||||
return getattr(self, _assertRegex)(*args, **kwargs)
|
||||
|
||||
|
||||
def assertNotRegex(self, *args, **kwargs):
|
||||
return getattr(self, _assertNotRegex)(*args, **kwargs)
|
||||
|
||||
|
||||
if PY3:
|
||||
exec_ = getattr(moves.builtins, "exec")
|
||||
|
||||
def reraise(tp, value, tb=None):
|
||||
if value is None:
|
||||
value = tp()
|
||||
if value.__traceback__ is not tb:
|
||||
raise value.with_traceback(tb)
|
||||
raise value
|
||||
try:
|
||||
if value is None:
|
||||
value = tp()
|
||||
if value.__traceback__ is not tb:
|
||||
raise value.with_traceback(tb)
|
||||
raise value
|
||||
finally:
|
||||
value = None
|
||||
tb = None
|
||||
|
||||
else:
|
||||
def exec_(_code_, _globs_=None, _locs_=None):
|
||||
@ -699,19 +735,19 @@ else:
|
||||
exec("""exec _code_ in _globs_, _locs_""")
|
||||
|
||||
exec_("""def reraise(tp, value, tb=None):
|
||||
raise tp, value, tb
|
||||
try:
|
||||
raise tp, value, tb
|
||||
finally:
|
||||
tb = None
|
||||
""")
|
||||
|
||||
|
||||
if sys.version_info[:2] == (3, 2):
|
||||
if sys.version_info[:2] > (3,):
|
||||
exec_("""def raise_from(value, from_value):
|
||||
if from_value is None:
|
||||
raise value
|
||||
raise value from from_value
|
||||
""")
|
||||
elif sys.version_info[:2] > (3, 2):
|
||||
exec_("""def raise_from(value, from_value):
|
||||
raise value from from_value
|
||||
try:
|
||||
raise value from from_value
|
||||
finally:
|
||||
value = None
|
||||
""")
|
||||
else:
|
||||
def raise_from(value, from_value):
|
||||
@ -786,13 +822,33 @@ if sys.version_info[:2] < (3, 3):
|
||||
_add_doc(reraise, """Reraise an exception.""")
|
||||
|
||||
if sys.version_info[0:2] < (3, 4):
|
||||
# This does exactly the same what the :func:`py3:functools.update_wrapper`
|
||||
# function does on Python versions after 3.2. It sets the ``__wrapped__``
|
||||
# attribute on ``wrapper`` object and it doesn't raise an error if any of
|
||||
# the attributes mentioned in ``assigned`` and ``updated`` are missing on
|
||||
# ``wrapped`` object.
|
||||
def _update_wrapper(wrapper, wrapped,
|
||||
assigned=functools.WRAPPER_ASSIGNMENTS,
|
||||
updated=functools.WRAPPER_UPDATES):
|
||||
for attr in assigned:
|
||||
try:
|
||||
value = getattr(wrapped, attr)
|
||||
except AttributeError:
|
||||
continue
|
||||
else:
|
||||
setattr(wrapper, attr, value)
|
||||
for attr in updated:
|
||||
getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
|
||||
wrapper.__wrapped__ = wrapped
|
||||
return wrapper
|
||||
_update_wrapper.__doc__ = functools.update_wrapper.__doc__
|
||||
|
||||
def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
|
||||
updated=functools.WRAPPER_UPDATES):
|
||||
def wrapper(f):
|
||||
f = functools.wraps(wrapped, assigned, updated)(f)
|
||||
f.__wrapped__ = wrapped
|
||||
return f
|
||||
return wrapper
|
||||
return functools.partial(_update_wrapper, wrapped=wrapped,
|
||||
assigned=assigned, updated=updated)
|
||||
wraps.__doc__ = functools.wraps.__doc__
|
||||
|
||||
else:
|
||||
wraps = functools.wraps
|
||||
|
||||
@ -802,10 +858,22 @@ def with_metaclass(meta, *bases):
|
||||
# This requires a bit of explanation: the basic idea is to make a dummy
|
||||
# metaclass for one level of class instantiation that replaces itself with
|
||||
# the actual metaclass.
|
||||
class metaclass(meta):
|
||||
class metaclass(type):
|
||||
|
||||
def __new__(cls, name, this_bases, d):
|
||||
return meta(name, bases, d)
|
||||
if sys.version_info[:2] >= (3, 7):
|
||||
# This version introduced PEP 560 that requires a bit
|
||||
# of extra care (we mimic what is done by __build_class__).
|
||||
resolved_bases = types.resolve_bases(bases)
|
||||
if resolved_bases is not bases:
|
||||
d['__orig_bases__'] = bases
|
||||
else:
|
||||
resolved_bases = bases
|
||||
return meta(name, resolved_bases, d)
|
||||
|
||||
@classmethod
|
||||
def __prepare__(cls, name, this_bases):
|
||||
return meta.__prepare__(name, bases)
|
||||
return type.__new__(metaclass, 'temporary_class', (), {})
|
||||
|
||||
|
||||
@ -821,13 +889,75 @@ def add_metaclass(metaclass):
|
||||
orig_vars.pop(slots_var)
|
||||
orig_vars.pop('__dict__', None)
|
||||
orig_vars.pop('__weakref__', None)
|
||||
if hasattr(cls, '__qualname__'):
|
||||
orig_vars['__qualname__'] = cls.__qualname__
|
||||
return metaclass(cls.__name__, cls.__bases__, orig_vars)
|
||||
return wrapper
|
||||
|
||||
|
||||
def ensure_binary(s, encoding='utf-8', errors='strict'):
|
||||
"""Coerce **s** to six.binary_type.
|
||||
|
||||
For Python 2:
|
||||
- `unicode` -> encoded to `str`
|
||||
- `str` -> `str`
|
||||
|
||||
For Python 3:
|
||||
- `str` -> encoded to `bytes`
|
||||
- `bytes` -> `bytes`
|
||||
"""
|
||||
if isinstance(s, binary_type):
|
||||
return s
|
||||
if isinstance(s, text_type):
|
||||
return s.encode(encoding, errors)
|
||||
raise TypeError("not expecting type '%s'" % type(s))
|
||||
|
||||
|
||||
def ensure_str(s, encoding='utf-8', errors='strict'):
|
||||
"""Coerce *s* to `str`.
|
||||
|
||||
For Python 2:
|
||||
- `unicode` -> encoded to `str`
|
||||
- `str` -> `str`
|
||||
|
||||
For Python 3:
|
||||
- `str` -> `str`
|
||||
- `bytes` -> decoded to `str`
|
||||
"""
|
||||
# Optimization: Fast return for the common case.
|
||||
if type(s) is str:
|
||||
return s
|
||||
if PY2 and isinstance(s, text_type):
|
||||
return s.encode(encoding, errors)
|
||||
elif PY3 and isinstance(s, binary_type):
|
||||
return s.decode(encoding, errors)
|
||||
elif not isinstance(s, (text_type, binary_type)):
|
||||
raise TypeError("not expecting type '%s'" % type(s))
|
||||
return s
|
||||
|
||||
|
||||
def ensure_text(s, encoding='utf-8', errors='strict'):
|
||||
"""Coerce *s* to six.text_type.
|
||||
|
||||
For Python 2:
|
||||
- `unicode` -> `unicode`
|
||||
- `str` -> `unicode`
|
||||
|
||||
For Python 3:
|
||||
- `str` -> `str`
|
||||
- `bytes` -> decoded to `str`
|
||||
"""
|
||||
if isinstance(s, binary_type):
|
||||
return s.decode(encoding, errors)
|
||||
elif isinstance(s, text_type):
|
||||
return s
|
||||
else:
|
||||
raise TypeError("not expecting type '%s'" % type(s))
|
||||
|
||||
|
||||
def python_2_unicode_compatible(klass):
|
||||
"""
|
||||
A decorator that defines __unicode__ and __str__ methods under Python 2.
|
||||
A class decorator that defines __unicode__ and __str__ methods under Python 2.
|
||||
Under Python 3 it does nothing.
|
||||
|
||||
To support Python 2 and 3 with a single code base, define a __str__ method
|
||||
|
||||
@ -24,7 +24,7 @@ THE SOFTWARE.
|
||||
|
||||
"""
|
||||
|
||||
from six.moves import range # pylint: disable=import-error
|
||||
from rplibs.six.moves import range # pylint: disable=import-error
|
||||
|
||||
from panda3d.core import SamplerState, Vec4
|
||||
|
||||
|
||||
@ -1,3 +1,29 @@
|
||||
"""
|
||||
|
||||
RenderPipeline
|
||||
|
||||
Copyright (c) 2014-2016 tobspr <tobias.springer1@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
"""
|
||||
|
||||
from rpcore.render_stage import RenderStage
|
||||
|
||||
|
||||
|
||||
@ -1,3 +1,29 @@
|
||||
"""
|
||||
|
||||
RenderPipeline
|
||||
|
||||
Copyright (c) 2014-2016 tobspr <tobias.springer1@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
"""
|
||||
|
||||
from rpcore.pluginbase.base_plugin import BasePlugin
|
||||
|
||||
from .dof_stage import DoFStage
|
||||
|
||||
@ -25,7 +25,7 @@ THE SOFTWARE.
|
||||
"""
|
||||
|
||||
from __future__ import division
|
||||
from six.moves import range # pylint: disable=import-error
|
||||
from rplibs.six.moves import range # pylint: disable=import-error
|
||||
from rplibs.six import itervalues
|
||||
|
||||
from panda3d.core import Camera, PerspectiveLens, Vec4, Vec3, PTAInt
|
||||
|
||||
@ -25,7 +25,7 @@ THE SOFTWARE.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
from six.moves import range # pylint: disable=import-error
|
||||
from rplibs.six.moves import range # pylint: disable=import-error
|
||||
from panda3d.core import PTAVecBase3f
|
||||
|
||||
from rpcore.globals import Globals
|
||||
|
||||
@ -24,7 +24,7 @@ THE SOFTWARE.
|
||||
|
||||
"""
|
||||
from __future__ import division
|
||||
from six.moves import range # pylint: disable=import-error
|
||||
from rplibs.six.moves import range # pylint: disable=import-error
|
||||
|
||||
from panda3d.core import SamplerState
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ THE SOFTWARE.
|
||||
|
||||
import math
|
||||
|
||||
from six.moves import range # pylint: disable=import-error
|
||||
from rplibs.six.moves import range # pylint: disable=import-error
|
||||
from rplibs.six import iteritems, itervalues
|
||||
|
||||
from direct.stdpy.file import listdir, isfile, join
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#extension GL_ARB_shading_language_420pack : enable
|
||||
|
||||
// This file includes defines and functions used for the scattering
|
||||
|
||||
|
||||
@ -7,8 +9,6 @@
|
||||
|
||||
#pragma include "render_pipeline_base.inc.glsl"
|
||||
|
||||
#extension GL_ARB_shading_language_420pack : enable
|
||||
|
||||
|
||||
// These can be overridden depending on if the shader is a compute shader
|
||||
// or a regular fragment shader
|
||||
|
||||
@ -26,7 +26,7 @@ THE SOFTWARE.
|
||||
|
||||
from panda3d.core import LVecBase2i
|
||||
|
||||
from six.moves import range # pylint: disable=import-error
|
||||
from rplibs.six.moves import range # pylint: disable=import-error
|
||||
from rpcore.render_stage import RenderStage
|
||||
|
||||
|
||||
|
||||
BIN
RenderPipelineFile/rptemp/core/RotationHandleFull.fbx
Executable file
BIN
RenderPipelineFile/rptemp/core/RotationHandleFull.fbx
Executable file
Binary file not shown.
BIN
RenderPipelineFile/rptemp/core/RotationHandleQuarter.fbx
Executable file
BIN
RenderPipelineFile/rptemp/core/RotationHandleQuarter.fbx
Executable file
Binary file not shown.
BIN
RenderPipelineFile/rptemp/core/TranslateArrowHandle.fbx
Executable file
BIN
RenderPipelineFile/rptemp/core/TranslateArrowHandle.fbx
Executable file
Binary file not shown.
BIN
RenderPipelineFile/rptemp/core/UniformScaleHandle.fbx
Executable file
BIN
RenderPipelineFile/rptemp/core/UniformScaleHandle.fbx
Executable file
Binary file not shown.
63
RenderPipelineFile/samples/.gitignore
vendored
Normal file
63
RenderPipelineFile/samples/.gitignore
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*,cover
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
|
||||
*.blend1
|
||||
03-Forest
|
||||
*.blend1
|
||||
*.blend2
|
||||
14
RenderPipelineFile/samples/README.md
Normal file
14
RenderPipelineFile/samples/README.md
Normal file
@ -0,0 +1,14 @@
|
||||
## Render Pipeline Samples
|
||||
|
||||
The samples are not included in this repository to keep the size small.
|
||||
|
||||
#### Automatic Download (recommended)
|
||||
You can run `python download_samples.py` to automatically download the samples.
|
||||
|
||||
#### Manual Download
|
||||
If you want to manually download the samples (for whatever reason), you can
|
||||
find them here:
|
||||
<a href="https://github.com/tobspr/RenderPipeline-Samples
|
||||
">https://github.com/tobspr/RenderPipeline-Samples</a>
|
||||
|
||||
After downloading, place the downloaded contents in this folder to run the samples.
|
||||
44
RenderPipelineFile/samples/download_samples.py
Normal file
44
RenderPipelineFile/samples/download_samples.py
Normal file
@ -0,0 +1,44 @@
|
||||
"""
|
||||
|
||||
RenderPipeline
|
||||
|
||||
Copyright (c) 2014-2016 tobspr <tobias.springer1@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
"""
|
||||
|
||||
# Script to download the Render Pipeline samples
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, "../")
|
||||
sys.path.insert(0, "../rpcore/util")
|
||||
|
||||
from submodule_downloader import download_submodule # noqa
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# Make sure we are in the right directory
|
||||
main_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
os.chdir(main_dir)
|
||||
|
||||
# Now extract the samples
|
||||
download_submodule("tobspr", "RenderPipeline-Samples", ".", ["README.md", "LICENSE"])
|
||||
@ -47,7 +47,7 @@ CURRENT_STEP = 0
|
||||
os.chdir(SETUP_DIR)
|
||||
sys.path.insert(0, ".")
|
||||
|
||||
from six.moves import input # pylint: disable=import-error
|
||||
from rplibs.six.moves import input # pylint: disable=import-error
|
||||
|
||||
# Load and init colorama, used to color the output
|
||||
from rplibs.colorama import init as init_colorama
|
||||
|
||||
2
RenderPipelineFile/setup_input.txt
Normal file
2
RenderPipelineFile/setup_input.txt
Normal file
@ -0,0 +1,2 @@
|
||||
n
|
||||
n
|
||||
@ -25,15 +25,11 @@ THE SOFTWARE.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
# from PyQt5 import Qt
|
||||
# from PyQt5.QtGui import QPainter, QColor, QPen
|
||||
# from PyQt5.QtWidgets import QWidget
|
||||
from six.moves import range # pylint: disable=import-error
|
||||
from rplibs.six.moves import range # pylint: disable=import-error
|
||||
|
||||
import math
|
||||
|
||||
from RenderPipelineFile.rplibs.pyqt_imports import * # noqa
|
||||
from rplibs.pyqt_imports import * # noqa
|
||||
|
||||
class CurveWidget(QWidget):
|
||||
|
||||
@ -216,13 +212,13 @@ class CurveWidget(QWidget):
|
||||
painter.setPen(QColor(200, 200, 200))
|
||||
for i in range(num_vert_lines + 1):
|
||||
line_pos = i * line_spacing_x + self._legend_border - 1
|
||||
painter.drawLine(int(line_pos), self._bar_h, int(line_pos), canvas_height + self._bar_h)
|
||||
painter.drawLine(line_pos, self._bar_h, line_pos, canvas_height + self._bar_h)
|
||||
|
||||
# Draw horizontal lines
|
||||
painter.setPen(QColor(200, 200, 200))
|
||||
for i in range(num_horiz_lines):
|
||||
line_pos = canvas_height - i * line_spacing_y + self._bar_h
|
||||
painter.drawLine(self._legend_border, int(line_pos), self.width(), int(line_pos))
|
||||
painter.drawLine(self._legend_border, line_pos, self.width(), line_pos)
|
||||
|
||||
# Draw vetical legend labels
|
||||
painter.setPen(QColor(120, 120, 120))
|
||||
@ -230,7 +226,7 @@ class CurveWidget(QWidget):
|
||||
line_pos = canvas_height - i * line_spacing_y + self._bar_h
|
||||
# painter.drawText(6, line_pos + 3, str(round(float(i) / (num_horiz_lines-1), 2)))
|
||||
painter.drawText(
|
||||
6, int(line_pos + 3), self._unit_processor(float(i) / (num_horiz_lines - 1)))
|
||||
6, line_pos + 3, self._unit_processor(float(i) / (num_horiz_lines - 1)))
|
||||
|
||||
# Draw horizontal legend labels
|
||||
for i in range(num_vert_lines + 1):
|
||||
@ -241,7 +237,7 @@ class CurveWidget(QWidget):
|
||||
elif i == num_vert_lines:
|
||||
offpos_x = -27
|
||||
time_string = str(int(float(i) / num_vert_lines * 24)).zfill(2) + ":00"
|
||||
painter.drawText(int(line_pos + offpos_x), canvas_height + self._bar_h + 18, time_string)
|
||||
painter.drawText(line_pos + offpos_x, canvas_height + self._bar_h + 18, time_string)
|
||||
|
||||
# Draw curve
|
||||
for index, curve in enumerate(self._curves):
|
||||
@ -255,7 +251,7 @@ class CurveWidget(QWidget):
|
||||
last_value = curve_height
|
||||
|
||||
painter.drawLine(
|
||||
int(self._legend_border + i - 1), int(last_value), int(self._legend_border + i), int(curve_height))
|
||||
self._legend_border + i - 1, last_value, self._legend_border + i, curve_height)
|
||||
last_value = curve_height
|
||||
|
||||
# Draw the CV points of the curve
|
||||
@ -271,7 +267,7 @@ class CurveWidget(QWidget):
|
||||
else:
|
||||
painter.setPen(QColor(100, 100, 100))
|
||||
painter.drawRect(
|
||||
int(offs_x - self._cv_point_size), int(offs_y - self._cv_point_size),
|
||||
offs_x - self._cv_point_size, offs_y - self._cv_point_size,
|
||||
2 * self._cv_point_size, 2 * self._cv_point_size)
|
||||
|
||||
# Draw bar background
|
||||
@ -306,7 +302,7 @@ class CurveWidget(QWidget):
|
||||
g = max(0, min(255, int(bar_curve[1].get_value(relv) * 255.0)))
|
||||
b = max(0, min(255, int(bar_curve[2].get_value(relv) * 255.0)))
|
||||
painter.setPen(QColor(r, g, b))
|
||||
painter.drawLine(int(xpos), bar_top_pos, int(xpos), bar_top_pos + 2 * bar_half_height)
|
||||
painter.drawLine(xpos, bar_top_pos, xpos, bar_top_pos + 2 * bar_half_height)
|
||||
|
||||
# Draw selected time
|
||||
if self._drag_point:
|
||||
@ -316,14 +312,14 @@ class CurveWidget(QWidget):
|
||||
canvas_width + 10, self._drag_time * canvas_width + self._legend_border - 19))
|
||||
offs_y = self.height() - self._legend_border
|
||||
minutes = int(self._drag_time * 24 * 60)
|
||||
hours = int(minutes / 60)
|
||||
hours = minutes / 60
|
||||
minutes = minutes % 60
|
||||
painter.drawRect(int(offs_x), self.height() - self._legend_border + 5, 40, 20)
|
||||
painter.drawText(int(offs_x + 7), offs_y + 20, "{:02}:{:02}".format(int(hours), int(minutes)))
|
||||
painter.drawRect(offs_x, self.height() - self._legend_border + 5, 40, 20)
|
||||
painter.drawText(offs_x + 7, offs_y + 20, "{:02}:{:02}".format(hours, minutes))
|
||||
|
||||
painter.setPen(QColor(150, 150, 150))
|
||||
painter.drawLine(
|
||||
int(offs_x) + 19, bar_top_pos + 15, int(offs_x + 19), self.height() - self._legend_border + 5)
|
||||
offs_x + 19, bar_top_pos + 15, offs_x + 19, self.height() - self._legend_border + 5)
|
||||
|
||||
# Display current time
|
||||
pen = QPen()
|
||||
@ -332,7 +328,7 @@ class CurveWidget(QWidget):
|
||||
painter.setPen(pen)
|
||||
|
||||
xoffs = self._legend_border + self._current_time * (canvas_width - 1)
|
||||
painter.drawLine(int(xoffs), self._bar_h, int(xoffs), self._bar_h + canvas_height)
|
||||
painter.drawLine(xoffs, self._bar_h, xoffs, self._bar_h + canvas_height)
|
||||
|
||||
# Draw usage hints
|
||||
painter.setPen(QColor(100, 100, 100))
|
||||
|
||||
@ -40,8 +40,8 @@ os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__))))
|
||||
# Add the render pipeline to the path
|
||||
sys.path.insert(0, "../../")
|
||||
|
||||
from RenderPipelineFile.rplibs.six import iteritems # noqa
|
||||
from RenderPipelineFile.rplibs.pyqt_imports import * # noqa
|
||||
from rplibs.six import iteritems # noqa
|
||||
from rplibs.pyqt_imports import * # noqa
|
||||
|
||||
from curve_widget import CurveWidget # noqa
|
||||
|
||||
@ -185,10 +185,7 @@ class DayTimeEditor(QMainWindow, Ui_MainWindow):
|
||||
widget.setText(1, formatted)
|
||||
|
||||
if setting_handle.type == "color":
|
||||
color_values = [int(v*255)for v in value]
|
||||
widget.setBackground(1, QBrush(QColor(*color_values)))
|
||||
# else:
|
||||
# widget.setBackground(1,QBrush(QColor(*value)))
|
||||
widget.setBackground(1, QBrush(QColor(*value)))
|
||||
|
||||
def _on_curve_edited(self):
|
||||
""" Called when the curve got edited in the curve widget """
|
||||
|
||||
@ -45,7 +45,7 @@ sys.path.insert(0, "../../")
|
||||
from rplibs.six import iteritems # noqa
|
||||
from rplibs.pyqt_imports import * # noqa
|
||||
|
||||
from RenderPipelineFile.toolkit.material_editor.ui.main_window_generated import Ui_MainWindow # noqa
|
||||
from ui.main_window_generated import Ui_MainWindow # noqa
|
||||
from rpcore.util.network_communication import NetworkCommunication # noqa
|
||||
|
||||
# Allow working with an older version of the material DB.
|
||||
@ -170,9 +170,9 @@ class MaterialEditor(QMainWindow, Ui_MainWindow):
|
||||
|
||||
# Basecolor
|
||||
values = self.basecolor_to_tuple(self.material)
|
||||
self.basecolor_1.setValue(int(values[0] * 100.0))
|
||||
self.basecolor_2.setValue(int(values[1] * 100.0))
|
||||
self.basecolor_3.setValue(int(values[2] * 100.0))
|
||||
self.basecolor_1.setValue(values[0] * 100.0)
|
||||
self.basecolor_2.setValue(values[1] * 100.0)
|
||||
self.basecolor_3.setValue(values[2] * 100.0)
|
||||
|
||||
# Shading model
|
||||
self.cb_shading_model.setCurrentIndex(self.material.shading_model)
|
||||
@ -184,7 +184,7 @@ class MaterialEditor(QMainWindow, Ui_MainWindow):
|
||||
# Rest of sliders
|
||||
for slider, lbl, start, end, prop in self.sliders:
|
||||
val = getattr(self.material, prop)
|
||||
slider.setValue(int((val - start) / (end - start) * 100.0))
|
||||
slider.setValue((val - start) / (end - start) * 100.0)
|
||||
|
||||
self.in_update = False
|
||||
self.update_ui()
|
||||
|
||||
@ -471,7 +471,7 @@ font-weight: 600;</string>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background: rgba(60, 120, 255, 1);</string>
|
||||
<string notr="true">background: rgba(60, 120, 255);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
|
||||
@ -357,4 +357,4 @@ class Ui_MainWindow(object):
|
||||
self.cb_srgb.setText(_translate("MainWindow", "SRGB"))
|
||||
self.cb_hsv.setText(_translate("MainWindow", "HSV"))
|
||||
|
||||
#from . import resources_rc
|
||||
from . import resources_rc
|
||||
|
||||
@ -49,8 +49,6 @@ from rplibs.pyqt_imports import * #noqa
|
||||
# Load the generated UI Layout
|
||||
from ui.main_window_generated import Ui_MainWindow # noqa
|
||||
|
||||
from ui.widgets import UniversalMessageDialog
|
||||
|
||||
from rpcore.pluginbase.manager import PluginManager # noqa
|
||||
from rpcore.util.network_communication import NetworkCommunication # noqa
|
||||
from rpcore.mount_manager import MountManager # noqa
|
||||
@ -99,11 +97,6 @@ class PluginConfigurator(QMainWindow, Ui_MainWindow):
|
||||
update_thread = Thread(target=self.update_thread, args=())
|
||||
update_thread.start()
|
||||
|
||||
# 启动通信文件监听线程
|
||||
comm_thread = Thread(target=self.communication_thread, args=())
|
||||
comm_thread.daemon = True # 设置为守护线 程,主程序退出时自动结束
|
||||
comm_thread.start()
|
||||
|
||||
def closeEvent(self, event): # noqa
|
||||
event.accept()
|
||||
import os
|
||||
@ -121,13 +114,9 @@ class PluginConfigurator(QMainWindow, Ui_MainWindow):
|
||||
self, "Warning", msg, QMessageBox.Yes, QMessageBox.No)
|
||||
if reply == QMessageBox.Yes:
|
||||
|
||||
UniversalMessageDialog.show_success(
|
||||
self,
|
||||
"Success",
|
||||
"Settings have been reset! You may have to restart the pipeline.",
|
||||
show_cancel=False,
|
||||
confirm_text="OK"
|
||||
)
|
||||
QMessageBox.information(
|
||||
self, "Success",
|
||||
"Settings have been reset! You may have to restart the pipeline.")
|
||||
self._plugin_mgr.reset_plugin_settings(self._current_plugin)
|
||||
|
||||
# Save config
|
||||
@ -374,14 +363,14 @@ class PluginConfigurator(QMainWindow, Ui_MainWindow):
|
||||
|
||||
if setting.type == "float":
|
||||
box.setSingleStep(abs(setting.maxval - setting.minval) / 100.0)
|
||||
slider.setMinimum(int(setting.minval * 100000.0))
|
||||
slider.setMaximum(int(setting.maxval * 100000.0))
|
||||
slider.setValue(int(setting.value * 100000.0))
|
||||
slider.setMinimum(setting.minval * 100000.0)
|
||||
slider.setMaximum(setting.maxval * 100000.0)
|
||||
slider.setValue(setting.value * 100000.0)
|
||||
elif setting.type == "int":
|
||||
box.setSingleStep(int(max(1, (setting.maxval - setting.minval) / 32)))
|
||||
slider.setMinimum(int(setting.minval))
|
||||
slider.setMaximum(int(setting.maxval))
|
||||
slider.setValue(int(setting.value))
|
||||
box.setSingleStep(max(1, (setting.maxval - setting.minval) / 32))
|
||||
slider.setMinimum(setting.minval)
|
||||
slider.setMaximum(setting.maxval)
|
||||
slider.setValue(setting.value)
|
||||
|
||||
layout.addWidget(box)
|
||||
layout.addWidget(slider)
|
||||
@ -497,84 +486,6 @@ class PluginConfigurator(QMainWindow, Ui_MainWindow):
|
||||
|
||||
self.lst_plugins.setCurrentRow(0)
|
||||
|
||||
def communication_thread(self):
|
||||
"""监听来自主程序的通信文件"""
|
||||
import json
|
||||
import tempfile
|
||||
|
||||
comm_dir = os.path.join(tempfile.gettempdir(), "daytime_editor_comm")
|
||||
comm_file = os.path.join(comm_dir, "sun_azimuth_command.json")
|
||||
|
||||
print("🔄 Day Time Editor通信监听已启动")
|
||||
print(f" 监听文件: {comm_file}")
|
||||
|
||||
last_timestamp = 0
|
||||
|
||||
while True:
|
||||
try:
|
||||
if os.path.exists(comm_file):
|
||||
with open(comm_file, 'r') as f:
|
||||
command = json.load(f)
|
||||
|
||||
# 检查是否是新命令(避免重复执行)
|
||||
if command.get('timestamp', 0) > last_timestamp:
|
||||
last_timestamp = command.get('timestamp', 0)
|
||||
|
||||
if command.get('command') == 'set_sun_azimuth':
|
||||
azimuth_value = command.get('value', 0)
|
||||
print(f"📨 收到Sun Azimuth命令: {azimuth_value}°")
|
||||
|
||||
# 在主线程中执行UI更新
|
||||
QTimer.singleShot(0, partial(self.apply_sun_azimuth, azimuth_value))
|
||||
|
||||
time.sleep(0.1) # 100ms检查一次
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ 通信监听错误: {e}")
|
||||
time.sleep(1) # 出错时等待1秒再重试
|
||||
|
||||
def apply_sun_azimuth(self, azimuth_degrees):
|
||||
"""应用Sun Azimuth值到Day Time Editor"""
|
||||
try:
|
||||
print(f"🌞 正在应用Sun Azimuth: {azimuth_degrees}°")
|
||||
|
||||
# 查找Sun Azimuth相关的控件
|
||||
# 这里需要根据实际的UI结构来实现
|
||||
# 先尝试找到可能的控件
|
||||
|
||||
# 方法1:查找包含"azimuth"的控件
|
||||
for widget_name in dir(self):
|
||||
widget = getattr(self, widget_name, None)
|
||||
if widget and hasattr(widget, 'setValue'):
|
||||
if 'azimuth' in widget_name.lower() or 'sun' in widget_name.lower():
|
||||
print(f" 尝试设置控件: {widget_name}")
|
||||
try:
|
||||
widget.setValue(azimuth_degrees)
|
||||
print(f"✅ 成功设置 {widget_name} = {azimuth_degrees}°")
|
||||
return
|
||||
except Exception as e:
|
||||
print(f" 设置失败: {e}")
|
||||
|
||||
# 方法2:查找表格中的Sun Azimuth设置
|
||||
if hasattr(self, 'table_plugin_settings'):
|
||||
table = self.table_plugin_settings
|
||||
for row in range(table.rowCount()):
|
||||
item = table.item(row, 0) # 第一列通常是设置名称
|
||||
if item and 'azimuth' in item.text().lower():
|
||||
# 找到Sun Azimuth行,设置第二列的值
|
||||
value_item = table.item(row, 1)
|
||||
if value_item:
|
||||
value_item.setText(str(azimuth_degrees))
|
||||
print(f"✅ 在表格中设置Sun Azimuth = {azimuth_degrees}°")
|
||||
return
|
||||
|
||||
print("⚠️ 未找到Sun Azimuth控件,请检查UI结构")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 应用Sun Azimuth失败: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
# Start application
|
||||
app = QApplication(sys.argv)
|
||||
qt_register_fonts()
|
||||
|
||||
BIN
Resources/models_1_1/box.glb
Normal file
BIN
Resources/models_1_1/box.glb
Normal file
Binary file not shown.
BIN
Resources/textures/布料 针织法线贴图.jpg
Normal file
BIN
Resources/textures/布料 针织法线贴图.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 MiB |
BIN
Resources/textures/针织 编织 布料法线纹理贴图.jpg
Normal file
BIN
Resources/textures/针织 编织 布料法线纹理贴图.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.5 MiB |
20
Start_Run.py
20
Start_Run.py
@ -29,9 +29,21 @@ if __name__ == "__main__":
|
||||
# 将整个列表转换为字符串(包括方括号)
|
||||
args_str = ''.join(args)
|
||||
|
||||
from main import run
|
||||
from main import MyWorld
|
||||
if args:
|
||||
run(args_str)
|
||||
# run(args)
|
||||
# print(f"[DEBUG] 启动时传入项目路径: {args_str}")
|
||||
# 创建应用实例
|
||||
app = MyWorld()
|
||||
# 如果传入了项目路径,尝试打开项目
|
||||
if hasattr(app, 'project_manager'):
|
||||
# print(f"[DEBUG] 尝试打开项目: {args_str}")
|
||||
success = app.project_manager.openProject(args_str)
|
||||
# print(f"[DEBUG] 项目打开结果: {success}")
|
||||
else:
|
||||
# print(f"[DEBUG] 项目管理器未初始化")
|
||||
pass
|
||||
app.run()
|
||||
else:
|
||||
run()
|
||||
# print(f"[DEBUG] 无项目路径,正常启动")
|
||||
app = MyWorld()
|
||||
app.run()
|
||||
104
TransformGizmo/docs/transform_gizmo_events.md
Normal file
104
TransformGizmo/docs/transform_gizmo_events.md
Normal file
@ -0,0 +1,104 @@
|
||||
# TransformGizmo 事件钩子使用说明
|
||||
|
||||
本文档说明如何在 `TransformGizmo` 初始化时注入拖拽事件回调(类似 C# 委托),以及各事件的负载字段。
|
||||
|
||||
## 事件常量
|
||||
|
||||
所有事件名集中在 `TransformGizmo.events.GizmoEvent`,避免拼写错误:
|
||||
|
||||
```python
|
||||
from src.TransformGizmo.events import GizmoEvent
|
||||
|
||||
GizmoEvent.DRAG_START # "drag_start"
|
||||
GizmoEvent.DRAG_MOVE # "drag_move"
|
||||
GizmoEvent.DRAG_END # "drag_end"
|
||||
GizmoEvent.ALL # ("drag_start", "drag_move", "drag_end")
|
||||
```
|
||||
|
||||
## 基础用法示例
|
||||
|
||||
在构造 `TransformGizmo` 时传入 `event_hooks`,按 handle 类型分组(`"move"`, `"rotate"`, `"scale"` 或对应 `TransformGizmoMode` 值),每组里是事件名到回调列表的映射:
|
||||
|
||||
```python
|
||||
from src.TransformGizmo.transform_gizmo import TransformGizmo, TransformGizmoMode
|
||||
from src.TransformGizmo.events import GizmoEvent
|
||||
|
||||
|
||||
def on_move_start(info):
|
||||
print("[move] start", "axis", info["axis"], "plane", info["plane"])
|
||||
|
||||
|
||||
def on_move_drag(info):
|
||||
print("[move] pos ->", info["new_pos"])
|
||||
|
||||
|
||||
def on_rotate_drag(info):
|
||||
print("[rotate] delta_deg =", info["delta_deg"])
|
||||
|
||||
|
||||
def on_scale_end(info):
|
||||
print("[scale] final_scale =", info["final_scale"])
|
||||
|
||||
|
||||
hooks = {
|
||||
TransformGizmoMode.MOVE: {
|
||||
GizmoEvent.DRAG_START: [on_move_start],
|
||||
GizmoEvent.DRAG_MOVE: [on_move_drag],
|
||||
},
|
||||
TransformGizmoMode.ROTATE: {
|
||||
GizmoEvent.DRAG_MOVE: [on_rotate_drag],
|
||||
},
|
||||
TransformGizmoMode.SCALE: {
|
||||
GizmoEvent.DRAG_END: [on_scale_end],
|
||||
},
|
||||
}
|
||||
|
||||
# world: 你的 Panda3DWorld 实例
|
||||
gizmo = TransformGizmo(world, event_hooks=hooks)
|
||||
```
|
||||
|
||||
### 运行时追加 / 移除
|
||||
|
||||
初始化后也可以直接操作子 gizmo 的钩子列表:
|
||||
|
||||
```python
|
||||
from src.TransformGizmo.events import GizmoEvent
|
||||
|
||||
gizmo.move_gizmo._event_hooks[GizmoEvent.DRAG_MOVE].append(on_move_drag)
|
||||
# 移除同理,用 list.remove(on_move_drag)
|
||||
```
|
||||
|
||||
## 回调负载字段
|
||||
|
||||
各事件都会传入一个 `dict`,常见字段如下(不存在的字段将为 `None` 或缺省):
|
||||
|
||||
### Move
|
||||
- `axis`:0/1/2(X/Y/Z),平面拖拽时为 `None`
|
||||
- `plane`:0/1/2(XY/YZ/ZX),轴拖拽时为 `None`
|
||||
- `mouse`:`Point2`,拖拽开始/过程中鼠标 NDC 坐标
|
||||
- `start_pos` / `new_pos` / `final_pos`:世界坐标 `Vec3`
|
||||
- `target`:当前绑定的 `NodePath`
|
||||
- `gizmo`:字符串 `"move"`
|
||||
|
||||
### Rotate
|
||||
- `mode`:`"axis"` 或 `"trackball"`
|
||||
- `axis`:0/1/2(X/Y/Z),轨迹球时为 `None`
|
||||
- `delta_deg`:本次 `drag_move` 的角度增量(度)
|
||||
- `start_quat`:拖拽开始时的世界四元数
|
||||
- `final_hpr`:拖拽结束时的世界 HPR(仅 `drag_end`)
|
||||
- `center`:gizmo 中心点(世界坐标)
|
||||
- `axis_world`:当前旋转轴的世界方向
|
||||
- `mouse`:`Point2`
|
||||
- `target`,`gizmo` 同上
|
||||
|
||||
### Scale
|
||||
- `axis`:0/1/2 对应 X/Y/Z,3 表示中心均匀缩放
|
||||
- `scale_factor`:本次 `drag_move` 计算出的缩放倍率
|
||||
- `start_scale` / `new_scale` / `final_scale`:`Vec3`
|
||||
- `mouse`:`Point2`
|
||||
- `target`,`gizmo` 同上
|
||||
|
||||
## 小贴士
|
||||
- 事件字典的键可以用字符串 `"move"`/`"rotate"`/`"scale"`,也可以用 `TransformGizmoMode` 的对应值,内部都会匹配。
|
||||
- 每个事件支持多个回调(列表),内部对单个回调异常做了 try/except,互不影响。
|
||||
- 如果只想监听部分事件,留空即可,内部会自动填充为空列表。
|
||||
21
TransformGizmo/events.py
Normal file
21
TransformGizmo/events.py
Normal file
@ -0,0 +1,21 @@
|
||||
class GizmoEvent:
|
||||
"""String constants for gizmo event hook names."""
|
||||
|
||||
DRAG_START = "drag_start"
|
||||
DRAG_MOVE = "drag_move"
|
||||
DRAG_END = "drag_end"
|
||||
|
||||
ALL = (DRAG_START, DRAG_MOVE, DRAG_END)
|
||||
|
||||
|
||||
class TransformGizmoMode:
|
||||
"""Simple string constants for gizmo modes."""
|
||||
|
||||
NONE = "none"
|
||||
MOVE = "move"
|
||||
ROTATE = "rotate"
|
||||
SCALE = "scale" # reserved for future implementation
|
||||
ALL = "all" # move + rotate together (matches existing UI semantics)
|
||||
|
||||
|
||||
__all__ = ["GizmoEvent", "TransformGizmoMode"]
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user