public void MarkBoxForAddition(BoundingBoxD box)
        {
            ProfilerShort.Begin("VoxelNavMesh.MarkBoxForAddition");
            Vector3I pos, end;

            MyVoxelCoordSystems.WorldPositionToVoxelCoord(m_voxelMap.PositionLeftBottomCorner, ref box.Min, out pos);
            MyVoxelCoordSystems.WorldPositionToVoxelCoord(m_voxelMap.PositionLeftBottomCorner, ref box.Max, out end);

            m_voxelMap.Storage.ClampVoxelCoord(ref pos);
            m_voxelMap.Storage.ClampVoxelCoord(ref end);

            MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref pos, out pos);
            MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref end, out end);

            Vector3 center = pos + end;

            center = center * 0.5f;

            pos /= 1 << NAVMESH_LOD;
            end /= 1 << NAVMESH_LOD;

            for (var it = new Vector3I.RangeIterator(ref pos, ref end); it.IsValid(); it.GetNext(out pos))
            {
                if (!m_processedCells.Contains(ref pos) && !m_markedForAddition.Contains(ref pos))
                {
                    float weight = 1.0f / (0.01f + Vector3.RectangularDistance(pos, center));

                    if (!m_toAdd.Full)
                    {
                        m_toAdd.Insert(pos, weight);
                        m_markedForAddition.Add(ref pos);
                    }
                    else
                    {
                        float min = m_toAdd.MinKey();
                        if (weight > min)
                        {
                            Vector3I posRemoved = m_toAdd.RemoveMin();
                            m_markedForAddition.Remove(ref posRemoved);

                            m_toAdd.Insert(pos, weight);
                            m_markedForAddition.Add(ref pos);
                        }
                    }
                }
            }
            ProfilerShort.End();
        }
        public void RemoveTooFarCells(List <Vector3D> importantPositions, float maxDistance, MyVector3ISet processedCells)
        {
            // remove too far high level info (if it isn't in processed cells)
            m_removedHLpackedCoord.Clear();
            foreach (var cell in m_exploredCells)
            {
                Vector3D worldCellCenterPos;
                Vector3I cellPos = cell;
                MyVoxelCoordSystems.GeometryCellCenterCoordToWorldPos(m_mesh.VoxelMapReferencePosition, ref cellPos, out worldCellCenterPos);

                // finding of distance from the nearest important object
                float dist = float.PositiveInfinity;
                foreach (Vector3D vec in importantPositions)
                {
                    float d = Vector3.RectangularDistance(vec, worldCellCenterPos);
                    if (d < dist)
                    {
                        dist = d;
                    }
                }

                if (dist > maxDistance && !processedCells.Contains(cellPos))
                {
                    MyCellCoord coord = new MyCellCoord(MyVoxelNavigationMesh.NAVMESH_LOD, cellPos);
                    m_removedHLpackedCoord.Add(coord.PackId64());
                }
            }
            foreach (ulong coord in m_removedHLpackedCoord)
            {
                TryClearCell(coord);
            }
        }
