protected void CreateSubpartConstraint(VRage.Game.Entity.MyEntity subpart, out HkFixedConstraintData constraintData, out HkConstraint constraint) { constraintData = null; constraint = null; if (base.CubeGrid.Physics != null) { HkRigidBody rigidBody; uint info = HkGroupFilter.CalcFilterInfo(subpart.GetPhysicsBody().RigidBody.Layer, base.CubeGrid.GetPhysicsBody().HavokCollisionSystemID, 1, 1); subpart.Physics.RigidBody.SetCollisionFilterInfo(info); subpart.Physics.Enabled = true; constraintData = new HkFixedConstraintData(); constraintData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); constraintData.SetInertiaStabilizationFactor(1f); if ((base.CubeGrid.Physics.RigidBody2 == null) || !base.CubeGrid.Physics.Flags.HasFlag(RigidBodyFlag.RBF_DOUBLED_KINEMATIC)) { rigidBody = base.CubeGrid.Physics.RigidBody; } else { rigidBody = base.CubeGrid.Physics.RigidBody2; } constraint = new HkConstraint(rigidBody, subpart.Physics.RigidBody, constraintData); constraint.WantRuntime = true; } }
internal void Detach() { if (m_constraint == null) { return; } Debug.Assert(m_constraint != null); Debug.Assert(m_topGrid != null); Debug.Assert(m_topBlock != null); var tmpTopGrid = m_topGrid; m_fixedData.Dispose(); m_fixedData = null; CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_topGrid = null; if (m_topBlock != null) { m_topBlock.Detach(); } tmpTopGrid.OnPhysicsChanged -= CubeGrid_OnPhysicsChanged; m_conveyorEndpoint.Detach(m_topBlock.ConveyorEndpoint as MyAttachableConveyorEndpoint); m_topBlock = null; OnConstraintRemoved(GridLinkTypeEnum.Physical, tmpTopGrid); OnConstraintRemoved(GridLinkTypeEnum.Logical, tmpTopGrid); UpdateText(); }
private void CreateSubpartsConstraint(MyEntitySubpart subpart) { m_subpartsFixedData = new HkFixedConstraintData(); m_subpartsFixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); m_subpartsFixedData.SetInertiaStabilizationFactor(1); var matAD = MatrixD.CreateWorld(Position * CubeGrid.GridSize + Vector3D.Transform(Vector3D.Transform(m_subpartsConstraintPos, WorldMatrix), CubeGrid.PositionComp.LocalMatrix), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); matAD.Translation = CubeGrid.Physics.WorldToCluster(matAD.Translation); var matA = (Matrix)matAD; var matB = subpart.PositionComp.LocalMatrix; m_subpartsFixedData.SetInWorldSpace(ref matA, ref matB, ref matB); //Dont dispose the fixed data or we wont have access to them HkConstraintData constraintData = m_subpartsFixedData; if (Sync.IsServer) // Breakable only on server { constraintData = new HkBreakableConstraintData(m_subpartsFixedData) { Threshold = BreakOffTreshold }; } m_subpartsConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, subpart.Physics.RigidBody, constraintData); Debug.Assert(m_subpartsConstraint.RigidBodyA != null); m_subpartsConstraint.WantRuntime = true; }
private HkConstraintData CreateFixedConstraintData(ref Matrix otherLocalMatrix, float headDistance) { m_fixedConstraintData = new HkFixedConstraintData(); Matrix headPivotLocalMatrix; GetHeadPivotLocalMatrix(headDistance, out headPivotLocalMatrix); m_fixedConstraintData.SetInBodySpace(otherLocalMatrix, headPivotLocalMatrix, m_otherPhysicsBody, OwnerVirtualPhysics); if (MyFakes.MANIPULATION_TOOL_VELOCITY_LIMIT) { m_fixedConstraintData.MaximumLinearImpulse = 0.5f; m_fixedConstraintData.MaximumAngularImpulse = 0.5f; HkMalleableConstraintData mcData = new HkMalleableConstraintData(); mcData.SetData(m_fixedConstraintData); mcData.Strength = 0.0001f; m_fixedConstraintData.Dispose(); return(mcData); } else { m_fixedConstraintData.MaximumLinearImpulse = 0.005f; //7500 * MyDestructionHelper.MASS_REDUCTION_COEF * (MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * MyFakes.SIMULATION_SPEED); m_fixedConstraintData.MaximumAngularImpulse = 0.005f; //7500 * MyDestructionHelper.MASS_REDUCTION_COEF * (MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * MyFakes.SIMULATION_SPEED); } return(m_fixedConstraintData); //HkBreakableConstraintData bcData = new HkBreakableConstraintData(m_fixedConstraintData); //bcData.ReapplyVelocityOnBreak = false; //bcData.RemoveFromWorldOnBrake = true; //bcData.Threshold = /*100000;*/ 2500 * MyDestructionHelper.MASS_REDUCTION_COEF; //return bcData; }
private void CreateSubpartsConstraint(MyEntitySubpart subpart) { m_subpartsFixedData = new HkFixedConstraintData(); m_subpartsFixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); m_subpartsFixedData.SetInertiaStabilizationFactor(1); var matAD = MatrixD.CreateWorld(Position * CubeGrid.GridSize + Vector3D.Transform(Vector3D.Transform(m_subpartsConstraintPos, WorldMatrix), CubeGrid.PositionComp.LocalMatrix), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); matAD.Translation = CubeGrid.Physics.WorldToCluster(matAD.Translation); var matA = (Matrix)matAD; var matB = subpart.PositionComp.LocalMatrix; m_subpartsFixedData.SetInWorldSpace(ref matA, ref matB, ref matB); //Dont dispose the fixed data or we wont have access to them HkConstraintData constraintData = m_subpartsFixedData; m_subpartsConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, m_subpartPhysics.RigidBody, constraintData); var info = CubeGrid.Physics.RigidBody.GetCollisionFilterInfo(); info = HkGroupFilter.CalcFilterInfo(CubeGrid.Physics.RigidBody.Layer, HkGroupFilter.GetSystemGroupFromFilterInfo(info), 1, 1); m_subpartPhysics.RigidBody.SetCollisionFilterInfo(info); CubeGrid.Physics.HavokWorld.RefreshCollisionFilterOnEntity(m_subpartPhysics.RigidBody); Debug.Assert(m_subpartsConstraint.RigidBodyA != null); m_subpartsConstraint.WantRuntime = true; }
protected override bool Attach(MyAttachableTopBlockBase topBlock, bool updateGroup = true) { Debug.Assert(topBlock != null, "Top block cannot be null!"); if (CubeGrid == topBlock.CubeGrid) { return(false); } MyPistonTop pistonTop = topBlock as MyPistonTop; if (pistonTop != null && base.Attach(topBlock, updateGroup)) { Debug.Assert(m_constraint == null, "Contraint already attached, call detach first!"); Debug.Assert(m_connectionState.Value.TopBlockId.HasValue && (m_connectionState.Value.TopBlockId.Value == 0 || m_connectionState.Value.TopBlockId.Value == topBlock.EntityId), "m_topBlockId must be set prior calling Attach!"); UpdateAnimation(); var matAD = MatrixD.CreateWorld(Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); var matBD = MatrixD.CreateWorld(m_topBlock.Position * m_topBlock.CubeGrid.GridSize, m_topBlock.PositionComp.LocalMatrix.Forward, m_topBlock.PositionComp.LocalMatrix.Up); var matA = (Matrix)matAD; var matB = (Matrix)matBD; m_fixedData = new HkFixedConstraintData(); m_fixedData.SetInertiaStabilizationFactor(10); m_fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); m_fixedData.SetInBodySpace(matA, matB, CubeGrid.Physics, m_topGrid.Physics); //Dont dispose the fixed data or we wont have access to them m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, topBlock.CubeGrid.Physics.RigidBody, m_fixedData); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); if (!m_constraint.InWorld) { Debug.Fail("Constraint was not added to world"); CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_fixedData = null; return(false); } m_constraint.Enabled = true; m_topBlock = topBlock; m_topGrid = topBlock.CubeGrid; topBlock.Attach(this); m_isAttached = true; if (updateGroup) { m_conveyorEndpoint.Attach(pistonTop.ConveyorEndpoint as MyAttachableConveyorEndpoint); } UpdateText(); return(true); } return(false); }
public void Attach(MyPistonTop topBlock) { if (CubeGrid == topBlock.CubeGrid) { return; } Debug.Assert(topBlock != null, "Top block cannot be null!"); Debug.Assert(m_constraint == null, "Contraint already attached, call detach first!"); Debug.Assert(m_topBlockId.Value == topBlock.EntityId, "m_topBlockId must be set prior calling Attach!"); UpdateAnimation(); if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled && topBlock.CubeGrid.Physics != null) { m_topBlock = topBlock; m_topGrid = m_topBlock.CubeGrid; var rotorBody = m_topGrid.Physics.RigidBody; var matAD = MatrixD.CreateWorld(Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); var matBD = MatrixD.CreateWorld(m_topBlock.Position * m_topBlock.CubeGrid.GridSize, m_topBlock.PositionComp.LocalMatrix.Forward, m_topBlock.PositionComp.LocalMatrix.Up); var matA = (Matrix)matAD; var matB = (Matrix)matBD; m_fixedData = new HkFixedConstraintData(); m_fixedData.SetInertiaStabilizationFactor(10); m_fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); m_fixedData.SetInBodySpace(matA, matB, CubeGrid.Physics, m_topGrid.Physics); var breakData = new HkBreakableConstraintData(m_fixedData); //Dont dispose the fixed data or we wont have access to them breakData.Threshold = BreakOffTreshold; breakData.ReapplyVelocityOnBreak = true; breakData.RemoveFromWorldOnBrake = false; m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, rotorBody, breakData); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); if (!m_constraint.InWorld) { Debug.Fail("Constraint was not added to world"); CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_fixedData.Dispose(); m_fixedData = null; return; } m_constraint.Enabled = true; m_topBlock.Attach(this); m_topGrid.OnPhysicsChanged += CubeGrid_OnPhysicsChanged; OnConstraintAdded(GridLinkTypeEnum.Physical, m_topGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_topGrid); m_conveyorEndpoint.Attach(topBlock.ConveyorEndpoint as MyAttachableConveyorEndpoint); UpdateText(); } }
protected void DisposeSubpartConstraint(ref HkConstraint constraint, ref HkFixedConstraintData constraintData) { if (constraint != null) { base.CubeGrid.Physics.RemoveConstraint(constraint); constraint.Dispose(); constraint = null; constraintData = null; } }
protected override void DisposeConstraint() { if (m_constraint != null) { m_fixedData = null; CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; } }
private void DisposeSubpartsConstraint() { if (m_subPartContraintInScene) { m_subPartContraintInScene = false; CubeGrid.Physics.RemoveConstraint(m_subpartsConstraint); } m_subpartsConstraint.Dispose(); m_subpartsConstraint = null; m_subpartsFixedData = null; }
private void DisposeConstraints() { for (int i = 0; i < this.m_subpartConstraints.Count; i++) { HkConstraint constraint = this.m_subpartConstraints[i]; HkFixedConstraintData constraintData = this.m_subpartConstraintsData[i]; base.DisposeSubpartConstraint(ref constraint, ref constraintData); } this.m_subpartConstraints.Clear(); this.m_subpartConstraintsData.Clear(); }
public void Attach(MyPistonTop topBlock, bool updateSync = false) { if (m_topBlock != null) { Detach(); } if (CubeGrid.Physics == null || SafeConstraint != null) { return; } UpdateAnimation(); Debug.Assert(SafeConstraint == null); if (CubeGrid.Physics.Enabled && topBlock != null) { m_topBlock = topBlock; m_topBlockId = topBlock.EntityId; if (updateSync) { SyncObject.AttachTop(m_topBlock); } m_topGrid = m_topBlock.CubeGrid; var rotorBody = m_topGrid.Physics.RigidBody; var matAD = MatrixD.CreateWorld(Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); var matBD = MatrixD.CreateWorld(m_topBlock.Position * m_topBlock.CubeGrid.GridSize, m_topBlock.PositionComp.LocalMatrix.Forward, m_topBlock.PositionComp.LocalMatrix.Up); var matA = (Matrix)matAD; var matB = (Matrix)matBD; m_fixedData = new HkFixedConstraintData(); m_fixedData.SetInertiaStabilizationFactor(10); m_fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); m_fixedData.SetInBodySpace(ref matA, ref matB); var breakData = new HkBreakableConstraintData(m_fixedData); //Dont dispose the fixed data or we wont have access to them breakData.Threshold = BreakOffTreshold; breakData.ReapplyVelocityOnBreak = true; breakData.RemoveFromWorldOnBrake = false; m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, rotorBody, breakData); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; m_topBlock.Attach(this); OnConstraintAdded(GridLinkTypeEnum.Physical, m_topGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_topGrid); m_conveyorEndpoint.Attach(topBlock.ConveyorEndpoint as MyAttachableConveyorEndpoint); } }
public static void SetInBodySpace(this HkFixedConstraintData data, Matrix pivotA, Matrix pivotB, MyPhysicsBody bodyA, MyPhysicsBody bodyB) { if (bodyA.IsWelded) { pivotA = pivotA * bodyA.WeldInfo.Transform; } if (bodyB.IsWelded) { pivotB = pivotB * bodyB.WeldInfo.Transform; } data.SetInBodySpaceInternal(ref pivotA, ref pivotB); }
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 DisposeSubpartsConstraint() { if (m_subPartContraintInScene) { m_subPartContraintInScene = false; CubeGrid.Physics.RemoveConstraint(m_subpartsConstraint); } m_subpartsConstraint.Dispose(); m_subpartsConstraint = null; if (Sync.IsServer) { // On server, contraint contains breakable data, fixed data must be disposed manually // On client, contraint contains fixed data, which are disposed with constraint m_subpartsFixedData.Dispose(); } m_subpartsFixedData = null; }
private void InitSubpartsPhysics() { var subpart = m_subpart1; if (subpart == null || CubeGrid.Physics == null) { return; } subpart.Physics = new MyPhysicsBody(subpart, CubeGrid.IsStatic ? RigidBodyFlag.RBF_STATIC : (CubeGrid.GridSizeEnum == MyCubeSize.Large ? RigidBodyFlag.RBF_DOUBLED_KINEMATIC : RigidBodyFlag.RBF_DEFAULT)); HkCylinderShape shape = new HkCylinderShape(Vector3.Zero, new Vector3(0, 0, 2), CubeGrid.GridSize / 2); var mass = HkInertiaTensorComputer.ComputeCylinderVolumeMassProperties(Vector3.Zero, Vector3.One, 1, 40.0f * CubeGrid.GridSize); subpart.Physics.CreateFromCollisionObject(shape, Vector3.Zero, subpart.WorldMatrix, mass); shape.Base.RemoveReference(); subpart.Physics.RigidBody.Layer = CubeGrid.Physics.RigidBody.Layer; if (subpart.Physics.RigidBody2 != null) { subpart.Physics.RigidBody2.Layer = MyPhysics.KinematicDoubledCollisionLayer; } m_subpartsFixedData = new HkFixedConstraintData(); m_subpartsFixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); float res; var x = m_subpartsFixedData.GetInertiaStabilizationFactor(out res); m_subpartsFixedData.SetInertiaStabilizationFactor(1); var matAD = MatrixD.CreateWorld(Position * CubeGrid.GridSize + Vector3D.Transform(Vector3D.Transform(m_subpartsConstraintPos, WorldMatrix), CubeGrid.PositionComp.LocalMatrix), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); matAD.Translation = CubeGrid.Physics.WorldToCluster(matAD.Translation); var matA = (Matrix)matAD; var matB = subpart.PositionComp.LocalMatrix; m_subpartsFixedData.SetInWorldSpace(ref matA, ref matB, ref matB); var breakableData = new HkBreakableConstraintData(m_subpartsFixedData); //Dont dispose the fixed data or we wont have access to them breakableData.Threshold = BreakOffTreshold; m_subpartsConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, subpart.Physics.RigidBody, breakableData); m_subpartsConstraint.WantRuntime = true; m_posChanged = true; }
internal void Detach(bool updateGroups = true) { if (m_constraint == null) { return; } Debug.Assert(m_constraint != null); Debug.Assert(m_topGrid != null); Debug.Assert(m_topBlock != null); var tmpTopGrid = m_topGrid; if (m_constraint.InWorld && (m_constraint.ConstraintData as HkBreakableConstraintData).getIsBroken(m_constraint)) { m_topBlockId = 0; } m_fixedData.Dispose(); m_fixedData = null; CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_topGrid = null; if (m_topBlock != null) { m_topBlock.Detach(); } m_conveyorEndpoint.Detach(m_topBlock.ConveyorEndpoint as MyAttachableConveyorEndpoint); m_topBlock = null; if (updateGroups) { OnConstraintRemoved(GridLinkTypeEnum.Physical, tmpTopGrid); OnConstraintRemoved(GridLinkTypeEnum.Logical, tmpTopGrid); } // Try to reattach, if the block will still live next frame. This fixes missing attachments when splitting grids }
private void DisposeSubpartsPhysics() { if (m_subpartsConstraint != null) { m_subpartsFixedData.Dispose(); m_subpartsFixedData = null; if (m_subPartContraintInScene) { m_subPartContraintInScene = false; CubeGrid.Physics.RemoveConstraint(m_subpartsConstraint); } m_subpartsConstraint.Dispose(); m_subpartsConstraint = null; } if (m_subpart1 != null && m_subpart1.Physics != null) { m_subpart1.Physics.Enabled = false; m_subpart1.Physics.Close(); m_subpart1.Physics = null; } }
protected override bool CreateConstraint(MyAttachableTopBlockBase topBlock) { if (!base.CreateConstraint(topBlock)) { return(false); } var matAD = MatrixD.CreateWorld( Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); var matBD = MatrixD.CreateWorld(TopBlock.Position * TopBlock.CubeGrid.GridSize, TopBlock.PositionComp.LocalMatrix.Forward, TopBlock.PositionComp.LocalMatrix.Up); var matA = (Matrix)matAD; var matB = (Matrix)matBD; m_fixedData = new HkFixedConstraintData(); m_fixedData.SetInertiaStabilizationFactor(10); m_fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); m_fixedData.SetInBodySpace(matA, matB, CubeGrid.Physics, TopGrid.Physics); //Dont dispose the fixed data or we wont have access to them m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, topBlock.CubeGrid.Physics.RigidBody, m_fixedData); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); if (!m_constraint.InWorld) { Debug.Fail("Constraint was not added to world"); CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_fixedData = null; return(false); } m_constraint.Enabled = true; return(true); }
private void Attach(MyEntity entity, Vector3 gearSpacePivot, Matrix otherBodySpacePivot) { if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled) { var handle = StateChanged; if (Sync.IsServer && entity is MyCubeGrid) { (entity as MyCubeGrid).OnGridSplit += CubeGrid_OnGridSplit; } if (MyFakes.WELD_LANDING_GEARS && CanWeldTo(entity, ref otherBodySpacePivot)) { if (m_attachedTo != null || entity == null) return; if (entity is MyVoxelBase) { if (CubeGrid.Physics.RigidBody.IsFixed == false) { CubeGrid.Physics.ConvertToStatic(); m_converted = true; } } else { MyEntity parent = entity.GetTopMostParent(); MyWeldingGroups.Static.CreateLink(EntityId, CubeGrid, parent); } //OnConstraintAdded(GridLinkTypeEnum.LandingGear, entity); m_lockModeSync.Value = LandingGearMode.Locked; m_attachedTo = entity; m_attachedTo.OnPhysicsChanged += m_physicsChangedHandler; this.OnPhysicsChanged += m_physicsChangedHandler; if (CanAutoLock) ResetAutolock(); OnConstraintAdded(GridLinkTypeEnum.Physical, entity); //OnConstraintAdded(GridLinkTypeEnum.NoContactDamage, entity); if (!m_needsToRetryLock) StartSound(m_lockSound); if (handle != null) handle(true); return; } //var entity = body.GetBody().Entity; Debug.Assert(m_attachedTo == null, "Already attached"); Debug.Assert(entity != null, "Landing gear is attached to body which has no entity"); Debug.Assert(m_constraint == null); if (m_attachedTo != null || entity == null || m_constraint != null) return; var body = entity.GetTopMostParent().Physics.RigidBody; body.Activate(); CubeGrid.Physics.RigidBody.Activate(); m_attachedTo = entity; m_attachedTo.OnPhysicsChanged += m_physicsChangedHandler; this.OnPhysicsChanged += m_physicsChangedHandler; Matrix gearLocalSpacePivot = Matrix.Identity; gearLocalSpacePivot.Translation = gearSpacePivot; var fixedData = new HkFixedConstraintData(); if (MyFakes.OVERRIDE_LANDING_GEAR_INERTIA) { fixedData.SetInertiaStabilizationFactor(MyFakes.LANDING_GEAR_INTERTIA); } else { fixedData.SetInertiaStabilizationFactor(1); } fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); fixedData.SetInBodySpace(gearLocalSpacePivot, otherBodySpacePivot, CubeGrid.Physics, entity.Physics as MyPhysicsBody); HkConstraintData data = fixedData; if (MyFakes.LANDING_GEAR_BREAKABLE && BreakForce < MyObjectBuilder_LandingGear.MaxSolverImpulse) { var breakData = new HkBreakableConstraintData(fixedData); fixedData.Dispose(); breakData.Threshold = BreakForce; breakData.ReapplyVelocityOnBreak = true; breakData.RemoveFromWorldOnBrake = true; data = breakData; } if (!m_needsToRetryLock) StartSound(m_lockSound); m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, body, data); CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; m_lockModeSync.Value = LandingGearMode.Locked; if (CanAutoLock) ResetAutolock(); OnConstraintAdded(GridLinkTypeEnum.Physical, entity); OnConstraintAdded(GridLinkTypeEnum.NoContactDamage, entity); if (handle != null) handle(true); } }
public void StopManipulation() { if (m_state != MyState.NONE && Owner != null) { var characterMovementState = Owner.GetCurrentMovementState(); switch (characterMovementState) { case MyCharacterMovementEnum.Walking: case MyCharacterMovementEnum.BackWalking: case MyCharacterMovementEnum.WalkingLeftFront: case MyCharacterMovementEnum.WalkingRightFront: case MyCharacterMovementEnum.WalkingLeftBack: case MyCharacterMovementEnum.WalkingRightBack: case MyCharacterMovementEnum.WalkStrafingLeft: case MyCharacterMovementEnum.WalkStrafingRight: case MyCharacterMovementEnum.Running: case MyCharacterMovementEnum.Backrunning: case MyCharacterMovementEnum.RunStrafingLeft: case MyCharacterMovementEnum.RunStrafingRight: case MyCharacterMovementEnum.RunningRightFront: case MyCharacterMovementEnum.RunningRightBack: case MyCharacterMovementEnum.RunningLeftFront: case MyCharacterMovementEnum.RunningLeftBack: Owner.PlayCharacterAnimation("WalkBack", MyBlendOption.Immediate, MyFrameOption.Loop, 0.2f, 1f); break; case MyCharacterMovementEnum.Standing: case MyCharacterMovementEnum.RotatingLeft: case MyCharacterMovementEnum.RotatingRight: case MyCharacterMovementEnum.Flying: Owner.PlayCharacterAnimation("Idle", MyBlendOption.Immediate, MyFrameOption.Loop, 0.2f, 1f); break; } } if (m_constraint != null) { if (OwnerVirtualPhysics != null) { OwnerVirtualPhysics.RemoveConstraint(m_constraint); } m_constraint.Dispose(); m_constraint = null; } if (m_fixedConstraintData != null) { if (!m_fixedConstraintData.IsDisposed) { m_fixedConstraintData.Dispose(); } m_fixedConstraintData = null; } m_headLocalPivotMatrix = Matrix.Zero; m_otherLocalPivotMatrix = Matrix.Zero; if (m_otherEntity != null) { SetTransparent(m_otherEntity); if (m_state == MyState.HOLD) { SetMotionOnClient(m_otherEntity, HkMotionType.Dynamic); // Do not send when disconnecting if (IsOwnerLocalPlayer() && !MyEntities.CloseAllowed && !(m_otherEntity is MyCharacter)) { Sync.Players.RemoveControlledEntity(m_otherEntity); } } m_manipulatedEntitites.Remove(m_otherEntity); var handler = ManipulationStopped; if (handler != null) { handler(m_otherEntity); } m_otherEntity.SyncFlag = true; if (m_otherEntity.Physics != null && m_otherRigidBody != null && !m_otherRigidBody.IsDisposed) { SetManipulated(m_otherEntity, false); //m_otherRigidBody.AngularDamping = m_otherAngularDamping; //m_otherRigidBody.LinearDamping = m_otherLinearDamping; if (m_otherEntity is MyCharacter) { m_otherEntity.Physics.SetRagdollDefaults(); } else { m_otherRigidBody.Restitution = m_otherRestitution; m_otherRigidBody.MaxLinearVelocity = m_otherMaxLinearVelocity; m_otherRigidBody.MaxAngularVelocity = m_otherMaxAngularVelocity; if (m_massChange != null) { m_massChange.Remove(); } m_massChange = null; // Clamp output velocity m_otherRigidBody.LinearVelocity = Vector3.Clamp(m_otherRigidBody.LinearVelocity, -2 * Vector3.One, 2 * Vector3.One); m_otherRigidBody.AngularVelocity = Vector3.Clamp(m_otherRigidBody.AngularVelocity, -Vector3.One * (float)Math.PI, Vector3.One * (float)Math.PI); if (!m_otherRigidBody.IsActive) { m_otherRigidBody.Activate(); } m_otherRigidBody.EnableDeactivation = false; m_otherRigidBody.EnableDeactivation = true; //resets deactivation counter } m_otherRigidBody = null; } m_otherEntity.OnClosing -= OtherEntity_OnClosing; m_otherEntity = null; } m_constraintInitialized = false; RemoveOwnerVirtualPhysics(); if (Owner != null) { Owner.ManipulatedEntity = null; } m_state = MyState.NONE; }
public void StartManipulation(MyState state, MyEntity otherEntity, Vector3D hitPosition, ref MatrixD ownerWorldHeadMatrix, bool fromServer = false) { Debug.Assert(m_constraintInitialized == false); // Commenting this out to allow picking up dead bodies and characters if (otherEntity is MyCharacter) { return; } if (Owner == null) { Debug.Assert(!fromServer, "Desync!"); return; } if (otherEntity.Physics == null) { return; } m_otherRigidBody = otherEntity.Physics.RigidBody; m_otherPhysicsBody = otherEntity.Physics; if (otherEntity is MyCharacter) { if (!(otherEntity as MyCharacter).IsDead || !((otherEntity as MyCharacter).Components.Has <MyCharacterRagdollComponent>() && (otherEntity as MyCharacter).Components.Get <MyCharacterRagdollComponent>().IsRagdollActivated)) { Debug.Assert(!fromServer, "Desync!"); return; } m_otherRigidBody = (otherEntity as MyCharacter).Physics.Ragdoll.GetRootRigidBody(); } // else (!otherEntity.Physics.RigidBody.InWorld) // Do we need to check if the body is in the world when this was returned byt RayCast ? Commenting this out for now.. var characterMovementState = Owner.GetCurrentMovementState(); if (!CanManipulate(characterMovementState)) { Debug.Assert(!fromServer, "Desync!"); return; } if (!CanManipulateEntity(otherEntity)) { Debug.Assert(!fromServer, "Desync!"); return; } m_otherRigidBody.Activate(); Vector3D hitUp = Vector3D.Up; Vector3D hitRight; double dot = Vector3D.Dot(ownerWorldHeadMatrix.Forward, hitUp); if (dot == 1 || dot == -1) { hitRight = ownerWorldHeadMatrix.Right; } else { hitRight = Vector3D.Cross(ownerWorldHeadMatrix.Forward, hitUp); hitRight.Normalize(); } Vector3D hitForward = Vector3D.Cross(hitUp, hitRight); hitForward.Normalize(); // Matrix of constraint for other body in world MatrixD otherWorldMatrix = MatrixD.Identity; otherWorldMatrix.Forward = hitForward; otherWorldMatrix.Right = hitRight; otherWorldMatrix.Up = hitUp; otherWorldMatrix.Translation = hitPosition; const float headPivotOffset = 1.5f; MatrixD headPivotWorldMatrix = ownerWorldHeadMatrix; headPivotWorldMatrix.Translation = ownerWorldHeadMatrix.Translation + headPivotOffset * ownerWorldHeadMatrix.Forward; //float distanceToHead = (float)(headPivotWorldMatrix.Translation - otherWorldMatrix.Translation).Length(); //distanceToHead = MathHelper.Clamp(distanceToHead, 0.6f, 2.5f); // Matrix of constraint for other body in local m_otherLocalPivotMatrix = (Matrix)(otherWorldMatrix * otherEntity.PositionComp.WorldMatrixNormalizedInv); m_otherWorldPivotOrigin = otherWorldMatrix.Translation; MatrixD ownerWorldMatrixInverse = MatrixD.Normalize(MatrixD.Invert(ownerWorldHeadMatrix)); m_headLocalPivotMatrix = Matrix.Identity; m_headLocalPivotMatrix.Translation = Vector3D.Transform(headPivotWorldMatrix.Translation, ownerWorldMatrixInverse); HkConstraintData data; if (state == MyState.HOLD) { if (!fromServer) { float mass = 0; if (otherEntity is MyCubeGrid) { var group = MyCubeGridGroups.Static.Physical.GetGroup((otherEntity as MyCubeGrid)); foreach (var node in group.Nodes) { if (node.NodeData.IsStatic) //fixed constraint on part connected to static grid isnt good idea { return; } mass += node.NodeData.Physics.Mass; } mass = GetRealMass(mass); } else if (otherEntity is MyCharacter) { mass = (otherEntity as MyCharacter).Definition.Mass; } else { mass = GetRealMass(m_otherRigidBody.Mass); } // Player can hold large projectile (~222kg) if ((mass > 210) || ((otherEntity is MyCharacter) && (otherEntity.Physics.Mass > 210))) { return; } } if (!CreateOwnerVirtualPhysics()) { return; } if (IsOwnerLocalPlayer()) { var controllingPlayer = Sync.Players.GetControllingPlayer(otherEntity); if (controllingPlayer != null) { RemoveOwnerVirtualPhysics(); return; } if (!(otherEntity is MyCharacter)) // this would cause to start controlling the dead body.. { Sync.Players.TrySetControlledEntity(Owner.ControllerInfo.Controller.Player.Id, otherEntity); } } SetMotionOnClient(otherEntity, HkMotionType.Dynamic); data = CreateFixedConstraintData(ref m_otherLocalPivotMatrix, headPivotOffset); if (otherEntity is MyCharacter) { if (MyFakes.MANIPULATION_TOOL_VELOCITY_LIMIT) { HkMalleableConstraintData mcData = data as HkMalleableConstraintData; mcData.Strength = 0.005f; } else { HkFixedConstraintData fcData = data as HkFixedConstraintData; fcData.MaximumAngularImpulse = 0.0005f; fcData.MaximumLinearImpulse = 0.0005f; fcData.BreachImpulse = 0.0004f; } } } else { if (!CreateOwnerVirtualPhysics()) { return; } data = CreateBallAndSocketConstraintData(ref m_otherLocalPivotMatrix, ref m_headLocalPivotMatrix); if (otherEntity is MyCharacter) { HkMalleableConstraintData mcData = data as HkMalleableConstraintData; mcData.Strength = 0.005f; } } m_otherEntity = otherEntity; m_otherEntity.OnClosing += OtherEntity_OnClosing; //m_otherAngularDamping = m_otherRigidBody.AngularDamping; //m_otherLinearDamping = m_otherRigidBody.LinearDamping; m_otherRestitution = m_otherRigidBody.Restitution; m_otherMaxLinearVelocity = m_otherRigidBody.MaxLinearVelocity; m_otherMaxAngularVelocity = m_otherRigidBody.MaxAngularVelocity; SetManipulated(m_otherEntity, true); if (state == MyState.HOLD) { if (m_otherEntity is MyCharacter) { foreach (var body in m_otherEntity.Physics.Ragdoll.RigidBodies) { //body.AngularDamping = TARGET_ANGULAR_DAMPING; //body.LinearDamping = TARGET_LINEAR_DAMPING; //body.Mass = 5; body.Restitution = TARGET_RESTITUTION; body.MaxLinearVelocity = m_limitingLinearVelocity; body.MaxAngularVelocity = (float)Math.PI * 0.1f; } } else { m_massChange = HkMassChangerUtil.Create(m_otherRigidBody, int.MaxValue, 1, 0.001f); //m_otherRigidBody.AngularDamping = TARGET_ANGULAR_DAMPING; //m_otherRigidBody.LinearDamping = TARGET_LINEAR_DAMPING; m_otherRigidBody.Restitution = TARGET_RESTITUTION; m_otherRigidBody.MaxLinearVelocity = m_limitingLinearVelocity; m_otherRigidBody.MaxAngularVelocity = (float)Math.PI; } const float holdingTransparency = 0.4f; SetTransparent(otherEntity, holdingTransparency); } m_constraint = new HkConstraint(m_otherRigidBody, OwnerVirtualPhysics.RigidBody, data); OwnerVirtualPhysics.AddConstraint(m_constraint); m_constraintCreationTime = MySandboxGame.Static.UpdateTime; m_state = state; m_previousCharacterMovementState = Owner.GetCurrentMovementState(); if (m_state == MyState.HOLD) { Owner.PlayCharacterAnimation("PickLumber", MyBlendOption.Immediate, MyFrameOption.PlayOnce, 0.2f, 1f); } else { Owner.PlayCharacterAnimation("PullLumber", MyBlendOption.Immediate, MyFrameOption.PlayOnce, 0.2f, 1f); } m_manipulatedEntitites.Add(m_otherEntity); Owner.ManipulatedEntity = m_otherEntity; var handler = ManipulationStarted; if (handler != null) { handler(m_otherEntity); } }
private void Attach(HkRigidBody body, Vector3 gearSpacePivot, Matrix otherBodySpacePivot) { if (CubeGrid.Physics.Enabled) { var entity = body.GetEntity(); Debug.Assert(m_attachedTo == null, "Already attached"); Debug.Assert(entity != null, "Landing gear is attached to body which has no entity"); Debug.Assert(m_constraint == null); if (m_attachedTo != null || entity == null || m_constraint != null) return; body.Activate(); CubeGrid.Physics.RigidBody.Activate(); m_attachedTo = entity; if (entity != null) { entity.OnPhysicsChanged += m_physicsChangedHandler; } this.OnPhysicsChanged += m_physicsChangedHandler; Matrix gearLocalSpacePivot = Matrix.Identity; gearLocalSpacePivot.Translation = gearSpacePivot; var fixedData = new HkFixedConstraintData(); if (MyFakes.OVERRIDE_LANDING_GEAR_INERTIA) { fixedData.SetInertiaStabilizationFactor(MyFakes.LANDING_GEAR_INTERTIA); } else { fixedData.SetInertiaStabilizationFactor(1); } fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); fixedData.SetInBodySpace(ref gearLocalSpacePivot, ref otherBodySpacePivot); HkConstraintData data = fixedData; if (MyFakes.LANDING_GEAR_BREAKABLE && BreakForce < MaxSolverImpulse) { var breakData = new HkBreakableConstraintData(fixedData); fixedData.Dispose(); breakData.Threshold = BreakForce; breakData.ReapplyVelocityOnBreak = true; breakData.RemoveFromWorldOnBrake = true; data = breakData; } if (!m_needsToRetryLock) StartSound(m_lockSound); m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, body, data); CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; LockMode = LandingGearMode.Locked; if (CanAutoLock) ResetAutolock(); OnConstraintAdded(GridLinkTypeEnum.Physical, entity); OnConstraintAdded(GridLinkTypeEnum.NoContactDamage, entity); var handle = StateChanged; if (handle != null) handle(true); } }
public void Attach(MyPistonTop topBlock, bool updateSync = false) { if (m_topBlock != null) Detach(); if (CubeGrid.Physics == null || SafeConstraint != null) return; UpdateAnimation(); Debug.Assert(SafeConstraint == null); if (CubeGrid.Physics.Enabled && topBlock != null) { m_topBlock = topBlock; m_topBlockId = topBlock.EntityId; if (updateSync) SyncObject.AttachTop(m_topBlock); m_topGrid = m_topBlock.CubeGrid; var rotorBody = m_topGrid.Physics.RigidBody; var matAD = MatrixD.CreateWorld(Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); var matBD = MatrixD.CreateWorld(m_topBlock.Position * m_topBlock.CubeGrid.GridSize, m_topBlock.PositionComp.LocalMatrix.Forward, m_topBlock.PositionComp.LocalMatrix.Up); var matA = (Matrix)matAD; var matB = (Matrix)matBD; m_fixedData = new HkFixedConstraintData(); m_fixedData.SetInertiaStabilizationFactor(10); m_fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); m_fixedData.SetInBodySpace(ref matA, ref matB); var breakData = new HkBreakableConstraintData(m_fixedData); //Dont dispose the fixed data or we wont have access to them breakData.Threshold = BreakOffTreshold; breakData.ReapplyVelocityOnBreak = true; breakData.RemoveFromWorldOnBrake = false; m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, rotorBody, breakData); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; m_topBlock.Attach(this); OnConstraintAdded(GridLinkTypeEnum.Physical, m_topGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_topGrid); m_conveyorEndpoint.Attach(topBlock.ConveyorEndpoint as MyAttachableConveyorEndpoint); } }
private void InitSubpartsPhysics() { var subpart = m_subpart1; if (subpart == null || CubeGrid.Physics == null) return; subpart.Physics = new MyPhysicsBody(subpart, CubeGrid.IsStatic ? RigidBodyFlag.RBF_STATIC : (CubeGrid.GridSizeEnum == MyCubeSize.Large ? RigidBodyFlag.RBF_DOUBLED_KINEMATIC : RigidBodyFlag.RBF_DEFAULT)); HkCylinderShape shape = new HkCylinderShape(Vector3.Zero, new Vector3(0, 0, 2), CubeGrid.GridSize / 2); var mass = HkInertiaTensorComputer.ComputeCylinderVolumeMassProperties(Vector3.Zero, Vector3.One, 1, 40.0f*CubeGrid.GridSize); subpart.Physics.CreateFromCollisionObject(shape, Vector3.Zero, subpart.WorldMatrix, mass); shape.Base.RemoveReference(); subpart.Physics.RigidBody.Layer = CubeGrid.Physics.RigidBody.Layer; if (subpart.Physics.RigidBody2 != null) subpart.Physics.RigidBody2.Layer = MyPhysics.KinematicDoubledCollisionLayer; m_subpartsFixedData = new HkFixedConstraintData(); m_subpartsFixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); float res; var x = m_subpartsFixedData.GetInertiaStabilizationFactor(out res); m_subpartsFixedData.SetInertiaStabilizationFactor(1); var matAD = MatrixD.CreateWorld(Position * CubeGrid.GridSize + Vector3D.Transform(Vector3D.Transform(m_subpartsConstraintPos, WorldMatrix), CubeGrid.PositionComp.LocalMatrix), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); matAD.Translation = CubeGrid.Physics.WorldToCluster(matAD.Translation); var matA = (Matrix)matAD; var matB = subpart.PositionComp.LocalMatrix; m_subpartsFixedData.SetInWorldSpace(ref matA, ref matB, ref matB); var breakableData = new HkBreakableConstraintData(m_subpartsFixedData); //Dont dispose the fixed data or we wont have access to them breakableData.Threshold = BreakOffTreshold; m_subpartsConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, subpart.Physics.RigidBody, breakableData); m_subpartsConstraint.WantRuntime = true; m_posChanged = true; }
public void Attach(MyPistonTop topBlock) { if (CubeGrid == topBlock.CubeGrid) return; Debug.Assert(topBlock != null, "Top block cannot be null!"); Debug.Assert(m_constraint == null, "Contraint already attached, call detach first!"); Debug.Assert(m_topBlockId.Value == topBlock.EntityId, "m_topBlockId must be set prior calling Attach!"); UpdateAnimation(); if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled && topBlock.CubeGrid.Physics != null) { m_topBlock = topBlock; m_topGrid = m_topBlock.CubeGrid; var rotorBody = m_topGrid.Physics.RigidBody; var matAD = MatrixD.CreateWorld(Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); var matBD = MatrixD.CreateWorld(m_topBlock.Position * m_topBlock.CubeGrid.GridSize, m_topBlock.PositionComp.LocalMatrix.Forward, m_topBlock.PositionComp.LocalMatrix.Up); var matA = (Matrix)matAD; var matB = (Matrix)matBD; m_fixedData = new HkFixedConstraintData(); m_fixedData.SetInertiaStabilizationFactor(10); m_fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); m_fixedData.SetInBodySpace(matA, matB, CubeGrid.Physics, m_topGrid.Physics); var breakData = new HkBreakableConstraintData(m_fixedData); //Dont dispose the fixed data or we wont have access to them breakData.Threshold = BreakOffTreshold; breakData.ReapplyVelocityOnBreak = true; breakData.RemoveFromWorldOnBrake = false; m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, rotorBody, breakData); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); if(!m_constraint.InWorld) { Debug.Fail("Constraint was not added to world"); CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_fixedData.Dispose(); m_fixedData = null; return; } m_constraint.Enabled = true; m_topBlock.Attach(this); m_topGrid.OnPhysicsChanged += CubeGrid_OnPhysicsChanged; OnConstraintAdded(GridLinkTypeEnum.Physical, m_topGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_topGrid); m_conveyorEndpoint.Attach(topBlock.ConveyorEndpoint as MyAttachableConveyorEndpoint); UpdateText(); } }
internal void Detach() { if (m_constraint == null) return; Debug.Assert(m_constraint != null); Debug.Assert(m_topGrid != null); Debug.Assert(m_topBlock != null); var tmpTopGrid = m_topGrid; m_fixedData.Dispose(); m_fixedData = null; CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_topGrid = null; if (m_topBlock != null) m_topBlock.Detach(); tmpTopGrid.OnPhysicsChanged -= CubeGrid_OnPhysicsChanged; m_conveyorEndpoint.Detach(m_topBlock.ConveyorEndpoint as MyAttachableConveyorEndpoint); m_topBlock = null; OnConstraintRemoved(GridLinkTypeEnum.Physical, tmpTopGrid); OnConstraintRemoved(GridLinkTypeEnum.Logical, tmpTopGrid); UpdateText(); }
private void Attach(HkRigidBody body, Vector3 gearSpacePivot, Matrix otherBodySpacePivot) { if (CubeGrid.Physics.Enabled) { var entity = body.GetEntity(); Debug.Assert(m_attachedTo == null, "Already attached"); Debug.Assert(entity != null, "Landing gear is attached to body which has no entity"); Debug.Assert(m_constraint == null); if (m_attachedTo != null || entity == null || m_constraint != null) { return; } body.Activate(); CubeGrid.Physics.RigidBody.Activate(); m_attachedTo = entity; if (entity != null) { entity.OnPhysicsChanged += m_physicsChangedHandler; } this.OnPhysicsChanged += m_physicsChangedHandler; Matrix gearLocalSpacePivot = Matrix.Identity; gearLocalSpacePivot.Translation = gearSpacePivot; var fixedData = new HkFixedConstraintData(); if (MyFakes.OVERRIDE_LANDING_GEAR_INERTIA) { fixedData.SetInertiaStabilizationFactor(MyFakes.LANDING_GEAR_INTERTIA); } else { fixedData.SetInertiaStabilizationFactor(1); } fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); fixedData.SetInBodySpace(ref gearLocalSpacePivot, ref otherBodySpacePivot); HkConstraintData data = fixedData; if (MyFakes.LANDING_GEAR_BREAKABLE && BreakForce < MaxSolverImpulse) { var breakData = new HkBreakableConstraintData(fixedData); fixedData.Dispose(); breakData.Threshold = BreakForce; breakData.ReapplyVelocityOnBreak = true; breakData.RemoveFromWorldOnBrake = true; data = breakData; } if (!m_needsToRetryLock) { StartSound(m_lockSound); } m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, body, data); CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; LockMode = LandingGearMode.Locked; if (CanAutoLock) { ResetAutolock(); } OnConstraintAdded(GridLinkTypeEnum.Physical, entity); OnConstraintAdded(GridLinkTypeEnum.NoContactDamage, entity); var handle = StateChanged; if (handle != null) { handle(true); } } }
private void CreateConstraint(MyEntitySubpart subpart, ref HkConstraint constraint, ref HkFixedConstraintData constraintData) { if (subpart != null) { bool flag = !Sync.IsServer; if (subpart.Physics == null) { HkShape[] havokCollisionShapes = subpart.ModelCollision.HavokCollisionShapes; if ((havokCollisionShapes != null) && (havokCollisionShapes.Length != 0)) { MyPhysicsBody body = new MyPhysicsBody(subpart, flag ? RigidBodyFlag.RBF_STATIC : (RigidBodyFlag.RBF_UNLOCKED_SPEEDS | RigidBodyFlag.RBF_DOUBLED_KINEMATIC)) { IsSubpart = true }; subpart.Physics = body; HkShape shape = havokCollisionShapes[0]; MyPositionComponentBase positionComp = subpart.PositionComp; Vector3 center = positionComp.LocalVolume.Center; HkMassProperties properties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(positionComp.LocalAABB.HalfExtents, 100f); int collisionFilter = base.CubeGrid.IsStatic ? 9 : 0x10; body.CreateFromCollisionObject(shape, center, positionComp.WorldMatrix, new HkMassProperties?(properties), collisionFilter); } } if (flag) { subpart.Physics.Enabled = true; } else { base.CreateSubpartConstraint(subpart, out constraintData, out constraint); base.CubeGrid.Physics.AddConstraint(constraint); constraint.SetVirtualMassInverse(Vector4.Zero, Vector4.One); } } }
internal void Detach(bool updateGroups = true) { if (m_constraint == null) return; Debug.Assert(m_constraint != null); Debug.Assert(m_topGrid != null); Debug.Assert(m_topBlock != null); var tmpTopGrid = m_topGrid; if (m_constraint.InWorld && (m_constraint.ConstraintData as HkBreakableConstraintData).getIsBroken(m_constraint)) m_topBlockId = 0; m_fixedData.Dispose(); m_fixedData = null; CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_topGrid = null; if (m_topBlock != null) m_topBlock.Detach(); m_conveyorEndpoint.Detach(m_topBlock.ConveyorEndpoint as MyAttachableConveyorEndpoint); m_topBlock = null; if (updateGroups) { OnConstraintRemoved(GridLinkTypeEnum.Physical, tmpTopGrid); OnConstraintRemoved(GridLinkTypeEnum.Logical, tmpTopGrid); } // Try to reattach, if the block will still live next frame. This fixes missing attachments when splitting grids }
private void CreateSubpartsConstraint(MyEntitySubpart subpart) { m_subpartsFixedData = new HkFixedConstraintData(); m_subpartsFixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); m_subpartsFixedData.SetInertiaStabilizationFactor(1); var matAD = MatrixD.CreateWorld(Position * CubeGrid.GridSize + Vector3D.Transform(Vector3D.Transform(m_subpartsConstraintPos, WorldMatrix), CubeGrid.PositionComp.LocalMatrix), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); matAD.Translation = CubeGrid.Physics.WorldToCluster(matAD.Translation); var matA = (Matrix)matAD; var matB = subpart.PositionComp.LocalMatrix; m_subpartsFixedData.SetInWorldSpace(ref matA, ref matB, ref matB); //Dont dispose the fixed data or we wont have access to them HkConstraintData constraintData = m_subpartsFixedData; m_subpartsConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, subpart.Physics.RigidBody, constraintData); Debug.Assert(m_subpartsConstraint.RigidBodyA != null); m_subpartsConstraint.WantRuntime = true; }
public void StartManipulation(MyState state, MyEntity otherEntity, Vector3D hitPosition, ref MatrixD ownerWorldHeadMatrix) { Debug.Assert(m_constraintInitialized == false); // Commenting this out to allow picking up dead bodies and characters //if (otherEntity is MyCharacter) // return; if (Owner == null || Owner.VirtualPhysics == null || !Owner.VirtualPhysics.RigidBody.InWorld) { return; } var ownerRigidBody = Owner.VirtualPhysics.RigidBody; if (otherEntity.Physics == null) { return; } m_otherRigidBody = otherEntity.Physics.RigidBody; if (otherEntity is MyCharacter) { if (!(otherEntity as MyCharacter).IsDead || !(otherEntity as MyCharacter).IsRagdollActivated) { return; } m_otherRigidBody = (otherEntity as MyCharacter).Physics.Ragdoll.GetRootRigidBody(); } // else (!otherEntity.Physics.RigidBody.InWorld) // Do we need to check if the body is in the world when this was returned byt RayCast ? Commenting this out for now.. var characterMovementState = Owner.GetCurrentMovementState(); if (!CanManipulate(characterMovementState)) { return; } if (!CanManipulateEntity(otherEntity)) { return; } // PetrM:TODO: Make all client grids dynamic. if (!(otherEntity is MyCharacter && (otherEntity as MyCharacter).IsRagdollActivated) && state == MyState.HOLD) // In case of picking up a ragdoll don't turn off and on the physics { otherEntity.Physics.Enabled = false; otherEntity.SyncFlag = false; m_otherRigidBody.UpdateMotionType(HkMotionType.Dynamic); otherEntity.Physics.Enabled = true; // HACK: This is here only because disabling and enabling physics puts constraints into inconsistent state. otherEntity.RaisePhysicsChanged(); } Owner.VirtualPhysics.RigidBody.Activate(); m_otherRigidBody.Activate(); Vector3D hitUp = Vector3D.Up; Vector3D hitRight; double dot = Vector3D.Dot(ownerWorldHeadMatrix.Forward, hitUp); if (dot == 1 || dot == -1) { hitRight = ownerWorldHeadMatrix.Right; } else { hitRight = Vector3D.Cross(ownerWorldHeadMatrix.Forward, hitUp); hitRight.Normalize(); } Vector3D hitForward = Vector3D.Cross(hitUp, hitRight); hitForward.Normalize(); // Matrix of constraint for other body in world MatrixD otherWorldMatrix = MatrixD.Identity; otherWorldMatrix.Forward = hitForward; otherWorldMatrix.Right = hitRight; otherWorldMatrix.Up = hitUp; otherWorldMatrix.Translation = hitPosition; const float headPivotOffset = 1.5f; MatrixD headPivotWorldMatrix = ownerWorldHeadMatrix; headPivotWorldMatrix.Translation = ownerWorldHeadMatrix.Translation + headPivotOffset * ownerWorldHeadMatrix.Forward; //float distanceToHead = (float)(headPivotWorldMatrix.Translation - otherWorldMatrix.Translation).Length(); //distanceToHead = MathHelper.Clamp(distanceToHead, 0.6f, 2.5f); // Matrix of constraint for other body in local m_otherLocalPivotMatrix = (Matrix)(otherWorldMatrix * otherEntity.PositionComp.WorldMatrixNormalizedInv); m_otherWorldPivotOrigin = otherWorldMatrix.Translation; MatrixD ownerWorldMatrixInverse = MatrixD.Normalize(MatrixD.Invert(ownerWorldHeadMatrix)); m_headLocalPivotMatrix = Matrix.Identity; m_headLocalPivotMatrix.Translation = Vector3D.Transform(headPivotWorldMatrix.Translation, ownerWorldMatrixInverse); HkConstraintData data; if (state == MyState.HOLD) { float mass = 0; if (otherEntity is MyCubeGrid) { var group = MyCubeGridGroups.Static.Physical.GetGroup((otherEntity as MyCubeGrid)); foreach (var node in group.Nodes) { mass += node.NodeData.Physics.Mass; } mass = GetRealMass(mass); } else { mass = GetRealMass(otherEntity.Physics.Mass); } // Player can hold large projectile (~222kg) if ((mass <= 210) || ((otherEntity is MyCharacter) && (otherEntity.Physics.Mass < 210))) { data = CreateFixedConstraintData(ref m_otherLocalPivotMatrix, headPivotOffset); } else { return; } if (otherEntity is MyCharacter) { if (MyFakes.MANIPULATION_TOOL_VELOCITY_LIMIT) { HkMalleableConstraintData mcData = data as HkMalleableConstraintData; mcData.Strength = 0.005f; } else { HkFixedConstraintData fcData = data as HkFixedConstraintData; fcData.MaximumAngularImpulse = 2.0f; fcData.MaximumLinearImpulse = 2.0f; } } } else { data = CreateBallAndSocketConstraintData(ref m_otherLocalPivotMatrix, ref m_headLocalPivotMatrix); if (otherEntity is MyCharacter) { HkMalleableConstraintData mcData = data as HkMalleableConstraintData; mcData.Strength = 0.005f; } } m_otherEntity = otherEntity; m_otherEntity.OnClosing += OtherEntity_OnClosing; //m_otherAngularDamping = m_otherRigidBody.AngularDamping; //m_otherLinearDamping = m_otherRigidBody.LinearDamping; m_otherRestitution = m_otherRigidBody.Restitution; m_otherMaxLinearVelocity = m_otherRigidBody.MaxLinearVelocity; m_otherMaxAngularVelocity = m_otherRigidBody.MaxAngularVelocity; SetManipulated(m_otherEntity, true); if (state == MyState.HOLD) { m_massChange = HkMassChangerUtil.Create(m_otherRigidBody, int.MaxValue, 1, 0.001f); //m_otherRigidBody.AngularDamping = TARGET_ANGULAR_DAMPING; //m_otherRigidBody.LinearDamping = TARGET_LINEAR_DAMPING; m_otherRigidBody.Restitution = TARGET_RESTITUTION; m_otherRigidBody.MaxLinearVelocity = m_limitingLinearVelocity; m_otherRigidBody.MaxAngularVelocity = (float)Math.PI; if (m_otherEntity is MyCharacter) { foreach (var body in m_otherEntity.Physics.Ragdoll.RigidBodies) { //body.AngularDamping = TARGET_ANGULAR_DAMPING; //body.LinearDamping = TARGET_LINEAR_DAMPING; body.Restitution = TARGET_RESTITUTION; body.MaxLinearVelocity = m_limitingLinearVelocity; body.MaxAngularVelocity = (float)Math.PI; } } const float holdingTransparency = 0.4f; SetTransparent(otherEntity, holdingTransparency); //TODO jt: why it must be called twice? SetTransparent(otherEntity, holdingTransparency); } m_constraint = new HkConstraint(m_otherRigidBody, Owner.VirtualPhysics.RigidBody, data); Owner.VirtualPhysics.AddConstraint(m_constraint); m_constraintCreationTime = MySandboxGame.Static.UpdateTime; m_state = state; m_previousCharacterMovementState = Owner.GetCurrentMovementState(); if (m_state == MyState.HOLD) { Owner.PlayCharacterAnimation("PickLumber", false, MyPlayAnimationMode.Immediate | MyPlayAnimationMode.Play, 0.2f, 1f); } else { Owner.PlayCharacterAnimation("PullLumber", false, MyPlayAnimationMode.Immediate | MyPlayAnimationMode.Play, 0.2f, 1f); } m_manipulatedEntitites.Add(m_otherEntity); Owner.ManipulatedEntity = m_otherEntity; }
private void ConnectInternal(ref Matrix localSpaceA, ref Matrix localSpaceB, MyShipConnector otherConnector) { Debug.Assert(EntityId > otherConnector.EntityId, "Constraints should be created only master (entity with higher EntityId)"); Debug.Assert(!m_attachableConveyorEndpoint.AlreadyAttached()); if (m_attachableConveyorEndpoint.AlreadyAttached()) m_attachableConveyorEndpoint.DetachAll(); m_attachableConveyorEndpoint.Attach(otherConnector.m_attachableConveyorEndpoint); var data = new HkFixedConstraintData(); data.SetInBodySpace(localSpaceA, localSpaceB, CubeGrid.Physics, otherConnector.CubeGrid.Physics); var newConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, otherConnector.CubeGrid.Physics.RigidBody, data); this.Connected = true; otherConnector.Connected = true; this.SetConstraint(otherConnector, newConstraint); otherConnector.SetConstraint(this, newConstraint); AddConstraint(newConstraint); if (CubeGrid != otherConnector.CubeGrid) { this.OnConstraintAdded(GridLinkTypeEnum.Logical, otherConnector.CubeGrid); this.OnConstraintAdded(GridLinkTypeEnum.Physical, otherConnector.CubeGrid); } CubeGrid.OnPhysicsChanged += CubeGrid_OnPhysicsChanged; }
protected override bool Attach(MyAttachableTopBlockBase topBlock, bool updateGroup = true) { Debug.Assert(topBlock != null, "Top block cannot be null!"); if (CubeGrid == topBlock.CubeGrid) return false; MyPistonTop pistonTop = topBlock as MyPistonTop; if (pistonTop != null && base.Attach(topBlock, updateGroup)) { Debug.Assert(m_constraint == null, "Contraint already attached, call detach first!"); Debug.Assert(m_connectionState.Value.TopBlockId.HasValue && (m_connectionState.Value.TopBlockId.Value == 0 || m_connectionState.Value.TopBlockId.Value == topBlock.EntityId), "m_topBlockId must be set prior calling Attach!"); UpdateAnimation(); var matAD = MatrixD.CreateWorld(Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); var matBD = MatrixD.CreateWorld(m_topBlock.Position * m_topBlock.CubeGrid.GridSize, m_topBlock.PositionComp.LocalMatrix.Forward, m_topBlock.PositionComp.LocalMatrix.Up); var matA = (Matrix)matAD; var matB = (Matrix)matBD; m_fixedData = new HkFixedConstraintData(); m_fixedData.SetInertiaStabilizationFactor(10); m_fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); m_fixedData.SetInBodySpace(matA, matB, CubeGrid.Physics, m_topGrid.Physics); //Dont dispose the fixed data or we wont have access to them m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, topBlock.CubeGrid.Physics.RigidBody, m_fixedData); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); if (!m_constraint.InWorld) { Debug.Fail("Constraint was not added to world"); CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_fixedData = null; return false; } m_constraint.Enabled = true; m_topBlock = topBlock; m_topGrid = topBlock.CubeGrid; topBlock.Attach(this); m_isAttached = true; if (updateGroup) { m_conveyorEndpoint.Attach(pistonTop.ConveyorEndpoint as MyAttachableConveyorEndpoint); } UpdateText(); return true; } return false; }
private void ConnectInternal(ref Matrix thisMatrix, ref Matrix otherMatrix, MyShipConnector otherConnector, bool constructor) { Debug.Assert(!m_attachableConveyorEndpoint.AlreadyAttached()); if (m_attachableConveyorEndpoint.AlreadyAttached()) m_attachableConveyorEndpoint.DetachAll(); m_attachableConveyorEndpoint.Attach(otherConnector.m_attachableConveyorEndpoint); var data = new HkFixedConstraintData(); data.SetInWorldSpace(ref thisMatrix, ref otherMatrix, ref thisMatrix); var newConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, otherConnector.CubeGrid.Physics.RigidBody, data); this.Connected = true; this.Master = true; otherConnector.Connected = true; otherConnector.Master = false; if (!constructor) { this.ChangeConstraint(otherConnector, newConstraint); otherConnector.ChangeConstraint(this, newConstraint); } else { this.SetConstraint(otherConnector, newConstraint); otherConnector.SetConstraint(this, newConstraint); } AddConstraint(newConstraint); if (CubeGrid != otherConnector.CubeGrid) { this.OnConstraintAdded(GridLinkTypeEnum.Logical, otherConnector.CubeGrid); this.OnConstraintAdded(GridLinkTypeEnum.Physical, otherConnector.CubeGrid); } }
protected override void DisposeConstraint() { if(m_constraint != null) { m_fixedData = null; CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; } }
void CubeGrid_OnPhysicsChanged(MyEntity obj) { if (m_hasConstraint) { if (MyPhysicsBody.IsConstraintValid(m_constraint) == false && m_constraint.IsDisposed == false) { RemoveConstraint(m_other, m_constraint); if (m_connectionState.Value.MasterToSlave.HasValue) { Matrix localSpaceA = Matrix.CreateTranslation(m_connectionPosition); Matrix localSpaceB = localSpaceA * m_connectionState.Value.MasterToSlave.Value; localSpaceA = localSpaceA * this.PositionComp.LocalMatrix; localSpaceB = localSpaceB * m_other.PositionComp.LocalMatrix; var data = new HkFixedConstraintData(); data.SetInBodySpace(localSpaceA, localSpaceB, CubeGrid.Physics, m_other.CubeGrid.Physics); var newConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, m_other.CubeGrid.Physics.RigidBody, data); this.SetConstraint(m_other, newConstraint); m_other.SetConstraint(this, newConstraint); AddConstraint(newConstraint); } else { var posA = ConstraintPositionInGridSpace(); var posB = m_other.ConstraintPositionInGridSpace(); var axisA = ConstraintAxisGridSpace(); var axisB = -m_other.ConstraintAxisGridSpace(); var data = new HkHingeConstraintData(); data.SetInBodySpace(posA, posB, axisA, axisB, CubeGrid.Physics, m_other.CubeGrid.Physics); var data2 = new HkMalleableConstraintData(); data2.SetData(data); data.ClearHandle(); data = null; data2.Strength = GetEffectiveStrength(m_other); var newConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, m_other.CubeGrid.Physics.RigidBody, data2); this.SetConstraint(m_other, newConstraint); m_other.SetConstraint(this, newConstraint); AddConstraint(newConstraint); } } } }
private void Attach(MyEntity entity, Vector3 gearSpacePivot, Matrix otherBodySpacePivot) { if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled) { var body = entity.Physics.RigidBody; var handle = StateChanged; if (Sync.IsServer && entity is MyCubeGrid) { (entity as MyCubeGrid).OnGridSplit += CubeGrid_OnGridSplit; } if (MyFakes.WELD_LANDING_GEARS && CanWeldTo(entity, ref otherBodySpacePivot)) { if (m_attachedTo != null || entity == null) { return; } if (entity is MyVoxelBase) { if (CubeGrid.Physics.RigidBody.IsFixed == false) { CubeGrid.Physics.ConvertToStatic(); m_converted = true; } } else { MyWeldingGroups.Static.CreateLink(EntityId, CubeGrid, entity); } //OnConstraintAdded(GridLinkTypeEnum.LandingGear, entity); m_lockModeSync.Value = LandingGearMode.Locked; m_attachedTo = entity; m_attachedTo.OnPhysicsChanged += m_physicsChangedHandler; this.OnPhysicsChanged += m_physicsChangedHandler; if (CanAutoLock) { ResetAutolock(); } OnConstraintAdded(GridLinkTypeEnum.Physical, entity); //OnConstraintAdded(GridLinkTypeEnum.NoContactDamage, entity); if (!m_needsToRetryLock) { StartSound(m_lockSound); } if (handle != null) { handle(true); } return; } //var entity = body.GetBody().Entity; Debug.Assert(m_attachedTo == null, "Already attached"); Debug.Assert(entity != null, "Landing gear is attached to body which has no entity"); Debug.Assert(m_constraint == null); if (m_attachedTo != null || entity == null || m_constraint != null) { return; } body.Activate(); CubeGrid.Physics.RigidBody.Activate(); m_attachedTo = entity; m_attachedTo.OnPhysicsChanged += m_physicsChangedHandler; this.OnPhysicsChanged += m_physicsChangedHandler; Matrix gearLocalSpacePivot = Matrix.Identity; gearLocalSpacePivot.Translation = gearSpacePivot; var fixedData = new HkFixedConstraintData(); if (MyFakes.OVERRIDE_LANDING_GEAR_INERTIA) { fixedData.SetInertiaStabilizationFactor(MyFakes.LANDING_GEAR_INTERTIA); } else { fixedData.SetInertiaStabilizationFactor(1); } fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); fixedData.SetInBodySpace(gearLocalSpacePivot, otherBodySpacePivot, CubeGrid.Physics, entity.Physics as MyPhysicsBody); HkConstraintData data = fixedData; if (MyFakes.LANDING_GEAR_BREAKABLE && BreakForce < MyObjectBuilder_LandingGear.MaxSolverImpulse) { var breakData = new HkBreakableConstraintData(fixedData); fixedData.Dispose(); breakData.Threshold = BreakForce; breakData.ReapplyVelocityOnBreak = true; breakData.RemoveFromWorldOnBrake = true; data = breakData; } if (!m_needsToRetryLock) { StartSound(m_lockSound); } m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, body, data); CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; m_lockModeSync.Value = LandingGearMode.Locked; if (CanAutoLock) { ResetAutolock(); } OnConstraintAdded(GridLinkTypeEnum.Physical, entity); OnConstraintAdded(GridLinkTypeEnum.NoContactDamage, entity); if (handle != null) { handle(true); } } }
protected override bool CreateConstraint(MyAttachableTopBlockBase topBlock) { if (!base.CreateConstraint(topBlock)) return false; var matAD = MatrixD.CreateWorld( Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); var matBD = MatrixD.CreateWorld(TopBlock.Position*TopBlock.CubeGrid.GridSize, TopBlock.PositionComp.LocalMatrix.Forward, TopBlock.PositionComp.LocalMatrix.Up); var matA = (Matrix) matAD; var matB = (Matrix) matBD; m_fixedData = new HkFixedConstraintData(); m_fixedData.SetInertiaStabilizationFactor(10); m_fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); m_fixedData.SetInBodySpace(matA, matB, CubeGrid.Physics, TopGrid.Physics); //Dont dispose the fixed data or we wont have access to them m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, topBlock.CubeGrid.Physics.RigidBody, m_fixedData); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); if (!m_constraint.InWorld) { Debug.Fail("Constraint was not added to world"); CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_fixedData = null; return false; } m_constraint.Enabled = true; return true; }
public void StopManipulation() { if (m_state != MyState.NONE && Owner != null) { var characterMovementState = Owner.GetCurrentMovementState(); switch (characterMovementState) { case MyCharacterMovementEnum.Walking: case MyCharacterMovementEnum.BackWalking: case MyCharacterMovementEnum.WalkingLeftFront: case MyCharacterMovementEnum.WalkingRightFront: case MyCharacterMovementEnum.WalkingLeftBack: case MyCharacterMovementEnum.WalkingRightBack: case MyCharacterMovementEnum.WalkStrafingLeft: case MyCharacterMovementEnum.WalkStrafingRight: case MyCharacterMovementEnum.Running: case MyCharacterMovementEnum.Backrunning: case MyCharacterMovementEnum.RunStrafingLeft: case MyCharacterMovementEnum.RunStrafingRight: case MyCharacterMovementEnum.RunningRightFront: case MyCharacterMovementEnum.RunningRightBack: case MyCharacterMovementEnum.RunningLeftFront: case MyCharacterMovementEnum.RunningLeftBack: Owner.PlayCharacterAnimation("WalkBack", true, MyPlayAnimationMode.Immediate | MyPlayAnimationMode.Play, 0.2f, 1f); break; case MyCharacterMovementEnum.Standing: case MyCharacterMovementEnum.RotatingLeft: case MyCharacterMovementEnum.RotatingRight: case MyCharacterMovementEnum.Flying: Owner.PlayCharacterAnimation("Idle", true, MyPlayAnimationMode.Immediate | MyPlayAnimationMode.Play, 0.2f, 1f); break; } } if (m_constraint != null) { if (Owner != null && Owner.VirtualPhysics != null) { Owner.VirtualPhysics.RemoveConstraint(m_constraint); } m_constraint.Dispose(); m_constraint = null; } if (m_fixedConstraintData != null) { if (!m_fixedConstraintData.IsDisposed) { m_fixedConstraintData.Dispose(); } m_fixedConstraintData = null; } m_headLocalPivotMatrix = Matrix.Zero; m_otherLocalPivotMatrix = Matrix.Zero; if (m_otherEntity != null) { SetTransparent(m_otherEntity); SetTransparent(m_otherEntity); if (m_state == MyState.HOLD) { SetMotionOnClient(m_otherEntity, HkMotionType.Keyframed); } m_manipulatedEntitites.Remove(m_otherEntity); m_otherEntity.SyncFlag = true; if (m_otherEntity.Physics != null && m_otherRigidBody != null && !m_otherRigidBody.IsDisposed) { SetManipulated(m_otherEntity, false); //m_otherRigidBody.AngularDamping = m_otherAngularDamping; //m_otherRigidBody.LinearDamping = m_otherLinearDamping; m_otherRigidBody.Restitution = m_otherRestitution; m_otherRigidBody.MaxLinearVelocity = m_otherMaxLinearVelocity; m_otherRigidBody.MaxAngularVelocity = m_otherMaxAngularVelocity; if (m_massChange != null) { m_massChange.Remove(); } m_massChange = null; // Clamp output velocity m_otherRigidBody.LinearVelocity = Vector3.Clamp(m_otherRigidBody.LinearVelocity, -2 * Vector3.One, 2 * Vector3.One); m_otherRigidBody.AngularVelocity = Vector3.Clamp(m_otherRigidBody.AngularVelocity, -Vector3.One * (float)Math.PI, Vector3.One * (float)Math.PI); if (!m_otherRigidBody.IsActive) { m_otherRigidBody.Activate(); } m_otherRigidBody.EnableDeactivation = false; m_otherRigidBody.EnableDeactivation = true; //resets deactivation counter m_otherRigidBody = null; } m_otherEntity.OnClosing -= OtherEntity_OnClosing; m_otherEntity = null; } m_constraintInitialized = false; if (Owner != null) { Owner.ManipulatedEntity = null; } m_state = MyState.NONE; }