File size: 2,069 Bytes
b6a9b6d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import numpy as np
from scipy.spatial.transform import Rotation 
import bpy


def setup_camera(cam_location, cam_rot=(0, 0, 0)):
    bpy.ops.object.camera_add(location=cam_location, rotation=cam_rot)
    camera = bpy.context.active_object
    camera.rotation_mode = 'XYZ'
    bpy.data.scenes["Scene"].camera = camera
    scene = bpy.context.scene
    camera.data.sensor_height = (
        camera.data.sensor_width * scene.render.resolution_y / scene.render.resolution_x
    )
    for area in bpy.context.screen.areas:
        if area.type == "VIEW_3D":
            area.spaces.active.region_3d.view_perspective = "CAMERA"
            break
    cam_info_ng = bpy.data.node_groups.get("nodegroup_active_cam_info")
    if cam_info_ng is not None:
        cam_info_ng.nodes["Object Info"].inputs["Object"].default_value = camera
    return camera


def convert_sphere_to_xyz(dist, elevation, azimuth):
    """
    Convert spherical to cartesian coordinates. Assume camera is always looking at origin.
    """
    elevation_rad = elevation * np.pi / 180.0
    azimuth_rad = azimuth * np.pi / 180.0
    cam_pos_x = dist * np.sin(elevation_rad) * np.cos(azimuth_rad)
    cam_pos_y = dist * np.sin(elevation_rad) * np.sin(azimuth_rad)
    cam_pos_z = dist * np.cos(elevation_rad)
    # rotation
    gaze_direction = -np.array([cam_pos_x, cam_pos_y, cam_pos_z])
    R_look_at = look_at_rotation_matrix(gaze_direction)
    cam_rot_x, cam_rot_y, cam_rot_z = rotation_matrix_to_euler_angles(R_look_at)
    return [cam_pos_x, cam_pos_y, cam_pos_z, cam_rot_x, cam_rot_y, cam_rot_z]

def look_at_rotation_matrix(gaze_direction, world_up=(0,0,1)):
    forward = gaze_direction / np.linalg.norm(gaze_direction)
    right = np.cross(forward, world_up)
    right /= np.linalg.norm(right)
    up = np.cross(right, forward)
    up /= np.linalg.norm(up)
    R_look_at = np.array([right, up, -forward]).T
    return R_look_at

def rotation_matrix_to_euler_angles(R):  
    r =  Rotation.from_matrix(R)
    angles = r.as_euler("xyz", degrees=False)

    return angles[0], angles[1], angles[2]