IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> UE4 GDAL 生成Landscape (一) -> 正文阅读

[游戏开发]UE4 GDAL 生成Landscape (一)

UE4 GDAL 生成Landscape

使用GDAL加载DEM&DOM影像数据,在UE4中构建Landscape。

DEM& DOM

dom
DEM

UnrealGDAL

UnrealGDAL 插件
test
在这里插入图片描述
在这里插入图片描述

Code

加载GeoTIFF

加载高度图(DEM),加载纹理RGB (DOM)。

GDALDatasetRef heightmap = mergetiff::DatasetManagement::openDataset(TCHAR_TO_UTF8(*(this->HeightmapDataset)));
	if (!heightmap) {
		return TEXT("Failed to open the heightmap dataset");
	}
	
	// Attempt to open the RGB dataset
	GDALDatasetRef rgb = mergetiff::DatasetManagement::openDataset(TCHAR_TO_UTF8(*(this->RGBDataset)));
	if (!rgb) {
		return TEXT("Failed to open the RGB dataset");
	}

查询影像投影信息MetaData

坐标投影信息及Extent(Corners)。

// Attempt to retrieve the Well-Known Text (WKT) representation of the projected coordinate system used by the heightmap dataset
	FString heightmapWkt = GetProjectionWkt(heightmap);
	if (heightmapWkt.IsEmpty()) {
		return TEXT("Failed to retrieve the projected coordinate system used by the heightmap dataset");
	}
	
	// Attempt to retrieve the Well-Known Text (WKT) representation of the projected coordinate system used by the RGB dataset
	FString rgbWkt = GetProjectionWkt(rgb);
	if (rgbWkt.IsEmpty()) {
		return TEXT("Failed to retrieve the projected coordinate system used by the RGB dataset");
	}
	
	// Attempt to retrieve the projected corner coordinates for the heightmap dataset
	RasterCornerCoordinatesRef heightmapCorners = GDALHelpers::GetRasterCorners(heightmap);
	if (!heightmapCorners) {
		return TEXT("Failed to compute the projected corner coordinates of the heightmap dataset");
	}
	
	// Attempt to retrieve the projected corner coordinates for the RGB dataset
	RasterCornerCoordinatesRef rgbCorners = GDALHelpers::GetRasterCorners(rgb);
	if (!rgbCorners) {
		return TEXT("Failed to compute the projected corner coordinates of the RGB dataset");
	}

影像数据预处理

将DEM数据处理成GDT_Float32,将DOM数据处理成GDT_Byte

// If the heightmap data is not already in Float32 format then convert it
	if (heightmap->GetRasterBand(1)->GetRasterDataType() != GDT_Float32)
	{
		// Attempt to convert the heightmap data to Float32
		heightmap = GDALHelpers::Translate(heightmap, GDALHelpers::UniqueMemFilename(),
			GDALHelpers::ParseGDALTranslateOptions({
				TEXT("-ot"),
				TEXT("Float32"),
			})
		);
		
		// Verify that conversion succeeded
		if (!heightmap) {
			return TEXT("Failed to convert the heightmap to Float32 format");
		}
	}
	if (rgb->GetRasterBand(1)->GetRasterDataType() != GDT_Byte)
	{
		// Attempt to convert the heightmap data to Float32
		rgb = GDALHelpers::Translate(rgb, GDALHelpers::UniqueMemFilename(),
			GDALHelpers::ParseGDALTranslateOptions({
				TEXT("-ot"),
				TEXT("Byte"),
				})
				);

		// Verify that conversion succeeded
		if (!rgb) {
			return TEXT("Failed to convert the rgb to Byte format");
		}
	}

读取数据

//------- STEP 6: READ HEIGHTMAP RASTER DATA -------
	
	// Retrieve the raster dimensions for the heightmap
	data.HeightBufferX = heightmap->GetRasterXSize();
	data.HeightBufferY = heightmap->GetRasterYSize();
	
	// Create a buffer to hold the heightmap data and wrap it in a RasterData object
	mergetiff::RasterData<float> heightmapData = GDALHelpers::AllocateAndWrap<float>(data.HeightBuffer, 1, data.HeightBufferY, data.HeightBufferX, 0.0f);
	
	// Attempt to read the heightmap data into our buffer
	if (mergetiff::RasterIO::readDataset(heightmap, heightmapData, {1}) == false) {
		return TEXT("Failed to read the data from the heightmap");
	}
	
	
	//------- STEP 7: READ RGB RASTER DATA -------
	
	// Retrieve the raster dimensions for the RGB data
	data.ColorBufferX = rgb->GetRasterXSize();
	data.ColorBufferY = rgb->GetRasterYSize();
	
	// Create a buffer to hold the RGBA data and wrap it in a RasterData object, filling all channels with 255 by default
	data.PixelFormat = EPixelFormat::PF_R8G8B8A8;
	mergetiff::RasterData<uint8> rgbaData = GDALHelpers::AllocateAndWrap<uint8>(data.ColorBuffer, 4, data.ColorBufferY, data.ColorBufferX, 255);
	
	// Attempt to read the RGB data into our buffer, leaving the alpha channel filled with 255
	if (mergetiff::RasterIO::readDataset(rgb, rgbaData, {1,2,3}) == false) {
		return TEXT("Failed to read the data from the RGB dataset");
	}
	
	

生成 Landscape

  ALandscape* Landscape = WorldContext->GetWorld()->SpawnActor<ALandscape>();
	
	// Setup landscape configuration
	Landscape->ComponentSizeQuads = 255;
	Landscape->SubsectionSizeQuads = 255;
	Landscape->NumSubsections = 1;
	Landscape->SetLandscapeGuid(FGuid::NewGuid());
	
	// Build new material for landscape
	Landscape->LandscapeMaterial = GenerateUnlitLandscapeMaterial(LandscapeName, FString::Printf(TEXT("%s.%s"), *PackageName, *Name), FMath::CeilToInt(GISData.HeightBufferX / 255), FMath::CeilToInt(GISData.HeightBufferY / 255), 255);
	
	Landscape->CreateLandscapeInfo();
	Landscape->SetActorTransform(FTransform(FQuat::Identity, FVector(), ScaleVector));
	
	// Generate LandscapeActor from heightmap
	HeightmapDataPerLayers.Add(FGuid(), HeightGDAL);
	MaterialLayerDataPerLayer.Add(FGuid(), TArray<FLandscapeImportLayerInfo>());
	
	// Build in engine only function for taking height buffer and generating landscape components
	Landscape->Import(Landscape->GetLandscapeGuid(), 0, 0, GISData.HeightBufferX - 1,
		GISData.HeightBufferY - 1, Landscape->NumSubsections, Landscape->SubsectionSizeQuads, HeightmapDataPerLayers,
		TEXT("NONE"), MaterialLayerDataPerLayer, ELandscapeImportAlphamapType::Layered
	);
	
	// Translate Landscape so that lowest point is 0 in WorldSpace
	FVector LandscapeOrigin;
	FVector LandscapeBounds;
	Landscape->GetActorBounds(false, LandscapeOrigin, LandscapeBounds);
	Landscape->SetActorLocation(FVector(0, 0, LandscapeBounds.Z));
	
	// Create attach and register GISDataComponent
	Landscape->ReregisterAllComponents();
	
	// Get last components to fill out useful information
	ULandscapeComponent* lastComponent = Landscape->LandscapeComponents.Last();
	Landscape->CreateLandscapeInfo();
	Landscape->SetActorLabel(LandscapeName);

参考

  1. UE4 GDAL 生成 Landscape
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 22:09:00  更:2022-03-13 22:09:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/23 9:53:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计