Esempio n. 1
0
        /// <summary>
        /// Add an object to the scene.  This will both update the scene, and send information about the
        /// new object to all clients interested in the scene.
        /// </summary>
        /// <param name="sceneObject"></param>
        /// <param name="attachToBackup">
        /// If true, the object is made persistent into the scene.
        /// If false, the object will not persist over server restarts
        /// </param>
        /// <param name="sendClientUpdates">
        /// If true, updates for the new scene object are sent to all viewers in range.
        /// If false, it is left to the caller to schedule the update
        /// </param>
        /// <returns>
        /// true if the object was added, false if an object with the same uuid was already in the scene
        /// </returns>
        protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
        {
            if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero)
                return false;

            bool alreadyExisted = false;
            
            if (m_parentScene.m_clampPrimSize)
            {
                foreach (SceneObjectPart part in sceneObject.Children.Values)
                {
                    Vector3 scale = part.Shape.Scale;

                    if (scale.X > m_parentScene.m_maxNonphys)
                        scale.X = m_parentScene.m_maxNonphys;
                    if (scale.Y > m_parentScene.m_maxNonphys)
                        scale.Y = m_parentScene.m_maxNonphys;
                    if (scale.Z > m_parentScene.m_maxNonphys)
                        scale.Z = m_parentScene.m_maxNonphys;

                    part.Shape.Scale = scale;
                }
            }

            sceneObject.AttachToScene(m_parentScene);

            if (sendClientUpdates)
                sceneObject.ScheduleGroupForFullUpdate();

            lock (sceneObject)
            {
                if (!Entities.ContainsKey(sceneObject.UUID))
                {
                    Entities.Add(sceneObject);
                    m_numPrim += sceneObject.Children.Count;

                    if (attachToBackup)
                        sceneObject.AttachToBackup();

                    if (OnObjectCreate != null)
                        OnObjectCreate(sceneObject);
                    
                    lock (m_dictionary_lock)
                    {
                        SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
                        SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
                        foreach (SceneObjectPart part in sceneObject.Children.Values)
                        {
                            SceneObjectGroupsByFullID[part.UUID] = sceneObject;
                            SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
                        }
                    }
                }
                else
                {
                    alreadyExisted = true;
                }
            }

            return alreadyExisted;
        }
Esempio n. 2
0
        public SceneObjectGroup CreateEntity(
            UUID ownerID, UUID groupID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape)
        {
            if (Array.IndexOf(creationCapabilities, (PCode)shape.PCode) < 0)
            {
                m_log.DebugFormat("[VEGETATION]: PCode {0} not handled by {1}", shape.PCode, Name);
                return null;
            }

            SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape, m_scene);
            SceneObjectPart rootPart = sceneObject.GetChildPart(sceneObject.UUID);

            rootPart.AddFlag(PrimFlags.Phantom);
            if (rootPart.Shape.PCode != (byte)PCode.Grass)
            {
                // Tree size has to be adapted depending on its type
                switch ((Tree)rootPart.Shape.State)
                {
                    case Tree.Cypress1:
                    case Tree.Cypress2:
                    case Tree.Palm1:
                    case Tree.Palm2:
                    case Tree.WinterAspen:
                        rootPart.Scale = new Vector3(4, 4, 10);
                        break;
                    case Tree.WinterPine1:
                    case Tree.WinterPine2:
                        rootPart.Scale = new Vector3(4, 4, 20);
                        break;

                    case Tree.Dogwood:
                        rootPart.Scale = new Vector3(6.5f, 6.5f, 6.5f);
                        break;

                    // case... other tree types
                    // tree.Scale = new Vector3(?, ?, ?);
                    // break;

                    default:
                        rootPart.Scale = new Vector3(4, 4, 4);
                        break;
                }
            }

            m_scene.AddPrimToScene(sceneObject);
            sceneObject.ScheduleGroupForFullUpdate(PrimUpdateFlags.FullUpdate);
            sceneObject.SetGroup(groupID, null);

            return sceneObject;
        }
Esempio n. 3
0
        /// <summary>
        /// Add an object to the scene.  This will both update the scene, and send information about the
        /// new object to all clients interested in the scene.
        /// </summary>
        /// <remarks>
        /// The object's stored position, rotation and velocity are used.
        /// </remarks>
        /// <param name="sceneObject"></param>
        /// <param name="attachToBackup">
        /// If true, the object is made persistent into the scene.
        /// If false, the object will not persist over server restarts
        /// </param>
        /// <param name="sendClientUpdates">
        /// If true, updates for the new scene object are sent to all viewers in range.
        /// If false, it is left to the caller to schedule the update
        /// </param>
        /// <returns>
        /// true if the object was added, false if an object with the same uuid was already in the scene
        /// </returns>
        protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
        {
            if (sceneObject.UUID == UUID.Zero)
            {
                m_log.ErrorFormat(
                    "[SCENEGRAPH]: Tried to add scene object {0} to {1} with illegal UUID of {2}",
                    sceneObject.Name, m_parentScene.RegionInfo.RegionName, UUID.Zero);

                return false;
            }

            if (Entities.ContainsKey(sceneObject.UUID))
            {
                m_log.DebugFormat(
                    "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()",
                    m_parentScene.RegionInfo.RegionName, sceneObject.UUID);

                return false;
            }

//            m_log.DebugFormat(
//                "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}",
//                sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName);

            SceneObjectPart[] parts = sceneObject.Parts;

            // Clamp child prim sizes and add child prims to the m_numPrim count
            if (m_parentScene.m_clampPrimSize)
            {
                foreach (SceneObjectPart part in parts)
                {
                    Vector3 scale = part.Shape.Scale;

                    scale.X = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.X));
                    scale.Y = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Y));
                    scale.Z = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Z));

                    part.Shape.Scale = scale;
                }
            }
            m_numPrim += parts.Length;

            sceneObject.AttachToScene(m_parentScene);

            if (sendClientUpdates)
                sceneObject.ScheduleGroupForFullUpdate();

            Entities.Add(sceneObject);

            if (attachToBackup)
                sceneObject.AttachToBackup();

            lock (SceneObjectGroupsByFullID)
                SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;

            lock (SceneObjectGroupsByFullPartID)
            {
                foreach (SceneObjectPart part in parts)
                    SceneObjectGroupsByFullPartID[part.UUID] = sceneObject;
            }

            lock (SceneObjectGroupsByLocalPartID)
            {
//                m_log.DebugFormat(
//                    "[SCENE GRAPH]: Adding scene object {0} {1} {2} to SceneObjectGroupsByLocalPartID in {3}",
//                    sceneObject.Name, sceneObject.UUID, sceneObject.LocalId, m_parentScene.RegionInfo.RegionName);

                foreach (SceneObjectPart part in parts)
                    SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject;
            }

            return true;
        }
        /// <summary>
        /// Attach this scene object to the given avatar.
        /// </summary>
        /// <remarks>
        /// This isn't publicly available since attachments should always perform the corresponding inventory 
        /// operation (to show the attach in user inventory and update the asset with positional information).
        /// </remarks>
        /// <param name="sp"></param>
        /// <param name="so"></param>
        /// <param name="attachmentpoint"></param>
        /// <param name="attachOffset"></param>
        /// <param name="silent"></param>
        private void AttachToAgent(
            IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
        {
            if (DebugLevel > 0)
                m_log.DebugFormat(
                    "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
                    so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);

            so.DetachFromBackup();

            // Remove from database and parcel prim count
            m_scene.DeleteFromStorage(so.UUID);
            m_scene.EventManager.TriggerParcelPrimCountTainted();

            so.AttachedAvatar = sp.UUID;

            if (so.RootPart.PhysActor != null)
                so.RootPart.RemoveFromPhysics();

            so.AbsolutePosition = attachOffset;
            so.RootPart.AttachedPos = attachOffset;
            so.IsAttachment = true;
            so.RootPart.SetParentLocalId(sp.LocalId);
            so.AttachmentPoint = attachmentpoint;

            sp.AddAttachment(so);

            if (!silent)
            {
                if (so.HasPrivateAttachmentPoint)
                {
                    if (DebugLevel > 0)
                        m_log.DebugFormat(
                            "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}",
                            so.Name, sp.Name, so.AttachmentPoint);

                    // As this scene object can now only be seen by the attaching avatar, tell everybody else in the
                    // scene that it's no longer in their awareness.
                    m_scene.ForEachClient(
                        client =>
                            { if (client.AgentId != so.AttachedAvatar)
                                client.SendKillObject(new List<uint>() { so.LocalId });
                            });
                }

                // Fudge below is an extremely unhelpful comment.  It's probably here so that the scheduled full update
                // will succeed, as that will not update if an attachment is selected.
                so.IsSelected = false; // fudge.... 

                so.ScheduleGroupForFullUpdate();
            }

            // In case it is later dropped again, don't let
            // it get cleaned up
            so.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
        }
Esempio n. 5
0
        /// <summary>
        /// Add an object to the scene.  This will both update the scene, and send information about the
        /// new object to all clients interested in the scene.
        /// </summary>
        /// <param name="sceneObject"></param>
        /// <param name="attachToBackup">
        /// If true, the object is made persistent into the scene.
        /// If false, the object will not persist over server restarts
        /// </param>
        /// <param name="sendClientUpdates">
        /// If true, updates for the new scene object are sent to all viewers in range.
        /// If false, it is left to the caller to schedule the update
        /// </param>
        /// <returns>
        /// true if the object was added, false if an object with the same uuid was already in the scene
        /// </returns>
        protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
        {
            if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero)
                return false;

            //if (Entities.ContainsKey(sceneObject.UUID))
            //{
            //    m_log.WarnFormat(
            //            "[SCENE GRAPH]: Scene object {0} {1} was already in region {2} on add request",
            //            sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
            //    return false;
            //}

            IOpenRegionSettingsModule WSModule = sceneObject.Scene.RequestModuleInterface<IOpenRegionSettingsModule>();
            if (WSModule != null)
            {
                foreach (SceneObjectPart part in sceneObject.ChildrenList)
                {
                    if (part.Shape == null)
                        continue;

                    Vector3 scale = part.Shape.Scale;

                    if (WSModule.MinimumPrimScale != -1)
                    {
                        if (scale.X < WSModule.MinimumPrimScale)
                            scale.X = WSModule.MinimumPrimScale;
                        if (scale.Y < WSModule.MinimumPrimScale)
                            scale.Y = WSModule.MinimumPrimScale;
                        if (scale.Z < WSModule.MinimumPrimScale)
                            scale.Z = WSModule.MinimumPrimScale;
                    }

                    if (part.ParentGroup.RootPart.PhysActor != null && part.ParentGroup.RootPart.PhysActor.IsPhysical &&
                        WSModule.MaximumPhysPrimScale != -1)
                    {
                        if (scale.X > WSModule.MaximumPhysPrimScale)
                            scale.X = WSModule.MaximumPhysPrimScale;
                        if (scale.Y > WSModule.MaximumPhysPrimScale)
                            scale.Y = WSModule.MaximumPhysPrimScale;
                        if (scale.Z > WSModule.MaximumPhysPrimScale)
                            scale.Z = WSModule.MaximumPhysPrimScale;
                    }

                    if (WSModule.MaximumPrimScale != -1)
                    {
                        if (scale.X > WSModule.MaximumPrimScale)
                            scale.X = WSModule.MaximumPrimScale;
                        if (scale.Y > WSModule.MaximumPrimScale)
                            scale.Y = WSModule.MaximumPrimScale;
                        if (scale.Z > WSModule.MaximumPrimScale)
                            scale.Z = WSModule.MaximumPrimScale;
                    }

                    part.Shape.Scale = scale;
                }
            }
            sceneObject.AttachToScene(m_parentScene);
            Entities.Add(sceneObject);

            if (sendClientUpdates)
                sceneObject.ScheduleGroupForFullUpdate(PrimUpdateFlags.FullUpdate);

            m_numPrim += sceneObject.ChildrenList.Count;
            return true;
        }
