private void ComputeCollisionPhysics(MyCubeGrid entity1, MyCubeGrid entity2, Vector3D collisionAvg) { var e1Physics = ((IMyCubeGrid)entity1).Physics; var e2Physics = ((IMyCubeGrid)entity2).Physics; var e1IsStatic = e1Physics.IsStatic; var e2IsStatic = e2Physics.IsStatic; float bMass; if (e1IsStatic) { bMass = float.MaxValue * 0.001f; } else { bMass = entity1.GetCurrentMass(); } float sMass; if (e2IsStatic) { sMass = float.MaxValue * 0.001f; } else if (DsSet.Settings.FortifyShield && DsState.State.Enhancer) { sMass = entity2.GetCurrentMass() * 2; } else { sMass = entity2.GetCurrentMass(); } var bCom = e1Physics.CenterOfMassWorld; var bMassRelation = bMass / sMass; var bRelationClamp = MathHelper.Clamp(bMassRelation, 0, 1); var bCollisionCorrection = Vector3D.Lerp(bCom, collisionAvg, bRelationClamp); Vector3 bVelAtPoint; e1Physics.GetVelocityAtPointLocal(ref bCollisionCorrection, out bVelAtPoint); var sCom = e2IsStatic ? DetectionCenter : e2Physics.CenterOfMassWorld; var sMassRelation = sMass / bMass; var sRelationClamp = MathHelper.Clamp(sMassRelation, 0, 1); var sCollisionCorrection = Vector3D.Lerp(sCom, collisionAvg, sRelationClamp); Vector3 sVelAtPoint; e2Physics.GetVelocityAtPointLocal(ref sCollisionCorrection, out sVelAtPoint); var momentum = (bMass * bVelAtPoint) + (sMass * sVelAtPoint); var resultVelocity = momentum / (bMass + sMass); var bDir = (resultVelocity - bVelAtPoint) * bMass; var bForce = Vector3D.Normalize(bCom - collisionAvg); var sDir = (resultVelocity - sVelAtPoint) * sMass; var sforce = Vector3D.Normalize(sCom - collisionAvg); if (!e2IsStatic) { var collisionData = new MyCollisionPhysicsData { Entity1 = entity1, Entity2 = entity2, E1IsStatic = e1IsStatic, E2IsStatic = e2IsStatic, E1IsHeavier = e1IsStatic || bMass > sMass, E2IsHeavier = e2IsStatic || sMass > bMass, Mass1 = bMass, Mass2 = sMass, Com1 = bCom, Com2 = sCom, CollisionCorrection1 = bCollisionCorrection, CollisionCorrection2 = sCollisionCorrection, ImpDirection1 = bDir, ImpDirection2 = sDir, Force1 = bForce, Force2 = sforce, CollisionAvg = collisionAvg, }; var collisionEvent = Session.Instance.CollisionPool.Get(); collisionEvent.Init(collisionData, this); Session.Instance.ThreadEvents.Enqueue(collisionEvent); } else { var altMomentum = (bMass * bVelAtPoint); var altResultVelocity = altMomentum / (bMass + (bMass * 0.5f)); var bDir2 = (altResultVelocity - bVelAtPoint) * bMass; var transformInv = DetectMatrixOutsideInv; var normalMat = MatrixD.Transpose(transformInv); var localNormal = Vector3D.Transform(collisionAvg, transformInv); var surfaceNormal = Vector3D.Normalize(Vector3D.TransformNormal(localNormal, normalMat)); Vector3 velAtPoint; e1Physics.GetVelocityAtPointLocal(ref collisionAvg, out velAtPoint); var bSurfaceDir = -Vector3D.Dot(velAtPoint, surfaceNormal) * surfaceNormal; var collisionData = new MyCollisionPhysicsData { Entity1 = entity1, Mass1 = bMass, Com1 = bCom, CollisionCorrection1 = bCollisionCorrection, ImpDirection1 = bDir2, ImpDirection2 = bSurfaceDir, Force1 = bForce, CollisionAvg = collisionAvg }; var collisionEvent = Session.Instance.StaticCollisionPool.Get(); collisionEvent.Init(collisionData, this); Session.Instance.ThreadEvents.Enqueue(collisionEvent); } }
public static void SmallIntersect(EntIntersectInfo entInfo, ConcurrentQueue <IMySlimBlock> fewDmgBlocks, ConcurrentQueue <IMySlimBlock> destroyedBlocks, ConcurrentQueue <MyAddForceData> force, ConcurrentQueue <MyImpulseData> impulse, MyCubeGrid grid, MatrixD matrix, MatrixD matrixInv, bool damageBlocks = true) { try { var contactPoint = ContactPointOutside(grid, matrix); if (!(Vector3D.Transform(contactPoint, matrixInv).LengthSquared() <= 1)) { return; } var getBlocks = new List <IMySlimBlock>(); (grid as IMyCubeGrid).GetBlocks(getBlocks); var blockPoints = new Vector3D[9]; var collisionAvg = Vector3D.Zero; var c3 = 0; for (int i = 0; i < getBlocks.Count; i++) { var block = getBlocks[i]; if (damageBlocks && block.IsDestroyed) { destroyedBlocks.Enqueue(block); continue; } BoundingBoxD blockBox; block.GetWorldBoundingBox(out blockBox); blockBox.GetCorners(blockPoints); blockPoints[8] = blockBox.Center; for (int j = 8; j > -1; j--) { var point = blockPoints[j]; if (Vector3.Transform(point, matrixInv).LengthSquared() > 1) { continue; } c3++; collisionAvg += point; if (damageBlocks) { fewDmgBlocks.Enqueue(block); } break; } } if (collisionAvg != Vector3D.Zero) { collisionAvg /= c3; entInfo.ContactPoint = collisionAvg; var mass = grid.GetCurrentMass(); var transformInv = matrixInv; var normalMat = MatrixD.Transpose(transformInv); var localNormal = Vector3D.Transform(collisionAvg, transformInv); var surfaceNormal = Vector3D.Normalize(Vector3D.TransformNormal(localNormal, normalMat)); var gridLinearVel = grid.Physics.LinearVelocity; var gridLinearLen = gridLinearVel.Length(); var forceData = new MyAddForceData { MyGrid = grid, Force = (grid.PositionComp.WorldAABB.Center - matrix.Translation) * (mass * gridLinearLen), MaxSpeed = MathHelper.Clamp(gridLinearLen, 10, gridLinearLen * 0.5f) }; var impulseData = new MyImpulseData { MyGrid = grid, Direction = mass * 0.015 * -Vector3D.Dot(gridLinearVel, surfaceNormal) * surfaceNormal, Position = collisionAvg }; force.Enqueue(forceData); impulse.Enqueue(impulseData); entInfo.Damage = mass * 0.5f; } } catch (Exception ex) { Log.Line($"Exception in SmallIntersect: {ex}"); } }
private void CalculateShipCategory() { ShipTypeEnum originalType = m_shipCategory; if (m_shipThrusters == null && (m_shipWheels == null || m_shipWheels.WheelCount <= 0)) { m_shipCategory = ShipTypeEnum.Debris; } else { bool hasController = false; foreach (var block in m_shipGrid.GetFatBlocks()) { if (block is MyShipController) { if (m_shipGrid.MainCockpit == null && m_shipGrid.GridSizeEnum == MyCubeSize.Small) { m_shipSoundSource = block as MyEntity; } hasController = true; break; } } if (hasController) { int shipMass = m_shipGrid.GetCurrentMass(); if (shipMass >= SHIP_CATEGORY_MASS_HUGE) { m_shipCategory = ShipTypeEnum.Huge; } else if (shipMass >= SHIP_CATEGORY_MASS_LARGE) { m_shipCategory = ShipTypeEnum.Large; } else if (shipMass >= SHIP_CATEGORY_MASS_MEDIUM) { m_shipCategory = ShipTypeEnum.Medium; } else if (shipMass >= SHIP_CATEGORY_MASS_SMALL) { m_shipCategory = ShipTypeEnum.Small; } else if (shipMass >= SHIP_CATEGORY_MASS_TINY) { m_shipCategory = ShipTypeEnum.Tiny; } else { m_shipCategory = ShipTypeEnum.Debris; } } else { m_shipCategory = ShipTypeEnum.Debris; } } if (originalType != m_shipCategory) { m_categoryChange = true; if (m_shipCategory == ShipTypeEnum.Debris) { for (int i = 0; i < m_emitters.Length; i++) { if (m_emitters[i].IsPlaying && m_emitters[i].Loop) { if (i == (int)ShipEmitters.WheelsMain || i == (int)ShipEmitters.WheelsSecondary) { m_emitters[i].StopSound(m_shipWheels == null); } else { m_emitters[i].StopSound(m_shipThrusters == null); } } } } else { for (int i = 0; i < m_emitters.Length; i++) { if (m_emitters[i].IsPlaying && m_emitters[i].Loop) { m_emitters[i].StopSound(true); } } } } if (m_shipCategory == ShipTypeEnum.Debris) { SetGridSounds(false); } else { SetGridSounds(true); } }
private void RecreateControls() { Debug.Assert(m_infoPage != null, "Terminal page is null"); if (m_infoPage == null) { return; } if (MyFakes.ENABLE_CENTER_OF_MASS) { var centerBtn = (MyGuiControlCheckbox)m_infoPage.Controls.GetControlByName("CenterBtn"); centerBtn.IsChecked = MyCubeGrid.ShowCenterOfMass; centerBtn.IsCheckedChanged = centerBtn_IsCheckedChanged; var pivotBtn = (MyGuiControlCheckbox)m_infoPage.Controls.GetControlByName("PivotBtn"); pivotBtn.IsChecked = MyCubeGrid.ShowGridPivot; pivotBtn.IsCheckedChanged = pivotBtn_IsCheckedChanged; } var showGravityGizmoBtn = (MyGuiControlCheckbox)m_infoPage.Controls.GetControlByName("ShowGravityGizmo"); showGravityGizmoBtn.IsChecked = MyCubeGrid.ShowGravityGizmos; showGravityGizmoBtn.IsCheckedChanged = showGravityGizmos_IsCheckedChanged; var showSenzorGizmoBtn = (MyGuiControlCheckbox)m_infoPage.Controls.GetControlByName("ShowSenzorGizmo"); showSenzorGizmoBtn.IsChecked = MyCubeGrid.ShowSenzorGizmos; showSenzorGizmoBtn.IsCheckedChanged = showSenzorGizmos_IsCheckedChanged; var showAntenaGizmoBtn = (MyGuiControlCheckbox)m_infoPage.Controls.GetControlByName("ShowAntenaGizmo"); showAntenaGizmoBtn.IsChecked = MyCubeGrid.ShowAntennaGizmos; showAntenaGizmoBtn.IsCheckedChanged = showAntenaGizmos_IsCheckedChanged; var friendAntennaRange = (MyGuiControlSlider)m_infoPage.Controls.GetControlByName("FriendAntennaRange"); friendAntennaRange.Value = MyHudMarkerRender.FriendAntennaRange; friendAntennaRange.ValueChanged += (MyGuiControlSlider s) => { MyHudMarkerRender.FriendAntennaRange = s.Value; }; var enemyAntennaRange = (MyGuiControlSlider)m_infoPage.Controls.GetControlByName("EnemyAntennaRange"); enemyAntennaRange.Value = MyHudMarkerRender.EnemyAntennaRange; enemyAntennaRange.ValueChanged += (MyGuiControlSlider s) => { MyHudMarkerRender.EnemyAntennaRange = s.Value; }; var ownedAntennaRange = (MyGuiControlSlider)m_infoPage.Controls.GetControlByName("OwnedAntennaRange"); ownedAntennaRange.Value = MyHudMarkerRender.OwnerAntennaRange; ownedAntennaRange.ValueChanged += (MyGuiControlSlider s) => { MyHudMarkerRender.OwnerAntennaRange = s.Value; }; if (MyFakes.ENABLE_TERMINAL_PROPERTIES) { var renameShipLabel = (MyGuiControlLabel)m_infoPage.Controls.GetControlByName("RenameShipLabel"); var renameShipBtn = (MyGuiControlButton)m_infoPage.Controls.GetControlByName("RenameShipButton"); var renameShipText = (MyGuiControlTextbox)m_infoPage.Controls.GetControlByName("RenameShipText"); if (renameShipText != null && m_grid != null) { renameShipText.Text = m_grid.DisplayName; } var showRenameShip = IsPlayerOwner(m_grid); renameShipLabel.Visible = showRenameShip; renameShipBtn.Visible = showRenameShip; renameShipText.Visible = showRenameShip; } var convertBtn = (MyGuiControlButton)m_infoPage.Controls.GetControlByName("ConvertBtn"); MyGuiControlList list = (MyGuiControlList)m_infoPage.Controls.GetControlByName("InfoList"); list.Controls.Clear(); if (m_grid == null || m_grid.Physics == null) { convertBtn.Enabled = false; MyGuiControlLabel noShip = new MyGuiControlLabel(text: MyTexts.GetString(MySpaceTexts.ScreenTerminalError_ShipNotConnected), font: MyFontEnum.Red); list.Controls.Add(noShip); return; } if (!m_grid.IsStatic || m_grid.MarkedForClose) { convertBtn.Enabled = false; } if (!m_grid.BigOwners.Contains(MySession.Static.LocalPlayerId)) { convertBtn.Enabled = false; } var setDestructibleBlocks = (MyGuiControlCheckbox)m_infoPage.Controls.GetControlByName("SetDestructibleBlocks"); setDestructibleBlocks.IsChecked = m_grid.DestructibleBlocks; setDestructibleBlocks.Visible = MySession.Static.Settings.ScenarioEditMode || MySession.Static.IsScenario; setDestructibleBlocks.Enabled = MySession.Static.Settings.ScenarioEditMode; setDestructibleBlocks.IsCheckedChanged = setDestructibleBlocksBtn_IsCheckedChanged; int gravityCounter = 0; if (m_grid.BlocksCounters.ContainsKey(typeof(MyObjectBuilder_GravityGenerator))) { gravityCounter = m_grid.BlocksCounters[typeof(MyObjectBuilder_GravityGenerator)]; } int massCounter = 0; if (m_grid.BlocksCounters.ContainsKey(typeof(MyObjectBuilder_VirtualMass))) { massCounter = m_grid.BlocksCounters[typeof(MyObjectBuilder_VirtualMass)]; } int lightCounter = 0; if (m_grid.BlocksCounters.ContainsKey(typeof(MyObjectBuilder_InteriorLight))) { lightCounter = m_grid.BlocksCounters[typeof(MyObjectBuilder_InteriorLight)]; } var conveyorCounter = 0; foreach (var key in m_grid.BlocksCounters.Keys) { Type blockType = MyCubeBlockFactory.GetProducedType(key); if (typeof(IMyConveyorSegmentBlock).IsAssignableFrom(blockType) || typeof(IMyConveyorEndpointBlock).IsAssignableFrom(blockType)) { conveyorCounter += m_grid.BlocksCounters[key]; } } int polygonCounter = 0; foreach (var block in m_grid.GetBlocks()) { if (block.FatBlock != null) { polygonCounter += block.FatBlock.Model.GetTrianglesCount(); } } foreach (var cell in m_grid.RenderData.Cells.Values) { foreach (var part in cell.CubeParts) { polygonCounter += part.Model.GetTrianglesCount(); } } int thrustCount = 0; var thrustComp = m_grid.Components.Get <MyEntityThrustComponent>(); if (thrustComp != null) { thrustCount = thrustComp.ThrustCount; } MyGuiControlLabel thrustCountLabel = new MyGuiControlLabel(text: new StringBuilder().AppendStringBuilder(MyTexts.Get(MySpaceTexts.TerminalTab_Info_Thrusters)).AppendInt32(thrustCount).ToString()); MyGuiControlLabel polygonCount = new MyGuiControlLabel(text: new StringBuilder().AppendStringBuilder(MyTexts.Get(MySpaceTexts.TerminalTab_Info_Triangles)).AppendInt32(polygonCounter).ToString()); polygonCount.SetToolTip(MySpaceTexts.TerminalTab_Info_TrianglesTooltip); MyGuiControlLabel cubeCount = new MyGuiControlLabel(text: new StringBuilder().AppendStringBuilder(MyTexts.Get(MySpaceTexts.TerminalTab_Info_Blocks)).AppendInt32(m_grid.GetBlocks().Count).ToString()); cubeCount.SetToolTip(MySpaceTexts.TerminalTab_Info_BlocksTooltip); MyGuiControlLabel blockCount = new MyGuiControlLabel(text: new StringBuilder().AppendStringBuilder(MyTexts.Get(MySpaceTexts.TerminalTab_Info_NonArmor)).AppendInt32(m_grid.Hierarchy.Children.Count).ToString()); MyGuiControlLabel lightCount = new MyGuiControlLabel(text: new StringBuilder().Clear().AppendStringBuilder(MyTexts.Get(MySpaceTexts.TerminalTab_Info_Lights)).AppendInt32(lightCounter).ToString()); MyGuiControlLabel reflectorCount = new MyGuiControlLabel(text: new StringBuilder().AppendStringBuilder(MyTexts.Get(MySpaceTexts.TerminalTab_Info_Reflectors)).AppendInt32(m_grid.GridSystems.ReflectorLightSystem.ReflectorCount).ToString()); //MyGuiControlLabel wheelCount = new MyGuiControlLabel(text: new StringBuilder().AppendStringBuilder(MyTexts.Get(MySpaceTexts.TerminalTab_Info_Rotors)).AppendInt32(m_grid.WheelSystem.WheelCount)); MyGuiControlLabel gravityCount = new MyGuiControlLabel(text: new StringBuilder().AppendStringBuilder(MyTexts.Get(MySpaceTexts.TerminalTab_Info_GravGens)).AppendInt32(gravityCounter).ToString()); MyGuiControlLabel massCount = new MyGuiControlLabel(text: new StringBuilder().AppendStringBuilder(MyTexts.Get(MySpaceTexts.TerminalTab_Info_VirtualMass)).AppendInt32(massCounter).ToString()); MyGuiControlLabel conveyorCount = new MyGuiControlLabel(text: new StringBuilder().AppendStringBuilder(MyTexts.Get(MySpaceTexts.TerminalTab_Info_Conveyors)).AppendInt32(conveyorCounter).ToString()); var mainCockpit = m_grid.MainCockpit as MyShipController; MyCharacter pilot = null; if (mainCockpit != null) { pilot = mainCockpit.Pilot; } MyGuiControlLabel gridMass = new MyGuiControlLabel(text: new StringBuilder().AppendStringBuilder(MyTexts.Get(MySpaceTexts.TerminalTab_Info_GridMass)).AppendInt32(m_grid.GetCurrentMass(pilot)).ToString()); list.InitControls(new MyGuiControlBase[] { cubeCount, blockCount, conveyorCount, thrustCountLabel, lightCount, reflectorCount, gravityCount, massCount, polygonCount, gridMass }); }
private void CalculateShipCategory() { bool originalDebris = m_isDebris; MyDefinitionId originalType = m_shipCategory; if (m_shipThrusters == null && (m_shipWheels == null || m_shipWheels.WheelCount <= 0)) { m_isDebris = true; } else if (m_shipGrid.GridSystems.GyroSystem.GyroCount == 0) { m_isDebris = true; } else { bool hasController = false; foreach (var block in m_shipGrid.GetFatBlocks()) { if (block is MyShipController) { if (m_shipGrid.MainCockpit == null && m_shipGrid.GridSizeEnum == MyCubeSize.Small) { m_shipSoundSource = block as MyEntity; } hasController = true; break; } } if (hasController) { int shipMass = m_shipGrid.GetCurrentMass(); float bestWeight = float.MinValue; foreach (var group in m_categories.Values) { if (group.MinWeight < shipMass && ((group.AllowSmallGrid && m_shipGrid.GridSizeEnum == MyCubeSize.Small) || (group.AllowLargeGrid && m_shipGrid.GridSizeEnum == MyCubeSize.Large))) { if (bestWeight == float.MinValue || group.MinWeight > bestWeight) { bestWeight = group.MinWeight; m_shipCategory = group.Id; m_groupData = group; } } } if (bestWeight == float.MinValue) { m_isDebris = true; } else { m_isDebris = false; } } else { m_isDebris = true; } } if (m_groupData == null) { m_isDebris = true; } if (originalType != m_shipCategory || m_isDebris != originalDebris) { m_categoryChange = true; if (m_isDebris) { for (int i = 0; i < m_emitters.Length; i++) { if (m_emitters[i].IsPlaying && m_emitters[i].Loop) { if (i == (int)ShipEmitters.WheelsMain || i == (int)ShipEmitters.WheelsSecondary) { m_emitters[i].StopSound(m_shipWheels == null); } else { m_emitters[i].StopSound(m_shipThrusters == null); } } } } else { for (int i = 0; i < m_emitters.Length; i++) { if (m_emitters[i].IsPlaying && m_emitters[i].Loop) { m_emitters[i].StopSound(true); } } } } if (m_isDebris) { SetGridSounds(false); } else { SetGridSounds(true); } }
private void ComputeVoxelPhysics(MyEntity entity1, MyCubeGrid entity2, Vector3D collisionAvg) { var e2Physics = ((IMyCubeGrid)entity2).Physics; var e2IsStatic = e2Physics.IsStatic; float bMass; if (e2IsStatic) { bMass = float.MaxValue * 0.001f; } else { bMass = entity2.GetCurrentMass(); } var sMass = float.MaxValue * 0.001f; var bCom = e2Physics.CenterOfMassWorld; var bMassRelation = bMass / sMass; var bRelationClamp = MathHelper.Clamp(bMassRelation, 0, 1); var bCollisionCorrection = Vector3D.Lerp(bCom, collisionAvg, bRelationClamp); Vector3 bVelAtPoint; e2Physics.GetVelocityAtPointLocal(ref bCollisionCorrection, out bVelAtPoint); var momentum = (bMass * bVelAtPoint) + (sMass * 0); var resultVelocity = momentum / (bMass + sMass); var bDir = (resultVelocity - bVelAtPoint) * bMass; var bForce = Vector3D.Normalize(bCom - collisionAvg); var collisionData = new MyCollisionPhysicsData { Entity1 = entity1, Entity2 = entity2, E1IsStatic = true, E2IsStatic = false, E1IsHeavier = true, E2IsHeavier = false, Mass1 = sMass, Mass2 = bMass, Com1 = Vector3D.Zero, Com2 = bCom, CollisionCorrection1 = Vector3D.Zero, CollisionCorrection2 = bCollisionCorrection, ImpDirection1 = Vector3D.Zero, ImpDirection2 = bDir, ImpPosition1 = Vector3D.Zero, ImpPosition2 = bCollisionCorrection, Force1 = Vector3D.Zero, Force2 = bForce, ForcePos1 = null, ForcePos2 = null, ForceTorque1 = null, ForceTorque2 = null, CollisionAvg = collisionAvg, Immediate = false }; var collisionEvent = Session.Instance.VoxelCollisionPhysicsPool.Get(); collisionEvent.Init(collisionData, this); Session.Instance.ThreadEvents.Enqueue(collisionEvent); }