Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- USTRUCT()
- struct FWVertexData
- {
- GENERATED_USTRUCT_BODY()
- public:
- float GetSortValue() const
- {
- return mPosition.X + mRowSize * mPosition.Y;
- }
- uint32 mRowSize;
- uint32 mIndex;
- FVector mPosition;
- };
- inline bool operator<(const FWVertexData& lhs, const FWVertexData& rhs)
- {
- return (lhs.GetSortValue() < rhs.GetSortValue());
- }
- UCLASS()
- class SPELLSWORN_API AWLavaActor : public AActor
- {
- GENERATED_UCLASS_BODY()
- virtual void BeginPlay() override;
- virtual void PostInitializeComponents() override;
- virtual void Tick(float DeltaTime) override;
- UPROPERTY()
- class AStaticMeshActor* mLavaActor;
- FStaticMeshComponentLODInfo* mLavaLODInfo;
- TArray<FColor> mColors;
- TArray<FColor> mOriginalColors;
- TArray<float> mLavaValueArray;
- int32 GetRowSize() const { return mRowSize; }
- int32 GetCellSize() const { return mCellSize; }
- TArray<FWVertexData> mVertecies;
- private:
- void RebuildArray();
- void SetColors(const TArray<FColor>& someColors);
- UFUNCTION()
- void ResetColors();
- UPROPERTY(EditAnywhere, Category = "WLavaActor")
- float mMeltRate;
- UPROPERTY(EditAnywhere, Category = "WLavaActor")
- uint8 mMeltWhenNeighborIsBelow;
- int32 mCellSize;
- int32 mRowSize;
- };
- AWLavaActor::AWLavaActor(const class FPostConstructInitializeProperties& PCIP)
- : Super(PCIP)
- {
- PrimaryActorTick.bCanEverTick = true;
- mMeltRate = 0.05f;
- mMeltWhenNeighborIsBelow = 127;
- }
- void AWLavaActor::BeginPlay()
- {
- Super::BeginPlay();
- UWorld* world = GetWorld();
- if (world)
- {
- AWGameState* gameState = world->GetGameState<AWGameState>();
- if (gameState)
- {
- gameState->mRestartRoundDelegate.AddDynamic(this, &AWLavaActor::ResetColors);
- }
- }
- }
- void AWLavaActor::PostInitializeComponents()
- {
- Super::PostInitializeComponents();
- mOriginalColors.Empty();
- mColors.Empty();
- mLavaValueArray.Empty();
- mVertecies.Empty();
- RebuildArray();
- }
- void AWLavaActor::ResetColors()
- {
- mColors = mOriginalColors;
- for (int i = 0; i < mColors.Num(); ++i) mLavaValueArray[i] = (float)mColors[i].R;
- SetColors(mOriginalColors);
- }
- void AWLavaActor::RebuildArray()
- {
- mLavaActor = nullptr;
- for (TActorIterator<AStaticMeshActor> Itr(GetWorld()); Itr; ++Itr)
- {
- if (Itr->ActorHasTag("Lava"))
- {
- PRINT("Aquiring new reference to LavaActor");
- mLavaActor = *Itr;
- break;
- }
- }
- if(!mLavaActor)
- UE_LOG(WCastError, Fatal, TEXT(">> No lava actor!"));
- auto colorSpreadComponent = mLavaActor->StaticMeshComponent;
- mLavaLODInfo = &colorSpreadComponent->LODData[0];
- mLavaLODInfo->OverrideVertexColors->GetVertexColors(mColors);
- mOriginalColors = mColors;
- auto vertexBuffer = &colorSpreadComponent->StaticMesh->RenderData->LODResources[0].PositionVertexBuffer;
- if (!vertexBuffer->IsInitialized())
- UE_LOG(WCastError, Fatal, TEXT(">> vertexBuffer Is not initialized!"));
- mRowSize = FMath::FloorToInt(FMath::Sqrt((float)mColors.Num()));
- for(uint32 i = 0; i < vertexBuffer->GetNumVertices(); ++i)
- {
- FWVertexData v;
- v.mIndex = i;
- v.mPosition = vertexBuffer->VertexPosition(i) * mLavaActor->GetActorScale();
- v.mRowSize = mRowSize;
- mVertecies.Add(v);
- mLavaValueArray.Add(mColors[i].R);
- }
- mVertecies.Sort();
- mCellSize = abs(mVertecies[0].mPosition.X - mVertecies[1].mPosition.X);
- }
- void AWLavaActor::Tick(float DeltaTime)
- {
- Super::Tick(DeltaTime);
- float digressionRate = mMeltRate * DeltaTime;
- int rowSize = (int)FMath::Sqrt((float)mColors.Num());
- for (int32 i = 0; i < mVertecies.Num(); ++i)
- {
- int /*neighborTL, */ neighborT, /*neighborTR,*/
- neighborL, /*this*/ neighborR,
- /*neighborBL, */ neighborB/*, neighborBR*/;
- int x = i % rowSize;
- int y = FMath::FloorToInt(i / rowSize);
- neighborT = rowSize * (y - 1) + (x - 0);
- neighborL = rowSize * (y - 0) + (x - 1);
- neighborR = rowSize * (y - 0) + (x + 1);
- neighborB = rowSize * (y + 1) + (x + 0);
- int cIndex = mVertecies[i].mIndex,
- TIndex = neighborT >= 0 ? mVertecies[neighborT].mIndex : -1,
- LIndex = neighborL >= 0 ? mVertecies[neighborL].mIndex : -1,
- RIndex = neighborR < mColors.Num() ? mVertecies[neighborR].mIndex : mColors.Num(),
- BIndex = neighborB < mColors.Num() ? mVertecies[neighborB].mIndex : mColors.Num();
- if ( TIndex >= 0 && mColors[TIndex].R <= mMeltWhenNeighborIsBelow ||
- LIndex >= 0 && mColors[LIndex].R <= mMeltWhenNeighborIsBelow ||
- RIndex < mColors.Num() && mColors[RIndex].R <= mMeltWhenNeighborIsBelow ||
- BIndex < mColors.Num() && mColors[BIndex].R <= mMeltWhenNeighborIsBelow)
- {
- mLavaValueArray[cIndex] -= digressionRate;
- mColors[cIndex].R = FMath::Clamp<uint8>((uint8)mLavaValueArray[cIndex], mColors[cIndex].B, mColors[cIndex].R);
- }
- }
- SetColors(mColors);
- }
- void AWLavaActor::SetColors(const TArray<FColor>& someColors)
- {
- mLavaLODInfo->PaintedVertices.Empty();
- mLavaLODInfo->BeginReleaseOverrideVertexColors();
- mLavaLODInfo->OverrideVertexColors->CleanUp();
- mLavaLODInfo->OverrideVertexColors = new FColorVertexBuffer;
- mLavaLODInfo->OverrideVertexColors->InitFromColorArray(&someColors[0], someColors.Num());
- BeginInitResource(mLavaLODInfo->OverrideVertexColors);
- mLavaActor->StaticMeshComponent->MarkRenderStateDirty();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement