From 1c208d6baa15d3e5bbb709418fb2c3549994a17f Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 8 Mar 2021 20:32:16 -0500 Subject: [PATCH] Fixes division by zero when 3d body does not have valid shape (3.2 only) Fixes #46738 by setting the default inertia to a valid value when there are no valid shapes for a 3d body. --- servers/physics/body_sw.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp index 70a51b5d58f3..23a7a3d7c741 100644 --- a/servers/physics/body_sw.cpp +++ b/servers/physics/body_sw.cpp @@ -53,13 +53,13 @@ void BodySW::_update_transform_dependant() { void BodySW::update_inertias() { - //update shapes and motions + // Update shapes and motions. switch (mode) { case PhysicsServer::BODY_MODE_RIGID: { - //update tensor for all shapes, not the best way but should be somehow OK. (inspired from bullet) + // Update tensor for all shapes, not the best way but should be somehow OK. (inspired from bullet) real_t total_area = 0; for (int i = 0; i < get_shape_count(); i++) { @@ -67,7 +67,7 @@ void BodySW::update_inertias() { total_area += get_shape_area(i); } - // We have to recompute the center of mass + // We have to recompute the center of mass. center_of_mass_local.zero(); for (int i = 0; i < get_shape_count(); i++) { @@ -75,15 +75,16 @@ void BodySW::update_inertias() { real_t mass = area * this->mass / total_area; - // NOTE: we assume that the shape origin is also its center of mass + // NOTE: we assume that the shape origin is also its center of mass. center_of_mass_local += mass * get_shape_transform(i).origin; } center_of_mass_local /= mass; - // Recompute the inertia tensor + // Recompute the inertia tensor. Basis inertia_tensor; inertia_tensor.set_zero(); + bool inertia_set = false; for (int i = 0; i < get_shape_count(); i++) { @@ -91,6 +92,8 @@ void BodySW::update_inertias() { continue; } + inertia_set = true; + const ShapeSW *shape = get_shape(i); real_t area = get_shape_area(i); @@ -108,7 +111,12 @@ void BodySW::update_inertias() { inertia_tensor += shape_inertia_tensor + (Basis() * shape_origin.dot(shape_origin) - shape_origin.outer(shape_origin)) * mass; } - // Compute the principal axes of inertia + // Set the inertia to a valid value when there are no valid shapes. + if (!inertia_set) { + inertia_tensor.set_diagonal(Vector3(1.0, 1.0, 1.0)); + } + + // Compute the principal axes of inertia. principal_inertia_axes_local = inertia_tensor.diagonalize().transposed(); _inv_inertia = inertia_tensor.get_main_diagonal().inverse();