106 double massKg()
const {
return mass_kg_; }
114 mass_kg_ = (mass_kg > 0.0) ? mass_kg : 1.0;
115 inv_mass_ = 1.0 / mass_kg_;
140 void position(
double* x_m,
double* y_m,
double* z_m)
const {
142 *x_m = position_m_.x;
145 *y_m = position_m_.y;
148 *z_m = position_m_.z;
169 linear_velocity_mps_ = velocity_mps;
188 *vx_mps = linear_velocity_mps_.x;
191 *vy_mps = linear_velocity_mps_.y;
194 *vz_mps = linear_velocity_mps_.z;
206 angular_velocity_radps_ = angular_velocity_radps;
225 *wx_radps = angular_velocity_radps_.x;
228 *wy_radps = angular_velocity_radps_.y;
231 *wz_radps = angular_velocity_radps_.z;
239 body_inertia_tensor_ = inertia;
240 inv_body_inertia_tensor_ = inertia.
inverse();
252 return material_ ? &(*material_) :
nullptr;
259 void setMaterialId(std::int32_t material_id) { material_id_ = material_id; }
293 aerodynamic_geometry_ = geometry;
297 return aerodynamic_geometry_ ? &(*aerodynamic_geometry_) :
nullptr;
304 if (!aerodynamic_geometry_) {
330 if (!aerodynamic_geometry_) {
335 if (axis_local.
isZero()) {
339 aerodynamic_geometry_->cylinder_axis_local = axis_local;
368 if (!aerodynamic_geometry_)
375 switch (geometry.
shape) {
377 const double radius_m = std::max(0.0, geometry.
radius_m);
378 return 3.14159265358979323846 * radius_m * radius_m;
390 velocity_direction = orientation_.inverse().rotate(velocity_direction);
393 return std::abs(velocity_direction.
x) * dims.
y * dims.
z +
394 std::abs(velocity_direction.
y) * dims.
x * dims.
z +
395 std::abs(velocity_direction.
z) * dims.
x * dims.
y;
398 const double radius_m = std::max(0.0, geometry.
radius_m);
400 if (radius_m <= 0.0 || length_m <= 0.0) {
404 const Vector3 velocity_direction_world =
408 if (cylinder_axis_local.
isZero()) {
412 const Vector3 velocity_direction_local =
413 orientation_.inverse().rotate(velocity_direction_world);
414 const double axis_alignment =
415 std::abs(velocity_direction_local.
dot(cylinder_axis_local));
416 const double side_alignment =
417 std::sqrt(std::max(0.0, 1.0 - axis_alignment * axis_alignment));
419 const double endcap_area_m2 =
420 3.14159265358979323846 * radius_m * radius_m * axis_alignment;
421 const double side_area_m2 = 2.0 * radius_m * length_m * side_alignment;
422 return endcap_area_m2 + side_area_m2;
449 const Vector3 r = world_point_m - position_m_;
450 accumulated_torque_nm_ += r.
cross(force_n);
463 double py_m,
double pz_m) {
491 const Vector3& gravity_mps2,
double linear_damping_per_s,
492 double angular_damping_per_s) {
493 if (flags_.is_kinematic) {
498 Vector3 total_force = accumulated_force_n_;
499 if (flags_.enable_gravity) {
500 total_force += gravity_mps2 * mass_kg_;
503 const Vector3 linear_accel = total_force * inv_mass_;
520 const double linear_damp = std::max(0.0, 1.0 - linear_damping_per_s * dt_s);
521 linear_velocity_mps_ *= linear_damp;
524 inv_body_inertia_tensor_ * accumulated_torque_nm_;
529 const double angular_damp =
530 std::max(0.0, 1.0 - angular_damping_per_s * dt_s);
531 angular_velocity_radps_ *= angular_damp;
537 double mass_kg_{1.0};
538 double inv_mass_{1.0};
540 Vector3 position_m_{};
541 Quaternion orientation_{};
542 Vector3 linear_velocity_mps_{};
543 Vector3 angular_velocity_radps_{};
545 Vector3 accumulated_force_n_{};
546 Vector3 accumulated_torque_nm_{};
552 std::optional<Material> material_{};
553 std::int32_t material_id_{0};
554 std::uint32_t collision_layer_bits_{0xFFFFFFFFu};
555 std::uint32_t collision_mask_bits_{0xFFFFFFFFu};
556 std::optional<AerodynamicGeometry> aerodynamic_geometry_{};
void applyForce(const Vector3 &force_n)
Adds force at center of mass in newtons.
Definition rigid_body.hpp:431
void setPosition(double x_m, double y_m, double z_m)
Sets world-space position in meters from scalar components.
Definition rigid_body.hpp:131
void applyForce(double fx_n, double fy_n, double fz_n)
Adds force at center of mass in newtons from scalar components.
Definition rigid_body.hpp:438
void clearAccumulators()
Clears accumulated force and torque buffers.
Definition rigid_body.hpp:468
void setAerodynamicGeometry(const AerodynamicGeometry &geometry)
Sets optional aerodynamic geometry metadata.
Definition rigid_body.hpp:292
void setAngularVelocity(const Vector3 &angular_velocity_radps)
Sets world angular velocity in radians per second.
Definition rigid_body.hpp:205
void setBodyInertiaTensor(const Matrix3 &inertia)
Sets body-frame inertia tensor and cached inverse tensor.
Definition rigid_body.hpp:238
void linearVelocity(double *vx_mps, double *vy_mps, double *vz_mps) const
Gets world linear velocity in meters per second via pointers.
Definition rigid_body.hpp:186
void applyForceAtPoint(const Vector3 &force_n, const Vector3 &world_point_m)
Adds force at world-space point, accumulating both force and torque.
Definition rigid_body.hpp:447
const Vector3 & angularVelocity() const
Returns world angular velocity in radians per second.
Definition rigid_body.hpp:199
std::uint32_t collisionMask() const
Gets broad-phase collision mask bits.
Definition rigid_body.hpp:289
void angularVelocity(double *wx_radps, double *wy_radps, double *wz_radps) const
Gets world angular velocity in radians per second via pointers.
Definition rigid_body.hpp:223
const Material * material() const
Gets material if configured, otherwise returns null.
Definition rigid_body.hpp:251
void position(double *x_m, double *y_m, double *z_m) const
Gets world-space position in meters via scalar output pointers.
Definition rigid_body.hpp:140
const AerodynamicGeometry * aerodynamicGeometry() const
Gets aerodynamic geometry if configured, otherwise returns null.
Definition rigid_body.hpp:296
CylinderAxis
Principal axis selection for cylindrical aerodynamic geometry.
Definition rigid_body.hpp:47
@ kX
Local +X axis.
Definition rigid_body.hpp:49
@ kY
Local +Y axis.
Definition rigid_body.hpp:51
@ kZ
Local +Z axis.
Definition rigid_body.hpp:53
const BodyFlags & flags() const
Const access to runtime body flags.
Definition rigid_body.hpp:246
double dragReferenceAreaM2(const Vector3 &velocity_world) const
Computes effective drag reference area for current geometry and motion direction.
Definition rigid_body.hpp:367
void setMassKg(double mass_kg)
Sets mass in kilograms.
Definition rigid_body.hpp:113
BodyFlags & flags()
Mutable access to runtime body flags.
Definition rigid_body.hpp:244
void integrate(double dt_s, IntegrationMethod method, const Vector3 &gravity_mps2, double linear_damping_per_s, double angular_damping_per_s)
Advances translational and rotational state by one fixed timestep.
Definition rigid_body.hpp:490
const Matrix3 & bodyInertiaTensor() const
Returns inertia tensor in body frame.
Definition rigid_body.hpp:236
const Vector3 & linearVelocity() const
Returns world linear velocity in meters per second.
Definition rigid_body.hpp:163
void setMaterial(const Material &material)
Sets optional physical material properties.
Definition rigid_body.hpp:249
void setCollisionLayer(std::uint32_t layer_bits)
Sets broad-phase collision layer bits for this body.
Definition rigid_body.hpp:271
double massKg() const
Returns mass in kilograms.
Definition rigid_body.hpp:106
void setLinearVelocity(double vx_mps, double vy_mps, double vz_mps)
Sets world linear velocity in meters per second from scalars.
Definition rigid_body.hpp:177
void setCylinderAxisWorld(const Vector3 &axis_world)
Sets cylinder axis from world-space direction.
Definition rigid_body.hpp:329
void setLinearVelocity(const Vector3 &velocity_mps)
Sets world linear velocity in meters per second.
Definition rigid_body.hpp:168
void setOrientation(const Quaternion &orientation)
Sets body orientation quaternion.
Definition rigid_body.hpp:158
void setCollisionMask(std::uint32_t mask_bits)
Sets broad-phase collision mask bits for this body.
Definition rigid_body.hpp:283
std::int32_t materialId() const
Gets numeric material identifier used by world interaction tables.
Definition rigid_body.hpp:265
std::uint32_t collisionLayer() const
Gets broad-phase collision layer bits.
Definition rigid_body.hpp:277
void applyForceAtPoint(double fx_n, double fy_n, double fz_n, double px_m, double py_m, double pz_m)
Adds force at world-space point from scalar components.
Definition rigid_body.hpp:462
void setCylinderAxisLocal(CylinderAxis axis)
Sets cylinder axis in local coordinates via canonical enum axis.
Definition rigid_body.hpp:303
void setCylinderAxisWorld(double x, double y, double z)
Sets cylinder axis from world-space scalar direction components.
Definition rigid_body.hpp:348
void setMaterialId(std::int32_t material_id)
Sets numeric material identifier used by world interaction tables.
Definition rigid_body.hpp:259
void setAngularVelocity(double wx_radps, double wy_radps, double wz_radps)
Sets world angular velocity in radians per second from scalars.
Definition rigid_body.hpp:214
const Quaternion & orientation() const
Returns body orientation as a unit quaternion.
Definition rigid_body.hpp:153
double inverseMass() const
Returns inverse mass in 1/kg.
Definition rigid_body.hpp:108
RigidBody(double mass_kg=1.0)
Constructs a rigid body with a sanitized positive mass.
Definition rigid_body.hpp:103
void setPosition(const Vector3 &position_m)
Sets world-space position in meters.
Definition rigid_body.hpp:124
const Vector3 & position() const
Returns world position in meters.
Definition rigid_body.hpp:119
IntegrationMethod
Integration strategy used for rigid body state updates.
Definition rigid_body.hpp:22
@ kExplicitEuler
Position-first explicit Euler integration.
Definition rigid_body.hpp:26
@ kSemiImplicitEuler
Velocity-first (symplectic) Euler integration.
Definition rigid_body.hpp:24
@ kRK2
Second-order midpoint (RK2) integration.
Definition rigid_body.hpp:28
Definition body_flags.hpp:9
static void integrateAngular(Quaternion &orientation, const Vector3 &angularVelocity, double dt) noexcept
Definition integrators.hpp:53
static void integrateLinearExplicit(Vector3 &position, Vector3 &velocity, const Vector3 &acceleration, double dt) noexcept
Definition integrators.hpp:41
static void integrateLinear(Vector3 &position, Vector3 &velocity, const Vector3 &acceleration, double dt) noexcept
Definition integrators.hpp:31
static void integrateLinearRK2(Vector3 &position, Vector3 &velocity, const Vector3 &acceleration, double dt) noexcept
Definition integrators.hpp:74
static void integrateAngularVelocity(Vector3 &angularVelocity, const Vector3 &angularAcceleration, double dt) noexcept
Definition integrators.hpp:65
Contact material parameters for collision response.
Definition material.hpp:20
3x3 matrix type used for rotations and inertia-tensor operations.
Definition matrix.hpp:27
static constexpr Matrix3 identity() noexcept
Definition matrix.hpp:38
Matrix3 inverse() const noexcept
Definition matrix.hpp:154
Unit-quaternion rotation representation and rotation algebra helpers.
Definition quaternion.hpp:25
Geometric metadata used to estimate drag reference area.
Definition rigid_body.hpp:63
Shape
Primitive shape model used for reference-area estimation.
Definition rigid_body.hpp:65
@ kBox
Box model parameterized by box_dimensions_m.
Definition rigid_body.hpp:71
@ kCustom
Use only explicit caller-provided area (no shape inference).
Definition rigid_body.hpp:67
@ kCylinder
Cylinder model parameterized by radius, length, and axis.
Definition rigid_body.hpp:73
@ kSphere
Sphere model parameterized by radius_m.
Definition rigid_body.hpp:69
double reference_area_m2
Explicit area override in square meters.
Definition rigid_body.hpp:84
double radius_m
Sphere/cylinder radius in meters.
Definition rigid_body.hpp:87
Vector3 box_dimensions_m
Box dimensions (x, y, z) in meters.
Definition rigid_body.hpp:90
Shape shape
Selected shape model.
Definition rigid_body.hpp:77
Vector3 cylinder_axis_local
Cylinder principal axis expressed in local body coordinates.
Definition rigid_body.hpp:96
double cylinder_length_m
Cylinder length in meters along cylinder_axis_local.
Definition rigid_body.hpp:93
3D vector utility used throughout JSim physics.
Definition vector.hpp:22
static constexpr Vector3 unitY() noexcept
Returns the +Y basis vector.
Definition vector.hpp:394
Vector3 normalized() const noexcept
Returns the normalized direction vector.
Definition vector.hpp:119
Vector3 cross(const Vector3 &o) const noexcept
Returns cross product with o.
Definition vector.hpp:172
double z
Z component.
Definition vector.hpp:28
static constexpr Vector3 unitX() noexcept
Returns the +X basis vector.
Definition vector.hpp:392
static constexpr Vector3 unitZ() noexcept
Returns the +Z basis vector.
Definition vector.hpp:396
constexpr double dot(const Vector3 &o) const noexcept
Returns dot product with o.
Definition vector.hpp:168
static constexpr Vector3 zero() noexcept
Returns the zero vector.
Definition vector.hpp:360
double x
X component.
Definition vector.hpp:24
constexpr bool isZero(double eps=1e-12) const noexcept
Checks whether the vector is near zero magnitude.
Definition vector.hpp:128
double y
Y component.
Definition vector.hpp:26