ui替换
This commit is contained in:
parent
35d28f4e2b
commit
bde899a04f
685
demo.py
685
demo.py
@ -174,6 +174,9 @@ class MyWorld(CoreWorld):
|
||||
|
||||
# 默认启用模型间碰撞检测(可选)
|
||||
self.enableModelCollisionDetection(enable=True, frequency=0.1, threshold=0.5)
|
||||
|
||||
# 碰撞检测UI相关变量
|
||||
self._selected_collision_shape = "球形 (Sphere)" # 默认选择的碰撞形状
|
||||
|
||||
# 启动脚本系统
|
||||
self.script_manager.start_system()
|
||||
@ -1408,7 +1411,7 @@ class MyWorld(CoreWorld):
|
||||
imgui.spacing()
|
||||
|
||||
# 物体名称组(使用Qt版本的样式)
|
||||
if imgui.collapsing_header("物体名称", True):
|
||||
if imgui.collapsing_header("物体名称"):
|
||||
# 第一行:可见性复选框和名称输入
|
||||
user_visible = node.getPythonTag("user_visible")
|
||||
if user_visible is None:
|
||||
@ -1447,7 +1450,7 @@ class MyWorld(CoreWorld):
|
||||
imgui.spacing()
|
||||
|
||||
# 变换属性组
|
||||
if imgui.collapsing_header("变换 Transform", True):
|
||||
if imgui.collapsing_header("变换 Transform"):
|
||||
self._draw_transform_properties(node)
|
||||
|
||||
# 根据节点类型显示特定属性组
|
||||
@ -1465,6 +1468,10 @@ class MyWorld(CoreWorld):
|
||||
if imgui.collapsing_header("外观属性"):
|
||||
self._draw_appearance_properties(node)
|
||||
|
||||
# 碰撞检测组
|
||||
if imgui.collapsing_header("碰撞检测"):
|
||||
self._draw_collision_properties(node)
|
||||
|
||||
# 操作按钮组
|
||||
if imgui.collapsing_header("操作"):
|
||||
self._draw_property_actions(node)
|
||||
@ -1554,7 +1561,7 @@ class MyWorld(CoreWorld):
|
||||
def _draw_transform_properties(self, node):
|
||||
"""绘制变换属性"""
|
||||
# 位置组
|
||||
if imgui.collapsing_header("位置 Position", True):
|
||||
if imgui.collapsing_header("位置 Position"):
|
||||
# 相对位置
|
||||
imgui.text("相对位置")
|
||||
pos = node.getPos()
|
||||
@ -1654,7 +1661,7 @@ class MyWorld(CoreWorld):
|
||||
imgui.text(f"GUI类型: {gui_type}")
|
||||
|
||||
# 基本属性
|
||||
if imgui.collapsing_header("基本属性", True):
|
||||
if imgui.collapsing_header("基本属性"):
|
||||
# 文本内容 (适用于按钮、标签等)
|
||||
if hasattr(gui_element, 'text'):
|
||||
changed, new_text = imgui.input_text("文本内容", gui_element.text, 256)
|
||||
@ -1956,6 +1963,674 @@ class MyWorld(CoreWorld):
|
||||
# 材质数量
|
||||
imgui.text("材质数量: (暂不支持显示)")
|
||||
|
||||
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 "球形 (Sphere)"
|
||||
|
||||
# 形状选择下拉框
|
||||
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._selected_collision_shape = selected_shape
|
||||
# 如果已经有碰撞体,询问用户是否要重新创建
|
||||
if has_collision:
|
||||
print(f"形状已更改为 {selected_shape},点击'移除碰撞'后'添加碰撞'来应用新形状")
|
||||
|
||||
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 _has_collision(self, node):
|
||||
"""检查节点是否有碰撞体"""
|
||||
try:
|
||||
if not node or node.isEmpty():
|
||||
return False
|
||||
|
||||
# 检查是否有碰撞节点
|
||||
for child in node.getChildren():
|
||||
if hasattr(child, 'getName') and child.getName():
|
||||
name = child.getName()
|
||||
if 'collision' in name.lower() or 'Collision' in name:
|
||||
return True
|
||||
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"检查碰撞状态失败: {e}")
|
||||
return False
|
||||
|
||||
def _get_current_collision_shape(self, node):
|
||||
"""获取当前碰撞形状"""
|
||||
try:
|
||||
if not self._has_collision(node):
|
||||
return "球形 (Sphere)"
|
||||
|
||||
# 查找碰撞节点并判断形状
|
||||
for child in node.getChildren():
|
||||
if hasattr(child, 'getName') and child.getName():
|
||||
name = child.getName()
|
||||
if 'collision' in name.lower() or 'Collision' in name:
|
||||
# 根据碰撞节点名称判断形状
|
||||
if 'sphere' in name.lower():
|
||||
return "球形 (Sphere)"
|
||||
elif 'box' in name.lower():
|
||||
return "盒型 (Box)"
|
||||
elif 'capsule' in name.lower():
|
||||
return "胶囊体 (Capsule)"
|
||||
elif 'plane' in name.lower():
|
||||
return "平面 (Plane)"
|
||||
|
||||
return "球形 (Sphere)" # 默认
|
||||
except Exception as e:
|
||||
print(f"获取碰撞形状失败: {e}")
|
||||
return "球形 (Sphere)"
|
||||
|
||||
def _get_current_collision_shape_type(self, node):
|
||||
"""获取当前碰撞形状类型(内部标识)"""
|
||||
try:
|
||||
shape_name = self._get_current_collision_shape(node)
|
||||
if "Sphere" in shape_name:
|
||||
return "sphere"
|
||||
elif "Box" in shape_name:
|
||||
return "box"
|
||||
elif "Capsule" in shape_name:
|
||||
return "capsule"
|
||||
elif "Plane" in shape_name:
|
||||
return "plane"
|
||||
else:
|
||||
return "sphere"
|
||||
except Exception as e:
|
||||
print(f"获取碰撞形状类型失败: {e}")
|
||||
return "sphere"
|
||||
|
||||
def _get_collision_position_offset(self, node):
|
||||
"""获取碰撞体位置偏移"""
|
||||
try:
|
||||
if not self._has_collision(node):
|
||||
return (0.0, 0.0, 0.0)
|
||||
|
||||
# 查找碰撞节点并获取位置
|
||||
for child in node.getChildren():
|
||||
if hasattr(child, 'getName') and child.getName():
|
||||
name = child.getName()
|
||||
if 'collision' in name.lower() or 'Collision' in name:
|
||||
pos = child.getPos()
|
||||
return (pos.x, pos.y, pos.z)
|
||||
|
||||
return (0.0, 0.0, 0.0)
|
||||
except Exception as e:
|
||||
print(f"获取碰撞位置失败: {e}")
|
||||
return (0.0, 0.0, 0.0)
|
||||
|
||||
def _is_collision_visible(self, node):
|
||||
"""检查碰撞体是否可见"""
|
||||
try:
|
||||
if not self._has_collision(node):
|
||||
return False
|
||||
|
||||
# 查找碰撞节点并检查可见性
|
||||
for child in node.getChildren():
|
||||
if hasattr(child, 'getName') and child.getName():
|
||||
name = child.getName()
|
||||
if 'collision' in name.lower() or 'Collision' in name:
|
||||
return child.isHidden() == False
|
||||
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"检查碰撞可见性失败: {e}")
|
||||
return False
|
||||
|
||||
def _add_collision_to_node(self, node):
|
||||
"""为节点添加碰撞体"""
|
||||
try:
|
||||
if not node or node.isEmpty():
|
||||
print("无效的节点")
|
||||
return
|
||||
|
||||
if self._has_collision(node):
|
||||
print("节点已有碰撞体")
|
||||
return
|
||||
|
||||
# 获取选择的形状
|
||||
shape_name = getattr(self, '_selected_collision_shape', '球形 (Sphere)')
|
||||
|
||||
if hasattr(self, 'collision_manager'):
|
||||
# 使用碰撞管理器添加碰撞体
|
||||
shape_type = self._get_shape_type_from_name(shape_name)
|
||||
collision_node = self.collision_manager.setupAdvancedCollision(
|
||||
node,
|
||||
shape_type=shape_type,
|
||||
mask_type='MODEL_COLLISION'
|
||||
)
|
||||
|
||||
if collision_node:
|
||||
print(f"成功为节点 {node.getName()} 添加 {shape_name} 碰撞体")
|
||||
else:
|
||||
print(f"添加碰撞体失败")
|
||||
else:
|
||||
print("碰撞管理器未初始化")
|
||||
|
||||
except Exception as e:
|
||||
print(f"添加碰撞体失败: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
def _remove_collision_from_node(self, node):
|
||||
"""从节点移除碰撞体"""
|
||||
try:
|
||||
if not node or node.isEmpty():
|
||||
print("无效的节点")
|
||||
return
|
||||
|
||||
if not self._has_collision(node):
|
||||
print("节点没有碰撞体")
|
||||
return
|
||||
|
||||
# 查找并移除碰撞节点
|
||||
children_to_remove = []
|
||||
for child in node.getChildren():
|
||||
if hasattr(child, 'getName') and child.getName():
|
||||
name = child.getName()
|
||||
if 'collision' in name.lower() or 'Collision' in name:
|
||||
children_to_remove.append(child)
|
||||
|
||||
# 移除找到的碰撞节点
|
||||
for child in children_to_remove:
|
||||
child.removeNode()
|
||||
|
||||
if children_to_remove:
|
||||
print(f"成功移除节点 {node.getName()} 的碰撞体")
|
||||
else:
|
||||
print(f"未找到碰撞体")
|
||||
|
||||
except Exception as e:
|
||||
print(f"移除碰撞体失败: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
def _toggle_collision_visibility(self, node):
|
||||
"""切换碰撞体可见性"""
|
||||
try:
|
||||
if not node or node.isEmpty():
|
||||
return
|
||||
|
||||
# 查找碰撞节点并切换可见性
|
||||
for child in node.getChildren():
|
||||
if hasattr(child, 'getName') and child.getName():
|
||||
name = child.getName()
|
||||
if 'collision' in name.lower() or 'Collision' in name:
|
||||
if child.isHidden():
|
||||
child.show()
|
||||
else:
|
||||
child.hide()
|
||||
break
|
||||
|
||||
except Exception as e:
|
||||
print(f"切换碰撞可见性失败: {e}")
|
||||
|
||||
def _update_collision_position(self, node, axis, value):
|
||||
"""更新碰撞体位置"""
|
||||
try:
|
||||
if not node or node.isEmpty():
|
||||
return
|
||||
|
||||
# 查找碰撞节点并更新位置
|
||||
for child in node.getChildren():
|
||||
if hasattr(child, 'getName') and child.getName():
|
||||
name = child.getName()
|
||||
if 'collision' in name.lower() or 'Collision' in name:
|
||||
current_pos = child.getPos()
|
||||
if axis == 'x':
|
||||
child.setPos(value, current_pos.y, current_pos.z)
|
||||
elif axis == 'y':
|
||||
child.setPos(current_pos.x, value, current_pos.z)
|
||||
elif axis == 'z':
|
||||
child.setPos(current_pos.x, current_pos.y, value)
|
||||
break
|
||||
|
||||
except Exception as e:
|
||||
print(f"更新碰撞位置失败: {e}")
|
||||
|
||||
def _get_shape_type_from_name(self, shape_name):
|
||||
"""从形状名称获取形状类型"""
|
||||
if "Sphere" in shape_name:
|
||||
return "sphere"
|
||||
elif "Box" in shape_name:
|
||||
return "box"
|
||||
elif "Capsule" in shape_name:
|
||||
return "capsule"
|
||||
elif "Plane" in shape_name:
|
||||
return "plane"
|
||||
else:
|
||||
return "sphere"
|
||||
|
||||
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}")
|
||||
|
||||
def _get_sphere_radius(self, node):
|
||||
"""获取球形半径"""
|
||||
try:
|
||||
# 从碰撞节点获取半径信息
|
||||
for child in node.getChildren():
|
||||
if hasattr(child, 'getName') and child.getName():
|
||||
name = child.getName()
|
||||
if 'collision' in name.lower() or 'Collision' in name:
|
||||
if hasattr(child.node(), 'getSolids') and child.node().getNumSolids() > 0:
|
||||
solid = child.node().getSolid(0)
|
||||
from panda3d.core import CollisionSphere
|
||||
if isinstance(solid, CollisionSphere):
|
||||
return solid.getRadius()
|
||||
return 1.0
|
||||
except Exception as e:
|
||||
print(f"获取球形半径失败: {e}")
|
||||
return 1.0
|
||||
|
||||
def _update_sphere_radius(self, node, radius):
|
||||
"""更新球形半径"""
|
||||
try:
|
||||
# 重新创建碰撞体来更新参数
|
||||
if hasattr(self, 'collision_manager'):
|
||||
# 先移除旧的碰撞体
|
||||
self._remove_collision_from_node(node)
|
||||
# 重新创建带有新参数的碰撞体
|
||||
self.collision_manager.setupAdvancedCollision(
|
||||
node,
|
||||
shape_type='sphere',
|
||||
mask_type='MODEL_COLLISION',
|
||||
radius=radius
|
||||
)
|
||||
print(f"更新球形半径为: {radius}")
|
||||
except Exception as e:
|
||||
print(f"更新球形半径失败: {e}")
|
||||
|
||||
def _get_box_size(self, node):
|
||||
"""获取盒型尺寸"""
|
||||
try:
|
||||
# 从碰撞节点获取尺寸信息
|
||||
for child in node.getChildren():
|
||||
if hasattr(child, 'getName') and child.getName():
|
||||
name = child.getName()
|
||||
if 'collision' in name.lower() or 'Collision' in name:
|
||||
# 尝试从碰撞体获取尺寸
|
||||
if hasattr(child.node(), 'getSolids') and child.node().getNumSolids() > 0:
|
||||
solid = child.node().getSolid(0)
|
||||
from panda3d.core import CollisionBox
|
||||
if isinstance(solid, CollisionBox):
|
||||
min_p = solid.getMin()
|
||||
max_p = solid.getMax()
|
||||
return (
|
||||
max_p.x - min_p.x,
|
||||
max_p.y - min_p.y,
|
||||
max_p.z - min_p.z
|
||||
)
|
||||
return (1.0, 1.0, 1.0)
|
||||
except Exception as e:
|
||||
print(f"获取盒型尺寸失败: {e}")
|
||||
return (1.0, 1.0, 1.0)
|
||||
|
||||
def _update_box_size(self, node, axis, value):
|
||||
"""更新盒型尺寸"""
|
||||
try:
|
||||
# 获取当前尺寸
|
||||
current_size = self._get_box_size(node)
|
||||
new_size = list(current_size)
|
||||
|
||||
# 更新指定轴的尺寸
|
||||
if axis == 'x':
|
||||
new_size[0] = value
|
||||
elif axis == 'y':
|
||||
new_size[1] = value
|
||||
elif axis == 'z':
|
||||
new_size[2] = value
|
||||
|
||||
# 重新创建碰撞体
|
||||
if hasattr(self, 'collision_manager'):
|
||||
self._remove_collision_from_node(node)
|
||||
self.collision_manager.setupAdvancedCollision(
|
||||
node,
|
||||
shape_type='box',
|
||||
mask_type='MODEL_COLLISION',
|
||||
width=new_size[0],
|
||||
length=new_size[1],
|
||||
height=new_size[2]
|
||||
)
|
||||
print(f"更新盒型尺寸: {new_size}")
|
||||
except Exception as e:
|
||||
print(f"更新盒型尺寸失败: {e}")
|
||||
|
||||
def _get_capsule_radius(self, node):
|
||||
"""获取胶囊体半径"""
|
||||
try:
|
||||
# 从碰撞节点获取半径信息
|
||||
for child in node.getChildren():
|
||||
if hasattr(child, 'getName') and child.getName():
|
||||
name = child.getName()
|
||||
if 'collision' in name.lower() or 'Collision' in name:
|
||||
if hasattr(child.node(), 'getSolids') and child.node().getNumSolids() > 0:
|
||||
solid = child.node().getSolid(0)
|
||||
from panda3d.core import CollisionCapsule
|
||||
if isinstance(solid, CollisionCapsule):
|
||||
return solid.getRadius()
|
||||
return 1.0
|
||||
except Exception as e:
|
||||
print(f"获取胶囊体半径失败: {e}")
|
||||
return 1.0
|
||||
|
||||
def _update_capsule_radius(self, node, radius):
|
||||
"""更新胶囊体半径"""
|
||||
try:
|
||||
# 获取当前高度
|
||||
height = self._get_capsule_height(node)
|
||||
|
||||
# 重新创建碰撞体
|
||||
if hasattr(self, 'collision_manager'):
|
||||
self._remove_collision_from_node(node)
|
||||
self.collision_manager.setupAdvancedCollision(
|
||||
node,
|
||||
shape_type='capsule',
|
||||
mask_type='MODEL_COLLISION',
|
||||
radius=radius,
|
||||
height=height
|
||||
)
|
||||
print(f"更新胶囊体半径为: {radius}")
|
||||
except Exception as e:
|
||||
print(f"更新胶囊体半径失败: {e}")
|
||||
|
||||
def _get_capsule_height(self, node):
|
||||
"""获取胶囊体高度"""
|
||||
try:
|
||||
# 从碰撞节点获取高度信息
|
||||
for child in node.getChildren():
|
||||
if hasattr(child, 'getName') and child.getName():
|
||||
name = child.getName()
|
||||
if 'collision' in name.lower() or 'Collision' in name:
|
||||
if hasattr(child.node(), 'getSolids') and child.node().getNumSolids() > 0:
|
||||
solid = child.node().getSolid(0)
|
||||
from panda3d.core import CollisionCapsule
|
||||
if isinstance(solid, CollisionCapsule):
|
||||
point_a = solid.getPointA()
|
||||
point_b = solid.getPointB()
|
||||
return (point_b - point_a).length() + 2 * solid.getRadius()
|
||||
return 2.0
|
||||
except Exception as e:
|
||||
print(f"获取胶囊体高度失败: {e}")
|
||||
return 2.0
|
||||
|
||||
def _update_capsule_height(self, node, height):
|
||||
"""更新胶囊体高度"""
|
||||
try:
|
||||
# 获取当前半径
|
||||
radius = self._get_capsule_radius(node)
|
||||
|
||||
# 重新创建碰撞体
|
||||
if hasattr(self, 'collision_manager'):
|
||||
self._remove_collision_from_node(node)
|
||||
self.collision_manager.setupAdvancedCollision(
|
||||
node,
|
||||
shape_type='capsule',
|
||||
mask_type='MODEL_COLLISION',
|
||||
radius=radius,
|
||||
height=height
|
||||
)
|
||||
print(f"更新胶囊体高度为: {height}")
|
||||
except Exception as e:
|
||||
print(f"更新胶囊体高度失败: {e}")
|
||||
|
||||
def _get_plane_normal(self, node):
|
||||
"""获取平面法向量"""
|
||||
try:
|
||||
# 从碰撞节点获取法向量信息
|
||||
for child in node.getChildren():
|
||||
if hasattr(child, 'getName') and child.getName():
|
||||
name = child.getName()
|
||||
if 'collision' in name.lower() or 'Collision' in name:
|
||||
if hasattr(child.node(), 'getSolids') and child.node().getNumSolids() > 0:
|
||||
solid = child.node().getSolid(0)
|
||||
from panda3d.core import CollisionPlane
|
||||
if isinstance(solid, CollisionPlane):
|
||||
plane = solid.getPlane()
|
||||
normal = plane.getNormal()
|
||||
return (normal.x, normal.y, normal.z)
|
||||
return (0.0, 0.0, 1.0)
|
||||
except Exception as e:
|
||||
print(f"获取平面法向量失败: {e}")
|
||||
return (0.0, 0.0, 1.0)
|
||||
|
||||
def _update_plane_normal(self, node, axis, value):
|
||||
"""更新平面法向量"""
|
||||
try:
|
||||
# 获取当前法向量
|
||||
current_normal = self._get_plane_normal(node)
|
||||
new_normal = list(current_normal)
|
||||
|
||||
# 更新指定轴的值
|
||||
if axis == 'x':
|
||||
new_normal[0] = value
|
||||
elif axis == 'y':
|
||||
new_normal[1] = value
|
||||
elif axis == 'z':
|
||||
new_normal[2] = value
|
||||
|
||||
# 标准化法向量
|
||||
from panda3d.core import Vec3
|
||||
normal_vec = Vec3(*new_normal)
|
||||
normal_vec.normalize()
|
||||
|
||||
# 重新创建碰撞体
|
||||
if hasattr(self, 'collision_manager'):
|
||||
self._remove_collision_from_node(node)
|
||||
self.collision_manager.setupAdvancedCollision(
|
||||
node,
|
||||
shape_type='plane',
|
||||
mask_type='MODEL_COLLISION',
|
||||
normal=normal_vec
|
||||
)
|
||||
print(f"更新平面法向量为: ({normal_vec.x:.2f}, {normal_vec.y:.2f}, {normal_vec.z:.2f})")
|
||||
except Exception as e:
|
||||
print(f"更新平面法向量失败: {e}")
|
||||
|
||||
def _manual_collision_detection(self):
|
||||
"""手动执行碰撞检测"""
|
||||
try:
|
||||
if hasattr(self, 'collision_manager'):
|
||||
results = self.collision_manager.detectModelCollisions(log_results=True)
|
||||
if results:
|
||||
print(f"手动碰撞检测完成,发现 {len(results)} 个碰撞")
|
||||
else:
|
||||
print("手动碰撞检测完成,未发现碰撞")
|
||||
except Exception as e:
|
||||
print(f"手动碰撞检测失败: {e}")
|
||||
|
||||
def _draw_property_actions(self, node):
|
||||
"""绘制属性操作按钮"""
|
||||
# 重置变换
|
||||
@ -2082,7 +2757,7 @@ class MyWorld(CoreWorld):
|
||||
for i, material in enumerate(materials):
|
||||
material_name = material.get_name() if hasattr(material, 'get_name') and material.get_name() else f"材质{i + 1}"
|
||||
|
||||
if imgui.collapsing_header(f"材质: {material_name}", True):
|
||||
if imgui.collapsing_header(f"材质: {material_name}"):
|
||||
# 材质基础颜色
|
||||
base_color = self._get_material_base_color(material)
|
||||
if base_color:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user