Search code examples
c++game-physicsunreal-engine5physics-engine

Geometry Collection get each bone mass and velocity


Using Unreal Engine 5.4.3, I've implemented a custom AGeometryCollectionActor. I want to get the mass and velocity of each of the individual bones of this collection on tick. Following is a toy version of what I'm trying to do.

ACustomGeometryCollection.cpp

#include "GeometryCollection/GeometryCollectionComponent.h"
#include "Runtime/Experimental/Chaos/Private/Chaos/PhysicsObjectInternal.h"

void ACustomGeometryCollection::Tick(float DeltaSeconds)
{
    Super::Tick(DeltaSeconds);

    for (int32 i = 0; i < GeometryCollectionComponent->GetDynamicCollection()->GetNumTransforms(); ++i)
    {
        // I haven't figured out how to get from any of these to the mass and linear/angular velocity
        Chaos::FPhysicsObject* PhysicsObject = GeometryCollectionComponent->GetPhysicsObjectById(i);
        Chaos::FPBDRigidClusteredParticleHandle* Particle = PhysicsProxy->GetParticle_Internal(i);

        // This gets me the position but doesn't seem to pertain to mass or velocity
        FTransform3f Transform = GeometryCollectionComponent->GetDynamicCollection()->GetTransform(i);
    }
}

Also I have added "GeometryCollectionEngine" to the dependency module names in the <Project>.Build.cs file.


Solution

  • Here's my solution:

    ACustomGeometryCollection.cpp

    #include "GeometryCollection/GeometryCollectionComponent.h"
    #include "Runtime/Experimental/Chaos/Private/Chaos/PhysicsObjectInternal.h"
    
    void ACustomGCActor::Tick(float DeltaTime)
    {
        Super::Tick(DeltaTime);
    
        FGeometryCollectionPhysicsProxy* PhysicsProxy = GeometryCollectionComponent->GetPhysicsProxy();
        for (int32 i = FirstRealParticleIndex; i < GeometryCollectionComponent->GetDynamicCollection()->GetNumTransforms(); ++i)
        {
            if (Chaos::FPBDRigidClusteredParticleHandle* Particle = PhysicsProxy->GetParticle_Internal(i))
            {
                const FVector_NetQuantize10 LinearVelocity = Particle->GetV();
                const float Mass = Particle->M();
            }
        }
    }
    

    See also: how to compute FirstRealParticleIndex how to tell real particles from clusters (and ignore the cluster union particles)

    Don't forget to add "GeometryCollectionEngine" to the dependency module names in the <Project>.Build.cs file.