Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PhysicsServer error with rigid BodySetSpace() GodotPhysics #46738

Closed
Tracked by #45333
starwolfy opened this issue Mar 6, 2021 · 4 comments · Fixed by #46805
Closed
Tracked by #45333

PhysicsServer error with rigid BodySetSpace() GodotPhysics #46738

starwolfy opened this issue Mar 6, 2021 · 4 comments · Fixed by #46805

Comments

@starwolfy
Copy link

starwolfy commented Mar 6, 2021

Godot version:

3.2.3 mono official stable.

OS/device including version:

Windows 10 64 bit

Issue description:

When setting the space of a rigid body from a PhysicsServer a stream of a repetitive error occurs with GodotPhysics enabled:
ERROR: The axis Vector3 must be normalized. At: core/math/basis.cpp:980

Steps to reproduce in:

  1. Create a space
  2. Set space to active
  3. Create a body
  4. Set body space to space we created earlier.
  5. Enable GodotPhysics
  6. Watch "The axis Vector3 must be normalized" spam.

Minimal reproduction project:

godotBug.zip

@starwolfy
Copy link
Author

This also happens with GDScript




var defaultSpaceState : RID

func _ready():
	
	defaultSpaceState = PhysicsServer.space_create()
	PhysicsServer.space_set_active(defaultSpaceState, true)
	
	var bodyRID : RID = PhysicsServer.body_create(PhysicsServer.BODY_MODE_RIGID,false)
	
	PhysicsServer.body_set_space(bodyRID, defaultSpaceState)
	

@starwolfy starwolfy changed the title PhysicsServer error with rigid BodySetSpace() C# & GodotPhysics PhysicsServer error with rigid BodySetSpace() GodotPhysics Mar 6, 2021
@pouleyKetchoupp
Copy link
Contributor

This also occurs with any Rigidbody node with all CollisionShape nodes disabled, or no CollisionShape at all.
It's not a common use case (the body doesn't collide with anything and just falls), but it can be supported by the physics simulation and can be useful for special cases (particles with advanced physics or joint attachments).

Note for junior job:
This is due to how inertia is calculated for a body with no valid shape in Body3DSW::update_inertias():

// Recompute the inertia tensor
Basis inertia_tensor;
inertia_tensor.set_zero();
for (int i = 0; i < get_shape_count(); i++) {
if (is_shape_disabled(i)) {
continue;
}
const Shape3DSW *shape = get_shape(i);
real_t area = get_shape_area(i);
real_t 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;
}

inertia_tensor is initialized to zero and inertias are added from valid shapes (this is correct), but in case there's no valid shape at all it should be set to a valid default inertia with inertia_tensor.set_diagonal(Vector3(1.0, 1.0, 1.0)); to avoid divisions by zero during the simulation.

@Bhu1-V
Copy link
Contributor

Bhu1-V commented Mar 8, 2021

hlo Current master branch has some changes in the PhysicsServer so the above code need some changes to run

var defaultSpaceState : RID

func _ready():
	
	defaultSpaceState = PhysicsServer3D.space_create()
	PhysicsServer3D.space_set_active(defaultSpaceState, true)
	
	var bodyRID : RID = PhysicsServer3D.body_create()
	
	PhysicsServer3D.body_set_space(bodyRID, defaultSpaceState)

as u can see body_create() got different syntax and also this code is no longer going to update_inertia(). atleast thats what I'm thinking . and I really don't known what went wrong.

@pouleyKetchoupp
Copy link
Contributor

@Bhu1-V Your sample code works for me on master, I'm able to reproduce the issue. It calls update_inertias() on the next physics step with this callstack:

 	godot.windows.tools.64.exe!Body3DSW::update_inertias() Line 107	C++
 	godot.windows.tools.64.exe!Space3DSW::setup() Line 1165	C++
 	godot.windows.tools.64.exe!Step3DSW::step(Space3DSW * p_space, float p_delta, int p_iterations) Line 147	C++
 	godot.windows.tools.64.exe!PhysicsServer3DSW::step(float p_step) Line 1354	C++
 	godot.windows.tools.64.exe!PhysicsServer3DWrapMT::step(float p_step) Line 76	C++
 	godot.windows.tools.64.exe!Main::iteration() Line 2472	C++
 	godot.windows.tools.64.exe!OS_Windows::run() Line 622	C++

The only difference is body_create creates a body with BODY_MODE_RIGID by default, and body_set_mode needs to be called separately for making it static or kinematic.

likeich added a commit to likeich/godot that referenced this issue Mar 9, 2021
Fixes godotengine#46738 by setting the default inertia to a valid value when there are no valid shapes for a 3d body.
Changed the comment style for the update_inertias method as well.
likeich added a commit to likeich/godot that referenced this issue Mar 9, 2021
Fixes godotengine#46738 by setting the default inertia to a valid value when there are no valid shapes for a 3d body.
@akien-mga akien-mga added this to the 4.0 milestone Mar 9, 2021
lekoder pushed a commit to KoderaSoftwareUnlimited/godot that referenced this issue Apr 24, 2021
Fixes godotengine#46738 by setting the default inertia to a valid value when there are no valid shapes for a 3d body.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants