【iOS ARKit】3D文字

   首先,3D场景中渲染的任何虚拟元素都必须具有网格(顶点及顶点间的拓扑关系),没有网格的元素无法利用GPU 进行渲染,因此,在3D 场景申渲染 3D文字时,文字也必须具有网格。在计算机系统中,文字以平面点阵的形式存储和表示,所以进行3D文字渲染,需要将平面点阵转换为3D网格。

       在 RealityKit 中,开发人员可以程序化地生成立方体、球体、圆柱体等3D虚拟对象,这个过程其实就是利用算法生成立方体、球体、圆柱体的网格信息、法线信息、UV坐标信息的过程,有了这些基础信息,CPU与 GPU 就知道如何将虚拟对象渲染出来。

       RealityKit 也提供了根据指定文字自动生成文字网格、法线信息、UV坐标信息的方法 generateText(),该方法返回 MeshResource 类型对象,利用这个对象就可以对文字进行3D 渲染。在 RealityKit 中,生成3D文字的典型代码如代码如下所示。

//
//  Text3DView.swift
//  ARKitDeamo
//
//  Created by zhaoquan du on 2024/3/21.
//import SwiftUI
import ARKit
import RealityKit
import Combinestruct Text3DView: View {@State var change: String = "中文汉字"var body: some View {Text3DViewContainer(change: change).overlay(VStack{Spacer()TextField( LocalizedStringKey(""), text: $change).foregroundColor(.black).background(Color.white).frame(width:300,height:50).cornerRadius(5).opacity(0.6).offset(y:-330).padding(.bottom, 300)}).navigationTitle("3D文字").edgesIgnoringSafeArea(.all)}
}struct Text3DViewContainer:UIViewRepresentable {var change:String = ""func makeUIView(context: Context) -> some ARView {let arView = ARView(frame: .zero)context.coordinator.arView = arViewlet config = ARWorldTrackingConfiguration()config.planeDetection = .horizontalcontext.coordinator.createPlane()arView.session.run(config)return arView}func updateUIView(_ uiView: UIViewType, context: Context) {if !change.isEmpty {context.coordinator.chengeText(text: change)}}func makeCoordinator() -> Coordinator {Coordinator()}class Coordinator: NSObject {var arView: ARView!var text: String = ""var textEntity: ModelEntity!func createPlane() {let planeAnchor = AnchorEntity(plane: .horizontal)let textr = MeshResource.generateText("中文汉字",extrusionDepth: 0.05,font: .systemFont(ofSize: 15),containerFrame: .zero,alignment: .left,lineBreakMode: .byWordWrapping)let textMetiral = SimpleMaterial(color: .red, isMetallic: true)textEntity = ModelEntity(mesh: textr, materials: [textMetiral])textEntity.generateCollisionShapes(recursive: false)planeAnchor.addChild(textEntity)arView.scene.addAnchor(planeAnchor)arView.installGestures(.all, for: textEntity)}func chengeText(text: String) {let planeAnchor = AnchorEntity(plane: .horizontal)let textr = MeshResource.generateText(text,extrusionDepth: 0.05,font: .systemFont(ofSize: 2),containerFrame: .zero,alignment: .left,lineBreakMode: .byWordWrapping)let textMetiral = SimpleMaterial(color: .red, isMetallic: true)textEntity.removeFromParent()textEntity = ModelEntity(mesh: textr, materials: [textMetiral])textEntity.generateCollisionShapes(recursive: false)planeAnchor.addChild(textEntity)arView.scene.addAnchor(planeAnchor)arView.installGestures(.all, for: textEntity)}}
}
#Preview {Text3DView()
}

   从代码可以看到,生成3D文字的过程与生成其他程序化虚拟模型对象的过程完全一致,唯一区别是生成 3D 文字网格的方法要求设置的参数更多,generateText()方法原型

static func generateText (_ string: String, extrusionDepth: Float = 0. 25, font: MeshResource. Font = .systemPont(ofSize: MeshResource. Font. systemFontSize), containerFrame: CGRect = CGRect. zero, alignment: CTTextAlignment =. left, lineBreakMode: CTLineBreakMode = byTruncatingTail) - > MeshResource

generateText()方法参数众多,但实际除了 string 其余参数都可以使用默认值,各参数的意义如下表所示。

               表11-1 生成3D文字网格的参数属性

参数名

描述

string

需要3D渲染的文字,使用内置的systemFont 可以渲染中文汉字与英文字符,如果使用其他字体渲染中文汉字需要确保字体支持

extrusionDepth

渲染的文字厚度,即在Z轴上的长度,以米为单位

font

