private void GetCellLineIntersectionOctree(ref VRage.Game.Models.MyIntersectionResultLineTriangle?result, ref Line modelSpaceLine, ref float?minDistanceUntilNow, CellData cachedDataCell, IntersectionFlags flags) { m_overlapElementCache.Clear(); if (cachedDataCell.Octree != null) { Vector3 packedStart, packedEnd; cachedDataCell.GetPackedPosition(ref modelSpaceLine.From, out packedStart); cachedDataCell.GetPackedPosition(ref modelSpaceLine.To, out packedEnd); var ray = new Ray(packedStart, packedEnd - packedStart); cachedDataCell.Octree.GetIntersectionWithLine(ref ray, m_overlapElementCache); } for (int j = 0; j < m_overlapElementCache.Count; j++) { var i = m_overlapElementCache[j]; if (cachedDataCell.VoxelTriangles == null) //probably not calculated yet { continue; } // this should never happen if (i >= cachedDataCell.VoxelTriangles.Length) { Debug.Assert(i < cachedDataCell.VoxelTriangles.Length); continue; } MyVoxelTriangle voxelTriangle = cachedDataCell.VoxelTriangles[i]; MyTriangle_Vertexes triangleVertices; cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex0, out triangleVertices.Vertex0); cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex1, out triangleVertices.Vertex1); cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex2, out triangleVertices.Vertex2); Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangleVertices); if (!calculatedTriangleNormal.IsValid()) { continue; } //We dont want backside intersections if (((int)(flags & IntersectionFlags.FLIPPED_TRIANGLES) == 0) && Vector3.Dot(modelSpaceLine.Direction, calculatedTriangleNormal) > 0) { continue; } // AABB intersection test removed, AABB is tested inside BVH float?distance = MyUtils.GetLineTriangleIntersection(ref modelSpaceLine, ref triangleVertices); // If intersection occured and if distance to intersection is closer to origin than any previous intersection if ((distance != null) && ((result == null) || (distance.Value < result.Value.Distance))) { minDistanceUntilNow = distance.Value; result = new VRage.Game.Models.MyIntersectionResultLineTriangle(ref triangleVertices, ref calculatedTriangleNormal, distance.Value); } } }
public bool Intersect(ref Line localLine, out VRage.Game.Models.MyIntersectionResultLineTriangle result, IntersectionFlags flags) { MyPrecalcComponent.AssertUpdateThread(); ProfilerShort.Begin("VoxelMap.LineIntersection AABB sweep"); m_sweepResultCache.Clear(); MyGridIntersection.Calculate( m_sweepResultCache, (int)MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES, localLine.From, localLine.To, new Vector3I(0, 0, 0), m_cellsCount - 1 ); ProfilerShort.End(); ProfilerShort.Begin("VoxelMap.LineIntersection test AABBs"); float? minDistanceUntilNow = null; BoundingBox cellBoundingBox; MyCellCoord cell = new MyCellCoord(); VRage.Game.Models.MyIntersectionResultLineTriangle?tmpResult = null; for (int index = 0; index < m_sweepResultCache.Count; index++) { cell.CoordInLod = m_sweepResultCache[index]; MyVoxelCoordSystems.GeometryCellCoordToLocalAABB(ref cell.CoordInLod, out cellBoundingBox); float?distanceToBoundingBox = MyUtils.GetLineBoundingBoxIntersection(ref localLine, ref cellBoundingBox); // Sweep results are sorted; when we get far enough, make an early exit const float earlyOutDistance = 1.948557f * MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES; // = sqrt(3) * 9/8 * cell_side if (minDistanceUntilNow != null && distanceToBoundingBox != null && minDistanceUntilNow + earlyOutDistance < distanceToBoundingBox.Value) { break; } // Get cell from cache. If not there, precalc it and store in the cache. // If null is returned, we know that cell doesn't contain any triangleVertexes so we don't need to do intersections. CellData cachedDataCell = GetCell(ref cell); if (cachedDataCell == null || cachedDataCell.VoxelTrianglesCount == 0) { continue; } GetCellLineIntersectionOctree(ref tmpResult, ref localLine, ref minDistanceUntilNow, cachedDataCell, flags); } ProfilerShort.End(); result = tmpResult ?? default(VRage.Game.Models.MyIntersectionResultLineTriangle); return(tmpResult.HasValue); }
private void GetCellLineIntersectionOctree(ref VRage.Game.Models.MyIntersectionResultLineTriangle? result, ref Line modelSpaceLine, ref float? minDistanceUntilNow, CellData cachedDataCell, IntersectionFlags flags) { m_overlapElementCache.Clear(); if (cachedDataCell.Octree != null) { Vector3 packedStart, packedEnd; cachedDataCell.GetPackedPosition(ref modelSpaceLine.From, out packedStart); cachedDataCell.GetPackedPosition(ref modelSpaceLine.To, out packedEnd); var ray = new Ray(packedStart, packedEnd - packedStart); cachedDataCell.Octree.GetIntersectionWithLine(ref ray, m_overlapElementCache); } for (int j = 0; j < m_overlapElementCache.Count; j++) { var i = m_overlapElementCache[j]; if (cachedDataCell.VoxelTriangles == null) //probably not calculated yet continue; // this should never happen if (i >= cachedDataCell.VoxelTriangles.Length) { Debug.Assert(i < cachedDataCell.VoxelTriangles.Length); continue; } MyVoxelTriangle voxelTriangle = cachedDataCell.VoxelTriangles[i]; MyTriangle_Vertexes triangleVertices; cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex0, out triangleVertices.Vertex0); cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex1, out triangleVertices.Vertex1); cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex2, out triangleVertices.Vertex2); Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangleVertices); if (!calculatedTriangleNormal.IsValid()) continue; //We dont want backside intersections if (((int)(flags & IntersectionFlags.FLIPPED_TRIANGLES) == 0) && Vector3.Dot(modelSpaceLine.Direction, calculatedTriangleNormal) > 0) continue; // AABB intersection test removed, AABB is tested inside BVH float? distance = MyUtils.GetLineTriangleIntersection(ref modelSpaceLine, ref triangleVertices); // If intersection occured and if distance to intersection is closer to origin than any previous intersection if ((distance != null) && ((result == null) || (distance.Value < result.Value.Distance))) { minDistanceUntilNow = distance.Value; result = new VRage.Game.Models.MyIntersectionResultLineTriangle(ref triangleVertices, ref calculatedTriangleNormal, distance.Value); } } }