Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Fill out your copyright notice in the Description page of Project Settings.
- #include "Voxel/VoxelTerrainActor.h"
- #include "DrawDebugHelpers.h"
- #include "ProceduralMeshComponent.h"
- #include "KismetProceduralMeshLibrary.h"
- #include "Components/TextRenderComponent.h"
- void FChunk::SetCanUpdate(FChunk& Chunk, bool NewUpdate)
- {
- Chunk.CanUpdateVoxels = NewUpdate;
- }
- // Sets default values
- AVoxelTerrainActor::AVoxelTerrainActor()
- {
- // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
- PrimaryActorTick.bCanEverTick = true;
- ProceduralMesh = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("Procedural Mesh"));
- ProceduralMesh->bUseAsyncCooking = true;
- }
- // Called when the game starts or when spawned
- void AVoxelTerrainActor::BeginPlay()
- {
- Super::BeginPlay();
- Setup(1.0f);
- GetWorldTimerManager().SetTimer(ShuffleTimerHandle, [this]()
- {
- ShuffleChunk(Chunks[0]);
- }, 1.0f / ShuffleFrequency, false);
- }
- void AVoxelTerrainActor::Setup(float Res)
- {
- for (int i = 0; i < 1; i++)
- {
- auto& Chunk = Chunks.AddDefaulted_GetRef();
- Chunk.Extent = FVector2D(ChunkSize, ChunkSize);
- SetupChunk(Chunk);
- }
- }
- void AVoxelTerrainActor::SetupChunk(FChunk& Chunk)
- {
- Chunk.Voxels.SetNum(ChunkSize * ChunkSize * 1024);
- for (int x = VoxelSize / 2; x < ChunkSize * VoxelSize; x += VoxelSize)
- {
- for (int y = VoxelSize / 2; y < ChunkSize * VoxelSize; y += VoxelSize)
- {
- for (int z = VoxelSize / 2; z < 1024 * VoxelSize; z += VoxelSize)
- {
- FVoxel Vox;
- Vox.Position = FVector(x, y, z);
- if (FMath::FRand() > Density)
- {
- //DrawDebugPoint(GetWorld(), FVector(x, y, z), 5, FColor::Green, true);
- Vox.Flags = 0x01;
- }
- else
- {
- //DrawDebugPoint(GetWorld(), FVector(x, y, z), 5, FColor::Red, true);
- Vox.Flags = 0x00;
- }
- Chunk.Voxels[GetVoxelIndex(x, y, z)] = Vox;
- /*if (x == 0 || x == (ChunkSize - 1) * VoxelSize || y == 0 || y == (ChunkSize - 1) * VoxelSize)
- DrawDebugPoint(GetWorld(), FVector(x, y, z), 2.0f, (z >= 256 * VoxelSize ? FColor::Red : FColor::Green), true);*/
- }
- }
- }
- BuildChunk(Chunk, TArray<FVector>{});
- }
- void AVoxelTerrainActor::BuildChunkMesh(FChunk& Chunk)
- {
- if (!IsInGameThread() || Chunk.CanUpdateVoxels)
- return;
- ProceduralMesh->CreateMeshSection(0, Chunk.Vertices, Chunk.Triangles, Chunk.Normals, Chunk.UVs, TArray<FColor>(), TArray<FProcMeshTangent>(), true);
- if (Material)
- {
- ProceduralMesh->SetMaterial(0, Material);
- }
- FChunk::SetCanUpdate(Chunk, true);
- }
- void AVoxelTerrainActor::BuildChunk(FChunk& Chunk, TArray<FVector> AffectedVoxels)
- {
- AsyncTask(ENamedThreads::AnyHiPriThreadHiPriTask, [this, &Chunk, AffectedVoxels]()
- {
- if (!Chunk.CanUpdateVoxels)
- return;
- FChunk::SetCanUpdate(Chunk, false);
- if (AffectedVoxels.Num() == 0 || !AffectedVoxels.IsValidIndex(0))
- {
- Chunk.Vertices.Empty();
- Chunk.Triangles.Empty();
- Chunk.Normals.Empty();
- Chunk.UVs.Empty();
- for (int x = VoxelSize / 2; x < ChunkSize * VoxelSize; x += VoxelSize)
- {
- for (int y = VoxelSize / 2; y < ChunkSize * VoxelSize; y += VoxelSize)
- {
- for (int z = VoxelSize / 2; z < 1024 * VoxelSize; z += VoxelSize)
- {
- InitialBuildVoxel(Chunk, x, y, z);
- }
- }
- }
- }
- else
- {
- for (auto& Pos : AffectedVoxels)
- {
- if (FVoxel* Voxel = GetVoxel(Chunk, Pos.X, Pos.Y, Pos.Z))
- {
- for (int i = 0; i < Voxel->VertexStartIndexes.Num(); i++)
- {
- const int V = Voxel->VertexStartIndexes[i];
- const int T = Voxel->TriangleStartIndexes[i];
- Chunk.Vertices.RemoveAt(V, 4, false);
- Chunk.Triangles.RemoveAt(T, 6, false);
- Chunk.Normals.RemoveAt(V, 4, false);
- Chunk.UVs.RemoveAt(V, 4, false);
- for (int j = i + 1; j < Voxel->VertexStartIndexes.Num(); j++)
- {
- Voxel->VertexStartIndexes[j] -= 4;
- Voxel->TriangleStartIndexes[j] -= 6;
- }
- }
- UpdateVoxel(Chunk, Voxel);
- }
- }
- }
- AsyncTask(ENamedThreads::GameThread, [this, &Chunk]()
- {
- BuildChunkMesh(Chunk);
- });
- });
- }
- void AVoxelTerrainActor::InitialBuildVoxel(FChunk& Chunk, int x, int y, int z)
- {
- /* Not enveloped
- * Fully enveloped
- * Pos X
- * Pos Y
- * Pos Z
- * Neg X
- * Neg Y
- * Neg Z
- */
- //DrawDebugPoint(GetWorld(), FVector(x, y, z), 2.0f, FColor::Red, true);
- FVoxel* Voxel = GetVoxel(Chunk, x, y, z);
- if (!Voxel)
- return;
- Voxel->VertexStartIndexes.Empty();
- Voxel->TriangleStartIndexes.Empty();
- const uint8 VE = VoxelEnveloped(Chunk, x, y, z);
- if (VE & (1 << 1))
- return;
- if (!(VE & (1 << 2)))
- {
- // pos X
- const int NumVerts = Chunk.Vertices.Num();
- const int NumTris = Chunk.Triangles.Num();
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 0);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 3);
- Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
- Chunk.Normals.Add(FVector(1.0f, 0.0f, 0.0f));
- Chunk.Normals.Add(FVector(1.0f, 0.0f, 0.0f));
- Chunk.Normals.Add(FVector(1.0f, 0.0f, 0.0f));
- Chunk.Normals.Add(FVector(1.0f, 0.0f, 0.0f));
- Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
- Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
- }
- if (!(VE & (1 << 3)))
- {
- // pos Y
- const int NumVerts = Chunk.Vertices.Num();
- const int NumTris = Chunk.Triangles.Num();
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Triangles.Add(NumVerts + 0);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 3);
- Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
- Chunk.Normals.Add(FVector(0.0f, 1.0f, 0.0f));
- Chunk.Normals.Add(FVector(0.0f, 1.0f, 0.0f));
- Chunk.Normals.Add(FVector(0.0f, 1.0f, 0.0f));
- Chunk.Normals.Add(FVector(0.0f, 1.0f, 0.0f));
- Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
- Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
- }
- if (!(VE & (1 << 4)))
- {
- // pos Z
- const int NumVerts = Chunk.Vertices.Num();
- const int NumTris = Chunk.Triangles.Num();
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 0);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 3);
- Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
- Chunk.Normals.Add(FVector(0.0f, 0.0f, 1.0f));
- Chunk.Normals.Add(FVector(0.0f, 0.0f, 1.0f));
- Chunk.Normals.Add(FVector(0.0f, 0.0f, 1.0f));
- Chunk.Normals.Add(FVector(0.0f, 0.0f, 1.0f));
- Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
- Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
- }
- if (!(VE & (1 << 5)))
- {
- // neg X
- const int NumVerts = Chunk.Vertices.Num();
- const int NumTris = Chunk.Triangles.Num();
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Triangles.Add(NumVerts + 0);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 3);
- Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
- Chunk.Normals.Add(FVector(-1.0f, 0.0f, 0.0f));
- Chunk.Normals.Add(FVector(-1.0f, 0.0f, 0.0f));
- Chunk.Normals.Add(FVector(-1.0f, 0.0f, 0.0f));
- Chunk.Normals.Add(FVector(-1.0f, 0.0f, 0.0f));
- Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
- Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
- }
- if (!(VE & (1 << 6)))
- {
- // neg Y
- const int NumVerts = Chunk.Vertices.Num();
- const int NumTris = Chunk.Triangles.Num();
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 0);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 3);
- Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
- Chunk.Normals.Add(FVector(0.0f, -1.0f, 0.0f));
- Chunk.Normals.Add(FVector(0.0f, -1.0f, 0.0f));
- Chunk.Normals.Add(FVector(0.0f, -1.0f, 0.0f));
- Chunk.Normals.Add(FVector(0.0f, -1.0f, 0.0f));
- Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
- Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
- }
- if (!(VE & (1 << 7)))
- {
- // neg Z
- const int NumVerts = Chunk.Vertices.Num();
- const int NumTris = Chunk.Triangles.Num();
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Triangles.Add(NumVerts + 0);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 3);
- Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
- Chunk.Normals.Add(FVector(0.0f, 0.0f, -1.0f));
- Chunk.Normals.Add(FVector(0.0f, 0.0f, -1.0f));
- Chunk.Normals.Add(FVector(0.0f, 0.0f, -1.0f));
- Chunk.Normals.Add(FVector(0.0f, 0.0f, -1.0f));
- Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
- Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
- }
- }
- void AVoxelTerrainActor::UpdateVoxel(FChunk& Chunk, int x, int y, int z)
- {
- /* Not enveloped
- * Fully enveloped
- * Pos X
- * Pos Y
- * Pos Z
- * Neg X
- * Neg Y
- * Neg Z
- */
- //DrawDebugPoint(GetWorld(), FVector(x, y, z), 2.0f, FColor::Red, true);
- FVoxel* Voxel = GetVoxel(Chunk, x, y, z);
- if (!Voxel)
- return;
- if (Voxel->Flags & 0x01)
- BuildAdjacentVoxels(Chunk, x, y, z);
- Voxel->VertexStartIndexes.Empty();
- Voxel->TriangleStartIndexes.Empty();
- const uint8 VE = VoxelEnveloped(Chunk, x, y, z);
- if (VE & (1 << 1))
- return;
- if (!(VE & (1 << 2)))
- {
- // pos X
- const int NumVerts = Chunk.Vertices.Num();
- const int NumTris = Chunk.Triangles.Num();
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 0);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 3);
- Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
- Chunk.Normals.Add(FVector(1.0f, 0.0f, 0.0f));
- Chunk.Normals.Add(FVector(1.0f, 0.0f, 0.0f));
- Chunk.Normals.Add(FVector(1.0f, 0.0f, 0.0f));
- Chunk.Normals.Add(FVector(1.0f, 0.0f, 0.0f));
- Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
- Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
- }
- if (!(VE & (1 << 3)))
- {
- // pos Y
- const int NumVerts = Chunk.Vertices.Num();
- const int NumTris = Chunk.Triangles.Num();
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Triangles.Add(NumVerts + 0);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 3);
- Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
- Chunk.Normals.Add(FVector(0.0f, 1.0f, 0.0f));
- Chunk.Normals.Add(FVector(0.0f, 1.0f, 0.0f));
- Chunk.Normals.Add(FVector(0.0f, 1.0f, 0.0f));
- Chunk.Normals.Add(FVector(0.0f, 1.0f, 0.0f));
- Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
- Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
- }
- if (!(VE & (1 << 4)))
- {
- // pos Z
- const int NumVerts = Chunk.Vertices.Num();
- const int NumTris = Chunk.Triangles.Num();
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 0);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 3);
- Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
- Chunk.Normals.Add(FVector(0.0f, 0.0f, 1.0f));
- Chunk.Normals.Add(FVector(0.0f, 0.0f, 1.0f));
- Chunk.Normals.Add(FVector(0.0f, 0.0f, 1.0f));
- Chunk.Normals.Add(FVector(0.0f, 0.0f, 1.0f));
- Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
- Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
- }
- if (!(VE & (1 << 5)))
- {
- // neg X
- const int NumVerts = Chunk.Vertices.Num();
- const int NumTris = Chunk.Triangles.Num();
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Triangles.Add(NumVerts + 0);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 3);
- Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
- Chunk.Normals.Add(FVector(-1.0f, 0.0f, 0.0f));
- Chunk.Normals.Add(FVector(-1.0f, 0.0f, 0.0f));
- Chunk.Normals.Add(FVector(-1.0f, 0.0f, 0.0f));
- Chunk.Normals.Add(FVector(-1.0f, 0.0f, 0.0f));
- Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
- Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
- }
- if (!(VE & (1 << 6)))
- {
- // neg Y
- const int NumVerts = Chunk.Vertices.Num();
- const int NumTris = Chunk.Triangles.Num();
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z + VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 0);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 3);
- Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
- Chunk.Normals.Add(FVector(0.0f, -1.0f, 0.0f));
- Chunk.Normals.Add(FVector(0.0f, -1.0f, 0.0f));
- Chunk.Normals.Add(FVector(0.0f, -1.0f, 0.0f));
- Chunk.Normals.Add(FVector(0.0f, -1.0f, 0.0f));
- Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
- Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
- }
- if (!(VE & (1 << 7)))
- {
- // neg Z
- const int NumVerts = Chunk.Vertices.Num();
- const int NumTris = Chunk.Triangles.Num();
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x - VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y + VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Vertices.Add(FVector(x + VoxelSize / 2, y - VoxelSize / 2, z - VoxelSize / 2));
- Chunk.Triangles.Add(NumVerts + 0);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 2);
- Chunk.Triangles.Add(NumVerts + 1);
- Chunk.Triangles.Add(NumVerts + 3);
- Chunk.UVs.Add(FVector2D(0.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(0.0f, 1.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 0.0f));
- Chunk.UVs.Add(FVector2D(1.0f, 1.0f));
- Chunk.Normals.Add(FVector(0.0f, 0.0f, -1.0f));
- Chunk.Normals.Add(FVector(0.0f, 0.0f, -1.0f));
- Chunk.Normals.Add(FVector(0.0f, 0.0f, -1.0f));
- Chunk.Normals.Add(FVector(0.0f, 0.0f, -1.0f));
- Voxel->VertexStartIndexes.Add(Chunk.Vertices.Num() - 4);
- Voxel->TriangleStartIndexes.Add(Chunk.Triangles.Num() - 6);
- }
- }
- void AVoxelTerrainActor::UpdateVoxel(FChunk& Chunk, const FVoxel* Voxel)
- {
- UpdateVoxel(Chunk, Voxel->Position.X, Voxel->Position.Y, Voxel->Position.Z);
- }
- void AVoxelTerrainActor::BuildAdjacentVoxels(FChunk& Chunk, int x, int y, int z)
- {
- /* Not enveloped
- * Fully enveloped
- * Pos X
- * Pos Y
- * Pos Z
- * Neg X
- * Neg Y
- * Neg Z
- */
- if (IsVoxelNull(Chunk, x - VoxelSize, y, z) && IsVoxelNull(Chunk, x, y - VoxelSize, z) && IsVoxelNull(Chunk, x, y, z - VoxelSize)
- && IsVoxelNull(Chunk, x + VoxelSize, y, z) && IsVoxelNull(Chunk, x, y + VoxelSize, z) && IsVoxelNull(Chunk, x, y, z + VoxelSize))
- return;
- if (!IsVoxelNull(Chunk, x + VoxelSize, y, z))
- UpdateVoxel(Chunk, x + VoxelSize, y, z);
- if (!IsVoxelNull(Chunk, x - VoxelSize, y, z))
- UpdateVoxel(Chunk, x - VoxelSize, y, z);
- if (!IsVoxelNull(Chunk, x, y + VoxelSize, z))
- UpdateVoxel(Chunk, x, y + VoxelSize, z);
- if (!IsVoxelNull(Chunk, x, y - VoxelSize, z))
- UpdateVoxel(Chunk, x, y - VoxelSize, z);
- if (!IsVoxelNull(Chunk, x, y, z + VoxelSize))
- UpdateVoxel(Chunk, x, y, z + VoxelSize);
- if (!IsVoxelNull(Chunk, x, y, z - VoxelSize))
- UpdateVoxel(Chunk, x, y, z - VoxelSize);
- }
- void AVoxelTerrainActor::ShuffleChunk(FChunk& Chunk)
- {
- bool s = false;
- TArray<FVector> VoxelsShuffled;
- do
- {
- 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))
- {
- if (FMath::FRand() > CVarShuffleDensity.GetValueOnGameThread())
- {
- //DrawDebugPoint(GetWorld(), FVector(x, y, z), 5, FColor::Green, true);
- Voxel->Flags = 0x01;
- }
- else
- {
- //DrawDebugPoint(GetWorld(), FVector(x, y, z), 5, FColor::Red, true);
- Voxel->Flags = 0x00;
- }
- VoxelsShuffled.Add(Voxel->Position);
- s = true;
- }
- } while (!s);
- while (!Chunk.CanUpdateVoxels)
- {
- }
- BuildChunk(Chunk, VoxelsShuffled);
- GetWorldTimerManager().SetTimer(ShuffleTimerHandle, [this]()
- {
- ShuffleChunk(Chunks[0]);
- }, 1.0f / CVarShuffleFrequency.GetValueOnGameThread(), false);
- }
- FVoxel* AVoxelTerrainActor::GetVoxel(FChunk& Chunk, int x, int y, int z)
- {
- 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)
- return nullptr;
- /*if (z == 16 * VoxelSize + VoxelSize / 2)
- {
- const bool n = Chunk.Voxels[z * ChunkSize + y + x / VoxelSize].Flags & 0x01;
- if (!n)
- UE_LOG(LogTemp, Warning, TEXT("%d, %d, %d : %d"), x, y, z, n);
- DrawDebugPoint(GetWorld(), FVector(x, y, z), 5, n ? FColor::Green : FColor::Red, true);
- }*/
- return &Chunk.Voxels[GetVoxelIndex(x, y, z)];
- }
- int32 AVoxelTerrainActor::GetVoxelIndex(int x, int y, int z)
- {
- return (z - VoxelSize / 2) * VoxelSize + (y - VoxelSize / 2) + (x - VoxelSize / 2) / VoxelSize;
- }
- bool AVoxelTerrainActor::IsVoxelNull(FChunk& Chunk, int x, int y, int z)
- {
- FVoxel* Voxel = GetVoxel(Chunk, x, y, z);
- if (!Voxel)
- return true;
- return Voxel->Flags & 0x01;
- }
- uint8 AVoxelTerrainActor::VoxelEnveloped(FChunk& Chunk, int x, int y, int z)
- {
- /* Not enveloped
- * Fully enveloped
- * Pos X
- * Pos Y
- * Pos Z
- * Neg X
- * Neg Y
- * Neg Z
- */
- uint8 Ret = 0;
- if (IsVoxelNull(Chunk, x - VoxelSize, y, z) && IsVoxelNull(Chunk, x, y - VoxelSize, z) && IsVoxelNull(Chunk, x, y, z - VoxelSize)
- && IsVoxelNull(Chunk, x + VoxelSize, y, z) && IsVoxelNull(Chunk, x, y + VoxelSize, z) && IsVoxelNull(Chunk, x, y, z + VoxelSize))
- return 0x01;
- if (!IsVoxelNull(Chunk, x - VoxelSize, y, z) && !IsVoxelNull(Chunk, x, y - VoxelSize, z) && !IsVoxelNull(Chunk, x, y, z - VoxelSize)
- && !IsVoxelNull(Chunk, x + VoxelSize, y, z) && !IsVoxelNull(Chunk, x, y + VoxelSize, z) && !IsVoxelNull(Chunk, x, y, z + VoxelSize))
- return 0xFF & 0xFE;
- if (!IsVoxelNull(Chunk, x + VoxelSize, y, z))
- Ret |= 1 << 2;
- if (!IsVoxelNull(Chunk, x - VoxelSize, y, z))
- Ret |= 1 << 5;
- if (!IsVoxelNull(Chunk, x, y + VoxelSize, z))
- Ret |= 1 << 3;
- if (!IsVoxelNull(Chunk, x, y - VoxelSize, z))
- Ret |= 1 << 6;
- if (!IsVoxelNull(Chunk, x, y, z + VoxelSize))
- Ret |= 1 << 4;
- if (!IsVoxelNull(Chunk, x, y, z - VoxelSize))
- Ret |= 1 << 7;
- return Ret;
- }
- // Called every frame
- void AVoxelTerrainActor::Tick(float DeltaTime)
- {
- Super::Tick(DeltaTime);
- if (GEngine)
- {
- GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0.0f, FColor::Blue, FString::Printf(TEXT("Shuffle Frequency: %.3f\nShuffle Density: %.3f"), CVarShuffleFrequency.GetValueOnGameThread(), CVarShuffleDensity.GetValueOnGameThread()));
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement