private void DeactivatePhantom() { if (ENABLE_AABB_PHANTOM) { MyTrace.Send(TraceWindow.Analytics, "RemovePhantom-before"); HavokWorld.RemovePhantom(m_aabbPhantom); MyTrace.Send(TraceWindow.Analytics, "RemovePhantom-after"); Debug.Assert(m_nearbyEntities.Count == 0, "Inconsistent entities management"); m_nearbyEntities.Clear(); } }
private void ActivatePhantom() { if (ENABLE_AABB_PHANTOM) { var center = GetRigidBodyMatrix().Translation + m_voxelMap.SizeInMetresHalf; var size = m_voxelMap.SizeInMetres; size *= m_phantomExtend; m_aabbPhantom.Aabb = new BoundingBox(center - 0.5f * size, center + 0.5f * size); MyTrace.Send(TraceWindow.Analytics, "AddPhantom-before"); HavokWorld.AddPhantom(m_aabbPhantom); MyTrace.Send(TraceWindow.Analytics, "AddPhantom-after"); } }
private void DeactivatePhantom() { if (ENABLE_AABB_PHANTOM) { MyTrace.Send(TraceWindow.Analytics, "RemovePhantom-before"); Debug.Assert(m_aabbPhantom != null); HavokWorld.RemovePhantom(m_aabbPhantom); MyTrace.Send(TraceWindow.Analytics, "RemovePhantom-after"); // TODO(DI): Check if this assert is really not valid anymore //Debug.Assert(m_nearbyEntities.Count == 0, "Inconsistent entities management"); m_nearbyEntities.Clear(); } }
public void CloseRagdoll() { if (Ragdoll != null) { if (IsRagdollModeActive) { CloseRagdollMode(HavokWorld); } if (Ragdoll.InWorld) { HavokWorld.RemoveRagdoll(Ragdoll); } Ragdoll.Dispose(); Ragdoll = null; } }
internal void DisableRagdollBodiesCollisions() { Debug.Assert(Ragdoll != null, "Ragdoll is null!"); if (MyFakes.ENABLE_RAGDOLL_DEBUG) { var world = HavokWorld; Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.StaticCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.VoxelCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.DefaultCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CharacterCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CharacterNetworkCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.DynamicDoubledCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.KinematicDoubledCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.DebrisCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.FloatingObjectCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.LightFloatingObjectCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.GravityPhantomLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.VirtualMassLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.NoCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.ExplosionRaycastLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CollisionLayerWithoutCharacter), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CollideWithStaticLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CollectorCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.AmmoLayer), "Collision isn't disabled!"); } if (Ragdoll != null) { foreach (var body in Ragdoll.RigidBodies) { var info = HkGroupFilter.CalcFilterInfo(MyPhysics.CollisionLayers.RagdollCollisionLayer, 0, 0, 0); //HavokWorld.DisableCollisionsBetween(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.RagdollCollisionLayer); //HavokWorld.DisableCollisionsBetween(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CharacterCollisionLayer); body.SetCollisionFilterInfo(info); body.LinearVelocity = Vector3.Zero;// Character.Physics.LinearVelocity; body.AngularVelocity = Vector3.Zero; HavokWorld.RefreshCollisionFilterOnEntity(body); Debug.Assert(body.InWorld, "Body isn't in world!"); Debug.Assert(MyPhysics.CollisionLayers.RagdollCollisionLayer == HkGroupFilter.GetLayerFromFilterInfo(body.GetCollisionFilterInfo()), "Body is in wrong layer!"); } } }
private void RemoveConstraints(HkRigidBody hkRigidBody) { foreach (var constraint in m_constraints) { if (constraint.IsDisposed || (constraint.RigidBodyA == hkRigidBody || constraint.RigidBodyB == hkRigidBody)) m_constraintsRemoveBatch.Add(constraint); } foreach (var constraint in m_constraintsRemoveBatch) { m_constraints.Remove(constraint); if (!constraint.IsDisposed && constraint.InWorld) { //System.Diagnostics.Debug.Assert(world.RigidBodies.Contains(constraint.RigidBodyA), "Object was removed prior to constraint"); //System.Diagnostics.Debug.Assert(world.RigidBodies.Contains(constraint.RigidBodyB), "Object was removed prior to constraint"); constraint.OnRemovedFromWorld(); HavokWorld.RemoveConstraint(constraint); } } m_constraintsRemoveBatch.Clear(); }
private void ActivateRagdoll(Matrix worldMatrix) { if (MyFakes.ENABLE_RAGDOLL_DEBUG) { Debug.WriteLine("MyPhysicsBody.ActivateRagdoll"); MyLog.Default.WriteLine("MyPhysicsBody.ActivateRagdoll"); } if (Ragdoll == null) { Debug.Fail("Can not switch to Ragdoll mode, ragdoll is null!"); return; } if (HavokWorld == null) { Debug.Fail("Can not swtich to Ragdoll mode, HavokWorld is null!"); return; } if (IsRagdollModeActive) { Debug.Fail("Can not switch to ragdoll mode, ragdoll is still active!"); return; } //Matrix world = Entity.WorldMatrix; //world.Translation = WorldToCluster(world.Translation); Debug.Assert(worldMatrix.IsValid() && worldMatrix != Matrix.Zero, "Ragdoll world matrix is invalid!"); Ragdoll.SetWorldMatrix(worldMatrix); // Because after cluster's reorder, the bodies can collide! HavokWorld.AddRagdoll(Ragdoll); DisableRagdollBodiesCollisions(); if (MyFakes.ENABLE_RAGDOLL_DEBUG) { Debug.WriteLine("MyPhysicsBody.ActivateRagdoll - FINISHED"); MyLog.Default.WriteLine("MyPhysicsBody.ActivateRagdoll - FINISHED"); } }
public void SwitchToRagdollMode(bool deadMode = true, int firstRagdollSubID = 1) { Debug.Assert(Enabled, "Trying to switch to ragdoll mode, but Physics are not enabled"); if (MyFakes.ENABLE_RAGDOLL_DEBUG) { Debug.WriteLine("MyPhysicsBody.SwitchToRagdollMode"); MyLog.Default.WriteLine("MyPhysicsBody.SwitchToRagdollMode"); } if (HavokWorld == null || !Enabled) { SwitchToRagdollModeOnActivate = true; m_ragdollDeadMode = deadMode; return; } if (IsRagdollModeActive) { Debug.Fail("Ragdoll mode is already active!"); return; } Matrix havokMatrix = Entity.WorldMatrix; havokMatrix.Translation = WorldToCluster(havokMatrix.Translation); Debug.Assert(havokMatrix.IsValid() && havokMatrix != Matrix.Zero, "Invalid world matrix!"); if (RagdollSystemGroupCollisionFilterID == 0) { RagdollSystemGroupCollisionFilterID = m_world.GetCollisionFilter().GetNewSystemGroup(); } Ragdoll.SetToKeyframed(); // this will disable the bodies to get the impulse when repositioned Ragdoll.GenerateRigidBodiesCollisionFilters(deadMode ? MyPhysics.CollisionLayers.CharacterCollisionLayer : MyPhysics.CollisionLayers.RagdollCollisionLayer, RagdollSystemGroupCollisionFilterID, firstRagdollSubID); Ragdoll.ResetToRigPose(); Ragdoll.SetWorldMatrix(havokMatrix); if (deadMode) { Ragdoll.SetToDynamic(); } if (deadMode) { foreach (HkRigidBody body in Ragdoll.RigidBodies) { // set the velocities for the bodies body.AngularVelocity = AngularVelocity; body.LinearVelocity = LinearVelocity; } } else { Ragdoll.ResetVelocities(); } if (CharacterProxy != null && deadMode) { CharacterProxy.Deactivate(HavokWorld); CharacterProxy.Dispose(); CharacterProxy = null; } if (RigidBody != null && deadMode) { RigidBody.Deactivate(); HavokWorld.RemoveRigidBody(RigidBody); RigidBody.Dispose(); RigidBody = null; } if (RigidBody2 != null && deadMode) { RigidBody2.Deactivate(); HavokWorld.RemoveRigidBody(RigidBody2); RigidBody2.Dispose(); RigidBody2 = null; } foreach (var body in Ragdoll.RigidBodies) { body.UserObject = deadMode ? this : null; // TODO: THIS SHOULD BE SET IN THE RAGDOLL MODEL AND NOT DEFINING IT FOR EVERY MODEL HERE body.Motion.SetDeactivationClass(deadMode ? HkSolverDeactivation.High : HkSolverDeactivation.Medium);// - TODO: Find another way - this is deprecated by Havok } Ragdoll.OptimizeInertiasOfConstraintTree(); if (!Ragdoll.InWorld) { //Ragdoll.RecreateConstraints(); HavokWorld.AddRagdoll(Ragdoll); } Ragdoll.EnableConstraints(); Ragdoll.Activate(); m_ragdollDeadMode = deadMode; if (MyFakes.ENABLE_RAGDOLL_DEBUG) { Debug.WriteLine("MyPhysicsBody.SwitchToRagdollMode - FINISHED"); MyLog.Default.WriteLine("MyPhysicsBody.SwitchToRagdollMode - FINISHED"); } }
public void Weld(MyPhysicsBody other, bool recreateShape = true) { if (other.WeldInfo.Parent == this) //already welded to this { return; } if (other.IsWelded && !IsWelded) { other.Weld(this); return; } if (IsWelded) { WeldInfo.Parent.Weld(other); return; } if (other.WeldInfo.Children.Count > 0) { Debug.Fail("Welding other welded gorup"); other.UnweldAll(false); //they should end in same group and get welded } ProfilerShort.Begin("Weld"); HkShape thisShape; bool firstWelded = WeldInfo.Children.Count == 0; if (firstWelded) { //RemoveConstraints(RigidBody); WeldedRigidBody = RigidBody; thisShape = RigidBody.GetShape(); if (HavokWorld != null) { HavokWorld.RemoveRigidBody(WeldedRigidBody); } RigidBody = HkRigidBody.Clone(WeldedRigidBody); if (HavokWorld != null) { HavokWorld.AddRigidBody(RigidBody); } HkShape.SetUserData(thisShape, RigidBody); Entity.OnPhysicsChanged += WeldedEntity_OnPhysicsChanged; WeldInfo.UpdateMassProps(RigidBody); //Entity.OnClose += Entity_OnClose; } else { thisShape = GetShape(); } other.Deactivate(); var transform = other.Entity.WorldMatrix * Entity.WorldMatrixInvScaled; other.WeldInfo.Transform = transform; other.WeldInfo.UpdateMassProps(other.RigidBody); Debug.Assert(other.WeldedRigidBody == null); other.WeldedRigidBody = other.RigidBody; other.RigidBody = RigidBody; other.WeldInfo.Parent = this; other.ClusterObjectID = ClusterObjectID; WeldInfo.Children.Add(other); //if(recreateShape) // RecreateWeldedShape(thisShape); ProfilerShort.BeginNextBlock("OnPhysicsChanged"); //(other.Entity as MyEntity).RaisePhysicsChanged(); //other.Entity.OnPhysicsChanged += WeldedEntity_OnPhysicsChanged; //Debug.Assert(other.m_constraints.Count == 0, "Constraints left in welded body"); ProfilerShort.BeginNextBlock("RemoveConstraints"); ProfilerShort.End(); OnWelded(other); other.OnWelded(this); }
public void Unweld(MyPhysicsBody other, bool insertToWorld = true, bool recreateShape = true) { Debug.Assert(other.IsWelded && RigidBody != null && other.WeldedRigidBody != null, "Invalid welding state!"); if (IsWelded) { WeldInfo.Parent.Unweld(other, insertToWorld, recreateShape); Debug.Assert(other.IsWelded); return; } if (other.IsInWorld || RigidBody == null || other.WeldedRigidBody == null) { WeldInfo.Children.Remove(other); return; } var rbWorldMatrix = RigidBody.GetRigidBodyMatrix(); //other.Entity.OnPhysicsChanged -= WeldedEntity_OnPhysicsChanged; other.WeldInfo.Parent = null; Debug.Assert(WeldInfo.Children.Contains(other)); WeldInfo.Children.Remove(other); var body = other.RigidBody; Debug.Assert(body == RigidBody); other.RigidBody = other.WeldedRigidBody; other.WeldedRigidBody = null; if (!other.RigidBody.IsDisposed) { other.RigidBody.SetWorldMatrix(other.WeldInfo.Transform * rbWorldMatrix); other.RigidBody.LinearVelocity = body.LinearVelocity; other.WeldInfo.MassElement.Tranform = Matrix.Identity; other.WeldInfo.Transform = Matrix.Identity; } else { Debug.Fail("Disposed welded body"); } //RemoveConstraints(other.RigidBody); other.ClusterObjectID = MyHavokCluster.CLUSTERED_OBJECT_ID_UNITIALIZED; if (insertToWorld) { other.Activate(); other.OnMotion(other.RigidBody, 0); } if (WeldInfo.Children.Count == 0) { recreateShape = false; Entity.OnPhysicsChanged -= WeldedEntity_OnPhysicsChanged; Entity.OnClose -= Entity_OnClose; WeldedRigidBody.LinearVelocity = RigidBody.LinearVelocity; WeldedRigidBody.AngularVelocity = RigidBody.AngularVelocity; if (HavokWorld != null) { HavokWorld.RemoveRigidBody(RigidBody); } RigidBody.Dispose(); RigidBody = WeldedRigidBody; WeldedRigidBody = null; RigidBody.SetWorldMatrix(rbWorldMatrix); WeldInfo.Transform = Matrix.Identity; if (HavokWorld != null) { HavokWorld.AddRigidBody(RigidBody); } else if (!Entity.MarkedForClose) { Activate(); } if (RigidBody2 != null) { RigidBody2.SetShape(RigidBody.GetShape()); } } if (RigidBody != null && recreateShape) { RecreateWeldedShape(GetShape()); } OnUnwelded(other); other.OnUnwelded(this); Debug.Assert(!other.IsWelded); }