FBX文件结构解读【文本格式】
FBX 格式几乎受到所有 3D 引擎的支持,是 Autodesk 开发的 3D 模型的专有格式。它支持顶点、索引、法线、UV坐标、材质和动画。
FBX还支持许多其他类型的信息,但它们对游戏引擎几乎没有用处。
推荐:用 NSDT编辑器 快速搭建可编程3D场景
有两种可行的方法可以将 FBX 文件支持集成到引擎中:
- 使用 Autodesk 官方的 FBX SDK,它允许导入和导出 FBX 文件或具有相同用途的其他库。 SDK 公开了两个接口,一个是 C++ 接口,另一个是 Python 接口。
- 编写自定义 FBX 解析器,避免对其他库的依赖。
第一种方法很简单:只需下载 SDK 并按照文档进行操作即可。 请注意,FBX SDK 的使用并不像人们想象的那么简单。
我将在本文中介绍 FBX 文件的结构。 对它的理解允许我们编写一个自定义的、轻量级的解析器。 有关自定义 FBX 解析器的示例,你可以查找 Blender 的 FBX 导入器/导出器插件。
然而,由于该格式是专有的,因此该格式的公共规范不可用。 尽管如此,FBX SDK 仍包含一些标头,部分揭示了格式的布局。
格式可以是 ASCII(文本文件,人类可读)或二进制形式。
因此,从第一个表示更容易推断出格式的结构是什么,以及我们需要的信息(几何、材质等)在哪里。
首先,我将展示如何从 FBX ASCII 文件获取基本几何信息。 如果你在实际实现方面需要帮助(此处未涵盖),请随时询问我,我将尽最大努力通过伪代码甚至 C 语言帮助你。如果你解析FBX的目的是为了转换为其他格式,那么可以直接使用NSDT 3DConvert这个强大的 在线3D格式转换工具,支持FBX、GLTF、GLB、OBJ、DAE、STL、PLY等数十种3D格式:
1、FBX文件结构
这是一个 示例 FBX 文件。
首先要注意的是,有些行以分号开头:这些是注释,在读取文件时必须忽略。
在初始注释之后,找到了标识符 FBXHeaderExtension。 这是文件结构的第一个主节点。 FBX 文件格式确实是遵循以下方案的树结构:
每个节点或子节点都可以有自己的特定属性。 属性也可以在主节点之外找到,但通常可以忽略。 一般来说,节点的基本结构如下:
node name: eventual_properties { <---- beginning of nodeNode_Property_1: valueNode_Property_2: valueSubnode1 : { <---- beginning of subnodeSubnode_Property_1: value[…]} <---- end of subnodeNode_Property_3: value[…]
} <---- end of node
这是在示例文件中找到的一个节点(第一个):
FBXHeaderExtension: { <---- beginning of nodeFBXHeaderVersion: 1003 <---- node propertyFBXVersion: 6100CreationTimeStamp: { <---- beginning of subnode (1)Version: 1000 <---- subnode propertyYear: 2014Month: 03Day: 20Hour: 17Minute: 38Second: 29Millisecond: 0} <---- end of subnode (1)Creator: "FBX SDK/FBX Plugins build 20070228"OtherFlags: { <---- beginning of subnode (2)FlagPLE: 0} <---- end of subnode (2)
}
理解结构是编写高效解析器的基础。
在第一个节点中,我们找到两个属性(FBXHeaderVersion 和 FBXVersion),其值是格式版本。 在本例中为 6.1 版本。 其他信息可以忽略,除非还想读取创建日期 (CreationTimeStamp)。
2、FBX对象节点
最重要的节点肯定是对象节点。
对象节点包含模型的顶点、索引、法线、UV 坐标和材质。 它的结构如下:
Objects: { <---- beginning of node ObjectsModel: “model name”, “Mesh” { <---- beginning of node of the model[…]Vertices: […] <---- verticesPolygonVertexIndex: […] <---- indicesLayerElementNormal: { } <---- node of the normalsLayerElementUV: { } <---- node of the UV coords} <---- end of node of the modelMaterial: “material name”, “” { } <---- node of the material[…]
} <---- end of node Objects
3、FBX顶点
正如我们所见,顶点可以在模型子节点的“Vertex”属性中找到。
语法如下:
Vertices: v1_x, v1_y, v1_z, v2_x, v2_y, v2_z, […]
每个顶点都有三个空间坐标 (x,y,z),用逗号分隔(也将一个顶点与另一个顶点分开)。 坐标显然是用十进制形式表示的,带有点。
示例如下:
Vertices: 0.000000,0.104800,39.291698,0.000000,0.043400,-44.424301,0.000000,38.654301,-41.818802,-0.000000,39.455002,44.424400
构成模型的顶点将是:
v1(0.000000,0.104800,39.291698)v2(00.000000,0.043400,-44.424301)v3(0.000000,38.654301,-41.818802)v4(0.000000,39.455002,44.424400)
4、FBX多边形的顶点索引
索引可以在 PolygonVertexIndex 属性下找到。
FBX 文件可以导出三边多边形(三角形)或更多。 大多数文件导出四边形多边形(四边形)。 语法和顶点类似,但是有一点需要注意:
PolygonVertexIndex: i1, i2,-i3, i4, i5,-i6,[…] <—- triangles syntaxPolygonVertexIndex: i1, i2, i3, -i4, i5, i6, i7, -i8, […] <—- quads syntax
组成多边形的索引是按顺序排列的,负索引意味着它是多边形的最后一个索引。 该指数需要设为正数,然后你必须从中减去 1!
[如果你想知道为什么,那是因为原始索引与 -1 进行了异或。 例如索引 3 变为 -4]
示例如下:
PolygonVertexIndex: 8,7,3,-7,4,8,7,-3,0,5,8,-5
组成模型的多边形将是:
p1(8,7,3,6)p2(4,8,7,2)p3(0,5,8,4)
请注意表示多边形末端的索引已设为正数,然后从中减去 1。
提醒:显卡不喜欢四边形,因此在显示模型之前必须将每个具有四个边的多边形分成两个三角形。
5、FBX法线
法线可以在 Normals 属性的子节点 LayerElementNormal(它又是 Model 的子节点)下找到。 语法与其中一个顶点相同,即一系列 (x,y,z) 坐标。
Normals: n1_x, n1_y, n1_z, n2_x, n2_y, n2_z, […]
你需要注意 MappingInformationType 属性,它可以具有以下值:
- ByPolygon:按多边形处理,这意味着模型的每个多边形都有一个法线。
- ByPolygonVertex:按多边形顶点处理,这意味着模型的每个多边形的每个顶点都有一个法线。例如,如果模型有 8 个顶点组成四个四边形,则将有 16 个法线(1 个法线 * 4 个多边形 * 4 个多边形顶点)。 请注意,通常游戏引擎需要顶点仅定义一个法线。 因此,如果你发现一个顶点具有多个法线,可以忽略第一个法线之后找到的法线,或者计算所有法线的平均值(法线平滑)。
- ByVertex:按顶点处理,这意味着模型的每个顶点都有一个法线。有时也称为 ByVertice,如 Blender 导出器所写。我认为作者是西班牙人。
- ByEdge:按边处理,这意味着模型的每个边都有一个法线(罕见)
- AllSame:这意味着模型的每个顶点都有相同的法线,这对于大多数模型来说很少见或不可能。
另一个重要的属性是 ReferenceInformationType 属性,它可以具有以下值:
- Direct:表示法线是有序的。
- IndexToDirect(或旧版本 FBX 格式的索引):表示法线的顺序由 NormalsIndex 属性给出。
以下是一个可能比文字更清楚的图形示例。 示例模型是一个位于 X 轴和 Y 轴上的平面(因此所有顶点的 Z 坐标将为 0),由 9 个顶点和 4 个多边形(四边形)组成。 示例图是从顶部看到的平面视图。
6、FBX UV坐标
UV 坐标可以在 UV 属性中的子节点 LayerElementUV(它又是 Model 的子节点)下找到。 语法类似于顶点和法线的语法,但当然会有两个坐标而不是三个。
UV: u1, v1, u2, v2, […]
你仍然需要注意 MappingInformationType 和 ReferenceInformationType 属性! 这两个属性可以具有的值与法线的值相同,因此适用相同的规则。 索引属性(如果有,即定义了 IndexToDirect)是 UVIndex。
原文链接:FBX文件结构解读 — BimAnt
相关文章:

