全新 .NET 3.5 3D 元素





5.00/5 (3投票s)
全新的 .NET 3.5 3D 元素
我又开始研究 WPF 中的 3D 了。我之前写过关于 Viewport2DVisual3D 3D WPF 元素的博客。好吧,对于我正在做的事情,我不需要能够在 3D 表面上放置 2D 交互元素,但我希望 3D 对象能够响应 Mouse
事件。 过去,你会的做法是在 Viewport3D
上使用 MouseDown
事件并进行某种命中测试。这还可以…
但是现在,有了很棒的全新 .NET 3.5 元素 ModelUIElement3D
,它是一个完全成熟的元素,支持事件。太棒了!
还有一个新的容器元素,用于托管一个或多个 ModelUIElement3D
元素。
让我们看一个例子
<Window x:Class=”Shapes.Window1″
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
xmlns:local=”clr-namespace:Shapes”
Title=”Window1″ Height=”610.122″ Width=”633.46″>
<Window.Resources>
<!– The 3D cube –>
<MeshGeometry3D x:Key=”CubeMesh”
TriangleIndices = “0,1,2 2,3,0
4,7,6 6,5,4
8,11,10 10,9,8
12,13,14 14,15,12
16,17,18 18,19,16
20,23,22 22,21,20″
Positions = “-1,-1,1 -1,-1,-1 1,-1,-1 1,-1,1
-1,1,1 -1,1,-1 1,1,-1 1,1,1
-1,-1,1 -1,1,1 1,1,1 1,-1,1
-1,-1,-1 -1,1,-1 1,1,-1 1,-1,-1
-1,-1,1 -1,1,1 -1,1,-1 -1,-1,-1
1,-1,1 1,1,1 1,1,-1 1,-1,-1″ />
</Window.Resources>
<Viewport3D>
<Viewport3D.Camera>
<PerspectiveCamera x:Name=”camera” Position=”-2,2,5″
LookDirection=”2,-2,-5″ FieldOfView=”90″ />
</Viewport3D.Camera>
<!– Container for 3D Elements –>
<ContainerUIElement3D x:Name=”container”>
<ContainerUIElement3D.Transform>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D Axis=”0, 1, 0″ Angle=”0″ />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</ContainerUIElement3D.Transform>
<!– A fully Fledged 3d element complete with routed events –>
<ModelUIElement3D MouseDown=”Cube1_MouseDown”>
<ModelUIElement3D.Transform>
<Transform3DGroup>
<TranslateTransform3D OffsetZ=”1.5″ />
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D Axis=”0, 1, 0″ Angle=”0″ />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</Transform3DGroup>
</ModelUIElement3D.Transform>
<ModelUIElement3D.Model>
<GeometryModel3D Geometry=”{StaticResource CubeMesh}”>
<GeometryModel3D.Material>
<DiffuseMaterial x:Name=”cube1Material” Brush=”Blue” />
</GeometryModel3D.Material>
</GeometryModel3D>
</ModelUIElement3D.Model>
</ModelUIElement3D>
</ContainerUIElement3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color=”White” Direction=”-1,-1,-1″/>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
</Window>
以下是具有 ModelUIElement3D
事件的 C# 代码。
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5: using System.Windows;
6: using System.Windows.Controls;
7: using System.Windows.Data;
8: using System.Windows.Documents;
9: using System.Windows.Input;
10: using System.Windows.Media;
11: using System.Windows.Media.Animation;
12: using System.Windows.Media.Media3D;
13: using System.Windows.Media.Imaging;
14: using System.Windows.Navigation;
15: using System.Windows.Shapes;
16:
17: namespace Shapes
18: {
19: /// <summary>
20: /// Interaction logic for Window1.xaml
21: /// </summary>
22: public partial class Window1 : Window
23: {
24:
25:
26: public Window1()
27: {
28: InitializeComponent();
29: }
30:
31:
32: /// <summary>
33: /// 3d Element Mouse Event, Neat
34: /// </summary>
35: private void Cube1_MouseDown(object sender, MouseButtonEventArgs e)
36: {
37: ModelUIElement3D currentObject = sender as ModelUIElement3D;
38: if (currentObject.Transform is Transform3DGroup)
39: {
40: RotateTransform3D rotateTrans = null;
41:
42: Transform3DGroup transGroup =
43: currentObject.Transform as Transform3DGroup;
44: rotateTrans = TryFindChild<RotateTransform3D>(transGroup);
45: if (rotateTrans != null)
46: {
47: // spin the object around
48: DoubleAnimation doubleAnimation =
49: new DoubleAnimation(0,360,
50: new Duration(TimeSpan.FromSeconds(0.5)));
51: rotateTrans.Rotation.BeginAnimation(
52: AxisAngleRotation3D.AngleProperty, doubleAnimation);
53: }
54: }
55: }
56:
57:
58: /// <summary>
59: /// Try and find child of type T in the Transform3DGroup
60: /// </summary>
61: public static T TryFindChild<T>(Transform3DGroup parent)
62: where T : DependencyObject
63: {
64: foreach (DependencyObject child in parent.Children)
65: {
66: if (child is T)
67: {
68: return child as T;
69: }
70: }
71: return null;
72: }
73:
74:
75: }
76: }
就这样了。因此,在这个例子中,如果立方体收到 MouseDown
,我会查找它的 RotateTransform3D
并将其旋转 360 度。
并且 这里有一个 zip 文件,包含演示项目代码。