Esempio n. 6
0
        /// <summary>
        /// Move the given scene object into a new region depending on which region its absolute position has moved
        /// into.
        ///
        /// Using the objects new world location, ask the grid service for a the new region and adjust the prim
        /// position to be relative to the new region.
        /// </summary>
        /// <param name="grp">the scene object that we're crossing</param>
        /// <param name="attemptedPosition">the attempted out of region position of the scene object. This position is
        /// relative to the region the object currently is in.</param>
        /// <param name="silent">if 'true', the deletion of the client from the region is not broadcast to the clients</param>
        public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent)
        {
            if (grp == null)
                return;
            if (grp.IsDeleted)
                return;

            Scene scene = grp.Scene;
            if (scene == null)
                return;

            if (grp.RootPart.DIE_AT_EDGE)
            {
                // We remove the object here
                try
                {
                    scene.DeleteSceneObject(grp, false);
                }
                catch (Exception)
                {
                    m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border.");
                }
                return;
            }

            // Remember the old group position in case the region lookup fails so position can be restored.
            Vector3 oldGroupPosition = grp.RootPart.GroupPosition;

            // Compute the absolute position of the object.
            double objectWorldLocX = (double)scene.RegionInfo.WorldLocX + attemptedPosition.X;
            double objectWorldLocY = (double)scene.RegionInfo.WorldLocY + attemptedPosition.Y;

            // Ask the grid service for the region that contains the passed address
            GridRegion destination = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID,
                                objectWorldLocX, objectWorldLocY);

            Vector3 pos = Vector3.Zero;
            if (destination != null)
            {
                // Adjust the object's relative position from the old region (attemptedPosition)
                //    to be relative to the new region (pos).
                pos = new Vector3(  (float)(objectWorldLocX - (double)destination.RegionLocX),
                                    (float)(objectWorldLocY - (double)destination.RegionLocY),
                                    attemptedPosition.Z);
            }

            if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
            {
                m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID);

                // We are going to move the object back to the old position so long as the old position
                // is in the region
                oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1));
                oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1));
                oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 1.0f, Constants.RegionHeight);

                grp.AbsolutePosition = oldGroupPosition;
                grp.Velocity = Vector3.Zero;
                if (grp.RootPart.PhysActor != null)
                    grp.RootPart.PhysActor.CrossingFailure();

                if (grp.RootPart.KeyframeMotion != null)
                    grp.RootPart.KeyframeMotion.CrossingFailure();

                grp.ScheduleGroupForFullUpdate();
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Move the given scene object into a new region depending on which region its absolute position has moved
        /// into.
        ///
        /// This method locates the new region handle and offsets the prim position for the new region
        /// </summary>
        /// <param name="attemptedPosition">the attempted out of region position of the scene object</param>
        /// <param name="grp">the scene object that we're crossing</param>
        public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent)
        {
            if (grp == null)
                return;
            if (grp.IsDeleted)
                return;

            Scene scene = grp.Scene;
            if (scene == null)
                return;
            if (grp.RootPart.DIE_AT_EDGE)
            {
                // We remove the object here
                try
                {
                    scene.DeleteSceneObject(grp, false, true);
                }
                catch (Exception)
                {
                    m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border.");
                }
                return;
            }

            int thisx = (int)scene.RegionInfo.RegionLocX;
            int thisy = (int)scene.RegionInfo.RegionLocY;
            Vector3 EastCross = new Vector3(0.1f, 0, 0);
            Vector3 WestCross = new Vector3(-0.1f, 0, 0);
            Vector3 NorthCross = new Vector3(0, 0.1f, 0);
            Vector3 SouthCross = new Vector3(0, -0.1f, 0);


            // use this if no borders were crossed!
            ulong newRegionHandle
                        = Util.UIntsToLong((uint)((thisx) * Constants.RegionSize),
                                           (uint)((thisy) * Constants.RegionSize));

            Vector3 pos = attemptedPosition;

            int changeX = 1;
            int changeY = 1;

            if (scene.TestBorderCross(attemptedPosition + WestCross, Cardinals.W))
            {
                if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
                {

                    Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);

                    if (crossedBorderx.BorderLine.Z > 0)
                    {
                        pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
                        changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.X = ((pos.X + Constants.RegionSize));

                    Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                    //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                    if (crossedBordery.BorderLine.Z > 0)
                    {
                        pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                        changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.Y = ((pos.Y + Constants.RegionSize));



                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
                                           (uint)((thisy - changeY) * Constants.RegionSize));
                    // x - 1
                    // y - 1
                }
                else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
                {
                    Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);

                    if (crossedBorderx.BorderLine.Z > 0)
                    {
                        pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
                        changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.X = ((pos.X + Constants.RegionSize));


                    Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                    //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                    if (crossedBordery.BorderLine.Z > 0)
                    {
                        pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                        changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.Y = ((pos.Y + Constants.RegionSize));

                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
                                           (uint)((thisy + changeY) * Constants.RegionSize));
                    // x - 1
                    // y + 1
                }
                else
                {
                    Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);

                    if (crossedBorderx.BorderLine.Z > 0)
                    {
                        pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
                        changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.X = ((pos.X + Constants.RegionSize));

                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
                                           (uint)(thisy * Constants.RegionSize));
                    // x - 1
                }
            }
            else if (scene.TestBorderCross(attemptedPosition + EastCross, Cardinals.E))
            {
                if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
                {

                    pos.X = ((pos.X - Constants.RegionSize));
                    Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                    //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                    if (crossedBordery.BorderLine.Z > 0)
                    {
                        pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                        changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.Y = ((pos.Y + Constants.RegionSize));


                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
                                           (uint)((thisy - changeY) * Constants.RegionSize));
                    // x + 1
                    // y - 1
                }
                else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
                {
                    pos.X = ((pos.X - Constants.RegionSize));
                    pos.Y = ((pos.Y - Constants.RegionSize));
                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
                                           (uint)((thisy + changeY) * Constants.RegionSize));
                    // x + 1
                    // y + 1
                }
                else
                {
                    pos.X = ((pos.X - Constants.RegionSize));
                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
                                           (uint)(thisy * Constants.RegionSize));
                    // x + 1
                }
            }
            else if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
            {
                Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                if (crossedBordery.BorderLine.Z > 0)
                {
                    pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                    changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                }
                else
                    pos.Y = ((pos.Y + Constants.RegionSize));

                newRegionHandle
                    = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - changeY) * Constants.RegionSize));
                // y - 1
            }
            else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
            {

                pos.Y = ((pos.Y - Constants.RegionSize));
                newRegionHandle
                    = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize));
                // y + 1
            }

            // Offset the positions for the new region across the border
            Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
            grp.OffsetForNewRegion(pos);

            // If we fail to cross the border, then reset the position of the scene object on that border.
            uint x = 0, y = 0;
            Utils.LongToUInts(newRegionHandle, out x, out y);
            GridRegion destination = scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
            if (destination != null && !CrossPrimGroupIntoNewRegion(destination, grp, silent))
            {
                grp.OffsetForNewRegion(oldGroupPosition);
                grp.ScheduleGroupForFullUpdate(PrimUpdateFlags.FullUpdate);
            }
        }
 void DoSierpinski(SceneObjectGroup sog, Vector3 scale)
 {
     //replace the original prim with 5 new prims
     Vector3 newsize = new Vector3(scale.X / 2, scale.Y / 2, scale.Z / 2);
     Vector3 offset = new Vector3(scale.X / 4, scale.Y / 4, scale.Z / 4);
     Vector3 pos = sog.AbsolutePosition;
     //Move and resize the existing prim to become the new prim#1
     //This is much faster than creating a new one and deleting the old
     Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z + offset.Z);
     sog.AbsolutePosition = newpos;
     sog.RootPart.Scale = newsize;
     sog.ScheduleGroupForFullUpdate();
     m_newprims.Add(sog);
     // Add new prim#2
     PrimitiveBaseShape prim2 = PrimitiveBaseShape.CreateBox();
     prim2.Textures = new Primitive.TextureEntry(new UUID("5748decc-f629-461c-9a36-a35a236fe36f"));
     newpos = new Vector3(pos.X - offset.X, pos.Y - offset.Y, pos.Z - offset.Z);
     SceneObjectGroup newsog2 = new SceneObjectGroup(UUID.Zero, newpos, prim2);
     newsog2.RootPart.Scale = newsize;
     m_newprims.Add(newsog2); //add it to our list of managed objects
     m_scene.AddNewSceneObject(newsog2, false);  //add it to the scene (not backed up to the db)
     Primitive.TextureEntry tex = newsog2.RootPart.Shape.Textures;
     tex.DefaultTexture.RGBA = RandomColor();
     newsog2.RootPart.UpdateTexture(tex);
     // Add new prim#3
     PrimitiveBaseShape prim3 = PrimitiveBaseShape.CreateBox();
     prim3.Textures = new Primitive.TextureEntry(new UUID("5748decc-f629-461c-9a36-a35a236fe36f"));
     newpos = new Vector3(pos.X - offset.X, pos.Y + offset.Y, pos.Z - offset.Z);
     SceneObjectGroup newsog3 = new SceneObjectGroup(UUID.Zero, newpos, prim3);
     newsog3.RootPart.Scale = newsize;
     m_newprims.Add(newsog3); //add it to our list of managed objects
     m_scene.AddNewSceneObject(newsog3, false);  //add it to the scene (not backed up to the db)
     tex = newsog3.RootPart.Shape.Textures;
     tex.DefaultTexture.RGBA = RandomColor();
     newsog3.RootPart.UpdateTexture(tex);
     // Add new prim#4
     PrimitiveBaseShape prim4 = PrimitiveBaseShape.CreateBox();
     prim4.Textures = new Primitive.TextureEntry(new UUID("5748decc-f629-461c-9a36-a35a236fe36f"));
      	newpos = new Vector3(pos.X + offset.X, pos.Y - offset.Y, pos.Z - offset.Z);
     SceneObjectGroup newsog4 = new SceneObjectGroup(UUID.Zero, newpos, prim4);
     newsog4.RootPart.Scale = newsize;
     m_newprims.Add(newsog4); //add it to our list of managed objects
     m_scene.AddNewSceneObject(newsog4, false);  //add it to the scene (not backed up to the db)
     tex = newsog4.RootPart.Shape.Textures;
     tex.DefaultTexture.RGBA = RandomColor();
     newsog4.RootPart.UpdateTexture(tex);
     // Add new prim#5
     PrimitiveBaseShape prim5 = PrimitiveBaseShape.CreateBox();
     prim5.Textures = new Primitive.TextureEntry(new UUID("5748decc-f629-461c-9a36-a35a236fe36f"));
     newpos = new Vector3(pos.X + offset.X, pos.Y + offset.Y, pos.Z - offset.Z);
     SceneObjectGroup newsog5 = new SceneObjectGroup(UUID.Zero, newpos, prim5);
     newsog5.RootPart.Scale = newsize;
     m_newprims.Add(newsog5); //add it to our list of managed objects
     m_scene.AddNewSceneObject(newsog5, false);  //add it to the scene (not backed up to the db)
     tex = newsog5.RootPart.Shape.Textures;
     tex.DefaultTexture.RGBA = RandomColor();
     newsog5.RootPart.UpdateTexture(tex);
 }
