WPF 3D Cube及点击交互
在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及点击交互的更多相关文章
- WPF 3D 知识点大全以及实例
引言 现在物联网概念这么火,如果监控的信息能够实时在手机的客服端中以3D形式展示给我们,那种体验大家可以发挥自己的想象. 那生活中我们还有很多地方用到这些,如上图所示的Kinect 在医疗上的应用,当 ...
- WPF 3D 小小小小引擎 - ·WPF 3D变换应用
原文:WPF 3D 小小小小引擎 - ·WPF 3D变换应用 WPF可以提供的3D模型使我们可以轻松地创建3D实体,虽然目前来看还很有一些性能上的问题,不过对于一些简单的3D应用应该是可取的,毕竟其开 ...
- TextView + Spanned实现图文混排以及图片点击交互
最近要实现图文混排的需求,webview过大,所以想到了用SpannableStringBuilder来实现. 不过参考了大量国内文章,大多数是教你如何实现图文混排,并没有提及图片点击交互的.有翻阅了 ...
- WPF MVVM UI分离之《交互与数据分离》 基础才是重中之重~delegate里的Invoke和BeginInvoke 将不确定变为确定系列~目录(“机器最能证明一切”) 爱上MVC3系列~全局异常处理与异常日志 基础才是重中之重~lock和monitor的区别 将不确定变成确定~我想监视我的对象,如果是某个值,就叫另一些方法自动运行 将不确定变成确定~LINQ DBML模型可以对
WPF MVVM UI分离之<交互与数据分离> 在我们使用WPF过程中,不可避免并且超级喜欢使用MVVM框架. 那么,使用MVVM的出发点是视觉与业务逻辑分离,即UI与数据分离 诸如下 ...
- WPF 3D变换应用
WPF可以提供的3D模型使我们可以轻松地创建3D实体,虽然目前来看还很有一些性能上的问题,不过对于一些简单的3D应用应该是可取的,毕竟其开发效率高,而且也容易上手. 下面给大家演示的是使用在WPF 3 ...
- WPF 3D中多个模型如何设置某一个在最前?
原文:WPF 3D中多个模型如何设置某一个在最前? 问题:我们的模型包括导入的3D solid模型和axis坐标轴模型,当模型旋转的时候,3D会将axis挡住. 期望:axis一直在最前面,不会被3D ...
- WPF 3D 获取鼠标在场景的3d坐标
原文:WPF 3D 获取鼠标在场景的3d坐标 上一篇中我们谈到了WPF 3d做图的一些简单原理,这里我们简单介绍一下怎样获得鼠标在场景中的3d坐标,知道了3d坐标就可以进行很多操作了: 首先介绍一下3 ...
- 最优化WPF 3D性能(基于“Tier-2”硬件)
原文:最优化WPF 3D性能(基于"Tier-2"硬件) 原文地址:Maximizing WPF 3D Performance on Tier-2 Hardware 开发人员在应用 ...
- 优化WPF 3D性能
Maximize WPF 3D Performance .NET Framework 4.5 As you use the Windows Presentation Foundation (WPF ...
随机推荐
- 性能达到原生 MySQL 七倍,华为云 Taurus 技术解读【华为云技术分享】
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...
- 我是怎样测试Java类的线程安全性的
线程安全性是Java等语言/平台中类的一个重要标准,在Java中,我们经常在线程之间共享对象.由于缺乏线程安全性而导致的问题很难调试,因为它们是偶发的,而且几乎不可能有目的地重现.如何测试对象以确保它 ...
- 转:Spring配置文件<context:property-placeholder>标签使用漫谈
<context:property-placeholder>标签提供了一种优雅的外在化参数配置的方式,不过该标签在Spring配置文件中只能存在一份!!! 众所周知,Spring容器是采用 ...
- Java语法进阶13-文件、IO流
File File是文件和目录路径名的抽象表示形式,即File类是文件或目录的路径,而不是文件本身,因此File类不能直接访问文件内容本身,如果需要访问文件内容本身,则需要使用输入/输出流. File ...
- Mysql 执行计划以及常见索引问题总结
Mysql 执行计划以及常见索引问题总结
- 强化学习一:Introduction Of Reinforcement Learning
引言: 最近和实验室的老师做项目要用到强化学习的有关内容,就开始学习强化学习的相关内容了.也不想让自己学习的内容荒废掉,所以想在博客里面记载下来,方便后面复习,也方便和大家交流. 一.强化学习是什么? ...
- UVa-10652 包装木板
Input: standard inputOutput: standard output Time Limit: 2 seconds The small sawmill in Mission, Bri ...
- css3(1)
边框: 盒子圆角:border-radius:5px / 20%: border-radius:5px 4px 3px 2px; 左上,右上,右下,左下. 盒子阴影: box-shadow: box- ...
- Oracle 12C CDB、PDB常用管理命令
Oracle 12C CDB.PDB常用管理命令 --查看PDB信息(在CDB模式下) show pdbs --查看所有pdbselect name,open_mode from v$pdbs; ...
- ssh jail
useradd -s /sbin/nologin -M updateuserpasswd updateusermkdir /home/updatechown root:root /home/updat ...