diff options
author | Tom Grimshaw | 2010-07-03 06:10:55 -0700 |
---|---|---|
committer | Tom Grimshaw | 2010-07-03 06:10:55 -0700 |
commit | fe2b044d38f3bd3aa669334d34567fd991a67b3e (patch) | |
tree | bb94a343716c2620e043ac070a8cb269564f3a9c /OpenSim | |
parent | Re-implement the Undo stack as a List; the old implementation was buggy (diff) | |
download | opensim-SC-fe2b044d38f3bd3aa669334d34567fd991a67b3e.zip opensim-SC-fe2b044d38f3bd3aa669334d34567fd991a67b3e.tar.gz opensim-SC-fe2b044d38f3bd3aa669334d34567fd991a67b3e.tar.bz2 opensim-SC-fe2b044d38f3bd3aa669334d34567fd991a67b3e.tar.xz |
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..
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 39 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 16 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/UndoState.cs | 55 |
3 files changed, 87 insertions, 23 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index c48ce3b..da664da 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -349,7 +349,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
349 | public virtual Quaternion Rotation | 349 | public virtual Quaternion Rotation |
350 | { | 350 | { |
351 | get { return m_rotation; } | 351 | get { return m_rotation; } |
352 | set { m_rotation = value; } | 352 | set { |
353 | lockPartsForRead(true); | ||
354 | try | ||
355 | { | ||
356 | foreach(SceneObjectPart p in m_parts.Values) | ||
357 | { | ||
358 | p.StoreUndoState(true); | ||
359 | } | ||
360 | } | ||
361 | finally | ||
362 | { | ||
363 | lockPartsForRead(false); | ||
364 | } | ||
365 | m_rotation = value; | ||
366 | } | ||
353 | } | 367 | } |
354 | 368 | ||
355 | public Quaternion GroupRotation | 369 | public Quaternion GroupRotation |
@@ -421,6 +435,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
421 | get { return m_rootPart.GroupPosition; } | 435 | get { return m_rootPart.GroupPosition; } |
422 | set | 436 | set |
423 | { | 437 | { |
438 | |||
424 | Vector3 val = value; | 439 | Vector3 val = value; |
425 | 440 | ||
426 | if ((m_scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || m_scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) | 441 | if ((m_scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || m_scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) |
@@ -431,7 +446,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
431 | } | 446 | } |
432 | 447 | ||
433 | lockPartsForRead(true); | 448 | lockPartsForRead(true); |
434 | 449 | foreach (SceneObjectPart part in m_parts.Values) | |
450 | { | ||
451 | part.IgnoreUndoUpdate = true; | ||
452 | } | ||
435 | if (RootPart.GetStatusSandbox()) | 453 | if (RootPart.GetStatusSandbox()) |
436 | { | 454 | { |
437 | if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) | 455 | if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) |
@@ -443,12 +461,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
443 | return; | 461 | return; |
444 | } | 462 | } |
445 | } | 463 | } |
446 | |||
447 | foreach (SceneObjectPart part in m_parts.Values) | 464 | foreach (SceneObjectPart part in m_parts.Values) |
448 | { | 465 | { |
466 | part.IgnoreUndoUpdate = false; | ||
467 | part.StoreUndoState(true); | ||
449 | part.GroupPosition = val; | 468 | part.GroupPosition = val; |
450 | } | 469 | } |
451 | |||
452 | lockPartsForRead(false); | 470 | lockPartsForRead(false); |
453 | 471 | ||
454 | //if (m_rootPart.PhysActor != null) | 472 | //if (m_rootPart.PhysActor != null) |
@@ -724,7 +742,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
724 | { | 742 | { |
725 | foreach (SceneObjectPart part in m_parts.Values) | 743 | foreach (SceneObjectPart part in m_parts.Values) |
726 | { | 744 | { |
727 | |||
728 | Vector3 partscale = part.Scale; | 745 | Vector3 partscale = part.Scale; |
729 | Vector3 partoffset = part.OffsetPosition; | 746 | Vector3 partoffset = part.OffsetPosition; |
730 | 747 | ||
@@ -3132,7 +3149,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3132 | SceneObjectPart part = GetChildPart(localID); | 3149 | SceneObjectPart part = GetChildPart(localID); |
3133 | if (part != null) | 3150 | if (part != null) |
3134 | { | 3151 | { |
3135 | part.IgnoreUndoUpdate = true; | ||
3136 | if (scale.X > m_scene.m_maxNonphys) | 3152 | if (scale.X > m_scene.m_maxNonphys) |
3137 | scale.X = m_scene.m_maxNonphys; | 3153 | scale.X = m_scene.m_maxNonphys; |
3138 | if (scale.Y > m_scene.m_maxNonphys) | 3154 | if (scale.Y > m_scene.m_maxNonphys) |
@@ -3218,8 +3234,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3218 | y *= a; | 3234 | y *= a; |
3219 | z *= a; | 3235 | z *= a; |
3220 | } | 3236 | } |
3221 | obPart.IgnoreUndoUpdate = false; | 3237 | |
3222 | obPart.StoreUndoState(); | ||
3223 | } | 3238 | } |
3224 | } | 3239 | } |
3225 | } | 3240 | } |
@@ -3229,13 +3244,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
3229 | Vector3 prevScale = part.Scale; | 3244 | Vector3 prevScale = part.Scale; |
3230 | prevScale.X *= x; | 3245 | prevScale.X *= x; |
3231 | prevScale.Y *= y; | 3246 | prevScale.Y *= y; |
3232 | prevScale.Z *= z; | 3247 | prevScale.Z *= z;; |
3248 | part.IgnoreUndoUpdate = true; | ||
3233 | part.Resize(prevScale); | 3249 | part.Resize(prevScale); |
3250 | part.IgnoreUndoUpdate = false; | ||
3234 | 3251 | ||
3235 | lockPartsForRead(true); | 3252 | lockPartsForRead(true); |
3236 | { | 3253 | { |
3237 | foreach (SceneObjectPart obPart in m_parts.Values) | 3254 | foreach (SceneObjectPart obPart in m_parts.Values) |
3238 | { | 3255 | { |
3256 | obPart.IgnoreUndoUpdate = false; | ||
3257 | obPart.StoreUndoState(true); | ||
3239 | obPart.IgnoreUndoUpdate = true; | 3258 | obPart.IgnoreUndoUpdate = true; |
3240 | if (obPart.UUID != m_rootPart.UUID) | 3259 | if (obPart.UUID != m_rootPart.UUID) |
3241 | { | 3260 | { |
@@ -3251,7 +3270,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3251 | obPart.UpdateOffSet(currentpos); | 3270 | obPart.UpdateOffSet(currentpos); |
3252 | } | 3271 | } |
3253 | obPart.IgnoreUndoUpdate = false; | 3272 | obPart.IgnoreUndoUpdate = false; |
3254 | obPart.StoreUndoState(); | ||
3255 | } | 3273 | } |
3256 | } | 3274 | } |
3257 | lockPartsForRead(false); | 3275 | lockPartsForRead(false); |
@@ -3263,7 +3281,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3263 | } | 3281 | } |
3264 | 3282 | ||
3265 | part.IgnoreUndoUpdate = false; | 3283 | part.IgnoreUndoUpdate = false; |
3266 | part.StoreUndoState(); | ||
3267 | HasGroupChanged = true; | 3284 | HasGroupChanged = true; |
3268 | ScheduleGroupForTerseUpdate(); | 3285 | ScheduleGroupForTerseUpdate(); |
3269 | } | 3286 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 5b007e6..72ad281 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -3504,9 +3504,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3504 | m_parentGroup.ScheduleGroupForTerseUpdate(); | 3504 | m_parentGroup.ScheduleGroupForTerseUpdate(); |
3505 | //m_parentGroup.ScheduleGroupForFullUpdate(); | 3505 | //m_parentGroup.ScheduleGroupForFullUpdate(); |
3506 | } | 3506 | } |
3507 | |||
3508 | public void StoreUndoState() | 3507 | public void StoreUndoState() |
3509 | { | 3508 | { |
3509 | StoreUndoState(false); | ||
3510 | } | ||
3511 | public void StoreUndoState(bool group) | ||
3512 | { | ||
3510 | if (!Undoing) | 3513 | if (!Undoing) |
3511 | { | 3514 | { |
3512 | if (!IgnoreUndoUpdate) | 3515 | if (!IgnoreUndoUpdate) |
@@ -3528,7 +3531,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3528 | if (m_parentGroup.GetSceneMaxUndo() > 0) | 3531 | if (m_parentGroup.GetSceneMaxUndo() > 0) |
3529 | { | 3532 | { |
3530 | UndoState nUndo = new UndoState(this); | 3533 | UndoState nUndo = new UndoState(this); |
3531 | 3534 | nUndo.GroupChange = group; | |
3532 | m_undo.Push(nUndo); | 3535 | m_undo.Push(nUndo); |
3533 | } | 3536 | } |
3534 | 3537 | ||
@@ -4010,6 +4013,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
4010 | nUndo = new UndoState(this); | 4013 | nUndo = new UndoState(this); |
4011 | } | 4014 | } |
4012 | UndoState goback = m_undo.Pop(); | 4015 | UndoState goback = m_undo.Pop(); |
4016 | m_log.Debug("Got goback"); | ||
4017 | if (goback == null) | ||
4018 | { | ||
4019 | m_log.Debug("it's null"); | ||
4020 | } | ||
4021 | else | ||
4022 | { | ||
4023 | m_log.Debug(goback.GroupPosition.ToString()); | ||
4024 | } | ||
4013 | if (goback != null) | 4025 | if (goback != null) |
4014 | { | 4026 | { |
4015 | goback.PlaybackState(this); | 4027 | goback.PlaybackState(this); |
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 | |||
35 | public Vector3 Position = Vector3.Zero; | 35 | public Vector3 Position = Vector3.Zero; |
36 | public Vector3 Scale = Vector3.Zero; | 36 | public Vector3 Scale = Vector3.Zero; |
37 | public Quaternion Rotation = Quaternion.Identity; | 37 | public Quaternion Rotation = Quaternion.Identity; |
38 | public bool GroupChange = false; | ||
39 | public Vector3 GroupPosition = Vector3.Zero; | ||
40 | public Quaternion GroupRotation = Quaternion.Identity; | ||
41 | public Vector3 GroupScale = Vector3.Zero; | ||
38 | 42 | ||
39 | public UndoState(SceneObjectPart part) | 43 | public UndoState(SceneObjectPart part) |
40 | { | 44 | { |
@@ -42,12 +46,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
42 | { | 46 | { |
43 | if (part.ParentID == 0) | 47 | if (part.ParentID == 0) |
44 | { | 48 | { |
45 | Position = part.ParentGroup.AbsolutePosition; | 49 | GroupScale = part.Shape.Scale; |
50 | |||
51 | //FUBAR WARNING: Do NOT get the group's absoluteposition here | ||
52 | //or you'll experience a loop and/or a stack issue | ||
53 | GroupPosition = part.ParentGroup.RootPart.AbsolutePosition; | ||
54 | GroupRotation = part.ParentGroup.Rotation; | ||
55 | Position = part.ParentGroup.RootPart.AbsolutePosition; | ||
46 | Rotation = part.RotationOffset; | 56 | Rotation = part.RotationOffset; |
47 | Scale = part.Shape.Scale; | 57 | Scale = part.Shape.Scale; |
48 | } | 58 | } |
49 | else | 59 | else |
50 | { | 60 | { |
61 | GroupScale = part.Shape.Scale; | ||
62 | |||
63 | //FUBAR WARNING: Do NOT get the group's absoluteposition here | ||
64 | //or you'll experience a loop and/or a stack issue | ||
65 | GroupPosition = part.ParentGroup.RootPart.AbsolutePosition; | ||
66 | GroupRotation = part.ParentGroup.Rotation; | ||
51 | Position = part.OffsetPosition; | 67 | Position = part.OffsetPosition; |
52 | Rotation = part.RotationOffset; | 68 | Rotation = part.RotationOffset; |
53 | Scale = part.Shape.Scale; | 69 | Scale = part.Shape.Scale; |
@@ -61,14 +77,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
61 | { | 77 | { |
62 | if (part.ParentID == 0) | 78 | if (part.ParentID == 0) |
63 | { | 79 | { |
64 | if (Position == part.ParentGroup.AbsolutePosition && Rotation == part.ParentGroup.Rotation) | 80 | if (Position == part.ParentGroup.RootPart.AbsolutePosition && Rotation == part.ParentGroup.Rotation && GroupPosition == part.ParentGroup.RootPart.AbsolutePosition && part.ParentGroup.Rotation == GroupRotation && part.Shape.Scale == GroupScale) |
65 | return true; | 81 | return true; |
66 | else | 82 | else |
67 | return false; | 83 | return false; |
68 | } | 84 | } |
69 | else | 85 | else |
70 | { | 86 | { |
71 | if (Position == part.OffsetPosition && Rotation == part.RotationOffset && Scale == part.Shape.Scale) | 87 | if (Position == part.OffsetPosition && Rotation == part.RotationOffset && Scale == part.Shape.Scale && GroupPosition == part.ParentGroup.RootPart.AbsolutePosition && part.ParentGroup.Rotation == GroupRotation && part.Shape.Scale == GroupScale) |
72 | return true; | 88 | return true; |
73 | else | 89 | else |
74 | return false; | 90 | return false; |
@@ -84,10 +100,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
84 | { | 100 | { |
85 | part.Undoing = true; | 101 | part.Undoing = true; |
86 | 102 | ||
87 | if (part.ParentID == 0) | 103 | if (part.ParentID == 0 && GroupChange == false) |
88 | { | 104 | { |
89 | if (Position != Vector3.Zero) | 105 | if (Position != Vector3.Zero) |
90 | part.ParentGroup.AbsolutePosition = Position; | 106 | part.ParentGroup.AbsolutePosition = Position; |
91 | part.RotationOffset = Rotation; | 107 | part.RotationOffset = Rotation; |
92 | if (Scale != Vector3.Zero) | 108 | if (Scale != Vector3.Zero) |
93 | part.Resize(Scale); | 109 | part.Resize(Scale); |
@@ -95,11 +111,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
95 | } | 111 | } |
96 | else | 112 | else |
97 | { | 113 | { |
98 | if (Position != Vector3.Zero) | 114 | if (GroupChange) |
99 | part.OffsetPosition = Position; | 115 | { |
100 | part.UpdateRotation(Rotation); | 116 | if (Position != Vector3.Zero) |
101 | if (Scale != Vector3.Zero) | 117 | { |
102 | part.Resize(Scale); part.ScheduleTerseUpdate(); | 118 | //Calculate the scale... |
119 | Vector3 gs = part.Shape.Scale; | ||
120 | float scale = GroupScale.Z / gs.Z; | ||
121 | |||
122 | //Scale first since it can affect our position | ||
123 | part.ParentGroup.GroupResize(gs * scale, part.LocalId); | ||
124 | part.ParentGroup.AbsolutePosition = GroupPosition; | ||
125 | part.ParentGroup.Rotation = GroupRotation; | ||
126 | |||
127 | } | ||
128 | } | ||
129 | else | ||
130 | { | ||
131 | if (Position != Vector3.Zero) //We can use this for all the updates since all are set | ||
132 | { | ||
133 | part.OffsetPosition = Position; | ||
134 | part.UpdateRotation(Rotation); | ||
135 | part.Resize(Scale); part.ScheduleTerseUpdate(); | ||
136 | } | ||
137 | } | ||
103 | } | 138 | } |
104 | part.Undoing = false; | 139 | part.Undoing = false; |
105 | 140 | ||