拖动节点面板属性实时更新
This commit is contained in:
parent
6e3f47b7b0
commit
0cce93b05a
2
.idea/EG.iml
generated
2
.idea/EG.iml
generated
@ -4,7 +4,7 @@
|
|||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="jdk" jdkName="Python 3.10 (EG)" jdkType="Python SDK" />
|
<orderEntry type="jdk" jdkName="Python 3.12 (PythonProject)" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PyDocumentationSettings">
|
<component name="PyDocumentationSettings">
|
||||||
|
|||||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -3,5 +3,5 @@
|
|||||||
<component name="Black">
|
<component name="Black">
|
||||||
<option name="sdkName" value="Python 3.12 (PythonProject)" />
|
<option name="sdkName" value="Python 3.12 (PythonProject)" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (EG)" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (PythonProject)" project-jdk-type="Python SDK" />
|
||||||
</project>
|
</project>
|
||||||
File diff suppressed because one or more lines are too long
@ -105,6 +105,37 @@ class SelectionSystem:
|
|||||||
if not self.selectionBox or not self.selectionBoxTarget:
|
if not self.selectionBox or not self.selectionBoxTarget:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# 检查是否需要重新计算边界框
|
||||||
|
if not hasattr(self, '_bounds_cache'):
|
||||||
|
self._bounds_cache = {}
|
||||||
|
|
||||||
|
node_name = self.selectionBoxTarget.getName()
|
||||||
|
import time
|
||||||
|
current_time = time.time()
|
||||||
|
|
||||||
|
# 如果缓存存在且未过期,则使用缓存
|
||||||
|
if (node_name in self._bounds_cache and
|
||||||
|
current_time - self._bounds_cache[node_name]['time'] < 0.1):
|
||||||
|
minPoint, maxPoint = self._bounds_cache[node_name]['bounds']
|
||||||
|
else:
|
||||||
|
# 计算新的边界框并缓存
|
||||||
|
minPoint = Point3()
|
||||||
|
maxPoint = Point3()
|
||||||
|
if not self.selectionBoxTarget.calcTightBounds(minPoint, maxPoint, self.world.render):
|
||||||
|
return
|
||||||
|
|
||||||
|
# 缓存结果
|
||||||
|
self._bounds_cache[node_name] = {
|
||||||
|
'bounds': (minPoint, maxPoint),
|
||||||
|
'time': current_time
|
||||||
|
}
|
||||||
|
|
||||||
|
# 清理旧缓存
|
||||||
|
expired_keys = [k for k, v in self._bounds_cache.items()
|
||||||
|
if current_time - v['time'] > 1.0]
|
||||||
|
for key in expired_keys:
|
||||||
|
del self._bounds_cache[key]
|
||||||
|
|
||||||
# 清除现有的几何体
|
# 清除现有的几何体
|
||||||
self.selectionBox.removeNode()
|
self.selectionBox.removeNode()
|
||||||
self.selectionBox = self.world.render.attachNewNode("selectionBox")
|
self.selectionBox = self.world.render.attachNewNode("selectionBox")
|
||||||
@ -177,6 +208,15 @@ class SelectionSystem:
|
|||||||
def updateSelectionBoxTask(self, task):
|
def updateSelectionBoxTask(self, task):
|
||||||
"""选择框更新任务"""
|
"""选择框更新任务"""
|
||||||
try:
|
try:
|
||||||
|
if not hasattr(self,'_last_selection_box_update'):
|
||||||
|
self._last_selection_box_update = 0
|
||||||
|
|
||||||
|
import time
|
||||||
|
current_time = time.time()
|
||||||
|
if current_time - self._last_selection_box_update < 0.1:
|
||||||
|
return task.cont
|
||||||
|
self._last_selection_box_update = current_time
|
||||||
|
|
||||||
if not self.selectionBox or not self.selectionBoxTarget:
|
if not self.selectionBox or not self.selectionBoxTarget:
|
||||||
return task.done # 结束任务
|
return task.done # 结束任务
|
||||||
|
|
||||||
@ -598,6 +638,16 @@ class SelectionSystem:
|
|||||||
def updateGizmoTask(self, task):
|
def updateGizmoTask(self, task):
|
||||||
"""坐标轴更新任务 - 包含固定大小功能"""
|
"""坐标轴更新任务 - 包含固定大小功能"""
|
||||||
try:
|
try:
|
||||||
|
# 限制更新频率
|
||||||
|
if not hasattr(self, '_last_gizmo_update'):
|
||||||
|
self._last_gizmo_update = 0
|
||||||
|
|
||||||
|
import time
|
||||||
|
current_time = time.time()
|
||||||
|
if current_time - self._last_gizmo_update < 0.05: # 每0.05秒更新一次
|
||||||
|
return task.cont
|
||||||
|
self._last_gizmo_update = current_time
|
||||||
|
|
||||||
if not self.gizmo or not self.gizmoTarget:
|
if not self.gizmo or not self.gizmoTarget:
|
||||||
return task.done
|
return task.done
|
||||||
|
|
||||||
@ -613,25 +663,27 @@ class SelectionSystem:
|
|||||||
self.gizmoTarget.setPos(light_pos)
|
self.gizmoTarget.setPos(light_pos)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# 更新坐标轴位置,始终在目标节点中心
|
# 只在必要时更新位置和朝向
|
||||||
minPoint = Point3()
|
self._updateGizmoPositionAndOrientation()
|
||||||
maxPoint = Point3()
|
# # 更新坐标轴位置,始终在目标节点中心
|
||||||
if self.gizmoTarget.calcTightBounds(minPoint, maxPoint, self.world.render):
|
# minPoint = Point3()
|
||||||
# 计算中心点
|
# maxPoint = Point3()
|
||||||
center = Point3((minPoint.x + maxPoint.x) * 0.5,
|
# if self.gizmoTarget.calcTightBounds(minPoint, maxPoint, self.world.render):
|
||||||
(minPoint.y + maxPoint.y) * 0.5,
|
# # 计算中心点
|
||||||
(minPoint.z + maxPoint.z) * 0.5)
|
# center = Point3((minPoint.x + maxPoint.x) * 0.5,
|
||||||
self.gizmo.setPos(center)
|
# (minPoint.y + maxPoint.y) * 0.5,
|
||||||
|
# (minPoint.z + maxPoint.z) * 0.5)
|
||||||
# 【关键修复】:更新坐标轴朝向以跟踪父节点的变化
|
# self.gizmo.setPos(center)
|
||||||
parent_node = self.gizmoTarget.getParent()
|
#
|
||||||
if parent_node and parent_node != self.world.render:
|
# # 【关键修复】:更新坐标轴朝向以跟踪父节点的变化
|
||||||
# 子节点:坐标轴朝向跟随父节点
|
# parent_node = self.gizmoTarget.getParent()
|
||||||
parent_hpr = parent_node.getHpr()
|
# if parent_node and parent_node != self.world.render:
|
||||||
self.gizmo.setHpr(parent_hpr)
|
# # 子节点:坐标轴朝向跟随父节点
|
||||||
else:
|
# parent_hpr = parent_node.getHpr()
|
||||||
# 顶级模型:使用世界坐标系朝向
|
# self.gizmo.setHpr(parent_hpr)
|
||||||
self.gizmo.setHpr(0, 0, 0)
|
# else:
|
||||||
|
# # 顶级模型:使用世界坐标系朝向
|
||||||
|
# self.gizmo.setHpr(0, 0, 0)
|
||||||
|
|
||||||
# 【新功能】:动态调整坐标轴大小,保持固定的屏幕大小
|
# 【新功能】:动态调整坐标轴大小,保持固定的屏幕大小
|
||||||
self._updateGizmoScreenSize()
|
self._updateGizmoScreenSize()
|
||||||
@ -642,6 +694,33 @@ class SelectionSystem:
|
|||||||
print(f"坐标轴更新任务出错: {str(e)}")
|
print(f"坐标轴更新任务出错: {str(e)}")
|
||||||
return task.done
|
return task.done
|
||||||
|
|
||||||
|
def _updateGizmoPositionAndOrientation(self):
|
||||||
|
"""优化的Gizmo位置和朝向更新"""
|
||||||
|
# 只在必要时重新计算边界框
|
||||||
|
if not hasattr(self, '_last_gizmo_bounds_update'):
|
||||||
|
self._last_gizmo_bounds_update = 0
|
||||||
|
|
||||||
|
import time
|
||||||
|
current_time = time.time()
|
||||||
|
if current_time - self._last_gizmo_bounds_update > 0.2: # 每0.2秒计算一次边界框
|
||||||
|
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._last_gizmo_bounds_update = current_time
|
||||||
|
|
||||||
|
# 更新朝向
|
||||||
|
parent_node = self.gizmoTarget.getParent()
|
||||||
|
if parent_node and parent_node != self.world.render:
|
||||||
|
parent_hpr = parent_node.getHpr()
|
||||||
|
self.gizmo.setHpr(parent_hpr)
|
||||||
|
else:
|
||||||
|
self.gizmo.setHpr(0, 0, 0)
|
||||||
|
|
||||||
def _updateGizmoScreenSize(self):
|
def _updateGizmoScreenSize(self):
|
||||||
"""动态调整坐标轴大小,保持固定的屏幕大小"""
|
"""动态调整坐标轴大小,保持固定的屏幕大小"""
|
||||||
try:
|
try:
|
||||||
|
|||||||
@ -309,6 +309,50 @@ class PropertyPanelManager:
|
|||||||
# 材质属性组
|
# 材质属性组
|
||||||
self._updateModelMaterialPanel(model)
|
self._updateModelMaterialPanel(model)
|
||||||
|
|
||||||
|
def refreshModelValues(self,nodePath):
|
||||||
|
if not nodePath or self._propertyLayout is None:
|
||||||
|
return
|
||||||
|
parent = nodePath.getParent()
|
||||||
|
render = self.world.render
|
||||||
|
relPos = nodePath.getPos(parent) if parent else nodePath.getPos()
|
||||||
|
if hasattr(self,'pos_x') and self.pos_x:
|
||||||
|
self.pos_x.blockSignals(True)
|
||||||
|
self.pos_x.setValue(relPos.getX())
|
||||||
|
self.pos_x.blockSignals(False)
|
||||||
|
if hasattr(self,'pos_y') and self.pos_y:
|
||||||
|
self.pos_y.blockSignals(True)
|
||||||
|
self.pos_y.setValue(relPos.getY())
|
||||||
|
self.pos_y.blockSignals(False)
|
||||||
|
if hasattr(self,'pos_z') and self.pos_z:
|
||||||
|
self.pos_z.blockSignals(True)
|
||||||
|
self.pos_z.setValue(relPos.getZ())
|
||||||
|
self.pos_z.blockSignals(False)
|
||||||
|
|
||||||
|
worldPos = nodePath.getPos(render)
|
||||||
|
for axis,attr in zip(('x','y','z'),('world_pos_x','world_pos_y','world_pos_z')):
|
||||||
|
spin = getattr(self,attr,None)
|
||||||
|
if spin:
|
||||||
|
spin.blockSignals(True)
|
||||||
|
spin.setValue(getattr(worldPos,axis))
|
||||||
|
spin.blockSignals(False)
|
||||||
|
|
||||||
|
hpr = nodePath.getHpr()
|
||||||
|
for idx,(attr,val) in enumerate(zip(('rot_h','rot_p','rot_r'),hpr)):
|
||||||
|
spin = getattr(self,attr,None)
|
||||||
|
if spin:
|
||||||
|
spin.blockSignals(True)
|
||||||
|
spin.setValue(val)
|
||||||
|
spin.blockSignals(False)
|
||||||
|
|
||||||
|
scale = nodePath.getScale()
|
||||||
|
for axis,attr in zip(('x','y','z'),('scale_x','scale_y','scale_z')):
|
||||||
|
spin = getattr(self,attr,None)
|
||||||
|
if spin:
|
||||||
|
spin.blockSignals(True)
|
||||||
|
spin.setValue(getattr(scale,axis))
|
||||||
|
spin.blockSignals(False)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def updateGUIPropertyPanel(self, gui_element):
|
def updateGUIPropertyPanel(self, gui_element):
|
||||||
"""更新GUI元素属性面板"""
|
"""更新GUI元素属性面板"""
|
||||||
@ -877,7 +921,7 @@ class PropertyPanelManager:
|
|||||||
print(f"材质基础颜色: {base_color}")
|
print(f"材质基础颜色: {base_color}")
|
||||||
|
|
||||||
# 基础颜色标题
|
# 基础颜色标题
|
||||||
color_row = 2 if material_status != "标准PBR材质" else 0
|
color_row = 2 if material_status != "标准PBR材质" else 1
|
||||||
material_layout.addWidget(QLabel("基础颜色"), color_row, 0)
|
material_layout.addWidget(QLabel("基础颜色"), color_row, 0)
|
||||||
|
|
||||||
# R, G, B 标签
|
# R, G, B 标签
|
||||||
@ -3870,20 +3914,14 @@ class PropertyPanelManager:
|
|||||||
azimuth, altitude = presets[preset_name]
|
azimuth, altitude = presets[preset_name]
|
||||||
|
|
||||||
# 更新滑块和数值框
|
# 更新滑块和数值框
|
||||||
self.sun_azimuth_slider.blockSignals(True)
|
self.azimuthSpinBox.blockSignals(True)
|
||||||
self.sun_azimuth_spinbox.blockSignals(True)
|
self.altitudeSpinBox.blockSignals(True)
|
||||||
self.sun_altitude_slider.blockSignals(True)
|
|
||||||
self.sun_altitude_spinbox.blockSignals(True)
|
|
||||||
|
|
||||||
self.sun_azimuth_slider.setValue(azimuth)
|
self.azimuthSpinBox.setValue(azimuth)
|
||||||
self.sun_azimuth_spinbox.setValue(azimuth)
|
self.altitudeSpinBox.setValue(altitude)
|
||||||
self.sun_altitude_slider.setValue(altitude)
|
|
||||||
self.sun_altitude_spinbox.setValue(altitude)
|
|
||||||
|
|
||||||
self.sun_azimuth_slider.blockSignals(False)
|
self.azimuthSpinBox.blockSignals(False)
|
||||||
self.sun_azimuth_spinbox.blockSignals(False)
|
self.altitudeSpinBox.blockSignals(False)
|
||||||
self.sun_altitude_slider.blockSignals(False)
|
|
||||||
self.sun_altitude_spinbox.blockSignals(False)
|
|
||||||
|
|
||||||
# 应用设置 - 优先使用Day Time Editor
|
# 应用设置 - 优先使用Day Time Editor
|
||||||
azimuth_success = self._updateDayTimeEditorSetting("scattering", "sun_azimuth", azimuth)
|
azimuth_success = self._updateDayTimeEditorSetting("scattering", "sun_azimuth", azimuth)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user