Procedural Rivers Generator - rought funtionality
This commit is contained in:
parent
3b7675e021
commit
0edc8c3c1b
Binary file not shown.
|
@ -0,0 +1,173 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma de Barcelona (UAB). This work is licensed under the terms of the MIT license. For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
|
||||
#include "ProceduralWaterManager.h"
|
||||
|
||||
#include "Components/SplineComponent.h"
|
||||
#include "FileHelpers.h"
|
||||
#include "Misc/FileHelper.h"
|
||||
#include "Misc/CString.h"
|
||||
#include "Runtime/Engine/Public/DrawDebugHelpers.h"
|
||||
#include "UnrealString.h"
|
||||
|
||||
#include "Actor.h"
|
||||
#include "Engine/World.h"
|
||||
#include "UObject/ConstructorHelpers.h"
|
||||
|
||||
// #define DEBUG_MSG(x, ...) if(GEngine){GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::White, FString::Printf(TEXT(x), __VA_ARGS__));}
|
||||
|
||||
// Sets default values
|
||||
UProceduralWaterManager::UProceduralWaterManager()
|
||||
{
|
||||
// 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;
|
||||
// static ConstructorHelpers::FObjectFinder<UBlueprint> DummyBlueprint(TEXT("Blueprint'/CarlaTools/ProceduralWaterManager/DummyActor.DummyActor'"));
|
||||
// if (DummyBlueprint.Object){
|
||||
// MyDummyBlueprint = (UClass*)DummyBlueprint.Object->GeneratedClass;
|
||||
// }
|
||||
static ConstructorHelpers::FObjectFinder<UBlueprint> RiverBlueprint(TEXT("Blueprint'/Game/racer-sim/Blueprints/Water/BP_River.BP_River'"));
|
||||
if (RiverBlueprint.Object){
|
||||
RiverBlueprintClass = (UClass*)RiverBlueprint.Object->GeneratedClass;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
FString UProceduralWaterManager::StartWaterGeneration(const FProceduralRiversMetaInfo metaInfo)
|
||||
{
|
||||
FString errorMsg;
|
||||
|
||||
const FString WaterInfoPath = metaInfo.WaterInfoPath;
|
||||
if(!FPlatformFileManager::Get().GetPlatformFile().FileExists(*WaterInfoPath))
|
||||
{
|
||||
errorMsg = "File Not Found!! :(";
|
||||
DEBUG_MSG("File Not Found!! :(");
|
||||
return errorMsg;
|
||||
}
|
||||
|
||||
TArray<FString> file;
|
||||
FFileHelper::LoadFileToStringArray(file, *WaterInfoPath);
|
||||
|
||||
TArray<FSplinePoint> riverPoints;
|
||||
|
||||
float inputKeyCount = 0.0f;
|
||||
int iterationNumber = 0;
|
||||
|
||||
AActor* riverActor = nullptr;
|
||||
|
||||
FString x_str, y_str;
|
||||
FVector previusPosition(NAN, NAN, NAN);
|
||||
|
||||
float scaleFactor = metaInfo.CustomScaleFactor;
|
||||
FVector locationOffset(0,0,0);
|
||||
|
||||
for(FString line : file)
|
||||
{
|
||||
if(line == "# _")
|
||||
{
|
||||
// Important IF to add last point for every spline
|
||||
// Uses data from previus iteration
|
||||
if(iterationNumber != 0 && iterationNumber != -1)
|
||||
{
|
||||
// Add Last point to river spline
|
||||
FSplinePoint location(inputKeyCount, previusPosition);
|
||||
if(riverActor != nullptr)
|
||||
AddRiverPointFromCode(riverActor, location); // Last Point
|
||||
CheckAndReverseWaterFlow(riverActor);
|
||||
}
|
||||
|
||||
riverActor = SpawnRiverBlueprintActor();
|
||||
inputKeyCount = 0.0f;
|
||||
iterationNumber = -1; // Wildcard value used for headers
|
||||
}
|
||||
else{
|
||||
if(!line.Split(TEXT(" "), &y_str, &x_str))
|
||||
{
|
||||
return "Erroorrrrr";
|
||||
}
|
||||
|
||||
float positionX = scaleFactor*FCString::Atof(*x_str);
|
||||
float positionY = scaleFactor*FCString::Atof(*y_str);
|
||||
float positionZ;
|
||||
|
||||
if(metaInfo.CustomHeight > -100000000.0f)
|
||||
positionZ = metaInfo.CustomHeight;
|
||||
else
|
||||
positionZ = GetLandscapeSurfaceHeight(positionX, positionY, false);
|
||||
|
||||
FVector position(positionX, positionY, positionZ);
|
||||
|
||||
|
||||
position += metaInfo.CustomLocationOffset;
|
||||
|
||||
if((iterationNumber % metaInfo.CustomSampling) == 0){
|
||||
FSplinePoint newPoint(inputKeyCount, position);
|
||||
newPoint.Scale = FVector(1.0f, 2.5f, 1.0f);
|
||||
if(riverActor != nullptr)
|
||||
AddRiverPointFromCode(riverActor, newPoint);
|
||||
inputKeyCount += 1.0f;
|
||||
}
|
||||
previusPosition = position;
|
||||
}
|
||||
iterationNumber++;
|
||||
}
|
||||
|
||||
return "Successfully processed";
|
||||
}
|
||||
|
||||
AActor* UProceduralWaterManager::SpawnRiverBlueprintActor()
|
||||
{
|
||||
|
||||
FVector location(0, 0, 0);
|
||||
FRotator rotation(0,0,0);
|
||||
FActorSpawnParameters spawnInfo;
|
||||
|
||||
UWorld* World = GetWorld();
|
||||
AActor* riverActor = World->SpawnActor<AActor>(RiverBlueprintClass, location, rotation, spawnInfo);
|
||||
|
||||
return riverActor;
|
||||
}
|
||||
|
||||
float UProceduralWaterManager::GetLandscapeSurfaceHeight(float x, float y, bool bDrawDebugLines)
|
||||
{
|
||||
UWorld* world = GetWorld();
|
||||
|
||||
if(world)
|
||||
{
|
||||
FVector RayStartingPoint(x, y, 999999);
|
||||
FVector RayEndPoint(x, y, 0);
|
||||
|
||||
// Raytrace
|
||||
FHitResult HitResult;
|
||||
world->LineTraceSingleByObjectType(
|
||||
OUT HitResult,
|
||||
RayStartingPoint,
|
||||
RayEndPoint,
|
||||
FCollisionObjectQueryParams(ECollisionChannel::ECC_WorldStatic),
|
||||
FCollisionQueryParams()
|
||||
);
|
||||
|
||||
// Draw debug line.
|
||||
if (bDrawDebugLines)
|
||||
{
|
||||
FColor LineColor;
|
||||
|
||||
if (HitResult.GetActor()) LineColor = FColor::Red;
|
||||
else LineColor = FColor::Green;
|
||||
|
||||
DrawDebugLine(
|
||||
world,
|
||||
RayStartingPoint,
|
||||
RayEndPoint,
|
||||
LineColor,
|
||||
true,
|
||||
5.f,
|
||||
0.f,
|
||||
10.f
|
||||
);
|
||||
}
|
||||
|
||||
// Return Z location.
|
||||
if (HitResult.GetActor()) return HitResult.ImpactPoint.Z;
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma de Barcelona (UAB). This work is licensed under the terms of the MIT license. For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
#include "Components/SplineComponent.h"
|
||||
#include "EditorUtilityWidget.h"
|
||||
#include "Math/Vector.h"
|
||||
|
||||
#include "ProceduralWaterManager.generated.h"
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct CARLATOOLS_API FProceduralRiversMetaInfo
|
||||
{
|
||||
GENERATED_USTRUCT_BODY();
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FString WaterInfoPath;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
int CustomSampling;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
float CustomScaleFactor;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FVector CustomLocationOffset;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
float CustomHeight;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
int SizeOfLandscape;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
int SizeOfTexture;
|
||||
};
|
||||
|
||||
UCLASS(BlueprintType)
|
||||
class CARLATOOLS_API UProceduralWaterManager : public UEditorUtilityWidget
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
// Sets default values for this actor's properties
|
||||
UProceduralWaterManager();
|
||||
|
||||
public:
|
||||
/// Main function to be called from the widget to start all the generation process
|
||||
/// @a metaInfo is the input data for this process
|
||||
UFUNCTION(BlueprintCallable)
|
||||
FString StartWaterGeneration(const FProceduralRiversMetaInfo metaInfo);
|
||||
|
||||
/// Add river @a riverActor spline point @a splinePoint to SplinePoint
|
||||
/// collection to be added in later processes to the spline component.
|
||||
/// This is implemented in blueprint code.
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void AddRiverPointFromCode(AActor* riverActor, FSplinePoint splinePoint);
|
||||
|
||||
/// It checks which is the direction the flow of the river depending on the
|
||||
/// altitude of the start and the end of the river @a riverActor
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void CheckAndReverseWaterFlow(AActor* riverActor);
|
||||
|
||||
private:
|
||||
TSubclassOf<class AActor> RiverBlueprintClass;
|
||||
|
||||
/// Instantiate a new actor of type RiverBlueprintClass
|
||||
/// Returns the the actor created
|
||||
UFUNCTION()
|
||||
AActor* SpawnRiverBlueprintActor();
|
||||
|
||||
/// Calculates the height of the landscape in an specific 2D coordinate ( @a x, @a y)
|
||||
/// throwing rays and detecting the hit point. @a bDrawDebugLines allows to visualize
|
||||
/// the rays in the viewport, only for debug purposes.
|
||||
/// Return the Z value
|
||||
UFUNCTION()
|
||||
float GetLandscapeSurfaceHeight(float x, float y, bool bDrawDebugLines = false);
|
||||
};
|
Loading…
Reference in New Issue