添加预计算检测间隙扩大率配置,优化动画参数初始化和碰撞检测逻辑

This commit is contained in:
tian 2026-01-09 14:47:41 +08:00
parent 1a2312f3f6
commit 98c23b986e
11 changed files with 92 additions and 67 deletions

View File

@ -40,6 +40,10 @@ duration_seconds = 10.0
# 检测间隙(米)
detection_gap_meters = 0.05
# 预计算检测间隙扩大率(>0表示扩大的倍数
# 例如1.0表示检测间隙增大1倍即使用2倍的检测间隙进行预计算
precomputed_detection_gap_expansion_rate = 1.0
[logistics]
# 可通行性默认值true
traversable = true

View File

@ -8,6 +8,7 @@
2. [x] BUG碰撞结果高亮应该显示clashdetective检测的结果
3. [x] 优化对clashdetective的检测结果进行向上合并找到集合对象。
4. [x] (功能)碰撞检测结果保存数据库,列表展示
5. [x] (优化)系统设置中增加预计算检测间隙扩大率,扩大预计算碰撞检测范围。
### [2025/12/25]

View File

@ -82,10 +82,10 @@ namespace NavisworksTransport.Commands
public int UniqueCollidedObjectsCount { get; set; }
// 新增:动画参数
public string PathName { get; set; } = "未知路径";
public int FrameRate { get; set; } = 30;
public double Duration { get; set; } = 10.0;
public double DetectionGap { get; set; } = 0.05;
public string PathName { get; set; }
public int FrameRate { get; set; }
public double Duration { get; set; }
public double DetectionGap { get; set; }
}
/// <summary>

View File

