在WPF中构建一个简单的立方体比较容易实现,可参考资料也比较众多。比较麻烦的是处理点击交互。

我在WPF中用两种方式实现了3DCube,效果图如下:

方式一: 最常见的3D内容构建模式,结构如下图。

参考

 <Viewport3D SnapsToDevicePixels="True" ClipToBounds="True"
RenderTransformOrigin="0.5 0.5" RenderOptions.EdgeMode="Aliased"
RenderOptions.CachingHint="Cache">
<!--Camera-->
<Viewport3D.Camera>
<PerspectiveCamera x:Name="CameraMain" Position="4,4,6" UpDirection="0,1,0" LookDirection="-4,-4,-6"
NearPlaneDistance="" FarPlaneDistance="" FieldOfView="">
<PerspectiveCamera.Transform>
<Transform3DGroup>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="CameraRotate" Axis="0,1,0" Angle=""/>
</RotateTransform3D.Rotation>
</RotateTransform3D>
<ScaleTransform3D />
</Transform3DGroup>
</PerspectiveCamera.Transform>
</PerspectiveCamera>
</Viewport3D.Camera>
<!--Light-->
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup>
<AmbientLight Color="White"></AmbientLight>
<DirectionalLight Color="White" Direction="4,6,-6"/>
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
<!--六个面-->
<ModelVisual3D x:Name="CubeSlaveContainer">
<ModelUIElement3D>
<GeometryModel3D x:Name="TopPanel">
<GeometryModel3D.Material>
<DiffuseMaterial x:Name="MaterialTop">
<DiffuseMaterial.Brush>
<VisualBrush>
<VisualBrush.Visual>
<TextBlock Text="" Foreground="White"/>
</VisualBrush.Visual>
</VisualBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
<GeometryModel3D.BackMaterial>
<DiffuseMaterial Brush="Transparent"/>
</GeometryModel3D.BackMaterial>
<GeometryModel3D.Geometry>
<MeshGeometry3D Positions="-2,2,2 2,2,2 2,2,-2 -2,2,-2"
TriangleIndices="0,1,2 0,2,3"
TextureCoordinates="-2,2 2,2 2,-2 -2,-2">
</MeshGeometry3D>
</GeometryModel3D.Geometry>
</GeometryModel3D>
</ModelUIElement3D>
<ModelUIElement3D>
<GeometryModel3D x:Name="BottomPanel">
<GeometryModel3D.Material>
<DiffuseMaterial x:Name="MaterialBottom">
<DiffuseMaterial.Brush>
<VisualBrush>
<VisualBrush.Visual>
<TextBlock Text="" Foreground="White"/>
</VisualBrush.Visual>
</VisualBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
<GeometryModel3D.BackMaterial>
<DiffuseMaterial Brush="Transparent"/>
</GeometryModel3D.BackMaterial>
<GeometryModel3D.Geometry>
<MeshGeometry3D Positions="-2,-2,2 2,-2,2 2,-2,-2 -2,-2,-2"
TriangleIndices="0,2,1 0,3,2"
TextureCoordinates="-2,2 2,2 2,-2 -2,-2">
</MeshGeometry3D>
</GeometryModel3D.Geometry>
</GeometryModel3D>
</ModelUIElement3D>
<ModelUIElement3D>
<GeometryModel3D x:Name="LeftPanel">
<GeometryModel3D.Material>
<DiffuseMaterial x:Name="MaterialLeft">
<DiffuseMaterial.Brush>
<VisualBrush>
<VisualBrush.Visual>
<TextBlock Text="" Foreground="White"/>
</VisualBrush.Visual>
</VisualBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
<GeometryModel3D.BackMaterial>
<DiffuseMaterial Brush="Transparent"/>
</GeometryModel3D.BackMaterial>
<GeometryModel3D.Geometry>
<MeshGeometry3D Positions="-2,-2,-2 -2,-2,2 -2,2,2 -2,2,-2"
TriangleIndices="0,1,2 0,2,3"
TextureCoordinates="-2,2 2,2 2,-2 -2,-2">
</MeshGeometry3D>
</GeometryModel3D.Geometry>
</GeometryModel3D>
</ModelUIElement3D>
<ModelUIElement3D>
<GeometryModel3D x:Name="RightPanel">
<GeometryModel3D.Material>
<DiffuseMaterial x:Name="MaterialRight">
<DiffuseMaterial.Brush>
<VisualBrush>
<VisualBrush.Visual>
<TextBlock Text="" Foreground="White"/>
</VisualBrush.Visual>
</VisualBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
<GeometryModel3D.BackMaterial>
<DiffuseMaterial Brush="Transparent"/>
</GeometryModel3D.BackMaterial>
<GeometryModel3D.Geometry>
<MeshGeometry3D Positions="2,-2,2 2,-2,-2 2,2,-2 2,2,2"
TriangleIndices="0,1,2 0,2,3"
TextureCoordinates="-2,2 2,2 2,-2 -2,-2">
</MeshGeometry3D>
</GeometryModel3D.Geometry>
</GeometryModel3D>
</ModelUIElement3D>
<ModelUIElement3D>
<GeometryModel3D x:Name="FrontPanel">
<GeometryModel3D.Material>
<DiffuseMaterial x:Name="MaterialFront">
<DiffuseMaterial.Brush>
<VisualBrush>
<VisualBrush.Visual>
<TextBlock Text="" Foreground="White"/>
</VisualBrush.Visual>
</VisualBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
<GeometryModel3D.BackMaterial>
<DiffuseMaterial Brush="Transparent"/>
</GeometryModel3D.BackMaterial>
<GeometryModel3D.Geometry>
<MeshGeometry3D Positions="-2,-2,2 2,-2,2 2,2,2 -2,2,2"
TriangleIndices="0,1,2 0,2,3"
TextureCoordinates="-2,2 2,2 2,-2 -2,-2">
</MeshGeometry3D>
</GeometryModel3D.Geometry>
</GeometryModel3D> </ModelUIElement3D>
<ModelUIElement3D>
<GeometryModel3D x:Name="BackPanel">
<GeometryModel3D.Material>
<DiffuseMaterial x:Name="MaterialBack">
<DiffuseMaterial.Brush>
<VisualBrush>
<VisualBrush.Visual>
<TextBlock Text="" Foreground="White"></TextBlock>
</VisualBrush.Visual>
</VisualBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
<GeometryModel3D.BackMaterial>
<DiffuseMaterial Brush="Transparent"/>
</GeometryModel3D.BackMaterial>
<GeometryModel3D.Geometry>
<MeshGeometry3D Positions="2,-2,-2 -2,-2,-2 -2,2,-2 2,2,-2"
TriangleIndices="0,1,2 0,2,3"
TextureCoordinates="-2,2 2,2 2,-2 -2,-2">
</MeshGeometry3D>
</GeometryModel3D.Geometry>
</GeometryModel3D>
</ModelUIElement3D>
</ModelVisual3D>
</Viewport3D>

