diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 5e156f1772..1bd4749713 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -130,6 +130,8 @@ namespace OpenSim.Framework
public delegate void UpdateVector(uint localID, Vector3 pos, IClientAPI remoteClient);
+ public delegate void ClientChangeObject(uint localID, object data ,IClientAPI remoteClient);
+
public delegate void UpdatePrimRotation(uint localID, Quaternion rot, IClientAPI remoteClient);
public delegate void UpdatePrimSingleRotation(uint localID, Quaternion rot, IClientAPI remoteClient);
@@ -838,6 +840,7 @@ namespace OpenSim.Framework
event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
event UpdatePrimFlags OnUpdatePrimFlags;
event UpdatePrimTexture OnUpdatePrimTexture;
+ event ClientChangeObject onClientChangeObject;
event UpdateVector OnUpdatePrimGroupPosition;
event UpdateVector OnUpdatePrimSinglePosition;
event UpdatePrimRotation OnUpdatePrimGroupRotation;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 051c4fa8e3..7d51323456 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -125,6 +125,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
public event UpdatePrimFlags OnUpdatePrimFlags;
public event UpdatePrimTexture OnUpdatePrimTexture;
+ public event ClientChangeObject onClientChangeObject;
public event UpdateVector OnUpdatePrimGroupPosition;
public event UpdateVector OnUpdatePrimSinglePosition;
public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -11517,22 +11518,151 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// parts[j].IgnoreUndoUpdate = true;
// }
- UpdatePrimGroupRotation handlerUpdatePrimGroupRotation;
- UpdateVector handlerUpdatePrimGroupScale;
+// UpdatePrimGroupRotation handlerUpdatePrimGroupRotation;
+// UpdateVector handlerUpdatePrimGroupScale;
- Quaternion arot;
- Vector3 ascale;
- Vector3 apos;
-/*ubit from ll JIRA:
- * 0x01 position
- * 0x02 rotation
- * 0x04 scale
+ ClientChangeObject updatehandler = onClientChangeObject;
+
+ if (updatehandler != null)
+ {
+ ObjectChangeData udata = new ObjectChangeData();
+
+ /*ubit from ll JIRA:
+ * 0x01 position
+ * 0x02 rotation
+ * 0x04 scale
- * 0x08 LINK_SET
- * 0x10 UNIFORM for scale
- */
+ * 0x08 LINK_SET
+ * 0x10 UNIFORM for scale
+ */
+ // translate to internal changes
+ // not all cases .. just the ones older code did
+ switch (block.Type)
+ {
+ case 1: //change position sp
+ udata.position = new Vector3(block.Data, 0);
+
+ udata.what = ObjectChangeWhat.primP;
+ updatehandler(localId, udata, this);
+ break;
+
+ case 2: // rotation sp
+ udata.rotation = new Quaternion(block.Data, 0, true);
+
+ udata.what = ObjectChangeWhat.primR;
+ updatehandler(localId, udata, this);
+ break;
+
+ case 3: // position plus rotation
+ udata.position = new Vector3(block.Data, 0);
+ udata.rotation = new Quaternion(block.Data, 12, true);
+
+ udata.what = ObjectChangeWhat.primPR;
+ updatehandler(localId, udata, this);
+
+ break;
+
+ case 4: // scale sp
+ udata.scale = new Vector3(block.Data, 0);
+ udata.what = ObjectChangeWhat.primS;
+
+ updatehandler(localId, udata, this);
+ break;
+
+ case 0x14: // uniform scale sp
+ udata.scale = new Vector3(block.Data, 0);
+
+ udata.what = ObjectChangeWhat.primUS;
+ updatehandler(localId, udata, this);
+ break;
+
+ case 5: // scale and position sp
+ udata.position = new Vector3(block.Data, 0);
+ udata.scale = new Vector3(block.Data, 12);
+
+ udata.what = ObjectChangeWhat.primPS;
+ updatehandler(localId, udata, this);
+ break;
+
+ case 0x15: //uniform scale and position
+ udata.position = new Vector3(block.Data, 0);
+ udata.scale = new Vector3(block.Data, 12);
+
+ udata.what = ObjectChangeWhat.primPUS;
+ updatehandler(localId, udata, this);
+ break;
+
+ // now group related (bit 4)
+ case 9: //( 8 + 1 )group position
+ udata.position = new Vector3(block.Data, 0);
+
+ udata.what = ObjectChangeWhat.groupP;
+ updatehandler(localId, udata, this);
+ break;
+
+ case 0x0A: // (8 + 2) group rotation
+ udata.rotation = new Quaternion(block.Data, 0, true);
+
+ udata.what = ObjectChangeWhat.groupR;
+ updatehandler(localId, udata, this);
+ break;
+
+ case 0x0B: //( 8 + 2 + 1) group rotation and position
+ udata.position = new Vector3(block.Data, 0);
+ udata.rotation = new Quaternion(block.Data, 12, true);
+
+ udata.what = ObjectChangeWhat.groupPR;
+ updatehandler(localId, udata, this);
+ break;
+
+ case 0x0C: // (8 + 4) group scale
+ // only afects root prim and only sent by viewer editor object tab scaling
+ // mouse edition only allows uniform scaling
+ // SL MAY CHANGE THIS in viewers
+
+ udata.scale = new Vector3(block.Data, 0);
+
+ // udata.what = ObjectChangeWhat.groupS;
+ udata.what = ObjectChangeWhat.primS; // to conform to current SL
+ updatehandler(localId, udata, this);
+
+ break;
+
+ case 0x0D: //(8 + 4 + 1) group scale and position
+ // exception as above
+
+ udata.position = new Vector3(block.Data, 0);
+ udata.scale = new Vector3(block.Data, 12);
+
+ // udata.what = ObjectChangeWhat.groupPS;
+ udata.what = ObjectChangeWhat.primPS; // to conform to current SL
+ updatehandler(localId, udata, this);
+ break;
+
+ case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
+ udata.scale = new Vector3(block.Data, 0);
+
+ udata.what = ObjectChangeWhat.groupUS;
+ updatehandler(localId, udata, this);
+ break;
+
+ case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
+ udata.position = new Vector3(block.Data, 0);
+ udata.scale = new Vector3(block.Data, 12);
+
+ udata.what = ObjectChangeWhat.groupPUS;
+ updatehandler(localId, udata, this);
+ break;
+
+ default:
+ m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
+ break;
+ }
+ }
+
+/*
switch (block.Type)
{
case 1: //change position sp
@@ -11788,7 +11918,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
break;
}
-
+*/
// for (int j = 0; j < parts.Length; j++)
// parts[j].IgnoreUndoUpdate = false;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 68c05f85d6..a3358a597d 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2811,6 +2811,8 @@ namespace OpenSim.Region.Framework.Scenes
client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition;
client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition;
+ client.onClientChangeObject += m_sceneGraph.ClientChangeObject;
+
client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimGroupRotation;
client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation;
client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation;
@@ -2940,6 +2942,8 @@ namespace OpenSim.Region.Framework.Scenes
client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimGroupPosition;
client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition;
+ client.onClientChangeObject -= m_sceneGraph.ClientChangeObject;
+
client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimGroupRotation;
client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimGroupRotation;
client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation;
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 3cd4a10e6c..5e770ba1fd 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -47,6 +47,57 @@ namespace OpenSim.Region.Framework.Scenes
public delegate void ChangedBackupDelegate(SceneObjectGroup sog);
+
+ public enum ObjectChangeWhat : uint
+ {
+ // bits definitions
+ Position = 0x01,
+ Rotation = 0x02,
+ Scale = 0x04,
+ Group = 0x08,
+ UniformScale = 0x10,
+
+ // macros from above
+ // single prim
+ primP = 0x01,
+ primR = 0x02,
+ primPR = 0x03,
+ primS = 0x04,
+ primPS = 0x05,
+ primRS = 0x06,
+ primPSR = 0x07,
+
+ primUS = 0x14,
+ primPUS = 0x15,
+ primRUS = 0x16,
+ primPUSR = 0x17,
+
+ // group
+ groupP = 0x09,
+ groupR = 0x0A,
+ groupPR = 0x0B,
+ groupS = 0x0C,
+ groupPS = 0x0D,
+ groupRS = 0x0E,
+ groupPSR = 0x0F,
+
+ groupUS = 0x1C,
+ groupPUS = 0x1D,
+ groupRUS = 0x1E,
+ groupPUSR = 0x1F,
+
+ PRSmask = 0x07
+ }
+
+ public struct ObjectChangeData
+ {
+ public Quaternion rotation;
+ public Vector3 position;
+ public Vector3 scale;
+ public ObjectChangeWhat what;
+ }
+
+
///
/// This class used to be called InnerScene and may not yet truly be a SceneGraph. The non scene graph components
/// should be migrated out over time.
@@ -1289,6 +1340,87 @@ namespace OpenSim.Region.Framework.Scenes
#region Client Event handlers
+ protected internal void ClientChangeObject(uint localID, object odata, IClientAPI remoteClient)
+ {
+ SceneObjectPart part = GetSceneObjectPart(localID);
+ ObjectChangeData data = (ObjectChangeData)odata;
+
+ if (part != null)
+ {
+ SceneObjectGroup grp = part.ParentGroup;
+ if (grp != null)
+ {
+ if (m_parentScene.Permissions.CanEditObject(grp.UUID, remoteClient.AgentId))
+ {
+// part.StoreUndoState(data.what | ObjectChangeWhat.PRSmask); // for now save all to keep previus behavour ???
+ part.StoreUndoState(data.what); // lets test only saving what we changed
+ grp.doChangeObject(part, (ObjectChangeData)data);
+ }
+ }
+ }
+ }
+
+/* moved to SOG
+ protected internal void doChangeObject(SceneObjectPart part, ObjectChangeData data)
+ {
+ if (part != null && part.ParentGroup != null)
+ {
+ ObjectChangeWhat what = data.what;
+ bool togroup = ((what & ObjectChangeWhat.Group) != 0);
+// bool uniform = ((what & ObjectChangeWhat.UniformScale) != 0); not in use
+
+ SceneObjectGroup group = part.ParentGroup;
+ PhysicsActor pha = group.RootPart.PhysActor;
+
+ if (togroup)
+ {
+ // related to group
+ if ((what & ObjectChangeWhat.Position) != 0)
+ group.AbsolutePosition = data.position;
+ if ((what & ObjectChangeWhat.Rotation) != 0)
+ group.RootPart.UpdateRotation(data.rotation);
+ if ((what & ObjectChangeWhat.Scale) != 0)
+ {
+ if (pha != null)
+ pha.Building = true;
+ group.GroupResize(data.scale);
+ if (pha != null)
+ pha.Building = false;
+ }
+ }
+ else
+ {
+ // related to single prim in a link-set ( ie group)
+ if (pha != null)
+ pha.Building = true;
+
+ // must deal with root part specially for position and rotation
+ // so parts offset positions or rotations are fixed
+
+ if (part == group.RootPart)
+ {
+ if ((what & ObjectChangeWhat.Position) != 0)
+ group.UpdateRootPosition(data.position);
+ if ((what & ObjectChangeWhat.Rotation) != 0)
+ group.UpdateRootRotation(data.rotation);
+ }
+ else
+ {
+ if ((what & ObjectChangeWhat.Position) != 0)
+ part.OffsetPosition = data.position;
+ if ((what & ObjectChangeWhat.Rotation) != 0)
+ part.UpdateRotation(data.rotation);
+ }
+
+ if ((what & ObjectChangeWhat.Scale) != 0)
+ part.Resize(data.scale);
+
+ if (pha != null)
+ pha.Building = false;
+ }
+ }
+ }
+*/
///
/// Update the scale of an individual prim.
///
@@ -1303,7 +1435,17 @@ namespace OpenSim.Region.Framework.Scenes
{
if (m_parentScene.Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId))
{
+ bool physbuild = false;
+ if (part.ParentGroup.RootPart.PhysActor != null)
+ {
+ part.ParentGroup.RootPart.PhysActor.Building = true;
+ physbuild = true;
+ }
+
part.Resize(scale);
+
+ if (physbuild)
+ part.ParentGroup.RootPart.PhysActor.Building = false;
}
}
}
@@ -1315,7 +1457,17 @@ namespace OpenSim.Region.Framework.Scenes
{
if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
{
+ bool physbuild = false;
+ if (group.RootPart.PhysActor != null)
+ {
+ group.RootPart.PhysActor.Building = true;
+ physbuild = true;
+ }
+
group.GroupResize(scale);
+
+ if (physbuild)
+ group.RootPart.PhysActor.Building = false;
}
}
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 58187983d2..92f2d54f52 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -3124,10 +3124,6 @@ namespace OpenSim.Region.Framework.Scenes
///
public void GroupResize(Vector3 scale)
{
-// m_log.DebugFormat(
-// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale);
-// RootPart.StoreUndoState(true);
-
scale.X = Math.Min(scale.X, Scene.m_maxNonphys);
scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys);
scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys);
@@ -3152,7 +3148,6 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart obPart = parts[i];
if (obPart.UUID != m_rootPart.UUID)
{
-// obPart.IgnoreUndoUpdate = true;
Vector3 oldSize = new Vector3(obPart.Scale);
float f = 1.0f;
@@ -3216,8 +3211,6 @@ namespace OpenSim.Region.Framework.Scenes
z *= a;
}
}
-
-// obPart.IgnoreUndoUpdate = false;
}
}
}
@@ -3226,9 +3219,8 @@ namespace OpenSim.Region.Framework.Scenes
prevScale.X *= x;
prevScale.Y *= y;
prevScale.Z *= z;
-// RootPart.IgnoreUndoUpdate = true;
+
RootPart.Resize(prevScale);
-// RootPart.IgnoreUndoUpdate = false;
parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++)
@@ -3237,8 +3229,6 @@ namespace OpenSim.Region.Framework.Scenes
if (obPart.UUID != m_rootPart.UUID)
{
-// obPart.IgnoreUndoUpdate = true;
-
Vector3 currentpos = new Vector3(obPart.OffsetPosition);
currentpos.X *= x;
currentpos.Y *= y;
@@ -3251,18 +3241,12 @@ namespace OpenSim.Region.Framework.Scenes
obPart.Resize(newSize);
obPart.UpdateOffSet(currentpos);
-
-// obPart.IgnoreUndoUpdate = false;
}
-// obPart.IgnoreUndoUpdate = false;
HasGroupChanged = true;
m_rootPart.TriggerScriptChangedEvent(Changed.SCALE);
ScheduleGroupForTerseUpdate();
}
-
-// m_log.DebugFormat(
-// "[SCENE OBJECT GROUP]: Finished group resizing {0} {1} to {2}", Name, LocalId, RootPart.Scale);
}
#endregion
@@ -3275,14 +3259,6 @@ namespace OpenSim.Region.Framework.Scenes
///
public void UpdateGroupPosition(Vector3 pos)
{
-// m_log.DebugFormat("[SCENE OBJECT GROUP]: Updating group position on {0} {1} to {2}", Name, LocalId, pos);
-
-// RootPart.StoreUndoState(true);
-
-// SceneObjectPart[] parts = m_parts.GetArray();
-// for (int i = 0; i < parts.Length; i++)
-// parts[i].StoreUndoState();
-
if (m_scene.EventManager.TriggerGroupMove(UUID, pos))
{
if (IsAttachment)
@@ -3314,22 +3290,14 @@ namespace OpenSim.Region.Framework.Scenes
///
///
///
+ ///
+
public void UpdateSinglePosition(Vector3 pos, uint localID)
{
SceneObjectPart part = GetChildPart(localID);
-// SceneObjectPart[] parts = m_parts.GetArray();
-// for (int i = 0; i < parts.Length; i++)
-// parts[i].StoreUndoState();
-
if (part != null)
{
-// m_log.DebugFormat(
-// "[SCENE OBJECT GROUP]: Updating single position of {0} {1} to {2}", part.Name, part.LocalId, pos);
-
-// part.StoreUndoState(false);
-// part.IgnoreUndoUpdate = true;
-
// unlock parts position change
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = true;
@@ -3347,7 +3315,6 @@ namespace OpenSim.Region.Framework.Scenes
m_rootPart.PhysActor.Building = false;
HasGroupChanged = true;
-// part.IgnoreUndoUpdate = false;
}
}
@@ -3357,13 +3324,7 @@ namespace OpenSim.Region.Framework.Scenes
///
public void UpdateRootPosition(Vector3 pos)
{
-// m_log.DebugFormat(
-// "[SCENE OBJECT GROUP]: Updating root position of {0} {1} to {2}", Name, LocalId, pos);
-
-// SceneObjectPart[] parts = m_parts.GetArray();
-// for (int i = 0; i < parts.Length; i++)
-// parts[i].StoreUndoState();
-
+ // needs to be called with phys building true
Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
Vector3 oldPos =
new Vector3(AbsolutePosition.X + m_rootPart.OffsetPosition.X,
@@ -3383,17 +3344,7 @@ namespace OpenSim.Region.Framework.Scenes
obPart.OffsetPosition = obPart.OffsetPosition + diff;
}
- //We have to set undoing here because otherwise an undo state will be saved
-// if (!m_rootPart.Undoing)
-// {
-// m_rootPart.Undoing = true;
- AbsolutePosition = newPos;
-// m_rootPart.Undoing = false;
-// }
-// else
-// {
-// AbsolutePosition = newPos;
-// }
+ AbsolutePosition = newPos;
HasGroupChanged = true;
if (m_rootPart.Undoing)
@@ -3416,17 +3367,6 @@ namespace OpenSim.Region.Framework.Scenes
///
public void UpdateGroupRotationR(Quaternion rot)
{
-// m_log.DebugFormat(
-// "[SCENE OBJECT GROUP]: Updating group rotation R of {0} {1} to {2}", Name, LocalId, rot);
-
-// SceneObjectPart[] parts = m_parts.GetArray();
-// for (int i = 0; i < parts.Length; i++)
-// parts[i].StoreUndoState();
-
-// m_rootPart.StoreUndoState(true);
-
-// m_rootPart.UpdateRotation(rot);
-
PhysicsActor actor = m_rootPart.PhysActor;
if (actor != null)
{
@@ -3445,16 +3385,6 @@ namespace OpenSim.Region.Framework.Scenes
///
public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot)
{
-// m_log.DebugFormat(
-// "[SCENE OBJECT GROUP]: Updating group rotation PR of {0} {1} to {2}", Name, LocalId, rot);
-
-// SceneObjectPart[] parts = m_parts.GetArray();
-// for (int i = 0; i < parts.Length; i++)
-// parts[i].StoreUndoState();
-
-// RootPart.StoreUndoState(true);
-// RootPart.IgnoreUndoUpdate = true;
-
m_rootPart.UpdateRotation(rot);
PhysicsActor actor = m_rootPart.PhysActor;
@@ -3468,8 +3398,6 @@ namespace OpenSim.Region.Framework.Scenes
HasGroupChanged = true;
ScheduleGroupForTerseUpdate();
-
-// RootPart.IgnoreUndoUpdate = false;
}
///
@@ -3484,9 +3412,6 @@ namespace OpenSim.Region.Framework.Scenes
if (part != null)
{
-// m_log.DebugFormat(
-// "[SCENE OBJECT GROUP]: Updating single rotation of {0} {1} to {2}", part.Name, part.LocalId, rot);
-
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = true;
@@ -3514,30 +3439,13 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart part = GetChildPart(localID);
if (part != null)
{
-// m_log.DebugFormat(
-// "[SCENE OBJECT GROUP]: Updating single position and rotation of {0} {1} to {2}",
-// part.Name, part.LocalId, rot);
-
-// part.StoreUndoState();
-// part.IgnoreUndoUpdate = true;
-
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = true;
if (part.UUID == m_rootPart.UUID)
{
UpdateRootRotation(rot);
-/* if (!m_rootPart.Undoing)
- {
- m_rootPart.Undoing = true;
- AbsolutePosition = pos;
- m_rootPart.Undoing = false;
- }
- else
- {
- */
- AbsolutePosition = pos;
-// }
+ AbsolutePosition = pos;
}
else
{
@@ -3547,8 +3455,6 @@ namespace OpenSim.Region.Framework.Scenes
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = false;
-
-// part.IgnoreUndoUpdate = false;
}
}
@@ -3558,13 +3464,9 @@ namespace OpenSim.Region.Framework.Scenes
///
public void UpdateRootRotation(Quaternion rot)
{
-// m_log.DebugFormat(
-// "[SCENE OBJECT GROUP]: Updating root rotation of {0} {1} to {2}",
-// Name, LocalId, rot);
-
+ // needs to be called with phys building true
Quaternion axRot = rot;
Quaternion oldParentRot = m_rootPart.RotationOffset;
-// m_rootPart.StoreUndoState();
//Don't use UpdateRotation because it schedules an update prematurely
m_rootPart.RotationOffset = rot;
@@ -3580,8 +3482,6 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart prim = parts[i];
if (prim.UUID != m_rootPart.UUID)
{
-// prim.IgnoreUndoUpdate = true;
-
Quaternion NewRot = oldParentRot * prim.RotationOffset;
NewRot = Quaternion.Inverse(axRot) * NewRot;
prim.RotationOffset = NewRot;
@@ -3591,26 +3491,88 @@ namespace OpenSim.Region.Framework.Scenes
axPos *= oldParentRot;
axPos *= Quaternion.Inverse(axRot);
prim.OffsetPosition = axPos;
-
-// prim.IgnoreUndoUpdate = false;
}
}
-// for (int i = 0; i < parts.Length; i++)
-// {
-// SceneObjectPart childpart = parts[i];
-// if (childpart != m_rootPart)
-// {
-//// childpart.IgnoreUndoUpdate = false;
-//// childpart.StoreUndoState();
-// }
-// }
HasGroupChanged = true;
ScheduleGroupForFullUpdate();
+ }
-// m_log.DebugFormat(
-// "[SCENE OBJECT GROUP]: Updated root rotation of {0} {1} to {2}",
-// Name, LocalId, rot);
+ public void doChangeObject(SceneObjectPart part, ObjectChangeData data)
+ {
+ // TODO this still as excessive ScheduleGroupForTerseUpdate()s
+
+ if (part != null && part.ParentGroup != null)
+ {
+ ObjectChangeWhat what = data.what;
+ bool togroup = ((what & ObjectChangeWhat.Group) != 0);
+ // bool uniform = ((what & ObjectChangeWhat.UniformScale) != 0); not in use
+
+ SceneObjectGroup group = part.ParentGroup;
+ PhysicsActor pha = group.RootPart.PhysActor;
+
+ bool needgrpUpdate = false;
+
+ if (togroup)
+ {
+ // related to group
+ if ((what & ObjectChangeWhat.Position) != 0)
+ {
+ group.AbsolutePosition = data.position;
+ needgrpUpdate = true;
+ }
+ if ((what & ObjectChangeWhat.Rotation) != 0)
+ group.RootPart.UpdateRotation(data.rotation);
+ if ((what & ObjectChangeWhat.Scale) != 0)
+ {
+ if (pha != null)
+ pha.Building = true;
+ group.GroupResize(data.scale);
+ if (pha != null)
+ pha.Building = false;
+ }
+ }
+ else
+ {
+ // related to single prim in a link-set ( ie group)
+ if (pha != null)
+ pha.Building = true;
+
+ // must deal with root part specially for position and rotation
+ // so parts offset positions or rotations are fixed
+
+ if (part == group.RootPart)
+ {
+ if ((what & ObjectChangeWhat.Position) != 0)
+ group.UpdateRootPosition(data.position);
+ if ((what & ObjectChangeWhat.Rotation) != 0)
+ group.UpdateRootRotation(data.rotation);
+ }
+ else
+ {
+
+ if ((what & ObjectChangeWhat.Position) != 0)
+ {
+ part.OffsetPosition = data.position;
+ needgrpUpdate = true;
+ }
+ if ((what & ObjectChangeWhat.Rotation) != 0)
+ part.UpdateRotation(data.rotation);
+ }
+
+ if ((what & ObjectChangeWhat.Scale) != 0)
+ part.Resize(data.scale);
+
+ if (pha != null)
+ pha.Building = false;
+ }
+
+ if (needgrpUpdate)
+ {
+ HasGroupChanged = true;
+ ScheduleGroupForTerseUpdate();
+ }
+ }
}
#endregion
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 662249597a..c806fda5cc 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1944,6 +1944,7 @@ namespace OpenSim.Region.Framework.Scenes
PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
+
if (ParentID != 0 && ParentID != LocalId)
{
if (ParentGroup.RootPart.PhysActor != null)
@@ -3656,7 +3657,7 @@ namespace OpenSim.Region.Framework.Scenes
ParentGroup.ScheduleGroupForTerseUpdate();
//ParentGroup.ScheduleGroupForFullUpdate();
}
-
+/*
public void StoreUndoState()
{
StoreUndoState(false);
@@ -3697,6 +3698,44 @@ namespace OpenSim.Region.Framework.Scenes
}
}
}
+*/
+
+
+ public void StoreUndoState(ObjectChangeWhat what)
+ {
+ if (!Undoing && !IgnoreUndoUpdate) // just to read better - undo is in progress, or suspended
+ {
+ if (ParentGroup != null)
+ {
+ lock (m_undo)
+ {
+ if (m_undo.Count > 0)
+ {
+ // see if we had a change
+
+ UndoState last = m_undo.Peek();
+ if (last != null)
+ {
+ if (last.Compare(this, what))
+ {
+ return;
+ }
+ }
+ }
+
+ if (ParentGroup.GetSceneMaxUndo() > 0)
+ {
+ UndoState nUndo = new UndoState(this, what);
+
+ m_undo.Push(nUndo);
+
+ if (m_redo.Count > 0)
+ m_redo.Clear();
+ }
+ }
+ }
+ }
+ }
///
/// Return number of undos on the stack. Here temporarily pending a refactor.
@@ -3725,10 +3764,10 @@ namespace OpenSim.Region.Framework.Scenes
if (goback != null)
{
UndoState nUndo = null;
-
+
if (ParentGroup.GetSceneMaxUndo() > 0)
{
- nUndo = new UndoState(this, goback.ForGroup);
+ nUndo = new UndoState(this, goback.data.what);
}
goback.PlayState(this);
@@ -3760,7 +3799,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if (ParentGroup.GetSceneMaxUndo() > 0)
{
- UndoState nUndo = new UndoState(this, gofwd.ForGroup);
+ UndoState nUndo = new UndoState(this, gofwd.data.what);
m_undo.Push(nUndo);
}
diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs
index 38474def84..eb76ca5bba 100644
--- a/OpenSim/Region/Framework/Scenes/UndoState.cs
+++ b/OpenSim/Region/Framework/Scenes/UndoState.cs
@@ -48,6 +48,7 @@ namespace OpenSim.Region.Framework.Scenes
STATE_ALL = 63
}
+/*
public class UndoState
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -121,9 +122,16 @@ namespace OpenSim.Region.Framework.Scenes
public void PlayState(SceneObjectPart part)
{
part.Undoing = true;
-
+ bool physbuilding = false;
+
if (part.ParentID == 0)
{
+ if (!ForGroup && part.PhysActor != null)
+ {
+ part.PhysActor.Building = true;
+ physbuilding = true;
+ }
+
if (Position != Vector3.Zero)
{
if (ForGroup)
@@ -139,17 +147,34 @@ namespace OpenSim.Region.Framework.Scenes
if (Scale != Vector3.Zero)
{
+ if (!physbuilding && part.PhysActor != null)
+ {
+ part.PhysActor.Building = true;
+ physbuilding = true;
+ }
+
if (ForGroup)
part.ParentGroup.GroupResize(Scale);
else
part.Resize(Scale);
}
+
+ if (physbuilding)
+ part.PhysActor.Building = false;
+
part.ParentGroup.ScheduleGroupForTerseUpdate();
}
else
{
if (ForGroup) // trap for group since seems parts can't do it
return;
+
+ // changing a part invalidates entire object physical rep
+ if (part.ParentGroup != null && part.ParentGroup.RootPart != null && part.ParentGroup.RootPart.PhysActor != null)
+ {
+ part.ParentGroup.RootPart.PhysActor.Building = true;
+ physbuilding = true;
+ }
// Note: Updating these properties on sop automatically schedules an update if needed
part.OffsetPosition = Position;
@@ -158,11 +183,97 @@ namespace OpenSim.Region.Framework.Scenes
{
part.Resize(Scale);
}
+
+ if (physbuilding)
+ part.ParentGroup.RootPart.PhysActor.Building = false;
}
part.Undoing = false;
}
}
+*/
+ public class UndoState
+ {
+ public ObjectChangeData data;
+ ///
+ /// Constructor.
+ ///
+ ///
+ /// True if the undo is for an entire group
+ /// only for root parts ????
+ public UndoState(SceneObjectPart part, ObjectChangeWhat what)
+ {
+ data = new ObjectChangeData();
+
+ data.what = what;
+
+ if (part.ParentGroup.RootPart == part)
+ {
+ if ((what & ObjectChangeWhat.Position) != 0)
+ data.position = part.ParentGroup.AbsolutePosition;
+ if ((what & ObjectChangeWhat.Rotation) != 0)
+ data.rotation = part.RotationOffset;
+ if ((what & ObjectChangeWhat.Scale) != 0)
+ data.scale = part.Shape.Scale;
+ }
+ else
+ {
+ if ((what & ObjectChangeWhat.Position) != 0)
+ data.position = part.OffsetPosition;
+ if ((what & ObjectChangeWhat.Rotation) != 0)
+ data.rotation = part.RotationOffset;
+ if ((what & ObjectChangeWhat.Scale) != 0)
+ data.scale = part.Shape.Scale;
+ }
+ }
+
+ ///
+ /// Compare the relevant state in the given part to this state.
+ ///
+ ///
+ /// true if both the part's position, rotation and scale match those in this undo state. False otherwise.
+ public bool Compare(SceneObjectPart part, ObjectChangeWhat what)
+ {
+ if (data.what != what) // if diferent targets, then they are diferent
+ return false;
+
+ if (part != null)
+ {
+ if (part.ParentID == 0)
+ {
+ if ((what & ObjectChangeWhat.Position) != 0 && data.position != part.ParentGroup.AbsolutePosition)
+ return false;
+ }
+ else
+ {
+ if ((what & ObjectChangeWhat.Position) != 0 && data.position != part.OffsetPosition)
+ return false;
+ }
+
+ if ((what & ObjectChangeWhat.Rotation) != 0 && data.rotation != part.RotationOffset)
+ return false;
+ if ((what & ObjectChangeWhat.Rotation) != 0 && data.scale == part.Shape.Scale)
+ return false;
+ return true;
+
+ }
+ return false;
+ }
+
+ public void PlayState(SceneObjectPart part)
+ {
+ part.Undoing = true;
+
+ SceneObjectGroup grp = part.ParentGroup;
+
+ if (grp != null)
+ {
+ grp.doChangeObject(part, data);
+ }
+ part.Undoing = false;
+ }
+ }
+
public class LandUndoState
{
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 0f62b2a1a7..18f8f34002 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -714,6 +714,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
public event UpdatePrimFlags OnUpdatePrimFlags;
public event UpdatePrimTexture OnUpdatePrimTexture;
+ public event ClientChangeObject onClientChangeObject;
public event UpdateVector OnUpdatePrimGroupPosition;
public event UpdateVector OnUpdatePrimSinglePosition;
public event UpdatePrimRotation OnUpdatePrimGroupRotation;
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index d0b822c64b..96f33a5a91 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -240,6 +240,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
public event UpdatePrimTexture OnUpdatePrimTexture;
public event UpdateVector OnUpdatePrimGroupPosition;
public event UpdateVector OnUpdatePrimSinglePosition;
+ public event ClientChangeObject onClientChangeObject;
public event UpdatePrimRotation OnUpdatePrimGroupRotation;
public event UpdatePrimSingleRotationPosition OnUpdatePrimSingleRotationPosition;
public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation;
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index fa750aba1b..be6b81b5ac 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -135,6 +135,7 @@ namespace OpenSim.Tests.Common.Mock
public event GenericCall7 OnObjectMaterial;
public event UpdatePrimFlags OnUpdatePrimFlags;
public event UpdatePrimTexture OnUpdatePrimTexture;
+ public event ClientChangeObject onClientChangeObject;
public event UpdateVector OnUpdatePrimGroupPosition;
public event UpdateVector OnUpdatePrimSinglePosition;
public event UpdatePrimRotation OnUpdatePrimGroupRotation;