From 2dc92e7de11086c7649d3ee0f8adc974efce6805 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Sun, 4 Aug 2013 19:19:11 +0200 Subject: [PATCH] Preserve attachment point & position when attachment is rezzed in world Patch taken from http://opensimulator.org/mantis/view.php?id=4905 originally by Greg C. Fixed to apply to r/23314 commit ba9daf849e7c8db48e7c03e7cdedb77776b2052f (cherry picked from commit 4ff9fbca441110cc2b93edc7286e0e9339e61cbe) --- OpenSim/Data/MSSQL/MSSQLSimulationData.cs | 17 ++++++++--- .../MSSQL/Resources/RegionStore.migrations | 12 ++++++++ OpenSim/Data/MySQL/MySQLSimulationData.cs | 29 +++++++++++++++---- .../MySQL/Resources/RegionStore.migrations | 10 +++++++ .../SQLite/Resources/RegionStore.migrations | 12 ++++++++ OpenSim/Data/SQLite/SQLiteSimulationData.cs | 16 ++++++++++ OpenSim/Framework/PrimitiveBaseShape.cs | 11 +++++++ .../Linden/Caps/ObjectCaps/ObjectAdd.cs | 4 +++ .../ObjectCaps/UploadObjectAssetModule.cs | 1 + .../ClientStack/Linden/UDP/LLClientView.cs | 1 + .../Avatar/Attachments/AttachmentsModule.cs | 18 +++++++++++- .../InventoryAccess/InventoryAccessModule.cs | 8 +++++ .../Framework/Scenes/Scene.Inventory.cs | 7 +++++ .../Serialization/SceneObjectSerializer.cs | 14 +++++++++ 14 files changed, 150 insertions(+), 10 deletions(-) diff --git a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs index 51350506e8..f41f60ccff 100644 --- a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs +++ b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs @@ -351,7 +351,7 @@ IF EXISTS (SELECT UUID FROM prims WHERE UUID = @UUID) ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice, SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem, ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches, - LinkNumber = @LinkNumber, MediaURL = @MediaURL, DynAttrs = @DynAttrs, + LinkNumber = @LinkNumber, MediaURL = @MediaURL, AttachedPosX = @AttachedPosX, AttachedPosY = @AttachedPosY, AttachedPosZ = @AttachedPosZ, DynAttrs = @DynAttrs, PhysicsShapeType = @PhysicsShapeType, Density = @Density, GravityModifier = @GravityModifier, Friction = @Friction, Restitution = @Restitution WHERE UUID = @UUID END @@ -367,7 +367,7 @@ ELSE PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX, OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ, ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA, - ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber, MediaURL, DynAttrs, + ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber, MediaURL, AttachedPosX, AttachedPosY, AttachedPosZ, DynAttrs, PhysicsShapeType, Density, GravityModifier, Friction, Restitution ) VALUES ( @UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask, @@ -378,7 +378,7 @@ ELSE @PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX, @OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ, @ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA, - @ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber, @MediaURL, @DynAttrs, + @ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber, @MediaURL, @AttachedPosX, @AttachedPosY, @AttachedPosZ, @DynAttrs, @PhysicsShapeType, @Density, @GravityModifier, @Friction, @Restitution ) END"; @@ -1695,6 +1695,12 @@ VALUES if (!(primRow["MediaURL"] is System.DBNull)) prim.MediaUrl = (string)primRow["MediaURL"]; + if (!(primRow["AttachedPosX"] is System.DBNull)) + prim.AttachedPos = new Vector3( + Convert.ToSingle(primRow["AttachedPosX"]), + Convert.ToSingle(primRow["AttachedPosY"]), + Convert.ToSingle(primRow["AttachedPosZ"])); + if (!(primRow["DynAttrs"] is System.DBNull)) prim.DynAttrs = DAMap.FromXml((string)primRow["DynAttrs"]); else @@ -2099,7 +2105,10 @@ VALUES parameters.Add(_Database.CreateParameter("PassTouches", 0)); parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum)); parameters.Add(_Database.CreateParameter("MediaURL", prim.MediaUrl)); - + parameters.Add(_Database.CreateParameter("AttachedPosX", prim.AttachedPos.X)); + parameters.Add(_Database.CreateParameter("AttachedPosY", prim.AttachedPos.Y)); + parameters.Add(_Database.CreateParameter("AttachedPosZ", prim.AttachedPos.Z)); + if (prim.DynAttrs.CountNamespaces > 0) parameters.Add(_Database.CreateParameter("DynAttrs", prim.DynAttrs.ToXml())); else diff --git a/OpenSim/Data/MSSQL/Resources/RegionStore.migrations b/OpenSim/Data/MSSQL/Resources/RegionStore.migrations index 4549801218..bb898845b4 100644 --- a/OpenSim/Data/MSSQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/MSSQL/Resources/RegionStore.migrations @@ -1168,3 +1168,15 @@ ALTER TABLE prims ADD `Friction` double NOT NULL default '0.6'; ALTER TABLE prims ADD `Restitution` double NOT NULL default '0.5'; COMMIT + +:VERSION 40 #---------------- Save Attachment info + +BEGIN TRANSACTION + +ALTER TABLE prims ADD AttachedPosX float(53) default 0.0; +ALTER TABLE prims ADD AttachedPosY float(53) default 0.0; +ALTER TABLE prims ADD AttachedPosZ float(53) default 0.0; +ALTER TABLE primshapes ADD LastAttachPoint int not null default 0; + +COMMIT + diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index cf367efc67..b03a9042ba 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -173,7 +173,8 @@ namespace OpenSim.Data.MySQL "ParticleSystem, ClickAction, Material, " + "CollisionSound, CollisionSoundVolume, " + "PassTouches, " + - "LinkNumber, MediaURL, KeyframeMotion, " + + "LinkNumber, MediaURL, AttachedPosX, " + + "AttachedPosY, AttachedPosZ, KeyframeMotion, " + "PhysicsShapeType, Density, GravityModifier, " + "Friction, Restitution, DynAttrs " + ") values (" + "?UUID, " + @@ -208,7 +209,8 @@ namespace OpenSim.Data.MySQL "?ColorB, ?ColorA, ?ParticleSystem, " + "?ClickAction, ?Material, ?CollisionSound, " + "?CollisionSoundVolume, ?PassTouches, " + - "?LinkNumber, ?MediaURL, ?KeyframeMotion, " + + "?LinkNumber, ?MediaURL, ?AttachedPosX, " + + "?AttachedPosY, ?AttachedPosZ, ?KeyframeMotion, " + "?PhysicsShapeType, ?Density, ?GravityModifier, " + "?Friction, ?Restitution, ?DynAttrs)"; @@ -227,7 +229,7 @@ namespace OpenSim.Data.MySQL "PathTaperX, PathTaperY, PathTwist, " + "PathTwistBegin, ProfileBegin, ProfileEnd, " + "ProfileCurve, ProfileHollow, Texture, " + - "ExtraParams, State, Media) " + + "ExtraParams, State, LastAttachPoint, Media) " + "values (?UUID, " + "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " + "?PCode, ?PathBegin, ?PathEnd, " + @@ -239,7 +241,7 @@ namespace OpenSim.Data.MySQL "?PathTwistBegin, ?ProfileBegin, " + "?ProfileEnd, ?ProfileCurve, " + "?ProfileHollow, ?Texture, ?ExtraParams, " + - "?State, ?Media)"; + "?State, ?LastAttachPoint, ?Media)"; FillShapeCommand(cmd, prim); @@ -1303,7 +1305,16 @@ namespace OpenSim.Data.MySQL if (!(row["MediaURL"] is System.DBNull)) prim.MediaUrl = (string)row["MediaURL"]; - + + if (!(row["AttachedPosX"] is System.DBNull)) + { + prim.AttachedPos = new Vector3( + (float)(double)row["AttachedPosX"], + (float)(double)row["AttachedPosY"], + (float)(double)row["AttachedPosZ"] + ); + } + if (!(row["DynAttrs"] is System.DBNull)) prim.DynAttrs = DAMap.FromXml((string)row["DynAttrs"]); else @@ -1673,6 +1684,12 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum); cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl); + if (prim.AttachedPos != null) + { + cmd.Parameters.AddWithValue("AttachedPosX", (double)prim.AttachedPos.X); + cmd.Parameters.AddWithValue("AttachedPosY", (double)prim.AttachedPos.Y); + cmd.Parameters.AddWithValue("AttachedPosZ", (double)prim.AttachedPos.Z); + } if (prim.KeyframeMotion != null) cmd.Parameters.AddWithValue("KeyframeMotion", prim.KeyframeMotion.Serialize()); @@ -1879,6 +1896,7 @@ namespace OpenSim.Data.MySQL s.ExtraParams = (byte[])row["ExtraParams"]; s.State = (byte)(int)row["State"]; + s.LastAttachPoint = (byte)(int)row["LastAttachPoint"]; if (!(row["Media"] is System.DBNull)) s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]); @@ -1925,6 +1943,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("Texture", s.TextureEntry); cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams); cmd.Parameters.AddWithValue("State", s.State); + cmd.Parameters.AddWithValue("LastAttachPoint", s.LastAttachPoint); cmd.Parameters.AddWithValue("Media", null == s.Media ? null : s.Media.ToXml()); } diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations index 70b9558222..a77e44daeb 100644 --- a/OpenSim/Data/MySQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations @@ -930,3 +930,13 @@ BEGIN; ALTER TABLE prims ADD COLUMN `KeyframeMotion` blob; COMMIT; + +:VERSION 49 #--------------------- Save attachment info + +BEGIN; +ALTER TABLE prims ADD COLUMN AttachedPosX double default 0; +ALTER TABLE prims ADD COLUMN AttachedPosY double default 0; +ALTER TABLE prims ADD COLUMN AttachedPosZ double default 0; +ALTER TABLE primshapes ADD COLUMN LastAttachPoint int(4) not null default '0'; +COMMIT; + diff --git a/OpenSim/Data/SQLite/Resources/RegionStore.migrations b/OpenSim/Data/SQLite/Resources/RegionStore.migrations index bff039d75d..901068ff65 100644 --- a/OpenSim/Data/SQLite/Resources/RegionStore.migrations +++ b/OpenSim/Data/SQLite/Resources/RegionStore.migrations @@ -600,3 +600,15 @@ BEGIN; ALTER TABLE prims ADD COLUMN `KeyframeMotion` blob; COMMIT; + +:VERSION 30 #---------------- Save Attachment info + +BEGIN; + +ALTER TABLE prims ADD COLUMN AttachedPosX double default '0'; +ALTER TABLE prims ADD COLUMN AttachedPosY double default '0'; +ALTER TABLE prims ADD COLUMN AttachedPosZ double default '0'; +ALTER TABLE primshapes ADD COLUMN LastAttachPoint int not null default '0'; + +COMMIT; + diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index eba6612dc5..d938b6b03a 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs @@ -1236,6 +1236,10 @@ namespace OpenSim.Data.SQLite createCol(prims, "MediaURL", typeof(String)); + createCol(prims, "AttachedPosX", typeof(Double)); + createCol(prims, "AttachedPosY", typeof(Double)); + createCol(prims, "AttachedPosZ", typeof(Double)); + createCol(prims, "DynAttrs", typeof(String)); createCol(prims, "PhysicsShapeType", typeof(Byte)); @@ -1724,6 +1728,12 @@ namespace OpenSim.Data.SQLite prim.MediaUrl = (string)row["MediaURL"]; } + prim.AttachedPos = new Vector3( + Convert.ToSingle(row["AttachedPosX"]), + Convert.ToSingle(row["AttachedPosY"]), + Convert.ToSingle(row["AttachedPosZ"]) + ); + if (!(row["DynAttrs"] is System.DBNull)) { //m_log.DebugFormat("[SQLITE]: DynAttrs type [{0}]", row["DynAttrs"].GetType()); @@ -2176,6 +2186,10 @@ namespace OpenSim.Data.SQLite row["MediaURL"] = prim.MediaUrl; + row["AttachedPosX"] = prim.AttachedPos.X; + row["AttachedPosY"] = prim.AttachedPos.Y; + row["AttachedPosZ"] = prim.AttachedPos.Z; + if (prim.DynAttrs.CountNamespaces > 0) row["DynAttrs"] = prim.DynAttrs.ToXml(); else @@ -2444,6 +2458,7 @@ namespace OpenSim.Data.SQLite s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]); s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]); s.State = Convert.ToByte(row["State"]); + s.LastAttachPoint = Convert.ToByte(row["LastAttachPoint"]); byte[] textureEntry = (byte[])row["Texture"]; s.TextureEntry = textureEntry; @@ -2493,6 +2508,7 @@ namespace OpenSim.Data.SQLite row["ProfileCurve"] = s.ProfileCurve; row["ProfileHollow"] = s.ProfileHollow; row["State"] = s.State; + row["LastAttachPoint"] = s.LastAttachPoint; row["Texture"] = s.TextureEntry; row["ExtraParams"] = s.ExtraParams; diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs index c1e1a4f363..c8a53763af 100644 --- a/OpenSim/Framework/PrimitiveBaseShape.cs +++ b/OpenSim/Framework/PrimitiveBaseShape.cs @@ -105,6 +105,7 @@ namespace OpenSim.Framework private ushort _profileHollow; private Vector3 _scale; private byte _state; + private byte _lastattach; private ProfileShape _profileShape; private HollowShape _hollowShape; @@ -207,6 +208,7 @@ namespace OpenSim.Framework PCode = (byte)prim.PrimData.PCode; State = prim.PrimData.State; + LastAttachPoint = prim.PrimData.State; PathBegin = Primitive.PackBeginCut(prim.PrimData.PathBegin); PathEnd = Primitive.PackEndCut(prim.PrimData.PathEnd); PathScaleX = Primitive.PackPathScale(prim.PrimData.PathScaleX); @@ -583,6 +585,15 @@ namespace OpenSim.Framework } } + public byte LastAttachPoint { + get { + return _lastattach; + } + set { + _lastattach = value; + } + } + public ProfileShape ProfileShape { get { return _profileShape; diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs index 92805e26ea..94f8bc1fe8 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs @@ -155,6 +155,7 @@ namespace OpenSim.Region.ClientStack.Linden Quaternion rotation = Quaternion.Identity; Vector3 scale = Vector3.Zero; int state = 0; + int lastattach = 0; if (r.Type != OSDType.Map) // not a proper req return responsedata; @@ -224,6 +225,7 @@ namespace OpenSim.Region.ClientStack.Linden ray_target_id = ObjMap["RayTargetId"].AsUUID(); state = ObjMap["State"].AsInteger(); + lastattach = ObjMap["LastAttachPoint"].AsInteger(); try { ray_end = ((OSDArray)ObjMap["RayEnd"]).AsVector3(); @@ -290,6 +292,7 @@ namespace OpenSim.Region.ClientStack.Linden //session_id = rm["session_id"].AsUUID(); state = rm["state"].AsInteger(); + lastattach = rm["last_attach_point"].AsInteger(); try { ray_end = ((OSDArray)rm["ray_end"]).AsVector3(); @@ -331,6 +334,7 @@ namespace OpenSim.Region.ClientStack.Linden pbs.ProfileEnd = (ushort)profile_end; pbs.Scale = scale; pbs.State = (byte)state; + pbs.LastAttachPoint = (byte)lastattach; SceneObjectGroup obj = null; ; diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs index 55a503e68c..769fe285ed 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs @@ -277,6 +277,7 @@ namespace OpenSim.Region.ClientStack.Linden pbs.ProfileEnd = (ushort) obj.ProfileEnd; pbs.Scale = obj.Scale; pbs.State = (byte) 0; + pbs.LastAttachPoint = (byte) 0; SceneObjectPart prim = new SceneObjectPart(); prim.UUID = UUID.Random(); prim.CreatorID = AgentId; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 1b091bfda2..3609ec17ec 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -12188,6 +12188,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP shape.PCode = addPacket.ObjectData.PCode; shape.State = addPacket.ObjectData.State; + shape.LastAttachPoint = addPacket.ObjectData.State; shape.PathBegin = addPacket.ObjectData.PathBegin; shape.PathEnd = addPacket.ObjectData.PathEnd; shape.PathScaleX = addPacket.ObjectData.PathScaleX; diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 28187129e5..d0e0b3507d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -422,6 +422,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments attachPos = Vector3.Zero; } + // if the attachment point is the same as previous, make sure we get the saved + // position info. + if (attachmentPt != 0 && attachmentPt == group.RootPart.Shape.LastAttachPoint) + { + attachPos = group.RootPart.AttachedPos; + } + // AttachmentPt 0 means the client chose to 'wear' the attachment. if (attachmentPt == (uint)AttachmentPoint.Default) { @@ -429,6 +436,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments attachmentPt = group.AttachmentPoint; } + // if we didn't find an attach point, look for where it was last attached + if (attachmentPt == 0) + { + attachmentPt = (uint)group.RootPart.Shape.LastAttachPoint; + attachPos = group.RootPart.AttachedPos; + group.HasGroupChanged = true; + } + // if we still didn't find a suitable attachment point....... if (attachmentPt == 0) { @@ -619,6 +634,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments so.ClearPartAttachmentData(); rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive); so.HasGroupChanged = true; + so.RootPart.Shape.LastAttachPoint = (byte)so.AttachmentPoint; rootPart.Rezzed = DateTime.Now; rootPart.RemFlag(PrimFlags.TemporaryOnRez); so.AttachToBackup(); @@ -1210,4 +1226,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments #endregion } -} \ No newline at end of file +} diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 68e4e26f60..0ec957520b 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -836,6 +836,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3"); } + // if this was previously an attachment and is now being rezzed, + // save the old attachment info. + if (group.IsAttachment == false && group.RootPart.Shape.State != 0) + { + group.RootPart.AttachedPos = group.AbsolutePosition; + group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint; + } + foreach (SceneObjectPart part in group.Parts) { // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset. diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 69b5f43ba0..4bebbe8c05 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2230,6 +2230,13 @@ namespace OpenSim.Region.Framework.Scenes sourcePart.Inventory.RemoveInventoryItem(item.ItemID); } + + if (group.IsAttachment == false && group.RootPart.Shape.State != 0) + { + group.RootPart.AttachedPos = group.AbsolutePosition; + group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint; + } + group.FromPartID = sourcePart.UUID; AddNewSceneObject(group, true, pos, rot, vel); diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 945745eff5..3ea936cc00 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -365,6 +365,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization m_SOPXmlProcessors.Add("CollisionSound", ProcessCollisionSound); m_SOPXmlProcessors.Add("CollisionSoundVolume", ProcessCollisionSoundVolume); m_SOPXmlProcessors.Add("MediaUrl", ProcessMediaUrl); + m_SOPXmlProcessors.Add("AttachedPos", ProcessAttachedPos); m_SOPXmlProcessors.Add("DynAttrs", ProcessDynAttrs); m_SOPXmlProcessors.Add("TextureAnimation", ProcessTextureAnimation); m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem); @@ -433,6 +434,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization m_ShapeXmlProcessors.Add("ProfileEnd", ProcessShpProfileEnd); m_ShapeXmlProcessors.Add("ProfileHollow", ProcessShpProfileHollow); m_ShapeXmlProcessors.Add("Scale", ProcessShpScale); + m_ShapeXmlProcessors.Add("LastAttachPoint", ProcessShpLastAttach); m_ShapeXmlProcessors.Add("State", ProcessShpState); m_ShapeXmlProcessors.Add("ProfileShape", ProcessShpProfileShape); m_ShapeXmlProcessors.Add("HollowShape", ProcessShpHollowShape); @@ -761,6 +763,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization obj.MediaUrl = reader.ReadElementContentAsString("MediaUrl", String.Empty); } + private static void ProcessAttachedPos(SceneObjectPart obj, XmlTextReader reader) + { + obj.AttachedPos = Util.ReadVector(reader, "AttachedPos"); + } + private static void ProcessDynAttrs(SceneObjectPart obj, XmlTextReader reader) { obj.DynAttrs.ReadXml(reader); @@ -1043,6 +1050,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization shp.State = (byte)reader.ReadElementContentAsInt("State", String.Empty); } + private static void ProcessShpLastAttach(PrimitiveBaseShape shp, XmlTextReader reader) + { + shp.LastAttachPoint = (byte)reader.ReadElementContentAsInt("LastAttachPoint", String.Empty); + } + private static void ProcessShpProfileShape(PrimitiveBaseShape shp, XmlTextReader reader) { shp.ProfileShape = Util.ReadEnum(reader, "ProfileShape"); @@ -1289,6 +1301,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString()); if (sop.MediaUrl != null) writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString()); + WriteVector(writer, "AttachedPos", sop.AttachedPos); if (sop.DynAttrs.CountNamespaces > 0) { @@ -1471,6 +1484,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("ProfileEnd", shp.ProfileEnd.ToString()); writer.WriteElementString("ProfileHollow", shp.ProfileHollow.ToString()); writer.WriteElementString("State", shp.State.ToString()); + writer.WriteElementString("LastAttachPoint", shp.LastAttachPoint.ToString()); WriteFlags(writer, "ProfileShape", shp.ProfileShape.ToString(), options); WriteFlags(writer, "HollowShape", shp.HollowShape.ToString(), options);