虚幻地形高度图生成及测试

虚幻地形高度图生成及测试

虚幻引擎地形系统将高度数据存储在高度图中,这是一个灰阶图像,使用黑白色值来存储地貌高程。在高度图中,纯黑色值表示最低点,纯白色值表示最高点。支持16位灰阶PNG、8位灰阶r8及16位灰阶r16格式。

本文测试使用开源的opencvcgal库将地形网格体采样插值生成栅格,并写入到16位灰阶PNG图片中,结果可支持导入虚幻UE Landscape

示例代码

#include<iostream>
#include<cmath>#include<CGAL/Surface_mesh.h>
#include<CGAL/Surface_mesh/IO/PLY.h>#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Projection_traits_xy_3.h>
#include <CGAL/Delaunay_triangulation_2.h>#include <CGAL/Polygon_mesh_processing/locate.h>#include <opencv2/opencv.hpp>using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using Projection_traits = CGAL::Projection_traits_xy_3<Kernel>;
using Point_2 = Kernel::Point_2;
using Point_3 = Kernel::Point_3;// Triangulated Irregular Network
using TIN = CGAL::Delaunay_triangulation_2<Projection_traits>;
using Mesh = CGAL::Surface_mesh<Point_3>;int main(){Mesh mesh;CGAL::IO::read_PLY("test.ply",mesh);CGAL::Bbox_3 bbox = CGAL::bbox_3(mesh.points().begin(), mesh.points().end());std::cout << "with:" << bbox.x_span() << "\nheight:" << bbox.y_span() << std::endl;int width = std::ceil(bbox.x_span());int height = std::ceil(bbox.y_span());width = std::max(width, height);height = width;// 特殊处理,虚幻地形表示的范围为512单位 (可略)//  int max_multiple = std::ceil(bbox.zmax() / 512);//  int min_multiple = std::ceil(std::abs(bbox.zmin()) / 512);//  min_multiple = bbox.zmin() < 0 ? min_multiple : 0;int maxHeight = max_multiple * 512;int minHeight = min_multiple * 512;int maxGray = (1 << 16) - 1;//65535 cv::Mat image(height, width, CV_16UC1);TIN tin (mesh.points().begin(), mesh.points().end());TIN::Face_handle location;for (std::size_t y = 0; y < height; ++y)for (std::size_t x = 0; x < width; ++x){Point_3 query(bbox.xmin() + x * (bbox.xmax() - bbox.xmin()) / double(width),bbox.ymin() + (height - y) * (bbox.ymax() - bbox.ymin()) / double(height),0); // not relevant for location in 2Dlocation = tin.locate(query, location);// Points outside the convex hull will be colored blackif (!tin.is_infinite(location)){std::array<double, 3> barycentric_coordinates= CGAL::Polygon_mesh_processing::barycentric_coordinates(Point_2(location->vertex(0)->point().x(), location->vertex(0)->point().y()),Point_2(location->vertex(1)->point().x(), location->vertex(1)->point().y()),Point_2(location->vertex(2)->point().x(), location->vertex(2)->point().y()),Point_2(query.x(), query.y()),Kernel());double height_at_query= (barycentric_coordinates[0] * location->vertex(0)->point().z()+ barycentric_coordinates[1] * location->vertex(1)->point().z()+ barycentric_coordinates[2] * location->vertex(2)->point().z());// 重新映射高度值到0~65535double height_ratio = (height_at_query + minHeight) / (maxHeight+minHeight);image.at<uint16_t>(y,x)=(uint16_t)(height_ratio* maxGray);}else {image.at<uint16_t>(y, x) = (uint16_t)0;}}cv::imwrite("output.png", image);return 0;
}

测试运行

cmake_minimum_required(VERSION 3.1...3.23)
project(main)
# cgal
find_package(CGAL REQUIRED)
# opencv 
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )create_single_source_cgal_program("main.cpp")
target_link_libraries(main PRIVATE ${OpenCV_LIBS})

编译&构建
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=D:\vcpkg\scripts\buildsystems\vcpkg.cmake
cmake --build build --config Debug

结果

测试地形网格
在这里插入图片描述

生成的灰度图
在这里插入图片描述

导入虚幻Landscape
在这里插入图片描述