FBX文件结构解读【文本格式】
FBX 格式几乎受到所有 3D 引擎的支持,是 Autodesk 开发的 3D 模型的专有格式。它支持顶点、索引、法线、UV坐标、材质和动画。 FBX还支持许多其他类型的信息,但它们对游戏引擎几乎没有用处。 推荐:用 NSDT编辑器 快速搭建可编程3D场景 有两种…...

JS基础语法
JS是一门面向对象的编程语言,运行在客户端的脚本语言,可以基于Node.js进行服务器端编程 JS的作用: 表单动态校验网页特效服务端开发 浏览器执行JS: 浏览器分为两部分:渲染引擎和JS引擎 渲染引擎用来解析HTML和CSS,…...

【Zabbix监控一】zabbix的原理与安装
利用一个优秀的监控软件,我们可以: ●通过一个友好的界面进行浏览整个网站所有的服务器状态 ●可以在 Web 前端方便的查看监控数据 ●可以回溯寻找事故发生时系统的问题和报警情况 总结:zabbix主要功能 监控,cpu负载,内存使用&a…...

图的十字链表存储结构
1.其实就是邻接表和逆邻接表的结合,说明白点,就是用箭头表示出弧头,弧尾,以及他们之间的关系 2.顶点结构 3.弧结构 3.这样根据上面的结点十字链表结构就很好分析了...

