Merge pull request #7807 from Goober5000/fix/moment_of_inertia

fix the collision moment of inertia rotation
This commit is contained in:
Goober5000 authored and GitHub committed 2026-10-01 20:02:11 -04:00
commit 80652b13ea
4 files changed
+42 -7

No files matched your search

+28
View File
@@ -192,6 +192,8 @@ float Min_radius_for_persistent_debris;
bool Zero_radius_explosions_skip_fireballs;
bool Render_insignias_as_decals;
bool Link_special_point_subsystems_to_destroyed_submodels;
bool Fix_density_moment_of_inertia;
bool Fix_collision_moment_of_inertia;
#ifdef WITH_DISCORD
@@ -1696,6 +1698,24 @@ void parse_mod_table(const char *filename)
stuff_boolean(&Link_special_point_subsystems_to_destroyed_submodels);
}
if (optional_string("$Fix density moment of inertia:")) {
stuff_boolean(&Fix_density_moment_of_inertia);
if (Fix_density_moment_of_inertia) {
mprintf(("Game Settings Table: Using fixed density moment of inertia (higher density makes a ship harder to rotate)\n"));
} else {
mprintf(("Game Settings Table: Using retail density moment of inertia (higher density makes a ship easier to rotate)\n"));
}
}
if (optional_string("$Fix collision moment of inertia:")) {
stuff_boolean(&Fix_collision_moment_of_inertia);
if (Fix_collision_moment_of_inertia) {
mprintf(("Game Settings Table: Using fixed collision moment of inertia (collision rotation will use the object's actual orientation)\n"));
} else {
mprintf(("Game Settings Table: Using retail collision moment of inertia (collision rotation will use the inverse of the object's orientation)\n"));
}
}
// end of options ----------------------------------------
// if we've been through once already and are at the same place, force a move
@@ -1980,10 +2000,15 @@ void mod_table_reset()
Zero_radius_explosions_skip_fireballs = false;
Render_insignias_as_decals = false;
Link_special_point_subsystems_to_destroyed_submodels = false;
Fix_density_moment_of_inertia = false;
Fix_collision_moment_of_inertia = false;
}
void mod_table_set_version_flags()
{
if (mod_supports_version(21, 0, 0)) {
Fix_density_moment_of_inertia = true;
}
if (mod_supports_version(22, 0, 0)) {
Fixed_turret_collisions = true;
Fixed_missile_detonation = true;
@@ -2012,4 +2037,7 @@ void mod_table_set_version_flags()
Zero_radius_explosions_skip_fireballs = true;
Render_insignias_as_decals = true;
}
if (mod_supports_version(26, 2, 0)) {
Fix_collision_moment_of_inertia = true;
}
}
+2
View File
@@ -212,6 +212,8 @@ extern float Min_radius_for_persistent_debris;
extern bool Zero_radius_explosions_skip_fireballs;
extern bool Render_insignias_as_decals;
extern bool Link_special_point_subsystems_to_destroyed_submodels;
extern bool Fix_density_moment_of_inertia;
extern bool Fix_collision_moment_of_inertia;
void mod_table_init();
void mod_table_post_process();
+8 -4
View File
@@ -19,6 +19,7 @@
#include "hud/hudshield.h"
#include "io/joy_ff.h"
#include "io/timer.h"
#include "mod_table/mod_table.h"
#include "network/multi.h"
#include "network/multi_interpolate.h"
#include "object/objcollide.h"
@@ -869,14 +870,17 @@ void calculate_ship_ship_collision_physics(collision_info_struct *ship_ship_hit_
//
static void get_I_inv (matrix* I_inv, matrix* I_inv_body, matrix* orient)
{
matrix Mtemp1, Mtemp2;
matrix orient_t;
// I_inv = (Rt)(I_inv_body)(R)
// This is opposite to what is commonly seen in books since we are rotating coordianates axes
// which is equivalent to rotating in the opposite direction (or transpose)
vm_matrix_x_matrix(&Mtemp1, I_inv_body, orient);
vm_copy_transpose(&Mtemp2, orient);
vm_matrix_x_matrix(I_inv, &Mtemp2, &Mtemp1);
vm_copy_transpose(&orient_t, orient);
if (Fix_collision_moment_of_inertia)
*I_inv = orient_t * (*I_inv_body) * (*orient);
else
*I_inv = (*orient) * (*I_inv_body) * orient_t; // retail multiplied in the opposite order
}
#define PLANET_DAMAGE_SCALE 4.0f
+4 -3
View File
@@ -6734,9 +6734,10 @@ void physics_ship_init(object *objp)
pi->I_body_inv = pm->moment_of_inertia;
// scale inverse moment of inertia value by inverse density
vm_vec_scale( &pi->I_body_inv.vec.rvec, 1/sinfo->density );
vm_vec_scale( &pi->I_body_inv.vec.uvec, 1/sinfo->density );
vm_vec_scale( &pi->I_body_inv.vec.fvec, 1/sinfo->density );
float moi_scale = Fix_density_moment_of_inertia ? 1/sinfo->density : sinfo->density; // retail scaled by density, not inverse density
vm_vec_scale( &pi->I_body_inv.vec.rvec, moi_scale );
vm_vec_scale( &pi->I_body_inv.vec.uvec, moi_scale );
vm_vec_scale( &pi->I_body_inv.vec.fvec, moi_scale );
pi->center_of_mass = pm->center_of_mass;
pi->side_slip_time_const = sinfo->damp;