wpf 3D学习

最近在看一些关于wpf 3d的效果,研究了一些代码特效,现在和广大博友共享一下.

首先用到的是MeshGeometry3D,msdn上介绍:用于生成三维形状的三角形基元。
主要有4个依赖属性:NormalsProperty,PositionsProperty,TextureCoordinatesProperty,
TriangleIndicesProperty。4中属性具体含义大家可以直接参考msdn上。

具体代码如下:

MeshGeometry3D meshGeometry3D = new MeshGeometry3D();Point3DCollection positions = new Point3DCollection();positions.Add(new Point3D(0, 0, 1));positions.Add(new Point3D(0, 0, 0));positions.Add(new Point3D(1, 0, 0));positions.Add(new Point3D(1, 0, 1));positions.Add(new Point3D(0, 1, 1));positions.Add(new Point3D(0, 1, 0));positions.Add(new Point3D(1, 1, 0));positions.Add(new Point3D(1, 1, 1));positions.Freeze();Int32Collection triangleIndices = new Int32Collection();triangleIndices.Add(0);triangleIndices.Add(1);triangleIndices.Add(2);triangleIndices.Add(2);triangleIndices.Add(3);triangleIndices.Add(0);triangleIndices.Add(4);triangleIndices.Add(7);triangleIndices.Add(6);triangleIndices.Add(6);triangleIndices.Add(5);triangleIndices.Add(4);triangleIndices.Add(0);triangleIndices.Add(3);triangleIndices.Add(7);triangleIndices.Add(7);triangleIndices.Add(4);triangleIndices.Add(0);triangleIndices.Add(1);triangleIndices.Add(5);triangleIndices.Add(6);triangleIndices.Add(6);triangleIndices.Add(2);triangleIndices.Add(1);triangleIndices.Add(3);triangleIndices.Add(2);triangleIndices.Add(6);triangleIndices.Add(6);triangleIndices.Add(7);triangleIndices.Add(3);triangleIndices.Add(0);triangleIndices.Add(4);triangleIndices.Add(5);triangleIndices.Add(5);triangleIndices.Add(7);triangleIndices.Add(0);triangleIndices.Freeze();// finally set the datameshGeometry3D.TriangleIndices = triangleIndices;meshGeometry3D.Positions = positions;

然后定义GeometryModel3D,代码:

// create the geometry modelGeometryModel3D geom3D = new GeometryModel3D();geom3D.Geometry = meshGeometry3D;Color color = WpfUtil.HsbToRgb(index / (float)count, .9f, 1f);SolidColorBrush solidColorBrush = new SolidColorBrush(color);solidColorBrush.Freeze();geom3D.Material = new DiffuseMaterial(solidColorBrush);

然后将GeometryModel3D归入Model3DGroup中,代码:

Model3DGroup group = new Model3DGroup();group.Children.Add(geom3D);ModelVisual3D model = new ModelVisual3D();model.Content = group;DirectionalLight dl = new DirectionalLight();dl.Color = Colors.White; dl.Direction = new Vector3D(-1, -1, -3);group.Children.Add(dl);AmbientLight al = new AmbientLight();al.Color = (Color)ColorConverter.ConvertFromString("#555555");group.Children.Add(al);

xaml如下:

<ModelVisual3D><ModelVisual3D.Content><Model3DGroup><DirectionalLight Direction="1 0 -2"Color="White"/><GeometryModel3D><GeometryModel3D.Geometry><!--Positions获取或设置 meshgeometry3d 的顶点位置的集合TextureCoordinates获取或设置 meshgeometry3d 的纹理坐标的集合TriangleIndices获取或设置 meshgeometry3d 的三角形索引的集合--><MeshGeometry3D Positions="-1 1 0, 0 1 1, -1 0 0, 0 0 1, 0 1 1, 1 1 0, 0 0 1, 1 0 0"TriangleIndices="2 1 0, 2 3 1, 6 5 4, 6 7 5"/></GeometryModel3D.Geometry><GeometryModel3D.Material><DiffuseMaterial Brush="Green"/></GeometryModel3D.Material></GeometryModel3D></Model3DGroup></ModelVisual3D.Content></ModelVisual3D>

