合并更新

This commit is contained in:
Hector 2026-02-28 10:49:03 +08:00
parent 2ac08b0582
commit 28d2b124cc
3 changed files with 68 additions and 17 deletions

View File

@ -31,19 +31,19 @@ DockId=0x0000000D,0
[Window][场景树]
Pos=0,20
Size=276,622
Size=276,634
Collapsed=0
DockId=0x00000007,0
[Window][属性面板]
Pos=1575,20
Size=345,971
Size=345,989
Collapsed=0
DockId=0x00000003,0
[Window][控制台]
Pos=0,644
Size=276,347
Pos=0,656
Size=276,353
Collapsed=0
DockId=0x00000008,0
@ -60,7 +60,7 @@ Collapsed=0
[Window][WindowOverViewport_11111111]
Pos=0,20
Size=1920,971
Size=1920,989
Collapsed=0
[Window][测试窗口1]
@ -99,7 +99,7 @@ Size=600,500
Collapsed=0
[Window][资源管理器]
Pos=278,657
Pos=278,675
Size=1295,334
Collapsed=0
DockId=0x00000006,0
@ -201,7 +201,7 @@ Size=600,400
Collapsed=0
[Docking][Data]
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,20 Size=1920,971 Split=X
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,20 Size=1920,989 Split=X
DockNode ID=0x00000001 Parent=0x08BD597D SizeRef=1573,989 Split=X
DockNode ID=0x00000009 Parent=0x00000001 SizeRef=276,989 Split=Y Selected=0xE0015051
DockNode ID=0x00000007 Parent=0x00000009 SizeRef=271,634 Selected=0xE0015051

View File

@ -30,6 +30,8 @@ class ObjectController:
self.display_names = {}
self.global_transforms = []
self.position_offsets = {}
self.vertex_index = {}
self.original_positions = {}
self.local_to_global_id = {}
self.local_transform_state = {}
self.local_transform_base_positions = {}
@ -741,9 +743,30 @@ class ObjectController:
chunk["dynamic_enabled"] = False
self.active_chunks.discard(chunk_id)
def _resolve_chunk_and_local_idx(self, global_id):
"""
Compatibility helper for merged branches:
- legacy: id_to_chunk[gid] -> (chunk_id, local_idx)
- current: id_to_chunk[gid] -> chunk_id (local_idx defaults to gid)
"""
mapping = self.id_to_chunk.get(global_id)
if mapping is None:
return None, None
if isinstance(mapping, (tuple, list)):
if not mapping:
return None, None
chunk_id = mapping[0]
local_idx = mapping[1] if len(mapping) > 1 else global_id
return chunk_id, local_idx
return mapping, global_id
def set_active_ids(self, active_ids):
"""切换编辑激活集合,仅保留 active_ids 对应 chunk 为动态模式。"""
target_chunks = {self.id_to_chunk[obj_id] for obj_id in active_ids if obj_id in self.id_to_chunk}
target_chunks = set()
for obj_id in active_ids:
chunk_id, _ = self._resolve_chunk_and_local_idx(obj_id)
if chunk_id is not None:
target_chunks.add(chunk_id)
# Demote no-longer-active chunks. Dirty chunks are re-baked before demotion.
for chunk_id in list(self.active_chunks):
@ -940,10 +963,9 @@ class ObjectController:
return local_indices
seen = set()
for global_id in global_ids:
mapping = self.id_to_chunk.get(global_id)
if not mapping:
_, local_idx = self._resolve_chunk_and_local_idx(global_id)
if local_idx is None:
continue
_, local_idx = mapping
if local_idx in seen:
continue
if local_idx not in self.vertex_index:
@ -1102,10 +1124,28 @@ class ObjectController:
if global_id not in self.id_to_chunk:
return
_, local_idx = self.id_to_chunk[global_id]
if local_idx not in self.vertex_index:
chunk_id, local_idx = self._resolve_chunk_and_local_idx(global_id)
if local_idx is None:
return
# Hybrid chunk mode (current) may move NodePaths directly without
# vertex_index/original_positions populated.
if local_idx not in self.vertex_index or local_idx not in self.original_positions:
obj_np = self.id_to_object_np.get(global_id)
if not obj_np or obj_np.is_empty():
return
next_pos = obj_np.get_pos() + delta
if hasattr(obj_np, "set_fluid_pos"):
obj_np.set_fluid_pos(next_pos)
else:
obj_np.set_pos(next_pos)
pick_np = self.id_to_pick_np.get(global_id)
if pick_np and not pick_np.is_empty():
pick_np.set_mat(self.model, obj_np.get_mat(self.model))
if chunk_id is not None and chunk_id in self.chunks:
self.chunks[chunk_id]["dirty"] = True
self.position_offsets[local_idx] = self.position_offsets.get(local_idx, Vec3(0)) + delta
return
# Accumulate offset
@ -1132,9 +1172,17 @@ class ObjectController:
self._apply_vertices_to_pick(local_idx, i, new_pos)
def get_world_pos(self, global_id):
if global_id not in self.id_to_object_np or not self.model:
if not self.model:
return Vec3(0, 0, 0)
obj_np = self.id_to_object_np.get(global_id)
if obj_np and not obj_np.is_empty():
p = obj_np.get_pos(self.model)
return self._local_point_to_world(Vec3(p))
_, local_idx = self._resolve_chunk_and_local_idx(global_id)
if local_idx is None:
return Vec3(0, 0, 0)
_, local_idx = self.id_to_chunk[global_id]
original_mat = self.global_transforms[global_id]
original_pos = original_mat.get_row3(3)

View File

@ -66,6 +66,9 @@ class SSBOEditor:
self.ssbo = None
self.font_path = font_path
self._transform_gizmo = None
self._ssbo_transform_active = False
self._ssbo_selected_local_indices = []
self._ssbo_gizmo_proxy = None
# Internal State
self.selected_name = None