try:
    from pyrender import (Mesh, OffscreenRenderer, PerspectiveCamera, Scene,
                          OrthographicCamera, Node, DirectionalLight,
                          PointLight)
    from pyrender.renderer import RenderFlags
except:
    pass
import numpy as np


def _rotation_mat_x(rad):
    cos = np.cos(rad)
    sin = np.sin(rad)
    return np.array([
        [1, 0, 0, 0],
        [0, cos, -sin, 0],
        [0, sin, cos, 0],
        [0, 0, 0, 1],
    ])


def _rotation_mat_y(rad):
    cos = np.cos(rad)
    sin = np.sin(rad)
    return np.array([
        [cos, 0, sin, 0],
        [0, 1, 0, 0],
        [-sin, 0, cos, 0],
        [0, 0, 0, 1],
    ])


def _rotation_mat_z(rad):
    cos = np.cos(rad)
    sin = np.sin(rad)
    return np.array([
        [cos, -sin, 0, 0],
        [sin, cos, 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, 1],
    ])


def render_mesh(trimesh,
                image_width=640,
                image_height=640,
                bg_color=[255, 255, 255],
                yfov=(np.pi / 2.0),
                camera_translation=[0, 0, 0],
                camera_rotation=[0, 0, 0, 1],
                camera_mag=1):
    mesh = Mesh.from_trimesh(trimesh, smooth=False)

    # camera_aspect_ratio = image_width / image_height
    # camera = PerspectiveCamera(yfov=yfov, aspectRatio=camera_aspect_ratio)
    camera = OrthographicCamera(camera_mag, camera_mag)

    camera_node = Node(camera=camera, translation=np.array([0, 0, 0]))
    camera_node.rotation = camera_rotation
    camera_node.translation = camera_translation

    light = DirectionalLight(intensity=10)
    light_node = Node(light=light, translation=np.array([0, 1, 0]))

    scene = Scene(bg_color=bg_color)
    scene.add(mesh)
    scene.add_node(camera_node)
    scene.add_node(light_node)

    r = OffscreenRenderer(viewport_width=image_width,
                          viewport_height=image_height)
    image, depth = r.render(scene)
    r.delete()
    return image


def render_point_cloud(points: np.ndarray,
                       colors: np.ndarray,
                       image_width=640,
                       image_height=640,
                       bg_color=[255, 255, 255],
                       yfov=(np.pi / 2.0),
                       camera_translation=[0, 0, 0],
                       camera_rotation=[0, 0, 0, 1],
                       camera_mag=1,
                       point_size=1):
    # camera_aspect_ratio = image_width / image_height
    # camera = PerspectiveCamera(yfov=yfov, aspectRatio=camera_aspect_ratio)
    camera = OrthographicCamera(camera_mag, camera_mag)
    mesh = Mesh.from_points(points, colors=colors)

    camera_node = Node(camera=camera, translation=np.array([0, 0, 0]))
    camera_node.rotation = camera_rotation
    camera_node.translation = camera_translation

    scene = Scene(bg_color=bg_color, ambient_light=[255, 255, 255])
    scene.add(mesh)
    scene.add_node(camera_node)

    r = OffscreenRenderer(viewport_width=image_width,
                          viewport_height=image_height,
                          point_size=point_size)
    image, depth = r.render(scene)
    r.delete()
    return image
