From 4ec4cf77eed7639a6398241e61bdec5992be69db Mon Sep 17 00:00:00 2001
From: tian <11429339@qq.com>
Date: Thu, 2 Apr 2026 22:14:26 +0800
Subject: [PATCH] Refine path viewpoint behavior and config editing
---
.../CoordinateSystem/ViewpointHelperTests.cs | 35 ++++----
resources/default_config.toml | 13 +++
src/Core/Config/ConfigManager.cs | 4 +
src/Core/Config/SystemConfig.cs | 30 +++++++
.../ViewModels/LogisticsControlViewModel.cs | 8 +-
src/UI/WPF/ViewModels/PathEditingViewModel.cs | 9 +-
.../ViewModels/SystemManagementViewModel.cs | 7 +-
src/UI/WPF/Views/ConfigEditorDialog.xaml.cs | 54 +++++++++---
src/Utils/ViewpointHelper.cs | 82 ++++++++++++-------
9 files changed, 180 insertions(+), 62 deletions(-)
diff --git a/UnitTests/CoordinateSystem/ViewpointHelperTests.cs b/UnitTests/CoordinateSystem/ViewpointHelperTests.cs
index 90dad79..168e72a 100644
--- a/UnitTests/CoordinateSystem/ViewpointHelperTests.cs
+++ b/UnitTests/CoordinateSystem/ViewpointHelperTests.cs
@@ -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]
diff --git a/resources/default_config.toml b/resources/default_config.toml
index da3e2b4..8825899 100644
--- a/resources/default_config.toml
+++ b/resources/default_config.toml
@@ -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
diff --git a/src/Core/Config/ConfigManager.cs b/src/Core/Config/ConfigManager.cs
index a89a216..5b04d96 100644
--- a/src/Core/Config/ConfigManager.cs
+++ b/src/Core/Config/ConfigManager.cs
@@ -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);
}
}
diff --git a/src/Core/Config/SystemConfig.cs b/src/Core/Config/SystemConfig.cs
index 024d340..1c424f7 100644
--- a/src/Core/Config/SystemConfig.cs
+++ b/src/Core/Config/SystemConfig.cs
@@ -119,6 +119,26 @@ namespace NavisworksTransport.Core.Config
///
public double ArcSamplingStepMeters { get; set; }
+ ///
+ /// 吊装路径自动视角距离(米)
+ ///
+ public double HoistingViewDistanceMeters { get; set; }
+
+ ///
+ /// 吊装路径自动视角仰角(度)
+ ///
+ public double HoistingViewElevationDegrees { get; set; }
+
+ ///
+ /// Rail 路径自动视角距离(米)
+ ///
+ public double RailViewDistanceMeters { get; set; }
+
+ ///
+ /// Rail 路径自动视角仰角(度)
+ ///
+ public double RailViewElevationDegrees { get; set; }
+
// === 模型单位接口(用于内部计算) ===
///
@@ -160,6 +180,16 @@ namespace NavisworksTransport.Core.Config
/// 圆弧采样步长(模型单位)
///
public double ArcSamplingStep => ArcSamplingStepMeters * Utils.UnitsConverter.GetMetersToUnitsConversionFactor();
+
+ ///
+ /// 吊装路径自动视角距离(模型单位)
+ ///
+ public double HoistingViewDistance => HoistingViewDistanceMeters * Utils.UnitsConverter.GetMetersToUnitsConversionFactor();
+
+ ///
+ /// Rail 路径自动视角距离(模型单位)
+ ///
+ public double RailViewDistance => RailViewDistanceMeters * Utils.UnitsConverter.GetMetersToUnitsConversionFactor();
}
///
diff --git a/src/UI/WPF/ViewModels/LogisticsControlViewModel.cs b/src/UI/WPF/ViewModels/LogisticsControlViewModel.cs
index bfe3c2e..17b7089 100644
--- a/src/UI/WPF/ViewModels/LogisticsControlViewModel.cs
+++ b/src/UI/WPF/ViewModels/LogisticsControlViewModel.cs
@@ -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
}
-}
\ No newline at end of file
+}
diff --git a/src/UI/WPF/ViewModels/PathEditingViewModel.cs b/src/UI/WPF/ViewModels/PathEditingViewModel.cs
index 6e01e40..67fb46d 100644
--- a/src/UI/WPF/ViewModels/PathEditingViewModel.cs
+++ b/src/UI/WPF/ViewModels/PathEditingViewModel.cs
@@ -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
{
diff --git a/src/UI/WPF/ViewModels/SystemManagementViewModel.cs b/src/UI/WPF/ViewModels/SystemManagementViewModel.cs
index 4468645..4048f76 100644
--- a/src/UI/WPF/ViewModels/SystemManagementViewModel.cs
+++ b/src/UI/WPF/ViewModels/SystemManagementViewModel.cs
@@ -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
{
diff --git a/src/UI/WPF/Views/ConfigEditorDialog.xaml.cs b/src/UI/WPF/Views/ConfigEditorDialog.xaml.cs
index f8b3638..73e6d56 100644
--- a/src/UI/WPF/Views/ConfigEditorDialog.xaml.cs
+++ b/src/UI/WPF/Views/ConfigEditorDialog.xaml.cs
@@ -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
{
///
- /// 配置编辑器对话框 - 非模态窗口,避免独占焦点
+ /// 配置编辑器对话框
///
public partial class ConfigEditorDialog : Window
{
@@ -297,7 +299,7 @@ namespace NavisworksTransport.UI.WPF.Views
}
///
- /// 窗口加载事件 - 处理激活逻辑避免独占焦点
+ /// 窗口初始化后,确保获得稳定的键盘焦点
///
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
}
}
+ ///
+ /// 窗口内容渲染完成后再次请求焦点,避免宿主窗口抢占键盘
+ ///
+ protected override void OnContentRendered(EventArgs e)
+ {
+ base.OnContentRendered(e);
+ Dispatcher.BeginInvoke(new Action(FocusEditorTextBox), DispatcherPriority.Input);
+ }
+
///
/// 激活并显示已存在的窗口
///
@@ -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 静态工厂方法
///
- /// 创建并显示配置编辑器对话框(单例模式,非模态)
+ /// 创建并显示配置编辑器对话框(单例模式,模态)
///
/// 对话框实例
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;
}
}
diff --git a/src/Utils/ViewpointHelper.cs b/src/Utils/ViewpointHelper.cs
index 08aea47..6b4c0b0 100644
--- a/src/Utils/ViewpointHelper.cs
+++ b/src/Utils/ViewpointHelper.cs
@@ -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);
}
///
@@ -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;