参考

  1. https://dev.epicgames.com/documentation/zh-cn/unreal-engine/importing-and-exporting-landscape-heightmaps-in-unreal-engine
  2. https://blog.csdn.net/mrbaolong/article/details/141643001?spm=1001.2014.3001.5501

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/52197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为 HCIP-Datacom H12-821 题库 (8)

有需要题库的可以看主页置顶 1.在 DHCP 运行过程中&#xff0c;如果客户端 IP 地址在相约过去 87.5%还没有完成续约的话&#xff0c;客户将发送什么报文进行再次续约&#xff1f; A、DHCP discover 广播报文 B、DHCP release 单播报文 C、DHCP request 广播报文 D、DHCP reques…

硬刚苹果还得是华为

文&#xff5c;琥珀食酒社 作者 | 璇子 牛皮啊 华为发三折叠不意外 意外的是 这各种翻转简直颠覆想象 市面上没见过这么能“翻转”的&#xff1f; 要不怎么说硬刚苹果 还得看华为 就跟你同天怎么了&#xff1f; 拼创新、拼技术、拼热度 你就说哪比你差吧&#xff1f…

使用modelsim小技巧

1、当我们不想打开modelsim gui界面进行工程仿真时&#xff0c;modelsim提供了命令仿真的方法 vsim -c -do test_sim.do执行上述命令可以在不打开gui界面的情况下直接仿真工程 2、当我们代码里有systemverilog语法时编译代码方式 vlog -sv -sv09compat defineT133 test.v

基于VUE的校园二手物品交易管理系统的设计与实现 (含源码+sql+视频导入教程)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于VUE的校园二手物品交易管理系统8拥有两种角色 管理员&#xff1a;闲置物品管理、订单管理、用户管理 用户&#xff1a;登录注册、购物车、发布闲置物品、评论、发货、收货地址管理等…

电力设计院10大排行榜!这个大院屠榜!

今天晚上阅读了中国电力规划设计协会《2022年度电力勘测设计行业统计分析报告》&#xff0c;这本报告是依据协会会员企业统计报表数据进行编制分析的。报告共收集了167家勘测设计企业上报的数据信息&#xff0c;统计的企业数量较2021 年166家企业增加1 家。 按业务板块划分为&…

element ui form 表单出现英文提示的解决方案

场景再现&#xff1a; 在使用 form 表单的时候&#xff0c;一般都需要对表单元素进行验证&#xff0c;错误就出现在了这里&#xff0c;除了配置的错误信息&#xff0c;还会出现一个 英文校验提示&#xff0c;如下图&#xff1a; 解决方案 出现的原因是在el-form-item中使用…

python转换并提取pdf文件中的图片

#安装fitz包 pip install pymupdf 脚本如下所示&#xff1a; import fitz import re import os import time import sysarguments sys.argvfor arg in arguments:print(arg)def file_name_list(base_dir):for i, j, k in os.walk(base_dir):name [i.replace(.pdf, ) for i …

Tensorflow2 如何扩展现有数据集(缩放、随机旋转、水平翻转、平移等),从而提高模型的准确率 -- Tensorflow自学笔记14

实际生活中的数据集&#xff0c;往往不是标准的数据&#xff0c;而是有倾斜角度、有旋转、有偏移的数据&#xff0c;为了提高数据集的真实性&#xff0c;提高模型预测的准确率&#xff0c;可以用ImageDataGenerator函数来扩展数据集 import tensorflow as tffrom tensorflow.k…

萌新5:日历游戏(博弈论,递推找规律)

题目描述 Alice 和 Bob 在玩一个游戏&#xff0c;他们先从 2000.1.1 到 2024.8.1 这个日期之间&#xff08;不包括2024.8.1&#xff09;随意抽取一个日期出来。然后他们轮流对这个日期进行操作&#xff1a; 把日期的天数加 1&#xff0c;例如&#xff1a;2000.1.1 变到 2000.1…

【0325】Postgres内核之 VACUUM(FULL) 创建 BufferAccessStrategy object(16)

