private void ComputeGravityAlignedOrientation(out MatrixD resultOrientationStorage) { // Y axis bool inGravityField = true; Vector3D upVector = -MyGravityProviderSystem.CalculateTotalGravityInPoint(Position); if (upVector.LengthSquared() < MyMathConstants.EPSILON) { upVector = m_lastUpVec; m_lastOrientationWeight = 1; inGravityField = false; } else { m_lastUpVec = upVector; } upVector.Normalize(); // X axis Vector3D rightVector = m_lastRightVec - Vector3D.Dot(m_lastRightVec, upVector) * upVector; if (rightVector.LengthSquared() < MyMathConstants.EPSILON) { rightVector = m_orientation.Right - Vector3D.Dot(m_orientation.Right, upVector) * upVector; // backup behavior if singularity happens if (rightVector.LengthSquared() < MyMathConstants.EPSILON) { rightVector = m_orientation.Forward - Vector3D.Dot(m_orientation.Forward, upVector) * upVector; } // backup behavior if singularity happens } rightVector.Normalize(); m_lastRightVec = rightVector; // Z axis Vector3D forwardVector; Vector3D.Cross(ref upVector, ref rightVector, out forwardVector); resultOrientationStorage = MatrixD.Identity; resultOrientationStorage.Right = rightVector; resultOrientationStorage.Up = upVector; resultOrientationStorage.Forward = forwardVector; resultOrientationStorage = MatrixD.CreateFromAxisAngle(Vector3D.Right, m_pitch) * resultOrientationStorage * MatrixD.CreateFromAxisAngle(upVector, m_yaw); upVector = resultOrientationStorage.Up; rightVector = resultOrientationStorage.Right; resultOrientationStorage.Right = Math.Cos(m_roll) * rightVector + Math.Sin(m_roll) * upVector; resultOrientationStorage.Up = -Math.Sin(m_roll) * rightVector + Math.Cos(m_roll) * upVector; if (inGravityField && m_lastOrientationWeight > 0) { m_lastOrientationWeight = Math.Max(0, m_lastOrientationWeight - MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); resultOrientationStorage = MatrixD.Slerp(resultOrientationStorage, m_lastOrientation, MathHelper.SmoothStepStable(m_lastOrientationWeight)); } if (!inGravityField) { m_lastOrientation = resultOrientationStorage; } }
private Vector3D WorldPositionToLocalNavmeshPosition(Vector3D position, float heightIncrease) { Vector3D v = -Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(this.Center)); MatrixD matrix = MatrixD.CreateFromQuaternion(Quaternion.Inverse(Quaternion.CreateFromForwardUp((Vector3)Vector3D.CalculatePerpendicularVector(v), (Vector3)v))); return(Vector3D.Transform((position - this.Center) + (heightIncrease * v), matrix)); }
public override void UpdateBeforeSimulation() { //if (MyFakes.ENABLE_RAGDOLL_DEBUG) Debug.WriteLine("RagdollComponent.UpdateBeforeSimulation"); base.UpdateBeforeSimulation(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Update Ragdoll"); UpdateRagdoll(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); // TODO: This should be changed so the ragdoll gets registered in the generators, now for SE, apply gravity explictly // Apply Gravity on Ragdoll // OM: This should be called only in SE, in ME this is handled by world! if (Character.Physics != null && Character.Physics.Ragdoll != null && Character.Physics.Ragdoll.InWorld && (!Character.Physics.Ragdoll.IsKeyframed || RagdollMapper.IsPartiallySimulated) && (IsRagdollMoving || m_gravityTimer > 0)) { Vector3 gravity = MyGravityProviderSystem.CalculateTotalGravityInPoint(Character.PositionComp.WorldAABB.Center) + Character.GetPhysicsBody().HavokWorld.Gravity *MyPerGameSettings.CharacterGravityMultiplier; Character.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, gravity * (MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(Character.Definition.Mass) : Character.Definition.Mass), null, null); m_gravityTimer = IsRagdollMoving ? GRAVITY_DELAY : m_gravityTimer - 1; } if (Character.Physics != null && Character.Physics.Ragdoll != null && IsRagdollMoving) { m_lastPosition = Character.Physics.Ragdoll.WorldMatrix.Translation; } }
public void Update() { ProfilerShort.Begin("MyBotNavigation.Update"); AssertIsValid(); if (m_entity == null) { return; } ProfilerShort.Begin("UpdateMatrices"); UpdateMatrices(); ProfilerShort.End(); m_gravityDirection = MyGravityProviderSystem.CalculateTotalGravityInPoint(m_entity.PositionComp.WorldMatrix.Translation); if (!Vector3.IsZero(m_gravityDirection, 0.01f)) { m_gravityDirection = Vector3D.Normalize(m_gravityDirection); } if (MyPerGameSettings.NavmeshPresumesDownwardGravity) { m_upVector = Vector3.Up; } else { m_upVector = -m_gravityDirection; } if (!m_speed.IsValid()) { m_forwardVector = PositionAndOrientation.Forward; m_speed = 0.0f; m_rotationSpeedModifier = 1; } ProfilerShort.Begin("Steering update"); foreach (var steering in m_steerings) { ProfilerShort.Begin(steering.GetName()); steering.Update(); ProfilerShort.End(); } ProfilerShort.End(); ProfilerShort.Begin("Aiming"); m_aiming.Update(); ProfilerShort.End(); ProfilerShort.Begin("Steering accumulate correction"); CorrectMovement(m_aiming.RotationHint); ProfilerShort.End(); ProfilerShort.Begin("MoveCharacter"); MoveCharacter(); ProfilerShort.End(); AssertIsValid(); ProfilerShort.End(); }
public void Update(int behaviorTicks) { this.m_stuckDetection.SetCurrentTicks(behaviorTicks); if (this.m_entity != null) { this.UpdateMatrices(); this.m_gravityDirection = MyGravityProviderSystem.CalculateTotalGravityInPoint(this.m_entity.PositionComp.WorldMatrix.Translation); if (!Vector3.IsZero(this.m_gravityDirection, 0.01f)) { this.m_gravityDirection = (Vector3)Vector3D.Normalize(this.m_gravityDirection); } this.m_upVector = !MyPerGameSettings.NavmeshPresumesDownwardGravity ? -this.m_gravityDirection : Vector3.Up; if (!this.m_speed.IsValid()) { this.m_forwardVector = (Vector3)this.PositionAndOrientation.Forward; this.m_speed = 0f; this.m_rotationSpeedModifier = 1f; } using (List <MySteeringBase> .Enumerator enumerator = this.m_steerings.GetEnumerator()) { while (enumerator.MoveNext()) { enumerator.Current.Update(); } } this.m_aiming.Update(); this.CorrectMovement(this.m_aiming.RotationHint); if (this.m_speed < 0.1f) { this.m_speed = 0f; } this.MoveCharacter(); } }
private unsafe void DebugDrawInternal() { if (this.m_navmeshOBBs != null) { this.m_navmeshOBBs.DebugDraw(); } if (this.DrawNavmesh) { this.DrawPersistentDebugNavmesh(false); } if (this.DrawPhysicalMesh) { this.DebugDrawPhysicalShapes(); } Vector3D position = MySession.Static.ControlledEntity.ControllerInfo.Controller.Player.GetPosition(); double * numPtr1 = (double *)ref position.Y; numPtr1[0] += 2.4000000953674316; MyRenderProxy.DebugDrawText3D(position, $"X: {Math.Round(position.X, 2)} Y: {Math.Round(position.Y, 2)} Z: {Math.Round(position.Z, 2)}", Color.Red, 1f, true, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP, -1, false); if (this.m_lastGroundMeshQuery.Count > 0) { MyRenderProxy.DebugDrawSphere(this.m_lastGroundMeshQuery[0].Center, 1f, Color.Yellow, 1f, true, false, true, false); foreach (BoundingBoxD xd2 in this.m_lastGroundMeshQuery) { MyRenderProxy.DebugDrawOBB(xd2.Matrix, Color.Yellow, 0f, true, false, true, false); } if (this.m_navmeshOBBs != null) { float num; float num2; foreach (MyNavmeshOBBs.OBBCoords coords in this.m_debugDrawIntersectedOBBs) { MyRenderProxy.DebugDrawOBB(new MyOrientedBoundingBoxD(coords.OBB.Center, new Vector3(coords.OBB.HalfExtent.X, coords.OBB.HalfExtent.Y / 2.0, coords.OBB.HalfExtent.Z), coords.OBB.Orientation), Color.White, 0f, true, false, false); } MyOrientedBoundingBoxD obb = this.m_navmeshOBBs.GetOBB(0, 0).Value; MyPlanet planet = this.GetPlanet(obb.Center); Vector3 *points = (Vector3 *)stackalloc byte[(((IntPtr)4) * sizeof(Vector3))]; GetMiddleOBBPoints(obb, ref points); planet.Provider.Shape.GetBounds(points, 4, out num, out num2); if (num.IsValid() && num2.IsValid()) { Vector3D vectord2 = obb.Orientation.Up * num2; MyRenderProxy.DebugDrawSphere(obb.Orientation.Up * num, 1f, Color.Blue, 0f, true, false, true, false); MyRenderProxy.DebugDrawSphere(vectord2, 1f, Color.Blue, 0f, true, false, true, false); } DrawTerrainLimits(planet, obb); } MyRenderProxy.DebugDrawSphere(this.m_meshCenter, 2f, Color.Red, 0f, true, false, true, false); } if ((this.m_polygons != null) && (this.m_pathfindingDebugTarget != null)) { Vector3D vectord3 = -Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(this.m_pathfindingDebugTarget.Value)); MyRenderProxy.DebugDrawSphere(this.m_pathfindingDebugTarget.Value + (1.5 * vectord3), 0.2f, Color.Red, 0f, true, false, true, false); } }
public MyNavigationInputMesh(MyRDPathfinding rdPathfinding, MyPlanet planet, Vector3D center) { this.m_rdPathfinding = rdPathfinding; this.m_planet = planet; this.m_center = center; Vector3 v = (Vector3) - Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(this.m_center)); Vector3 forward = Vector3.CalculatePerpendicularVector(v); this.rdWorldQuaternion = Quaternion.Inverse(Quaternion.CreateFromForwardUp(forward, v)); }
private Vector3D LocalPositionToWorldPosition(Vector3D position) { Vector3D worldPoint = position; if (this.m_navmeshOBBs != null) { worldPoint = this.Center; } Vector3D vectord2 = -Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(worldPoint)); return(this.LocalNavmeshPositionToWorldPosition(this.m_navmeshOBBs.CenterOBB, position, worldPoint, (Vector3D)(-this.m_heightCoordTransformationIncrease * vectord2))); }
private void ComputeGravityAlignedOrientation(out MatrixD resultOrientationStorage) { Vector3D vectord3; bool flag = true; Vector3D up = -MyGravityProviderSystem.CalculateTotalGravityInPoint(base.Position); if (up.LengthSquared() >= 9.9999997473787516E-06) { this.m_lastUpVec = up; } else { up = this.m_lastUpVec; this.m_lastOrientationWeight = 1f; flag = false; } up.Normalize(); Vector3D right = this.m_lastRightVec - (Vector3D.Dot(this.m_lastRightVec, up) * up); if (right.LengthSquared() < 9.9999997473787516E-06) { right = base.m_orientation.Right - (Vector3D.Dot(base.m_orientation.Right, up) * up); if (right.LengthSquared() < 9.9999997473787516E-06) { right = base.m_orientation.Forward - (Vector3D.Dot(base.m_orientation.Forward, up) * up); } } right.Normalize(); this.m_lastRightVec = right; Vector3D.Cross(ref up, ref right, out vectord3); resultOrientationStorage = MatrixD.Identity; resultOrientationStorage.Right = right; resultOrientationStorage.Up = up; resultOrientationStorage.Forward = vectord3; resultOrientationStorage = (MatrixD.CreateFromAxisAngle(Vector3D.Right, this.m_pitch) * resultOrientationStorage) * MatrixD.CreateFromAxisAngle(up, this.m_yaw); up = resultOrientationStorage.Up; right = resultOrientationStorage.Right; resultOrientationStorage.Right = (Vector3D)((Math.Cos(this.m_roll) * right) + (Math.Sin(this.m_roll) * up)); resultOrientationStorage.Up = (Vector3D)((-Math.Sin(this.m_roll) * right) + (Math.Cos(this.m_roll) * up)); if (flag && (this.m_lastOrientationWeight > 0f)) { this.m_lastOrientationWeight = Math.Max((float)0f, (float)(this.m_lastOrientationWeight - 0.01666667f)); resultOrientationStorage = MatrixD.Slerp(resultOrientationStorage, this.m_lastOrientation, MathHelper.SmoothStepStable(this.m_lastOrientationWeight)); resultOrientationStorage = MatrixD.Orthogonalize(resultOrientationStorage); resultOrientationStorage.Forward = Vector3D.Cross(resultOrientationStorage.Up, resultOrientationStorage.Right); } if (!flag) { this.m_lastOrientation = resultOrientationStorage; } }
private MyNavmeshManager CreateManager(Vector3D center, Vector3D?forwardDirection = new Vector3D?()) { if (forwardDirection == null) { Vector3D v = -Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(center)); forwardDirection = new Vector3D?(Vector3D.CalculatePerpendicularVector(v)); } int tileSize = 0x10; MyNavmeshManager item = new MyNavmeshManager(this, center, forwardDirection.Value, tileSize, 70, 0x19, this.GetRecastOptions(null)) { DrawNavmesh = this.m_drawNavmesh }; this.m_planetManagers[item.Planet].Add(item); return(item); }
public override void UpdateBeforeSimulation100() { base.UpdateBeforeSimulation100(); if (m_soundEmitter != null) { m_soundEmitter.Update(); if (m_soundEmitter.IsPlaying && (DateTime.UtcNow - m_soundStart).TotalSeconds >= 15f)//stop falling sound if it playing too long { m_fallSoundShouldPlay.Value = false; } } var grav = MyGravityProviderSystem.CalculateTotalGravityInPoint(PositionComp.GetPosition()); Physics.RigidBody.Gravity = grav; }
public void DebugDraw() { MatrixD viewMatrix = MySector.MainCamera.ViewMatrix; Vector3D?nullable = null; foreach (MyHighLevelPrimitive local1 in this.m_pathNodes) { Vector3D down = MyGravityProviderSystem.CalculateTotalGravityInPoint(local1.WorldPosition); if (Vector3D.IsZero(down, 0.001)) { down = Vector3D.Down; } down.Normalize(); MyHighLevelPrimitive local2 = local1; Vector3D position = local2.WorldPosition + (down * -10.0); MyRenderProxy.DebugDrawSphere(position, 1f, Color.IndianRed, 1f, false, false, true, false); MyRenderProxy.DebugDrawLine3D(local2.WorldPosition, position, Color.IndianRed, Color.IndianRed, false, false); if (nullable != null) { MyRenderProxy.DebugDrawLine3D(position, nullable.Value, Color.IndianRed, Color.IndianRed, false, false); } nullable = new Vector3D?(position); } MyRenderProxy.DebugDrawSphere(this.m_startPoint, 0.5f, Color.HotPink, 1f, false, false, true, false); if (this.m_goal != null) { this.m_goal.DebugDraw(); } if (MyFakes.DEBUG_DRAW_FOUND_PATH) { Vector3D?nullable2 = null; for (int i = 0; i < this.m_expandedPath.Count; i++) { Vector3D position = new Vector3D(this.m_expandedPath[i]); float w = (float)this.m_expandedPath[i].W; Color color = (i == (this.m_expandedPath.Count - 1)) ? Color.OrangeRed : Color.Orange; MyRenderProxy.DebugDrawPoint(position, color, false, false); MyRenderProxy.DebugDrawText3D(position + (viewMatrix.Right * 0.10000000149011612), w.ToString(), color, 0.7f, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP, -1, false); if (nullable2 != null) { MyRenderProxy.DebugDrawLine3D(nullable2.Value, position, Color.Pink, Color.Pink, false, false); } nullable2 = new Vector3D?(position); } } }
private Vector3D WorldPositionToLocalNavmeshPosition(Vector3D position, float heightIncrease) { MyOrientedBoundingBoxD?oBB = this.m_navmeshOBBs.GetOBB(position); if (oBB != null) { MyOrientedBoundingBoxD local1 = oBB.Value; } else { Vector3D meshCenter = this.m_meshCenter; } Vector3D v = -Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(this.m_meshCenter)); MatrixD matrix = MatrixD.CreateFromQuaternion(Quaternion.Inverse(Quaternion.CreateFromForwardUp((Vector3)Vector3D.CalculatePerpendicularVector(v), (Vector3)v))); return(Vector3D.Transform((position - this.m_meshCenter) + (heightIncrease * v), matrix)); }
public override void UpdateBeforeSimulation() { //if (MyFakes.ENABLE_RAGDOLL_DEBUG) Debug.WriteLine("RagdollComponent.UpdateBeforeSimulation"); base.UpdateBeforeSimulation(); // TODO: This should be changed so the ragdoll gets registered in the generators, now for SE, apply gravity explictly // Apply Gravity on Ragdoll // OM: This should be called only in SE, in ME this is handled by world! if (Character.Physics.Ragdoll != null && Character.Physics.Ragdoll.InWorld && (!Character.Physics.Ragdoll.IsKeyframed || RagdollMapper.IsPartiallySimulated) && (MyPerGameSettings.Game == GameEnum.SE_GAME)) { Vector3 gravity = MyGravityProviderSystem.CalculateTotalGravityInPoint(Character.PositionComp.WorldAABB.Center) + Character.Physics.HavokWorld.Gravity * MyCharacter.CHARACTER_GRAVITY_MULTIPLIER; Character.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_FORCE, gravity * (MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(Character.Definition.Mass) : Character.Definition.Mass), null, null); } VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Update Ragdoll"); UpdateRagdoll(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); }
public override void UpdateOnceBeforeFrame() { base.UpdateOnceBeforeFrame(); Physics.Enabled = true; Physics.RigidBody.Activate(); Physics.RigidBody.ContactPointCallbackDelay = 0; Physics.RigidBody.ContactSoundCallbackEnabled = true; //return; if (InitialHit != null) { Physics.ApplyImpulse(InitialHit.Impulse, Physics.CenterOfMassWorld); MyPhysics.FractureImpactDetails fid = new Sandbox.Engine.Physics.MyPhysics.FractureImpactDetails(); fid.Entity = this; fid.World = Physics.HavokWorld; fid.ContactInWorld = InitialHit.Position; HkdFractureImpactDetails details = HkdFractureImpactDetails.Create(); details.SetBreakingBody(Physics.RigidBody); details.SetContactPoint(Physics.WorldToCluster(InitialHit.Position)); details.SetDestructionRadius(0.05f); details.SetBreakingImpulse(30000); details.SetParticleVelocity(InitialHit.Impulse); details.SetParticlePosition(Physics.WorldToCluster(InitialHit.Position)); details.SetParticleMass(500); fid.Details = details; MyPhysics.EnqueueDestruction(fid); } var grav = MyGravityProviderSystem.CalculateTotalGravityInPoint(PositionComp.GetPosition()); Physics.RigidBody.Gravity = grav; }
private bool SpawnDrone(MyRadioAntenna antenna, long ownerId, Vector3D position, MySpawnGroupDefinition spawnGroup, Vector3?spawnUp = null, Vector3?spawnForward = null) { long antennaEntityId = antenna.EntityId; Vector3D antennaPos = antenna.PositionComp.GetPosition(); Vector3D upVector; var planet = MyGamePruningStructure.GetClosestPlanet(position); if (planet != null) { if (!MyGravityProviderSystem.IsPositionInNaturalGravity(antennaPos)) { MySandboxGame.Log.WriteLine("Couldn't spawn drone; antenna is not in natural gravity but spawn location is."); return(false); } planet.CorrectSpawnLocation(ref position, spawnGroup.SpawnRadius * 2.0); upVector = position - planet.PositionComp.GetPosition(); upVector.Normalize(); } else { var totalGravityInPoint = MyGravityProviderSystem.CalculateTotalGravityInPoint(position); if (totalGravityInPoint != Vector3.Zero) { upVector = -totalGravityInPoint; upVector.Normalize(); } else if (spawnUp != null) { upVector = spawnUp.Value; } else { upVector = MyUtils.GetRandomVector3Normalized(); } } Vector3D direction = MyUtils.GetRandomPerpendicularVector(ref upVector); if (spawnForward != null) { // Align forward to up vector. Vector3 forward = spawnForward.Value; if (Math.Abs(Vector3.Dot(forward, upVector)) >= 0.98f) { forward = Vector3.CalculatePerpendicularVector(upVector); } else { Vector3 right = Vector3.Cross(forward, upVector); right.Normalize(); forward = Vector3.Cross(upVector, right); forward.Normalize(); } direction = forward; } MatrixD originMatrix = MatrixD.CreateWorld(position, direction, upVector); foreach (var shipPrefab in spawnGroup.Prefabs) { Vector3D shipPosition = Vector3D.Transform((Vector3D)shipPrefab.Position, originMatrix); List <MyCubeGrid> tmpGridList = new List <MyCubeGrid>(); Stack <Action> callback = new Stack <Action>(); callback.Push(delegate() { ChangeDroneOwnership(tmpGridList, ownerId, antennaEntityId); }); MyPrefabManager.Static.SpawnPrefab( resultList: tmpGridList, prefabName: shipPrefab.SubtypeId, position: shipPosition, forward: direction, up: upVector, initialLinearVelocity: default(Vector3), beaconName: null, spawningOptions: VRage.Game.ModAPI.SpawningOptions.None, ownerId: ownerId, updateSync: true, callbacks: callback); } return(true); }
private bool CalculateComplete() { if (!Definition.RequiredSupport.HasValue) { return(true); } if (_shapeDirty) { CalculateShape(); } var edge = _bendy.Edges.FirstOrDefault(); var curve = edge?.Curve; if (curve == null) { return(true); } var shape = Definition.RequiredSupport.Value; var sphere = new BoundingSphereD(Vector3D.Transform(_localBox.Center, Entity.PositionComp.WorldMatrix), _localBox.HalfExtents.Length()); var supported = 0; var total = 0; var entities = MyEntities.GetTopMostEntitiesInSphere(ref sphere); using (entities.GetClearToken()) { var gravity = MyGravityProviderSystem.CalculateTotalGravityInPoint(Entity.GetPosition()); gravity.Normalize(); for (var i = 0; i < shape.Segments; i++) { var t = (i + 0.5f) / shape.Segments; var pos = curve.Sample(t); pos += gravity; var aabb = new BoundingBoxD(pos - 0.5f, pos + 0.5f); var found = false; foreach (var e in entities) { var vox = e as MyVoxelBase; var grid = e.Components.Get <MyGridDataComponent>(); if (vox != null) { Vector3I vc; var test = pos; MyVoxelCoordSystems.WorldPositionToVoxelCoord(vox.PositionLeftBottomCorner, ref test, out vc); _voxelStorage.Resize(Vector3I.One); vox.Storage.ReadRange(_voxelStorage, MyStorageDataTypeFlags.Content, 0, in vc, in vc); found |= _voxelStorage.Get(MyStorageDataTypeEnum.Content, ref Vector3I.Zero) > 0; } else if (grid != null) { found |= grid.AnyBlocksInAABB(aabb); } if (found) { break; } } if (found) { supported++; } total++; } } return(supported >= 0.8 * total); }
public Vector3D GetTotalGravity() { return(MyGravityProviderSystem.CalculateTotalGravityInPoint(WorldMatrix.Translation)); }
public override bool HandleRespawnRequest(bool joinGame, bool newIdentity, long medicalRoomId, string respawnShipId, MyPlayer.PlayerId playerId, Vector3D?spawnPosition, VRage.ObjectBuilders.SerializableDefinitionId?botDefinitionId) { MyPlayer player = Sync.Players.GetPlayerById(playerId); bool spawnAsNewPlayer = newIdentity || player == null; Debug.Assert(player == null || player.Identity != null, "Respawning player has no identity!"); if (!MySessionComponentMissionTriggers.CanRespawn(playerId)) { return(false); } Vector3D currentPosition = Vector3D.Zero; if (player != null && player.Character != null) { currentPosition = player.Character.PositionComp.GetPosition(); } if (TryFindCryoChamberCharacter(player)) { //Player found in chamber; return(true); } MyBotDefinition botDefinition = null; if (botDefinitionId != null) { MyDefinitionManager.Static.TryGetBotDefinition((MyDefinitionId)botDefinitionId, out botDefinition); } if (!spawnAsNewPlayer) { if (respawnShipId != null) { SpawnAtShip(player, respawnShipId, botDefinition); return(true); } if (spawnPosition.HasValue) { Vector3D gravity = MyGravityProviderSystem.CalculateTotalGravityInPoint(spawnPosition.Value); if (Vector3D.IsZero(gravity)) { gravity = Vector3D.Down; } else { gravity.Normalize(); } Vector3D perpendicular; gravity.CalculatePerpendicularVector(out perpendicular); player.SpawnAt(MatrixD.CreateWorld(spawnPosition.Value, perpendicular, -gravity), Vector3.Zero, null, botDefinition, true); return(true); } // Find respawn block to spawn at MyRespawnComponent foundRespawn = null; if (medicalRoomId == 0 || !MyFakes.SHOW_FACTIONS_GUI) { List <MyRespawnComponent> respawns = null; var nearestRespawn = GetNearestRespawn(currentPosition, out respawns, MySession.Static.CreativeMode ? (long?)null : player.Identity.IdentityId); if (joinGame && respawns.Count > 0) { foundRespawn = respawns[MyRandom.Instance.Next(0, respawns.Count)]; } } else { foundRespawn = FindRespawnById(medicalRoomId, player); if (foundRespawn == null) { return(false); } } // If spawning in respawn block fails, we will spawn as a new player if (foundRespawn != null) { SpawnInRespawn(player, foundRespawn, botDefinition); } else { spawnAsNewPlayer = true; } } if (spawnAsNewPlayer) { bool resetIdentity = false; if (MySession.Static.Settings.PermanentDeath.Value) { var oldIdentity = Sync.Players.TryGetPlayerIdentity(playerId); resetIdentity = oldIdentity.FirstSpawnDone; } if (player == null) { var identity = Sync.Players.CreateNewIdentity(player.DisplayName); player = Sync.Players.CreateNewPlayer(identity, playerId, player.DisplayName); resetIdentity = false; } if (MySession.Static.CreativeMode) { Vector3D?correctedPos = MyEntities.FindFreePlace(currentPosition, 2, 200); if (correctedPos.HasValue) { currentPosition = correctedPos.Value; } player.SpawnAt(Matrix.CreateTranslation(currentPosition), Vector3.Zero, null, botDefinition); } else { SpawnAsNewPlayer(player, currentPosition, respawnShipId, resetIdentity, botDefinition); } } return(true); }
public override void UpdateBeforeSimulation() { bool isDead; base.UpdateBeforeSimulation(); this.UpdateRagdoll(); if (base.Character.Physics == null) { goto TR_0004; } else if (base.Character.Physics.Ragdoll == null) { goto TR_0004; } else if (!base.Character.Physics.Ragdoll.InWorld) { goto TR_0004; } else { if (base.Character.Physics.Ragdoll.IsKeyframed && !this.RagdollMapper.IsPartiallySimulated) { goto TR_0004; } if (this.IsRagdollMoving || (this.m_gravityTimer > 0)) { Vector3 vector = MyGravityProviderSystem.CalculateTotalGravityInPoint(base.Character.PositionComp.WorldAABB.Center) + (base.Character.GetPhysicsBody().HavokWorld.Gravity *MyPerGameSettings.CharacterGravityMultiplier); isDead = base.Character.IsDead; if (isDead) { foreach (HkRigidBody body in base.Character.Physics.Ragdoll.RigidBodies) { if (!body.IsFixedOrKeyframed) { body.ApplyForce(0.01666667f, vector * body.Mass); } } } else { vector *= MyFakes.RAGDOLL_GRAVITY_MULTIPLIER; Vector3.ClampToSphere(ref vector, 500f); foreach (HkRigidBody body2 in base.Character.Physics.Ragdoll.RigidBodies) { if (!body2.IsFixedOrKeyframed) { body2.ApplyForce(0.01666667f, vector); } } } } else { goto TR_0004; } } if (!this.IsRagdollMoving) { this.m_gravityTimer--; } else { this.m_gravityTimer = 300; if (isDead) { this.m_gravityTimer /= 5; } } TR_0004: if (((base.Character.Physics != null) && (base.Character.Physics.Ragdoll != null)) && this.IsRagdollMoving) { this.m_lastPosition = base.Character.Physics.Ragdoll.WorldMatrix.Translation; } }
private unsafe void AddVoxelMesh(MyVoxelBase voxelBase, IMyStorage storage, Dictionary <Vector3I, MyIsoMesh> cache, float border, Vector3D originPosition, MyOrientedBoundingBoxD obb, List <BoundingBoxD> bbList) { Vector3I vectori3; Vector3I vectori4; bool flag = cache != null; if (flag) { this.CheckCacheValidity(); } Vector3D *vectordPtr1 = (Vector3D *)ref obb.HalfExtent; vectordPtr1[0] += new Vector3D((double)border, 0.0, (double)border); BoundingBoxD aABB = obb.GetAABB(); int num = (int)Math.Round((double)(aABB.HalfExtents.Max() * 2.0)); BoundingBoxD *xdPtr1 = (BoundingBoxD *)ref aABB; xdPtr1 = (BoundingBoxD *)new BoundingBoxD(aABB.Min, aABB.Min + num); ((BoundingBoxD *)ref aABB).Translate(obb.Center - aABB.Center); bbList.Add(new BoundingBoxD(aABB.Min, aABB.Max)); aABB = aABB.TransformFast(voxelBase.PositionComp.WorldMatrixInvScaled); aABB.Translate(voxelBase.SizeInMetresHalf); Vector3I voxelCoord = Vector3I.Round(aABB.Min); Vector3I vectori2 = (Vector3I)(voxelCoord + num); MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref voxelCoord, out vectori3); MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref vectori2, out vectori4); MyOrientedBoundingBoxD xd2 = obb; xd2.Transform(voxelBase.PositionComp.WorldMatrixInvScaled); Vector3D *vectordPtr2 = (Vector3D *)ref xd2.Center; vectordPtr2[0] += voxelBase.SizeInMetresHalf; Vector3I_RangeIterator iterator = new Vector3I_RangeIterator(ref vectori3, ref vectori4); MyCellCoord coord = new MyCellCoord { Lod = 0 }; int num2 = 0; Vector3 offset = (Vector3)(originPosition - voxelBase.PositionLeftBottomCorner); Vector3 up = -Vector3.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(originPosition)); Matrix rotation = Matrix.CreateFromQuaternion(Quaternion.Inverse(Quaternion.CreateFromForwardUp(Vector3.CalculatePerpendicularVector(up), up))); Matrix orientation = (Matrix)voxelBase.PositionComp.WorldMatrix.GetOrientation(); while (iterator.IsValid()) { BoundingBox box; MyIsoMesh mesh; if (flag && cache.TryGetValue(iterator.Current, out mesh)) { if (mesh != null) { this.AddMeshTriangles(mesh, offset, rotation, orientation); } iterator.MoveNext(); continue; } coord.CoordInLod = iterator.Current; MyVoxelCoordSystems.GeometryCellCoordToLocalAABB(ref coord.CoordInLod, out box); if (!xd2.Intersects(ref box)) { num2++; iterator.MoveNext(); } else { BoundingBoxD item = new BoundingBoxD(box.Min, box.Max).Translate(-voxelBase.SizeInMetresHalf); bbList.Add(item); Vector3I lodVoxelMin = (coord.CoordInLod * 8) - 1; MyIsoMesh mesh2 = MyPrecalcComponent.IsoMesher.Precalc(storage, 0, lodVoxelMin, (Vector3I)(((lodVoxelMin + 8) + 1) + 1), MyStorageDataTypeFlags.Content, 0); if (flag) { cache[iterator.Current] = mesh2; } if (mesh2 != null) { this.AddMeshTriangles(mesh2, offset, rotation, orientation); } iterator.MoveNext(); } } }
public MyNavmeshManager(MyRDPathfinding rdPathfinding, Vector3D center, Vector3D forwardDirection, int tileSize, int tileHeight, int tileLineCount, MyRecastOptions recastOptions) { Vector3 vector = new Vector3(ran.NextFloat(), ran.NextFloat(), ran.NextFloat()); vector -= Math.Min(vector.X, Math.Min(vector.Y, vector.Z)); vector /= Math.Max(vector.X, Math.Max(vector.Y, vector.Z)); this.m_debugColor = new Color(vector); this.m_tileSize = tileSize; this.m_tileHeight = tileHeight; this.m_tileLineCount = tileLineCount; this.Planet = this.GetPlanet(center); this.m_heightCoordTransformationIncrease = 0.5f; float cellSize = 0.2f; this.m_recastOptions = recastOptions; float num2 = (this.m_tileSize * 0.5f) + (this.m_tileSize * ((float)Math.Floor((double)(this.m_tileLineCount * 0.5f)))); float num3 = this.m_tileHeight * 0.5f; this.m_border = this.m_recastOptions.agentRadius + (3f * cellSize); float[] bMin = new float[] { -num2, -num3, -num2 }; float[] bMax = new float[] { num2, num3, num2 }; this.m_rdWrapper = new MyRDWrapper(); this.m_rdWrapper.Init(cellSize, (float)this.m_tileSize, bMin, bMax); Vector3D vectord = Vector3D.CalculatePerpendicularVector(-Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(center))); this.m_navmeshOBBs = new MyNavmeshOBBs(this.Planet, center, vectord, this.m_tileLineCount, this.m_tileSize, this.m_tileHeight); this.m_debugTileSize = new int?[this.m_tileLineCount][]; for (int i = 0; i < this.m_tileLineCount; i++) { this.m_debugTileSize[i] = new int?[this.m_tileLineCount]; } this.m_extendedBaseOBB = new MyOrientedBoundingBoxD(this.m_navmeshOBBs.BaseOBB.Center, new Vector3D(this.m_navmeshOBBs.BaseOBB.HalfExtent.X, (double)this.m_tileHeight, this.m_navmeshOBBs.BaseOBB.HalfExtent.Z), this.m_navmeshOBBs.BaseOBB.Orientation); this.m_navInputMesh = new MyNavigationInputMesh(rdPathfinding, this.Planet, center); }
private Vector3D GetPositionAtDistanceFromPlanetCenter(Vector3D position, double distance) { (position - this.Planet.PositionComp.WorldAABB.Center).Length(); return((-Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(position)) * distance) + this.Planet.PositionComp.WorldAABB.Center); }
private MatrixD LocalNavmeshPositionToWorldPositionTransform(MyOrientedBoundingBoxD obb, Vector3D center) { Vector3D v = -Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(center)); return(MatrixD.CreateFromQuaternion(Quaternion.CreateFromForwardUp((Vector3)Vector3D.CalculatePerpendicularVector(v), (Vector3)v))); }
private Vector3D LocalPositionToWorldPosition(Vector3D position) { Vector3D center = position; if (this.m_navmeshOBBs != null) { center = this.m_meshCenter; } return(this.LocalNavmeshPositionToWorldPosition(this.m_navmeshOBBs.CenterOBB, position, center, (Vector3D)(0.5 * -Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(center))))); }
public void InitializeNavmesh(Vector3D center) { this.m_isNavmeshInitialized = true; float cellSize = 0.2f; this.m_singleTileSize = 20; this.m_tileLineCount = 50; this.m_singleTileHeight = 70; MyRecastOptions options1 = new MyRecastOptions(); options1.cellHeight = 0.2f; options1.agentHeight = 1.5f; options1.agentRadius = 0.5f; options1.agentMaxClimb = 0.5f; options1.agentMaxSlope = 50f; options1.regionMinSize = 1f; options1.regionMergeSize = 10f; options1.edgeMaxLen = 50f; options1.edgeMaxError = 3f; options1.vertsPerPoly = 6f; options1.detailSampleDist = 6f; options1.detailSampleMaxError = 1f; options1.partitionType = 1; this.m_recastOptions = options1; float num2 = (this.m_singleTileSize * 0.5f) + (this.m_singleTileSize * ((float)Math.Floor((double)(this.m_tileLineCount * 0.5f)))); float num3 = this.m_singleTileHeight * 0.5f; this.m_border = this.m_recastOptions.agentRadius + (3f * cellSize); float[] bMin = new float[] { -num2, -num3, -num2 }; float[] bMax = new float[] { num2, num3, num2 }; this.rdWrapper = new MyRDWrapper(); this.rdWrapper.Init(cellSize, (float)this.m_singleTileSize, bMin, bMax); Vector3D forwardDirection = Vector3D.CalculatePerpendicularVector(-Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(center))); this.UnloadData(); this.m_navmeshOBBs = new MyNavmeshOBBs(this.GetPlanet(center), center, forwardDirection, this.m_tileLineCount, this.m_singleTileSize, this.m_singleTileHeight); this.m_meshCenter = center; this.m_visualNavmesh.Clear(); }
protected void Init_GotoRandomLocation() { // generate position and set navigation var position = Bot.AgentEntity.PositionComp.GetPosition(); var up = MyPerGameSettings.NavmeshPresumesDownwardGravity ? Vector3D.UnitY : (Vector3D)MyGravityProviderSystem.CalculateTotalGravityInPoint(position); var randomDir = MyUtils.GetRandomPerpendicularVector(ref up); var correctedPosition = position - randomDir * 15; AiTargetBase.SetTargetPosition(position + randomDir * 30); m_locationSphere.Init(ref correctedPosition, 30, randomDir); Bot.Navigation.Goto(m_locationSphere); }
private void Simulate() { var root = Entity; while (root != null && root.Physics == null) { root = root.Parent; } if (root?.Physics == null || root.Physics.IsStatic) { if (!RailConstants.Debug.DrawBogiePhysics) { return; } var drawPivot = Entity.GetPosition() + 4 * Entity.PositionComp.WorldMatrix.Up; var colorTarget = new Vector4(1, 1, 0, 1); MySimpleObjectDraw.DrawLine(Entity.GetPosition(), drawPivot, DebugMtl, ref colorTarget, .01f); return; } // Clean good controllers { _goodControllers.Clear(); FindAttachedAnimControllers(Entity, _goodControllers); _removedControllers.Clear(); foreach (var k in _activeControllers) { if (!_goodControllers.Contains(k)) { _removedControllers.Add(k); } } foreach (var k in _removedControllers) { _activeControllers.Remove(k); } _removedControllers.Clear(); var sync = false; foreach (var k in _goodControllers) { if (_activeControllers.Add(k)) { sync = true; } } if (sync) { AddScheduledCallback(ControllerSync, 30); } } var physics = root.Physics; var pivotWorld = Entity.PositionComp.WorldMatrix.Translation; var best = double.MaxValue; var bestTangent = Vector3.Zero; Edge bestEdge = null; RailSegmentComponent bestEdgeSegment; RailSegmentDefinition.RailSegmentCaps?bestEdgeCaps = null; float bestTime = 0; using (var e = Graph.Edges.SortedByDistance(pivotWorld)) while (e.MoveNext()) { if (Math.Sqrt(e.Current.DistanceSquared) - TotalBias > best) { break; } var edge = (Edge)e.Current.UserData; if (edge.Curve == null) { continue; } var edgeSegment = edge.Owner.Entity.Components.Get <RailSegmentComponent>(); var edgeCaps = edgeSegment?.Definition.CapabilitiesFor(edge.Owner.Entity.GetBuildRatio()); if (edgeSegment == null || !edgeCaps.HasValue) { continue; // no capabilities at this stage } float t0 = 0, t1 = 1; CurveExtensions.NearestPoint(edge.Curve, pivotWorld, 16, ref t0, ref t1); var p0 = edge.Curve.Sample(t0); var p1 = edge.Curve.Sample(t1); var dir = p1 - p0; var factor = (float)MathHelper.Clamp(dir.Dot(pivotWorld - p0) / dir.LengthSquared(), 0, 1); var t = t0 + (t1 - t0) * factor; var pos = edge.Curve.Sample(t); var dist = Vector3D.Distance(pos, pivotWorld); if (dist - TotalBias > best) { continue; } var tangent = (Vector3)edge.Curve.SampleDerivative(t); tangent.Normalize(); const float switchingEpsilon = 0.25f; var switched = false; if (t < switchingEpsilon) { switched = edge.From.IsSwitchedTo(edge.To); } else if (t >= 1 - switchingEpsilon) { switched = edge.To.IsSwitchedTo(edge.From); } if (switched) { dist -= SwitchingDistanceBias + AlignmentTangentBias; } else { dist -= AlignmentTangentBias * Math.Abs(Entity.PositionComp.WorldMatrix.Forward.Dot(tangent)); } if (RailConstants.Debug.DrawBogieEdges) { edge.Draw(0, 1, switched ? new Vector4(0, 1, 0, 1) : new Vector4(1, 0, 1, 1), 2); } // ReSharper disable once InvertIf if (dist < best) { best = dist; bestTangent = tangent; bestEdge = edge; bestEdgeSegment = edgeSegment; bestEdgeCaps = edgeCaps; bestTime = t; } } var selfVelocity = physics.GetVelocityAtPoint(pivotWorld); SetAnimVar(SpeedZVar, selfVelocity.Dot((Vector3)Entity.PositionComp.WorldMatrix.Forward)); if (bestEdge == null) { if (!RailConstants.Debug.DrawBogiePhysics) { return; } var drawPivot = pivotWorld + 4 * Entity.PositionComp.WorldMatrix.Up; var colorTarget = new Vector4(1, 0, 0, 1); MySimpleObjectDraw.DrawLine(pivotWorld, drawPivot, DebugMtl, ref colorTarget, .01f); return; } if (best > Definition.DetachDistance) { if (!RailConstants.Debug.DrawBogiePhysics) { return; } var drawPivot = pivotWorld + 4 * Entity.PositionComp.WorldMatrix.Up; var colorTarget = new Vector4(1, 0, 1, 1); MySimpleObjectDraw.DrawLine(pivotWorld, drawPivot, DebugMtl, ref colorTarget, .01f); return; } var up = (Vector3)Vector3D.Lerp(bestEdge.From.Up, bestEdge.To.Up, bestTime); // Not aligned vertically, abort if (Entity.PositionComp.WorldMatrix.Up.Dot(up) < 0.5) { return; } if (Entity.PositionComp.WorldMatrix.Forward.Dot(bestTangent) < 0) { bestTangent = -bestTangent; } var curvePosition = bestEdge.Curve.Sample(bestTime) + up * Definition.VerticalOffset; var normal = Vector3.Cross(bestTangent, up); normal.Normalize(); up = Vector3.Cross(normal, bestTangent); up.Normalize(); var impulse = Vector3.Zero; var allowDeactivation = true; var effectiveMass = root.Physics.Mass; var inertiaTensor = root.Physics.InertiaTensor; var qCurrent = Quaternion.CreateFromRotationMatrix(Entity.PositionComp.WorldMatrix); var qDesired = Quaternion.CreateFromRotationMatrix(Matrix.CreateWorld(Vector3.Zero, bestTangent, up)); var qConj = Quaternion.Multiply(Quaternion.Conjugate(qCurrent), qDesired); var localAngularDesired = 2 * qConj.W * new Vector3(qConj.X, qConj.Y, qConj.Z); if (localAngularDesired.LengthSquared() > .01f) { allowDeactivation = false; } var desiredAngular = Vector3.Transform(localAngularDesired, qCurrent) * 2; var rotApply = desiredAngular; var angularImpulse = Vector3.TransformNormal(desiredAngular - 0.25f * physics.AngularVelocity, inertiaTensor) * Definition.OrientationConvergenceFactor / MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; var com = physics.GetCenterOfMassWorld(); // a) spring joint along normal to get dot(normal, (pivot*matrix - position)) == 0 var err = (Vector3)(curvePosition - pivotWorld); // preemptive up force to counteract gravity. var gravityHere = MyGravityProviderSystem.CalculateTotalGravityInPoint(pivotWorld); impulse += Vector3.Dot(gravityHere, up) * up * physics.Mass * MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; impulse += SolveImpulse(err, normal, physics.LinearVelocity, effectiveMass); // b) half spring joint along up to get dot(up, (pivot*matrix - position)) >= 0 impulse += SolveImpulse(err, up, physics.LinearVelocity, effectiveMass, 1); // only up force if (err.LengthSquared() > .01f) { allowDeactivation = false; } var braking = false; // Hack until I fix EquinoxCore if (Definition.MaxVelocity > 0 && (_powerObserver.IsPowered || Definition.NeedsPower == PowerObserver.RequiredPowerEnum.None)) { var cvel = physics.LinearVelocity.Dot(bestTangent); var velocityMod = 0f; // get nearest character var totalControl = 0f; var controllers = 0; var sprinters = 0; foreach (var player in _activeControllers) { var component = player?.Get <MyCharacterMovementComponent>(); if (component == null) { continue; } var control = Vector3.TransformNormal(component.MoveIndicator, player.WorldMatrix).Dot(bestTangent); totalControl += control; controllers++; var speed = new MyMovementSpeed { Forward = 1f }; var speedMod = component.ApplyMovementSpeedEffects(speed); velocityMod = Math.Max(velocityMod, speedMod.Forward); if (!component.WantsSprint) { continue; } var stats = component.Container?.Get <MyEntityStatComponent>(); stats?.AddEffect(SprintingEffect); sprinters++; } if (controllers > 0) { braking |= Math.Sign(cvel) != Math.Sign(totalControl) && Math.Abs(cvel) > 0.01 && Math.Abs(totalControl) > 0.01; SetAnimVar(BrakingVar, braking ? 1 : 0); _powerFactor = MathHelper.Clamp(_powerFactor * (1 - PowerSmooth) + totalControl * PowerSmooth, -1, 1); if (Math.Abs(totalControl) < .01f) { _powerFactor = 0; } var velocityLimit = Definition.MaxVelocity * velocityMod; velocityLimit = Math.Min(velocityLimit, bestEdgeCaps.Value.MaxSpeed); var forceFactorBase = MathHelper.Clamp(1 - Math.Abs(cvel) / velocityLimit, 0, 1); var forceFactorControl = Math.Abs(_powerFactor); if (sprinters > 0) { forceFactorControl *= 5 * ((float)sprinters) / controllers; } forceFactorControl *= .9f + controllers * .1f; var dir = Math.Sign(_powerFactor); if (dir != Math.Sign(cvel)) { forceFactorBase = 1; } var force = Definition.MaxForce * forceFactorControl * forceFactorBase * dir * bestTangent * MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; physics.AddForce(MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, force, com, Vector3.Zero); } } Vector3 frictiveImpulse; { var frictiveNormalForce = Math.Max(0, impulse.Dot(up) / MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); var frictiveCoefficient = Math.Max(Definition.CoefficientOfFriction, braking ? Definition.BrakingCoefficientOfFriction : 0); if (physics.LinearVelocity.LengthSquared() > .01f) { frictiveCoefficient *= 0.75f; } var frictiveForce = frictiveCoefficient * (bestEdgeCaps?.Friction ?? 1) * frictiveNormalForce; // clamp frictive impulse to at-max stopping. var tangentMomentumAfterUpdate = (physics.Mass * (physics.LinearVelocity + gravityHere * MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS) + impulse).Dot(bestTangent); var frictiveFloatImpulse = frictiveForce * MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; if (frictiveFloatImpulse > Math.Abs(tangentMomentumAfterUpdate)) { // Stationary, allow deactivation frictiveImpulse = -tangentMomentumAfterUpdate * bestTangent; } else { frictiveImpulse = -Math.Sign(tangentMomentumAfterUpdate) * frictiveFloatImpulse * bestTangent; allowDeactivation = false; } impulse += frictiveImpulse; } if (!MyAPIGateway.Utilities.IsDedicated && RailConstants.Debug.DrawBogiePhysics) { var drawPivot = pivotWorld + 4 * up; var colorTarget = Vector4.One; MySimpleObjectDraw.DrawLine(pivotWorld, curvePosition, DebugMtl, ref colorTarget, .01f); var colorMarker = new Vector4(0, 1, 0, 1); MySimpleObjectDraw.DrawLine(drawPivot, drawPivot + frictiveImpulse * 10, DebugMtl, ref colorMarker, .01f); var colorImpulse = new Vector4(1, 0, 0, 1); MySimpleObjectDraw.DrawLine(drawPivot, drawPivot + impulse, DebugMtl, ref colorImpulse, .01f); var colorAngImpulse = new Vector4(0, 0, 1, 1); MySimpleObjectDraw.DrawLine(drawPivot, drawPivot + rotApply, DebugMtl, ref colorAngImpulse, .01f); } if (allowDeactivation) { // physics.Sleep(); // if (!physics.IsActive) // return; } physics.AddForce(MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, impulse, com, Vector3.Zero); physics.AddForce(MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, Vector3.Zero, pivotWorld, angularImpulse); }
internal void ChangeSlotInternal(EquiPlayerAttachmentComponent.Slot slot, float randSeed) { this.GetLogger().Debug($"Changing slot for {Entity} to {slot?.Controllable?.Entity}#{slot?.Definition.Name}"); var old = _controlledSlot; _controlledSlot = slot; var oldAnimData = old?.Definition.ByIndex(_saveData.AnimationId); EquiPlayerAttachmentComponentDefinition.AnimationDesc?newAnimData = null; if (slot != null && _saveData.ControlledSlot == slot.Definition.Name) { newAnimData = slot.Definition.ByIndex(_saveData.AnimationId); } if (!newAnimData.HasValue) { newAnimData = slot?.Definition.SelectAnimation(Entity.DefinitionId ?? default(MyDefinitionId), randSeed, out _saveData.AnimationId); } // Handles animation controller switching var animController = Entity.Components.Get <MyAnimationControllerComponent>(); if (animController != null) { if (oldAnimData.HasValue) { animController.TriggerAction(oldAnimData.Value.Stop); } if (newAnimData.HasValue) { AddScheduledCallback(CommitAnimationStart); } } // Handle restoring character's position if (slot == null && old?.Controllable?.Entity != null && old.Controllable.Entity.InScene) { var relMatrix = _saveData.RelativeOrientation.GetMatrix(); if (relMatrix.Scale.AbsMax() < 1) { relMatrix = MatrixD.Identity; } var outPos = relMatrix * old.AttachMatrix; var transformedCenter = Vector3.TransformNormal(Entity.PositionComp.LocalAABB.Center, outPos); var orientation = Quaternion.CreateFromRotationMatrix(Entity.PositionComp.WorldMatrix.GetOrientation()); var halfExtents = Entity.PositionComp.LocalAABB.HalfExtents; halfExtents.X *= 0.25f; halfExtents.Z *= 0.25f; var translate = MyEntities.FindFreePlace(outPos.Translation + transformedCenter, orientation, halfExtents, 200, 20, 0.1f, false); if (translate.HasValue) { outPos.Translation = translate.Value - transformedCenter; } else { outPos = old.AttachMatrix; } var gravity = Vector3.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(outPos.Translation)); if (MyAPIGateway.Physics.CastRay(outPos.Translation - gravity, outPos.Translation + 10 * gravity, out var hit)) { outPos.Translation = hit.Position; } Entity.PositionComp.SetWorldMatrix(outPos, Entity.Parent, true); } // Handles storing the character's position when attaching if (slot != null) { _saveData.RelativeOrientation = new MyPositionAndOrientation(MatrixD.Normalize(Entity.WorldMatrix * MatrixD.Invert(slot.AttachMatrix))); } // Handle keeping the physics in check if (Entity.Physics != null) { var wantsPhysicsEnabled = slot == null; if (wantsPhysicsEnabled && !Entity.Physics.Enabled) { Entity.Physics.Activate(); } else if (!wantsPhysicsEnabled && Entity.Physics.Enabled) { Entity.Physics.Deactivate(); } if (slot == null) { var oldPhys = old?.Controllable?.Entity.ParentedPhysics(); if (oldPhys != null) { Entity.Physics.LinearVelocity = oldPhys.GetVelocityAtPoint(old.Controllable.Entity.WorldMatrix.Translation); } } } _saveData.ControlledEntity = slot?.Controllable.Entity.EntityId ?? 0; _saveData.ControlledSlot = slot?.Definition.Name; if (slot == null) { _tracker.Unlink(Entity.EntityId); } else { _tracker.Link(Entity.EntityId, new ControlledId(slot)); } if (old?.Controllable != null) { RemoveFixedUpdate(FixPosition); } if (slot?.Controllable != null) { AddFixedUpdate(FixPosition, PriorityOverride); } FixPosition(); if (old != null) { old.AttachedCharacter = null; } if (slot != null) { slot.AttachedCharacter = Entity; } ControlledChanged?.Invoke(this, old, slot); _tracker.RaiseControlledChange(this, old, slot); }
public static bool AttemptPhysicsSleep(MyEntity start) { var relativeTo = start.Get <MyPhysicsComponentBase>(); using (PoolManager.Get(out HashSet <MyGroup> visitedGroups)) using (PoolManager.Get(out HashSet <MyEntity> visitedEntities)) using (PoolManager.Get(out List <MyEntity> pruningEntities)) using (PoolManager.Get(out Queue <MyEntity> queue)) { visitedEntities.Clear(); visitedGroups.Clear(); queue.Clear(); queue.Enqueue(start); visitedEntities.Add(start); while (queue.Count > 0) { var e = queue.Dequeue(); if (e.Components.TryGet(out MyBlockComponent block)) { if (visitedEntities.Add(block.GridData.Entity)) { queue.Enqueue(block.GridData.Entity); } continue; } if (!e.Components.TryGet <MyPhysicsComponentBase>(out var physicsComponent) || physicsComponent.IsStatic || !physicsComponent.Enabled) { continue; } if (e.Components.TryGet <MyCharacterPhysics>(out var characterPhysics) && characterPhysics.Enabled) { return(false); } if (relativeTo != physicsComponent && !CanSleepPhysics(physicsComponent, relativeTo)) { return(false); } foreach (var group in MySession.Static.Scene.GetEntityGroups(e.Id)) { if (visitedGroups.Add(@group)) { foreach (var entity in @group.Entities) { if (visitedEntities.Add(entity)) { queue.Enqueue(entity); } } } } var queryVol = e.PositionComp.WorldVolume; queryVol.Radius += 1; pruningEntities.Clear(); MyGamePruningStructure.GetTopMostEntitiesInSphere(in queryVol, pruningEntities, MyEntityQueryType.Dynamic); foreach (var nearby in pruningEntities) { if (visitedEntities.Add(nearby) && nearby.PositionComp.WorldVolume.Intersects(queryVol)) { queue.Enqueue(nearby); } } } foreach (var ent in visitedEntities) { var gridPhysics = ent.Get <MyGridRigidBodyComponent>(); if (gridPhysics == null) { continue; } gridPhysics.Gravity = MyGravityProviderSystem.CalculateTotalGravityInPoint(ent.PositionComp.GetPosition()); gridPhysics.Sleep(); } return(true); } }