Skip to content

Commit 4b10b64

Browse files
M1thieuclaude
andcommitted
feat(physics): add rigid-body rotation tracking (entity-based)
Addresses erematorg#145 (partial - entity backend only) **SCOPE**: Entity-based rigid body rotation for non-continuum objects (cameras, UI elements, large non-deformable bodies). Continuum matter will use MPM (Material Point Method) when implemented. **Added:** - MomentOfInertia component (rigid body inertia) - AppliedTorque component (torque application) - integrate_torques system (τ = I·α integration) - RotationalWorkEvent (feeds energy ledger) - Helper functions: calculate_angular_momentum, calculate_rotational_kinetic_energy - ForcesDiagnostics now tracks angular momentum + rotational KE - Tests for all rotational physics formulas **Architecture:** - Entity backend: Uses components (MomentOfInertia, AppliedTorque) - MPM backend (future): Will compute L = Σ(r × m·v) from particles - Both backends feed same energy ledger for unified conservation **TODO (MPM):** - MPM particle-based angular momentum computation - MPM rotational work tracking from grid interactions - Aggregate diagnostics across both backends Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent e2db7bc commit 4b10b64

3 files changed

Lines changed: 449 additions & 13 deletions

File tree

crates/energy/src/conservation.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use bevy::prelude::*;
2-
use forces::prelude::WorkDoneEvent;
2+
use forces::prelude::{RotationalWorkEvent, WorkDoneEvent};
33

44
/// Enum representing different types of energy
55
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Component, Reflect)]
@@ -297,6 +297,34 @@ pub fn track_work_from_forces(
297297
}
298298
}
299299

300+
/// System to track rotational work done by torques and record in energy balance
301+
pub fn track_rotational_work_from_torques(
302+
mut work_events: MessageReader<RotationalWorkEvent>,
303+
mut query: Query<&mut EnergyBalance>,
304+
time: Res<Time>,
305+
) {
306+
for event in work_events.read() {
307+
if let Ok(mut ledger) = query.get_mut(event.entity) {
308+
// Same logic as linear work: positive work = energy input, negative = output
309+
let (transaction_type, source, destination) = if event.work > 0.0 {
310+
(TransactionType::Input, None, Some(event.entity))
311+
} else {
312+
(TransactionType::Output, Some(event.entity), None)
313+
};
314+
315+
ledger.record_transaction(EnergyTransaction {
316+
transaction_type,
317+
amount: event.work.abs(),
318+
source,
319+
destination,
320+
timestamp: time.elapsed_secs(),
321+
transfer_rate: event.work.abs() / time.delta_secs().max(f32::EPSILON),
322+
duration: time.delta_secs(),
323+
});
324+
}
325+
}
326+
}
327+
300328
/// Plugin to manage energy conservation systems
301329
pub struct EnergyConservationPlugin;
302330

@@ -319,7 +347,8 @@ impl Plugin for EnergyConservationPlugin {
319347
(
320348
initialize_energy_balance,
321349
ApplyDeferred,
322-
track_work_from_forces.after(forces::PhysicsSet::ApplyForces),
350+
(track_work_from_forces, track_rotational_work_from_torques)
351+
.after(forces::PhysicsSet::ApplyForces),
323352
)
324353
.chain(),
325354
);

crates/forces/src/core/mod.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ pub mod prelude {
1515

1616
// Re-export from newton_laws module
1717
pub use crate::core::newton_laws::{
18-
AppliedForce, Distance, ForceImpulse, ForcesDiagnostics, ForcesDiagnosticsPlugin,
19-
IntegratorKind, Mass, NewtonLawsPlugin, Norm, PairedForce, PairedForceInteraction,
20-
Velocity, WorkDoneEvent, calculate_kinetic_energy, calculate_momentum,
21-
integrate_newton_second_law, integrate_positions_symplectic_euler,
18+
AppliedForce, AppliedTorque, Distance, ForceImpulse, ForcesDiagnostics,
19+
ForcesDiagnosticsPlugin, IntegratorKind, Mass, MomentOfInertia, NewtonLawsPlugin, Norm,
20+
PairedForce, PairedForceInteraction, RotationalWorkEvent, Velocity, WorkDoneEvent,
21+
calculate_angular_momentum, calculate_kinetic_energy, calculate_momentum,
22+
calculate_rotational_kinetic_energy, calculate_torque_from_force,
23+
integrate_newton_second_law, integrate_positions_symplectic_euler, integrate_torques,
2224
update_forces_diagnostics,
2325
};
2426
}

0 commit comments

Comments
 (0)