Esempio n. 9
0
        /// <summary>
        /// Move the given scene object into a new region depending on which region its absolute position has moved
        /// into.
        ///
        /// This method locates the new region handle and offsets the prim position for the new region
        /// </summary>
        /// <param name="attemptedPosition">the attempted out of region position of the scene object</param>
        /// <param name="grp">the scene object that we're crossing</param>
        public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent)
        {
            if (grp == null)
                return;
            if (grp.IsDeleted)
                return;

            Scene scene = grp.Scene;
            if (scene == null)
                return;

            if (grp.RootPart.DIE_AT_EDGE)
            {
                // We remove the object here
                try
                {
                    scene.DeleteSceneObject(grp, false);
                }
                catch (Exception)
                {
                    m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border.");
                }
                return;
            }

            int thisx = (int)scene.RegionInfo.RegionLocX;
            int thisy = (int)scene.RegionInfo.RegionLocY;
            Vector3 EastCross = new Vector3(0.1f, 0, 0);
            Vector3 WestCross = new Vector3(-0.1f, 0, 0);
            Vector3 NorthCross = new Vector3(0, 0.1f, 0);
            Vector3 SouthCross = new Vector3(0, -0.1f, 0);


            // use this if no borders were crossed!
            ulong newRegionHandle
                        = Util.UIntsToLong((uint)((thisx) * Constants.RegionSize),
                                           (uint)((thisy) * Constants.RegionSize));

            Vector3 pos = attemptedPosition;

            int changeX = 1;
            int changeY = 1;

            if (scene.TestBorderCross(attemptedPosition + WestCross, Cardinals.W))
            {
                if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
                {

                    Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);

                    if (crossedBorderx.BorderLine.Z > 0)
                    {
                        pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
                        changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.X = ((pos.X + Constants.RegionSize));

                    Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                    //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                    if (crossedBordery.BorderLine.Z > 0)
                    {
                        pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                        changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.Y = ((pos.Y + Constants.RegionSize));



                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
                                           (uint)((thisy - changeY) * Constants.RegionSize));
                    // x - 1
                    // y - 1
                }
                else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
                {
                    Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);

                    if (crossedBorderx.BorderLine.Z > 0)
                    {
                        pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
                        changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.X = ((pos.X + Constants.RegionSize));


                    Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                    //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                    if (crossedBordery.BorderLine.Z > 0)
                    {
                        pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                        changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.Y = ((pos.Y + Constants.RegionSize));

                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
                                           (uint)((thisy + changeY) * Constants.RegionSize));
                    // x - 1
                    // y + 1
                }
                else
                {
                    Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);

                    if (crossedBorderx.BorderLine.Z > 0)
                    {
                        pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
                        changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.X = ((pos.X + Constants.RegionSize));

                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
                                           (uint)(thisy * Constants.RegionSize));
                    // x - 1
                }
            }
            else if (scene.TestBorderCross(attemptedPosition + EastCross, Cardinals.E))
            {
                if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
                {

                    pos.X = ((pos.X - Constants.RegionSize));
                    Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                    //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                    if (crossedBordery.BorderLine.Z > 0)
                    {
                        pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                        changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.Y = ((pos.Y + Constants.RegionSize));


                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
                                           (uint)((thisy - changeY) * Constants.RegionSize));
                    // x + 1
                    // y - 1
                }
                else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
                {
                    pos.X = ((pos.X - Constants.RegionSize));
                    pos.Y = ((pos.Y - Constants.RegionSize));
                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
                                           (uint)((thisy + changeY) * Constants.RegionSize));
                    // x + 1
                    // y + 1
                }
                else
                {
                    pos.X = ((pos.X - Constants.RegionSize));
                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
                                           (uint)(thisy * Constants.RegionSize));
                    // x + 1
                }
            }
            else if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
            {
                Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                if (crossedBordery.BorderLine.Z > 0)
                {
                    pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                    changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                }
                else
                    pos.Y = ((pos.Y + Constants.RegionSize));

                newRegionHandle
                    = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - changeY) * Constants.RegionSize));
                // y - 1
            }
            else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
            {

                pos.Y = ((pos.Y - Constants.RegionSize));
                newRegionHandle
                    = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize));
                // y + 1
            }

            // Offset the positions for the new region across the border
            Vector3 oldGroupPosition = grp.RootPart.GroupPosition;

            // If we fail to cross the border, then reset the position of the scene object on that border.
            uint x = 0, y = 0;
            Utils.LongToUInts(newRegionHandle, out x, out y);
            GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);

            if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
            {
                m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID);

                // We are going to move the object back to the old position so long as the old position
                // is in the region
                oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1);
                oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1);
                oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f);

                grp.RootPart.GroupPosition = oldGroupPosition;

                // Need to turn off the physics flags, otherwise the object will continue to attempt to
                // move out of the region creating an infinite loop of failed attempts to cross
                grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);

                grp.ScheduleGroupForFullUpdate();
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Move the given scene object into a new region depending on which region its absolute position has moved
        /// into.
        ///
        /// This method locates the new region handle and offsets the prim position for the new region
        /// </summary>
        /// <param name="attemptedPosition">the attempted out of region position of the scene object</param>
        /// <param name="grp">the scene object that we're crossing</param>
        public void CrossPrimGroupIntoNewRegion(Vector3 attemptedPosition, SceneObjectGroup grp, bool silent)
        {
            if (grp == null)
                return;
            if (grp.IsDeleted)
                return;

            if (grp.RootPart.DIE_AT_EDGE)
            {
                // We remove the object here
                try
                {
                    DeleteSceneObject(grp, false);
                }
                catch (Exception)
                {
                    m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border.");
                }
                return;
            }

            if (grp.RootPart.RETURN_AT_EDGE)
            {
                // We remove the object here
                try
                {
                    List<SceneObjectGroup> objects = new List<SceneObjectGroup>();
                    objects.Add(grp);
                    SceneObjectGroup[] objectsArray = objects.ToArray();
                    returnObjects(objectsArray, UUID.Zero);
                }
                catch (Exception)
                {
                    m_log.Warn("[DATABASE]: exception when trying to return the prim that crossed the border.");
                }
                return;
            }

            int thisx = (int)RegionInfo.RegionLocX;
            int thisy = (int)RegionInfo.RegionLocY;
            Vector3 EastCross = new Vector3(0.1f,0,0);
            Vector3 WestCross = new Vector3(-0.1f, 0, 0);
            Vector3 NorthCross = new Vector3(0, 0.1f, 0);
            Vector3 SouthCross = new Vector3(0, -0.1f, 0);

            
            // use this if no borders were crossed!
            ulong newRegionHandle
                        = Util.UIntsToLong((uint)((thisx) * Constants.RegionSize),
                                           (uint)((thisy) * Constants.RegionSize));

            Vector3 pos = attemptedPosition;

            int changeX = 1;
            int changeY = 1;

            if (TestBorderCross(attemptedPosition + WestCross, Cardinals.W))
            {
                if (TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
                {

                    Border crossedBorderx = GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);

                    if (crossedBorderx.BorderLine.Z > 0)
                    {
                        pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
                        changeX = (int)(crossedBorderx.BorderLine.Z /(int) Constants.RegionSize);
                    }
                    else
                        pos.X = ((pos.X + Constants.RegionSize));

                    Border crossedBordery = GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                    //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                    if (crossedBordery.BorderLine.Z > 0)
                    {
                        pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                        changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.Y = ((pos.Y + Constants.RegionSize));


                    
                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
                                           (uint)((thisy - changeY) * Constants.RegionSize));
                    // x - 1
                    // y - 1
                }
                else if (TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
                {
                    Border crossedBorderx = GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);

                    if (crossedBorderx.BorderLine.Z > 0)
                    {
                        pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
                        changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.X = ((pos.X + Constants.RegionSize));


                    Border crossedBordery = GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                    //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                    try
                    {
                        if (crossedBordery.BorderLine.Z > 0)
                        {
                            pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                            changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                        }
                        else
                            pos.Y = ((pos.Y + Constants.RegionSize));

                        newRegionHandle
                            = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
                                               (uint)((thisy + changeY) * Constants.RegionSize));
                        // x - 1
                        // y + 1
                    }
                    catch (Exception ex)
                    {
                    }
                }
                else
                {
                    Border crossedBorderx = GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);

                    if (crossedBorderx.BorderLine.Z > 0)
                    {
                        pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
                        changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.X = ((pos.X + Constants.RegionSize));
                       
                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
                                           (uint) (thisy*Constants.RegionSize));
                    // x - 1
                }
            }
            else if (TestBorderCross(attemptedPosition + EastCross, Cardinals.E))
            {
                if (TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
                {
                    
                    pos.X = ((pos.X - Constants.RegionSize));
                    Border crossedBordery = GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                    //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                    if (crossedBordery.BorderLine.Z > 0)
                    {
                        pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                        changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.Y = ((pos.Y + Constants.RegionSize));
                    
                    
                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
                                           (uint)((thisy - changeY) * Constants.RegionSize));
                    // x + 1
                    // y - 1
                }
                else if (TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
                {
                    pos.X = ((pos.X - Constants.RegionSize));
                    pos.Y = ((pos.Y - Constants.RegionSize));
                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
                                           (uint)((thisy + changeY) * Constants.RegionSize));
                    // x + 1
                    // y + 1
                }
                else
                {
                    pos.X = ((pos.X - Constants.RegionSize));
                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
                                           (uint) (thisy*Constants.RegionSize));
                    // x + 1
                }
            } 
            else if (TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
            {
                Border crossedBordery = GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                if (crossedBordery.BorderLine.Z > 0)
                {
                    pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                    changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                }
                else
                    pos.Y = ((pos.Y + Constants.RegionSize));

                newRegionHandle
                    = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - changeY) * Constants.RegionSize));
                // y - 1
            }
            else if (TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
            {
                
                pos.Y = ((pos.Y - Constants.RegionSize));
                newRegionHandle
                    = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize));
                // y + 1
            }

            // Offset the positions for the new region across the border
            Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
            grp.OffsetForNewRegion(pos);

            // If we fail to cross the border, then reset the position of the scene object on that border.
            if (!CrossPrimGroupIntoNewRegion(newRegionHandle, grp, silent))
            {
                grp.OffsetForNewRegion(oldGroupPosition);
                grp.ScheduleGroupForFullUpdate();
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Add an object to the scene.  This will both update the scene, and send information about the
        /// new object to all clients interested in the scene.
        /// </summary>
        /// <remarks>
        /// The object's stored position, rotation and velocity are used.
        /// </remarks>
        /// <param name="sceneObject"></param>
        /// <param name="attachToBackup">
        /// If true, the object is made persistent into the scene.
        /// If false, the object will not persist over server restarts
        /// </param>
        /// <param name="sendClientUpdates">
        /// If true, updates for the new scene object are sent to all viewers in range.
        /// If false, it is left to the caller to schedule the update
        /// </param>
        /// <returns>
        /// true if the object was added, false if an object with the same uuid was already in the scene
        /// </returns>
        protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
        {
            if (sceneObject == null || sceneObject.RootPart.UUID == UUID.Zero)
                return false;

            if (Entities.ContainsKey(sceneObject.UUID))
                return false;
            
//            m_log.DebugFormat(
//                "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}", 
//                sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName);

            SceneObjectPart[] parts = sceneObject.Parts;

            // Clamp child prim sizes and add child prims to the m_numPrim count
            if (m_parentScene.m_clampPrimSize)
            {
                foreach (SceneObjectPart part in parts)
                {
                    Vector3 scale = part.Shape.Scale;

                    if (scale.X > m_parentScene.m_maxNonphys)
                        scale.X = m_parentScene.m_maxNonphys;
                    if (scale.Y > m_parentScene.m_maxNonphys)
                        scale.Y = m_parentScene.m_maxNonphys;
                    if (scale.Z > m_parentScene.m_maxNonphys)
                        scale.Z = m_parentScene.m_maxNonphys;

                    part.Shape.Scale = scale;
                }
            }
            m_numPrim += parts.Length;

            sceneObject.AttachToScene(m_parentScene);

            if (sendClientUpdates)
                sceneObject.ScheduleGroupForFullUpdate();

            Entities.Add(sceneObject);

            if (attachToBackup)
                sceneObject.AttachToBackup();

            if (OnObjectCreate != null)
                OnObjectCreate(sceneObject);

            lock (SceneObjectGroupsByFullID)
                SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
            
            lock (SceneObjectGroupsByFullPartID)
            {
                foreach (SceneObjectPart part in parts)
                    SceneObjectGroupsByFullPartID[part.UUID] = sceneObject;
            }

            lock (SceneObjectGroupsByLocalPartID)
            {
//                m_log.DebugFormat(
//                    "[SCENE GRAPH]: Adding scene object {0} {1} {2} to SceneObjectGroupsByLocalPartID in {3}",
//                    sceneObject.Name, sceneObject.UUID, sceneObject.LocalId, m_parentScene.RegionInfo.RegionName);

                foreach (SceneObjectPart part in parts)
                    SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject;
            }

            return true;
        }
Esempio n. 12
0
        /// <summary>
        /// Add an object to the scene.  This will both update the scene, and send information about the
        /// new object to all clients interested in the scene.
        /// </summary>
        /// <param name="sceneObject"></param>
        /// <param name="attachToBackup">
        /// If true, the object is made persistent into the scene.
        /// If false, the object will not persist over server restarts
        /// </param>
        /// <param name="sendClientUpdates">
        /// If true, updates for the new scene object are sent to all viewers in range.
        /// If false, it is left to the caller to schedule the update
        /// </param>
        /// <returns>
        /// true if the object was added, false if an object with the same uuid was already in the scene
        /// </returns>
        protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
        {
            if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero)
                return false;

            if (Entities.ContainsKey(sceneObject.UUID))
                return false;

            SceneObjectPart[] children = sceneObject.Parts;

            // Clamp child prim sizes and add child prims to the m_numPrim count
            if (m_parentScene.m_clampPrimSize)
            {
                foreach (SceneObjectPart part in children)
                {
                    Vector3 scale = part.Shape.Scale;

                    if (scale.X > m_parentScene.m_maxNonphys)
                        scale.X = m_parentScene.m_maxNonphys;
                    if (scale.Y > m_parentScene.m_maxNonphys)
                        scale.Y = m_parentScene.m_maxNonphys;
                    if (scale.Z > m_parentScene.m_maxNonphys)
                        scale.Z = m_parentScene.m_maxNonphys;

                    part.Shape.Scale = scale;
                }
            }
            m_numPrim += children.Length;

            sceneObject.AttachToScene(m_parentScene);

            if (sendClientUpdates)
                sceneObject.ScheduleGroupForFullUpdate();

            Entities.Add(sceneObject);

            if (attachToBackup)
                sceneObject.AttachToBackup();

            if (OnObjectCreate != null)
                OnObjectCreate(sceneObject);

            lock (SceneObjectGroupsByFullID)
            {
                SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
                foreach (SceneObjectPart part in children)
                    SceneObjectGroupsByFullID[part.UUID] = sceneObject;
            }

            lock (SceneObjectGroupsByLocalID)
            {
                SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
                foreach (SceneObjectPart part in children)
                    SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
            }

            return true;
        }
