ZoomPanel + 3D
#1
Can I use a ZoomPanel and it's functionality in a 3D view?  

Most of the time I am looking for using the zoom box while in a 3D view that is emulating a 2D view (i.e Top-Down for PlanView).  However, it might be convenient to be able to use it in a "real" 3D view (isometric) but I would want to prevent any rotation while doing this.  

I need to give my users the ability to have a "zoom-box" and I'm hoping that ZoomPanel is my solution. It has all of the UI that I'm looking for with panning, zoombox, zoomin, zoomout, "home" - 1:1, and mini-map.
#2
This is an interesting idea.

I have tried it and this may actually work for the Orthographics camera and when the view is parallel with coordinate axis - for example top-down view. You would also need a button on UI that would enable such navigation - in this mode the 3D rotation would be disabled.

You can try this with the following XAML and cs:

XAML:
Code:
<Window x:Class="WpfApplication16.DXEngineWithZoomPanel"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:cameras="clr-namespace:Ab3d.Cameras;assembly=Ab3d.PowerToys"
     xmlns:ab3d="clr-namespace:Ab3d.Controls;assembly=Ab3d.PowerToys"  
     xmlns:visuals="clr-namespace:Ab3d.Visuals;assembly=Ab3d.PowerToys"
     xmlns:dxControls="clr-namespace:Ab3d.DirectX.Controls;assembly=Ab3d.DXEngine.Wpf"
     xmlns:controls="clr-namespace:Ab2d.Controls;assembly=Ab2d.Controls.ZoomPanel"
     Title="StandardXaml"
     mc:Ignorable="d"
     d:DesignHeight="400" d:DesignWidth="800">

   <Grid Name="RootGrid">
       <Border Name="ViewportBorder" Background="Transparent">

           <dxControls:DXViewportView Name="MainDXViewportView" PresentationType="DirectXImage">

               <Viewport3D Name="MainViewport">
                   <visuals:WireGridVisual3D CenterPosition="0 0 0" Size="100 100" WidthCellsCount="5" HeightCellsCount="5" LineColor="#555555" LineThickness="2"/>

                   <visuals:BoxVisual3D x:Name="Box1Visual3D" CenterPosition="0 10 0" Size="50 20 50" Material="Gold" />
               </Viewport3D>

           </dxControls:DXViewportView>
       </Border>

       <cameras:TargetPositionCamera Name="Camera1"
                                     TargetPosition="0 0 0"
                                     Heading="0" Attitude="-90" Bank="0"
                                     Distance="400"
                                     CameraWidth="1000"
                                     ShowCameraLight="Always"
                                     CameraType="OrthographicCamera"
                                     TargetViewport3D="{Binding ElementName=MainViewport}"/>

       <ab3d:MouseCameraController Name="MouseCameraController1"
                                   RotateCameraConditions="LeftMouseButtonPressed"
                                   MoveCameraConditions="LeftMouseButtonPressed, ControlKey"
                                   EventsSourceElement="{Binding ElementName=ViewportBorder}"
                                   TargetCamera="{Binding ElementName=Camera1}" />


       <controls:ZoomPanel x:Name="ZoomPanel1" ZoomMode="ZoomIn" IsHitTestVisible="{Binding ElementName=IsZoomPanelEnabledCheckBox, Path=IsChecked}">
           <Canvas Name="ZoomPanelCanvas" Width="100" Height="100" />
       </controls:ZoomPanel>

       <StackPanel VerticalAlignment="Top" HorizontalAlignment="Right" Orientation="Vertical">
           <controls:ZoomController TargetZoomPanel="{Binding ElementName=ZoomPanel1}"/>
           <CheckBox Name="IsZoomPanelEnabledCheckBox" Content="IsZoomPanelEnabled" IsChecked="True" />
       </StackPanel>

       <controls:ZoomPanelNavigator MinZoomFactor="0.1" MaxZoomFactor="5"
                                    VerticalAlignment="Top" HorizontalAlignment="Left" Height="200"
                                    TargetZoomPanel="{Binding ElementName=ZoomPanel1}"/>
       
       
       <Border VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5" BorderBrush="Black" BorderThickness="1">
           <StackPanel Orientation="Vertical">
               <TextBlock Text="MiniMap:" />
               <!-- To display an image in MiniMap set the MapImageElement property to an Image -->
               <controls:ZoomPanelMiniMap TargetZoomPanel="{Binding ElementName=ZoomPanel1}" />
           </StackPanel>
       </Border>
   </Grid>
</Window>
cs:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Media.Media3D;
using System.Windows.Shapes;
using Ab2d.Controls;

namespace WpfApplication16
{
   /// <summary>
   /// Interaction logic for DXEngineWithZoomPanel.xaml
   /// </summary>
   public partial class DXEngineWithZoomPanel : Window
   {
       private double _initialWidth;
       private double _initialHeight;

       public DXEngineWithZoomPanel()
       {
           InitializeComponent();

           _initialWidth = 1000; // Width at 1:1 view (Viewbox.Width == 1)
           Camera1.CameraWidth = _initialWidth;


           this.Loaded += delegate (object sender, RoutedEventArgs args)
           {
               ZoomPanelCanvas.Width = this.ActualWidth;
               ZoomPanelCanvas.Height = this.ActualHeight;

               _initialHeight = _initialWidth * this.ActualHeight / this.ActualWidth;

               ZoomPanel1.ZoomFactor = 2;
           };

           ZoomPanel1.ViewboxChanged += delegate(object sender, ViewboxChangedRoutedEventArgs e)
           {
               Camera1.CameraWidth = _initialWidth * e.NewViewboxValue.Width;

               double centerX = e.NewViewboxValue.X + (e.NewViewboxValue.Width * 0.5);
               double centerY = e.NewViewboxValue.Y + (e.NewViewboxValue.Height * 0.5);

               Camera1.TargetPosition = new Point3D((centerX - 0.5) * _initialWidth, 0, (centerY - 0.5) * _initialHeight);
           };
       }
   }
}

Note that when ZoomPanel is enabled (IsHitTestVisible is set to true), it will get all mouse events and MouseCameraController will not get any (so 3D rotation will be disabled).
If you would also like to have animated zooming, you would need to subscribe to ZoomFactor DepandencyProperty changes.


Also note that I do not have time to test this solution fully so use with caution.
Andrej Benedik
  


Forum Jump:


Users browsing this thread:
1 Guest(s)