我构建了一个自定义几何集合,需要获取每个粒子的绝对世界位置。但到目前为止,我只得到了粒子的相对平移。因此,在下面的代码中,在几何集合与原始其余集合分离之前,所有粒子平移都是 [0, 0, 0]:
void ACustomGCActor::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
for (int32 i = 0; i < GeometryCollectionComponent->GetDynamicCollection()->GetNumTransforms(); ++i)
{
// This is the translation relative to the original resting location
UE::Math::TVector<float> T = GeometryCollectionComponent->GetDynamicCollection()->GetTransform(i).GetTranslation();
}
}
我认为我在
Particle->GetP()
或Particle->GetX()
的正确轨道上。我还注意到索引 0 处的粒子有一些特殊的行为。
答案基本上是
Particle->GetX()
从几何集合物理代理获取粒子后,但是一个主要问题是粒子仅在脱离时更新其位置。
来自 GeometryCollectionEngine -> GeometryCollectionComponent.cpp:2135 的代码注释对此提供了一些启示:
簇总是会破裂,其中一块被移除。 这意味着我们只需要记录发生故障的一次性组件,然后我们就可以免费获得连接的组件。 如果第一个子级被禁用,则意味着属性适用于父级(即集群)。 如果启用第一个子节点,则意味着它是一次性的,并且集群是第一个子节点
因此,我们必须检查每个粒子是否被禁用,如果是,则使用其父位置。
void ACustomGCActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
const FGeometryCollectionPhysicsProxy* PhysicsProxy = GeometryCollectionComponent->GetPhysicsProxy();
for (int32 i = FirstRealParticleIndex; i < GeometryCollectionComponent->GetDynamicCollection()->GetNumTransforms(); ++i)
{
if (Chaos::FPBDRigidClusteredParticleHandle* Particle = PhysicsProxy->GetParticle_Internal(i))
{
const Chaos::TVector<double, 3> Location =
Particle->Disabled()
? GeometryCollectionComponent->GetPhysicsProxy()->GetParticleByIndex_External(
GeometryCollectionComponent->GetParentArrayRest()[i + FirstRealParticleIndex])->GetX()
: Particle->GetX();
}
}
}
另请参阅:如何计算
FirstRealParticleIndex
如何区分真实粒子和簇(并忽略簇并集粒子)
不要忘记将
"GeometryCollectionEngine"
添加到