@ -115,7 +115,7 @@ namespace NavisworksTransport.Core.Animation
private PathRoute _route = null; // 路径引用
// === 碰撞测试优化 ===
private string _currentAnimationHash = ""; // 当前动画配置的哈希值
private string _currentAnimationHash; // 当前动画配置的哈希值
// === 动画播放机制 ===
private double _frameInterval; // 帧间隔(毫秒)
@ -123,16 +123,15 @@ namespace NavisworksTransport.Core.Animation
private DispatcherTimer _animationTimer; // 备用DispatcherTimer定时器
// === 动画参数 ===
private double _animationDuration = 10.0; // 动画总时长(秒)
private double _animationDuration; // 动画总时长(秒)
private DateTime _animationStartTime;
private int _animationFrameRate = 30; // 动画帧率默认30FPS
private int _animationFrameCount = 0; // 动画帧计数
private double _collisionDetectionAccuracy = 0.1; // 检测精度(内部存储:模型单位/帧)
private double _movementSpeed = 1.0; // 运动速度(仅用于显示,单位:米/秒)
private double _detectionGap = 0.05; // 检测间隙(内部存储:模型单位)
private string _pathName = "未知路径"; // 路径名称
private string _currentRouteId = null; // 当前路由ID
private string _animatedObjectName = null; // 动画对象名称
private int _animationFrameRate; // 动画帧率默认30FPS
private double _collisionDetectionAccuracy; // 检测精度(内部存储:模型单位/帧)
private double _movementSpeed; // 运动速度(仅用于显示,单位:米/秒)
private double _detectionGap; // 检测间隙(内部存储:模型单位)
private double _precomputedDetectionGap; // 预计算时使用的扩大检测间隙(内部存储:模型单位)
private string _pathName; // 路径名称
private string _currentRouteId; // 当前路由ID
// === 双向播放和步进控制 ===
private int _playbackDirection = 1; // 播放方向1=正向,-1=反向
@ -184,6 +183,18 @@ namespace NavisworksTransport.Core.Animation
_animationFrames = new List<AnimationFrame>();
_allCollisionResults = new List<CollisionResult>();
// 🔥 从配置初始化动画参数
var config = ConfigManager.Instance.Current;
_animationFrameRate = config.Animation.FrameRate;
_animationDuration = config.Animation.DurationSeconds;
var detectionGapMeters = config.Animation.DetectionGapMeters;
_detectionGap = UnitsConverter.ConvertFromMeters(detectionGapMeters);
var expansionRate = config.Animation.PrecomputedDetectionGapExpansionRate;
var expandedGapInMeters = detectionGapMeters * (1.0 + expansionRate);
_precomputedDetectionGap = UnitsConverter.ConvertFromMeters(expandedGapInMeters);
// 初始化动画模式
_frameInterval = 1000.0 / _animationFrameRate; // 计算帧间隔
_lastFrameTime = DateTime.MinValue;
@ -506,7 +517,7 @@ namespace NavisworksTransport.Core.Animation
// 原因:车辆在通道上水平移动,主要检测侧面碰撞
double maxHorizontalDimension = Math.Max(boundingBoxSize.X, boundingBoxSize.Y);
searchRadiusInModelUnits = maxHorizontalDimension + _detectionGap;
searchRadiusInModelUnits = maxHorizontalDimension + _precomputedDetectionGap;
LogManager.Info($"空间查询半径: {searchRadiusInModelUnits:F2} 模型单位 (基于最大水平尺寸: {maxHorizontalDimension:F2})");
}
@ -602,7 +613,7 @@ namespace NavisworksTransport.Core.Animation
// 使用改进的精确距离检测方法(先检查相交,再计算精确距离)
double preciseDistance = BoundingBoxGeometryUtils.CalculatePreciseDistance(virtualBoundingBox, colliderBox);
bool intersects = preciseDistance <= _detectionGap;
bool intersects = preciseDistance <= _precomputedDetectionGap;
if (intersects)
{
@ -911,7 +922,6 @@ namespace NavisworksTransport.Core.Animation
// 初始化动画状态
_animationStartTime = DateTime.Now;
_animationFrameCount = 0; // 重置帧计数
_currentFrameIndex = 0; // 重置当前帧索引,确保从第一帧开始
_pausedProgress = 0.0; // 重置暂停进度
@ -2132,6 +2142,14 @@ namespace NavisworksTransport.Core.Animation
{
_detectionGap = roundedGapInModelUnits;
LogManager.Info($"检测间隙设置为: {gapInMeters:F2}米");
// 计算预计算时使用的扩大检测间隙
var config = ConfigManager.Instance.Current;
var expansionRate = config?.Animation?.PrecomputedDetectionGapExpansionRate ?? 0.0;
var expandedGapInMeters = gapInMeters * (1.0 + expansionRate);
var expandedGapInModelUnits = UnitsConverter.ConvertFromMeters(expandedGapInMeters);
_precomputedDetectionGap = Math.Round(expandedGapInModelUnits, 4);
LogManager.Info($"预计算检测间隙设置为: {expandedGapInMeters:F2}米(扩大率: {expansionRate:F2}");
}
}
@ -2407,7 +2425,6 @@ namespace NavisworksTransport.Core.Animation
// 记录帧时间和统计
_lastFrameTime = now;
_animationFrameCount++;
// 性能监控和自动切换
UpdateFPSCounterAndCheckSwitch();

View File

@ -540,7 +540,7 @@ namespace NavisworksTransport
/// <param name="virtualVehicleLength">虚拟车辆长度(米)</param>
/// <param name="virtualVehicleWidth">虚拟车辆宽度(米)</param>
/// <param name="virtualVehicleHeight">虚拟车辆高度(米)</param>
public void CreateAllAnimationCollisionTests(List<CollisionResult> precomputedCollisions, double detectionGap = 0.05,
public void CreateAllAnimationCollisionTests(List<CollisionResult> precomputedCollisions, double detectionGap,
string pathName = "未知路径", string routeId = null,
ModelItem animatedObject = null, bool isVirtualVehicle = false,
int frameRate = 30, double duration = 10.0,

View File

@ -198,6 +198,7 @@ namespace NavisworksTransport.Core.Config
config.Animation.FrameRate = GetRequiredIntValue(anim, "frame_rate");
config.Animation.DurationSeconds = GetRequiredDoubleValue(anim, "duration_seconds");
config.Animation.DetectionGapMeters = GetRequiredDoubleValue(anim, "detection_gap_meters");
config.Animation.PrecomputedDetectionGapExpansionRate = GetRequiredDoubleValue(anim, "precomputed_detection_gap_expansion_rate");
// 加载物流属性配置
if (!model.ContainsKey("logistics"))
@ -344,6 +345,7 @@ namespace NavisworksTransport.Core.Config
anim["frame_rate"] = config.Animation.FrameRate;
anim["duration_seconds"] = config.Animation.DurationSeconds;
anim["detection_gap_meters"] = config.Animation.DetectionGapMeters;
anim["precomputed_detection_gap_expansion_rate"] = config.Animation.PrecomputedDetectionGapExpansionRate;
}
}

