我用 C++ 创建了一个自定义几何集合组件以及基于它的蓝图。这是我的测试几何集合在编辑器中的样子:
算根,4个簇内有9个“真实粒子”。我的自定义几何组件总共记录了 13 个粒子:
void ACustomGCActor::BeginPlay()
{
Super::BeginPlay();
const FGeometryCollectionPhysicsProxy* PhysicsProxy = GeometryCollectionComponent->GetPhysicsProxy();
for (int32 i = 0; i < GeometryCollectionComponent->GetDynamicCollection()->GetNumTransforms(); ++i)
{
if (const Chaos::TPBDRigidParticle<Chaos::FReal, 3>* Particle = PhysicsProxy->GetParticleByIndex_External(i))
{
UE_LOG(LogTemp, Warning, TEXT("%s[%d] M: %f"), *GetName(), i, Particle->M());
}
}
}
我记录了每个粒子的质量:
GeometryCollectionActor_1[0] M: 100000.000000
GeometryCollectionActor_1[1] M: 53194.617188
GeometryCollectionActor_1[2] M: 30795.964844
GeometryCollectionActor_1[3] M: 16009.417969
GeometryCollectionActor_1[4] M: 17966.726562
GeometryCollectionActor_1[5] M: 33580.132812
GeometryCollectionActor_1[6] M: 1647.759644
GeometryCollectionActor_1[7] M: 9634.439453
GeometryCollectionActor_1[8] M: 7064.375000
GeometryCollectionActor_1[9] M: 14097.150391
GeometryCollectionActor_1[10] M: 1927.681030
GeometryCollectionActor_1[11] M: 14055.364258
GeometryCollectionActor_1[12] M: 26.372398
索引为
0
的第一个粒子的质量立即引人注目,因为它是整个物体的总质量。所以,我假设这是上面屏幕截图中名为 SM_ChamferCube
的根节点。
以下三个位于索引
1
、2
和 3
的粒子的质量加起来等于第一个粒子的质量 (53194.617188 + 30795.964844 + 16009.417969 = 100000.000000),所以我假设它们是 SM_ChamferCube_0
, SM_ChamferCube_1
和SM_ChamferCube_2
方法
GeometryCollectionComponent->GetParentArrayRest()
获取任何粒子索引的父索引。该数组中还有 13 个值,它们如下所示:
-1
0
0
0
1
1
1
2
2
2
3
3
3
索引
0
父级是 -1
,因为它是根。索引 1
、2
和 3
的父级是索引 0
。其余粒子是真实粒子,具有父粒子 1
、2
或 3
。任何作为另一个粒子的父粒子的粒子都不是真实的;它是一个“团簇联合粒子”。
因此,我们可以通过迭代父数组来确定几何集合中有多少个簇联合粒子组,找到最高索引 + 1,并将该值存储为
FirstRealParticleIndex
以用作任何循环的开始仅迭代真实粒子。
void ACustomGCActor::BeginPlay()
{
Super::BeginPlay();
for (const int32 i : GeometryCollectionComponent->GetParentArrayRest())
{
FirstRealParticleIndex = FMath::Max(FirstRealParticleIndex, i + 1);
}
const FGeometryCollectionPhysicsProxy* PhysicsProxy = GeometryCollectionComponent->GetPhysicsProxy();
for (int32 i = FirstRealParticleIndex; i < GeometryCollectionComponent->GetDynamicCollection()->GetNumTransforms();
++i)
{
if (const Chaos::TPBDRigidParticle<Chaos::FReal, 3>* Particle = PhysicsProxy->GetParticleByIndex_External(i))
{
// ...do something with the particle
}
}
}