|
|
|
@ -5,7 +5,9 @@ using System.Windows.Input; |
|
|
|
|
using System.Windows.Media.Media3D; |
|
|
|
|
using HandyControl.Controls; |
|
|
|
|
using HelixToolkit.Wpf.SharpDX; |
|
|
|
|
using Microsoft.Win32; |
|
|
|
|
using SharpDX; |
|
|
|
|
using SparkClient.Model.Helper; |
|
|
|
|
using SparkClient.Views.UserControl.ViewportData.Entity; |
|
|
|
|
using SparkClient.Views.UserControl.ViewportData.Enum; |
|
|
|
|
using SparkClient.Views.UserControl.ViewportData.Helper; |
|
|
|
@ -134,6 +136,46 @@ public partial class Viewport3D |
|
|
|
|
} |
|
|
|
|
camera.LookDirection = new Vector3D(center.X - camera.Position.X, center.Y - camera.Position.Y, center.Z - camera.Position.Z); |
|
|
|
|
} |
|
|
|
|
/// <summary> |
|
|
|
|
/// 顶部按钮 - 功能 |
|
|
|
|
/// </summary> |
|
|
|
|
/// <param name="sender"></param> |
|
|
|
|
/// <param name="e"></param> |
|
|
|
|
/// <exception cref="NotImplementedException"></exception> |
|
|
|
|
private async void BtnFunction_OnClick(object sender, RoutedEventArgs e) |
|
|
|
|
{ |
|
|
|
|
var directionName = ((Button)sender).Name.ToString(); |
|
|
|
|
var directionValue = (int) TbCustomizeRevolve.Value; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (directionName) |
|
|
|
|
{ |
|
|
|
|
case "BtnFcuntion1View": |
|
|
|
|
//测 |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
case "BtnFcuntion2View": |
|
|
|
|
//顶 |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
case "BtnFcuntion3View": |
|
|
|
|
//低 |
|
|
|
|
var center = ViewportManager.ModelBounds.Center; |
|
|
|
|
var maxDimension = ViewportManager.ModelBounds.Size.Length(); |
|
|
|
|
var distance = maxDimension *1.2; // 调整相机到模型的距离,保证视野范围内 |
|
|
|
|
var camera = Viewport3Dx.Camera as HelixToolkit.Wpf.SharpDX.PerspectiveCamera; |
|
|
|
|
camera.Position = new Point3D(center.X, center.Y, center.Z + distance); // 从前面看,Z轴正方向 |
|
|
|
|
camera.UpDirection = new Vector3D(0, -1, 0); |
|
|
|
|
camera.LookDirection = new Vector3D(center.X - camera.Position.X, center.Y - camera.Position.Y, center.Z - camera.Position.Z); |
|
|
|
|
ViewportHelperPro.RotateModel(new Vector3D(0,-1,0)); |
|
|
|
|
await Task.Delay(5000); |
|
|
|
|
ViewportHelperPro.RotateModel(new Vector3D(-1,0,0)); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
|
/// 按钮调整相机方向[底部按钮] |
|
|
|
@ -143,23 +185,56 @@ public partial class Viewport3D |
|
|
|
|
private void BtnDirection_OnClick(object sender, RoutedEventArgs e) |
|
|
|
|
{ |
|
|
|
|
var directionName = ((Button)sender).Name.ToString(); |
|
|
|
|
var directionValue = (int) TbCustomizeRevolve.Value; |
|
|
|
|
var directionValue = (int)TbCustomizeRevolve.Value; // 旋转角度(单位:度) |
|
|
|
|
|
|
|
|
|
// 获取当前相机和模型中心 |
|
|
|
|
var camera = Viewport3Dx.Camera as HelixToolkit.Wpf.SharpDX.PerspectiveCamera; |
|
|
|
|
if (camera == null) return; |
|
|
|
|
|
|
|
|
|
var modelCenter = ViewportManager.CenterVector; // 模型中心 |
|
|
|
|
var currentPosition = camera.Position; |
|
|
|
|
|
|
|
|
|
// 将相机位置转换为极坐标 |
|
|
|
|
var dx = currentPosition.X - modelCenter.X; |
|
|
|
|
var dy = currentPosition.Y - modelCenter.Y; |
|
|
|
|
var dz = currentPosition.Z - modelCenter.Z; |
|
|
|
|
|
|
|
|
|
var radius = Math.Sqrt(dx * dx + dy * dy + dz * dz); // 相机与模型中心的距离 |
|
|
|
|
var azimuth = Math.Atan2(dz, dx) * 180.0 / Math.PI; // 方位角(水平平面上的角度) |
|
|
|
|
var elevation = Math.Atan2(dy, Math.Sqrt(dx * dx + dz * dz)) * 180.0 / Math.PI; // 仰角(垂直方向的角度) |
|
|
|
|
|
|
|
|
|
switch (directionName) |
|
|
|
|
{ |
|
|
|
|
case "BtnTop": |
|
|
|
|
//上 |
|
|
|
|
elevation += directionValue; |
|
|
|
|
break; |
|
|
|
|
case "BtnBottom": |
|
|
|
|
//下 |
|
|
|
|
elevation -= directionValue; |
|
|
|
|
break; |
|
|
|
|
case "BtnLeft": |
|
|
|
|
//左 |
|
|
|
|
azimuth -= directionValue; |
|
|
|
|
break; |
|
|
|
|
case "BtnRight": |
|
|
|
|
//右 |
|
|
|
|
azimuth += directionValue; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
// 限制仰角范围在 -89.9 到 89.9 度,避免超出范围导致位置错误 |
|
|
|
|
elevation = Math.Clamp(elevation, -89.9, 89.9); |
|
|
|
|
azimuth = (azimuth + 360) % 360; // 方位角在 0 到 360 范围内循环 |
|
|
|
|
|
|
|
|
|
// 将极坐标转换回直角坐标 |
|
|
|
|
var newX = modelCenter.X + radius * Math.Cos(elevation * Math.PI / 180.0) * Math.Cos(azimuth * Math.PI / 180.0); |
|
|
|
|
var newY = modelCenter.Y + radius * Math.Sin(elevation * Math.PI / 180.0); |
|
|
|
|
var newZ = modelCenter.Z + radius * Math.Cos(elevation * Math.PI / 180.0) * Math.Sin(azimuth * Math.PI / 180.0); |
|
|
|
|
|
|
|
|
|
// 更新相机位置和视角 |
|
|
|
|
camera.Position = new Point3D(newX, newY, newZ); |
|
|
|
|
camera.LookDirection = new Vector3D(modelCenter.X - newX, modelCenter.Y - newY, modelCenter.Z - newZ); |
|
|
|
|
camera.UpDirection = new Vector3D(0, 1, 0); // 保持 Y 轴为上方向 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -247,11 +322,38 @@ public partial class Viewport3D |
|
|
|
|
break; |
|
|
|
|
case "ViewportRightMenuSaveViewToPNG": |
|
|
|
|
//保存图片 |
|
|
|
|
var saveFileDialog = new SaveFileDialog |
|
|
|
|
{ |
|
|
|
|
Filter = "PNG Files (*.png)|*.png", |
|
|
|
|
Title = MultilingualHelper.getString("ViewportSelectPath"), |
|
|
|
|
DefaultExt = "png" |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
if (saveFileDialog.ShowDialog() != true) |
|
|
|
|
{ |
|
|
|
|
return; // 用户取消 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
string filePath = saveFileDialog.FileName; |
|
|
|
|
|
|
|
|
|
try |
|
|
|
|
{ |
|
|
|
|
ViewportHelperPro.SaveViewportAsImage(Viewport3Dx, filePath); |
|
|
|
|
System.Windows.MessageBox.Show(MultilingualHelper.getString("ViewportSaveSucceed")); |
|
|
|
|
} |
|
|
|
|
catch (Exception ex) |
|
|
|
|
{ |
|
|
|
|
System.Windows.MessageBox.Show($"{MultilingualHelper.getString("ViewportSaveFail")}:{ex.Message}", MultilingualHelper.getString("ViewportSaveFail"), System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
// <sys:String x:Key="ViewportSaveSucceed">保存成功</sys:String> |
|
|
|
|
// <sys:String x:Key="ViewportSaveFail">保存失败</sys:String> |
|
|
|
|
// <sys:String x:Key="ViewportSelectPath">选择路径</sys:String> |
|
|
|
|
|
|
|
|
|
#region 页面隐式交互 |
|
|
|
|
|
|
|
|
|