精华回顾:Web3 前沿创新者在 DESTINATION MOON 共话未来
9 月 17 日,由 TinTinLand 主办的「DESTINATION MOON: Web3 Dev Summit Shanghai 2023」线下活动在上海黄浦如约而至。 本次 DESTINATION MOON 活动作为 2023 上海区块链国际周的 Side Event,设立了 4 场主题演讲与 3 个圆桌讨论,聚集了诸多…...
【RPC】gRPC 安装及使用
本文记录下 Mac 安装 gRPC 的过程。 参考:官网 1. gRPC 安装 gRPC 安装步骤如下: 克隆 grpc 代码 git clone --recurse-submodules -b v1.58.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc注意:不要直接 git clone http…...

Pygame中Sprite类的使用3
在Pygame中Sprite类的使用2_棉猴的博客-CSDN博客中提到了通过派生自pygame.sprite.Sprite类的自定义类Zombie,可以实现一个僵尸的移动。可以通过pygame.sprite.Group类实现对多个Zombie类实例的管理,即可以实现多个僵尸的移动。 1 pygame.sprite.Group类…...

23年下考前须知-软考中级信息安全工程师
信息安全工程师主要涉及计算机信息安全方面,在计算机软硬件、网络、应用相关领域从事安全系统设计、安全产品开发、产品集成、信息系统安全检测与审计等方面工作,服务单位可以是国家机关、企事业单位及科研教学单位等。 一、考试报名时间 信安考试一年…...

关于表单快速开发低代码技术平台的内容介绍
运用什么样的表单快速开发软件平台可以实现高效率创收?随着科技的进步和飞速发展,专业的低代码技术平台已经走入了很多企业的办公职场中,它们灵活、轻量级、优质、高效、易维护等优势特点,可以高效助力广大企业提质增效࿰…...

比特币 ZK 赏金系列:第 1 部分——支付解密密钥
以前,我们使用零知识赏金 (ZKB) 来支付比特币上的数独解决方案。在本系列中,我们将使用 ZKB 来解决范围更广的更实际的问题。 在第 1 部分中,我们应用 ZKB 来支付解密密钥。假设 Alice 使用对称密钥 K 加密她的文件。为了安全起见࿰…...
【Python深度学习】深度学习中框架和模型的区别
深度学习是人工智能领域的一股强大力量,它的快速发展离不开深度学习框架和模型的进步。本文将介绍深度学习框架和模型的基本概念、它们之间的联系与区别,以及如何根据项目需求选择合适的框架和模型。 一、深度学习框架 深度学习框架是进行深度学习研究和…...
MyBatis面试题(二)
文章目录 前言一、MyBatis 与 Hibernate 有哪些不同?二、MyBatis 的好处是什么?三、简述 Mybatis 的 Xml 映射文件和 Mybatis 内部数据结构之间的映射关系?四、什么是 MyBatis 的接口绑定,有什么好处?五、接口绑定有几种实现方式,…...

Android之MediaMetricsService实现本质(四十二)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…...

Flutter超好用的路由库-fluro
文章目录 fluro的介绍fluro简介安装和导入路由配置导航到路由参数传递 fluro的典型使用创建路由管理类代码解释例子小结 初始化路由导航到路由 总结 fluro的介绍 fluro简介 fluro是一个流行的Flutter插件,用于实现高级路由管理。它提供了灵活的路由配置和导航功能…...
约数个数(蓝桥杯)
约数个数 题目描述 本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。 答案:96 1200000 有多少个约数(只计算正约数)。 约数,又称因数。整数a除以整数b(b≠0) 除得的商正好是整…...
越狱(快速幂C++)
题目 监狱有连续编号为 11 到 n 的 n 个房间,每个房间关押一个犯人。 有 m 种宗教,每个犯人可能信仰其中一种。 不存在没有信仰的犯人。 如果相邻房间的犯人信仰的宗教相同,就可能发生越狱。 求有多少种状态可能发生越狱。 输入格式 共…...
电脑入门:怎么进入路由器设置
怎么进入路由器设置 在浏览器地址栏上输入路由器的出厂默认IP地址(192.168.0.1)后按回车。在登录窗口中输入说明书上的密码,点击“Log in”按钮进入宽带路由器管理设置界面。 管理设置界面分为左右栏,左栏是主菜单,右边则是与之对应的设置内容。 请根据自己接…...

Vue3大屏项目实现数字跳动的效果
一、vue-count-to组件: 1、安装: npm install vue3-count-to --save 2、使用: <template><BaseCountTo:startVal"startVal":endVal"endVal":duration"duration":decimals"decimals":pr…...

MATLAB打开历史命令窗口并保持
版本:matlab 2021a 方法:菜单栏 主页 - 布局 - 命令历史记录 - 停靠...
等差数列和等比数列 常用公式
等差数列 定义 通项公式 , 公差 , 前n项和公式 中项公式 下标:mnpq,则 等比数列 定义 通项公式 , 公比 , 前n项和公式 , 中项公式 下标:mnpq,则...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...

【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...