diff options
author | Melanie | 2010-10-07 05:12:39 +0200 |
---|---|---|
committer | Melanie | 2011-04-03 20:26:18 +0100 |
commit | a4b3439025f7ae8cf3a795f540675714d6324122 (patch) | |
tree | bc12f2c6a9b03c64d032b074fa296c69233d7e94 | |
parent | Implement taking of coalesced objects. (diff) | |
download | opensim-SC_OLD-a4b3439025f7ae8cf3a795f540675714d6324122.zip opensim-SC_OLD-a4b3439025f7ae8cf3a795f540675714d6324122.tar.gz opensim-SC_OLD-a4b3439025f7ae8cf3a795f540675714d6324122.tar.bz2 opensim-SC_OLD-a4b3439025f7ae8cf3a795f540675714d6324122.tar.xz |
Implement rezzing coalesced objects
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | 277 |
1 files changed, 172 insertions, 105 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 88dff02..a7d59c7 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | |||
@@ -458,7 +458,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
458 | item.Folder = folder.ID; | 458 | item.Folder = folder.ID; |
459 | item.Owner = userID; | 459 | item.Owner = userID; |
460 | if (objlist.Count > 1) | 460 | if (objlist.Count > 1) |
461 | { | ||
461 | item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; | 462 | item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; |
463 | } | ||
464 | else | ||
465 | { | ||
466 | item.SaleType = objlist[0].RootPart.ObjectSaleType; | ||
467 | item.SalePrice = objlist[0].RootPart.SalePrice; | ||
468 | } | ||
462 | } | 469 | } |
463 | 470 | ||
464 | AssetBase asset = CreateAsset( | 471 | AssetBase asset = CreateAsset( |
@@ -522,7 +529,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
522 | 7); // Preserve folded permissions | 529 | 7); // Preserve folded permissions |
523 | } | 530 | } |
524 | 531 | ||
525 | // TODO: add the new fields (Flags, Sale info, etc) | ||
526 | item.CreationDate = Util.UnixTimeSinceEpoch(); | 532 | item.CreationDate = Util.UnixTimeSinceEpoch(); |
527 | item.Description = asset.Description; | 533 | item.Description = asset.Description; |
528 | item.Name = asset.Name; | 534 | item.Name = asset.Name; |
@@ -598,6 +604,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
598 | 604 | ||
599 | AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); | 605 | AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); |
600 | 606 | ||
607 | SceneObjectGroup group = null; | ||
608 | |||
601 | if (rezAsset != null) | 609 | if (rezAsset != null) |
602 | { | 610 | { |
603 | UUID itemId = UUID.Zero; | 611 | UUID itemId = UUID.Zero; |
@@ -606,34 +614,78 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
606 | // item that it came from. This allows us to enable 'save object to inventory' | 614 | // item that it came from. This allows us to enable 'save object to inventory' |
607 | if (!m_Scene.Permissions.BypassPermissions()) | 615 | if (!m_Scene.Permissions.BypassPermissions()) |
608 | { | 616 | { |
609 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy) | 617 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) |
610 | { | 618 | { |
611 | itemId = item.ID; | 619 | itemId = item.ID; |
612 | } | 620 | } |
613 | } | 621 | } |
614 | else | 622 | else |
615 | { | 623 | { |
616 | // Brave new fullperm world | 624 | if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) |
617 | // | 625 | { |
618 | itemId = item.ID; | 626 | // Brave new fullperm world |
627 | itemId = item.ID; | ||
628 | } | ||
619 | } | 629 | } |
620 | 630 | ||
621 | string xmlData = Utils.BytesToString(rezAsset.Data); | 631 | string xmlData = Utils.BytesToString(rezAsset.Data); |
622 | SceneObjectGroup group | 632 | List<SceneObjectGroup> objlist = |
623 | = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); | 633 | new List<SceneObjectGroup>(); |
634 | List<Vector3> veclist = new List<Vector3>(); | ||
635 | |||
636 | XmlDocument doc = new XmlDocument(); | ||
637 | doc.LoadXml(xmlData); | ||
638 | XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); | ||
639 | if (e == null || attachment) // Single | ||
640 | { | ||
641 | SceneObjectGroup g = | ||
642 | SceneObjectSerializer.FromOriginalXmlFormat( | ||
643 | itemId, xmlData); | ||
644 | objlist.Add(g); | ||
645 | veclist.Add(new Vector3(0, 0, 0)); | ||
624 | 646 | ||
625 | Util.FireAndForget(delegate { AddUserData(group); }); | 647 | float offsetHeight = 0; |
626 | 648 | pos = m_Scene.GetNewRezLocation( | |
627 | group.RootPart.FromFolderID = item.Folder; | 649 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, |
650 | BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); | ||
651 | pos.Z += offsetHeight; | ||
652 | } | ||
653 | else | ||
654 | { | ||
655 | XmlElement coll = (XmlElement)e; | ||
656 | float bx = Convert.ToSingle(coll.GetAttribute("x")); | ||
657 | float by = Convert.ToSingle(coll.GetAttribute("y")); | ||
658 | float bz = Convert.ToSingle(coll.GetAttribute("z")); | ||
659 | Vector3 bbox = new Vector3(bx, by, bz); | ||
628 | 660 | ||
629 | // If it's rezzed in world, select it. Much easier to | 661 | pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, |
630 | // find small items. | 662 | RayTargetID, Quaternion.Identity, |
631 | // | 663 | BypassRayCast, bRayEndIsIntersection, true, |
632 | if (!attachment) | 664 | bbox, false); |
633 | group.RootPart.CreateSelected = true; | 665 | |
666 | pos -= bbox / 2; | ||
667 | |||
668 | XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); | ||
669 | foreach (XmlNode n in groups) | ||
670 | { | ||
671 | SceneObjectGroup g = | ||
672 | SceneObjectSerializer.FromOriginalXmlFormat( | ||
673 | itemId, n.OuterXml); | ||
674 | objlist.Add(g); | ||
675 | XmlElement el = (XmlElement)n; | ||
676 | float x = Convert.ToSingle(el.GetAttribute("offsetx")); | ||
677 | float y = Convert.ToSingle(el.GetAttribute("offsety")); | ||
678 | float z = Convert.ToSingle(el.GetAttribute("offsetz")); | ||
679 | veclist.Add(new Vector3(x, y, z)); | ||
680 | } | ||
681 | } | ||
682 | |||
683 | int primcount = 0; | ||
684 | foreach (SceneObjectGroup g in objlist) | ||
685 | primcount += g.PrimCount; | ||
634 | 686 | ||
635 | if (!m_Scene.Permissions.CanRezObject( | 687 | if (!m_Scene.Permissions.CanRezObject( |
636 | group.PrimCount, remoteClient.AgentId, pos) | 688 | primcount, remoteClient.AgentId, pos) |
637 | && !attachment) | 689 | && !attachment) |
638 | { | 690 | { |
639 | // The client operates in no fail mode. It will | 691 | // The client operates in no fail mode. It will |
@@ -646,121 +698,137 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
646 | return null; | 698 | return null; |
647 | } | 699 | } |
648 | 700 | ||
649 | group.ResetIDs(); | 701 | for (int i = 0 ; i < objlist.Count ; i++ ) |
650 | |||
651 | if (attachment) | ||
652 | { | 702 | { |
653 | group.RootPart.Flags |= PrimFlags.Phantom; | 703 | group = objlist[i]; |
654 | group.RootPart.IsAttachment = true; | 704 | |
705 | Vector3 storedPosition = group.AbsolutePosition; | ||
706 | if (group.UUID == UUID.Zero) | ||
707 | { | ||
708 | m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3"); | ||
709 | } | ||
710 | group.RootPart.FromFolderID = item.Folder; | ||
711 | |||
712 | // If it's rezzed in world, select it. Much easier to | ||
713 | // find small items. | ||
714 | // | ||
715 | if (!attachment) | ||
716 | { | ||
717 | group.RootPart.CreateSelected = true; | ||
718 | foreach (SceneObjectPart child in group.Parts) | ||
719 | child.CreateSelected = true; | ||
720 | } | ||
721 | group.ResetIDs(); | ||
722 | |||
723 | if (attachment) | ||
724 | { | ||
725 | group.RootPart.Flags |= PrimFlags.Phantom; | ||
726 | group.RootPart.IsAttachment = true; | ||
727 | } | ||
655 | 728 | ||
656 | // If we're rezzing an attachment then don't ask | 729 | // If we're rezzing an attachment then don't ask |
657 | // AddNewSceneObject() to update the client since | 730 | // AddNewSceneObject() to update the client since |
658 | // we'll be doing that later on. Scheduling more | 731 | // we'll be doing that later on. Scheduling more than |
659 | // than one full update during the attachment | 732 | // one full update during the attachment |
660 | // process causes some clients to fail to display | 733 | // process causes some clients to fail to display the |
661 | // the attachment properly. | 734 | // attachment properly. |
662 | // Also, don't persist attachments. | ||
663 | m_Scene.AddNewSceneObject(group, false, false); | ||
664 | } | ||
665 | else | ||
666 | { | ||
667 | m_Scene.AddNewSceneObject(group, true, false); | 735 | m_Scene.AddNewSceneObject(group, true, false); |
668 | } | ||
669 | 736 | ||
670 | // m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z); | 737 | // if attachment we set it's asset id so object updates |
671 | // if attachment we set it's asset id so object updates can reflect that | 738 | // can reflect that, if not, we set it's position in world. |
672 | // if not, we set it's position in world. | 739 | if (!attachment) |
673 | if (!attachment) | 740 | { |
674 | { | 741 | group.ScheduleGroupForFullUpdate(); |
675 | group.ScheduleGroupForFullUpdate(); | 742 | |
676 | 743 | group.AbsolutePosition = pos + veclist[i]; | |
677 | float offsetHeight = 0; | 744 | } |
678 | pos = m_Scene.GetNewRezLocation( | 745 | else |
679 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, | 746 | { |
680 | BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false); | 747 | group.SetFromItemID(itemID); |
681 | pos.Z += offsetHeight; | 748 | } |
682 | group.AbsolutePosition = pos; | ||
683 | // m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2} and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight); | ||
684 | |||
685 | } | ||
686 | else | ||
687 | { | ||
688 | group.SetFromItemID(itemID); | ||
689 | } | ||
690 | 749 | ||
691 | SceneObjectPart rootPart = null; | 750 | SceneObjectPart rootPart = null; |
692 | try | ||
693 | { | ||
694 | rootPart = group.GetChildPart(group.UUID); | ||
695 | } | ||
696 | catch (NullReferenceException) | ||
697 | { | ||
698 | string isAttachment = ""; | ||
699 | 751 | ||
700 | if (attachment) | 752 | try |
701 | isAttachment = " Object was an attachment"; | 753 | { |
754 | rootPart = group.GetChildPart(group.UUID); | ||
755 | } | ||
756 | catch (NullReferenceException) | ||
757 | { | ||
758 | string isAttachment = ""; | ||
702 | 759 | ||
703 | m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); | 760 | if (attachment) |
704 | } | 761 | isAttachment = " Object was an attachment"; |
705 | 762 | ||
706 | // Since renaming the item in the inventory does not affect the name stored | 763 | m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); |
707 | // in the serialization, transfer the correct name from the inventory to the | 764 | } |
708 | // object itself before we rez. | ||
709 | rootPart.Name = item.Name; | ||
710 | rootPart.Description = item.Description; | ||
711 | 765 | ||
712 | if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0) | 766 | // Since renaming the item in the inventory does not |
713 | { | 767 | // affect the name stored in the serialization, transfer |
768 | // the correct name from the inventory to the | ||
769 | // object itself before we rez. | ||
770 | rootPart.Name = item.Name; | ||
771 | rootPart.Description = item.Description; | ||
714 | rootPart.ObjectSaleType = item.SaleType; | 772 | rootPart.ObjectSaleType = item.SaleType; |
715 | rootPart.SalePrice = item.SalePrice; | 773 | rootPart.SalePrice = item.SalePrice; |
716 | } | ||
717 | 774 | ||
718 | group.SetGroup(remoteClient.ActiveGroupId, remoteClient); | 775 | group.SetGroup(remoteClient.ActiveGroupId, remoteClient); |
719 | if ((rootPart.OwnerID != item.Owner) || | 776 | if ((rootPart.OwnerID != item.Owner) || |
720 | (item.CurrentPermissions & 16) != 0 || // Magic number | 777 | (item.CurrentPermissions & 16) != 0) |
721 | (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) | ||
722 | { | ||
723 | //Need to kill the for sale here | ||
724 | rootPart.ObjectSaleType = 0; | ||
725 | rootPart.SalePrice = 10; | ||
726 | |||
727 | if (m_Scene.Permissions.PropagatePermissions()) | ||
728 | { | 778 | { |
729 | foreach (SceneObjectPart part in group.Parts) | 779 | //Need to kill the for sale here |
780 | rootPart.ObjectSaleType = 0; | ||
781 | rootPart.SalePrice = 10; | ||
782 | |||
783 | if (m_Scene.Permissions.PropagatePermissions()) | ||
730 | { | 784 | { |
731 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) | 785 | foreach (SceneObjectPart part in group.Parts) |
732 | part.EveryoneMask = item.EveryOnePermissions; | 786 | { |
733 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) | 787 | if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) |
734 | part.NextOwnerMask = item.NextPermissions; | 788 | { |
735 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) | 789 | part.EveryoneMask = item.EveryOnePermissions; |
736 | part.GroupMask = item.GroupPermissions; | 790 | part.NextOwnerMask = item.NextPermissions; |
791 | } | ||
792 | part.GroupMask = 0; // DO NOT propagate here | ||
793 | } | ||
794 | |||
795 | group.ApplyNextOwnerPermissions(); | ||
737 | } | 796 | } |
797 | } | ||
738 | 798 | ||
739 | foreach (SceneObjectPart part in group.Parts) | 799 | foreach (SceneObjectPart part in group.Parts) |
800 | { | ||
801 | if ((part.OwnerID != item.Owner) || | ||
802 | (item.CurrentPermissions & 16) != 0) | ||
740 | { | 803 | { |
741 | part.LastOwnerID = part.OwnerID; | 804 | part.LastOwnerID = part.OwnerID; |
742 | part.OwnerID = item.Owner; | 805 | part.OwnerID = item.Owner; |
743 | part.Inventory.ChangeInventoryOwner(item.Owner); | 806 | part.Inventory.ChangeInventoryOwner(item.Owner); |
807 | part.GroupMask = 0; // DO NOT propagate here | ||
744 | } | 808 | } |
745 | 809 | part.EveryoneMask = item.EveryOnePermissions; | |
746 | group.ApplyNextOwnerPermissions(); | 810 | part.NextOwnerMask = item.NextPermissions; |
747 | } | 811 | } |
748 | } | ||
749 | 812 | ||
750 | rootPart.TrimPermissions(); | 813 | rootPart.TrimPermissions(); |
751 | 814 | ||
752 | if (!attachment) | 815 | if (!attachment) |
753 | { | ||
754 | if (group.RootPart.Shape.PCode == (byte)PCode.Prim) | ||
755 | { | 816 | { |
756 | group.ClearPartAttachmentData(); | 817 | if (group.RootPart.Shape.PCode == (byte)PCode.Prim) |
757 | } | 818 | { |
758 | 819 | // Save attachment data | |
759 | // Fire on_rez | 820 | group.RootPart.AttachPoint = group.RootPart.Shape.State; |
760 | group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); | 821 | group.RootPart.AttachOffset = storedPosition; |
761 | rootPart.ParentGroup.ResumeScripts(); | ||
762 | 822 | ||
763 | rootPart.ScheduleFullUpdate(); | 823 | group.ClearPartAttachmentData(); |
824 | } | ||
825 | |||
826 | // Fire on_rez | ||
827 | group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); | ||
828 | rootPart.ParentGroup.ResumeScripts(); | ||
829 | |||
830 | rootPart.ScheduleFullUpdate(); | ||
831 | } | ||
764 | } | 832 | } |
765 | 833 | ||
766 | if (!m_Scene.Permissions.BypassPermissions()) | 834 | if (!m_Scene.Permissions.BypassPermissions()) |
@@ -778,9 +846,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
778 | } | 846 | } |
779 | } | 847 | } |
780 | } | 848 | } |
781 | |||
782 | return rootPart.ParentGroup; | ||
783 | } | 849 | } |
850 | return group; | ||
784 | } | 851 | } |
785 | 852 | ||
786 | return null; | 853 | return null; |