Advertisement
deblasipaste

Untitled

May 16th, 2024
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.11 KB | None | 0 0
  1. // Fill out your copyright notice in the Description page of Project Settings.
  2.  
  3.  
  4. #include "Voxel/VoxelTerrainActor.h"
  5. #include "DrawDebugHelpers.h"
  6. #include "ProceduralMeshComponent.h"
  7. #include "KismetProceduralMeshLibrary.h"
  8. #include "Components/TextRenderComponent.h"
  9.  
  10. void FChunk::SetCanUpdate(FChunk& Chunk, bool NewUpdate)
  11. {
  12. Chunk.CanUpdateVoxels = NewUpdate;
  13. }
  14.  
  15. // Sets default values
  16. AVoxelTerrainActor::AVoxelTerrainActor()
  17. {
  18. // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
  19. PrimaryActorTick.bCanEverTick = true;
  20.  
  21. ProceduralMesh = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("Procedural Mesh"));
  22. ProceduralMesh->bUseAsyncCooking = true;
  23. }
  24.  
  25. // Called when the game starts or when spawned
  26. void AVoxelTerrainActor::BeginPlay()
  27. {
  28. Super::BeginPlay();
  29.  
  30. Setup(1.0f);
  31.  
  32. GetWorldTimerManager().SetTimer(ShuffleTimerHandle, [this]()
  33. {
  34. ShuffleChunk(Chunks[0]);
  35. }, 1.0f / ShuffleFrequency, false);
  36. }
  37.  
  38. void AVoxelTerrainActor::Setup(float Res)
  39. {
  40. for (int i = 0; i < 1; i++)
  41. {
  42. auto& Chunk = Chunks.AddDefaulted_GetRef();
  43. Chunk.Extent = FVector2D(ChunkSize, ChunkSize);
  44. SetupChunk(Chunk);
  45. }
  46. }
  47.  
  48. void AVoxelTerrainActor::SetupChunk(FChunk& Chunk)
  49. {
  50. Chunk.Voxels.SetNum(ChunkSize * ChunkSize * 1024);
  51.  
  52. for (int x = VoxelSize / 2; x < ChunkSize * VoxelSize; x += VoxelSize)
  53. {
  54. for (int y = VoxelSize / 2; y < ChunkSize * VoxelSize; y += VoxelSize)
  55. {
  56. for (int z = VoxelSize / 2; z < 1024 * VoxelSize; z += VoxelSize)
  57. {
  58. FVoxel Vox;
  59. Vox.Position = FVector(x, y, z);
  60.  
  61. if (FMath::FRand() > Density)
  62. {
  63. //DrawDebugPoint(GetWorld(), FVector(x, y, z), 5, FColor::Green, true);
  64. Vox.Flags = 0x01;
  65. }
  66. else
  67. {
  68. //DrawDebugPoint(GetWorld(), FVector(x, y, z), 5, FColor::Red, true);
  69. Vox.Flags = 0x00;
  70. }
  71.  
  72. Chunk.Voxels[GetVoxelIndex(x, y, z)] = Vox;
  73. /*if (x == 0 || x == (ChunkSize - 1) * VoxelSize || y == 0 || y == (ChunkSize - 1) * VoxelSize)
  74. DrawDebugPoint(GetWorld(), FVector(x, y, z), 2.0f, (z >= 256 * VoxelSize ? FColor::Red : FColor::Green), true);*/
  75. }
  76. }
  77. }
  78.  
  79. BuildChunk(Chunk, TArray<FVector>{});
  80. }
  81.  
  82. void AVoxelTerrainActor::BuildChunkMesh(FChunk& Chunk)
  83. {
  84. if (!IsInGameThread() || Chunk.CanUpdateVoxels)
  85. return;
  86.  
  87. ProceduralMesh->CreateMeshSection(0, Chunk.Vertices, Chunk.Triangles, Chunk.Normals, Chunk.UVs, TArray<FColor>(), TArray<FProcMeshTangent>(), true);
  88. if (Material)
  89. {
  90. ProceduralMesh->SetMaterial(0, Material);
  91. }
  92.  
  93. FChunk::SetCanUpdate(Chunk, true);
  94. }
  95.  
  96. void AVoxelTerrainActor::BuildChunk(FChunk& Chunk, TArray<FVector> AffectedVoxels)
  97. {
  98. AsyncTask(ENamedThreads::AnyHiPriThreadHiPriTask, [this, &Chunk, AffectedVoxels]()
  99. {
  100. if (!Chunk.CanUpdateVoxels)
  101. return;
  102.  
  103. FChunk::SetCanUpdate(Chunk, false);
  104.  
  105. if (AffectedVoxels.Num() == 0 || !AffectedVoxels.IsValidIndex(0))
  106. {
  107. Chunk.Vertices.Empty();
  108. Chunk.Triangles.Empty();
  109. Chunk.Normals.Empty();
  110. Chunk.UVs.Empty();
  111.  
  112. for (int x = VoxelSize / 2; x < ChunkSize * VoxelSize; x += VoxelSize)
  113. {
  114. for (int y = VoxelSize / 2; y < ChunkSize * VoxelSize; y += VoxelSize)
  115. {
  116. for (int z = VoxelSize / 2; z < 1024 * VoxelSize; z += VoxelSize)
  117. {
  118. InitialBuildVoxel(Chunk, x, y, z);
  119. }
  120. }
  121. }
  122. }
  123. else
  124. {
  125. for (auto& Pos : AffectedVoxels)
  126. {
  127. if (FVoxel* Voxel = GetVoxel(Chunk, Pos.X, Pos.Y, Pos.Z))
  128. {
  129. for (int i = 0; i < Voxel->VertexStartIndexes.Num(); i++)
  130. {
  131. const int V = Voxel->VertexStartIndexes[i];
  132. const int T = Voxel->TriangleStartIndexes[i];
  133. Chunk.Vertices.RemoveAt(V, 4, false);
  134. Chunk.Triangles.RemoveAt(T, 6, false);
  135. Chunk.Normals.RemoveAt(V, 4, false);
  136. Chunk.UVs.RemoveAt(V, 4, false);
  137. for (int j = i + 1; j < Voxel->VertexStartIndexes.Num(); j++)
  138. {
  139. Voxel->VertexStartIndexes[j] -= 4;
  140. Voxel->TriangleStartIndexes[j] -= 6;
  141. }
  142. }
  143.  
  144. UpdateVoxel(Chunk, Voxel);
  145. }
  146. }
  147. }
  148.  
  149. AsyncTask(ENamedThreads::GameThread, [this, &Chunk]()
  150. {
  151. BuildChunkMesh(Chunk);
  152. });
  153. });
  154. }
  155.  
  156. void AVoxelTerrainActor::InitialBuildVoxel(FChunk& Chunk, int x, int y, int z)
  157. {
  158. /* Not enveloped
  159. * Fully enveloped
  160. * Pos X
  161. * Pos Y
  162. * Pos Z
  163. * Neg X
  164. * Neg Y
  165. * Neg Z
  166. */
  167.  
  168. //DrawDebugPoint(GetWorld(), FVector(x, y, z), 2.0f, FColor::Red, true);
  169.  
  170. FVoxel* Voxel = GetVoxel(Chunk, x, y, z);
  171. if (!Voxel)
  172. return;
  173.  
  174. Voxel->VertexStartIndexes.Empty();
  175. Voxel->TriangleStartIndexes.Empty();
  176.  
  177. const uint8 VE = VoxelEnveloped(Chunk, x, y, z);
  178. if (VE & (1 << 1))
  179. return;
  180.  
  181. if (!(VE & (1 << 2)))
  182. {
  183. // pos X
  184. const int NumVerts = Chunk.Vertices.Num();
  185. const int NumTris = Chunk.Triangles.Num();
  186.  
  187. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
  188. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
  189. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
  190. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
  191.  
  192. Chunk.Triangles.Add(NumVerts + 1);
  193. Chunk.Triangles.Add(NumVerts + 0);
  194. Chunk.Triangles.Add(NumVerts + 2);
  195.  
  196. Chunk.Triangles.Add(NumVerts + 1);
  197. Chunk.Triangles.Add(NumVerts + 2);
  198. Chunk.Triangles.Add(NumVerts + 3);
  199.  
  200. Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
  201. Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
  202. Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
  203. Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
  204.  
  205. Chunk.Normals.Add(FVector(1.0f, 0.0f, 0.0f));
  206. Chunk.Normals.Add(FVector(1.0f, 0.0f, 0.0f));
  207. Chunk.Normals.Add(FVector(1.0f, 0.0f, 0.0f));
  208. Chunk.Normals.Add(FVector(1.0f, 0.0f, 0.0f));
  209.  
  210. Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
  211. Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
  212. }
  213. if (!(VE & (1 << 3)))
  214. {
  215. // pos Y
  216. const int NumVerts = Chunk.Vertices.Num();
  217. const int NumTris = Chunk.Triangles.Num();
  218.  
  219. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
  220. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
  221. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
  222. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
  223.  
  224. Chunk.Triangles.Add(NumVerts + 0);
  225. Chunk.Triangles.Add(NumVerts + 1);
  226. Chunk.Triangles.Add(NumVerts + 2);
  227.  
  228. Chunk.Triangles.Add(NumVerts + 2);
  229. Chunk.Triangles.Add(NumVerts + 1);
  230. Chunk.Triangles.Add(NumVerts + 3);
  231.  
  232. Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
  233. Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
  234. Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
  235. Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
  236.  
  237. Chunk.Normals.Add(FVector(0.0f, 1.0f, 0.0f));
  238. Chunk.Normals.Add(FVector(0.0f, 1.0f, 0.0f));
  239. Chunk.Normals.Add(FVector(0.0f, 1.0f, 0.0f));
  240. Chunk.Normals.Add(FVector(0.0f, 1.0f, 0.0f));
  241.  
  242. Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
  243. Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
  244. }
  245. if (!(VE & (1 << 4)))
  246. {
  247. // pos Z
  248. const int NumVerts = Chunk.Vertices.Num();
  249. const int NumTris = Chunk.Triangles.Num();
  250.  
  251. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
  252. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
  253. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
  254. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
  255.  
  256. Chunk.Triangles.Add(NumVerts + 1);
  257. Chunk.Triangles.Add(NumVerts + 0);
  258. Chunk.Triangles.Add(NumVerts + 2);
  259.  
  260. Chunk.Triangles.Add(NumVerts + 1);
  261. Chunk.Triangles.Add(NumVerts + 2);
  262. Chunk.Triangles.Add(NumVerts + 3);
  263.  
  264. Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
  265. Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
  266. Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
  267. Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
  268.  
  269. Chunk.Normals.Add(FVector(0.0f, 0.0f, 1.0f));
  270. Chunk.Normals.Add(FVector(0.0f, 0.0f, 1.0f));
  271. Chunk.Normals.Add(FVector(0.0f, 0.0f, 1.0f));
  272. Chunk.Normals.Add(FVector(0.0f, 0.0f, 1.0f));
  273.  
  274. Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
  275. Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
  276. }
  277. if (!(VE & (1 << 5)))
  278. {
  279. // neg X
  280. const int NumVerts = Chunk.Vertices.Num();
  281. const int NumTris = Chunk.Triangles.Num();
  282.  
  283. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
  284. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
  285. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
  286. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
  287.  
  288. Chunk.Triangles.Add(NumVerts + 0);
  289. Chunk.Triangles.Add(NumVerts + 1);
  290. Chunk.Triangles.Add(NumVerts + 2);
  291.  
  292. Chunk.Triangles.Add(NumVerts + 2);
  293. Chunk.Triangles.Add(NumVerts + 1);
  294. Chunk.Triangles.Add(NumVerts + 3);
  295.  
  296. Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
  297. Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
  298. Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
  299. Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
  300.  
  301. Chunk.Normals.Add(FVector(-1.0f, 0.0f, 0.0f));
  302. Chunk.Normals.Add(FVector(-1.0f, 0.0f, 0.0f));
  303. Chunk.Normals.Add(FVector(-1.0f, 0.0f, 0.0f));
  304. Chunk.Normals.Add(FVector(-1.0f, 0.0f, 0.0f));
  305.  
  306. Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
  307. Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
  308. }
  309. if (!(VE & (1 << 6)))
  310. {
  311. // neg Y
  312. const int NumVerts = Chunk.Vertices.Num();
  313. const int NumTris = Chunk.Triangles.Num();
  314.  
  315. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
  316. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
  317. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
  318. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
  319.  
  320. Chunk.Triangles.Add(NumVerts + 1);
  321. Chunk.Triangles.Add(NumVerts + 0);
  322. Chunk.Triangles.Add(NumVerts + 2);
  323.  
  324. Chunk.Triangles.Add(NumVerts + 1);
  325. Chunk.Triangles.Add(NumVerts + 2);
  326. Chunk.Triangles.Add(NumVerts + 3);
  327.  
  328. Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
  329. Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
  330. Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
  331. Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
  332.  
  333. Chunk.Normals.Add(FVector(0.0f, -1.0f, 0.0f));
  334. Chunk.Normals.Add(FVector(0.0f, -1.0f, 0.0f));
  335. Chunk.Normals.Add(FVector(0.0f, -1.0f, 0.0f));
  336. Chunk.Normals.Add(FVector(0.0f, -1.0f, 0.0f));
  337.  
  338. Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
  339. Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
  340. }
  341. if (!(VE & (1 << 7)))
  342. {
  343. // neg Z
  344. const int NumVerts = Chunk.Vertices.Num();
  345. const int NumTris = Chunk.Triangles.Num();
  346.  
  347. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
  348. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
  349. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
  350. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
  351.  
  352. Chunk.Triangles.Add(NumVerts + 0);
  353. Chunk.Triangles.Add(NumVerts + 1);
  354. Chunk.Triangles.Add(NumVerts + 2);
  355.  
  356. Chunk.Triangles.Add(NumVerts + 2);
  357. Chunk.Triangles.Add(NumVerts + 1);
  358. Chunk.Triangles.Add(NumVerts + 3);
  359.  
  360. Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
  361. Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
  362. Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
  363. Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
  364.  
  365. Chunk.Normals.Add(FVector(0.0f, 0.0f, -1.0f));
  366. Chunk.Normals.Add(FVector(0.0f, 0.0f, -1.0f));
  367. Chunk.Normals.Add(FVector(0.0f, 0.0f, -1.0f));
  368. Chunk.Normals.Add(FVector(0.0f, 0.0f, -1.0f));
  369.  
  370. Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
  371. Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
  372. }
  373. }
  374.  
  375. void AVoxelTerrainActor::UpdateVoxel(FChunk& Chunk, int x, int y, int z)
  376. {
  377. /* Not enveloped
  378. * Fully enveloped
  379. * Pos X
  380. * Pos Y
  381. * Pos Z
  382. * Neg X
  383. * Neg Y
  384. * Neg Z
  385. */
  386.  
  387. //DrawDebugPoint(GetWorld(), FVector(x, y, z), 2.0f, FColor::Red, true);
  388.  
  389. FVoxel* Voxel = GetVoxel(Chunk, x, y, z);
  390. if (!Voxel)
  391. return;
  392.  
  393. if (Voxel->Flags & 0x01)
  394. BuildAdjacentVoxels(Chunk, x, y, z);
  395.  
  396. Voxel->VertexStartIndexes.Empty();
  397. Voxel->TriangleStartIndexes.Empty();
  398.  
  399. const uint8 VE = VoxelEnveloped(Chunk, x, y, z);
  400. if (VE & (1 << 1))
  401. return;
  402.  
  403. if (!(VE & (1 << 2)))
  404. {
  405. // pos X
  406. const int NumVerts = Chunk.Vertices.Num();
  407. const int NumTris = Chunk.Triangles.Num();
  408.  
  409. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
  410. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
  411. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
  412. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
  413.  
  414. Chunk.Triangles.Add(NumVerts + 1);
  415. Chunk.Triangles.Add(NumVerts + 0);
  416. Chunk.Triangles.Add(NumVerts + 2);
  417.  
  418. Chunk.Triangles.Add(NumVerts + 1);
  419. Chunk.Triangles.Add(NumVerts + 2);
  420. Chunk.Triangles.Add(NumVerts + 3);
  421.  
  422. Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
  423. Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
  424. Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
  425. Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
  426.  
  427. Chunk.Normals.Add(FVector(1.0f, 0.0f, 0.0f));
  428. Chunk.Normals.Add(FVector(1.0f, 0.0f, 0.0f));
  429. Chunk.Normals.Add(FVector(1.0f, 0.0f, 0.0f));
  430. Chunk.Normals.Add(FVector(1.0f, 0.0f, 0.0f));
  431.  
  432. Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
  433. Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
  434. }
  435. if (!(VE & (1 << 3)))
  436. {
  437. // pos Y
  438. const int NumVerts = Chunk.Vertices.Num();
  439. const int NumTris = Chunk.Triangles.Num();
  440.  
  441. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
  442. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
  443. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
  444. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
  445.  
  446. Chunk.Triangles.Add(NumVerts + 0);
  447. Chunk.Triangles.Add(NumVerts + 1);
  448. Chunk.Triangles.Add(NumVerts + 2);
  449.  
  450. Chunk.Triangles.Add(NumVerts + 2);
  451. Chunk.Triangles.Add(NumVerts + 1);
  452. Chunk.Triangles.Add(NumVerts + 3);
  453.  
  454. Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
  455. Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
  456. Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
  457. Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
  458.  
  459. Chunk.Normals.Add(FVector(0.0f, 1.0f, 0.0f));
  460. Chunk.Normals.Add(FVector(0.0f, 1.0f, 0.0f));
  461. Chunk.Normals.Add(FVector(0.0f, 1.0f, 0.0f));
  462. Chunk.Normals.Add(FVector(0.0f, 1.0f, 0.0f));
  463.  
  464. Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
  465. Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
  466. }
  467. if (!(VE & (1 << 4)))
  468. {
  469. // pos Z
  470. const int NumVerts = Chunk.Vertices.Num();
  471. const int NumTris = Chunk.Triangles.Num();
  472.  
  473. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
  474. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
  475. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
  476. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
  477.  
  478. Chunk.Triangles.Add(NumVerts + 1);
  479. Chunk.Triangles.Add(NumVerts + 0);
  480. Chunk.Triangles.Add(NumVerts + 2);
  481.  
  482. Chunk.Triangles.Add(NumVerts + 1);
  483. Chunk.Triangles.Add(NumVerts + 2);
  484. Chunk.Triangles.Add(NumVerts + 3);
  485.  
  486. Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
  487. Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
  488. Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
  489. Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
  490.  
  491. Chunk.Normals.Add(FVector(0.0f, 0.0f, 1.0f));
  492. Chunk.Normals.Add(FVector(0.0f, 0.0f, 1.0f));
  493. Chunk.Normals.Add(FVector(0.0f, 0.0f, 1.0f));
  494. Chunk.Normals.Add(FVector(0.0f, 0.0f, 1.0f));
  495.  
  496. Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
  497. Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
  498. }
  499. if (!(VE & (1 << 5)))
  500. {
  501. // neg X
  502. const int NumVerts = Chunk.Vertices.Num();
  503. const int NumTris = Chunk.Triangles.Num();
  504.  
  505. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
  506. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
  507. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
  508. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
  509.  
  510. Chunk.Triangles.Add(NumVerts + 0);
  511. Chunk.Triangles.Add(NumVerts + 1);
  512. Chunk.Triangles.Add(NumVerts + 2);
  513.  
  514. Chunk.Triangles.Add(NumVerts + 2);
  515. Chunk.Triangles.Add(NumVerts + 1);
  516. Chunk.Triangles.Add(NumVerts + 3);
  517.  
  518. Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
  519. Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
  520. Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
  521. Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
  522.  
  523. Chunk.Normals.Add(FVector(-1.0f, 0.0f, 0.0f));
  524. Chunk.Normals.Add(FVector(-1.0f, 0.0f, 0.0f));
  525. Chunk.Normals.Add(FVector(-1.0f, 0.0f, 0.0f));
  526. Chunk.Normals.Add(FVector(-1.0f, 0.0f, 0.0f));
  527.  
  528. Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
  529. Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
  530. }
  531. if (!(VE & (1 << 6)))
  532. {
  533. // neg Y
  534. const int NumVerts = Chunk.Vertices.Num();
  535. const int NumTris = Chunk.Triangles.Num();
  536.  
  537. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
  538. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
  539. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
  540. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
  541.  
  542. Chunk.Triangles.Add(NumVerts + 1);
  543. Chunk.Triangles.Add(NumVerts + 0);
  544. Chunk.Triangles.Add(NumVerts + 2);
  545.  
  546. Chunk.Triangles.Add(NumVerts + 1);
  547. Chunk.Triangles.Add(NumVerts + 2);
  548. Chunk.Triangles.Add(NumVerts + 3);
  549.  
  550. Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
  551. Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
  552. Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
  553. Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
  554.  
  555. Chunk.Normals.Add(FVector(0.0f, -1.0f, 0.0f));
  556. Chunk.Normals.Add(FVector(0.0f, -1.0f, 0.0f));
  557. Chunk.Normals.Add(FVector(0.0f, -1.0f, 0.0f));
  558. Chunk.Normals.Add(FVector(0.0f, -1.0f, 0.0f));
  559.  
  560. Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
  561. Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
  562. }
  563. if (!(VE & (1 << 7)))
  564. {
  565. // neg Z
  566. const int NumVerts = Chunk.Vertices.Num();
  567. const int NumTris = Chunk.Triangles.Num();
  568.  
  569. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
  570. Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
  571. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
  572. Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
  573.  
  574. Chunk.Triangles.Add(NumVerts + 0);
  575. Chunk.Triangles.Add(NumVerts + 1);
  576. Chunk.Triangles.Add(NumVerts + 2);
  577.  
  578. Chunk.Triangles.Add(NumVerts + 2);
  579. Chunk.Triangles.Add(NumVerts + 1);
  580. Chunk.Triangles.Add(NumVerts + 3);
  581.  
  582. Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
  583. Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
  584. Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
  585. Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
  586.  
  587. Chunk.Normals.Add(FVector(0.0f, 0.0f, -1.0f));
  588. Chunk.Normals.Add(FVector(0.0f, 0.0f, -1.0f));
  589. Chunk.Normals.Add(FVector(0.0f, 0.0f, -1.0f));
  590. Chunk.Normals.Add(FVector(0.0f, 0.0f, -1.0f));
  591.  
  592. Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
  593. Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
  594. }
  595. }
  596.  
  597. void AVoxelTerrainActor::UpdateVoxel(FChunk& Chunk, const FVoxel* Voxel)
  598. {
  599. UpdateVoxel(Chunk, Voxel->Position.X, Voxel->Position.Y, Voxel->Position.Z);
  600. }
  601.  
  602. void AVoxelTerrainActor::BuildAdjacentVoxels(FChunk& Chunk, int x, int y, int z)
  603. {
  604. /* Not enveloped
  605. * Fully enveloped
  606. * Pos X
  607. * Pos Y
  608. * Pos Z
  609. * Neg X
  610. * Neg Y
  611. * Neg Z
  612. */
  613.  
  614. if (IsVoxelNull(Chunk, x - VoxelSize, y, z) && IsVoxelNull(Chunk, x, y - VoxelSize, z) && IsVoxelNull(Chunk, x, y, z - VoxelSize)
  615. && IsVoxelNull(Chunk, x + VoxelSize, y, z) && IsVoxelNull(Chunk, x, y + VoxelSize, z) && IsVoxelNull(Chunk, x, y, z + VoxelSize))
  616. return;
  617.  
  618. if (!IsVoxelNull(Chunk, x + VoxelSize, y, z))
  619. UpdateVoxel(Chunk, x + VoxelSize, y, z);
  620.  
  621. if (!IsVoxelNull(Chunk, x - VoxelSize, y, z))
  622. UpdateVoxel(Chunk, x - VoxelSize, y, z);
  623.  
  624. if (!IsVoxelNull(Chunk, x, y + VoxelSize, z))
  625. UpdateVoxel(Chunk, x, y + VoxelSize, z);
  626.  
  627. if (!IsVoxelNull(Chunk, x, y - VoxelSize, z))
  628. UpdateVoxel(Chunk, x, y - VoxelSize, z);
  629.  
  630. if (!IsVoxelNull(Chunk, x, y, z + VoxelSize))
  631. UpdateVoxel(Chunk, x, y, z + VoxelSize);
  632.  
  633. if (!IsVoxelNull(Chunk, x, y, z - VoxelSize))
  634. UpdateVoxel(Chunk, x, y, z - VoxelSize);
  635. }
  636.  
  637. void AVoxelTerrainActor::ShuffleChunk(FChunk& Chunk)
  638. {
  639. bool s = false;
  640. TArray<FVector> VoxelsShuffled;
  641. do
  642. {
  643. if (FVoxel* Voxel = GetVoxel(Chunk, FMath::RandRange(0, ChunkSize) * VoxelSize + VoxelSize / 2, FMath::RandRange(0, ChunkSize) * VoxelSize + VoxelSize / 2, FMath::RandRange(0, 1023) * VoxelSize + VoxelSize / 2))
  644. {
  645. if (FMath::FRand() > CVarShuffleDensity.GetValueOnGameThread())
  646. {
  647. //DrawDebugPoint(GetWorld(), FVector(x, y, z), 5, FColor::Green, true);
  648. Voxel->Flags = 0x01;
  649. }
  650. else
  651. {
  652. //DrawDebugPoint(GetWorld(), FVector(x, y, z), 5, FColor::Red, true);
  653. Voxel->Flags = 0x00;
  654. }
  655. VoxelsShuffled.Add(Voxel->Position);
  656. s = true;
  657. }
  658. } while (!s);
  659.  
  660. while (!Chunk.CanUpdateVoxels)
  661. {
  662.  
  663. }
  664.  
  665. BuildChunk(Chunk, VoxelsShuffled);
  666.  
  667. GetWorldTimerManager().SetTimer(ShuffleTimerHandle, [this]()
  668. {
  669. ShuffleChunk(Chunks[0]);
  670. }, 1.0f / CVarShuffleFrequency.GetValueOnGameThread(), false);
  671. }
  672.  
  673. FVoxel* AVoxelTerrainActor::GetVoxel(FChunk& Chunk, int x, int y, int z)
  674. {
  675. if (x > (ChunkSize - 1) * VoxelSize + VoxelSize / 2 || y > (ChunkSize - 1) * VoxelSize + VoxelSize / 2 || z > 1023 * VoxelSize + VoxelSize / 2 || z < VoxelSize / 2 || x < VoxelSize / 2 || y < VoxelSize / 2)
  676. return nullptr;
  677.  
  678. /*if (z == 16 * VoxelSize + VoxelSize / 2)
  679. {
  680. const bool n = Chunk.Voxels[z * ChunkSize + y + x / VoxelSize].Flags & 0x01;
  681. if (!n)
  682. UE_LOG(LogTemp, Warning, TEXT("%d, %d, %d : %d"), x, y, z, n);
  683. DrawDebugPoint(GetWorld(), FVector(x, y, z), 5, n ? FColor::Green : FColor::Red, true);
  684. }*/
  685.  
  686. return &Chunk.Voxels[GetVoxelIndex(x, y, z)];
  687. }
  688.  
  689. int32 AVoxelTerrainActor::GetVoxelIndex(int x, int y, int z)
  690. {
  691. return (z - VoxelSize / 2) * VoxelSize + (y - VoxelSize / 2) + (x - VoxelSize / 2) / VoxelSize;
  692. }
  693.  
  694. bool AVoxelTerrainActor::IsVoxelNull(FChunk& Chunk, int x, int y, int z)
  695. {
  696. FVoxel* Voxel = GetVoxel(Chunk, x, y, z);
  697.  
  698. if (!Voxel)
  699. return true;
  700.  
  701. return Voxel->Flags & 0x01;
  702. }
  703.  
  704. uint8 AVoxelTerrainActor::VoxelEnveloped(FChunk& Chunk, int x, int y, int z)
  705. {
  706. /* Not enveloped
  707. * Fully enveloped
  708. * Pos X
  709. * Pos Y
  710. * Pos Z
  711. * Neg X
  712. * Neg Y
  713. * Neg Z
  714. */
  715. uint8 Ret = 0;
  716.  
  717. if (IsVoxelNull(Chunk, x - VoxelSize, y, z) && IsVoxelNull(Chunk, x, y - VoxelSize, z) && IsVoxelNull(Chunk, x, y, z - VoxelSize)
  718. && IsVoxelNull(Chunk, x + VoxelSize, y, z) && IsVoxelNull(Chunk, x, y + VoxelSize, z) && IsVoxelNull(Chunk, x, y, z + VoxelSize))
  719. return 0x01;
  720.  
  721. if (!IsVoxelNull(Chunk, x - VoxelSize, y, z) && !IsVoxelNull(Chunk, x, y - VoxelSize, z) && !IsVoxelNull(Chunk, x, y, z - VoxelSize)
  722. && !IsVoxelNull(Chunk, x + VoxelSize, y, z) && !IsVoxelNull(Chunk, x, y + VoxelSize, z) && !IsVoxelNull(Chunk, x, y, z + VoxelSize))
  723. return 0xFF & 0xFE;
  724.  
  725. if (!IsVoxelNull(Chunk, x + VoxelSize, y, z))
  726. Ret |= 1 << 2;
  727.  
  728. if (!IsVoxelNull(Chunk, x - VoxelSize, y, z))
  729. Ret |= 1 << 5;
  730.  
  731. if (!IsVoxelNull(Chunk, x, y + VoxelSize, z))
  732. Ret |= 1 << 3;
  733.  
  734. if (!IsVoxelNull(Chunk, x, y - VoxelSize, z))
  735. Ret |= 1 << 6;
  736.  
  737. if (!IsVoxelNull(Chunk, x, y, z + VoxelSize))
  738. Ret |= 1 << 4;
  739.  
  740. if (!IsVoxelNull(Chunk, x, y, z - VoxelSize))
  741. Ret |= 1 << 7;
  742.  
  743. return Ret;
  744. }
  745.  
  746. // Called every frame
  747. void AVoxelTerrainActor::Tick(float DeltaTime)
  748. {
  749. Super::Tick(DeltaTime);
  750.  
  751. if (GEngine)
  752. {
  753. GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0.0f, FColor::Blue, FString::Printf(TEXT("Shuffle Frequency: %.3f\nShuffle Density: %.3f"), CVarShuffleFrequency.GetValueOnGameThread(), CVarShuffleDensity.GetValueOnGameThread()));
  754. }
  755. }
  756.  
  757.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement