Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 21 additions & 13 deletions Plugins/BrickGrid/Source/BrickGrid/Classes/BrickGridComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace BrickGridConstants
{
enum { MaxBricksPerRegionAxisLog2 = 7 };
enum { MaxBricksPerRegionAxis = 1 << MaxBricksPerRegionAxisLog2 };
enum { MaxBricksPerRegionAxis = 1 << MaxBricksPerRegionAxisLog2 };
};

/** Shifts a number right with sign extension. */
Expand All @@ -26,19 +26,27 @@ inline int32 SignedShiftRight(int32 A,int32 B)
#endif
}

UENUM(BlueprintType)
enum class EBrickFace : uint8
{
BF_PlusZ UMETA(DisplayName = "PlusZ"),
BF_MinusZ UMETA(DisplayName = "MinusZ"),
BF_PlusX UMETA(DisplayName = "PlusX"),
BF_MinusX UMETA(DisplayName = "MinusX"),
BF_PlusY UMETA(DisplayName = "PlusY"),
BF_MinusY UMETA(DisplayName = "MinusY")
};

/** Information about a brick material. */
USTRUCT(BlueprintType)
struct FBrickMaterial
{
GENERATED_USTRUCT_BODY()
GENERATED_USTRUCT_BODY()

UPROPERTY(EditAnywhere,BlueprintReadWrite,Category = Bricks)
class UMaterialInterface* SurfaceMaterial;

UPROPERTY(EditAnywhere,BlueprintReadWrite,Category = Bricks)
class UMaterialInterface* OverrideTopSurfaceMaterial;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Bricks)
TArray<class UMaterialInterface*> FaceMaterials;

FBrickMaterial() : SurfaceMaterial(NULL), OverrideTopSurfaceMaterial(NULL) {}
FBrickMaterial() {}
};

/** Information about a brick. */
Expand Down Expand Up @@ -157,7 +165,7 @@ struct FBrickRegion

// Contains the material index for each brick, stored in an 8-bit integer.
UPROPERTY()
TArray<uint8> BrickContents;
TArray<uint16> BrickContents;

// Contains the occupied brick with highest Z in this region for each XY coordinate in the region. -1 means no non-empty bricks in this region at that XY.
TArray<int8> MaxNonEmptyBrickRegionZs;
Expand All @@ -170,11 +178,11 @@ struct FBrickGridParameters
GENERATED_USTRUCT_BODY()

// The materials to render for each brick material.
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Materials)
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Materials)
TArray<FBrickMaterial> Materials;

// The material index that means "empty".
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Materials)
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Materials)
int32 EmptyMaterialIndex;

// The number of bricks along each axis of a region is 2^BricksPerChunkLog2
Expand Down Expand Up @@ -242,8 +250,8 @@ class UBrickGridComponent : public USceneComponent
UFUNCTION(BlueprintCallable,Category = "Brick Grid")
BRICKGRID_API FBrick GetBrick(const FInt3& BrickCoordinates) const;

BRICKGRID_API void GetBrickMaterialArray(const FInt3& MinBrickCoordinates,const FInt3& MaxBrickCoordinates,TArray<uint8>& OutBrickMaterials) const;
BRICKGRID_API void SetBrickMaterialArray(const FInt3& MinBrickCoordinates,const FInt3& MaxBrickCoordinates,const TArray<uint8>& BrickMaterials);
BRICKGRID_API void GetBrickMaterialArray(const FInt3& MinBrickCoordinates,const FInt3& MaxBrickCoordinates,TArray<uint16>& OutBrickMaterials) const;
BRICKGRID_API void SetBrickMaterialArray(const FInt3& MinBrickCoordinates,const FInt3& MaxBrickCoordinates,const TArray<uint16>& BrickMaterials);

// Returns a height-map containing the non-empty brick with greatest Z for each XY in the rectangle bounded by MinBrickCoordinates.XY-MaxBrickCoordinates.XY.
// The returned heights are relative to MinBrickCoordinates.Z, but MaxBrickCoordinates.Z is ignored.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ static void ComputeChunkAO(
const FInt3 LocalBrickExpansion,
const FInt3 LocalBricksDim,
const FInt3 LocalVertexDim,
const TArray<uint8>& LocalBrickMaterials,
const TArray<uint16>& LocalBrickMaterials,
TArray<uint8>& OutLocalVertexAmbientFactors
)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ static const FInt3 FaceNormals[6] =
FInt3(0, 0, +1)
};

UBrickCollisionComponent::UBrickCollisionComponent( const FPostConstructInitializeProperties& PCIP )
UBrickCollisionComponent::UBrickCollisionComponent(const FObjectInitializer& PCIP)
: Super( PCIP )
{
PrimaryComponentTick.bCanEverTick = false;
Expand Down Expand Up @@ -65,7 +65,7 @@ void UBrickCollisionComponent::UpdateCollisionBody()

// Read the brick materials for all the bricks that affect this chunk.
const FInt3 LocalBricksDim = Grid->BricksPerCollisionChunk + LocalBrickExpansion * FInt3::Scalar(2);
TArray<uint8> LocalBrickMaterials;
TArray<uint16> LocalBrickMaterials;
LocalBrickMaterials.Init(LocalBricksDim.X * LocalBricksDim.Y * LocalBricksDim.Z);
Grid->GetBrickMaterialArray(MinLocalBrickCoordinates,MinLocalBrickCoordinates + LocalBricksDim - FInt3::Scalar(1),LocalBrickMaterials);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ FBrick UBrickGridComponent::GetBrick(const FInt3& BrickCoordinates) const
return FBrick(Parameters.EmptyMaterialIndex);
}

void UBrickGridComponent::GetBrickMaterialArray(const FInt3& MinBrickCoordinates,const FInt3& MaxBrickCoordinates,TArray<uint8>& OutBrickMaterials) const
void UBrickGridComponent::GetBrickMaterialArray(const FInt3& MinBrickCoordinates,const FInt3& MaxBrickCoordinates,TArray<uint16>& OutBrickMaterials) const
{
const FInt3 OutputSize = MaxBrickCoordinates - MinBrickCoordinates + FInt3::Scalar(1);
const FInt3 MinRegionCoordinates = BrickToRegionCoordinates(MinBrickCoordinates);
Expand Down Expand Up @@ -123,11 +123,11 @@ void UBrickGridComponent::GetBrickMaterialArray(const FInt3& MinBrickCoordinates
const uint32 RegionBaseBrickIndex = (((RegionBrickY << Parameters.BricksPerRegionLog2.X) + RegionBrickX) << Parameters.BricksPerRegionLog2.Z) + MinOutputRegionBrickCoordinates.Z;
if(RegionIndex)
{
FMemory::Memcpy(&OutBrickMaterials[OutputBaseBrickIndex],&Regions[*RegionIndex].BrickContents[RegionBaseBrickIndex],OutputSizeZ * sizeof(uint8));
FMemory::Memcpy(&OutBrickMaterials[OutputBaseBrickIndex], &Regions[*RegionIndex].BrickContents[RegionBaseBrickIndex], OutputSizeZ * sizeof(OutBrickMaterials[0]));
}
else
{
FMemory::Memset(&OutBrickMaterials[OutputBaseBrickIndex],Parameters.EmptyMaterialIndex,OutputSizeZ * sizeof(uint8));
FMemory::Memset(&OutBrickMaterials[OutputBaseBrickIndex], Parameters.EmptyMaterialIndex, OutputSizeZ * sizeof(OutBrickMaterials[0]));
}
}
}
Expand All @@ -136,7 +136,7 @@ void UBrickGridComponent::GetBrickMaterialArray(const FInt3& MinBrickCoordinates
}
}

void UBrickGridComponent::SetBrickMaterialArray(const FInt3& MinBrickCoordinates,const FInt3& MaxBrickCoordinates,const TArray<uint8>& BrickMaterials)
void UBrickGridComponent::SetBrickMaterialArray(const FInt3& MinBrickCoordinates, const FInt3& MaxBrickCoordinates, const TArray<uint16>& BrickMaterials)
{
const FInt3 InputSize = MaxBrickCoordinates - MinBrickCoordinates + FInt3::Scalar(1);
const FInt3 MinRegionCoordinates = BrickToRegionCoordinates(MinBrickCoordinates);
Expand Down Expand Up @@ -164,7 +164,7 @@ void UBrickGridComponent::SetBrickMaterialArray(const FInt3& MinBrickCoordinates
const uint32 RegionBaseBrickIndex = (((RegionBrickY << Parameters.BricksPerRegionLog2.X) + RegionBrickX) << Parameters.BricksPerRegionLog2.Z) + MinInputRegionBrickCoordinates.Z;
if(RegionIndex)
{
FMemory::Memcpy(&Regions[*RegionIndex].BrickContents[RegionBaseBrickIndex],&BrickMaterials[InputBaseBrickIndex],InputSizeZ * sizeof(uint8));
FMemory::Memcpy(&Regions[*RegionIndex].BrickContents[RegionBaseBrickIndex], &BrickMaterials[InputBaseBrickIndex], InputSizeZ * sizeof(BrickMaterials[0]));
}
}
}
Expand Down Expand Up @@ -519,7 +519,7 @@ FBrickGridParameters::FBrickGridParameters()
Materials.Add(FBrickMaterial());
}

