WinUI(WASDK)使用HelixToolkit加载3D模型并进行项目实践
2023/6/7 5:22:14
本文主要是介绍WinUI(WASDK)使用HelixToolkit加载3D模型并进行项目实践,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
前言
本人之前开发了一个叫电子脑壳的上位机应用,给稚晖君ElectronBot开源机器人提供一些功能,但是由于是结合硬件才能使用的软件,如果拥有硬件的人员太少,就会导致我的软件没什么人用,于是我就想着能不能将机器人硬件的模型加载到软件里,这样用户就可以不使用硬件也可以使用我的软件了。于是就有了在WinUI(WASDK)里使用3D模型的需求。
先来个B站复刻机器人的开箱视频吧。(如果感觉无聊可以直接拖到代码讲解部分)
库选择的纠结过程
在选择库的过程中其实并不是一帆风顺,因为WinUI(WASDK)是个比较新的框架,框架本身也没有提供3D模型加载的功能,于是我就在想到底选择什么样的办法加载,之前有看到一些UWP加载模型的demo,但是基本上就是封装的c++的库,对于我这c++垃圾的人来说还是很痛苦的,我的要求就是不能有c++代码。
要满足模型的加载,模型的旋转变换平移,模型材质的更换,在经过筛选以后,备选方案有three.js,HelixToolkit。
-
three.js
GitHub Copilot:
three.js
是一个基于 JavaScript 的 3D 图形库,它使用 WebGL 技术在浏览器中渲染 3D 图形。它提供了一组易于使用的 API,使用户可以创建高度可定制的 3D 场景,包括模型、纹理、光源和相机等部分。此外,three.js
还支持动画、物理模拟和粒子系统等功能,使用户可以创建逼真的 3D 动画效果。three.js
可以在多种浏览器和设备上运行,并且有一个庞大的社区支持和贡献。由于要和前端框架进行互操作,所以这个我也不是优先考虑了。
-
HelixToolkit(基于SharpDX再次封装的)
所用框架和库介绍
1. WASDK
这个框架是微软最新的UI框架,我主要是用来开发程序的主体,做一些交互和功能的承载,本质上和wpf,uwp这类程序没什么太大的区别,区别就是一些工具链的不同。
2. HelixToolkit
GitHub Copilot: HelixToolkit是一个面向.NET开发人员的3D图形库。它提供了一组控件和辅助类,用于在WPF和WinForms应用程序中创建和渲染3D场景。HelixToolkit支持多种3D文件格式,包括OBJ、STL和FBX,并包括照明、材质、纹理和动画等功能。它还支持高级渲染技术,如阴影、反射和透明度。HelixToolkit是开源的,可以从GitHub下载。
代码讲解
1. Demo项目介绍
demo项目地址
项目结构如下图:
处理过程
=>加载器加载模型=>将模型加载到模型组=>初始化相机=>进行数据到控件的绑定
2. 核心代码讲解
预备知识
-
SharpDX的坐标系是左手坐标系
GitHub Copilot: DirectX使用左手坐标系来描述3D空间中的对象位置和方向。在左手坐标系中,x轴向右,y轴向上,z轴向外(屏幕外)。这与右手坐标系的z轴方向相反。左手坐标系在计算机图形学中广泛使用,因为它与人眼的观察方式相符合。
- 3D场景下的模型变换(平移 旋转 缩放)
模型加载完成以后,就需要让模型动起来,这样才能算是完整的过程了。
核心旋转代码如下:
场景是将模型绕手臂点进行旋转,需要将手臂模型组移动到原点,旋转完成之后再移动到原来的位置。
3. 实际项目使用
下载电子脑壳源码
动作序列以及表情帧数据处理实际代码如下:
private void Instance_ModelActionFrame(object? sender, Verdure.ElectronBot.Core.Models.ModelActionFrame e) { BodyModel.HxTransform3D = _bodyMt * Matrix.RotationY(MathUtil.DegreesToRadians((e.J6))); Material = new DiffuseMaterial() { EnableUnLit = false, DiffuseMap = LoadTextureByStream(e.FrameStream) }; var nodeList = HeadModel.GroupNode; foreach (var itemMode in nodeList.Items) { if (itemMode.Name == "Head3.obj") { foreach (var node in itemMode.Traverse()) { if (node is MeshNode meshNode) { meshNode.Material = Material; } } } } var rightList = RightShoulderBoundingBox.GetCorners(); var rightAverage = new SharpDX.Vector3( (rightList[1].X + rightList[5].X) / 2f, ((rightList[1].Y + rightList[5].Y) / 2f) - 8f, (rightList[1].Z + rightList[5].Z) / 2f); var leftList = LeftShoulderBoundingBox.GetCorners(); var leftAverage = new SharpDX.Vector3( (leftList[0].X + leftList[4].X) / 2f, ((leftList[0].Y + leftList[4].Y) / 2f) - 8f, (leftList[0].Z + leftList[4].Z) / 2f); var translationMatrix = Matrix.Translation(-rightAverage.X, -rightAverage.Y, -rightAverage.Z); var tr2 = _rightArmMt * translationMatrix; var tr3 = tr2 * Matrix.RotationZ(MathUtil.DegreesToRadians(-(e.J2))); var tr4 = tr3 * Matrix.RotationX(MathUtil.DegreesToRadians(-(e.J3))); var tr5 = tr4 * Matrix.Translation(rightAverage.X, rightAverage.Y, rightAverage.Z); var tr6 = tr5 * Matrix.RotationY(MathUtil.DegreesToRadians((e.J6))); RightArmModel.HxTransform3D = tr6; var leftMatrix = Matrix.Translation(-leftAverage.X, -leftAverage.Y, -leftAverage.Z); var leftTr2 = _leftArmMt * leftMatrix; var leftTr3 = leftTr2 * Matrix.RotationZ(MathUtil.DegreesToRadians((e.J4))); var leftTr4 = leftTr3 * Matrix.RotationX(MathUtil.DegreesToRadians(-(e.J5))); var leftTr5 = leftTr4 * Matrix.Translation(leftAverage.X, leftAverage.Y, leftAverage.Z); var leftTr6 = leftTr5 * Matrix.RotationY(MathUtil.DegreesToRadians((e.J6))); LeftArmModel.HxTransform3D = leftTr6; var headMatrix = Matrix.Translation(-HeadModelCentroidPoint.X, -HeadModelCentroidPoint.Y, -HeadModelCentroidPoint.Z); var headTr2 = _headMt * headMatrix; var headTr3 = headTr2 * Matrix.RotationX(MathUtil.DegreesToRadians(-(e.J1))); var headTr4 = headTr3 * Matrix.Translation(HeadModelCentroidPoint.X, HeadModelCentroidPoint.Y, HeadModelCentroidPoint.Z); var headTr5 = headTr4 * Matrix.RotationY(MathUtil.DegreesToRadians((e.J6))); HeadModel.HxTransform3D = headTr5; }
最终效果如下:
个人感悟
通过模型加载的这个过程的学习,最大的感悟就是编程开发其实只是运用工具实现自己的想法,这个过程中我们对于工具的使用可能比较熟悉了,但是如果我们的领域知识不够丰富,那基本上也是做不了什么的,所以学习一些东西的时候我们的相关知识也要进行学习才好。
我也是在这个过程中才学习了什么是左手坐标系,以及4x4矩阵的变换和相机视角。这些东西都是和框架无关的知识,假如我们都学精通了,用什么框架实现我们的想法其实都不是问题了。
总结,还是要努力学习呀。
参考推荐文档项目如下
demo地址
电子脑壳
WASDK文档地址
ElectronBot
HelixToolkit
这篇关于WinUI(WASDK)使用HelixToolkit加载3D模型并进行项目实践的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-10百万架构师第十三课:源码分析:Spring 源码分析:Spring核心IOC容器及依赖注入原理|JavaGuide
- 2025-01-10便捷好用的电商API工具合集
- 2025-01-09必试!帮 J 人团队解决物流错发漏发的软件神器!
- 2025-01-09不容小觑!助力 J 人物流客服安抚情绪的软件!
- 2025-01-09为什么医疗团队协作离不开智能文档工具?
- 2025-01-09惊叹:J 人团队用啥软件让物流服务快又准?
- 2025-01-09如何利用数据分析工具优化项目资源分配?4种工具推荐
- 2025-01-09多学科协作难?这款文档工具可以帮你省心省力
- 2025-01-09团队中的技术项目经理TPM:工作内容与资源优化策略
- 2025-01-09JIT生产管理法:优化流程,提升竞争力的秘诀