diff --git a/.idea/AugmentWebviewStateStore.xml b/.idea/AugmentWebviewStateStore.xml index a67ef38e..a6b0ca0d 100644 --- a/.idea/AugmentWebviewStateStore.xml +++ b/.idea/AugmentWebviewStateStore.xml @@ -3,7 +3,7 @@ diff --git a/QPanda3D/__pycache__/Panda3DWorld.cpython-312.pyc b/QPanda3D/__pycache__/Panda3DWorld.cpython-312.pyc index c3c7a60c..d8877870 100644 Binary files a/QPanda3D/__pycache__/Panda3DWorld.cpython-312.pyc and b/QPanda3D/__pycache__/Panda3DWorld.cpython-312.pyc differ diff --git a/QPanda3D/__pycache__/QMouseWatcherNode.cpython-312.pyc b/QPanda3D/__pycache__/QMouseWatcherNode.cpython-312.pyc index 591e15cf..7ce623ea 100644 Binary files a/QPanda3D/__pycache__/QMouseWatcherNode.cpython-312.pyc and b/QPanda3D/__pycache__/QMouseWatcherNode.cpython-312.pyc differ diff --git a/QPanda3D/__pycache__/QPanda3DWidget.cpython-312.pyc b/QPanda3D/__pycache__/QPanda3DWidget.cpython-312.pyc index 6a22d045..f2c8b2cf 100644 Binary files a/QPanda3D/__pycache__/QPanda3DWidget.cpython-312.pyc and b/QPanda3D/__pycache__/QPanda3DWidget.cpython-312.pyc differ diff --git a/QPanda3D/__pycache__/QPanda3D_Buttons_Translation.cpython-312.pyc b/QPanda3D/__pycache__/QPanda3D_Buttons_Translation.cpython-312.pyc index 086f3426..ffe62000 100644 Binary files a/QPanda3D/__pycache__/QPanda3D_Buttons_Translation.cpython-312.pyc and b/QPanda3D/__pycache__/QPanda3D_Buttons_Translation.cpython-312.pyc differ diff --git a/QPanda3D/__pycache__/QPanda3D_Keys_Translation.cpython-312.pyc b/QPanda3D/__pycache__/QPanda3D_Keys_Translation.cpython-312.pyc index 971da875..98f78c67 100644 Binary files a/QPanda3D/__pycache__/QPanda3D_Keys_Translation.cpython-312.pyc and b/QPanda3D/__pycache__/QPanda3D_Keys_Translation.cpython-312.pyc differ diff --git a/QPanda3D/__pycache__/QPanda3D_Modifiers_Translation.cpython-312.pyc b/QPanda3D/__pycache__/QPanda3D_Modifiers_Translation.cpython-312.pyc index 24e5ba36..f2cd37d1 100644 Binary files a/QPanda3D/__pycache__/QPanda3D_Modifiers_Translation.cpython-312.pyc and b/QPanda3D/__pycache__/QPanda3D_Modifiers_Translation.cpython-312.pyc differ diff --git a/QPanda3D/__pycache__/__init__.cpython-312.pyc b/QPanda3D/__pycache__/__init__.cpython-312.pyc index 868b2e22..8519d196 100644 Binary files a/QPanda3D/__pycache__/__init__.cpython-312.pyc and b/QPanda3D/__pycache__/__init__.cpython-312.pyc differ diff --git a/__pycache__/main.cpython-312.pyc b/__pycache__/main.cpython-312.pyc index e35aa17c..c1b6b806 100644 Binary files a/__pycache__/main.cpython-312.pyc and b/__pycache__/main.cpython-312.pyc differ diff --git a/core/__pycache__/CustomMouseController.cpython-312.pyc b/core/__pycache__/CustomMouseController.cpython-312.pyc index 4c3504de..3005ff4f 100644 Binary files a/core/__pycache__/CustomMouseController.cpython-312.pyc and b/core/__pycache__/CustomMouseController.cpython-312.pyc differ diff --git a/core/__pycache__/selection.cpython-312.pyc b/core/__pycache__/selection.cpython-312.pyc index da8b40dd..68ef7ea4 100644 Binary files a/core/__pycache__/selection.cpython-312.pyc and b/core/__pycache__/selection.cpython-312.pyc differ diff --git a/core/__pycache__/world.cpython-312.pyc b/core/__pycache__/world.cpython-312.pyc index 31895cc1..ebe521bc 100644 Binary files a/core/__pycache__/world.cpython-312.pyc and b/core/__pycache__/world.cpython-312.pyc differ diff --git a/core/selection.py b/core/selection.py index 8f2c020c..d1c62a24 100644 --- a/core/selection.py +++ b/core/selection.py @@ -1187,44 +1187,32 @@ class SelectionSystem: # 检查目标节点是否有父节点 parent_node = self.gizmoTarget.getParent() - # 确定轴向量的变换上下文 - if parent_node and parent_node != self.world.render: - # 子节点:使用父节点的局部坐标系 - print(f"子节点拖拽 - 父节点: {parent_node.getName()}, 父节点旋转: {parent_node.getHpr()}") - transform_context = parent_node - else: - # 顶级模型:使用世界坐标系 - print(f"顶级模型拖拽 - 使用世界坐标系") - transform_context = self.world.render - # 计算轴向量在正确坐标系中的方向 if self.dragGizmoAxis == "x": - # 在变换上下文中的X轴方向 + # 在局部坐标系中的X轴方向 local_axis_vector = Vec3(1, 0, 0) elif self.dragGizmoAxis == "y": - # 在变换上下文中的Y轴方向 + # 在局部坐标系中的Y轴方向 local_axis_vector = Vec3(0, 1, 0) elif self.dragGizmoAxis == "z": - # 在变换上下文中的Z轴方向 + # 在局部坐标系中的Z轴方向 local_axis_vector = Vec3(0, 0, 1) else: print(f"拖拽更新失败: 未知轴类型 {self.dragGizmoAxis}") return - # 将局部轴向量转换到世界坐标系(用于屏幕投影) - if transform_context != self.world.render: - # 获取变换矩阵并应用到轴向量上 - transform_mat = transform_context.getMat(self.world.render) - # 只旋转向量,不平移 + # 确定轴向量的变换上下文 + if parent_node and parent_node != self.world.render: + # 子节点:使用父节点的局部坐标系 + # print(f"子节点拖拽 - 父节点: {parent_node.getName()}, 父节点旋转: {parent_node.getHpr()}") + # transform_context = parent_node + transform_mat = parent_node.getMat(self.world.render) world_axis_vector = transform_mat.xformVec(local_axis_vector) - world_axis_vector.normalize() # 归一化 - print(f"转换后的轴向量: {local_axis_vector} -> {world_axis_vector}") else: - # 顶级节点,直接使用世界轴向量 world_axis_vector = local_axis_vector - print(f"世界轴向量: {world_axis_vector}") - - # 计算轴的端点位置(用于屏幕投影) + # 顶级模型:使用世界坐标系 + # print(f"顶级模型拖拽 - 使用世界坐标系") + # transform_context = self.world.render axis_end = gizmo_world_pos + world_axis_vector # 投影到屏幕空间 @@ -1279,83 +1267,62 @@ class SelectionSystem: projected_distance = (mouseDeltaX * screen_axis_dir[0] + mouseDeltaY * screen_axis_dir[1]) - # 计算动态比例因子,基于相机距离和视野角度 - cam_pos = self.world.cam.getPos() - distance_to_object = (cam_pos - gizmo_world_pos).length() + scale_adjustment = 1.0 + if parent_node and parent_node!= self.world.render: + current_node = parent_node + total_scale = 1.0 + while current_node and current_node != self.world.render: + node_scale = current_node.getScale() + avg_scale = (node_scale.x+node_scale.y + node_scale.z)/3.0 + total_scale *= avg_scale + current_node = current_node.getParent() + if total_scale>0: + scale_adjustment = 1.0 / total_scale + # parent_scale = parent_node.getScale() + # avg_scale = (parent_scale.x+parent_scale.y+parent_scale.z)/3.0 + # if avg_scale>0: + # scale_adjustment = 1.0 / avg_scale - # 获取相机的视野角度 - fov = self.world.cam.node().getLens().getFov()[0] # 水平视野角度 - fov_radians = math.radians(fov) - # 获取窗口尺寸 - winWidth, winHeight = self.world.getWindowSize() + fixed_pixel_to_world_ratio = 0.01 # 1像素 = 0.01世界单位 + scale_factor = fixed_pixel_to_world_ratio * scale_adjustment - # 计算一个像素在世界坐标系中的大小(在目标物体的距离处) - # 使用透视投影公式:world_size = screen_size * distance * tan(fov/2) / (screen_width/2) - pixel_to_world_ratio = distance_to_object * math.tan(fov_radians / 2) / (winWidth / 2) - - # 【改进修复】:智能缩放补偿,区分继承缩放和本体缩放 - # 计算父节点链的累积缩放(不包括目标节点本身) - parent_cumulative_scale = 1.0 - current_node = self.gizmoTarget.getParent() - while current_node and current_node != self.world.render: - node_scale = current_node.getScale() - # 使用缩放的几何平均值作为累积因子 - scale_magnitude = (abs(node_scale.x) * abs(node_scale.y) * abs(node_scale.z)) ** (1.0/3.0) - parent_cumulative_scale *= scale_magnitude - current_node = current_node.getParent() - - # 获取目标节点自身的缩放 - target_scale = self.gizmoTarget.getScale() - target_scale_magnitude = (abs(target_scale.x) * abs(target_scale.y) * abs(target_scale.z)) ** (1.0/3.0) - - # 智能补偿策略: - # 1. 只对父节点链的小缩放进行完全补偿(这通常是单位转换导致的) - # 2. 对目标节点自身的缩放进行部分补偿(避免大模型缩小后移动过快) - parent_compensation = 1.0 / parent_cumulative_scale if parent_cumulative_scale > 0 else 1.0 - - # 对目标节点自身的缩放使用平方根补偿,减少过度补偿 - target_compensation = 1.0 / math.sqrt(target_scale_magnitude) if target_scale_magnitude > 0 else 1.0 - - # 限制目标补偿的最大值,避免移动过快 - target_compensation = min(target_compensation, 10.0) # 最大10倍补偿 - - # 综合补偿因子 - total_compensation = parent_compensation * target_compensation - scale_factor = pixel_to_world_ratio * 0.5*total_compensation - - # 【关键修复】:在正确的坐标系中计算移动向量 - # 计算移动距离(标量) movement_distance = projected_distance * scale_factor - - # 在正确的坐标系中计算移动向量 - if transform_context != self.world.render: - # 子节点:在父节点的局部坐标系中移动 - if self.dragGizmoAxis == "x": - movement_local = Vec3(movement_distance, 0, 0) - elif self.dragGizmoAxis == "y": - movement_local = Vec3(0, movement_distance, 0) - elif self.dragGizmoAxis == "z": - movement_local = Vec3(0, 0, movement_distance) - - # 将局部移动向量转换到父节点的坐标系中 - # 由于我们要应用到目标节点上,而目标节点相对于父节点,我们直接使用局部移动 - movement = movement_local - print(f"子节点移动向量(局部): {movement}") + # 获取当前位置并只修改选中轴的坐标 + currentPos = self.gizmoTargetStartPos + + # 根据拖拽的轴,只修改对应的坐标分量 + if self.dragGizmoAxis == "x": + newPos = Vec3(currentPos.x + movement_distance, currentPos.y, currentPos.z) + print(f"X轴移动:{currentPos.x} -> {newPos.x}") + elif self.dragGizmoAxis == "y": + newPos = Vec3(currentPos.x, currentPos.y + movement_distance, currentPos.z) + print(f"Y轴移动:{currentPos.y} -> {newPos.y}") + elif self.dragGizmoAxis == "z": + newPos = Vec3(currentPos.x, currentPos.y, currentPos.z + movement_distance) + print(f"Z轴移动:{currentPos.z} -> {newPos.z}") else: - # 顶级模型:在世界坐标系中移动 - if self.dragGizmoAxis == "x": - movement = Vec3(movement_distance, 0, 0) - elif self.dragGizmoAxis == "y": - movement = Vec3(0, movement_distance, 0) - elif self.dragGizmoAxis == "z": - movement = Vec3(0, 0, movement_distance) - print(f"顶级模型移动向量(世界): {movement}") - - # 应用移动到目标节点 - newPos = self.gizmoTargetStartPos + movement - self.gizmoTarget.setPos(newPos) + print(f"未知轴: {self.dragGizmoAxis}") + return + + # 应用新位置到目标节点 + light_object = self.gizmoTarget.getPythonTag("rp_light_object") + if light_object: + light_object.pos = newPos + self.gizmoTarget.setPos(newPos) + else: + self.gizmoTarget.setPos(newPos) + + # 更新坐标轴位置 - 计算新的中心位置 + minPoint = Point3() + maxPoint = Point3() + if self.gizmoTarget.calcTightBounds(minPoint, maxPoint, self.world.render): + center = Point3((minPoint.x + maxPoint.x) * 0.5, + (minPoint.y + maxPoint.y) * 0.5, + (minPoint.z + maxPoint.z) * 0.5) + self.gizmo.setPos(center) + # 实时更新属性面板 self.world.property_panel.refreshModelValues(self.gizmoTarget) # 每次拖拽都输出调试信息(但限制频率) @@ -1365,18 +1332,9 @@ class SelectionSystem: import time current_time = time.time() if current_time - self._last_drag_debug_time > 0.1: # 每0.1秒最多输出一次 - print(f"拖拽更新成功 - 轴:{self.dragGizmoAxis}, 距离:{distance_to_object:.2f}, 比例:{scale_factor:.6f}, 投影:{projected_distance:.2f}") + print(f"拖拽更新成功 - 轴:{self.dragGizmoAxis}, 比例:{scale_factor:.6f}, 投影:{projected_distance:.2f}") self._last_drag_debug_time = current_time - newPos = self.gizmoTargetStartPos + movement - light_object = self.gizmoTarget.getPythonTag("rp_light_object") - if light_object: - light_object.pos = newPos - self.gizmoTarget.setPos(newPos) - else: - self.gizmoTarget.setPos(newPos) - self.gizmo.setPos(newPos) - except Exception as e: print(f"更新坐标轴拖拽失败: {str(e)}") import traceback diff --git a/scene/__pycache__/scene_manager.cpython-312.pyc b/scene/__pycache__/scene_manager.cpython-312.pyc index 4bded081..17a23d1f 100644 Binary files a/scene/__pycache__/scene_manager.cpython-312.pyc and b/scene/__pycache__/scene_manager.cpython-312.pyc differ diff --git a/ui/__pycache__/interface_manager.cpython-312.pyc b/ui/__pycache__/interface_manager.cpython-312.pyc index 7bd170e2..d09cfa6e 100644 Binary files a/ui/__pycache__/interface_manager.cpython-312.pyc and b/ui/__pycache__/interface_manager.cpython-312.pyc differ diff --git a/ui/__pycache__/main_window.cpython-312.pyc b/ui/__pycache__/main_window.cpython-312.pyc index 022d6921..392e3cba 100644 Binary files a/ui/__pycache__/main_window.cpython-312.pyc and b/ui/__pycache__/main_window.cpython-312.pyc differ diff --git a/ui/__pycache__/property_panel.cpython-312.pyc b/ui/__pycache__/property_panel.cpython-312.pyc index dec4f11d..83e41f96 100644 Binary files a/ui/__pycache__/property_panel.cpython-312.pyc and b/ui/__pycache__/property_panel.cpython-312.pyc differ diff --git a/ui/__pycache__/widgets.cpython-312.pyc b/ui/__pycache__/widgets.cpython-312.pyc index d85def46..9d499c72 100644 Binary files a/ui/__pycache__/widgets.cpython-312.pyc and b/ui/__pycache__/widgets.cpython-312.pyc differ diff --git a/ui/main_window.py b/ui/main_window.py index 85860f0e..cccd4160 100644 --- a/ui/main_window.py +++ b/ui/main_window.py @@ -391,7 +391,8 @@ class MainWindow(QMainWindow): self.createPointLight.clicked.connect(lambda :self.world.createPointLight()) # 连接树节点点击信号 - self.treeWidget.itemClicked.connect(self.world.onTreeItemClicked) + # self.treeWidget.itemClicked.connect(self.world.onTreeItemClicked) + self.treeWidget.itemSelectionChanged.connect(lambda :self.world.onTreeItemClicked(self.treeWidget.currentItem(), 0)) print("已连接点击信号") # 连接工具切换信号