Esempio n. 13
0
        /// <summary>
        /// Add an object to the scene.  This will both update the scene, and send information about the
        /// new object to all clients interested in the scene.
        /// </summary>
        /// <param name="sceneObject"></param>
        /// <param name="attachToBackup">
        /// If true, the object is made persistent into the scene.
        /// If false, the object will not persist over server restarts
        /// </param>
        /// <param name="sendClientUpdates">
        /// If true, updates for the new scene object are sent to all viewers in range.
        /// If false, it is left to the caller to schedule the update
        /// </param>
        /// <returns>
        /// true if the object was added, false if an object with the same uuid was already in the scene
        /// </returns>
        protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
        {
            if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero)
                return false;

            lock (sceneObject)
            {            
                if (Entities.ContainsKey(sceneObject.UUID))
                {
//                    m_log.WarnFormat(
//                        "[SCENE GRAPH]: Scene object {0} {1} was already in region {2} on add request", 
//                        sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);                    
                    return false;
                }
                   
//                    m_log.DebugFormat(
//                        "[SCENE GRAPH]: Adding object {0} {1} to region {2}", 
//                        sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);                
            
                if (m_parentScene.m_clampPrimSize)
                {
                    foreach (SceneObjectPart part in sceneObject.Children.Values)
                    {
                        Vector3 scale = part.Shape.Scale;
    
                        if (scale.X > m_parentScene.m_maxNonphys)
                            scale.X = m_parentScene.m_maxNonphys;
                        if (scale.Y > m_parentScene.m_maxNonphys)
                            scale.Y = m_parentScene.m_maxNonphys;
                        if (scale.Z > m_parentScene.m_maxNonphys)
                            scale.Z = m_parentScene.m_maxNonphys;
    
                        part.Shape.Scale = scale;
                    }
                }
    
                sceneObject.AttachToScene(m_parentScene);
    
                if (sendClientUpdates)
                    sceneObject.ScheduleGroupForFullUpdate();
                                     
                Entities.Add(sceneObject);
                m_numPrim += sceneObject.Children.Count;

                if (attachToBackup)
                    sceneObject.AttachToBackup();

                if (OnObjectCreate != null)
                    OnObjectCreate(sceneObject);
                
                lock (m_dictionary_lock)
                {
                    SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
                    SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
                    foreach (SceneObjectPart part in sceneObject.Children.Values)
                    {
                        SceneObjectGroupsByFullID[part.UUID] = sceneObject;
                        SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
                    }
                }
            }

            return true;
        }
