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
ba9daf849e
(cherry picked from commit 4ff9fbca441110cc2b93edc7286e0e9339e61cbe)
varregion
Aleric Inglewood 2013-08-04 19:19:11 +02:00 committed by teravus
parent a37c59b43e
commit 2dc92e7de1
14 changed files with 150 additions and 10 deletions

View File

@ -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

View File

@ -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

View File

@ -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());
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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; ;

View File

@ -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;

View File

@ -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;

View File

@ -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
}
}
}

View File

@ -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.

View File

@ -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);

View File

@ -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<ProfileShape>(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);