View File

@ -127,6 +127,11 @@ namespace NavisworksTransport.Core.Config
/// 检测间隙(米)
/// </summary>
public double DetectionGapMeters { get; set; }
/// <summary>
/// 预计算检测间隙扩大率(>0表示扩大的倍数
/// </summary>
public double PrecomputedDetectionGapExpansionRate { get; set; }
}
/// <summary>

View File

@ -334,6 +334,17 @@ namespace NavisworksTransport
LogManager.Info("[文档管理] 插件OnLoaded - 开始初始化");
//显式初始化配置管理器,确保配置加载完成
try
{
var config = NavisworksTransport.Core.Config.ConfigManager.Instance.Current;
LogManager.Info($"[配置管理] 配置已加载");
}
catch (Exception ex)
{
LogManager.Error($"[配置管理] 配置加载失败: {ex.Message}");
}
// 订阅文档事件
SubscribeToDocumentEvents();

View File

@ -24,37 +24,37 @@ namespace NavisworksTransport.PathPlanning
/// <summary>
/// 共线检测的容差值(米)
/// </summary>
public double CollinearTolerance { get; set; } = 0.01;
public double CollinearTolerance { get; set; }
/// <summary>
/// 是否启用路径平滑(未来扩展)
/// </summary>
public bool EnableSmoothing { get; set; } = false;
public bool EnableSmoothing { get; set; }
/// <summary>
/// 转弯半径(米,未来扩展)
/// </summary>
public double TurningRadius { get; set; } = 1.0;
public double TurningRadius { get; set; }
/// <summary>
/// 圆弧分段数(未来扩展)
/// </summary>
public int ArcSegments { get; set; } = 8;
public int ArcSegments { get; set; }
/// <summary>
/// 是否启用碰撞检测验证(未来扩展)
/// </summary>
public bool EnableCollisionCheck { get; set; } = false;
public bool EnableCollisionCheck { get; set; }
/// <summary>
/// 车辆长度(米,未来扩展)
/// </summary>
public double VehicleLength { get; set; } = 2.0;
public double VehicleLength { get; set; }
/// <summary>
/// 车辆宽度(米,未来扩展)
/// </summary>
public double VehicleWidth { get; set; } = 1.0;
public double VehicleWidth { get; set; }
}
private readonly OptimizationConfig _config;

View File

