29 using System.Threading;
30 using System.Collections.Generic;
31 using System.Reflection;
33 using OpenMetaverse.Packets;
35 using OpenSim.Framework;
36 using OpenSim.Region.Framework.Scenes.Types;
37 using OpenSim.Region.PhysicsModules.SharedBase;
38 using OpenSim.Region.Framework.Interfaces;
40 namespace OpenSim.
Region.Framework.Scenes
56 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
60 protected internal event PhysicsCrash UnRecoverableError;
71 protected OpenMetaverse.ReaderWriterLockSlim m_scenePresencesLock =
new OpenMetaverse.ReaderWriterLockSlim();
72 protected Dictionary<UUID, ScenePresence> m_scenePresenceMap =
new Dictionary<UUID, ScenePresence>();
73 protected List<ScenePresence> m_scenePresenceArray =
new List<ScenePresence>();
78 protected Dictionary<UUID, SceneObjectGroup> m_updateList =
new Dictionary<UUID, SceneObjectGroup>();
79 protected int m_numRootAgents = 0;
80 protected int m_numTotalPrim = 0;
81 protected int m_numPrim = 0;
82 protected int m_numMesh = 0;
83 protected int m_numChildAgents = 0;
84 protected int m_physicalPrim = 0;
86 protected int m_activeScripts = 0;
87 protected int m_scriptLPS = 0;
94 protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullID =
new Dictionary<UUID, SceneObjectGroup>();
99 protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullPartID =
new Dictionary<UUID, SceneObjectGroup>();
104 protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalPartID =
new Dictionary<uint, SceneObjectGroup>();
119 m_parentScene = parent;
126 if (_PhyScene == null)
127 _PhyScene = m_parentScene.RequestModuleInterface<
PhysicsScene>();
135 if (_PhyScene != null)
136 _PhyScene.OnPhysicsCrash -= physicsBasedCrash;
140 if (_PhyScene != null)
141 _PhyScene.OnPhysicsCrash += physicsBasedCrash;
145 protected internal void Close()
147 m_scenePresencesLock.EnterWriteLock();
150 Dictionary<UUID, ScenePresence> newmap =
new Dictionary<UUID, ScenePresence>();
151 List<ScenePresence> newlist =
new List<ScenePresence>();
152 m_scenePresenceMap = newmap;
153 m_scenePresenceArray = newlist;
157 m_scenePresencesLock.ExitWriteLock();
160 lock (SceneObjectGroupsByFullID)
161 SceneObjectGroupsByFullID.Clear();
162 lock (SceneObjectGroupsByFullPartID)
163 SceneObjectGroupsByFullPartID.Clear();
164 lock (SceneObjectGroupsByLocalPartID)
165 SceneObjectGroupsByLocalPartID.Clear();
170 #region Update Methods
172 protected internal void UpdatePreparePhysics()
182 PhysicsScene.GetResults();
192 protected internal void UpdatePresences()
194 ForEachScenePresence(delegate(ScenePresence presence)
205 protected internal float UpdatePhysics(
double elapsed)
222 return PhysicsScene.Simulate((float)elapsed);
225 protected internal void ProcessPhysicsPreSimulation()
228 PhysicsScene.ProcessPreSimulation();
231 protected internal void UpdateScenePresenceMovement()
233 ForEachScenePresence(delegate(ScenePresence presence)
235 presence.UpdateMovement();
239 public void GetCoarseLocations(out List<Vector3> coarseLocations, out List<UUID> avatarUUIDs, uint maxLocations)
241 coarseLocations =
new List<Vector3>();
242 avatarUUIDs =
new List<UUID>();
244 List<ScenePresence> presences = GetScenePresences();
245 for (
int i = 0; i < Math.Min(presences.Count, maxLocations); ++i)
253 coarseLocations.Add(sp.AbsolutePosition);
255 avatarUUIDs.Add(sp.UUID);
261 #region Entity Methods
282 protected internal bool AddRestoredSceneObject(
283 SceneObjectGroup sceneObject,
bool attachToBackup,
bool alreadyPersisted,
bool sendClientUpdates)
285 if (!m_parentScene.CombineRegions)
288 float regionSizeX = m_parentScene.RegionInfo.RegionSizeX;
289 if (regionSizeX == 0)
290 regionSizeX = Constants.RegionSize;
291 float regionSizeY = m_parentScene.RegionInfo.RegionSizeY;
292 if (regionSizeY == 0)
293 regionSizeY = Constants.RegionSize;
299 bool clampZ = m_parentScene.ClampNegativeZ;
302 npos.X > regionSizeX ||
303 npos.Y > regionSizeY))
305 if (npos.X < 0.0) npos.X = 1.0f;
306 if (npos.Y < 0.0) npos.Y = 1.0f;
307 if (npos.Z < 0.0 && clampZ) npos.Z = 0.0f;
308 if (npos.X > regionSizeX) npos.X = regionSizeX - 1.0f;
309 if (npos.Y > regionSizeY) npos.Y = regionSizeY - 1.0f;
312 rootpart.GroupPosition = npos;
316 if (part == rootpart)
318 part.GroupPosition = npos;
320 rootpart.Velocity = Vector3.Zero;
321 rootpart.AngularVelocity = Vector3.Zero;
322 rootpart.Acceleration = Vector3.Zero;
326 bool ret = AddSceneObject(sceneObject, attachToBackup, sendClientUpdates);
328 if (attachToBackup && (!alreadyPersisted))
330 sceneObject.ForceInventoryPersistence();
331 sceneObject.HasGroupChanged =
true;
349 protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject,
bool attachToBackup,
bool sendClientUpdates)
352 bool ret = AddSceneObject(sceneObject, attachToBackup, sendClientUpdates);
358 sceneObject.HasGroupChanged =
true;
376 SceneObjectGroup sceneObject,
bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel)
378 AddNewSceneObject(sceneObject, attachToBackup,
false);
381 sceneObject.AbsolutePosition = (Vector3)pos;
385 sceneObject.ClearPartAttachmentData();
389 sceneObject.UpdateGroupRotationR((Quaternion)rot);
392 if (pa != null && pa.
IsPhysical && vel != Vector3.Zero)
394 sceneObject.RootPart.ApplyImpulse((vel * sceneObject.GetMass()),
false);
421 if (sceneObject == null)
423 m_log.ErrorFormat(
"[SCENEGRAPH]: Tried to add null scene object");
429 "[SCENEGRAPH]: Tried to add scene object {0} to {1} with illegal UUID of {2}",
430 sceneObject.Name, m_parentScene.RegionInfo.RegionName, UUID.Zero);
435 if (Entities.ContainsKey(sceneObject.
UUID))
438 "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()",
439 m_parentScene.RegionInfo.RegionName, sceneObject.UUID);
452 if (m_parentScene.m_clampPrimSize)
456 Vector3 scale = part.Shape.Scale;
458 scale.X = Util.Clamp(scale.X, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys);
459 scale.Y = Util.Clamp(scale.Y, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys);
460 scale.Z = Util.Clamp(scale.Z, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys);
462 part.Shape.Scale = scale;
465 m_numTotalPrim += parts.Length;
479 sceneObject.AttachToScene(m_parentScene);
481 Entities.Add(sceneObject);
483 lock (SceneObjectGroupsByFullID)
484 SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
488 lock (SceneObjectGroupsByFullPartID)
489 SceneObjectGroupsByFullPartID[part.UUID] = sceneObject;
491 lock (SceneObjectGroupsByLocalPartID)
492 SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject;
495 if (sendClientUpdates)
496 sceneObject.ScheduleGroupForFullUpdate();
499 sceneObject.AttachToBackup();
507 lock (SceneObjectGroupsByFullPartID)
508 SceneObjectGroupsByFullPartID[part.UUID] = grp;
510 lock (SceneObjectGroupsByLocalPartID)
511 SceneObjectGroupsByLocalPartID[part.LocalId] = grp;
525 if (!Entities.TryGetValue(uuid, out entity) || (!(entity is
SceneObjectGroup)))
533 if (!resultOfObjectLinked)
537 m_numTotalPrim -= grp.PrimCount;
555 bool ret = Entities.Remove(uuid);
557 lock (SceneObjectGroupsByFullID)
558 SceneObjectGroupsByFullID.Remove(grp.UUID);
561 for (
int i = 0; i < parts.Length; i++)
563 lock (SceneObjectGroupsByFullPartID)
564 SceneObjectGroupsByFullPartID.Remove(parts[i].UUID);
566 lock (SceneObjectGroupsByLocalPartID)
567 SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId);
582 m_updateList[obj.UUID] = obj;
587 if (OnAttachToBackup != null)
589 OnAttachToBackup(obj);
595 if (OnDetachFromBackup != null)
597 OnDetachFromBackup(obj);
603 if (OnChangeBackup != null)
612 protected internal void UpdateObjectGroups()
614 if (!Monitor.TryEnter(m_updateLock))
618 List<SceneObjectGroup> updates;
624 updates =
new List<SceneObjectGroup>(m_updateList.Values);
625 m_updateList.Clear();
629 for (
int i = 0; i < updates.Count; i++)
631 SceneObjectGroup sog = updates[i];
641 "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e);
647 Monitor.Exit(m_updateLock);
651 protected internal void AddPhysicalPrim(
int number)
653 m_physicalPrim += number;
656 protected internal void RemovePhysicalPrim(
int number)
658 m_physicalPrim -= number;
661 protected internal void AddToScriptLPS(
int number)
663 m_scriptLPS += number;
666 protected internal void AddActiveScripts(
int number)
668 m_activeScripts += number;
671 protected internal void HandleUndo(
IClientAPI remoteClient, UUID primId)
673 if (primId !=
UUID.Zero)
675 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primId);
681 protected internal void HandleRedo(
IClientAPI remoteClient, UUID primId)
683 if (primId !=
UUID.Zero)
685 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primId);
692 protected internal ScenePresence CreateAndAddChildScenePresence(
696 ScenePresence presence =
new ScenePresence(client, m_parentScene, appearance, type);
698 Entities[presence.UUID] = presence;
700 m_scenePresencesLock.EnterWriteLock();
705 Dictionary<UUID, ScenePresence> newmap =
new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
706 List<ScenePresence> newlist =
new List<ScenePresence>(m_scenePresenceArray);
708 if (!newmap.ContainsKey(presence.UUID))
710 newmap.Add(presence.UUID, presence);
711 newlist.Add(presence);
716 ScenePresence oldref = newmap[presence.UUID];
718 newmap[presence.UUID] = presence;
720 newlist[newlist.IndexOf(oldref)] = presence;
724 m_scenePresenceMap = newmap;
725 m_scenePresenceArray = newlist;
729 m_scenePresencesLock.ExitWriteLock();
738 protected internal void RemoveScenePresence(UUID agentID)
740 if (!Entities.Remove(agentID))
743 "[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene Entities list",
747 m_scenePresencesLock.EnterWriteLock();
750 Dictionary<UUID, ScenePresence> newmap =
new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
751 List<ScenePresence> newlist =
new List<ScenePresence>(m_scenePresenceArray);
754 if (newmap.ContainsKey(agentID))
756 ScenePresence oldref = newmap[agentID];
757 newmap.Remove(agentID);
760 newlist.RemoveAt(newlist.IndexOf(oldref));
762 m_scenePresenceMap = newmap;
763 m_scenePresenceArray = newlist;
767 m_log.WarnFormat(
"[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
772 m_scenePresencesLock.ExitWriteLock();
776 protected internal void SwapRootChildAgent(
bool direction_RC_CR_T_F)
778 if (direction_RC_CR_T_F)
815 m_numRootAgents = rootcount;
816 m_numChildAgents = childcount;
821 return m_numChildAgents;
826 return m_numRootAgents;
831 return m_numTotalPrim;
846 return m_physicalPrim;
851 return m_activeScripts;
856 int returnval = m_scriptLPS;
882 if (presence != null)
884 return presence.ControllingClient;
897 protected internal List<ScenePresence> GetScenePresences()
899 return m_scenePresenceArray;
907 protected internal ScenePresence GetScenePresence(UUID agentID)
909 Dictionary<UUID, ScenePresence> presences = m_scenePresenceMap;
910 ScenePresence presence;
911 presences.TryGetValue(agentID, out presence);
921 protected internal ScenePresence GetScenePresence(
string firstName,
string lastName)
923 List<ScenePresence> presences = GetScenePresences();
924 foreach (ScenePresence presence
in presences)
926 if (
string.Equals(presence.Firstname, firstName, StringComparison.CurrentCultureIgnoreCase)
927 &&
string.Equals(presence.Lastname, lastName, StringComparison.CurrentCultureIgnoreCase))
938 protected internal ScenePresence GetScenePresence(uint localID)
940 List<ScenePresence> presences = GetScenePresences();
941 foreach (ScenePresence presence
in presences)
942 if (presence.LocalId == localID)
947 protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar)
949 Dictionary<UUID, ScenePresence> presences = m_scenePresenceMap;
950 presences.TryGetValue(agentID, out avatar);
951 return (avatar != null);
954 protected internal bool TryGetAvatarByName(
string name, out ScenePresence avatar)
957 foreach (ScenePresence presence
in GetScenePresences())
959 if (
String.Compare(name, presence.ControllingClient.Name,
true) == 0)
965 return (avatar != null);
976 if (Entities.TryGetValue(localID, out entity))
982 lock (SceneObjectGroupsByLocalPartID)
983 SceneObjectGroupsByLocalPartID.TryGetValue(localID, out sog);
997 lock (SceneObjectGroupsByLocalPartID)
1000 "[SCENE GRAPH]: Found scene object {0} {1} {2} via SceneObjectGroupsByLocalPartID index but it doesn't contain part with local id {3}. Removing from entry from index in {4}.",
1001 sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName);
1002 m_log.WarnFormat(
"stack: {0}", Environment.StackTrace);
1003 SceneObjectGroupsByLocalPartID.Remove(localID);
1014 sog = (SceneObjectGroup)ent;
1015 if (sog.ContainsPart(localID))
1017 lock (SceneObjectGroupsByLocalPartID)
1018 SceneObjectGroupsByLocalPartID[localID] = sog;
1035 lock (SceneObjectGroupsByFullPartID)
1036 SceneObjectGroupsByFullPartID.TryGetValue(fullID, out sog);
1043 lock (SceneObjectGroupsByFullPartID)
1044 SceneObjectGroupsByFullPartID.Remove(fullID);
1052 sog = (SceneObjectGroup)ent;
1053 if (sog.ContainsPart(fullID))
1055 lock (SceneObjectGroupsByFullPartID)
1056 SceneObjectGroupsByFullPartID[fullID] = sog;
1065 protected internal EntityIntersection GetClosestIntersectingPrim(Ray hray,
bool frontFacesOnly,
bool faceCenters)
1068 float closestDistance = 280f;
1075 SceneObjectGroup reportingG = (SceneObjectGroup)ent;
1076 EntityIntersection inter = reportingG.TestIntersection(hray, frontFacesOnly, faceCenters);
1079 closestDistance = inter.distance;
1093 protected internal List<SceneObjectGroup> GetSceneObjectGroups()
1095 lock (SceneObjectGroupsByFullID)
1096 return new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values);
1104 protected internal SceneObjectGroup GetSceneObjectGroup(UUID fullID)
1106 lock (SceneObjectGroupsByFullID)
1108 if (SceneObjectGroupsByFullID.ContainsKey(fullID))
1109 return SceneObjectGroupsByFullID[fullID];
1123 protected internal SceneObjectGroup GetSceneObjectGroup(uint localID)
1125 lock (SceneObjectGroupsByLocalPartID)
1127 if (SceneObjectGroupsByLocalPartID.ContainsKey(localID))
1129 SceneObjectGroup so = SceneObjectGroupsByLocalPartID[localID];
1131 if (so.LocalId == localID)
1145 protected internal SceneObjectGroup GetSceneObjectGroup(
string name)
1147 SceneObjectGroup so = null;
1150 delegate(EntityBase entity)
1152 if (entity is SceneObjectGroup)
1154 if (entity.Name == name)
1156 so = (SceneObjectGroup)entity;
1173 protected internal SceneObjectPart GetSceneObjectPart(uint localID)
1175 SceneObjectGroup group = GetGroupByPrim(localID);
1176 if (group == null || group.IsDeleted)
1178 return group.GetPart(localID);
1187 protected internal SceneObjectPart GetSceneObjectPart(
string name)
1189 SceneObjectPart sop = null;
1192 delegate(EntityBase entity)
1194 if (entity is SceneObjectGroup)
1196 foreach (SceneObjectPart p
in ((SceneObjectGroup)entity).Parts)
1220 protected internal SceneObjectPart GetSceneObjectPart(UUID fullID)
1222 SceneObjectGroup group = GetGroupByPrim(fullID);
1225 return group.GetPart(fullID);
1233 protected internal EntityBase[] GetEntities()
1235 return Entities.GetEntities();
1240 #region Other Methods
1242 protected internal void physicsBasedCrash()
1244 handlerPhysicsCrash = UnRecoverableError;
1245 if (handlerPhysicsCrash != null)
1247 handlerPhysicsCrash();
1251 protected internal UUID ConvertLocalIDToFullID(uint localID)
1253 SceneObjectGroup group = GetGroupByPrim(localID);
1255 return group.GetPartsFullID(localID);
1264 protected internal void ForEachSOG(Action<SceneObjectGroup> action)
1266 foreach (SceneObjectGroup obj
in GetSceneObjectGroups())
1276 "[SCENEGRAPH]: Problem processing action in ForEachSOG: {0} {1}", e.Message, e.StackTrace);
1320 List<ScenePresence> presences = GetScenePresences();
1329 m_log.Error(
"[SCENEGRAPH]: Error in " + m_parentScene.RegionInfo.RegionName +
": " + e.ToString());
1336 #region Client Event handlers
1345 SceneObjectGroup grp = part.ParentGroup;
1348 if (m_parentScene.Permissions.CanEditObject(grp.
UUID, remoteClient.
AgentId))
1354 data.change = ObjectChangeType.primS;
1356 data.change = ObjectChangeType.primPS;
1357 part.StoreUndoState(data.change);
1369 if (m_parentScene.Permissions.CanMoveObject(grp.
UUID, remoteClient.
AgentId))
1372 data.change &= (ObjectChangeType.Group | ObjectChangeType.Position | ObjectChangeType.Rotation);
1374 part.StoreUndoState(data.change);
1390 protected internal void UpdatePrimScale(uint localID, Vector3 scale,
IClientAPI remoteClient)
1392 SceneObjectPart part = GetSceneObjectPart(localID);
1396 if (m_parentScene.Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.
AgentId))
1398 bool physbuild =
false;
1399 if (part.ParentGroup.RootPart.PhysActor != null)
1401 part.ParentGroup.RootPart.PhysActor.Building =
true;
1408 part.ParentGroup.RootPart.PhysActor.Building =
false;
1413 protected internal void UpdatePrimGroupScale(uint localID, Vector3 scale,
IClientAPI remoteClient)
1415 SceneObjectGroup group = GetGroupByPrim(localID);
1418 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.
AgentId))
1420 bool physbuild =
false;
1421 if (group.RootPart.PhysActor != null)
1423 group.RootPart.PhysActor.Building =
true;
1427 group.GroupResize(scale);
1430 group.RootPart.PhysActor.Building =
false;
1444 IClientAPI remoteClient, UUID AgentID, uint RequestFlags, UUID ObjectID)
1446 SceneObjectGroup group = GetGroupByPrim(ObjectID);
1449 group.ServiceObjectPropertiesFamilyRequest(remoteClient, AgentID, RequestFlags);
1461 SceneObjectGroup group = GetGroupByPrim(localID);
1464 if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.
AgentId))
1466 group.UpdateSingleRotation(rot, localID);
1479 SceneObjectGroup group = GetGroupByPrim(localID);
1482 if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.
AgentId))
1484 group.UpdateSingleRotation(rot, pos, localID);
1497 SceneObjectGroup group = GetGroupByPrim(localID);
1500 if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.
AgentId))
1502 group.UpdateGroupRotationR(rot);
1516 SceneObjectGroup group = GetGroupByPrim(localID);
1519 if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.
AgentId))
1521 group.UpdateGroupRotationPR(pos, rot);
1532 protected internal void UpdatePrimSinglePosition(uint localID, Vector3 pos,
IClientAPI remoteClient)
1534 SceneObjectGroup group = GetGroupByPrim(localID);
1537 if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.
AgentId) || group.IsAttachment)
1539 group.UpdateSinglePosition(pos, localID);
1552 UpdatePrimGroupPosition(localId, pos, remoteClient.
AgentId);
1563 SceneObjectGroup group = GetGroupByPrim(localId);
1570 byte attachmentPoint = group.GetAttachmentPoint();
1571 group.UpdateGroupPosition(pos);
1572 group.IsAttachment =
false;
1573 group.AbsolutePosition = group.RootPart.AttachedPos;
1574 group.AttachmentPoint = attachmentPoint;
1575 group.HasGroupChanged =
true;
1579 if (m_parentScene.Permissions.CanMoveObject(group.
UUID, updatingAgentId)
1580 && m_parentScene.Permissions.CanObjectEntry(group.UUID,
false, pos))
1582 group.UpdateGroupPosition(pos);
1600 SceneObjectGroup group = GetGroupByPrim(localID);
1604 if (m_parentScene.Permissions.CanEditObject(group.
UUID,remoteClient.
AgentId))
1606 group.UpdateTextureEntry(localID, texture);
1625 SceneObjectGroup group = GetGroupByPrim(localID);
1628 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.
AgentId))
1633 bool wantedPhys = UsePhysics;
1638 vdtc = group.RootPart.VolumeDetectActive;
1642 group.UpdatePrimFlags(localID, UsePhysics, SetTemporary, SetPhantom, vdtc);
1646 SceneObjectPart part = GetSceneObjectPart(localID);
1649 part.UpdateExtraPhysics(PhysData);
1650 if (part.UpdatePhysRequired && remoteClient != null)
1651 remoteClient.SendPartPhysicsProprieties(part);
1655 if (wantedPhys != group.UsesPhysics && remoteClient != null)
1657 remoteClient.SendAlertMessage(
"Object physics canceled because exceeds the limit of " +
1658 m_parentScene.m_linksetPhysCapacity +
" physical prims with shape type not set to None");
1659 group.RootPart.ScheduleFullUpdate();
1672 protected internal void MoveObject(UUID objectID, Vector3 offset, Vector3 pos,
IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
1674 SceneObjectGroup group = GetGroupByPrim(objectID);
1677 if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.
AgentId))
1679 group.GrabMovement(objectID, offset, pos, remoteClient);
1686 group.SendGroupTerseUpdate();
1698 SceneObjectGroup group = GetGroupByPrim(objectID);
1701 if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.
AgentId))
1703 group.SpinStart(remoteClient);
1716 SceneObjectGroup group = GetGroupByPrim(objectID);
1719 if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.
AgentId))
1721 group.SpinMovement(
rotation, remoteClient);
1727 group.SendGroupTerseUpdate();
1736 protected internal void PrimName(
IClientAPI remoteClient, uint primLocalID,
string name)
1738 SceneObjectGroup group = GetGroupByPrim(primLocalID);
1741 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.
AgentId))
1743 group.SetPartName(Util.CleanString(name), primLocalID);
1744 group.HasGroupChanged =
true;
1754 protected internal void PrimDescription(
IClientAPI remoteClient, uint primLocalID,
string description)
1756 SceneObjectGroup group = GetGroupByPrim(primLocalID);
1759 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.
AgentId))
1761 group.SetPartDescription(Util.CleanString(description), primLocalID);
1762 group.HasGroupChanged =
true;
1773 protected internal void PrimClickAction(
IClientAPI remoteClient, uint primLocalID,
string clickAction)
1778 SceneObjectGroup group = GetGroupByPrim(primLocalID);
1781 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.
AgentId))
1783 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID);
1786 part.ClickAction = Convert.ToByte(clickAction);
1787 group.HasGroupChanged =
true;
1793 protected internal void PrimMaterial(
IClientAPI remoteClient, uint primLocalID,
string material)
1795 SceneObjectGroup group = GetGroupByPrim(primLocalID);
1798 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.
AgentId))
1800 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID);
1803 part.Material = Convert.ToByte(material);
1804 group.HasGroupChanged =
true;
1805 remoteClient.SendPartPhysicsProprieties(part);
1811 protected internal void UpdateExtraParam(UUID agentID, uint primLocalID, ushort type,
bool inUse, byte[] data)
1813 SceneObjectGroup group = GetGroupByPrim(primLocalID);
1817 if (m_parentScene.Permissions.CanEditObject(group.UUID, agentID))
1819 group.UpdateExtraParam(primLocalID, type, inUse, data);
1829 protected internal void UpdatePrimShape(UUID agentID, uint primLocalID,
UpdateShapeArgs shapeBlock)
1831 SceneObjectGroup group = GetGroupByPrim(primLocalID);
1834 if (m_parentScene.Permissions.CanEditObject(group.UUID, agentID))
1836 ObjectShapePacket.ObjectDataBlock shapeData =
new ObjectShapePacket.ObjectDataBlock();
1837 shapeData.ObjectLocalID = shapeBlock.ObjectLocalID;
1838 shapeData.PathBegin = shapeBlock.PathBegin;
1839 shapeData.PathCurve = shapeBlock.PathCurve;
1840 shapeData.PathEnd = shapeBlock.PathEnd;
1841 shapeData.PathRadiusOffset = shapeBlock.PathRadiusOffset;
1842 shapeData.PathRevolutions = shapeBlock.PathRevolutions;
1843 shapeData.PathScaleX = shapeBlock.PathScaleX;
1844 shapeData.PathScaleY = shapeBlock.PathScaleY;
1845 shapeData.PathShearX = shapeBlock.PathShearX;
1846 shapeData.PathShearY = shapeBlock.PathShearY;
1847 shapeData.PathSkew = shapeBlock.PathSkew;
1848 shapeData.PathTaperX = shapeBlock.PathTaperX;
1849 shapeData.PathTaperY = shapeBlock.PathTaperY;
1850 shapeData.PathTwist = shapeBlock.PathTwist;
1851 shapeData.PathTwistBegin = shapeBlock.PathTwistBegin;
1852 shapeData.ProfileBegin = shapeBlock.ProfileBegin;
1853 shapeData.ProfileCurve = shapeBlock.ProfileCurve;
1854 shapeData.ProfileEnd = shapeBlock.ProfileEnd;
1855 shapeData.ProfileHollow = shapeBlock.ProfileHollow;
1857 group.UpdateShape(shapeData, primLocalID);
1868 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1870 if (root.KeyframeMotion != null)
1872 root.KeyframeMotion.Stop();
1873 root.KeyframeMotion = null;
1876 SceneObjectGroup parentGroup = root.ParentGroup;
1877 if (parentGroup == null)
return;
1880 if (parentGroup.OwnerID == parentGroup.GroupID)
1883 Monitor.Enter(m_updateLock);
1888 List<SceneObjectGroup> childGroups =
new List<SceneObjectGroup>();
1891 for (
int i = 0; i < children.Count; i++)
1893 SceneObjectGroup child = children[i].ParentGroup;
1896 if (child == parentGroup)
1905 child.RootPart.ObjectSaleType = 0;
1906 child.RootPart.SalePrice = 10;
1907 childGroups.Add(child);
1911 foreach (SceneObjectGroup child
in childGroups)
1913 if (parentGroup.OwnerID == child.OwnerID)
1915 parentGroup.LinkToGroup(child);
1917 child.DetachFromBackup();
1921 child.AbsolutePosition = child.AbsolutePosition;
1927 if (childGroups.Count > 0)
1929 parentGroup.RootPart.CreateSelected =
true;
1930 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1931 parentGroup.HasGroupChanged =
true;
1932 parentGroup.ScheduleGroupForFullUpdate();
1944 parentGroup.AdjustChildPrimPermissions(
false);
1945 parentGroup.HasGroupChanged =
true;
1946 parentGroup.ProcessBackup(m_parentScene.SimulationDataService,
true);
1947 parentGroup.ScheduleGroupForFullUpdate();
1948 Monitor.Exit(m_updateLock);
1956 protected internal void DelinkObjects(List<SceneObjectPart> prims)
1958 Monitor.Enter(m_updateLock);
1961 List<SceneObjectPart> childParts =
new List<SceneObjectPart>();
1962 List<SceneObjectPart> rootParts =
new List<SceneObjectPart>();
1963 List<SceneObjectGroup> affectedGroups =
new List<SceneObjectGroup>();
1966 foreach (SceneObjectPart part
in prims)
1970 if (part.KeyframeMotion != null)
1972 part.KeyframeMotion.Stop();
1973 part.KeyframeMotion = null;
1975 if (part.ParentGroup.PrimCount != 1)
1977 if (part.LinkNum < 2)
1979 rootParts.Add(part);
1983 part.LastOwnerID = part.ParentGroup.RootPart.LastOwnerID;
1984 childParts.Add(part);
1987 SceneObjectGroup group = part.ParentGroup;
1988 if (!affectedGroups.Contains(group))
1990 affectedGroups.Add(group);
1996 if (childParts.Count > 0)
1998 foreach (SceneObjectPart child
in childParts)
2002 child.ParentGroup.DelinkFromGroup(child,
true);
2003 child.ParentGroup.HasGroupChanged =
true;
2004 child.ParentGroup.ScheduleGroupForFullUpdate();
2008 foreach (SceneObjectPart root
in rootParts)
2014 SceneObjectGroup group = root.ParentGroup;
2016 List<SceneObjectPart> newSet =
new List<SceneObjectPart>(group.Parts);
2017 int numChildren = newSet.Count;
2019 if (numChildren == 1)
2026 bool sendEventsToRemainder =
false;
2027 if (numChildren == 2)
2028 sendEventsToRemainder =
true;
2030 foreach (SceneObjectPart p
in newSet)
2032 if (p != group.RootPart)
2034 group.DelinkFromGroup(p, sendEventsToRemainder);
2035 if (sendEventsToRemainder)
2037 p.ParentGroup.HasGroupChanged =
true;
2038 p.ParentGroup.ScheduleGroupForFullUpdate();
2046 if (numChildren > 2)
2050 if (newSet.Contains(root))
2051 newSet.Remove(root);
2055 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
2057 return a.LinkNum.CompareTo(b.LinkNum);
2062 SceneObjectPart newRoot = newSet[0];
2065 foreach (SceneObjectPart newChild
in newSet)
2066 newChild.ClearUpdateSchedule();
2076 foreach (SceneObjectGroup g
in affectedGroups)
2082 g.AdjustChildPrimPermissions(
false);
2083 m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID);
2084 g.TriggerScriptChangedEvent(Changed.LINK);
2085 g.HasGroupChanged =
true;
2086 g.ScheduleGroupForFullUpdate();
2091 Monitor.Exit(m_updateLock);
2095 protected internal void MakeObjectSearchable(
IClientAPI remoteClient,
bool IncludeInSearch, uint localID)
2097 UUID user = remoteClient.AgentId;
2098 UUID objid = UUID.Zero;
2099 SceneObjectPart obj = null;
2101 EntityBase[] entityList = GetEntities();
2102 foreach (EntityBase ent
in entityList)
2104 if (ent is SceneObjectGroup)
2106 SceneObjectGroup sog = ent as SceneObjectGroup;
2108 foreach (SceneObjectPart part
in sog.Parts)
2110 if (part.LocalId == localID)
2133 #pragma warning disable 0612
2134 if (IncludeInSearch && m_parentScene.Permissions.CanEditObject(objid, user))
2136 obj.ParentGroup.RootPart.AddFlag(PrimFlags.JointWheel);
2137 obj.ParentGroup.HasGroupChanged =
true;
2139 else if (!IncludeInSearch && m_parentScene.Permissions.CanMoveObject(objid,user))
2141 obj.ParentGroup.RootPart.RemFlag(PrimFlags.JointWheel);
2142 obj.ParentGroup.HasGroupChanged =
true;
2144 #pragma warning restore 0612
2158 public SceneObjectGroup
DuplicateObject(uint originalPrimID, Vector3 offset, uint flags, UUID AgentID, UUID GroupID, Quaternion rot)
2164 SceneObjectGroup original = GetGroupByPrim(originalPrimID);
2165 if (original != null)
2167 if (m_parentScene.Permissions.CanDuplicateObject(
2170 SceneObjectGroup copy = original.Copy(
true);
2171 copy.AbsolutePosition = copy.AbsolutePosition + offset;
2173 if (original.
OwnerID != AgentID)
2175 copy.SetOwnerId(AgentID);
2176 copy.SetRootPartOwner(copy.RootPart, AgentID, GroupID);
2180 if (m_parentScene.Permissions.PropagatePermissions())
2184 child.Inventory.ChangeInventoryOwner(AgentID);
2185 child.TriggerScriptChangedEvent(Changed.OWNER);
2186 child.ApplyNextOwnerPermissions();
2194 lock (SceneObjectGroupsByFullID)
2195 SceneObjectGroupsByFullID[copy.UUID] = copy;
2200 lock (SceneObjectGroupsByFullPartID)
2201 SceneObjectGroupsByFullPartID[part.UUID] = copy;
2202 lock (SceneObjectGroupsByLocalPartID)
2203 SceneObjectGroupsByLocalPartID[part.LocalId] = copy;
2213 copy.IsSelected =
false;
2215 m_numPrim += copy.Parts.Length;
2217 if (rot != Quaternion.Identity)
2219 copy.UpdateGroupRotationR(rot);
2222 copy.CreateScriptInstances(0,
false, m_parentScene.DefaultScriptEngine, 1);
2223 copy.HasGroupChanged =
true;
2224 copy.ScheduleGroupForFullUpdate();
2225 copy.ResumeScripts();
2228 copy.AbsolutePosition = copy.AbsolutePosition;
2235 m_log.WarnFormat(
"[SCENE]: Attempted to duplicate nonexistant prim id {0}", GroupID);
2246 protected internal float Vector3Distance(Vector3 v1, Vector3 v2)
2253 Math.Sqrt((v1.X - v2.X) * (v1.X - v2.X) + (v1.Y - v2.Y) * (v1.Y - v2.Y) + (v1.Z - v2.Z) * (v1.Z - v2.Z));
void updateScenePartGroup(SceneObjectPart part, SceneObjectGroup grp)
Vector3 GroupPosition
The position of the entire group that this prim belongs to.
delegate void UpdatePrimSingleRotationPosition(uint localID, Quaternion rot, Vector3 pos, IClientAPI remoteClient)
delegate void UpdatePrimGroupRotation(uint localID, Vector3 pos, Quaternion rot, IClientAPI remoteClient)
delegate void UpdatePrimSingleRotation(uint localID, Quaternion rot, IClientAPI remoteClient)
void removeUserCount(bool TypeRCTF)
int GetTotalMeshObjectsCount()
PrimType GetPrimType()
Tell us what type this prim is
delegate void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, ExtraPhysicsData PhysData, IClientAPI remoteClient)
Contains the Avatar's Appearance and methods to manipulate the appearance.
delegate void ClientChangeObject(uint localID, object data, IClientAPI remoteClient)
delegate void DelinkObjects(List< uint > primIds, IClientAPI client)
ChangedBackupDelegate OnChangeBackup
SceneObjectGroup GetGroupByPrim(uint localID)
Get a scene object group that contains the prim with the given local id
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
Add an object to the scene. This will both update the scene, and send information about the new objec...
PrimFlags Flags
Property flags. See OpenMetaverse.PrimFlags
bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked)
Delete an object from the scene
delegate void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient)
int GetTotalPrimObjectsCount()
void GetCoarseLocations(out List< Vector3 > coarseLocations, out List< UUID > avatarUUIDs, uint maxLocations)
AttachToBackupDelegate OnAttachToBackup
PresenceType
Indicate the type of ScenePresence.
SceneObjectGroup DuplicateObject(uint originalPrimID, Vector3 offset, uint flags, UUID AgentID, UUID GroupID, Quaternion rot)
Duplicate the given object.
int PrimCount
Number of prims in this group
IClientAPI GetControllingClient(UUID agentId)
Get the controlling client for the given avatar, if there is one.
delegate void AttachToBackupDelegate(SceneObjectGroup sog)
void FireDetachFromBackup(SceneObjectGroup obj)
delegate void MoveObject(UUID objectID, Vector3 offset, Vector3 grapPos, IClientAPI remoteClient, List< SurfaceTouchEventArgs > surfaceArgs)
void FireChangeBackup(SceneObjectGroup obj)
OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion rotation
int GetActiveScriptsCount()
void UpdatePrimGroupPosition(uint localId, Vector3 pos, UUID updatingAgentId)
Update the position of the given group.
int GetActiveObjectsCount()
bool ContainsPart(UUID partID)
delegate void LinkObjects(IClientAPI remoteClient, uint parent, List< uint > children)
delegate void ChangedBackupDelegate(SceneObjectGroup sog)
delegate void SpinStart(UUID objectID, IClientAPI remoteClient)
delegate void SpinObject(UUID objectID, Quaternion rotation, IClientAPI remoteClient)
delegate void PhysicsCrash()
DetachFromBackupDelegate OnDetachFromBackup
void ForEachAvatar(Action< ScenePresence > action)
Performs action on all ROOT (not child) scene presences. This is just a shortcut function since frequ...
override Vector3 AbsolutePosition
The absolute position of this scene object in the scene
void UpdatePrimGroupPosition(uint localId, Vector3 pos, IClientAPI remoteClient)
Update the position of the given group.
void ForEachScenePresence(Action< ScenePresence > action)
Performs action on all scene presences. This can ultimately run the actions in parallel but any deleg...
int GetTotalObjectsCount()
delegate void RequestObjectPropertiesFamily(IClientAPI remoteClient, UUID AgentID, uint RequestFlags, UUID TaskID)
bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, Vector3?pos, Quaternion?rot, Vector3 vel)
Add a newly created object to the scene.
This class used to be called InnerScene and may not yet truly be a SceneGraph. The non scene graph co...
delegate void DetachFromBackupDelegate(SceneObjectGroup sog)
SceneObjectGroup GetGroupByPrim(UUID fullID)
Get a scene object group that contains the prim with the given uuid
bool IsAttachment
Is this scene object acting as an attachment?