private void RecreateWeldedShape(HkShape thisShape) { if (RigidBody == null || RigidBody.IsDisposed) { Debug.Fail("Missing rigid body"); MyTrace.Send(TraceWindow.Analytics, "Recreating welded shape without RB", string.Format("{0},{1}", Entity.MarkedForClose, WeldInfo.Children.Count)); return; } ProfilerShort.Begin("RecreateWeldedShape"); //me.Tranform.Translation = Entity.PositionComp.LocalAABB.Center; if (WeldInfo.Children.Count == 0) { RigidBody.SetShape(thisShape); if (RigidBody2 != null) RigidBody2.SetShape(thisShape); } else { ProfilerShort.Begin("Create shapes"); //m_tmpElements.Add(WeldInfo.MassElement); m_tmpShapeList.Add(thisShape); foreach (var child in WeldInfo.Children) { var transformShape = new HkTransformShape(child.WeldedRigidBody.GetShape(), ref child.WeldInfo.Transform); HkShape.SetUserData(transformShape, child.WeldedRigidBody); m_tmpShapeList.Add(transformShape); //m_tmpElements.Add(child.WeldInfo.MassElement); } //var list = new HkListShape(m_tmpShapeList.ToArray(), HkReferencePolicy.None); var list = new HkSmartListShape(0); foreach (var shape in m_tmpShapeList) list.AddShape(shape); RigidBody.SetShape(list); if (RigidBody2 != null) RigidBody2.SetShape(list); list.Base.RemoveReference(); WeldedMarkBreakable(); for (int i = 1; i < m_tmpShapeList.Count; i++) m_tmpShapeList[i].RemoveReference(); m_tmpShapeList.Clear(); ProfilerShort.End(); ProfilerShort.Begin("CalcMassProps"); UpdateMassProps(); //m_tmpElements.Clear(); ProfilerShort.End(); } 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); }