Esempio n. 14
0
        /// <summary>
        /// Add a given object to the world. If you prefer argument to use default value, when pass it as null. 
        /// *There is 1 compulsory fields which is position of the object. The rest are optionals. 
        /// By Thanakorn Tuanwachat 07/2013
        /// </summary>
        /// <param name="name">Name of this object. Use default value "primative" if null is given</param>
        /// <param name="position">"Vector(x y z) where x, y, and z represent the coordinates in the world"</param>
        /// <param name="dimension">"Vector(x, y, z) where x, y, and z represent the size of the object"</param>
        /// <param name="rotation">double(x, y, z) where x, y, and z represent angle of rotation from its axis in radian</param>
        /// <param name="primType">There are only 3 types which are Box, </param>
        /// <param name="script"> The LSL script which will be attached to this object</param>
        public void addObjectToTheWorld(string name, Vector3 position, Vector3 dimension, Quaternion rotation, int primType, string script)
        {

            //Generate a new UUID for this ray
            UUID rayUUID = UUID.Random();

            //Place an object into the world. It can either be Box, Sphere, or Cylinder. according to the given PrimType

            SceneObjectGroup sog;
            switch (primType)
            {
                case PrimType.Box:
                    sog = new SceneObjectGroup(new UUID(rayUUID), position, OpenSim.Framework.PrimitiveBaseShape.CreateBox());
                    break;
                case PrimType.Sphere:
                    sog = new SceneObjectGroup(new UUID(rayUUID), position, OpenSim.Framework.PrimitiveBaseShape.CreateSphere());
                    break;
                case PrimType.Cylinder:
                    sog = new SceneObjectGroup(new UUID(rayUUID), position, OpenSim.Framework.PrimitiveBaseShape.CreateCylinder());
                    break;
                default:
                    sog = new SceneObjectGroup(new UUID(rayUUID), position, OpenSim.Framework.PrimitiveBaseShape.CreateBox());
                    break;
            }//switch

            //Check if it is possible to set thses parameters. If not then use default value

            if(dimension != null)
            {
              sog.RootPart.Scale = dimension;
            }
            if(rotation != null)
            {
                sog.RootPart.UpdateRotation(rotation);
            }//if
            if(name != null)
            {
                sog.Name = name;
            }//if
            else
            {
                sog.Name = "Primative";
            }//else
            if (script != null)
            {
                addScript(sog.RootPart, script);
            }

            //Add this object to the scene.

            m_scene.AddNewSceneObject(sog, false);
            sog.ScheduleGroupForFullUpdate();
            sog.HasGroupChanged = true;

            addedSog.Add(sog);
        }
Esempio n. 15
0
        /// <summary>
        /// Move the given scene object into a new region depending on which region its absolute position has moved
        /// into.
        ///
        /// This method locates the new region handle and offsets the prim position for the new region
        /// </summary>
        /// <param name="attemptedPosition">the attempted out of region position of the scene object</param>
        /// <param name="grp">the scene object that we're crossing</param>
        public void CrossPrimGroupIntoNewRegion(Vector3 attemptedPosition, SceneObjectGroup grp, bool silent)
        {
            if (grp == null)
                return;
            if (grp.IsDeleted)
                return;

            if (grp.RootPart.DIE_AT_EDGE)
            {
                // We remove the object here
                try
                {
                    DeleteSceneObject(grp, false);
                }
                catch (Exception)
                {
                    m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border.");
                }
                return;
            }

            int thisx = (int)RegionInfo.RegionLocX;
            int thisy = (int)RegionInfo.RegionLocY;

            ulong newRegionHandle = 0;
            Vector3 pos = attemptedPosition;

            if (attemptedPosition.X > Constants.RegionSize + 0.1f)
            {
                pos.X = ((pos.X - Constants.RegionSize));
                newRegionHandle
                    = Util.UIntsToLong((uint)((thisx + 1) * Constants.RegionSize), (uint)(thisy * Constants.RegionSize));
                // x + 1
            }
            else if (attemptedPosition.X < -0.1f)
            {
                pos.X = ((pos.X + Constants.RegionSize));
                newRegionHandle
                    = Util.UIntsToLong((uint)((thisx - 1) * Constants.RegionSize), (uint)(thisy * Constants.RegionSize));
                // x - 1
            }

            if (attemptedPosition.Y > Constants.RegionSize + 0.1f)
            {
                pos.Y = ((pos.Y - Constants.RegionSize));
                newRegionHandle
                    = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + 1) * Constants.RegionSize));
                // y + 1
            }
            else if (attemptedPosition.Y < -0.1f)
            {
                pos.Y = ((pos.Y + Constants.RegionSize));
                newRegionHandle
                    = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - 1) * Constants.RegionSize));
                // y - 1
            }

            // Offset the positions for the new region across the border
            Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
            grp.OffsetForNewRegion(pos);

            // If we fail to cross the border, then reset the position of the scene object on that border.
            if (!CrossPrimGroupIntoNewRegion(newRegionHandle, grp, silent))
            {
                grp.OffsetForNewRegion(oldGroupPosition);
                grp.ScheduleGroupForFullUpdate();
            }
        }