UBrickGridComponent::UBrickGridComponent(const FPostConstructInitializeProperties& PCIP)
UBrickGridComponent::UBrickGridComponent(const FObjectInitializer& PCIP)
: Super( PCIP )
{
PrimaryComponentTick.bStartWithTickEnabled =true;
Expand Down
45 changes: 22 additions & 23 deletions Plugins/BrickGrid/Source/BrickGrid/Private/BrickRenderComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class FBrickChunkVertexBuffer : public FVertexBuffer
VertexBufferRHI = RHICreateVertexBuffer(Vertices.Num() * sizeof(FBrickVertex), BUF_Dynamic, CreateInfo);
// Copy the vertex data into the vertex buffer.
void* VertexBufferData = RHILockVertexBuffer(VertexBufferRHI, 0, Vertices.Num() * sizeof(FBrickVertex), RLM_WriteOnly);
FMemory::Memcpy(VertexBufferData, Vertices.GetTypedData(), Vertices.Num() * sizeof(FBrickVertex));
FMemory::Memcpy(VertexBufferData, Vertices.GetData(), Vertices.Num() * sizeof(FBrickVertex));
RHIUnlockVertexBuffer(VertexBufferRHI);
}
}
Expand All @@ -78,7 +78,7 @@ class FBrickChunkIndexBuffer : public FIndexBuffer
IndexBufferRHI = RHICreateIndexBuffer(sizeof(uint16), Indices.Num() * sizeof(uint16), BUF_Static, CreateInfo);
// Write the indices to the index buffer.
void* Buffer = RHILockIndexBuffer(IndexBufferRHI, 0, Indices.Num() * sizeof(uint16), RLM_WriteOnly);
FMemory::Memcpy(Buffer, Indices.GetTypedData(), Indices.Num() * sizeof(uint16));
FMemory::Memcpy(Buffer, Indices.GetData(), Indices.Num() * sizeof(uint16));
RHIUnlockIndexBuffer(IndexBufferRHI);
}
}
Expand Down Expand Up @@ -190,7 +190,7 @@ class FBrickChunkSceneProxy : public FPrimitiveSceneProxy
PrimitiveUniformBuffer = CreatePrimitiveUniformBufferImmediate(FScaleMatrix(FVector(255, 255, 255)) * GetLocalToWorld(), GetBounds(), GetLocalBounds(), true, UseEditorDepthTest());
}

virtual void DrawDynamicElements(FPrimitiveDrawInterface* PDI,const FSceneView* View) override
virtual void DrawDynamicElements(FPrimitiveDrawInterface* PDI,const FSceneView* View)
{
// Set up the wireframe material Face.
FColoredMaterialRenderProxy WireframeMaterialFace(
Expand Down Expand Up @@ -318,7 +318,7 @@ class FBrickChunkSceneProxy : public FPrimitiveSceneProxy
}
};

