wpf加载带材料的3D模型(下载的3D预览一样有纹理)
背景:最近真的是忙啊,累出汁水了
整体效果:
放大可以看清砖头:
1、需要自己准备好3D模型,比如我这里是下载的这里的3D Warehouse,下载Collada File格式文件
2、解压可以看到一个model.dae和材料的文件夹,如果只是使用这个3D的结构不需要图片的材料就直接导入blender然后导出.obj就拿去用就行了。但是如果想要在WPF中也加载这些材料出来就需要在导出的时候勾选材料,然后路径选择相对(好像这个相对的没有什么作用)
3、然后就可以看到导出的内容有文件和一个.obj、一个.mtl
4、关键来了,这个.mtl文件就是决定包含什么材料
如果材料想要放到两个文件的同一个文件夹就将.mtl中的对应的两行改为
map_Kd ./__Brick-dark_grout_.jpg
map_Kd ./__Metal-floor_.jpg
如果是想要跟我图片那样用一个文件夹存材料图片就将.mtl文件对应的两行修改为
map_Kd ./textures/__Brick-dark_grout_.jpg
map_Kd ./textures/__Metal-floor_.jpg
将这些加到项目后还需要将材料和两个文件修改为(不然运行报错)
5、然后就是正常载入这个.obj就可以看见跟下载预览一样的3D了
xaml(有点乱,有些没相关的东西没删除):
<ht:HelixViewport3D Name="viewport" ShowCoordinateSystem="True"><!--相机--><ht:HelixViewport3D.Camera><PerspectiveCamera Position="100,100,100"LookDirection="-100,-100,-100"UpDirection="0,0,1"FieldOfView="80"></PerspectiveCamera></ht:HelixViewport3D.Camera><ht:HelixViewport3D.RotateGesture><MouseGesture MouseAction="LeftClick"/></ht:HelixViewport3D.RotateGesture><ht:HelixViewport3D.PanGesture><MouseGesture MouseAction="RightClick"/></ht:HelixViewport3D.PanGesture><!--光源--><!--<ht:DefaultLights/>--><ModelVisual3D><ModelVisual3D.Content><Model3DGroup><!--环境光:提亮整体的环境亮度--><AmbientLight Color="#999"/><!--点光源:光影层次感--><PointLight Color="#DDD" Position="100,0,100"/></Model3DGroup></ModelVisual3D.Content></ModelVisual3D><!--模型--><ModelUIElement3D Visibility="Collapsed"><ModelUIElement3D.Model><Model3DGroup><GeometryModel3D><!--模型的点线面--><GeometryModel3D.Geometry><MeshGeometry3D Positions="2,-2,4 2,2,4 2,2,0 2,-2,0-2,-2,4 -2,2,4 -2,2,0 -2,-2,0"TriangleIndices="0,2,1 0,3,24,0,1 4,1,51,2,6 1,6,55,6,7 5,7,44,7,3 4,3,03,6,2 3,7,6"/></GeometryModel3D.Geometry><GeometryModel3D.Material><DiffuseMaterial Brush="Orange"/></GeometryModel3D.Material><GeometryModel3D.BackMaterial><DiffuseMaterial Brush="Red"/></GeometryModel3D.BackMaterial></GeometryModel3D></Model3DGroup></ModelUIElement3D.Model></ModelUIElement3D><ModelUIElement3D Visibility="Collapsed"><ModelUIElement3D.Transform><TranslateTransform3D OffsetZ="4"/></ModelUIElement3D.Transform><ModelUIElement3D.Model><GeometryModel3D><GeometryModel3D.Geometry><!--Positions="1,-1,6 1,1,6 1,1,4 1,-1,4-1,-1,6 -1,1,6 -1,1,4 -1,-1,4"--><MeshGeometry3D Positions="1,-1,2 1,1,2 1,1,0 1,-1,0-1,-1,2 -1,1,2 -1,1,0 -1,-1,0"TriangleIndices="0,2,1 0,3,24,0,1 4,1,51,2,6 1,6,55,6,7 5,7,44,7,3 4,3,03,6,2 3,7,6"/></GeometryModel3D.Geometry><GeometryModel3D.Material><DiffuseMaterial Brush="LavenderBlush"/></GeometryModel3D.Material></GeometryModel3D></ModelUIElement3D.Model></ModelUIElement3D></ht:HelixViewport3D>
code_hehind:
#region 带材料的一个房屋string path = Environment.CurrentDirectory;
path = System.IO.Path.Combine(path, "3d导出", "test1.obj");path = System.IO.Path.Combine(Environment.CurrentDirectory, "3d导出", "test2.obj");ModelImporter modelImporter = new ModelImporter();Model3DGroup group = modelImporter.Load(path);// 创建Transform3D对象,沿Y轴(或Z轴)进行平移
Transform3DGroup transformGroup = new Transform3DGroup();
TranslateTransform3D translate = new TranslateTransform3D(15, 20, 26); // 调整Y轴或Z轴的数值
transformGroup.Children.Add(translate);// 旋转
RotateTransform3D rotateX = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1, 0, 0), 90)); // 沿X轴旋转90度
//RotateTransform3D rotateY = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 90)); // 沿Y轴旋转90度
transformGroup.Children.Add(rotateX);
//transformGroup.Children.Add(rotateY);group.Transform = transformGroup;ModelVisual3D modelVisual3D = new ModelVisual3D();
modelVisual3D.Content = group;
viewport.Children.Add(modelVisual3D);#endregion
地面的代码(有点简陋):
private void CreateGround()
{ModelUIElement3D elemet = new ModelUIElement3D();GeometryModel3D model = new GeometryModel3D();model.Material = MaterialHelper.CreateMaterial(Brushes.LightGray, null, null, 1);model.BackMaterial = MaterialHelper.CreateMaterial(Brushes.LightGray, null, null, 1);// 地平面var builder = new MeshBuilder(false, false);builder.AddQuad(new Point3D(100, 100, 0),new Point3D(-100, 100, 0),new Point3D(-100, -100, 0),new Point3D(100, -100, 0));model.Geometry = builder.ToMesh(true);elemet.Model = model;this.viewport.Children.Add(elemet);
}
相关文章:

