protected override bool CanPlaceRotor(MyMotorRotor rotorBlock, long builtBy) { BoundingSphereD sphere = rotorBlock.Model.BoundingSphere; sphere.Center = Vector3D.Transform(sphere.Center, rotorBlock.WorldMatrix); CubeGrid.GetBlocksInsideSphere(ref sphere, m_tmpSet); HkSphereShape spShape = new HkSphereShape((float)sphere.Radius); Quaternion q = Quaternion.Identity;//Quaternion.CreateFromForwardUp(rotorBlock.WorldMatrix.Forward, rotorBlock.WorldMatrix.Up); var position = rotorBlock.WorldMatrix.Translation; MyPhysics.GetPenetrationsShape(spShape, ref position, ref q, m_tmpList, MyPhysics.CharacterNetworkCollisionLayer); if (m_tmpSet.Count > 1 || m_tmpList.Count > 0) { m_tmpList.Clear(); m_tmpSet.Clear(); if (builtBy == MySession.LocalPlayerId) { MyHud.Notifications.Add(MyNotificationSingletons.WheelNotPlaced); } return(false); } m_tmpList.Clear(); m_tmpSet.Clear(); return(true); }
private void WeldGroup() { var topGrid = m_rotorGrid; var topBlock = m_rotorBlock; m_isWelding = true; m_weldedRotorBlockId = m_rotorBlock.EntityId; if (Sync.IsServer) { MatrixD masterToSlave = topBlock.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix); m_rotorBlockId.Value = new State() { OtherEntityId = m_weldedRotorBlockId, MasterToSlave = masterToSlave }; m_weldedEntityId.Value = m_weldedRotorBlockId; } Detach(false); MyWeldingGroups.Static.CreateLink(EntityId, CubeGrid, topGrid); m_rotorGrid = topGrid; m_rotorBlock = topBlock; m_welded = true; m_isWelding = false; }
public override bool Attach(MyMotorRotor rotor, bool updateSync = false, bool updateGroup = true) { if (CubeGrid.Physics == null || SafeConstraint != null) { return(false); } Debug.Assert(SafeConstraint == null); if (CubeGrid.Physics.Enabled && rotor != null) { m_rotorBlock = rotor; m_rotorBlockId = rotor.EntityId; if (updateSync) { SyncObject.AttachRotor(m_rotorBlock); } m_rotorGrid = m_rotorBlock.CubeGrid; if (m_rotorGrid.Physics == null) { return(false); } var rotorBody = m_rotorGrid.Physics.RigidBody; var data = new HkLimitedHingeConstraintData(); m_motor = new HkVelocityConstraintMotor(1.0f, 1000000f); data.SetSolvingMethod(HkSolvingMethod.MethodStabilized); data.Motor = m_motor; data.DisableLimits(); var posA = DummyPosition; var posB = rotor.Position * rotor.CubeGrid.GridSize; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; var axisBPerp = rotor.PositionComp.LocalMatrix.Forward; data.SetInBodySpace(ref posA, ref posB, ref axisA, ref axisB, ref axisAPerp, ref axisBPerp); m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, rotorBody, data); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; SetAngleToPhysics(); m_rotorBlock.Attach(this); if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); } m_isAttached = true; return(true); } return(false); }
protected void CreateRotorGrid(out MyCubeGrid rotorGrid, out MyAttachableTopBlockBase rotorBlock, long builtBy, MyCubeBlockDefinitionGroup rotorGroup) { Debug.Assert(Sync.IsServer, "Rotor grid can be created only on server"); if (rotorGroup == null) { rotorGrid = null; rotorBlock = null; return; } var gridSize = CubeGrid.GridSizeEnum; float size = MyDefinitionManager.Static.GetCubeSize(gridSize); var matrix = MatrixD.CreateWorld(Vector3D.Transform(DummyPosition, CubeGrid.WorldMatrix), WorldMatrix.Forward, WorldMatrix.Up); var definition = rotorGroup[gridSize]; Debug.Assert(definition != null); var block = MyCubeGrid.CreateBlockObjectBuilder(definition, Vector3I.Zero, MyBlockOrientation.Identity, MyEntityIdentifier.AllocateId(), OwnerId, fullyBuilt: MySession.Static.CreativeMode); var gridBuilder = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_CubeGrid>(); gridBuilder.GridSizeEnum = gridSize; gridBuilder.IsStatic = false; gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(matrix); gridBuilder.CubeBlocks.Add(block); var grid = MyEntityFactory.CreateEntity <MyCubeGrid>(gridBuilder); grid.Init(gridBuilder); rotorGrid = grid; MyMotorRotor rotor = (MyMotorRotor)rotorGrid.GetCubeBlock(Vector3I.Zero).FatBlock; rotorBlock = rotor; rotorGrid.PositionComp.SetPosition(rotorGrid.WorldMatrix.Translation - (Vector3D.Transform(rotor.DummyPosLoc, rotorGrid.WorldMatrix) - rotorGrid.WorldMatrix.Translation)); if (!CanPlaceRotor(rotorBlock, builtBy)) { rotorGrid = null; rotorBlock = null; grid.Close(); return; } MyEntities.Add(grid); if (MyFakes.ENABLE_SENT_GROUP_AT_ONCE) { MyMultiplayer.ReplicateImmediatelly(MyExternalReplicable.FindByObject(grid), MyExternalReplicable.FindByObject(CubeGrid)); } MatrixD masterToSlave = rotorBlock.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix); m_connectionState.Value = new State() { TopBlockId = rotorBlock.EntityId, MasterToSlave = masterToSlave }; }
public void AttachRotor(MyMotorRotor rotor) { AttachMsg msg = new AttachMsg(); msg.EntityId = this.Entity.EntityId; msg.AttachableEntityId = rotor.EntityId; Sync.Layer.SendMessageToAll(ref msg); }
public override bool Attach(MyMotorRotor rotor, bool updateSync = false, bool updateGroup = true) { if (CubeGrid.Physics == null || SafeConstraint != null) { return(false); } Debug.Assert(SafeConstraint == null); if (CubeGrid.Physics.Enabled && rotor != null) { m_rotorBlock = rotor; m_rotorBlockId = rotor.EntityId; if (updateSync) { SyncObject.AttachRotor(m_rotorBlock); } m_rotorGrid = m_rotorBlock.CubeGrid; var rotorBody = m_rotorGrid.Physics.RigidBody; HkWheelConstraintData data = new HkWheelConstraintData(); var suspensionAx = PositionComp.LocalMatrix.Forward; var posA = DummyPosition + (suspensionAx * m_height); var posB = rotor.DummyPosLoc; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; //empirical values because who knows what havoc sees behind this //docs say one value should mean same effect for 2 ton or 200 ton vehicle //but we have virtual mass blocks so real mass doesnt corespond to actual "weight" in game and varying gravity data.SetSuspensionDamping(Damping); data.SetSuspensionStrength(Strength); //Min/MaxHeight also define the limits of the suspension and SuspensionTravel lowers this limit data.SetSuspensionMinLimit((BlockDefinition.MinHeight - m_height) * SuspensionTravel); data.SetSuspensionMaxLimit((BlockDefinition.MaxHeight - m_height) * SuspensionTravel); data.SetInBodySpace(ref posB, ref posA, ref axisB, ref axisA, ref suspensionAx, ref suspensionAx); m_constraint = new HkConstraint(rotorBody, CubeGrid.Physics.RigidBody, data); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; m_rotorBlock.Attach(this); UpdateIsWorking(); if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); } return(true); } return(false); }
protected override bool CanPlaceRotor(MyMotorRotor rotorBlock, long builtBy) { // Compute the rough actual position for the wheel, this improves the detection if it can be placed float wheelDistance = BlockDefinition.Size.Y * CubeGrid.GridSize - 0.2f * CubeGrid.GridSize; Vector3D wheelPosition = this.WorldMatrix.Translation + this.WorldMatrix.Up * wheelDistance; float wheelRadius = rotorBlock.ModelCollision.HavokCollisionShapes[0].ConvexRadius * 0.9f; // First test if we intersect any blocks of our own grid BoundingSphereD sphere = rotorBlock.Model.BoundingSphere; sphere.Center = wheelPosition; sphere.Radius = wheelRadius; CubeGrid.GetBlocksInsideSphere(ref sphere, m_tmpSet); // If we intersect more than 1 block (because wheel sometimes intersects suspension), don't add wheel if (m_tmpSet.Count > 1) { m_tmpSet.Clear(); if (builtBy == MySession.Static.LocalPlayerId) { MyHud.Notifications.Add(MyNotificationSingletons.WheelNotPlaced); } return(false); } m_tmpSet.Clear(); // Next test if we intersect any physics objects HkSphereShape spShape = new HkSphereShape(wheelRadius); Quaternion q = Quaternion.Identity; MyPhysics.GetPenetrationsShape(rotorBlock.ModelCollision.HavokCollisionShapes[0], ref wheelPosition, ref q, m_tmpList, MyPhysics.CollisionLayers.DefaultCollisionLayer); // If we have any collisions with anything other than our own grid, don't add the wheel // We already checked for inner-grid collisions in the previous case for (int i = 0; i < m_tmpList.Count; i++) { MyCubeGrid grid = m_tmpList[i].GetCollisionEntity() as MyCubeGrid; if (grid == null || grid != CubeGrid) { m_tmpList.Clear(); if (builtBy == MySession.Static.LocalPlayerId) { MyHud.Notifications.Add(MyNotificationSingletons.WheelNotPlaced); } return(false); } } m_tmpList.Clear(); return(true); }
protected void CreateRotorGrid(out MyCubeGrid rotorGrid, out MyMotorRotor rotorBlock, long builtBy, MyCubeBlockDefinitionGroup rotorGroup) { if (rotorGroup == null) { CreateRotorGridFailed(builtBy, out rotorGrid, out rotorBlock); return; } var gridSize = CubeGrid.GridSizeEnum; float size = MyDefinitionManager.Static.GetCubeSize(gridSize); var matrix = MatrixD.CreateWorld(Vector3D.Transform(DummyPosition, CubeGrid.WorldMatrix), WorldMatrix.Forward, WorldMatrix.Up); var definition = rotorGroup[gridSize]; Debug.Assert(definition != null); var block = MyCubeGrid.CreateBlockObjectBuilder(definition, Vector3I.Zero, MyBlockOrientation.Identity, MyEntityIdentifier.AllocateId(), OwnerId, fullyBuilt: MySession.Static.CreativeMode); var gridBuilder = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_CubeGrid>(); gridBuilder.GridSizeEnum = gridSize; gridBuilder.IsStatic = false; gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(matrix); gridBuilder.CubeBlocks.Add(block); var grid = MyEntityFactory.CreateEntity <MyCubeGrid>(gridBuilder); grid.Init(gridBuilder); rotorGrid = grid; rotorBlock = (MyMotorRotor)rotorGrid.GetCubeBlock(Vector3I.Zero).FatBlock; rotorGrid.PositionComp.SetPosition(rotorGrid.WorldMatrix.Translation - (Vector3D.Transform(rotorBlock.DummyPosLoc, rotorGrid.WorldMatrix) - rotorGrid.WorldMatrix.Translation)); if (!CanPlaceRotor(rotorBlock, builtBy)) { CreateRotorGridFailed(builtBy, out rotorGrid, out rotorBlock); grid.Close(); return; } if (Sync.IsServer) { MyEntities.Add(grid); MySyncCreate.SendEntityCreated(grid.GetObjectBuilder()); } else { grid.Close(); } }
public override bool Attach(MyMotorRotor rotor, bool updateSync = false, bool updateGroup = true) { var ret = base.Attach(rotor, updateSync, updateGroup); if (ret) { if (m_rotorBlock is MyMotorAdvancedRotor) { m_conveyorEndpoint.Attach((m_rotorBlock as MyMotorAdvancedRotor).ConveyorEndpoint as MyAttachableConveyorEndpoint); } } return ret; }
public override bool Attach(MyMotorRotor rotor, bool updateSync = false, bool updateGroup = true) { var ret = base.Attach(rotor, updateSync, updateGroup); if (ret) { if (m_rotorBlock is MyMotorAdvancedRotor) { m_conveyorEndpoint.Attach((m_rotorBlock as MyMotorAdvancedRotor).ConveyorEndpoint as MyAttachableConveyorEndpoint); } } return(ret); }
public virtual bool Detach(bool updateGroup = true, bool reattach = true) { if (m_constraint == null) { return(false); } Debug.Assert(m_constraint != null); Debug.Assert(m_rotorGrid != null); Debug.Assert(m_rotorBlock != null); var tmpRotorGrid = m_rotorGrid; CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_rotorGrid = null; if (m_rotorBlock != null) { m_rotorBlock.Detach(); } m_rotorBlock = null; // The following line is commented out on purpose! If you move the motor between grids (e.g. after splitting), // you have to remember the attached rotor somehow. This rotorBlockId is how it's remembered. //m_rotorBlockId = 0; if (updateGroup) { OnConstraintRemoved(GridLinkTypeEnum.Physical, tmpRotorGrid); OnConstraintRemoved(GridLinkTypeEnum.Logical, tmpRotorGrid); } if (reattach) { // Try to reattach, if the block will still live next frame. This fixes missing attachments when splitting grids NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME; } if (tmpRotorGrid != null) { tmpRotorGrid.OnPhysicsChanged -= cubeGrid_OnPhysicsChanged; } return(true); }
private void WeldGroup() { var topGrid = m_rotorGrid; var topBlock = m_rotorBlock; m_isWelding = true; m_weldedRotorBlockId = m_rotorBlock.EntityId; if (Sync.IsServer) { MatrixD masterToSlave = topBlock.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix); m_rotorBlockId.Value = new State() { OtherEntityId = m_weldedRotorBlockId, MasterToSlave = masterToSlave }; m_weldedEntityId.Value = m_weldedRotorBlockId; } Detach(false); MyWeldingGroups.Static.CreateLink(EntityId, CubeGrid, topGrid); if (MyCubeGridGroups.Static.GetGroups(GridLinkTypeEnum.Physical).LinkExists(EntityId, CubeGrid, topGrid) == false) { OnConstraintAdded(GridLinkTypeEnum.Physical, topGrid); } if (MyCubeGridGroups.Static.GetGroups(GridLinkTypeEnum.Logical).LinkExists(EntityId, CubeGrid, topGrid) == false) { OnConstraintAdded(GridLinkTypeEnum.Logical, topGrid); } m_rotorGrid = topGrid; m_rotorBlock = topBlock; m_welded = true; m_isWelding = false; RaisePropertiesChanged(); }
public virtual bool Detach(bool updateGroup = true) { if (m_isWelding == false) { UnweldGroup(); } var tmpRotorGrid = m_rotorGrid; if (updateGroup) { OnConstraintRemoved(GridLinkTypeEnum.Physical, tmpRotorGrid); OnConstraintRemoved(GridLinkTypeEnum.Logical, tmpRotorGrid); } if (m_constraint == null) { return(false); } Debug.Assert(m_constraint != null); Debug.Assert(m_rotorGrid != null); Debug.Assert(m_rotorBlock != null); CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_rotorGrid = null; if (m_rotorBlock != null) { m_rotorBlock.Detach(m_welded || m_isWelding); } m_rotorBlock = null; m_isAttached = false; UpdateText(); return(true); }
protected override bool CanPlaceRotor(MyMotorRotor rotorBlock, long builtBy) { BoundingSphereD sphere = rotorBlock.Model.BoundingSphere; sphere.Center = Vector3D.Transform(sphere.Center, rotorBlock.WorldMatrix); CubeGrid.GetBlocksInsideSphere(ref sphere, m_tmpSet); HkSphereShape spShape = new HkSphereShape((float)sphere.Radius); Quaternion q = Quaternion.Identity;//Quaternion.CreateFromForwardUp(rotorBlock.WorldMatrix.Forward, rotorBlock.WorldMatrix.Up); var position = rotorBlock.WorldMatrix.Translation; MyPhysics.GetPenetrationsShape(spShape, ref position, ref q, m_tmpList, MyPhysics.CharacterNetworkCollisionLayer); if (m_tmpSet.Count > 1 || m_tmpList.Count > 0) { m_tmpList.Clear(); m_tmpSet.Clear(); if (builtBy == MySession.LocalPlayerId) MyHud.Notifications.Add(MyNotificationSingletons.WheelNotPlaced); return false; } m_tmpList.Clear(); m_tmpSet.Clear(); return true; }
public override bool Attach(MyMotorRotor rotor, bool updateSync = false, bool updateGroup = true) { if (CubeGrid.Physics == null || SafeConstraint != null) return false; Debug.Assert(SafeConstraint == null); if (CubeGrid.Physics.Enabled && rotor != null) { m_rotorBlock = rotor; m_rotorBlockId = rotor.EntityId; if (updateSync) SyncObject.AttachRotor(m_rotorBlock); m_rotorGrid = m_rotorBlock.CubeGrid; var rotorBody = m_rotorGrid.Physics.RigidBody; rotorBody.MaxAngularVelocity = float.MaxValue; rotorBody.AngularDamping *= 4; if (MyFakes.WHEEL_SOFTNESS) { HkUtils.SetSoftContact(rotorBody, null, MyPhysicsConfig.WheelSoftnessRatio, MyPhysicsConfig.WheelSoftnessVelocity); } var info = HkGroupFilter.CalcFilterInfo(rotorBody.Layer, CubeGrid.Physics.HavokCollisionSystemID, 1, 1); rotorBody.SetCollisionFilterInfo(info); HkWheelConstraintData data = new HkWheelConstraintData(); var suspensionAx = PositionComp.LocalMatrix.Forward; var posA = DummyPosition + (suspensionAx * m_height); var posB = rotor.DummyPosLoc; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; //empirical values because who knows what havoc sees behind this //docs say one value should mean same effect for 2 ton or 200 ton vehicle //but we have virtual mass blocks so real mass doesnt corespond to actual "weight" in game and varying gravity data.SetSuspensionDamping(Damping); data.SetSuspensionStrength(Strength); //Min/MaxHeight also define the limits of the suspension and SuspensionTravel lowers this limit data.SetSuspensionMinLimit((BlockDefinition.MinHeight - m_height) * SuspensionTravel); data.SetSuspensionMaxLimit((BlockDefinition.MaxHeight - m_height) * SuspensionTravel); data.SetInBodySpace( posB, posA, axisB, axisA, suspensionAx, suspensionAx, RotorGrid.Physics, CubeGrid.Physics); m_constraint = new HkConstraint(rotorBody, CubeGrid.Physics.RigidBody, data); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; m_rotorBlock.Attach(this); PropagateFriction(m_friction); UpdateIsWorking(); if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); } return true; } return false; }
public override bool Attach(MyMotorRotor rotor, bool updateGroup = true) { Debug.Assert(rotor != null, "Rotor cannot be null!"); Debug.Assert(m_constraint == null, "Already attached, call detach first!"); Debug.Assert(m_rotorBlockId.Value.OtherEntityId == rotor.EntityId, "m_rotorBlockId must be set prior calling Attach"); if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled) { m_rotorBlock = rotor; m_rotorGrid = m_rotorBlock.CubeGrid; var rotorBody = m_rotorGrid.Physics.RigidBody; rotorBody.MaxAngularVelocity = float.MaxValue; rotorBody.Restitution = 0.5f; CubeGrid.GetPhysicsBody().HavokWorld.BreakOffPartsUtil.UnmarkEntityBreakable(rotorBody); if (MyFakes.WHEEL_SOFTNESS) { HkUtils.SetSoftContact(rotorBody, null, MyPhysicsConfig.WheelSoftnessRatio, MyPhysicsConfig.WheelSoftnessVelocity); } var info = HkGroupFilter.CalcFilterInfo(rotorBody.Layer, CubeGrid.GetPhysicsBody().HavokCollisionSystemID, 1, 1); rotorBody.SetCollisionFilterInfo(info); HkWheelConstraintData data = new HkWheelConstraintData(); var suspensionAx = PositionComp.LocalMatrix.Forward; var posA = DummyPosition + (suspensionAx * m_height); var posB = rotor.DummyPosLoc; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; //empirical values because who knows what havoc sees behind this //docs say one value should mean same effect for 2 ton or 200 ton vehicle //but we have virtual mass blocks so real mass doesnt corespond to actual "weight" in game and varying gravity data.SetSuspensionDamping(Sync.RelativeSimulationRatio * m_damping); data.SetSuspensionStrength(Sync.RelativeSimulationRatio * m_strenth); //Min/MaxHeight also define the limits of the suspension and SuspensionTravel lowers this limit data.SetSuspensionMinLimit((BlockDefinition.MinHeight - m_height) * SuspensionTravel); data.SetSuspensionMaxLimit((BlockDefinition.MaxHeight - m_height) * SuspensionTravel); data.SetInBodySpace(posB, posA, axisB, axisA, suspensionAx, suspensionAx, RotorGrid.Physics, CubeGrid.Physics); m_constraint = new HkConstraint(rotorBody, CubeGrid.Physics.RigidBody, data); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); if (!m_constraint.InWorld) { Debug.Fail("Constraint not added!"); CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint = null; return(false); } m_constraint.Enabled = true; m_rotorBlock.Attach(this); PropagateFriction(m_friction); UpdateIsWorking(); if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); } return(true); } return(false); }
public override bool Attach(MyMotorRotor rotor, bool updateSync = false, bool updateGroup = true) { if (CubeGrid.Physics == null || SafeConstraint != null) return false; Debug.Assert(SafeConstraint == null); if (CubeGrid.Physics.Enabled && rotor != null) { m_rotorBlock = rotor; m_rotorBlockId = rotor.EntityId; if (updateSync) SyncObject.AttachRotor(m_rotorBlock); m_rotorGrid = m_rotorBlock.CubeGrid; var rotorBody = m_rotorGrid.Physics.RigidBody; HkWheelConstraintData data = new HkWheelConstraintData(); var posA = DummyPosition; var posB = rotor.DummyPosLoc; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; var suspensionAx = PositionComp.LocalMatrix.Forward; //empirical values because who knows what havoc sees behind this //docs say one value should mean same effect for 2 ton or 200 ton vehicle //but we have virtual mass blocks so real mass doesnt corespond to actual "weight" in game and varying gravity data.SetSuspensionDamping(Damping); data.SetSuspensionStrength(Strength); data.SetSuspensionMaxLimit(BlockDefinition.SuspensionLimit); data.SetSuspensionMinLimit(-BlockDefinition.SuspensionLimit); data.SetInBodySpace(ref posB, ref posA, ref axisB, ref axisA, ref suspensionAx, ref suspensionAx); m_constraint = new HkConstraint(rotorBody, CubeGrid.Physics.RigidBody, data); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; m_rotorBlock.Attach(this); UpdateIsWorking(); if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); } return true; } return false; }
public override bool Attach(MyMotorRotor rotor, bool updateGroup = true) { Debug.Assert(rotor != null, "Rotor cannot be null!"); Debug.Assert(m_constraint == null, "Already attached, call detach first!"); Debug.Assert(m_rotorBlockId.Value.OtherEntityId == 0 || m_rotorBlockId.Value.OtherEntityId == rotor.EntityId, "m_rotorBlockId must be set prior calling Attach"); if (rotor == null || MarkedForClose || Closed || rotor.MarkedForClose || rotor.Closed || CubeGrid.MarkedForClose || CubeGrid.Closed) { return false; } if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled) { m_rotorBlock = rotor; m_rotorGrid = m_rotorBlock.CubeGrid; if (m_rotorGrid.Physics == null) return false; if (CubeGrid.Physics.RigidBody == m_rotorGrid.Physics.RigidBody) { if (updateGroup && m_welded) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); } m_isAttached = true; return true; } var rotorBody = m_rotorGrid.Physics.RigidBody; var data = new HkLimitedHingeConstraintData(); m_motor = new HkVelocityConstraintMotor(1.0f, 1000000f); data.SetSolvingMethod(HkSolvingMethod.MethodStabilized); data.Motor = m_motor; data.DisableLimits(); var posA = DummyPosition; var posB = rotor.Position * rotor.CubeGrid.GridSize; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; var axisBPerp = rotor.PositionComp.LocalMatrix.Forward; data.SetInBodySpace(posA, posB, axisA, axisB, axisAPerp, axisBPerp, CubeGrid.Physics, m_rotorGrid.Physics); m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, rotorBody, data); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); if(!m_constraint.InWorld) { CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; return false; } m_constraint.Enabled = true; SetAngleToPhysics(); m_rotorBlock.Attach(this); if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); m_rotorGrid.OnPhysicsChanged += cubeGrid_OnPhysicsChanged; } m_isAttached = true; UpdateText(); return true; } return false; }
public override bool Attach(MyMotorRotor rotor, bool updateGroup = true) { Debug.Assert(rotor != null, "Rotor cannot be null!"); Debug.Assert(m_constraint == null, "Already attached, call detach first!"); Debug.Assert(m_rotorBlockId.Value.OtherEntityId == 0 || m_rotorBlockId.Value.OtherEntityId == rotor.EntityId, "m_rotorBlockId must be set prior calling Attach"); if (rotor == null || rotor.CubeGrid == null || MarkedForClose || Closed || CubeGrid.MarkedForClose || CubeGrid.Closed || rotor.MarkedForClose || rotor.Closed || rotor.CubeGrid.MarkedForClose || rotor.CubeGrid.Closed) { return(false); } if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled) { m_rotorBlock = rotor; m_rotorGrid = m_rotorBlock.CubeGrid; if (m_rotorGrid.Physics == null) { return(false); } if (CubeGrid.Physics.RigidBody == m_rotorGrid.Physics.RigidBody) { if (updateGroup && m_welded) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); } m_isAttached = true; return(true); } var rotorBody = m_rotorGrid.Physics.RigidBody; var data = new HkLimitedHingeConstraintData(); m_motor = new HkVelocityConstraintMotor(1.0f, 1000000f); data.SetSolvingMethod(HkSolvingMethod.MethodStabilized); data.Motor = m_motor; data.DisableLimits(); var posA = DummyPosition; var posB = rotor.Position * rotor.CubeGrid.GridSize; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; var axisBPerp = rotor.PositionComp.LocalMatrix.Forward; data.SetInBodySpace(posA, posB, axisA, axisB, axisAPerp, axisBPerp, CubeGrid.Physics, m_rotorGrid.Physics); m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, rotorBody, data); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); if (!m_constraint.InWorld) { CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; return(false); } m_constraint.Enabled = true; SetAngleToPhysics(); m_rotorBlock.Attach(this); if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); m_rotorGrid.OnPhysicsChanged += cubeGrid_OnPhysicsChanged; } m_isAttached = true; UpdateText(); return(true); } return(false); }
public override bool Attach(MyMotorRotor rotor, bool updateSync = false, bool updateGroup = true) { if (CubeGrid.Physics == null || SafeConstraint != null) return false; Debug.Assert(SafeConstraint == null); if (CubeGrid.Physics.Enabled && rotor != null) { m_rotorBlock = rotor; m_rotorBlockId = rotor.EntityId; if (updateSync) SyncObject.AttachRotor(m_rotorBlock); m_rotorGrid = m_rotorBlock.CubeGrid; if (m_rotorGrid.Physics == null) return false; var rotorBody = m_rotorGrid.Physics.RigidBody; var data = new HkLimitedHingeConstraintData(); m_motor = new HkVelocityConstraintMotor(1.0f, 1000000f); data.SetSolvingMethod(HkSolvingMethod.MethodStabilized); data.Motor = m_motor; data.DisableLimits(); var posA = DummyPosition; var posB = rotor.Position * rotor.CubeGrid.GridSize; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; var axisBPerp = rotor.PositionComp.LocalMatrix.Forward; data.SetInBodySpace(ref posA, ref posB, ref axisA, ref axisB, ref axisAPerp, ref axisBPerp); m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, rotorBody, data); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; SetAngleToPhysics(); m_rotorBlock.Attach(this); if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); } m_isAttached = true; return true; } return false; }
public override bool Attach(MyMotorRotor rotor, bool updateGroup = true) { Debug.Assert(rotor != null, "Rotor cannot be null!"); Debug.Assert(m_constraint == null, "Already attached, call detach first!"); Debug.Assert(m_rotorBlockId.Value.OtherEntityId == rotor.EntityId, "m_rotorBlockId must be set prior calling Attach"); if (rotor == null || MarkedForClose || Closed || rotor.MarkedForClose || rotor.Closed || CubeGrid.MarkedForClose || CubeGrid.Closed) { return false; } if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled) { m_rotorBlock = rotor; m_rotorGrid = m_rotorBlock.CubeGrid; var rotorBody = m_rotorGrid.Physics.RigidBody; rotorBody.MaxAngularVelocity = float.MaxValue; rotorBody.Restitution = 0.5f; CubeGrid.GetPhysicsBody().HavokWorld.BreakOffPartsUtil.UnmarkEntityBreakable(rotorBody); if (MyFakes.WHEEL_SOFTNESS) { HkUtils.SetSoftContact(rotorBody, null, MyPhysicsConfig.WheelSoftnessRatio, MyPhysicsConfig.WheelSoftnessVelocity); } var info = HkGroupFilter.CalcFilterInfo(rotorBody.Layer, CubeGrid.GetPhysicsBody().HavokCollisionSystemID, 1, 1); rotorBody.SetCollisionFilterInfo(info); HkWheelConstraintData data = new HkWheelConstraintData(); var suspensionAx = PositionComp.LocalMatrix.Forward; var posA = DummyPosition + (suspensionAx * m_height); var posB = rotor.DummyPosLoc; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; //empirical values because who knows what havoc sees behind this //docs say one value should mean same effect for 2 ton or 200 ton vehicle //but we have virtual mass blocks so real mass doesnt corespond to actual "weight" in game and varying gravity data.SetSuspensionDamping(Sync.RelativeSimulationRatio * m_damping); data.SetSuspensionStrength(Sync.RelativeSimulationRatio * m_strenth); //Min/MaxHeight also define the limits of the suspension and SuspensionTravel lowers this limit data.SetSuspensionMinLimit((BlockDefinition.MinHeight - m_height) * SuspensionTravel); data.SetSuspensionMaxLimit((BlockDefinition.MaxHeight - m_height) * SuspensionTravel); data.SetInBodySpace( posB, posA, axisB, axisA, suspensionAx, suspensionAx, RotorGrid.Physics, CubeGrid.Physics); m_constraint = new HkConstraint(rotorBody, CubeGrid.Physics.RigidBody, data); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); if(!m_constraint.InWorld) { Debug.Fail("Constraint not added!"); CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint = null; return false; } m_constraint.Enabled = true; m_rotorBlock.Attach(this); PropagateFriction(m_friction); UpdateIsWorking(); if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); } return true; } return false; }
public virtual bool Detach(bool updateGroup = true,bool reattach = true) { if (m_constraint == null) return false; Debug.Assert(m_constraint != null); Debug.Assert(m_rotorGrid != null); Debug.Assert(m_rotorBlock != null); var tmpRotorGrid = m_rotorGrid; CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_rotorGrid = null; if (m_rotorBlock != null) m_rotorBlock.Detach(); m_rotorBlock = null; // The following line is commented out on purpose! If you move the motor between grids (e.g. after splitting), // you have to remember the attached rotor somehow. This rotorBlockId is how it's remembered. //m_rotorBlockId = 0; if (updateGroup) { OnConstraintRemoved(GridLinkTypeEnum.Physical, tmpRotorGrid); OnConstraintRemoved(GridLinkTypeEnum.Logical, tmpRotorGrid); } if (reattach) { // Try to reattach, if the block will still live next frame. This fixes missing attachments when splitting grids NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME; } return true; }
protected void CreateRotorGrid(out MyCubeGrid rotorGrid, out MyMotorRotor rotorBlock, long builtBy, MyCubeBlockDefinitionGroup rotorGroup) { if (rotorGroup == null) { CreateRotorGridFailed(builtBy, out rotorGrid, out rotorBlock); return; } var gridSize = CubeGrid.GridSizeEnum; float size = MyDefinitionManager.Static.GetCubeSize(gridSize); var matrix = MatrixD.CreateWorld(Vector3D.Transform(DummyPosition,CubeGrid.WorldMatrix), WorldMatrix.Forward, WorldMatrix.Up); var definition = rotorGroup[gridSize]; Debug.Assert(definition != null); var block = MyCubeGrid.CreateBlockObjectBuilder(definition, Vector3I.Zero, MyBlockOrientation.Identity, MyEntityIdentifier.AllocateId(), OwnerId, fullyBuilt: MySession.Static.CreativeMode); var gridBuilder = Sandbox.Common.ObjectBuilders.Serializer.MyObjectBuilderSerializer.CreateNewObject<MyObjectBuilder_CubeGrid>(); gridBuilder.GridSizeEnum = gridSize; gridBuilder.IsStatic = false; gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(matrix); gridBuilder.CubeBlocks.Add(block); var grid = MyEntityFactory.CreateEntity<MyCubeGrid>(gridBuilder); grid.Init(gridBuilder); rotorGrid = grid; rotorBlock = (MyMotorRotor)rotorGrid.GetCubeBlock(Vector3I.Zero).FatBlock; rotorGrid.PositionComp.SetPosition(rotorGrid.WorldMatrix.Translation - (Vector3D.Transform(rotorBlock.DummyPosLoc, rotorGrid.WorldMatrix) - rotorGrid.WorldMatrix.Translation)); if (!CanPlaceRotor(rotorBlock, builtBy)) { CreateRotorGridFailed(builtBy, out rotorGrid, out rotorBlock); grid.Close(); return; } if (Sync.IsServer) { MyEntities.Add(grid); MySyncCreate.SendEntityCreated(grid.GetObjectBuilder()); } else grid.Close(); }
public virtual bool Detach(bool updateGroup = true) { if (m_isWelding == false) { UnweldGroup(); } var tmpRotorGrid = m_rotorGrid; if (updateGroup) { OnConstraintRemoved(GridLinkTypeEnum.Physical, tmpRotorGrid); OnConstraintRemoved(GridLinkTypeEnum.Logical, tmpRotorGrid); } if (m_constraint == null) return false; Debug.Assert(m_constraint != null); Debug.Assert(m_rotorGrid != null); Debug.Assert(m_rotorBlock != null); CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_rotorGrid = null; if (m_rotorBlock != null) m_rotorBlock.Detach(m_welded || m_isWelding); m_rotorBlock = null; UpdateText(); return true; }
protected void CreateRotorGrid(out MyCubeGrid rotorGrid, out MyMotorRotor rotorBlock, long builtBy, MyCubeBlockDefinitionGroup rotorGroup) { Debug.Assert(Sync.IsServer, "Rotor grid can be created only on server"); if (rotorGroup == null) { rotorGrid = null; rotorBlock = null; return; } var gridSize = CubeGrid.GridSizeEnum; float size = MyDefinitionManager.Static.GetCubeSize(gridSize); var matrix = MatrixD.CreateWorld(Vector3D.Transform(DummyPosition, CubeGrid.WorldMatrix), WorldMatrix.Forward, WorldMatrix.Up); var definition = rotorGroup[gridSize]; Debug.Assert(definition != null); var block = MyCubeGrid.CreateBlockObjectBuilder(definition, Vector3I.Zero, MyBlockOrientation.Identity, MyEntityIdentifier.AllocateId(), OwnerId, fullyBuilt: MySession.Static.CreativeMode); var gridBuilder = MyObjectBuilderSerializer.CreateNewObject<MyObjectBuilder_CubeGrid>(); gridBuilder.GridSizeEnum = gridSize; gridBuilder.IsStatic = false; gridBuilder.PositionAndOrientation = new MyPositionAndOrientation(matrix); gridBuilder.CubeBlocks.Add(block); var grid = MyEntityFactory.CreateEntity<MyCubeGrid>(gridBuilder); grid.Init(gridBuilder); rotorGrid = grid; rotorBlock = (MyMotorRotor)rotorGrid.GetCubeBlock(Vector3I.Zero).FatBlock; rotorGrid.PositionComp.SetPosition(rotorGrid.WorldMatrix.Translation - (Vector3D.Transform(rotorBlock.DummyPosLoc, rotorGrid.WorldMatrix) - rotorGrid.WorldMatrix.Translation)); if (!CanPlaceRotor(rotorBlock, builtBy)) { rotorGrid = null; rotorBlock = null; grid.Close(); return; } MyEntities.Add(grid); MatrixD masterToSlave = rotorBlock.CubeGrid.WorldMatrix * MatrixD.Invert(WorldMatrix); m_rotorBlockId.Value = new State() { OtherEntityId = rotorBlock.EntityId, MasterToSlave = masterToSlave}; }
public abstract bool Attach(MyMotorRotor rotor, bool updateGroup = true);
private static void CreateRotorGridFailed(long builtBy, out MyCubeGrid rotorGrid, out MyMotorRotor rotorBlock) { if (builtBy == MySession.LocalPlayerId) MyGuiAudio.PlaySound(MyGuiSounds.HudUnable); rotorGrid = null; rotorBlock = null; }
protected virtual void CreateRotorGrid(out MyCubeGrid rotorGrid, out MyMotorRotor rotorBlock, long builtBy) { CreateRotorGrid(out rotorGrid, out rotorBlock, builtBy, MyDefinitionManager.Static.TryGetDefinitionGroup(MotorDefinition.RotorPart)); }
private static void CreateRotorGridFailed(long builtBy, out MyCubeGrid rotorGrid, out MyMotorRotor rotorBlock) { if (builtBy == MySession.LocalPlayerId) { MyGuiAudio.PlaySound(MyGuiSounds.HudUnable); } rotorGrid = null; rotorBlock = null; }
public override bool Attach(MyMotorRotor rotor, bool updateSync = false, bool updateGroup = true) { if (CubeGrid.Physics == null || SafeConstraint != null) { return(false); } Debug.Assert(SafeConstraint == null); if (CubeGrid.Physics.Enabled && rotor != null) { m_rotorBlock = rotor; m_rotorBlockId = rotor.EntityId; if (updateSync) { SyncObject.AttachRotor(m_rotorBlock); } m_rotorGrid = m_rotorBlock.CubeGrid; var rotorBody = m_rotorGrid.Physics.RigidBody; rotorBody.MaxAngularVelocity = float.MaxValue; rotorBody.AngularDamping *= 4; if (MyFakes.WHEEL_SOFTNESS) { HkUtils.SetSoftContact(rotorBody, null, MyPhysicsConfig.WheelSoftnessRatio, MyPhysicsConfig.WheelSoftnessVelocity); } var info = HkGroupFilter.CalcFilterInfo(rotorBody.Layer, CubeGrid.Physics.HavokCollisionSystemID, 1, 1); rotorBody.SetCollisionFilterInfo(info); HkWheelConstraintData data = new HkWheelConstraintData(); var suspensionAx = PositionComp.LocalMatrix.Forward; var posA = DummyPosition + (suspensionAx * m_height); var posB = rotor.DummyPosLoc; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; //empirical values because who knows what havoc sees behind this //docs say one value should mean same effect for 2 ton or 200 ton vehicle //but we have virtual mass blocks so real mass doesnt corespond to actual "weight" in game and varying gravity data.SetSuspensionDamping(Damping); data.SetSuspensionStrength(Strength); //Min/MaxHeight also define the limits of the suspension and SuspensionTravel lowers this limit data.SetSuspensionMinLimit((BlockDefinition.MinHeight - m_height) * SuspensionTravel); data.SetSuspensionMaxLimit((BlockDefinition.MaxHeight - m_height) * SuspensionTravel); data.SetInBodySpace(posB, posA, axisB, axisA, suspensionAx, suspensionAx, RotorGrid.Physics, CubeGrid.Physics); m_constraint = new HkConstraint(rotorBody, CubeGrid.Physics.RigidBody, data); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; m_rotorBlock.Attach(this); PropagateFriction(m_friction); UpdateIsWorking(); if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); } return(true); } return(false); }
protected virtual bool CanPlaceRotor(MyMotorRotor rotorBlock, long builtBy) { return(true); }
protected virtual bool CanPlaceRotor(MyMotorRotor rotorBlock, long builtBy) { return true; }
public abstract bool Attach(MyMotorRotor rotor, bool updateSync = false, bool updateGroup = true);
protected MyMotorRotor FindMatchingRotor() { Debug.Assert(CubeGrid != null); Debug.Assert(m_penetrations != null); Debug.Assert(CubeGrid.Physics != null); if (CubeGrid == null) { MySandboxGame.Log.WriteLine("MyMotorStator.FindMatchingRotor(): Cube grid == null!"); return(null); } if (m_penetrations == null) { MySandboxGame.Log.WriteLine("MyMotorStator.FindMatchingRotor(): penetrations cache == null!"); return(null); } if (CubeGrid.Physics == null) { MySandboxGame.Log.WriteLine("MyMotorStator.FindMatchingRotor(): Cube grid physics == null!"); return(null); } Quaternion orientation; Vector3D pos; Vector3 halfExtents; ComputeRotorQueryBox(out pos, out halfExtents, out orientation); try { MyPhysics.GetPenetrationsBox(ref halfExtents, ref pos, ref orientation, m_penetrations, MyPhysics.CollisionLayers.DefaultCollisionLayer); foreach (var obj in m_penetrations) { var entity = obj.GetCollisionEntity(); if (entity == null || entity == CubeGrid) { continue; } MyMotorRotor rotor = FindRotorInGrid(entity); if (rotor != null) { return(rotor); } MyPhysicsBody body = entity.Physics as MyPhysicsBody; if (body != null) { foreach (var child in body.WeldInfo.Children) { rotor = FindRotorInGrid(child.Entity); if (rotor != null) { return(rotor); } } } } } finally { m_penetrations.Clear(); } return(null); }