| Viewport3D in WPF XBAP-application |
| Section: WPF | Rating: Not rated yet! |
 | CodeGod submitted this resource The member's homepage is http://www.codegod.de Visit the profile here |
Attachment
Introduction
| In a previous article I showed how to add a 3D-cube programmatically to a 3D-scene with WPF and XAML. With WPF it is also possible to run this application in a browser (IE or firefox with IE-plugin). In this article the author describes how to achieve this. | |
Figure 1The example
In our example we port the WPF-application explained in
this article to an XBAP-application. We enhanced the user-interaction a little bit by adding mouse-support for moving the 3D-cube along the X, Y and Z-axis. The user-interface for rotating the cube is the same, but it is loaded into a
Page- and not into a
Window-object. This means, it can be loaded in a browser. But there are some more things to be done to get this running ? keep on reading.
The project
In VS 2008 Beta2 there is a project-type called WPF Browser application. We used this template to create our application:
Figure 2After that, a Page1.xaml-file is created for us and all references we need to develop a WPF-application. A WPF browser application can be published to the internet by defining the ftp-server or website in Properties->Publish. There is also a Publish-Wizard on the page available you can use for that. The default-security-setting is Internet. It is recommended to develop browser applications with that settings cause more elevated settings require to install certificates on the client.
In the example we don't touch the default-settings and import all needed classes we used in our previous project for the 3D-cube:
1. The Cube-control
This is a WPF-control with a ViewPort3D-instance. We use this to display a 3D-Cube-model. It contains a definition of a camera, 2 light-sources (ambient and directional) and a Transform3DGroup for rotating the cube along X-,Y- and Z-axis:
<UserControl x:Class="WpfCubeControl.CubeControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Viewport3D Name="mainViewport" ClipToBounds="True">
<Viewport3D.Camera>
<PerspectiveCamera
Position="10,8,9"
LookDirection="-11,-9,-10"
FarPlaneDistance="100"
UpDirection="0,1,0"
NearPlaneDistance="1"
FieldOfView="90" >
<PerspectiveCamera.Transform>
<Transform3DGroup x:Name="transformGroup">
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="rotY"
Axis="0 1 0"
Angle="0" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="rotX"
Axis="1 0 0"
Angle="0" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="rotZ"
Axis="0 0 1"
Angle="0" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</Transform3DGroup>
</PerspectiveCamera.Transform>
</PerspectiveCamera>
</Viewport3D.Camera>
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup>
<AmbientLight Color="Blue"/>
<DirectionalLight
Color="White"
Direction="-2,-3,-1" />
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
</UserControl>
2. The CubeBuilder-classThis class is used to add a 3D-cube to the ViewPort3D-obejct programmatically. I introduced it already in the
previous article, just like the classes
ModelBuilder from which it is derived and the
VectorHelper-class.
3. The MouseHelper-classThis class is added to allow the user to move the cube with the mouse over the screen. When pressing the left mouse-button you can move the mouse along the X- and Y-axis, when pressing the right-mousebutton the cube is moving along the Z-axis.
4. The main pageThe main-page for our browser application is the Page1.xaml. I copied the Grid with all content defined in our previous WPF-application to this page, no modification is needed. We need 3 sliders for the rotation-interaction, a ComboBox for the colorization of the cube and of course an instance of the CubeControl:
<Page x:Class="WpfBrowserCube.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfCubeControl"
Title="Page1" Height="500" Width="800" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="247*" />
<RowDefinition Height="66" />
</Grid.RowDefinitions>
<local:CubeControl x:Name="cubeControl1" CubeColor="Thistle" Grid.RowSpan="1" />
<StackPanel Background="#FFEEEEEE" Grid.Row="1">
<StackPanel FlowDirection="LeftToRight" Orientation="Horizontal">
<Label Name="label1" Width="120" Height="23"
VerticalAlignment="Top">Rotations (X,Y,Z)</Label>
</StackPanel>
<StackPanel Margin="5" FlowDirection="LeftToRight"
Grid.RowSpan="2" VerticalAlignment="Bottom" Orientation="Horizontal">
<Slider Name="rotateX" Width="80" Value="0" Maximum="360"
Minimum="0" ValueChanged="rotateX_ValueChanged" />
<Slider Maximum="360" Name="rotationY" Value="0"
Grid.Row="1" Width="80" Minimum="0" ValueChanged="rotationY_ValueChanged"/>
<Slider Maximum="360" Name="rotationZ" Value="0" Width="80"
Minimum="0" ValueChanged="rotationZ_ValueChanged" />
<ComboBox Height="21" Name="cbColors" Width="120"
SelectionChanged="cbColors_SelectionChanged" />
</StackPanel>
</StackPanel>
</Grid>
</Page>
This is the code-behind in Page1.xaml which contains the logic for rotating and colorizing the cube:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Drawing;
namespace WpfBrowserCube
{
/// <summary>
/// Interaction logic for Page1.xaml
/// </summary>
public partial class Page1 : Page
{
public Page1()
{
InitializeComponent();
KnownColor t = new KnownColor();
foreach (KnownColor kc in System.Enum.GetValues(t.GetType()))
{
System.Drawing.ColorConverter cc = new System.Drawing.ColorConverter();
System.Drawing.Color c = System.Drawing.Color.FromName(kc.ToString());
if (!c.IsSystemColor)
cbColors.Items.Add(c);
}
cbColors.SelectedItem = System.Drawing.Color.DeepSkyBlue;
cubeControl1.Render();
}
private void rotateX_ValueChanged(object sender,
RoutedPropertyChangedEventArgs<double> e)
{
cubeControl1.RotateX(e.NewValue);
}
private void rotationY_ValueChanged(object sender,
RoutedPropertyChangedEventArgs<double> e)
{
cubeControl1.RotateY(e.NewValue);
}
private void rotationZ_ValueChanged(object sender,
RoutedPropertyChangedEventArgs<double> e)
{
cubeControl1.RotateZ(e.NewValue);
}
private void cbColors_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
System.Drawing.Color color = (System.Drawing.Color)cbColors.SelectedItem;
cubeControl1.CubeColor = System.Windows.Media.Color.FromRgb(
color.R, color.G, color.B);
cubeControl1.Render();
}
}
}
When pressing F5 the application is started in the browser.
Live-sample
You can see a live-sample
here. I found out that you have to deactivate the popup-blocker in the internet-settings (Security->settings->misc) to run the sample. At least under Vista it is the case... have fun wit the attached project!