渲染所用字体,渲染中文汉字需要字体支持,使用该属性可以指定字体大小。默认使用系统字体

containerFrame

该属性指定文字所占空间尺寸,类似于 Word文字排版软件中的文本框指定文字所占尺寸,当指定该值时,如果文字渲染超出该尺寸则会以 lineBreakMode 属性指定的方式截断。默认为(0,0),会以最合适的大小包裹所有文字

alignment

文字在 containerFrame 中的对齐方式,可以为 center(居中对齐)、justified(分散对齐)、left(左对齐)、natural(两端对齐)、right(右对齐)之一,该属性会影响缩放、旋转3D文字时的定位点

lineBreakMode

文字超出 containerFrame 范围时的截断方式,可以 byWordWrapping(以单词/汉字为单位显示,超出部分不显示)、byCharWrapping(以字符/汉字单位显示,超出部分不显示)、byClipping(剪切与containerFrame 尺寸一致的内容长度,后半部分被截断)、byTruncatingHead(前面文字被截断,用省略号显示)、byTruncatingTail(后面文字被截断,用省略号显示)、byTruncatingMiddle(两端文字保留,中间文字被省略,用省略号显示)之一

       generateText()方法生成的文字 3D网格可以与其他程序化虚拟模型对象一样被赋子材质,包括纹理,也可以使用 ARAnchor 将其固定到场景中。

       在 RealityKit 中生成的文字 3D网格不可修改,因此,无法通过网格修改的方式更新谊染的3D文字,果需要更新已生成的3D文字,则只能重新生成新的文字3D网格。

       上述代码我们直接使用 changeText()方法重新生成新的文字3D网格,然后重新生成 textEntity 实体更新渲染的3D文字。在实际开发中,也可以通过扩展(extension) Entity 或者 ModelEntity 类,添加更新 3D文字的方法达到更方便使用的目的。

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

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

相关文章

#Linux(SSH软件安装及简单使用)

(一)发行版:Ubuntu16.04.7 (二)记录: (1)终端键入(root权限)安装 apt-get install openssh-server 安装时遇到报错 E: Could not get lock /var/lib/dpkg/…

【前端学习——js篇】6.事件模型

具体见:https://github.com/febobo/web-interview 6.事件模型 ①事件与事件流 事件(Events) 事件是指页面中发生的交互行为,比如用户点击按钮、键盘输入、鼠标移动等。在js中,可以通过事件来触发相应的操作,例如执行函数、改变…

javaScript | 报错:JSX expressions must have one parent element

#错误记录:在做一个练习时候出现这个错误 #错误原因分析:在React和JSX中,每个JSX表达式都必须有一个父元素。这意味着你想要渲染的所有组件或元素都必须被一个单独的容器所包含。这个规则的原因是JSX最终会被编译成调用React.createElement()…

C++基本语法

C是如何工作的 文章目录 C是如何工作的1、新建Hello World工程1.1使用Visual Studio新建项目1.2 HelloWorld1.2.1 命名空间1.2.2 输出输出 1.3 注释1.4 函数1.4.1 使用有返回的函数1.4.2 自定义函数 1、新建Hello World工程 1.1使用Visual Studio新建项目 按照下面的图片&…

星云小窝项目1.0——项目介绍(一)

星云小窝项目1.0——项目介绍(一) 文章目录 前言1. 介绍页面2. 首页2.1. 游客模式2.2. 注册用户后 3. 星云笔记3.1. 星云笔记首页3.2. 星云笔记 个人中心3.2. 星云笔记 系统管理3.3. 星云笔记 文章展示3.3. 星云笔记 新建文章 4. 数据中心5. 交流评论6. …

PMP考试的时间有多长?

PMP考试时长为230分钟,即3小时50分钟,这3小时50分钟的时间里,考生需要全神贯注,充分展现自己的专业水平和能力,既是一个考验,也是一个挑战,对于每一位参加PMP考试的考生来说,都是一次…

浏览器导出excel

做java web项目时&#xff0c;经常遇到需要在页面上点击导出按钮&#xff0c;然后直浏览器接下载下来一个excel文档。 比如一个List<Person>的集合&#xff0c;需要将每个Person当做一行&#xff0c;输出到excel中去。其中Person实体类如下&#xff1a; import lombok.…

智驾芯片“独角兽”地平线流血冲刺上市,三年累计亏损47亿元

3月26日&#xff0c;Horizon Robotics&#xff08;下称“地平线”&#xff09;向港交所递交招股书&#xff0c;高盛、摩根士丹利、中信建投国际为其联席保荐人。 据介绍&#xff0c;成立于2015年的地平线是一家人工智能计算平台公司&#xff0c;专注于为智能汽车提供高级辅助驾…

