code: def test_rotate_on_spot_pitch(self):
      N = 14
      eye = torch.rand(N, 3)
      at = torch.rand(N, 3)
      up = torch.rand(N, 3)
  
      R, T = look_at_view_transform(eye=eye, at=at, up=up)
  
      # Moving around the x axis looks down.
      angles = torch.FloatTensor([-radians(10), 0, 0])
      rotation = axis_angle_to_matrix(angles)
      R_rot, T_rot = rotate_on_spot(R, T, rotation)
      eye_rot, at_rot, up_rot = camera_to_eye_at_up(
          get_world_to_view_transform(R=R_rot, T=T_rot)
      )
      self.assertClose(eye, eye_rot, atol=1e-5)
  
      # A vector pointing left is unchanged
      left = torch.cross(up, at - eye, dim=-1)
      left_rot = torch.cross(up_rot, at_rot - eye_rot, dim=-1)
      self.assertClose(normalize(left), normalize(left_rot), atol=1e-5)
  
      # The camera has moved down
      fully_up = torch.cross(at - eye, left, dim=-1)
      fully_up_rot = torch.cross(at_rot - eye_rot, left_rot, dim=-1)
      agree = _batched_dotprod(
          torch.cross(fully_up, fully_up_rot, dim=1), left
      )
      self.assertGreater(agree.min(), 0)
  
file_path: pytorch3d/tests/test_camera_utils.py
imports: import unittest
  from math import radians
  import torch
  from pytorch3d.renderer.camera_utils import camera_to_eye_at_up, rotate_on_spot
  from pytorch3d.renderer.cameras import get_world_to_view_transform, look_at_view_transform, PerspectiveCameras
  from pytorch3d.transforms import axis_angle_to_matrix
  from torch.nn.functional import normalize
  from .common_testing import TestCaseMixin
label_desc: Use image node_id 4 for calling the TestCameraUtils obj's underlying member method code with example usage: obj.test_rotate_on_spot_pitch() without return types