UBrickRenderComponent::UBrickRenderComponent( const FPostConstructInitializeProperties& PCIP )
UBrickRenderComponent::UBrickRenderComponent(const FObjectInitializer& PCIP)
: Super( PCIP )
{
PrimaryComponentTick.bCanEverTick = false;
Expand Down Expand Up @@ -354,7 +354,7 @@ FPrimitiveSceneProxy* UBrickRenderComponent::CreateSceneProxy()

// Read the brick materials for all the bricks that affect this chunk.
const FInt3 LocalBricksDim = Grid->BricksPerRenderChunk + LocalBrickExpansion * FInt3::Scalar(2);
TArray<uint8> LocalBrickMaterials;
TArray<uint16> LocalBrickMaterials;
LocalBrickMaterials.Init(LocalBricksDim.X * LocalBricksDim.Y * LocalBricksDim.Z);
Grid->GetBrickMaterialArray(MinLocalBrickCoordinates,MinLocalBrickCoordinates + LocalBricksDim - FInt3::Scalar(1),LocalBrickMaterials);

Expand Down Expand Up @@ -440,7 +440,7 @@ FPrimitiveSceneProxy* UBrickRenderComponent::CreateSceneProxy()
{
// Only draw faces of bricks that aren't empty.
const uint32 LocalBrickIndex = (LocalBrickY * LocalBricksDim.X + LocalBrickX) * LocalBricksDim.Z + LocalBrickZ;
const uint8 BrickMaterial = LocalBrickMaterials[LocalBrickIndex];
const uint16 BrickMaterial = LocalBrickMaterials[LocalBrickIndex];
if (BrickMaterial != EmptyMaterialIndex)
{
const FInt3 RelativeBrickCoordinates = FInt3(LocalBrickX,LocalBrickY,LocalBrickZ) - LocalBrickExpansion;
Expand Down Expand Up @@ -488,32 +488,31 @@ FPrimitiveSceneProxy* UBrickRenderComponent::CreateSceneProxy()
}
}
SceneProxy->IndexBuffer.Indices.Empty(NumIndices);
for(int32 BrickMaterialIndex = 0; BrickMaterialIndex < MaterialBatches.Num(); ++BrickMaterialIndex)
{
UMaterialInterface* SurfaceMaterial = Grid->Parameters.Materials[BrickMaterialIndex].SurfaceMaterial;
if(SurfaceMaterial == NULL)
{
SurfaceMaterial = UMaterial::GetDefaultMaterial(MD_Surface);
}
SceneProxy->MaterialRelevance |= SurfaceMaterial->GetRelevance_Concurrent(GetScene()->GetFeatureLevel());
const int32 ProxyMaterialIndex = SceneProxy->Materials.AddUnique(SurfaceMaterial);

UMaterialInterface* OverrideTopSurfaceMaterial = Grid->Parameters.Materials[BrickMaterialIndex].OverrideTopSurfaceMaterial;
if(OverrideTopSurfaceMaterial)
{
SceneProxy->MaterialRelevance |= OverrideTopSurfaceMaterial->GetRelevance_Concurrent(GetScene()->GetFeatureLevel());
}
const int32 TopProxyMaterialIndex = OverrideTopSurfaceMaterial ? SceneProxy->Materials.AddUnique(OverrideTopSurfaceMaterial) : ProxyMaterialIndex;
UMaterialInterface* defaultMaterial = UMaterial::GetDefaultMaterial(MD_Surface);

// Setup materials for the faces
for(int32 BrickMaterialIndex = 0; BrickMaterialIndex < MaterialBatches.Num(); ++BrickMaterialIndex)
{
TArray<class UMaterialInterface*>& faceMaterials = Grid->Parameters.Materials[BrickMaterialIndex].FaceMaterials;
for(uint32 FaceIndex = 0;FaceIndex < 6;++FaceIndex)
{
{
UMaterialInterface* faceMaterial = (faceMaterials.Num() > 0) ? faceMaterials[0] : defaultMaterial;
if (faceMaterials.Num() > 0 && FaceIndex < (uint32)(faceMaterials.Num()))
{
faceMaterial = faceMaterials[FaceIndex];
}
auto relevance = faceMaterial->GetRelevance(GetScene()->GetFeatureLevel());
SceneProxy->MaterialRelevance |= relevance;

const int32 ProxyMaterialIndex = SceneProxy->Materials.AddUnique(faceMaterial);
const FFaceBatch& FaceBatch = MaterialBatches[BrickMaterialIndex].FaceBatches[FaceIndex];
if (FaceBatch.Indices.Num() > 0)
{
FBrickChunkSceneProxy::FElement& Element = *new(SceneProxy->Elements)FBrickChunkSceneProxy::FElement;
Element.FirstIndex = SceneProxy->IndexBuffer.Indices.Num();
Element.NumPrimitives = FaceBatch.Indices.Num() / 3;
Element.MaterialIndex = FaceIndex == 5 ? TopProxyMaterialIndex : ProxyMaterialIndex;
Element.MaterialIndex = ProxyMaterialIndex;
Element.FaceIndex = FaceIndex;

// Append the batch's indices to the index buffer.
Expand Down