forked from Rowland/EG
聚焦功能
This commit is contained in:
parent
1c660c781a
commit
2a76703b89
@ -452,33 +452,41 @@ class EventHandler:
|
||||
|
||||
if selectedModel:
|
||||
#print(f"✓ 最终选中模型: {selectedModel.getName()}")
|
||||
self.world.selection.handleMouseClick(selectedModel)
|
||||
|
||||
# 更新选择状态并显示选择框和坐标轴
|
||||
self.world.selection.updateSelection(selectedModel)
|
||||
|
||||
# 在树形控件中查找并选中对应的项
|
||||
if self.world.interface_manager.treeWidget:
|
||||
#print("查找树形控件中的对应项...")
|
||||
root = self.world.interface_manager.treeWidget.invisibleRootItem()
|
||||
foundItem = None
|
||||
|
||||
for i in range(root.childCount()):
|
||||
sceneItem = root.child(i)
|
||||
if sceneItem.text(0) == "场景":
|
||||
#print(f"在场景节点下查找...")
|
||||
foundItem = self.world.interface_manager.findTreeItem(selectedModel, sceneItem)
|
||||
if foundItem:
|
||||
print(f"✓ 在树形控件中找到对应项: {foundItem.text(0)}")
|
||||
self.world.interface_manager.treeWidget.setCurrentItem(foundItem)
|
||||
self.world.property_panel.updatePropertyPanel(foundItem)
|
||||
else:
|
||||
print("× 在树形控件中没有找到对应项")
|
||||
break
|
||||
|
||||
if not foundItem:
|
||||
print("× 没有找到场景节点或对应的树形项")
|
||||
else:
|
||||
print("× 树形控件不存在")
|
||||
# # 在树形控件中查找并选中对应的项
|
||||
# if self.world.interface_manager.treeWidget:
|
||||
# #print("查找树形控件中的对应项...")
|
||||
# root = self.world.interface_manager.treeWidget.invisibleRootItem()
|
||||
# foundItem = None
|
||||
#
|
||||
# for i in range(root.childCount()):
|
||||
# sceneItem = root.child(i)
|
||||
# if sceneItem.text(0) == "场景":
|
||||
# #print(f"在场景节点下查找...")
|
||||
# foundItem = self.world.interface_manager.findTreeItem(selectedModel, sceneItem)
|
||||
# if foundItem:
|
||||
# print(f"✓ 在树形控件中找到对应项: {foundItem.text(0)}")
|
||||
# try:
|
||||
# self.world.interface_manager.treeWidget.itemClicked.disconnect()
|
||||
# except TypeError:
|
||||
# pass
|
||||
#
|
||||
# self.world.interface_manager.treeWidget.setCurrentItem(foundItem)
|
||||
#
|
||||
# self.world.interface_manager.treeWidget.itemClicked.connect(
|
||||
# self.world.interface_manager.onTreeItemClicked)
|
||||
# else:
|
||||
# print("× 在树形控件中没有找到对应项")
|
||||
# break
|
||||
#
|
||||
# if not foundItem:
|
||||
# print("× 没有找到场景节点或对应的树形项")
|
||||
# else:
|
||||
# print("× 树形控件不存在")
|
||||
else:
|
||||
print("× 没有找到可选择的模型节点")
|
||||
self.world.selection.updateSelection(None)
|
||||
|
||||
@ -1228,10 +1228,10 @@ class SelectionSystem:
|
||||
distance = self.distanceToLine(
|
||||
(mouseX, mouseY), center_screen, axis_screen
|
||||
)
|
||||
print(f"{axis_label}距离: {distance:.2f}")
|
||||
#print(f"{axis_label}距离: {distance:.2f}")
|
||||
|
||||
if distance < click_threshold:
|
||||
print(f"✓ 点击了{axis_label}")
|
||||
#print(f"✓ 点击了{axis_label}")
|
||||
return axis_name
|
||||
|
||||
return None
|
||||
@ -1930,8 +1930,10 @@ class SelectionSystem:
|
||||
is_double_click = self.checkDoubleClick(nodePath)
|
||||
if is_double_click:
|
||||
print(f"检测到双击 {node_name},执行聚焦")
|
||||
# 启动聚焦(在下一帧执行,确保选择状态已更新)
|
||||
taskMgr.doMethodLater(0.01, self._delayedFocusTask, "delayedFocus")
|
||||
# 双击时直接执行聚焦,不执行选择逻辑
|
||||
self.focusCameraOnSelectedNodeAdvanced()
|
||||
print("=== 选择状态更新完成 ===\n")
|
||||
return # 直接返回,不执行下面的选择逻辑
|
||||
|
||||
self.selectedNode = nodePath
|
||||
# 添加兼容性属性
|
||||
@ -2596,19 +2598,22 @@ class SelectionSystem:
|
||||
import time
|
||||
current_time = time.time()
|
||||
|
||||
is_double_click = (self._last_clicked_node == nodePath and
|
||||
current_time - self._last_click_time < self._double_click_threshold)
|
||||
# 检查节点和时间
|
||||
time_diff = current_time - self._last_click_time
|
||||
is_same_node = (self._last_clicked_node == nodePath)
|
||||
|
||||
if is_double_click:
|
||||
# 双击 detected,重置状态
|
||||
# 如果是同一节点且在时间阈值内,认为是双击
|
||||
if is_same_node and time_diff < self._double_click_threshold:
|
||||
# 只有在双击时才重置状态
|
||||
self._last_click_time = 0
|
||||
self._last_clicked_node = None
|
||||
return True
|
||||
else:
|
||||
# 更新状态为单击
|
||||
self._last_click_time = current_time
|
||||
self._last_clicked_node = nodePath
|
||||
|
||||
return is_double_click
|
||||
# 只有在非双击情况下才更新状态
|
||||
if not is_same_node:
|
||||
self._last_click_time = current_time
|
||||
self._last_clicked_node = nodePath
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"双击检测失败: {e}")
|
||||
|
||||
@ -143,7 +143,9 @@ class SceneManager:
|
||||
|
||||
# 验证并修复模型变换矩阵(在任何操作之前)
|
||||
#
|
||||
#self._validateAndFixAllTransforms(model)
|
||||
self._validateAndFixAllTransforms(model)
|
||||
|
||||
self._fixModelStructure(model)
|
||||
|
||||
# 设置模型名称
|
||||
model_name = os.path.basename(filepath)
|
||||
@ -153,14 +155,14 @@ class SceneManager:
|
||||
model.setName(model_name)
|
||||
|
||||
# 使用安全方法将模型添加到场景
|
||||
self._safeReparentTo(model, self.world.render)
|
||||
#self._safeReparentTo(model, self.world.render)
|
||||
|
||||
# 设置模型名称
|
||||
model_name = os.path.basename(filepath)
|
||||
model.setName(model_name)
|
||||
|
||||
# 将模型添加到场景
|
||||
#model.reparentTo(self.world.render)
|
||||
model.reparentTo(self.world.render)
|
||||
# 保存原始路径和转换后的路径
|
||||
model.setTag("model_path", filepath)
|
||||
model.setTag("original_path", original_filepath)
|
||||
@ -236,6 +238,80 @@ class SceneManager:
|
||||
print(f"导入模型失败: {str(e)}")
|
||||
return None
|
||||
|
||||
def _fixModelStructure(self,model):
|
||||
try:
|
||||
from panda3d.core import CharacterNode,AnimBundleNode
|
||||
|
||||
character_nodes = model.findAllMatches("**/+CharacterNode")
|
||||
anim_bundle_nodes = model.findAllMatches("**/+AnimBundleNode")
|
||||
|
||||
if character_nodes.getNumPaths() > 0 or anim_bundle_nodes.getNumPaths() > 0:
|
||||
print(f"检测到模型{model.getName()}包含角色相节点:")
|
||||
if character_nodes.getNumPaths() > 0:
|
||||
print(f"CharacterNode数量:{character_nodes.getNumPaths()}")
|
||||
if anim_bundle_nodes.getNumPaths() > 0:
|
||||
print(f"AnimBundleNode数量: {anim_bundle_nodes.getNumPaths()}")
|
||||
|
||||
model.setTag("fixed_structure","true")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"修复模型结构时出错{e}")
|
||||
return False
|
||||
|
||||
def _validateAndFixAllTransforms(self, model):
|
||||
"""验证并修复所有节点的变换矩阵"""
|
||||
try:
|
||||
def fix_node_transform(node_path, depth=0):
|
||||
indent = " " * depth
|
||||
try:
|
||||
# 检查节点的变换矩阵是否有效
|
||||
transform = node_path.getTransform()
|
||||
if not transform.isInvalid():
|
||||
# 检查是否有NaN或无穷大值
|
||||
pos = node_path.getPos()
|
||||
hpr = node_path.getHpr()
|
||||
scale = node_path.getScale()
|
||||
|
||||
# 检查位置
|
||||
if pos.x != pos.x or pos.y != pos.y or pos.z != pos.z: # NaN检查
|
||||
print(f"{indent}修复NaN位置: {node_path.getName()}")
|
||||
node_path.setPos(0, 0, 0)
|
||||
|
||||
# 检查旋转
|
||||
if hpr.x != hpr.x or hpr.y != hpr.y or hpr.z != hpr.z: # NaN检查
|
||||
print(f"{indent}修复NaN旋转: {node_path.getName()}")
|
||||
node_path.setHpr(0, 0, 0)
|
||||
|
||||
# 检查缩放
|
||||
if scale.x != scale.x or scale.y != scale.y or scale.z != scale.z: # NaN检查
|
||||
print(f"{indent}修复NaN缩放: {node_path.getName()}")
|
||||
node_path.setScale(1, 1, 1)
|
||||
|
||||
# 检查过大值
|
||||
if abs(pos.x) > 1e10 or abs(pos.y) > 1e10 or abs(pos.z) > 1e10:
|
||||
print(f"{indent}修复过大位置值: {node_path.getName()}")
|
||||
node_path.setPos(0, 0, 0)
|
||||
|
||||
else:
|
||||
print(f"{indent}检测到无效变换矩阵: {node_path.getName()}")
|
||||
node_path.setPos(0, 0, 0)
|
||||
node_path.setHpr(0, 0, 0)
|
||||
node_path.setScale(1, 1, 1)
|
||||
|
||||
except Exception as e:
|
||||
print(f"{indent}修复节点变换时出错 {node_path.getName()}: {e}")
|
||||
|
||||
# 递归处理子节点
|
||||
for child in node_path.getChildren():
|
||||
fix_node_transform(child, depth + 1)
|
||||
|
||||
# 从模型根节点开始修复
|
||||
fix_node_transform(model)
|
||||
print(f"✓ 完成模型 {model.getName()} 的变换验证和修复")
|
||||
|
||||
except Exception as e:
|
||||
print(f"验证和修复模型变换时出错: {e}")
|
||||
|
||||
def _applyModelScale(self, model, scale_factor):
|
||||
"""应用模型特定缩放
|
||||
|
||||
@ -652,6 +728,8 @@ class SceneManager:
|
||||
def setupCollision(self, model):
|
||||
"""为模型设置碰撞检测(增强版本)"""
|
||||
try:
|
||||
|
||||
|
||||
# 创建碰撞节点
|
||||
cNode = CollisionNode(f'modelCollision_{model.getName()}')
|
||||
|
||||
@ -693,7 +771,7 @@ class SceneManager:
|
||||
|
||||
# 根据调试设置决定是否显示碰撞体
|
||||
if hasattr(self.world, 'debug_collision') and self.world.debug_collision:
|
||||
cNodePath.show()
|
||||
cNodePath.hide()
|
||||
else:
|
||||
cNodePath.hide()
|
||||
|
||||
@ -1424,7 +1502,17 @@ class SceneManager:
|
||||
|
||||
# 为模型节点设置碰撞检测
|
||||
if nodePath.hasTag("is_model_root"):
|
||||
self.setupCollision(nodePath)
|
||||
print(f"J{indent}处理模型节点{nodePath.getName()}")
|
||||
|
||||
self._validateAndFixAllTransforms(nodePath)
|
||||
|
||||
self._fixModelStructure(nodePath)
|
||||
|
||||
if self.world.property_panel._hasCollision(nodePath):
|
||||
print(f"{indent}模型{nodePath.getName()}已有碰撞体,跳过碰撞体设置")
|
||||
else:
|
||||
print(f"{indent}为模型{nodePath.getName()}设置碰撞检测")
|
||||
self.setupCollision(nodePath)
|
||||
self.models.append(nodePath)
|
||||
|
||||
# 递归处理子节点
|
||||
@ -1530,7 +1618,7 @@ class SceneManager:
|
||||
tags = gui_info.get("tags", {})
|
||||
text = gui_info.get("text", "")
|
||||
image_path = gui_info.get("image_path", "")
|
||||
video_path = gui_info.get("video_path","")
|
||||
video_path = gui_info.get("video_path", "")
|
||||
bg_image_path = gui_info.get("bg_image_path", "") # 背景图片路径
|
||||
panel_id = gui_info.get("panel_id", name) # 信息面板ID
|
||||
panel_data = gui_info.get("panel_data", None) # 面板数据
|
||||
|
||||
@ -1921,7 +1921,7 @@ class MainWindow(QMainWindow):
|
||||
main_window.addDockWidget(Qt.RightDockWidgetArea, browser_dock)
|
||||
|
||||
# 添加到GUI元素列表以便管理
|
||||
self.gui_elements.append(browser_dock)
|
||||
self.world.gui_elements.append(browser_dock)
|
||||
|
||||
print("✓ 网页浏览器视图已创建并集成到项目中")
|
||||
return browser_dock
|
||||
|
||||
@ -8936,13 +8936,17 @@ except Exception as e:
|
||||
"""检查模型是否已有碰撞体"""
|
||||
try:
|
||||
from panda3d.core import CollisionNode
|
||||
|
||||
|
||||
# if model.hasTag("has_collision") and model.getTag("has_collision") == "true":
|
||||
# return True
|
||||
|
||||
# 检查模型及其子节点是否有碰撞节点
|
||||
collision_nodes = model.findAllMatches("**/+CollisionNode")
|
||||
has_collision = collision_nodes.getNumPaths() > 0
|
||||
|
||||
print(f"碰撞检查:模型 {model.getName()} - {'有' if has_collision else '无'}碰撞 (找到{collision_nodes.getNumPaths()}个碰撞节点)")
|
||||
|
||||
|
||||
if has_collision:
|
||||
print(f"检测到模型{model.getName()}已有{collision_nodes.getNumPaths()}个碰撞节点")
|
||||
|
||||
return has_collision
|
||||
except Exception as e:
|
||||
print(f"检查碰撞失败: {e}")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user