protected override void CreateTerminalControls() { if (MyTerminalControlFactory.AreControlsCreated <MyMechanicalConnectionBlockBase>()) { return; } base.CreateTerminalControls(); var weldSpeed = new MyTerminalControlSlider <MyMechanicalConnectionBlockBase>("Weld speed", MySpaceTexts.BlockPropertyTitle_WeldSpeed, MySpaceTexts.Blank); weldSpeed.SetLimits((block) => 0f, (block) => MyGridPhysics.SmallShipMaxLinearVelocity()); weldSpeed.DefaultValueGetter = (block) => MyGridPhysics.LargeShipMaxLinearVelocity() - 5f; weldSpeed.Getter = (x) => x.m_weldSpeed; weldSpeed.Setter = (x, v) => x.m_weldSpeed.Value = v; weldSpeed.Writer = (x, res) => res.AppendDecimal((float)Math.Sqrt(x.m_weldSpeedSq), 1).Append("m/s"); weldSpeed.EnableActions(); MyTerminalControlFactory.AddControl(weldSpeed); var weldForce = new MyTerminalControlCheckbox <MyMechanicalConnectionBlockBase>("Force weld", MySpaceTexts.BlockPropertyTitle_WeldForce, MySpaceTexts.Blank); weldForce.Getter = (x) => x.m_forceWeld; weldForce.Setter = (x, v) => x.m_forceWeld.Value = v; weldForce.EnableAction(); MyTerminalControlFactory.AddControl(weldForce); var addPistonHead = new MyTerminalControlButton <MyMechanicalConnectionBlockBase>("Add Top Part", MySpaceTexts.BlockActionTitle_AddPistonHead, MySpaceTexts.BlockActionTooltip_AddPistonHead, (b) => b.RecreateTop()); addPistonHead.Enabled = (b) => (b.TopBlock == null); addPistonHead.EnableAction(MyTerminalActionIcons.STATION_ON); MyTerminalControlFactory.AddControl(addPistonHead); }
private void AabbPhantom_CollidableRemoved(ref HkpCollidableRemovedEvent eventData) { if (this.m_mesher != null) { HkRigidBody rigidBody = eventData.RigidBody; if (rigidBody != null) { List <IMyEntity> allEntities = rigidBody.GetAllEntities(); foreach (IMyEntity entity in allEntities) { MyGridPhysics physics = entity.Physics as MyGridPhysics; MyPhysicsBody body2 = entity.Physics as MyPhysicsBody; if ((physics != null) && (physics.RigidBody == rigidBody)) { using (this.m_nearbyEntitiesLock.AcquireExclusiveUsing()) { MyPhysicsBody body1 = body2; this.m_nearbyEntities.Remove(entity); } } } allEntities.Clear(); } } }
private void WeldedMarkBreakable() { if (HavokWorld == null) { return; } MyGridPhysics gp = this as MyGridPhysics; if (gp != null && (gp.Entity as MyCubeGrid).BlocksDestructionEnabled) { HavokWorld.BreakOffPartsUtil.MarkPieceBreakable(RigidBody, 0, gp.Shape.BreakImpulse); } uint shapeKey = 1; foreach (var child in WeldInfo.Children) { gp = child as MyGridPhysics; if (gp != null && (gp.Entity as MyCubeGrid).BlocksDestructionEnabled) { HavokWorld.BreakOffPartsUtil.MarkPieceBreakable(RigidBody, shapeKey, gp.Shape.BreakImpulse); } shapeKey++; } }
public void EnableFlyingState(bool enable) { float maxCharacterSpeed = MyGridPhysics.ShipMaxLinearVelocity() + this.m_maxSpeedRelativeToShip; this.m_physicsBody.ShapeChangeInProgress = true; this.EnableFlyingState(enable, maxCharacterSpeed, MyGridPhysics.ShipMaxLinearVelocity() + this.m_maxSpeedRelativeToShip, 9f); this.m_physicsBody.ShapeChangeInProgress = false; }
static void OnAddDestructionEffectMessage(ref AddDestructionEffectMsg msg, MyNetworkClient sender) { MyGridPhysics.CreateDestructionEffect(msg.EffectId, msg.Position, msg.Direction, msg.Scale); if (Sync.IsServer) { Sync.Layer.SendMessageToAllButOne(ref msg, sender.SteamUserId); } }
private void RigidBody_CollisionRemovedCallback(ref HkCollisionEvent e) { MyGridPhysics physics = base.CubeGrid.Physics; if ((this.IsAcceptableContact(e.BodyA) || this.IsAcceptableContact(e.BodyB)) && (Interlocked.Decrement(ref this.m_staticHitCount) < 0)) { Interlocked.Increment(ref this.m_staticHitCount); } }
public void EnableFlyingState(bool enable) { //multiply by constant because walking on max moving ship float maxCharacterWalkingSpeed = MyGridPhysics.ShipMaxLinearVelocity() + m_maxSpeedRelativeToShip; float maxCharacterFlyingSpeed = MyGridPhysics.ShipMaxLinearVelocity() + m_maxSpeedRelativeToShip; float maxAcceleration = 9; // why EnableFlyingState(enable, maxCharacterWalkingSpeed, maxCharacterFlyingSpeed, maxAcceleration); }
public static void MarkGridTensorDirty(MyCubeGrid grid) { MyGridPhysics physics = grid.Physics; if (physics != null) { physics.Shape.MarkSharedTensorDirty(); } }
protected override unsafe void UpdateDoorPosition() { if (base.m_subparts.Count != 0) { float num = (float)Math.Sqrt(1.1375000476837158); float z = base.m_currOpening * 1.75f; float num3 = base.m_currOpening * 1.570796f; if (z < num) { num3 = (float)Math.Asin((double)(z / 1.2f)); } else { float num5 = (1.75f - z) / (1.75f - num); num3 = 1.570796f - ((num5 * num5) * ((float)(1.570796012878418 - Math.Asin((double)(num / 1.2f))))); } z--; MyGridPhysics bodyA = base.CubeGrid.Physics; bool flag = !Sync.IsServer; int num4 = 0; bool flag2 = true; foreach (MyEntitySubpart subpart in base.m_subparts) { if (subpart != null) { Matrix matrix; Matrix *matrixPtr1; Matrix.CreateRotationY(flag2 ? num3 : -num3, out matrix); matrixPtr1.Translation = new Vector3(flag2 ? -1.2f : 1.2f, 0f, z); matrixPtr1 = (Matrix *)ref matrix; Matrix renderLocal = matrix * base.PositionComp.LocalMatrix; MyPhysicsComponentBase physics = subpart.Physics; if (flag && (physics != null)) { Matrix *matrixPtr2; Matrix identity = Matrix.Identity; matrixPtr2.Translation = new Vector3(flag2 ? -0.55f : 0.55f, 0f, 0f); matrixPtr2 = (Matrix *)ref identity; Matrix *matrixPtr3 = (Matrix *)ref identity; Matrix.Multiply(ref (Matrix) ref matrixPtr3, ref matrix, out identity); subpart.PositionComp.SetLocalMatrix(ref identity, null, true); } subpart.PositionComp.SetLocalMatrix(ref matrix, physics, true, ref renderLocal, true); if (((bodyA != null) && (physics != null)) && (base.m_subpartConstraintsData.Count > num4)) { bodyA.RigidBody.Activate(); physics.RigidBody.Activate(); matrix = Matrix.Invert(matrix); base.m_subpartConstraintsData[num4].SetInBodySpace(base.PositionComp.LocalMatrix, matrix, bodyA, (MyPhysicsBody)physics); } } flag2 = !flag2; num4++; } } }
public static void Postfix(ref MyPhysicsBody __instance) { if (SpeedLimitFix.Shared.isEnabled && __instance.RigidBody2 != null) { if (MySession.Static.OnlineMode == VRage.Game.MyOnlineModeEnum.OFFLINE) { __instance.RigidBody2.MaxLinearVelocity = MyGridPhysics.ShipMaxLinearVelocity() + 100; } } }
public void EnableFlyingState(bool enable) { //multiply by constant because walking on max moving ship bool shouldLimitSpeed = Sync.IsServer; float maxCharacterWalkingSpeed = shouldLimitSpeed ? (MyGridPhysics.ShipMaxLinearVelocity() + m_maxSpeedRelativeToShip) : MyGridPhysics.MAX_SHIP_SPEED; float maxCharacterFlyingSpeed = shouldLimitSpeed ? (MyGridPhysics.ShipMaxLinearVelocity() + m_maxSpeedRelativeToShip) : MyGridPhysics.MAX_SHIP_SPEED; float maxAcceleration = 9; // why EnableFlyingState(enable, maxCharacterWalkingSpeed, maxCharacterFlyingSpeed, maxAcceleration); }
private void RigidBody_CollisionAddedCallback(ref HkCollisionEvent e) { MyGridPhysics physics = base.CubeGrid.Physics; if (this.IsAcceptableContact(e.BodyA) || this.IsAcceptableContact(e.BodyB)) { this.m_contactCountdown = 30; Interlocked.Increment(ref this.m_staticHitCount); this.RegisterPerFrameUpdate(); } }
// ReSharper disable once InconsistentNaming private static void InitPatch(MyGyro __instance) { var max = ((MyGyroDefinition)_gyroDefinition.GetValue(__instance)).CubeSize == MyCubeSize.Small ? MyGridPhysics.GetSmallShipMaxAngularVelocity() : MyGridPhysics.GetLargeShipMaxAngularVelocity(); _gyroOverrideVelocity.GetSync <Vector3>(__instance).ValueChangedInRange( new Vector3(-max, -max, -max), new Vector3(max, max, max) ); }
static float MaxAngularRadiansPerSecond(MyGyro gyro) { if (gyro.m_gyroDefinition.CubeSize == MyCubeSize.Small) { return(MyGridPhysics.GetSmallShipMaxAngularVelocity()); } else { Debug.Assert(gyro.m_gyroDefinition.CubeSize == MyCubeSize.Large, "Maximal grid velocity not defined for other grids than small/large"); return(MyGridPhysics.GetLargeShipMaxAngularVelocity()); } }
public void ApplyGravity(Vector3 gravity) { HkCharacterRigidBody characterRigidBody = this.CharacterRigidBody; characterRigidBody.LinearVelocity += gravity * 0.01666667f; if (this.CharacterRigidBody.LinearVelocity.LengthSquared() > this.m_maxCharacterSpeedSq) { Vector3 linearVelocity = this.CharacterRigidBody.LinearVelocity; linearVelocity.Normalize(); linearVelocity *= MyGridPhysics.ShipMaxLinearVelocity() + this.MaxSpeedRelativeToShip; this.CharacterRigidBody.LinearVelocity = linearVelocity; } }
protected override float CalculateMass() { var group = MyCubeGridGroups.Static.PhysicalDynamic.GetGroup(Entity); MyGridPhysics body = Entity.Physics; float gridMass = body.WeldedRigidBody != null ? body.WeldedRigidBody.Mass : Entity.Physics.Mass; MyCubeGrid biggestGrid = null; float deathWeight = 0.0f; if (group != null) { float maxRadius = 0; foreach (var node in group.Nodes) { MyCubeGrid grid = node.NodeData; if (grid.IsStatic || grid.Physics == null) { continue; } var thrustComp = grid.Components.Get <MyEntityThrustComponent>(); bool hasThrust = thrustComp != null && thrustComp.Enabled && thrustComp.HasPower; if (hasThrust == false) { deathWeight += grid.Physics.WeldedRigidBody != null ? grid.Physics.WeldedRigidBody.Mass : grid.Physics.Mass; } else { var rad = grid.PositionComp.LocalVolume.Radius; if (rad > maxRadius || (rad == maxRadius && (biggestGrid == null || grid.EntityId > biggestGrid.EntityId))) { maxRadius = rad; biggestGrid = grid; } } } } if (biggestGrid == CubeGrid) { gridMass += deathWeight; } return(gridMass); }
protected override void UpdateThrusts() { base.UpdateThrusts(); ProfilerShort.Begin("MyJetpackThrustComponent.UpdateThrusts"); if (Character != null && Character.Physics != null && Jetpack.TurnedOn && (MySession.Static.LocalCharacter == Character || MySession.Static.ControlledEntity == Character || MySandboxGame.IsDedicated || (MySession.Static.GetCameraControllerEnum() == MyCameraControllerEnum.Entity && (MySector.MainCamera.IsInFrustum(Character.PositionComp.WorldAABB) || (Character.PositionComp.GetPosition() - MySector.MainCamera.Position).LengthSquared() < 100f)))) { if (FinalThrust.LengthSquared() > 0.001f) { if (Character.Physics.IsInWorld) { Character.Physics.AddForce(MyPhysicsForceType.ADD_BODY_FORCE_AND_BODY_TORQUE, FinalThrust, null, null); if (MyPerGameSettings.EnableMultiplayerVelocityCompensation) { Vector3 velocity = Character.Physics.LinearVelocity; float maxCharacterSpeedRelativeToShip = Math.Max(Character.Definition.MaxSprintSpeed, Math.Max(Character.Definition.MaxRunSpeed, Character.Definition.MaxBackrunSpeed)); float maxSpeed = (MyGridPhysics.ShipMaxLinearVelocity() + maxCharacterSpeedRelativeToShip) * (Sync.IsServer ? 1.0f : Sync.RelativeSimulationRatio); if (velocity.LengthSquared() > maxSpeed * maxSpeed) { velocity.Normalize(); velocity *= maxSpeed; Character.Physics.LinearVelocity = velocity; } } } } const float stoppingVelocitySq = 0.001f * 0.001f; if (Character.Physics.Enabled) { if (Character.Physics.LinearVelocity != Vector3.Zero && Character.Physics.LinearVelocity.LengthSquared() < stoppingVelocitySq) { Character.Physics.LinearVelocity = Vector3.Zero; ControlThrustChanged = true; } } } ProfilerShort.End(); }
private void CreatePhantomConstraint() { if (this.m_phantomConstraint != null) { this.DisposePhantomContraint(null); } MyGridPhysics bodyA = base.CubeGrid.Physics; MyPhysicsBody physics = base.Physics; if (((bodyA != null) && (physics != null)) && physics.Enabled) { HkFixedConstraintData data = new HkFixedConstraintData(); data.SetInBodySpace(base.PositionComp.LocalMatrix, Matrix.CreateTranslation(-physics.Center), bodyA, physics); this.m_phantomConstraint = new HkConstraint(bodyA.RigidBody, physics.RigidBody, data); bodyA.AddConstraint(this.m_phantomConstraint); } }
private void UpdateGridMaxSpeed(MyCubeGrid grid, bool fromServer = true) { if (Sync.IsServer == false && MyPerGameSettings.EnableMultiplayerVelocityCompensation && grid != null && grid.Physics != null && grid.Physics.RigidBody != null) { float maxSpeed = grid.GridSizeEnum == MyCubeSize.Large ? MyGridPhysics.LargeShipMaxLinearVelocity() : MyGridPhysics.SmallShipMaxLinearVelocity(); maxSpeed *= Sync.RelativeSimulationRatio; if (fromServer && grid.Physics.RigidBody.LinearVelocity.LengthSquared() > maxSpeed * maxSpeed) { grid.Physics.RigidBody.MaxLinearVelocity = grid.Physics.RigidBody.LinearVelocity.Length(); } else { grid.Physics.RigidBody.MaxLinearVelocity = maxSpeed; } } }
private static void UpdateGridMaxSpeed(MyCubeGrid grid, bool fromServer = true) { if (Sync.IsServer == false && grid != null && grid.Physics != null && grid.Physics.RigidBody != null) { float maxSpeed = 1.04f * (grid.GridSizeEnum == MyCubeSize.Large ? MyGridPhysics.LargeShipMaxLinearVelocity() : MyGridPhysics.SmallShipMaxLinearVelocity()); maxSpeed *= Sync.RelativeSimulationRatio; if (fromServer && grid.Physics.RigidBody.LinearVelocity.LengthSquared() > maxSpeed * maxSpeed) { grid.Physics.RigidBody.MaxLinearVelocity = grid.Physics.RigidBody.LinearVelocity.Length(); } else { grid.Physics.RigidBody.MaxLinearVelocity = maxSpeed; } } }
protected override void UpdateThrusts() { base.UpdateThrusts(); ProfilerShort.Begin("MyJetpackThrustComponent.UpdateThrusts"); if (Character != null && Character.Physics != null && Jetpack.TurnedOn && (!Character.ControllerInfo.IsRemotelyControlled() || Sync.IsServer)) { if (FinalThrust.LengthSquared() > 0.001f) { if (Character.Physics.IsInWorld) { Character.Physics.AddForce(MyPhysicsForceType.ADD_BODY_FORCE_AND_BODY_TORQUE, FinalThrust, null, null); if (MyPerGameSettings.EnableMultiplayerVelocityCompensation) { Vector3 velocity = Character.Physics.LinearVelocity; float maxCharacterSpeedRelativeToShip = Math.Max(Character.Definition.MaxSprintSpeed, Math.Max(Character.Definition.MaxRunSpeed, Character.Definition.MaxBackrunSpeed)); float maxSpeed = (MyGridPhysics.ShipMaxLinearVelocity() + maxCharacterSpeedRelativeToShip) * (Sync.IsServer ? 1.0f : Sync.RelativeSimulationRatio); if (velocity.LengthSquared() > maxSpeed * maxSpeed) { velocity.Normalize(); velocity *= maxSpeed; Character.Physics.LinearVelocity = velocity; } } } } const float stoppingVelocitySq = 0.001f * 0.001f; if (Character.Physics.Enabled) { if (Character.Physics.LinearVelocity != Vector3.Zero && Character.Physics.LinearVelocity.LengthSquared() < stoppingVelocitySq) { Character.Physics.LinearVelocity = Vector3.Zero; ControlThrustChanged = true; } } } ProfilerShort.End(); }
private bool IsAcceptableContact(HkRigidBody rb) { object userObject = rb.UserObject; if (userObject == null) { return(false); } if (userObject == base.CubeGrid.Physics) { return(false); } if (userObject is MyVoxelPhysicsBody) { return(true); } MyGridPhysics physics = userObject as MyGridPhysics; return((physics != null) && physics.IsStatic); }
private float GetObserverAngularVelocityDiff() { MyGridPhysics physics = base.CubeGrid.Physics; if ((physics != null) && (physics.LinearVelocity.LengthSquared() > 16f)) { IMyControllableEntity controlledEntity = MySession.Static.ControlledEntity; if (controlledEntity != null) { VRage.Game.Entity.MyEntity entity = controlledEntity.Entity; if (entity != null) { MyPhysicsComponentBase base2 = entity.GetTopMostParent(null).Physics; if (base2 != null) { return((physics.AngularVelocity - base2.AngularVelocity).Length()); } } } } return(0f); }
protected override void UpdateThrusts(bool enableDampers) { base.UpdateThrusts(enableDampers); ProfilerShort.Begin("MyJetpackThrustComponent.UpdateThrusts"); if (Character != null && Character.Physics != null && Jetpack.TurnedOn) { if (FinalThrust.LengthSquared() > 0.0001f) { if (Character.Physics.IsInWorld) { Character.Physics.AddForce(MyPhysicsForceType.ADD_BODY_FORCE_AND_BODY_TORQUE, FinalThrust, null, null); Vector3 velocity = Character.Physics.LinearVelocity; float maxCharacterSpeedRelativeToShip = Math.Max(Character.Definition.MaxSprintSpeed, Math.Max(Character.Definition.MaxRunSpeed, Character.Definition.MaxBackrunSpeed)); float maxSpeed = (MyGridPhysics.ShipMaxLinearVelocity() + maxCharacterSpeedRelativeToShip); if (velocity.LengthSquared() > maxSpeed * maxSpeed) { velocity.Normalize(); velocity *= maxSpeed; Character.Physics.LinearVelocity = velocity; } } } const float stoppingVelocitySq = 0.001f * 0.001f; if (Character.Physics.Enabled) { if (Character.Physics.LinearVelocity != Vector3.Zero && Character.Physics.LinearVelocity.LengthSquared() < stoppingVelocitySq) { Character.Physics.LinearVelocity = Vector3.Zero; ControlThrustChanged = true; } } } ProfilerShort.End(); }
protected override void CalculatePositionDifference(ulong clientId, out bool isValid, out bool correctServer, out Vector3D delta) { isValid = true; correctServer = false; Vector3D clientData = m_additionalServerClientData[clientId]; MatrixD worldMatrix = Entity.PositionComp.WorldMatrix; delta = m_additionalServerClientData[clientId] - worldMatrix.Translation; Vector3D currentMoveDistance = Entity.Physics.LinearVelocity / 60.0f; if (currentMoveDistance.Equals(-delta, 0.01)) { return; } float deltaL = (float)((currentMoveDistance + delta).LengthSquared()); float maxSpeed = 1.04f * MyGridPhysics.ShipMaxLinearVelocity(); float maxMoveDistance = (maxSpeed * maxSpeed) / (60f * 60f); if (deltaL > (maxMoveDistance + 0.0001)) { correctServer = true; return; isValid = false; delta = Vector3D.Zero; } else if (deltaL > 0.1 * 0.1) { correctServer = true; } }
static void CreateTerminalControls() { if (MyTerminalControlFactory.AreControlsCreated <MyMechanicalConnectionBlockBase>()) { return; } var weldSpeed = new MyTerminalControlSlider <MyMechanicalConnectionBlockBase>("Weld speed", MySpaceTexts.BlockPropertyTitle_WeldSpeed, MySpaceTexts.Blank); weldSpeed.SetLimits((block) => 0f, (block) => MyGridPhysics.SmallShipMaxLinearVelocity()); weldSpeed.DefaultValueGetter = (block) => MyGridPhysics.LargeShipMaxLinearVelocity() - 5f; weldSpeed.Getter = (x) => (float)Math.Sqrt(x.m_weldSpeedSq); weldSpeed.Setter = (x, v) => x.m_weldSpeedSq.Value = v * v; weldSpeed.Writer = (x, res) => res.AppendDecimal((float)Math.Sqrt(x.m_weldSpeedSq), 1).Append("m/s"); weldSpeed.EnableActions(); MyTerminalControlFactory.AddControl(weldSpeed); var weldForce = new MyTerminalControlCheckbox <MyMechanicalConnectionBlockBase>("Force weld", MySpaceTexts.BlockPropertyTitle_WeldForce, MySpaceTexts.Blank); weldForce.Getter = (x) => x.m_forceWeld; weldForce.Setter = (x, v) => x.m_forceWeld.Value = v; weldForce.EnableAction(); MyTerminalControlFactory.AddControl(weldForce); }
protected override void CustomClientRead(uint timeStamp, ref MyTimeStampValues serverPositionAndOrientation, VRage.Library.Collections.BitStream stream) { bool hasSupport = stream.ReadBool(); if (hasSupport) { long entityId = stream.ReadInt64(); Vector3D serverDelta = stream.ReadVector3D(); Vector3D serverSupportPos = stream.ReadVector3D(); if (!MyEntities.EntityExists(entityId)) { return; } MyEntity support = MyEntities.GetEntityById(entityId); MyTimeStampValues?clientTransform = m_timestamp.GetTransform(timeStamp); Vector3D clientDelta = Vector3.Zero; Vector3D clientVelocity = Vector3D.Zero; Quaternion rotationComp = Quaternion.Identity; if (clientTransform != null) { if (m_supportTimeStamp == null) { return; } MyTimeStampValues?supportTransform = m_supportTimeStamp.GetTransform(timeStamp); Vector3D supportPosition = support.PositionComp.WorldMatrix.Translation; if (supportTransform.HasValue) { supportPosition = supportTransform.Value.Transform.Position; if (supportTransform.Value.EntityId != entityId) { supportPosition = serverSupportPos; return; } } clientDelta = supportPosition - clientTransform.Value.Transform.Position; clientVelocity = clientTransform.Value.LinearVelocity; rotationComp = Quaternion.Inverse(clientTransform.Value.Transform.Rotation); } else { m_character.PositionComp.SetWorldMatrix(serverPositionAndOrientation.Transform.TransformMatrix, null, true); return; } MyTimeStampValues delta = new MyTimeStampValues(); Quaternion.Multiply(ref serverPositionAndOrientation.Transform.Rotation, ref rotationComp, out delta.Transform.Rotation); delta.Transform.Position = clientDelta - serverDelta; delta.LinearVelocity = serverPositionAndOrientation.LinearVelocity - clientVelocity; double deltaL = delta.Transform.Position.Length(); //if difference is more than if (deltaL < (MyGridPhysics.ShipMaxLinearVelocity() * Sync.RelativeSimulationRatio)) { delta.Transform.Position = delta.Transform.Position * 0.2; delta.Transform.Rotation = Quaternion.Slerp(delta.Transform.Rotation, Quaternion.Identity, 0.2f); } Quaternion normalized = delta.Transform.Rotation; normalized.Normalize(); delta.Transform.Rotation = normalized; normalized = serverPositionAndOrientation.Transform.Rotation; normalized.Normalize(); serverPositionAndOrientation.Transform.Rotation = normalized; Quaternion clientNormalized = clientTransform.Value.Transform.Rotation; clientNormalized.Normalize(); double eps = 0.001; if (Math.Abs(Quaternion.Dot(serverPositionAndOrientation.Transform.Rotation, clientNormalized)) < 1 - eps && m_character.IsDead == false) { Quaternion currentOrientation = Quaternion.CreateFromForwardUp(m_character.WorldMatrix.Forward, m_character.WorldMatrix.Up); Quaternion.Multiply(ref delta.Transform.Rotation, ref currentOrientation, out currentOrientation); MatrixD matrix = MatrixD.CreateFromQuaternion(currentOrientation); MatrixD currentMatrix = m_character.PositionComp.WorldMatrix; currentMatrix.Translation = Vector3D.Zero; if (currentMatrix.EqualsFast(ref matrix) == false) { if (m_character.Physics.CharacterProxy != null) { m_character.Physics.CharacterProxy.Forward = matrix.Forward; m_character.Physics.CharacterProxy.Up = matrix.Up; } } } if (deltaL > (MyGridPhysics.ShipMaxLinearVelocity() * Sync.RelativeSimulationRatio)) { m_character.PositionComp.SetPosition(serverPositionAndOrientation.Transform.Position); m_character.Physics.LinearVelocity = serverPositionAndOrientation.LinearVelocity; m_timestamp.OverwriteServerPosition(timeStamp, ref serverPositionAndOrientation); return; } else if (deltaL > 5.0f * MyTimestampHelper.POSITION_TOLERANCE) { m_character.CacheMoveDelta(ref delta.Transform.Position); } m_character.Physics.LinearVelocity += delta.LinearVelocity; m_timestamp.UpdateDeltaPosition(timeStamp, ref delta); } else { base.CustomClientRead(timeStamp, ref serverPositionAndOrientation, stream); } }
public void ServerResponse(uint timeStamp, ref MyTimeStampValues serverPositionAndOrientation) { if (timeStamp < m_lastTSFromServer) { return; } if (m_timeStampData.ContainsKey(timeStamp) == false) { m_entity.PositionComp.SetWorldMatrix(serverPositionAndOrientation.Transform.TransformMatrix, null, true); return; } MyTimeStampValues cachedData = m_timeStampData[timeStamp]; MatrixD worldMatrix = m_entity.PositionComp.WorldMatrix; MyTimeStampValues delta = new MyTimeStampValues(); delta.Transform.Position = serverPositionAndOrientation.Transform.Position - cachedData.Transform.Position; double deltaL = delta.Transform.Position.Length(); MyCharacter character = (m_entity as MyCharacter); cachedData.Transform.Rotation = Quaternion.Inverse(cachedData.Transform.Rotation); Quaternion.Multiply(ref serverPositionAndOrientation.Transform.Rotation, ref cachedData.Transform.Rotation, out delta.Transform.Rotation); if (deltaL < (MyGridPhysics.ShipMaxLinearVelocity() / (60f * Sync.RelativeSimulationRatio))) { delta.Transform.Position = delta.Transform.Position * 0.2; } delta.Transform.Rotation = Quaternion.Slerp(delta.Transform.Rotation, Quaternion.Identity, 0.2f); Vector3D position = worldMatrix.Translation; position += delta.Transform.Position; delta.LinearVelocity = serverPositionAndOrientation.LinearVelocity - cachedData.LinearVelocity; delta.AngularVelocity = serverPositionAndOrientation.AngularVelocity - cachedData.AngularVelocity; double deltaVelocity = delta.LinearVelocity.LengthSquared(); if (deltaVelocity > 0.1 * 0.1) { m_entity.Physics.LinearVelocity += delta.LinearVelocity; } deltaVelocity = delta.AngularVelocity.LengthSquared(); if (deltaVelocity > 0.01 * 0.01) { m_entity.Physics.AngularVelocity += delta.AngularVelocity; } Quaternion orientation = Quaternion.CreateFromForwardUp(worldMatrix.Forward, worldMatrix.Up); Quaternion normalized = cachedData.Transform.Rotation; normalized.Normalize(); cachedData.Transform.Rotation = normalized; normalized = serverPositionAndOrientation.Transform.Rotation; normalized.Normalize(); serverPositionAndOrientation.Transform.Rotation = normalized; double eps = 0.001; if (Math.Abs(Quaternion.Dot(serverPositionAndOrientation.Transform.Rotation, cachedData.Transform.Rotation)) < 1 - eps) { Quaternion.Multiply(ref delta.Transform.Rotation, ref orientation, out orientation); MatrixD matrix = MatrixD.CreateFromQuaternion(orientation); MatrixD currentMatrix = m_entity.PositionComp.WorldMatrix; Vector3D translation = currentMatrix.Translation; currentMatrix.Translation = Vector3D.Zero; if (currentMatrix.EqualsFast(ref matrix, 0.01) == false) { matrix.Translation = translation; m_entity.PositionComp.SetWorldMatrix(matrix, null, true); } } if (deltaL > (MyGridPhysics.ShipMaxLinearVelocity() / (60f * Sync.RelativeSimulationRatio))) { m_entity.PositionComp.SetPosition(serverPositionAndOrientation.Transform.Position); } else if (deltaL > POSITION_TOLERANCE) { if (m_entity is MyCharacter) { (m_entity as MyCharacter).CacheMoveDelta(ref delta.Transform.Position); } else { m_entity.PositionComp.SetPosition(position); } } UpdateDeltaPosition(timeStamp, ref delta); m_lastTSFromServer = timeStamp; }
public override void UpdateBeforeSimulation() { return; base.UpdateBeforeSimulation(); if (m_particleSpawnCounter-- > 0) { return; } var entity = MySession.Static.ControlledEntity as MyEntity; if (entity == null) { return; } var controlledEntity = entity.GetTopMostParent(); if (controlledEntity == null) { return; } try { ProfilerShort.Begin("Grassland.UpdateBeforeSimulation"); m_particleSpawnCounter = (int)Math.Round(m_particleSpawnCounter + m_particleSpawnCounter * m_particleSpawnIntervalRandomness * (MyRandom.Instance.NextFloat() * 2.0f - 1.0f)); if (MyRandom.Instance.FloatNormal() <= m_particleDensity) { return; } var cameraPosition = MySector.MainCamera.Position; MyPlanet nearestPlanet = MyGravityProviderSystem.GetNearestPlanet(cameraPosition); Vector3D naturalGravity = nearestPlanet.GetWorldGravityGrid(MySector.MainCamera.Position); if (naturalGravity.Dot(MySector.DirectionToSunNormalized) > 0) // Only spawn during the day { return; } var velocity = (MySession.Static.GetCameraControllerEnum() != MyCameraControllerEnum.Entity && MySession.Static.GetCameraControllerEnum() != MyCameraControllerEnum.ThirdPersonSpectator ? Vector3.Zero : controlledEntity.Physics.LinearVelocity); var speed = velocity.Length(); var cameraPositionLocal = Vector3D.Transform(cameraPosition, MatrixD.Invert(nearestPlanet.WorldMatrix)); //Vector3D nearestSurfacePointLocal = nearestPlanet.GetClosestSurfacePointLocal(cameraPosition); // Vector3D nearestSurfacePointWorld = Vector3D.Transform(nearestSurfacePointLocal, nearestPlanet.WorldMatrix); // bool test = nearestPlanet.IsFloraAtPosition(nearestSurfacePointLocal); var currentCharacter = controlledEntity as MyCharacter; float characterFlyingMaxSpeed = (currentCharacter != null) ? currentCharacter.Physics.CharacterProxy.CharacterFlyingMaxLinearVelocity() : MyGridPhysics.ShipMaxLinearVelocity(); Vector3 halfExtents = Vector3.One * m_particleSpawnDistance; if (speed / characterFlyingMaxSpeed > 1.0f) { halfExtents += 10.0f * velocity / characterFlyingMaxSpeed; } var entityTranslation = cameraPosition; var searchPosition = entityTranslation + velocity; MyPhysics.GetPenetrationsBox(ref halfExtents, ref searchPosition, ref Quaternion.Identity, m_bodyCollisions, MyPhysics.CollisionLayers.NotCollideWithStaticLayer); var spawnPosition = default(Vector3D); bool spawnPositionFound = false; foreach (var foundEntity in m_bodyCollisions) { var environmentItems = foundEntity.Body.GetEntity(foundEntity.ShapeKey) as MyEnvironmentItems; if (environmentItems != null) { environmentItems.GetAllItemsInRadius(searchPosition, m_particleSpawnDistance, m_tmpItemInfos); } } if (m_tmpItemInfos.Count != 0) { int selectedTreeIndex = MyRandom.Instance.Next(0, m_tmpItemInfos.Count - 1); spawnPosition = m_tmpItemInfos[selectedTreeIndex].Transform.Position; spawnPositionFound = true; } if (!spawnPositionFound) { return; } var spawnedParticle = Spawn(spawnPosition); if (spawnedParticle == null) { return; } InitializePath(spawnedParticle); } finally { m_bodyCollisions.Clear(); ProfilerShort.End(); } }
protected override void UpdateThrusts(bool networkUpdate = false) { base.UpdateThrusts(networkUpdate); ProfilerShort.Begin("ThrusterBlockComponent.UpdateThrusts"); if (CubeGrid != null && CubeGrid.Physics != null) { if (CubeGrid.Physics.Enabled) { if (FinalThrust.LengthSquared() > 0.001f) { var thrust = FinalThrust; if (CubeGrid.Physics.IsWelded) //only reliable variant { thrust = Vector3.TransformNormal(thrust, CubeGrid.WorldMatrix); thrust = Vector3.TransformNormal(thrust, Matrix.Invert(CubeGrid.Physics.RigidBody.GetRigidBodyMatrix())); } CubeGrid.Physics.AddForce(MyPhysicsForceType.ADD_BODY_FORCE_AND_BODY_TORQUE, thrust, null, null); if (MyPerGameSettings.EnableMultiplayerVelocityCompensation) { Vector3 velocity = CubeGrid.Physics.LinearVelocity; float maxSpeed = CubeGrid.GridSizeEnum == MyCubeSize.Large ? MyGridPhysics.LargeShipMaxLinearVelocity() : MyGridPhysics.SmallShipMaxLinearVelocity(); maxSpeed *= Sync.RelativeSimulationRatio; if (velocity.LengthSquared() > maxSpeed * maxSpeed) { velocity.Normalize(); velocity *= maxSpeed; CubeGrid.Physics.LinearVelocity = velocity; } } } const float stoppingVelocitySq = 0.001f * 0.001f; if (CubeGrid.Physics.LinearVelocity != Vector3.Zero && CubeGrid.Physics.LinearVelocity.LengthSquared() < stoppingVelocitySq && CubeGrid.Physics.RigidBody.IsActive) { CubeGrid.Physics.LinearVelocity = Vector3.Zero; ControlThrustChanged = true; } } } ProfilerShort.End(); }