上面已经设置了灯光,接下来要设置摄像机,代码如下:

var camera=new PerspectiveCamera( new Point3D(0,3,3),new Vector3D(0,-3,-3),new Vector3D(0,0,1),45););

xmal:

<Viewport3D.Camera><!--<PerspectiveCamera Position="0,0,10"/>--><PerspectiveCamera  LookDirection = " 0,  -3, -3"UpDirection   = " 0,  0,  1"Position      = "0,  3,  3"FieldOfView   = "45" /></Viewport3D.Camera>

最后可以把它们一起归入Viewport3D

Viewport3D view3D=new Viewport3D();
view3D.Camera = camera;
view3D.Children.Add(group);

当然我们也可以在指定灯光时,只定义DirectionalLight (方向光)

  <ModelVisual3D><ModelVisual3D.Content><Model3DGroup><!--<AmbientLight Color="White"/>--><DirectionalLight Color="#FFFFFF" Direction="0,0,-10" /><DirectionalLight Color="#FFFFFF" Direction="1,0,0" /></Model3DGroup></ModelVisual3D.Content></ModelVisual3D>

然后自定义3D模型

<local:TreeMap3D x:Name="_treeMap3D" WeightBindingPath="CustomerCount"><local:TreeMap3D.Transform><Transform3DGroup><ScaleTransform3D ScaleX="1.2" ScaleY="1.2" ScaleZ="1.2" /><RotateTransform3D><RotateTransform3D.Rotation><AxisAngleRotation3D Angle="30" Axis="0, 0, 1" /></RotateTransform3D.Rotation></RotateTransform3D><TranslateTransform3D OffsetZ="0.6" OffsetX="-0.3"/></Transform3DGroup></local:TreeMap3D.Transform></local:TreeMap3D>

添加TreeMap3D类

public class TreeMap3D : UIElement3D
{
private string m_weightBindingPath;private IList m_itemsSource;private TreeMap3DElement m_selectedElement;private int[] m_weightMap;private TreeMap3DElement m_lastClickedElement;private readonly List<TreeMap3DElement> m_elements = new List<TreeMap3DElement>();
}
}

定义ItemSource

