public StepVectors(Vector3I up) { if (up.RectangularLength() != 1) { throw new ArgumentException("Up must be a unit vector."); } Steps[UpIdx] = up; Steps[DownIdx] = -up; // We don't care which side is actually forward, we just don't want to travel up or down. // Maybe there is some clever math how to do this transformation. if (up.Z == 0) { Steps[FwdIdx] = Vector3I.Forward; Steps[RightIdx] = (up.X == 0) ? Vector3I.Right : Vector3I.Up; } else // Z != 0 -> the other two dimensions should be "free" to use for side directions { if (up.X != 0 || up.Y != 0) { throw new ArgumentException("X and Y of the Up vector expected to be 0."); } Steps[FwdIdx] = Vector3I.Up; Steps[RightIdx] = Vector3I.Right; } Steps[LeftIdx] = -Right; Steps[BackIdx] = -Forward; }
private bool ProcessTriangleForHierarchy(MyNavigationTriangle triangle) { // The triangle parent can be wrong when we have multiple navmeshes connected via external edges if (triangle.Parent != m_mesh) { return(false); } // Previously unvisited triangle will be assigned the current relative component index if (triangle.ComponentIndex == -1) { m_navmeshComponents.AddComponentTriangle(triangle, triangle.Center); m_tmpComponentTriangles.Add(triangle); triangle.ComponentIndex = m_currentComponentMarker; return(true); } else if (triangle.ComponentIndex == m_currentComponentMarker) { // We can safely ignore this triangle (it has already been processed); return(true); } else { ulong cellIndex; if (m_navmeshComponents.GetComponentCell(triangle.ComponentIndex, out cellIndex)) { MyCellCoord cellCoord = new MyCellCoord(); cellCoord.SetUnpack(cellIndex); Vector3I diff = cellCoord.CoordInLod - m_currentCell; if (diff.RectangularLength() != 1) { // CH: TODO: Connection of components over cell edges or vertices. I currently silently ignore that... return(false); } ConnectionInfo connection = new ConnectionInfo(); connection.Direction = Base6Directions.GetDirection(diff); connection.ComponentIndex = triangle.ComponentIndex; // Save connections to other components. There won't be so many, so we can keep them in a list instead of a HashSet if (!m_currentCellConnections[m_currentComponentRel].Contains(connection)) { m_currentCellConnections[m_currentComponentRel].Add(connection); } } } return(false); }
public Vector3ILineIterator(Vector3I start, Vector3I end) { if (start == end) { throw new ArgumentException("Start and end cannot be equal"); } _start = start; _end = end; Current = start; _direction = Vector3I.Clamp(end - start, -Vector3I.One, Vector3I.One); if (_direction.RectangularLength() > 1) { throw new ArgumentException("Start and end are not in a straight line"); } }
private bool ProcessTriangleForHierarchy(MyNavigationTriangle triangle) { if (ReferenceEquals(triangle.Parent, this.m_mesh)) { ulong num; if (triangle.ComponentIndex == -1) { this.m_navmeshComponents.AddComponentTriangle(triangle, triangle.Center); this.m_tmpComponentTriangles.Add(triangle); triangle.ComponentIndex = this.m_currentComponentMarker; return(true); } if (triangle.ComponentIndex == this.m_currentComponentMarker) { return(true); } if (this.m_navmeshComponents.GetComponentCell(triangle.ComponentIndex, out num)) { MyCellCoord coord = new MyCellCoord(); coord.SetUnpack(num); Vector3I vec = coord.CoordInLod - this.m_currentCell; if (vec.RectangularLength() != 1) { return(false); } ConnectionInfo item = new ConnectionInfo { Direction = Base6Directions.GetDirection(vec), ComponentIndex = triangle.ComponentIndex }; if (!this.m_currentCellConnections[this.m_currentComponentRel].Contains(item)) { this.m_currentCellConnections[this.m_currentComponentRel].Add(item); } } } return(false); }
public void InitOrientation(ref Vector3I forward, ref Vector3I up) { Debug.Assert(forward.RectangularLength() == 1 && up.RectangularLength() == 1); Debug.Assert(Vector3I.Dot(ref forward, ref up) == 0); InitOrientation(Base6Directions.GetDirection(forward), Base6Directions.GetDirection(up)); }
/// <summary> /// Yields the first occupied cells encountered when raycasting a grid in a given base direction. /// </summary> /// <param name="grid">The grid to get blocks from.</param> /// <param name="baseDirection">The direction of ray.</param> public static IEnumerable <Vector3I> FirstBlocks(this IMyCubeGrid grid, Vector3I baseDirection) { Logger.DebugLog("baseDirection(" + baseDirection + ") has a magnitude", Logger.severity.FATAL, condition: baseDirection.RectangularLength() != 1); BoundingBox localAABB = grid.LocalAABB; Vector3I min = grid.Min, max = grid.Max; // ??? //Vector3 minF; Vector3.Divide(ref localAABB.Min, grid.GridSize, out minF); //Vector3 maxF; Vector3.Divide(ref localAABB.Max, grid.GridSize, out maxF); //Vector3I min, max; //Func<float, int> round = f => (int)Math.Round(f); //minF.ApplyOperation(round, out min); //maxF.ApplyOperation(round, out max); Vector3I perp0, perp1; perp0 = Base6Directions.GetIntVector(Base6Directions.GetPerpendicular(Base6Directions.GetDirection(baseDirection))); Vector3I.Cross(ref baseDirection, ref perp0, out perp1); int baseStart; Vector3I.Dot(ref baseDirection, ref min, out baseStart); int baseEnd; Vector3I.Dot(ref baseDirection, ref max, out baseEnd); if (baseStart > baseEnd) { int temp = baseStart; baseStart = baseEnd; baseEnd = temp; } bool incrementBase = baseStart <= baseEnd; int perp0Min; Vector3I.Dot(ref perp0, ref min, out perp0Min); int perp0Max; Vector3I.Dot(ref perp0, ref max, out perp0Max); if (perp0Max < perp0Min) { int temp = perp0Max; perp0Max = perp0Min; perp0Min = temp; } int perp1Min; Vector3I.Dot(ref perp1, ref min, out perp1Min); int perp1Max; Vector3I.Dot(ref perp1, ref max, out perp1Max); if (perp1Max < perp1Min) { int temp = perp1Max; perp1Max = perp1Min; perp1Min = temp; } Logger.TraceLog("min: " + min + ", max: " + max, Logger.severity.DEBUG); Logger.TraceLog("base: " + baseDirection + ", perp0: " + perp0 + ", perp1: " + perp1, Logger.severity.DEBUG); Logger.TraceLog("base range: " + baseStart + ":" + baseEnd, Logger.severity.DEBUG); Logger.TraceLog("perp0 range: " + perp0Min + ":" + perp0Max, Logger.severity.DEBUG); Logger.TraceLog("perp1 range: " + perp1Min + ":" + perp1Max, Logger.severity.DEBUG); for (int perp0Value = perp0Min; perp0Value <= perp0Max; perp0Value++) { for (int perp1Value = perp1Min; perp1Value <= perp1Max; perp1Value++) { int baseValue = baseStart; while (true) { Vector3I cell = baseValue * baseDirection + perp0Value * perp0 + perp1Value * perp1; if (grid.CubeExists(cell)) { yield return(cell); break; } if (baseValue == baseEnd) { break; } if (incrementBase) { baseValue++; } else { baseValue--; } } } } yield break; }