点击交互:

给ModelUIElement3D附加事件,如下图

方式二: 使用3DTools.dll构建,结构如下图

参考

        <!-- xmlns:Plugin3D="clr-namespace:_3DTools;assembly=3DTools" -->
<Plugin3D:Interactive3DDecorator HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Viewport3D x:Name="Viewport3DMain" Margin="0,-50,0,50"
SnapsToDevicePixels="True" ClipToBounds="True"
RenderTransformOrigin="0.5 0.5" RenderOptions.EdgeMode="Aliased"
RenderOptions.CachingHint="Cache">
<!--摄像机-->
<Viewport3D.Camera>
<PerspectiveCamera x:Name="CameraMain" Position="4,4,6"
UpDirection="0,1,0" LookDirection="-4,-4,-6"
NearPlaneDistance="" FarPlaneDistance="" FieldOfView="">
<PerspectiveCamera.Transform>
<Transform3DGroup>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="CameraRotate" Axis="0,1,0" Angle=""/>
</RotateTransform3D.Rotation>
</RotateTransform3D>
</Transform3DGroup>
</PerspectiveCamera.Transform>
</PerspectiveCamera>
</Viewport3D.Camera>
<!--Light-->
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup>
<AmbientLight Color="White"></AmbientLight>
<DirectionalLight Color="White" Direction="4,6,-6"/>
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
<!--六个面-->
<Plugin3D:InteractiveVisual3D x:Name="TopPanel" IsBackVisible="True">
<Plugin3D:InteractiveVisual3D.Geometry>
<MeshGeometry3D Positions="-2,2,2 2,2,2 2,2,-2 -2,2,-2"
TriangleIndices="0,1,2 0,2,3"
TextureCoordinates="0,0 0,1 1,1 1,0"
Normals="0,1,0 0,1,0 0,1,0 0,1,0"/>
</Plugin3D:InteractiveVisual3D.Geometry>
</Plugin3D:InteractiveVisual3D>
<Plugin3D:InteractiveVisual3D x:Name="BottomPanel" IsBackVisible="True">
<Plugin3D:InteractiveVisual3D.Geometry>
<MeshGeometry3D Positions="-2,-2,2 2,-2,2 2,-2,-2 -2,-2,-2"
TriangleIndices="0,2,1 0,3,2"
TextureCoordinates="0,0 0,1 1,1 1,0"
Normals="0,1,0 0,1,0 0,1,0 0,1,0"/>
</Plugin3D:InteractiveVisual3D.Geometry>
</Plugin3D:InteractiveVisual3D>
<Plugin3D:InteractiveVisual3D x:Name="LeftPanel" IsBackVisible="True">
<Plugin3D:InteractiveVisual3D.Geometry>
<MeshGeometry3D Positions="-2,-2,-2 -2,-2,2 -2,2,2 -2,2,-2"
TriangleIndices="0,1,2 0,2,3"
TextureCoordinates="0,0 0,1 1,1 1,0"
Normals="0,1,0 0,1,0 0,1,0 0,1,0"/>
</Plugin3D:InteractiveVisual3D.Geometry>
</Plugin3D:InteractiveVisual3D>
<Plugin3D:InteractiveVisual3D x:Name="RightPanel" IsBackVisible="True">
<Plugin3D:InteractiveVisual3D.Geometry>
<MeshGeometry3D Positions="2,-2,2 2,-2,-2 2,2,-2 2,2,2"
TriangleIndices="0,1,2 0,2,3"
TextureCoordinates="0,0 0,1 1,1 1,0"
Normals="0,1,0 0,1,0 0,1,0 0,1,0"/>
</Plugin3D:InteractiveVisual3D.Geometry>
</Plugin3D:InteractiveVisual3D>
<Plugin3D:InteractiveVisual3D x:Name="FrontPanel" IsBackVisible="True">
<Plugin3D:InteractiveVisual3D.Geometry>
<MeshGeometry3D Positions="-2,-2,2 2,-2,2 2,2,2 -2,2,2"
TriangleIndices="0,1,2 0,2,3"
TextureCoordinates="0,0 0,1 1,1 1,0"
Normals="0,1,0 0,1,0 0,1,0 0,1,0"/>
</Plugin3D:InteractiveVisual3D.Geometry>
</Plugin3D:InteractiveVisual3D>
<Plugin3D:InteractiveVisual3D x:Name="BackPanel" IsBackVisible="True">
<Plugin3D:InteractiveVisual3D.Geometry>
<MeshGeometry3D Positions="2,-2,-2 -2,-2,-2 -2,2,-2 2,2,-2"
TriangleIndices="0,1,2 0,2,3"
TextureCoordinates="0,0 0,1 1,1 1,0"
Normals="0,1,0 0,1,0 0,1,0 0,1,0"/>
</Plugin3D:InteractiveVisual3D.Geometry>
</Plugin3D:InteractiveVisual3D>
</Viewport3D>
</Plugin3D:Interactive3DDecorator>

