* Added basic 3-5 level undo on prim position/rotation/scale.
* In the future this should be a config option... and, hopefully this tides the builders over for a little while.0.6.0-stable
parent
7693a7dac9
commit
1fb54b074c
|
@ -571,6 +571,8 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
event ScriptAnswer OnScriptAnswer;
|
event ScriptAnswer OnScriptAnswer;
|
||||||
|
|
||||||
|
event AgentSit OnUndo;
|
||||||
|
|
||||||
LLVector3 StartPos { get; set; }
|
LLVector3 StartPos { get; set; }
|
||||||
|
|
||||||
LLUUID AgentId { get; }
|
LLUUID AgentId { get; }
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Undo stack. Deletes entries beyond a certain capacity
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
[Serializable]
|
||||||
|
public class UndoStack<T>
|
||||||
|
{
|
||||||
|
|
||||||
|
private int m_new = 1;
|
||||||
|
private int m_old = 0;
|
||||||
|
private T[] m_Undos;
|
||||||
|
|
||||||
|
public bool IsFull
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_new == m_old;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int Capacity
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_Undos.Length - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public UndoStack(int capacity)
|
||||||
|
{
|
||||||
|
m_Undos = new T[capacity + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Push(T item)
|
||||||
|
{
|
||||||
|
if (IsFull)
|
||||||
|
{
|
||||||
|
m_old++;
|
||||||
|
if (m_old >= m_Undos.Length)
|
||||||
|
m_old -= m_Undos.Length;
|
||||||
|
}
|
||||||
|
if (++m_new >= m_Undos.Length)
|
||||||
|
m_new -= m_Undos.Length;
|
||||||
|
m_Undos[m_new] = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Pop()
|
||||||
|
{
|
||||||
|
if (Count > 0)
|
||||||
|
{
|
||||||
|
T deleted = m_Undos[m_new];
|
||||||
|
m_Undos[m_new--] = default(T);
|
||||||
|
if (m_new < 0)
|
||||||
|
m_new += m_Undos.Length;
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new InvalidOperationException("Cannot pop from emtpy stack");
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
int count = m_new - m_old - 1;
|
||||||
|
if (count < 0)
|
||||||
|
count += m_Undos.Length;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public T Peek()
|
||||||
|
{
|
||||||
|
return m_Undos[m_new];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
if (Count > 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_Undos.Length; i++)
|
||||||
|
{
|
||||||
|
m_Undos[i] = default(T);
|
||||||
|
}
|
||||||
|
m_new = 1;
|
||||||
|
m_old = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -238,6 +238,7 @@ namespace OpenSim.Region.ClientStack
|
||||||
private ScriptAnswer handlerScriptAnswer = null;
|
private ScriptAnswer handlerScriptAnswer = null;
|
||||||
private RequestPayPrice handlerRequestPayPrice = null;
|
private RequestPayPrice handlerRequestPayPrice = null;
|
||||||
private ObjectDeselect handlerObjectDetach = null;
|
private ObjectDeselect handlerObjectDetach = null;
|
||||||
|
private AgentSit handlerOnUndo = null;
|
||||||
|
|
||||||
/* Properties */
|
/* Properties */
|
||||||
|
|
||||||
|
@ -799,6 +800,7 @@ namespace OpenSim.Region.ClientStack
|
||||||
|
|
||||||
public event ScriptAnswer OnScriptAnswer;
|
public event ScriptAnswer OnScriptAnswer;
|
||||||
public event RequestPayPrice OnRequestPayPrice;
|
public event RequestPayPrice OnRequestPayPrice;
|
||||||
|
public event AgentSit OnUndo;
|
||||||
|
|
||||||
#region Scene/Avatar to Client
|
#region Scene/Avatar to Client
|
||||||
|
|
||||||
|
@ -3884,6 +3886,23 @@ namespace OpenSim.Region.ClientStack
|
||||||
// That means multiple object perms may be updated in a single packet.
|
// That means multiple object perms may be updated in a single packet.
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PacketType.Undo:
|
||||||
|
UndoPacket undoitem = (UndoPacket)Pack;
|
||||||
|
if (undoitem.ObjectData.Length > 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < undoitem.ObjectData.Length; i++)
|
||||||
|
{
|
||||||
|
LLUUID objiD = undoitem.ObjectData[i].ObjectID;
|
||||||
|
handlerOnUndo = OnUndo;
|
||||||
|
if (handlerOnUndo != null)
|
||||||
|
{
|
||||||
|
handlerOnUndo(this, objiD);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case PacketType.ObjectDuplicateOnRay:
|
case PacketType.ObjectDuplicateOnRay:
|
||||||
ObjectDuplicateOnRayPacket dupeOnRay = (ObjectDuplicateOnRayPacket)Pack;
|
ObjectDuplicateOnRayPacket dupeOnRay = (ObjectDuplicateOnRayPacket)Pack;
|
||||||
|
|
||||||
|
|
|
@ -312,6 +312,20 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void HandleUndo(IClientAPI remoteClient, LLUUID primId)
|
||||||
|
{
|
||||||
|
if (primId != LLUUID.Zero)
|
||||||
|
{
|
||||||
|
SceneObjectPart part = m_parentScene.GetSceneObjectPart(primId);
|
||||||
|
if (part != null)
|
||||||
|
part.Undo();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event Handling routine for Attach Object
|
/// Event Handling routine for Attach Object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -78,6 +78,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
private readonly Mutex updateLock;
|
private readonly Mutex updateLock;
|
||||||
public bool m_physicalPrim;
|
public bool m_physicalPrim;
|
||||||
public bool m_seeIntoRegionFromNeighbor;
|
public bool m_seeIntoRegionFromNeighbor;
|
||||||
|
public int MaxUndoCount = 5;
|
||||||
private int m_RestartTimerCounter;
|
private int m_RestartTimerCounter;
|
||||||
private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
|
private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
|
||||||
private int m_incrementsof15seconds = 0;
|
private int m_incrementsof15seconds = 0;
|
||||||
|
@ -1628,6 +1629,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
client.OnTeleportHomeRequest += TeleportClientHome;
|
client.OnTeleportHomeRequest += TeleportClientHome;
|
||||||
|
|
||||||
client.OnSetStartLocationRequest += SetHomeRezPoint;
|
client.OnSetStartLocationRequest += SetHomeRezPoint;
|
||||||
|
client.OnUndo += m_innerScene.HandleUndo;
|
||||||
|
|
||||||
EventManager.TriggerOnNewClient(client);
|
EventManager.TriggerOnNewClient(client);
|
||||||
}
|
}
|
||||||
|
|
|
@ -378,6 +378,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
part.RegionHandle = m_regionHandle;
|
part.RegionHandle = m_regionHandle;
|
||||||
|
|
||||||
part.TrimPermissions();
|
part.TrimPermissions();
|
||||||
|
part.StoreUndoState();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XmlNodeType.EndElement:
|
case XmlNodeType.EndElement:
|
||||||
|
@ -436,6 +437,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
{
|
{
|
||||||
SceneObjectPart Part = SceneObjectPart.FromXml(reader);
|
SceneObjectPart Part = SceneObjectPart.FromXml(reader);
|
||||||
AddPart(Part);
|
AddPart(Part);
|
||||||
|
Part.StoreUndoState();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -703,6 +705,8 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_scene.m_physicalPrim);
|
m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_scene.m_physicalPrim);
|
||||||
AttachToBackup();
|
AttachToBackup();
|
||||||
m_rootPart.ScheduleFullUpdate();
|
m_rootPart.ScheduleFullUpdate();
|
||||||
|
m_rootPart.ClearUndoState();
|
||||||
|
|
||||||
}
|
}
|
||||||
public void DetachToInventoryPrep()
|
public void DetachToInventoryPrep()
|
||||||
{
|
{
|
||||||
|
@ -731,6 +735,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
private void SetPartAsNonRoot(SceneObjectPart part)
|
private void SetPartAsNonRoot(SceneObjectPart part)
|
||||||
{
|
{
|
||||||
part.ParentID = m_rootPart.LocalId;
|
part.ParentID = m_rootPart.LocalId;
|
||||||
|
part.ClearUndoState();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -783,6 +788,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_parts.Add(part.UUID, part);
|
m_parts.Add(part.UUID, part);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -803,6 +809,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
if (part.UUID != m_rootPart.UUID)
|
if (part.UUID != m_rootPart.UUID)
|
||||||
{
|
{
|
||||||
part.ParentID = m_rootPart.LocalId;
|
part.ParentID = m_rootPart.LocalId;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -815,10 +822,17 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
part.UUID = LLUUID.Random();
|
part.UUID = LLUUID.Random();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// helper provided for parts.
|
||||||
|
public int GetSceneMaxUndo()
|
||||||
|
{
|
||||||
|
if (m_scene != null)
|
||||||
|
return m_scene.MaxUndoCount;
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
public void ResetChildPrimPhysicsPositions()
|
public void ResetChildPrimPhysicsPositions()
|
||||||
{
|
{
|
||||||
AbsolutePosition = AbsolutePosition;
|
AbsolutePosition = AbsolutePosition;
|
||||||
|
@ -845,12 +859,15 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
{
|
{
|
||||||
SceneObjectPart part = GetChildPart(localId);
|
SceneObjectPart part = GetChildPart(localId);
|
||||||
OnGrabPart(part, offsetPos, remoteClient);
|
OnGrabPart(part, offsetPos, remoteClient);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnGrabPart(SceneObjectPart part, LLVector3 offsetPos, IClientAPI remoteClient)
|
public virtual void OnGrabPart(SceneObjectPart part, LLVector3 offsetPos, IClientAPI remoteClient)
|
||||||
{
|
{
|
||||||
|
part.StoreUndoState();
|
||||||
part.OnGrab(offsetPos, remoteClient);
|
part.OnGrab(offsetPos, remoteClient);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnGrabGroup(LLVector3 offsetPos, IClientAPI remoteClient)
|
public virtual void OnGrabGroup(LLVector3 offsetPos, IClientAPI remoteClient)
|
||||||
|
@ -1384,6 +1401,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
SetPartAsNonRoot(newPart);
|
SetPartAsNonRoot(newPart);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1758,6 +1776,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
{
|
{
|
||||||
LinkNonRootPart(part, oldGroupPosition, oldRootRotation);
|
LinkNonRootPart(part, oldGroupPosition, oldRootRotation);
|
||||||
}
|
}
|
||||||
|
part.ClearUndoState();
|
||||||
}
|
}
|
||||||
|
|
||||||
DetachFromBackup(objectGroup);
|
DetachFromBackup(objectGroup);
|
||||||
|
@ -1781,7 +1800,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
public void DelinkFromGroup(uint partID)
|
public void DelinkFromGroup(uint partID)
|
||||||
{
|
{
|
||||||
SceneObjectPart linkPart = GetChildPart(partID);
|
SceneObjectPart linkPart = GetChildPart(partID);
|
||||||
|
linkPart.ClearUndoState();
|
||||||
if (null != linkPart)
|
if (null != linkPart)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
@ -106,6 +107,8 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
[XmlIgnore] public LLVector3 m_attachedPos = LLVector3.Zero;
|
[XmlIgnore] public LLVector3 m_attachedPos = LLVector3.Zero;
|
||||||
[XmlIgnore] public LLUUID fromAssetID = LLUUID.Zero;
|
[XmlIgnore] public LLUUID fromAssetID = LLUUID.Zero;
|
||||||
|
|
||||||
|
[XmlIgnore] public bool m_undoing = false;
|
||||||
|
|
||||||
public Int32 CreationDate;
|
public Int32 CreationDate;
|
||||||
public uint ParentID = 0;
|
public uint ParentID = 0;
|
||||||
|
|
||||||
|
@ -123,6 +126,8 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
public uint EveryoneMask = (uint)PermissionMask.None;
|
public uint EveryoneMask = (uint)PermissionMask.None;
|
||||||
public uint NextOwnerMask = (uint)PermissionMask.All;
|
public uint NextOwnerMask = (uint)PermissionMask.All;
|
||||||
|
|
||||||
|
private UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5);
|
||||||
|
|
||||||
public LLObject.ObjectFlags Flags = LLObject.ObjectFlags.None;
|
public LLObject.ObjectFlags Flags = LLObject.ObjectFlags.None;
|
||||||
|
|
||||||
public uint ObjectFlags
|
public uint ObjectFlags
|
||||||
|
@ -267,6 +272,40 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void StoreUndoState()
|
||||||
|
{
|
||||||
|
if (!m_undoing)
|
||||||
|
{
|
||||||
|
if (m_parentGroup != null)
|
||||||
|
{
|
||||||
|
if (m_undo.Count > 0)
|
||||||
|
{
|
||||||
|
UndoState last = m_undo.Peek();
|
||||||
|
if (last != null)
|
||||||
|
{
|
||||||
|
if (last.Compare(this))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (m_parentGroup.GetSceneMaxUndo() > 0)
|
||||||
|
{
|
||||||
|
UndoState nUndo = new UndoState(this);
|
||||||
|
|
||||||
|
m_undo.Push(nUndo);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearUndoState()
|
||||||
|
{
|
||||||
|
m_undo.Clear();
|
||||||
|
StoreUndoState();
|
||||||
|
}
|
||||||
|
|
||||||
public LLVector3 GroupPosition
|
public LLVector3 GroupPosition
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -291,6 +330,8 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
StoreUndoState();
|
||||||
|
|
||||||
m_groupPosition = value;
|
m_groupPosition = value;
|
||||||
|
|
||||||
if (PhysActor != null)
|
if (PhysActor != null)
|
||||||
|
@ -334,7 +375,10 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
public LLVector3 OffsetPosition
|
public LLVector3 OffsetPosition
|
||||||
{
|
{
|
||||||
get { return m_offsetPosition; }
|
get { return m_offsetPosition; }
|
||||||
set { m_offsetPosition = value;
|
set
|
||||||
|
{
|
||||||
|
StoreUndoState();
|
||||||
|
m_offsetPosition = value;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Hack to get the child prim to update world positions in the physics engine
|
// Hack to get the child prim to update world positions in the physics engine
|
||||||
|
@ -380,6 +424,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
StoreUndoState();
|
||||||
m_rotationOffset = value;
|
m_rotationOffset = value;
|
||||||
|
|
||||||
if (PhysActor != null)
|
if (PhysActor != null)
|
||||||
|
@ -651,6 +696,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
get { return m_shape.Scale; }
|
get { return m_shape.Scale; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
StoreUndoState();
|
||||||
m_shape.Scale = value;
|
m_shape.Scale = value;
|
||||||
TriggerScriptChangedEvent(Changed.SCALE);
|
TriggerScriptChangedEvent(Changed.SCALE);
|
||||||
}
|
}
|
||||||
|
@ -759,6 +805,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
LLObject.ObjectFlags.CreateSelected;
|
LLObject.ObjectFlags.CreateSelected;
|
||||||
|
|
||||||
TrimPermissions();
|
TrimPermissions();
|
||||||
|
//m_undo = new UndoStack<UndoState>(ParentGroup.GetSceneMaxUndo());
|
||||||
|
|
||||||
ScheduleFullUpdate();
|
ScheduleFullUpdate();
|
||||||
}
|
}
|
||||||
|
@ -1982,6 +2029,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
|
|
||||||
public void UpdateRotation(LLQuaternion rot)
|
public void UpdateRotation(LLQuaternion rot)
|
||||||
{
|
{
|
||||||
|
//StoreUndoState();
|
||||||
RotationOffset = new LLQuaternion(rot.X, rot.Y, rot.Z, rot.W);
|
RotationOffset = new LLQuaternion(rot.X, rot.Y, rot.Z, rot.W);
|
||||||
ScheduleTerseUpdate();
|
ScheduleTerseUpdate();
|
||||||
}
|
}
|
||||||
|
@ -2097,6 +2145,7 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
/// <param name="scale"></param>
|
/// <param name="scale"></param>
|
||||||
public void Resize(LLVector3 scale)
|
public void Resize(LLVector3 scale)
|
||||||
{
|
{
|
||||||
|
StoreUndoState();
|
||||||
m_shape.Scale = scale;
|
m_shape.Scale = scale;
|
||||||
|
|
||||||
ScheduleFullUpdate();
|
ScheduleFullUpdate();
|
||||||
|
@ -2522,5 +2571,15 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
info.AddValue("PayPrice", PayPrice);
|
info.AddValue("PayPrice", PayPrice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Undo()
|
||||||
|
{
|
||||||
|
if (m_undo.Count > 0)
|
||||||
|
{
|
||||||
|
UndoState goback = m_undo.Pop();
|
||||||
|
if (goback != null)
|
||||||
|
goback.PlaybackState(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSim Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using libsecondlife;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Scenes
|
||||||
|
{
|
||||||
|
public class UndoState
|
||||||
|
{
|
||||||
|
public LLVector3 Position = LLVector3.Zero;
|
||||||
|
public LLVector3 Scale = LLVector3.Zero;
|
||||||
|
public LLQuaternion Rotation = LLQuaternion.Identity;
|
||||||
|
|
||||||
|
public UndoState(LLVector3 pos, LLQuaternion rot, LLVector3 scale)
|
||||||
|
{
|
||||||
|
Position = pos;
|
||||||
|
Rotation = rot;
|
||||||
|
Scale = scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UndoState(SceneObjectPart part)
|
||||||
|
{
|
||||||
|
if (part != null)
|
||||||
|
{
|
||||||
|
if (part.ParentID == 0)
|
||||||
|
{
|
||||||
|
Position = part.AbsolutePosition;
|
||||||
|
Rotation = part.RotationOffset;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Position = part.GroupPosition;
|
||||||
|
Rotation = part.RotationOffset;
|
||||||
|
Scale = part.Shape.Scale;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Compare(SceneObjectPart part)
|
||||||
|
{
|
||||||
|
if (part != null)
|
||||||
|
{
|
||||||
|
if (part.ParentID == 0)
|
||||||
|
{
|
||||||
|
if (Position == part.AbsolutePosition && Rotation == part.RotationOffset)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Position == part.GroupPosition && Rotation == part.RotationOffset && Scale == part.Shape.Scale)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PlaybackState(SceneObjectPart part)
|
||||||
|
{
|
||||||
|
if (part != null)
|
||||||
|
{
|
||||||
|
part.m_undoing = true;
|
||||||
|
|
||||||
|
if (part.ParentID == 0)
|
||||||
|
{
|
||||||
|
part.ParentGroup.AbsolutePosition = Position;
|
||||||
|
part.UpdateRotation(Rotation);
|
||||||
|
part.ParentGroup.ScheduleGroupForTerseUpdate();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
part.OffsetPosition = Position;
|
||||||
|
part.UpdateRotation(Rotation);
|
||||||
|
part.Resize(Scale);
|
||||||
|
part.ScheduleTerseUpdate();
|
||||||
|
}
|
||||||
|
part.m_undoing = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public UndoState()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -171,6 +171,7 @@ namespace OpenSim.Region.Examples.SimpleModule
|
||||||
|
|
||||||
public event ScriptAnswer OnScriptAnswer;
|
public event ScriptAnswer OnScriptAnswer;
|
||||||
public event RequestPayPrice OnRequestPayPrice;
|
public event RequestPayPrice OnRequestPayPrice;
|
||||||
|
public event AgentSit OnUndo;
|
||||||
|
|
||||||
|
|
||||||
#pragma warning restore 67
|
#pragma warning restore 67
|
||||||
|
|
Loading…
Reference in New Issue