Refine path viewpoint behavior and config editing
This commit is contained in:
parent
24951d4205
commit
4ec4cf77ee
@ -1,6 +1,7 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using NavisworksTransport.Utils;
|
||||
using System.Numerics;
|
||||
using NavisworksTransport.Core.Config;
|
||||
|
||||
namespace NavisworksTransport.UnitTests.CoordinateSystem
|
||||
{
|
||||
@ -10,32 +11,35 @@ namespace NavisworksTransport.UnitTests.CoordinateSystem
|
||||
[TestMethod]
|
||||
public void ResolvePathViewpointProfile_ShouldReturnExpectedDefaults()
|
||||
{
|
||||
var config = ConfigManager.Instance.Current.PathEditing;
|
||||
var ground = ViewpointHelper.ResolvePathViewpointProfile(ViewpointHelper.ViewpointStrategy.PathGroundSelection);
|
||||
var hoisting = ViewpointHelper.ResolvePathViewpointProfile(ViewpointHelper.ViewpointStrategy.PathHoistingSelection);
|
||||
var rail = ViewpointHelper.ResolvePathViewpointProfile(ViewpointHelper.ViewpointStrategy.PathRailSelection);
|
||||
|
||||
Assert.AreEqual(1.0, ground.DistanceScale, 1e-9);
|
||||
Assert.AreEqual(12.0, ground.MinDistanceMeters, 1e-9);
|
||||
Assert.AreEqual(12.0, ground.CameraDistanceMeters, 1e-9);
|
||||
Assert.AreEqual(90.0, ground.ElevationDegrees, 1e-9);
|
||||
|
||||
Assert.AreEqual(1.2, hoisting.DistanceScale, 1e-9);
|
||||
Assert.AreEqual(8.0, hoisting.MinDistanceMeters, 1e-9);
|
||||
Assert.AreEqual(22.0, hoisting.ElevationDegrees, 1e-9);
|
||||
Assert.AreEqual(config.HoistingViewDistanceMeters, hoisting.CameraDistanceMeters, 1e-9);
|
||||
Assert.AreEqual(config.HoistingViewElevationDegrees, hoisting.ElevationDegrees, 1e-9);
|
||||
Assert.AreEqual(ViewpointHelper.PathCameraHorizontalMode.Side, hoisting.HorizontalMode);
|
||||
|
||||
Assert.AreEqual(0.75, rail.DistanceScale, 1e-9);
|
||||
Assert.AreEqual(4.5, rail.MinDistanceMeters, 1e-9);
|
||||
Assert.AreEqual(12.0, rail.ElevationDegrees, 1e-9);
|
||||
Assert.AreEqual(config.RailViewDistanceMeters, rail.CameraDistanceMeters, 1e-9);
|
||||
Assert.AreEqual(config.RailViewElevationDegrees, rail.ElevationDegrees, 1e-9);
|
||||
Assert.AreEqual(ViewpointHelper.PathCameraHorizontalMode.Side, rail.HorizontalMode);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ResolveCameraOffsetDirection_Hoisting_ShouldLookFromBehindAndAbove()
|
||||
public void ResolveCameraOffsetDirection_Hoisting_ShouldLookFromSideAndSlightlyAbove()
|
||||
{
|
||||
Vector3 hostUp = Vector3.UnitZ;
|
||||
Vector3 forward = Vector3.UnitX;
|
||||
var profile = ViewpointHelper.ResolvePathViewpointProfile(ViewpointHelper.ViewpointStrategy.PathHoistingSelection);
|
||||
|
||||
Vector3 offset = ViewpointHelper.ResolveCameraOffsetDirection(PathType.Hoisting, hostUp, forward);
|
||||
Vector3 offset = ViewpointHelper.ResolveCameraOffsetDirection(profile, hostUp, forward);
|
||||
|
||||
Assert.IsTrue(offset.X < -0.8f);
|
||||
Assert.IsTrue(offset.Z > 0.3f);
|
||||
Assert.AreEqual(0.0f, offset.X, 1e-5f);
|
||||
Assert.IsTrue(offset.Y > 0.0f);
|
||||
Assert.IsTrue(offset.Z > 0.0f);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@ -43,12 +47,13 @@ namespace NavisworksTransport.UnitTests.CoordinateSystem
|
||||
{
|
||||
Vector3 hostUp = Vector3.UnitZ;
|
||||
Vector3 forward = Vector3.UnitX;
|
||||
var profile = ViewpointHelper.ResolvePathViewpointProfile(ViewpointHelper.ViewpointStrategy.PathRailSelection);
|
||||
|
||||
Vector3 offset = ViewpointHelper.ResolveCameraOffsetDirection(PathType.Rail, hostUp, forward);
|
||||
Vector3 offset = ViewpointHelper.ResolveCameraOffsetDirection(profile, hostUp, forward);
|
||||
|
||||
Assert.AreEqual(0.0f, offset.X, 1e-5f);
|
||||
Assert.IsTrue(offset.Y > 0.9f);
|
||||
Assert.IsTrue(offset.Z > 0.15f);
|
||||
Assert.IsTrue(offset.Y > 0.0f);
|
||||
Assert.IsTrue(offset.Z > 0.0f);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
||||
@ -26,6 +26,19 @@ default_path_turn_radius = 2.5
|
||||
# 圆弧采样步长(米)- 推荐值:0.02-0.1
|
||||
arc_sampling_step = 0.05
|
||||
|
||||
# 吊装路径自动视角距离(米)
|
||||
# 默认为近距离低侧视
|
||||
hoisting_view_distance_meters = 6.0
|
||||
|
||||
# 吊装路径自动视角仰角(度)
|
||||
hoisting_view_elevation_degrees = 30.0
|
||||
|
||||
# Rail 路径自动视角距离(米)
|
||||
rail_view_distance_meters = 6.0
|
||||
|
||||
# Rail 路径自动视角仰角(度)
|
||||
rail_view_elevation_degrees = 30.0
|
||||
|
||||
[visualization]
|
||||
# 地图边距比例(0-1之间)
|
||||
margin_ratio = 0.1
|
||||
|
||||
@ -394,6 +394,10 @@ namespace NavisworksTransport.Core.Config
|
||||
config.PathEditing.SafetyMarginMeters = GetDoubleValueWithDefault(pathEdit, "safety_margin_meters", 0.1, missingItems);
|
||||
config.PathEditing.DefaultPathTurnRadiusMeters = GetDoubleValueWithDefault(pathEdit, "default_path_turn_radius", 2.5, missingItems);
|
||||
config.PathEditing.ArcSamplingStepMeters = GetDoubleValueWithDefault(pathEdit, "arc_sampling_step", 0.05, missingItems);
|
||||
config.PathEditing.HoistingViewDistanceMeters = GetDoubleValueWithDefault(pathEdit, "hoisting_view_distance_meters", 6.0, missingItems);
|
||||
config.PathEditing.HoistingViewElevationDegrees = GetDoubleValueWithDefault(pathEdit, "hoisting_view_elevation_degrees", 30.0, missingItems);
|
||||
config.PathEditing.RailViewDistanceMeters = GetDoubleValueWithDefault(pathEdit, "rail_view_distance_meters", 6.0, missingItems);
|
||||
config.PathEditing.RailViewElevationDegrees = GetDoubleValueWithDefault(pathEdit, "rail_view_elevation_degrees", 30.0, missingItems);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -119,6 +119,26 @@ namespace NavisworksTransport.Core.Config
|
||||
/// </summary>
|
||||
public double ArcSamplingStepMeters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 吊装路径自动视角距离(米)
|
||||
/// </summary>
|
||||
public double HoistingViewDistanceMeters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 吊装路径自动视角仰角(度)
|
||||
/// </summary>
|
||||
public double HoistingViewElevationDegrees { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Rail 路径自动视角距离(米)
|
||||
/// </summary>
|
||||
public double RailViewDistanceMeters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Rail 路径自动视角仰角(度)
|
||||
/// </summary>
|
||||
public double RailViewElevationDegrees { get; set; }
|
||||
|
||||
// === 模型单位接口(用于内部计算) ===
|
||||
|
||||
/// <summary>
|
||||
@ -160,6 +180,16 @@ namespace NavisworksTransport.Core.Config
|
||||
/// 圆弧采样步长(模型单位)
|
||||
/// </summary>
|
||||
public double ArcSamplingStep => ArcSamplingStepMeters * Utils.UnitsConverter.GetMetersToUnitsConversionFactor();
|
||||
|
||||
/// <summary>
|
||||
/// 吊装路径自动视角距离(模型单位)
|
||||
/// </summary>
|
||||
public double HoistingViewDistance => HoistingViewDistanceMeters * Utils.UnitsConverter.GetMetersToUnitsConversionFactor();
|
||||
|
||||
/// <summary>
|
||||
/// Rail 路径自动视角距离(模型单位)
|
||||
/// </summary>
|
||||
public double RailViewDistance => RailViewDistanceMeters * Utils.UnitsConverter.GetMetersToUnitsConversionFactor();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -240,6 +240,12 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
if (IsClipBoxEnabled)
|
||||
{
|
||||
if (_pathPlanningManager.PathEditState == PathEditState.Creating)
|
||||
{
|
||||
LogManager.Info("[剖面盒] 当前处于新建路径流程,跳过自动跟随");
|
||||
return;
|
||||
}
|
||||
|
||||
LogManager.Info("[剖面盒] 路径已切换,重新设置剖面盒聚焦到新路径");
|
||||
EnableClipBoxForCurrentRoute();
|
||||
}
|
||||
@ -418,4 +424,4 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Drawing;
|
||||
@ -385,8 +385,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
_pathPlanningManager.SetCurrentRoute(coreRoute);
|
||||
LogManager.Info($"UI路径切换:已同步PathPlanningManager的CurrentRoute到 {value.Name}");
|
||||
|
||||
// 新建路径流程里禁止自动改视角,避免打断建路径操作。
|
||||
if (_pathPlanningManager.PathEditState == PathEditState.Creating)
|
||||
{
|
||||
LogManager.Info($"UI路径切换:当前处于新建路径流程,跳过自动视角调整: {value.Name}");
|
||||
}
|
||||
// 自动调整视角到路径中心(只有路径有点时才调整)
|
||||
if (coreRoute.Points.Count > 0)
|
||||
else if (coreRoute.Points.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@ -832,14 +832,13 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
{
|
||||
try
|
||||
{
|
||||
// 使用单例模式显示配置编辑器(非模态,避免独占焦点)
|
||||
// 不传递 owner,让 ShowEditor 自己通过 DialogHelper 处理
|
||||
// 使用模态配置编辑器,确保键盘输入不会被 Navisworks 主窗口截获
|
||||
var dialog = NavisworksTransport.UI.WPF.Views.ConfigEditorDialog.ShowEditor();
|
||||
|
||||
if (dialog != null)
|
||||
{
|
||||
UpdateMainStatus("配置编辑器已打开");
|
||||
LogManager.Info("配置编辑器:已打开(非模态)");
|
||||
UpdateMainStatus("配置编辑器已关闭");
|
||||
LogManager.Info("配置编辑器:已打开并关闭(模态)");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -2,13 +2,15 @@ using System;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Threading;
|
||||
using System.Diagnostics;
|
||||
using NavisworksTransport.Core.Config;
|
||||
|
||||
namespace NavisworksTransport.UI.WPF.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置编辑器对话框 - 非模态窗口,避免独占焦点
|
||||
/// 配置编辑器对话框
|
||||
/// </summary>
|
||||
public partial class ConfigEditorDialog : Window
|
||||
{
|
||||
@ -297,7 +299,7 @@ namespace NavisworksTransport.UI.WPF.Views
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 窗口加载事件 - 处理激活逻辑避免独占焦点
|
||||
/// 窗口初始化后,确保获得稳定的键盘焦点
|
||||
/// </summary>
|
||||
protected override void OnSourceInitialized(EventArgs e)
|
||||
{
|
||||
@ -305,11 +307,10 @@ namespace NavisworksTransport.UI.WPF.Views
|
||||
|
||||
try
|
||||
{
|
||||
// 激活并前置窗口,但不独占焦点
|
||||
// 先置顶再取消置顶,让窗口前置但不系统级置顶
|
||||
this.Activate();
|
||||
this.Topmost = true;
|
||||
this.Topmost = false;
|
||||
Dispatcher.BeginInvoke(new Action(FocusEditorTextBox), DispatcherPriority.Input);
|
||||
|
||||
LogManager.Debug("配置编辑器对话框已激活并前置显示");
|
||||
}
|
||||
@ -319,6 +320,15 @@ namespace NavisworksTransport.UI.WPF.Views
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 窗口内容渲染完成后再次请求焦点,避免宿主窗口抢占键盘
|
||||
/// </summary>
|
||||
protected override void OnContentRendered(EventArgs e)
|
||||
{
|
||||
base.OnContentRendered(e);
|
||||
Dispatcher.BeginInvoke(new Action(FocusEditorTextBox), DispatcherPriority.Input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激活并显示已存在的窗口
|
||||
/// </summary>
|
||||
@ -332,10 +342,10 @@ namespace NavisworksTransport.UI.WPF.Views
|
||||
this.WindowState = WindowState.Normal;
|
||||
}
|
||||
|
||||
// 激活并前置窗口(先置顶再取消置顶,避免独占焦点)
|
||||
this.Activate();
|
||||
this.Topmost = true;
|
||||
this.Topmost = false;
|
||||
FocusEditorTextBox();
|
||||
|
||||
LogManager.Info("配置编辑器对话框已激活并前置显示");
|
||||
}
|
||||
@ -345,10 +355,29 @@ namespace NavisworksTransport.UI.WPF.Views
|
||||
}
|
||||
}
|
||||
|
||||
private void FocusEditorTextBox()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ConfigContentTextBox == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigContentTextBox.Focus();
|
||||
Keyboard.Focus(ConfigContentTextBox);
|
||||
ConfigContentTextBox.CaretIndex = ConfigContentTextBox.Text?.Length ?? 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Debug($"配置编辑器焦点设置失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
#region 静态工厂方法
|
||||
|
||||
/// <summary>
|
||||
/// 创建并显示配置编辑器对话框(单例模式,非模态)
|
||||
/// 创建并显示配置编辑器对话框(单例模式,模态)
|
||||
/// </summary>
|
||||
/// <returns>对话框实例</returns>
|
||||
public static ConfigEditorDialog ShowEditor()
|
||||
@ -385,16 +414,19 @@ namespace NavisworksTransport.UI.WPF.Views
|
||||
// 创建新的对话框实例
|
||||
var dialog = new ConfigEditorDialog();
|
||||
|
||||
// 使用 DialogHelper 安全地设置 owner
|
||||
NavisworksTransport.Utils.DialogHelper.SetOwnerSafely(dialog);
|
||||
// 优先设置 WPF Owner,失败时回退到 Navisworks 主窗口句柄
|
||||
if (!NavisworksTransport.Utils.DialogHelper.SetOwnerSafely(dialog))
|
||||
{
|
||||
NavisworksTransport.Utils.DialogHelper.SetWin32Owner(dialog);
|
||||
}
|
||||
|
||||
// 设置为当前实例
|
||||
_currentInstance = dialog;
|
||||
|
||||
// 使用 Show() 非模态显示,避免独占焦点
|
||||
dialog.Show();
|
||||
// 使用 ShowDialog() 确保键盘输入不会被宿主窗口吃掉
|
||||
dialog.ShowDialog();
|
||||
|
||||
LogManager.Info("新的配置编辑器对话框已显示(非模态)");
|
||||
LogManager.Info("新的配置编辑器对话框已显示(模态)");
|
||||
return dialog;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Autodesk.Navisworks.Api;
|
||||
using NavisworksTransport.Core.Config;
|
||||
using NavisworksTransport.Utils.CoordinateSystem;
|
||||
|
||||
namespace NavisworksTransport.Utils
|
||||
@ -22,18 +23,25 @@ namespace NavisworksTransport.Utils
|
||||
CollisionCloseUp
|
||||
}
|
||||
|
||||
internal enum PathCameraHorizontalMode
|
||||
{
|
||||
Top,
|
||||
Side,
|
||||
Rear
|
||||
}
|
||||
|
||||
internal struct PathViewpointProfile
|
||||
{
|
||||
public PathViewpointProfile(double distanceScale, double minDistanceMeters, double elevationDegrees)
|
||||
public PathViewpointProfile(double cameraDistanceMeters, double elevationDegrees, PathCameraHorizontalMode horizontalMode)
|
||||
{
|
||||
DistanceScale = distanceScale;
|
||||
MinDistanceMeters = minDistanceMeters;
|
||||
CameraDistanceMeters = cameraDistanceMeters;
|
||||
ElevationDegrees = elevationDegrees;
|
||||
HorizontalMode = horizontalMode;
|
||||
}
|
||||
|
||||
public double DistanceScale { get; }
|
||||
public double MinDistanceMeters { get; }
|
||||
public double CameraDistanceMeters { get; }
|
||||
public double ElevationDegrees { get; }
|
||||
public PathCameraHorizontalMode HorizontalMode { get; }
|
||||
}
|
||||
|
||||
internal struct FocusViewpointProfile
|
||||
@ -146,8 +154,7 @@ namespace NavisworksTransport.Utils
|
||||
|
||||
Point3D startPoint = path.Points[0].Position;
|
||||
Point3D endPoint = path.Points[path.Points.Count - 1].Position;
|
||||
BoundingBox3D focusBoundingBox = CreateBoundingBoxFromPoints(startPoint, endPoint);
|
||||
BoundingBox3D viewBoundingBox = CalculatePathBoundingBox(path);
|
||||
BoundingBox3D focusBoundingBox = ResolveDirectionalFocusBoundingBox(path);
|
||||
Point3D focusCenter = GetBoundingBoxCenter(focusBoundingBox);
|
||||
|
||||
var adapter = CoordinateSystemManager.Instance.CreateHostAdapter();
|
||||
@ -158,31 +165,40 @@ namespace NavisworksTransport.Utils
|
||||
(float)(endPoint.Z - startPoint.Z));
|
||||
Vector3 fallbackForward = ToVector3(ProjectVectorOntoPlane(doc.FrontRightTopViewVector, adapter.HostUpVector));
|
||||
Vector3 horizontalForward = ResolveHorizontalPathForward(rawPathDirection, hostUp, fallbackForward);
|
||||
Vector3 cameraOffsetDirection = ResolveCameraOffsetDirection(path.PathType, hostUp, horizontalForward);
|
||||
|
||||
double maxDimensionModel = GetMaxDimension(viewBoundingBox);
|
||||
double minDistanceModel = UnitsConverter.ConvertFromMeters(profile.MinDistanceMeters);
|
||||
double cameraDistance = Math.Max(maxDimensionModel * profile.DistanceScale, minDistanceModel);
|
||||
Vector3 cameraOffsetDirection = ResolveCameraOffsetDirection(profile, hostUp, horizontalForward);
|
||||
double cameraDistance = UnitsConverter.ConvertFromMeters(profile.CameraDistanceMeters);
|
||||
Point3D cameraPosition = new Point3D(
|
||||
focusCenter.X + cameraOffsetDirection.X * (float)cameraDistance,
|
||||
focusCenter.Y + cameraOffsetDirection.Y * (float)cameraDistance,
|
||||
focusCenter.Z + cameraOffsetDirection.Z * (float)cameraDistance);
|
||||
|
||||
double expansionMargin = Math.Max(
|
||||
maxDimensionModel * (VIEW_BOUNDING_BOX_EXPANSION_FACTOR - 1.0) / 2.0,
|
||||
UnitsConverter.ConvertFromMeters(2.0));
|
||||
|
||||
ApplyViewpointWithZoomBox(
|
||||
ApplyViewpoint(
|
||||
cameraPosition,
|
||||
focusCenter,
|
||||
new Vector3D(hostUp.X, hostUp.Y, hostUp.Z),
|
||||
viewBoundingBox,
|
||||
expansionMargin);
|
||||
useAlignDirection: true);
|
||||
|
||||
LogManager.Info(
|
||||
$"视角已调整完成: 类型={path.PathType}, 焦点=({focusCenter.X:F2},{focusCenter.Y:F2},{focusCenter.Z:F2}), " +
|
||||
$"相机=({cameraPosition.X:F2},{cameraPosition.Y:F2},{cameraPosition.Z:F2}), " +
|
||||
$"距离={UnitsConverter.ConvertToMeters(cameraDistance):F2}米, elevation={profile.ElevationDegrees:F1}°");
|
||||
$"距离={UnitsConverter.ConvertToMeters(cameraDistance):F2}米, elevation={profile.ElevationDegrees:F1}°, 模式={profile.HorizontalMode}");
|
||||
}
|
||||
|
||||
internal static BoundingBox3D ResolveDirectionalFocusBoundingBox(PathRoute path)
|
||||
{
|
||||
if (path == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(path));
|
||||
}
|
||||
|
||||
if (path.Points == null || path.Points.Count == 0)
|
||||
{
|
||||
throw new ArgumentException("路径为空或没有路径点", nameof(path));
|
||||
}
|
||||
|
||||
// 侧视路径应聚焦整条路径包络,而不是只看首尾点。
|
||||
// 对吊装路径尤其重要:首尾点常在地面,若只取首尾中心,高处主路径会被挤到画面上半部。
|
||||
return CalculatePathBoundingBox(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -296,15 +312,25 @@ namespace NavisworksTransport.Utils
|
||||
|
||||
internal static PathViewpointProfile ResolvePathViewpointProfile(ViewpointStrategy strategy)
|
||||
{
|
||||
PathEditingConfig config = ConfigManager.Instance.Current?.PathEditing ?? new PathEditingConfig();
|
||||
switch (strategy)
|
||||
{
|
||||
case ViewpointStrategy.PathHoistingSelection:
|
||||
return new PathViewpointProfile(distanceScale: 1.2, minDistanceMeters: 8.0, elevationDegrees: 22.0);
|
||||
return new PathViewpointProfile(
|
||||
cameraDistanceMeters: config.HoistingViewDistanceMeters > 0 ? config.HoistingViewDistanceMeters : 6.0,
|
||||
elevationDegrees: config.HoistingViewElevationDegrees > 0 ? config.HoistingViewElevationDegrees : 30.0,
|
||||
horizontalMode: PathCameraHorizontalMode.Side);
|
||||
case ViewpointStrategy.PathRailSelection:
|
||||
return new PathViewpointProfile(distanceScale: 0.75, minDistanceMeters: 4.5, elevationDegrees: 12.0);
|
||||
return new PathViewpointProfile(
|
||||
cameraDistanceMeters: config.RailViewDistanceMeters > 0 ? config.RailViewDistanceMeters : 6.0,
|
||||
elevationDegrees: config.RailViewElevationDegrees > 0 ? config.RailViewElevationDegrees : 30.0,
|
||||
horizontalMode: PathCameraHorizontalMode.Side);
|
||||
case ViewpointStrategy.PathGroundSelection:
|
||||
default:
|
||||
return new PathViewpointProfile(distanceScale: 1.0, minDistanceMeters: 12.0, elevationDegrees: 90.0);
|
||||
return new PathViewpointProfile(
|
||||
cameraDistanceMeters: 12.0,
|
||||
elevationDegrees: 90.0,
|
||||
horizontalMode: PathCameraHorizontalMode.Top);
|
||||
}
|
||||
}
|
||||
|
||||
@ -340,27 +366,25 @@ namespace NavisworksTransport.Utils
|
||||
return Vector3.Normalize(ProjectOntoPlane(canonicalFallback, hostUp));
|
||||
}
|
||||
|
||||
internal static Vector3 ResolveCameraOffsetDirection(PathType pathType, Vector3 hostUp, Vector3 horizontalForward)
|
||||
internal static Vector3 ResolveCameraOffsetDirection(PathViewpointProfile profile, Vector3 hostUp, Vector3 horizontalForward)
|
||||
{
|
||||
PathViewpointProfile profile = ResolvePathViewpointProfile(pathType);
|
||||
float elevationRadians = (float)(profile.ElevationDegrees * Math.PI / 180.0);
|
||||
float horizontalWeight = (float)Math.Cos(elevationRadians);
|
||||
float verticalWeight = (float)Math.Sin(elevationRadians);
|
||||
|
||||
Vector3 horizontalDirection;
|
||||
switch (pathType)
|
||||
switch (profile.HorizontalMode)
|
||||
{
|
||||
case PathType.Hoisting:
|
||||
case PathCameraHorizontalMode.Rear:
|
||||
horizontalDirection = -horizontalForward;
|
||||
break;
|
||||
case PathType.Rail:
|
||||
case PathCameraHorizontalMode.Side:
|
||||
horizontalDirection = Vector3.Cross(hostUp, horizontalForward);
|
||||
if (horizontalDirection.LengthSquared() <= 1e-8f)
|
||||
{
|
||||
horizontalDirection = -horizontalForward;
|
||||
}
|
||||
break;
|
||||
case PathType.Ground:
|
||||
default:
|
||||
horizontalDirection = hostUp;
|
||||
break;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user