29 using System.ComponentModel;
30 using System.Collections.Generic;
33 using System.Diagnostics;
35 using System.Threading;
37 using System.Xml.Serialization;
39 using OpenMetaverse.Packets;
40 using OpenSim.Framework;
41 using OpenSim.Region.Framework.Interfaces;
42 using OpenSim.Region.PhysicsModules.SharedBase;
43 using OpenSim.Region.Framework.Scenes.Serialization;
45 using OpenSim.Services.Interfaces;
47 namespace OpenSim.
Region.Framework.Scenes
111 STATUS_ROTATE_X = 0x002,
112 STATUS_ROTATE_Y = 0x004,
113 STATUS_ROTATE_Z = 0x008,
114 NOT_STATUS_ROTATE_X = 0xFD,
115 NOT_STATUS_ROTATE_Y = 0xFB,
116 NOT_STATUS_ROTATE_Z = 0xF7
120 public static readonly uint SLAM = 16;
128 private bool m_hasGroupChanged =
false;
129 private long timeFirstChanged = 0;
130 private long timeLastChanged = 0;
131 private long m_maxPersistTime = 0;
132 private long m_minPersistTime = 0;
144 public bool HasGroupChanged
153 m_scene.SceneGraph.FireChangeBackup(
this);
155 timeLastChanged = DateTime.Now.Ticks;
156 if (!m_hasGroupChanged)
157 timeFirstChanged = DateTime.Now.Ticks;
158 if (m_rootPart != null && m_rootPart.UUID != null && m_scene != null)
168 if (m_scene.GetRootAgentCount() == 0)
175 m_maxPersistTime = (long)((
float)m_scene.m_persistAfter * factor);
176 m_minPersistTime = (long)((
float)m_scene.m_dontPersistBefore * factor);
184 m_maxPersistTime = m_scene.m_persistAfter;
185 m_minPersistTime = m_scene.m_dontPersistBefore;
189 m_hasGroupChanged = value;
195 get {
return m_hasGroupChanged; }
198 private bool m_groupContainsForeignPrims =
false;
206 public bool GroupContainsForeignPrims
210 m_groupContainsForeignPrims = value;
211 if (m_groupContainsForeignPrims)
212 HasGroupChanged =
true;
215 get {
return m_groupContainsForeignPrims; }
218 public bool HasGroupChangedDueToDelink {
get; set; }
220 private bool isTimeToPersist()
222 if (IsSelected || IsDeleted || IsAttachment)
224 if (!m_hasGroupChanged)
226 if (m_scene.ShuttingDown)
229 if (m_minPersistTime == 0 || m_maxPersistTime == 0)
231 m_maxPersistTime = m_scene.m_persistAfter;
232 m_minPersistTime = m_scene.m_dontPersistBefore;
235 long currentTime = DateTime.Now.Ticks;
237 if (timeLastChanged == 0) timeLastChanged = currentTime;
238 if (timeFirstChanged == 0) timeFirstChanged = currentTime;
240 if (currentTime - timeLastChanged > m_minPersistTime || currentTime - timeFirstChanged > m_maxPersistTime)
248 public bool IsAttachment {
get; set; }
256 public UUID AttachedAvatar {
get; set; }
268 return m_rootPart.Shape.State;
273 IsAttachment = value != 0;
274 m_rootPart.Shape.State = (byte)value;
285 public bool HasPrivateAttachmentPoint
289 return AttachmentPoint >= (uint)OpenMetaverse.AttachmentPoint.HUDCenter2
290 &&
AttachmentPoint <= (uint)OpenMetaverse.AttachmentPoint.HUDBottomRight;
299 if (RootPart.Shape.PCode == (byte)PCode.Tree ||
300 RootPart.Shape.PCode == (byte)PCode.NewTree)
307 part.Shape.State = 0;
316 public bool IsPhantom
318 get {
return (RootPart.Flags &
PrimFlags.Phantom) != 0; }
327 public bool UsesPhysics
329 get {
return (RootPart.Flags &
PrimFlags.Physics) != 0; }
339 public bool IsTemporary
341 get {
return (RootPart.Flags &
PrimFlags.TemporaryOnRez) != 0; }
344 public bool IsVolumeDetect
346 get {
return RootPart.VolumeDetectActive; }
349 private Vector3 lastPhysGroupPos;
350 private Quaternion lastPhysGroupRot;
355 public bool Backup {
get;
private set; }
357 protected MapAndArray<UUID, SceneObjectPart> m_parts =
new MapAndArray<UUID, SceneObjectPart>();
363 private SortedDictionary<uint, scriptPosTarget> m_targets =
new SortedDictionary<uint, scriptPosTarget>();
364 private SortedDictionary<uint, scriptRotTarget> m_rotTargets =
new SortedDictionary<uint, scriptRotTarget>();
366 public SortedDictionary<uint, scriptPosTarget> AtTargets
368 get {
return m_targets; }
371 public SortedDictionary<uint, scriptRotTarget> RotTargets
373 get {
return m_rotTargets; }
376 private bool m_scriptListens_atTarget;
377 private bool m_scriptListens_notAtTarget;
378 private bool m_scriptListens_atRotTarget;
379 private bool m_scriptListens_notAtRotTarget;
381 public bool m_dupeInProgress =
false;
382 internal Dictionary<UUID, string> m_savedScriptState;
389 public override string Name
391 get {
return RootPart.Name; }
392 set { RootPart.Name = value; }
395 public string Description
397 get {
return RootPart.Description; }
398 set { RootPart.Description = value; }
408 protected bool m_isSelected =
false;
415 get {
return m_parts.Count; }
428 public Quaternion GroupRotation
430 get {
return m_rootPart.RotationOffset; }
433 public Vector3 GroupScale
438 Vector3 maxScale = Vector3.Zero;
439 Vector3 finalScale =
new Vector3(0.5f, 0.5f, 0.5f);
442 for (
int i = 0; i < parts.Length; i++)
445 Vector3 partscale = part.Scale;
446 Vector3 partoffset = part.OffsetPosition;
448 minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X;
449 minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y;
450 minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z;
452 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
453 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
454 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
457 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
458 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
459 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
467 get {
return m_rootPart.GroupID; }
468 set { m_rootPart.GroupID = value; }
473 get {
return m_parts.GetArray(); }
478 return m_parts.ContainsKey(partID);
490 for (
int i = 0; i < parts.Length; i++)
492 if (parts[i].LocalId == localID)
504 get {
return m_rootPart; }
507 public ulong RegionHandle
509 get {
return m_regionHandle; }
512 m_regionHandle = value;
514 for (
int i = 0; i < parts.Length; i++)
515 parts[i].RegionHandle = value;
532 return (IsAttachment ||
533 (m_rootPart.Shape.PCode == (byte)
PCodeEnum.Primitive && m_rootPart.Shape.State != 0));
536 private struct avtocrossInfo
543 public bool inTransit =
false;
549 public override Vector3 AbsolutePosition
551 get {
return m_rootPart.GroupPosition; }
557 && !IsAttachmentCheckFull()
558 && !Scene.LoadingPrims
564 SOGCrossDelegate d = CrossAsync;
565 d.BeginInvoke(
this, val, CrossAsyncCompleted, d);
570 if (RootPart.GetStatusSandbox())
572 if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
574 RootPart.ScriptSetPhysicsStatus(
false);
577 Scene.SimChat(Utils.StringToBytes(
"Hit Sandbox Limit"),
578 ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name,
UUID,
false);
584 bool triggerScriptEvent = m_rootPart.GroupPosition != val;
585 if (m_dupeInProgress || IsDeleted)
586 triggerScriptEvent =
false;
588 m_rootPart.GroupPosition = val;
597 if (part != m_rootPart)
598 part.GroupPosition = val;
608 if (triggerScriptEvent)
612 part.TriggerScriptChangedEvent(Changed.POSITION);
617 Scene.EventManager.TriggerParcelPrimCountTainted();
624 Scene sogScene = sog.m_scene;
627 Vector3 newpos = Vector3.Zero;
634 sogScene.DeleteSceneObject(sog,
false);
638 m_log.Warn(
"[SCENE]: exception when trying to remove the prim that crossed the border.");
648 List<uint> localIDs =
new List<uint>();
649 localIDs.Add(sog.RootPart.LocalId);
650 sogScene.AddReturn(sog.OwnerID, sog.Name, sog.AbsolutePosition,
651 "Returned at region cross");
652 sogScene.DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, UUID.Zero);
656 m_log.Warn(
"[SCENE]: exception when trying to return the prim that crossed the border.");
662 sog.m_rootPart.KeyframeMotion.StartCrossingCheck();
664 if (entityTransfer == null)
667 destination = entityTransfer.GetObjectDestination(sog, val, out newpos);
668 if (destination == null)
671 if (sog.m_sittingAvatars.Count == 0)
673 entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog,
true,
true);
677 string reason = String.Empty;
690 if(!entityTransfer.checkAgentAccessToRegion(av, destination, newpos, ctx, out reason))
694 m_log.DebugFormat(
"[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
700 List<avtocrossInfo> avsToCross =
new List<avtocrossInfo>();
704 avtocrossInfo avinfo =
new avtocrossInfo();
706 if (parentPart != null)
707 av.ParentUUID = parentPart.UUID;
710 avinfo.ParentID = av.ParentID;
711 avsToCross.Add(avinfo);
713 av.PrevSitOffset = av.OffsetPosition;
717 if (entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog,
true,
false))
719 foreach (avtocrossInfo avinfo
in avsToCross)
724 m_log.DebugFormat(
"[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
726 av.IsInTransit =
true;
730 entityTransfer.CrossAgentToNewRegionAsync(av, newpos, destination, av.Flying, ctx);
734 if (av.ParentUUID !=
UUID.Zero)
737 av.ParentPart = null;
746 av.UnRegisterSeatControls(sog.UUID);
749 av.ParentUUID = UUID.Zero;
751 av.IsInTransit =
false;
753 m_log.DebugFormat(
"[SCENE OBJECT]: Crossing agent {0} {1} completed.", av.Firstname, av.Lastname);
756 m_log.DebugFormat(
"[SCENE OBJECT]: Crossing avatar already in transit {0} to {1}", av.Name, val);
759 sog.RemoveScriptInstances(
true);
765 foreach (avtocrossInfo avinfo
in avsToCross)
768 av.ParentUUID = UUID.Zero;
769 av.ParentID = avinfo.ParentID;
779 SOGCrossDelegate icon = (SOGCrossDelegate)iar.AsyncState;
785 Vector3 oldp = rootp.GroupPosition;
786 oldp.X = Util.Clamp<
float>(oldp.X, 0.5f, sog.m_scene.RegionInfo.RegionSizeX - 0.5f);
787 oldp.Y = Util.Clamp<
float>(oldp.Y, 0.5f, sog.m_scene.RegionInfo.RegionSizeY - 0.5f);
788 rootp.GroupPosition = oldp;
795 part.GroupPosition = oldp;
803 sog.Velocity = Vector3.Zero;
805 if (sog.m_rootPart.KeyframeMotion != null)
806 sog.m_rootPart.KeyframeMotion.CrossingFailure();
808 if (sog.RootPart.PhysActor != null)
810 sog.RootPart.PhysActor.CrossingFailure();
813 sog.inTransit =
false;
814 sog.ScheduleGroupForFullUpdate();
846 get {
return RootPart.Velocity; }
847 set { RootPart.Velocity = value; }
850 public override uint LocalId
852 get {
return m_rootPart.LocalId; }
853 set { m_rootPart.LocalId = value; }
858 get {
return m_rootPart.UUID; }
861 lock (m_parts.SyncRoot)
863 m_parts.Remove(m_rootPart.UUID);
864 m_rootPart.UUID = value;
865 m_parts.Add(value, m_rootPart);
870 public UUID LastOwnerID
872 get {
return m_rootPart.LastOwnerID; }
873 set { m_rootPart.LastOwnerID = value; }
878 get {
return m_rootPart.OwnerID; }
879 set { m_rootPart.OwnerID = value; }
884 get {
return m_rootPart.Damage; }
885 set { m_rootPart.Damage = value; }
890 get {
return m_rootPart.Color; }
891 set { m_rootPart.Color = value; }
897 string returnstr = m_rootPart.Text;
898 if (returnstr.Length > 255)
900 returnstr = returnstr.Substring(0, 255);
904 set { m_rootPart.Text = value; }
911 protected virtual bool CanBeBackedUp
916 public bool IsSelected
918 get {
return m_isSelected; }
921 m_isSelected = value;
936 for (
int i = 0; i < parts.Length; i++)
942 childPa.Selected = value;
945 if (RootPart.KeyframeMotion != null)
946 RootPart.KeyframeMotion.Selected = value;
953 if (m_isSelected == partSelect)
958 IsSelected = partSelect;
970 for (
int i = 0; i < parts.Length; i++)
976 IsSelected = partSelect;
987 get {
return m_PlaySoundMasterPrim; }
988 set { m_PlaySoundMasterPrim = value; }
991 private List<SceneObjectPart> m_PlaySoundSlavePrims =
new List<SceneObjectPart>();
992 public List<SceneObjectPart> PlaySoundSlavePrims
994 get {
return m_PlaySoundSlavePrims; }
995 set { m_PlaySoundSlavePrims = value; }
1002 get {
return m_LoopSoundMasterPrim; }
1003 set { m_LoopSoundMasterPrim = value; }
1007 private List<SceneObjectPart> m_LoopSoundSlavePrims =
new List<SceneObjectPart>();
1008 public List<SceneObjectPart> LoopSoundSlavePrims
1010 get {
return m_LoopSoundSlavePrims; }
1011 set { m_LoopSoundSlavePrims = value; }
1017 public UUID RegionUUID
1021 if (m_scene != null)
1023 return m_scene.RegionInfo.RegionID;
1035 public UUID FromItemID {
get; set; }
1043 public UUID FromPartID {
get; set; }
1051 public UUID FromFolderID {
get; set; }
1057 public bool BlockGrabOverride {
get; set; }
1069 protected internal List<ScenePresence> m_sittingAvatars =
new List<ScenePresence>();
1079 #region Constructors
1105 SetRootPart(
new SceneObjectPart(ownerID, shape, pos, rot, Vector3.Zero));
1112 : this(ownerID, pos, Quaternion.Identity, shape)
1118 XmlNodeList nodes = doc.GetElementsByTagName(
"SavedScriptState");
1119 if (nodes.Count > 0)
1121 if (m_savedScriptState == null)
1122 m_savedScriptState =
new Dictionary<UUID, string>();
1123 foreach (XmlNode node
in nodes)
1125 if (node.Attributes[
"UUID"] != null)
1127 UUID itemid =
new UUID(node.Attributes[
"UUID"].Value);
1128 if (itemid !=
UUID.Zero)
1129 m_savedScriptState[itemid] = node.InnerXml;
1141 if (reader.Name ==
"SavedScriptState" && reader.NodeType == XmlNodeType.Element)
1145 if (m_savedScriptState == null)
1146 m_savedScriptState =
new Dictionary<UUID, string>();
1148 string uuid = reader.GetAttribute(
"UUID");
1152 string innerXml = reader.ReadInnerXml();
1159 if (itemid !=
UUID.Zero)
1160 m_savedScriptState[itemid] = innerXml;
1164 m_log.WarnFormat(
"[SCENE OBJECT GROUP]: SavedScriptState element had no UUID in object {0}", Name);
1180 if (IsAttachment)
return;
1181 m_scene.SceneGraph.FireAttachToBackup(
this);
1189 m_scene.EventManager.OnBackup += ProcessBackup;
1202 RegionHandle = m_scene.RegionInfo.RegionHandle;
1204 if (m_rootPart.Shape.PCode != 9 || m_rootPart.Shape.State == 0)
1205 m_rootPart.ParentID = 0;
1206 if (m_rootPart.LocalId == 0)
1207 m_rootPart.LocalId = m_scene.AllocateLocalId();
1210 for (
int i = 0; i < parts.Length; i++)
1215 part.KeyframeMotion.UpdateSceneObject(
this);
1218 if (
Object.ReferenceEquals(part, m_rootPart))
1222 part.LocalId = m_scene.AllocateLocalId();
1224 part.ParentID = m_rootPart.LocalId;
1230 if (RootPart.PhysActor != null)
1231 RootPart.Force = RootPart.Force;
1232 if (RootPart.PhysActor != null)
1233 RootPart.Torque = RootPart.Torque;
1234 if (RootPart.PhysActor != null)
1235 RootPart.Buoyancy = RootPart.Buoyancy;
1254 float idist = float.MaxValue;
1256 for (
int i = 0; i < parts.Length; i++)
1263 Quaternion parentrotation = GroupRotation;
1268 EntityIntersection inter = part.TestIntersectionOBB(hRay, parentrotation, frontFacesOnly, faceCenters);
1275 result.HitTF =
true;
1276 result.ipoint = inter.ipoint;
1278 result.normal = inter.normal;
1279 result.distance = inter.distance;
1281 idist = inter.distance;
1296 maxX = float.MinValue;
1297 maxY = float.MinValue;
1298 maxZ = float.MinValue;
1299 minX = float.MaxValue;
1300 minY = float.MaxValue;
1301 minZ = float.MaxValue;
1306 Vector3 worldPos = part.GetWorldPosition();
1307 Vector3 offset = worldPos - AbsolutePosition;
1308 Quaternion worldRot;
1311 worldRot = part.RotationOffset;
1315 worldRot = part.GetWorldRotation();
1318 Vector3 frontTopLeft;
1319 Vector3 frontTopRight;
1320 Vector3 frontBottomLeft;
1321 Vector3 frontBottomRight;
1323 Vector3 backTopLeft;
1324 Vector3 backTopRight;
1325 Vector3 backBottomLeft;
1326 Vector3 backBottomRight;
1330 Vector3 orig = Vector3.Zero;
1332 frontTopLeft.X = orig.X - (part.Scale.X / 2);
1333 frontTopLeft.Y = orig.Y - (part.Scale.Y / 2);
1334 frontTopLeft.Z = orig.Z + (part.Scale.Z / 2);
1336 frontTopRight.X = orig.X - (part.Scale.X / 2);
1337 frontTopRight.Y = orig.Y + (part.Scale.Y / 2);
1338 frontTopRight.Z = orig.Z + (part.Scale.Z / 2);
1340 frontBottomLeft.X = orig.X - (part.Scale.X / 2);
1341 frontBottomLeft.Y = orig.Y - (part.Scale.Y / 2);
1342 frontBottomLeft.Z = orig.Z - (part.Scale.Z / 2);
1344 frontBottomRight.X = orig.X - (part.Scale.X / 2);
1345 frontBottomRight.Y = orig.Y + (part.Scale.Y / 2);
1346 frontBottomRight.Z = orig.Z - (part.Scale.Z / 2);
1348 backTopLeft.X = orig.X + (part.Scale.X / 2);
1349 backTopLeft.Y = orig.Y - (part.Scale.Y / 2);
1350 backTopLeft.Z = orig.Z + (part.Scale.Z / 2);
1352 backTopRight.X = orig.X + (part.Scale.X / 2);
1353 backTopRight.Y = orig.Y + (part.Scale.Y / 2);
1354 backTopRight.Z = orig.Z + (part.Scale.Z / 2);
1356 backBottomLeft.X = orig.X + (part.Scale.X / 2);
1357 backBottomLeft.Y = orig.Y - (part.Scale.Y / 2);
1358 backBottomLeft.Z = orig.Z - (part.Scale.Z / 2);
1360 backBottomRight.X = orig.X + (part.Scale.X / 2);
1361 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
1362 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
1396 frontTopLeft = frontTopLeft * worldRot;
1397 frontTopRight = frontTopRight * worldRot;
1398 frontBottomLeft = frontBottomLeft * worldRot;
1399 frontBottomRight = frontBottomRight * worldRot;
1401 backBottomLeft = backBottomLeft * worldRot;
1402 backBottomRight = backBottomRight * worldRot;
1403 backTopLeft = backTopLeft * worldRot;
1404 backTopRight = backTopRight * worldRot;
1407 frontTopLeft += offset;
1408 frontTopRight += offset;
1409 frontBottomLeft += offset;
1410 frontBottomRight += offset;
1412 backBottomLeft += offset;
1413 backBottomRight += offset;
1414 backTopLeft += offset;
1415 backTopRight += offset;
1426 if (frontTopRight.X > maxX)
1427 maxX = frontTopRight.X;
1428 if (frontTopLeft.X > maxX)
1429 maxX = frontTopLeft.X;
1430 if (frontBottomRight.X > maxX)
1431 maxX = frontBottomRight.X;
1432 if (frontBottomLeft.X > maxX)
1433 maxX = frontBottomLeft.X;
1435 if (backTopRight.X > maxX)
1436 maxX = backTopRight.X;
1437 if (backTopLeft.X > maxX)
1438 maxX = backTopLeft.X;
1439 if (backBottomRight.X > maxX)
1440 maxX = backBottomRight.X;
1441 if (backBottomLeft.X > maxX)
1442 maxX = backBottomLeft.X;
1444 if (frontTopRight.X < minX)
1445 minX = frontTopRight.X;
1446 if (frontTopLeft.X < minX)
1447 minX = frontTopLeft.X;
1448 if (frontBottomRight.X < minX)
1449 minX = frontBottomRight.X;
1450 if (frontBottomLeft.X < minX)
1451 minX = frontBottomLeft.X;
1453 if (backTopRight.X < minX)
1454 minX = backTopRight.X;
1455 if (backTopLeft.X < minX)
1456 minX = backTopLeft.X;
1457 if (backBottomRight.X < minX)
1458 minX = backBottomRight.X;
1459 if (backBottomLeft.X < minX)
1460 minX = backBottomLeft.X;
1463 if (frontTopRight.Y > maxY)
1464 maxY = frontTopRight.Y;
1465 if (frontTopLeft.Y > maxY)
1466 maxY = frontTopLeft.Y;
1467 if (frontBottomRight.Y > maxY)
1468 maxY = frontBottomRight.Y;
1469 if (frontBottomLeft.Y > maxY)
1470 maxY = frontBottomLeft.Y;
1472 if (backTopRight.Y > maxY)
1473 maxY = backTopRight.Y;
1474 if (backTopLeft.Y > maxY)
1475 maxY = backTopLeft.Y;
1476 if (backBottomRight.Y > maxY)
1477 maxY = backBottomRight.Y;
1478 if (backBottomLeft.Y > maxY)
1479 maxY = backBottomLeft.Y;
1481 if (frontTopRight.Y < minY)
1482 minY = frontTopRight.Y;
1483 if (frontTopLeft.Y < minY)
1484 minY = frontTopLeft.Y;
1485 if (frontBottomRight.Y < minY)
1486 minY = frontBottomRight.Y;
1487 if (frontBottomLeft.Y < minY)
1488 minY = frontBottomLeft.Y;
1490 if (backTopRight.Y < minY)
1491 minY = backTopRight.Y;
1492 if (backTopLeft.Y < minY)
1493 minY = backTopLeft.Y;
1494 if (backBottomRight.Y < minY)
1495 minY = backBottomRight.Y;
1496 if (backBottomLeft.Y < minY)
1497 minY = backBottomLeft.Y;
1500 if (frontTopRight.Z > maxZ)
1501 maxZ = frontTopRight.Z;
1502 if (frontTopLeft.Z > maxZ)
1503 maxZ = frontTopLeft.Z;
1504 if (frontBottomRight.Z > maxZ)
1505 maxZ = frontBottomRight.Z;
1506 if (frontBottomLeft.Z > maxZ)
1507 maxZ = frontBottomLeft.Z;
1509 if (backTopRight.Z > maxZ)
1510 maxZ = backTopRight.Z;
1511 if (backTopLeft.Z > maxZ)
1512 maxZ = backTopLeft.Z;
1513 if (backBottomRight.Z > maxZ)
1514 maxZ = backBottomRight.Z;
1515 if (backBottomLeft.Z > maxZ)
1516 maxZ = backBottomLeft.Z;
1518 if (frontTopRight.Z < minZ)
1519 minZ = frontTopRight.Z;
1520 if (frontTopLeft.Z < minZ)
1521 minZ = frontTopLeft.Z;
1522 if (frontBottomRight.Z < minZ)
1523 minZ = frontBottomRight.Z;
1524 if (frontBottomLeft.Z < minZ)
1525 minZ = frontBottomLeft.Z;
1527 if (backTopRight.Z < minZ)
1528 minZ = backTopRight.Z;
1529 if (backTopLeft.Z < minZ)
1530 minZ = backTopLeft.Z;
1531 if (backBottomRight.Z < minZ)
1532 minZ = backBottomRight.Z;
1533 if (backBottomLeft.Z < minZ)
1534 minZ = backBottomLeft.Z;
1547 GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
1548 Vector3 boundingBox =
new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
1551 float lower = (minZ * -1);
1554 offsetHeight = lower - (boundingBox.Z / 2);
1557 else if (maxZ > lower)
1559 offsetHeight = maxZ - (boundingBox.Z / 2);
1570 out
float linksetResCost, out
float linksetPhysCost, out
float partCost, out
float partPhysCost)
1577 bool ComplexCost =
false;
1584 parts = m_parts.GetArray();
1587 int nparts = parts.Length;
1590 for (
int i = 0; i < nparts; i++)
1604 linksetPhysCost = 0;
1608 for (
int i = 0; i < nparts; i++)
1612 cost = p.StreamingCost;
1613 tmpcost = p.SimulationCost;
1616 tmpcost = p.PhysicsCost;
1620 linksetPhysCost += tmpcost;
1621 linksetResCost += cost;
1626 partPhysCost = tmpcost;
1632 partPhysCost = 1.0f;
1634 linksetResCost = (float)nparts;
1635 linksetPhysCost = linksetResCost;
1646 parts = m_parts.GetArray();
1649 int nparts = parts.Length;
1655 for (
int i = 0; i < nparts; i++)
1659 StreamCost += p.StreamingCost;
1660 SimulCost += p.SimulationCost;
1661 PhysCost += p.PhysicsCost;
1667 SaveScriptedState(writer,
false);
1672 XmlDocument doc =
new XmlDocument();
1673 Dictionary<UUID,string> states =
new Dictionary<UUID,string>();
1676 for (
int i = 0; i < parts.Length; i++)
1678 Dictionary<UUID, string> pstates = parts[i].Inventory.GetScriptStates(oldIDs);
1679 foreach (KeyValuePair<UUID, string> kvp
in pstates)
1680 states[kvp.Key] = kvp.Value;
1683 if (states.Count > 0)
1686 writer.WriteStartElement(String.Empty,
"GroupScriptStates", String.Empty);
1687 foreach (
UUID itemid
in states.Keys)
1689 doc.LoadXml(states[itemid]);
1690 writer.WriteStartElement(String.Empty,
"SavedScriptState", String.Empty);
1691 writer.WriteAttributeString(String.Empty,
"UUID", String.Empty, itemid.ToString());
1692 writer.WriteRaw(doc.DocumentElement.OuterXml);
1693 writer.WriteEndElement();
1695 writer.WriteEndElement();
1705 private void AttachToAgent(
1714 m_scene.DeleteFromStorage(so.UUID);
1715 m_scene.EventManager.TriggerParcelPrimCountTainted();
1717 so.AttachedAvatar = avatar.UUID;
1721 m_scene.PhysicsScene.RemovePrim(so.RootPart.PhysActor);
1722 so.RootPart.PhysActor = null;
1725 so.AbsolutePosition = attachOffset;
1726 so.RootPart.AttachedPos = attachOffset;
1727 so.IsAttachment =
true;
1728 so.RootPart.SetParentLocalId(avatar.LocalId);
1729 so.AttachmentPoint = attachmentpoint;
1731 avatar.AddAttachment(
this);
1741 m_scene.SendKillObject(
new List<uint> { m_rootPart.LocalId });
1745 ScheduleGroupForFullUpdate();
1751 "[SOG]: Tried to add attachment {0} to avatar with UUID {1} in region {2} but the avatar is not present",
1752 UUID, avatar.ControllingClient.AgentId, Scene.RegionInfo.RegionName);
1758 return m_rootPart.Shape.State;
1763 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
1766 m_rootPart.Shape.LastAttachPoint = m_rootPart.Shape.State;
1767 m_rootPart.AttachedPos = m_rootPart.OffsetPosition;
1768 avatar.RemoveAttachment(
this);
1770 Vector3 detachedpos =
new Vector3(127f,127f,127f);
1774 detachedpos = avatar.AbsolutePosition;
1775 FromItemID = UUID.Zero;
1777 AbsolutePosition = detachedpos;
1778 AttachedAvatar = UUID.Zero;
1784 m_rootPart.SetParentLocalId(0);
1790 HasGroupChanged =
true;
1791 RootPart.Rezzed = DateTime.Now;
1792 RootPart.RemFlag(PrimFlags.TemporaryOnRez);
1794 m_scene.EventManager.TriggerParcelPrimCountTainted();
1795 m_rootPart.ScheduleFullUpdate();
1796 m_rootPart.ClearUndoState();
1801 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
1806 avatar.RemoveAttachment(
this);
1809 AttachedAvatar = UUID.Zero;
1815 m_rootPart.SetParentLocalId(0);
1817 IsAttachment =
false;
1818 AbsolutePosition = m_rootPart.AttachedPos;
1830 part.ParentID = m_rootPart.LocalId;
1831 part.ClearUndoState();
1836 return Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
1846 throw new ArgumentNullException(
"Cannot give SceneObjectGroup a null root SceneObjectPart");
1848 part.SetParent(
this);
1854 m_parts.Add(m_rootPart.UUID, m_rootPart);
1863 part.SetParent(
this);
1864 m_parts.Add(part.UUID, part);
1866 part.LinkNum = m_parts.Count;
1869 RootPart.LinkNum = 1;
1875 private void UpdateParentIDs()
1878 for (
int i = 0; i < parts.Length; i++)
1881 if (part.
UUID != m_rootPart.UUID)
1882 part.ParentID = m_rootPart.LocalId;
1889 for (
int i = 0; i < parts.Length; i++)
1896 if (m_scene != null)
1897 return m_scene.MaxUndoCount;
1929 Vector3 groupPosition = m_rootPart.GroupPosition;
1934 if (part != m_rootPart)
1935 part.GroupPosition = groupPosition;
1951 if (m_rootPart.LocalId == localId)
1953 OnGrabGroup(offsetPos, remoteClient);
1958 OnGrabPart(part, offsetPos, remoteClient);
1969 part.OnGrab(offsetPos, remoteClient);
1974 m_scene.EventManager.TriggerGroupGrab(
UUID, offsetPos, remoteClient.AgentId);
1994 for (
int i = 0; i < parts.Length; i++)
2000 Scene.ForEachRootScenePresence(delegate(
ScenePresence avatar)
2007 part.ClearUpdateSchedule();
2008 if (part == m_rootPart)
2012 || !HasPrivateAttachmentPoint)
2013 avatar.ControllingClient.SendKillObject(
new List<uint> { part.LocalId });
2023 m_scene.SceneGraph.AddToScriptLPS(count);
2029 d.AddActiveScripts(count);
2039 for (
int i = 0; i < parts.Length; i++)
2044 if (part != RootPart)
2045 part.Flags = objectflagupdate;
2046 aggregateScriptEvents |= part.AggregateScriptEvents;
2049 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
2050 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
2052 if (!m_scriptListens_atTarget && !m_scriptListens_notAtTarget)
2056 m_scene.RemoveGroupTarget(
this);
2058 m_scriptListens_atRotTarget = ((aggregateScriptEvents & scriptEvents.at_rot_target) != 0);
2059 m_scriptListens_notAtRotTarget = ((aggregateScriptEvents & scriptEvents.not_at_rot_target) != 0);
2061 if (!m_scriptListens_atRotTarget && !m_scriptListens_notAtRotTarget)
2064 m_rotTargets.Clear();
2065 m_scene.RemoveGroupTarget(
this);
2068 ScheduleGroupForFullUpdate();
2071 public void SetText(
string text, Vector3 color,
double alpha)
2073 Color = Color.FromArgb(0xff - (int) (alpha * 0xff),
2074 (int) (color.X * 0xff),
2075 (int) (color.Y * 0xff),
2076 (int) (color.Z * 0xff));
2079 HasGroupChanged =
true;
2080 m_rootPart.ScheduleFullUpdate();
2089 if (parts.Length > 1)
2091 ResetChildPrimPhysicsPositions();
2094 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive,
true);
2097 for (
int i = 0; i < parts.Length; i++)
2100 if (part.
LocalId != m_rootPart.LocalId)
2101 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.
VolumeDetectActive,
true);
2105 if (m_rootPart.PhysActor != null)
2107 m_rootPart.PhysActor.Building =
false;
2113 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive,
false);
2122 part.OwnerID = userId;
2130 for (
int i = 0; i < parts.Length; i++)
2149 if (IsDeleted || inTransit ||
UUID ==
UUID.Zero)
2156 if ((RootPart.Flags &
PrimFlags.TemporaryOnRez) != 0)
2163 if (!m_scene.ShuttingDown ||
2164 !m_scene.LoginsEnabled ||
2165 m_scene.LoadingPrims)
2168 ILandObject parcel = m_scene.LandChannel.GetLandObject(
2169 m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y);
2171 if (parcel != null && parcel.
LandData != null &&
2178 if ((DateTime.UtcNow - RootPart.Rezzed).TotalMinutes >
2179 parcel.LandData.OtherCleanTime)
2183 "[SCENE OBJECT GROUP]: Returning object {0} due to parcel autoreturn",
2185 m_scene.AddReturn(OwnerID == GroupID ? LastOwnerID : OwnerID, Name, AbsolutePosition,
"parcel autoreturn");
2186 m_scene.DeRezObjects(null,
new List<uint>() { RootPart.LocalId }, UUID.Zero,
2187 DeRezAction.Return, UUID.Zero);
2196 if (m_scene.UseBackup && HasGroupChanged)
2199 if (isTimeToPersist() || forcedBackup)
2201 if (m_rootPart.PhysActor != null &&
2202 (!m_rootPart.PhysActor.IsPhysical))
2205 if (m_rootPart.PhysActor.Position != m_rootPart.GroupPosition)
2211 part.GroupPosition = m_rootPart.GroupPosition;
2219 if (RootPart.Shape.PCode == 9 && RootPart.Shape.State != 0)
2221 RootPart.Shape.LastAttachPoint = RootPart.Shape.State;
2222 RootPart.Shape.State = 0;
2223 ScheduleGroupForFullUpdate();
2227 backup_group.RootPart.Velocity = RootPart.Velocity;
2228 backup_group.RootPart.Acceleration = RootPart.Acceleration;
2229 backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity;
2230 backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem;
2231 HasGroupChanged =
false;
2232 GroupContainsForeignPrims =
false;
2234 m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group,
this);
2236 datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID);
2240 part.Inventory.ProcessInventoryBackup(datastore);
2244 part.KeyframeMotion.Delete();
2245 part.KeyframeMotion = null;
2249 backup_group.Clear();
2250 backup_group = null;
2263 "[SCENE]: Storing of {0}, {1} in {2} failed with exception {3}{4}",
2264 Name,
UUID, m_scene.RegionInfo.RegionName, e.Message, e.StackTrace);
2279 RootPart.SendFullUpdate(remoteClient);
2282 for (
int i = 0; i < parts.Length; i++)
2285 if (part != RootPart)
2286 part.SendFullUpdate(remoteClient);
2299 m_dupeInProgress =
true;
2302 dupe.m_parts =
new MapAndArray<OpenMetaverse.UUID,
SceneObjectPart>();
2305 dupe.Backup =
false;
2308 dupe.inTransit =
false;
2311 dupe.m_sittingAvatars =
new List<ScenePresence>();
2313 dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed);
2314 dupe.m_rootPart.LinkNum = m_rootPart.LinkNum;
2318 dupe.m_rootPart.TrimPermissions();
2320 List<SceneObjectPart> partList =
new List<SceneObjectPart>(m_parts.GetArray());
2324 return p1.LinkNum.CompareTo(p2.LinkNum);
2331 if (part.
UUID != m_rootPart.UUID)
2333 newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed);
2334 newPart.LinkNum = part.LinkNum;
2336 newPart.ParentID = dupe.m_rootPart.LocalId;
2340 newPart = dupe.m_rootPart;
2368 newPart.KeyframeMotion = part.KeyframeMotion.Copy(dupe);
2375 if (dupe.m_rootPart.PhysActor != null)
2376 dupe.m_rootPart.PhysActor.Building =
false;
2378 dupe.HasGroupChanged =
true;
2379 dupe.AttachToBackup();
2381 ScheduleGroupForFullUpdate();
2384 m_dupeInProgress =
false;
2396 SceneObjectPart newpart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed);
2400 SetRootPart(newpart);
2402 RootPart.Velocity = Vector3.Zero;
2409 if (RootPart.KeyframeMotion != null)
2410 RootPart.KeyframeMotion.Stop();
2411 RootPart.KeyframeMotion = null;
2413 UpdatePrimFlags(RootPart.LocalId, usePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2418 UpdatePrimFlags(RootPart.LocalId, UsesPhysics, makeTemporary, IsPhantom, IsVolumeDetect);
2423 UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, makePhantom, IsVolumeDetect);
2428 UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, IsPhantom, makeVolumeDetect);
2448 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
2451 avatar.PushForce(impulse);
2461 pa.AddForce(impulse,
false);
2462 m_scene.PhysicsScene.AddPhysicsActorTaint(pa);
2476 pa.AddAngularForce(impulse,
false);
2477 m_scene.PhysicsScene.AddPhysicsActorTaint(pa);
2484 return RootPart.Torque;
2492 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
2495 avatar.MoveToTarget(target,
false,
false);
2503 pa.PIDTarget = target;
2505 pa.PIDActive =
true;
2514 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
2518 avatar.ResetMoveToTarget();
2526 pa.PIDActive =
false;
2528 RootPart.ScheduleTerseUpdate();
2532 public void RotLookAt(Quaternion target,
float strength,
float damping)
2538 if(!UsesPhysics || IsAttachment)
2542 if (rootpart != null)
2554 rootpart.RotLookAt(target, strength, damping);
2558 public void StartLookAt(Quaternion target,
float strength,
float damping)
2564 if(!UsesPhysics || IsAttachment)
2567 if (m_rootPart != null)
2568 m_rootPart.RotLookAt(target, strength, damping);
2574 if (rootpart != null)
2578 rootpart.PhysActor.APIDActive =
false;
2581 rootpart.StopLookAt();
2595 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
2597 pa = avatar.PhysicsActor;
2600 pa = RootPart.PhysActor;
2606 pa.PIDHoverHeight = height;
2607 pa.PIDHoverType = hoverType;
2608 pa.PIDHoverTau = tau;
2609 pa.PIDHoverActive =
true;
2613 pa.PIDHoverActive =
false;
2626 part.LastOwnerID = part.OwnerID;
2627 part.OwnerID = cAgentID;
2628 part.GroupID = cGroupID;
2633 if (!m_scene.Permissions.BypassPermissions())
2634 ApplyNextOwnerPermissions();
2637 part.ScheduleFullUpdate();
2648 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
2654 SetPartAsNonRoot(newPart);
2667 lock (m_parts.SyncRoot)
2669 List<SceneObjectPart> partsList =
new List<SceneObjectPart>(m_parts.GetArray());
2673 part.ResetIDs(part.LinkNum);
2674 m_parts.Add(part.UUID, part);
2685 remoteClient.SendObjectPropertiesFamilyData(RootPart, RequestFlags);
2695 part.OwnerID = cAgentID;
2696 part.GroupID = cGroupID;
2709 if (IsDeleted || inTransit)
2721 m_rootPart.UpdateFlag = UpdateRequired.TERSE;
2726 ScenePresence sp = m_scene.GetScenePresence(AttachedAvatar);
2729 sp.SendAttachmentScheduleUpdate(
this);
2736 RootPart.UpdateLookAt();
2739 for (
int i = 0; i < parts.Length; i++)
2742 part.SendScheduledUpdates();
2760 RootPart.ScheduleFullUpdate();
2763 for (
int i = 0; i < parts.Length; i++)
2766 if (part != RootPart)
2767 part.ScheduleFullUpdate();
2784 for (
int i = 0; i < parts.Length; i++)
2785 parts[i].ScheduleTerseUpdate();
2800 ScenePresence sp = m_scene.GetScenePresence(AttachedAvatar);
2803 sp.SendAttachmentUpdate(
this,UpdateRequired.FULL);
2808 RootPart.SendFullUpdateToAllClientsInternal();
2811 for (
int i = 0; i < parts.Length; i++)
2814 if (part != RootPart)
2815 part.SendFullUpdateToAllClientsInternal();
2827 if (IsDeleted || inTransit)
2830 RootPart.SendTerseUpdateToAllClients();
2835 if (m_scene == null)
2838 m_scene.SceneGraph.AddToUpdateList(
this);
2846 if (IsDeleted || inTransit)
2851 ScenePresence sp = m_scene.GetScenePresence(AttachedAvatar);
2854 sp.SendAttachmentUpdate(
this, UpdateRequired.TERSE);
2860 for (
int i = 0; i < parts.Length; i++)
2861 parts[i].SendTerseUpdateToAllClientsInternal();
2870 m_rootPart.SendPropertiesToClient(client);
2873 #region SceneGroupPart Methods
2883 for (
int i = 0; i < parts.Length; i++)
2885 if (parts[i].LinkNum == linknum)
2900 m_parts.TryGetValue(primID, out childPart);
2912 for (
int i = 0; i < parts.Length; i++)
2914 if (parts[i].LocalId == localID)
2923 #region Packet Handlers
2935 LinkToGroup(objectGroup,
false);
2947 if (objectGroup ==
this)
2953 if (m_scene.m_linksetCapacity > 0 &&
2955 m_scene.m_linksetCapacity)
2958 "[SCENE OBJECT GROUP]: Cannot link group with root" +
2959 " part {0}, {1} ({2} prims) to group with root part" +
2960 " {3}, {4} ({5} prims) because the new linkset" +
2961 " would exceed the configured maximum of {6}",
2962 objectGroup.RootPart.Name, objectGroup.RootPart.UUID,
2963 objectGroup.PrimCount, RootPart.Name, RootPart.UUID,
2964 PrimCount, m_scene.m_linksetCapacity);
2972 if (UsesPhysics && m_scene.m_linksetPhysCapacity > 0 && (PrimCount + objectGroup.
PrimCount) >
2973 m_scene.m_linksetPhysCapacity)
2987 if (cntr > m_scene.m_linksetPhysCapacity)
2999 if (m_rootPart.PhysActor != null)
3000 m_rootPart.PhysActor.Building =
true;
3002 linkPart.PhysActor.Building =
true;
3005 bool grpusephys = UsesPhysics;
3006 bool grptemporary = IsTemporary;
3009 Vector3 oldGroupPosition = linkPart.GroupPosition;
3010 Quaternion oldRootRotation = linkPart.RotationOffset;
3020 linkPart.setOffsetPosition(linkPart.GroupPosition - AbsolutePosition);
3022 linkPart.ParentID = m_rootPart.LocalId;
3024 linkPart.setGroupPosition(AbsolutePosition);
3027 Quaternion parentRot = m_rootPart.RotationOffset;
3030 Quaternion oldRot = linkPart.RotationOffset;
3031 Quaternion newRot = Quaternion.Conjugate(parentRot) * oldRot;
3032 linkPart.setRotationOffset(newRot);
3034 Vector3 axPos = linkPart.OffsetPosition;
3035 axPos *= Quaternion.Conjugate(parentRot);
3036 linkPart.OffsetPosition = axPos;
3042 if (m_rootPart.LinkNum == 0)
3043 m_rootPart.LinkNum = 1;
3045 lock (m_parts.SyncRoot)
3060 linkNum = PrimCount + 1;
3064 m_parts.Add(linkPart.UUID, linkPart);
3066 linkPart.SetParent(
this);
3067 m_scene.updateScenePartGroup(linkPart,
this);
3069 linkPart.CreateSelected =
true;
3072 linkPart.UpdatePrimFlags(grpusephys, grptemporary, (IsPhantom || (linkPart.Flags & PrimFlags.Phantom) != 0), linkPart.VolumeDetectActive,
true);
3075 if (linkPart.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical)
3077 linkPart.PhysActor.link(m_rootPart.PhysActor);
3078 this.Scene.PhysicsScene.AddPhysicsActorTaint(linkPart.PhysActor);
3081 linkPart.LinkNum = linkNum++;
3082 linkPart.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect,
false);
3088 return a.LinkNum - b.LinkNum;
3092 for (
int i = 0; i < ogParts.Length; i++)
3097 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
3101 part.UpdatePrimFlags(grpusephys, grptemporary, (IsPhantom || (part.Flags & PrimFlags.Phantom) != 0), part.VolumeDetectActive,
true);
3104 if (part.
PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.
IsPhysical)
3106 part.PhysActor.link(m_rootPart.PhysActor);
3107 this.Scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
3110 part.ClearUndoState();
3115 m_scene.UnlinkSceneObject(objectGroup,
true);
3116 objectGroup.IsDeleted =
true;
3118 objectGroup.m_parts.Clear();
3124 AdjustChildPrimPermissions(
false);
3126 GroupContainsForeignPrims =
true;
3133 ResetChildPrimPhysicsPositions();
3135 if (m_rootPart.PhysActor != null)
3136 m_rootPart.PhysActor.Building =
false;
3155 return DelinkFromGroup(partID,
true);
3174 if (linkPart != null)
3176 return DelinkFromGroup(linkPart, sendEvents);
3180 m_log.WarnFormat(
"[SCENE OBJECT GROUP]: " +
3181 "DelinkFromGroup(): Child prim {0} not found in object {1}, {2}",
3182 partID, LocalId,
UUID);
3206 if (m_rootPart.PhysActor != null)
3207 m_rootPart.PhysActor.Building =
true;
3209 linkPart.ClearUndoState();
3211 Vector3 worldPos = linkPart.GetWorldPosition();
3212 Quaternion worldRot = linkPart.GetWorldRotation();
3215 lock (m_parts.SyncRoot)
3217 m_parts.Remove(linkPart.UUID);
3222 if (parts.Length == 1 && RootPart != null)
3225 RootPart.LinkNum = 0;
3229 for (
int i = 0; i < parts.Length; i++)
3238 linkPart.ParentID = 0;
3239 linkPart.LinkNum = 0;
3248 if (linkPartPa != null)
3249 m_scene.PhysicsScene.RemovePrim(linkPartPa);
3263 linkPart.setGroupPosition(worldPos);
3264 linkPart.setOffsetPosition(Vector3.Zero);
3265 linkPart.setRotationOffset(worldRot);
3270 m_scene.AddNewSceneObject(objectGroup,
true);
3272 linkPart.Rezzed = RootPart.Rezzed;
3281 if (m_rootPart.PhysActor != null)
3282 m_rootPart.PhysActor.Building =
false;
3284 objectGroup.HasGroupChangedDueToDelink =
true;
3287 linkPart.TriggerScriptChangedEvent(Changed.LINK);
3298 if (m_scene != null)
3299 m_scene.SceneGraph.FireDetachFromBackup(
this);
3300 if (Backup &&
Scene != null)
3301 m_scene.EventManager.OnBackup -= ProcessBackup;
3311 private void LinkNonRootPart(
SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation,
int linkNum)
3313 Quaternion parentRot = oldGroupRotation;
3314 Quaternion oldRot = part.RotationOffset;
3317 Vector3 axPos = part.OffsetPosition;
3319 Vector3 newPos = oldGroupPosition + axPos;
3320 part.setGroupPosition(newPos);
3321 part.setOffsetPosition(Vector3.Zero);
3324 Quaternion worldRot = parentRot * oldRot;
3325 part.RotationOffset = worldRot;
3328 part.SetParent(
this);
3329 part.ParentID = m_rootPart.LocalId;
3330 m_parts.Add(part.UUID, part);
3332 part.LinkNum = linkNum;
3334 m_scene.updateScenePartGroup(part,
this);
3337 part.setOffsetPosition(newPos - AbsolutePosition);
3345 parentRot = m_rootPart.RotationOffset;
3347 oldRot = part.RotationOffset;
3348 Quaternion newRot = Quaternion.Conjugate(parentRot) * worldRot;
3349 part.setRotationOffset(newRot);
3351 Vector3 pos = part.OffsetPosition;
3352 pos *= Quaternion.Conjugate(parentRot);
3354 part.OffsetPosition = pos;
3372 if (m_scene.EventManager.TriggerGroupMove(
UUID, pos))
3385 if (!BlockGrabOverride && !part.
BlockGrab)
3392 Vector3 grabforce = pos - AbsolutePosition;
3393 grabforce = grabforce * (pa.Mass/ 10.0f);
3394 pa.AddForce(grabforce,
false);
3395 m_scene.PhysicsScene.AddPhysicsActorTaint(pa);
3400 NonPhysicalGrabMovement(pos);
3405 NonPhysicalGrabMovement(pos);
3419 if(!IsAttachment && ScriptCount() == 0)
3420 UpdateGroupPosition(pos);
3430 if (m_scene.EventManager.TriggerGroupSpinStart(
UUID))
3438 m_rootPart.IsWaitingForFirstSpinUpdatePacket =
true;
3477 if (m_scene.EventManager.TriggerGroupSpin(
UUID, newOrientation))
3485 if (m_rootPart.IsWaitingForFirstSpinUpdatePacket)
3488 m_rootPart.SpinOldOrientation = newOrientation;
3489 m_rootPart.IsWaitingForFirstSpinUpdatePacket =
false;
3494 Quaternion old = m_rootPart.SpinOldOrientation;
3495 m_rootPart.SpinOldOrientation = newOrientation;
3500 Quaternion minimalRotationFromQ1ToQ2 = Quaternion.Inverse(old) * newOrientation;
3502 float rotationAngle;
3503 Vector3 rotationAxis;
3504 minimalRotationFromQ1ToQ2.GetAxisAngle(out rotationAxis, out rotationAngle);
3505 rotationAxis.Normalize();
3508 Vector3 spinforce =
new Vector3(rotationAxis.X, rotationAxis.Y, rotationAxis.Z);
3509 spinforce = (spinforce/8) * pa.
Mass;
3511 m_scene.PhysicsScene.AddPhysicsActorTaint(pa);
3516 NonPhysicalSpinMovement(newOrientation);
3521 NonPhysicalSpinMovement(newOrientation);
3531 private void NonPhysicalSpinMovement(Quaternion newOrientation)
3533 if(!IsAttachment && ScriptCount() == 0)
3534 UpdateGroupRotationR(newOrientation);
3556 part.Description = des;
3585 return String.Empty;
3593 return part.Description;
3595 return String.Empty;
3606 public void UpdatePrimFlags(uint localID,
bool UsePhysics,
bool SetTemporary,
bool SetPhantom,
bool SetVolumeDetect)
3608 HasGroupChanged =
true;
3619 m_scene.DeleteFromStorage(
UUID);
3628 m_scene.EventManager.TriggerParcelPrimCountTainted();
3631 if (selectionPart != null)
3635 if (
Scene != null && UsePhysics)
3637 int maxprims = m_scene.m_linksetPhysCapacity;
3638 bool checkShape = (maxprims > 0 &&
3639 parts.Length > maxprims);
3641 for (
int i = 0; i < parts.Length; i++)
3644 if (part.
Scale.X > m_scene.m_maxPhys ||
3645 part.
Scale.Y > m_scene.m_maxPhys ||
3646 part.
Scale.Z > m_scene.m_maxPhys )
3663 if (parts.Length > 1)
3665 m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect,
true);
3667 for (
int i = 0; i < parts.Length; i++)
3670 if (parts[i].
UUID != m_rootPart.UUID)
3671 parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect,
true);
3674 if (m_rootPart.PhysActor != null)
3675 m_rootPart.PhysActor.Building =
false;
3678 m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect,
false);
3687 part.UpdateExtraParam(type, inUse, data);
3699 return Parts.Count();
3712 part.UpdateTextureEntry(textureEntry);
3719 uint foldedPerms = RootPart.OwnerMask & 3;
3723 newOwnerMask &= part.BaseMask;
3724 if (part != RootPart)
3726 if (forceTaskInventoryPermissive)
3727 part.Inventory.ApplyGodPermissions(part.BaseMask);
3732 RootPart.OwnerMask = (RootPart.OwnerMask & lockBit) | ((newOwnerMask | foldedPerms) & lockMask);
3738 RootPart.ScheduleFullUpdate();
3742 uint mask, byte addRemTF)
3744 RootPart.UpdatePermissions(AgentID, field, localID, mask, addRemTF);
3746 bool god = Scene.Permissions.IsGod(AgentID);
3748 if (field == 1 && god)
3752 part.BaseMask = RootPart.BaseMask;
3756 AdjustChildPrimPermissions(
false);
3758 if (field == 1 && god)
3761 part.Inventory.ApplyGodPermissions(RootPart.BaseMask);
3764 HasGroupChanged =
true;
3769 SendPropertiesToClient(client);
3780 public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock, uint localID)
3785 part.UpdateShape(shapeBlock);
3790 m_scene.PhysicsScene.AddPhysicsActorTaint(pa);
3812 float minsize = Scene.m_minNonphys;
3813 float maxsize = Scene.m_maxNonphys;
3817 minsize = Scene.m_minPhys;
3818 maxsize = Scene.m_maxPhys;
3821 scale.X = Util.Clamp(scale.X, minsize, maxsize);
3822 scale.Y = Util.Clamp(scale.Y, minsize, maxsize);
3823 scale.Z = Util.Clamp(scale.Z, minsize, maxsize);
3826 float x = (scale.X / RootPart.Scale.X);
3827 float y = (scale.Y / RootPart.Scale.Y);
3828 float z = (scale.Z / RootPart.Scale.Z);
3833 for(
int i = 0;i < parts.Length;i++)
3836 if(obPart.
UUID != m_rootPart.UUID)
3838 Vector3 oldSize =
new Vector3(obPart.
Scale);
3843 if(oldSize.X * x > maxsize)
3845 f = maxsize / oldSize.X;
3851 else if(oldSize.X * x < minsize)
3853 f = minsize / oldSize.X;
3860 if(oldSize.Y * y > maxsize)
3862 f = maxsize / oldSize.Y;
3868 else if(oldSize.Y * y < minsize)
3870 f = minsize / oldSize.Y;
3877 if(oldSize.Z * z > maxsize)
3879 f = maxsize / oldSize.Z;
3885 else if(oldSize.Z * z < minsize)
3887 f = minsize / oldSize.Z;
3896 Vector3 rootScale = RootPart.Scale;
3901 RootPart.Scale = rootScale;
3903 for (
int i = 0; i < parts.Length; i++)
3907 if (obPart.
UUID != m_rootPart.UUID)
3914 Vector3 newSize =
new Vector3(obPart.
Scale);
3919 obPart.Scale = newSize;
3920 obPart.UpdateOffSet(currentpos);
3923 HasGroupChanged =
true;
3924 m_rootPart.TriggerScriptChangedEvent(Changed.SCALE);
3925 ScheduleGroupForFullUpdate();
3939 if (m_scene.EventManager.TriggerGroupMove(
UUID, pos))
3943 m_rootPart.AttachedPos = pos;
3946 if (RootPart.GetStatusSandbox())
3948 if (Util.GetDistanceTo(RootPart.StatusSandboxPos, pos) > 10)
3950 RootPart.ScriptSetPhysicsStatus(
false);
3951 pos = AbsolutePosition;
3952 Scene.SimChat(Utils.StringToBytes(
"Hit Sandbox Limit"),
3953 ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name,
UUID,
false);
3957 AbsolutePosition = pos;
3958 HasGroupChanged =
true;
3963 RootPart.ScheduleTerseUpdate();
3980 if (m_rootPart.PhysActor != null)
3981 m_rootPart.PhysActor.Building =
true;
3983 if (part.
UUID == m_rootPart.UUID)
3985 UpdateRootPosition(pos);
3989 part.UpdateOffSet(pos);
3992 if (m_rootPart.PhysActor != null)
3993 m_rootPart.PhysActor.Building =
false;
3995 HasGroupChanged =
true;
4009 oldPos = m_rootPart.AttachedPos + m_rootPart.OffsetPosition;
4011 oldPos = AbsolutePosition + m_rootPart.OffsetPosition;
4013 Vector3 diff = oldPos - newPos;
4014 Quaternion partRotation = m_rootPart.RotationOffset;
4015 diff *= Quaternion.Inverse(partRotation);
4018 for (
int i = 0; i < parts.Length; i++)
4021 if (obPart.
UUID != m_rootPart.UUID)
4022 obPart.OffsetPosition = obPart.OffsetPosition + diff;
4025 AbsolutePosition = newPos;
4028 m_rootPart.AttachedPos = newPos;
4030 HasGroupChanged =
true;
4031 if (m_rootPart.Undoing)
4033 ScheduleGroupForFullUpdate();
4037 ScheduleGroupForTerseUpdate();
4051 m_rootPart.UpdateRotation(rot);
4061 HasGroupChanged =
true;
4062 ScheduleGroupForTerseUpdate();
4072 m_rootPart.UpdateRotation(rot);
4077 actor.Orientation = m_rootPart.RotationOffset;
4078 m_scene.PhysicsScene.AddPhysicsActorTaint(actor);
4083 m_rootPart.AttachedPos = pos;
4086 AbsolutePosition = pos;
4088 HasGroupChanged =
true;
4089 ScheduleGroupForTerseUpdate();
4105 if (m_rootPart.PhysActor != null)
4106 m_rootPart.PhysActor.Building =
true;
4108 if (part.
UUID == m_rootPart.UUID)
4110 UpdateRootRotation(rot);
4114 part.UpdateRotation(rot);
4117 if (m_rootPart.PhysActor != null)
4118 m_rootPart.PhysActor.Building =
false;
4132 if (m_rootPart.PhysActor != null)
4133 m_rootPart.PhysActor.Building =
true;
4135 if (part.
UUID == m_rootPart.UUID)
4137 UpdateRootRotation(rot);
4138 AbsolutePosition = pos;
4142 part.UpdateRotation(rot);
4143 part.OffsetPosition = pos;
4146 if (m_rootPart.PhysActor != null)
4147 m_rootPart.PhysActor.Building =
false;
4158 Quaternion axRot = rot;
4159 Quaternion oldParentRot = m_rootPart.RotationOffset;
4162 m_rootPart.RotationOffset = rot;
4168 pa.Orientation = m_rootPart.RotationOffset;
4169 m_scene.PhysicsScene.AddPhysicsActorTaint(pa);
4173 for (
int i = 0; i < parts.Length; i++)
4176 if (prim.
UUID != m_rootPart.UUID)
4178 Quaternion NewRot = oldParentRot * prim.RotationOffset;
4179 NewRot = Quaternion.Inverse(axRot) * NewRot;
4180 prim.RotationOffset = NewRot;
4182 Vector3 axPos = prim.OffsetPosition;
4184 axPos *= oldParentRot;
4185 axPos *= Quaternion.Inverse(axRot);
4186 prim.OffsetPosition = axPos;
4190 HasGroupChanged =
true;
4191 ScheduleGroupForFullUpdate();
4194 private enum updatetype :
int
4210 bool togroup = ((change & ObjectChangeType.Group) != 0);
4216 updatetype updateType = updatetype.none;
4226 updateType = updatetype.none;
4230 if (IsAttachment || m_scene.Permissions.CanObjectEntry(group.
UUID,
false, data.
position))
4231 UpdateGroupPosition(data.
position);
4232 updateType = updatetype.groupterse;
4237 group.ResetChildPrimPhysicsPositions();
4244 pha.Building =
true;
4246 group.GroupResize(data.scale);
4247 updateType = updatetype.none;
4250 pha.Building =
false;
4257 pha.Building =
true;
4267 group.UpdateRootPosition(data.position);
4275 part.OffsetPosition = data.position;
4276 updateType = updatetype.partterse;
4281 updateType = updatetype.none;
4285 part.Resize(data.scale);
4286 updateType = updatetype.none;
4291 pha.Building =
false;
4294 if (updateType != updatetype.none)
4296 group.HasGroupChanged =
true;
4300 case updatetype.partterse:
4301 part.ScheduleTerseUpdate();
4303 case updatetype.partfull:
4304 part.ScheduleFullUpdate();
4306 case updatetype.groupterse:
4307 group.ScheduleGroupForTerseUpdate();
4309 case updatetype.groupfull:
4310 group.ScheduleGroupForFullUpdate();
4321 internal void SetAxisRotation(
int axis,
int rotate10)
4327 if (setX || setY || setZ)
4329 bool lockaxis = (rotate10 == 0);
4331 byte locks = RootPart.RotationAxisLocks;
4338 locks &= (byte)SceneObjectGroup.axisSelect.NOT_STATUS_ROTATE_X;
4344 locks |= (byte)SceneObjectGroup.axisSelect.STATUS_ROTATE_Y;
4346 locks &= (byte)SceneObjectGroup.axisSelect.NOT_STATUS_ROTATE_Y;
4352 locks |= (byte)SceneObjectGroup.axisSelect.STATUS_ROTATE_Z;
4354 locks &= (byte)SceneObjectGroup.axisSelect.NOT_STATUS_ROTATE_Z;
4357 RootPart.RotationAxisLocks = locks;
4358 RootPart.SetPhysicsAxisRotation();
4364 byte rotAxislocks = RootPart.RotationAxisLocks;
4380 waypoint.targetRot = target;
4381 waypoint.tolerance = tolerance;
4382 uint handle = m_scene.AllocateLocalId();
4383 waypoint.handle = handle;
4386 if (m_rotTargets.Count >= 8)
4387 m_rotTargets.Remove(m_rotTargets.ElementAt(0).Key);
4388 m_rotTargets.Add(handle, waypoint);
4390 m_scene.AddGroupTarget(
this);
4398 m_rotTargets.Remove((uint)handle);
4399 if (m_targets.Count == 0)
4400 m_scene.RemoveGroupTarget(
this);
4407 waypoint.targetPos = target;
4408 waypoint.tolerance = tolerance;
4409 uint handle = m_scene.AllocateLocalId();
4410 waypoint.handle = handle;
4413 if (m_targets.Count >= 8)
4414 m_targets.Remove(m_targets.ElementAt(0).Key);
4415 m_targets.Add(handle, waypoint);
4417 m_scene.AddGroupTarget(
this);
4425 m_targets.Remove((uint)handle);
4426 if (m_targets.Count == 0)
4427 m_scene.RemoveGroupTarget(
this);
4433 if (m_scriptListens_atTarget || m_scriptListens_notAtTarget)
4435 if (m_targets.Count > 0)
4440 Dictionary<uint, scriptPosTarget> atTargets =
new Dictionary<uint, scriptPosTarget>();
4443 foreach (uint idx
in m_targets.Keys)
4446 if (Util.GetDistanceTo(target.
targetPos, m_rootPart.GroupPosition) <= target.tolerance)
4451 if (m_scriptListens_atTarget)
4454 att.targetPos = target.targetPos;
4455 att.tolerance = target.tolerance;
4456 att.handle = target.handle;
4457 atTargets.Add(idx, att);
4463 if (atTargets.Count > 0)
4466 uint[] localids =
new uint[parts.Length];
4467 for (
int i = 0; i < parts.Length; i++)
4468 localids[i] = parts[i].LocalId;
4470 for (
int ctr = 0; ctr < localids.Length; ctr++)
4472 foreach (uint target
in atTargets.Keys)
4475 m_scene.EventManager.TriggerAtTargetEvent(
4476 localids[ctr], att.handle, att.targetPos, m_rootPart.GroupPosition);
4483 if (m_scriptListens_notAtTarget && !at_target)
4487 uint[] localids =
new uint[parts.Length];
4488 for (
int i = 0; i < parts.Length; i++)
4489 localids[i] = parts[i].LocalId;
4491 for (
int ctr = 0; ctr < localids.Length; ctr++)
4493 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
4498 if (m_scriptListens_atRotTarget || m_scriptListens_notAtRotTarget)
4500 if (m_rotTargets.Count > 0)
4502 bool at_Rottarget =
false;
4503 Dictionary<uint, scriptRotTarget> atRotTargets =
new Dictionary<uint, scriptRotTarget>();
4506 foreach (uint idx
in m_rotTargets.Keys)
4511 target.targetRot.X * m_rootPart.RotationOffset.X
4512 + target.targetRot.Y * m_rootPart.RotationOffset.Y
4513 + target.targetRot.Z * m_rootPart.RotationOffset.Z
4514 + target.targetRot.W * m_rootPart.RotationOffset.W)
4516 if (angle < 0) angle = -angle;
4517 if (angle > Math.PI) angle = (Math.PI * 2 - angle);
4521 if (m_scriptListens_atRotTarget)
4523 at_Rottarget =
true;
4525 att.targetRot = target.targetRot;
4526 att.tolerance = target.tolerance;
4527 att.handle = target.handle;
4528 atRotTargets.Add(idx, att);
4534 if (atRotTargets.Count > 0)
4537 uint[] localids =
new uint[parts.Length];
4538 for (
int i = 0; i < parts.Length; i++)
4539 localids[i] = parts[i].LocalId;
4541 for (
int ctr = 0; ctr < localids.Length; ctr++)
4543 foreach (uint target
in atRotTargets.Keys)
4546 m_scene.EventManager.TriggerAtRotTargetEvent(
4547 localids[ctr], att.handle, att.targetRot, m_rootPart.RotationOffset);
4554 if (m_scriptListens_notAtRotTarget && !at_Rottarget)
4558 uint[] localids =
new uint[parts.Length];
4559 for (
int i = 0; i < parts.Length; i++)
4560 localids[i] = parts[i].LocalId;
4562 for (
int ctr = 0; ctr < localids.Length; ctr++)
4564 m_scene.EventManager.TriggerNotAtRotTargetEvent(localids[ctr]);
4578 Vector3 gc = Vector3.Zero;
4580 int nparts = m_parts.Count;
4585 nparts = parts.Length;
4589 Quaternion parentRot = RootPart.RotationOffset;
4593 for (
int i = 0; i < nparts; i++)
4597 if (parts[i] != RootPart)
4599 pPos = parts[i].OffsetPosition;
4615 for (
int i = 0; i < parts.Length; i++)
4616 retmass += parts[i].GetMass();
4626 if(((RootPart.Flags &
PrimFlags.Physics) !=0) && pa !=null)
4629 Vector3 tmp = pa.CenterOfMass;
4633 Vector3 Ptot = Vector3.Zero;
4638 for (
int i = 0; i < parts.Length; i++)
4640 m = parts[i].GetMass();
4641 Ptot += parts[i].GetPartCenterOfMass() * m;
4648 totmass = 1 / totmass;
4686 for (
int i = 0; i < parts.Length; i++)
4689 part.SetGroup(GroupID, client);
4690 part.Inventory.ChangeInventoryGroup(GroupID);
4693 HasGroupChanged =
true;
4703 for (
int i = 0; i < parts.Length; i++)
4704 parts[i].TriggerScriptChangedEvent(val);
4714 for (
int i = 0; i < parts.Length; i++)
4715 count += parts[i].Inventory.ScriptCount();
4727 if (engines.Length == 0)
4734 List<TaskInventoryItem> scripts =
new List<TaskInventoryItem>();
4735 for (
int i = 0; i < parts.Length; i++)
4737 scripts.AddRange(parts[i].Inventory.GetInventoryItems(InventoryType.LSL));
4740 List<UUID> ids =
new List<UUID>(scripts.Count);
4743 if (!ids.Contains(script.
ItemID))
4745 ids.Add(script.ItemID);
4753 time += e.GetScriptExecutionTime(ids);
4766 for (
int i = 0; i < parts.Length; i++)
4767 count += parts[i].Inventory.RunningScriptCount();
4782 lock (m_sittingAvatars)
4783 return new List<ScenePresence>(m_sittingAvatars);
4793 lock (m_sittingAvatars)
4794 return m_sittingAvatars.Count;
4799 return String.Format(
"{0} {1} ({2})", Name,
UUID, AbsolutePosition);
4802 #region ISceneObject
4807 sog.IsDeleted =
false;
4813 return SceneObjectSerializer.ToXml2Format(
this);
4818 return "<ExtraFromItemID>" + FromItemID.ToString() +
"</ExtraFromItemID>";
4823 string id = xmlstr.Substring(xmlstr.IndexOf(
"<ExtraFromItemID>"));
4824 id = xmlstr.Replace(
"<ExtraFromItemID>",
"");
4825 id = id.Replace(
"</ExtraFromItemID>",
"");
4827 UUID uuid = UUID.Zero;
4828 UUID.TryParse(id, out uuid);
4837 part.ResetOwnerChangeFlag();
4845 m_sittingAvatars.Clear();
4848 m_PlaySoundMasterPrim = null;
4849 m_PlaySoundSlavePrims.Clear();
4850 m_LoopSoundMasterPrim = null;
virtual void OnGrabGroup(Vector3 offsetPos, IClientAPI remoteClient)
void MoveToTarget(Vector3 target, float tau)
void SendGroupTerseUpdate()
Immediately send a terse update for this scene object.
SceneObjectGroup(SceneObjectPart part)
This constructor creates a SceneObjectGroup using a pre-existing SceneObjectPart. The original SceneO...
SceneObjectGroup CrossAsync(SceneObjectGroup sog, Vector3 val)
void AdjustChildPrimPermissions(bool forceTaskInventoryPermissive)
void SetPartName(string name, uint localID)
Set the name of a prim
Vector3 GetGeometricCenter()
void ApplyAngularImpulse(Vector3 impulse)
IClientAPI ControllingClient
void SendGroupRootTerseUpdate()
Immediately send an update for this scene object's root prim only. This is for updates regarding the ...
abstract void AddAngularForce(Vector3 force, bool pushforce)
void ResetOwnerChangeFlag()
void SetPartText(string text, UUID partID)
int GetPartCount()
Gets the number of parts
void SetPartOwner(SceneObjectPart part, UUID cAgentID, UUID cGroupID)
const uint MaximumRegionSize
void ResetChildPrimPhysicsPositions()
SceneObjectGroup DelinkFromGroup(uint partID)
Delink the given prim from this group. The delinked prim is established as an independent SceneObject...
void NonPhysicalGrabMovement(Vector3 pos)
Apply possition for grabbing non-physical linksets (Ctrl+Drag) This MUST be blocked for linksets that...
void SetRootPartOwner(SceneObjectPart part, UUID cAgentID, UUID cGroupID)
Set the owner of the root part.
SceneObjectPart GetLinkNumPart(int linknum)
Get the child part by LinkNum
SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
Make a copy of the given part.
void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock, uint localID)
override string ToString()
void UpdatePrimFlags(uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect)
Update prim flags for this group.
Vector3 GetCenterOfMass()
void UpdateGroupRotationPR(Vector3 pos, Quaternion rot)
Update the position and rotation of a group simultaneously.
void ScriptSetPhysicsStatus(bool usePhysics)
void SetPartText(string text, uint localID)
void StartLookAt(Quaternion target, float strength, float damping)
void AddPart(SceneObjectPart part)
Add a new part to this scene object. The part must already be correctly configured.
SceneObjectGroup DelinkFromGroup(SceneObjectPart linkPart, bool sendEvents)
Delink the given prim from this group. The delinked prim is established as an independent SceneObject...
void PartSelectChanged(bool partSelect)
delegate void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, ExtraPhysicsData PhysData, IClientAPI remoteClient)
SceneObjectGroup(UUID ownerID, Vector3 pos, PrimitiveBaseShape shape)
Constructor.
void ObjectGrabHandler(uint localId, Vector3 offsetPos, IClientAPI remoteClient)
void SpinMovement(Quaternion newOrientation, IClientAPI remoteClient)
If object is physical, apply torque to spin it around
float ScriptExecutionTime()
A float the value is a representative execution time in milliseconds of all scripts in the link set...
virtual void AttachToBackup()
Hooks this object up to the backup event so that it is persisted to the database when the update thre...
UUID GetPartsFullID(uint localID)
bool ContainsPart(uint localID)
Does this group contain the given part? should be able to remove these methods once we have a entity ...
void SendPropertiesToClient(IClientAPI client)
Send metadata about the root prim (name, description, sale price, permissions, etc.) to a client.
void GetResourcesCosts(SceneObjectPart apart, out float linksetResCost, out float linksetPhysCost, out float partCost, out float partPhysCost)
SceneObjectGroup(UUID ownerID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape)
Constructor. This object is added to the scene later via AttachToScene()
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
void GroupResize(Vector3 scale)
Resize the entire group of prims.
void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
Gets a vector representing the size of the bounding box containing all the prims in the group Treats ...
PrimFlags Flags
Property flags. See OpenMetaverse.PrimFlags
void SetHoverHeight(float height, PIDHoverType hoverType, float tau)
Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds...
int registerTargetWaypoint(Vector3 target, float tolerance)
Represents an item in a task inventory
void AttachToScene(Scene scene)
Attach this object to a scene. It will also now appear to agents.
void LoadScriptState(XmlDocument doc)
void ScriptSetPhantomStatus(bool makePhantom)
override void Update()
Performs any updates that need to be done at each frame, as opposed to immediately. These included scheduled updates and updates that occur due to physics processing.
void UpdateRootRotation(Quaternion rot)
Update the rotation of just the root prim of a linkset.
void UpdateExtraParam(uint localID, ushort type, bool inUse, byte[] data)
SceneObjectGroup()
Constructor
void SetOwnerId(UUID userId)
virtual void ExtraFromXmlString(string xmlstr)
int OtherCleanTime
Autoreturn number of minutes to return SceneObjectGroup that are owned by someone who doesn't own the...
void AddActiveScriptCount(int count)
void Resize(Vector3 scale)
Set the scale of this part.
int GetAxisRotation(int axis)
void applyImpulse(Vector3 impulse)
SceneObjectGroup Copy(bool userExposed)
Duplicates this object, including operations such as physics set up and attaching to the backup event...
Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
void ClearPartAttachmentData()
void UpdatePermissions(UUID AgentID, byte field, uint localID, uint mask, byte addRemTF)
int PrimCount
Number of prims in this group
void ScriptSetTemporaryStatus(bool makeTemporary)
SceneObjectPart GetPart(uint localID)
Get a part with a given local ID
void RotLookAt(Quaternion target, float strength, float damping)
void ClonePermissions(SceneObjectPart source)
void unregisterRotTargetWaypoint(int handle)
void DeleteGroupFromScene(bool silent)
Delete this group from its scene.
void TriggerScriptChangedEvent(Changed val)
void UpdateGroupRotationR(Quaternion rot)
Update the rotation of the group.
Vector3 Scale
Change the scale of this part.
bool IsAttachmentCheckFull()
Check both the attachment property and the relevant properties of the underlying root part...
EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly, bool faceCenters)
void CrossAsyncCompleted(IAsyncResult iar)
void AddScriptLPS(int count)
OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion rotation
UUID GroupID
Unique ID of the Group that owns
void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags)
void aggregateScriptEvents()
void SetGroup(UUID GroupID, IClientAPI client)
If the object is a sculpt/mesh, retrieve the mesh data for each part and reinsert it into each shape ...
void UpdateRootPosition(Vector3 newPos)
Update just the root prim position in a linkset
SceneObjectPart GetPart(UUID primID)
Get a part with a given UUID
delegate void PrimCountTaintedDelegate()
void UpdateSingleRotation(Quaternion rot, Vector3 pos, uint localID)
Update the position and rotation simultaneously of a single prim within the group.
void doChangeObject(SceneObjectPart part, ObjectChangeData data)
void SetPartDescription(string des, uint localID)
void LinkToGroup(SceneObjectGroup objectGroup, bool insert)
void UpdateSinglePosition(Vector3 pos, uint localID)
Update the position of a single part of this scene object
string GetPartName(uint localID)
PhysicsActor PhysActor
The representation of this part in the physics scene.
virtual void ProcessBackup(ISimulationDataService datastore, bool forcedBackup)
Processes backup.
byte DefaultPhysicsShapeType()
void GrabMovement(UUID partID, Vector3 offset, Vector3 pos, IClientAPI remoteClient)
If object is physical, apply force to move it around If object is not physical, just put it at the re...
virtual void DetachFromBackup()
Stop this object from being persisted over server restarts.
void UpdateGroupPosition(Vector3 pos)
Move this scene object
bool ContainsPart(UUID partID)
void SaveScriptedState(XmlTextWriter writer)
void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
Copy the given part as the root part of this scene object.
byte GetAttachmentPoint()
void GetSelectedCosts(out float PhysCost, out float StreamCost, out float SimulCost)
int ScriptCount()
Returns a count of the number of scripts in this groups parts.
void SendFullUpdateToClient(IClientAPI remoteClient)
Send the parts of this SOG to a single client
void unregisterTargetWaypoint(int handle)
void ScheduleGroupForTerseUpdate()
Schedule a terse update for this scene object to all interested viewers.
SceneObjectGroup ParentGroup
void ScheduleGroupForFullUpdate()
Schedule a full update for this scene object to all interested viewers.
void ApplyPhysics()
Apply physics to this group
void ForEachPart(Action< SceneObjectPart > whatToDo)
virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient)
uint ParentID
The parent ID of this part.
bool PositionIsInCurrentRegion(Vector3 pos)
void ResetIDs()
Reset the UUIDs for all the prims that make up this group.
bool IsInTransit
This signals whether the presence is in transit between neighbouring regions.
int GetSittingAvatarsCount()
Gets the number of sitting avatars.
void SendGroupFullUpdate()
Immediately send a full update for this scene object.
void UpdateTextureEntry(uint localID, byte[] textureEntry)
Update the texture entry for this part
string GetPartDescription(uint localID)
void DetachToInventoryPrep()
int RunningScriptCount()
Returns a count of the number of running scripts in this groups parts.
int registerRotTargetWaypoint(Quaternion target, float tolerance)
void LinkToGroup(SceneObjectGroup objectGroup)
Link the prims in a given group to this group
void UpdateSingleRotation(Quaternion rot, uint localID)
Update the rotation of a single prim within the group.
SceneObjectGroup DelinkFromGroup(uint partID, bool sendEvents)
Delink the given prim from this group. The delinked prim is established as an independent SceneObject...
KeyframeMotion KeyframeMotion
void SetText(string text, Vector3 color, double alpha)
SceneObjectPart m_rootPart
void SetRootPart(SceneObjectPart part)
Set a part to act as the root part for this scene object
virtual string ExtraToXmlString()
OpenSim.Framework.PermissionMask PermissionMask
void SaveScriptedState(XmlTextWriter writer, bool oldIDs)
bool TryGetClient(UUID avatarID, out IClientAPI client)
virtual ISceneObject CloneForNewScene()
void SpinStart(IClientAPI remoteClient)
If object is physical, prepare for spinning torques (set flag to save old orientation) ...
This class used to be called InnerScene and may not yet truly be a SceneGraph. The non scene graph co...
void ScriptSetVolumeDetect(bool makeVolumeDetect)
List< ScenePresence > GetSittingAvatars()
Get a copy of the list of sitting avatars on all prims of this object.
void LoadScriptState(XmlReader reader)
void QueueForUpdateCheck()
uint ParentID
If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero...
UUID OwnerID
Owner Avatar or Group of the parcel. Naturally, all land masses must be owned by someone ...