Advertisement
Guest User

Property of EPIC, All rights reserved

a guest
Oct 30th, 2014
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.     USTRUCT()
  2.     struct FWVertexData
  3.     {
  4.         GENERATED_USTRUCT_BODY()
  5.     public:
  6.    
  7.         float GetSortValue() const
  8.         {
  9.             return mPosition.X + mRowSize * mPosition.Y;
  10.         }
  11.    
  12.         uint32 mRowSize;
  13.         uint32 mIndex;
  14.         FVector mPosition;
  15.     };
  16.    
  17.     inline bool operator<(const FWVertexData& lhs, const FWVertexData& rhs)
  18.     {
  19.         return (lhs.GetSortValue() < rhs.GetSortValue());
  20.     }
  21.    
  22.     UCLASS()
  23.     class SPELLSWORN_API AWLavaActor : public AActor
  24.     {
  25.         GENERATED_UCLASS_BODY()
  26.         virtual void BeginPlay() override;
  27.         virtual void PostInitializeComponents() override;
  28.         virtual void Tick(float DeltaTime) override;
  29.         UPROPERTY()
  30.         class AStaticMeshActor* mLavaActor;
  31.         FStaticMeshComponentLODInfo* mLavaLODInfo;
  32.         TArray<FColor> mColors;
  33.         TArray<FColor> mOriginalColors;
  34.         TArray<float> mLavaValueArray;
  35.         int32 GetRowSize() const { return mRowSize; }
  36.         int32 GetCellSize() const { return mCellSize; }
  37.         TArray<FWVertexData> mVertecies;
  38.     private:
  39.         void RebuildArray();
  40.         void SetColors(const TArray<FColor>& someColors);
  41.         UFUNCTION()
  42.         void ResetColors();
  43.         UPROPERTY(EditAnywhere, Category = "WLavaActor")
  44.         float mMeltRate;
  45.         UPROPERTY(EditAnywhere, Category = "WLavaActor")
  46.         uint8 mMeltWhenNeighborIsBelow;
  47.         int32 mCellSize;
  48.         int32 mRowSize;
  49.     };
  50.    
  51.     AWLavaActor::AWLavaActor(const class FPostConstructInitializeProperties& PCIP)
  52.         : Super(PCIP)
  53.     {
  54.         PrimaryActorTick.bCanEverTick = true;
  55.         mMeltRate = 0.05f;
  56.         mMeltWhenNeighborIsBelow = 127;
  57.     }
  58.    
  59.     void AWLavaActor::BeginPlay()
  60.     {
  61.         Super::BeginPlay();
  62.    
  63.         UWorld* world = GetWorld();
  64.         if (world)
  65.         {
  66.             AWGameState* gameState = world->GetGameState<AWGameState>();
  67.             if (gameState)
  68.             {
  69.                 gameState->mRestartRoundDelegate.AddDynamic(this, &AWLavaActor::ResetColors);
  70.             }
  71.         }
  72.     }
  73.    
  74.     void AWLavaActor::PostInitializeComponents()
  75.     {
  76.         Super::PostInitializeComponents();
  77.         mOriginalColors.Empty();
  78.         mColors.Empty();
  79.         mLavaValueArray.Empty();
  80.         mVertecies.Empty();
  81.         RebuildArray();
  82.     }
  83.    
  84.     void AWLavaActor::ResetColors()
  85.     {
  86.         mColors = mOriginalColors;
  87.         for (int i = 0; i < mColors.Num(); ++i) mLavaValueArray[i] = (float)mColors[i].R;
  88.         SetColors(mOriginalColors);
  89.     }
  90.    
  91.     void AWLavaActor::RebuildArray()
  92.     {
  93.         mLavaActor = nullptr;
  94.    
  95.         for (TActorIterator<AStaticMeshActor> Itr(GetWorld()); Itr; ++Itr)
  96.         {
  97.             if (Itr->ActorHasTag("Lava"))
  98.             {
  99.                 PRINT("Aquiring new reference to LavaActor");
  100.                 mLavaActor = *Itr;
  101.                 break;
  102.             }
  103.         }
  104.    
  105.         if(!mLavaActor)
  106.             UE_LOG(WCastError, Fatal, TEXT(">> No lava actor!"));
  107.    
  108.         auto colorSpreadComponent = mLavaActor->StaticMeshComponent;
  109.         mLavaLODInfo = &colorSpreadComponent->LODData[0];
  110.         mLavaLODInfo->OverrideVertexColors->GetVertexColors(mColors);
  111.         mOriginalColors = mColors;
  112.    
  113.         auto vertexBuffer = &colorSpreadComponent->StaticMesh->RenderData->LODResources[0].PositionVertexBuffer;
  114.         if (!vertexBuffer->IsInitialized())
  115.             UE_LOG(WCastError, Fatal, TEXT(">> vertexBuffer Is not initialized!"));
  116.    
  117.         mRowSize = FMath::FloorToInt(FMath::Sqrt((float)mColors.Num()));
  118.    
  119.         for(uint32 i = 0; i < vertexBuffer->GetNumVertices(); ++i)
  120.         {
  121.             FWVertexData v;
  122.             v.mIndex = i;
  123.             v.mPosition = vertexBuffer->VertexPosition(i) * mLavaActor->GetActorScale();
  124.             v.mRowSize = mRowSize;
  125.             mVertecies.Add(v);
  126.             mLavaValueArray.Add(mColors[i].R);
  127.         }
  128.         mVertecies.Sort();
  129.         mCellSize = abs(mVertecies[0].mPosition.X - mVertecies[1].mPosition.X);
  130.     }
  131.    
  132.     void AWLavaActor::Tick(float DeltaTime)
  133.     {
  134.         Super::Tick(DeltaTime);
  135.         float digressionRate = mMeltRate * DeltaTime;
  136.         int rowSize = (int)FMath::Sqrt((float)mColors.Num());
  137.         for (int32 i = 0; i < mVertecies.Num(); ++i)
  138.         {
  139.             int     /*neighborTL,   */ neighborT,   /*neighborTR,*/
  140.                 neighborL,  /*this*/    neighborR,
  141.                 /*neighborBL,   */ neighborB/*, neighborBR*/;
  142.    
  143.             int x = i % rowSize;
  144.             int y = FMath::FloorToInt(i / rowSize);
  145.             neighborT = rowSize * (y - 1) + (x - 0);
  146.             neighborL = rowSize * (y - 0) + (x - 1);
  147.             neighborR = rowSize * (y - 0) + (x + 1);
  148.             neighborB = rowSize * (y + 1) + (x + 0);
  149.             int     cIndex = mVertecies[i].mIndex,
  150.                 TIndex = neighborT >= 0 ? mVertecies[neighborT].mIndex : -1,
  151.                 LIndex = neighborL >= 0 ? mVertecies[neighborL].mIndex : -1,
  152.                 RIndex = neighborR < mColors.Num() ? mVertecies[neighborR].mIndex : mColors.Num(),
  153.                 BIndex = neighborB < mColors.Num() ? mVertecies[neighborB].mIndex : mColors.Num();
  154.    
  155.             if (    TIndex >= 0 && mColors[TIndex].R <= mMeltWhenNeighborIsBelow ||
  156.                 LIndex >= 0 && mColors[LIndex].R <= mMeltWhenNeighborIsBelow ||
  157.                 RIndex < mColors.Num() && mColors[RIndex].R <= mMeltWhenNeighborIsBelow ||
  158.                 BIndex < mColors.Num() && mColors[BIndex].R <= mMeltWhenNeighborIsBelow)
  159.             {
  160.                 mLavaValueArray[cIndex] -= digressionRate;
  161.                 mColors[cIndex].R = FMath::Clamp<uint8>((uint8)mLavaValueArray[cIndex], mColors[cIndex].B, mColors[cIndex].R);
  162.             }
  163.         }
  164.         SetColors(mColors);
  165.     }
  166.    
  167.     void AWLavaActor::SetColors(const TArray<FColor>& someColors)
  168.     {
  169.         mLavaLODInfo->PaintedVertices.Empty();
  170.         mLavaLODInfo->BeginReleaseOverrideVertexColors();
  171.         mLavaLODInfo->OverrideVertexColors->CleanUp();
  172.         mLavaLODInfo->OverrideVertexColors = new FColorVertexBuffer;
  173.         mLavaLODInfo->OverrideVertexColors->InitFromColorArray(&someColors[0], someColors.Num());
  174.         BeginInitResource(mLavaLODInfo->OverrideVertexColors);
  175.         mLavaActor->StaticMeshComponent->MarkRenderStateDirty();
  176.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement