Ensure view matrix is not computed more than it needs to be

This commit is contained in:
Grant Sanderson 2023-01-31 12:20:25 -08:00
parent 2d0bdfbdb6
commit 424db4b3e4

View file

@ -29,6 +29,9 @@ class CameraFrame(Mobject):
):
super().__init__(**kwargs)
self.uniforms["orientation"] = Rotation.identity().as_quat()
self.uniforms["fovy"] = fovy
self.view_matrix = np.identity(4)
self.default_orientation = Rotation.identity()
@ -36,8 +39,10 @@ class CameraFrame(Mobject):
self.set_width(frame_shape[0], stretch=True)
self.set_height(frame_shape[1], stretch=True)
self.move_to(center_point)
self.uniforms["orientation"] = Rotation.identity().as_quat()
self.uniforms["fovy"] = fovy
def note_changed_data(self, recurse_up: bool = True):
super().note_changed_data(recurse_up)
self.get_view_matrix(refresh=True)
def set_orientation(self, rotation: Rotation):
self.uniforms["orientation"][:] = rotation.as_quat()
@ -77,20 +82,32 @@ class CameraFrame(Mobject):
def get_inverse_camera_rotation_matrix(self):
return self.get_orientation().as_matrix().T
def get_view_matrix(self):
def get_view_matrix(self, refresh=False):
"""
Returns a 4x4 for the affine transformation mapping a point
into the camera's internal coordinate system
"""
shift = Matrix44.from_translation(-self.get_center()).T
rotation = Matrix44.from_quaternion(self.uniforms["orientation"]).T
scale = Matrix44(np.identity(3) / self.get_scale())
self.view_matrix[:] = shift * rotation * scale
if refresh:
shift = np.identity(4)
rotation = np.identity(4)
scale = np.identity(4)
shift[:3, 3] = -self.get_center()
rotation[:3, :3] = self.get_inverse_camera_rotation_matrix()
scale[:3, :3] /= self.get_scale()
self.view_matrix = np.dot(scale, np.dot(rotation, shift))
return self.view_matrix
def get_inv_view_matrix(self):
return np.linalg.inv(self.get_view_matrix())
def interpolate(self, *args, **kwargs):
super().interpolate(*args, **kwargs)
self.get_view_matrix(refresh=True)
@Mobject.affects_data
def rotate(self, angle: float, axis: np.ndarray = OUT, **kwargs):
rot = Rotation.from_rotvec(angle * normalize(axis))
self.set_orientation(rot * self.get_orientation())