Example #1
0
        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));
        }
Example #2
0
            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);
                }
            }
Example #3
0
        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();
        }
Example #4
0
    // 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);
    }
Example #5
0
        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;
                }
            }
        }
Example #6
0
            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));
        }
Example #8
0
        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;
 }
Example #10
0
 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));
        }
Example #12
0
        /// <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));
            }
        }
Example #13
0
            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);
            }
Example #14
0
 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);
     }
 }
Example #15
0
 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);
     }
 }
Example #16
0
            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);
        }
Example #19
0
        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);
        }
Example #20
0
            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;
                }
            }
Example #21
0
        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));
        }
Example #23
0
 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);
 }
Example #24
0
 //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);
 }
Example #25
0
        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);
        }
Example #26
0
        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());
            }
        }
Example #27
0
        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();
        }
Example #28
0
        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;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Example #29
0
        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);
        }
Example #30
0
 /// <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);
 }