wpf加载带材料的3D模型(下载的3D预览一样有纹理)
背景:最近真的是忙啊,累出汁水了 整体效果: 放大可以看清砖头: 1、需要自己准备好3D模型,比如我这里是下载的这里的3D Warehouse,下载Collada File格式文件 2、解压可以看到一个model.dae和材料的文件夹&…...

【k8s之深入理解调度】调度框架扩展点理解
参考自 K8s 调度框架设计与 scheduler plugins 开发部署示例(2024) 调度插件扩展点 等待调度阶段PreEnqueuePod 处于 ready for scheduling 的阶段。 内部工作原理:sig-scheduling/scheduler_queues.md。在 Pod 被放入调度队列之前执行的插…...

音视频基础理论
1. 音频基础 1.1 音频基本概念 1.1 频率:声波的频率,即声音的音调,人类听觉的频率(音调)范围为20Hz--20KHz 1.2 振幅:即声波的响度,通俗的讲就是声音的高低,一般男生的声音振幅(响度)大于女生。 1.3 波形…...
《江苏科技大学学报(自然科学版)》
《江苏科技大学学报(自然科学版)》(双月刊,国内外公开发行)是由江苏省教育厅主管、江苏科技大学主办的理工类学术期刊,1986年创刊,国际刊号:ISSN1673-4807,国内刊号&…...

C++初学者指南-5.标准库(第二部分)–随机数生成
C初学者指南-5.标准库(第二部分)–随机数生成 文章目录 C初学者指南-5.标准库(第二部分)–随机数生成基本概念例子统一随机数布尔值(“抛硬币”)正态分布具有独立概率的整数 怎么做种子引擎使用自定义生成器 shuffle算法分布类型概述通用接口均匀分布采样…...
Unity2017在安卓下获取GPS位置时闪退的解决办法
在Unity使用低功耗蓝牙通信(BLE)需要用到设备的位置信息。但是调用Input.location.Start()程序会闪退。 解决办法:调用原生安卓接口。 参见《Unity2021通过aar调用Android方法》编写一个aar插件gpsplugin,在插件中提供获取GPS位…...

OpenGL ES 索引缓冲区(4)
OpenGL ES 索引缓冲区(4) 简述 本节会介绍索引缓冲区,索引缓冲区和顶点缓冲区类似,也是显存上的一段内存,只不过上面的数据用处不同,索引缓冲区故名思义里面的数据是用于索引,主要作用是用于复用顶点缓冲区里的数据。…...

