// Checks distance to plane along axis. private bool TestAxis(int x, int y, int z) { Vector3I v = new Vector3I(x, y, z); int numerator = normal.Dot(a - Coords); int denominator = normal.Dot(v); if (denominator == 0) { return(numerator == 0); } double distance = ( double )numerator / denominator; return(distance > -0.5 && distance <= 0.5); }
private static void CheckStepVectors(Vector3I up) { var stepVectors = new StepVectors(up); // Sides are perpendicular to the Up vector (dot product is zero) foreach (var side in stepVectors.EnumerateSides()) { Assert.Equal(0, Vector3I.Dot(up, side)); } // All directions are unit vectors and they are different from each other. for (int i = 0; i < StepVectors.Count; i++) { var step = stepVectors.Steps[i]; Assert.Equal(1, step.RectangularLength()); for (int j = 0; j < StepVectors.Count; j++) // Check all are different. { if (j != i) { Assert.False(step.Equals(stepVectors.Steps[j])); } } } }
private void FixSnapTransformationBase6() { if (base.CopiedGrids.Count != 0) { MyCubeGrid hitEntity = base.m_hitEntity as MyCubeGrid; if (hitEntity != null) { Matrix rotationDeltaMatrixToHitGrid = this.GetRotationDeltaMatrixToHitGrid(hitEntity); foreach (MyCubeGrid local1 in base.PreviewGrids) { MatrixD worldMatrix = local1.WorldMatrix; Matrix matrix2 = (Matrix)(worldMatrix.GetOrientation() * rotationDeltaMatrixToHitGrid); MatrixD xd = MatrixD.CreateWorld(base.m_pastePosition, matrix2.Forward, matrix2.Up); local1.PositionComp.SetWorldMatrix(xd, null, false, true, true, false, false, false); } if ((hitEntity.GridSizeEnum == MyCubeSize.Large) && (base.PreviewGrids[0].GridSizeEnum == MyCubeSize.Small)) { base.m_pastePosition = hitEntity.GridIntegerToWorld(MyCubeBuilder.TransformLargeGridHitCoordToSmallGrid(base.m_hitPos, hitEntity.PositionComp.WorldMatrixNormalizedInv, hitEntity.GridSize)); } else { Vector3I vectori = Vector3I.Round(base.m_hitNormal); Vector3I gridOffset = hitEntity.WorldToGridInteger(base.m_pastePosition); Vector3I min = base.PreviewGrids[0].Min; Vector3I vectori4 = Vector3I.Abs(Vector3I.Round(Vector3D.TransformNormal(Vector3D.TransformNormal((Vector3D)((base.PreviewGrids[0].Max - min) + Vector3I.One), base.PreviewGrids[0].WorldMatrix), hitEntity.PositionComp.WorldMatrixNormalizedInv))); int num = Math.Abs(Vector3I.Dot(ref vectori, ref vectori4)); int num2 = 0; while (true) { if ((num2 >= num) || hitEntity.CanMergeCubes(base.PreviewGrids[0], gridOffset)) { if (num2 == num) { gridOffset = hitEntity.WorldToGridInteger(base.m_pastePosition); } base.m_pastePosition = hitEntity.GridIntegerToWorld(gridOffset); break; } gridOffset = (Vector3I)(gridOffset + vectori); num2++; } } for (int i = 0; i < base.PreviewGrids.Count; i++) { MyCubeGrid local2 = base.PreviewGrids[i]; MatrixD worldMatrix = local2.WorldMatrix; worldMatrix.Translation = base.m_pastePosition + Vector3.Transform(base.m_copiedGridOffsets[i], rotationDeltaMatrixToHitGrid); local2.PositionComp.SetWorldMatrix(worldMatrix, null, false, true, true, false, false, false); } if (MyDebugDrawSettings.DEBUG_DRAW_COPY_PASTE) { MyRenderProxy.DebugDrawLine3D(base.m_hitPos, base.m_hitPos + base.m_hitNormal, Color.Red, Color.Green, false, false); } } } }
public Vector3I Mark(Vector3I pos, IMySlimBlock block, char mark = '▓') { var projected = pos * planeIsh; map[projected] = mark; int alongWide = wide.Dot(ref pos); int alongHigh = high.Dot(ref pos); if(alongWide < wideLow) wideLow = alongWide; if(alongWide > wideHigh) wideHigh = alongWide; if(alongHigh < highLow) highLow = alongHigh; if(alongHigh > highHigh) highHigh = alongHigh; return projected; }
/// <summary> /// Move air by velocity. /// </summary> private void MoveAir() { Profiler.StartProfileBlock(); Log.TraceLog("entered"); int dirDim = m_shipDirection.Max() == 0 ? 0 : m_sizeCell.Dot(ref m_shipDirection) - 1; Vector3I index; for (index.X = 0; index.X < m_sizeCell.X; index.X++) { for (index.Y = 0; index.Y < m_sizeCell.Y; index.Y++) { for (index.Z = 0; index.Z < m_sizeCell.Z; index.Z++) { AeroCell currentData; GetValue(ref index, out currentData); if (!currentData.Process) { continue; } Vector3I currentCell = index + m_minCell; //Vector3 currentCellF = currentCell; Vector3 targetCellAvg = currentCell + currentData.CurVelocity; //Vector3.Add(ref currentCellF, ref currentData.MoveVelocity, out targetCellAvg); if (!currentData.BlockTest) { BlockTest(currentData, ref currentCell, ref targetCellAvg); } PushAir(ref currentCell, currentData, ref targetCellAvg); int dot; Vector3I.Dot(ref index, ref m_shipDirection, out dot); if (dot == dirDim) { currentData.NextAirPress += m_defaultData.CurAirPress; } Log.TraceLog("Cell: " + currentCell + ", " + currentData, condition: currentData.LogChange); } } } Log.TraceLog("exiting"); Profiler.EndProfileBlock(); }
private void GenerateBlockSphere(MyCubeSize gridSizeEnum, double radiusInMeters) { var gridSizeInv = 2.0; // Assume small grid (1 / 0.5) if (gridSizeEnum == MyCubeSize.Large) { gridSizeInv = 0.4; // Large grid (1 / 2.5) } var radiusInBlocks = radiusInMeters * gridSizeInv; var radiusSq = radiusInBlocks * radiusInBlocks; var radiusCeil = (int)Math.Ceiling(radiusInBlocks); int i, j, k; var max = Vector3I.One * radiusCeil; var min = Vector3I.One * -radiusCeil; var blockSphereLst = _blockSpherePool.Get(); for (i = min.X; i <= max.X; ++i) { for (j = min.Y; j <= max.Y; ++j) { for (k = min.Z; k <= max.Z; ++k) { if (i * i + j * j + k * k < radiusSq) { blockSphereLst.Add(new Vector3I(i, j, k)); } } } } blockSphereLst.Sort((a, b) => Vector3I.Dot(a, a).CompareTo(Vector3I.Dot(b, b))); if (gridSizeEnum == MyCubeSize.Large) { LargeBlockSphereDb.Add(radiusInMeters, blockSphereLst); } else { SmallBlockSphereDb.Add(radiusInMeters, blockSphereLst); } }
private void GetIntVectorsInSphere2(MyCubeGrid grid, Vector3I center, double radius) { _slimsSortedList.Clear(); radius *= grid.GridSizeR; var gridMin = grid.Min; var gridMax = grid.Max; double radiusSq = radius * radius; int radiusCeil = (int)Math.Ceiling(radius); int i, j, k; Vector3I max = Vector3I.Min(Vector3I.One * radiusCeil, gridMax - center); Vector3I min = Vector3I.Max(Vector3I.One * -radiusCeil, gridMin - center); for (i = min.X; i <= max.X; ++i) { for (j = min.Y; j <= max.Y; ++j) { for (k = min.Z; k <= max.Z; ++k) { if (i * i + j * j + k * k < radiusSq) { var vector3I = center + new Vector3I(i, j, k); IMySlimBlock slim = grid.GetCubeBlock(vector3I); if (slim != null && slim.Position == vector3I) { var radiatedBlock = new RadiatedBlock { Center = center, Slim = slim, Position = vector3I }; _slimsSortedList.Add(radiatedBlock); } } } } } _slimsSortedList.Sort((a, b) => Vector3I.Dot(a.Position, a.Position).CompareTo(Vector3I.Dot(b.Position, b.Position))); }
public bool IsInCorridor(IMyCubeBlock block) { Vector3I v1 = block.Position - position; return(Vector3I.Dot(v1, Base6Directions.GetIntVector(core.Orientation.Up)) == 0 && Vector3I.Dot(v1, Base6Directions.GetIntVector(core.Orientation.Left)) == 0); }
private new void FixSnapTransformationBase6() { Debug.Assert(CopiedGrids.Count > 0); if (CopiedGrids.Count == 0) { return; } var hitGrid = m_hitEntity as MyCubeGrid; if (hitGrid == null) { return; } // Fix rotation of the first pasted grid Matrix hitGridRotation = hitGrid.WorldMatrix.GetOrientation(); Matrix firstRotation = PreviewGrids[0].WorldMatrix.GetOrientation(); Matrix newFirstRotation = Matrix.AlignRotationToAxes(ref firstRotation, ref hitGridRotation); Matrix rotationDelta = Matrix.Invert(firstRotation) * newFirstRotation; foreach (var grid in PreviewGrids) { Matrix rotation = grid.WorldMatrix.GetOrientation(); rotation = rotation * rotationDelta; Matrix rotationInv = Matrix.Invert(rotation); Vector3D position = m_pastePosition; MatrixD newWorld = MatrixD.CreateWorld(position, rotation.Forward, rotation.Up); Debug.Assert(newWorld.GetOrientation().IsRotation()); grid.PositionComp.SetWorldMatrix(newWorld); } bool smallOnLargeGrid = hitGrid.GridSizeEnum == MyCubeSize.Large && PreviewGrids[0].GridSizeEnum == MyCubeSize.Small; if (smallOnLargeGrid) { Vector3 pasteOffset = TransformLargeGridHitCoordToSmallGrid(m_hitPos, hitGrid.PositionComp.WorldMatrixNormalizedInv, hitGrid.GridSize); m_pastePosition = hitGrid.GridIntegerToWorld(pasteOffset); } else { // Find a collision-free position for the first paste grid along the raycast normal Vector3I collisionTestStep = Vector3I.Round(m_hitNormal); Vector3I pasteOffset = hitGrid.WorldToGridInteger(m_pastePosition); Vector3I previewGridMin = PreviewGrids[0].Min; Vector3I previewGridMax = PreviewGrids[0].Max; Vector3I previewGridSize = previewGridMax - previewGridMin + Vector3I.One; Vector3D previewGridSizeInWorld = Vector3D.TransformNormal((Vector3D)previewGridSize, PreviewGrids[0].WorldMatrix); Vector3I previewGridSizeInHitGrid = Vector3I.Abs(Vector3I.Round(Vector3D.TransformNormal(previewGridSizeInWorld, hitGrid.PositionComp.WorldMatrixNormalizedInv))); int attemptsCount = Math.Abs(Vector3I.Dot(ref collisionTestStep, ref previewGridSizeInHitGrid)); Debug.Assert(attemptsCount > 0); int i; for (i = 0; i < attemptsCount; ++i) { if (hitGrid.CanMergeCubes(PreviewGrids[0], pasteOffset)) { break; } pasteOffset += collisionTestStep; } if (i == attemptsCount) { pasteOffset = hitGrid.WorldToGridInteger(m_pastePosition); } m_pastePosition = hitGrid.GridIntegerToWorld(pasteOffset); } // Move all the grids according to the collision-free position of the first one for (int i = 0; i < PreviewGrids.Count; ++i) { var grid = PreviewGrids[i]; MatrixD matrix = grid.WorldMatrix; matrix.Translation = m_pastePosition + Vector3.Transform(m_copiedGridOffsets[i], rotationDelta); grid.PositionComp.SetWorldMatrix(matrix); } if (MyDebugDrawSettings.DEBUG_DRAW_COPY_PASTE) { MyRenderProxy.DebugDrawLine3D(m_hitPos, m_hitPos + m_hitNormal, Color.Red, Color.Green, false); } }
/// <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; }
public void Dot() { Vector3I a = new Vector3I(1, 2, 3); Vector3I b = new Vector3I(4, 5, 6); double dot = a.Dot(b); Assert.AreEqual(1 * 4 + 2 * 5 + 3 * 6, dot, 1e-14); }