219 lines
9.1 KiB
Python
219 lines
9.1 KiB
Python
from imgui_bundle import imgui, imgui_ctx
|
|
|
|
class EditorPanelsRightCollisionMixin:
|
|
"""Auto-split mixin from editor_panels_right.py."""
|
|
|
|
def _draw_collision_properties(self, node):
|
|
"""绘制碰撞检测属性"""
|
|
if not node or node.isEmpty():
|
|
return
|
|
|
|
try:
|
|
# 检查节点是否已有碰撞
|
|
has_collision = self._has_collision(node)
|
|
|
|
# 碰撞状态徽章
|
|
imgui.text("状态:")
|
|
imgui.same_line()
|
|
if has_collision:
|
|
imgui.text_colored((0.0, 0.8, 0.0, 1.0), "🟢 已启用")
|
|
else:
|
|
imgui.text_colored((0.8, 0.0, 0.0, 1.0), "🔴 未启用")
|
|
|
|
imgui.separator()
|
|
|
|
# 碰撞形状选择
|
|
imgui.text("碰撞形状:")
|
|
imgui.same_line()
|
|
|
|
# 碰撞形状选项
|
|
collision_shapes = ["球形 (Sphere)", "盒型 (Box)", "胶囊体 (Capsule)", "平面 (Plane)", "自动选择 (Auto)"]
|
|
|
|
# 获取当前形状
|
|
current_shape = self._get_current_collision_shape(node) if has_collision else getattr(self.app, '_selected_collision_shape', "球形 (Sphere)")
|
|
if has_collision: self.app._selected_collision_shape = current_shape
|
|
|
|
# 形状选择下拉框
|
|
current_index = collision_shapes.index(current_shape) if current_shape in collision_shapes else 0
|
|
changed, selected_index = imgui.combo("##collision_shape", current_index, collision_shapes)
|
|
if changed:
|
|
# 始终更新选择的形状
|
|
selected_shape = collision_shapes[selected_index]
|
|
self.app._selected_collision_shape = selected_shape
|
|
# 如果已经有碰撞体,询问用户是否要重新创建
|
|
if has_collision:
|
|
self._remove_collision_from_node(node)
|
|
self._add_collision_to_node(node)
|
|
|
|
imgui.separator()
|
|
|
|
# 位置偏移控件
|
|
imgui.text("位置偏移:")
|
|
|
|
# 获取当前位置偏移
|
|
pos_offset = self._get_collision_position_offset(node)
|
|
|
|
# X位置
|
|
changed, new_x = imgui.drag_float("X##collision_pos_x", pos_offset[0], 0.1, -100.0, 100.0, "%.2f")
|
|
if changed and has_collision:
|
|
self._update_collision_position(node, 'x', new_x)
|
|
|
|
# Y位置
|
|
changed, new_y = imgui.drag_float("Y##collision_pos_y", pos_offset[1], 0.1, -100.0, 100.0, "%.2f")
|
|
if changed and has_collision:
|
|
self._update_collision_position(node, 'y', new_y)
|
|
|
|
# Z位置
|
|
changed, new_z = imgui.drag_float("Z##collision_pos_z", pos_offset[2], 0.1, -100.0, 100.0, "%.2f")
|
|
if changed and has_collision:
|
|
self._update_collision_position(node, 'z', new_z)
|
|
|
|
# 形状特定参数(始终显示,但根据状态启用/禁用)
|
|
shape_type = self._get_current_collision_shape_type(node)
|
|
self._draw_shape_specific_parameters(node, shape_type, has_collision)
|
|
|
|
imgui.separator()
|
|
|
|
# 操作按钮
|
|
if has_collision:
|
|
# 显示/隐藏碰撞体按钮
|
|
is_visible = self._is_collision_visible(node)
|
|
visibility_text = "隐藏碰撞体" if is_visible else "显示碰撞体"
|
|
if imgui.button(visibility_text):
|
|
self._toggle_collision_visibility(node)
|
|
|
|
imgui.same_line()
|
|
|
|
# 移除碰撞按钮
|
|
if imgui.button("移除碰撞"):
|
|
self._remove_collision_from_node(node)
|
|
else:
|
|
# 添加碰撞按钮
|
|
if imgui.button("添加碰撞"):
|
|
self._add_collision_to_node(node)
|
|
|
|
imgui.separator()
|
|
|
|
# 碰撞检测触发模式
|
|
imgui.text("触发模式:")
|
|
|
|
# 自动检测开关
|
|
auto_enabled = self.collision_manager.model_collision_enabled if hasattr(self, 'collision_manager') else False
|
|
changed, new_auto = imgui.checkbox("自动检测", auto_enabled)
|
|
if changed and hasattr(self, 'collision_manager'):
|
|
self.collision_manager.enableModelCollisionDetection(new_auto, 0.1, 0.5)
|
|
|
|
imgui.same_line()
|
|
|
|
# 手动检测按钮
|
|
if imgui.button("立即检测"):
|
|
if hasattr(self, 'collision_manager'):
|
|
self._manual_collision_detection()
|
|
|
|
except Exception as e:
|
|
print(f"绘制碰撞属性失败: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
|
|
def _draw_shape_specific_parameters(self, node, shape_type, has_collision=True):
|
|
"""绘制形状特定参数"""
|
|
try:
|
|
if shape_type == "sphere":
|
|
self._draw_sphere_parameters(node, has_collision)
|
|
elif shape_type == "box":
|
|
self._draw_box_parameters(node, has_collision)
|
|
elif shape_type == "capsule":
|
|
self._draw_capsule_parameters(node, has_collision)
|
|
elif shape_type == "plane":
|
|
self._draw_plane_parameters(node, has_collision)
|
|
except Exception as e:
|
|
print(f"绘制形状参数失败: {e}")
|
|
|
|
def _draw_sphere_parameters(self, node, has_collision=True):
|
|
"""绘制球形参数"""
|
|
try:
|
|
imgui.text("球形参数:")
|
|
imgui.same_line()
|
|
|
|
# 获取当前半径
|
|
radius = self._get_sphere_radius(node)
|
|
|
|
# 半径调整
|
|
changed, new_radius = imgui.drag_float("半径##sphere_radius", radius, 0.1, 0.1, 100.0, "%.2f")
|
|
if changed and has_collision:
|
|
self._update_sphere_radius(node, new_radius)
|
|
|
|
except Exception as e:
|
|
print(f"绘制球形参数失败: {e}")
|
|
|
|
def _draw_box_parameters(self, node, has_collision=True):
|
|
"""绘制盒型参数"""
|
|
try:
|
|
imgui.text("盒型参数:")
|
|
|
|
# 获取当前尺寸
|
|
size = self._get_box_size(node)
|
|
|
|
# 尺寸调整
|
|
changed, new_x = imgui.drag_float("长度##box_length", size[0], 0.1, 0.1, 100.0, "%.2f")
|
|
if changed and has_collision:
|
|
self._update_box_size(node, 'x', new_x)
|
|
|
|
changed, new_y = imgui.drag_float("宽度##box_width", size[1], 0.1, 0.1, 100.0, "%.2f")
|
|
if changed and has_collision:
|
|
self._update_box_size(node, 'y', new_y)
|
|
|
|
changed, new_z = imgui.drag_float("高度##box_height", size[2], 0.1, 0.1, 100.0, "%.2f")
|
|
if changed and has_collision:
|
|
self._update_box_size(node, 'z', new_z)
|
|
|
|
except Exception as e:
|
|
print(f"绘制盒型参数失败: {e}")
|
|
|
|
def _draw_capsule_parameters(self, node, has_collision=True):
|
|
"""绘制胶囊体参数"""
|
|
try:
|
|
imgui.text("胶囊体参数:")
|
|
|
|
# 获取当前参数
|
|
radius = self._get_capsule_radius(node)
|
|
height = self._get_capsule_height(node)
|
|
|
|
# 半径调整
|
|
changed, new_radius = imgui.drag_float("半径##capsule_radius", radius, 0.1, 0.1, 100.0, "%.2f")
|
|
if changed and has_collision:
|
|
self._update_capsule_radius(node, new_radius)
|
|
|
|
# 高度调整
|
|
changed, new_height = imgui.drag_float("高度##capsule_height", height, 0.1, 0.1, 100.0, "%.2f")
|
|
if changed and has_collision:
|
|
self._update_capsule_height(node, new_height)
|
|
|
|
except Exception as e:
|
|
print(f"绘制胶囊体参数失败: {e}")
|
|
|
|
def _draw_plane_parameters(self, node, has_collision=True):
|
|
"""绘制平面参数"""
|
|
try:
|
|
imgui.text("平面参数:")
|
|
|
|
# 获取当前法向量
|
|
normal = self._get_plane_normal(node)
|
|
|
|
# 法向量调整
|
|
changed, new_x = imgui.drag_float("法向量 X##plane_normal_x", normal[0], 0.1, -1.0, 1.0, "%.2f")
|
|
if changed and has_collision:
|
|
self._update_plane_normal(node, 'x', new_x)
|
|
|
|
changed, new_y = imgui.drag_float("法向量 Y##plane_normal_y", normal[1], 0.1, -1.0, 1.0, "%.2f")
|
|
if changed and has_collision:
|
|
self._update_plane_normal(node, 'y', new_y)
|
|
|
|
changed, new_z = imgui.drag_float("法向量 Z##plane_normal_z", normal[2], 0.1, -1.0, 1.0, "%.2f")
|
|
if changed and has_collision:
|
|
self._update_plane_normal(node, 'z', new_z)
|
|
|
|
except Exception as e:
|
|
print(f"绘制平面参数失败: {e}")
|
|
|