Esempio n. 16
0
        /// <summary>
        /// Attach this scene object to the given avatar.
        /// </summary>
        /// <remarks>
        /// This isn't publicly available since attachments should always perform the corresponding inventory 
        /// operation (to show the attach in user inventory and update the asset with positional information).
        /// </remarks>
        /// <param name="sp"></param>
        /// <param name="so"></param>
        /// <param name="attachmentpoint"></param>
        /// <param name="attachOffset"></param>
        /// <param name="silent"></param>
        private void AttachToAgent(
            IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
        {
            //            m_log.DebugFormat(
            //                "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
            //                so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);

            so.DetachFromBackup();

            // Remove from database and parcel prim count
            m_scene.DeleteFromStorage(so.UUID);
            m_scene.EventManager.TriggerParcelPrimCountTainted();

            so.AttachedAvatar = sp.UUID;

            if (so.RootPart.PhysActor != null)
                so.RootPart.RemoveFromPhysics();

            so.AbsolutePosition = attachOffset;
            so.RootPart.AttachedPos = attachOffset;
            so.IsAttachment = true;
            so.RootPart.SetParentLocalId(sp.LocalId);
            so.AttachmentPoint = attachmentpoint;

            sp.AddAttachment(so);

            if (!silent)
            {
                // Killing it here will cause the client to deselect it
                // It then reappears on the avatar, deselected
                // through the full update below
                //
                if (so.IsSelected)
                {
                    m_scene.SendKillObject(new List<uint> { so.RootPart.LocalId });
                }

                so.IsSelected = false; // fudge....
                so.ScheduleGroupForFullUpdate();
            }

            // In case it is later dropped again, don't let
            // it get cleaned up
            so.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
        }
Esempio n. 17
0
        /// <summary>
        /// Attach this scene object to the given avatar.
        /// </summary>
        /// <remarks>
        /// This isn't publicly available since attachments should always perform the corresponding inventory 
        /// operation (to show the attach in user inventory and update the asset with positional information).
        /// </remarks>
        /// <param name="sp"></param>
        /// <param name="so"></param>
        /// <param name="attachmentpoint"></param>
        /// <param name="attachOffset"></param>
        /// <param name="silent"></param>
        private void AttachToAgent(
            IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
        {
//            m_log.DebugFormat(
//                "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
//                so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);

            so.DetachFromBackup();

            // Remove from database and parcel prim count
            m_scene.DeleteFromStorage(so.UUID);
            m_scene.EventManager.TriggerParcelPrimCountTainted();

            so.AttachedAvatar = sp.UUID;

            if (so.RootPart.PhysActor != null)
                so.RootPart.RemoveFromPhysics();

            so.AbsolutePosition = attachOffset;
            so.RootPart.AttachedPos = attachOffset;
            so.IsAttachment = true;
            so.RootPart.SetParentLocalId(sp.LocalId);
            so.AttachmentPoint = attachmentpoint;

            sp.AddAttachment(so);

            if (!silent)
            {
                // Killing it here will cause the client to deselect it
                // It then reappears on the avatar, deselected
                // through the full update below
                //
                if (so.IsSelected)
                {
                    m_scene.SendKillObject(new List<uint> { so.RootPart.LocalId });
                }
                else if (so.HasPrivateAttachmentPoint)
                {
//                    m_log.DebugFormat(
//                        "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}",
//                        so.Name, sp.Name, so.AttachmentPoint);

                    // As this scene object can now only be seen by the attaching avatar, tell everybody else in the
                    // scene that it's no longer in their awareness.
                    m_scene.ForEachClient(
                        client =>
                            { if (client.AgentId != so.AttachedAvatar)
                                client.SendKillObject(m_scene.RegionInfo.RegionHandle, new List<uint>() { so.LocalId });
                            });
                }

                so.IsSelected = false; // fudge....
                so.ScheduleGroupForFullUpdate();
            }

            // In case it is later dropped again, don't let
            // it get cleaned up
            so.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
        }
Esempio n. 18
0
        /// <summary>
        /// Add an object to the scene.  This will both update the scene, and send information about the
        /// new object to all clients interested in the scene.
        /// </summary>
        /// <remarks>
        /// The object's stored position, rotation and velocity are used.
        /// </remarks>
        /// <param name="sceneObject"></param>
        /// <param name="attachToBackup">
        /// If true, the object is made persistent into the scene.
        /// If false, the object will not persist over server restarts
        /// </param>
        /// <param name="sendClientUpdates">
        /// If true, updates for the new scene object are sent to all viewers in range.
        /// If false, it is left to the caller to schedule the update
        /// </param>
        /// <returns>
        /// true if the object was added, false if an object with the same uuid was already in the scene
        /// </returns>
        protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
        {
            if (sceneObject == null)
            {
                m_log.ErrorFormat("[SCENEGRAPH]: Tried to add null scene object");
                return false;
            }
            if (sceneObject.UUID == UUID.Zero)
            {
                m_log.ErrorFormat(
                    "[SCENEGRAPH]: Tried to add scene object {0} to {1} with illegal UUID of {2}",
                    sceneObject.Name, m_parentScene.RegionInfo.RegionName, UUID.Zero);

                return false;
            }

            if (Entities.ContainsKey(sceneObject.UUID))
            {
                m_log.DebugFormat(
                    "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()",
                    m_parentScene.RegionInfo.RegionName, sceneObject.UUID);

                return false;
            }

//            m_log.DebugFormat(
//                "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}",
//                sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName);

            SceneObjectPart[] parts = sceneObject.Parts;

            // Clamp the sizes (scales) of the child prims and add the child prims to the count of all primitives
            // (meshes and geometric primitives) in the scene; add child prims to m_numTotalPrim count
            if (m_parentScene.m_clampPrimSize)
            {
                foreach (SceneObjectPart part in parts)
                {
                    Vector3 scale = part.Shape.Scale;

                    scale.X = Util.Clamp(scale.X, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys);
                    scale.Y = Util.Clamp(scale.Y, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys);
                    scale.Z = Util.Clamp(scale.Z, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys);

                    part.Shape.Scale = scale;
                }
            }
            m_numTotalPrim += parts.Length;

            // Go through all parts (geometric primitives and meshes) of this Scene Object
            foreach (SceneObjectPart part in parts)
            {
                // Keep track of the total number of meshes or geometric primitives now in the scene;
                // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to
                // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives
                if (part.GetPrimType() == PrimType.SCULPT)
                    m_numMesh++;
                else
                    m_numPrim++;
            }

            sceneObject.AttachToScene(m_parentScene);

            Entities.Add(sceneObject);

            lock (SceneObjectGroupsByFullID)
                SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;

            foreach (SceneObjectPart part in parts)
            {
                lock (SceneObjectGroupsByFullPartID)
                    SceneObjectGroupsByFullPartID[part.UUID] = sceneObject;

                lock (SceneObjectGroupsByLocalPartID)
                    SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject;
            }

            if (sendClientUpdates)
                sceneObject.ScheduleGroupForFullUpdate();

            if (attachToBackup)
                sceneObject.AttachToBackup();

            return true;
        }
Esempio n. 19
0
        /// <summary>
        /// Attach this scene object to the given avatar.
        /// </summary>
        /// 
        /// This isn't publicly available since attachments should always perform the corresponding inventory 
        /// operation (to show the attach in user inventory and update the asset with positional information).
        /// 
        /// <param name="sp"></param>
        /// <param name="so"></param>
        /// <param name="attachmentpoint"></param>
        /// <param name="AttachOffset"></param>
        /// <param name="silent"></param>
        protected void AttachToAgent(ScenePresence avatar, SceneObjectGroup so, int attachmentpoint, Vector3 AttachOffset, bool silent)
        {
            // don't attach attachments to child agents
            if (avatar.IsChildAgent) return;

            //                m_log.DebugFormat("[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1}", Name, avatar.Name);

            so.DetachFromBackup();

            // Remove from database and parcel prim count
            m_scene.DeleteFromStorage(so.UUID);
            m_scene.EventManager.TriggerParcelPrimCountTainted();

            so.RootPart.AttachedAvatar = avatar.UUID;

            //Anakin Lohner bug #3839 
            SceneObjectPart[] parts = so.Parts;
            for (int i = 0; i < parts.Length; i++)
                parts[i].AttachedAvatar = avatar.UUID;

            if (so.RootPart.PhysActor != null)
            {
                m_scene.PhysicsScene.RemovePrim(so.RootPart.PhysActor);
                so.RootPart.PhysActor = null;
            }

            so.AbsolutePosition = AttachOffset;
            so.RootPart.AttachedPos = AttachOffset;
            so.RootPart.IsAttachment = true;

            so.RootPart.SetParentLocalId(avatar.LocalId);
            so.SetAttachmentPoint(Convert.ToByte(attachmentpoint));

            avatar.AddAttachment(so);

            if (!silent)
            {
                // Killing it here will cause the client to deselect it
                // It then reappears on the avatar, deselected
                // through the full update below
                //
                if (so.IsSelected)
                {
                    m_scene.SendKillObject(so.RootPart.LocalId);
                }

                so.IsSelected = false; // fudge....
                so.ScheduleGroupForFullUpdate(PrimUpdateFlags.FullUpdate);
            }

            // In case it is later dropped again, don't let
            // it get cleaned up
            so.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
            so.HasGroupChanged = false;
        }
Esempio n. 20
0
        /// <summary>
        /// Move the given scene object into a new region depending on which region its absolute position has moved
        /// into.
        ///
        /// This method locates the new region handle and offsets the prim position for the new region
        /// </summary>
        /// <param name="attemptedPosition">the attempted out of region position of the scene object</param>
        /// <param name="grp">the scene object that we're crossing</param>
        public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent)
        {
            if (grp == null)
                return;
            if (grp.IsDeleted)
                return;

            Scene scene = grp.Scene;
            if (scene == null)
                return;

            if (grp.RootPart.DIE_AT_EDGE)
            {
                // We remove the object here
                try
                {
                    scene.DeleteSceneObject(grp, false);
                }
                catch (Exception)
                {
                    m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border.");
                }
                return;
            }

            int thisx = (int)scene.RegionInfo.RegionLocX;
            int thisy = (int)scene.RegionInfo.RegionLocY;
            Vector3 EastCross = new Vector3(0.1f, 0, 0);
            Vector3 WestCross = new Vector3(-0.1f, 0, 0);
            Vector3 NorthCross = new Vector3(0, 0.1f, 0);
            Vector3 SouthCross = new Vector3(0, -0.1f, 0);


            // use this if no borders were crossed!
            ulong newRegionHandle
                        = Util.UIntsToLong((uint)((thisx) * Constants.RegionSize),
                                           (uint)((thisy) * Constants.RegionSize));

            Vector3 pos = attemptedPosition;

            int changeX = 1;
            int changeY = 1;

            if (scene.TestBorderCross(attemptedPosition + WestCross, Cardinals.W))
            {
                if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
                {

                    Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);

                    if (crossedBorderx.BorderLine.Z > 0)
                    {
                        pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
                        changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.X = ((pos.X + Constants.RegionSize));

                    Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                    //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                    if (crossedBordery.BorderLine.Z > 0)
                    {
                        pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                        changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.Y = ((pos.Y + Constants.RegionSize));



                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
                                           (uint)((thisy - changeY) * Constants.RegionSize));
                    // x - 1
                    // y - 1
                }
                else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
                {
                    Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);

                    if (crossedBorderx.BorderLine.Z > 0)
                    {
                        pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
                        changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.X = ((pos.X + Constants.RegionSize));


                    Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                    //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                    if (crossedBordery.BorderLine.Z > 0)
                    {
                        pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                        changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.Y = ((pos.Y + Constants.RegionSize));

                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
                                           (uint)((thisy + changeY) * Constants.RegionSize));
                    // x - 1
                    // y + 1
                }
                else
                {
                    Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);

                    if (crossedBorderx.BorderLine.Z > 0)
                    {
                        pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
                        changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.X = ((pos.X + Constants.RegionSize));

                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
                                           (uint)(thisy * Constants.RegionSize));
                    // x - 1
                }
            }
            else if (scene.TestBorderCross(attemptedPosition + EastCross, Cardinals.E))
            {
                if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
                {

                    pos.X = ((pos.X - Constants.RegionSize));
                    Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                    //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                    if (crossedBordery.BorderLine.Z > 0)
                    {
                        pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                        changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.Y = ((pos.Y + Constants.RegionSize));


                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
                                           (uint)((thisy - changeY) * Constants.RegionSize));
                    // x + 1
                    // y - 1
                }
                else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
                {
                    pos.X = ((pos.X - Constants.RegionSize));
                    pos.Y = ((pos.Y - Constants.RegionSize));
                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
                                           (uint)((thisy + changeY) * Constants.RegionSize));
                    // x + 1
                    // y + 1
                }
                else
                {
                    pos.X = ((pos.X - Constants.RegionSize));
                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
                                           (uint)(thisy * Constants.RegionSize));
                    // x + 1
                }
            }
            else if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
            {
                Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                if (crossedBordery.BorderLine.Z > 0)
                {
                    pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                    changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                }
                else
                    pos.Y = ((pos.Y + Constants.RegionSize));

                newRegionHandle
                    = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - changeY) * Constants.RegionSize));
                // y - 1
            }
            else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
            {

                pos.Y = ((pos.Y - Constants.RegionSize));
                newRegionHandle
                    = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize));
                // y + 1
            }

            // Offset the positions for the new region across the border
            Vector3 oldGroupPosition = grp.RootPart.GroupPosition;

            // If we fail to cross the border, then reset the position of the scene object on that border.
            uint x = 0, y = 0;
            Utils.LongToUInts(newRegionHandle, out x, out y);
            GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);

            if (destination != null)
            {
                if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
                    return; // we did it
            }

            // no one or failed lets go back and tell physics to go on
            oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f);
            oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
            oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);

            grp.AbsolutePosition = oldGroupPosition;
            grp.Velocity = Vector3.Zero;

            if (grp.RootPart.PhysActor != null)
                grp.RootPart.PhysActor.CrossingFailure();

            if (grp.RootPart.KeyframeMotion != null)
                grp.RootPart.KeyframeMotion.CrossingFailure();

            grp.ScheduleGroupForFullUpdate();
        }
        public UUID tsuccirRezLinkset(UUID host, UUID script, int numberOfChildPrims)
        {
            numberOfChildPrims = Math.Max(0, numberOfChildPrims);

            SceneObjectPart part = m_scene.GetSceneObjectPart(host);

            if (part == null || !m_scene.Permissions.CanRezObject(1 + numberOfChildPrims, part.OwnerID, Vector3.Zero))
                return UUID.Zero;

            SceneObjectGroup newGroup = new SceneObjectGroup(part.OwnerID, part.AbsolutePosition, Quaternion.Identity, PrimitiveBaseShape.Default);
            for (int i = 0; i < numberOfChildPrims; ++i)
            {
                newGroup.AddPart(new SceneObjectPart(part.OwnerID, PrimitiveBaseShape.Default, part.AbsolutePosition, Quaternion.Identity, Vector3.Zero));
            }

            if (!m_scene.SceneGraph.AddNewSceneObject(newGroup, true, part.AbsolutePosition, Quaternion.Identity, Vector3.Zero))
            {
                ScriptError(part, "Failed to add linkset to scene graph.");
                return UUID.Zero;
            }
            else
            {
                newGroup.FromPartID = host;
                newGroup.ScheduleGroupForFullUpdate();
                IScriptModule[] modules = m_scene.RequestModuleInterfaces<IScriptModule>();
                foreach (IScriptModule module in modules)
                {
                    module.PostObjectEvent(host, "object_rez", new object[] { new LSL_String(newGroup.UUID.ToString()) });
                }
                return newGroup.UUID;
            }
        }
