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();
        }
Пример #2
0
        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);
        }