From 6fc74b36d1d0f7dcd6f013893c3189a3f989431c Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 18 Jul 2011 04:54:21 +0100
Subject: Make various tweaks to undo code in an effort to get things working
better.
Undo rotation and position appear to be working.
Resizing a single prim appears to be working, though the undo has to be done twice.
Resizing a group of prims still does not work properly - possibly because in the UndoState we don't store a knowledge of when we're resizing a whole group rather than individual prims.
This needs to be addressed.
---
OpenSim/Region/Framework/Scenes/SceneGraph.cs | 1 +
.../Region/Framework/Scenes/SceneObjectGroup.cs | 58 +++++++++++---
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 92 +++++++++++++--------
.../Scenes/Tests/SceneObjectResizeTests.cs | 2 +-
OpenSim/Region/Framework/Scenes/UndoState.cs | 93 ++++++++++++++++++++--
5 files changed, 193 insertions(+), 53 deletions(-)
(limited to 'OpenSim/Region/Framework')
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index bdb7f95..0a0bde8 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -564,6 +564,7 @@ namespace OpenSim.Region.Framework.Scenes
part.Undo();
}
}
+
protected internal void HandleRedo(IClientAPI remoteClient, UUID primId)
{
if (primId != UUID.Zero)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index ce5db5f..7254992 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1145,6 +1145,10 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient)
{
+// m_log.DebugFormat(
+// "[SCENE OBJECT GROUP]: Processing OnGrabPart for {0} on {1} {2}, offsetPos {3}",
+// remoteClient.Name, part.Name, part.LocalId, offsetPos);
+
part.StoreUndoState();
part.OnGrab(offsetPos, remoteClient);
}
@@ -2611,17 +2615,14 @@ namespace OpenSim.Region.Framework.Scenes
#region Resize
-
///
/// Resize the entire group of prims.
///
///
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.IgnoreUndoUpdate = true;
+// m_log.DebugFormat(
+// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale);
scale.X = Math.Min(scale.X, Scene.m_maxNonphys);
scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys);
@@ -2647,7 +2648,7 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart obPart = parts[i];
if (obPart.UUID != m_rootPart.UUID)
{
- obPart.IgnoreUndoUpdate = true;
+// obPart.IgnoreUndoUpdate = true;
Vector3 oldSize = new Vector3(obPart.Scale);
float f = 1.0f;
@@ -2663,6 +2664,7 @@ namespace OpenSim.Region.Framework.Scenes
y *= a;
z *= a;
}
+
if (oldSize.Y * y > m_scene.m_maxPhys)
{
f = m_scene.m_maxPhys / oldSize.Y;
@@ -2671,6 +2673,7 @@ namespace OpenSim.Region.Framework.Scenes
y *= a;
z *= a;
}
+
if (oldSize.Z * z > m_scene.m_maxPhys)
{
f = m_scene.m_maxPhys / oldSize.Z;
@@ -2690,6 +2693,7 @@ namespace OpenSim.Region.Framework.Scenes
y *= a;
z *= a;
}
+
if (oldSize.Y * y > m_scene.m_maxNonphys)
{
f = m_scene.m_maxNonphys / oldSize.Y;
@@ -2698,6 +2702,7 @@ namespace OpenSim.Region.Framework.Scenes
y *= a;
z *= a;
}
+
if (oldSize.Z * z > m_scene.m_maxNonphys)
{
f = m_scene.m_maxNonphys / oldSize.Z;
@@ -2708,7 +2713,7 @@ namespace OpenSim.Region.Framework.Scenes
}
}
- obPart.IgnoreUndoUpdate = false;
+// obPart.IgnoreUndoUpdate = false;
}
}
}
@@ -2723,7 +2728,7 @@ namespace OpenSim.Region.Framework.Scenes
for (int i = 0; i < parts.Length; i++)
{
SceneObjectPart obPart = parts[i];
- obPart.IgnoreUndoUpdate = true;
+// obPart.IgnoreUndoUpdate = true;
if (obPart.UUID != m_rootPart.UUID)
{
@@ -2738,16 +2743,18 @@ namespace OpenSim.Region.Framework.Scenes
newSize.Z *= z;
obPart.Resize(newSize);
+
+ obPart.IgnoreUndoUpdate = true;
obPart.UpdateOffSet(currentpos);
+ obPart.IgnoreUndoUpdate = false;
}
- obPart.IgnoreUndoUpdate = false;
- obPart.StoreUndoState();
+// obPart.IgnoreUndoUpdate = false;
+// obPart.StoreUndoState();
}
- RootPart.IgnoreUndoUpdate = false;
-
- RootPart.StoreUndoState();
+// m_log.DebugFormat(
+// "[SCENE OBJECT GROUP]: Finished group resizing {0} {1} to {2}", Name, LocalId, RootPart.Scale);
}
#endregion
@@ -2760,6 +2767,8 @@ 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);
+
SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++)
parts[i].StoreUndoState();
@@ -2805,6 +2814,9 @@ namespace OpenSim.Region.Framework.Scenes
if (part != null)
{
+// m_log.DebugFormat(
+// "[SCENE OBJECT GROUP]: Updating single position of {0} {1} to {2}", part.Name, part.LocalId, pos);
+
if (part.UUID == m_rootPart.UUID)
{
UpdateRootPosition(pos);
@@ -2824,6 +2836,9 @@ namespace OpenSim.Region.Framework.Scenes
///
private 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();
@@ -2868,6 +2883,9 @@ 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();
@@ -2892,6 +2910,9 @@ 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();
@@ -2926,6 +2947,9 @@ 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 (part.UUID == m_rootPart.UUID)
{
UpdateRootRotation(rot);
@@ -2947,6 +2971,10 @@ 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);
+
if (part.UUID == m_rootPart.UUID)
{
UpdateRootRotation(rot);
@@ -2969,6 +2997,10 @@ namespace OpenSim.Region.Framework.Scenes
///
private void UpdateRootRotation(Quaternion rot)
{
+// m_log.DebugFormat(
+// "[SCENE OBJECT GROUP]: Updating root rotation of {0} {1} to {2}",
+// Name, LocalId, rot);
+
Quaternion axRot = rot;
Quaternion oldParentRot = m_rootPart.RotationOffset;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index a1200ee..aab83b8 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1014,15 +1014,19 @@ namespace OpenSim.Region.Framework.Scenes
get { return m_shape; }
set { m_shape = value; }
}
-
+
+ ///
+ /// Change the scale of this part.
+ ///
public Vector3 Scale
{
get { return m_shape.Scale; }
set
{
- StoreUndoState();
if (m_shape != null)
{
+ StoreUndoState();
+
m_shape.Scale = value;
PhysicsActor actor = PhysActor;
@@ -1033,11 +1037,16 @@ namespace OpenSim.Region.Framework.Scenes
if (m_parentGroup.Scene.PhysicsScene != null)
{
actor.Size = m_shape.Scale;
- m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
+
+ if (((OpenMetaverse.SculptType)Shape.SculptType) == SculptType.Mesh)
+ CheckSculptAndLoad();
+ else
+ ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
}
}
}
}
+
TriggerScriptChangedEvent(Changed.SCALE);
}
}
@@ -2827,8 +2836,12 @@ namespace OpenSim.Region.Framework.Scenes
}
///
- /// Resize this part.
+ /// Set the scale of this part.
///
+ ///
+ /// Unlike the scale property, this checks the new size against scene limits and schedules a full property
+ /// update to viewers.
+ ///
///
public void Resize(Vector3 scale)
{
@@ -2836,33 +2849,18 @@ namespace OpenSim.Region.Framework.Scenes
scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys);
scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys);
-// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale);
-
- StoreUndoState();
- m_shape.Scale = scale;
-
- // If we're a mesh/sculpt, then we need to tell the physics engine about our new size. To do this, we
- // need to reinsert the sculpt data into the shape, since the physics engine deletes it when done to
- // save memory
- if (PhysActor != null)
+ if (PhysActor != null && PhysActor.IsPhysical)
{
- if (PhysActor.IsPhysical)
- {
- scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys);
- scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys);
- scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys);
- }
+ scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys);
+ scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys);
+ scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys);
+ }
- PhysActor.Size = scale;
+// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale);
- if (((OpenMetaverse.SculptType)Shape.SculptType) == SculptType.Mesh)
- CheckSculptAndLoad();
- else
- ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
- }
+ Scale = scale;
ParentGroup.HasGroupChanged = true;
- TriggerScriptChangedEvent(Changed.SCALE);
ScheduleFullUpdate();
}
@@ -3673,8 +3671,6 @@ namespace OpenSim.Region.Framework.Scenes
{
if (m_parentGroup != null)
{
-// m_log.DebugFormat("[SCENE OBJECT PART]: Storing undo state for {0} {1}", Name, LocalId);
-
lock (m_undo)
{
if (m_undo.Count > 0)
@@ -3683,15 +3679,29 @@ namespace OpenSim.Region.Framework.Scenes
if (last != null)
{
if (last.Compare(this))
+ {
+// m_log.DebugFormat(
+// "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
+// Name, LocalId, m_undo.Count);
+
return;
+ }
}
}
+// m_log.DebugFormat(
+// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, initial stack size {2}",
+// Name, LocalId, m_undo.Count);
+
if (m_parentGroup.GetSceneMaxUndo() > 0)
{
UndoState nUndo = new UndoState(this);
m_undo.Push(nUndo);
+
+// m_log.DebugFormat(
+// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, stack size now {2}",
+// Name, LocalId, m_undo.Count);
}
}
}
@@ -3703,7 +3713,8 @@ namespace OpenSim.Region.Framework.Scenes
}
// else
// {
-// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
+// m_log.DebugFormat(
+// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
// }
}
@@ -3721,10 +3732,12 @@ namespace OpenSim.Region.Framework.Scenes
public void Undo()
{
-// m_log.DebugFormat("[SCENE OBJECT PART]: Handling undo request for {0} {1}", Name, LocalId);
-
lock (m_undo)
{
+// m_log.DebugFormat(
+// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
+// Name, LocalId, m_undo.Count);
+
if (m_undo.Count > 0)
{
UndoState nUndo = null;
@@ -3739,19 +3752,26 @@ namespace OpenSim.Region.Framework.Scenes
if (goback != null)
{
goback.PlaybackState(this);
+
if (nUndo != null)
m_redo.Push(nUndo);
}
}
+
+// m_log.DebugFormat(
+// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}",
+// Name, LocalId, m_undo.Count);
}
}
public void Redo()
{
-// m_log.DebugFormat("[SCENE OBJECT PART]: Handling redo request for {0} {1}", Name, LocalId);
-
lock (m_redo)
{
+// m_log.DebugFormat(
+// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
+// Name, LocalId, m_redo.Count);
+
if (m_parentGroup.GetSceneMaxUndo() > 0)
{
UndoState nUndo = new UndoState(this);
@@ -3763,11 +3783,17 @@ namespace OpenSim.Region.Framework.Scenes
if (gofwd != null)
gofwd.PlayfwdState(this);
+
+// m_log.DebugFormat(
+// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}",
+// Name, LocalId, m_redo.Count);
}
}
public void ClearUndoState()
{
+// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId);
+
lock (m_undo)
{
m_undo.Clear();
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
index 6dbac3c..c4047ee 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
@@ -50,7 +50,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
public void TestResizeSceneObject()
{
TestHelper.InMethod();
- //log4net.Config.XmlConfigurator.Configure();
+// log4net.Config.XmlConfigurator.Configure();
Scene scene = SceneSetupHelpers.SetupScene();
SceneObjectGroup g1 = SceneSetupHelpers.AddSceneObject(scene).ParentGroup;
diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs
index 55e407e..38bbeb0 100644
--- a/OpenSim/Region/Framework/Scenes/UndoState.cs
+++ b/OpenSim/Region/Framework/Scenes/UndoState.cs
@@ -25,6 +25,9 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+using System;
+using System.Reflection;
+using log4net;
using OpenMetaverse;
using OpenSim.Region.Framework.Interfaces;
@@ -32,49 +35,80 @@ namespace OpenSim.Region.Framework.Scenes
{
public class UndoState
{
+// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
public Vector3 Position = Vector3.Zero;
public Vector3 Scale = Vector3.Zero;
public Quaternion Rotation = Quaternion.Identity;
+ ///
+ /// Constructor.
+ ///
+ ///
public UndoState(SceneObjectPart part)
{
if (part != null)
{
if (part.ParentID == 0)
{
+// m_log.DebugFormat(
+// "[UNDO STATE]: Storing undo position {0} for root part", part.ParentGroup.AbsolutePosition);
Position = part.ParentGroup.AbsolutePosition;
+
+// m_log.DebugFormat(
+// "[UNDO STATE]: Storing undo rotation {0} for root part", part.RotationOffset);
Rotation = part.RotationOffset;
+
+// m_log.DebugFormat(
+// "[UNDO STATE]: Storing undo scale {0} for root part", part.Shape.Scale);
Scale = part.Shape.Scale;
}
else
{
+// m_log.DebugFormat(
+// "[UNDO STATE]: Storing undo position {0} for child part", part.OffsetPosition);
Position = part.OffsetPosition;
+
+// m_log.DebugFormat(
+// "[UNDO STATE]: Storing undo rotation {0} for child part", part.RotationOffset);
Rotation = part.RotationOffset;
+
+// m_log.DebugFormat(
+// "[UNDO STATE]: Storing undo scale {0} for child part", part.Shape.Scale);
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)
{
if (part != null)
{
if (part.ParentID == 0)
{
- if (Position == part.ParentGroup.AbsolutePosition && Rotation == part.ParentGroup.Rotation)
+ if (Position == part.ParentGroup.AbsolutePosition
+ && Rotation == part.RotationOffset
+ && Scale == part.Shape.Scale)
return true;
else
return false;
}
else
{
- if (Position == part.OffsetPosition && Rotation == part.RotationOffset && Scale == part.Shape.Scale)
+ if (Position == part.OffsetPosition
+ && Rotation == part.RotationOffset
+ && Scale == part.Shape.Scale)
return true;
else
return false;
-
}
}
+
return false;
}
@@ -87,24 +121,64 @@ namespace OpenSim.Region.Framework.Scenes
if (part.ParentID == 0)
{
if (Position != Vector3.Zero)
+ {
+// m_log.DebugFormat(
+// "[UNDO STATE]: Undoing position {0} to {1} for root part {2} {3}",
+// part.ParentGroup.AbsolutePosition, Position, part.Name, part.LocalId);
+
part.ParentGroup.AbsolutePosition = Position;
+ }
+
+// m_log.DebugFormat(
+// "[UNDO STATE]: Undoing rotation {0} to {1} for root part {2} {3}",
+// part.RotationOffset, Rotation, part.Name, part.LocalId);
+
part.RotationOffset = Rotation;
+
if (Scale != Vector3.Zero)
+ {
+// m_log.DebugFormat(
+// "[UNDO STATE]: Undoing scale {0} to {1} for root part {2} {3}",
+// part.Shape.Scale, Scale, part.Name, part.LocalId);
+
part.Resize(Scale);
+ }
+
part.ParentGroup.ScheduleGroupForTerseUpdate();
}
else
{
if (Position != Vector3.Zero)
+ {
+// m_log.DebugFormat(
+// "[UNDO STATE]: Undoing position {0} to {1} for child part {2} {3}",
+// part.OffsetPosition, Position, part.Name, part.LocalId);
+
part.OffsetPosition = Position;
+ }
+
+// m_log.DebugFormat(
+// "[UNDO STATE]: Undoing rotation {0} to {1} for child part {2} {3}",
+// part.RotationOffset, Rotation, part.Name, part.LocalId);
+
part.UpdateRotation(Rotation);
+
if (Scale != Vector3.Zero)
- part.Resize(Scale); part.ScheduleTerseUpdate();
+ {
+// m_log.DebugFormat(
+// "[UNDO STATE]: Undoing scale {0} to {1} for child part {2} {3}",
+// part.Shape.Scale, Scale, part.Name, part.LocalId);
+
+ part.Resize(Scale);
+ }
+
+ part.ScheduleTerseUpdate();
}
- part.Undoing = false;
+ part.Undoing = false;
}
}
+
public void PlayfwdState(SceneObjectPart part)
{
if (part != null)
@@ -115,27 +189,34 @@ namespace OpenSim.Region.Framework.Scenes
{
if (Position != Vector3.Zero)
part.ParentGroup.AbsolutePosition = Position;
+
if (Rotation != Quaternion.Identity)
part.UpdateRotation(Rotation);
+
if (Scale != Vector3.Zero)
part.Resize(Scale);
+
part.ParentGroup.ScheduleGroupForTerseUpdate();
}
else
{
if (Position != Vector3.Zero)
part.OffsetPosition = Position;
+
if (Rotation != Quaternion.Identity)
part.UpdateRotation(Rotation);
+
if (Scale != Vector3.Zero)
part.Resize(Scale);
+
part.ScheduleTerseUpdate();
}
- part.Undoing = false;
+ part.Undoing = false;
}
}
}
+
public class LandUndoState
{
public ITerrainModule m_terrainModule;
--
cgit v1.1