Esempio n. 22
0
        public void DelinkFromGroup(SceneObjectPart linkPart, bool sendEvents, bool sendGroupUpdate)
        {
            linkPart.ClearUndoState();
            //                m_log.DebugFormat(
            //                    "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}",
            //                    linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID);

            Quaternion worldRot = linkPart.GetWorldRotation();

            // Remove the part from this object
            lock (m_parts)
            {
                m_parts.Remove(linkPart.UUID);
                _partsByLocalId.Remove(linkPart.LocalId);

                if (m_parts.Count == 1 && RootPart != null) //Single prim is left
                {
                    RootPart.LinkNum = 0;
                }
                else
                {
                    foreach (SceneObjectPart p in m_parts.Values)
                    {
                        if (p.LinkNum > linkPart.LinkNum)
                            p.LinkNum--;
                    }
                }
            }

            linkPart.ParentID = 0;
            linkPart.LinkNum = 0;

            // We need to reset the child part's position
            // ready for life as a separate object after being a part of another object
            Quaternion parentRot = m_rootPart.RotationOffset;

            Vector3 axPos = linkPart.OffsetPosition;
            axPos *= parentRot;

            Vector3 groupPosition = AbsolutePosition + axPos;

            linkPart.SetGroupPositionDirect(groupPosition);
            linkPart.SetOffsetPositionDirect(Vector3.Zero);
            linkPart.SetRotationOffsetDirect(worldRot);

            SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart);

            PhysicsActor partActor = linkPart.PhysActor;
            if (partActor != null)
            {
                partActor.DelinkFromParent(groupPosition, worldRot);
            }

            m_scene.AddNewSceneObject(objectGroup, true);

            if (sendEvents)
                linkPart.TriggerScriptChangedEvent(Changed.LINK);

            linkPart.Rezzed = RootPart.Rezzed;

            //Rebuild the bounding box
            ClearBoundingBoxCache();

            // Update the ServerWeight/LandImpact and StreamingCost
            RecalcPrimWeights();

            if (sendGroupUpdate)
            {
                HasGroupChanged = true;
                ScheduleGroupForFullUpdate();
                objectGroup.ScheduleGroupForFullUpdate();
            }
        }
        /// <summary>
        /// Move the given scene object into a new region depending on which region its absolute position has moved
        /// into.
        ///
        /// This method locates the new region handle and offsets the prim position for the new region
        /// </summary>
        /// <param name="attemptedPosition">the attempted out of region position of the scene object</param>
        /// <param name="grp">the scene object that we're crossing</param>
        public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent)
        {
            if (grp == null)
                return;
            if (grp.IsDeleted)
                return;

            Scene scene = grp.Scene;
            if (scene == null)
                return;

            if (grp.RootPart.DIE_AT_EDGE)
            {
                // We remove the object here
                try
                {
                    scene.DeleteSceneObject(grp, false);
                }
                catch (Exception)
                {
                    m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border.");
                }
                return;
            }

            int thisx = (int)scene.RegionInfo.RegionLocX;
            int thisy = (int)scene.RegionInfo.RegionLocY;


/*
            Vector3 EastCross = new Vector3(0.1f, 0, 0);
            Vector3 WestCross = new Vector3(-0.1f, 0, 0);
            Vector3 NorthCross = new Vector3(0, 0.1f, 0);
            Vector3 SouthCross = new Vector3(0, -0.1f, 0);


            // use this if no borders were crossed!
            ulong newRegionHandle
                        = Util.UIntsToLong((uint)((thisx) * Constants.RegionSize),
                                           (uint)((thisy) * Constants.RegionSize));

            Vector3 pos = attemptedPosition;

            int changeX = 1;
            int changeY = 1;

            if (scene.TestBorderCross(attemptedPosition + WestCross, Cardinals.W))
            {
                if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
                {

                    Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);

                    if (crossedBorderx.BorderLine.Z > 0)
                    {
                        pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
                        changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.X = ((pos.X + Constants.RegionSize));

                    Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                    //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                    if (crossedBordery.BorderLine.Z > 0)
                    {
                        pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                        changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.Y = ((pos.Y + Constants.RegionSize));



                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
                                           (uint)((thisy - changeY) * Constants.RegionSize));
                    // x - 1
                    // y - 1
                }
                else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
                {
                    Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);

                    if (crossedBorderx.BorderLine.Z > 0)
                    {
                        pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
                        changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.X = ((pos.X + Constants.RegionSize));


                    Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                    //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                    if (crossedBordery.BorderLine.Z > 0)
                    {
                        pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                        changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.Y = ((pos.Y + Constants.RegionSize));

                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
                                           (uint)((thisy + changeY) * Constants.RegionSize));
                    // x - 1
                    // y + 1
                }
                else
                {
                    Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);

                    if (crossedBorderx.BorderLine.Z > 0)
                    {
                        pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
                        changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.X = ((pos.X + Constants.RegionSize));

                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
                                           (uint)(thisy * Constants.RegionSize));
                    // x - 1
                }
            }
            else if (scene.TestBorderCross(attemptedPosition + EastCross, Cardinals.E))
            {
                if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
                {

                    pos.X = ((pos.X - Constants.RegionSize));
                    Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                    //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                    if (crossedBordery.BorderLine.Z > 0)
                    {
                        pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                        changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                    }
                    else
                        pos.Y = ((pos.Y + Constants.RegionSize));


                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
                                           (uint)((thisy - changeY) * Constants.RegionSize));
                    // x + 1
                    // y - 1
                }
                else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
                {
                    pos.X = ((pos.X - Constants.RegionSize));
                    pos.Y = ((pos.Y - Constants.RegionSize));
                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
                                           (uint)((thisy + changeY) * Constants.RegionSize));
                    // x + 1
                    // y + 1
                }
                else
                {
                    pos.X = ((pos.X - Constants.RegionSize));
                    newRegionHandle
                        = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
                                           (uint)(thisy * Constants.RegionSize));
                    // x + 1
                }
            }
            else if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
            {
                Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
                //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)

                if (crossedBordery.BorderLine.Z > 0)
                {
                    pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
                    changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
                }
                else
                    pos.Y = ((pos.Y + Constants.RegionSize));

                newRegionHandle
                    = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - changeY) * Constants.RegionSize));
                // y - 1
            }
            else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
            {

                pos.Y = ((pos.Y - Constants.RegionSize));
                newRegionHandle
                    = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize));
                // y + 1
            }

 */
            // If we fail to cross the border, then reset the position of the scene object on that border.
//            Utils.LongToUInts(newRegionHandle, out x, out y);

            int x, y;
            Vector3 pos = attemptedPosition;
            Vector3 newpos = pos;
            float boundaryDistance = 1.0f;

            if (scene.RegionInfo.CombinedRegionHandle != 0) // we are a slave region send to main region
            {
                uint tmp1;
                uint tmp2;

                Utils.LongToUInts(scene.RegionInfo.CombinedRegionHandle, out tmp1, out tmp2);
                x = (int)tmp1;
                y = (int)tmp2;

                newpos.X += ((int)scene.RegionInfo.RegionLocX * Constants.RegionSize - x);
                newpos.Y += ((int)scene.RegionInfo.RegionLocY * Constants.RegionSize - y);
            }
            else
            {
                if (pos.X - boundaryDistance < 0) // going W
                {
                    x = -1;
                    newpos.X = Constants.RegionSize + pos.X - boundaryDistance;
                }
                else // assume we are going E
                {
                    x = ((int)(pos.X + boundaryDistance) / (int)Constants.RegionSize);
                    newpos.X = pos.X - x * (int)Constants.RegionSize;
                }

                x += (int)scene.RegionInfo.RegionLocX;
                x *= (int)Constants.RegionSize;

                if (pos.Y - boundaryDistance < 0) // going S  SW or SE
                {
                    y = -1;
                    newpos.Y = Constants.RegionSize + pos.Y - boundaryDistance;
                }
                else // assume we are going N NW or NE
                {
                    y = ((int)(pos.Y + boundaryDistance) / (int)Constants.RegionSize);
                    newpos.Y = pos.Y - y * (int)Constants.RegionSize;
                }

                y += (int)scene.RegionInfo.RegionLocY;
                y *= (int)Constants.RegionSize;
            }

            //            int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);

            ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);

            GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);

            if (destination == null)
            {
                // let physics know (for now ode needs this)
                if (!grp.IsDeleted)
                {
                    if (grp.RootPart.PhysActor != null)
                    {
                        grp.RootPart.PhysActor.CrossingFailure();
                    }
                }
            }

            else
            {
                // Offset the positions for the new region across the border
                Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
                grp.RootPart.GroupPosition = newpos;
                if (!CrossPrimGroupIntoNewRegion(destination, grp, silent))
                {
                    if (!grp.IsDeleted)
                    {
                        grp.RootPart.GroupPosition = oldGroupPosition;
                        if (grp.RootPart.PhysActor != null)
                        {
                            grp.RootPart.PhysActor.CrossingFailure();
                        }
                        grp.ScheduleGroupForFullUpdate();
                    }
                }
            }
        }
Esempio n. 24
0
        public virtual SceneObjectGroup AddNewPrim(
            UUID ownerID, UUID groupID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape)
        {
            //m_log.DebugFormat(
            //    "[SCENE]: Scene.AddNewPrim() pcode {0} called for {1} in {2}", shape.PCode, ownerID, RegionInfo.RegionName);

            SceneObjectGroup sceneObject = null;

            // If an entity creator has been registered for this prim type then use that
            if (m_entityCreators.ContainsKey((PCode)shape.PCode))
            {
                sceneObject = m_entityCreators[(PCode)shape.PCode].CreateEntity(ownerID, groupID, pos, rot, shape);
            }
            else
            {
                // Otherwise, use this default creation code;
                sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape, this);
                //This has to be set, otherwise it will break things like rezzing objects in an area where crossing is disabled, but rez isn't
                sceneObject.m_lastSignificantPosition = pos;

                AddPrimToScene(sceneObject);
                sceneObject.ScheduleGroupForFullUpdate(PrimUpdateFlags.FullUpdate);
                sceneObject.SetGroup(groupID, null);
            }


            return sceneObject;
        }