//  [python]
def on_mouse_double_click(self, x, y):
        res = self._scene.camera.resolution
        fov_y = np.radians(self._scene.camera.fov[1] / 2.0)
        fov_x = fov_y * (res[0] / float(res[1]))
        half_fov = np.stack([fov_x, fov_y])

        right_top = np.tan(half_fov)
        right_top *= 1 - (1.0 / res)
        left_bottom = -right_top

        right, top = right_top
        left, bottom = left_bottom

        xy_vec = tu.grid_linspace(bounds=[[left, top], [right, bottom]], count=res).astype(np.float64)
        pixels = tu.grid_linspace(bounds=[[0, 0], [res[0] - 1, res[1] - 1]], count=res).astype(np.int64)
        assert xy_vec.shape == pixels.shape

        transform = self._scene.camera_transform
        vectors = tu.unitize(np.column_stack((xy_vec, -np.ones_like(xy_vec[:, :1]))))
        vectors = tf.transform_points(vectors, transform, translate=False)
        origins = (np.ones_like(vectors) * tf.translation_from_matrix(transform))

        indices = np.where(np.all(pixels == np.array([x, y]), axis=1))
        if len(indices) > 0 and len(indices[0]) > 0:
            pixel_id = indices[0][0]
            ray_origin = np.expand_dims(origins[pixel_id], 0)
            ray_direction = np.expand_dims(vectors[pixel_id], 0)
            # print(x, y, pixel_id, ray_origin, ray_direction)

            mesh = self._scene.geometry['geometry_0']

            locations, index_ray, index_tri = mesh.ray.intersects_location(
                ray_origins=ray_origin,
                ray_directions=ray_direction)

            if locations.size == 0:
                return

            ray_origins = np.tile(ray_origin, [locations.shape[0], 1])
            distances = np.linalg.norm(locations - ray_origins, axis=1)
            idx = np.argsort(distances)  # sort by disctances

            # color closest hit
            tri_color = mesh.visual.face_colors[index_tri[idx[0]]]
            if not np.alltrue(tri_color == [255, 0, 0, 255]):
                tri_color = [255, 0, 0, 255]
            else:
                # unselect triangle
                tri_color = [200, 200, 200, 255]

            mesh.visual.face_colors[index_tri[idx[0]]] = tri_color

            # collect clicked triangle ids
            tri_ids = np.where(np.all(mesh.visual.face_colors == [255, 0, 0, 255], axis=-1))[0]

            if len(tri_ids) >= self._settings_loader.min_triangles:
                # get center of triangles
                barycentric = mesh.triangles_center[tri_ids]
                joint_x = np.mean(barycentric[:, 0])
                joint_y = np.mean(barycentric[:, 1])
                joint_z = np.mean(barycentric[:, 2])
                joint = np.stack([joint_x, joint_y, joint_z])

                if 'joint_0' in self._scene.geometry:
                    self._scene.delete_geometry('joint_0')

                joint = np.expand_dims(joint, 0)
                joint = PointCloud(joint, process=False)
                self._scene.add_geometry(joint, geom_name='joint_0')

            if self.view['rays']:
                from trimesh import load_path
                ray_visualize = load_path(np.hstack((ray_origin, ray_origin + ray_direction)).reshape(-1, 2, 3))
                self._scene.add_geometry(ray_visualize, geom_name='cam_rays')

                # draw path where camera ray hits with mesh (only take 2 closest hits)
                path = np.hstack(locations[:2]).reshape(-1, 2, 3)
                ray_visualize = load_path(path)
                self._scene.add_geometry(ray_visualize, geom_name='cam_rays_hits')