天天看點

WPF中的3D特性和常見的幾個類

原文: WPF中的3D特性和常見的幾個類

WPF 3D 常用的幾個類及其關系

1.  Visual 類

     所有二維可視化元素的基類,為 WPF 中的呈現提供支援,其中包括命中測試、坐标轉換和邊界框計算。

     Visual 對象是一個核心 WPF 對象,其主要作用是提供呈現支援。使用者界面控件(例如 Button 和 TextBox)派生自 Visual 類,并使用 Visual 定義的屬性來儲存它們所呈現的資料。Visual 對象可對下列功能提供支援:

輸出顯示:為可視對象呈現持久的序列化繪圖内容。

轉換:對可視對象執行轉換。

剪輯:為可視對象提供剪輯區域支援。

命中測試:确定指定的坐标(點)或幾何圖形是否包含在可視對象的邊界内。

邊界框計算:确定可視對象的邊框。

2. Visual3D 類

      所有三維可視化元素的基類,提供可視三維對象通用的服務和屬性,其中包括命中測試、坐标轉換和邊界框計算。

3.  Viewport3D類

      為三維可視内容提供呈現圖面。

      此控件顯示三維内容,同時提供與二維布局(如剪輯、高度和寬度及滑鼠事件)一緻的屬性。

當此控件作為布局元素(如 Canvas)的内容包含時,可通過設定其 Height 和 Width 屬性(繼承自 FrameworkElement)來指定 Viewport3D 的大小。

      Viewport3D 可提供三維場景級别的命中測試。 調用 HitTest 方法可傳回有關命中可視對象、模型、網格和交點的詳細命中結果資訊。

4. Viewport3DVisual 類

在指定的二維視區邊界内呈現 Visual3D 子對象。

Viewport3DVisual 是具有三維子對象的二維 Visual 對象。Viewport3DVisual 為 Viewport3D 元素提供了必需的基礎結構。 大多數使用者都需要使用 Viewport3D 元素。

Viewport3DVisual 在二維 Visual 和 Visual3D 對象之間起到橋梁作用。Visual3D 類是所有三維可視化元素的基類。Viewport3DVisual 要求您定義一個 Camera 值和一個 Viewport 值。可以借助照相機來檢視場景。投影映射到二維圖面的區域稱作視區。

 繼承層次結構

System..::.Object

  System.Windows.Threading..::.DispatcherObject

    System.Windows..::.DependencyObject

      System.Windows.Media..::.Visual

        System.Windows.Media.Media3D..::.Viewport3DVisual

5. Model3D 類

      為三維模型提供功能的抽象類。此類對象包括 GeometryModel3D 和 Light。

      System.Windows..::.Freezable

        System.Windows.Media.Animation..::.Animatable

          System.Windows.Media.Media3D..::.Model3D

            System.Windows.Media.Media3D..::.GeometryModel3D

            System.Windows.Media.Media3D..::.Light

            System.Windows.Media.Media3D..::.Model3DGroup

6. ModelVisual3D 類

包含三維模型的 Visual。提供所有可視對象通用的服務和屬性,其中包括命中測試、坐标轉換和邊界框計算。

      System.Windows.Media.Media3D..::.Visual3D

        System.Windows.Media.Media3D..::.ModelVisual3D

7. GeometryModel3D 類

      建立由一個 MeshGeometry3D 和一個 Material 構成的三維模型。

8.  MeshGeometry3D 類

用于生成三維形狀的三角形基元。

        System.Windows..::.UIElement

          System.Windows..::.FrameworkElement

            System.Windows.Controls..::.Viewport3D

http://blog.csdn.net/wmjcom/archive/2009/07/24/4377050.aspx

WPF中的3D特性,其中包含了開始使用該特性的資訊。

提示:

WPF中的3D特性在System.Windows.Media.Media3D命名空間中。

為了了解WPF中的3D特性,一定要知道坐标系統之間的差別。圖35-22顯示了WPF 3D中的坐标系統。原點位于中心。X軸的正值在右邊,負值在左邊。Y軸是垂直的,正值在上邊,負值在下邊。Z軸在指向觀察者的方向上定義了正值。

表35-9描述了最重要的類及其功能。

表  35-9