Esempio n. 3
0
 public void RemoveTooFarCells(List <Vector3D> importantPositions, float maxDistance, MyVector3ISet processedCells)
 {
     m_removedHLpackedCoord.Clear();
     foreach (Vector3I vectori in this.m_exploredCells)
     {
         Vector3D vectord;
         MyVoxelCoordSystems.GeometryCellCenterCoordToWorldPos(this.m_mesh.VoxelMapReferencePosition, ref vectori, out vectord);
         float positiveInfinity = float.PositiveInfinity;
         using (List <Vector3D> .Enumerator enumerator2 = importantPositions.GetEnumerator())
         {
             while (enumerator2.MoveNext())
             {
                 float num2 = Vector3.RectangularDistance(enumerator2.Current, (Vector3)vectord);
                 if (num2 < positiveInfinity)
                 {
                     positiveInfinity = num2;
                 }
             }
         }
         if ((positiveInfinity > maxDistance) && !processedCells.Contains(vectori))
         {
             m_removedHLpackedCoord.Add(new MyCellCoord(0, vectori).PackId64());
         }
     }
     foreach (ulong num3 in m_removedHLpackedCoord)
     {
         this.TryClearCell(num3);
     }
 }
        public void InvalidateRange(Vector3I minVoxelChanged, Vector3I maxVoxelChanged)
        {
            minVoxelChanged -= MyPrecalcComponent.InvalidatedRangeInflate;
            maxVoxelChanged += MyPrecalcComponent.InvalidatedRangeInflate;

            m_voxelMap.Storage.ClampVoxelCoord(ref minVoxelChanged);
            m_voxelMap.Storage.ClampVoxelCoord(ref maxVoxelChanged);

            Vector3I minCell, maxCell;

            MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref minVoxelChanged, out minCell);
            MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref maxVoxelChanged, out maxCell);

            Vector3I currentCell = minCell;

            for (var it = new Vector3I.RangeIterator(ref minCell, ref maxCell); it.IsValid(); it.GetNext(out currentCell))
            {
                if (m_processedCells.Contains(ref currentCell))
                {
                    RemoveCell(currentCell);
                }

                MyCellCoord coord = new MyCellCoord(NAVMESH_LOD, currentCell);
                m_higherLevelHelper.TryClearCell(coord.PackId64());
            }
        }
        public IMyHighLevelComponent GetComponent(MyHighLevelPrimitive primitive)
        {
            ulong cellIndex;

            if (m_navmeshComponents.GetComponentCell(primitive.Index, out cellIndex))
            {
                Base6Directions.DirectionFlags exploredDirections;

                if (m_navmeshComponents.GetComponentInfo(primitive.Index, cellIndex, out exploredDirections))
                {
                    MyCellCoord coord = new MyCellCoord();
                    coord.SetUnpack(cellIndex);

                    // Look at present unexplored cells around this cell.
                    // Their direction can be marked as explored, because there was no geometry when they were being explored
                    foreach (var direction in Base6Directions.EnumDirections)
                    {
                        var directionFlag = Base6Directions.GetDirectionFlag(direction);
                        if (exploredDirections.HasFlag(directionFlag))
                        {
                            continue;
                        }

                        Vector3I neighbor = coord.CoordInLod + Base6Directions.GetIntVector(direction);
                        if (m_exploredCells.Contains(ref neighbor))
                        {
                            exploredDirections |= directionFlag;
                        }
                    }

                    return(new Component(primitive.Index, exploredDirections));
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                return(null);
            }
        }
        private void MergeFromAnotherMesh(MyGridNavigationMesh otherMesh, ref MatrixI transform)
        {
            ProfilerShort.Begin("MergeFromAnotherMesh");
            m_mergeHelper.Clear();

            // Save the cubes from the other mesh that are touching cubes of this mesh into a helper set.
            // Also put the touched cubes from this mesh into the set.
            foreach (var position in otherMesh.m_smallTriangleRegistry.Keys)
            {
                bool add = false;
                foreach (var direction in Base6Directions.IntDirections)
                {
                    // CH: TODO: We query the grid so far, but in the future, we should make sure that the access is thread-safe
                    Vector3I pos = Vector3I.Transform(position + direction, transform);
                    if (m_cubeSet.Contains(ref pos))             // Test the transformed position...
                    {
                        m_mergeHelper.Add(position + direction); // ... but add the original one
                        add = true;
                    }
                }
                if (add)
                {
                    m_mergeHelper.Add(position);
                }
            }

            foreach (var entry in otherMesh.m_smallTriangleRegistry)
            {
                Vector3I originalCube = entry.Key;
                Vector3I tformedCube; Vector3I.Transform(ref originalCube, ref transform, out tformedCube);

                // If the cube is one of the touching cubes, we have to intersect the touching triangles
                if (m_mergeHelper.Contains(originalCube))
                {
                    // Take the touching pairs one by one and calculate triangulation of the disjoint union of the opposing faces
                    // Remove the opposing faces from the old block
                    // Add the triangulation to the mesh
                    // Add the rest of the navmesh from this block to the mesh

                    m_tmpTriangleList.Clear();

                    // CH: TODO. Just remove the triangles now
                    foreach (var direction in Base6Directions.EnumDirections)
                    {
                        Vector3I directionVec = Base6Directions.GetIntVector((int)direction);
                        Base6Directions.Direction tformedDirection = transform.GetDirection(direction);
                        Vector3I tformedFlippedVec = Base6Directions.GetIntVector((int)Base6Directions.GetFlippedDirection(tformedDirection));

                        // Remove face triangles from this mesh
                        if (m_mergeHelper.Contains(originalCube + directionVec))
                        {
                            List <int> triList = null;
                            if (m_smallTriangleRegistry.TryGetValue(tformedCube - tformedFlippedVec, out triList))
                            {
                                foreach (var index in triList)
                                {
                                    var triangle = GetTriangle(index);
                                    // CH: TODO: This will probably be expensive. Could we precalculate it?
                                    if (IsFaceTriangle(triangle, tformedCube - tformedFlippedVec, tformedFlippedVec))
                                    {
                                        m_tmpTriangleList.Add(new KeyValuePair <MyNavigationTriangle, Vector3I>(triangle, tformedCube - tformedFlippedVec));
                                    }
                                }
                            }
                        }
                    }

                    foreach (var triangle in m_tmpTriangleList)
                    {
                        RemoveTriangle(triangle.Key, triangle.Value);
                    }
                    m_tmpTriangleList.Clear();

                    int debugCounter = 0;

                    // CH: TODO: optimize this (actually whole this method)
                    foreach (var triangleIndex in entry.Value)
                    {
                        var      triangle    = otherMesh.GetTriangle(triangleIndex);
                        Vector3I pos         = entry.Key;
                        bool     addTriangle = true;
                        foreach (var direction in Base6Directions.EnumDirections)
                        {
                            Vector3I dirvec = Base6Directions.GetIntVector((int)direction);
                            if (m_mergeHelper.Contains(pos + dirvec) && IsFaceTriangle(triangle, pos, dirvec))
                            {
                                addTriangle = false;
                                break;
                            }
                        }

                        if (addTriangle)
                        {
                            if (debugCounter == 5)
                            {
                            }
                            CopyTriangle(triangle, pos, ref transform);
                            debugCounter++;
                        }
                    }
                }
                // Otherwise, we just transform the triangles from the other mesh and add them to this mesh
                else
                {
                    foreach (var triangleIndex in entry.Value)
                    {
                        var triangle = otherMesh.GetTriangle(triangleIndex);
                        CopyTriangle(triangle, entry.Key, ref transform);
                        //if (triangleIndex > 1) break;
                    }
                }
            }

            m_mergeHelper.Clear();
            ProfilerShort.End();
        }
        public void RemoveTooFarCells(List<Vector3D> importantPositions, float maxDistance, MyVector3ISet processedCells)
        {
            // remove too far high level info (if it isn't in processed cells)
            m_removedHLpackedCoord.Clear();
            foreach (var cell in m_exploredCells)
            {
                Vector3D worldCellCenterPos;
                Vector3I cellPos = cell;
                MyVoxelCoordSystems.GeometryCellCenterCoordToWorldPos(m_mesh.VoxelMapReferencePosition, ref cellPos, out worldCellCenterPos);

                // finding of distance from the nearest important object
                float dist = float.PositiveInfinity;
                foreach (Vector3D vec in importantPositions)
                {
                    float d = Vector3.RectangularDistance(vec, worldCellCenterPos);
                    if (d < dist)
                        dist = d;
                }

                if (dist > maxDistance && !processedCells.Contains(cellPos))
                {
                    MyCellCoord coord = new MyCellCoord(MyVoxelNavigationMesh.NAVMESH_LOD, cellPos);
                    m_removedHLpackedCoord.Add(coord.PackId64());
                }
            }
            foreach(ulong coord in m_removedHLpackedCoord)
            {
                TryClearCell(coord);
            }
        }