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

news2024/9/27 23:30:12

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

虚幻引擎地形系统将高度数据存储在高度图中,这是一个灰阶图像,使用黑白色值来存储地貌高程。在高度图中,纯黑色值表示最低点,纯白色值表示最高点。支持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 2D
            location = tin.locate(query, location);
            // Points outside the convex hull will be colored black
            if (!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~65535
                double 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.coloradmin.cn/o/2089231.html

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

相关文章

纯vue实现笔记系统

前言 最近研究了一个笔记记录系统&#xff0c;然后突然想到一个问题&#xff0c;我该如何才能只用前端就实现笔记的记录系统&#xff1f;经过这两天的研究将其做出来了&#xff0c;接下来将分享实现的过程 ✨✨✨✨✨✨✨✨✨✨ 项目演示 在我的项目中&#xff0c;是可以适…

PCIe prefix总结

这周研究了一下spec中关于prefix的部分&#xff0c;在此做一个总结&#xff0c;欢迎大家指正补充。 TLP Prefix基本介绍 • TLP 第 0 字节的 Fmt [2:0] 字段值为 100b 表示当前 DW 为 TLP Prefix 。 • TLP Prefix 分为两大类&#xff1a; Local 和 End-End &#xff0c;其中…

深入理解归并排序

目录 一、概念 二、递归版实现 三、非递归实现 三、文件归并排序 小结 一、概念 归并排序&#xff08;Merge sort&#xff09;是建立在归并操作上的一种有效的排序算法&#xff0c;该算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用。将…

海外新闻稿发布:企业如何充分利用数字化媒体进行

在全球数字化进程加速的时代&#xff0c;企业要在激烈的国际市场中脱颖而出&#xff0c;利用数字化媒体进行海外新闻稿发布是一个不可或缺的战略。精确的策略和有效的执行能够帮助企业获得更高的曝光度和市场份额。以下将从多个角度探讨如何充分利用数字化媒体进行海外新闻稿发…

万亿生成式AI市场,商汤迎来“长坡厚雪”

AI掀起了全球科技玩家的军备竞赛&#xff0c;然而声浪越强噪音越多&#xff0c;这个领域的混乱程度也变得远超以往。就连刚刚公布财报的英伟达&#xff0c;市场也没有买账&#xff0c;因为担心AI驱动的增长高峰已过&#xff0c;接下来&#xff0c;下游会更看重实际成果。 “囤…

【电子数据取证】微信8.0.50版本数据库解密

文章关键词&#xff1a;电子数据取证、手机取证、微信取证、数据库解密 通过对8.0.50这一特定版本的分析&#xff0c;我们期望揭示软件迭代背后的逻辑思考&#xff0c;以及安全策略的演进方向。这不单纯是对技术细节的揭秘&#xff0c;更是一次关于未来通信安全趋势的展望&…

在Linux中如何安装JDK

一、卸载JDK &#xff08;可以不删除&#xff0c;直接安装新的JDK&#xff0c;然后修改环境变量&#xff09; 1.1卸载使用yum安装的jdk 1.1.1卸载系统预安装的JDK 使用命令&#xff1a;yum list installed |grep java 注意&#xff1a;该命令只能查看使用yum命令安装的jav…

python模块和包的区别有哪些

模块&#xff1a;就是.py文件&#xff0c;里面定义了一些函数和变量&#xff0c;需要的时候就可以导入这些模块。 包&#xff1a;在模块之上的概念&#xff0c;为了方便管理而将文件进行打包。包目录下第一个文件便是 __init__.py&#xff0c;然后是一些模块文件和子目录&…

pytorch 均方误差损失函数

均方误差损失函数主要用于回归问题。它计算预测值与真实值之间差的平方&#xff0c;然后取平均值。这个损失函数通过惩罚大的误差&#xff0c;使得模型在训练时更加注重减少较大的偏差。 import torch import torch.nn as nn# 创建预测值和实际值张量 predicted torch.tensor(…

Spring Boot 中的 “依赖管理和自动配置” 详解透彻到底(附+详细代码流程)

1. 如何理解 “ 约定优于配置 ” 约定优于配置&#xff08;Convention over Configuration / CoC&#xff09;,又称约定编程&#xff0c;是一种软件设计规范&#xff0c;本质上是对系统&#xff0c;类库或框架中一些东西。 一个大众化合理的默认值&#xff08;缺省值&#xff0…

VSCode+Keil协同开发之Keil Assistant

VSCodeKeil协同开发之Keil Assistant 目录 VSCodeKeil协同开发之Keil Assistant1. 效果展示2. Keil Assistant简介3. Keil Assistant功能特性4. 部署步骤4.1. 1.部署准备4.2. 2.安装Keil Assistant插件4.3. 3.配置Keil Assistant插件 5. Keil Assistant使用6. 总结 大家在单片机…

java 使用网易邮箱发送邮件

java 使用网易邮箱发送邮件 准备条件 网易邮箱账号开通邮箱的POP3/SMPT服务&#xff0c;申请授权码 引入工具包 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.26</version></de…

深入浅出Entity-Component-System:重塑游戏开发的未来

引言 在游戏开发领域&#xff0c;架构设计往往决定了项目的成败。随着游戏规模和复杂度的不断增加&#xff0c;传统的面向对象编程(OOP)模式逐渐显露出其局限性。而ECS(Entity-Component-System)架构作为一种新兴的设计模式&#xff0c;正在彻底改变游戏开发的方式。本文将深入…

C# 安卓开发1(基于MAUI框架)

1&#xff1a;什么是 .NET MAUI&#xff1f;这里参考一下官方文档&#xff0c;因为解释的更详细&#xff0c;点击这里&#xff1b; 2&#xff1a;开发工具VS2022&#xff0c;下载下图开发框架 3: 安装完成后创建新项目,选择net6.0长期支持(创建文件的存放路径不要有中文): 4:…

FPGA速度优化

速度优化 文章目录 速度优化前言一、时序优化1.1 减少关键路径上的时序1.1.1 关键路径重组1.1.2 解决扇出问题1.1.3 路径上插入寄存器1.1.4 寄存器平衡1.1.5 并行结构1.1.6 消除代码优先级 总结 前言 速度优化&#xff0c;主要就是设计时序进行优化 吞吐量&#xff1a;每个时…

bbr 随机 phase 的麻烦与 inflight 守恒算法的动机

bbr 有个要点&#xff0c;要把 probebw 的 phase 错开&#xff1a; static void bbr_reset_probe_bw_mode(struct sock *sk) {struct bbr *bbr inet_csk_ca(sk);bbr->mode BBR_PROBE_BW;bbr->cycle_idx CYCLE_LEN - 1 - prandom_u32_max(bbr_cycle_rand);bbr_advance…

炒现货黄金白银通用的技术

要在现货黄金、现货白银等市场&#xff0c;甚至是股票、期货等其他以市场走势为分析对象的市场&#xff0c;我们都需要熟练的掌握一些交易的技术&#xff0c;这些技术可以为我们入场交易打好基础&#xff0c;让我们获得比随机交易更高一点的概率。下面我们就来讨论一下炒现货黄…

关于el-table的show-summary,合计栏不显示以及保留两位小数问题

<el-tableref"table1"v-loading"loading":data"":stripe"true"height"600"show-summary:summary-method"getSummaries":show-overflow-tooltip"true">...</el-table>合计部分不显示的问题 …

安全升级:Docker部署Redis,启用密码验证

1.在自己选定的目录中创建文件夹 在redis文件夹里面创建&#xff1a;data文件夹和conf文件夹&#xff08;文件夹名称随意&#xff09; 2.在conf文件夹中创建redis.conf文件&#xff1a; vim redis.conf 2.1.redis.conf里面编写内容可以根据官网&#xff08;Index of /releases…

Threejs之OrbitControls轨道控制器

本文目录 前言一、Orbitcontrols&#xff08;轨道控制器&#xff09;1.1 基础使用1.2 代码演示 二、效果展示 前言 Orbitcontrols&#xff08;轨道控制器&#xff09;可以使得相机围绕目标进行轨道运动。 一、Orbitcontrols&#xff08;轨道控制器&#xff09; 1.1 基础使用 C…