此示例演示如何使用 XAML 显示和旋转 3D 立方体。它显示一个带有滚动条的蓝色三维立方体,您可以使用滚动条旋转立方体以从不同方向查看它。
下面显示了该程序的完整 XAML 代码。XAML 代码处理所有用户交互,包括旋转立方体,因此该示例不需要任何后台 C# 代码。
窗口包含一个网格,该网格定义了一个大行和大列以及一个小行和小列。滚动条位于网格的细长单元格中。左上角的大单元格包含一个可以显示三维场景的Viewport3D对象。它包含一个ModelVisual3D和一个Camera。
ModelVisual3D包含一个Model3DGroup,它定义了一些用于照亮场景的灯光和一个GeometryModel3D 。 GeometryModel3D定义三维对象的几何形状及其材质。
GeometryModel3D包含一个MeshGeometry3D对象来定义立方体。该对象的Positions值给出了立方体顶点在三维空间中的位置。TriangleIndices属性给出了应该用来构成三角形的顶点的索引。例如,TriangleIndices中的前三个值是 0、1 和 2,这意味着应该使用索引为 0、1 和 2 的顶点来构成三角形。
请注意,GeometryModel3D只能定义一个几何体和一个材质。这意味着,如果您想要制作多个具有不同材质的物体,例如红色和蓝色立方体或具有不同颜色侧面的单个立方体,那么您需要使用多个GeometryModel3D对象。
Viewport3D 对象的Camera属性定义用于查看三维场景的相机。此示例使用位于 (1.5, 2, 3) 的透视相机回望原点。UpDirection确定相机的倾斜度。在此示例中,相机垂直放置。FieldOfView确定相机可查看的区域有多宽。
此示例使用两个变换来修改相机的位置。第一个变换是围绕 Y 轴的旋转。旋转角度由水平滚动条hscroll的Value属性指定。第二个变换是围绕 X 轴的旋转,旋转角度由垂直滚动条的Value属性指定。
将旋转角度绑定到滚动条的Value属性可让 XAML 代码处理旋转,而无需任何 C# 代码。调整滚动条时,旋转角度会更新,立方体会自动旋转。
这看起来可能相当复杂(是的,确实如此),但如果您想构建三维场景,了解这些 XAML 对象的工作原理非常重要。下载示例并花一些时间研究它,然后再继续学习更复杂的 3D 示例。尝试一些实验。例如,尝试添加具有不同颜色的第二个立方体。
下载示例进行试验并查看更多详细信息。
<Window x:Class="howto_xaml_rotate_cube.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="howto_xaml_rotate_cube" Height="300" Width="330">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<ScrollBar Name="vscroll"
Grid.Row="0" Grid.Column="1"
Orientation="Vertical"
Minimum="-180" Maximum="180"
LargeChange="10" SmallChange="1" Value="0" />
<ScrollBar Name="hscroll"
Grid.Row="1" Grid.Column="0"
Orientation="Horizontal"
Minimum="-180" Maximum="180"
LargeChange="10" SmallChange="1" Value="0" />
<Viewport3D Margin="4,4,4,4" Grid.Row="0" Grid.Column="0">
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup>
<!-- Lights -->
<AmbientLight Color="Gray" />
<DirectionalLight Color="Gray" Direction="1,-2,-3" />
<DirectionalLight Color="Gray" Direction="-1,2,3" />
<GeometryModel3D>
<GeometryModel3D.Geometry>
<!-- Cube -->
<MeshGeometry3D
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
"
TriangleIndices="
0 1 2 2 3 0
4 5 6 6 7 4
8 9 10 10 11 8
12 13 14 14 15 12
16 17 18 18 19 16
20 21 22 22 23 20
" />
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial Brush="Blue" />
</GeometryModel3D.Material>
</GeometryModel3D>
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
<Viewport3D.Camera>
<PerspectiveCamera
Position = "1.5, 2, 3"
LookDirection = "-1.5, -2, -3"
UpDirection = "0, 1, 0"
FieldOfView = "60">
<PerspectiveCamera.Transform>
<Transform3DGroup>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D
Axis="0 1 0"
Angle="{Binding ElementName=hscroll, Path=Value}" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D
Axis="1 0 0"
Angle="{Binding ElementName=vscroll, Path=Value}" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</Transform3DGroup>
</PerspectiveCamera.Transform>
</PerspectiveCamera>
</Viewport3D.Camera>
</Viewport3D>
</Grid>
</Window>