diff --git a/.gitignore b/.gitignore
index e3163bcf..74ae8b6c 100644
Binary files a/.gitignore and b/.gitignore differ
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 359bb530..00000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# 默认忽略的文件
-/shelf/
-/workspace.xml
diff --git a/.idea/AugmentWebviewStateStore.xml b/.idea/AugmentWebviewStateStore.xml
deleted file mode 100644
index 0e433175..00000000
--- a/.idea/AugmentWebviewStateStore.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/EG.iml b/.idea/EG.iml
index c1574376..8a3456df 100644
--- a/.idea/EG.iml
+++ b/.idea/EG.iml
@@ -4,7 +4,7 @@
-
+
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index 84212658..00000000
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
deleted file mode 100644
index 105ce2da..00000000
--- a/.idea/inspectionProfiles/profiles_settings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 51b9fc17..370e0928 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,5 +3,5 @@
-
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 4bfd7d3a..00000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 35eb1ddf..00000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/RenderPipelineFile/config/daytime.yaml b/RenderPipelineFile/config/daytime.yaml
index af9861ed..0a5dfddc 100644
--- a/RenderPipelineFile/config/daytime.yaml
+++ b/RenderPipelineFile/config/daytime.yaml
@@ -17,7 +17,7 @@ control_points:
scattering:
sun_intensity: [[[0.0000000000,0.0000000000],[0.0041666667,0.0000000000],[0.0083333333,0.0000000000],[0.0125000000,0.0000000000],[0.0166666667,0.0000000000],[0.0208333333,0.0000000000],[0.0250000000,0.0000000000],[0.0291666667,0.0000000000],[0.0333333333,0.0000000000],[0.0375000000,0.0000000000],[0.0416666667,0.0000000000],[0.0458333333,0.0000000000],[0.0500000000,0.0000000000],[0.0541666667,0.0000000000],[0.0583333333,0.0000000000],[0.0625000000,0.0000000000],[0.0666666667,0.0000000000],[0.0708333333,0.0000000000],[0.0750000000,0.0000000000],[0.0791666667,0.0000000000],[0.0833333333,0.0000000000],[0.0875000000,0.0000000000],[0.0916666667,0.0000000000],[0.0958333333,0.0000000000],[0.1000000000,0.0000000000],[0.1041666667,0.0000000000],[0.1083333333,0.0000000000],[0.1125000000,0.0000000000],[0.1166666667,0.0000000000],[0.1208333333,0.0000000000],[0.1250000000,0.0000000000],[0.1291666667,0.0000000000],[0.1333333333,0.0000000000],[0.1375000000,0.0000000000],[0.1416666667,0.0000000000],[0.1458333333,0.0000000000],[0.1500000000,0.0000000000],[0.1541666667,0.0000000000],[0.1583333333,0.0000028805],[0.1625000000,0.0003577724],[0.1666666667,0.0013331400],[0.1708333333,0.0029671803],[0.1750000000,0.0052963381],[0.1791666667,0.0083550556],[0.1833333333,0.0121755589],[0.1875000000,0.0167876159],[0.1916666667,0.0222183530],[0.1958333333,0.0284919947],[0.2000000000,0.0356297193],[0.2041666667,0.0436494349],[0.2083333333,0.0525656099],[0.2125000000,0.0623891610],[0.2166666667,0.0731272461],[0.2208333333,0.0847831708],[0.2250000000,0.0973563167],[0.2291666667,0.1108419698],[0.2333333333,0.1252313631],[0.2375000000,0.1405115250],[0.2416666667,0.1566653434],[0.2458333333,0.1736715009],[0.2500000000,0.1915046014],[0.2541666667,0.2101350464],[0.2583333333,0.2295292930],[0.2625000000,0.2496498145],[0.2666666667,0.2704552670],[0.2708333333,0.2919006662],[0.2750000000,0.3139375192],[0.2791666667,0.3365139497],[0.2833333333,0.3595750662],[0.2875000000,0.3830630359],[0.2916666667,0.4069173972],[0.2958333333,0.4310753462],[0.3000000000,0.4554720417],[0.3041666667,0.4800408236],[0.3083333333,0.5047136020],[0.3125000000,0.5294212108],[0.3166666667,0.5540936424],[0.3208333333,0.5786605298],[0.3250000000,0.6030514553],[0.3291666667,0.6271963182],[0.3333333333,0.6510256858],[0.3375000000,0.6744711982],[0.3416666667,0.6974659988],[0.3458333333,0.7199450163],[0.3500000000,0.7418453485],[0.3541666667,0.7631067095],[0.3583333333,0.7836717291],[0.3625000000,0.8034862953],[0.3666666667,0.8224999302],[0.3708333333,0.8406661079],[0.3750000000,0.8579425235],[0.3791666667,0.8742914270],[0.3833333333,0.8896799131],[0.3875000000,0.9040801386],[0.3916666667,0.9174695289],[0.3958333333,0.9298310650],[0.4000000000,0.9411533765],[0.4041666667,0.9514309312],[0.4083333333,0.9606641691],[0.4125000000,0.9688595571],[0.4166666667,0.9760296330],[0.4208333333,0.9821930708],[0.4250000000,0.9873746114],[0.4291666667,0.9916050060],[0.4333333333,0.9949209310],[0.4375000000,0.9973647924],[0.4416666667,0.9989845508],[0.4458333333,0.9998334497],[0.4500000000,0.9999696949],[0.4541666667,0.9994560801],[0.4583333333,0.9983595429],[0.4625000000,0.9967506613],[0.4666666667,0.9947030614],[0.4708333333,0.9922927758],[0.4750000000,0.9895975125],[0.4791666667,0.9866958610],[0.4833333333,0.9836664262],[0.4875000000,0.9805868867],[0.4916666667,0.9775330316],[0.4958333333,0.9745777179],[0.5000000000,0.9717898417],[0.5041666667,0.9692332877],[0.5083333333,0.9669658924],[0.5125000000,0.9650384806],[0.5089595376,0.9690650222],[0.5208333333,0.9623666659],[0.5250000000,0.9616814371],[0.5291666667,0.9614534423],[0.5333333333,0.9616877089],[0.5375000000,0.9623790807],[0.5416666667,0.9635123329],[0.5458333333,0.9650624244],[0.5500000000,0.9669949804],[0.5541666667,0.9692669864],[0.5583333333,0.9718275065],[0.5625000000,0.9746185969],[0.5666666667,0.9775762863],[0.5708333333,0.9806315864],[0.5750000000,0.9837115661],[0.5791666667,0.9867403433],[0.5833333333,0.9896401655],[0.5875000000,0.9923323562],[0.5916666667,0.9947382579],[0.5958333333,0.9967800977],[0.6000000000,0.9983817820],[0.6041666667,0.9994696263],[0.6083333333,0.9999730028],[0.6125000000,0.9998249266],[0.6166666667,0.9989625601],[0.6208333333,0.9973276624],[0.6250000000,0.9948669567],[0.6291666667,0.9915324664],[0.6333333333,0.9872817545],[0.6375000000,0.9820781426],[0.6416666667,0.9758908775],[0.6458333333,0.9686952146],[0.6500000000,0.9604725211],[0.6541666667,0.9512102537],[0.6583333333,0.9409019858],[0.6625000000,0.9295473441],[0.6666666667,0.9171518878],[0.6708333333,0.9037270619],[0.6750000000,0.8892899902],[0.6791666667,0.8738633008],[0.6833333333,0.8574749656],[0.6875000000,0.8401579787],[0.6916666667,0.8219502453],[0.6958333333,0.8028941798],[0.7000000000,0.7830364456],[0.7041666667,0.7624277344],[0.7083333333,0.7411222520],[0.7125000000,0.7191776044],[0.7166666667,0.6966542563],[0.7208333333,0.6736152714],[0.7250000000,0.6501259629],[0.7291666667,0.6262533880],[0.7333333333,0.6020661121],[0.7375000000,0.5776338043],[0.7416666667,0.5530267796],[0.7458333333,0.5283156992],[0.7500000000,0.5035711751],[0.7541666667,0.4788634341],[0.7583333333,0.4542618347],[0.7625000000,0.4298347613],[0.7666666667,0.4056490351],[0.7708333333,0.3817697830],[0.7750000000,0.3582600107],[0.7791666667,0.3351803495],[0.7833333333,0.3125888445],[0.7875000000,0.2905406366],[0.7916666667,0.2690876955],[0.7958333333,0.2482787388],[0.8000000000,0.2281588906],[0.8041666667,0.2087696425],[0.8083333333,0.1901486315],[0.8125000000,0.1723295359],[0.8166666667,0.1553419918],[0.8208333333,0.1392115328],[0.8250000000,0.1239595144],[0.8291666667,0.1096030703],[0.8333333333,0.0961551918],[0.8375000000,0.0836246599],[0.8416666667,0.0720161369],[0.8458333333,0.0613302273],[0.8500000000,0.0515635598],[0.8541666667,0.0427088803],[0.8583333333,0.0347551990],[0.8625000000,0.0276878920],[0.8666666667,0.0214889271],[0.8708333333,0.0161369711],[0.8750000000,0.0116076130],[0.8791666667,0.0078735477],[0.8833333333,0.0049047927],[0.8875000000,0.0026688977],[0.8916666667,0.0011311782],[0.8958333333,0.0002549473],[0.9000000000,0.0000000000],[0.9041666667,0.0000000000],[0.9083333333,0.0000000000],[0.9125000000,0.0000000000],[0.9166666667,0.0000000000],[0.9208333333,0.0000000000],[0.9250000000,0.0000000000],[0.9291666667,0.0000000000],[0.9333333333,0.0000000000],[0.9375000000,0.0000000000],[0.9416666667,0.0000000000],[0.9458333333,0.0000000000],[0.9500000000,0.0000000000],[0.9541666667,0.0000000000],[0.9583333333,0.0000000000],[0.9625000000,0.0000000000],[0.9666666667,0.0000000000],[0.9708333333,0.0000000000],[0.9750000000,0.0000000000],[0.9791666667,0.0000000000],[0.9833333333,0.0000000000],[0.9875000000,0.0000000000],[0.9916666667,0.0000000000],[0.9958333333,0.0000000000]]]
sun_color: [[[0.5010435645,0.5818710306],[0.0433100000,0.8999700000],[0.8635787716,0.9130000000],[0.1785000000,0.8973600000],[0.8099800000,0.8651100000],[0.2360800000,0.7712700000],[0.6583432177,0.8485126184],[0.1266806142,0.9648102053],[0.9558541267,0.9090909091],[0.5568400771,0.7353760446]],[[0.5001318426,0.5160300000],[0.0572700000,0.6541600000],[0.2395000000,0.5976800000],[0.8104600000,0.6009000000],[0.6967400000,0.5483900000]],[[0.0862400000,0.4257800000],[0.4955600000,0.4033000000],[0.8234200000,0.4340200000]]]
- sun_azimuth: [[[0.5000000000,0.5000000000]]]
+ sun_azimuth: [[[0.5000000000,0.1888888889]]]
sun_altitude: [[[0.5000000000,1.0000000000]]]
extinction: [[[0.4913294798,0.6378830084]]]
volumetrics:
diff --git a/core/selection.py b/core/selection.py
index d1c62a24..4c55c3e4 100644
--- a/core/selection.py
+++ b/core/selection.py
@@ -105,6 +105,37 @@ class SelectionSystem:
if not self.selectionBox or not self.selectionBoxTarget:
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 = self.world.render.attachNewNode("selectionBox")
@@ -177,6 +208,15 @@ class SelectionSystem:
def updateSelectionBoxTask(self, task):
"""选择框更新任务"""
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:
return task.done # 结束任务
@@ -598,6 +638,16 @@ class SelectionSystem:
def updateGizmoTask(self, task):
"""坐标轴更新任务 - 包含固定大小功能"""
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:
return task.done
@@ -613,25 +663,27 @@ class SelectionSystem:
self.gizmoTarget.setPos(light_pos)
else:
- # 更新坐标轴位置,始终在目标节点中心
- 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)
-
- # 【关键修复】:更新坐标轴朝向以跟踪父节点的变化
- 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)
+ # 只在必要时更新位置和朝向
+ self._updateGizmoPositionAndOrientation()
+ # # 更新坐标轴位置,始终在目标节点中心
+ # 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)
+ #
+ # # 【关键修复】:更新坐标轴朝向以跟踪父节点的变化
+ # 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)
# 【新功能】:动态调整坐标轴大小,保持固定的屏幕大小
self._updateGizmoScreenSize()
@@ -642,6 +694,33 @@ class SelectionSystem:
print(f"坐标轴更新任务出错: {str(e)}")
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):
"""动态调整坐标轴大小,保持固定的屏幕大小"""
try:
@@ -1203,33 +1282,23 @@ class SelectionSystem:
# 确定轴向量的变换上下文
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)
else:
world_axis_vector = local_axis_vector
- # 顶级模型:使用世界坐标系
- # print(f"顶级模型拖拽 - 使用世界坐标系")
- # transform_context = self.world.render
- axis_end = gizmo_world_pos + world_axis_vector
+
+ #axis_end = gizmo_world_pos + world_axis_vector
# 投影到屏幕空间
def worldToScreen(worldPos):
try:
- # 先转换为相机坐标系
camPos = self.world.cam.getRelativePoint(self.world.render, worldPos)
-
- # 检查是否在相机前方
if camPos.getY() <= 0:
return None
screenPos = Point2()
if self.world.cam.node().getLens().project(camPos, screenPos):
- # 获取准确的窗口尺寸
winWidth, winHeight = self.world.getWindowSize()
-
winX = (screenPos.x + 1) * 0.5 * winWidth
winY = (1 - screenPos.y) * 0.5 * winHeight
return (winX, winY)
@@ -1237,28 +1306,45 @@ class SelectionSystem:
except Exception as e:
print(f"世界坐标转屏幕坐标失败: {e}")
return None
+ axis_start_screen = worldToScreen(gizmo_world_pos)
+ axis_end_world = gizmo_world_pos + world_axis_vector
+ axis_end_screen = worldToScreen(axis_end_world)
+ #gizmo_screen = worldToScreen(gizmo_world_pos)
+ #axis_screen = worldToScreen(axis_end)
- gizmo_screen = worldToScreen(gizmo_world_pos)
- axis_screen = worldToScreen(axis_end)
+ # if not gizmo_screen:
+ # print("拖拽更新失败: 坐标轴中心不在屏幕内")
+ # return
+ # if not axis_screen:
+ # print("拖拽更新失败: 坐标轴端点不在屏幕内")
+ # return
+ #
+ # # 计算轴在屏幕空间的方向向量
+ # screen_axis_dir = (
+ # axis_screen[0] - gizmo_screen[0],
+ # axis_screen[1] - gizmo_screen[1]
+ # )
- if not gizmo_screen:
- print("拖拽更新失败: 坐标轴中心不在屏幕内")
- return
- if not axis_screen:
- print("拖拽更新失败: 坐标轴端点不在屏幕内")
+ if not axis_start_screen or not axis_end_screen:
+ print("拖拽更新失败: 无法获取轴线屏幕坐标")
return
- # 计算轴在屏幕空间的方向向量
screen_axis_dir = (
- axis_screen[0] - gizmo_screen[0],
- axis_screen[1] - gizmo_screen[1]
+ axis_end_screen[0] - axis_start_screen[0],
+ axis_end_screen[1] - axis_start_screen[1]
)
+
# 归一化屏幕轴方向
import math
length = math.sqrt(screen_axis_dir[0]**2 + screen_axis_dir[1]**2)
if length > 0:
- screen_axis_dir = (screen_axis_dir[0] / length, screen_axis_dir[1] / length)
+ #screen_axis_dir = (screen_axis_dir[0] / length, screen_axis_dir[1] / length)
+ screen_axis_dir = (
+ screen_axis_dir[0] / length,
+ screen_axis_dir[1] / length
+ )
+
else:
print("拖拽更新失败: 屏幕轴方向长度为0")
return
@@ -1267,29 +1353,54 @@ class SelectionSystem:
projected_distance = (mouseDeltaX * screen_axis_dir[0] +
mouseDeltaY * screen_axis_dir[1])
- 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
+ cam_pos = self.world.cam.getPos(self.world.render)
+ distance_to_object = (cam_pos - gizmo_world_pos).length()
+ lens = self.world.cam.node().getLens()
+ fov = lens.getFov()[0]
+ winWidth,winHeight = self.world.getWindowSize()
- fixed_pixel_to_world_ratio = 0.01 # 1像素 = 0.01世界单位
- scale_factor = fixed_pixel_to_world_ratio * scale_adjustment
+ pixels_to_world_units = (2*distance_to_object*math.tan(math.radians(fov/2)))/winWidth
+
+ movement_distance = projected_distance * pixels_to_world_units
+
+ total_scale_factor = 1.0
+ current_node = self.gizmoTarget.getParent()
+
+ 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_factor *= avg_scale
+ current_node = current_node.getParent()
+
+ if total_scale_factor > 0:
+ movement_distance = movement_distance / total_scale_factor
- movement_distance = projected_distance * scale_factor
- # 获取当前位置并只修改选中轴的坐标
currentPos = self.gizmoTargetStartPos
+
+ # 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
+ #
+ #
+ # fixed_pixel_to_world_ratio = 0.01 # 1像素 = 0.01世界单位
+ # scale_factor = fixed_pixel_to_world_ratio * scale_adjustment
+ #
+ # movement_distance = projected_distance * scale_factor
+ # # 获取当前位置并只修改选中轴的坐标
+ # currentPos = self.gizmoTargetStartPos
# 根据拖拽的轴,只修改对应的坐标分量
if self.dragGizmoAxis == "x":
@@ -1332,7 +1443,7 @@ class SelectionSystem:
import time
current_time = time.time()
if current_time - self._last_drag_debug_time > 0.1: # 每0.1秒最多输出一次
- print(f"拖拽更新成功 - 轴:{self.dragGizmoAxis}, 比例:{scale_factor:.6f}, 投影:{projected_distance:.2f}")
+ #print(f"拖拽更新成功 - 轴:{self.dragGizmoAxis}, 比例:{scale_factor:.6f}, 投影:{projected_distance:.2f}")
self._last_drag_debug_time = current_time
except Exception as e:
diff --git a/ui/property_panel.py b/ui/property_panel.py
index 5736cdb0..05cae777 100644
--- a/ui/property_panel.py
+++ b/ui/property_panel.py
@@ -21,25 +21,6 @@ class PropertyPanelManager:
self._propertyLayout = None
self._actor_cache={}
- # 定义紧凑样式
- self.compact_style = """
- QDoubleSpinBox {
- min-width: 45px;
- }
- QPushButton {
- min-width: 10px;
- }
- QComboBox {
- min-width: 60px;
- }
- QLineEdit {
- min-width: 60px;
- }
- QCheckBox {
- min-width: 20px;
- }
- """
-
def setPropertyLayout(self, layout):
"""设置属性面板布局引用"""
print("开始设置属性布局")
@@ -77,10 +58,6 @@ class PropertyPanelManager:
self.clearPropertyPanel()
- # 应用紧凑样式到属性面板容器
- if self._propertyLayout.parent():
- self._propertyLayout.parent().setStyleSheet(self.compact_style)
-
itemText = item.text(0)
# 如果点击的是场景根节点,显示提示信息
@@ -215,9 +192,24 @@ class PropertyPanelManager:
self.pos_z.setValue(relativePos.getZ())
# 连接位置变化事件
- self.pos_x.valueChanged.connect(lambda v: model.setX(parent, v) if parent else model.setX(v))
- self.pos_y.valueChanged.connect(lambda v: model.setY(parent, v) if parent else model.setY(v))
- self.pos_z.valueChanged.connect(lambda v: model.setZ(parent, v) if parent else model.setZ(v))
+ # self.pos_x.valueChanged.connect(lambda v: model.setX(parent, v) if parent else model.setX(v))
+ # self.pos_y.valueChanged.connect(lambda v: model.setY(parent, v) if parent else model.setY(v))
+ # self.pos_z.valueChanged.connect(lambda v: model.setZ(parent, v) if parent else model.setZ(v))
+
+ def updateXPosition(value):
+ model.setX(value)
+ self.refreshModelValues(model)
+ self.pos_x.valueChanged.connect(updateXPosition)
+
+ def updateYPosition(value):
+ model.setY(value)
+ self.refreshModelValues(model)
+ self.pos_y.valueChanged.connect(updateYPosition)
+
+ def updateZPosition(value):
+ model.setZ(value)
+ self.refreshModelValues(model)
+ self.pos_z.valueChanged.connect(updateZPosition)
# 创建并设置 X, Y, Z 标签居中
x_label1 = QLabel("X")
@@ -332,6 +324,50 @@ class PropertyPanelManager:
# 材质属性组
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):
"""更新GUI元素属性面板"""
@@ -3892,7 +3928,6 @@ class PropertyPanelManager:
if preset_name in presets:
azimuth, altitude = presets[preset_name]
- # 更新滑块和数值框
# 更新滑块和数值框
self.azimuthSpinBox.blockSignals(True)
self.altitudeSpinBox.blockSignals(True)
@@ -4962,20 +4997,18 @@ except Exception as e:
# 如果有多种类型的动画,使用标签页
if len(animations) > 1:
tab_widget = QTabWidget()
- tab_widget.setMinimumWidth(200) # 设置最小宽度
for anim_type, anim_data in animations.items():
tab = QWidget()
- tab_layout = QGridLayout(tab) # 改为QGridLayout保持一致
+ tab_layout = QVBoxLayout(tab)
self._buildAnimationTypeUI(tab_layout, origin_model, anim_type, anim_data)
tab_widget.addTab(tab, self._getAnimTypeDisplayName(anim_type))
- layout.addWidget(QLabel("动画类型:"), 1, 0)
- layout.addWidget(tab_widget, 1, 1, 1, 3)
+ self._propertyLayout.addRow("动画类型:", tab_widget)
else:
# 只有一种类型,直接显示
anim_type, anim_data = next(iter(animations.items()))
- self._buildAnimationTypeUI(layout, origin_model, anim_type, anim_data)
+ self._buildAnimationTypeUI(self._propertyLayout, origin_model, anim_type, anim_data)
# 存储动画信息供控制使用
if not hasattr(self, '_non_skeletal_cache'):
@@ -4986,69 +5019,46 @@ except Exception as e:
"""为特定动画类型构建UI"""
from PyQt5.QtWidgets import QLabel, QComboBox, QHBoxLayout, QWidget, QPushButton, QDoubleSpinBox
- current_row = layout.rowCount()
-
if anim_type == 'transform':
# 变换动画控制
self.ns_transform_combo = QComboBox()
self.ns_transform_combo.addItems(anim_data['names'])
- self.ns_transform_combo.setMinimumWidth(80)
- layout.addWidget(QLabel("变换动画:"), current_row, 0)
- layout.addWidget(self.ns_transform_combo, current_row, 1, 1, 3)
- current_row += 1
+ layout.addRow("变换动画:", self.ns_transform_combo)
elif anim_type == 'texture':
# 纹理动画控制
self.ns_texture_combo = QComboBox()
self.ns_texture_combo.addItems(anim_data['stages'])
- self.ns_texture_combo.setMinimumWidth(80)
- layout.addWidget(QLabel("纹理动画:"), current_row, 0)
- layout.addWidget(self.ns_texture_combo, current_row, 1, 1, 3)
- current_row += 1
+ layout.addRow("纹理动画:", self.ns_texture_combo)
elif anim_type == 'material':
# 材质动画控制
self.ns_material_combo = QComboBox()
self.ns_material_combo.addItems(anim_data['properties'])
- self.ns_material_combo.setMinimumWidth(80)
- layout.addWidget(QLabel("材质动画:"), current_row, 0)
- layout.addWidget(self.ns_material_combo, current_row, 1, 1, 3)
- current_row += 1
+ layout.addRow("材质动画:", self.ns_material_combo)
elif anim_type == 'lerp':
# Lerp动画控制
self.ns_lerp_combo = QComboBox()
self.ns_lerp_combo.addItems(anim_data['intervals'])
- self.ns_lerp_combo.setMinimumWidth(80)
- layout.addWidget(QLabel("Lerp动画:"), current_row, 0)
- layout.addWidget(self.ns_lerp_combo, current_row, 1, 1, 3)
- current_row += 1
+ layout.addRow("Lerp动画:", self.ns_lerp_combo)
# 通用控制按钮
btn_box = QWidget()
btn_lay = QHBoxLayout(btn_box)
- btn_lay.setContentsMargins(0, 0, 0, 0)
for txt, cmd in (("播放", "play"), ("暂停", "pause"), ("停止", "stop"), ("循环", "loop")):
btn = QPushButton(txt)
- btn.setMinimumWidth(35) # 设置按钮最小宽度
- btn.setMaximumWidth(50) # 限制按钮最大宽度
btn.clicked.connect(lambda _, c=cmd, t=anim_type: self._controlNonSkeletalAnimation(origin_model, t, c))
btn_lay.addWidget(btn)
- layout.addWidget(QLabel("控制:"), current_row, 0)
- layout.addWidget(btn_box, current_row, 1, 1, 3)
- current_row += 1
+ layout.addRow("控制:", btn_box)
# 播放速度
speed_spinbox = QDoubleSpinBox()
speed_spinbox.setRange(0.1, 5.0)
speed_spinbox.setSingleStep(0.1)
speed_spinbox.setValue(1.0)
- speed_spinbox.setMinimumWidth(60)
- speed_spinbox.setMaximumWidth(80)
- speed_spinbox.valueChanged.connect(
- lambda v, t=anim_type: self._setNonSkeletalAnimationSpeed(origin_model, t, v))
- layout.addWidget(QLabel("播放速度:"), current_row, 0)
- layout.addWidget(speed_spinbox, current_row, 1, 1, 3)
+ speed_spinbox.valueChanged.connect(lambda v, t=anim_type: self._setNonSkeletalAnimationSpeed(origin_model, t, v))
+ layout.addRow("播放速度:", speed_spinbox)
def _getAnimTypeDisplayName(self, anim_type):
"""获取动画类型的显示名称"""