Commit bb9138ce by Kai Westerkamp

Tileset parsiong, transfoms, i3dm start

parent d60d7614
......@@ -12,7 +12,7 @@ void UHttpDownloader::DownloadFile(const FString &URL)
HttpRequest->OnProcessRequestComplete().BindUObject(this, &UHttpDownloader::OnResponseReceived);
// Execute the request
UE_LOG(TILES, Log, TEXT("Downlaoding: %s "), *HttpRequest->GetURL());
//UE_LOG(TILES, Log, TEXT("Downlaoding: %s "), *HttpRequest->GetURL());
HttpRequest->ProcessRequest();
......
......@@ -17,19 +17,20 @@ void UTileDownloader::GetTileContent(ATilesetActor *Actor, FTileContent *Content
void UTileDownloader::OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
//FIXME download with error in http
if (Response.IsValid()) {
if (Request->GetURL().EndsWith(TEXT(".json"))) {
UE_LOG(TILES, Log, TEXT("Downloded Tilset: %s Scucess: %s"), *Request->GetURL(), bWasSuccessful ? TEXT("True") : TEXT("False"));
parent->tileset = actor->parseTileset(Response->GetContentAsString(), Request->GetURL());
UE_LOG(TILES, Warning, TEXT("Parsed Tilset: %s Scucess: %s "), *Request->GetURL(), bWasSuccessful ? TEXT("True") : TEXT("False"));
parent->tileset->parent = parentTile;
}
else {
FString url = Request->GetURL();
actor->parseTile(Response->GetContent(), parentTile);
UE_LOG(TILES, Warning, TEXT("Parsed Tile: %s Scucess: %s "), *Request->GetURL(), bWasSuccessful ? TEXT("True") : TEXT("False"));
UE_LOG(TILES, Log, TEXT("Downloded Tile: %s Scucess: %s "), *Request->GetURL(), bWasSuccessful ? TEXT("True") : TEXT("False"));
actor->parse3DTile(Response->GetContent(), parentTile);
}
}
else {
UE_LOG(TILES, Warning, TEXT("Downlaod Finished: %s Scucess: %s not Valid"), *Request->GetURL(), bWasSuccessful ? TEXT("True") : TEXT("False"));
UE_LOG(TILES, Error, TEXT("Downlaod Finished: %s Scucess: %s not Valid"), *Request->GetURL(), bWasSuccessful ? TEXT("True") : TEXT("False"));
}
}
\ No newline at end of file
......@@ -33,7 +33,7 @@ FTileset* ATilesetActor::parseTileset(FString JsonString, FString BaseURL)
TSharedPtr<FJsonObject> root = JsonParsed->GetObjectField("root");
ATilesetActor::parseTile(root, &tileset->root, tileset);
UE_LOG(TILES, Warning, TEXT("Parsed: Success:%s Version:\"%s\" geometricError:%f"), success ? TEXT("True") : TEXT("False"), *tileset->asset.version, tileset->geometricError);
UE_LOG(TILES, Log, TEXT("Parsed Tileset %s: Success:%s Version:\"%s\" geometricError:%f"), *BaseURL, success ? TEXT("True") : TEXT("False"), *tileset->asset.version, tileset->geometricError);
return tileset;
}
......@@ -41,75 +41,103 @@ FTileset* ATilesetActor::parseTileset(FString JsonString, FString BaseURL)
return nullptr;
}
void ATilesetActor::parseTile(const TArray<uint8> data, FTile *tile)
void ATilesetActor::parseTile(TSharedPtr<FJsonObject> json, FTile *targetTile, FTileset* parent) {
bool success = FJsonObjectConverter::JsonObjectToUStruct<FTile>(json.ToSharedRef(), targetTile, 0, 0);
targetTile->parentTilset = parent;
if (json->HasField("children")) {
const TArray<TSharedPtr<FJsonValue>> children = json->GetArrayField("children");
UE_LOG(TILES, Log, TEXT("Parsed Tile %s: Success:%s Version:\"%s\" Children: "), *targetTile->content.url, success ? TEXT("True") : TEXT("False"), *targetTile->content.url);
for (TSharedPtr<FJsonValue> child : children)
{
FTile *newTile = new FTile();
newTile->parent = targetTile;
ATilesetActor::parseTile(child->AsObject(), newTile, parent);
targetTile->children.Add(newTile);
}
}
else {
UE_LOG(TILES, Log, TEXT("Parsed Tile %s: Success:%s Version:\"%s\" no Childs "), *targetTile->content.url, success ? TEXT("True") : TEXT("False"), *targetTile->content.url);
}
if (!targetTile->content.url.IsEmpty()) {
UTileDownloader *downloader = NewObject<UTileDownloader>(UTileDownloader::StaticClass());
downloader->GetTileContent(this, &targetTile->content, parent->absoluteURL, targetTile);
}
}
void ATilesetActor::parse3DTile(const TArray<uint8> data, FTile *tile)
{
TileHeader *header = (TileHeader*) data.GetData();
UE_LOG(TILES, Log, TEXT("Magic: %s Version %d lenght %d, array %d "), *header->getMagicAsFString(), header->version, header->byteLength, data.Num());
UE_LOG(TILES, Warning, TEXT("Shared Tile Header: Magic: %s Version %d lenght %d, array lenght %d "), *header->getMagicAsFString(), header->version, header->byteLength, data.Num());
if (header->magic[0] == 'b' && header->magic[1] == '3' && header->magic[2] == 'd' && header->magic[3] == 'm') {
if (header->isB3DM()) {
Batch3DModelHeader *b3dmheader = (Batch3DModelHeader*) data.GetData();
UE_LOG(TILES, Log, TEXT("Batch %d %d %d"), b3dmheader->batchtable.batchTableJSONByteLength, b3dmheader->batchtable.batchTableBinaryByteLength, b3dmheader->batchLength);
UE_LOG(TILES, Log, TEXT("Batch3DModel Batches: %d"), b3dmheader->batchLength);
UWorld* const World = GetWorld();
if (World)
{
UE_LOG(TILES, Log, TEXT("TileUrL %s"), *tile->content.url);
//FString path = tile->content.url
/* FString path = tile->content.url.Replace(TEXT("\\"), TEXT("/"));
FString basePath, name;
if (!path.Split(TEXT("/"), &basePath, &name, ESearchCase::IgnoreCase, ESearchDir::FromEnd)) {
name = FString(TEXT("Error"));
}*/
//FName(*name);
AProceduralEntity *gltf = World->SpawnActor<AProceduralEntity>(AProceduralEntity::StaticClass());
if (tile) {
// for (int32 b = 0; b < tile->transform.Num() && b < 20; b++)
// {
UE_LOG(TILES, Log, TEXT("Transform %d %s"), tile->transform.Num(), *gltf->GetName());
//}
}
gltf->tile = *tile;
#if WITH_EDITOR
gltf->SetFolderPath(FName(*("SpawnedGLTF/"+this->GetName())));
#endif
gltf->AttachToActor(this, FAttachmentTransformRules::KeepWorldTransform);
gltf->SetActorRelativeTransform(FTransform(*tile->getAbsoluteTransform()));
int GLTFstart = b3dmheader->getGLTFStart();
gltf->loadModel(&data.GetData()[GLTFstart], (data.Num() - GLTFstart));
}
}
else if (header->isI3DM()) {
Instanced3DModelHeader *i3dmheader = (Instanced3DModelHeader* ) data.GetData();
FString featureJSON = i3dmheader->getpartAsString(i3dmheader->getFeatureStart(), i3dmheader->featureTable.featureTableJSONByteLength);
UE_LOG(TILES, Log, TEXT("Instanced3DModelHeader GLTFFormat %s FeatureTable JSON: %s"), i3dmheader->gltfFormat == 0? TEXT("URL"): TEXT("Binary GLTF") , *featureJSON);
}
}
void ATilesetActor::parseTile(TSharedPtr<FJsonObject> json, FTile *targetTile, FTileset* parent) {
bool success = FJsonObjectConverter::JsonObjectToUStruct<FTile>(json.ToSharedRef(), targetTile, 0, 0);
targetTile->parentReference = parent;
if (json->HasField("children")) {
const TArray<TSharedPtr<FJsonValue>> children = json->GetArrayField("children");
UE_LOG(TILES, Warning, TEXT("\nDownload Tile: Success:%s Version:\"%s\" Children: "), success ? TEXT("True") : TEXT("False"), *targetTile->content.url);
for (TSharedPtr<FJsonValue> child : children)
{
FTile newTile;
ATilesetActor::parseTile(child->AsObject(), &newTile, parent);
targetTile->children.Add(newTile);
FMatrix * FTile::getMatrix()
{
if (realtiveTransform == nullptr) {
if (transform.Num() == 16) {
FPlane X(transform[0], transform[1], transform[2], transform[3]);
FPlane Y(transform[4], transform[5], transform[6], transform[7]);
FPlane Z(transform[8], transform[9], transform[10], transform[11]);
FPlane W(transform[12], transform[13], transform[14], transform[15]);
//FMatrix(FPlane(), FPlane(), FPlane(), FPlane())
realtiveTransform = new FMatrix(X, Y, Z, W);
}
else if (transform.Num() == 0) {
realtiveTransform = new FMatrix();
realtiveTransform->SetIdentity();
}
else {
UE_LOG(TILES, Warning, TEXT("Download Tile: Success:%s Version:\"%s\" no Childs "), success ? TEXT("True") : TEXT("False"), *targetTile->content.url);
UE_LOG(TILES, Log, TEXT("Not allowed Transorm in %s ArrayLength: %d [0 or 16 allowed]"), *content.url, transform.Num());
}
if (!targetTile->content.url.IsEmpty()) {
UTileDownloader *downloader = NewObject<UTileDownloader>(UTileDownloader::StaticClass());
downloader->GetTileContent(this, &targetTile->content, parent->absoluteURL, targetTile);
//UE_LOG(TILES, Log, TEXT("%s Computed transform: %s"), *content.url, *realtiveTransform->ToString());
}
return realtiveTransform;
}
FMatrix * FTile::getAbsoluteTransform()
{
FMatrix(absoluteTrans);
absoluteTrans.SetIdentity();
for (FTile *current = this; current != nullptr; current = current->parent) {
absoluteTrans = *current->getMatrix() * absoluteTrans;
}
if (this->parentTilset != nullptr && this->parentTilset->parent != nullptr) {
absoluteTrans = *this->parentTilset->parent->getAbsoluteTransform() * absoluteTrans;
}
return new FMatrix(absoluteTrans);
}
\ No newline at end of file
......@@ -125,12 +125,20 @@ struct FTile
//UPROPERTY()
//struct FTile children;
TArray<struct FTile> children;
struct FTileset *parentReference;
TArray<struct FTile*> children;
struct FTileset *parentTilset;
struct FTile *parent;
FMatrix *realtiveTransform;
FMatrix *getMatrix();
FMatrix *getAbsoluteTransform();
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;
//transform.Append(transformDefault, 16);
}
};
......@@ -153,12 +161,16 @@ struct FTileset
FTile root;
FString absoluteURL;
FTile* parent;
FTileset() {
geometricError = -1;
parent = nullptr;
}
};
//3D Tiles
struct TileHeader {
unsigned char magic[4];
uint32 version;
......@@ -170,11 +182,38 @@ struct TileHeader {
ansiiData[4] = 0; //Add null terminator
return ANSI_TO_TCHAR(ansiiData); //Convert to FString
}
bool isB3DM() {
return magic[0] == 'b' && magic[1] == '3' && magic[2] == 'd' && magic[3] == 'm';
}
bool isI3DM() {
return magic[0] == 'i' && magic[1] == '3' && magic[2] == 'd' && magic[3] == 'm';
}
bool isCMPT() {
return magic[0] == 'c' && magic[1] == 'm' && magic[2] == 'p' && magic[3] == 't';
}
bool isPNTS() {
return magic[0] == 'p' && magic[1] == 'n' && magic[2] == 't' && magic[3] == 's';
}
};
struct BatchTableHeader {
uint32 batchTableJSONByteLength;
uint32 batchTableBinaryByteLength;
uint32 length() {
return batchTableJSONByteLength + batchTableBinaryByteLength;
}
};
struct FeatureTableHeader {
uint32 featureTableJSONByteLength;
uint32 featureTableBinaryByteLength;
uint32 length() {
return featureTableJSONByteLength + featureTableBinaryByteLength;
}
};
struct BinaryGLTFHeader {
......@@ -187,16 +226,50 @@ struct BinaryGLTFHeader {
struct Batch3DModelHeader {
TileHeader general;
BatchTableHeader batchtable;
BatchTableHeader batchTable;
uint32 batchLength;
uint32 getBatchStart() {
return 24 /*headersize*/;
}
uint32 getGLTFStart() {
return 24 + batchtable.batchTableJSONByteLength + batchtable.batchTableBinaryByteLength;
return getBatchStart() + batchTable.length();
}
};
struct Instanced3DModelHeader {
TileHeader general;
FeatureTableHeader featureTable;
BatchTableHeader batchTable;
uint32 gltfFormat;
uint32 getFeatureStart() {
return 32 /*headersize*/;
}
uint32 getBatchStart() {
return getFeatureStart() + featureTable.length();
}
uint32 getGLTFStart() {
return getBatchStart() + batchTable.length();
}
FString getpartAsString(int start, int lenght) {
if (lenght > 2048) { lenght = 2048; }
char ansiiData[2048 + 1]; //A temp buffer for the data
memcpy(ansiiData, (void*)(((uint8*)this)+start), lenght); //Assumes bytesRead is always smaller than 1024 bytes
ansiiData[lenght] = 0; //Add null terminator
return ANSI_TO_TCHAR(ansiiData); //Convert to FString
}
};
/**
*
*/
......@@ -216,7 +289,7 @@ public:
virtual void BeginPlay() override;
FTileset* parseTileset(FString JsonString, FString BaseURL);
void parseTile(const TArray<uint8> data, FTile *tile);
void parse3DTile(const TArray<uint8> data, FTile *tile);
private:
FTileContent *rootTileset;
......@@ -226,4 +299,5 @@ private:
};
......@@ -52,8 +52,8 @@ void AProceduralEntity::PostActorCreated() {
Super::PostActorCreated();
if (!IsTemplate(RF_Transient)) {
UE_LOG(GLTF, Warning, TEXT("File Path: %s"), *_filePath);
std::string filename(TCHAR_TO_UTF8(*_filePath));
// UE_LOG(GLTF, Warning, TEXT("File Path: %s"), *_filePath);
// std::string filename(TCHAR_TO_UTF8(*_filePath));
// loadModel(filename);
}
}
......
......@@ -7,8 +7,7 @@
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include "ImageUtils.h"
#include "ImageWrapper.h" //requires "ImageWrapper" in public dependencies in build CS
#include "Tileset.h"
#include "GameFramework/Actor.h"
#include "ProceduralMeshComponent.h"
......@@ -20,6 +19,9 @@ class AProceduralEntity : public AActor
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Generation")
FTile tile;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Generation")
UProceduralMeshComponent* _mesh;
......@@ -54,7 +56,11 @@ public:
void loadModel(const uint8* RawFileData, int32 lenght);
private:
int32 _selectedVertex;
int32 _meshCurrentlyProcessed;
bool _addModifier;
......
Subproject commit db1c6f5fc862ace1f833ed35646a7479e5f053b9
Subproject commit 63485bdd265729d2ae8c65ef0bc4c6bfe4c4df73
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