說    明
ViewPort3D ViewPort3D定義了3D對象的渲染表面。這個元素包含3D繪圖的所有可見元素
ModelVisual3D ModelVisual3D包含在ViewPort3D中,它包含了所有可見元素。可以給完整的模型指定變換
GeometryModel3D GeometryModel3D包含在ModelVisual3D中,它包含網格和材質
Geometry3D Geometry3D是一個抽象基類,定義了幾何形狀。派生于Geometry3D的類是MeshGeometry3D。使用MeshGeometry3D可以定義三角形的位置,建立3D模型
Material Material是一個抽象基類,定義了MeshGeometry3D指定的三角形的前邊和後邊。Material包含在GeometryModel3D中。.NET 3.5定義了幾個材質類,例如DiffuseMaterial、EmissiveMaterial和SpecularMaterial。根據材質的類型,以不同的方式計算燈光。EmissiveMaterial利用燈光的計算,使材質發出等于筆刷顔色的光。DiffuseMaterial使用漫射光,SpecularMaterial定義了鏡面發光模型。使用MaterialGroup類可以建立由其他材質合并而成的材質
Light Light是燈光的抽象基類。其派生類有AmbientLight、DirectionalLight、PointLight和SpotLight。AmbientLight是不自然的光,會近似照亮整個場景。使用這種光看不到邊界。DirectionalLight定義了定向光。太陽光就是一種定向光,光線來自一邊,此時可以看到邊界和陰影。PointLight是一種位于指定位置的光,會照亮所有的方向。SpotLight照亮指定的方向。這個光定義了一個圓錐,會得到一個發出光亮的區域
Camera Camera是錄影機的抽象基類,用于把3D場景映射為2D顯示。其派生類是PerspectiveCamera、OrthographicCamera和MatrixCamera。在PerspectiveCamera中,3D對象離得越遠就越小,這不同于OrthographicCamera,在Orthographic Camera中,錄影機的距離對對象的大小沒有影響。在MatrixCamera中,可以在矩陣中定義視圖和變換
Transform3D Transform3D是3D變換的抽象基類。其派生類是RotateTransform3D、ScaleTransform3D、TranslateTransform3D、MatrixTransform3D和Transform3D Group。TranslateTransform3D允許在x、y和z向上變換對象,ScaleTransform3D可以重置對象的大小。RotateTransform3D可以在x、y和z向上把對象旋轉指定的角度。Transform3DGroup可以合并其他變換效果

三角形

本節從一個簡單的3D示例開始。3D模型由三角形組成,是以最簡單的模型是一個三角形。三角形用MeshGeometry3D的Positions屬性定義。3個頂點都使用相同的z坐标-4,x、y坐标分别為-1-1、1-1和01。屬性TriangleIndices指定了逆時針的位置順序。使用這個屬性可以确定三角形的哪一邊是可見的。三角形的一邊顯示了用GeometryModel3D類的Meterial屬性定義的顔色,其他邊顯示了BackMeterial屬性定義的顔色。

用于顯示場景的錄影機位于坐标0,0,0,其方向指向0,0,-8。把錄影機的位置改變到左邊,矩形就移動到右邊,反之亦然。改變錄影機的y位置,矩形就會變大或變小。

這個場景中使用的光線是AmbientLight,它用白色光照亮了整個場景。圖35-23顯示了三角形的效果。

< Window x:Class="Triangle3D.Window1"
xmlns="        http://schemas.microsoft.com/winfx/2006/xaml/presentation               "
xmlns:x="        http://schemas.microsoft.com/winfx/2006/xaml               "
Title="3D" Height="300" Width="300" >
< Grid >
< Viewport3D >
< Viewport3D.Camera >
< PerspectiveCamera Position="0 0 0" LookDirection="0 0 -8" / >
< /Viewport3D.Camera >      
< ModelVisual3D >
< ModelVisual3D.Content >
< AmbientLight Color="White" / >
< /ModelVisual3D.Content >
< /ModelVisual3D >      
< ModelVisual3D >
< ModelVisual3D.Content >
< GeometryModel3D >
< GeometryModel3D.Geometry >
< MeshGeometry3D
Positions="-1 -1 -4, 1 -1 -4, 0 1 -4"
TriangleIndices="0, 1, 2" / >
< /GeometryModel3D.Geometry >
< GeometryModel3D.Material >
< MaterialGroup >
< DiffuseMaterial >
< DiffuseMaterial.Brush >
< SolidColorBrush Color="Red" / >
< /DiffuseMaterial.Brush >
< /DiffuseMaterial >
< /MaterialGroup >
< /GeometryModel3D.Material >
< /GeometryModel3D >
< /ModelVisual3D.Content >
< /ModelVisual3D >
< /Viewport3D >
< /Grid >
< /Window >      

1. 改變光線

圖35-23僅顯示了一個簡單的三角形,它與2D的效果相同。但是,下面将繼續添加3D特性。例如,用SpotLight元素把環境光改為聚光燈,就可以看到三角形的另一個外觀,使用聚光燈可以定義光源的位置和光線的照射方向。給光源的位置指定-1 1 2,光就位于三角形的左邊頂點處,其y坐标是三角形的高度。之後,光線向下向左照射。圖35-24顯示了三角形的新外觀。

< ModelVisual3D >
< ModelVisual3D.Content >
< SpotLight Position="-1 1 -2" Color="White"
Direction="-1.5, -1, -5" / >
< /ModelVisual3D.Content >
< /ModelVisual3D >      

2. 添加紋理

除了給三角形的材質使用純色筆刷之外,還可以使用其他筆刷,例如LinearGradient- Brush,如下面的XAML代碼所示。用DiffuseMeterial定義的LinearGradientBrush元素指定了黃色、橙色、紅色、藍色和紫羅蘭色的漸變點。要把使用這種筆刷的對象的2D表面映射到3D幾何體上,必須設定TextCoordinates屬性。TextCoordinates定義了2D點的集合,它可以映射到3D位置上。圖35-25顯示了示例應用程式中筆刷的2D坐标。三角形中的第一個位置-1-1映射到筆刷坐标0 1上,右下角的位置1 -1映射到筆刷的1 1上,即紫羅蘭色;0 1映射到0.5 0上。圖35-26顯示了材質為漸變筆刷的三角形,這裡也使用了環境光。

< ModelVisual3D >
< ModelVisual3D.Content >
< GeometryModel3D >
< GeometryModel3D.Geometry >
< MeshGeometry3D
Positions="-1 -1 -4, 1 -1 -4, 0 1 -4"
TriangleIndices="0, 1, 2"
TextureCoordinates="0 1, 1 1, 0.5 0" / >
< /GeometryModel3D.Geometry >      
< GeometryModel3D.Material >
< MaterialGroup >
< DiffuseMaterial >
< DiffuseMaterial.Brush >
< LinearGradientBrush StartPoint="0,0"
EndPoint="1,1" >
< GradientStop Color="Yellow" Offset="0" / >
< GradientStop Color="Orange" Offset="0.25" / >
< GradientStop Color="Red" Offset="0.50" / >
< GradientStop Color="Blue" Offset="0.75" / >
< GradientStop Color="Violet" Offset="1" / >
< /LinearGradientBrush >
< /DiffuseMaterial.Brush >
< /DiffuseMaterial >
< /MaterialGroup >
< /GeometryModel3D.Material >
< /GeometryModel3D >
< /ModelVisual3D.Content >
< /ModelVisual3D >      

可以用類似的方式添加文本和其他控件。為此,隻需用要繪制的元素建立VisualBrush。

3. 3D對象

下面研究真正的3D對象:立方體。立方體由5個矩形組成:後面、前面、左面、右面和底面。每個矩形都由兩個三角形組成,因為這是網格的核心。在WPF和3D術語中,網格用于描述建立3D形狀的基本三角形。

下面是立方體中前面矩形的代碼,該矩形由兩個三角形組成。三角形的位置按TriangleIndies定義的逆時針設定。立方體的前面用紅色的筆刷繪制,後面用灰色筆刷繪制。這兩個筆刷都是SolidColorBrush類型,用Window的資源定義。

< !-- Front -- >
< GeometryModel3D >
< GeometryModel3D.Geometry >
< MeshGeometry3D
Positions="-1 -1 1, 1 -1 1, 1 1 1, 1 1 1,
-1 1 1, -1 -1 1"
TriangleIndices="0 1 2, 3 4 5" / >
< /GeometryModel3D.Geometry >
< GeometryModel3D.Material >
< DiffuseMaterial Brush="{StaticResource redBrush}" / >
< /GeometryModel3D.Material >
< GeometryModel3D.BackMaterial >
< DiffuseMaterial Brush="{StaticResource grayBrush}" / >
< /GeometryModel3D.BackMaterial >
< /GeometryModel3D >      

