| 25 | class GaussianModel: |
| 26 | |
| 27 | def setup_functions(self): |
| 28 | def build_covariance_from_scaling_rotation(scaling, scaling_modifier, rotation): |
| 29 | L = build_scaling_rotation(scaling_modifier * scaling, rotation) |
| 30 | actual_covariance = L.transpose(1, 2) @ L |
| 31 | symm = strip_symmetric(actual_covariance) |
| 32 | return symm |
| 33 | |
| 34 | def build_covariance_from_scaling_rotation_4d(scaling, scaling_modifier, rotation_l, rotation_r, dt=0.0): |
| 35 | L = build_scaling_rotation_4d(scaling_modifier * scaling, rotation_l, rotation_r) |
| 36 | actual_covariance = L @ L.transpose(1, 2) |
| 37 | cov_11 = actual_covariance[:,:3,:3] |
| 38 | cov_12 = actual_covariance[:,0:3,3:4] |
| 39 | cov_t = actual_covariance[:,3:4,3:4] |
| 40 | current_covariance = cov_11 - cov_12 @ cov_12.transpose(1, 2) / cov_t |
| 41 | symm = strip_symmetric(current_covariance) |
| 42 | if dt.shape[1] > 1: |
| 43 | mean_offset = (cov_12.squeeze(-1) / cov_t.squeeze(-1))[:, None, :] * dt[..., None] |
| 44 | mean_offset = mean_offset[..., None] # [num_pts, num_time, 3, 1] |
| 45 | else: |
| 46 | mean_offset = cov_12.squeeze(-1) / cov_t.squeeze(-1) * dt |
| 47 | return symm, mean_offset.squeeze(-1) |
| 48 | |
| 49 | self.scaling_activation = torch.exp |
| 50 | self.scaling_inverse_activation = torch.log |
| 51 | |
| 52 | if not self.rot_4d: |
| 53 | self.covariance_activation = build_covariance_from_scaling_rotation |
| 54 | else: |
| 55 | self.covariance_activation = build_covariance_from_scaling_rotation_4d |
| 56 | |
| 57 | self.opacity_activation = torch.sigmoid |
| 58 | self.inverse_opacity_activation = inverse_sigmoid |
| 59 | |
| 60 | self.rotation_activation = torch.nn.functional.normalize |
| 61 | |
| 62 | |
| 63 | def __init__(self, sh_degree : int, gaussian_dim : int = 3, time_duration: list = [-0.5, 0.5], rot_4d: bool = False, force_sh_3d: bool = False, sh_degree_t : int = 0): |