diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 202 |
1 files changed, 196 insertions, 6 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index e31270c..c6b98ca 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -121,6 +121,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
121 | private bool m_hasGroupChanged = false; | 121 | private bool m_hasGroupChanged = false; |
122 | private long timeFirstChanged; | 122 | private long timeFirstChanged; |
123 | private long timeLastChanged; | 123 | private long timeLastChanged; |
124 | private List<ScenePresence> m_linkedAvatars = new List<ScenePresence>(); | ||
124 | 125 | ||
125 | /// <summary> | 126 | /// <summary> |
126 | /// This indicates whether the object has changed such that it needs to be repersisted to permenant storage | 127 | /// This indicates whether the object has changed such that it needs to be repersisted to permenant storage |
@@ -333,7 +334,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
333 | { | 334 | { |
334 | get | 335 | get |
335 | { | 336 | { |
336 | Vector3 minScale = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize); | 337 | Vector3 minScale = new Vector3(Constants.MaximumRegionSize, Constants.MaximumRegionSize, Constants.MaximumRegionSize); |
337 | Vector3 maxScale = Vector3.Zero; | 338 | Vector3 maxScale = Vector3.Zero; |
338 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); | 339 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); |
339 | 340 | ||
@@ -431,6 +432,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
431 | return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0)); | 432 | return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0)); |
432 | } | 433 | } |
433 | 434 | ||
435 | private struct avtocrossInfo | ||
436 | { | ||
437 | public ScenePresence av; | ||
438 | public uint ParentID; | ||
439 | } | ||
440 | |||
434 | /// <summary> | 441 | /// <summary> |
435 | /// The absolute position of this scene object in the scene | 442 | /// The absolute position of this scene object in the scene |
436 | /// </summary> | 443 | /// </summary> |
@@ -458,13 +465,122 @@ namespace OpenSim.Region.Framework.Scenes | |||
458 | || Scene.TestBorderCross(val, Cardinals.S)) | 465 | || Scene.TestBorderCross(val, Cardinals.S)) |
459 | && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) | 466 | && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) |
460 | { | 467 | { |
468 | IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); | ||
469 | string version = String.Empty; | ||
470 | Vector3 newpos = Vector3.Zero; | ||
471 | OpenSim.Services.Interfaces.GridRegion destination = null; | ||
472 | |||
461 | if (m_rootPart.KeyframeMotion != null) | 473 | if (m_rootPart.KeyframeMotion != null) |
462 | m_rootPart.KeyframeMotion.StartCrossingCheck(); | 474 | m_rootPart.KeyframeMotion.StartCrossingCheck(); |
463 | 475 | ||
464 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); | 476 | bool canCross = true; |
477 | foreach (ScenePresence av in m_linkedAvatars) | ||
478 | { | ||
479 | // We need to cross these agents. First, let's find | ||
480 | // out if any of them can't cross for some reason. | ||
481 | // We have to deny the crossing entirely if any | ||
482 | // of them are banned. Alternatively, we could | ||
483 | // unsit banned agents.... | ||
484 | |||
485 | |||
486 | // We set the avatar position as being the object | ||
487 | // position to get the region to send to | ||
488 | if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out version, out newpos)) == null) | ||
489 | { | ||
490 | canCross = false; | ||
491 | break; | ||
492 | } | ||
493 | |||
494 | m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName); | ||
495 | } | ||
496 | |||
497 | if (canCross) | ||
498 | { | ||
499 | // We unparent the SP quietly so that it won't | ||
500 | // be made to stand up | ||
501 | |||
502 | List<avtocrossInfo> avsToCross = new List<avtocrossInfo>(); | ||
503 | |||
504 | foreach (ScenePresence av in m_linkedAvatars) | ||
505 | { | ||
506 | avtocrossInfo avinfo = new avtocrossInfo(); | ||
507 | SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID); | ||
508 | if (parentPart != null) | ||
509 | av.ParentUUID = parentPart.UUID; | ||
510 | |||
511 | avinfo.av = av; | ||
512 | avinfo.ParentID = av.ParentID; | ||
513 | avsToCross.Add(avinfo); | ||
514 | |||
515 | av.PrevSitOffset = av.OffsetPosition; | ||
516 | av.ParentID = 0; | ||
517 | } | ||
518 | |||
519 | // m_linkedAvatars.Clear(); | ||
520 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); | ||
521 | |||
522 | // Normalize | ||
523 | if (val.X >= m_scene.RegionInfo.RegionSizeX) | ||
524 | val.X -= m_scene.RegionInfo.RegionSizeX; | ||
525 | if (val.Y >= m_scene.RegionInfo.RegionSizeY) | ||
526 | val.Y -= m_scene.RegionInfo.RegionSizeY; | ||
527 | if (val.X < 0) | ||
528 | val.X += m_scene.RegionInfo.RegionSizeX; | ||
529 | if (val.Y < 0) | ||
530 | val.Y += m_scene.RegionInfo.RegionSizeY; | ||
531 | |||
532 | // If it's deleted, crossing was successful | ||
533 | if (IsDeleted) | ||
534 | { | ||
535 | // foreach (ScenePresence av in m_linkedAvatars) | ||
536 | foreach (avtocrossInfo avinfo in avsToCross) | ||
537 | { | ||
538 | ScenePresence av = avinfo.av; | ||
539 | if (!av.IsInTransit) // just in case... | ||
540 | { | ||
541 | m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val); | ||
542 | |||
543 | av.IsInTransit = true; | ||
544 | |||
545 | CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync; | ||
546 | d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d); | ||
547 | } | ||
548 | else | ||
549 | m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val); | ||
550 | } | ||
551 | avsToCross.Clear(); | ||
552 | return; | ||
553 | } | ||
554 | else // cross failed, put avas back ?? | ||
555 | { | ||
556 | foreach (avtocrossInfo avinfo in avsToCross) | ||
557 | { | ||
558 | ScenePresence av = avinfo.av; | ||
559 | av.ParentUUID = UUID.Zero; | ||
560 | av.ParentID = avinfo.ParentID; | ||
561 | // m_linkedAvatars.Add(av); | ||
562 | } | ||
563 | } | ||
564 | avsToCross.Clear(); | ||
565 | |||
566 | } | ||
567 | else | ||
568 | { | ||
569 | if (m_rootPart.KeyframeMotion != null) | ||
570 | m_rootPart.KeyframeMotion.CrossingFailure(); | ||
571 | |||
572 | if (RootPart.PhysActor != null) | ||
573 | { | ||
574 | RootPart.PhysActor.CrossingFailure(); | ||
575 | } | ||
576 | } | ||
577 | Vector3 oldp = AbsolutePosition; | ||
578 | val.X = Util.Clamp<float>(oldp.X, 0.5f, (float)m_scene.RegionInfo.RegionSizeX - 0.5f); | ||
579 | val.Y = Util.Clamp<float>(oldp.Y, 0.5f, (float)m_scene.RegionInfo.RegionSizeY - 0.5f); | ||
580 | val.Z = Util.Clamp<float>(oldp.Z, 0.5f, Constants.RegionHeight); | ||
465 | } | 581 | } |
466 | } | 582 | } |
467 | 583 | ||
468 | if (RootPart.GetStatusSandbox()) | 584 | if (RootPart.GetStatusSandbox()) |
469 | { | 585 | { |
470 | if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) | 586 | if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) |
@@ -498,6 +614,39 @@ namespace OpenSim.Region.Framework.Scenes | |||
498 | } | 614 | } |
499 | } | 615 | } |
500 | 616 | ||
617 | public override Vector3 Velocity | ||
618 | { | ||
619 | get { return RootPart.Velocity; } | ||
620 | set { RootPart.Velocity = value; } | ||
621 | } | ||
622 | |||
623 | private void CrossAgentToNewRegionCompleted(IAsyncResult iar) | ||
624 | { | ||
625 | CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState; | ||
626 | ScenePresence agent = icon.EndInvoke(iar); | ||
627 | |||
628 | //// If the cross was successful, this agent is a child agent | ||
629 | if (agent.IsChildAgent) | ||
630 | { | ||
631 | if (agent.ParentUUID != UUID.Zero) | ||
632 | { | ||
633 | agent.ParentPart = null; | ||
634 | // agent.ParentPosition = Vector3.Zero; | ||
635 | // agent.ParentUUID = UUID.Zero; | ||
636 | } | ||
637 | } | ||
638 | |||
639 | agent.ParentUUID = UUID.Zero; | ||
640 | // agent.Reset(); | ||
641 | // else // Not successful | ||
642 | // agent.RestoreInCurrentScene(); | ||
643 | |||
644 | // In any case | ||
645 | agent.IsInTransit = false; | ||
646 | |||
647 | m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); | ||
648 | } | ||
649 | |||
501 | public override uint LocalId | 650 | public override uint LocalId |
502 | { | 651 | { |
503 | get { return m_rootPart.LocalId; } | 652 | get { return m_rootPart.LocalId; } |
@@ -845,9 +994,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
845 | maxX = -256f; | 994 | maxX = -256f; |
846 | maxY = -256f; | 995 | maxY = -256f; |
847 | maxZ = -256f; | 996 | maxZ = -256f; |
848 | minX = 256f; | 997 | minX = 10000f; |
849 | minY = 256f; | 998 | minY = 10000f; |
850 | minZ = 8192f; | 999 | minZ = 10000f; |
851 | 1000 | ||
852 | SceneObjectPart[] parts = m_parts.GetArray(); | 1001 | SceneObjectPart[] parts = m_parts.GetArray(); |
853 | for (int i = 0; i < parts.Length; i++) | 1002 | for (int i = 0; i < parts.Length; i++) |
@@ -1099,6 +1248,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1099 | } | 1248 | } |
1100 | } | 1249 | } |
1101 | 1250 | ||
1251 | |||
1102 | /// <summary> | 1252 | /// <summary> |
1103 | /// | 1253 | /// |
1104 | /// </summary> | 1254 | /// </summary> |
@@ -1108,6 +1258,46 @@ namespace OpenSim.Region.Framework.Scenes | |||
1108 | part.ParentID = m_rootPart.LocalId; | 1258 | part.ParentID = m_rootPart.LocalId; |
1109 | part.ClearUndoState(); | 1259 | part.ClearUndoState(); |
1110 | } | 1260 | } |
1261 | /// <summary> | ||
1262 | /// Add the avatar to this linkset (avatar is sat). | ||
1263 | /// </summary> | ||
1264 | /// <param name="agentID"></param> | ||
1265 | public void AddAvatar(UUID agentID) | ||
1266 | { | ||
1267 | ScenePresence presence; | ||
1268 | if (m_scene.TryGetScenePresence(agentID, out presence)) | ||
1269 | { | ||
1270 | if (!m_linkedAvatars.Contains(presence)) | ||
1271 | { | ||
1272 | m_linkedAvatars.Add(presence); | ||
1273 | } | ||
1274 | } | ||
1275 | } | ||
1276 | |||
1277 | /// <summary> | ||
1278 | /// Delete the avatar from this linkset (avatar is unsat). | ||
1279 | /// </summary> | ||
1280 | /// <param name="agentID"></param> | ||
1281 | public void DeleteAvatar(UUID agentID) | ||
1282 | { | ||
1283 | ScenePresence presence; | ||
1284 | if (m_scene.TryGetScenePresence(agentID, out presence)) | ||
1285 | { | ||
1286 | if (m_linkedAvatars.Contains(presence)) | ||
1287 | { | ||
1288 | m_linkedAvatars.Remove(presence); | ||
1289 | } | ||
1290 | } | ||
1291 | } | ||
1292 | |||
1293 | /// <summary> | ||
1294 | /// Returns the list of linked presences (avatars sat on this group) | ||
1295 | /// </summary> | ||
1296 | /// <param name="agentID"></param> | ||
1297 | public List<ScenePresence> GetLinkedAvatars() | ||
1298 | { | ||
1299 | return m_linkedAvatars; | ||
1300 | } | ||
1111 | 1301 | ||
1112 | public ushort GetTimeDilation() | 1302 | public ushort GetTimeDilation() |
1113 | { | 1303 | { |