其他矩形非常類似,隻是在不同的位置上。下面是立方體左面的XAML代碼:

< !-- Left side -- >
< GeometryModel3D >
< GeometryModel3D.Geometry >
< MeshGeometry3D
Positions="-1 -1 1, -1 1 1, -1 -1 -1, -1 -1 -1, -1 1 1,
-1 1 -1"
TriangleIndices="0 1 2, 3 4 5" / >
< /GeometryModel3D.Geometry >
< GeometryModel3D.Material >
< DiffuseMaterial Brush="{StaticResource redBrush}" / >
< /GeometryModel3D.Material >
< GeometryModel3D.BackMaterial >
< DiffuseMaterial Brush="{StaticResource grayBrush}" / >
< /GeometryModel3D.BackMaterial >
< /GeometryModel3D >      

示例代碼為立方體的每個面定義了一個GeometryModel3D,僅是為了更好地了解代碼。隻要每個面都使用相同的材質,就可以定義一個網格,它包含立方體所有面的全部10個三角形。

所有的矩形都在Model3DGroup中組合,是以可以對立方體的所有面進行變換:

< !-- the model -- >
< ModelVisual3D >
< ModelVisual3D.Content >
< Model3DGroup >      
< ! - GeometryModel3D elements for every side of the box -- >      
< /Model3DGroup >      

使用Model3DGroup的Transform屬性,就可以變換這個組中的所有幾何體。下面使用RotateTransform3D定義一個AxisAngleRotation3D。要在運作期間旋轉立方體,Angle屬性要綁定到Slider控件的值上。

< !-- Transformation of the complete model -- >
< Model3DGroup.Transform >
< RotateTransform3D CenterX="0" CenterY="0" CenterZ="0" >
< RotateTransform3D.Rotation >
< AxisAngleRotation3D x:Name="axisRotation"
Axis="0, 0, 0"
Angle="{Binding Path=Value,
ElementName=axisAngle}" / >
< /RotateTransform3D.Rotation >
< /RotateTransform3D >
< /Model3DGroup.Transform >      

為了檢視立方體,需要一個錄影機。這裡使用PerspectiveCamera,是以立方體離錄影機越遠,就越小。錄影機的位置的方向在運作期間設定。

< !-- Camera -- >
< Viewport3D.Camera >
< PerspectiveCamera x:Name="camera"
Position="{Binding Path=Text,
ElementName=textCameraPosition}"
LookDirection="{Binding Path=Text,
ElementName=textCameraDirection}" / >
< /Viewport3D.Camera >      

應用程式使用兩個不同的光源,其中一個光源是DirectionalLight:

< !-- directional light -- >
< ModelVisual3D >
< ModelVisual3D.Content >
< DirectionalLight Color="White" x:Name="directionalLight" >
< DirectionalLight.Direction >
< Vector3D X="1" Y="2" Z="3" / >
< /DirectionalLight.Direction >
< /DirectionalLight >
< /ModelVisual3D.Content >
< /ModelVisual3D >      

另一個光源是SpotLight。使用這個光源可以突出顯示立方體的一個特定區域。SpotLight定義了屬性InnerConeAngle和OuterConeAngle,以指定完全照亮的區域:

< !-- spot light -- >
< ModelVisual3D >
< ModelVisual3D.Content >
< SpotLight x:Name="spotLight"
InnerConeAngle="{Binding Path=Value,
ElementName=spotInnerCone}"
OuterConeAngle="{Binding Path=Value,
ElementName=spotOuterCone}"
Color="#FFFFFF"
Direction="{Binding Path=Text, ElementName=spotDirection}"
Position="{Binding Path=Text, ElementName=spotPosition}"
Range="{Binding Path=Value, ElementName=spotRange}" / >
< /ModelVisual3D.Content >
< /ModelVisual3D >      

運作應用程式,就可以改變立方體的旋轉角度、錄影機和燈光,如圖35-27所示。

建立僅包含矩形或三角形的3D模型是很簡單的。不應手工建立更複雜的模型,而應使用對應的工具。WPF的3D工具在

www.codeplex/3DTools

上。