2017年1月16日月曜日

最も近いメッシュのトランスフォームを取得するテスト

最も近いメッシュのトランスフォームを取得

// AInstancedFoliageActorから最も近いメッシュのトランスフォームを取得するテスト
bool AThirdPersonCppCharacter::FindClosestMeshTransform(FTransform& TM)
{
 bool bFound = false;

// float fMinDist = FLT_MAX;
// float fMinDist = WORLD_MAX;  // Runtime\Engine\Public\EngineDefines.h
 float fMinDist = MAX_flt;  // Runtime\Core\Public\Math\NumericLimits.h

 float fRadius = 50.0 * 100.0f; // 50m
 FVector ActorLocation = GetActorLocation();

 DrawDebugSphere(GWorld, ActorLocation, fRadius, 8, FColor::White, false, 5.0f);

 bool bWorldSpace = true;

 ULevel* Level = GetLevel();
 if(!Level) return false;

 AInstancedFoliageActor* IFA = AInstancedFoliageActor::GetInstancedFoliageActorForLevel(Level);

 for (auto It = IFA->FoliageMeshes.CreateConstIterator(); It; ++It)
 {
  //UFoliageType* Key = It.Key();
  //FFoliageMeshInfo& Value = It.Value();
  FFoliageMeshInfo const* MeshInfo = &*It.Value();

  if (!MeshInfo) {
   continue;
  }
  if(!MeshInfo->Component) {
   continue;
  }

  UHierarchicalInstancedStaticMeshComponent* HISMComponent = MeshInfo->Component;

  TArray<int32> IdxArray = HISMComponent->GetInstancesOverlappingSphere(ActorLocation, fRadius, bWorldSpace);

  for(int32 i = 0; i < IdxArray.Num(); i++)
  {
   FTransform OutInstanceTransform;
    
   if(HISMComponent->GetInstanceTransform(IdxArray[i], OutInstanceTransform, bWorldSpace))
   {
    const FVector& MeshLocation = OutInstanceTransform.GetLocation();

    if(!IsForward(MeshLocation, 0.707f))
    {
     continue;
    }

    float Dist = FVector::Dist(OutInstanceTransform.GetLocation(), ActorLocation);
    if(Dist < fMinDist)
    {
     fMinDist = Dist;
     TM = OutInstanceTransform;

     bFound = true;
    }
   }
  }
 }

 return bFound;
}