Esempio n. 1
0
        /// <summary>
        /// Link the prims in a given group to this group
        /// </summary>
        /// <param name="objectGroup">The group of prims which should be linked to this group</param>
        public void LinkToGroup(SceneObjectGroup objectGroup)
        {
            //m_log.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);

            //Clear the update schedule so that we don't send wrong updates later about how this group is set up
            objectGroup.RootPart.ClearUpdateScheduleOnce();
            
            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)
                    {
                    linkPart.PhysActor.link(m_rootPart.PhysActor);
                    this.Scene.SceneGraph.PhysicsScene.AddPhysicsActorTaint(linkPart.PhysActor);
                    }
                //rest of parts
                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);
                            this.Scene.SceneGraph.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
                            }
                    }
                }
            }
            // 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!
            ResetChildPrimPhysicsPositions();
        }