| | | 1 | | //======================================================================= |
| | | 2 | | // MeshSurfaceMassProperties.cs |
| | | 3 | | //======================================================================= |
| | | 4 | | // MIT License, Copyright (c) 2026-present David Oravsky (mrdav30) |
| | | 5 | | // See LICENSE file in the project root for full license information. |
| | | 6 | | //======================================================================= |
| | | 7 | | |
| | | 8 | | using FixedMathSharp; |
| | | 9 | | using FixedMathSharp.Geometry; |
| | | 10 | | using System; |
| | | 11 | | |
| | | 12 | | namespace Gravitas.Colliders; |
| | | 13 | | |
| | | 14 | | /// <summary> |
| | | 15 | | /// Stores deterministic uniform thin-shell mass properties for scaled mesh triangles. |
| | | 16 | | /// </summary> |
| | | 17 | | public readonly struct MeshSurfaceMassProperties |
| | | 18 | | { |
| | | 19 | | internal MeshSurfaceMassProperties( |
| | | 20 | | Fixed64 area, |
| | | 21 | | Vector3d centerOfMass, |
| | | 22 | | Vector3d inertiaReferencePoint, |
| | | 23 | | Fixed3x3 unitMassInertiaTensor) |
| | | 24 | | { |
| | 427 | 25 | | Area = area; |
| | 427 | 26 | | CenterOfMass = centerOfMass; |
| | 427 | 27 | | InertiaReferencePoint = inertiaReferencePoint; |
| | 427 | 28 | | UnitMassInertiaTensor = unitMassInertiaTensor; |
| | 427 | 29 | | } |
| | | 30 | | |
| | | 31 | | /// <summary>Gets the scaled triangle surface area represented by this shell.</summary> |
| | | 32 | | public Fixed64 Area { get; } |
| | | 33 | | |
| | | 34 | | /// <summary>Gets the shell center of mass in scaled mesh-local coordinates.</summary> |
| | | 35 | | public Vector3d CenterOfMass { get; } |
| | | 36 | | |
| | | 37 | | /// <summary>Gets the scaled mesh-local point about which the cached unit tensor is expressed.</summary> |
| | | 38 | | public Vector3d InertiaReferencePoint { get; } |
| | | 39 | | |
| | | 40 | | /// <summary>Gets the unit-mass thin-shell inertia tensor about <see cref="InertiaReferencePoint"/>.</summary> |
| | | 41 | | public Fixed3x3 UnitMassInertiaTensor { get; } |
| | | 42 | | |
| | | 43 | | /// <summary>Calculates shell inertia for the supplied mass about a scaled mesh-local reference point.</summary> |
| | | 44 | | public Fixed3x3 CalculateInertiaTensor(Fixed64 mass, Vector3d localReferencePoint) |
| | | 45 | | { |
| | 122 | 46 | | Fixed3x3 referenceTensor = UnitMassInertiaTensor * mass; |
| | 122 | 47 | | Fixed3x3 centerTensor = InertiaTensorMath.SubtractParallelAxisTensor( |
| | 122 | 48 | | referenceTensor, |
| | 122 | 49 | | mass, |
| | 122 | 50 | | InertiaReferencePoint - CenterOfMass); |
| | 122 | 51 | | return InertiaTensorMath.AddParallelAxisTensor( |
| | 122 | 52 | | centerTensor, |
| | 122 | 53 | | mass, |
| | 122 | 54 | | localReferencePoint - CenterOfMass); |
| | | 55 | | } |
| | | 56 | | |
| | | 57 | | internal static bool TryCreate( |
| | | 58 | | ReadOnlySpan<Vector3d> localVertices, |
| | | 59 | | ReadOnlySpan<int> triangles, |
| | | 60 | | Fixed64 totalArea, |
| | | 61 | | out ExactMassWeight totalWeight, |
| | | 62 | | out MeshSurfaceMassProperties properties) |
| | | 63 | | { |
| | 453 | 64 | | properties = default; |
| | 453 | 65 | | if (!TriangleShellMassProperties.TryCreateUniformShell( |
| | 453 | 66 | | localVertices, |
| | 453 | 67 | | triangles, |
| | 453 | 68 | | out totalWeight, |
| | 453 | 69 | | out Vector3d centerOfMass, |
| | 453 | 70 | | out Fixed3x3 unitCenterTensor)) |
| | | 71 | | { |
| | 26 | 72 | | return false; |
| | | 73 | | } |
| | | 74 | | |
| | 427 | 75 | | properties = new MeshSurfaceMassProperties( |
| | 427 | 76 | | totalArea, |
| | 427 | 77 | | centerOfMass, |
| | 427 | 78 | | centerOfMass, |
| | 427 | 79 | | unitCenterTensor); |
| | 427 | 80 | | return true; |
| | | 81 | | } |
| | | 82 | | } |