下面是一个基于WPF实现3D画廊动画效果的示例代码:
using System;using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Media3D;
namespace WPF3DGallery
{
public partial class MainWindow : Window
{
private const double AngleIncrement = 30;
private const double ScaleIncrement = 0.1;
private PerspectiveCamera _camera;
private Model3DGroup _modelGroup;
private Point _lastMousePosition;
public MainWindow()
{
InitializeComponent();
CreateScene();
}
private void CreateScene()
{
// 创建3D场景
_modelGroup = new Model3DGroup();
_modelGroup.Children.Add(CreateCubeModel(new Point3D(-100, 0, 0), Colors.Red));
_modelGroup.Children.Add(CreateCubeModel(new Point3D(0, 0, 0), Colors.Green));
_modelGroup.Children.Add(CreateCubeModel(new Point3D(100, 0, 0), Colors.Blue));
// 创建灯光
var directionalLight = new DirectionalLight(Colors.White, new Vector3D(0, -0.5, -1));
_modelGroup.Children.Add(directionalLight);
// 设置相机
_camera = new PerspectiveCamera(new Point3D(0, 0, 200), new Vector3D(0, 0, -1), new Vector3D(0, 1, 0));
// 将模型和相机添加到Viewport3D中
var viewport = new Viewport3D();
viewport.Camera = _camera;
viewport.Children.Add(_modelGroup);
// 设置Viewport3D为窗口的内容
Content = viewport;
}
private GeometryModel3D CreateCubeModel(Point3D position, Color color)
{
var mesh = new MeshGeometry3D();
mesh.Positions.Add(new Point3D(-50, -50, 50));
mesh.Positions.Add(new Point3D(50, -50, 50));
mesh.Positions.Add(new Point3D(-50, 50, 50));
mesh.Positions.Add(new Point3D(50, 50, 50));
mesh.Positions.Add(new Point3D(-50, -50, -50));
mesh.Positions.Add(new Point3D(50, -50, -50));
mesh.Positions.Add(new Point3D(-50, 50, -50));
mesh.Positions.Add(new Point3D(50, 50, -50));
mesh.TriangleIndices.Add(0);
mesh.TriangleIndices.Add(1);
mesh.TriangleIndices.Add(2);
mesh.TriangleIndices.Add(2);
mesh.TriangleIndices.Add(1);
mesh.TriangleIndices.Add(3);
mesh.TriangleIndices.Add(4);
mesh.TriangleIndices.Add(5);
mesh.TriangleIndices.Add(6);
mesh.TriangleIndices.Add(6);
mesh.TriangleIndices.Add(5);
mesh.TriangleIndices.Add(7);
mesh.TriangleIndices.Add(2);
mesh.TriangleIndices.Add(3);
mesh.TriangleIndices.Add(6);
mesh.TriangleIndices.Add(6);
mesh.TriangleIndices.Add(3);
mesh.TriangleIndices.Add(7);
mesh.TriangleIndices.Add(0);
mesh.TriangleIndices.Add(2);
mesh.TriangleIndices.Add(4);
mesh.TriangleIndices.Add(4);
mesh.TriangleIndices.Add(2);
mesh.TriangleIndices.Add(6);
mesh.TriangleIndices.Add(1);
mesh.TriangleIndices.Add(0);
mesh.TriangleIndices.Add(5);
mesh.TriangleIndices.Add(5);
mesh.TriangleIndices.Add(0);
mesh.TriangleIndices.Add(4);
mesh.TriangleIndices.Add(1);
mesh.TriangleIndices.Add(5);
mesh.TriangleIndices.Add(3);
mesh.TriangleIndices.Add(3);
mesh.TriangleIndices.Add(5);
mesh.TriangleIndices.Add(7);
var material = new DiffuseMaterial(new SolidColorBrush(color));
return new GeometryModel3D(mesh, material)
{
Transform = new TranslateTransform3D(position.X, position.Y, position.Z)
};
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
_lastMousePosition = e.GetPosition(this);
CaptureMouse();
}
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
ReleaseMouseCapture