Exemplo n.º 1
0
        /// <summary>
        ///   Link the prims in a given group to this group
        /// </summary>
        /// <param name = "grp">The group of prims which should be linked to this group</param>
        public void LinkToGroup(ISceneEntity grp)
        {
            //MainConsole.Instance.DebugFormat(
            //    "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}",
            //    objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID);

            if (!(grp is SceneObjectGroup))
                return;
            SceneObjectGroup objectGroup = (SceneObjectGroup) grp;

            if (m_rootPart.PhysActor != null)
                m_rootPart.PhysActor.BlockPhysicalReconstruction = true;

            SceneObjectPart linkPart = objectGroup.m_rootPart;

            Vector3 oldGroupPosition = linkPart.GroupPosition;
            Quaternion oldRootRotation = linkPart.RotationOffset;
            Quaternion parentRot = m_rootPart.RotationOffset;

            linkPart.SetGroupPosition(AbsolutePosition); // just change it without doing anything else

            Vector3 axPos = oldGroupPosition - AbsolutePosition;
            axPos *= Quaternion.Inverse(parentRot);
            linkPart.SetOffsetPosition(axPos);

            Quaternion newRot = Quaternion.Inverse(parentRot)*oldRootRotation;
            linkPart.SetRotationOffset(false, newRot, false);

            //Fix the link number for the root
            if (m_rootPart.LinkNum == 0)
                m_rootPart.LinkNum = 1;

            SceneObjectPart[] objectGroupChildren = new SceneObjectPart[objectGroup.ChildrenList.Count];
            objectGroup.ChildrenList.CopyTo(objectGroupChildren, 0);

            //Destroy the old group
            m_scene.SceneGraph.DeleteEntity(objectGroup);
            objectGroup.IsDeleted = true;
            objectGroup.ClearChildren();


            lock (m_partsLock)
            {
                int linkNum = 2;
                //Add the root part to our group!
                m_scene.SceneGraph.LinkPartToSOG(this, linkPart, linkNum++);
                linkPart.CreateSelected = true;
                linkPart.FixOffsetPosition(linkPart.OffsetPosition, true); // nasty let all know about where this is
                // let physics link it
                if (linkPart.PhysActor != null && m_rootPart.PhysActor != null)
                {
                    if (linkPart.PhysicsType != (byte) PhysicsShapeType.None)
                    {
                        linkPart.PhysActor.link(m_rootPart.PhysActor);
                        Scene.PhysicsScene.AddPhysicsActorTaint(linkPart.PhysActor);
                    }
                }
                //rest of parts
#if (!ISWIN)
                foreach (SceneObjectPart part in objectGroupChildren)
                {
                    if (part.UUID != objectGroup.m_rootPart.UUID)
                    {
                        LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
                        part.FixOffsetPosition(part.OffsetPosition, true);
                        if (part.PhysActor != null && m_rootPart.PhysActor != null)
                        {
                            part.PhysActor.link(m_rootPart.PhysActor);
                            Scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
                        }
                    }
                }
#else
                foreach (SceneObjectPart part in objectGroupChildren.Where(part => part.UUID != objectGroup.m_rootPart.UUID))
                {
                    LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
                    part.FixOffsetPosition(part.OffsetPosition, true);
                    if (part.PhysActor != null && m_rootPart.PhysActor != null)
                    {
                        part.PhysActor.link(m_rootPart.PhysActor);
                        Scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
                    }
                }
#endif
            }
            // Here's the deal, this is ABSOLUTELY CRITICAL so the physics scene gets the update about the 
            // position of linkset prims.  IF YOU CHANGE THIS, YOU MUST TEST colliding with just linked and 
            // unmoved prims!
            m_ValidgrpOOB = false;
            ResetChildPrimPhysicsPositions();

            if (m_rootPart.PhysActor != null)
                m_rootPart.PhysActor.BlockPhysicalReconstruction = false;
        }