From fe2b044d38f3bd3aa669334d34567fd991a67b3e Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 3 Jul 2010 06:10:55 -0700 Subject: Fix Undo! Made a lot of changes to Undo state saving; it now considers that groups of objects can be moved and not just individual prims.. --- OpenSim/Region/Framework/Scenes/UndoState.cs | 55 +++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/UndoState.cs') diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 55e407e..77381ab 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -35,6 +35,10 @@ namespace OpenSim.Region.Framework.Scenes public Vector3 Position = Vector3.Zero; public Vector3 Scale = Vector3.Zero; public Quaternion Rotation = Quaternion.Identity; + public bool GroupChange = false; + public Vector3 GroupPosition = Vector3.Zero; + public Quaternion GroupRotation = Quaternion.Identity; + public Vector3 GroupScale = Vector3.Zero; public UndoState(SceneObjectPart part) { @@ -42,12 +46,24 @@ namespace OpenSim.Region.Framework.Scenes { if (part.ParentID == 0) { - Position = part.ParentGroup.AbsolutePosition; + GroupScale = part.Shape.Scale; + + //FUBAR WARNING: Do NOT get the group's absoluteposition here + //or you'll experience a loop and/or a stack issue + GroupPosition = part.ParentGroup.RootPart.AbsolutePosition; + GroupRotation = part.ParentGroup.Rotation; + Position = part.ParentGroup.RootPart.AbsolutePosition; Rotation = part.RotationOffset; Scale = part.Shape.Scale; } else { + GroupScale = part.Shape.Scale; + + //FUBAR WARNING: Do NOT get the group's absoluteposition here + //or you'll experience a loop and/or a stack issue + GroupPosition = part.ParentGroup.RootPart.AbsolutePosition; + GroupRotation = part.ParentGroup.Rotation; Position = part.OffsetPosition; Rotation = part.RotationOffset; Scale = part.Shape.Scale; @@ -61,14 +77,14 @@ namespace OpenSim.Region.Framework.Scenes { if (part.ParentID == 0) { - if (Position == part.ParentGroup.AbsolutePosition && Rotation == part.ParentGroup.Rotation) + if (Position == part.ParentGroup.RootPart.AbsolutePosition && Rotation == part.ParentGroup.Rotation && GroupPosition == part.ParentGroup.RootPart.AbsolutePosition && part.ParentGroup.Rotation == GroupRotation && part.Shape.Scale == GroupScale) 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 && GroupPosition == part.ParentGroup.RootPart.AbsolutePosition && part.ParentGroup.Rotation == GroupRotation && part.Shape.Scale == GroupScale) return true; else return false; @@ -84,10 +100,10 @@ namespace OpenSim.Region.Framework.Scenes { part.Undoing = true; - if (part.ParentID == 0) + if (part.ParentID == 0 && GroupChange == false) { if (Position != Vector3.Zero) - part.ParentGroup.AbsolutePosition = Position; + part.ParentGroup.AbsolutePosition = Position; part.RotationOffset = Rotation; if (Scale != Vector3.Zero) part.Resize(Scale); @@ -95,11 +111,30 @@ namespace OpenSim.Region.Framework.Scenes } else { - if (Position != Vector3.Zero) - part.OffsetPosition = Position; - part.UpdateRotation(Rotation); - if (Scale != Vector3.Zero) - part.Resize(Scale); part.ScheduleTerseUpdate(); + if (GroupChange) + { + if (Position != Vector3.Zero) + { + //Calculate the scale... + Vector3 gs = part.Shape.Scale; + float scale = GroupScale.Z / gs.Z; + + //Scale first since it can affect our position + part.ParentGroup.GroupResize(gs * scale, part.LocalId); + part.ParentGroup.AbsolutePosition = GroupPosition; + part.ParentGroup.Rotation = GroupRotation; + + } + } + else + { + if (Position != Vector3.Zero) //We can use this for all the updates since all are set + { + part.OffsetPosition = Position; + part.UpdateRotation(Rotation); + part.Resize(Scale); part.ScheduleTerseUpdate(); + } + } } part.Undoing = false; -- cgit v1.1 From 5b68343361cbd000a2f024b37797ec235abb7207 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sun, 4 Jul 2010 19:28:39 -0700 Subject: The majority of the Undo fix. There is still an issue with Rotation which i'll address next; however position undo and scale undo should be working just fine now. Also removed some residual debug logging. --- OpenSim/Region/Framework/Scenes/UndoState.cs | 80 ++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/UndoState.cs') diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 77381ab..ad05351 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -27,26 +27,43 @@ using OpenMetaverse; using OpenSim.Region.Framework.Interfaces; +using System; namespace OpenSim.Region.Framework.Scenes { + [Flags] + public enum UndoType + { + STATE_PRIM_POSITION = 1, + STATE_PRIM_ROTATION = 2, + STATE_PRIM_SCALE = 4, + STATE_PRIM_ALL = 7, + STATE_GROUP_POSITION = 8, + STATE_GROUP_ROTATION = 16, + STATE_GROUP_SCALE = 32, + STATE_GROUP_ALL = 56, + STATE_ALL = 63 + } + public class UndoState { public Vector3 Position = Vector3.Zero; public Vector3 Scale = Vector3.Zero; public Quaternion Rotation = Quaternion.Identity; - public bool GroupChange = false; public Vector3 GroupPosition = Vector3.Zero; public Quaternion GroupRotation = Quaternion.Identity; public Vector3 GroupScale = Vector3.Zero; + public DateTime LastUpdated = DateTime.Now; + public UndoType Type; - public UndoState(SceneObjectPart part) + public UndoState(SceneObjectPart part, UndoType type) { + Type = type; if (part != null) { if (part.ParentID == 0) { - GroupScale = part.Shape.Scale; + GroupScale = part.ParentGroup.RootPart.Shape.Scale; //FUBAR WARNING: Do NOT get the group's absoluteposition here //or you'll experience a loop and/or a stack issue @@ -55,6 +72,7 @@ namespace OpenSim.Region.Framework.Scenes Position = part.ParentGroup.RootPart.AbsolutePosition; Rotation = part.RotationOffset; Scale = part.Shape.Scale; + LastUpdated = DateTime.Now; } else { @@ -67,10 +85,54 @@ namespace OpenSim.Region.Framework.Scenes Position = part.OffsetPosition; Rotation = part.RotationOffset; Scale = part.Shape.Scale; + LastUpdated = DateTime.Now; } } } - + public void Merge(UndoState last) + { + if ((Type & UndoType.STATE_GROUP_POSITION) == 0 || ((last.Type & UndoType.STATE_GROUP_POSITION) >= (Type & UndoType.STATE_GROUP_POSITION))) + { + GroupPosition = last.GroupPosition; + Position = last.Position; + } + if ((Type & UndoType.STATE_GROUP_SCALE) == 0 || ((last.Type & UndoType.STATE_GROUP_SCALE) >= (Type & UndoType.STATE_GROUP_SCALE))) + { + Console.WriteLine("Setting groupscale to " + last.GroupScale.ToString()); + GroupScale = last.GroupScale; + Scale = last.Scale; + } + if ((Type & UndoType.STATE_GROUP_ROTATION) == 0 || ((last.Type & UndoType.STATE_GROUP_ROTATION) >= (Type & UndoType.STATE_GROUP_ROTATION))) + { + GroupRotation = last.GroupRotation; + Rotation = last.Rotation; + } + if ((Type & UndoType.STATE_PRIM_POSITION) == 0 || ((last.Type & UndoType.STATE_PRIM_POSITION) >= (Type & UndoType.STATE_PRIM_POSITION))) + { + Position = last.Position; + } + if ((Type & UndoType.STATE_PRIM_SCALE) == 0 || ((last.Type & UndoType.STATE_PRIM_SCALE) >= (Type & UndoType.STATE_PRIM_SCALE))) + { + Scale = last.Scale; + } + if ((Type & UndoType.STATE_PRIM_ROTATION) == 0 || ((last.Type & UndoType.STATE_PRIM_ROTATION) >= (Type & UndoType.STATE_PRIM_ROTATION))) + { + Rotation = last.Rotation; + } + Type = Type | last.Type; + } + public bool Compare(UndoState undo) + { + if (undo == null || Position == null) return false; + if (undo.Position == Position && undo.Rotation == Rotation && undo.Scale == Scale && undo.GroupPosition == GroupPosition && undo.GroupScale == GroupScale && undo.GroupRotation == GroupRotation) + { + return true; + } + else + { + return false; + } + } public bool Compare(SceneObjectPart part) { if (part != null) @@ -96,6 +158,14 @@ namespace OpenSim.Region.Framework.Scenes public void PlaybackState(SceneObjectPart part) { + bool GroupChange = false; + if ((Type & UndoType.STATE_GROUP_POSITION) != 0 + || (Type & UndoType.STATE_GROUP_ROTATION) != 0 + || (Type & UndoType.STATE_GROUP_SCALE) != 0) + { + GroupChange = true; + } + if (part != null) { part.Undoing = true; @@ -113,6 +183,7 @@ namespace OpenSim.Region.Framework.Scenes { if (GroupChange) { + part.ParentGroup.RootPart.Undoing = true; if (Position != Vector3.Zero) { //Calculate the scale... @@ -125,6 +196,7 @@ namespace OpenSim.Region.Framework.Scenes part.ParentGroup.Rotation = GroupRotation; } + part.ParentGroup.RootPart.Undoing = false; } else { -- cgit v1.1 From c616335019dc9419460407930af4e40e84663efa Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sun, 4 Jul 2010 19:58:52 -0700 Subject: Rotation undo fix and remove a debug chatter i missed. Still not working: Individual child prim rotational undo and special cases where the root prim was moved or rotated (all the children then need to restore their offsets). Coming shortly. --- OpenSim/Region/Framework/Scenes/UndoState.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/UndoState.cs') diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index ad05351..f9601e6 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -68,7 +68,7 @@ namespace OpenSim.Region.Framework.Scenes //FUBAR WARNING: Do NOT get the group's absoluteposition here //or you'll experience a loop and/or a stack issue GroupPosition = part.ParentGroup.RootPart.AbsolutePosition; - GroupRotation = part.ParentGroup.Rotation; + GroupRotation = part.ParentGroup.GroupRotation; Position = part.ParentGroup.RootPart.AbsolutePosition; Rotation = part.RotationOffset; Scale = part.Shape.Scale; @@ -98,7 +98,6 @@ namespace OpenSim.Region.Framework.Scenes } if ((Type & UndoType.STATE_GROUP_SCALE) == 0 || ((last.Type & UndoType.STATE_GROUP_SCALE) >= (Type & UndoType.STATE_GROUP_SCALE))) { - Console.WriteLine("Setting groupscale to " + last.GroupScale.ToString()); GroupScale = last.GroupScale; Scale = last.Scale; } @@ -184,7 +183,7 @@ namespace OpenSim.Region.Framework.Scenes if (GroupChange) { part.ParentGroup.RootPart.Undoing = true; - if (Position != Vector3.Zero) + if (GroupPosition != Vector3.Zero) { //Calculate the scale... Vector3 gs = part.Shape.Scale; @@ -193,7 +192,7 @@ namespace OpenSim.Region.Framework.Scenes //Scale first since it can affect our position part.ParentGroup.GroupResize(gs * scale, part.LocalId); part.ParentGroup.AbsolutePosition = GroupPosition; - part.ParentGroup.Rotation = GroupRotation; + part.ParentGroup.UpdateGroupRotationR(GroupRotation); } part.ParentGroup.RootPart.Undoing = false; -- cgit v1.1 From be5dd04150bae69745de3cf5efde3d5be288dd71 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 5 Jul 2010 03:58:18 -0700 Subject: Bring "Redo" up to date with "Undo" so it works too --- OpenSim/Region/Framework/Scenes/UndoState.cs | 41 +++++++--------------------- 1 file changed, 10 insertions(+), 31 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/UndoState.cs') diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index f9601e6..2af3316 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -123,7 +123,7 @@ namespace OpenSim.Region.Framework.Scenes public bool Compare(UndoState undo) { if (undo == null || Position == null) return false; - if (undo.Position == Position && undo.Rotation == Rotation && undo.Scale == Scale && undo.GroupPosition == GroupPosition && undo.GroupScale == GroupScale && undo.GroupRotation == GroupRotation) + if (undo.Position == Position && undo.Rotation == Rotation && undo.Scale == Scale && undo.GroupPosition == GroupPosition && undo.GroupScale == GroupScale && undo.GroupRotation == GroupRotation) { return true; } @@ -155,7 +155,7 @@ namespace OpenSim.Region.Framework.Scenes return false; } - public void PlaybackState(SceneObjectPart part) + private void RestoreState(SceneObjectPart part) { bool GroupChange = false; if ((Type & UndoType.STATE_GROUP_POSITION) != 0 @@ -172,7 +172,7 @@ namespace OpenSim.Region.Framework.Scenes if (part.ParentID == 0 && GroupChange == false) { if (Position != Vector3.Zero) - part.ParentGroup.AbsolutePosition = Position; + part.ParentGroup.AbsolutePosition = Position; part.RotationOffset = Rotation; if (Scale != Vector3.Zero) part.Resize(Scale); @@ -193,7 +193,7 @@ namespace OpenSim.Region.Framework.Scenes part.ParentGroup.GroupResize(gs * scale, part.LocalId); part.ParentGroup.AbsolutePosition = GroupPosition; part.ParentGroup.UpdateGroupRotationR(GroupRotation); - + } part.ParentGroup.RootPart.Undoing = false; } @@ -211,35 +211,13 @@ namespace OpenSim.Region.Framework.Scenes } } + public void PlaybackState(SceneObjectPart part) + { + RestoreState(part); + } public void PlayfwdState(SceneObjectPart part) { - if (part != null) - { - part.Undoing = true; - - if (part.ParentID == 0) - { - 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; - - } + RestoreState(part); } } public class LandUndoState @@ -267,3 +245,4 @@ namespace OpenSim.Region.Framework.Scenes } } } + -- cgit v1.1 From e947d04038f7b42929368d9f7b6d440be139e675 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 5 Jul 2010 05:44:35 -0700 Subject: Undo fix is now complete. This commit repairs the special case of the root prim moving or rotating independently of the rest of the group. --- OpenSim/Region/Framework/Scenes/UndoState.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/UndoState.cs') diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 2af3316..f71b507 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -172,8 +172,9 @@ namespace OpenSim.Region.Framework.Scenes if (part.ParentID == 0 && GroupChange == false) { if (Position != Vector3.Zero) - part.ParentGroup.AbsolutePosition = Position; - part.RotationOffset = Rotation; + + part.ParentGroup.UpdateSinglePosition(Position, part.LocalId); + part.ParentGroup.UpdateSingleRotation(Rotation, part.LocalId); if (Scale != Vector3.Zero) part.Resize(Scale); part.ParentGroup.ScheduleGroupForTerseUpdate(); -- cgit v1.1