|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import numpy as np |
|
import torch |
|
|
|
|
|
|
|
|
|
|
|
def rotate_camera_towards_depth(depth_tensor, turn_weight, width, height, h_fov=60, target_depth=1): |
|
|
|
target_depth_index = int(target_depth * depth_tensor.shape[0]) |
|
target_depth_values = depth_tensor[target_depth_index] |
|
max_depth_index = torch.argmax(target_depth_values).item() |
|
max_depth_index = (max_depth_index, target_depth_index) |
|
max_depth = target_depth_values[max_depth_index[0]].item() |
|
|
|
|
|
x, y = max_depth_index |
|
x_normalized = (x / (width - 1)) * 2 - 1 |
|
y_normalized = (y / (height - 1)) * 2 - 1 |
|
|
|
|
|
h_fov_rad = np.radians(h_fov) |
|
aspect_ratio = width / height |
|
v_fov_rad = h_fov_rad / aspect_ratio |
|
|
|
|
|
x_world = np.tan(h_fov_rad / 2) * max_depth * x_normalized |
|
y_world = np.tan(v_fov_rad / 2) * max_depth * y_normalized |
|
|
|
|
|
target_position = np.array([x_world, y_world, max_depth]) |
|
|
|
|
|
cam_position = np.array([0, 0, 0]) |
|
current_direction = np.array([0, 0, -1]) |
|
|
|
|
|
direction = target_position - cam_position |
|
direction = direction / np.linalg.norm(direction) |
|
|
|
|
|
axis = np.cross(current_direction, direction) |
|
axis = axis / np.linalg.norm(axis) |
|
angle = np.arcsin(np.linalg.norm(axis)) |
|
max_angle = np.pi * (0.1 / turn_weight) |
|
rotation_angle = np.clip(np.sign(np.cross(current_direction, direction)) * angle / turn_weight, -max_angle, max_angle) |
|
|
|
|
|
rotation_matrix = np.eye(3) + np.sin(rotation_angle) * np.array([ |
|
[0, -axis[2], axis[1]], |
|
[axis[2], 0, -axis[0]], |
|
[-axis[1], axis[0], 0] |
|
]) + (1 - np.cos(rotation_angle)) * np.outer(axis, axis) |
|
|
|
|
|
rotation_matrix_tensor = torch.from_numpy(rotation_matrix).float() |
|
|
|
|
|
rotation_matrix_tensor = rotation_matrix_tensor.unsqueeze(0) |
|
|
|
return rotation_matrix_tensor |
|
|
|
def rotation_matrix(axis, angle): |
|
axis = np.asarray(axis) |
|
axis = axis / np.linalg.norm(axis) |
|
a = np.cos(angle / 2.0) |
|
b, c, d = -axis * np.sin(angle / 2.0) |
|
aa, bb, cc, dd = a * a, b * b, c * c, d * d |
|
bc, ad, ac, ab, bd, cd = b * c, a * d, a * c, a * b, b * d, c * d |
|
return np.array([[aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac)], |
|
[2 * (bc - ad), aa + cc - bb - dd, 2 * (cd + ab)], |
|
[2 * (bd + ac), 2 * (cd - ab), aa + dd - bb - cc]]) |
|
|