Commit 3816d3b0 by Kai Westerkamp

LOD

parent 8e28c734
......@@ -8,23 +8,144 @@
#include "Tileset.h"
ATilesetActor::ATilesetActor(const FObjectInitializer& ObjectInitializer) {
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.bStartWithTickEnabled = true;
PrimaryActorTick.bAllowTickOnDedicatedServer = true;
}
void ATilesetActor::BeginPlay()
{
Super::BeginPlay();
//RootComponent = CreateDefaultSubobject<UStaticMeshComponent>("TESTMesh");
rootTileset = new FTileContent();
rootTileset->url = relativeURL;
UTileDownloader *downloader = NewObject<UTileDownloader>(UTileDownloader::StaticClass());
downloader->GetTileContent(this, rootTileset, host);
}
void ATilesetActor::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
UWorld* const World = GetWorld();
if (World && GEngine && GEngine->GameViewport //game init
&& rootTileset && rootTileset->tileset) // tilset loaded
{
// viewport Cam pos and FOV
APlayerController* Controller = World->GetFirstPlayerController();
FVector CamLocation = Controller->PlayerCameraManager->GetCameraLocation();
float FOV = Controller->PlayerCameraManager->GetFOVAngle();
FVector2D ViewportSize = FVector2D(1, 1);
GEngine->GameViewport->GetViewportSize(ViewportSize);
double lambda = ViewportSize.X / FOV;
FTile *tile = &rootTileset->tileset->root;
//FVector ActorPos = FTransform(*tile->getAbsoluteTransform()).GetTranslation();
//double dist = (CamLocation - ActorPos).Size();
//
////SSE http://folk.uio.no/inftt/Div/visualization2.pdf
//double ScreenSpaceError1 = lambda * tile->geometricError / dist;
updateScreenSpaceError(tile, 0, lambda, CamLocation);
//SSE2 https://wiki.delphigl.com/index.php/Screenspace_Error
double maxPixelError = 30.0f;
double T = maxPixelError / ViewportSize.X;
double C = FOV / T;
double SSE2 = tile->geometricError * C;
//UE_LOG(TILES, Error, TEXT("SSError= %f,SSE2= %f, GeoError = %f, Dist %f"), ScreenSpaceError1, SSE2, tile.geometricError, dist);
}
}
double FTile::getScreenSpaceError(double lambda, FVector CamLocation)
{
FVector ActorPos = FTransform(*this->getAbsoluteTransform()).GetTranslation();
double dist = (CamLocation - ActorPos).Size();
//SSE http://folk.uio.no/inftt/Div/visualization2.pdf
return lambda * this->geometricError / dist;
}
void FTile::setVisible(bool visible)
{
if (content.tiles.Num() == 0 && !content.tileset) {
if (visible) {
//load
}
//maybe set parent visible untill loaded?
}
else if(content.tiles.Num() > 0) {
for (AProceduralEntity* object : content.tiles) {
object->setActorDisabled(!visible);
}
}
}
void ATilesetActor::updateScreenSpaceError(FTile* current, double currentSSE, double constant, FVector CamLocation)
{
double ScreenSpaceError1 = current->getScreenSpaceError(constant, CamLocation);
if (ScreenSpaceError1 > LODtreshold && current->children.Num() > 0) {
for (FTile* child : current->children)
{
updateScreenSpaceError(child, 0, constant, CamLocation);
}
current->setVisible(false);
}
else {
current->setVisible(true);
for (FTile* child : current->children)
{
child->setVisible(false);
}
UE_LOG(TILES, Error, TEXT("Set Visible %s SSError= %f"), *current->content.url, ScreenSpaceError1);
}
if (current->children.Num() == 0) {
// set visible keine
}
else {
double SSEchildren = 0.0;
for (FTile* child : current->children)
{
SSEchildren += child->getScreenSpaceError(constant, CamLocation);
}
//UE_LOG(TILES, Error, TEXT("SSError= %f,SSE2 Childs= %f"), ScreenSpaceError1, SSEchildren );
}
}
FTileset* ATilesetActor::parseTileset(FString JsonString, FString BaseURL)
{
//TODO error Handling
......@@ -96,6 +217,7 @@ void ATilesetActor::parseBatched3DTile(const TArray<uint8> data, FTile * tile)
gltf->loadModel(&data.GetData()[GLTFstart], (data.Num() - GLTFstart));
tile->content.tiles.Add(gltf);
tile->setVisible(false);
}
}
......@@ -169,6 +291,7 @@ void ATilesetActor::parseInstanced3DTile(const TArray<uint8> data, FTile * tile)
}
}
tile->setVisible(false);
}
void ATilesetActor::parse3DTile(const TArray<uint8> data, FTile *tile)
......@@ -188,7 +311,6 @@ void ATilesetActor::parse3DTile(const TArray<uint8> data, FTile *tile)
FMatrix * FTile::getMatrix()
{
if (realtiveTransform == nullptr) {
......@@ -215,6 +337,7 @@ FMatrix * FTile::getMatrix()
FMatrix * FTile::getAbsoluteTransform()
{
if (!absoluteTransform) {
FMatrix(absoluteTrans);
absoluteTrans.SetIdentity();
for (FTile *current = this; current != nullptr; current = current->parent) {
......@@ -225,5 +348,9 @@ FMatrix * FTile::getAbsoluteTransform()
absoluteTrans = *this->parentTilset->parent->getAbsoluteTransform() * absoluteTrans;
}
return new FMatrix(absoluteTrans);
absoluteTransform = new FMatrix(absoluteTrans);
}
return absoluteTransform;
}
......@@ -90,6 +90,7 @@ struct FTileContent
UPROPERTY()
FString url;
//bool loadingStarted;
TArray<uint8> content;
struct FTileset *tileset;
TArray<class AProceduralEntity*> tiles;
......@@ -132,18 +133,26 @@ struct FTile
struct FTileset *parentTilset;
struct FTile *parent;
FMatrix *realtiveTransform;
FMatrix *absoluteTransform;
FMatrix *getMatrix();
FMatrix *getAbsoluteTransform();
double getScreenSpaceError(double lambda, FVector CamLocation);
void setVisible(bool visible);
FTile() {
float transformDefault[] = { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 };
transform.Empty();
parentTilset = nullptr;
parent = nullptr;
realtiveTransform = nullptr;
absoluteTransform = nullptr;
//transform.Append(transformDefault, 16);
}
};
USTRUCT()
......@@ -282,12 +291,18 @@ class MASTERTESTPROJECT_API ATilesetActor : public AActor
GENERATED_BODY()
public:
ATilesetActor(const FObjectInitializer& ObjectInitializer);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Generation")
FString host;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Generation")
FString relativeURL;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "LOD")
float LODtreshold = 0.1;
// Called when the game starts or when spawned
virtual void BeginPlay() override;
......@@ -297,6 +312,10 @@ public:
FTileset* parseTileset(FString JsonString, FString BaseURL);
void parse3DTile(const TArray<uint8> data, FTile *tile);
//virtual bool ShouldTickIfViewportsOnly() override { return true; }
void updateScreenSpaceError(FTile* current, double currentSSE, double constant, FVector CamLocation);
private:
FTileContent *rootTileset;
......
......@@ -305,6 +305,13 @@ AProceduralEntity* AProceduralEntity::clone(const FVector position)
}
void AProceduralEntity::setActorDisabled(bool disabled)
{
this->SetActorHiddenInGame(disabled);
this->SetActorEnableCollision(!disabled);
this->SetActorTickEnabled(!disabled);
}
UMaterialInterface *AProceduralEntity::GetMaterialForIndex(unsigned int index, const aiScene* scene){
if (MaterialMap.Contains(index)) {
return *MaterialMap.Find(index);
......
......@@ -58,6 +58,8 @@ public:
AProceduralEntity* clone(FVector position);
void setActorDisabled(bool disabled);
private:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment