public static void PresetLimitsForTranslation(IList <EngineWrapper> engines, Vector3 translation) { if (translation.IsZero()) { return; } var num_engines = engines.Count; for (var i = 0; i < num_engines; i++) { var e = engines[i]; if (e.preset_limit >= 0) { continue; } if (e.translationEnabled) { e.limit_tmp = Vector3.Dot(e.thrustDirection, translation); e.limit = e.preset_limit = e.limit_tmp > 0 ? e.limit_tmp : 0; } else { e.limit = e.preset_limit = 0; } } }
protected override bool GetDirection(out Vector3 direction) { direction = new Vector3(Input.GetAxis(AxisNames.Horizontal), 0, Input.GetAxis(AxisNames.Vertical)); return(!direction.IsZero()); }
protected override Transform get_deploy_transform(Vector3 size, out Vector3 spawn_offset) { var localRotation = Quaternion.identity; if (yRotation > 0) { localRotation = get_Y_rotation(); if (!size.IsZero()) { size = Quaternion.Inverse(localRotation) * ((localRotation * size).AbsComponents()); } } var T = get_deploy_transform_unrotated(size, out spawn_offset); if (yRotation > 0 && T != null) { var rT = T.Find("__SPAWN_TRANSFORM_ROTATED"); if (rT == null) { var empty = new GameObject("__SPAWN_TRANSFORM_ROTATED"); empty.transform.SetParent(T, false); rT = empty.transform; } rT.localPosition = Vector3.zero; rT.localRotation = localRotation; return(rT); } return(T); }
protected void compute_steering(Vector3 current, Vector3 needed) { var cur_inv = current.IsInvalid() || current.IsZero(); var ned_inv = needed.IsInvalid() || needed.IsZero(); if (cur_inv || ned_inv) { Log("compute_steering: Invalid argumetns:\ncurrent {}\nneeded {}\ncurrent thrust {}", current, needed, VSL.Engines.CurrentDefThrustDir); steering = Vector3.zero; return; } var direct_rotation = Quaternion.FromToRotation(needed, current); update_angular_error(direct_rotation); VSL.Controls.SetAttitudeError(Vector3.Angle(needed, current)); //calculate steering if (VSL.Controls.AttitudeError > ATCB.AngleThreshold) { //rotational axis var current_maxI = current.MaxI(); var axis = Vector3.Cross(needed, current).Exclude(current_maxI); if (axis.sqrMagnitude < 0.01f) { axis = VSL.Torque.MaxCurrent.AA.Exclude(current_maxI).MaxComponentV(); } //main rotation component var axis1 = axis.MaxComponentV(); var current_cmp1 = Vector3.ProjectOnPlane(current, axis1); var needed_cmp1 = Vector3.ProjectOnPlane(needed, axis1); var angle1 = Vector3.Angle(needed_cmp1, current_cmp1); //second rotation component var axis2 = (axis - axis1).MaxComponentV(); var angle2 = Vector3.Angle(needed, needed_cmp1); //steering steering = (axis1.normalized * angle1 + axis2.normalized * angle2) * Mathf.Deg2Rad; // LogF("\ncurrent_maxI: {}\n" + // "axis: {}\n" + // "axis1: {}\n" + // "axis2: {}\n" + // "current_cmp1: {}\n" + // "needed_cmp1: {}\n" + // "angle1: {}\n" + // "angle2: {}\n", // current_maxI, axis, axis1, axis2, current_cmp1, needed_cmp1, angle1, angle2);//debug } else { steering = rotation2steering(direct_rotation); } // Log("\nneeded {}\ncurrent {}\nangle {}\nsteering {}\ndirect_rotation {}", // needed, current, Vector3.Angle(needed, current), steering, direct_rotation.eulerAngles);//debug //FIXME: sometimes generates NaN // needed (2.309423E+09, -5.479368E+11, -2.858228E+11); |v| = 6.180087E+11 // current (-0.0680542, -28.58647, -718.0868); |v| = 718.6556 // angle 60.17245 > threshold // steering [pitch NaN, roll NaN, yaw NaN] }
/// <summary> /// TargetPosition으로 접근함 /// true를 리턴하면 타겟에 접근했음 /// </summary> /// <param name="targetPosition"> 이동할 타겟 포지션(Transfrom</param> /// <param name="range">접근 영역값</param> public bool MoveTargetUpdate(Vector3 targetPosition, float range) { // 회전 Vector3 lookPos = targetPosition - this.unit.transform.position; lookPos.y = 0; // y축은 무시한다 if (!lookPos.IsZero()) { this.unit.RotateUnit(Quaternion.LookRotation(lookPos)); } // 공격하기에 거리가 멀면 다가간다 if ((targetPosition - this.unit.transform.position).sqrMagnitude > (range * range)) { this.unit.SetMovable(true); this.unit.MovePosition(targetPosition); return(false); } else { this.unit.SetMovable(false); return(true); } }
public override void Draw() { if (!util.GameReady || util.CameraGrid?.Physics == null) { return; } var velocity = util.CameraGrid.Physics.LinearVelocity; if (target?.Physics != null) { velocity -= target.Physics.LinearVelocity; } velocity = averageVelocity.Update(velocity); if (Vector3.IsZero(velocity)) { return; } velocity.Normalize(); DrawFlightPathMarker(velocity, Color.LightGreen); DrawFlightPathMarker(-velocity, Color.Red); }
protected virtual bool IsMoving(MyEntity entity) { // Never know if somebody is moving entity when physics is null return(entity.Physics == null || Vector3.IsZero(entity.Physics.LinearVelocity, PRECISION) == false || Vector3.IsZero(entity.Physics.AngularVelocity, PRECISION) == false); }
public void UpdateRotation() { if (!_rotating) //|| _moveType != ActorMoveType.eTouch) { { return; } if (_targetDir.IsZero()) { _rotating = false; return; } Quaternion rot = Quaternion.LookRotation(_targetDir); float angle = Quaternion.Angle(this.TF.rotation, rot); if (angle <= 0.01f) { this.TF.rotation = rot; _rotating = false; return; } float rt = 14.0f * Time.deltaTime; this.TF.rotation = Quaternion.Slerp(this.TF.rotation, rot, rt); }
private void AllignToTerrain() { Vector3 position = base.transform.position; position.y = MainLevel.GetTerrainY(position); base.transform.position = position; if (base.IsVisible()) { Vector3 normalized2D = base.transform.forward.GetNormalized2D(); Vector3 vector = this.m_BoxCollider.bounds.center + normalized2D * this.m_BoxCollider.size.z + Vector3.up * this.m_BoxCollider.size.y; vector.y = MainLevel.GetTerrainY(vector); Vector3 vector2 = this.m_BoxCollider.bounds.center - normalized2D * this.m_BoxCollider.size.z + Vector3.up * this.m_BoxCollider.size.y; vector2.y = MainLevel.GetTerrainY(vector2); Vector3 vector3 = vector - vector2; Vector3 normalized2D2 = base.transform.right.GetNormalized2D(); Vector3 vector4 = this.m_BoxCollider.bounds.center + normalized2D2 * this.m_BoxCollider.size.x + Vector3.up * this.m_BoxCollider.size.y; vector4.y = MainLevel.GetTerrainY(vector4); Vector3 vector5 = this.m_BoxCollider.bounds.center - normalized2D2 * this.m_BoxCollider.size.x + Vector3.up * this.m_BoxCollider.size.y; vector5.y = MainLevel.GetTerrainY(vector5); Vector3 vector6 = vector4 - vector5; Vector3 vector7 = Vector3.Cross(vector3.normalized, vector6.normalized); if (!vector7.IsZero()) { base.transform.rotation = Quaternion.Slerp(base.transform.rotation, Quaternion.LookRotation(vector3.normalized, vector7.normalized), 1f); } } }
public override void UpdateAfterSimulation() { if (!Visible || !Gyro.IsFunctional || Gyro.MarkedForClose) { return; } if (SubpartOuter == null || SubpartInner == null || SubpartCore == null) { SetEmissiveColor(Gyro); return; } if (!Override && Gyro.GyroOverride) { Override = true; SetEmissiveColor(Gyro); } else if (Override && !Gyro.GyroOverride) { Override = false; SetEmissiveColor(Gyro); } if (!Vector3.IsZero(Gyro.CubeGrid.Physics.AngularVelocity)) { RotateSubparts(); } }
public void Update() { ProfilerShort.Begin("MyBotNavigation.Update"); AssertIsValid(); if (m_entity == null) { return; } ProfilerShort.Begin("UpdateMatrices"); UpdateMatrices(); ProfilerShort.End(); m_gravityDirection = MyGravityProviderSystem.CalculateTotalGravityInPoint(m_entity.PositionComp.WorldMatrix.Translation); if (!Vector3.IsZero(m_gravityDirection, 0.01f)) { m_gravityDirection = Vector3D.Normalize(m_gravityDirection); } if (MyPerGameSettings.NavmeshPresumesDownwardGravity) { m_upVector = Vector3.Up; } else { m_upVector = -m_gravityDirection; } if (!m_speed.IsValid()) { m_forwardVector = PositionAndOrientation.Forward; m_speed = 0.0f; m_rotationSpeedModifier = 1; } ProfilerShort.Begin("Steering update"); foreach (var steering in m_steerings) { ProfilerShort.Begin(steering.GetName()); steering.Update(); ProfilerShort.End(); } ProfilerShort.End(); ProfilerShort.Begin("Aiming"); m_aiming.Update(); ProfilerShort.End(); ProfilerShort.Begin("Steering accumulate correction"); CorrectMovement(m_aiming.RotationHint); ProfilerShort.End(); ProfilerShort.Begin("MoveCharacter"); MoveCharacter(); ProfilerShort.End(); AssertIsValid(); ProfilerShort.End(); }
void setup_grapple_node(Part other, Part host) { if (host == part) { grappleNode.attachedPart = other; grappleNode.owner = part; part.attachNodes.Add(grappleNode); } else { grappleNode.attachedPart = part; grappleNode.owner = other; other.attachNodes.Add(grappleNode); } if (grapplePos.IsZero()) { var joint_pos = Vector3.zero; grapple_transforms.ForEach(t => joint_pos += t.position); grappleNode.position = host.partTransform.InverseTransformPoint(joint_pos / grapple_transforms.Count); grappleNode.orientation = host.partTransform.InverseTransformDirection(part.partTransform.TransformDirection(Vector3.up)); grappleNode.secondaryAxis = host.partTransform.InverseTransformDirection(part.partTransform.TransformDirection(Vector3.back)); } else { grappleNode.position = grapplePos; grappleNode.orientation = grappleOrt; grappleNode.secondaryAxis = grappleOrt2; } grappleNode.originalPosition = grappleNode.position; grappleNode.originalOrientation = grappleNode.orientation; grappleNode.originalSecondaryAxis = grappleNode.secondaryAxis; }
public void Update(int behaviorTicks) { this.m_stuckDetection.SetCurrentTicks(behaviorTicks); if (this.m_entity != null) { this.UpdateMatrices(); this.m_gravityDirection = MyGravityProviderSystem.CalculateTotalGravityInPoint(this.m_entity.PositionComp.WorldMatrix.Translation); if (!Vector3.IsZero(this.m_gravityDirection, 0.01f)) { this.m_gravityDirection = (Vector3)Vector3D.Normalize(this.m_gravityDirection); } this.m_upVector = !MyPerGameSettings.NavmeshPresumesDownwardGravity ? -this.m_gravityDirection : Vector3.Up; if (!this.m_speed.IsValid()) { this.m_forwardVector = (Vector3)this.PositionAndOrientation.Forward; this.m_speed = 0f; this.m_rotationSpeedModifier = 1f; } using (List <MySteeringBase> .Enumerator enumerator = this.m_steerings.GetEnumerator()) { while (enumerator.MoveNext()) { enumerator.Current.Update(); } } this.m_aiming.Update(); this.CorrectMovement(this.m_aiming.RotationHint); if (this.m_speed < 0.1f) { this.m_speed = 0f; } this.MoveCharacter(); } }
override protected bool IsMoving(MyEntity entity) { // Never know if somebody is moving entity when physics is null return(Entity.Physics == null || Vector3.IsZero(entity.Physics.LinearVelocity, PRECISION) == false || Entity.RotationSpeed > 0.0f); }
private void OnPlayerAngle(NetPacketBase packet) { var startPositionX = packet.Read <float>(); var startPositionY = packet.Read <float>(); var startPositionZ = packet.Read <float>(); var startPosition = new Vector3(startPositionX, startPositionY, startPositionZ); var directionX = packet.Read <float>(); var directionY = packet.Read <float>(); var directionZ = packet.Read <float>(); var directionVector = new Vector3(directionX, directionY, directionZ); var angle = packet.Read <float>(); var angleY = packet.Read <float>(); float flySpeed = packet.Read <float>(); this.Player.TurnAngle = packet.Read <float>(); var tick = packet.Read <long>(); this.Player.Angle = angle; this.Player.AngleFly = angle; this.Player.Position = startPosition.Clone(); if (directionVector.IsZero()) { this.Player.DestinationPosition = this.Player.Position.Clone(); } this.Player.SendMoverAngle(directionVector, tick, this.Player.TurnAngle); }
private void OnPlayerMoved2(NetPacketBase packet) { var startPositionX = packet.Read <float>(); var startPositionY = packet.Read <float>(); var startPositionZ = packet.Read <float>(); var startPosition = new Vector3(startPositionX, startPositionY, startPositionZ); var directionX = packet.Read <float>(); var directionY = packet.Read <float>(); var directionZ = packet.Read <float>(); var directionVector = new Vector3(directionX, directionY, directionZ); if (directionVector.IsZero()) { this.Player.DestinationPosition = startPosition.Clone(); } this.Player.Angle = packet.Read <float>(); this.Player.AngleFly = packet.Read <float>(); var flySpeed = packet.Read <float>(); var turnAngle = packet.Read <float>(); this.Player.MovingFlags = (ObjectState)packet.Read <uint>(); this.Player.MotionFlags = (StateFlags)packet.Read <int>(); this.Player.ActionFlags = packet.Read <int>(); var motionEx = packet.Read <int>(); var loop = packet.Read <int>(); var motionOption = packet.Read <int>(); var tick = packet.Read <long>(); var frame = packet.Read <byte>(); this.Player.IsFlying = this.Player.MovingFlags.HasFlag(ObjectState.OBJSTA_FMOVE); this.Player.SendMoverMoved(directionVector, motionEx, loop, motionOption, tick, frame, turnAngle); }
override protected bool IsMoving(MyEntity entity) { // Never know if somebody is moving entity when physics is null return(Entity.Physics == null || Vector3.IsZero(entity.Physics.LinearVelocity, PRECISION) == false || Vector2.IsZero(Entity.RotationIndicator, PRECISION) == false || Math.Abs(Entity.RollIndicator - 0.0f) > 0.001f); }
private bool IsNearPlanet() { if (ControlledEntity == null) { return(false); } return(!Vector3.IsZero(MyGravityProviderSystem.CalculateNaturalGravityInPoint(ControlledEntity.PositionComp.GetPosition()))); }
public bool Optimize(IList<RCSWrapper> engines, Vector3 needed_torque) { var num_engines = engines.Count; var zero_torque = needed_torque.IsZero(); TorqueAngle = TorqueError = -1f; float error, angle; var last_error = -1f; Vector3 cur_imbalance, target; for(int i = 0; i < RCS.MaxIterations; i++) { //calculate current errors and target cur_imbalance = Vector3.zero; for(int j = 0; j < num_engines; j++) { var e = engines[j]; cur_imbalance += e.Torque(e.limit); } angle = zero_torque? 0f : Vector3.Angle(cur_imbalance, needed_torque); target = needed_torque-cur_imbalance; error = VSL.Torque.AngularAcceleration(target).magnitude; //remember the best state if(angle <= 0f && error < TorqueError || angle < TorqueAngle || TorqueAngle < 0) { for(int j = 0; j < num_engines; j++) { var e = engines[j]; e.best_limit = e.limit; } TorqueAngle = angle; TorqueError = error; } //check convergence conditions if(error < RCS.OptimizationTorqueCutoff*RCS.OptimizationPrecision || last_error > 0 && Mathf.Abs(error-last_error) < RCS.OptimizationPrecision*last_error) break; last_error = error; //normalize limits before optimization var limit_norm = 0f; for(int j = 0; j < num_engines; j++) { var e = engines[j]; if(limit_norm < e.limit) limit_norm = e.limit; } if(limit_norm > 0) { for(int j = 0; j < num_engines; j++) { var e = engines[j]; e.limit = Mathf.Clamp01(e.limit / limit_norm); } } if(!optimization_pass(engines, num_engines, target, error, RCS.OptimizationPrecision)) break; } var optimized = TorqueError < RCS.OptimizationTorqueCutoff || (!zero_torque && TorqueAngle < RCS.OptimizationAngleCutoff); //treat single-engine crafts specially if(num_engines == 1) engines[0].limit = optimized? 1f : 0f; else //restore the best state for(int j = 0; j < num_engines; j++) { var e = engines[j]; e.limit = e.best_limit; } return optimized; }
private void GetBaseSunDirection(out Vector3 baseSunDirection, out Vector3 sunRotationAxis) { baseSunDirection = Vector3.Zero; var ed = ((MyObjectBuilder_EnvironmentDefinition)MyDefinitionManager.Static.EnvironmentDefinition.GetObjectBuilder()); if (!MyAPIGateway.Session.SessionSettings.EnableSunRotation) { baseSunDirection = ed.SunProperties.SunDirectionNormalized; sunRotationAxis = Vector3.Zero; return; } // -- Sandbox.Game.SessionComponents.MySectorWeatherComponent.Init() -- var cpnt = MyAPIGateway.Session.GetCheckpoint("null"); foreach (var comp in cpnt.SessionComponents) { var weatherComp = comp as MyObjectBuilder_SectorWeatherComponent; if (weatherComp != null) { baseSunDirection = weatherComp.BaseSunDirection; } } if (Vector3.IsZero(baseSunDirection)) { baseSunDirection = ed.SunProperties.BaseSunDirectionNormalized; } // -- Sandbox.Game.SessionComponents.MySectorWeatherComponent.BeforeStart() -- float num = Math.Abs(baseSunDirection.X) + Math.Abs(baseSunDirection.Y) + Math.Abs(baseSunDirection.Z); if ((double)num < 0.001) { baseSunDirection = ed.SunProperties.BaseSunDirectionNormalized; } // -- VRage.Game.MySunProperties.SunRotationAxis -- Vector3 baseSunDirectionNormalized = ed.SunProperties.BaseSunDirectionNormalized; float num2 = Math.Abs(Vector3.Dot(baseSunDirectionNormalized, Vector3.Up)); Vector3 result; if (num2 > 0.95f) { result = Vector3.Cross(Vector3.Cross(baseSunDirectionNormalized, Vector3.Left), baseSunDirectionNormalized); } else { result = Vector3.Cross(Vector3.Cross(baseSunDirectionNormalized, Vector3.Up), baseSunDirectionNormalized); } result.Normalize(); sunRotationAxis = result; }
public bool Contains(ref Vector3D point) { Vector3D vectord; List <BoundingBox> .Enumerator enumerator; Vector3D.Transform(ref point, ref this.m_worldInv, out vectord); Vector3 vector = Vector3.TransformNormal(MyGravityProviderSystem.CalculateNaturalGravityInPoint(this.m_grid.PositionComp.WorldAABB.Center), this.m_worldInv); if (!Vector3.IsZero(vector)) { vector = Vector3.Normalize(vector); Ray ray = new Ray((Vector3)vectord, -vector * 2f); using (enumerator = this.m_segments.GetEnumerator()) { bool flag; while (true) { if (enumerator.MoveNext()) { float?nullable = enumerator.Current.Intersects(ray); if (nullable == null) { continue; } flag = true; } else { goto TR_0000; } break; } return(flag); } } using (enumerator = this.m_segments.GetEnumerator()) { while (true) { if (!enumerator.MoveNext()) { break; } BoundingBox current = enumerator.Current; if (current.Contains(vectord) == ContainmentType.Contains) { return(true); } } } TR_0000: return(false); }
protected override void Update() { if (!IsActive) { return; } if (scan()) { var correction = Vector3d.zero; for (int i = 0, count = Corrections.Count; i < count; i++) { correction += Corrections[i]; } if (correction.IsZero()) { if (ManeuverTimer.TimePassed) { Dangerous.Clear(); Correction = Vector3.zero; filter.Reset(); return; } } else { ManeuverTimer.Reset(); Correction = correction; } } if (Correction.IsZero()) { return; } filter.Update(Correction.ClampComponents(-CPS.MaxAvoidanceSpeed, CPS.MaxAvoidanceSpeed)); //correct needed vertical speed if (CFG.VF[VFlight.AltitudeControl]) { var dVSP = (float)Vector3d.Dot(filter.Value, VSL.Physics.Up); if (VSC != null && (dVSP > 0 || VSL.Altitude.Relative - VSL.Geometry.H + (dVSP + VSL.VerticalSpeed.Relative) * CPS.LookAheadTime > 0)) { VSC.SetpointOverride = CFG.VerticalCutoff + dVSP; } // else dVSP = 0;//debug // Log("\nCorrection {}\nAction {}\ndVSP {}\ncorrectins: {}", // Correction, filter.Value, dVSP, // Corrections.Aggregate("\n", (s, v) => s+v+"\n"));//debug } //correct horizontal course HSC.AddWeightedCorrection(Vector3d.Exclude(VSL.Physics.Up, filter.Value)); }
protected void compute_steering(Vector3 current, Vector3 needed) { #if DEBUG if (current.IsZero() || needed.IsZero()) { LogFST("compute steering:\ncurrent {}\nneeded {}\ncurrent thrust {}", current, needed, VSL.Engines.CurrentThrustDir); } #endif VSL.Controls.SetAttitudeError(Vector3.Angle(needed, current)); if (VSL.Controls.AttitudeError > ATCB.AngleThreshold) { //rotational axis var current_maxI = current.MaxI(); var axis = Vector3.Cross(needed, current).Exclude(current_maxI); if (axis.sqrMagnitude < 0.01f) { axis = VSL.Torque.MaxCurrent.AA.Exclude(current_maxI).MaxComponentV(); } //main rotation component var axis1 = axis.MaxComponentV(); var current_cmp1 = Vector3.ProjectOnPlane(current, axis1); var needed_cmp1 = Vector3.ProjectOnPlane(needed, axis1); var angle1 = Vector3.Angle(needed_cmp1, current_cmp1); //second rotation component var axis2 = (axis - axis1).MaxComponentV(); var angle2 = Vector3.Angle(needed, needed_cmp1); //steering steering = (axis1.normalized * angle1 + axis2.normalized * angle2) * Mathf.Deg2Rad; // LogF("\ncurrent_maxI: {}\n" + // "axis: {}\n" + // "axis1: {}\n" + // "axis2: {}\n" + // "current_cmp1: {}\n" + // "needed_cmp1: {}\n" + // "angle1: {}\n" + // "angle2: {}\n", // current_maxI, axis, axis1, axis2, current_cmp1, needed_cmp1, angle1, angle2);//debug } else { steering = rotation2steering(Quaternion.FromToRotation(needed, current)); } // LogF("\nneeded {}\ncurrent {}\nangle {}\nsteering {}", // needed, current, Vector3.Angle(needed, current), DebugUtils.FormatSteering(steering));//debug //FIXME: sometimes generates NaN // needed (2.309423E+09, -5.479368E+11, -2.858228E+11); |v| = 6.180087E+11 // current (-0.0680542, -28.58647, -718.0868); |v| = 718.6556 // angle 60.17245 > threshold // steering [pitch NaN, roll NaN, yaw NaN] }
public override void OnLoad(ConfigNode node) { base.OnLoad(node); if (OrigSize.IsZero() || OrigScale.IsZero() || OrigPartSize.IsZero()) { var part_metric = new Metric(part); var metric = default(Metric); if (!string.IsNullOrEmpty(MetricMesh)) { var metric_mesh = part.FindModelComponent <MeshFilter>(MetricMesh); if (metric_mesh != null) { metric = new Metric(metric_mesh, part.transform); } else { this.Warning($"MeshMetric: no such MeshFilter: {MetricMesh.GetID()}"); } } if (metric.Empty) { metric = part_metric; } OrigSize = metric.size; OrigScale = model.localScale; OrigPartSize = part_metric.size; PartCenter = part_metric.center.Local2Local(part.partTransform, model); } if (Size.IsZero()) { Size = OrigSize; } update_model(false); //deprecated config conversion if (node.HasValue("Deploying")) { state = DeploymentState.IDLE; var val = node.GetValue("Deploying"); if (bool.TryParse(val, out bool _deploy) && _deploy) { state = DeploymentState.DEPLOYING; } else { val = node.GetValue("Deployed"); if (bool.TryParse(val, out _deploy) && _deploy) { state = DeploymentState.DEPLOYED; } } } }
public override void Update() { Steering = new Vector3(vessel.ctrlState.pitch, vessel.ctrlState.roll, vessel.ctrlState.yaw); Translation = new Vector3(vessel.ctrlState.X, vessel.ctrlState.Z, vessel.ctrlState.Y); if (!Steering.IsZero()) { Steering = Steering / Steering.CubeNorm().magnitude; } if (!Translation.IsZero()) { Translation = Translation / Translation.CubeNorm().magnitude; } }
public override bool HandleCommand(ulong userId, string[] words) { var entities = MyEntities.GetEntities( ).ToArray( ); var planets = new HashSet <MyPlanet>( ); int count = 0; foreach (var entity in entities) { MyPlanet item = entity as MyPlanet; if (item != null) { planets.Add(item); } } foreach (var planet in planets) { var sphere25 = new BoundingSphereD(planet.PositionComp.GetPosition(), planet.MinimumRadius * 0.25); var sphere75 = new BoundingSphereD(planet.PositionComp.GetPosition(), planet.MinimumRadius * 0.75); foreach (var entity in entities) { if (entity.MarkedForClose || entity.Physics == null || entity is MyCharacter) { continue; } if (sphere25.Contains(entity.PositionComp.GetPosition()) != ContainmentType.Disjoint) { count++; Wrapper.BeginGameAction(entity.Close, null, null); continue; } if (Vector3.IsZero(entity.Physics.LinearVelocity)) { continue; } if (sphere75.Contains(entity.PositionComp.GetPosition()) == ContainmentType.Disjoint) { continue; } count++; Wrapper.BeginGameAction(entity.Close, null, null); } } Communication.SendPrivateInformation(userId, $"Deleted {count} entities trapped in planets."); return(true); }
protected void compute_steering() { #if DEBUG VSL.Controls.GimbalLimit = UseGimball && VSL.PreUpdateControls.mainThrottle > 0 ? 100 : 0; #else VSL.Controls.GimbalLimit = VSL.PreUpdateControls.mainThrottle > 0? 100 : 0; #endif if (rotation_axis.IsZero()) { return; } var AV = get_angular_velocity(); var AM = Vector3.Scale(AV, VSL.Physics.MoI); var angular_error = VSL.Controls.AttitudeError / 180; var abs_rotation_axis = rotation_axis.AbsComponents(); var ErrV = angular_error * abs_rotation_axis; var iErr = Vector3.one - ErrV; var MaxAA = VSL.Torque.Slow ? VSL.Torque.Instant.AA + VSL.Torque.SlowMaxPossible.AA * Mathf.Min(VSL.PreUpdateControls.mainThrottle, VSL.OnPlanetParams.GeeVSF) : VSL.Torque.MaxCurrent.AA; MaxAA_Filter.Tau = (1 - Mathf.Sqrt(angular_error)) * C.AALowPassF; MaxAA = MaxAA_Filter.Update(MaxAA); var iMaxAA = MaxAA.Inverse(0); if (VSL.Torque.Slow) { pid_pitch.Tune(AV.x, AM.x, MaxAA.x, iMaxAA.x, ErrV.x, iErr.x, MaxAA.x > 0 ? VSL.Torque.Instant.AA.x / MaxAA.x : 1, VSL.Torque.EnginesResponseTime.x, VSL.Torque.MaxPossible.SpecificTorque.x); pid_roll.Tune(AV.y, AM.y, MaxAA.y, iMaxAA.y, ErrV.y, iErr.y, MaxAA.y > 0 ? VSL.Torque.Instant.AA.y / MaxAA.y : 1, VSL.Torque.EnginesResponseTime.y, VSL.Torque.MaxPossible.SpecificTorque.y); pid_yaw.Tune(AV.z, AM.z, MaxAA.z, iMaxAA.z, ErrV.z, iErr.z, MaxAA.z > 0 ? VSL.Torque.Instant.AA.z / MaxAA.z : 1, VSL.Torque.EnginesResponseTime.z, VSL.Torque.MaxPossible.SpecificTorque.z); } else { pid_pitch.TuneFast(AV.x, AM.x, MaxAA.x, iMaxAA.x, iErr.x); pid_roll.TuneFast(AV.y, AM.y, MaxAA.y, iMaxAA.y, iErr.y); pid_yaw.TuneFast(AV.z, AM.z, MaxAA.z, iMaxAA.z, iErr.z); } pid_pitch.atPID.Update(ErrV.x * Mathf.PI, -AV.x * Mathf.Sign(rotation_axis.x)); pid_roll.atPID.Update(ErrV.y * Mathf.PI, -AV.y * Mathf.Sign(rotation_axis.y)); pid_yaw.atPID.Update(ErrV.z * Mathf.PI, -AV.z * Mathf.Sign(rotation_axis.z)); var avErr = compute_av_error(AV, angular_error); steering = new Vector3(pid_pitch.UpdateAV(avErr.x), pid_roll.UpdateAV(avErr.y), pid_yaw.UpdateAV(avErr.z)); correct_steering(); }
protected override Vector3 UpdatePosition() { vectorSum = Vector3.zero; totalMass = 0f; EditorUtils.RunOnAllParts(calculateCoM); if (vectorSum.IsZero()) { return(vectorSum); } return(vectorSum / totalMass); }
public override void Update() { Steering = new Vector3(vessel.ctrlState.pitch, vessel.ctrlState.roll, vessel.ctrlState.yaw); Translation = new Vector3(vessel.ctrlState.X, vessel.ctrlState.Z, vessel.ctrlState.Y); if (!Steering.IsZero()) { Steering = Steering / Steering.CubeNorm().magnitude; } if (!Translation.IsZero()) { Translation = Translation / Translation.CubeNorm().magnitude; } TranslationAvailable = VSL.Engines.Maneuver.Count > 0 || VSL.Engines.NumActiveRCS > 0; }
public override void Handle() { if (!PluginSettings.Instance.ProtectionZonesEnabled) { return; } MyEntity[] entities = MyEntities.GetEntities().ToArray(); if (entities.Length == 0) { NoGrief.Log.Info("Failed to get entities in protection zone update. Skipping update."); return; } foreach (SettingsProtectionItem item in PluginSettings.Instance.ProtectionItems) { if (!item.Enabled) { continue; } MyEntity outEntity; if (!MyEntities.TryGetEntityById(item.EntityId, out outEntity)) { NoGrief.Log.Error($"Can't find entity with ID {item.EntityId} in protection zone update!"); continue; } item.ContainsEntities.Clear(); if (outEntity.Physics != null) { //zones don't work on moving entities if (!Vector3.IsZero(outEntity.Physics.LinearVelocity) || !Vector3.IsZero(outEntity.Physics.AngularVelocity)) { continue; } } var sphere = new BoundingSphereD(outEntity.Center(), item.Radius); foreach (MyEntity entity in entities) { if (sphere.Contains(entity.Center()) == ContainmentType.Contains) { item.ContainsEntities.Add(entity.EntityId); } } } }
public override void Update(float deltaTime) { //check for optimized update path. if (!UseDirection && (Attenuation == 0f)) { if (UseMaxDistance) { UpdateNoAttenuationNoDir(deltaTime); } else { UpdateNoAttenuationNoDirNoDist(deltaTime); } return; } Vector3 dragAxis = Vector3.one; if (UseDirection && !Direction.IsZero()) { dragAxis = DragObj.rotation * Direction; dragAxis.Normalize(); } float distance = (Node.GetOriginalPos() - DragObj.position).magnitude; if (!UseMaxDistance || distance <= MaxDistance) { float proj = 1f; if (UseDirection) { Vector3 nodeDir = Node.Velocity; nodeDir.Normalize(); proj = Vector3.Dot(nodeDir, dragAxis); } float reduction = (Magnitude * deltaTime * proj / (1f + distance * Attenuation)); if (reduction < 1f) { Node.Velocity -= reduction * Node.Velocity; } else { Node.Velocity = Vector3.zero; } } }
protected void compute_steering(Vector3 current, Vector3 needed) { #if DEBUG if(current.IsZero() || needed.IsZero()) LogFST("compute steering:\ncurrent {}\nneeded {}\ncurrent thrust {}", current, needed, VSL.Engines.CurrentThrustDir); #endif VSL.Controls.SetAttitudeError(Vector3.Angle(needed, current)); if(VSL.Controls.AttitudeError > ATCB.AngleThreshold) { //rotational axis var current_maxI = current.MaxI(); var axis = Vector3.Cross(needed, current).Exclude(current_maxI); if(axis.sqrMagnitude < 0.01f) axis = VSL.Torque.MaxCurrent.AA.Exclude(current_maxI).MaxComponentV(); //main rotation component var axis1 = axis.MaxComponentV(); var current_cmp1 = Vector3.ProjectOnPlane(current, axis1); var needed_cmp1 = Vector3.ProjectOnPlane(needed, axis1); var angle1 = Vector3.Angle(needed_cmp1, current_cmp1); //second rotation component var axis2 = (axis - axis1).MaxComponentV(); var angle2 = Vector3.Angle(needed, needed_cmp1); //steering steering = (axis1.normalized * angle1 + axis2.normalized * angle2) * Mathf.Deg2Rad; // LogF("\ncurrent_maxI: {}\n" + // "axis: {}\n" + // "axis1: {}\n" + // "axis2: {}\n" + // "current_cmp1: {}\n" + // "needed_cmp1: {}\n" + // "angle1: {}\n" + // "angle2: {}\n", // current_maxI, axis, axis1, axis2, current_cmp1, needed_cmp1, angle1, angle2);//debug } else steering = rotation2steering(Quaternion.FromToRotation(needed, current)); // LogF("\nneeded {}\ncurrent {}\nangle {}\nsteering {}", // needed, current, Vector3.Angle(needed, current), DebugUtils.FormatSteering(steering));//debug //FIXME: sometimes generates NaN // needed (2.309423E+09, -5.479368E+11, -2.858228E+11); |v| = 6.180087E+11 // current (-0.0680542, -28.58647, -718.0868); |v| = 718.6556 // angle 60.17245 > threshold // steering [pitch NaN, roll NaN, yaw NaN] }
public bool OptimizeLimitsForTorque(IList<EngineWrapper> engines, Vector3 needed_torque, out float max_limit) { var num_engines = engines.Count; var zero_torque = needed_torque.IsZero(); TorqueAngle = TorqueError = -1f; float error, angle; var last_error = -1f; Vector3 cur_imbalance = VSL.Torque.Engines.Torque, target; // Log("=============================== Optimization ===============================\n" + // "needed_torque {}\n" + // "OnPlanet.VSF {}, GeeVSF {}, MaxTWR {}\n" + // "Physics.M {}, G {}\n" + // "Engines.MaxThrust {}\n" + // "Control.AttitudeError {}, InvFactor {}\n", // needed_torque, // VSL.OnPlanetParams.VSF, VSL.OnPlanetParams.GeeVSF, VSL.OnPlanetParams.MaxTWR, // VSL.Physics.M, VSL.Physics.G, // VSL.Engines.MaxThrust, // VSL.Controls.AttitudeError, VSL.Controls.InvAlignmentFactor);//debug for(int i = 0; i < ENG.MaxIterations; i++) { //calculate current errors and target cur_imbalance = VSL.Torque.Engines.Torque; for(int j = 0; j < num_engines; j++) { var e = engines[j]; cur_imbalance += e.Torque(e.throttle * e.limit); } angle = zero_torque? 0f : Vector3.Angle(cur_imbalance, needed_torque); target = needed_torque-cur_imbalance; error = VSL.Torque.AngularAcceleration(target).magnitude; //remember the best state if(angle <= 0f && error < TorqueError || angle+error < TorqueAngle+TorqueError || TorqueAngle < 0) { for(int j = 0; j < num_engines; j++) { var e = engines[j]; e.best_limit = e.limit; } TorqueAngle = angle; TorqueError = error; } //check convergence conditions if(error < ENG.OptimizationTorqueCutoff*ENG.OptimizationPrecision || last_error > 0 && Mathf.Abs(error-last_error) < ENG.OptimizationPrecision*last_error) break; last_error = error; //normalize limits of main and balanced engines before optimization var limit_norm = 0f; for(int j = 0; j < num_engines; j++) { var e = engines[j]; if(e.Role == TCARole.MANEUVER) continue; if(limit_norm < e.limit) limit_norm = e.limit; } if(limit_norm > 0) { for(int j = 0; j < num_engines; j++) { var e = engines[j]; if(e.Role == TCARole.MANEUVER) continue; e.limit = Mathf.Clamp01(e.limit / limit_norm); } } //optimize limits if(!optimization_for_torque_pass(engines, num_engines, target, error, ENG.OptimizationPrecision)) break; } var optimized = TorqueError < ENG.OptimizationTorqueCutoff || (!zero_torque && TorqueAngle < ENG.OptimizationAngleCutoff); // Log("num engines {}, optimized {}, TorqueError {}, TorqueAngle {}\nneeded torque {}\ncurrent turque {}\nlimits:\n{}\n" + // "-------------------------------------------------------------------------------------------------", // num_engines, optimized, TorqueError, TorqueAngle, needed_torque, cur_imbalance, // engines.Aggregate("", (s, e) => s+string.Format("{0}: VSF {1:P1}, throttle {2:P1}, best limit {3:P1}\n", // e.name, e.VSF, e.throttle, e.best_limit)));//debug //treat single-engine crafts specially if(num_engines == 1) { engines[0].limit = optimized? engines[0].best_limit : 0f; max_limit = engines[0].limit; } else //restore the best state { max_limit = 0; for(int j = 0; j < num_engines; j++) { var e = engines[j]; e.limit = e.best_limit; if(e.limit > max_limit) max_limit = e.limit; } } return optimized; }
public override void Update(GameTime gameTime) { if (!camera.Active) return; var dt = gameTime.GetDeltaTime(); var newPosition = camera.Position; var newOrientation = camera.Orientation; var deltaRotation = new Vector2(); var mouse = InputDevice.GetMouse(); if (mouse.IsMouseMoved) { deltaRotation.X += mouse.DeltaX; deltaRotation.Y += mouse.DeltaY; mouse.ResetPosition(); } var pad = InputDevice.GetGamePad(PlayerIndex); { const float padRotationAmount = 10.0f; var stickPosition = pad.CurrentState.ThumbSticks.Right; deltaRotation.X += stickPosition.X * padRotationAmount; deltaRotation.Y += -stickPosition.Y * padRotationAmount; } { float yaw; float pitch; float roll; camera.Orientation.ToYawPitchRoll(out yaw, out pitch, out roll); yaw -= RotationVelocity * deltaRotation.X * dt % (2 * MathHelper.Pi); pitch -= RotationVelocity * deltaRotation.Y * dt; if (MathHelper.PiOver2 < pitch) { pitch = MathHelper.PiOver2; } else if (pitch < -MathHelper.PiOver2) { pitch = -MathHelper.PiOver2; } newOrientation = Matrix.CreateFromYawPitchRoll(yaw, pitch, roll); } var moveDirection = new Vector3(0, 0, 0); var keyboard = InputDevice.GetKeybord(PlayerIndex); if (keyboard.IsKeyDown(Keys.W)) { moveDirection.Z = -1; } if (keyboard.IsKeyDown(Keys.S)) { moveDirection.Z = 1; } if (keyboard.IsKeyDown(Keys.D)) { moveDirection.X = 1; } if (keyboard.IsKeyDown(Keys.A)) { moveDirection.X = -1; } if (keyboard.IsKeyDown(Keys.Q)) { moveDirection.Y = 1; } if (keyboard.IsKeyDown(Keys.Z)) { moveDirection.Y = -1; } { var delta = pad.CurrentState.ThumbSticks.Left; moveDirection.X += delta.X; moveDirection.Z += -delta.Y; if (pad.IsButtonDown(Buttons.LeftShoulder)) { moveDirection.Y += 1; } if (pad.IsButtonDown(Buttons.RightShoulder)) { moveDirection.Y += -1; } } if (!moveDirection.IsZero()) { moveDirection.Normalize(); newPosition += MoveVelocity * dt * Vector3.Transform(moveDirection, newOrientation); } camera.Position = newPosition; camera.Orientation = newOrientation; }
public override void Update() { Steering = new Vector3(vessel.ctrlState.pitch, vessel.ctrlState.roll, vessel.ctrlState.yaw); Translation = new Vector3(vessel.ctrlState.X, vessel.ctrlState.Z, vessel.ctrlState.Y); if(!Steering.IsZero()) Steering = Steering/Steering.CubeNorm().magnitude; if(!Translation.IsZero()) Translation = Translation/Translation.CubeNorm().magnitude; TranslationAvailable = VSL.Engines.Maneuver.Count > 0 || VSL.Engines.NumActiveRCS > 0; }
protected override Vector3 UpdatePosition() { vectorSum = Vector3.zero; totalMass = 0f; EditorUtils.RunOnAllParts (calculateCoM); if (vectorSum.IsZero ()) { return vectorSum; } return vectorSum / totalMass; }
/// <summary> /// 指定の方向ベクトルについての衝突情報とその衝突法線ベクトルを探します。 /// </summary> /// <param name="direction">判定する方向ベクトル。</param> /// <param name="resultCollision">衝突情報 (JigLibX)。</param> /// <param name="resultNormal">衝突法線ベクトル。</param> void FindCollisionAndNormal(ref Vector3 direction, out CollisionInfo resultCollision, out Vector3? resultNormal) { resultCollision = null; resultNormal = null; if (direction.IsZero()) return; // 衝突リストから指定された検査方向ベクトルの逆ベクトルを // 衝突法線ベクトルとする CollisionSkin を探します。 // 逆ベクトルと法線ベクトルの一致性は、 // その内積結果が一定の範囲内である場合に一致とみなします。 var dir = -direction; dir.Normalize(); foreach (var collision in Collisions) { var normal = collision.DirToBody0; if (collision.SkinInfo.Skin1 == this) { Vector3.Negate(ref normal, out normal); } float nDotDir; Vector3.Dot(ref normal, ref dir, out nDotDir); if (0.7f < nDotDir) { resultCollision = collision; resultNormal = normal; break; } } }