protected bool CanPlaceBlock(Vector3I position, MyCubeBlockDefinition definition, Vector3I forward, Vector3I up) { MyBlockOrientation orientation = new MyBlockOrientation(Base6Directions.GetDirection(forward), Base6Directions.GetDirection(up)); int?ignoreMultiblockId = null; return(this.m_grid.CanPlaceBlock(position, position, orientation, definition, ignoreMultiblockId, false)); }
public void SetYawPitchRoll(float yaw, float pitch, float roll) { for (int i = 0; i < Gyros.Count; i++) { string Axis; float sign; Vector3 RotatedVector = Base6Directions.GetVector(Forward); Vector3.TransformNormal(ref RotatedVector, Gyros[i].Orientation, out RotatedVector); RollAxisDir = Base6Directions.GetDirection(ref RotatedVector); RotatedVector = Base6Directions.GetVector(Left); Vector3.TransformNormal(ref RotatedVector, Gyros[i].Orientation, out RotatedVector); PitchAxisDir = Base6Directions.GetDirection(ref RotatedVector); RotatedVector = Base6Directions.GetVector(Up); Vector3.TransformNormal(ref RotatedVector, Gyros[i].Orientation, out RotatedVector); YawAxisDir = Base6Directions.GetDirection(ref RotatedVector); GetAxisAndDir(RefUp, out Axis, out sign); SetAxis(Gyros[i], Axis, sign * yaw); // Gyros[i].SetValueFloat(Axis, sign * yaw); GetAxisAndDir(RefLeft, out Axis, out sign); SetAxis(Gyros[i], Axis, sign * pitch); // Gyros[i].SetValueFloat(Axis, sign * pitch); GetAxisAndDir(RefForward, out Axis, out sign); SetAxis(Gyros[i], Axis, sign * roll); // Gyros[i].SetValueFloat(Axis, sign * roll); } }
public void SetAilerons(IEnumerable <IMyMotorStator> rotors, float sensitivity, float trim) { m_controlSensitivity.Z = sensitivity; m_trim.Z = trim; List <FlightControlStator> statorList = new List <FlightControlStator>(); foreach (IMyMotorStator stator in rotors) { Vector3 facing = stator.LocalMatrix.Up; if (facing == Pseudo.LocalMatrix.Forward || facing == Pseudo.LocalMatrix.Backward) { Log.AlwaysLog("Facing the wrong way: " + stator.nameWithId() + ", facing: " + facing + ", local flight matrix: " + Pseudo.LocalMatrix, Logger.severity.WARNING); continue; } FlightControlStator flightControl = new FlightControlStator(stator); if (!stator.IsOnSide(facing)) { Log.DebugLog("On " + Base6Directions.GetDirection(-facing) + " side and facing " + Base6Directions.GetDirection(facing)); flightControl.Flip(); } statorList.Add(flightControl); } m_aileron = statorList.ToArray(); }
// TODO: this could use a cache check - so that the calculations not run every cycle // because the thrusters don't change the directions public bool SetDirections() { bool aResult = false; myThrustDirections[Base6Directions.Direction.Forward] = new List <IMyThrust>(); myThrustDirections[Base6Directions.Direction.Backward] = new List <IMyThrust>(); myThrustDirections[Base6Directions.Direction.Left] = new List <IMyThrust>(); myThrustDirections[Base6Directions.Direction.Right] = new List <IMyThrust>(); myThrustDirections[Base6Directions.Direction.Up] = new List <IMyThrust>(); myThrustDirections[Base6Directions.Direction.Down] = new List <IMyThrust>(); foreach (IMyThrust aThruster in mThrusters) { Vector3D aThrustDirection = aThruster.GridThrustDirection; myThrustDirections[Base6Directions.GetDirection(aThrustDirection)].Add(aThruster); } // Note: not sure if this is a good test but for now it will do // When the ship is not under control by a player or a remote control the 'GridThrustDirection' for // all thrusters is always 'Forward' // TODO: this will not work for thrusters not mounted on the main grid - a thruster on a rotor will // not give any usefull results I guess if (myThrustDirections[Base6Directions.Direction.Forward].Count != mThrusters.Count) { aResult = true; } return(aResult); }
private void LoadDummies() { var finalModel = VRage.Game.Models.MyModels.GetModelOnlyDummies(BlockDefinition.Model); foreach (var dummy in finalModel.Dummies) { if (dummy.Key.ToLower().Contains("merge")) { var matrix = dummy.Value.Matrix; Vector3 halfExtents = matrix.Scale / 2.0f; Vector3 projectedPosition = Vector3.DominantAxisProjection(matrix.Translation / halfExtents); projectedPosition.Normalize(); m_forward = Base6Directions.GetDirection(projectedPosition); m_right = Base6Directions.GetPerpendicular(m_forward); var world = MatrixD.Normalize(matrix) * this.WorldMatrix; var detectorShape = CreateFieldShape(halfExtents); Physics = new Sandbox.Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_STATIC); Physics.IsPhantom = true; Physics.CreateFromCollisionObject(detectorShape, matrix.Translation, world, null, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer); Physics.Enabled = IsWorking; Physics.RigidBody.ContactPointCallbackEnabled = true; detectorShape.Base.RemoveReference(); break; } } }
public DataCollectorThruster(Configuration.Options options, string connector) : base("thruster", "", options, connector) { AcceptBlock = (block) => { // IMyThrust.GridThrustDirection // X => 1 == Left, -1 Right // Y => 1 == Down, -1 Up // Z => 1 == Forward, -1 == Backwards if (referenceController_ != null) { // direction Matrix thrusterMatrix; block.Orientation.GetMatrix(out thrusterMatrix); var directionVector = Vector3D.Rotate(thrusterMatrix.Forward, referenceControllerMatrix_); var orientation = Base6Directions.GetDirection(directionVector); if (sameThrusterDirection(orientation) && sameThrusterType(block.DetailedInfo)) { Blocks.Add(block); } } }; }
protected bool CanPlaceBlock(Vector3I position, MyCubeBlockDefinition definition, Vector3I forward, Vector3I up) { Debug.Assert(forward != up); Debug.Assert(forward != Vector3I.Zero); Debug.Assert(up != Vector3I.Zero); MyBlockOrientation blockOrientation = new MyBlockOrientation(Base6Directions.GetDirection(forward), Base6Directions.GetDirection(up)); return(m_grid.CanPlaceBlock(position, position, blockOrientation, definition)); }
protected void AddGeneratedBlock(MySlimBlock refBlock, MyCubeBlockDefinition generatedBlockDefinition, Vector3I position, Vector3I forward, Vector3I up) { MyBlockOrientation orientation = new MyBlockOrientation(Base6Directions.GetDirection(ref forward), Base6Directions.GetDirection(ref up)); if (generatedBlockDefinition.Size == Vector3I.One) { ushort?blockIdInCompound = null; this.m_addLocations.Add(new MyGeneratedBlockLocation(refBlock, generatedBlockDefinition, position, orientation, blockIdInCompound, null)); } }
public MyGeneratedBlockLocation(MySlimBlock refBlock, MyCubeBlockDefinition blockDefinition, Vector3I position, Vector3I forward, Vector3I up, ushort?blockIdInCompound = null, MyGridInfo gridInfo = null) { RefBlock = refBlock; BlockDefinition = blockDefinition; Position = position; Orientation = new MyBlockOrientation(Base6Directions.GetDirection(ref forward), Base6Directions.GetDirection(ref up)); BlockIdInCompound = blockIdInCompound; GridInfo = gridInfo; GeneratedBlockType = MyStringId.NullOrEmpty; }
public MyGeneratedBlockLocation(MySlimBlock refBlock, MyCubeBlockDefinition blockDefinition, Vector3I position, Vector3I forward, Vector3I up, ushort?blockIdInCompound = new ushort?(), MyAdditionalModelGeneratorBase.MyGridInfo gridInfo = null) { this.RefBlock = refBlock; this.BlockDefinition = blockDefinition; this.Position = position; this.Orientation = new MyBlockOrientation(Base6Directions.GetDirection(ref forward), Base6Directions.GetDirection(ref up)); this.BlockIdInCompound = blockIdInCompound; this.GridInfo = gridInfo; this.GeneratedBlockType = MyStringId.NullOrEmpty; }
public Base6Directions.Direction CalculateConnectingDirection(Vector3I connectingPosition) { Vector3 halfExtents = new Vector3(CubeBlock.Max - CubeBlock.Min + Vector3I.One) * 0.5f; Vector3 dirVec = new Vector3(CubeBlock.Max + CubeBlock.Min) * 0.5f; dirVec = dirVec - connectingPosition; dirVec = Vector3.Multiply(dirVec, halfExtents); dirVec = Vector3.DominantAxisProjection(dirVec); dirVec.Normalize(); return(Base6Directions.GetDirection(dirVec)); }
/// <summary> /// Adds generated block to add block locations. /// </summary> protected void AddGeneratedBlock(MySlimBlock refBlock, MyCubeBlockDefinition generatedBlockDefinition, Vector3I position, Vector3I forward, Vector3I up) { Debug.Assert(refBlock != null && !refBlock.BlockDefinition.IsGeneratedBlock); var orientation = new MyBlockOrientation(Base6Directions.GetDirection(ref forward), Base6Directions.GetDirection(ref up)); Debug.Assert(generatedBlockDefinition.Size == Vector3I.One); if (generatedBlockDefinition.Size == Vector3I.One) { m_addLocations.Add(new MyGeneratedBlockLocation(refBlock, generatedBlockDefinition, position, orientation)); } }
public void setup() { piston_.SetValue <float>(Program.PropertyUpperLimit, 10f); piston_.SetValue <float>(Program.PropertyLowerLimit, 0f); piston_.SetValue <bool>(Program.PropertyInertiaTensor, true); piston_.Velocity = 0f; // calculate orientation Vector3D myselfM = piston_.WorldMatrix.Up; myselfM = Vector3D.Rotate(myselfM, Matrix.Invert(parent_.Me.WorldMatrix)); orientation_ = Base6Directions.GetDirection(myselfM); }
public void SetPitch(float pitch) { for (int i = 0; i < Gyros.Count; i++) { string Axis; float sign; Vector3 RotatedVector = Base6Directions.GetVector(Left); Vector3.TransformNormal(ref RotatedVector, Gyros[i].Orientation, out RotatedVector); PitchAxisDir = Base6Directions.GetDirection(ref RotatedVector); GetAxisAndDir(RefLeft, out Axis, out sign); Gyros[i].SetValueFloat(Axis, sign * pitch); } }
public void SetRoll(float roll) { for (int i = 0; i < Gyros.Count; i++) { string Axis; float sign; Vector3 RotatedVector = Base6Directions.GetVector(Forward); Vector3.TransformNormal(ref RotatedVector, Gyros[i].Orientation, out RotatedVector); RollAxisDir = Base6Directions.GetDirection(ref RotatedVector); GetAxisAndDir(RefForward, out Axis, out sign); Gyros[i].SetValueFloat(Axis, sign * roll); } }
public void SetYaw(float yaw) { for (int i = 0; i < Gyros.Count; i++) { string Axis; float sign; Vector3 RotatedVector = Base6Directions.GetVector(Up); Vector3.TransformNormal(ref RotatedVector, Gyros[i].Orientation, out RotatedVector); YawAxisDir = Base6Directions.GetDirection(ref RotatedVector); GetAxisAndDir(RefUp, out Axis, out sign); // Echo("Set axis=" + Azis + " yaw="+yaw.ToString("0.00")+" sign=" + sign); Gyros[i].SetValueFloat(Axis, sign * yaw); } }
protected static bool CheckConnectivityOnGrid(MySlimBlock block, ref MatrixI transform, ref MyGridPlacementSettings settings, MyCubeGrid hitGrid) { Vector3I position; Vector3I.Transform(ref block.Position, ref transform, out position); Vector3I forward = Base6Directions.GetIntVector(transform.GetDirection(block.Orientation.Forward)); Vector3I up = Base6Directions.GetIntVector(transform.GetDirection(block.Orientation.Up)); MyBlockOrientation blockOrientation = new MyBlockOrientation(Base6Directions.GetDirection(forward), Base6Directions.GetDirection(up)); Quaternion rotation; blockOrientation.GetQuaternion(out rotation); return(MyCubeGrid.CheckConnectivity(hitGrid, block.BlockDefinition, ref rotation, ref position)); }
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 static ConveyorLinePosition[] GetLinePositions(MyCubeBlock cubeBlock, IDictionary <string, MyModelDummy> dummies, string dummyName) { var definition = cubeBlock.BlockDefinition; float cubeSize = MyDefinitionManager.Static.GetCubeSize(definition.CubeSize); Vector3 blockCenter = new Vector3(definition.Size) * 0.5f * cubeSize; int count = 0; foreach (var dummy in dummies) { if (dummy.Key.ToLower().Contains(dummyName)) { count++; } } ConveyorLinePosition[] retval = new ConveyorLinePosition[count]; int i = 0; foreach (var dummy in dummies) { if (dummy.Key.ToLower().Contains(dummyName)) { var matrix = dummy.Value.Matrix; ConveyorLinePosition linePosition = new ConveyorLinePosition(); Vector3 doorPosition = matrix.Translation + definition.ModelOffset + blockCenter; Vector3I doorPositionInt = Vector3I.Floor(doorPosition / cubeSize); doorPositionInt = Vector3I.Max(Vector3I.Zero, doorPositionInt); doorPositionInt = Vector3I.Min(definition.Size - Vector3I.One, doorPositionInt); Vector3 cubeCenter = (new Vector3(doorPositionInt) + Vector3.Half) * cubeSize; var direction = Vector3.Normalize(Vector3.DominantAxisProjection(doorPosition - cubeCenter)); linePosition.LocalGridPosition = doorPositionInt - definition.Center; linePosition.Direction = Base6Directions.GetDirection(direction); retval[i] = linePosition; i++; } } return(retval); }
public void SetYaw(float yaw) { // for (int i = 0; i < Gyros.Count; i++) foreach (var gyro in useGyros) { string Axis; float sign; Vector3 RotatedVector = Base6Directions.GetVector(Up); Vector3.TransformNormal(ref RotatedVector, gyro.Orientation, out RotatedVector); YawAxisDir = Base6Directions.GetDirection(ref RotatedVector); GetAxisAndDir(RefUp, out Axis, out sign); // Echo("Set axis=" + Azis + " yaw="+yaw.ToString("0.00")+" sign=" + sign); SetAxis(gyro, Axis, sign * yaw); gyro.Enabled = true; gyro.GyroOverride = true; } }
public void ShipOrientation() { if (_shipControls != null) { var Origin = ((IMyCubeBlock)_shipControls).GetPosition(); var Up = Origin + (((IMyCubeBlock)_shipControls).LocalMatrix.Up); var Forward = Origin + (((IMyCubeBlock)_shipControls).LocalMatrix.Forward); var Left = Origin + (((IMyCubeBlock)_shipControls).LocalMatrix.Left); Vector3D forwardVector = Forward - Origin; Vector3D upVector = Up - Origin; Vector3D leftVector = Left - Origin; leftVector.Normalize(); forwardVector.Normalize(); upVector.Normalize(); _shipUp = Base6Directions.GetDirection(upVector); _shipLeft = Base6Directions.GetDirection(leftVector); } }
protected static bool TestBlockPlacementOnGrid(MySlimBlock block, ref MatrixI transform, ref MyGridPlacementSettings settings, MyCubeGrid hitGrid) { Vector3I positionMin; Vector3I.Transform(ref block.Min, ref transform, out positionMin); Vector3I positionMax; Vector3I.Transform(ref block.Max, ref transform, out positionMax); Vector3I min = Vector3I.Min(positionMin, positionMax); Vector3I max = Vector3I.Max(positionMin, positionMax); Vector3I forward = Base6Directions.GetIntVector(transform.GetDirection(block.Orientation.Forward)); Vector3I up = Base6Directions.GetIntVector(transform.GetDirection(block.Orientation.Up)); MyBlockOrientation blockOrientation = new MyBlockOrientation(Base6Directions.GetDirection(forward), Base6Directions.GetDirection(up)); if (!hitGrid.CanAddCubes(min, max, blockOrientation, block.BlockDefinition)) { return(false); } return(MyCubeGrid.TestPlacementAreaCube(hitGrid, ref settings, min, max, blockOrientation, block.BlockDefinition, ignoredEntity: hitGrid)); }
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); }
//recommended but not necessary, third to call if used (gyro system is set up then) //passing OrientBlock=null will use the grid as reference public void SetRefBlock(IMyTerminalBlock OrientBlock, Base6Directions.Direction DirForward = Forward, Base6Directions.Direction DirUp = Up) { if (Base6Directions.GetAxis(DirForward) == Base6Directions.GetAxis(DirUp)) { DirUp = Base6Directions.GetPerpendicular(DirForward); } if (OrientBlock == null) { } else { Vector3 RotatedVector = Base6Directions.GetVector(DirForward); Vector3.TransformNormal(ref RotatedVector, OrientBlock.Orientation, out RotatedVector); DirForward = Base6Directions.GetDirection(ref RotatedVector); RotatedVector = Base6Directions.GetVector(DirUp); Vector3.TransformNormal(ref RotatedVector, OrientBlock.Orientation, out RotatedVector); DirUp = Base6Directions.GetDirection(ref RotatedVector); } RefUp = DirUp; RefForward = DirForward; RefLeft = Base6Directions.GetLeft(RefUp, RefForward); }
private bool ConnectionAllowedInternal(ref Vector3I faceNormal, MyCubeBlockDefinition def) { if (IsWorking) { return(true); } if (def != this.BlockDefinition) { return(true); } Base6Directions.Direction connectionDirection = Orientation.TransformDirectionInverse(Base6Directions.GetDirection(faceNormal)); if (connectionDirection != m_forward) { return(true); } return(false); }
private void Process(CommandFeedback feedback, IMyCubeGrid grid) { if (grid.CustomName == null || !grid.CustomName.StartsWithICase("EqProcBuild")) { return; } var ob = grid.GetObjectBuilder(true) as MyObjectBuilder_CubeGrid; if (ob == null) { return; } this.Info("Begin processing {0}", grid.CustomName); feedback?.Invoke("Processing {0}", grid.CustomName); try { var dummyDel = new List <MyTuple <MyObjectBuilder_CubeBlock, string> >(); var blockKeep = new List <MyObjectBuilder_CubeBlock>(); var blockMap = new Dictionary <Vector3I, MyObjectBuilder_CubeBlock>(Vector3I.Comparer); foreach (var block in ob.CubeBlocks) { var mount = false; foreach (var name in block.ConfigNames()) { if (!name.StartsWithICase(MountDelegated) && !name.StartsWithICase(ReservedSpaceDelegated)) { continue; } dummyDel.Add(MyTuple.Create(block, name)); mount = true; break; } if (mount) { continue; } var blockMin = (Vector3I)block.Min; Vector3I blockMax; BlockTransformations.ComputeBlockMax(block, out blockMax); for (var rangeItr = new Vector3I_RangeIterator(ref blockMin, ref blockMax); rangeItr.IsValid(); rangeItr.MoveNext()) { blockMap[rangeItr.Current] = block; } blockKeep.Add(block); } this.Info("Found {0} blocks to keep, {1} block mounts to remap", blockKeep.Count, dummyDel.Count); foreach (var pair in dummyDel) { var block = pair.Item1; var useName = pair.Item2; IEnumerable <Base6Directions.Direction> dirs = Base6Directions.EnumDirections; var def = MyDefinitionManager.Static.GetCubeBlockDefinition(pair.Item1); var transform = new MatrixI(block.BlockOrientation); if (def?.MountPoints != null) { var mountDirs = new HashSet <Base6Directions.Direction>(); foreach (var mount in def.MountPoints) { mountDirs.Add(Base6Directions.GetDirection(Vector3I.TransformNormal(mount.Normal, ref transform))); } } var args = useName.Split(' '); var keepArgs = new List <string>(args.Length); foreach (var arg in args) { if (arg.StartsWithICase(PartDummyUtils.ArgumentMountDirection)) { Base6Directions.Direction dir; if (Enum.TryParse(arg.Substring(2), out dir)) { dirs = new[] { transform.GetDirection(Base6Directions.GetOppositeDirection(dir)) } } ; else { this.Error("Failed to parse direction argument \"{0}\"", arg); feedback?.Invoke("Error: Failed to parse direction argument \"{0}\"", arg); } } else { keepArgs.Add(arg); } } useName = string.Join(" ", keepArgs); MyObjectBuilder_CubeBlock outputBlock = null; var outputDir = Base6Directions.Direction.Forward; foreach (var dir in dirs) { MyObjectBuilder_CubeBlock tmp; if (!blockMap.TryGetValue(block.Min + Base6Directions.GetIntVector(dir), out tmp)) { continue; } if (tmp.ConfigNames().Any(x => x.StartsWithICase(MountDelegated))) { continue; } if (outputBlock != null) { this.Error("Multiple directions found for {0}", pair.Item2); feedback?.Invoke("Error: Multiple directions found for {0}", pair.Item2); } outputBlock = tmp; outputDir = dir; } if (outputBlock == null || !ApplyDelegate(ob, block, useName, outputBlock, outputDir)) { this.Error("Failed to find delegated mount point for {0}", pair.Item2); feedback?.Invoke("Error: Failed to find delegated mount point for {0}", pair.Item2); } } ob.CubeBlocks = blockKeep; // Grab related grids! var relatedGrids = new HashSet <IMyCubeGrid> { grid }; var scanRelated = new Queue <IMyCubeGrid>(); var relatedGridController = new Dictionary <IMyCubeGrid, IMyCubeBlock>(); scanRelated.Enqueue(grid); while (scanRelated.Count > 0) { var subGrid = scanRelated.Dequeue(); IMyCubeBlock controllerForThisGrid = null; relatedGridController.TryGetValue(subGrid, out controllerForThisGrid); subGrid.GetBlocks(null, (y) => { var x = y?.FatBlock; if (x == null) { return(false); } var childGrid = (x as IMyMechanicalConnectionBlock)?.TopGrid; if (childGrid != null && relatedGrids.Add(childGrid)) { scanRelated.Enqueue(childGrid); relatedGridController[childGrid] = x.CubeGrid == grid ? x : controllerForThisGrid; } var parentGrid = (x as IMyAttachableTopBlock)?.Base?.CubeGrid; // ReSharper disable once InvertIf if (parentGrid != null && relatedGrids.Add(parentGrid)) { scanRelated.Enqueue(parentGrid); relatedGridController[parentGrid] = x.CubeGrid == grid ? x : controllerForThisGrid; } return(false); }); } relatedGrids.Remove(grid); var removedNoController = relatedGrids.RemoveWhere(x => !relatedGridController.ContainsKey(x)); if (removedNoController > 0) { this.Error("Failed to find the mechanical connection block for all subgrids. {0} will be excluded", removedNoController); feedback?.Invoke("Error: Failed to find the mechanical connection block for all subgrids. {0} will be excluded", removedNoController); } // Need to add reserved space for subgrids so they don't overlap. So compute that. Yay! foreach (var rel in relatedGrids) { IMyCubeBlock root; if (!relatedGridController.TryGetValue(rel, out root)) { this.Error("Unable to find the mechanical connection for grid {0}", rel.CustomName); feedback?.Invoke("Error: Unable to find the mechanical connection for grid {0}", rel.CustomName); continue; } MyObjectBuilder_CubeBlock blockDest; if (blockMap.TryGetValue(root.Min, out blockDest)) { var blockLocal = (MatrixD) new MatrixI(blockDest.BlockOrientation).GetFloatMatrix(); blockLocal.Translation = (Vector3I)blockDest.Min * grid.GridSize; var blockWorld = MatrixD.Multiply(blockLocal, grid.WorldMatrix); var worldAABB = rel.WorldAABB; worldAABB = Utilities.TransformBoundingBox(worldAABB, MatrixD.Invert(blockWorld)); var gridAABB = new BoundingBoxI(Vector3I.Floor(worldAABB.Min / grid.GridSize), Vector3I.Ceiling(worldAABB.Max / grid.GridSize)); var code = $"{PartMetadata.ReservedSpacePrefix} NE:{gridAABB.Min.X}:{gridAABB.Min.Y}:{gridAABB.Min.Z} PE:{gridAABB.Max.X}:{gridAABB.Max.Y}:{gridAABB.Max.Z}"; this.Info("Added reserved space for subgrid {0}: Spec is \"{1}\"", rel.CustomName, code); if (blockDest.Name == null || blockDest.Name.Trim().Length == 0) { blockDest.Name = code; } else { blockDest.Name += PartMetadata.MultiUseSentinel + code; } } else { this.Error("Unable to find the OB for grid block {0} ({1}, {2}, {3}). Is it a delegate?", (root as IMyTerminalBlock)?.CustomName ?? root.Name, root.Min.X, root.Min.Y, root.Min.Z); feedback?.Invoke("Unable to the find OB for grid block {0} ({1}, {2}, {3}). Was it a delegate?", (root as IMyTerminalBlock)?.CustomName ?? root.Name, root.Min.X, root.Min.Y, root.Min.Z); } } var allGrids = new List <MyObjectBuilder_CubeGrid>(relatedGrids.Count + 1) { ob }; allGrids.AddRange(relatedGrids.Select(relGrid => relGrid.GetObjectBuilder(false)).OfType <MyObjectBuilder_CubeGrid>()); // Compose description: TODO I'd love if this actually worked :/ // var storage = new MyPartMetadata(); // storage.InitFromGrids(ob, allGrids); // var data = Convert.ToBase64String(MyAPIGateway.Utilities.SerializeToBinary(storage.GetObjectBuilder())); var defOut = new MyObjectBuilder_PrefabDefinition() { Id = new SerializableDefinitionId(typeof(MyObjectBuilder_PrefabDefinition), grid.CustomName), CubeGrids = allGrids.ToArray() }; var fileName = grid.CustomName + ".sbc"; this.Info("Saving {1} grids as {0}", fileName, defOut.CubeGrids.Length); feedback?.Invoke("Saving {1} grids as {0}", fileName, defOut.CubeGrids.Length); var mishMash = new MyObjectBuilder_Definitions() { Prefabs = new MyObjectBuilder_PrefabDefinition[] { defOut } }; var writer = MyAPIGateway.Utilities.WriteBinaryFileInLocalStorage(fileName, typeof(DesignTools)); var obCode = MyAPIGateway.Utilities.SerializeToXML(mishMash); obCode = obCode.Replace("encoding=\"utf-16\"", "encoding=\"utf-8\""); writer.Write(Encoding.UTF8.GetBytes(obCode)); writer.Close(); } catch (Exception e) { this.Error("Failed to parse. Error:\n{0}", e.ToString()); } }
private void Calculate() { Profiler.StartProfileBlock(); Log.TraceLog("entered"); m_minCell = m_grid.Min - GridPadding; m_maxCell = m_grid.Max + GridPadding; m_sizeCell = m_maxCell - m_minCell + 1; int blockCount = m_grid.BlocksCount; m_data = new AeroCell[m_sizeCell.X, m_sizeCell.Y, m_sizeCell.Z]; DragCoefficient = new Vector3[6]; Init(); if (m_drawDirection.HasValue) { UpdateManager.Register(1, DrawPressureVelocity); m_grid.OnBlockAdded += Unregister; m_grid.OnBlockRemoved += Unregister; m_grid.OnClose += Unregister; } for (int dirIndex = 0; dirIndex < 6; ++dirIndex) { if (m_drawDirection.HasValue) { m_shipDirection = Base6Directions.GetIntVector(m_drawDirection.Value); } else { m_shipDirection = Base6Directions.IntDirections[dirIndex]; } m_defaultData = new AeroCell(1f, -m_shipDirection); m_defaultData.ApplyChanges(); SetDefault(); Vector3[] dragValues = new Vector3[3]; int minSteps = m_sizeCell.AbsMax(); int maxSteps = m_sizeCell.Volume(); int steps = 0; while (true) { if (steps > minSteps) { float changeThreshold = Math.Max(dragValues[0].AbsMax(), 1f) * 0.01f; if (Vector3.RectangularDistance(ref dragValues[0], ref dragValues[1]) < changeThreshold || Vector3.RectangularDistance(ref dragValues[0], ref dragValues[2]) < changeThreshold) { dragValues[0] = (dragValues[0] + dragValues[1]) * 0.5f; Log.DebugLog("Drag is stable at " + dragValues[0] + ", direction: " + Base6Directions.GetDirection(m_shipDirection), Logger.severity.DEBUG); break; } if (steps == maxSteps) { Profiler.EndProfileBlock(); Logger.DebugNotify("Algorithm is unstable", 10000, Logger.severity.ERROR); throw new Exception("Algorithm is unstable"); } } Log.DebugLog("Steps: " + steps + ", current drag: " + dragValues[0] + ", previous drag: " + dragValues[1] + " and " + dragValues[2]); steps++; dragValues[2] = dragValues[1]; dragValues[1] = dragValues[0]; MoveAir(); ApplyAllChanges(); DiffuseAir(); ApplyAllChanges(); CalculateDrag(out dragValues[0]); if (m_grid.BlocksCount != blockCount) { Log.DebugLog("Block count changed from " + blockCount + " to " + m_grid.BlocksCount + ", cannot continue", Logger.severity.INFO); break; } } DragCoefficient[(int)Base6Directions.GetDirection(m_shipDirection)] = dragValues[0]; if (m_drawDirection.HasValue) { break; } } Log.TraceLog("exiting"); Profiler.EndProfileBlock(); }
public void InitPressurization() { IsCubePressurized = new Dictionary <Vector3I, Dictionary <Vector3I, bool> >(); for (int i = 0; i < Size.X; i++) { for (int j = 0; j < Size.Y; j++) { for (int k = 0; k < Size.Z; k++) { Vector3 originalStartOffset = new Vector3(i, j, k); Vector3 originalEndOffset = new Vector3(i, j, k) + Vector3.One; Vector3I intOffset = new Vector3I(i, j, k); IsCubePressurized[intOffset] = new Dictionary <Vector3I, bool>(); foreach (var direction in Base6Directions.IntDirections) { var normal = direction; IsCubePressurized[intOffset][normal] = false; if (normal.X == 1 && i != Size.X - 1) { continue; } if (normal.X == -1 && i != 0) { continue; } if (normal.Y == 1 && j != Size.Y - 1) { continue; } if (normal.Y == -1 && j != 0) { continue; } if (normal.Z == 1 && k != Size.Z - 1) { continue; } if (normal.Z == -1 && k != 0) { continue; } foreach (var mountPoint in MountPoints) { if (normal == mountPoint.Normal) { int wallIndex = MyCubeBlockDefinition.GetMountPointWallIndex(Base6Directions.GetDirection(ref normal)); Vector3I blockSize = Size; Vector3 originalStart = mountPoint.Start; Vector3 originalEnd = mountPoint.End; Vector3 start, end; MyCubeBlockDefinition.UntransformMountPointPosition(ref originalStart, wallIndex, blockSize, out start); MyCubeBlockDefinition.UntransformMountPointPosition(ref originalEnd, wallIndex, blockSize, out end); Vector3 endOffset; Vector3 startOffset; MyCubeBlockDefinition.UntransformMountPointPosition(ref originalStartOffset, wallIndex, blockSize, out startOffset); MyCubeBlockDefinition.UntransformMountPointPosition(ref originalEndOffset, wallIndex, blockSize, out endOffset); Vector3 eo = new Vector3(Math.Max(startOffset.X, endOffset.X), Math.Max(startOffset.Y, endOffset.Y), Math.Max(startOffset.Z, endOffset.Z)); Vector3 so = new Vector3(Math.Min(startOffset.X, endOffset.X), Math.Min(startOffset.Y, endOffset.Y), Math.Min(startOffset.Z, endOffset.Z)); if (start.X - 0.05 <= so.X && end.X + 0.05 > eo.X && start.Y - 0.05 <= so.Y && end.Y + 0.05 > eo.Y) { IsCubePressurized[intOffset][normal] = true; break; } } } } } } } }
public override bool DebugDraw() { if (MyDebugDrawSettings.DEBUG_DRAW_CONNECTORS_AND_MERGE_BLOCKS) { Matrix WorldMatrix = m_shipMergeBlock.PositionComp.WorldMatrix; MyRenderProxy.DebugDrawLine3D(m_shipMergeBlock.Physics.RigidBody.Position, m_shipMergeBlock.Physics.RigidBody.Position + m_shipMergeBlock.WorldMatrix.Right, Color.Green, Color.Green, false); MyRenderProxy.DebugDrawSphere(Vector3.Transform(m_shipMergeBlock.Position * m_shipMergeBlock.CubeGrid.GridSize, Matrix.Invert(m_shipMergeBlock.WorldMatrix)), 1, Color.Green, 1, false); MyRenderProxy.DebugDrawSphere(m_shipMergeBlock.WorldMatrix.Translation, 0.2f, m_shipMergeBlock.InConstraint ? Color.Yellow : Color.Orange, 1, false); if (m_shipMergeBlock.InConstraint) { MyRenderProxy.DebugDrawSphere(m_shipMergeBlock.Other.WorldMatrix.Translation, 0.2f, Color.Yellow, 1, false); MyRenderProxy.DebugDrawLine3D(m_shipMergeBlock.WorldMatrix.Translation, m_shipMergeBlock.Other.WorldMatrix.Translation, Color.Yellow, Color.Yellow, false); } MyRenderProxy.DebugDrawLine3D(WorldMatrix.Translation, WorldMatrix.Translation + m_shipMergeBlock.CubeGrid.WorldMatrix.GetDirectionVector(Base6Directions.GetDirection(m_shipMergeBlock.PositionComp.LocalMatrix.Right)), Color.Red, Color.Red, false); MyRenderProxy.DebugDrawLine3D(WorldMatrix.Translation, WorldMatrix.Translation + m_shipMergeBlock.CubeGrid.WorldMatrix.GetDirectionVector(Base6Directions.GetDirection(m_shipMergeBlock.PositionComp.LocalMatrix.Up)), Color.Green, Color.Green, false); MyRenderProxy.DebugDrawLine3D(WorldMatrix.Translation, WorldMatrix.Translation + m_shipMergeBlock.CubeGrid.WorldMatrix.GetDirectionVector(Base6Directions.GetDirection(m_shipMergeBlock.PositionComp.LocalMatrix.Backward)), Color.Blue, Color.Blue, false); MyRenderProxy.DebugDrawLine3D(WorldMatrix.Translation, WorldMatrix.Translation + m_shipMergeBlock.CubeGrid.WorldMatrix.GetDirectionVector(m_shipMergeBlock.OtherRight), Color.Violet, Color.Violet, false); MyRenderProxy.DebugDrawText3D(WorldMatrix.Translation, "Bodies: " + m_shipMergeBlock.GridCount, Color.White, 1.0f, false); if (m_shipMergeBlock.Other != null) { float x = (float)Math.Exp(-((WorldMatrix.Translation - m_shipMergeBlock.Other.WorldMatrix.Translation).Length() - m_shipMergeBlock.CubeGrid.GridSize) * 6.0f); MyRenderProxy.DebugDrawText3D(WorldMatrix.Translation + m_shipMergeBlock.CubeGrid.WorldMatrix.GetDirectionVector(Base6Directions.GetDirection(m_shipMergeBlock.PositionComp.LocalMatrix.Up)) * 0.5f, x.ToString("0.00"), Color.Red, 1.0f, false); } } return(true); }
/// <summary> /// Determines if the ship has enough force to accelerate forward. Checks against gravity. /// </summary> /// <param name="acceleration">The ammount of acceleration required, in m/s/s</param> public bool CanMoveForward(float acceleration = 1f) { Update(); return(GetForceInDirection(Base6Directions.GetDirection(Standard.LocalMatrix.Forward), true) > Grid.Physics.Mass * acceleration); }