diff options
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 154 |
1 files changed, 152 insertions, 2 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index f16a8e6..a2e4417 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -429,6 +429,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
429 | return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0)); | 429 | return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0)); |
430 | } | 430 | } |
431 | 431 | ||
432 | private struct avtocrossInfo | ||
433 | { | ||
434 | public ScenePresence av; | ||
435 | public uint ParentID; | ||
436 | } | ||
437 | |||
432 | /// <summary> | 438 | /// <summary> |
433 | /// The absolute position of this scene object in the scene | 439 | /// The absolute position of this scene object in the scene |
434 | /// </summary> | 440 | /// </summary> |
@@ -456,13 +462,124 @@ namespace OpenSim.Region.Framework.Scenes | |||
456 | || Scene.TestBorderCross(val, Cardinals.S)) | 462 | || Scene.TestBorderCross(val, Cardinals.S)) |
457 | && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) | 463 | && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) |
458 | { | 464 | { |
465 | IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); | ||
466 | uint x = 0; | ||
467 | uint y = 0; | ||
468 | string version = String.Empty; | ||
469 | Vector3 newpos = Vector3.Zero; | ||
470 | OpenSim.Services.Interfaces.GridRegion destination = null; | ||
471 | |||
459 | if (m_rootPart.KeyframeMotion != null) | 472 | if (m_rootPart.KeyframeMotion != null) |
460 | m_rootPart.KeyframeMotion.StartCrossingCheck(); | 473 | m_rootPart.KeyframeMotion.StartCrossingCheck(); |
461 | 474 | ||
462 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); | 475 | bool canCross = true; |
476 | foreach (ScenePresence av in m_linkedAvatars) | ||
477 | { | ||
478 | // We need to cross these agents. First, let's find | ||
479 | // out if any of them can't cross for some reason. | ||
480 | // We have to deny the crossing entirely if any | ||
481 | // of them are banned. Alternatively, we could | ||
482 | // unsit banned agents.... | ||
483 | |||
484 | |||
485 | // We set the avatar position as being the object | ||
486 | // position to get the region to send to | ||
487 | if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out x, out y, out version, out newpos)) == null) | ||
488 | { | ||
489 | canCross = false; | ||
490 | break; | ||
491 | } | ||
492 | |||
493 | m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName); | ||
494 | } | ||
495 | |||
496 | if (canCross) | ||
497 | { | ||
498 | // We unparent the SP quietly so that it won't | ||
499 | // be made to stand up | ||
500 | |||
501 | List<avtocrossInfo> avsToCross = new List<avtocrossInfo>(); | ||
502 | |||
503 | foreach (ScenePresence av in m_linkedAvatars) | ||
504 | { | ||
505 | avtocrossInfo avinfo = new avtocrossInfo(); | ||
506 | SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID); | ||
507 | if (parentPart != null) | ||
508 | av.ParentUUID = parentPart.UUID; | ||
509 | |||
510 | avinfo.av = av; | ||
511 | avinfo.ParentID = av.ParentID; | ||
512 | avsToCross.Add(avinfo); | ||
513 | |||
514 | av.PrevSitOffset = av.OffsetPosition; | ||
515 | av.ParentID = 0; | ||
516 | } | ||
517 | |||
518 | // m_linkedAvatars.Clear(); | ||
519 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); | ||
520 | |||
521 | // Normalize | ||
522 | if (val.X >= Constants.RegionSize) | ||
523 | val.X -= Constants.RegionSize; | ||
524 | if (val.Y >= Constants.RegionSize) | ||
525 | val.Y -= Constants.RegionSize; | ||
526 | if (val.X < 0) | ||
527 | val.X += Constants.RegionSize; | ||
528 | if (val.Y < 0) | ||
529 | val.Y += Constants.RegionSize; | ||
530 | |||
531 | // If it's deleted, crossing was successful | ||
532 | if (IsDeleted) | ||
533 | { | ||
534 | // foreach (ScenePresence av in m_linkedAvatars) | ||
535 | foreach (avtocrossInfo avinfo in avsToCross) | ||
536 | { | ||
537 | ScenePresence av = avinfo.av; | ||
538 | if (!av.IsInTransit) // just in case... | ||
539 | { | ||
540 | m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val); | ||
541 | |||
542 | av.IsInTransit = true; | ||
543 | |||
544 | CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync; | ||
545 | d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d); | ||
546 | } | ||
547 | else | ||
548 | m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val); | ||
549 | } | ||
550 | avsToCross.Clear(); | ||
551 | return; | ||
552 | } | ||
553 | else // cross failed, put avas back ?? | ||
554 | { | ||
555 | foreach (avtocrossInfo avinfo in avsToCross) | ||
556 | { | ||
557 | ScenePresence av = avinfo.av; | ||
558 | av.ParentUUID = UUID.Zero; | ||
559 | av.ParentID = avinfo.ParentID; | ||
560 | // m_linkedAvatars.Add(av); | ||
561 | } | ||
562 | } | ||
563 | avsToCross.Clear(); | ||
564 | |||
565 | } | ||
566 | else | ||
567 | { | ||
568 | if (m_rootPart.KeyframeMotion != null) | ||
569 | m_rootPart.KeyframeMotion.CrossingFailure(); | ||
570 | |||
571 | if (RootPart.PhysActor != null) | ||
572 | { | ||
573 | RootPart.PhysActor.CrossingFailure(); | ||
574 | } | ||
575 | } | ||
576 | Vector3 oldp = AbsolutePosition; | ||
577 | val.X = Util.Clamp<float>(oldp.X, 0.5f, (float)Constants.RegionSize - 0.5f); | ||
578 | val.Y = Util.Clamp<float>(oldp.Y, 0.5f, (float)Constants.RegionSize - 0.5f); | ||
579 | val.Z = Util.Clamp<float>(oldp.Z, 0.5f, 4096.0f); | ||
463 | } | 580 | } |
464 | } | 581 | } |
465 | 582 | ||
466 | if (RootPart.GetStatusSandbox()) | 583 | if (RootPart.GetStatusSandbox()) |
467 | { | 584 | { |
468 | if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) | 585 | if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) |
@@ -496,6 +613,39 @@ namespace OpenSim.Region.Framework.Scenes | |||
496 | } | 613 | } |
497 | } | 614 | } |
498 | 615 | ||
616 | public override Vector3 Velocity | ||
617 | { | ||
618 | get { return RootPart.Velocity; } | ||
619 | set { RootPart.Velocity = value; } | ||
620 | } | ||
621 | |||
622 | private void CrossAgentToNewRegionCompleted(IAsyncResult iar) | ||
623 | { | ||
624 | CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState; | ||
625 | ScenePresence agent = icon.EndInvoke(iar); | ||
626 | |||
627 | //// If the cross was successful, this agent is a child agent | ||
628 | if (agent.IsChildAgent) | ||
629 | { | ||
630 | if (agent.ParentUUID != UUID.Zero) | ||
631 | { | ||
632 | agent.ParentPart = null; | ||
633 | // agent.ParentPosition = Vector3.Zero; | ||
634 | // agent.ParentUUID = UUID.Zero; | ||
635 | } | ||
636 | } | ||
637 | |||
638 | agent.ParentUUID = UUID.Zero; | ||
639 | // agent.Reset(); | ||
640 | // else // Not successful | ||
641 | // agent.RestoreInCurrentScene(); | ||
642 | |||
643 | // In any case | ||
644 | agent.IsInTransit = false; | ||
645 | |||
646 | m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); | ||
647 | } | ||
648 | |||
499 | public override uint LocalId | 649 | public override uint LocalId |
500 | { | 650 | { |
501 | get { return m_rootPart.LocalId; } | 651 | get { return m_rootPart.LocalId; } |