01:(寄存器开发)点亮一个LED灯
寄存器开发 1、单片机的简介1.1、什么是单片机1.2、F1系列内核和芯片的系统架构1.3、存储器映像1.4、什么是寄存器 2、寄存器开发模板工程3、使用寄存器点亮一个LED4、代码改进15、代码改进2 本教程使用的是STM32F103C8T6最小系统板,教程来源B站up“嵌入式那些事”。…...
.Net 6.0 Windows平台如何判断当前电脑是否联网
最近在工作中开发需要判断当前电脑是否联网的需求,在网上找了一个调用window API来判断本机是否联网。具体请看下面介绍: 1.方法一(调用winAPI) [DllImport("wininet")] public static extern bool InternetGetConnec…...

微软准备了 Windows 11 24H2 ISO “OOBE/BypassNRO“命令依然可用
Windows 11 24H2 可能在未来几周内开始推出。 微软已经要求 OEM 遵循新的指南准备好 Windows 11 24H2 就绪的驱动程序,并且现在已经开始准备媒体文件 (.ISO)。 OEM ISO 的链接已在微软服务器上发布。 一个标有"X23-81971_26100.1742.240906-0331.ge_release_sv…...
MacOS 终端执行安装 Brew
在配置新的 Mac 环境时,如果你发现终端中无法识别 brew 命令,可以按照以下步骤进行解决。 步骤 1:确保网络稳定 为了避免安装过程中出现中断,建议使用 Wi-Fi 或有线连接,不推荐使用移动网络。 步骤 2:打…...

【设计模式-解释模式】
定义 解释器模式是一种行为设计模式,用于定义一种语言的文法,并提供一个解释器来处理该语言的句子。它通过为每个语法规则定义一个类,使得可以将复杂的表达式逐步解析和求值。这种模式适用于需要解析和执行语法规则的场景。 UML图 组成角色…...

51单片机应用开发(进阶)---数码管+按键+蜂鸣器(电磁炉显示模拟)
实现目标 1、加强数码管、按键的学习,实现数码显示变量数据(四位数的显示); 2、4位数码2个按键无源蜂鸣器实现模拟电磁炉功率调节及显示; 一、内容描述 功能描述:1、开机显示电磁炉功率300,每…...

Emergency Stop (ES)
文章目录 1. 介绍2. Feature List3. 紧急停止信号触发方式3.1 Port触发紧急停止信号3.2 SMU事件触发紧急停止信号3.3 软件触发紧急停止信号 4. 应用场景4.1 Port4.2 MSC 1. 介绍 Emergency Stop (ES)是Ifx System Control Units (SCU)六大模块之一。详细信息可以参考Infineon-…...
[C++][第三方库][gtest]详细讲解
目录 1.介绍2.安装3.使用1.头文件包含2.框架初始化接口3.调用测试样例4.TEST宏5.断言宏6.示例 1.介绍 gtest是一个跨平台的C单元测试框架,由Google公司发布gtest是为了在不同平台上为编写C单元测试而生成的,它提供了丰富的断言、致命和非致命判断、参数…...

【Java数据结构】 链表
【本节目标】 1. ArrayList 的缺陷 2. 链表 3. 链表相关 oj题目 一. ArrayList的缺陷 上节课已经熟悉了ArrayList 的使用,并且进行了简单模拟实现。通过源码知道, ArrayList 底层使用数组来存储元素: public class ArrayList<E>…...

前端——Ajax和jQuery
一、Ajax Ajax即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML), 通过 JS 异步的向服务器发送请 求并接收响应数据。 同步访问:当客户端向服务器发送请求时,服务器在处理的过程中,浏览器…...

C++-vector模拟实现
###vector底层相当于是数组,查看源码可以发现,这个类的私有成员变量是三个迭代器;在实现时迭代器就可以当作是vector里面的元素的指针类型; ###vector是一个类模板,实现时也应当按照这样的写法用一个模板去实现&#…...

Activity
69[toc] 1.启停活动页面 1.Activity启动和结束 从当前页面跳到新页面 startActivity(new Intent(this, ActFinishActivity.class));从当前页面返回上一个页面,相当于关闭当前页面 finish();2.Activity生命周期 官方描述生命周期 onCreate:创建活…...
【力扣 | SQL题 | 每日四题】力扣1581, 1811, 1821, 1831
今天的题目就1811这个比较难,其他非常的基础。 1. 力扣1581:进店却未进行过交易的顾客 1.1 题目: 表:Visits ---------------------- | Column Name | Type | ---------------------- | visit_id | int | | customer…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...