feat: move_camera.txt 改为速度段格式驱动相机运动
格式: 1-60 vx=1.0 rx=10 # 1-60帧:x平移1/帧 + 绕x转10°/帧 30-90 vy=2.0 ry=20 rz=10 # 30-90帧:y平移2/帧 + 绕y转20°/帧 + 绕z转10°/帧 draw.py 每帧累加平移速度修改center,累加旋转速度修改 elevation/azimuth,实现连续平滑的相机运动。
This commit is contained in:
+35
-10
@@ -87,25 +87,50 @@ Z_MIN = None
|
||||
Z_MAX = None
|
||||
|
||||
|
||||
def _load_camera_keyframes(path):
|
||||
"""读取 move_camera.txt,返回 JSON 数组字符串 [[frame,dist,el,az],...] 或空串。"""
|
||||
def _load_camera_motion(path):
|
||||
"""读取 move_camera.txt(速度段格式),返回 JSON 字符串。
|
||||
|
||||
格式:每行是一个运动段
|
||||
start-end vx=f1 vy=f2 vz=f3 rx=d1 ry=d2 rz=d3
|
||||
示例:
|
||||
1-60 vx=1.0 rx=10
|
||||
30-90 vy=2.0 ry=20 rz=10
|
||||
|
||||
返回 JSON: [{"start":N,"end":N,"v":[x,y,z],"r":[x,y,z]},...]
|
||||
"""
|
||||
import re
|
||||
if not os.path.exists(path):
|
||||
print(f"[compute] 警告: 未找到 {path},跳过运动相机")
|
||||
return ""
|
||||
keyframes = []
|
||||
segments = []
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#"):
|
||||
continue
|
||||
parts = line.split()
|
||||
if len(parts) >= 4:
|
||||
keyframes.append([int(parts[0]), float(parts[1]),
|
||||
float(parts[2]), float(parts[3])])
|
||||
if not keyframes:
|
||||
# 解析帧范围
|
||||
m = re.match(r'(\d+)\s*-\s*(\d+)', line)
|
||||
if not m:
|
||||
continue
|
||||
start, end = int(m.group(1)), int(m.group(2))
|
||||
v = [0.0, 0.0, 0.0]
|
||||
r = [0.0, 0.0, 0.0]
|
||||
# 解析 vx=, vy=, vz=
|
||||
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))
|
||||
# 解析 rx=, ry=, rz=
|
||||
for i, axis in enumerate(['x', 'y', 'z']):
|
||||
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):
|
||||
segments.append({"start": start, "end": end, "v": v, "r": r})
|
||||
if not segments:
|
||||
return ""
|
||||
import json
|
||||
return json.dumps(keyframes)
|
||||
return json.dumps(segments)
|
||||
|
||||
|
||||
def _to_text_value(value):
|
||||
@@ -757,7 +782,7 @@ def run_from_config(config, out_dir=None):
|
||||
cam_path = cam_rel
|
||||
if out_dir is not None and not os.path.isabs(cam_rel):
|
||||
cam_path = os.path.join(out_dir, cam_rel)
|
||||
camera_keyframes_raw = _load_camera_keyframes(cam_path)
|
||||
camera_keyframes_raw = _load_camera_motion(cam_path)
|
||||
|
||||
print(f"[compute] 使用算法: {METHOD}")
|
||||
print(f"[compute] 已加载成键信息: {len(BOND_PAIRS)} 条键")
|
||||
|
||||
Reference in New Issue
Block a user