feat: draw.py 直接读取 move_camera.txt,修改后重启即生效
draw.py 启动时优先读取 input/move_camera.txt(实时文件), 不存在或为空时回退到 display.txt header 中的缓存数据。 改动 move_camera.txt 后只需重启动画窗口(关掉旧窗口重新 run_dynamics.py),无需重新跑模拟。
This commit is contained in:
@@ -555,13 +555,46 @@ print(f"[draw] 渲染方式: {mode_str}")
|
||||
print(f"[draw] 绘图参数: ball_radius={ball_radius}, box_color=({box_color_r:.2f},{box_color_g:.2f},{box_color_b:.2f}), alpha={alpha_list}")
|
||||
|
||||
|
||||
# 运动相机(速度段驱动)
|
||||
_CAM_MOTION = json.loads(h.get("camera_keyframes", "null")) if h.get("camera_keyframes") else None
|
||||
# 运动相机(速度段驱动):优先读取 move_camera.txt,其次用 display.txt header 缓存
|
||||
import re as _re
|
||||
|
||||
def _load_move_camera_txt():
|
||||
"""直接读取 input/move_camera.txt(与 output 同级的 input 目录)。"""
|
||||
input_dir = os.path.join(os.path.dirname(output_dir), "input")
|
||||
cam_path = os.path.join(input_dir, "move_camera.txt")
|
||||
if not os.path.exists(cam_path):
|
||||
return None
|
||||
segs = []
|
||||
with open(cam_path, "r", encoding="utf-8") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#"):
|
||||
continue
|
||||
m = _re.match(r'(\d+)\s*-\s*(\d+)', line)
|
||||
if not m:
|
||||
continue
|
||||
start, end = int(m.group(1)), int(m.group(2))
|
||||
v, r = [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]
|
||||
for i, axis in enumerate(['x', 'y', 'z']):
|
||||
m2 = _re.search(r'v' + axis + r'\s*=\s*([-\d.]+)', line)
|
||||
if m2: v[i] = float(m2.group(1))
|
||||
m2 = _re.search(r'r' + axis + r'\s*=\s*([-\d.]+)', line)
|
||||
if m2: r[i] = float(m2.group(1))
|
||||
if any(v) or any(r):
|
||||
segs.append({"start": start, "end": end, "v": v, "r": r})
|
||||
return segs if segs else None
|
||||
|
||||
# 先试 move_camera.txt 直读,没有则用 display.txt 缓存
|
||||
_CAM_MOTION = _load_move_camera_txt()
|
||||
if not _CAM_MOTION:
|
||||
_CAM_MOTION = json.loads(h.get("camera_keyframes", "null")) if h.get("camera_keyframes") else None
|
||||
if _CAM_MOTION:
|
||||
_cam_center = [0.0, 0.0, 0.0]
|
||||
_cam_elev = initial_camera["elevation"]
|
||||
_cam_azim = initial_camera["azimuth"]
|
||||
_cam_dist = initial_camera["distance"]
|
||||
src = "move_camera.txt" if _load_move_camera_txt() else "display.txt header"
|
||||
print(f"[draw] 运动相机已启用(数据来源: {src},{len(_CAM_MOTION)} 段)")
|
||||
|
||||
|
||||
def _update_motion_camera(f_idx):
|
||||
|
||||
@@ -105,4 +105,4 @@ box_color_b: 0.85
|
||||
camera_distance: 40.0 # 摄像机到场景中心的距离
|
||||
camera_elevation: 0 # 俯仰角(度),负值=俯视
|
||||
camera_azimuth: 0 # 方位角(度)
|
||||
move_camera: 0 # 0=固定视角, 1=按 move_camera.txt 运动
|
||||
move_camera: 1 # 0=固定视角, 1=按 move_camera.txt 运动
|
||||
|
||||
@@ -5,5 +5,4 @@
|
||||
# rx → elevation(俯仰), ry → azimuth(方位), rz → (预留)
|
||||
#
|
||||
# 示例:前60帧向右平移+绕x旋转,30-90帧向上平移+绕y绕z旋转
|
||||
1-60 vx=1.0 rx=10
|
||||
30-90 vy=2.0 ry=20 rz=10
|
||||
1-200 vx=0.01
|
||||
|
||||
Reference in New Issue
Block a user