WPFのクラスで3Dプログラミング
WPFで3Dプログラミングをする場合、通常は裏でDirect3Dを用意してレンダリングを行います。
ただ、とても簡単な3D描画を行いたい場合は、WPFが用意する3D描画クラスを利用することができます。
今回は簡単な実装をしてみたいと思います。
アプリケーション
今回はキーボードの上下左右で回転する立方体を表示してみたいと思います。
コントロールの主体はViewport3Dで、そこにカメラやライト、メッシュを追加していく形となります。
法線は自動生成されるため、今回は作成していません。
回転はModel3DのTransformを更新することで行っています。
下記はC#で実装していますが、Xamlで記述することも可能です。
// Cubeの各三角形(12枚)を作成 var vertices = new [] { new Point3D(-1, 1, 1), new Point3D(-1, -1, 1), new Point3D( 1, -1, 1), new Point3D( 1, 1, 1), new Point3D(-1, 1, -1), new Point3D(-1, -1, -1), new Point3D( 1, -1, -1), new Point3D( 1, 1, -1) }; Point3D[] face(int i1, int i2, int i3, int i4) => new[] { i1, i2, i3, i1, i3, i4 }.Select(x => vertices[x]).ToArray(); Point3D[] positions = new[] { face(0, 1, 2, 3), face(3, 2, 6, 7), face(7, 6, 5, 4), face(4, 5, 1, 0), face(0, 3, 7, 4), face(5, 6, 2, 1), }.SelectMany(x => x).ToArray(); // 頂点座標と色をセット var model = new GeometryModel3D() { Geometry = new MeshGeometry3D() { Positions = new Point3DCollection(positions) }, Material = new DiffuseMaterial(Brushes.LightGreen), }; // ライト作成 var light = new DirectionalLight(Colors.White, new Vector3D(0, 0, -1)); // カメラ作成 var camera = new PerspectiveCamera(new Point3D(0, 0, 5), new Vector3D(0, 0, -1), new Vector3D(0, 1, 0), 45); // 表示用コントロールの作成 Viewport3D viewport3D = new Viewport3D(); viewport3D.Camera = camera; viewport3D.Children.Add(new ModelVisual3D() { Content = model }); viewport3D.Children.Add(new ModelVisual3D() { Content = light }); Content = viewport3D; // KeyDownでCubeが回転するよう実装 var quaternion = new Quaternion(); KeyDown += (s, e) => { var q = e.Key == Key.Left ? new Quaternion(new Vector3D(0, 1, 0), -1) : e.Key == Key.Right ? new Quaternion(new Vector3D(0, 1, 0), 1) : e.Key == Key.Up ? new Quaternion(new Vector3D(1, 0, 0), -1) : e.Key == Key.Down ? new Quaternion(new Vector3D(1, 0, 0), 1) : Quaternion.Identity; quaternion = q * quaternion; model.Transform = new RotateTransform3D(new QuaternionRotation3D(quaternion)); };
法線やインデックス
MeshGeometry3DにはNormalsとTriangleIndicesが設定可能となっています。
テクスチャ
MeshGeometry3DのTextureCoordinatesを設定し、DiffuseMaterialにImageBrushを設定します。
カリングOFF
GeometryModel3DのBackMaterialを設定するとOFFになります。
ライン描画
残念ながら対応していません。細いポリゴンを描くしかなさそうです。
オブジェクト毎のマウスイベントハンドリング
ModelVisual3Dの代わりにModelUIElement3Dを利用すると、MouseMoveなどが登録できるようになります。
2Dコントロール(Buttonなど)を3D上に配置
Viewport2DVisual3Dを用いると可能となります。