I'm familiar with OS.set*time*scale(), but I was curious if there is some simple way to apply time scaling to a single physics body like a RigidBody, without having to rewrite it's integration.

0 votes

I'm familiar with OS.set*time*scale(), but I was curious if there is some simple way to apply time scaling to a single physics body like a RigidBody, without having to rewrite it's integration.

I'm fairly sure it's going to either be duplicating all the integration in GDScript as an override, or add the feature to the source and create a fork of it. So just hoping someone might have some trick up their sleeve that I overlooked. X)

Maybe is just replicating this part in GDScript with the custom integrator(adds gravity and damps to velocity), I need to create some simple scenes to test.

https://github.com/godotengine/godot/blob/93ab45b6b5c4f8e0619e963156c983009d399a9d/servers/physics/body_sw.cpp#L524

I'll be looking at it too, let me know what you find.

I'm mostly tripped up by: `angular_velocity+=_inv_inertia_tensor.xform(torque)*p_step;`

Which is:

```
principal_inertia_axes_local = inertia_tensor.diagonalize().transposed();
principal_inertia_axes = get_transform().basis * principal_inertia_axes_local;
Basis tb = principal_inertia_axes;
Basis tbt = tb.transposed();
tb.scale(_inv_inertia);
_inv_inertia_tensor = tb * tbt;
```

And the inertia tensor: https://github.com/godotengine/godot/blob/93ab45b6b5c4f8e0619e963156c983009d399a9d/servers/physics/body_sw.cpp#L84

```
inertia_tensor.set_zero();
for (int i=0;i<get_shape_count();i++) {
const ShapeSW* shape=get_shape(i);
float area=get_shape_area(i);
float mass = area * this->mass / total_area;
Basis shape_inertia_tensor=shape->get_moment_of_inertia(mass).to_diagonal_matrix();
Transform shape_transform=get_shape_transform(i);
Basis shape_basis = shape_transform.basis.orthonormalized();
// NOTE: we don't take the scale of collision shapes into account when computing the inertia tensor!
shape_inertia_tensor = shape_basis * shape_inertia_tensor * shape_basis.transposed();
Vector3 shape_origin = shape_transform.origin - center_of_mass_local;
inertia_tensor += shape_inertia_tensor + (Basis()*shape_origin.dot(shape_origin)-shape_origin.outer(shape_origin))*mass;
}
```

I'm not very familiar with physics engines, so I'm not terribly confident about verifying results or debugging.

I was trying with GDScript and managed to replicate exact velocity -damp with custom integrator but scaling that is tricky because next steps quickly lower velocities at fixed damp, maybe everything needs to be faked to simulate slow motion with the script integrator.

The class Step_SW controls many things too

Here is the velocity integration part

https://github.com/godotengine/godot/blob/93ab45b6b5c4f8e0619e963156c983009d399a9d/servers/physics/step_sw.cpp#L272

- All categories
- Engine 12,488
- Projects 1,262
- Gossip 224

Right, but what you mean is making a custom integrator after all, I guess.

I don't know if other physics engines have that possibility or is all forced fake movement (highly probable).

And now thinking a bit more, maybe just affecting the step for linear and angular velocity calculations won't be enough, I need to see the default integrator, may do some 2d experiments.