WinUI(WASDK)使用HelixToolkit加载机器人3D模型并进行项目实践

这篇具有很好参考价值的文章主要介绍了WinUI(WASDK)使用HelixToolkit加载机器人3D模型并进行项目实践。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

本人之前开发了一个叫电子脑壳的上位机应用,给稚晖君ElectronBot开源机器人提供一些功能,但是由于是结合硬件才能使用的软件,如果拥有硬件的人员太少,就会导致我的软件没什么人用,于是我就想着能不能将机器人硬件的模型加载到软件里,这样用户就可以不使用硬件也可以使用我的软件了。于是就有了在WinUI(WASDK)里使用3D模型的需求。

最终效果如下:
WinUI(WASDK)使用HelixToolkit加载机器人3D模型并进行项目实践

先来个B站复刻机器人的开箱视频吧。(如果感觉无聊可以直接拖到代码讲解部分)

WinUI(WASDK)使用HelixToolkit加载机器人3D模型并进行项目实践

库选择的纠结过程

在选择库的过程中其实并不是一帆风顺,因为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项目地址

项目结构如下图:
WinUI(WASDK)使用HelixToolkit加载机器人3D模型并进行项目实践

处理过程

=>加载器加载模型=>将模型加载到模型组=>初始化相机=>进行数据到控件的绑定

2. 核心代码讲解

预备知识

  • SharpDX的坐标系是左手坐标系

    GitHub Copilot: DirectX使用左手坐标系来描述3D空间中的对象位置和方向。在左手坐标系中,x轴向右,y轴向上,z轴向外(屏幕外)。这与右手坐标系的z轴方向相反。左手坐标系在计算机图形学中广泛使用,因为它与人眼的观察方式相符合。

WinUI(WASDK)使用HelixToolkit加载机器人3D模型并进行项目实践

  • 3D场景下的模型变换(平移 旋转 缩放)

模型加载完成以后,就需要让模型动起来,这样才能算是完整的过程了。

核心旋转代码如下:

WinUI(WASDK)使用HelixToolkit加载机器人3D模型并进行项目实践

场景是将模型绕手臂点进行旋转,需要将手臂模型组移动到原点,旋转完成之后再移动到原来的位置。

3. 实际项目使用

下载电子脑壳源码

WinUI(WASDK)使用HelixToolkit加载机器人3D模型并进行项目实践

动作序列以及表情帧数据处理实际代码如下:

 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;
    }

最终效果如下:
WinUI(WASDK)使用HelixToolkit加载机器人3D模型并进行项目实践

个人感悟

通过模型加载的这个过程的学习,最大的感悟就是编程开发其实只是运用工具实现自己的想法,这个过程中我们对于工具的使用可能比较熟悉了,但是如果我们的领域知识不够丰富,那基本上也是做不了什么的,所以学习一些东西的时候我们的相关知识也要进行学习才好。

我也是在这个过程中才学习了什么是左手坐标系,以及4x4矩阵的变换和相机视角。这些东西都是和框架无关的知识,假如我们都学精通了,用什么框架实现我们的想法其实都不是问题了。

总结,还是要努力学习呀。

参考推荐文档项目如下

demo地址

电子脑壳

WASDK文档地址

ElectronBot

HelixToolkit文章来源地址https://www.toymoban.com/news/detail-475751.html

到了这里,关于WinUI(WASDK)使用HelixToolkit加载机器人3D模型并进行项目实践的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RobotStudio的基本布局方法,模型加载,工件坐标系的创建,手动操作机器人示教,以及模拟仿真机器人运动轨迹。

    1、在文件功能选项卡中,选择【空工作站】,单击【创建】,创建一个新的工作站。 2、在【基本】功能选项卡中,打开【ABB模型库】,选择【IRB2600】。 3、设定好数值,然后单击【确认】。 4、在【基本】功能选项里,打开【导入模型库】—【设备】,选择【myTool】。 5、右

    2023年04月08日
    浏览(198)
  • 对话机器人:使用 Python TensorFlow 训练 Chatbot 聊天机器人

    作者:禅与计算机程序设计艺术 为了能够在Facebook Messenger上与用户进行实时的沟通,开发者需要自行构建聊天机器人。然而,构建聊天机器人的过程却很复杂,需要掌握众多的技术、技能和知识。本文通过详细地阐述了如何用Python语言构建一个Facebook Messenger聊天机器人,并分

    2024年02月08日
    浏览(57)
  • 【机器人模拟-01】使用URDF在中创建模拟移动机器人

            在本教程中,我将向您展示如何使用 通用机器人描述格式 (URDF)(机器人 建模的标准 ROS 格式)创建模拟移动机器人。         机器人专家喜欢在构建机器人之前对其进行模拟,以测试不同的算法。您可以想象,使用物理机器人犯错的成本可能很高(例如,

    2024年02月16日
    浏览(56)
  • 遨博协作机器人高级编程 - 遨博机器人SDK用户自定义算法接口介绍与使用

    目录 一、简介 二、环境版本 三、开发环境部署 1.二次开发资料下载 2. AUBO PE编程仿真环境配置 四、linux C++ SDK示例 1. 编程环境 2. 加载C++ SDK工程 3. linux C++ SDK 文件构成 4.运行SDK示例 五、构建用户自定义算法SDK示例工程 1.Linux C++ SDK透传接口 2.  创建新项目 3.导入遨博机器人

    2024年02月14日
    浏览(55)
  • python飞机如何使用机器人

    1 电报账号,添加BotFather为好友,开始与它对话 2 对话框发送 /newbot ,提示你给机器人取名,必须以_bot或者Bot结尾. 3 提示你创建成功,会发送给你机器人的token=5418209785:AAGTKNOWLsOZFrONoqj26pq833pM79VUDrIm,记住这个token, 到这里机器人就创建好了 4 创建个群组,把机器人拉进群组,在群组

    2024年02月12日
    浏览(48)
  • 使用telegram机器人发送通知

    在训练深度学习模型时,除了粗略估计外,很难预测训练何时结束。此外,我们可能还想随时随地查看训练情况,如果每次都需要登录回服务器的话并不方便。因此,为我们的训练设置自动通知会大有裨益。 相关的插件和库其实很多,例如而knockknock、dinglingling,但是存在着

    2024年02月22日
    浏览(58)
  • 微信机器人的构建与使用

    一个不知名大学生,江湖人称菜狗 original author: jacky Li Email : 3435673055@qq.com Time of completion:2022.12.15 Last edited: 2022.12.17 目录 《微信机器人》程序使用说明 微信机器人使用说明 1.项目说明 2.  系统环境 3.准备条件 4.操作步骤 部分代码: 首先启动 Flask项目 ,然后启动 小米球内

    2024年02月09日
    浏览(45)
  • 【算法】行星碰撞&机器人碰撞(栈的使用)

    本文记录了两个使用栈来处理碰撞问题的算法题目。 https://leetcode.cn/problems/asteroid-collision/ 对于这种题目,各个元素分别会向左或向右移动,可以使用栈模拟碰撞的过程。 由于从左往右进行遍历,因此遍历当前元素时,如果它是向右移动的,就只可能会碰撞到它右边还没有被

    2024年02月16日
    浏览(46)
  • matlab机器人工具箱基础使用

    资料:https://blog.csdn.net/huangjunsheng123/article/details/110630665 test1.m

    2024年02月12日
    浏览(54)
  • 使用Streamlit 实现一个聊天机器人界面

    效果如下: 只需要效果generate_llama2_response 为你的 llm的输出即可。

    2024年03月09日
    浏览(85)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包