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); }
public override void Simulate() { if (MyFakes.PAUSE_PHYSICS && !MyFakes.STEP_PHYSICS) { return; } MyFakes.STEP_PHYSICS = false; if (!MySandboxGame.IsGameReady) { return; } AddTimestamp(); InsideSimulation = true; ProcessDestructions(); ProfilerShort.Begin("HavokWorld.Step"); foreach (HkWorld world in Clusters.GetList()) { //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(100, 100), "Constr:" + world.GetConstraintCount(), Color.Red, 0.9f); world.UnmarkForWrite(); world.StepSimulation(MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS * MyFakes.SIMULATION_SPEED); world.MarkForWrite(); } ProfilerShort.End(); InsideSimulation = false; ProfilerShort.Begin("Update rigid bodies"); long activeRigidBodies = 0; foreach (HkWorld world in Clusters.GetList()) { activeRigidBodies += world.ActiveRigidBodies.Count; } VRageRender.MyPerformanceCounter.PerCameraDrawWrite["Active rigid bodies"] = activeRigidBodies; ProfilerShort.CustomValue("Active bodies", activeRigidBodies, null); foreach (HkWorld world in Clusters.GetList()) { IterateBodies(world); } //ParallelTasks.Parallel.For(0, m_iterationBodies.Count, (rb) => //{ // MyPhysicsBody body = (MyPhysicsBody)m_iterationBodies[rb].UserObject; // if (body == null) // return; // body.OnMotion(m_iterationBodies[rb], MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); //}, Math.Max(1, m_iterationBodies.Count / 16)); foreach (var rb in m_iterationBodies) { MyPhysicsBody body = (MyPhysicsBody)rb.UserObject; if (body == null) { return; } body.OnMotion(rb, MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); } foreach (HkCharacterRigidBody rb in m_characterIterationBodies) { var body = (MyPhysicsBody)rb.GetHitRigidBody().UserObject; if (body.Entity.WorldMatrix.Translation != body.GetWorldMatrix().Translation) { body.UpdateCluster(); } } m_iterationBodies.Clear(); m_characterIterationBodies.Clear(); ProfilerShort.End(); ProfilerShort.Begin("HavokWorld.StepVDB"); foreach (HkWorld world in Clusters.GetList()) { world.StepVDB(MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); } ProfilerShort.End(); }
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); }
public override void Simulate() { if (MyFakes.PAUSE_PHYSICS && !MyFakes.STEP_PHYSICS) { return; } MyFakes.STEP_PHYSICS = false; if (!MySandboxGame.IsGameReady) { return; } AddTimestamp(); InsideSimulation = true; ProcessDestructions(); ProfilerShort.Begin("HavokWorld.Step"); if (MyFakes.CLIENTS_SIMULATE_SINGLE_WORLD && !Sync.IsServer) { var world = Clusters.GetClusterForPosition(MySector.MainCamera.Position); if (world != null) { StepWorld((HkWorld)world); } } else { foreach (HkWorld world in Clusters.GetList()) { StepWorld(world); } } ProfilerShort.End(); InsideSimulation = false; ProfilerShort.Begin("Update rigid bodies"); long activeRigidBodies = 0; foreach (HkWorld world in Clusters.GetList()) { activeRigidBodies += world.ActiveRigidBodies.Count; } VRageRender.MyPerformanceCounter.PerCameraDrawWrite["Active rigid bodies"] = activeRigidBodies; ProfilerShort.CustomValue("Active bodies", activeRigidBodies, null); foreach (HkWorld world in Clusters.GetList()) { IterateBodies(world); } //ParallelTasks.Parallel.For(0, m_iterationBodies.Count, (rb) => //{ // MyPhysicsBody body = (MyPhysicsBody)m_iterationBodies[rb].UserObject; // if (body == null) // return; // body.OnMotion(m_iterationBodies[rb], MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); //}, Math.Max(1, m_iterationBodies.Count / 16)); foreach (var rb in m_iterationBodies) { MyPhysicsBody body = (MyPhysicsBody)rb.UserObject; if (body == null) { return; } body.OnMotion(rb, MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); } foreach (HkCharacterRigidBody rb in m_characterIterationBodies) { var body = (MyPhysicsBody)rb.GetHitRigidBody().UserObject; if (body.Entity.WorldMatrix.Translation != body.GetWorldMatrix().Translation) { body.UpdateCluster(); } } m_iterationBodies.Clear(); m_characterIterationBodies.Clear(); ProfilerShort.End(); ProfilerShort.Begin("HavokWorld.StepVDB"); foreach (HkWorld world in Clusters.GetList()) { //if (MySession.ControlledEntity.Entity.GetTopMostParent().Physics.HavokWorld == world) world.StepVDB(MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); } ProfilerShort.End(); }