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;