In this article we are going to see how to create a 3D multi touch example, this example we are going to create a rotatable 3D world with touch as well as in Mouse.For this we have to use StoryBoard for animation, and ViewPort3D for 3D support of image.
<Window x:Class="CSWPF3DMultiTouch.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shapes="clr-namespace:CSWPF3DMultiTouch"
Title="Touch 3D World">
<Window.Resources>
<Storyboard x:Key="sb">
<DoubleAnimation Storyboard.TargetName="InfoScale" Storyboard.TargetProperty="ScaleX" From="0" To="1">
<DoubleAnimation.EasingFunction>
<BounceEase/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="InfoScale"
Storyboard.TargetProperty="ScaleY" From="0" To="1">
<DoubleAnimation.EasingFunction>
<BounceEase/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</Window.Resources>
<Grid Background="Black" IsManipulationEnabled="True"
ManipulationDelta="OnManipulationDelta" TouchUp="OnTouchUp" MouseLeftButtonDown="Grid_MouseLeftButtonDown" MouseMove="Grid_MouseMove" MouseLeftButtonUp="Grid_MouseLeftButtonUp" MouseWheel="Grid_MouseWheel">
<Viewport3D x:Name="viewport">
<Viewport3D.Camera>
<PerspectiveCamera Position="0,0,5"/>
</Viewport3D.Camera>
<ModelVisual3D x:Name="Light">
<ModelVisual3D.Content>
<Model3DGroup>
<AmbientLight x:Name="light" Color="White"/>
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
<shapes:Sphere x:Name="earth">
<shapes:Sphere.Material>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<ImageBrush ImageSource="Map.png"/>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</shapes:Sphere.Material>
<shapes:Sphere.Transform>
<Transform3DGroup x:Name="transformGroup">
<ScaleTransform3D x:Name="scaleTransform"/>
</Transform3DGroup>
</shapes:Sphere.Transform>
</shapes:Sphere>
</Viewport3D>
<Rectangle Fill="Transparent"/>
<CheckBox x:Name="MouseSimulationCheckBox" Content="Allow mouse
simulation" Foreground="RosyBrown" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10"/>
<TextBlock x:Name="InfoTextBox" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="10" FontSize="24" Foreground="RosyBrown" FontWeight="Bold" RenderTransformOrigin="0.5,0.5">
<TextBlock.RenderTransform>
<ScaleTransform x:Name="InfoScale"/>
</TextBlock.RenderTransform>
</TextBlock>
<Line x:Name="TouchLine" Stroke="Red" StrokeThickness="2"/>
</Grid>
</Window>
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Media3D;
namespace CSWPF3DMultiTouch
{
public partial class MainWindow :
Window
{
private double
_angleBuffer = 0d;
private static int _imageWidth = 1995;
private static int _imageHeight = 2051;
private List<DataCenter> _dataCenters;
private bool
_isMouseDown;
private Point
_startPoint;
public MainWindow()
{
InitializeComponent();
this._dataCenters = new
List<DataCenter>(6);
this._dataCenters.Add(new
DataCenter() { Name = "Chicago", Bound = new Rect(328, 790,
20, 20) });
this._dataCenters.Add(new
DataCenter() { Name = "San Antonio", Bound = new Rect(285, 873,
20, 20) });
this._dataCenters.Add(new
DataCenter() { Name = "Amsterdam", Bound = new Rect(856, 711,
20, 20) });
this._dataCenters.Add(new
DataCenter() { Name = "Dublin", Bound = new Rect(796, 703,
20, 20) });
this._dataCenters.Add(new
DataCenter() { Name = "Hong Kong", Bound = new Rect(1454,
923, 20, 20) });
this._dataCenters.Add(new
DataCenter() { Name = "Singapore", Bound = new Rect(1406,
1040, 20, 20) });
Touch.FrameReported
+= new TouchFrameEventHandler(Touch_FrameReported);
}
private void
OnManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
this.scaleTransform.ScaleX *= e.DeltaManipulation.Scale.X;
this.scaleTransform.ScaleY *=
e.DeltaManipulation.Scale.Y;
this.scaleTransform.ScaleZ *=
e.DeltaManipulation.Scale.X;
this._angleBuffer++;
if (_angleBuffer >= 0)
{
Vector delta = e.DeltaManipulation.Translation;
this.RotateEarth(delta);
}
e.Handled = true;
}
private void
RotateEarth(Vector delta)
{
if (delta.X != 0 || delta.Y != 0)
{
Vector3D vOriginal = new Vector3D(-delta.X,
delta.Y, 0d);
Vector3D vZ = new Vector3D(0, 0, 1);
Vector3D perpendicular = Vector3D.CrossProduct(vOriginal, vZ);
RotateTransform3D
rotate = new RotateTransform3D();
QuaternionRotation3D quatenion = new QuaternionRotation3D();
quatenion.Quaternion = new Quaternion(perpendicular, 3);
rotate.Rotation = quatenion;
this.transformGroup.Children.Add(rotate);
this._angleBuffer = 0;
}
}
private void
OnTouchUp(object sender, TouchEventArgs e)
{
DoHitTest(e.GetTouchPoint(this.viewport).Position);
}
private void
DoHitTest(Point point)
{
VisualTreeHelper.HitTest(this.viewport,
null, new HitTestResultCallback(target =>
{
RayMeshGeometry3DHitTestResult result
= target as RayMeshGeometry3DHitTestResult;
if (result != null)
{
Point
p1 = result.MeshHit.TextureCoordinates[result.VertexIndex1];
Point p2 =
result.MeshHit.TextureCoordinates[result.VertexIndex2];
Point p3 =
result.MeshHit.TextureCoordinates[result.VertexIndex3];
double hitX = p1.X *
result.VertexWeight1 + p2.X * result.VertexWeight2 + p3.X *
result.VertexWeight3;
double hitY = p1.Y *
result.VertexWeight1 + p2.Y * result.VertexWeight2 + p3.Y *
result.VertexWeight3;
Point pointHit = new Point(hitX *
_imageWidth, hitY * _imageHeight);
foreach (DataCenter
dc in this._dataCenters)
{
if (dc.Bound.Contains(pointHit))
{
this.InfoTextBox.Text = "You've
just touched the " + dc.Name + "
data center!";
Storyboard
sb = this.Resources["sb"]
as Storyboard;
if (sb != null)
{
sb.Begin();
}
return HitTestResultBehavior.Stop;
}
}
}
return HitTestResultBehavior.Continue;
}), new PointHitTestParameters(point));
}
void Touch_FrameReported(object
sender, TouchFrameEventArgs e)
{
var touchPoints = e.GetTouchPoints(this.viewport);
if (touchPoints.Count >= 2 &&
touchPoints[0].Action == TouchAction.Up)
{
this.TouchLine.X1 = touchPoints[0].Position.X;
this.TouchLine.X2 =
touchPoints[1].Position.X;
this.TouchLine.Y1 =
touchPoints[0].Position.Y;
this.TouchLine.Y2 =
touchPoints[1].Position.Y;
}
}
private void
Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this._isMouseDown = true;
this._startPoint = e.GetPosition(this.viewport);
}
private void
Grid_MouseMove(object sender, MouseEventArgs e)
{
if (this._isMouseDown
&& this.MouseSimulationCheckBox.IsChecked.Value)
{
this._angleBuffer++;
if (_angleBuffer >= 0)
{
Point currentPoint = e.GetPosition(this.viewport);
Vector delta = new Vector(currentPoint.X
- this._startPoint.X, currentPoint.Y - this._startPoint.Y);
RotateEarth(delta);
}
}
}
private void
Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
this._isMouseDown = false;
if (this.MouseSimulationCheckBox.IsChecked.Value)
{
this.DoHitTest(e.GetPosition(this.viewport));
}
}
private void
Grid_MouseWheel(object sender, MouseWheelEventArgs e)
{
if (this.MouseSimulationCheckBox.IsChecked.Value)
{
double delta = e.Delta > 0 ? 1.2 :
0.8;
this.scaleTransform.ScaleX *= delta;
this.scaleTransform.ScaleY *= delta;
this.scaleTransform.ScaleZ *= delta;
}
}
}
}
From this article i hope you will learn how to create a 3D view.
No comments:
Post a Comment