Commit 3b471513 by Kai Westerkamp

start point clouds

parent 24f6dcc3
// Fill out your copyright notice in the Description page of Project Settings.
#include "MasterTestProject.h"
#include "DynamicTextureUtilities.h"
// NOTE hard-coded to 64 * 64 texture sizes! I just copied this from some of my own code and modified it for you a little. You'll want to change a bunch of stuff in here for your own purposes.
void UDynamicTextureUtilities::UpdateTextureRegion(UTexture2D* Texture, int32 MipIndex, FUpdateTextureRegion2D Region, uint32 SrcPitch, uint32 SrcBpp, uint8* SrcData, bool bFreeData)
{
if (Texture->Resource)
{
struct FUpdateTextureRegionsData
{
FTexture2DResource* Texture2DResource;
int32 MipIndex;
FUpdateTextureRegion2D Region;
uint32 SrcPitch;
uint32 SrcBpp;
uint8* SrcData;
};
FUpdateTextureRegionsData* RegionData = new FUpdateTextureRegionsData;
RegionData->Texture2DResource = (FTexture2DResource*)Texture->Resource;
RegionData->MipIndex = MipIndex;
RegionData->Region = Region;
RegionData->SrcPitch = SrcPitch;
RegionData->SrcBpp = SrcBpp;
RegionData->SrcData = SrcData;
{
ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER(
UpdateTextureRegionsData,
FUpdateTextureRegionsData*, RegionData, RegionData,
bool, bFreeData, bFreeData,
{
int32 CurrentFirstMip = RegionData->Texture2DResource->GetCurrentFirstMip();
if (RegionData->MipIndex >= CurrentFirstMip)
{
RHIUpdateTexture2D(
RegionData->Texture2DResource->GetTexture2DRHI(),
RegionData->MipIndex - CurrentFirstMip,
RegionData->Region,
RegionData->SrcPitch,
RegionData->SrcData
+ RegionData->Region.SrcY * RegionData->SrcPitch
+ RegionData->Region.SrcX * RegionData->SrcBpp
);
}
// TODO is this leaking if we never set this to true??
if (bFreeData)
{
FMemory::Free(RegionData->SrcData);
}
delete RegionData;
});
}
}
}
void UDynamicTextureUtilities::UpdateDynamicVectorTexture(const TArray<FLinearColor>& Source, UTexture2D* Texture)
{
// Only handles 32-bit float textures
if (!Texture || Texture->GetPixelFormat() != PF_A32B32G32R32F) return;
// Shouldn't do anything if there's no data
if (Source.Num() < 1) return;
UpdateTextureRegion(Texture, 0, FUpdateTextureRegion2D(0, 0, 0, 0, Texture->GetSizeX(), Texture->GetSizeY()), Texture->GetSizeX() * sizeof(FLinearColor), sizeof(FLinearColor), (uint8*)Source.GetData(), false);
}
UTexture2D* UDynamicTextureUtilities::CreateTransientDynamicTexture(int32 Width, int32 Height, EPixelFormat PixelFormat /*= PF_A32B32G32R32F*/)
{
auto* Texture = UTexture2D::CreateTransient(Width, Height, PixelFormat);
if (Texture)
{
Texture->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
Texture->SRGB = 0;
Texture->UpdateResource();
}
return Texture;
}
/*
void UDynamicTextureUtilities::SetDynamicTextureAndIndex(class UStaticMeshComponent* Component, class UTexture2D* Texture, int32 Index, FName IndexParameterName, FName TextureParameterName)
{
if (!Component || !Texture) return;
for (int32 i = 0; i < Component->GetNumMaterials(); i++)
{
auto* DynamicMaterial = FMyProjInstanceProcedures::TryGetDynamicMaterial(Component, i);
if (!DynamicMaterial) continue;
FLinearColor CalculatedIndex(FMath::Fmod((float)Index, 64.0f) + 0.5f, FMath::FloorToFloat((float)Index / 64.0f) + 0.5f, 0.0f, 0.0f);
CalculatedIndex /= 64.0f;
DynamicMaterial->SetVectorParameterValue(IndexParameterName, CalculatedIndex);
DynamicMaterial->SetTextureParameterValue(TextureParameterName, Texture);
}
}
*/
\ No newline at end of file
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "UObject/NoExportTypes.h"
#include "DynamicTextureUtilities.generated.h"
/**
*
*/
UCLASS()
class MASTERTESTPROJECT_API UDynamicTextureUtilities : public UObject
{
GENERATED_BODY()
//https://answers.unrealengine.com/questions/288012/is-it-possible-to-create-textures-dynamically.html
public:
// Create a dynamic texture intended to be used for passing non-texture data
// into materials. Defaults to 32-bit RGBA. The texture is not added to the
// root set, so something else will need to hold a reference to it.
static UTexture2D* CreateTransientDynamicTexture(int32 Width, int32 Height, EPixelFormat PixelFormat = PF_A32B32G32R32F);
// Updates a region of a texture with the supplied input data. Does nothing
// if the pixel formats do not match.
static void UpdateTextureRegion(UTexture2D* Texture, int32 MipIndex, FUpdateTextureRegion2D Region, uint32 SrcPitch, uint32 SrcBpp, uint8* SrcData, bool bFreeData);
// Convenience wrapper for updating a dynamic texture with an array of
// FLinearColors.
static void UpdateDynamicVectorTexture(const TArray<FLinearColor>& Source, UTexture2D* Texture);
// Sets up a component's material instance parameters (on all materials) for
// use with the supplied UTexture. The proper parameters (specified by
// IndexParameterName and TextureParameterName) should exist on the
// material, otherwise this will not have the proper effect.
//static void SetDynamicTextureAndIndex(class UStaticMeshComponent* Component, class UTexture2D* Texture, int32 Index, FName IndexParameterName, FName TextureParameterName);
};
......@@ -8,37 +8,16 @@
#define TINYGLTF_LOADER_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#include "tiny_gltf_loader.h"
#include "Developer/RawMesh/Public/RawMesh.h"
#include "Developer/RawMesh/Public/RawMesh.h"
#include "StaticGLTFComponent.h"
/// @cond
// Syntactic sugar to neatly map the TinyGLTF enum to the corresponding data type
// Adapted from http://stackoverflow.com/questions/1735796/is-it-possible-to-choose-a-c-generic-type-parameter-at-runtime
template<int Type> struct GLTFComponentType;
template<> struct GLTFComponentType <TINYGLTF_COMPONENT_TYPE_BYTE> { typedef int8 Type; };
template<> struct GLTFComponentType <TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE> { typedef uint8 Type; };
template<> struct GLTFComponentType <TINYGLTF_COMPONENT_TYPE_SHORT> { typedef int16 Type; };
template<> struct GLTFComponentType <TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT> { typedef uint16 Type; };
template<> struct GLTFComponentType <TINYGLTF_COMPONENT_TYPE_INT> { typedef int32 Type; };
template<> struct GLTFComponentType <TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT> { typedef uint32 Type; };
template<> struct GLTFComponentType <TINYGLTF_COMPONENT_TYPE_FLOAT> { typedef float Type; };
template<> struct GLTFComponentType <TINYGLTF_COMPONENT_TYPE_DOUBLE> { typedef double Type; };
template<int Type> struct GLTFType;
template<> struct GLTFType <TINYGLTF_TYPE_VEC2> { typedef FVector2D Type; };
template<> struct GLTFType <TINYGLTF_TYPE_VEC3> { typedef FVector Type; };
template<> struct GLTFType <TINYGLTF_TYPE_VEC4> { typedef FVector4 Type; };
/// @endcond
UStaticGLTFComponent::UStaticGLTFComponent()
{
GLTFPath = TEXT("H:/Repositories/MasterArbeit/glTF-Sample-Models/1.0/Duck/glTF/Duck.gltf");
GLTFPath = TEXT("D:/Dropbox/Studium/MasterArbeit/glTF-Sample-Models/1.0/Duck/glTF/Duck.gltf");
Loader = new tinygltf::TinyGLTFLoader;
Scene = new tinygltf::Scene;
......@@ -70,6 +49,12 @@ void UStaticGLTFComponent::OnRegister()
else {
ImportNodes( Scene->scenes[Scene->defaultScene], newrawmesh, FMatrix());
}
}
......@@ -110,71 +95,6 @@ void UStaticGLTFComponent::ImportNodes( std::vector<std::string> nodes, FRawMesh
}
}
void UStaticGLTFComponent::ImportNodes(std::vector<std::string> nodes, FRawMesh& RawMesh, FMatrix ModelTransform)
{
for (auto CurrentNodeName : nodes) {
UE_LOG(GLTF, Log, TEXT("parsed Node %s"), *ToFString(CurrentNodeName));
tinygltf::Node CurrentNode = Scene->nodes[CurrentNodeName];
for (std::string meshName : CurrentNode.meshes) {
tinygltf::Mesh mesh = Scene->meshes[meshName];
for (tinygltf::Primitive primitive : mesh.primitives) {
if (primitive.mode != TINYGLTF_MODE_TRIANGLES) {
UE_LOG(GLTF, Error, TEXT("Unsupported Mesh Primitive Mode %d "), primitive.mode);
}
//TODO parse or link Material if necesssary
//primitive.material;
ModelTransform = ModelTransform * GetNodeTransform(&CurrentNode);
//TODO CorrectUp Direction
//FTransform Temp(FRotator(0.0f, 0.0f, -90.0f));
//TotalMatrix = TotalMatrix * Temp.ToMatrixWithScale();
//GetBufferData(OutArray, Scene->accessors[primitive.attributes["POSITION"]]);
}
}
ImportNodes(CurrentNode.children, RawMesh, ModelTransform);
}
}
FMatrix UStaticGLTFComponent::GetNodeTransform(tinygltf::Node* Node)
{
if (Node->matrix.size() == 16)
{
FMatrix Ret;
for (int32 i = 0; i < 4; ++i)
{
for (int32 j = 0; j < 4; ++j)
{
// Reverse order since glTF is column major and FMatrix is row major
Ret.M[j][i] = Node->matrix[(4 * i) + j];
}
}
return Ret;
}
else if (Node->rotation.size() == 4 && Node->scale.size() == 3 && Node->translation.size() == 3)
{
FQuat Rotation((float)Node->rotation[0], (float)Node->rotation[1], (float)Node->rotation[2], (float)Node->rotation[3]);
FVector Scale((float)Node->scale[0], (float)Node->scale[1], (float)Node->scale[2]);
FVector Translation((float)Node->translation[0], (float)Node->translation[1], (float)Node->translation[2]);
return FTransform(Rotation, Translation, Scale).ToMatrixWithScale();
}
else
{
return FMatrix::Identity;
}
}
FString UStaticGLTFComponent::ToFString(std::string InString)
{
return FString(InString.c_str());
......@@ -275,168 +195,3 @@ template <> double UStaticGLTFComponent::BufferValue(void* Data)
}
return Ret;
}
}
//Buffer Copy Methods:
// Retrieve a value from the buffer, implicitly accounting for endianness
// Adapted from http://stackoverflow.com/questions/13001183/how-to-read-little-endian-integers-from-file-in-c
template <typename T> T UStaticGLTFComponent::BufferValue(void* Data/*, uint8 Size*/)
{
T Ret = T(0);
auto NewData = reinterpret_cast<unsigned char*>(Data);
for (int i = 0; i < sizeof(T); ++i)
{
Ret |= (T)(NewData[i]) << (8 * i);
}
return Ret;
}
// Use unions for floats and doubles since they don't have a bitwise OR operator
template <> float UStaticGLTFComponent::BufferValue(void* Data)
{
assert(sizeof(float) == sizeof(int32));
union
{
float Ret;
int32 IntRet;
};
Ret = 0.0f;
auto NewData = reinterpret_cast<unsigned char*>(Data);
for (int i = 0; i < sizeof(int32); ++i)
{
IntRet |= (int32)(NewData[i]) << (8 * i);
}
return Ret;
}
template <> double UStaticGLTFComponent::BufferValue(void* Data)
{
assert(sizeof(float) == sizeof(int64));
union
{
double Ret;
int64 IntRet;
};
Ret = 0.0;
auto NewData = reinterpret_cast<unsigned char*>(Data);
for (int i = 0; i < sizeof(int64); ++i)
{
IntRet |= (int64)(NewData[i]) << (8 * i);
}
return Ret;
}
template <typename SrcType, typename DstTypse> void UStaticGLTFComponent::BufferCopy(TArray<DstTypse>& OutArray, unsigned char* Data, int32 Count, size_t Stride)
{
for (int32 i = 0; i < Count; ++i)
{
// At this point, assume we can cast directly to the destination type
OutArray.Add((DstType)BufferValue<SrcType>(Data));
Data += Stride;
}
}
template <typename SrcType> void UStaticGLTFComponent::BufferCopy(TArray<FVector2D> &OutArray, unsigned char* Data, int32 Count, size_t Stride)
{
for (int32 i = 0; i < Count; ++i)
{
// At this point, assume we can cast directly to the destination type
OutArray.Add(FVector2D(BufferValue<SrcType>(Data), BufferValue<SrcType>(Data + sizeof(SrcType))));
Data += Stride;
}
}
template <typename SrcType> void UStaticGLTFComponent::BufferCopy(TArray<FVector> &OutArray, unsigned char* Data, int32 Count, size_t Stride)
{
for (int32 i = 0; i < Count; ++i)
{
// At this point, assume we can cast directly to the destination type
OutArray.Add(FVector(BufferValue<SrcType>(Data), BufferValue<SrcType>(Data + sizeof(SrcType)), BufferValue<SrcType>(Data + 2 * sizeof(SrcType))));
Data += Stride;
}
}
template <typename SrcType> void UStaticGLTFComponent::BufferCopy(TArray<FVector4> &OutArray, unsigned char* Data, int32 Count, size_t Stride)
{
for (int32 i = 0; i < Count; ++i)
{
// At this point, assume we can cast directly to the destination type
OutArray.Add(FVector4(BufferValue<SrcType>(Data), BufferValue<SrcType>(Data + sizeof(SrcType)), BufferValue<SrcType>(Data + 2 * sizeof(SrcType)), BufferValue<SrcType>(Data + 3 * sizeof(SrcType))));
Data += Stride;
}
}
template <typename DstType>
bool UStaticGLTFComponent::GetBufferData(TArray<DstType> &OutArray, tinygltf::Accessor* Accessor, bool Append)
{
if (!Accessor)
{
return false;
}
tinygltf::BufferView* BufferView = &Scene->bufferViews[Accessor->bufferView];
if (!BufferView)
{
return false;
}
tinygltf::Buffer* Buffer = &Scene->buffers[BufferView->buffer];
if (!Buffer)
{
return false;
}
if (!Append)
{
OutArray.Empty();
}
size_t Stride;
if (Accessor->byteStride != 0)
{
Stride = Accessor->byteStride;
}
else
{
//FIXME wont work for type
Stride = TypeSize(Accessor->componentType);
switch (Accessor->componentType)
{
case TINYGLTF_TYPE_VEC2: Stride *= 2; break;
case TINYGLTF_TYPE_VEC3: Stride *= 3; break;
case TINYGLTF_TYPE_VEC4: Stride *= 4; break;
default: UE_LOG(GLTF, Error, TEXT("Unsupported Accessor Type %s"), Accessor->componentType); break;
}
}
unsigned char* Start = &Buffer->data[Accessor->byteOffset + BufferView->byteOffset];
switch (Accessor->componentType)
{
case TINYGLTF_COMPONENT_TYPE_BYTE: BufferCopy<GLTFType<TINYGLTF_COMPONENT_TYPE_BYTE> ::Type,DstType>(OutArray, Start, Accessor->count, Stride); break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE: BufferCopy<GLTFType<TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE> ::Type,DstType>(OutArray, Start, Accessor->count, Stride); break;
case TINYGLTF_COMPONENT_TYPE_SHORT: BufferCopy<GLTFType<TINYGLTF_COMPONENT_TYPE_SHORT> ::Type,DstType>(OutArray, Start, Accessor->count, Stride); break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT: BufferCopy<GLTFType<TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT> ::Type,DstType>(OutArray, Start, Accessor->count, Stride); break;
case TINYGLTF_COMPONENT_TYPE_INT: BufferCopy<GLTFType<TINYGLTF_COMPONENT_TYPE_INT> ::Type,DstType>(OutArray, Start, Accessor->count, Stride); break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT: BufferCopy<GLTFType<TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT> ::Type,DstType>(OutArray, Start, Accessor->count, Stride); break;
case TINYGLTF_COMPONENT_TYPE_FLOAT: BufferCopy<GLTFType<TINYGLTF_COMPONENT_TYPE_FLOAT> ::Type,DstType>(OutArray, Start, Accessor->count, Stride); break;
case TINYGLTF_COMPONENT_TYPE_DOUBLE: BufferCopy<GLTFType<TINYGLTF_COMPONENT_TYPE_DOUBLE> ::Type,DstType>(OutArray, Start, Accessor->count, Stride); break;
default: BufferCopy<DstType, DstType>(OutArray, Start, Accessor->count, Stride); break;
}
return true;
}
\ No newline at end of file
......@@ -28,8 +28,6 @@ namespace tinygltf
typedef struct MATERIAL Material;
}
struct FRawMesh;
/**
*
*/
......@@ -57,55 +55,6 @@ private:
bool tinygltfLoadSuccess;
FString tinygltfError;
void ImportNodes(std::vector<std::string> nodes, FRawMesh& RawMesh, FMatrix ModelTransform);
/// Returns the transform of a node relative to its parent.
FMatrix GetNodeTransform(tinygltf::Node* Node);
//Copy methods
/// @name Level 3: GetBufferData
///@{
/// Fills a TArray with typed data; works at the glTF Accessor level and figures out which arguments to send to <B>BufferCopy()</B>.
/// @param OutArray The array to fill with data from the imported file.
/// @param Accessor A pointer to a glTF Accessor containing the type data for the geometry attribute.
/// @param Append Whether to add to the array or overwrite the elements currently in it.
//template <typename T> bool GetBufferData (TArray<T> &OutArray, tinygltf::Accessor* Accessor, bool Append = true);
///@}
/// @name Level 1: BufferValue
///@{
/// Obtains a single value from the geometry data buffer, accounting for endianness.
/// Adapted from http://stackoverflow.com/questions/13001183/how-to-read-little-endian-integers-from-file-in-c
/// @param Data A pointer to the raw data to cast to the desired type.
/// @return The typed data value.
template <typename T> T BufferValue(void* Data);
///@}
/// @name Level 2: BufferCopy
///@{
/// Handles filling the TArray at the data type level.
/// @param OutArray The array to fill with data from the imported file.
/// @param Data A pointer to the raw data to use as the argument to <B>BufferValue()</B>.
/// @param Count The number of elements to add to the array i.e. the number of calls to <B>BufferValue()</B>.
/// @param Stride The number of bytes between the first byte of each element - usually the size of one element.
template <typename SrcType, typename DstType> void BufferCopy(TArray<DstType> &OutArray, unsigned char* Data, int32 Count, size_t Stride);
template <typename SrcType> void BufferCopy(TArray<FVector2D> &OutArray, unsigned char* Data, int32 Count, size_t Stride);
template <typename SrcType> void BufferCopy(TArray<FVector> &OutArray, unsigned char* Data, int32 Count, size_t Stride);
template <typename SrcType> void BufferCopy(TArray<FVector4> &OutArray, unsigned char* Data, int32 Count, size_t Stride);
///@}
/// @name Level 3: GetBufferData
///@{
/// Fills a TArray with typed data; works at the glTF Accessor level and figures out which arguments to send to <B>BufferCopy()</B>.
/// @param OutArray The array to fill with data from the imported file.
/// @param Accessor A pointer to a glTF Accessor containing the type data for the geometry attribute.
/// @param Append Whether to add to the array or overwrite the elements currently in it.
template <typename DstType> bool GetBufferData(TArray<DstType> &OutArray, tinygltf::Accessor* Accessor, bool Append = true);
///@}
void ImportNodes(std::vector<std::string> nodes, FRawMesh& RawMesh, FMatrix ModelTransform);
......
......@@ -20,7 +20,7 @@ public class MasterTestProject : ModuleRules
public MasterTestProject(TargetInfo Target)
{
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "ImageWrapper", "RawMesh", "HTTP", "Json", "JsonUtilities", "ProceduralMeshComponent" });
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "ImageWrapper", "RawMesh", "HTTP", "Json", "JsonUtilities", "ProceduralMeshComponent", "RHI", "RenderCore" });
PrivateDependencyModuleNames.AddRange(new string[] { });
......
......@@ -140,14 +140,14 @@ void ATilesetActor::updateScreenSpaceError(FTile* current, double currentSSE, do
{
updateScreenSpaceError(child, 0, constant, CamLocation);
}
current->setVisible(false);
current->setVisible(true);//FIXME
}
else {
current->setVisible(true);
for (FTile* child : current->children)
{
child->setVisible(false);
child->setVisible(true);//FIXME
}
//UE_LOG(TILES, Error, TEXT("Set Visible %s SSError= %f"), *current->content.url, ScreenSpaceError1);
......@@ -331,12 +331,52 @@ void ATilesetActor::parseInstanced3DTile(const TArray<uint8> data, FTile * tile)
tile->setVisible(false);
}
void ATilesetActor::parsePointCloudTile(const TArray<uint8> data, FTile * tile)
{
PointCloudHeader *pntheader = (PointCloudHeader*)data.GetData();
FString featureJSONString = pntheader->getpartAsString(pntheader->getFeatureStart(), pntheader->featureTable.featureTableJSONByteLength);
UE_LOG(TILES, Warning, TEXT("PointCloudHeader: FeatureTable JSON: %s"), *featureJSONString);
TSharedPtr<FJsonObject> FeatureTableJSON;
TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(featureJSONString);
if (FJsonSerializer::Deserialize(JsonReader, FeatureTableJSON))
{
int32 instances_length = FeatureTableJSON->GetIntegerField("POINTS_LENGTH");
UWorld* const World = GetWorld();
if (World)
{
if (FeatureTableJSON->HasField("POSITION")) {
uint32 featureTableBinaryOffset = pntheader->getFeatureStart() + pntheader->featureTable.featureTableJSONByteLength;
TSharedPtr<FJsonObject> binaryBodyReference = FeatureTableJSON->GetObjectField("POSITION");
int32 byteOffset = binaryBodyReference->GetIntegerField("byteOffset");
/*
TArray<FVector> positons = getAsArray<FVector>(data.GetData(), (int32)(featureTableBinaryOffset + byteOffset), instances_length);
FString outputString = "[";
for (FVector pos : positons)
{
outputString += "[" + pos.ToString() + "] ";
}
outputString += "]";
UE_LOG(TILES, Warning, TEXT("PointCloudHeader 3D Model Positions %s"), *outputString);*/
}
else {
UE_LOG(TILES, Error, TEXT("Pointcloud Quantized not supported"));
}
}
}
UE_LOG(TILES, Log, TEXT("PointCloudHeader: End"));
}
void ATilesetActor::parse3DTile(const TArray<uint8> data, FTile *tile)
{
TileHeader *header = (TileHeader*) data.GetData();
tile->content.content = data;
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());
UE_LOG(TILES, Log, TEXT("Shared Tile Header: Magic: %s Version %d lenght %d, array lenght %d "), *header->getMagicAsFString(), header->version, header->byteLength, data.Num());
if (header->isB3DM()) {
parseBatched3DTile(data, tile);
......@@ -344,6 +384,9 @@ void ATilesetActor::parse3DTile(const TArray<uint8> data, FTile *tile)
else if (header->isI3DM()) {
parseInstanced3DTile(data, tile);
}
else if (header->isPNTS()) {
parsePointCloudTile(data, tile);
}
}
......@@ -405,7 +448,7 @@ float FBoundingVolume::getDistanceTo(FVector Position, FMatrix bouindingTransfor
FVector ZAxis = FVector(box[9], box[10], box[11]);
//TODO FIXME is currently spher distance
UE_LOG(TILES, Error, TEXT("Box distance is not implemented"));
//UE_LOG(TILES, Error, TEXT("Box distance is not implemented"));
double dist = (localPos - Center).Size();
distance = dist - FMath::Max3(XAxis.Size(), YAxis.Size(), ZAxis.Size());
......@@ -413,7 +456,7 @@ float FBoundingVolume::getDistanceTo(FVector Position, FMatrix bouindingTransfor
else if (region.Num() == 6) {
// WGS84
//TODO FIXME is currently spher distance
UE_LOG(TILES, Error, TEXT("Region distance is not implemented"));
//UE_LOG(TILES, Error, TEXT("Region distance is not implemented"));
FVector Center = FVector(0, 0, 6378137);
double dist = (Position - Center).Size();
distance = dist;
......
......@@ -276,15 +276,40 @@ struct Instanced3DModelHeader {
}
FString getpartAsString(int start, int lenght) {
if (lenght > 2048) { lenght = 2048; }
char ansiiData[2048 + 1]; //A temp buffer for the data
char *ansiiData = new char[lenght + 1];
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
FString temp = ANSI_TO_TCHAR(ansiiData); //Convert to FString
delete ansiiData;
return temp;
}
};
struct PointCloudHeader {
TileHeader general;
FeatureTableHeader featureTable;
BatchTableHeader batchTable;
uint32 getFeatureStart() {
return 28 /*headersize*/;
}
uint32 getBatchStart() {
return getFeatureStart() + featureTable.length();
}
FString getpartAsString(int start, int lenght) {
char *ansiiData = new char[lenght + 1];
memcpy(ansiiData, (void*)(((uint8*)this) + start), lenght); //Assumes bytesRead is always smaller than 1024 bytes
ansiiData[lenght] = 0; //Add null terminator
FString temp = ANSI_TO_TCHAR(ansiiData); //Convert to FString
delete ansiiData;
return temp;
}
};
......@@ -329,6 +354,7 @@ private:
void parseBatched3DTile(const TArray<uint8> data, FTile *tile);
void parseInstanced3DTile(const TArray<uint8> data, FTile *tile);
void parsePointCloudTile(const TArray<uint8> data, FTile *tile);
template <typename T> TArray<T> getAsArray(const uint8* data, int32 offset, int32 numberOfElements);
};
......
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