要約
- WPF3D暫定版
- カメラの視点を制御する:キーボード;マウス
- テクスチャ:2次元の妻のために3Dギャラリーを作成します; C#で地球をこすります
- 光の効果;色
この記事は、WPF3Dシリーズの最後のブログです。
ソースアドレス:[C#]WPF3Dジオメトリの選択と移動
記事ディレクトリ
ジオメトリを操作する
Minecraftは1週間に3人のプログラマーによって開発されたと言われており、乞食バージョンのMinecraftを開発するのに1人のプログラマーが半日かかったと言われています。推論にはまったく問題はありません。
そして、ご存知のとおり、Minecraftは無数のピクセルブロックのコレクションであり、ピクセルブロックは立方体です。新しいキューブの作成に関しては、誰もがこれに非常に精通しています。新しいキューブを作成できるだけでなく、必要な数のキューブを作成することもできます。
新しいキューブ
ただし、現在、手動で作成することはできないため、次にショートカットCtrl
+を追加N
して、キューブをすばやく作成します。Ctrl
+を押すN
と、効果は
これは、キューブの行をすでに生成できる人にとっては間違いなく簡単です。最初にコンストラクターでショートカットをバインドします。
public MainWindow()
{
InitializeComponent();
KeyDown += MainWindow_KeyDown;
}
MainWindow_KeyDown
として定義
private void MainWindow_KeyDown(object sender, KeyEventArgs e)
{
if ((Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) && Keyboard.IsKeyDown(Key.N))
{
MeshGeometry3D mesh = MakeCubeMesh(0, 0, 0, 1);
Color color = Color.FromArgb(255, 0, 255, 0);
DiffuseMaterial material = new DiffuseMaterial(new SolidColorBrush(color));
GeometryModel3D model = new GeometryModel3D(mesh, material);
group3d.Children.Add(model);
}
}
その中にMakeCubeMesh
は、このシリーズの最初のブログで早くも書かれているカスタム関数や、光の効果などの他の関数があります。唯一の違いは、今回はそもそも複数のキューブを生成しないため、DefineModel
関数は必要ないということです。
立方体の位置を設定します
現在、新しい立方体が作成されていますが、立方体の位置を特定できません。次に、新しく作成された立方体の位置を設定するために、新しいダイアログボックスを作成する必要があります。
プロジェクトを右クリックし、新しいウィンドウを作成して名前を付けParaDialog
ますxaml
。
<Window x:Class="MyWord.ParaDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="输入参数" Height="180" Width="300">
<DockPanel LastChildFill="True">
<StackPanel DockPanel.Dock="Bottom"
Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="设置" Click="okButton_Click" Margin="5" Width="60" Height="25"/>
<Button Content="取消" IsCancel="True" Margin="5" Width="60" Height="25"/>
</StackPanel>
<UniformGrid Columns="1" Margin="5" x:Name="ufgLabel"/>
<UniformGrid Columns="1" Margin="5" x:Name="ufgTextBox"/>
</DockPanel>
</Window>
そのcs
コアコードは
public partial class ParaDialog : Window
{
static readonly string[] labels = new string[4] {
"x坐标", "y坐标", "z坐标", "边长" };
List<TextBox> paraBoxes = new List<TextBox>();
public double[] para;
public ParaDialog(double[] para)
{
this.para = para;
InitializeComponent();
string tmp;
for (int i = 0; i < 4; i++)
{
//向UniformGrid中欧给填充文字块
ufgLabel.Children.Add(new TextBlock() {
Text = labels[i] });
paraBoxes.Add(new TextBox());
ufgTextBox.Children.Add(paraBoxes[i]);
}
}
private void okButton_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 4; i++)
para[i] = double.Parse(paraBoxes[i].Text);
DialogResult = true;
}
}
最後に、Ctrl
+N
の応答コードを変更します
//...前面不用改
if ((Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) && Keyboard.IsKeyDown(Key.N))
{
double[] para = new double[4];
ParaDialog pDialog = new ParaDialog(para);
pDialog.ShowDialog();
if (pDialog.DialogResult != true)
return;
MeshGeometry3D mesh = MakeCubeMesh(para[0],para[1],para[2],para[3]);
//...后面不用改
}
選択したキューブ
ジオメトリを操作する場合は、ジオメトリを選択してから、マウスアクションをバインドして選択した操作を完了し、xaml
最初にコードを変更してViewport3D
、border
<Border Name="mainBorder" Background="White" MouseDown="mainBorder_MouseDown">
<Viewport3D x:Name="v3dMain">
</Viewport3D>
</Border>
次に、新しいmainBorder_MouseDown
関数を作成します
private void mainBorder_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Released) return;
Color color = Color.FromArgb(255, 0, 255, 0);
var material = new DiffuseMaterial(new SolidColorBrush(color));
//获取鼠标在对象中的位置
Point mousePos = e.GetPosition(v3dMain);
// 执行点击操作
HitTestResult result = VisualTreeHelper.HitTest(v3dMain, mousePos);
//此即鼠标点击到曲面上的结果
var meshResult = result as RayMeshGeometry3DHitTestResult;
GeometryModel3D model = null;
if ((meshResult != null) && (meshResult.ModelHit is GeometryModel3D))
model = meshResult.ModelHit as GeometryModel3D;
//如果刚才选了别的模型,则使之恢复绿色
if (SelectedModel != null)
SelectedModel.Material = material;
//选择新的模型
SelectedModel = model;
if (model != null)
model.Material = new DiffuseMaterial(Brushes.Fuchsia);
}
その効果は
ジオメトリを移動する
選択できるので、何かを動かすのは絶対に簡単です。
以前のマウス操作カメラを振り返ると、基本的なプロセスは、マウスをクリックした後、別の関数がバインドされ、マウスを離すとバインドが解除されるというものです。
WPF 3D
にはTranform
、ジオメトリの移動に使用できるメンバーが用意されているため、新しいジオメトリを作成するときは、必ず線を追加してください。
//MainWindow_KeyDown函数
model.Transform = new TranslateTransform3D(0, 0, 0);
次に、古い場所を保持するグローバル変数を追加します
private Point3D oldPoint;
次に、変更mainBorder_MouseDown
します。実際、最後に追加するだけです。
mainBorder.CaptureMouse();
mainBorder.MouseMove += MainBorder_MouseMove;
mainBorder.MouseUp += MainBorder_MouseUp;
次は、マウスを動かしてバウンスしたときのアクションです。バウンスは非常に単純で、マウスアクションのバインドを解除するだけです。マウスを動かしたときは、ジオメトリの変更パラメータを変更する必要があります。
private void MainBorder_MouseUp(object sender, MouseButtonEventArgs e)
{
mainBorder.ReleaseMouseCapture();
mainBorder.MouseMove -= MainBorder_MouseMove;
mainBorder.MouseUp -= MainBorder_MouseUp;
}
private void MainBorder_MouseMove(object sender, MouseEventArgs e)
{
Point newPoint = e.GetPosition(mainBorder);
var res = VisualTreeHelper.HitTest(v3dMain, newPoint);
if (res == null) return;
var newResult = res as RayMeshGeometry3DHitTestResult;
var deltaPt = newResult.PointHit - oldPoint;
var trans = SelectedModel.Transform as TranslateTransform3D;
trans.OffsetX += deltaPt.X;
trans.OffsetY += deltaPt.Y;
trans.OffsetZ += deltaPt.Z;
oldPoint = newResult.PointHit;
}
効果は
さて、Minecraftのスーパー乞食バージョンは準備ができています→_→それは米国または香港にリストされていますか?