|
|
(15 intermediate revisions by the same user not shown) |
Line 38: |
Line 38: |
| public ICommand RotateRightCmnd { get { return new DelegateCommand(OnRotateRight); } } | | public ICommand RotateRightCmnd { get { return new DelegateCommand(OnRotateRight); } } |
|
| |
|
| private void OnRotateLeft(object obj) | | private void OnRotateLeft(object obj) { Rotation += 1;} |
| { | | private void OnRotateRight(object obj) { Rotation -= 1;} |
| Rotation += 1;
| |
| } | |
| | |
| private void OnRotateRight(object obj) | |
| { | |
| Rotation -= 1;
| |
| } | |
|
| |
|
| public int Rotation | | public int Rotation |
Line 59: |
Line 52: |
| . . . | | . . . |
| </source> | | </source> |
|
| |
|
| |
|
| === Running with map rotation === | | === Running with map rotation === |
Line 109: |
Line 101: |
| === Additional components and code === | | === Additional components and code === |
|
| |
|
| To visualise the 3D settings, add display, with ability for modification, for: | | To visualise the 3D settings, add display, with ability of modification, for: |
| ;Camera | | ;Camera |
| :* Yaw | | :* Yaw |
Line 116: |
Line 108: |
| ;Target | | ;Target |
| :* Follow ground | | :* Follow ground |
| :* Distance
| |
| :* Altitude | | :* Altitude |
| ::Changes are not applicable while: | | ::Changes are not applicable while: |
Line 124: |
Line 115: |
| ::Changes are not applicable while: | | ::Changes are not applicable while: |
| ::* auto follow is active, as the target position is defined by the item followed. | | ::* auto follow is active, as the target position is defined by the item followed. |
| | :* Distance |
|
| |
|
| | {{Note|Example of necessary components, properties and command handlers [[Maria globe client/Advanced map settings/3D_settings_code_sample|''are described separately'' '''''here''''']].}} |
|
| |
|
| Example of necessary components, properties and command handlers are described [[3D_map_settings_components_and_code_sample|'''''here''''']].
| | === Synchronise with map actions === |
| | |
| <source lang="xml">
| |
| . . .
| |
| <GroupBox Header="3D Settings"
| |
| IsEnabled="{Binding MapViewModel.Is3DMode}" >
| |
| <Grid >
| |
| <Grid.RowDefinitions>
| |
| <RowDefinition Height="Auto" />
| |
| <RowDefinition Height="Auto" />
| |
| <RowDefinition Height="Auto" />
| |
| <RowDefinition Height="Auto" />
| |
| <RowDefinition Height="Auto" />
| |
| <RowDefinition Height="Auto" />
| |
| <RowDefinition Height="Auto" />
| |
| <RowDefinition Height="Auto" />
| |
| <RowDefinition Height="Auto" />
| |
| <RowDefinition Height="Auto" />
| |
| </Grid.RowDefinitions>
| |
| <Grid.ColumnDefinitions>
| |
| <ColumnDefinition Width="Auto"/>
| |
| <ColumnDefinition Width="Auto"/>
| |
| <ColumnDefinition Width="Auto"/>
| |
| <ColumnDefinition Width="Auto"/>
| |
| </Grid.ColumnDefinitions>
| |
| | |
| <Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4"
| |
| Content="Camera" FontWeight="DemiBold" />
| |
|
| |
| <Label Grid.Row="1" Grid.Column="0"
| |
| Content="Yaw" />
| |
| <TextBox Grid.Row="1" Grid.Column="1" Margin="3" Width="60"
| |
| Text="{Binding MapViewModel.CameraYaw, StringFormat=N2}" TextAlignment="Right"
| |
| IsReadOnly="True"/>
| |
| <RepeatButton Grid.Row="1" Grid.Column="2" Width="12" Margin="3" HorizontalAlignment="Center"
| |
| Content="+"
| |
| Command="{Binding MapViewModel.IncreaseYawCmnd}"/>
| |
| <RepeatButton Grid.Row="1" Grid.Column="3" Width="12" Margin="3" HorizontalAlignment="Center"
| |
| Content="-"
| |
| Command="{Binding MapViewModel.DecreaseYawCmnd}"/>
| |
|
| |
| <Label Grid.Row="2" Grid.Column="0"
| |
| Content="Roll" />
| |
| <TextBox Grid.Row="2" Grid.Column="1" Margin="3" Width="60"
| |
| Text="{Binding MapViewModel.CameraRoll, StringFormat=N2}" TextAlignment="Right"
| |
| IsReadOnly="True"/>
| |
| <RepeatButton Grid.Row="2" Grid.Column="2" Width="12" Margin="3" HorizontalAlignment="Center"
| |
| Content="+"
| |
| Command="{Binding MapViewModel.IncreaseRollCmnd}"/>
| |
| <RepeatButton Grid.Row="2" Grid.Column="3" Width="12" Margin="3" HorizontalAlignment="Center"
| |
| Content="-"
| |
| Command="{Binding MapViewModel.DecreaseRollCmnd}"/>
| |
|
| |
| <Label Grid.Row="3" Grid.Column="0"
| |
| Content="Pitch" />
| |
| <TextBox Grid.Row="3" Grid.Column="1" Margin="3" Width="60"
| |
| Text="{Binding MapViewModel.CameraPitch, StringFormat=N2}" TextAlignment="Right"
| |
| IsReadOnly="True"/>
| |
| <RepeatButton Grid.Row="3" Grid.Column="2" Width="12" Margin="3" HorizontalAlignment="Center"
| |
| Content="+"
| |
| Command="{Binding MapViewModel.IncreasePitchCmnd}"/>
| |
| <RepeatButton Grid.Row="3" Grid.Column="3" Width="12" Margin="3" HorizontalAlignment="Center"
| |
| Content="-"
| |
| Command="{Binding MapViewModel.DecreasePitchCmnd}"/>
| |
| | |
| <Label Grid.Row="4" Grid.Column="0"
| |
| Content="Target" FontWeight="DemiBold" />
| |
| <CheckBox Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="3" VerticalAlignment="Center" Margin="3"
| |
| Content="Follow ground"
| |
| IsChecked="{Binding MapViewModel.FollowGround}"/>
| |
| | |
| <Label Grid.Row="5" Grid.Column="0"
| |
| Content="Altitude" />
| |
| <TextBox Grid.Row="5" Grid.Column="1" Margin="3" Width="60"
| |
| Text="{Binding MapViewModel.TargetAltitude, StringFormat=N0}" TextAlignment="Right"
| |
| IsReadOnly="True"/>
| |
| <RepeatButton Grid.Row="5" Grid.Column="2" Width="12" Margin="3" HorizontalAlignment="Center"
| |
| Content="+"
| |
| Command="{Binding MapViewModel.IncreaseTargetAltitudeCmnd}"/>
| |
| <RepeatButton Grid.Row="5" Grid.Column="3" Width="12" Margin="3" HorizontalAlignment="Center"
| |
| Content="-"
| |
| Command="{Binding MapViewModel.DecreaseTargetAltitudeCmnd}"/>
| |
|
| |
| <Label Grid.Row="6" Grid.Column="0"
| |
| Content="Distance" />
| |
| <TextBox Grid.Row="6" Grid.Column="1" Margin="3" Width="60"
| |
| Text="{Binding MapViewModel.TargetDistance, StringFormat=N0}" TextAlignment="Right"
| |
| IsReadOnly="True"/>
| |
| <RepeatButton Grid.Row="6" Grid.Column="2" Width="12" Margin="3" HorizontalAlignment="Center"
| |
| Content="+"
| |
| Command="{Binding MapViewModel.IncreaseTargetDistanceCmnd}"/>
| |
| <RepeatButton Grid.Row="6" Grid.Column="3" Width="12" Margin="3" HorizontalAlignment="Center"
| |
| Content="-"
| |
| Command="{Binding MapViewModel.DecreaseTargetDistanceCmnd}"/>
| |
|
| |
|
| <Label Grid.Row="7" Grid.Column="0"
| | We need to synchronise the 3D map settings when 3D mode is entered, and also whenever altered by mouse actions in the map area. |
| Content="Position" />
| |
| <TextBox Grid.Row="7" Grid.Column="1" Grid.ColumnSpan="3" Margin="3"
| |
| Text="{Binding MapViewModel.TargetPosText, Mode=OneWay}" TextAlignment="Right"
| |
| IsReadOnly="True"/>
| |
| <Label Grid.Row="8" Grid.Column="1"
| |
| Content="Latitude"/>
| |
| <RepeatButton Grid.Row="8" Grid.Column="2" Width="12" Margin="3" HorizontalAlignment="Center"
| |
| Content="+"
| |
| Command="{Binding MapViewModel.IncreaseTargetPosLatCmnd}"/>
| |
| <RepeatButton Grid.Row="8" Grid.Column="3" Width="12" Margin="3" HorizontalAlignment="Center"
| |
| Content="-"
| |
| Command="{Binding MapViewModel.DecreaseTargetPosLatCmnd}"/>
| |
|
| |
|
| <Label Grid.Row="9" Grid.Column="1"
| | To do that, subscribe to events from: |
| Content="Longitude"/>
| |
| <RepeatButton Grid.Row="9" Grid.Column="2" Width="12" Margin="3" HorizontalAlignment="Center"
| |
| Content="+"
| |
| Command="{Binding MapViewModel.IncreaseTargetPosLonCmnd}"/>
| |
| <RepeatButton Grid.Row="9" Grid.Column="3" Width="12" Margin="3" HorizontalAlignment="Center"
| |
| Content="-"
| |
| Command="{Binding MapViewModel.DecreaseTargetPosLonCmnd}"/>
| |
| </Grid>
| |
| </GroupBox>
| |
| . . .
| |
| </source>
| |
|
| |
|
| | :;GlobeMapViewModel |
| | :* Entered2DMode |
| | :* Entered3DMode |
| | :;GlobeMapViewModel.Globe3DViewModel.CameraControl |
| | :* AfterPan |
| | :* TargetDistanceChanged |
| | :* TargetPosChanged |
| | :* OrientationChanged |
|
| |
|
| And add necessary command handlers and properties to '''''MapViewModel'''''
| | In '''''MapViewModel''''': |
|
| |
|
| <source lang="csharp"> | | <source lang="C#"> |
| . . . | | . . . |
| public ICommand IncreaseYawCmnd { get { return new DelegateCommand(OnIncreaseCameraYaw); } } | | public void SetGlobeMapViewModel(IGlobeMapViewModel globeMapViewModel) |
| public ICommand DecreaseYawCmnd { get { return new DelegateCommand(OnDecreaseCameraYaw); } }
| |
| | |
| public ICommand IncreaseRollCmnd { get { return new DelegateCommand(OnIncreaseCameraRoll); } }
| |
| public ICommand DecreaseRollCmnd { get { return new DelegateCommand(OnDecreaseCameraRoll); } }
| |
| | |
| public ICommand IncreasePitchCmnd { get { return new DelegateCommand(OnIncreaseCameraPitch); } }
| |
| public ICommand DecreasePitchCmnd { get { return new DelegateCommand(OnDecreaseCameraPitch); } }
| |
| | |
| public ICommand IncreaseTargetDistanceCmnd { get { return new DelegateCommand(OnIncreaseTargetDistance); } }
| |
| public ICommand DecreaseTargetDistanceCmnd { get { return new DelegateCommand(OnDecreaseTargetDistance); } }
| |
| | |
| public ICommand IncreaseTargetAltitudeCmnd { get { return new DelegateCommand(OnIncreaseTargetAlttitude, CanModTargetAltitude); } }
| |
| public ICommand DecreaseTargetAltitudeCmnd { get { return new DelegateCommand(OnDecreaseTargetAltitide, CanModTargetAltitude); } }
| |
| | |
| public ICommand IncreaseTargetPosLatCmnd { get { return new DelegateCommand(OnIncreaseTargetPosLat, CanModTargetPosition); } }
| |
| public ICommand DecreaseTargetPosLatCmnd { get { return new DelegateCommand(OnDecreaseTargetPosLat, CanModTargetPosition); } }
| |
| public ICommand IncreaseTargetPosLonCmnd { get { return new DelegateCommand(OnIncreaseTargetPosLon, CanModTargetPosition); } }
| |
| public ICommand DecreaseTargetPosLonCmnd { get { return new DelegateCommand(OnDecreaseTargetPosLon, CanModTargetPosition); } }
| |
| | |
| public bool Autofollow
| |
| {
| |
| get { return _autoFollow; }
| |
| set
| |
| {
| |
| _autoFollow = value;
| |
| | |
| RefreshTargetAndCameraValues();
| |
| }
| |
| }
| |
| | |
| private void OnIncreaseCameraYaw(object obj) { CameraYaw += 1; }
| |
| private void OnDecreaseCameraYaw(object obj) { CameraYaw -= 1; }
| |
| | |
| private void OnIncreaseCameraRoll(object obj) { CameraRoll += 1; }
| |
| private void OnDecreaseCameraRoll(object obj) { CameraRoll -= 1; }
| |
| | |
| private void OnIncreaseCameraPitch(object obj) { CameraPitch += 1; }
| |
| private void OnDecreaseCameraPitch(object obj) { CameraPitch -= 1; }
| |
| | |
| private void OnIncreaseTargetAlttitude(object obj) { TargetAltitude += 10; }
| |
| private void OnDecreaseTargetAltitide(object obj) { TargetAltitude -= 10; }
| |
| | |
| private void OnIncreaseTargetPosLat(object obj) { TargetPos = new GeoPos(TargetPos.Lat + (1.0 / (60 * 60)), TargetPos.Lon ); }
| |
| private void OnDecreaseTargetPosLat(object obj) { TargetPos = new GeoPos(TargetPos.Lat - (1.0 / (60 * 60)), TargetPos.Lon ); }
| |
| private void OnIncreaseTargetPosLon(object obj) { TargetPos = new GeoPos(TargetPos.Lat, TargetPos.Lon + (1.0 / (60 * 60))); }
| |
| private void OnDecreaseTargetPosLon(object obj) { TargetPos = new GeoPos(TargetPos.Lat, TargetPos.Lon - (1.0 / (60 * 60))); }
| |
| | |
| private bool CanModTargetAltitude(object obj) { return !FollowGround && !Autofollow; }
| |
| private bool CanModTargetPosition(object obj) { return !Autofollow; }
| |
| | |
| private void OnIncreaseTargetDistance(object obj) { TargetDistance += 10; }
| |
| private void OnDecreaseTargetDistance(object obj) { TargetDistance -= 10; }
| |
| | |
| public double CameraYaw
| |
| {
| |
| get
| |
| {
| |
| if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
| |
| return GlobeMapViewModel.Globe3DViewModel.CameraControl.Yaw;
| |
| return 0;
| |
| }
| |
| set
| |
| {
| |
| if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
| |
| {
| |
| GlobeMapViewModel.Globe3DViewModel.CameraControl.Yaw = value;
| |
| }
| |
| | |
| NotifyPropertyChanged(() => CameraYaw);
| |
| }
| |
| }
| |
| | |
| public double CameraRoll
| |
| {
| |
| get
| |
| {
| |
| if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
| |
| return GlobeMapViewModel.Globe3DViewModel.CameraControl.Roll;
| |
| return 0;
| |
| }
| |
| set
| |
| {
| |
| if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
| |
| {
| |
| GlobeMapViewModel.Globe3DViewModel.CameraControl.Roll = value;
| |
| }
| |
| | |
| NotifyPropertyChanged(() => CameraRoll);
| |
| }
| |
| }
| |
| | |
| public double CameraPitch
| |
| {
| |
| get
| |
| {
| |
| if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
| |
| return GlobeMapViewModel.Globe3DViewModel.CameraControl.Pitch;
| |
| return 0;
| |
| }
| |
| set
| |
| {
| |
| if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
| |
| {
| |
| GlobeMapViewModel.Globe3DViewModel.CameraControl.Pitch = value;
| |
| }
| |
| | |
| NotifyPropertyChanged(() => CameraPitch);
| |
| }
| |
| }
| |
| | |
| public string TargetPosText { get { return TargetPos.ToString(); } }
| |
| | |
| public GeoPos TargetPos
| |
| {
| |
| get
| |
| {
| |
| if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
| |
| return GlobeMapViewModel.Globe3DViewModel.CameraControl.TargetPos;
| |
| | |
| return GeoPos.InvalidPos;
| |
| }
| |
| set
| |
| {
| |
| if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
| |
| {
| |
| GlobeMapViewModel.Globe3DViewModel.CameraControl.TargetPos = value;
| |
| }
| |
| | |
| RefreshTargetAndCameraValues();
| |
| }
| |
| }
| |
| | |
| public double TargetAltitude
| |
| { | | { |
| get | | _globeMapViewModel = globeMapViewModel; |
| {
| |
| if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
| |
| return GlobeMapViewModel.Globe3DViewModel.CameraControl.TargetAltitude;
| |
| return 0;
| |
| }
| |
| set
| |
| {
| |
| if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
| |
| {
| |
| GlobeMapViewModel.Globe3DViewModel.CameraControl.TargetAltitude = value;
| |
| }
| |
| | |
| NotifyPropertyChanged(() => TargetAltitude);
| |
| }
| |
| }
| |
|
| |
|
| public bool FollowGround
| | _globeMapViewModel.Globe3DViewModel.CameraControl.AfterPan += OnModeOrSettingsChanged; |
| | _globeMapViewModel.Globe3DViewModel.CameraControl.TargetDistanceChanged += OnModeOrSettingsChanged; |
| | _globeMapViewModel.Globe3DViewModel.CameraControl.TargetPosChanged += OnModeOrSettingsChanged; |
| | _globeMapViewModel.Globe3DViewModel.CameraControl.OrientationChanged += OnModeOrSettingsChanged; |
| | _globeMapViewModel.Entered2DMode += OnModeOrSettingsChanged; |
| | _globeMapViewModel.Entered3DMode += OnModeOrSettingsChanged; |
| | } |
| | private void OnModeOrSettingsChanged(object sender, EventArgs args) |
| { | | { |
| get | | RefreshTargetAndCameraValues(); |
| {
| |
| if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
| |
| return GlobeMapViewModel.Globe3DViewModel.CameraControl.FollowGround;
| |
| return true;
| |
| }
| |
| set
| |
| {
| |
| if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
| |
| {
| |
| GlobeMapViewModel.Globe3DViewModel.CameraControl.FollowGround = value;
| |
| }
| |
| | |
| NotifyPropertyChanged(() => FollowGround);
| |
| }
| |
| }
| |
| | |
| public double TargetDistance
| |
| {
| |
| get
| |
| {
| |
| if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
| |
| return GlobeMapViewModel.Globe3DViewModel.CameraControl.TargetDistance;
| |
| return 0;
| |
| }
| |
| set
| |
| {
| |
| if (GlobeMapViewModel?.Globe3DViewModel?.CameraControl != null)
| |
| {
| |
| GlobeMapViewModel.Globe3DViewModel.CameraControl.TargetDistance = value;
| |
| }
| |
| | |
| NotifyPropertyChanged(() => TargetDistance);
| |
| }
| |
| }
| |
| . . .
| |
| private void RefreshTargetAndCameraValues()
| |
| {
| |
| NotifyPropertyChanged(() => FollowGround);
| |
| NotifyPropertyChanged(() => Autofollow);
| |
| | |
| NotifyPropertyChanged(() => CameraPitch);
| |
| NotifyPropertyChanged(() => CameraRoll);
| |
| NotifyPropertyChanged(() => CameraYaw);
| |
| | |
| NotifyPropertyChanged(() => TargetAltitude);
| |
| NotifyPropertyChanged(() => TargetPos);
| |
| NotifyPropertyChanged(() => TargetPosText);
| |
| NotifyPropertyChanged(() => TargetDistance);
| |
| }
| |
| . . .
| |
| </source>
| |
| | |
| ... and update '''''MapViewModel.Autofollow''''' when auto follow has changed in '''''MainViewModel'''''!
| |
| | |
| <source lang="c#">
| |
| . . .
| |
| public bool IsAutoFollowActive
| |
| {
| |
| . . .
| |
| set
| |
| {
| |
| if (!(value && GlobeMapViewModel.AutoFollow.FollowSelectedItem()))
| |
| GlobeMapViewModel.AutoFollow.TargetItem = null;
| |
| | |
| MapViewModel.Autofollow = IsAutoFollowActive;
| |
| NotifyPropertyChanged(() => IsAutoFollowActive);
| |
| NotifyPropertyChanged(() => AutoFollowItemName);
| |
| }
| |
| } | | } |
| . . . | | . . . |
| </source> | | </source> |
|
| |
|
| === Running with display of 3D settings === | | === Running with displayed 3D settings === |
|
| |
|
| Running the '''''Globe client''''' in 3D mode, altering the 3D parameters will give results like this: | | Running the '''''Globe client''''' in 3D mode, altering the 3D parameters will give results like this: |
Line 502: |
Line 178: |
| | | | | |
| [[File:3D_Set_P15_Y120_af_close.png|450px|Auto follow - closer ]] <br> | | [[File:3D_Set_P15_Y120_af_close.png|450px|Auto follow - closer ]] <br> |
| Auto follow - closer
| | With auto follow, modified target distance (camera closer) |
| | | | | |
| [[File:3D_Set_P15_Y120_R30_af.png|450px| Modified ''roll'' ]]<br> | | [[File:3D_Set_P15_Y120_R30_af.png|450px| Modified ''roll'' ]]<br> |