Vivado使用(2)——综合运行与OOC

目录 一、综合运行 二、OOC 2.1 如何设置 OOC 模块 2.2 存根文件和黑盒属性 2.3 使用限制 2.4 另一种设置方法 一、综合运行 一个“运行&#xff08;run&#xff09;”是指定义和配置设计在综合过程中的各方面&#xff0c;包括&#xff1a;使用到约束&#xff0c;针对的…

蓝桥杯算法赛(二进制王国)

问题描述 二进制王国是一个非常特殊的国家&#xff0c;因为该国家的居民仅由 0 和 1 组成。 在这个国家中&#xff0c;每个家庭都可以用一个由 0 和 1 组成的字符串 S 来表示&#xff0c;例如 101、 000、 111 等。 现在&#xff0c;国王选了出 N 户家庭参加邻国的庆典…

【unity】如何汉化unity Hub

相信大家下载安装unity后看着满操作栏的英文&#xff0c;英文不好的小伙伴们会一头雾水。但是没关系你要记住你要怎么高速运转的机器进入中国&#xff0c;请记住我给出的原理&#xff0c;不懂不代表不会用啊。现在我们就来把编译器给进行汉化。 第一步&#xff1a;我们打开Uni…

Qt如何直接处理系统事件(比如鼠标事件),而不是post事件

#include <QtGui/5.15.2/QtGui/qpa/qwindowsysteminterface.h> // 方便调试事件 QWindowSystemInterface::setSynchronousWindowSystemEvents(true); 直接再 qWindowsWndProc函数中处理 通常情况: 事件被放到一个队列中

JavaEE之网络初识(网络中的一些基本概念)详解

&#x1f63d;博主CSDN主页: 小源_&#x1f63d; &#x1f58b;️个人专栏: JavaEE &#x1f600;努力追逐大佬们的步伐~ 目录 1. 前言 2. 网络中的一些基本概念 2.1 IP地址 2.2 端口号 2.3 网络协议 2.4 协议分层 2.5 封装 2.6 分用 (封装的逆向过程) 2.7 客户端 vs …

韩顺平Java | C21网络编程

1 网络的相关概念 ip地址的组成&#xff1a;网络地址 主机地址 A类&#xff1a;0 ~ 2^7-1 0 ~ 127 B类&#xff1a;128 ~ 1282^6-1 128 ~ 191 C类&#xff1a;192 ~ 1922^5-1 192 ~ 223 D类&#xff1a;224 ~ 2242^4-1 224 ~ 239 E类&#xff1a;240 ~ 2402^3-1 240 ~ 2…

正弦实时数据库(SinRTDB)的使用(5)-历史数据查询(一)

前文已经将正弦实时数据库的使用进行了介绍&#xff0c;需要了解的可以先看下面的博客&#xff1a; 正弦实时数据库(SinRTDB)的安装 正弦实时数据库(SinRTDB)的使用(1)-使用数据发生器写入数据 正弦实时数据库(SinRTDB)的使用(2)-接入OPC DA的数据 正弦实时数据库(SinRTDB)…

20240321-1-AB测试面试题

AB测试面试题 1. 介绍一下ABTest的步骤 ABtest就是为了测试和验证模型/项目的效果&#xff0c;在app/pc端设计出多个版本&#xff0c;在同一时间维度下&#xff0c;分别用组成相同/相似的群组去随机访问这些版本&#xff0c;记录下群组的用户体验数据和业务数据&#xff0c;最…

力扣题库88题:合并两个有序数组(c语言)

解法&#xff1a; void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {int l1m-1;int l2n-1;int l3mn-1;while(l1>0&&l2>0){if(nums1[l1]>nums2[l2]){nums1[l3--]nums1[l1--];}else{nums1[l3--]nums2[l2--];}}while(l2>0)…

化工企业能源在线监测管理系统,智能节能助力生产

化工企业能源消耗量极大&#xff0c;其节能的空间也相对较大&#xff0c;所以需要控制能耗强度&#xff0c;保持更高的能源利用率。 化工企业能源消耗现状 1、能源管理方面 计量能源消耗时&#xff0c;计量器具存在问题&#xff0c;未能对能耗情况实施完全计量&#xff0c;有…

uniapp-Form示例(uviewPlus)

示例说明 Vue版本&#xff1a;vue3 组件&#xff1a;uviewPlus&#xff08;Form 表单 | uview-plus 3.0 - 全面兼容nvue的uni-app生态框架 - uni-app UI框架&#xff09; 说明&#xff1a;表单组建、表单验证、提交验证等&#xff1b; 截图&#xff1a; 示例代码 <templat…