public IList ItemsSource{get{VerifyAccess();return m_itemsSource;}set{if (m_itemsSource != value){VerifyAccess();refresh(value);m_itemsSource = value;}}

定义其子元素:

private class TreeMap3DElement : UIElement3D
{
public TreeMap3DElement(int index, int count){this.Visual3DModel = GenerateTreeMap3DModel(index, count);m_translate = new TranslateTransform3D();m_scale = new ScaleTransform3D();Transform3DGroup t3DGroup = new Transform3DGroup();t3DGroup.Children.Add(m_scale);t3DGroup.Children.Add(m_translate);base.Transform = t3DGroup;}
private object m_data;private string m_weightBindingPath;private bool m_isSelected;private double m_scaleZ;private readonly ScaleTransform3D m_scale;private readonly TranslateTransform3D m_translate;
}

加入动画设计:

public bool IsSelected{get { return m_isSelected; }set{if (value != m_isSelected){DoubleAnimation animation = new DoubleAnimation();if (value){animation.From = m_scale.ScaleZ;animation.To = m_scaleZ;}else{animation.From = m_scale.ScaleZ;animation.To = 0;}m_isSelected = value;animation.Duration = new Duration(TimeSpan.FromSeconds(0.2));m_scale.BeginAnimation(ScaleTransform3D.ScaleZProperty, animation);}}}

最后运行如下:

代码下载:http://files.cnblogs.com/gavinhuang/3DViewTest.rar

转载于:https://www.cnblogs.com/gavinhuang/archive/2013/03/20/2971187.html

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

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

相关文章

字符设备驱动高级篇4——自动创建设备文件的函数代码分析

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、概述 设备文件的创建&#xff0c;主要涉及class_create()函数、device_create()函数。 class_create()函数用于自动创建 /sys/class/目录下的xxx目录。 device_create()函数用于自动创建 /dev/…

unicode字符、python乱码问题

http://www.cnblogs.com/BeginMan/archive/2013/08/08/3246619.html#a1 Python常见常用知识点http://blog.csdn.net/tingsking18/article/details/4033645 Unicode和Python的中文处理如何让Python的Unicode字符串支持中文&#xff1f;要想利用Python的Unicode机制处理字符串&…

win10下如何安装vb6.0sp6_Mac如何安装win10系统?Parallels Desktop 15 Mac安装win10系统教程...

Parallels Desktop 15 mac版是mac上非常强大也非常好用的虚拟机软件&#xff0c;最新版本的parallels desktop mac 15针对最新的Windows 10更新和macOS Catalina&#xff08;10.15&#xff09;进行了优化。今天分享的内容就是Parallels Desktop 15 mac版如何安装win10系统。PD虚…

android面试题精选

1.android dvm 的进程和Linux的进程&#xff0c;应用程序的进程是否为同一个概念&#xff1a; 答&#xff1a;dvm是dalivk虚拟机。每一个android应用程序都在自己的进程中运行&#xff0c;都拥有一个dalivk虚拟机实例。而每一个dvm都是在linux的一个进程。所以说可以认为是同一…

字符设备驱动高级篇5——静态映射表的建立过程,动态映射结构体方式操作寄存器

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 补充内容&#xff1a;字符设备驱动基础5——驱动如何操控硬件_天糊土的博客-CSDN博客 一、静态映射表的建立过程 关于“静态映射表的建立”这部分内容&#xff0c;有以下三个关键&#xff1a; &…

python 分布图_python数据分布型图表柱形分布图系列带误差线的柱形图

柱形分布图系列柱形分布图系列使用柱形图的方式展示数据的分布规律&#xff1b;可以借助误差线或散点图&#xff1b;带误差线的柱形图就是使用每个类别的均值作为柱形的高度&#xff1b;再根据每个类别的标准差绘制误差线&#xff1b;缺点&#xff1a;无法显示数据的分布情况&a…

[汇编] 002基础知识-CPU和寄存器

CPU是什么 当然这里的内存不仅仅指电脑上的内存&#xff0c;例如&#xff1a;我的金士顿8G内存&#xff0c;七彩虹1G独显&#xff0c;在这里来说&#xff0c;显卡也是有内存的(寄存器) CPU如何控制其它部件的&#xff1f; 问题&#xff1a;CPU是如何和电脑主机中其它芯片有条不…

Asp.net中页面传值几种方式

页面传值是学习asp.net初期都会面临的一个问题&#xff0c;总的来说有页面传值、存储对象传值、ajax、类、model、表单等。但是一般来说&#xff0c;常用的较简单有QueryString&#xff0c;Session&#xff0c;Cookies&#xff0c;Application&#xff0c;Server.Transfer。  …

字符设备驱动高级篇6——内核提供的读写寄存器接口

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 1、访问寄存器的方式 之前对寄存器的操作&#xff0c;都是先定义指向寄存器的指针&#xff0c;然后再解引用来对寄存器进行操作。这是因为ARM体系中&#xff0c;内存和IO是统一编址的。但是其他体系…

java台球游戏设计原理_Java实现简单台球游戏

Java实现简单台球桌问题&#xff0c;供大家参考&#xff0c;具体内容如下需求&#xff1a;使小球可以在桌面上移动&#xff0c;移动到桌面边缘将被弹回&#xff0c;显示小区的移动素材&#xff1a;小球照片桌球照片程序源代码&#xff1a;package 桌球游戏;import java.awt.*;i…

wordpress教程:默认http头信息X-Pingback的隐藏与修改

利用站长工具的http状态查询工具查询可以看到类似如下的一段http HEAD信息 X-Pingback: http://www.kristain.com/wordpress真实路径/xmlrpc.php 其实这样就已经暴露了wordpress网站的真实路径了&#xff0c;那么如何来隐藏wordpress默认http HEAD信息中的X-Pingback信息呢&…

关于java assertion

大部分转载自参考资料&#xff1a;http://www.ibm.com/developerworks/cn/java/l-javaassertion/index.html assertion(断言)在软件开发中是一种常用的调试方式&#xff0c;assertion就是在程序中的一条语句&#xff0c;它对一个boolean表达式进行检查&#xff0c;一个正确程序…

mupdf不支持x64_Delphi xe2使用x64编译器编译ASM代码时出错 . 不支持的语言功能:'ASM'...

代码无法直接正确移植到x64&#xff0c;因为它将执行64位指针截断 - 有关详细信息&#xff0c;请参见下文 .64位应用程序不支持将汇编语句与Pascal代码混合使用 . 使用Pascal代码或完全用汇编编写的函数替换汇编语句 .这里使用装配是不必要的 . 我不确定为什么原作者会选择去解…

IOC是什么?

2019独角兽企业重金招聘Python工程师标准>>> Inversion of Control&#xff0c;即反转控制&#xff0c;或许说为依赖注入更为合适。IoC就是一种设计模式。 Interface Driven Design接口驱动&#xff0c;接口驱动有很多好处&#xff0c;可以提供不同灵活的子类实现&a…

poj2516Minimum Cost

http://poj.org/problem?id2516 建图的时候 有个地方写错了 卡了半年。。 题意看了N久啊 有N个店主需要K种物品 有M个供应点 每个供应点有K种物品 其实是算K次最小费用 然后叠加 分解开来这题就是求把某种物品从供应点送到店主那里 多个源点-》多个汇点 所以加一个超级源点 和…

设备驱动框架1——LED驱动框架的分析(核心层)

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、驱动框架的含义 1、理解层面1&#xff1a;驱动的分层设计 设备驱动程序&#xff0c;是由内核驱动部分的维护者&#xff0c;以及驱动开发工程师协作完成的。 内核驱动部分的维护者&#xff0c;往…

myeclipse连接mysql怎么调用_myeclipse连接mysql数据库详细步骤

第一步 打开Database windows-prefenrence-showview-DBbrowser ,此时会在工具底部有个DBbrowser &#xff0c;选中它&#xff0c;再它所控制的页面的任意位置 右击new---跳转到一个配置driver的页面 (选择连接方式)图一打开myeclipse然后点击window窗口 点击Open Perspective…

struts2中文件上传

注意点 private File image;//对应的就是表单中文件上传的那个输入域的名称&#xff0c;Struts2框架会封装成File类型的private String imageFileName;// 上传输入域FileName 文件名private String imageContentType;// 上传文件的MIME类型 单个文件 1 package cn.itcast.ac…

虚拟内存管理

MMU 现代操作系统普遍采用虚拟内存管理&#xff08;Virtual Memory Management&#xff09;机制&#xff0c;这需要处理器中的MMU&#xff08;Memory Management Unit&#xff0c;内存管理单元&#xff09;提供支持&#xff0c;本节简要介绍MMU的作用。 首先引入两个概念&…

设备驱动框架2——基于驱动框架写LED驱动(具体操作层)

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 前言 之前写到&#xff0c;九鼎没有使用内核推荐的LED驱动框架。因此&#xff0c;我们打算基于LED驱动框架来编写x210开发板的LED驱动。编写前先要去除九鼎移植的LED驱动&#xff0c;然后配置内核支…