protected override bool Attach(MyAttachableTopBlockBase rotor, bool updateGroup = true) { Debug.Assert(rotor != null, "Rotor cannot be null!"); Debug.Assert(m_constraint == null, "Already attached, call detach first!"); if (rotor is MyMotorRotor) { if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled) { m_topBlock = rotor; m_topGrid = m_topBlock.CubeGrid; var rotorBody = m_topGrid.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 as MyMotorRotor).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(m_damping); data.SetSuspensionStrength(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_topBlock.Attach(this); m_isAttached = true; PropagateFriction(m_friction); UpdateIsWorking(); if (m_updateBrakeNeeded) { UpdateBrake(); } if (m_updateFrictionNeeded) { FrictionChanged(); } if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_topGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_topGrid); } return(true); } } return(false); }
protected override bool Attach(MyAttachableTopBlockBase rotor, bool updateGroup = true) { if (rotor is MyMotorRotor) { Debug.Assert(rotor != null, "Rotor cannot be null!"); Debug.Assert(m_constraint == null, "Already attached, call detach first!"); Debug.Assert(m_connectionState.Value.TopBlockId == 0 || m_connectionState.Value.TopBlockId == rotor.EntityId, "m_rotorBlockId must be set prior calling Attach"); if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled) { m_topBlock = rotor; m_topGrid = m_topBlock.CubeGrid; if (m_topGrid.Physics == null) { return(false); } if (CubeGrid.Physics.RigidBody == m_topGrid.Physics.RigidBody) { if (updateGroup && m_welded) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_topGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_topGrid); } m_isAttached = true; return(true); } var rotorBody = m_topGrid.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_topGrid.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_topBlock.Attach(this); if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_topGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_topGrid); m_topGrid.OnPhysicsChanged += cubeGrid_OnPhysicsChanged; } m_isAttached = true; UpdateText(); return(true); } } return(false); }