新增空间查询AABB范围查询功能,不再使用半径查询。
This commit is contained in:
parent
71fe79a447
commit
5fdccf55c5
@ -7,6 +7,7 @@
|
||||
1. [x] (功能)在碰撞报告中支持多张截图
|
||||
2. [x] (功能)增加提取元素的包围盒信息,并一键拷贝到坐标编辑窗口
|
||||
3. [x] (功能)在状态栏增加路径可视化快捷按钮
|
||||
4. [x] (优化)利用通行空间过滤空间几何体,提高非手工指定模式的性能
|
||||
|
||||
### [2026/2/3]
|
||||
|
||||
|
||||
@ -792,7 +792,6 @@ namespace NavisworksTransport.Core.Animation
|
||||
|
||||
// 空间索引设置
|
||||
SpatialIndexManager spatialIndexManager = null;
|
||||
double searchRadiusInModelUnits = 0;
|
||||
var manualTargetsSnapshot = new List<ModelItem>();
|
||||
bool manualOverrideActive = _manualCollisionOverrideEnabled && _manualCollisionTargets != null && _manualCollisionTargets.Count > 0;
|
||||
|
||||
@ -844,13 +843,9 @@ namespace NavisworksTransport.Core.Animation
|
||||
|
||||
LogManager.Info(spatialIndexManager.GetStatistics());
|
||||
|
||||
// 🔥 修改:使用车辆的最大水平尺寸而不是对角线
|
||||
// 原因:车辆在通道上水平移动,主要检测侧面碰撞
|
||||
double maxHorizontalDimension = Math.Max(boundingBoxSize.X, boundingBoxSize.Y);
|
||||
|
||||
// 🔥 使用安全间隙计算空间查询半径 - _safetyMargin 已是模型单位
|
||||
searchRadiusInModelUnits = maxHorizontalDimension + _safetyMargin;
|
||||
LogManager.Info($"空间查询半径: {searchRadiusInModelUnits:F2} 模型单位 (基于最大水平尺寸: {maxHorizontalDimension:F2}, 安全间隙: {_safetyMargin:F4}模型单位)");
|
||||
// 🔥 优化:使用AABB查询代替球形查询,查询范围更精确
|
||||
// 不再预计算球形半径,改为每帧计算车辆AABB + 安全间隙的搜索AABB
|
||||
LogManager.Info($"空间查询使用AABB模式,安全间隙: {_safetyMargin:F4}模型单位");
|
||||
}
|
||||
|
||||
// 3. 生成每一帧
|
||||
@ -1028,9 +1023,22 @@ namespace NavisworksTransport.Core.Animation
|
||||
}
|
||||
else
|
||||
{
|
||||
nearbyObjects = spatialIndexManager.FindNearbyObjects(
|
||||
framePosition,
|
||||
searchRadiusInModelUnits,
|
||||
// 🔥 优化:使用AABB查询代替球形查询,避免球体扩大的无效范围
|
||||
// 查询AABB = 车辆AABB + 安全间隙扩展
|
||||
var searchBounds = new BoundingBox3D(
|
||||
new Point3D(
|
||||
virtualBoundingBox.Min.X - _safetyMargin,
|
||||
virtualBoundingBox.Min.Y - _safetyMargin,
|
||||
virtualBoundingBox.Min.Z - _safetyMargin
|
||||
),
|
||||
new Point3D(
|
||||
virtualBoundingBox.Max.X + _safetyMargin,
|
||||
virtualBoundingBox.Max.Y + _safetyMargin,
|
||||
virtualBoundingBox.Max.Z + _safetyMargin
|
||||
)
|
||||
);
|
||||
nearbyObjects = spatialIndexManager.FindInAABB(
|
||||
searchBounds,
|
||||
excludeObject: _animatedObject
|
||||
);
|
||||
}
|
||||
|
||||
@ -219,6 +219,54 @@ namespace NavisworksTransport.Core.Spatial
|
||||
return FindInRadius(center, radius, distanceFunc: null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AABB范围查询:查找与指定AABB相交格子中的所有对象
|
||||
/// 比球形查询更精确,避免球体扩大的无效范围
|
||||
/// </summary>
|
||||
/// <param name="boundsMin">AABB最小点</param>
|
||||
/// <param name="boundsMax">AABB最大点</param>
|
||||
/// <returns>范围内的对象列表(自动去重)</returns>
|
||||
public List<T> FindInAABB(Vector3d boundsMin, Vector3d boundsMax)
|
||||
{
|
||||
var results = new HashSet<T>();
|
||||
|
||||
// 计算AABB覆盖的格子范围
|
||||
var minGrid = _indexer.ToGrid(boundsMin);
|
||||
var maxGrid = _indexer.ToGrid(boundsMax);
|
||||
|
||||
// 只遍历AABB覆盖的格子(比球形查询更精确)
|
||||
for (int x = minGrid.x; x <= maxGrid.x; x++)
|
||||
{
|
||||
for (int y = minGrid.y; y <= maxGrid.y; y++)
|
||||
{
|
||||
for (int z = minGrid.z; z <= maxGrid.z; z++)
|
||||
{
|
||||
var gridCell = new Vector3i(x, y, z);
|
||||
|
||||
if (_grid.TryGetValue(gridCell, out var cellObjects))
|
||||
{
|
||||
foreach (var obj in cellObjects)
|
||||
{
|
||||
results.Add(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new List<T>(results);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AABB范围查询(使用Navisworks BoundingBox3D)
|
||||
/// </summary>
|
||||
public List<T> FindInAABB(Autodesk.Navisworks.Api.BoundingBox3D bounds)
|
||||
{
|
||||
var min = new Vector3d(bounds.Min.X, bounds.Min.Y, bounds.Min.Z);
|
||||
var max = new Vector3d(bounds.Max.X, bounds.Max.Y, bounds.Max.Z);
|
||||
return FindInAABB(min, max);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空所有数据
|
||||
/// </summary>
|
||||
|
||||
@ -237,6 +237,43 @@ namespace NavisworksTransport.Core.Spatial
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AABB范围查询:查找与指定AABB相交的对象
|
||||
/// 比球形查询更精确,避免球体扩大的无效范围
|
||||
/// </summary>
|
||||
/// <param name="bounds">查询AABB(Navisworks BoundingBox3D)</param>
|
||||
/// <param name="excludeObject">要排除的对象</param>
|
||||
/// <returns>与AABB相交格子中的对象列表</returns>
|
||||
public List<ModelItem> FindInAABB(
|
||||
BoundingBox3D bounds,
|
||||
ModelItem excludeObject = null)
|
||||
{
|
||||
if (!_isInitialized)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"[空间索引] 空间索引未初始化,请先调用 BuildGlobalIndex()");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 直接使用AABB查询(更精确)
|
||||
var nearbyObjects = _globalSpatialIndex.FindInAABB(bounds);
|
||||
|
||||
// 排除指定对象
|
||||
if (excludeObject != null)
|
||||
{
|
||||
nearbyObjects = nearbyObjects.Where(obj => !obj.Equals(excludeObject)).ToList();
|
||||
}
|
||||
|
||||
return nearbyObjects;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.Error($"[空间索引] AABB查询失败: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象的缓存位置
|
||||
/// </summary>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user