1. 创建 BufferAccessStrategy object 这部分是属于Postgres内核中 “后端进程私有缓冲区环管理” 内容。 GetAccessStrategy() 函数 用于创建一个 BufferAccessStrategy 对象,该对象将在当前内存上下文中分配。 该函数原型如下: BufferAccessStrategy GetAccessStrategy(…

(二)ASP.NET Core WebAPI项目的启动地址设置

上一篇介绍了ASP.NET Core WebAPI项目创建&#xff0c;可参考&#xff1a; 1.webAPI的访问地址 1) 启动时&#xff0c;选择CoreWebAPI(项目名称)运行项目 可以看到打开浏览器后的地址是&#xff1a;applicationUrl"\"launchUrl 2) 启动时&#xff0c;选择IIS Expre…

Ansys Zemax | 在OpticStudio中仿真单模光纤耦合

附件下载 联系工作人员获取附件 准确分析耦合效率在光纤耦合系统的设计中至关重要。本文演示了如何在OpticStudio中使用多种光纤耦合效率分析。 概要 OpticStudio序列模式可以很好地模拟单模光纤耦合效率。本文演示了如何设置耦合系统&#xff0c;并研究了序列模式下可用于…

redis分布式锁和lua脚本

业务场景&#xff1a;多个线程对共同资源的访问&#xff1a;库存超卖/用户重复下单的原因 解决方法一&#xff1a;利用jvm内置锁&#xff0c;将非原子性操作变成原子性操作 Synchronized锁的是对象&#xff0c;对象必须是单例的。锁的是this,代表当前所在的类&#xff0c;这个…

RabbitMQ 基础架构流程 数据隔离 创建用户

介绍 publisher&#xff1a;消息发送者-exchange&#xff1a;交换机&#xff0c;复制路由的消息-queue&#xff1a;队列&#xff0c;存储消息consumer&#xff1a;消息的消费者 工作流程 publisher消息发送者 -> exchange 交换机 -> queue 队列 -> consumer 消息的消…

流动会场:以声学专利为核心的完美移动场地—轻空间

流动会场作为一种全新的活动场所选择&#xff0c;凭借其便捷的移动性与先进的声学设计&#xff0c;正逐渐成为各类演出、会议和文化活动的热门场地。其独特之处不仅在于搭建速度快、灵活性高&#xff0c;还在于其核心技术——声学专利的强大支持。 专利声学设计&#xff0c;打造…

7个 C# 高阶用法详解:从基础到实战

C# 高阶用法详解&#xff1a;从基础到实战 在实际开发中&#xff0c;C# 提供了很多高级特性和设计模式&#xff0c;帮助我们写出更加简洁、灵活和高效的代码。本篇将深入探讨 C# 中的高阶用法&#xff0c;通过丰富的示例&#xff0c;带你掌握这些工具的精髓。 1. LINQ&#x…

Kotlin 流 Flow

挂起函数可以异步地返回一个值&#xff0c;而对于返回多个值&#xff0c;可以使用流&#xff0c;使用 emit(x) 发射多个值&#xff0c; collect { } 来收集值。 默认 流是冷的&#xff0c;只有 收集&#xff08;collect&#xff09; 时才会执行。 1. 流的创建 flow {} 生成流…

【LeetCode】06.Z字形变换

题目要求 解题思路 首先映入我们脑海的就是暴力。这一方法可行&#xff0c;但是时间复杂度空间复杂度很高&#xff0c;因此我们使用找规律的方法。这样的话我们可以模拟插入下标&#xff0c;这样的话很容易发现首行和末行插入的位置刚好是d2*n-2&#xff0c;而中间行的两个位置…

windows下安装elasticSearch和kibana

下载es 下载地址官网 下载后是个压缩包(elasticsearch-8.15.0-windows-x86_64)&#xff0c;解压即可 启动 配置 改一下 /conf/jvm.options文件&#xff0c;最后加一行编码配置&#xff0c;这个是为了启动后防止控制台乱码 -Dfile.encodingGBK启动es 依赖jdk8环境&#xf…

目标检测-YOLOv8

YOLOv8 YOLOv8 是 YOLO 系列的最新版本&#xff0c;它在 YOLOv7 的基础上进行了多项改进&#xff0c;主要侧重于进一步提升推理速度、检测精度以及模型的通用性。与之前版本相比&#xff0c;YOLOv8 引入了新的技术和优化策略&#xff0c;使其在多个方面更具优势。 相比 YOLOv…