BlueprintUtilityBPLibrary.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  1. // Copyright ECG . All Rights Reserved.
  2. #include "BlueprintUtilityBPLibrary.h"
  3. #include "BlueprintUtility.h"
  4. #include "Runtime/Engine/Classes/Engine/Engine.h"
  5. #include "ImageUtils.h"
  6. #include "IImageWrapper.h"
  7. #include "IImageWrapperModule.h"
  8. //#include "ImageLoader.h"
  9. //#include "../Public/FileHelper.h"
  10. #include "SecureHash.h"
  11. #include "Engine/Texture2D.h"
  12. #include "HighResScreenshot.h"
  13. #include "Kismet/KismetRenderingLibrary.h"
  14. UBlueprintUtilityBPLibrary::UBlueprintUtilityBPLibrary(const FObjectInitializer& ObjectInitializer)
  15. : Super(ObjectInitializer)
  16. {
  17. }
  18. //Use ContentDir()
  19. FString UBlueprintUtilityBPLibrary::GetFullPath(FString FilePath)
  20. {
  21. //Check Relative Or absolute path
  22. FString FullFilePath;
  23. if (FilePath.StartsWith(".", ESearchCase::CaseSensitive))
  24. {
  25. FullFilePath = *FPaths::Combine(FPaths::ProjectContentDir(), FilePath);
  26. FullFilePath = *FPaths::ConvertRelativePathToFull(FullFilePath);
  27. }
  28. else
  29. {
  30. FullFilePath = FilePath;
  31. }
  32. return FullFilePath;
  33. }
  34. float UBlueprintUtilityBPLibrary::BlueprintUtilitySampleFunction(float Param)
  35. {
  36. return -1;
  37. }
  38. //Discern Texture Type
  39. static TSharedPtr<IImageWrapper> GetImageWrapperByExtention(const FString InImagePath)
  40. {
  41. IImageWrapperModule& ImageWrapperModule = FModuleManager::GetModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
  42. if (InImagePath.EndsWith(".png"))
  43. {
  44. return ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);
  45. }
  46. else if (InImagePath.EndsWith(".jpg") || InImagePath.EndsWith(".jpeg"))
  47. {
  48. return ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
  49. }
  50. else if (InImagePath.EndsWith(".bmp"))
  51. {
  52. return ImageWrapperModule.CreateImageWrapper(EImageFormat::BMP);
  53. }
  54. else if (InImagePath.EndsWith(".ico"))
  55. {
  56. return ImageWrapperModule.CreateImageWrapper(EImageFormat::ICO);
  57. }
  58. else if (InImagePath.EndsWith(".exr"))
  59. {
  60. return ImageWrapperModule.CreateImageWrapper(EImageFormat::EXR);
  61. }
  62. else if (InImagePath.EndsWith(".icns"))
  63. {
  64. return ImageWrapperModule.CreateImageWrapper(EImageFormat::ICNS);
  65. }
  66. return nullptr;
  67. }
  68. UTexture2D* UBlueprintUtilityBPLibrary::LoadTexture2DFromFile(const FString& FilePath,
  69. bool& IsValid, int32& Width, int32& Height)
  70. {
  71. FString FullFilePath = GetFullPath(FilePath);
  72. if (!IsVaildPath(FullFilePath))
  73. {
  74. return NULL;
  75. }
  76. IsValid = false;
  77. UTexture2D* LoadedT2D = NULL;
  78. TSharedPtr<IImageWrapper> ImageWrapper = GetImageWrapperByExtention(FullFilePath);
  79. TArray<uint8> RawFileData;
  80. if (!FFileHelper::LoadFileToArray(RawFileData, *FullFilePath, 0)) return NULL ;
  81. if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(RawFileData.GetData(), RawFileData.Num()))
  82. {
  83. TArray<uint8> UncompressedBGRA ;
  84. if (ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, UncompressedBGRA))
  85. {
  86. LoadedT2D = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), PF_B8G8R8A8);
  87. if (!LoadedT2D) return NULL;
  88. Width = ImageWrapper->GetWidth();
  89. Height = ImageWrapper->GetHeight();
  90. void* TextureData = LoadedT2D->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
  91. FMemory::Memcpy(TextureData, UncompressedBGRA.GetData(), UncompressedBGRA.Num());
  92. LoadedT2D->PlatformData->Mips[0].BulkData.Unlock();
  93. LoadedT2D->UpdateResource();
  94. }
  95. }
  96. IsValid = true;
  97. return LoadedT2D;
  98. }
  99. UImageLoader* UBlueprintUtilityBPLibrary::LoadTexture2DFromFile_Async(const FString& FilePath,const FString& ID)
  100. {
  101. UImageLoader* Loader = NewObject<UImageLoader>();
  102. Loader->LoadImageAsync(FilePath,ID);
  103. return Loader;
  104. }
  105. UTexture2D* UBlueprintUtilityBPLibrary::BytesToTexture2d(const TArray<uint8> bytes)
  106. {
  107. UTexture2D* LoadedT2D = NULL;
  108. IImageWrapperModule& ImageWrapperModule = FModuleManager::Get().LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
  109. EImageFormat Format = ImageWrapperModule.DetectImageFormat(bytes.GetData(), bytes.Num());
  110. TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(Format);
  111. if (!ImageWrapper.IsValid())
  112. {
  113. return nullptr;
  114. }
  115. if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(bytes.GetData(), bytes.Num()))
  116. {
  117. TArray<uint8> UncompressedBGRA;
  118. if (ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, UncompressedBGRA))
  119. {
  120. LoadedT2D = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), PF_B8G8R8A8);
  121. if (!LoadedT2D) return NULL;
  122. void* TextureData = LoadedT2D->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
  123. FMemory::Memcpy(TextureData, UncompressedBGRA.GetData(), UncompressedBGRA.Num());
  124. LoadedT2D->PlatformData->Mips[0].BulkData.Unlock();
  125. LoadedT2D->UpdateResource();
  126. }
  127. }
  128. return LoadedT2D;
  129. }
  130. bool UBlueprintUtilityBPLibrary::ReadOggWaveData(class USoundWave* sw, TArray<uint8>* rawFile)
  131. {
  132. //FSoundQualityInfo info;
  133. //FVorbisAudioInfo vorbisObj ;
  134. //if (!vorbisObj.ReadCompressedInfo(rawFile->GetData(), rawFile->Num(), &info))
  135. //{
  136. // //Debug("Can't load header");
  137. // return true;
  138. //}
  139. //if (!sw) return true;
  140. //sw->SoundGroup = ESoundGroup::SOUNDGROUP_Default;
  141. //sw->NumChannels = info.NumChannels;
  142. //sw->Duration = info.Duration;
  143. //sw->RawPCMDataSize = info.SampleDataSize;
  144. //sw->SetSampleRate(info.SampleRate);
  145. //sw->RawData ;
  146. return false;
  147. }
  148. bool UBlueprintUtilityBPLibrary::ReadWavWaveData(class USoundWave* sw, TArray<uint8>* rawFile)
  149. {
  150. return false;
  151. }
  152. class USoundWave* UBlueprintUtilityBPLibrary::LoadWaveDataFromFile(const FString& FilePath)
  153. {
  154. USoundWave* sw = NewObject<USoundWave>(USoundWave::StaticClass());
  155. if (!sw)
  156. return nullptr;
  157. FString FullPath = GetFullPath(FilePath);
  158. TArray < uint8 > rawFile;
  159. FFileHelper::LoadFileToArray(rawFile, FullPath.GetCharArray().GetData());
  160. FWaveModInfo WaveInfo;
  161. if (WaveInfo.ReadWaveInfo(rawFile.GetData(), rawFile.Num()))
  162. {
  163. sw->InvalidateCompressedData();
  164. sw->RawData.Lock(LOCK_READ_WRITE);
  165. void* LockedData = sw->RawData.Realloc(rawFile.Num());
  166. FMemory::Memcpy(LockedData, rawFile.GetData(), rawFile.Num());
  167. sw->RawData.Unlock();
  168. int32 DurationDiv = *WaveInfo.pChannels * *WaveInfo.pBitsPerSample * *WaveInfo.pSamplesPerSec;
  169. if (DurationDiv)
  170. {
  171. sw->Duration = *WaveInfo.pWaveDataSize * 8.0f / DurationDiv;
  172. }
  173. else
  174. {
  175. sw->Duration = 0.0f;
  176. }
  177. sw->SetSampleRate(*WaveInfo.pSamplesPerSec);
  178. sw->NumChannels = *WaveInfo.pChannels;
  179. sw->RawPCMDataSize = WaveInfo.SampleDataSize;
  180. sw->SoundGroup = ESoundGroup::SOUNDGROUP_Default;
  181. }
  182. else {
  183. return nullptr;
  184. }
  185. return sw;
  186. }
  187. class USoundWave* UBlueprintUtilityBPLibrary::LoadOggDataFromFile(const FString& FilePath)
  188. {
  189. USoundWave* sw = NewObject<USoundWave>(USoundWave::StaticClass());
  190. if (!sw)
  191. return NULL;
  192. //* If true the song was successfully loaded
  193. bool loaded = false;
  194. FString FullPath = GetFullPath(FilePath);
  195. //* loaded song file (binary, encoded)
  196. TArray < uint8 > rawFile;
  197. loaded = FFileHelper::LoadFileToArray(rawFile, FullPath.GetCharArray().GetData());
  198. if (loaded)
  199. {
  200. FByteBulkData* bulkData = &sw->CompressedFormatData.GetFormat(TEXT("OGG"));
  201. //sw->RawData = sw->CompressedFormatData.GetFormat(TEXT("OGG"));
  202. bulkData->Lock(LOCK_READ_WRITE);
  203. FMemory::Memcpy(bulkData->Realloc(rawFile.Num()), rawFile.GetData(), rawFile.Num());
  204. bulkData->Unlock();
  205. sw->RawData = *bulkData;
  206. loaded = ReadOggWaveData(sw, &rawFile) == 0 ? true : false;
  207. }
  208. if (!loaded)
  209. return NULL;
  210. return sw;
  211. }
  212. void UBlueprintUtilityBPLibrary::ReadConfig(const FString& SectionName, const FString& ValueName, bool& succeed, FString &ReturnValue)
  213. {
  214. //GConfig->Flush(true, GGameIni);
  215. //bool succeed = false;
  216. succeed = GConfig->GetString(
  217. *SectionName,
  218. *ValueName,
  219. ReturnValue,
  220. GGameIni
  221. );
  222. UE_LOG(LogTemp, Warning, TEXT("Read Config %s "),succeed ? TEXT("Succeed") : TEXT("Fail"));
  223. }
  224. void UBlueprintUtilityBPLibrary::WriteConfig(const FString& SectionName, const FString& ValueName, const FString &ReturnValue)
  225. {
  226. //FString newSection = "/Script/CommunicationSetting";
  227. //FString TA = "DefaultMyConfig";
  228. GConfig->SetString(
  229. *SectionName,
  230. *ValueName,
  231. *ReturnValue,
  232. GGameIni
  233. );
  234. GConfig->Flush(false, GGameIni);
  235. /*
  236. FString log;
  237. ReadConfig(ReturnValue, ValueName, log);
  238. UE_LOG(LogTemp, Warning, TEXT("Set Config As %s "), *log);*/
  239. }
  240. bool UBlueprintUtilityBPLibrary::ReadCustomPathConfig(const FString&FilePath, const FString& SectionName, const FString& ValueName, FString &ReturnString)
  241. {
  242. FString FullPath = GetFullPath(FilePath);
  243. GConfig->Flush(true, FullPath);
  244. bool succeed = GConfig->GetString(*SectionName, *ValueName, ReturnString, FullPath);
  245. return succeed;
  246. }
  247. void UBlueprintUtilityBPLibrary::WriteCustomPathConfig(const FString&FilePath, const FString& SectionName, const FString& ValueName, const FString &WriteString)
  248. {
  249. FString FullPath = GetFullPath(FilePath);
  250. IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
  251. // Does the file exist?
  252. if (!PlatformFile.FileExists(*FullPath))
  253. {
  254. // File doesn't exist; (Attempt to) create a new one.
  255. FFileHelper::SaveStringToFile(TEXT(""), *FullPath);
  256. }
  257. GConfig->SetString(*SectionName, *ValueName, *WriteString, FullPath);
  258. GConfig->Flush(false, FullPath);
  259. }
  260. void UBlueprintUtilityBPLibrary::RefrashAllSkeletallAnimation()
  261. {
  262. for (TObjectIterator<AActor> iterator; iterator; ++iterator)
  263. {
  264. if (iterator)
  265. {
  266. for (auto actor_Component : iterator->GetComponents())
  267. {
  268. if (actor_Component->IsA(USkeletalMeshComponent::StaticClass()))
  269. {
  270. (Cast<USkeletalMeshComponent>(actor_Component))->TickAnimation(0.0f, false);
  271. (Cast<USkeletalMeshComponent>(actor_Component))->RefreshBoneTransforms();
  272. }
  273. }
  274. }
  275. }
  276. };
  277. bool UBlueprintUtilityBPLibrary::ReadFile(const FString FilePath, FString& ReturnString)
  278. {
  279. FString FullPath = GetFullPath(FilePath);
  280. FString Cache = "";
  281. bool Sucess = false;
  282. Sucess = FFileHelper::LoadFileToString(Cache, FullPath.GetCharArray().GetData());
  283. ReturnString = Cache;
  284. return Sucess;
  285. }
  286. bool UBlueprintUtilityBPLibrary::WriteFile(const FString FilePath, const FString ReturnString)
  287. {
  288. FString FullPath = GetFullPath(FilePath);
  289. bool Sucess;
  290. Sucess = FFileHelper::SaveStringToFile(ReturnString, *FullPath);
  291. return Sucess;
  292. }
  293. bool UBlueprintUtilityBPLibrary::WriteFileByte(TArray<uint8> bytes, const FString FilePath)
  294. {
  295. FString FullPath = GetFullPath(FilePath);
  296. bool Sucess;
  297. Sucess = FFileHelper::SaveArrayToFile(bytes, *FilePath);
  298. return Sucess;
  299. }
  300. bool UBlueprintUtilityBPLibrary::DeleteFile(const FString FilePath)
  301. {
  302. FString FullPath = GetFullPath(FilePath);
  303. IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
  304. if (PlatformFile.DeleteFile(*FullPath))
  305. {
  306. UE_LOG(LogTemp, Warning, TEXT("deleteFile: Delete the flie successfully!"));
  307. return true;
  308. }
  309. else
  310. {
  311. UE_LOG(LogTemp, Warning, TEXT("deleteFile: Not delete the flie!"));
  312. return false;
  313. }
  314. }
  315. bool UBlueprintUtilityBPLibrary::DeleteFiles(const FString FilePath)
  316. {
  317. FString FullPath = GetFullPath(FilePath);
  318. IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
  319. if (PlatformFile.DeleteDirectoryRecursively(*FullPath))
  320. {
  321. UE_LOG(LogTemp, Warning, TEXT("deleteFile: Delete the flie successfully!"));
  322. return true;
  323. }
  324. else
  325. {
  326. UE_LOG(LogTemp, Warning, TEXT("deleteFile: Not delete the flie!"));
  327. return false;
  328. }
  329. }
  330. bool UBlueprintUtilityBPLibrary::CopyFile(const FString FilePath, const FString ToPath)
  331. {
  332. IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
  333. return PlatformFile.CopyFile(*ToPath, *FilePath);
  334. }
  335. bool UBlueprintUtilityBPLibrary::Texture2d2PNG( UTextureRenderTarget2D* TextureRenderTarget, const FString& FilePath)
  336. {
  337. FTextureRenderTargetResource* rtResource = TextureRenderTarget->GameThread_GetRenderTargetResource();
  338. FReadSurfaceDataFlags readPixelFlags(RCM_UNorm);
  339. TArray<FColor> outBMP;
  340. for (FColor& color : outBMP)
  341. {
  342. color.A = 255;
  343. }
  344. outBMP.AddUninitialized(TextureRenderTarget->GetSurfaceWidth() * TextureRenderTarget->GetSurfaceHeight());
  345. rtResource->ReadPixels(outBMP, readPixelFlags);
  346. FIntPoint destSize(TextureRenderTarget->GetSurfaceWidth(), TextureRenderTarget->GetSurfaceHeight());
  347. TArray<uint8> CompressedBitmap;
  348. FImageUtils::CompressImageArray(destSize.X, destSize.Y, outBMP, CompressedBitmap);
  349. bool imageSavedOk = FFileHelper::SaveArrayToFile(CompressedBitmap, *FilePath);
  350. return imageSavedOk;
  351. }
  352. FString UBlueprintUtilityBPLibrary::GetGamePath(DirType E)
  353. {
  354. if (E == DirType::GameDir)
  355. {
  356. return FPaths::ProjectDir();
  357. }
  358. return FPaths::ProjectContentDir();
  359. }
  360. bool UBlueprintUtilityBPLibrary::IsVaildPath(const FString ImagePath)
  361. {
  362. if (!FPaths::FileExists(ImagePath))
  363. {
  364. UE_LOG(LogTemp, Warning, TEXT("File not found: %s"), *ImagePath);
  365. return false;
  366. }
  367. // Load the compressed byte data from the file
  368. TArray<uint8> FileData;
  369. if (!FFileHelper::LoadFileToArray(FileData, *ImagePath))
  370. {
  371. UE_LOG(LogTemp, Warning, TEXT("Failed to load file: %s"), *ImagePath);
  372. return false;
  373. }
  374. return true;
  375. }
  376. AExeActor* UBlueprintUtilityBPLibrary::OpenExe(UObject* SomeInWorldObject, const FString Path, const FString Args)
  377. {
  378. UWorld* world = SomeInWorldObject->GetWorld();
  379. FVector pos(150, 0, 20);
  380. AExeActor *Temp = world->SpawnActor<AExeActor>(pos, FRotator::ZeroRotator); ;
  381. //AExeActor *Temp = NewObject<AExeActor>();
  382. //EE->GetWorld()->AddNetworkActor(Temp);
  383. Temp->SetActorTickEnabled(true);
  384. Temp->ActorToWorld();
  385. Temp->CheckProc = FPlatformProcess::CreateProc(*Path, *Args, true, false, false, nullptr, 0, nullptr, nullptr);
  386. return Temp;
  387. }
  388. void UBlueprintUtilityBPLibrary::GenColors(int Length, const FColor color, TArray<FColor>& OuterColor)
  389. {
  390. TArray<FColor> setColor;
  391. for (int i=0;i<Length;i++)
  392. {
  393. setColor.Add(color);
  394. }
  395. OuterColor = setColor;
  396. }
  397. void UBlueprintUtilityBPLibrary::UVtimes(FVector2D tims, const TArray<FVector2D> inputUV, TArray<FVector2D>& OuterColor)
  398. {
  399. OuterColor.Reset(inputUV.Num());
  400. for (const FVector2D& tan : inputUV)
  401. {
  402. OuterColor.Add(tan*tims);
  403. }
  404. }
  405. bool UBlueprintUtilityBPLibrary::IsEditorMode()
  406. {
  407. #if WITH_EDITOR
  408. return true;
  409. #endif
  410. return false;
  411. }
  412. FString UBlueprintUtilityBPLibrary::GenMD5(FString inputstring)
  413. {
  414. FTCHARToUTF8 EchoStrUtf8(*inputstring);
  415. int32 DestLen = EchoStrUtf8.Length();
  416. FString RST = FMD5::HashBytes((unsigned char*)TCHAR_TO_UTF8(*inputstring), DestLen);
  417. return RST;
  418. }
  419. FString UBlueprintUtilityBPLibrary::GenSHA1(FString inputstring)
  420. {
  421. FSHAHash StringHash;
  422. FSHA1::HashBuffer(TCHAR_TO_ANSI(*inputstring), inputstring.Len(), StringHash.Hash);
  423. return *(StringHash.ToString());
  424. }
  425. FString UBlueprintUtilityBPLibrary::EnCryptoPPSHA1(FString inputstring,FString aes_key)
  426. {
  427. //std::string sKey = TCHAR_TO_UTF8(*aes_key);
  428. //const char* cipherText = TCHAR_TO_ANSI(*aes_content);
  429. //std::string outstr;
  430. //try
  431. //{
  432. // //填key
  433. // SecByteBlock key(AES::MAX_KEYLENGTH);
  434. // memset(key, 0x30, key.size());
  435. // sKey.size() <= AES::MAX_KEYLENGTH ? memcpy(key, sKey.c_str(), sKey.size()) : memcpy(key, sKey.c_str(), AES::MAX_KEYLENGTH);
  436. // ECB_Mode<AES >::Decryption ecbDecryption((byte*)key, AES::MAX_KEYLENGTH);
  437. // HexDecoder decryptor(new StreamTransformationFilter(ecbDecryption, new StringSink(outstr), BlockPaddingSchemeDef::BlockPaddingScheme::ZEROS_PADDING,
  438. // true
  439. // ));
  440. // decryptor.Put((byte*)cipherText, strlen(cipherText));
  441. // decryptor.MessageEnd();
  442. // _isSuc = true;
  443. //}
  444. //catch (...)
  445. //{
  446. // outstr = "error";
  447. // _isSuc = false;
  448. //}
  449. return "123";
  450. }
  451. bool UBlueprintUtilityBPLibrary::CheckActorInView(UPrimitiveComponent* actorComp,float checktime)
  452. {
  453. float c = actorComp->GetLastRenderTimeOnScreen();
  454. float d = actorComp->GetWorld()->GetTimeSeconds();
  455. //UE_LOG(LogTemp, Warning, TEXT("last render time :%f Game Time :%f"),c,d);
  456. if (d-c >=checktime)
  457. {
  458. return false;
  459. }
  460. return true;
  461. }
  462. void UBlueprintUtilityBPLibrary::GetProduralMeshInfo(UProceduralMeshComponent* InProcMesh, int32 SectionIndex, TArray<FVector>& Vertices, TArray<int32>& Triangles, TArray<FVector>& Normals, TArray<FVector2D>& UVs, TArray<FProcMeshTangent>& Tangents, TArray<FColor>& VerticesColor)
  463. {
  464. if (InProcMesh && SectionIndex >= 0 && SectionIndex < InProcMesh->GetNumSections())
  465. {
  466. const FProcMeshSection* Section = InProcMesh->GetProcMeshSection(SectionIndex);
  467. const int32 NumOutputVerts = Section->ProcVertexBuffer.Num();
  468. // Allocate output buffers for vert data
  469. Vertices.SetNumUninitialized(NumOutputVerts);
  470. Normals.SetNumUninitialized(NumOutputVerts);
  471. UVs.SetNumUninitialized(NumOutputVerts);
  472. Tangents.SetNumUninitialized(NumOutputVerts);
  473. VerticesColor.SetNumUninitialized(NumOutputVerts);
  474. // copy data
  475. for (int32 VertIdx = 0; VertIdx < NumOutputVerts; VertIdx++)
  476. {
  477. const FProcMeshVertex& Vert = Section->ProcVertexBuffer[VertIdx];
  478. Vertices[VertIdx] = Vert.Position;
  479. Normals[VertIdx] = Vert.Normal;
  480. UVs[VertIdx] = Vert.UV0;
  481. Tangents[VertIdx] = Vert.Tangent;
  482. VerticesColor[VertIdx] = Vert.Color;
  483. }
  484. // Copy index buffer
  485. const int32 NumIndices = Section->ProcIndexBuffer.Num();
  486. Triangles.SetNumUninitialized(NumIndices);
  487. for (int32 IndexIdx = 0; IndexIdx < NumIndices; IndexIdx++)
  488. {
  489. Triangles[IndexIdx] = Section->ProcIndexBuffer[IndexIdx];
  490. }
  491. }
  492. }