点击交互:

给Plugin3D:InteractiveVisual3D对象的Visual对象附加点击事件,如创建一个Grid, 将Grid作为Plugin3D:InteractiveVisual3D的Visual值。

调用: this.SetCubeMaterialBrush(this.FrontPanel, "定义的ImageBrush资源的Key值", 5);

工具:Visual Studio 2017

工程:WPF C#

源码下载:

WPF 3D Cube及点击交互的更多相关文章

  1. WPF 3D 知识点大全以及实例

    引言 现在物联网概念这么火,如果监控的信息能够实时在手机的客服端中以3D形式展示给我们,那种体验大家可以发挥自己的想象. 那生活中我们还有很多地方用到这些,如上图所示的Kinect 在医疗上的应用,当 ...

  2. WPF 3D 小小小小引擎 - ·WPF 3D变换应用

    原文:WPF 3D 小小小小引擎 - ·WPF 3D变换应用 WPF可以提供的3D模型使我们可以轻松地创建3D实体,虽然目前来看还很有一些性能上的问题,不过对于一些简单的3D应用应该是可取的,毕竟其开 ...

  3. TextView + Spanned实现图文混排以及图片点击交互

    最近要实现图文混排的需求,webview过大,所以想到了用SpannableStringBuilder来实现. 不过参考了大量国内文章,大多数是教你如何实现图文混排,并没有提及图片点击交互的.有翻阅了 ...

  4. WPF MVVM UI分离之《交互与数据分离》 基础才是重中之重~delegate里的Invoke和BeginInvoke 将不确定变为确定系列~目录(“机器最能证明一切”) 爱上MVC3系列~全局异常处理与异常日志 基础才是重中之重~lock和monitor的区别 将不确定变成确定~我想监视我的对象,如果是某个值,就叫另一些方法自动运行 将不确定变成确定~LINQ DBML模型可以对

    WPF MVVM UI分离之<交互与数据分离>   在我们使用WPF过程中,不可避免并且超级喜欢使用MVVM框架. 那么,使用MVVM的出发点是视觉与业务逻辑分离,即UI与数据分离 诸如下 ...

  5. WPF 3D变换应用

    WPF可以提供的3D模型使我们可以轻松地创建3D实体,虽然目前来看还很有一些性能上的问题,不过对于一些简单的3D应用应该是可取的,毕竟其开发效率高,而且也容易上手. 下面给大家演示的是使用在WPF 3 ...

  6. WPF 3D中多个模型如何设置某一个在最前?

    原文:WPF 3D中多个模型如何设置某一个在最前? 问题:我们的模型包括导入的3D solid模型和axis坐标轴模型,当模型旋转的时候,3D会将axis挡住. 期望:axis一直在最前面,不会被3D ...

  7. WPF 3D 获取鼠标在场景的3d坐标

    原文:WPF 3D 获取鼠标在场景的3d坐标 上一篇中我们谈到了WPF 3d做图的一些简单原理,这里我们简单介绍一下怎样获得鼠标在场景中的3d坐标,知道了3d坐标就可以进行很多操作了: 首先介绍一下3 ...

  8. 最优化WPF 3D性能(基于“Tier-2”硬件)

    原文:最优化WPF 3D性能(基于"Tier-2"硬件) 原文地址:Maximizing WPF 3D Performance on Tier-2 Hardware 开发人员在应用 ...

  9. 优化WPF 3D性能

    Maximize WPF 3D Performance .NET Framework 4.5   As you use the Windows Presentation Foundation (WPF ...

随机推荐

  1. 静态链表-C语言实现

    1.静态链表是在没有指针的编程语言里对链表的一种实现2.主要是用数组模拟指针3.在这里,使用结构体使数组的每一个空间可以存储一个数据元素(date)和一个游标(cur),游标的作用相当于链表的指针域, ...

  2. 转载一篇关于tab键与focus的文章

    Focusable HTML 元素中,并不是所有元素都可以获得焦点,有如下元素可以获得焦点: a, area, button, input, object, select, textarea,这些元素 ...

  3. java前端与后端怎么选??

    想做这个行业,就应该了解职能以及技能需求,这样学习才能更高效.我知道一些刚刚入行的小伙伴不清楚前端.后端.到底指的是什么?两者直接的区别 前端开发 前端开发主要涉及网站和App,用户能够从浏览器上或A ...

  4. SpringBoot整合freemarker模板

    一.目录展示 二.导入依赖 三.application.properties配置文件 四.在src/main/resource/templates文件夹中创建HelloFreeMarker.ftl文件 ...

  5. 一道题反映Java的类初始化过程

    Java的类初始化过程: 1. 父类的static成员变量,static语句块. 2. 子类的static成员变量,static语句块. 3. 父类的普通成员变量,构造函数. 4. 子类的普通成员变量 ...

  6. 牛客练习赛32 B题 Xor Path

    链接:https://ac.nowcoder.com/acm/contest/272/B来源:牛客网 题目描述 给定一棵n个点的树,每个点有权值.定义表示  到  的最短路径上,所有点的点权异或和. ...

  7. python3导入子模块

    基础知识 参考资料1上有一句话Regular packages are traditional packages as they existed in Python 3.2 and earlier. ...

  8. 笔记||Python3之文件的读写

    [文件的读模式]            文件的对象:文件的读写通过文件操作对象进行. Python2  -----  File Python3  -----  TextIOWrapper       ...

  9. 《JavaScript 正则表达式迷你书》知识点小抄本

    介绍 这周开始学习老姚大佬的<JavaScript 正则表达式迷你书> , 然后习惯性的看完一遍后,整理一下知识点,便于以后自己重新复习. 我个人觉得:自己整理下来的资料,对于知识重现,效 ...

  10. C#使用 OleDbConnection 连接读取Excel

    /// <summary> /// 读取Excel中数据 /// </summary> /// <param name="strExcelPath"& ...