+1 vote

I'm familiar with OS.settimescale(), 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.

asked Jan 14, 2017 in Engine by avencherus (4,811 points)

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.

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

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.