65.9K
CodeProject 正在变化。 阅读更多。
Home

全新 .NET 3.5 3D 元素

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2009年6月17日

CPOL
viewsIcon

17092

downloadIcon

178

全新的 .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 度。

37354/image-thumb6.png

并且 这里有一个 zip 文件,包含演示项目代码。

© . All rights reserved.