public void Init(ZACommons commons, EventDriver eventDriver, double maxError, Base6Directions.Direction thrusterDirection = Base6Directions.Direction.Forward) { MaxError = maxError; ThrusterDirection = thrusterDirection; var shipControl = (ShipControlCommons)commons; var forward = shipControl.ShipBlockOrientation.TransformDirection(ThrusterDirection); // Don't really care about "up," just pick a perpindicular direction seeker.Init(shipControl, shipUp: Base6Directions.GetPerpendicular(forward), shipForward: forward); var gyroControl = shipControl.GyroControl; gyroControl.Reset(); gyroControl.EnableOverride(true); LastPosition = shipControl.ReferencePoint; Enabled = true; shipControl.ThrustControl.Enable(false); eventDriver.Schedule(SampleDelay, DetermineVelocity); }
public void Init(ShipControlCommons shipControl, Base6Directions.Direction shipUp = Base6Directions.Direction.Up, Base6Directions.Direction shipForward = Base6Directions.Direction.Forward) { ShipForward = shipForward; ShipUp = shipUp; ShipLeft = Base6Directions.GetLeft(ShipUp, ShipForward); var small = shipControl.Reference.CubeGrid.GridSize == 0.5f; yawPID.Kp = small ? SmallGyroKp : LargeGyroKp; yawPID.Ti = small ? SmallGyroTi : LargeGyroTi; yawPID.Td = small ? SmallGyroTd : LargeGyroTd; pitchPID.Kp = small ? SmallGyroKp : LargeGyroKp; pitchPID.Ti = small ? SmallGyroTi : LargeGyroTi; pitchPID.Td = small ? SmallGyroTd : LargeGyroTd; rollPID.Kp = small ? SmallGyroKp : LargeGyroKp; rollPID.Ti = small ? SmallGyroTi : LargeGyroTi; rollPID.Td = small ? SmallGyroTd : LargeGyroTd; yawPID.Reset(); pitchPID.Reset(); rollPID.Reset(); }
public List<IMyThrust> GetThrusters(Base6Directions.Direction direction, Func<IMyThrust, bool> collect = null, bool disable = false) { List<IMyThrust> thrusterList; if (!thrusters.TryGetValue(direction, out thrusterList)) { thrusterList = new List<IMyThrust>(); thrusters.Add(direction, thrusterList); } if (collect == null) { return thrusterList; } else { var result = new List<IMyThrust>(); for (var e = thrusterList.GetEnumerator(); e.MoveNext();) { var thruster = (IMyThrust)e.Current; if (collect(thruster)) { result.Add(thruster); } else if (disable) { thruster.SetValue<bool>("OnOff", false); } } return result; } }
private void SetAxisDetails(IMyGyro gyro, int axis, Base6Directions.Direction axisDirection) { switch (gyro.Orientation.TransformDirectionInverse(axisDirection)) { case Base6Directions.Direction.Up: AxisDetails[axis] = new GyroAxisDetails(Yaw, -1); break; case Base6Directions.Direction.Down: AxisDetails[axis] = new GyroAxisDetails(Yaw, 1); break; case Base6Directions.Direction.Left: AxisDetails[axis] = new GyroAxisDetails(Pitch, -1); break; case Base6Directions.Direction.Right: AxisDetails[axis] = new GyroAxisDetails(Pitch, 1); break; case Base6Directions.Direction.Forward: AxisDetails[axis] = new GyroAxisDetails(Roll, 1); break; case Base6Directions.Direction.Backward: AxisDetails[axis] = new GyroAxisDetails(Roll, -1); break; } }
public void SetLauncherReference(IMyCubeBlock launcherReference, Base6Directions.Direction direction = Base6Directions.Direction.Forward) { LauncherReferencePoint = launcherReference.GetPosition(); var forward3I = launcherReference.Position + Base6Directions.GetIntVector(launcherReference.Orientation.TransformDirection(direction)); var forwardPoint = launcherReference.CubeGrid.GridIntegerToWorld(forward3I); LauncherReferenceDirection = Vector3D.Normalize(forwardPoint - LauncherReferencePoint); }
public void Init(ShipControlCommons shipControl, Base6Directions.Direction localForward = Base6Directions.Direction.Forward) { LocalForward = localForward; LocalBackward = Base6Directions.GetFlippedDirection(LocalForward); thrustPID.Reset(); }
public void SetOverride(Base6Directions.Direction direction, bool enable = true, Func<IMyThrust, bool> collect = null) { var thrusterList = GetThrusters(direction, collect, true); thrusterList.ForEach(thruster => thruster.SetValue<float>("Override", enable ? thruster.GetMaximum<float>("Override") : 0.0f)); }
public void SetOverride(Base6Directions.Direction direction, double percent, Func<IMyThrust, bool> collect = null) { percent = Math.Max(percent, 0.0); percent = Math.Min(percent, 1.0); var thrusterList = GetThrusters(direction, collect, true); thrusterList.ForEach(thruster => thruster.SetValue<float>("Override", (float)(thruster.GetMaximum<float>("Override") * percent))); }
public void Init(ZACommons commons, EventDriver eventDriver, Vector3D target, double speed, double delay = 1.0, Action<ZACommons, EventDriver> doneAction = null, Base6Directions.Direction localForward = Base6Directions.Direction.Forward) { if (!AutopilotEngaged) { AutopilotTarget = target; AutopilotSpeed = speed; AutopilotEngaged = true; DoneAction = doneAction; LocalForward = localForward; eventDriver.Schedule(delay, Start); } }
public GyroDetails(IMyGyro gyro, Base6Directions.Direction shipUp, Base6Directions.Direction shipForward) { Gyro = gyro; AxisDetails = new GyroAxisDetails[3]; var shipLeft = Base6Directions.GetLeft(shipUp, shipForward); // Determine yaw axis SetAxisDetails(gyro, Yaw, shipUp); // Determine pitch axis SetAxisDetails(gyro, Pitch, shipLeft); // Determine roll axis SetAxisDetails(gyro, Roll, shipForward); }
public void Init(IEnumerable<IMyTerminalBlock> blocks, Func<IMyGyro, bool> collect = null, Base6Directions.Direction shipUp = Base6Directions.Direction.Up, Base6Directions.Direction shipForward = Base6Directions.Direction.Forward) { gyros.Clear(); for (var e = blocks.GetEnumerator(); e.MoveNext();) { var gyro = e.Current as IMyGyro; if (gyro != null && gyro.IsFunctional && gyro.IsWorking && gyro.Enabled && (collect == null || collect(gyro))) { var details = new GyroDetails(gyro, shipUp, shipForward); gyros.Add(details); } } }
public IMyTerminalBlock SetLauncherReference(ZACommons commons, string groupName, Base6Directions.Direction direction = Base6Directions.Direction.Forward, Func<IMyTerminalBlock, bool> condition = null) { var group = commons.GetBlockGroupWithName(groupName); if (group != null) { for (var e = group.Blocks.GetEnumerator(); e.MoveNext();) { var block = e.Current; if (condition == null || condition(block)) { // Use first block that matches condition SetLauncherReference(block, direction); return block; } } } throw new Exception("Cannot set launcher reference from group: " + groupName); }
public void Init(IEnumerable<IMyTerminalBlock> blocks, Func<IMyThrust, bool> collect = null, Base6Directions.Direction shipUp = Base6Directions.Direction.Up, Base6Directions.Direction shipForward = Base6Directions.Direction.Forward) { MyBlockOrientation shipOrientation = new MyBlockOrientation(shipForward, shipUp); thrusters.Clear(); for (var e = blocks.GetEnumerator(); e.MoveNext();) { var thruster = e.Current as IMyThrust; if (thruster != null && thruster.IsFunctional && (collect == null || collect(thruster))) { var facing = thruster.Orientation.TransformDirection(Base6Directions.Direction.Forward); // Exhaust goes this way var thrustDirection = Base6Directions.GetFlippedDirection(facing); var shipDirection = shipOrientation.TransformDirectionInverse(thrustDirection); AddThruster(shipDirection, thruster); } } }
public static Vector3D Transform(this Vector3D vector, SerializableBlockOrientation orientation) { var matrix = MatrixD.CreateFromDir(Base6Directions.GetVector(orientation.Forward), Base6Directions.GetVector(orientation.Up)); return(Vector3D.Transform(vector, matrix)); }
public static Quaternion ToQuaternion(this SerializableBlockOrientation blockOrientation) { var matrix = Matrix.CreateFromDir(Base6Directions.GetVector(blockOrientation.Forward), Base6Directions.GetVector(blockOrientation.Up)); return(Quaternion.CreateFromRotationMatrix(matrix)); }
protected bool GetBlockAddPosition(float gridSize, bool placingSmallGridOnLargeStatic, out MySlimBlock intersectedBlock, out Vector3D intersectedBlockPos, out Vector3D intersectExactPos, out Vector3I addPositionBlock, out Vector3I addDirectionBlock, out ushort?compoundBlockId) { intersectedBlock = null; intersectedBlockPos = new Vector3D(); intersectExactPos = new Vector3(); addDirectionBlock = new Vector3I(); addPositionBlock = new Vector3I(); compoundBlockId = null; if (CurrentVoxelBase != null) { Vector3 hitInfoNormal = m_hitInfo.Value.HkHitInfo.Normal; Base6Directions.Direction closestDir = Base6Directions.GetClosestDirection(hitInfoNormal); Vector3I hitNormal = Base6Directions.GetIntVector(closestDir); double distance = IntersectionDistance * m_hitInfo.Value.HkHitInfo.HitFraction; Vector3D rayStart = IntersectionStart; Vector3D rayDir = Vector3D.Normalize(IntersectionDirection); Vector3D intersection = rayStart + distance * rayDir; // Get cube block placement position (add little threshold to hit normal direction to avoid wavy surfaces). addPositionBlock = MyCubeGrid.StaticGlobalGrid_WorldToUGInt(intersection + 0.1f * Vector3.Half * hitNormal * gridSize, gridSize, CubeBuilderDefinition.BuildingSettings.StaticGridAlignToCenter); addDirectionBlock = hitNormal; intersectedBlockPos = addPositionBlock - hitNormal; // Exact intersection in uniform grid coords. intersectExactPos = MyCubeGrid.StaticGlobalGrid_WorldToUG(intersection, gridSize, CubeBuilderDefinition.BuildingSettings.StaticGridAlignToCenter); // Project exact intersection to cube face of intersected block. intersectExactPos = ((Vector3.One - Vector3.Abs(hitNormal)) * intersectExactPos) + ((intersectedBlockPos + 0.5f * hitNormal) * Vector3.Abs(hitNormal)); return(true); } Vector3D?intersectedObjectPos = GetIntersectedBlockData(ref m_invGridWorldMatrix, out intersectExactPos, out intersectedBlock, out compoundBlockId); if (intersectedObjectPos == null) { return(false); } intersectedBlockPos = intersectedObjectPos.Value; Vector3I removePos; if (!GetCubeAddAndRemovePositions(Vector3I.Round(intersectedBlockPos), placingSmallGridOnLargeStatic, out addPositionBlock, out addDirectionBlock, out removePos)) { return(false); } if (!placingSmallGridOnLargeStatic) { if (MyFakes.ENABLE_BLOCK_PLACING_ON_INTERSECTED_POSITION) { Vector3I newRemovepos = Vector3I.Round(intersectedBlockPos); if (newRemovepos != removePos) { if (m_hitInfo.HasValue) { Vector3 hitInfoNormal = m_hitInfo.Value.HkHitInfo.Normal; Base6Directions.Direction closestDir = Base6Directions.GetClosestDirection(hitInfoNormal); Vector3I hitNormal = Base6Directions.GetIntVector(closestDir); addDirectionBlock = hitNormal; } removePos = newRemovepos; addPositionBlock = removePos + addDirectionBlock; } } else { if (CurrentGrid.CubeExists(addPositionBlock)) { return(false); } } } if (placingSmallGridOnLargeStatic) { removePos = Vector3I.Round(intersectedBlockPos); } intersectedBlockPos = removePos; intersectedBlock = CurrentGrid.GetCubeBlock(removePos); if (intersectedBlock == null) { Debug.Assert(false, "No intersected block"); return(false); } return(true); }
private Vector3D GetReferenceVector(ShipControlCommons shipControl, Base6Directions.Direction direction) { var offset = shipControl.Reference.Position + Base6Directions.GetIntVector(direction); return Vector3D.Normalize(shipControl.Reference.CubeGrid.GridIntegerToWorld(offset) - shipControl.ReferencePoint); }
// Last-ditch check before inducing spin private bool HaveWorkingThrusters2(ShipControlCommons shipControl, Base6Directions.Direction direction) { var found = false; var thrusters = shipControl.ThrustControl.GetThrusters(direction); thrusters.ForEach(thruster => { if (thruster.IsWorking) { // Really make sure it isn't overridden thruster.SetValue<float>("Override", 0.0f); found = true; } }); return found; }
/// <summary> /// Solves the required thrusts to go in targetDirection at max speed. This takes gravity into account. /// </summary> /// <param name="g">Gravity and unknown forces</param> /// <param name="targetDirection">The target direction to go in</param> /// <param name="maxPercentageThrustToUse">The maximum amount of thrust devoted to going in the target direction.</param> /// <returns></returns> public ThrusterGroup SolveMaxThrust(Vector3D minus_g, Vector3D targetDirection, double maxPercentageThrustToUse = 1) { //parent_program.Echo("Starting"); Base6Directions.Direction actual2Di; Base6Directions.Direction actual3Di; double t2c; double t3c; double Lambda; ThrusterGroup t1; ThrusterGroup t2; ThrusterGroup t3; if (maxPercentageThrustToUse > 1) { maxPercentageThrustToUse = 1; } else if (maxPercentageThrustToUse < 0) { maxPercentageThrustToUse = 0; } foreach (var entry in thrusterGroups) { //parent_program.Echo("Loading " + entry.Key.ToString()); t1 = entry.Value; if (t1.LocalThrustDirection == Base6Directions.Direction.Up || t1.LocalThrustDirection == Base6Directions.Direction.Down) { t2 = thrusterGroups[Base6Directions.Direction.Left]; t3 = thrusterGroups[Base6Directions.Direction.Forward]; } else if (t1.LocalThrustDirection == Base6Directions.Direction.Left || t1.LocalThrustDirection == Base6Directions.Direction.Right) { t2 = thrusterGroups[Base6Directions.Direction.Up]; t3 = thrusterGroups[Base6Directions.Direction.Forward]; } else if (t1.LocalThrustDirection == Base6Directions.Direction.Forward || t1.LocalThrustDirection == Base6Directions.Direction.Backward) { t2 = thrusterGroups[Base6Directions.Direction.Up]; t3 = thrusterGroups[Base6Directions.Direction.Left]; } else { parent_program.shipIOHandler.Error( "Encountered unusual thruster direction.\nIf you've gotten this error in particular,\nplease report it to the script owner, Spug."); t2 = thrusterGroups[Base6Directions.Direction.Up]; t3 = thrusterGroups[Base6Directions.Direction.Left]; } //var mat = new double[,] { //{ t2.WorldThrustDirection.X, t3.WorldThrustDirection.X, -targetDirection.X }, //{ t2.WorldThrustDirection.Y, t3.WorldThrustDirection.Y, -targetDirection.Y }, //{ t2.WorldThrustDirection.Z, t3.WorldThrustDirection.Z, -targetDirection.Z }, //}; t1.matrixM[0, 0] = t2.WorldThrustDirection.X; t1.matrixM[0, 1] = t3.WorldThrustDirection.X; t1.matrixM[0, 2] = -targetDirection.X; t1.matrixM[1, 0] = t2.WorldThrustDirection.Y; t1.matrixM[1, 1] = t3.WorldThrustDirection.Y; t1.matrixM[1, 2] = -targetDirection.Y; t1.matrixM[2, 0] = t2.WorldThrustDirection.Z; t1.matrixM[2, 1] = t3.WorldThrustDirection.Z; t1.matrixM[2, 2] = -targetDirection.Z; t1.ANS[0] = -t1.MaxThrust * t1.WorldThrustDirection.X * maxPercentageThrustToUse - minus_g.X; t1.ANS[1] = -t1.MaxThrust * t1.WorldThrustDirection.Y * maxPercentageThrustToUse - minus_g.Y; t1.ANS[2] = -t1.MaxThrust * t1.WorldThrustDirection.Z * maxPercentageThrustToUse - minus_g.Z; PID.ComputeCoefficients(t1.matrixM, t1.ANS); t2c = t1.ANS[0]; t3c = t1.ANS[1]; Lambda = t1.ANS[2]; actual2Di = t2.LocalThrustDirection; actual3Di = t3.LocalThrustDirection; if (t2c < 0) { actual2Di = Base6Directions.GetOppositeDirection(t2.LocalThrustDirection); t2c *= -1; } if (t3c < 0) { actual3Di = Base6Directions.GetOppositeDirection(t3.LocalThrustDirection); t3c *= -1; } //// Publish the results t1.finalThrustForces.X = t1.MaxThrust * maxPercentageThrustToUse; t1.finalThrustForces.Y = t2c; t1.finalThrustForces.Z = t3c; t1.lambdaResult = Lambda; t1.finalThrusterGroups[0] = t1; t1.finalThrusterGroups[1] = thrusterGroups[actual2Di]; t1.finalThrusterGroups[2] = thrusterGroups[actual3Di]; t1.finalThrusterGroups[3] = thrusterGroups[Base6Directions.GetOppositeDirection(t1.LocalThrustDirection)]; t1.finalThrusterGroups[4] = thrusterGroups[Base6Directions.GetOppositeDirection(t2.LocalThrustDirection)]; t1.finalThrusterGroups[5] = thrusterGroups[Base6Directions.GetOppositeDirection(t3.LocalThrustDirection)]; //parent_program.Echo("Completed " + entry.Key.ToString()); } ThrusterGroup bestCandidate = null; double bestCandidateLambda = -999999999; foreach (var entry in thrusterGroups) { if (entry.Value.lambdaResult > bestCandidateLambda) { if (entry.Value.finalThrustForces.Y <= entry.Value.finalThrusterGroups[1].MaxThrust + 1 && entry.Value.finalThrustForces.Z <= entry.Value.finalThrusterGroups[2].MaxThrust + 1) { bestCandidate = entry.Value; bestCandidateLambda = entry.Value.lambdaResult; } } } //parent_program.Echo("Finished"); //parent_program.Echo("Best: " + bestCandidate.LocalThrustDirection.ToString()); return(bestCandidate); }
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)); }
private void AddThruster(Base6Directions.Direction direction, IMyThrust thruster) { var thrusterList = GetThrusters(direction); // collect must be null to modify original list thrusterList.Add(thruster); }
public void Main(string argument, UpdateType updateSource) { string[] argInfo = argument.Split(new string[] { "," }, StringSplitOptions.None); if (argument == "RUN") { //Check if can scan, and scan if can. if (cam.CanScan(rayCastDistance)) { detectedInfo = cam.Raycast(rayCastDistance); } else { Echo("Can't scan yet!"); } Echo("INITIATING"); coordinate = Vector3D.Zero; //initating to zero value. Boolean found = false; if (detectedInfo.HitPosition != null) { coordinate = detectedInfo.HitPosition.Value; found = true; } if (found) { Vector3D currentCoords = rc.GetPosition(); //creating unit vector double denominator = Math.Sqrt(Math.Pow(coordinate.X - currentCoords.X, 2) + Math.Pow(coordinate.Y - currentCoords.Y, 2) + Math.Pow(coordinate.Z - currentCoords.Z, 2)); double xMultiplier = (coordinate.X - currentCoords.X) / denominator; double yMultiplier = (coordinate.Y - currentCoords.Y) / denominator; double zMultiplier = (coordinate.Z - currentCoords.Z) / denominator; //manipulating target coordinate with unit vector coordinate.X -= finalDistFromTarget * xMultiplier; coordinate.Y -= finalDistFromTarget * yMultiplier; coordinate.Z -= finalDistFromTarget * zMultiplier; //Setting up backward thrusters list backwardThrusters = new List <IMyThrust>(); //Obtaining each thruster pointing backward foreach (IMyThrust thruster in thrusters) { if (Base6Directions.GetFlippedDirection(rc.Orientation.Forward) == Base6Directions.GetFlippedDirection(thruster.Orientation.Forward)) { backwardThrusters.Add(thruster); } } //Obtaining max backward acceleration MyShipMass myShipMass = rc.CalculateShipMass(); backwardsAcceleration = CalculateAcceleration(myShipMass.TotalMass, backwardThrusters); //autopilot settings rc.ClearWaypoints(); rc.AddWaypoint(coordinate, "AUTO DYNAMIC BRAKING SCRIPT COORDINATE"); rc.SetAutoPilotEnabled(true); rc.SetCollisionAvoidance(false); rc.SetDockingMode(false); //CHANGE??? or dont? rc.FlightMode = FlightMode.OneWay; rc.Direction = Base6Directions.Direction.Forward; blindMode = false; } } else if (argInfo[0] == "blind".ToLower()) { int dist = 0; Boolean passed = Int32.TryParse(argInfo[1], out dist); if (passed) { Vector3D dir = rc.WorldMatrix.Forward; coordinate = rc.GetPosition(); coordinate.X += dir.X * dist; coordinate.Y += dir.Y * dist; coordinate.Z += dir.Z * dist; Vector3D currentCoords = rc.GetPosition(); //Setting up backward thrusters list backwardThrusters = new List <IMyThrust>(); //Obtaining each thruster pointing backward foreach (IMyThrust thruster in thrusters) { if (Base6Directions.GetFlippedDirection(rc.Orientation.Forward) == Base6Directions.GetFlippedDirection(thruster.Orientation.Forward)) { backwardThrusters.Add(thruster); } } //Obtaining max backward acceleration MyShipMass myShipMass = rc.CalculateShipMass(); backwardsAcceleration = CalculateAcceleration(myShipMass.TotalMass, backwardThrusters); //autopilot settings rc.ClearWaypoints(); rc.AddWaypoint(coordinate, "CAPTXAN'S SCRIPT COORDINATE"); rc.SetAutoPilotEnabled(true); rc.SetCollisionAvoidance(false); rc.SetDockingMode(false); //CHANGE??? or dont? rc.FlightMode = FlightMode.OneWay; rc.Direction = Base6Directions.Direction.Forward; blindMode = true; blindCounter = 0; } else { Echo("2nd parameter is not a number!"); } } else { //User Feedback if (!cam.CanScan(rayCastDistance)) { float percentage = ((cam.TimeUntilScan(rayCastDistance) / 1000) / (rayCastDistance / 2000)); percentage = (1 - percentage) * 100; Echo("Raycast is recharging " + percentage + "%"); if (!cam.EnableRaycast) { cam.EnableRaycast = true; } } else { Echo("Ready to Scan"); cam.EnableRaycast = false; } //Travelling CHANGE HERE FOR ENABLE / DISABLE AUTOPILOT if (rc.IsAutoPilotEnabled) { travelling = true; double currentDistanceFromTarget = Vector3D.Distance(coordinate, rc.GetPosition()); Echo("Travelling, ETA: " + (int)(currentDistanceFromTarget / rc.GetShipSpeed()) + "s"); //Calculating stopping distance to determine if thrusters need to be enabled. Echo("Current Speed: " + (int)rc.GetShipSpeed() + "m/s"); Echo("Ship Speed Limit: " + rc.SpeedLimit + "m/s"); if (rc.GetShipSpeed() > rc.SpeedLimit - 1) //If ship at max speed { Vector3D currentTrajectory = Vector3D.Normalize(rc.GetPosition() - prevPosition); prevPosition = rc.GetPosition(); Vector3D calculatedTrajectory = Vector3D.Normalize(rc.GetPosition() - coordinate); double accuracyAmount; if (currentDistanceFromTarget > 15000) { accuracyAmount = .99999; } else if (currentDistanceFromTarget > 5000) { accuracyAmount = .9999; } else { accuracyAmount = .999; } if (currentDistanceFromTarget * .90 > (Math.Pow(rc.GetShipSpeed(), 2) / (2 * backwardsAcceleration)) && Math.Abs(currentTrajectory.Dot(calculatedTrajectory)) > accuracyAmount) { foreach (IMyThrust thruster in thrusters) { thruster.ApplyAction("OnOff_Off"); } } else //Curr < stopp { foreach (IMyThrust thruster in thrusters) { thruster.ApplyAction("OnOff_On"); } } } Echo("Blind Mode: " + blindMode); if (blindMode) { Echo("Blind Counter: " + blindCounter); Echo("Coll Avoid: " + rc.); if (cam.CanScan(((Math.Pow(rc.GetShipSpeed(), 2) / (2 * backwardsAcceleration)) * 2))) { detectedInfo = cam.Raycast((Math.Pow(maxSpeed, 2) / (2 * backwardsAcceleration)) * 2); if (detectedInfo.HitPosition != null) { rc.SpeedLimit = 3; rc.SetCollisionAvoidance(true); blindCounter = 0; } else { if (blindCounter > 500) { rc.SpeedLimit = maxSpeed; rc.SetCollisionAvoidance(false); blindCounter = 0; } else { blindCounter++; } } } } } else if (travelling) { foreach (IMyThrust thruster in thrusters) { thruster.ApplyAction("OnOff_On"); } travelling = false; blindMode = false; } } //Additional Arugment Commands if (argument == "ABORT") { rc.SetAutoPilotEnabled(false); rc.DampenersOverride = true; } }
public void Main(string argument, UpdateType updateSource) { List <IMyGyro> gyros = new List <IMyGyro>(); GridTerminalSystem.GetBlocksOfType <IMyGyro>(gyros); if (Me.CustomData.Length > 0) { string[] strs = Me.CustomData.Split(' '); Vector3 desiredAngleSpeed = new Vector3(float.Parse(strs[0]), float.Parse(strs[1]), float.Parse(strs[2])); foreach (var gyro in gyros) { try { gyro.Pitch = -desiredAngleSpeed.Dot(Base6Directions.GetVector(gyro.Orientation.Left)) * 60; gyro.Yaw = desiredAngleSpeed.Dot(Base6Directions.GetVector(gyro.Orientation.Up)) * 60; gyro.Roll = -desiredAngleSpeed.Dot(Base6Directions.GetVector(gyro.Orientation.Forward)) * 60; } catch (Exception e) { Echo(e.StackTrace); } } } else { foreach (var gyro in gyros) { if (gyro.GyroOverride) { Echo(gyro.CustomName); Vector3I forward = Base6Directions.GetIntVector(gyro.Orientation.Forward); Echo(string.Format("FW: {0:0.0} {1:0.0} {2:0.0}", forward.X, forward.Y, forward.Z)); Vector3I up = Base6Directions.GetIntVector(gyro.Orientation.Up); Echo(string.Format("UP: {0:0.0} {1:0.0} {2:0.0}", up.X, up.Y, up.Z)); Vector3I left = Base6Directions.GetIntVector(gyro.Orientation.Left); Echo(string.Format("LF: {0:0.0} {1:0.0} {2:0.0}", left.X, left.Y, left.Z)); } } } List <IMyShipController> controllers = new List <IMyShipController>(); GridTerminalSystem.GetBlocksOfType(controllers); foreach (var controller in controllers) { Vector3 speeds = controller.GetShipVelocities().AngularVelocity; Echo(controller.CustomName); Echo(string.Format("SPDS: {0:0.0} {1:0.0} {2:0.0}", speeds.X, speeds.Y, speeds.Z)); /*Quaternion quat = Quaternion.CreateFromYawPitchRoll( speeds.X, speeds.Y, speeds.Z ); * Echo( string.Format( "QUAT: {0:0.0} {1:0.0} {2:0.0} {3:0.0}", quat.X, quat.Y, quat.Z, quat.W ) );*/ } /*Quaternion thisQuat = Quaternion.CreateFromRotationMatrix( Me.CubeGrid.WorldMatrix ); * * var quatDiff = Quaternion.Divide( thisQuat, previousQuat ); * * previousQuat = thisQuat; * * Echo("Calcualted: "); * Echo( string.Format( "QUAT: {0:0.00} {1:0.00} {2:0.00} {3:0.00}", thisQuat.X, thisQuat.Y, thisQuat.Z, thisQuat.W ) ); * Echo( string.Format( "DIFF: {0:0.00} {1:0.00} {2:0.00} {3:0.00}", quatDiff.X, quatDiff.Y, quatDiff.Z, quatDiff.W ) ); * */ }
private Vector3D GetReferenceVector(Base6Directions.Direction direction) { var offset = Reference.Position + Base6Directions.GetIntVector(direction); return Vector3D.Normalize(Reference.CubeGrid.GridIntegerToWorld(offset) - ReferencePoint); }
private bool HaveWorkingThrusters(ShipControlCommons shipControl, Base6Directions.Direction direction) { // First pass: Look for a working, non-overridden thruster var found = false; var overridden = new List<IMyThrust>(); var thrusters = shipControl.ThrustControl.GetThrusters(direction); thrusters.ForEach(thruster => { if (thruster.IsWorking) { if (thruster.GetValue<float>("Override") > 0.0f) { // Thruster is overridden. Keep track of it. overridden.Add(thruster); } else { // Found a good thruster found = true; } } }); // Depending on outcome, disable or zero-out overridden thrusters overridden.ForEach(thruster => { if (found) { // Disable and let good thrusters take care of it thruster.SetValue<bool>("OnOff", false); } else { // No good thrusters. Zero-out override. thruster.SetValue<float>("Override", 0.0f); found = true; // Note this means we will zero-out at most 1 thruster. // For now, this is the desired effect. } }); if (!found) { // Final desperation move. Enable and zero-out overrides for // all thrusters on this side. thrusters.ForEach(thruster => { thruster.SetValue<bool>("OnOff", true); thruster.SetValue<float>("Override", 0.0f); }); // Still return false, but we'll check again after a few ticks } return found; }
public static Vector3I Transform(this Vector3I size, SerializableBlockOrientation orientation) { var matrix = Matrix.CreateFromDir(Base6Directions.GetVector(orientation.Forward), Base6Directions.GetVector(orientation.Up)); var rotation = Quaternion.CreateFromRotationMatrix(matrix); return(Vector3I.Transform(size, rotation)); }
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); }
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 void HandleFacing(TempData tempData) { Vector3 desiredRotSpeed; if (command == null) { desiredRotSpeed = Vector3.Zero; } else { var navigationData = command.GetNavData(program); //Vector3 targetDirection = chosenTarget.Position - Me.CubeGrid.GridIntegerToWorld( Me.Position ); //targetDirection.Normalize(); Vector3 des = navigationData.desiredForward.Value; //VrageMath doesn't have Vector3 * Matrix3x3 multiplication //navigationData.desiredFacing = new Vector3( Vector3.Dot(des, directionAdjustMatrix.Col0), Vector3.Dot( des, directionAdjustMatrix.Col1 ), Vector3.Dot( des, directionAdjustMatrix.Col2 ) ); List <IMyRadioAntenna> antenna = new List <IMyRadioAntenna>(); GridTerminalSystem.GetBlocksOfType <IMyRadioAntenna>(antenna); antenna[0].CustomName = "Desired Facing: " + navigationData.desiredForward; desiredRotSpeed = tempData.facing.Cross(navigationData.desiredForward.Value); //get direction of desired rotation desiredRotSpeed.Normalize(); //Echo("Dd: " + desiredSpeed); desiredRotSpeed.Multiply(0.5f - tempData.facing.Dot(navigationData.desiredForward.Value) / 2); //get magnitude of desired rotation //Echo( "Desired speed: " + desiredSpeed.Length() ); //desiredSpeed = desiredDir - rotSpeed; //Echo( string.Format( "Facing: {0} TargetDir:{1}", facing, targetDirection ) ); } Vector3 targetRotation = new Vector3(tempData.facingLeft.Dot(desiredRotSpeed), tempData.facingUp.Dot(desiredRotSpeed), tempData.facing.Dot(desiredRotSpeed)); //targetRotation = new Vector3( 0,targetRotation.Y,0 ); //program.Echo( "TR: " + targetRotation ); if (useControlBlock) { List <IMyRemoteControl> control = new List <IMyRemoteControl>(); GridTerminalSystem.GetBlocksOfType <IMyRemoteControl>(control); if (shouldSetWaypoint == 0) { if (control.Count > 0) { IMyRemoteControl cntrl = control[0]; cntrl.ControlThrusters = false; cntrl.ControlWheels = true; cntrl.ClearWaypoints(); var desiredFacing = command.GetNavData(program).desiredForward.Value; cntrl.AddWaypoint(Me.CubeGrid.GridIntegerToWorld(cntrl.Position) + desiredFacing * 10000, "dummy rotation target"); cntrl.AddWaypoint(new MyWaypointInfo()); cntrl.SetAutoPilotEnabled(true); Vector3 target = Me.CubeGrid.GridIntegerToWorld(cntrl.Position) + (desiredFacing * 1000); program.Echo(string.Format("RC: {0:0.0} {1:0.0} {2:0.0}", target.X, target.Y, target.Z)); } else { program.Echo("Can't find any control blocks"); } shouldSetWaypoint = 50; } else { shouldSetWaypoint--; } } else { foreach (var gyro in gyros) { try { gyro.SetValueBool("Override", true); gyro.Pitch = -targetRotation.Dot(Base6Directions.GetVector(gyro.Orientation.Left)) * 60; gyro.Yaw = targetRotation.Dot(Base6Directions.GetVector(gyro.Orientation.Up)) * 60; gyro.Roll = -targetRotation.Dot(Base6Directions.GetVector(gyro.Orientation.Forward)) * 60; } catch (Exception e) { program.Echo(e.StackTrace); } } } }
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 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); }
public void RotateComponent() { var d1 = SpaceEngineersApi.GetCubeDefinition(new MyObjectBuilderType(typeof(MyObjectBuilder_Thrust)), MyCubeSize.Large, "LargeBlockLargeThrust"); Assert.AreEqual("DisplayName_Block_LargeThrust", d1.DisplayNameEnum.Value.String, "Must match"); Assert.AreEqual(MyCubeSize.Large, d1.CubeSize, "Must match"); Assert.AreEqual(3, d1.Size.X, "Must match"); Assert.AreEqual(2, d1.Size.Y, "Must match"); Assert.AreEqual(4, d1.Size.Z, "Must match"); //======// var orient = new SerializableBlockOrientation(Base6Directions.Direction.Forward, Base6Directions.Direction.Up); var f = Base6Directions.GetVector(orient.Forward); var u = Base6Directions.GetVector(orient.Up); var m = Matrix.CreateFromDir(f, u); var q = Quaternion.CreateFromRotationMatrix(m); var nf = Base6Directions.GetForward(q); var nu = Base6Directions.GetUp(q); // Test that Space Engineers orientation methods are working as expected. Forward is still Forward, Up is still Up. Assert.AreEqual(nf, orient.Forward, "Initial Orientation Forward must match."); Assert.AreEqual(nu, orient.Up, "Initial Orientation Forward must match."); //======// var v = d1.Size; var fV1 = Vector3.Transform(v, m); // Orientation of Forward/Up should provide the exact same dimentions as the original Component above. Assert.AreEqual(3, fV1.X, "Must match"); Assert.AreEqual(2, fV1.Y, "Must match"); Assert.AreEqual(4, fV1.Z, "Must match"); //======// var newOrient = new SerializableBlockOrientation(Base6Directions.Direction.Down, Base6Directions.Direction.Right); var newM = Matrix.CreateFromDir(Base6Directions.GetVector(newOrient.Forward), Base6Directions.GetVector(newOrient.Up)); var fV2 = Vector3.Transform(v, newM); // The reoriented Component size should now have changed. Assert.AreEqual(2, fV2.X, "Must match"); Assert.AreEqual(4, fV2.Y, "Must match"); Assert.AreEqual(3, fV2.Z, "Must match"); //======// // Reducing complexity of code with Extension. var direction = new SerializableBlockOrientation(Base6Directions.Direction.Down, Base6Directions.Direction.Right); var fV3 = d1.Size.Transform(direction); // The reoriented Component size should now have changed. Assert.AreEqual(2, fV3.X, "Must match"); Assert.AreEqual(4, fV3.Y, "Must match"); Assert.AreEqual(3, fV3.Z, "Must match"); }
public void Enable(Base6Directions.Direction direction, bool enable, Func<IMyThrust, bool> collect = null) { var thrusterList = GetThrusters(direction, collect, true); thrusterList.ForEach(thruster => thruster.SetValue<bool>("OnOff", enable)); }
public static void CreateDefaultTriangles(MyObjectBuilder_BlockNavigationDefinition ob) { Vector3I size = ob.Size; Vector3I center = ob.Center; int triCount = 4 * ((size.X * size.Y) + (size.X * size.Z) + (size.Y * size.Z)); ob.Triangles = new MyObjectBuilder_BlockNavigationDefinition.Triangle[triCount]; int i = 0; // Coords of the block's real center (i.e. origin) relative to blockDef.Center Vector3 origin = (size * 0.5f) - center - Vector3.Half; for (int d = 0; d < 6; ++d) { Base6Directions.Direction faceDirection = Base6Directions.EnumDirections[d]; Base6Directions.Direction rightDir, upDir; Vector3 faceOrigin = origin; switch (faceDirection) { case Base6Directions.Direction.Right: rightDir = Base6Directions.Direction.Forward; upDir = Base6Directions.Direction.Up; faceOrigin += new Vector3(0.5f, -0.5f, 0.5f) * size; break; case Base6Directions.Direction.Left: rightDir = Base6Directions.Direction.Backward; upDir = Base6Directions.Direction.Up; faceOrigin += new Vector3(-0.5f, -0.5f, -0.5f) * size; break; case Base6Directions.Direction.Up: rightDir = Base6Directions.Direction.Right; upDir = Base6Directions.Direction.Forward; faceOrigin += new Vector3(-0.5f, 0.5f, 0.5f) * size; break; case Base6Directions.Direction.Down: rightDir = Base6Directions.Direction.Right; upDir = Base6Directions.Direction.Backward; faceOrigin += new Vector3(-0.5f, -0.5f, -0.5f) * size; break; case Base6Directions.Direction.Backward: rightDir = Base6Directions.Direction.Right; upDir = Base6Directions.Direction.Up; faceOrigin += new Vector3(-0.5f, -0.5f, 0.5f) * size; break; case Base6Directions.Direction.Forward: default: rightDir = Base6Directions.Direction.Left; upDir = Base6Directions.Direction.Up; faceOrigin += new Vector3(0.5f, -0.5f, -0.5f) * size; break; } Vector3 rightVec = Base6Directions.GetVector(rightDir); Vector3 upVec = Base6Directions.GetVector(upDir); int uMax = size.AxisValue(Base6Directions.GetAxis(upDir)); int rMax = size.AxisValue(Base6Directions.GetAxis(rightDir)); for (int u = 0; u < uMax; ++u) { for (int r = 0; r < rMax; ++r) { var triangle = new MyObjectBuilder_BlockNavigationDefinition.Triangle(); triangle.Points = new SerializableVector3[3]; triangle.Points[0] = faceOrigin; triangle.Points[1] = faceOrigin + rightVec; triangle.Points[2] = faceOrigin + upVec; ob.Triangles[i++] = triangle; triangle = new MyObjectBuilder_BlockNavigationDefinition.Triangle(); triangle.Points = new SerializableVector3[3]; triangle.Points[0] = faceOrigin + rightVec; triangle.Points[1] = faceOrigin + rightVec + upVec; triangle.Points[2] = faceOrigin + upVec; ob.Triangles[i++] = triangle; faceOrigin += rightVec; } faceOrigin -= rightVec * rMax; faceOrigin += upVec; } } }
public SerializableBlockOrientation(ref Quaternion q) { Forward = Base6Directions.GetForward(q); Up = Base6Directions.GetUp(q); }
public void InitControl(MyEntity controller) { //sets direction of angular force and steering for concrete block based on position in grid var mat = controller.WorldMatrix * PositionComp.WorldMatrixNormalizedInv; Vector3 revolveAxis; if (Base6Directions.GetClosestDirection(mat.Forward) == Base6Directions.Direction.Up || Base6Directions.GetClosestDirection(mat.Forward) == Base6Directions.Direction.Down) { revolveAxis = controller.WorldMatrix.Forward; } else if (Base6Directions.GetClosestDirection(mat.Up) == Base6Directions.Direction.Up || Base6Directions.GetClosestDirection(mat.Up) == Base6Directions.Direction.Down) { revolveAxis = controller.WorldMatrix.Up; } else { revolveAxis = controller.WorldMatrix.Right; } // - "epsilon" var dotCockpit1 = Vector3.Dot(controller.WorldMatrix.Up, WorldMatrix.Translation - controller.WorldMatrix.Translation) - 0.0001 > 0; Vector3 steerAxis; if (Base6Directions.GetClosestDirection(mat.Forward) == Base6Directions.Direction.Forward || Base6Directions.GetClosestDirection(mat.Forward) == Base6Directions.Direction.Backward) { steerAxis = controller.WorldMatrix.Forward; } else if (Base6Directions.GetClosestDirection(mat.Up) == Base6Directions.Direction.Forward || Base6Directions.GetClosestDirection(mat.Up) == Base6Directions.Direction.Backward) { steerAxis = controller.WorldMatrix.Up; } else { steerAxis = controller.WorldMatrix.Right; } // - "epsilon" if (CubeGrid.Physics != null) { var dotMass = Vector3.Dot(controller.WorldMatrix.Forward, (WorldMatrix.Translation - CubeGrid.Physics.CenterOfMassWorld)) - 0.0001; var dotCockpit = Vector3.Dot(WorldMatrix.Forward, steerAxis); m_steerInvert = ((dotMass * dotCockpit) < 0) ^ dotCockpit1; m_revolveInvert = ((WorldMatrix.Up - revolveAxis).Length() > 0.1f) ^ dotCockpit1; } }
public void BroadcastAddCubeBlock(CubeBlockEntity cubeBlock) { try { Type packedStructType = CubeGridEntity.InternalType.GetNestedType(CubeGridEntity.CubeGridPackedCubeBlockClass); Object packedStruct = Activator.CreateInstance(packedStructType); MyCubeBlockDefinition def = MyDefinitionManager.Static.GetCubeBlockDefinition(cubeBlock.ObjectBuilder); //Set def id BaseObject.SetEntityFieldValue(packedStruct, "35E024D9E3B721592FB9B6FC1A1E239A", (DefinitionIdBlit)def.Id); //Set position BaseObject.SetEntityFieldValue(packedStruct, "5C3938C9B8CED1D0057CCF12F04329AB", cubeBlock.Position); //Set block size BaseObject.SetEntityFieldValue(packedStruct, "0DDB53EB9299ECC9826DF9A47E5E4F38", new Vector3UByte(def.Size)); //Set block margins BaseObject.SetEntityFieldValue(packedStruct, "4045ED59A8C93DE0B41218EF2E947E55", new Vector3B(0, 0, 0)); BaseObject.SetEntityFieldValue(packedStruct, "096897446D5BD5243D3D6E5C53CE1772", new Vector3B(0, 0, 0)); //Set block margin scale BaseObject.SetEntityFieldValue(packedStruct, "E28B9725868E18B339D1E0594EF14444", new Vector3B(0, 0, 0)); //Set orientation Quaternion rot; cubeBlock.BlockOrientation.GetQuaternion(out rot); BaseObject.SetEntityFieldValue(packedStruct, "F1AAFF5C8F200592F313BC7E02140A38", Base6Directions.GetForward(rot)); BaseObject.SetEntityFieldValue(packedStruct, "E80AA7B84131E39F9F88209A109EED59", Base6Directions.GetUp(rot)); //Set color BaseObject.SetEntityFieldValue(packedStruct, "556976F2528411FF5F95FC75DC13FEED", ColorExtensions.PackHSVToUint(cubeBlock.ColorMaskHSV)); object[] parameters = { packedStruct, new HashSet <Vector3UByte>(), cubeBlock.EntityId, MyRandom.Instance.CreateRandomSeed() }; BaseObject.InvokeEntityMethod(m_netManager, CubeGridNetManagerBroadcastAddCubeBlockMethod, parameters); } catch (Exception ex) { LogManager.ErrorLog.WriteLine(ex); } }
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; } } } } } } } }
// Returns a position with the same position and with a flipped direction // .-------. .-------. // | | | | // | o-->| ~> |<--o | // | | | | // '-------* .-------. public ConveyorLinePosition GetFlippedPosition() { return(new ConveyorLinePosition(LocalGridPosition, Base6Directions.GetFlippedDirection(Direction))); }
/// <summary> /// Returns true if the given small block connects to large one. /// </summary> /// <param name="smallBlock">small block</param> /// <param name="smallBlockWorldAabb">small block world AABB</param> /// <param name="largeBlock">large block</param> /// <param name="largeBlockWorldAabb">large block wotld AABB</param> /// <returns>true when connected</returns> private bool SmallBlockConnectsToLarge(MySlimBlock smallBlock, ref BoundingBoxD smallBlockWorldAabb, MySlimBlock largeBlock, ref BoundingBoxD largeBlockWorldAabb) { Debug.Assert(smallBlock.BlockDefinition.CubeSize == MyCubeSize.Small); Debug.Assert(largeBlock.BlockDefinition.CubeSize == MyCubeSize.Large); Debug.Assert(!(smallBlock.FatBlock is MyCompoundCubeBlock)); Debug.Assert(!(largeBlock.FatBlock is MyCompoundCubeBlock)); BoundingBoxD smallBlockWorldAabbReduced = smallBlockWorldAabb; smallBlockWorldAabbReduced.Inflate(-smallBlock.CubeGrid.GridSize / 4); // Small block aabb penetrates large block aabb (large timbers). bool penetratesAabbs = largeBlockWorldAabb.Contains(smallBlockWorldAabbReduced) == ContainmentType.Intersects; if (!penetratesAabbs) { Vector3D centerToCenter = smallBlockWorldAabb.Center - largeBlockWorldAabb.Center; Vector3I addDir = Base6Directions.GetIntVector(Base6Directions.GetClosestDirection(centerToCenter)); // Check small grid mount points Quaternion smallBlockRotation; smallBlock.Orientation.GetQuaternion(out smallBlockRotation); smallBlockRotation = Quaternion.CreateFromRotationMatrix(smallBlock.CubeGrid.WorldMatrix) * smallBlockRotation; if (!MyCubeGrid.CheckConnectivitySmallBlockToLargeGrid(largeBlock.CubeGrid, smallBlock.BlockDefinition, ref smallBlockRotation, ref addDir)) { return(false); } } BoundingBoxD smallBlockWorldAabbInflated = smallBlockWorldAabb; smallBlockWorldAabbInflated.Inflate(2 * smallBlock.CubeGrid.GridSize / 3); // Trim small block aabb with large block aabb. BoundingBoxD intersectedBox = smallBlockWorldAabbInflated.Intersect(largeBlockWorldAabb); Vector3D intersectedBoxCenter = intersectedBox.Center; HkShape shape = new HkBoxShape((Vector3)intersectedBox.HalfExtents); Quaternion largeRotation; largeBlock.Orientation.GetQuaternion(out largeRotation); largeRotation = Quaternion.CreateFromRotationMatrix(largeBlock.CubeGrid.WorldMatrix) * largeRotation; Vector3D largeTranslation; largeBlock.ComputeWorldCenter(out largeTranslation); bool result = false; try { if (largeBlock.FatBlock != null) { MyModel model = largeBlock.FatBlock.Model; if (model != null) { HkShape[] shapes = model.HavokCollisionShapes; if (shapes == null || shapes.Length == 0) { return(false); } for (int i = 0; i < shapes.Length; ++i) { result = MyPhysics.IsPenetratingShapeShape(shape, ref intersectedBoxCenter, ref Quaternion.Identity, shapes[i], ref largeTranslation, ref largeRotation); if (result) { break; } } } else { HkShape shapeLarge = new HkBoxShape(largeBlock.BlockDefinition.Size * largeBlock.CubeGrid.GridSize / 2); result = MyPhysics.IsPenetratingShapeShape(shape, ref intersectedBoxCenter, ref Quaternion.Identity, shapeLarge, ref largeTranslation, ref largeRotation); shapeLarge.RemoveReference(); } } else { HkShape shapeLarge = new HkBoxShape(largeBlock.BlockDefinition.Size * largeBlock.CubeGrid.GridSize / 2); result = MyPhysics.IsPenetratingShapeShape(shape, ref intersectedBoxCenter, ref Quaternion.Identity, shapeLarge, ref largeTranslation, ref largeRotation); shapeLarge.RemoveReference(); } } finally { shape.RemoveReference(); } return(result); }
private void MergeFromAnotherMesh(MyGridNavigationMesh otherMesh, ref MatrixI transform) { ProfilerShort.Begin("MergeFromAnotherMesh"); m_mergeHelper.Clear(); // Save the cubes from the other mesh that are touching cubes of this mesh into a helper set. // Also put the touched cubes from this mesh into the set. foreach (var position in otherMesh.m_smallTriangleRegistry.Keys) { bool add = false; foreach (var direction in Base6Directions.IntDirections) { // CH: TODO: We query the grid so far, but in the future, we should make sure that the access is thread-safe Vector3I pos = Vector3I.Transform(position + direction, transform); if (m_cubeSet.Contains(ref pos)) // Test the transformed position... { m_mergeHelper.Add(position + direction); // ... but add the original one add = true; } } if (add) { m_mergeHelper.Add(position); } } foreach (var entry in otherMesh.m_smallTriangleRegistry) { Vector3I originalCube = entry.Key; Vector3I tformedCube; Vector3I.Transform(ref originalCube, ref transform, out tformedCube); // If the cube is one of the touching cubes, we have to intersect the touching triangles if (m_mergeHelper.Contains(originalCube)) { // Take the touching pairs one by one and calculate triangulation of the disjoint union of the opposing faces // Remove the opposing faces from the old block // Add the triangulation to the mesh // Add the rest of the navmesh from this block to the mesh m_tmpTriangleList.Clear(); // CH: TODO. Just remove the triangles now foreach (var direction in Base6Directions.EnumDirections) { Vector3I directionVec = Base6Directions.GetIntVector((int)direction); Base6Directions.Direction tformedDirection = transform.GetDirection(direction); Vector3I tformedFlippedVec = Base6Directions.GetIntVector((int)Base6Directions.GetFlippedDirection(tformedDirection)); // Remove face triangles from this mesh if (m_mergeHelper.Contains(originalCube + directionVec)) { List <int> triList = null; if (m_smallTriangleRegistry.TryGetValue(tformedCube - tformedFlippedVec, out triList)) { foreach (var index in triList) { var triangle = GetTriangle(index); // CH: TODO: This will probably be expensive. Could we precalculate it? if (IsFaceTriangle(triangle, tformedCube - tformedFlippedVec, tformedFlippedVec)) { m_tmpTriangleList.Add(new KeyValuePair <MyNavigationTriangle, Vector3I>(triangle, tformedCube - tformedFlippedVec)); } } } } } foreach (var triangle in m_tmpTriangleList) { RemoveTriangle(triangle.Key, triangle.Value); } m_tmpTriangleList.Clear(); int debugCounter = 0; // CH: TODO: optimize this (actually whole this method) foreach (var triangleIndex in entry.Value) { var triangle = otherMesh.GetTriangle(triangleIndex); Vector3I pos = entry.Key; bool addTriangle = true; foreach (var direction in Base6Directions.EnumDirections) { Vector3I dirvec = Base6Directions.GetIntVector((int)direction); if (m_mergeHelper.Contains(pos + dirvec) && IsFaceTriangle(triangle, pos, dirvec)) { addTriangle = false; break; } } if (addTriangle) { if (debugCounter == 5) { } CopyTriangle(triangle, pos, ref transform); debugCounter++; } } } // Otherwise, we just transform the triangles from the other mesh and add them to this mesh else { foreach (var triangleIndex in entry.Value) { var triangle = otherMesh.GetTriangle(triangleIndex); CopyTriangle(triangle, entry.Key, ref transform); //if (triangleIndex > 1) break; } } } m_mergeHelper.Clear(); ProfilerShort.End(); }
private void HandleFacingWithQuat(TempData tempData) { Quaternion targetRotation = Quaternion.Identity; if (tempData.navData.desiredForward.HasValue) { if (tempData.navData.desiredUp.HasValue) //forward and up //inverse quaternion is used to transform world direction to local direction { Quaternion Quat_Two = Quaternion.CreateFromForwardUp(tempData.facing, tempData.facingUp); //var InvQuat = Quaternion.Inverse( Quat_Two ); var InvQuat = Quaternion.Inverse(Quat_Two); //program.DebugWithAntenna( string.Format( "FW: {0:0.00} {1:0.00} {2:0.00}", tempData.navData.desiredForward.Value.X, tempData.navData.desiredForward.Value.Y, tempData.navData.desiredForward.Value.Z ) ); //program.DebugWithAntenna( string.Format( "UP: {0:0.00} {1:0.00} {2:0.00}", tempData.navData.desiredUp.Value.X, tempData.navData.desiredUp.Value.Y, tempData.navData.desiredUp.Value.Z ) ); //transform to local coordinate system Vector3 desiredForward = Vector3.Transform(tempData.navData.desiredForward.Value, InvQuat); Vector3 desiredUp = Vector3.Transform(tempData.navData.desiredUp.Value, InvQuat); //program.DebugWithAntenna( string.Format( "L FW: {0:0.00} {1:0.00} {2:0.00}", desiredForward.X, desiredForward.Y, desiredForward.Z ) ); //program.DebugWithAntenna( string.Format( "L UP: {0:0.00} {1:0.00} {2:0.00}", desiredUp.X, desiredUp.Y, desiredUp.Z ) ); targetRotation = Quaternion.CreateFromForwardUp(desiredForward, desiredUp); } else //just forward { targetRotation = Quaternion.CreateFromTwoVectors(tempData.facing, tempData.navData.desiredForward.Value); } } else { return; } //program.DebugWithAntenna( string.Format( "Quat: {0:0.00} {1:0.00} {2:0.00} {3:0.00}", targetRotation.X, targetRotation.Y, targetRotation.Z, targetRotation.W ) ); Vector3 turningAxis; float angle; targetRotation.GetAxisAngle(out turningAxis, out angle); turningAxis = ToEulerAngles(targetRotation); //program.DebugWithAntenna( string.Format( "Angle: {0:0.00}", angle ) ); program.DebugWithAntenna(string.Format("Angles: {0:0.00} {1:0.00} {2:0.00}", turningAxis.X, turningAxis.Y, turningAxis.Z)); foreach (var gyro in gyros) { try { gyro.SetValueBool("Override", true); gyro.Pitch = -turningAxis.Dot(Base6Directions.GetVector(gyro.Orientation.Left)) * angle; gyro.Yaw = turningAxis.Dot(Base6Directions.GetVector(gyro.Orientation.Up)) * angle; gyro.Roll = -turningAxis.Dot(Base6Directions.GetVector(gyro.Orientation.Forward)) * angle; } catch (Exception e) { program.Echo(e.StackTrace); } } //program.Echo( string.Format( "DRS: {0:0.00} {1:0.00} {2:0.00}", desiredRotSpeed.X, desiredRotSpeed.Y, desiredRotSpeed.Z ) ); //program.Echo( string.Format( "Quat: {0:0.00} {1:0.00} {2:0.00}", targetRotation.X/targetRotation.W, targetRotation.Y / targetRotation.W, targetRotation.Z / targetRotation.W ) ); //Vector3 adjustedQuaternion = new Vector3( targetRotation.X, targetRotation.Y, targetRotation.Z ) * ( 0.5f - targetRotation.W/2 ); //Vector3 targetRotation = new Vector3( tempData.facingLeft.Dot( adjustedQuaternion ), tempData.facingUp.Dot( adjustedQuaternion ), tempData.facing.Dot( adjustedQuaternion ) ); //targetRotation = new Vector3( 0,targetRotation.Y,0 ); //program.Echo( "TR: " + targetRotation ); /*foreach(var gyro in gyros) { * try { * gyro.SetValueBool( "Override", true ); * * gyro.Pitch = -targetRotation.Dot( Base6Directions.GetVector( gyro.Orientation.Left ) ) * 60; * gyro.Yaw = targetRotation.Dot( Base6Directions.GetVector( gyro.Orientation.Up ) ) * 60; * gyro.Roll = -targetRotation.Dot( Base6Directions.GetVector( gyro.Orientation.Forward ) ) * 60; * * } catch(Exception e) { program.Echo( e.StackTrace ); } * }*/ }
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)); }
/// <summary> /// Checks for enough acceleration to move the ship forward and backward with the specified acceleration. /// </summary> private bool SufficientAcceleration(float acceleration) { return(m_mover.Thrust.CanMoveDirection(Base6Directions.GetClosestDirection(m_navDrill.LocalMatrix.Forward), acceleration) && m_mover.Thrust.CanMoveDirection(Base6Directions.GetClosestDirection(m_navDrill.LocalMatrix.Backward), acceleration)); }
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; }
/// <summary> /// Returns subblock data from dummy, subblock matrix can be offset (according to useOffset parameter) so the dummy position output is also provided. /// </summary> /// <returns>true when dummy is subblock otherwise false</returns> public static bool GetSubBlockDataFromDummy(MyCubeBlockDefinition ownerBlockDefinition, string dummyName, MyModelDummy dummy, bool useOffset, out MyCubeBlockDefinition subBlockDefinition, out MatrixD subBlockMatrix, out Vector3 dummyPosition) { subBlockDefinition = null; subBlockMatrix = MatrixD.Identity; dummyPosition = Vector3.Zero; if (!dummyName.ToLower().StartsWith(MyCubeBlock.DUMMY_SUBBLOCK_ID)) { return(false); } if (ownerBlockDefinition.SubBlockDefinitions == null) { return(false); } string dummyNameShort = dummyName.Substring(MyCubeBlock.DUMMY_SUBBLOCK_ID.Length); MyDefinitionId definitiondId; if (!ownerBlockDefinition.SubBlockDefinitions.TryGetValue(dummyNameShort, out definitiondId)) { Debug.Assert(false, "SubBlock definition not found!"); return(false); } MyDefinitionManager.Static.TryGetCubeBlockDefinition(definitiondId, out subBlockDefinition); if (subBlockDefinition == null) { Debug.Assert(false, "SubBlock definition not found!"); return(false); } const double dotEpsilon = 0.00000001; subBlockMatrix = MatrixD.Normalize(dummy.Matrix); Vector3I forward = Base6Directions.GetIntVector(Base6Directions.GetClosestDirection(subBlockMatrix.Forward)); double forwardDot = Vector3D.Dot(subBlockMatrix.Forward, (Vector3D)forward); if (Math.Abs(1 - forwardDot) <= dotEpsilon) { subBlockMatrix.Forward = forward; } Vector3I right = Base6Directions.GetIntVector(Base6Directions.GetClosestDirection(subBlockMatrix.Right)); double rightDot = Vector3D.Dot(subBlockMatrix.Right, (Vector3D)right); if (Math.Abs(1 - rightDot) <= dotEpsilon) { subBlockMatrix.Right = right; } Vector3I up = Base6Directions.GetIntVector(Base6Directions.GetClosestDirection(subBlockMatrix.Up)); double upDot = Vector3D.Dot(subBlockMatrix.Up, (Vector3D)up); if (Math.Abs(1 - upDot) <= dotEpsilon) { subBlockMatrix.Up = up; } dummyPosition = subBlockMatrix.Translation; if (useOffset) { Vector3 offset = MyCubeBlock.GetBlockGridOffset(subBlockDefinition); subBlockMatrix.Translation -= Vector3D.TransformNormal(offset, subBlockMatrix); } return(true); }
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)); } }
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)); }
static void GenerateConvexVertices() { List <Vector3> tmpHelperVerts = new List <Vector3>(27); var topologyValues = Enum.GetValues(typeof(MyCubeTopology)); Cache = new List <Vector3> [topologyValues.Length][]; foreach (var topologyObj in topologyValues) { var topology = (MyCubeTopology)topologyObj; GetTopologySwitch(topology, tmpHelperVerts); Cache[(int)topology] = new List <Vector3> [6 * 6]; foreach (var forward in Base6Directions.EnumDirections) { foreach (var up in Base6Directions.EnumDirections) { if (forward == up || Base6Directions.GetIntVector(forward) == -Base6Directions.GetIntVector(up)) { continue; } var list = new List <Vector3>(tmpHelperVerts.Count); Cache[(int)topology][(int)forward * 6 + (int)up] = list; var orientation = new MyBlockOrientation(forward, up); foreach (var vert in tmpHelperVerts) { list.Add(Vector3.TransformNormal(vert, orientation)); } } } tmpHelperVerts.Clear(); } }