From 316c28b86dbf3f688994a16869fe8295167dbd54 Mon Sep 17 00:00:00 2001
From: Valera <108022376+kekobka@users.noreply.github.com>
Date: Thu, 12 Jun 2025 22:55:58 +0700
Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=BB=D0=BE=D0=BC=D0=B0=D0=BB=20Ca?=
=?UTF-8?q?lculateVelocityOffset=20(=D0=BE=D0=BD=D0=BE=20=D0=B8=20=D0=BD?=
=?UTF-8?q?=D0=B5=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=BB=D0=BE)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Code/Utils/PhysicsExtensions.cs | 53 +++++++++++++++++++++++++--------
1 file changed, 41 insertions(+), 12 deletions(-)
diff --git a/Code/Utils/PhysicsExtensions.cs b/Code/Utils/PhysicsExtensions.cs
index 27aace7..b14b0a1 100644
--- a/Code/Utils/PhysicsExtensions.cs
+++ b/Code/Utils/PhysicsExtensions.cs
@@ -1,9 +1,33 @@
using Sandbox;
+using System;
+using System.Numerics;
namespace VeloX;
public static class PhysicsExtensions
{
+ public static Vector3 Transform( this Vector3 value, Quaternion rotation )
+ {
+ float x2 = rotation.X + rotation.X;
+ float y2 = rotation.Y + rotation.Y;
+ float z2 = rotation.Z + rotation.Z;
+
+ float wx2 = rotation.W * x2;
+ float wy2 = rotation.W * y2;
+ float wz2 = rotation.W * z2;
+ float xx2 = rotation.X * x2;
+ float xy2 = rotation.X * y2;
+ float xz2 = rotation.X * z2;
+ float yy2 = rotation.Y * y2;
+ float yz2 = rotation.Y * z2;
+ float zz2 = rotation.Z * z2;
+
+ return new Vector3(
+ value.x * (1.0f - yy2 - zz2) + value.y * (xy2 - wz2) + value.z * (xz2 + wy2),
+ value.x * (xy2 + wz2) + value.y * (1.0f - xx2 - zz2) + value.z * (yz2 - wx2),
+ value.x * (xz2 - wy2) + value.y * (yz2 + wx2) + value.z * (1.0f - xx2 - yy2)
+ );
+ }
///
/// Calculates the linear and angular velocities on the center of mass for an offset impulse.
///
@@ -22,21 +46,26 @@ public static class PhysicsExtensions
Vector3 linearVelocity = impulse / physObj.Mass;
- Vector3 centerOfMass = physObj.MassCenter;
- Vector3 relativePosition = position - centerOfMass;
- Vector3 torque = relativePosition.Cross( impulse );
+ Vector3 r = position - physObj.MassCenter;
- Rotation bodyRotation = physObj.Transform.Rotation;
- Vector3 localTorque = bodyRotation.Inverse * torque;
- Vector3 localInverseInertia = physObj.Inertia.Inverse;
+ // Calculate torque impulse in world frame: τ = r × impulse
+ Vector3 torqueImpulseWorld = r.Cross( impulse );
+ Rotation worldToLocal = physObj.Rotation.Inverse;
+ Vector3 torqueImpulseLocal = torqueImpulseWorld.Transform( worldToLocal );
- Vector3 localAngularVelocity = new(
- localTorque.x * localInverseInertia.x,
- localTorque.y * localInverseInertia.y,
- localTorque.z * localInverseInertia.z );
+ var InverseInertiaDiagLocal = physObj.Inertia.Inverse;
- return (linearVelocity, localAngularVelocity);
+ // Compute angular velocity change in rad/s (local frame)
+ Vector3 angularVelocityRadLocal = new(
+ InverseInertiaDiagLocal.x * torqueImpulseLocal.x,
+ InverseInertiaDiagLocal.y * torqueImpulseLocal.y,
+ InverseInertiaDiagLocal.z * torqueImpulseLocal.z
+ );
+ const float radToDeg = 180f / MathF.PI;
+ Vector3 angularVelocityDegLocal = angularVelocityRadLocal * radToDeg;
+
+ return (linearVelocity, angularVelocityDegLocal);
}
///
@@ -63,7 +92,7 @@ public static class PhysicsExtensions
Vector3 linearImpulse = impulse;
// 2. Calculate angular impulse (torque) from the offset force
- // τ = r × F (cross product of position relative to COM and force)
+ // τ = r * F (cross product of position relative to COM and force)
Vector3 centerOfMass = physObj.MassCenter;
Vector3 relativePosition = position - centerOfMass;
Vector3 worldAngularImpulse = relativePosition.Cross( impulse );