/** * Object-related communications */ public bool SendCreateObject(ulong regionHandle, SceneObjectGroup sog, bool isLocalCall, Vector3 posInOtherRegion, bool isAttachment) { foreach (Scene s in m_sceneList) { if (s.RegionInfo.RegionHandle == regionHandle) { //m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); if (isLocalCall) { if (!isAttachment) { sog.OffsetForNewRegion(posInOtherRegion); } // We need to make a local copy of the object ISceneObject sogClone = sog.CloneForNewScene(); sogClone.SetState(sog.GetStateSnapshot(true), s.RegionInfo.RegionID); return s.IncomingCreateObject(sogClone); } else { // Use the object as it came through the wire return s.IncomingCreateObject(sog); } } } return false; }
/// <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); } }
/// <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(); } }
/// <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> ///<param name="destination"></param> public bool CrossGroupToNewRegion(SceneObjectGroup grp, Vector3 attemptedPosition, GridRegion destination) { if (grp == null) return false; if (grp.IsDeleted) return false; if (grp.Scene == null) return false; if (grp.RootPart.DIE_AT_EDGE) { // We remove the object here try { IBackupModule backup = grp.Scene.RequestModuleInterface<IBackupModule>(); if (backup != null) return backup.DeleteSceneObjects(new[] { grp }, true, true); } catch (Exception) { MainConsole.Instance.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border."); } return false; } if (grp.RootPart.RETURN_AT_EDGE) { // We remove the object here try { List<ISceneEntity> objects = new List<ISceneEntity> { grp }; ILLClientInventory inventoryModule = grp.Scene.RequestModuleInterface<ILLClientInventory>(); if (inventoryModule != null) return inventoryModule.ReturnObjects(objects.ToArray(), UUID.Zero); } catch (Exception) { MainConsole.Instance.Warn("[SCENE]: exception when trying to return the prim that crossed the border."); } return false; } Vector3 oldGroupPosition = grp.RootPart.GroupPosition; // If we fail to cross the border, then reset the position of the scene object on that border. if (destination != null && !CrossPrimGroupIntoNewRegion(destination, grp, attemptedPosition)) { grp.OffsetForNewRegion(oldGroupPosition); grp.ScheduleGroupUpdate (PrimUpdateFlags.ForcedFullUpdate); return false; } return true; }
/// <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(); } }