Compute camera-to-world 4x4 transform matrix in spherical coordinates, looking at origin with up=(0,1,0). Uses standard LookAt formula where camera local -Z points at target and local Y is up. An additional +90 degree rotation around local Z axis is applied to match Blender Trac
(radius: float, yaw: float, pitch: float, dtype=torch.float32, device='cpu')
| 451 | import math |
| 452 | |
| 453 | def get_new_camera_matrix(radius: float, yaw: float, pitch: float, dtype=torch.float32, device='cpu'): |
| 454 | """ |
| 455 | Compute camera-to-world 4x4 transform matrix in spherical coordinates, |
| 456 | looking at origin with up=(0,1,0). |
| 457 | Uses standard LookAt formula where camera local -Z points at target and local Y is up. |
| 458 | An additional +90 degree rotation around local Z axis is applied to match |
| 459 | Blender Track-To local axis convention. |
| 460 | yaw, pitch are in radians. |
| 461 | """ |
| 462 | x = radius * math.cos(yaw) * math.cos(pitch) |
| 463 | y = radius * math.sin(yaw) * math.cos(pitch) |
| 464 | z = radius * math.sin(pitch) |
| 465 | eye = torch.tensor([x, y, z], dtype=dtype, device=device) |
| 466 | target = torch.zeros(3, dtype=dtype, device=device) |
| 467 | up_global = torch.tensor([0.0, 1.0, 0.0], dtype=dtype, device=device) |
| 468 | |
| 469 | f = (target - eye) |
| 470 | f = f / torch.norm(f) |
| 471 | r = torch.cross(f, up_global) |
| 472 | r = r / torch.norm(r) |
| 473 | u = torch.cross(r, f) |
| 474 | |
| 475 | z_cam = -f |
| 476 | x_cam = r |
| 477 | y_cam = u |
| 478 | |
| 479 | T = torch.eye(4, dtype=dtype, device=device) |
| 480 | T[:3, 0] = x_cam |
| 481 | T[:3, 1] = y_cam |
| 482 | T[:3, 2] = z_cam |
| 483 | T[:3, 3] = eye |
| 484 | |
| 485 | # +90 degree rotation matrix around local Z axis |
| 486 | Rz90 = torch.tensor([ |
| 487 | [0.0, -1.0, 0.0, 0.0], |
| 488 | [1.0, 0.0, 0.0, 0.0], |
| 489 | [0.0, 0.0, 1.0, 0.0], |
| 490 | [0.0, 0.0, 0.0, 1.0] |
| 491 | ], dtype=dtype, device=device) |
| 492 | |
| 493 | return T @ Rz90 |
| 494 | |
| 495 | |
| 496 | def transform_mesh(mesh_v, frame): |
no outgoing calls
no test coverage detected