@ -174,16 +174,15 @@ namespace NavisworksTransport.UI.WPF.ViewModels
// 移动物体相关字段
private ModelItem _selectedAnimatedObject;
private string _selectedAnimatedObjectName = "未选择移动物体";
private string _selectedAnimatedObjectName;
private bool _hasSelectedAnimatedObject = false;
private bool _canGenerateAnimation = false;
// 虚拟车辆相关字段
private bool _useSelectedObject = true; // 默认使用选择物体方式
private bool _useVirtualVehicle = false; // 使用虚拟车辆
private double _virtualVehicleLength = 1.0; // 虚拟车辆长度(米)
private double _virtualVehicleWidth = 1.0; // 虚拟车辆宽度(米)
private double _virtualVehicleHeight = 2.0; // 虚拟车辆高度(米)
private double _virtualVehicleLength; // 虚拟车辆长度(米)
private double _virtualVehicleWidth; // 虚拟车辆宽度(米)
private double _virtualVehicleHeight; // 虚拟车辆高度(米)
// 手工碰撞对象相关字段
private bool _isManualCollisionTargetEnabled = false;
@ -459,35 +458,6 @@ namespace NavisworksTransport.UI.WPF.ViewModels
/// <summary>
/// 是否使用选择的模型物体
/// </summary>
public bool UseSelectedObject
{
get => _useSelectedObject;
set
{
if (SetProperty(ref _useSelectedObject, value))
{
if (value)
{
_useVirtualVehicle = false;
OnPropertyChanged(nameof(UseVirtualVehicle));
// ✨ 模式切换清理:切换到手动选择模式时,移除存在的虚拟车辆并清理数据
try
{
VirtualVehicleManager.Instance.RemoveVirtualVehicle();
_pathAnimationManager?.ClearAnimationResults(); // 清理虚拟车辆留下的动画数据
LogManager.Info("已切换到手动选择模式,自动隐藏虚拟车辆并清理动画数据");
}
catch (Exception ex)
{
LogManager.Warning($"隐藏虚拟车辆失败: {ex.Message}");
}
}
UpdateCanGenerateAnimation();
}
}
}
/// <summary>
/// 是否使用虚拟车辆
/// </summary>
@ -498,12 +468,9 @@ namespace NavisworksTransport.UI.WPF.ViewModels
{
if (SetProperty(ref _useVirtualVehicle, value))
{
// ✨ 模式切换清理:切换到虚拟车辆模式时,移除选择物体的动画数据
if (value)
{
_useSelectedObject = false;
OnPropertyChanged(nameof(UseSelectedObject));
// ✨ 模式切换清理切换到虚拟车辆模式时重置之前手动选择物体的动画状态恢复到CAD位置
try
{
// 只有在当前动画对象不是虚拟车辆时才执行重置
@ -532,7 +499,21 @@ namespace NavisworksTransport.UI.WPF.ViewModels
}
catch (Exception ex)
{
LogManager.Warning($"重置手动选择物体状态失败: {ex.Message}");
LogManager.Warning($"切换到虚拟车辆模式失败: {ex.Message}");
}
}
else
{
// ✨ 模式切换清理:切换到手动选择模式时,移除存在的虚拟车辆并清理数据
try
{
VirtualVehicleManager.Instance.RemoveVirtualVehicle();
_pathAnimationManager?.ClearAnimationResults(); // 清理虚拟车辆留下的动画数据
LogManager.Info("已切换到手动选择模式,自动隐藏虚拟车辆并清理动画数据");
}
catch (Exception ex)
{
LogManager.Warning($"隐藏虚拟车辆失败: {ex.Message}");
}
}
UpdateCanGenerateAnimation();
@ -823,6 +804,11 @@ namespace NavisworksTransport.UI.WPF.ViewModels
DetectionGap = config.Animation.DetectionGapMeters;
AnimationFrameRate = config.Animation.FrameRate;
// 🔥 从配置加载虚拟车辆尺寸(与路径编辑保持一致)
VirtualVehicleLength = config.PathEditing.VehicleLengthMeters;
VirtualVehicleWidth = config.PathEditing.VehicleWidthMeters;
VirtualVehicleHeight = config.PathEditing.VehicleHeightMeters;
// 设置动画按钮的初始状态
UpdateAnimationButtonStates();

View File

@ -238,7 +238,6 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
<!-- 移动物体来源选择 -->
<StackPanel Orientation="Horizontal" Margin="0,10,0,10">
<RadioButton Content="选择模型物体"
IsChecked="{Binding UseSelectedObject}"
GroupName="ObjectSource"
VerticalAlignment="Center"/>
<RadioButton Content="使用虚拟车辆"
@ -250,7 +249,7 @@ NavisworksTransport 检测动画页签视图 - 采用与类别设置和分层管
<!-- 方式1选择模型物体 -->
<Grid Margin="0,5,0,10"
Visibility="{Binding UseSelectedObject, Converter={StaticResource BoolToVisConverter}}">
Visibility="{Binding UseVirtualVehicle, Converter={StaticResource BoolToVisConverter}, ConverterParameter=Inverse}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>