原文:WPF 3D:简单的Point3D和Vector3D动画创造一个旋转的正方体
运行结果:
事实上很简单,定义好一个正方体,处理好纹理。关于MeshGeometry3D的正确定义和纹理这里就不多讲了,可以参考我以前写过的一些文章:
WPF 3D: MeshGeometry3D纹理坐标的正确定义
接下来就是怎样让它动起来。我们通过3D点动画来改变照相机(Camera类型)的位置(Position属性)从而使正方体动起来(这样的话实际上正方体没动,而是照相机在动)。由于正方体是水平旋转的,那么Y轴可以忽略,参考下面整个3D图形的俯视图,动画是这样进行的:
我们的照相机初始时放置在Z轴(0,0,5)的位置,如下图:
所以旋转照相机只需要把Position属性调整到相应的点就可以,分别是0,0,5 5,0,0 0,0,-5 –5,0,0 ,如下代码:
<Point3DAnimationUsingKeyFrames Storyboard.TargetProperty="Position"
Storyboard.TargetName="camera">
<LinearPoint3DKeyFrame KeyTime="0:0:1" Value="5
0 0"/>
<LinearPoint3DKeyFrame KeyTime="0:0:2" Value="0
0 -5"/>
<LinearPoint3DKeyFrame KeyTime="0:0:3" Value="-5
0 0"/>
<LinearPoint3DKeyFrame KeyTime="0:0:4" Value="0
0 5"/>
</Point3DAnimationUsingKeyFrames>
注意上面使用的是Point3DAnimation类型。接下来需要注意的,我们还需要调整照相机的方向(Camera类型的LookDirection属性),否则照相机还会保持原方向。这个属性类型是3D向量,所以需要用Vector3DAnimation类型,调整向量也很简单,只需要根据照相机的移动点把方向调整到中心点。
如下代码:
<Vector3DAnimationUsingKeyFrames Storyboard.TargetProperty="LookDirection"
Storyboard.TargetName="camera">
<LinearVector3DKeyFrame KeyTime="0:0:1" Value="-1
0 0"/>
<LinearVector3DKeyFrame KeyTime="0:0:2" Value="0
0 1"/>
<LinearVector3DKeyFrame KeyTime="0:0:3" Value="1
0 0"/>
<LinearVector3DKeyFrame KeyTime="0:0:4" Value="0
0 -1"/>
</Vector3DAnimationUsingKeyFrames>
当运行动画时,你会发现等方块背面转过来后,它还保持这暗色,原因是整个光照没有被旋转。因此最好把光照再旋转一下就趋近完美了,在动画中再调节DirectionalLight的Direction属性就可以了,这个也是Vector3D类型。
下面是完整的XAML代码:
<Viewport3D>
<Viewport3D.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<Point3DAnimationUsingKeyFrames Storyboard.TargetProperty="Position"
Storyboard.TargetName="camera">
<LinearPoint3DKeyFrame KeyTime="0:0:1" Value="5
0 0"/>
<LinearPoint3DKeyFrame KeyTime="0:0:2" Value="0
0 -5"/>
<LinearPoint3DKeyFrame KeyTime="0:0:3" Value="-5
0 0"/>
<LinearPoint3DKeyFrame KeyTime="0:0:4" Value="0
0 5"/>
</Point3DAnimationUsingKeyFrames>
<Vector3DAnimationUsingKeyFrames Storyboard.TargetProperty="LookDirection"
Storyboard.TargetName="camera">
<LinearVector3DKeyFrame KeyTime="0:0:1" Value="-1
0 0"/>
<LinearVector3DKeyFrame KeyTime="0:0:2" Value="0
0 1"/>
<LinearVector3DKeyFrame KeyTime="0:0:3" Value="1
0 0"/>
<LinearVector3DKeyFrame KeyTime="0:0:4" Value="0
0 -1"/>
</Vector3DAnimationUsingKeyFrames>
<Vector3DAnimationUsingKeyFrames Storyboard.TargetProperty="Direction"
Storyboard.TargetName="light">
<LinearVector3DKeyFrame KeyTime="0:0:1" Value="-1
0 0"/>
<LinearVector3DKeyFrame KeyTime="0:0:2" Value="0
0 1"/>
<LinearVector3DKeyFrame KeyTime="0:0:3" Value="1
0 0"/>
<LinearVector3DKeyFrame KeyTime="0:0:4" Value="0
0 -1"/>
</Vector3DAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Viewport3D.Triggers>
<Viewport3D.Camera>
<PerspectiveCamera x:Name="camera" Position="0
0 5" LookDirection="0 0 -1"FieldOfView="60"/>
</Viewport3D.Camera>
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup>
<DirectionalLight Direction="0
0 -1"
x:Name="light"
Color="White"/>
<GeometryModel3D>
<GeometryModel3D.Geometry>
<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
2 1, 1 2 3, 5 6 4, 5 7 6
8 10 9, 9 10 11, 13 14 12, 13 15 14
16 18 17, 17 18 19, 22 21 20, 22 23 21"
TextureCoordinates="0
0, 1 0, 0 1, 1 1,
0 0, 1 0, 0 1, 1 1,
0 0, 1 0, 0 1, 1 1,
0 0, 1 0, 0 1, 1 1,
0 0, 1 0, 0 1, 1 1,
0 0, 1 0, 0 1, 1 1" />
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Color="YellowGreen" Offset="0"/>
<GradientStop Color="Green" Offset="1"/>
</LinearGradientBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
</GeometryModel3D>
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>