105 lines
3.3 KiB
Markdown
105 lines
3.3 KiB
Markdown
# 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,互不影响。
|
||
- 如果只想监听部分事件,留空即可,内部会自动填充为空列表。
|