diff options
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 21 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 28 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 479 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 301 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs | 4 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs | 104 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/UndoState.cs | 219 |
7 files changed, 723 insertions, 433 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 8195a0d..6e66632 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -1751,8 +1751,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1751 | SceneObjectPart rootPart = group.GetChildPart(group.UUID); | 1751 | SceneObjectPart rootPart = group.GetChildPart(group.UUID); |
1752 | rootPart.Flags &= ~PrimFlags.Scripted; | 1752 | rootPart.Flags &= ~PrimFlags.Scripted; |
1753 | rootPart.TrimPermissions(); | 1753 | rootPart.TrimPermissions(); |
1754 | group.CheckSculptAndLoad(); | 1754 | |
1755 | //rootPart.DoPhysicsPropertyUpdate(UsePhysics, true); | 1755 | // Don't do this here - it will get done later on when sculpt data is loaded. |
1756 | // group.CheckSculptAndLoad(); | ||
1756 | } | 1757 | } |
1757 | 1758 | ||
1758 | m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)"); | 1759 | m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)"); |
@@ -2715,12 +2716,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
2715 | 2716 | ||
2716 | public virtual void SubscribeToClientPrimEvents(IClientAPI client) | 2717 | public virtual void SubscribeToClientPrimEvents(IClientAPI client) |
2717 | { | 2718 | { |
2718 | client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimPosition; | 2719 | client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition; |
2719 | client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition; | 2720 | client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition; |
2720 | client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimRotation; | 2721 | |
2721 | client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimRotation; | 2722 | client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimGroupRotation; |
2723 | client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation; | ||
2722 | client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation; | 2724 | client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation; |
2723 | client.OnUpdatePrimSingleRotationPosition += m_sceneGraph.UpdatePrimSingleRotationPosition; | 2725 | client.OnUpdatePrimSingleRotationPosition += m_sceneGraph.UpdatePrimSingleRotationPosition; |
2726 | |||
2724 | client.OnUpdatePrimScale += m_sceneGraph.UpdatePrimScale; | 2727 | client.OnUpdatePrimScale += m_sceneGraph.UpdatePrimScale; |
2725 | client.OnUpdatePrimGroupScale += m_sceneGraph.UpdatePrimGroupScale; | 2728 | client.OnUpdatePrimGroupScale += m_sceneGraph.UpdatePrimGroupScale; |
2726 | client.OnUpdateExtraParams += m_sceneGraph.UpdateExtraParam; | 2729 | client.OnUpdateExtraParams += m_sceneGraph.UpdateExtraParam; |
@@ -2842,12 +2845,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
2842 | 2845 | ||
2843 | public virtual void UnSubscribeToClientPrimEvents(IClientAPI client) | 2846 | public virtual void UnSubscribeToClientPrimEvents(IClientAPI client) |
2844 | { | 2847 | { |
2845 | client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimPosition; | 2848 | client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimGroupPosition; |
2846 | client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition; | 2849 | client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition; |
2847 | client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimRotation; | 2850 | |
2848 | client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimRotation; | 2851 | client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimGroupRotation; |
2852 | client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimGroupRotation; | ||
2849 | client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation; | 2853 | client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation; |
2850 | client.OnUpdatePrimSingleRotationPosition -= m_sceneGraph.UpdatePrimSingleRotationPosition; | 2854 | client.OnUpdatePrimSingleRotationPosition -= m_sceneGraph.UpdatePrimSingleRotationPosition; |
2855 | |||
2851 | client.OnUpdatePrimScale -= m_sceneGraph.UpdatePrimScale; | 2856 | client.OnUpdatePrimScale -= m_sceneGraph.UpdatePrimScale; |
2852 | client.OnUpdatePrimGroupScale -= m_sceneGraph.UpdatePrimGroupScale; | 2857 | client.OnUpdatePrimGroupScale -= m_sceneGraph.UpdatePrimGroupScale; |
2853 | client.OnUpdateExtraParams -= m_sceneGraph.UpdateExtraParam; | 2858 | client.OnUpdateExtraParams -= m_sceneGraph.UpdateExtraParam; |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 7ec7ea3..65dc2c9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -564,11 +564,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
564 | part.Undo(); | 564 | part.Undo(); |
565 | } | 565 | } |
566 | } | 566 | } |
567 | |||
567 | protected internal void HandleRedo(IClientAPI remoteClient, UUID primId) | 568 | protected internal void HandleRedo(IClientAPI remoteClient, UUID primId) |
568 | { | 569 | { |
569 | if (primId != UUID.Zero) | 570 | if (primId != UUID.Zero) |
570 | { | 571 | { |
571 | SceneObjectPart part = m_parentScene.GetSceneObjectPart(primId); | 572 | SceneObjectPart part = m_parentScene.GetSceneObjectPart(primId); |
573 | |||
572 | if (part != null) | 574 | if (part != null) |
573 | part.Redo(); | 575 | part.Redo(); |
574 | } | 576 | } |
@@ -1210,19 +1212,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
1210 | #region Client Event handlers | 1212 | #region Client Event handlers |
1211 | 1213 | ||
1212 | /// <summary> | 1214 | /// <summary> |
1213 | /// | 1215 | /// Update the scale of an individual prim. |
1214 | /// </summary> | 1216 | /// </summary> |
1215 | /// <param name="localID"></param> | 1217 | /// <param name="localID"></param> |
1216 | /// <param name="scale"></param> | 1218 | /// <param name="scale"></param> |
1217 | /// <param name="remoteClient"></param> | 1219 | /// <param name="remoteClient"></param> |
1218 | protected internal void UpdatePrimScale(uint localID, Vector3 scale, IClientAPI remoteClient) | 1220 | protected internal void UpdatePrimScale(uint localID, Vector3 scale, IClientAPI remoteClient) |
1219 | { | 1221 | { |
1220 | SceneObjectGroup group = GetGroupByPrim(localID); | 1222 | SceneObjectPart part = GetSceneObjectPart(localID); |
1221 | if (group != null) | 1223 | |
1224 | if (part != null) | ||
1222 | { | 1225 | { |
1223 | if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) | 1226 | if (m_parentScene.Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId)) |
1224 | { | 1227 | { |
1225 | group.Resize(scale, localID); | 1228 | part.Resize(scale); |
1226 | } | 1229 | } |
1227 | } | 1230 | } |
1228 | } | 1231 | } |
@@ -1234,7 +1237,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1234 | { | 1237 | { |
1235 | if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) | 1238 | if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) |
1236 | { | 1239 | { |
1237 | group.GroupResize(scale, localID); | 1240 | group.GroupResize(scale); |
1238 | } | 1241 | } |
1239 | } | 1242 | } |
1240 | } | 1243 | } |
@@ -1288,19 +1291,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
1288 | { | 1291 | { |
1289 | if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId)) | 1292 | if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId)) |
1290 | { | 1293 | { |
1291 | group.UpdateSingleRotation(rot,pos, localID); | 1294 | group.UpdateSingleRotation(rot, pos, localID); |
1292 | } | 1295 | } |
1293 | } | 1296 | } |
1294 | } | 1297 | } |
1295 | 1298 | ||
1296 | |||
1297 | /// <summary> | 1299 | /// <summary> |
1298 | /// | 1300 | /// Update the rotation of a whole group. |
1299 | /// </summary> | 1301 | /// </summary> |
1300 | /// <param name="localID"></param> | 1302 | /// <param name="localID"></param> |
1301 | /// <param name="rot"></param> | 1303 | /// <param name="rot"></param> |
1302 | /// <param name="remoteClient"></param> | 1304 | /// <param name="remoteClient"></param> |
1303 | protected internal void UpdatePrimRotation(uint localID, Quaternion rot, IClientAPI remoteClient) | 1305 | protected internal void UpdatePrimGroupRotation(uint localID, Quaternion rot, IClientAPI remoteClient) |
1304 | { | 1306 | { |
1305 | SceneObjectGroup group = GetGroupByPrim(localID); | 1307 | SceneObjectGroup group = GetGroupByPrim(localID); |
1306 | if (group != null) | 1308 | if (group != null) |
@@ -1319,7 +1321,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1319 | /// <param name="pos"></param> | 1321 | /// <param name="pos"></param> |
1320 | /// <param name="rot"></param> | 1322 | /// <param name="rot"></param> |
1321 | /// <param name="remoteClient"></param> | 1323 | /// <param name="remoteClient"></param> |
1322 | protected internal void UpdatePrimRotation(uint localID, Vector3 pos, Quaternion rot, IClientAPI remoteClient) | 1324 | protected internal void UpdatePrimGroupRotation(uint localID, Vector3 pos, Quaternion rot, IClientAPI remoteClient) |
1323 | { | 1325 | { |
1324 | SceneObjectGroup group = GetGroupByPrim(localID); | 1326 | SceneObjectGroup group = GetGroupByPrim(localID); |
1325 | if (group != null) | 1327 | if (group != null) |
@@ -1350,12 +1352,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1350 | } | 1352 | } |
1351 | 1353 | ||
1352 | /// <summary> | 1354 | /// <summary> |
1353 | /// Update the position of the given part | 1355 | /// Update the position of the given group. |
1354 | /// </summary> | 1356 | /// </summary> |
1355 | /// <param name="localID"></param> | 1357 | /// <param name="localID"></param> |
1356 | /// <param name="pos"></param> | 1358 | /// <param name="pos"></param> |
1357 | /// <param name="remoteClient"></param> | 1359 | /// <param name="remoteClient"></param> |
1358 | public void UpdatePrimPosition(uint localID, Vector3 pos, IClientAPI remoteClient) | 1360 | public void UpdatePrimGroupPosition(uint localID, Vector3 pos, IClientAPI remoteClient) |
1359 | { | 1361 | { |
1360 | SceneObjectGroup group = GetGroupByPrim(localID); | 1362 | SceneObjectGroup group = GetGroupByPrim(localID); |
1361 | 1363 | ||
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index fa23fcd..b6fb5a4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -236,6 +236,38 @@ namespace OpenSim.Region.Framework.Scenes | |||
236 | get { return m_rootPart.RotationOffset; } | 236 | get { return m_rootPart.RotationOffset; } |
237 | } | 237 | } |
238 | 238 | ||
239 | public Vector3 GroupScale | ||
240 | { | ||
241 | get | ||
242 | { | ||
243 | Vector3 minScale = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize); | ||
244 | Vector3 maxScale = Vector3.Zero; | ||
245 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); | ||
246 | |||
247 | SceneObjectPart[] parts = m_parts.GetArray(); | ||
248 | for (int i = 0; i < parts.Length; i++) | ||
249 | { | ||
250 | SceneObjectPart part = parts[i]; | ||
251 | Vector3 partscale = part.Scale; | ||
252 | Vector3 partoffset = part.OffsetPosition; | ||
253 | |||
254 | minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X; | ||
255 | minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y; | ||
256 | minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z; | ||
257 | |||
258 | maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; | ||
259 | maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; | ||
260 | maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; | ||
261 | } | ||
262 | |||
263 | finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; | ||
264 | finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; | ||
265 | finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; | ||
266 | |||
267 | return finalScale; | ||
268 | } | ||
269 | } | ||
270 | |||
239 | public UUID GroupID | 271 | public UUID GroupID |
240 | { | 272 | { |
241 | get { return m_rootPart.GroupID; } | 273 | get { return m_rootPart.GroupID; } |
@@ -584,7 +616,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
584 | part.ParentID = m_rootPart.LocalId; | 616 | part.ParentID = m_rootPart.LocalId; |
585 | //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID); | 617 | //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID); |
586 | } | 618 | } |
587 | 619 | ||
588 | ApplyPhysics(m_scene.m_physicalPrim); | 620 | ApplyPhysics(m_scene.m_physicalPrim); |
589 | 621 | ||
590 | // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled | 622 | // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled |
@@ -592,34 +624,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
592 | //ScheduleGroupForFullUpdate(); | 624 | //ScheduleGroupForFullUpdate(); |
593 | } | 625 | } |
594 | 626 | ||
595 | public Vector3 GroupScale() | ||
596 | { | ||
597 | Vector3 minScale = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize); | ||
598 | Vector3 maxScale = Vector3.Zero; | ||
599 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); | ||
600 | |||
601 | SceneObjectPart[] parts = m_parts.GetArray(); | ||
602 | for (int i = 0; i < parts.Length; i++) | ||
603 | { | ||
604 | SceneObjectPart part = parts[i]; | ||
605 | Vector3 partscale = part.Scale; | ||
606 | Vector3 partoffset = part.OffsetPosition; | ||
607 | |||
608 | minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X; | ||
609 | minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y; | ||
610 | minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z; | ||
611 | |||
612 | maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; | ||
613 | maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; | ||
614 | maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; | ||
615 | } | ||
616 | |||
617 | finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; | ||
618 | finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; | ||
619 | finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; | ||
620 | return finalScale; | ||
621 | |||
622 | } | ||
623 | public EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly, bool faceCenters) | 627 | public EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly, bool faceCenters) |
624 | { | 628 | { |
625 | // We got a request from the inner_scene to raytrace along the Ray hRay | 629 | // We got a request from the inner_scene to raytrace along the Ray hRay |
@@ -1141,6 +1145,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
1141 | 1145 | ||
1142 | public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient) | 1146 | public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient) |
1143 | { | 1147 | { |
1148 | // m_log.DebugFormat( | ||
1149 | // "[SCENE OBJECT GROUP]: Processing OnGrabPart for {0} on {1} {2}, offsetPos {3}", | ||
1150 | // remoteClient.Name, part.Name, part.LocalId, offsetPos); | ||
1151 | |||
1144 | part.StoreUndoState(); | 1152 | part.StoreUndoState(); |
1145 | part.OnGrab(offsetPos, remoteClient); | 1153 | part.OnGrab(offsetPos, remoteClient); |
1146 | } | 1154 | } |
@@ -1463,17 +1471,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1463 | // Need to duplicate the physics actor as well | 1471 | // Need to duplicate the physics actor as well |
1464 | if (part.PhysActor != null && userExposed) | 1472 | if (part.PhysActor != null && userExposed) |
1465 | { | 1473 | { |
1466 | PrimitiveBaseShape pbs = part.Shape; | 1474 | PrimitiveBaseShape pbs = newPart.Shape; |
1467 | 1475 | ||
1468 | newPart.PhysActor | 1476 | newPart.PhysActor |
1469 | = m_scene.PhysicsScene.AddPrimShape( | 1477 | = m_scene.PhysicsScene.AddPrimShape( |
1470 | part.LocalId, | 1478 | string.Format("{0}/{1}", newPart.Name, newPart.UUID), |
1471 | string.Format("{0}/{1}", part.Name, part.UUID), | ||
1472 | pbs, | 1479 | pbs, |
1473 | part.AbsolutePosition, | 1480 | newPart.AbsolutePosition, |
1474 | part.Scale, | 1481 | newPart.Scale, |
1475 | part.RotationOffset, | 1482 | newPart.RotationOffset, |
1476 | part.PhysActor.IsPhysical); | 1483 | part.PhysActor.IsPhysical, |
1484 | newPart.LocalId); | ||
1477 | 1485 | ||
1478 | newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true); | 1486 | newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true); |
1479 | } | 1487 | } |
@@ -2608,195 +2616,150 @@ namespace OpenSim.Region.Framework.Scenes | |||
2608 | #region Resize | 2616 | #region Resize |
2609 | 2617 | ||
2610 | /// <summary> | 2618 | /// <summary> |
2611 | /// Resize the given part | 2619 | /// Resize the entire group of prims. |
2612 | /// </summary> | 2620 | /// </summary> |
2613 | /// <param name="scale"></param> | 2621 | /// <param name="scale"></param> |
2614 | /// <param name="localID"></param> | 2622 | public void GroupResize(Vector3 scale) |
2615 | public void Resize(Vector3 scale, uint localID) | ||
2616 | { | 2623 | { |
2617 | if (scale.X > m_scene.m_maxNonphys) | 2624 | // m_log.DebugFormat( |
2618 | scale.X = m_scene.m_maxNonphys; | 2625 | // "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale); |
2619 | if (scale.Y > m_scene.m_maxNonphys) | ||
2620 | scale.Y = m_scene.m_maxNonphys; | ||
2621 | if (scale.Z > m_scene.m_maxNonphys) | ||
2622 | scale.Z = m_scene.m_maxNonphys; | ||
2623 | 2626 | ||
2624 | SceneObjectPart part = GetChildPart(localID); | 2627 | RootPart.StoreUndoState(true); |
2625 | if (part != null) | ||
2626 | { | ||
2627 | part.Resize(scale); | ||
2628 | if (part.PhysActor != null) | ||
2629 | { | ||
2630 | if (part.PhysActor.IsPhysical) | ||
2631 | { | ||
2632 | if (scale.X > m_scene.m_maxPhys) | ||
2633 | scale.X = m_scene.m_maxPhys; | ||
2634 | if (scale.Y > m_scene.m_maxPhys) | ||
2635 | scale.Y = m_scene.m_maxPhys; | ||
2636 | if (scale.Z > m_scene.m_maxPhys) | ||
2637 | scale.Z = m_scene.m_maxPhys; | ||
2638 | } | ||
2639 | part.PhysActor.Size = scale; | ||
2640 | m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); | ||
2641 | } | ||
2642 | //if (part.UUID != m_rootPart.UUID) | ||
2643 | 2628 | ||
2644 | HasGroupChanged = true; | 2629 | scale.X = Math.Min(scale.X, Scene.m_maxNonphys); |
2645 | part.TriggerScriptChangedEvent(Changed.SCALE); | 2630 | scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); |
2646 | ScheduleGroupForFullUpdate(); | 2631 | scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys); |
2647 | 2632 | ||
2648 | //if (part.UUID == m_rootPart.UUID) | 2633 | if (RootPart.PhysActor != null && RootPart.PhysActor.IsPhysical) |
2649 | //{ | 2634 | { |
2650 | //if (m_rootPart.PhysActor != null) | 2635 | scale.X = Math.Min(scale.X, Scene.m_maxPhys); |
2651 | //{ | 2636 | scale.Y = Math.Min(scale.Y, Scene.m_maxPhys); |
2652 | //m_rootPart.PhysActor.Size = | 2637 | scale.Z = Math.Min(scale.Z, Scene.m_maxPhys); |
2653 | //new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z); | ||
2654 | //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); | ||
2655 | //} | ||
2656 | //} | ||
2657 | } | 2638 | } |
2658 | } | ||
2659 | 2639 | ||
2660 | public void GroupResize(Vector3 scale, uint localID) | 2640 | float x = (scale.X / RootPart.Scale.X); |
2661 | { | 2641 | float y = (scale.Y / RootPart.Scale.Y); |
2662 | SceneObjectPart part = GetChildPart(localID); | 2642 | float z = (scale.Z / RootPart.Scale.Z); |
2663 | if (part != null) | ||
2664 | { | ||
2665 | part.IgnoreUndoUpdate = true; | ||
2666 | if (scale.X > m_scene.m_maxNonphys) | ||
2667 | scale.X = m_scene.m_maxNonphys; | ||
2668 | if (scale.Y > m_scene.m_maxNonphys) | ||
2669 | scale.Y = m_scene.m_maxNonphys; | ||
2670 | if (scale.Z > m_scene.m_maxNonphys) | ||
2671 | scale.Z = m_scene.m_maxNonphys; | ||
2672 | if (part.PhysActor != null && part.PhysActor.IsPhysical) | ||
2673 | { | ||
2674 | if (scale.X > m_scene.m_maxPhys) | ||
2675 | scale.X = m_scene.m_maxPhys; | ||
2676 | if (scale.Y > m_scene.m_maxPhys) | ||
2677 | scale.Y = m_scene.m_maxPhys; | ||
2678 | if (scale.Z > m_scene.m_maxPhys) | ||
2679 | scale.Z = m_scene.m_maxPhys; | ||
2680 | } | ||
2681 | float x = (scale.X / part.Scale.X); | ||
2682 | float y = (scale.Y / part.Scale.Y); | ||
2683 | float z = (scale.Z / part.Scale.Z); | ||
2684 | 2643 | ||
2685 | SceneObjectPart[] parts; | 2644 | SceneObjectPart[] parts; |
2686 | if (x > 1.0f || y > 1.0f || z > 1.0f) | 2645 | if (x > 1.0f || y > 1.0f || z > 1.0f) |
2646 | { | ||
2647 | parts = m_parts.GetArray(); | ||
2648 | for (int i = 0; i < parts.Length; i++) | ||
2687 | { | 2649 | { |
2688 | parts = m_parts.GetArray(); | 2650 | SceneObjectPart obPart = parts[i]; |
2689 | for (int i = 0; i < parts.Length; i++) | 2651 | if (obPart.UUID != m_rootPart.UUID) |
2690 | { | 2652 | { |
2691 | SceneObjectPart obPart = parts[i]; | 2653 | // obPart.IgnoreUndoUpdate = true; |
2692 | if (obPart.UUID != m_rootPart.UUID) | 2654 | Vector3 oldSize = new Vector3(obPart.Scale); |
2655 | |||
2656 | float f = 1.0f; | ||
2657 | float a = 1.0f; | ||
2658 | |||
2659 | if (RootPart.PhysActor != null && RootPart.PhysActor.IsPhysical) | ||
2693 | { | 2660 | { |
2694 | obPart.IgnoreUndoUpdate = true; | 2661 | if (oldSize.X * x > m_scene.m_maxPhys) |
2695 | Vector3 oldSize = new Vector3(obPart.Scale); | 2662 | { |
2663 | f = m_scene.m_maxPhys / oldSize.X; | ||
2664 | a = f / x; | ||
2665 | x *= a; | ||
2666 | y *= a; | ||
2667 | z *= a; | ||
2668 | } | ||
2696 | 2669 | ||
2697 | float f = 1.0f; | 2670 | if (oldSize.Y * y > m_scene.m_maxPhys) |
2698 | float a = 1.0f; | 2671 | { |
2672 | f = m_scene.m_maxPhys / oldSize.Y; | ||
2673 | a = f / y; | ||
2674 | x *= a; | ||
2675 | y *= a; | ||
2676 | z *= a; | ||
2677 | } | ||
2699 | 2678 | ||
2700 | if (part.PhysActor != null && part.PhysActor.IsPhysical) | 2679 | if (oldSize.Z * z > m_scene.m_maxPhys) |
2701 | { | 2680 | { |
2702 | if (oldSize.X * x > m_scene.m_maxPhys) | 2681 | f = m_scene.m_maxPhys / oldSize.Z; |
2703 | { | 2682 | a = f / z; |
2704 | f = m_scene.m_maxPhys / oldSize.X; | 2683 | x *= a; |
2705 | a = f / x; | 2684 | y *= a; |
2706 | x *= a; | 2685 | z *= a; |
2707 | y *= a; | 2686 | } |
2708 | z *= a; | 2687 | } |
2709 | } | 2688 | else |
2710 | if (oldSize.Y * y > m_scene.m_maxPhys) | 2689 | { |
2711 | { | 2690 | if (oldSize.X * x > m_scene.m_maxNonphys) |
2712 | f = m_scene.m_maxPhys / oldSize.Y; | 2691 | { |
2713 | a = f / y; | 2692 | f = m_scene.m_maxNonphys / oldSize.X; |
2714 | x *= a; | 2693 | a = f / x; |
2715 | y *= a; | 2694 | x *= a; |
2716 | z *= a; | 2695 | y *= a; |
2717 | } | 2696 | z *= a; |
2718 | if (oldSize.Z * z > m_scene.m_maxPhys) | ||
2719 | { | ||
2720 | f = m_scene.m_maxPhys / oldSize.Z; | ||
2721 | a = f / z; | ||
2722 | x *= a; | ||
2723 | y *= a; | ||
2724 | z *= a; | ||
2725 | } | ||
2726 | } | 2697 | } |
2727 | else | 2698 | |
2699 | if (oldSize.Y * y > m_scene.m_maxNonphys) | ||
2728 | { | 2700 | { |
2729 | if (oldSize.X * x > m_scene.m_maxNonphys) | 2701 | f = m_scene.m_maxNonphys / oldSize.Y; |
2730 | { | 2702 | a = f / y; |
2731 | f = m_scene.m_maxNonphys / oldSize.X; | 2703 | x *= a; |
2732 | a = f / x; | 2704 | y *= a; |
2733 | x *= a; | 2705 | z *= a; |
2734 | y *= a; | 2706 | } |
2735 | z *= a; | 2707 | |
2736 | } | 2708 | if (oldSize.Z * z > m_scene.m_maxNonphys) |
2737 | if (oldSize.Y * y > m_scene.m_maxNonphys) | 2709 | { |
2738 | { | 2710 | f = m_scene.m_maxNonphys / oldSize.Z; |
2739 | f = m_scene.m_maxNonphys / oldSize.Y; | 2711 | a = f / z; |
2740 | a = f / y; | 2712 | x *= a; |
2741 | x *= a; | 2713 | y *= a; |
2742 | y *= a; | 2714 | z *= a; |
2743 | z *= a; | ||
2744 | } | ||
2745 | if (oldSize.Z * z > m_scene.m_maxNonphys) | ||
2746 | { | ||
2747 | f = m_scene.m_maxNonphys / oldSize.Z; | ||
2748 | a = f / z; | ||
2749 | x *= a; | ||
2750 | y *= a; | ||
2751 | z *= a; | ||
2752 | } | ||
2753 | } | 2715 | } |
2754 | obPart.IgnoreUndoUpdate = false; | ||
2755 | obPart.StoreUndoState(); | ||
2756 | } | 2716 | } |
2717 | |||
2718 | // obPart.IgnoreUndoUpdate = false; | ||
2757 | } | 2719 | } |
2758 | } | 2720 | } |
2721 | } | ||
2759 | 2722 | ||
2760 | Vector3 prevScale = part.Scale; | 2723 | Vector3 prevScale = RootPart.Scale; |
2761 | prevScale.X *= x; | 2724 | prevScale.X *= x; |
2762 | prevScale.Y *= y; | 2725 | prevScale.Y *= y; |
2763 | prevScale.Z *= z; | 2726 | prevScale.Z *= z; |
2764 | part.Resize(prevScale); | ||
2765 | 2727 | ||
2766 | parts = m_parts.GetArray(); | 2728 | // RootPart.IgnoreUndoUpdate = true; |
2767 | for (int i = 0; i < parts.Length; i++) | 2729 | RootPart.Resize(prevScale); |
2730 | // RootPart.IgnoreUndoUpdate = false; | ||
2731 | |||
2732 | parts = m_parts.GetArray(); | ||
2733 | for (int i = 0; i < parts.Length; i++) | ||
2734 | { | ||
2735 | SceneObjectPart obPart = parts[i]; | ||
2736 | |||
2737 | if (obPart.UUID != m_rootPart.UUID) | ||
2768 | { | 2738 | { |
2769 | SceneObjectPart obPart = parts[i]; | ||
2770 | obPart.IgnoreUndoUpdate = true; | 2739 | obPart.IgnoreUndoUpdate = true; |
2771 | if (obPart.UUID != m_rootPart.UUID) | ||
2772 | { | ||
2773 | Vector3 currentpos = new Vector3(obPart.OffsetPosition); | ||
2774 | currentpos.X *= x; | ||
2775 | currentpos.Y *= y; | ||
2776 | currentpos.Z *= z; | ||
2777 | Vector3 newSize = new Vector3(obPart.Scale); | ||
2778 | newSize.X *= x; | ||
2779 | newSize.Y *= y; | ||
2780 | newSize.Z *= z; | ||
2781 | obPart.Resize(newSize); | ||
2782 | obPart.UpdateOffSet(currentpos); | ||
2783 | } | ||
2784 | obPart.IgnoreUndoUpdate = false; | ||
2785 | obPart.StoreUndoState(); | ||
2786 | } | ||
2787 | 2740 | ||
2788 | if (part.PhysActor != null) | 2741 | Vector3 currentpos = new Vector3(obPart.OffsetPosition); |
2789 | { | 2742 | currentpos.X *= x; |
2790 | part.PhysActor.Size = prevScale; | 2743 | currentpos.Y *= y; |
2791 | m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); | 2744 | currentpos.Z *= z; |
2745 | |||
2746 | Vector3 newSize = new Vector3(obPart.Scale); | ||
2747 | newSize.X *= x; | ||
2748 | newSize.Y *= y; | ||
2749 | newSize.Z *= z; | ||
2750 | |||
2751 | obPart.Resize(newSize); | ||
2752 | obPart.UpdateOffSet(currentpos); | ||
2753 | |||
2754 | obPart.IgnoreUndoUpdate = false; | ||
2792 | } | 2755 | } |
2793 | 2756 | ||
2794 | part.IgnoreUndoUpdate = false; | 2757 | // obPart.IgnoreUndoUpdate = false; |
2795 | part.StoreUndoState(); | 2758 | // obPart.StoreUndoState(); |
2796 | HasGroupChanged = true; | ||
2797 | m_rootPart.TriggerScriptChangedEvent(Changed.SCALE); | ||
2798 | ScheduleGroupForTerseUpdate(); | ||
2799 | } | 2759 | } |
2760 | |||
2761 | // m_log.DebugFormat( | ||
2762 | // "[SCENE OBJECT GROUP]: Finished group resizing {0} {1} to {2}", Name, LocalId, RootPart.Scale); | ||
2800 | } | 2763 | } |
2801 | 2764 | ||
2802 | #endregion | 2765 | #endregion |
@@ -2809,9 +2772,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2809 | /// <param name="pos"></param> | 2772 | /// <param name="pos"></param> |
2810 | public void UpdateGroupPosition(Vector3 pos) | 2773 | public void UpdateGroupPosition(Vector3 pos) |
2811 | { | 2774 | { |
2812 | SceneObjectPart[] parts = m_parts.GetArray(); | 2775 | // m_log.DebugFormat("[SCENE OBJECT GROUP]: Updating group position on {0} {1} to {2}", Name, LocalId, pos); |
2813 | for (int i = 0; i < parts.Length; i++) | 2776 | |
2814 | parts[i].StoreUndoState(); | 2777 | RootPart.StoreUndoState(true); |
2778 | |||
2779 | // SceneObjectPart[] parts = m_parts.GetArray(); | ||
2780 | // for (int i = 0; i < parts.Length; i++) | ||
2781 | // parts[i].StoreUndoState(); | ||
2815 | 2782 | ||
2816 | if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) | 2783 | if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) |
2817 | { | 2784 | { |
@@ -2848,12 +2815,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
2848 | { | 2815 | { |
2849 | SceneObjectPart part = GetChildPart(localID); | 2816 | SceneObjectPart part = GetChildPart(localID); |
2850 | 2817 | ||
2851 | SceneObjectPart[] parts = m_parts.GetArray(); | 2818 | // SceneObjectPart[] parts = m_parts.GetArray(); |
2852 | for (int i = 0; i < parts.Length; i++) | 2819 | // for (int i = 0; i < parts.Length; i++) |
2853 | parts[i].StoreUndoState(); | 2820 | // parts[i].StoreUndoState(); |
2854 | 2821 | ||
2855 | if (part != null) | 2822 | if (part != null) |
2856 | { | 2823 | { |
2824 | // m_log.DebugFormat( | ||
2825 | // "[SCENE OBJECT GROUP]: Updating single position of {0} {1} to {2}", part.Name, part.LocalId, pos); | ||
2826 | |||
2827 | part.StoreUndoState(false); | ||
2828 | part.IgnoreUndoUpdate = true; | ||
2829 | |||
2857 | if (part.UUID == m_rootPart.UUID) | 2830 | if (part.UUID == m_rootPart.UUID) |
2858 | { | 2831 | { |
2859 | UpdateRootPosition(pos); | 2832 | UpdateRootPosition(pos); |
@@ -2864,18 +2837,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
2864 | } | 2837 | } |
2865 | 2838 | ||
2866 | HasGroupChanged = true; | 2839 | HasGroupChanged = true; |
2840 | part.IgnoreUndoUpdate = false; | ||
2867 | } | 2841 | } |
2868 | } | 2842 | } |
2869 | 2843 | ||
2870 | /// <summary> | 2844 | /// <summary> |
2871 | /// | 2845 | /// Update just the root prim position in a linkset |
2872 | /// </summary> | 2846 | /// </summary> |
2873 | /// <param name="pos"></param> | 2847 | /// <param name="pos"></param> |
2874 | private void UpdateRootPosition(Vector3 pos) | 2848 | public void UpdateRootPosition(Vector3 pos) |
2875 | { | 2849 | { |
2876 | SceneObjectPart[] parts = m_parts.GetArray(); | 2850 | // m_log.DebugFormat( |
2877 | for (int i = 0; i < parts.Length; i++) | 2851 | // "[SCENE OBJECT GROUP]: Updating root position of {0} {1} to {2}", Name, LocalId, pos); |
2878 | parts[i].StoreUndoState(); | 2852 | |
2853 | // SceneObjectPart[] parts = m_parts.GetArray(); | ||
2854 | // for (int i = 0; i < parts.Length; i++) | ||
2855 | // parts[i].StoreUndoState(); | ||
2879 | 2856 | ||
2880 | Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); | 2857 | Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); |
2881 | Vector3 oldPos = | 2858 | Vector3 oldPos = |
@@ -2888,7 +2865,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2888 | axDiff *= Quaternion.Inverse(partRotation); | 2865 | axDiff *= Quaternion.Inverse(partRotation); |
2889 | diff = axDiff; | 2866 | diff = axDiff; |
2890 | 2867 | ||
2891 | parts = m_parts.GetArray(); | 2868 | SceneObjectPart[] parts = m_parts.GetArray(); |
2892 | for (int i = 0; i < parts.Length; i++) | 2869 | for (int i = 0; i < parts.Length; i++) |
2893 | { | 2870 | { |
2894 | SceneObjectPart obPart = parts[i]; | 2871 | SceneObjectPart obPart = parts[i]; |
@@ -2917,9 +2894,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
2917 | /// <param name="rot"></param> | 2894 | /// <param name="rot"></param> |
2918 | public void UpdateGroupRotationR(Quaternion rot) | 2895 | public void UpdateGroupRotationR(Quaternion rot) |
2919 | { | 2896 | { |
2920 | SceneObjectPart[] parts = m_parts.GetArray(); | 2897 | // m_log.DebugFormat( |
2921 | for (int i = 0; i < parts.Length; i++) | 2898 | // "[SCENE OBJECT GROUP]: Updating group rotation R of {0} {1} to {2}", Name, LocalId, rot); |
2922 | parts[i].StoreUndoState(); | 2899 | |
2900 | // SceneObjectPart[] parts = m_parts.GetArray(); | ||
2901 | // for (int i = 0; i < parts.Length; i++) | ||
2902 | // parts[i].StoreUndoState(); | ||
2903 | |||
2904 | m_rootPart.StoreUndoState(true); | ||
2923 | 2905 | ||
2924 | m_rootPart.UpdateRotation(rot); | 2906 | m_rootPart.UpdateRotation(rot); |
2925 | 2907 | ||
@@ -2941,9 +2923,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2941 | /// <param name="rot"></param> | 2923 | /// <param name="rot"></param> |
2942 | public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) | 2924 | public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) |
2943 | { | 2925 | { |
2944 | SceneObjectPart[] parts = m_parts.GetArray(); | 2926 | // m_log.DebugFormat( |
2945 | for (int i = 0; i < parts.Length; i++) | 2927 | // "[SCENE OBJECT GROUP]: Updating group rotation PR of {0} {1} to {2}", Name, LocalId, rot); |
2946 | parts[i].StoreUndoState(); | 2928 | |
2929 | // SceneObjectPart[] parts = m_parts.GetArray(); | ||
2930 | // for (int i = 0; i < parts.Length; i++) | ||
2931 | // parts[i].StoreUndoState(); | ||
2932 | |||
2933 | RootPart.StoreUndoState(true); | ||
2934 | RootPart.IgnoreUndoUpdate = true; | ||
2947 | 2935 | ||
2948 | m_rootPart.UpdateRotation(rot); | 2936 | m_rootPart.UpdateRotation(rot); |
2949 | 2937 | ||
@@ -2958,6 +2946,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2958 | 2946 | ||
2959 | HasGroupChanged = true; | 2947 | HasGroupChanged = true; |
2960 | ScheduleGroupForTerseUpdate(); | 2948 | ScheduleGroupForTerseUpdate(); |
2949 | |||
2950 | RootPart.IgnoreUndoUpdate = false; | ||
2961 | } | 2951 | } |
2962 | 2952 | ||
2963 | /// <summary> | 2953 | /// <summary> |
@@ -2975,6 +2965,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2975 | 2965 | ||
2976 | if (part != null) | 2966 | if (part != null) |
2977 | { | 2967 | { |
2968 | // m_log.DebugFormat( | ||
2969 | // "[SCENE OBJECT GROUP]: Updating single rotation of {0} {1} to {2}", part.Name, part.LocalId, rot); | ||
2970 | |||
2978 | if (part.UUID == m_rootPart.UUID) | 2971 | if (part.UUID == m_rootPart.UUID) |
2979 | { | 2972 | { |
2980 | UpdateRootRotation(rot); | 2973 | UpdateRootRotation(rot); |
@@ -2996,6 +2989,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2996 | SceneObjectPart part = GetChildPart(localID); | 2989 | SceneObjectPart part = GetChildPart(localID); |
2997 | if (part != null) | 2990 | if (part != null) |
2998 | { | 2991 | { |
2992 | // m_log.DebugFormat( | ||
2993 | // "[SCENE OBJECT GROUP]: Updating single position and rotation of {0} {1} to {2}", | ||
2994 | // part.Name, part.LocalId, rot); | ||
2995 | |||
2996 | part.StoreUndoState(); | ||
2997 | part.IgnoreUndoUpdate = true; | ||
2998 | |||
2999 | if (part.UUID == m_rootPart.UUID) | 2999 | if (part.UUID == m_rootPart.UUID) |
3000 | { | 3000 | { |
3001 | UpdateRootRotation(rot); | 3001 | UpdateRootRotation(rot); |
@@ -3003,12 +3003,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
3003 | } | 3003 | } |
3004 | else | 3004 | else |
3005 | { | 3005 | { |
3006 | part.IgnoreUndoUpdate = true; | ||
3007 | part.UpdateRotation(rot); | 3006 | part.UpdateRotation(rot); |
3008 | part.OffsetPosition = pos; | 3007 | part.OffsetPosition = pos; |
3009 | part.IgnoreUndoUpdate = false; | ||
3010 | part.StoreUndoState(); | ||
3011 | } | 3008 | } |
3009 | |||
3010 | part.IgnoreUndoUpdate = false; | ||
3012 | } | 3011 | } |
3013 | } | 3012 | } |
3014 | 3013 | ||
@@ -3016,8 +3015,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3016 | /// | 3015 | /// |
3017 | /// </summary> | 3016 | /// </summary> |
3018 | /// <param name="rot"></param> | 3017 | /// <param name="rot"></param> |
3019 | private void UpdateRootRotation(Quaternion rot) | 3018 | public void UpdateRootRotation(Quaternion rot) |
3020 | { | 3019 | { |
3020 | // m_log.DebugFormat( | ||
3021 | // "[SCENE OBJECT GROUP]: Updating root rotation of {0} {1} to {2}", | ||
3022 | // Name, LocalId, rot); | ||
3023 | |||
3021 | Quaternion axRot = rot; | 3024 | Quaternion axRot = rot; |
3022 | Quaternion oldParentRot = m_rootPart.RotationOffset; | 3025 | Quaternion oldParentRot = m_rootPart.RotationOffset; |
3023 | 3026 | ||
@@ -3045,20 +3048,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
3045 | newRot *= Quaternion.Inverse(axRot); | 3048 | newRot *= Quaternion.Inverse(axRot); |
3046 | prim.RotationOffset = newRot; | 3049 | prim.RotationOffset = newRot; |
3047 | prim.ScheduleTerseUpdate(); | 3050 | prim.ScheduleTerseUpdate(); |
3051 | prim.IgnoreUndoUpdate = false; | ||
3048 | } | 3052 | } |
3049 | } | 3053 | } |
3050 | 3054 | ||
3051 | for (int i = 0; i < parts.Length; i++) | 3055 | // for (int i = 0; i < parts.Length; i++) |
3052 | { | 3056 | // { |
3053 | SceneObjectPart childpart = parts[i]; | 3057 | // SceneObjectPart childpart = parts[i]; |
3054 | if (childpart != m_rootPart) | 3058 | // if (childpart != m_rootPart) |
3055 | { | 3059 | // { |
3056 | childpart.IgnoreUndoUpdate = false; | 3060 | //// childpart.IgnoreUndoUpdate = false; |
3057 | childpart.StoreUndoState(); | 3061 | //// childpart.StoreUndoState(); |
3058 | } | 3062 | // } |
3059 | } | 3063 | // } |
3060 | 3064 | ||
3061 | m_rootPart.ScheduleTerseUpdate(); | 3065 | m_rootPart.ScheduleTerseUpdate(); |
3066 | |||
3067 | // m_log.DebugFormat( | ||
3068 | // "[SCENE OBJECT GROUP]: Updated root rotation of {0} {1} to {2}", | ||
3069 | // Name, LocalId, rot); | ||
3062 | } | 3070 | } |
3063 | 3071 | ||
3064 | #endregion | 3072 | #endregion |
@@ -3313,23 +3321,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3313 | } | 3321 | } |
3314 | 3322 | ||
3315 | /// <summary> | 3323 | /// <summary> |
3316 | /// Handle an asset received asynchronously from the asset service. | ||
3317 | /// </summary> | ||
3318 | /// <param name="id"></param> | ||
3319 | /// <param name="sender"></param> | ||
3320 | /// <param name="asset"></param> | ||
3321 | protected void AssetReceived(string id, Object sender, AssetBase asset) | ||
3322 | { | ||
3323 | SceneObjectPart sop = (SceneObjectPart)sender; | ||
3324 | |||
3325 | if (sop != null) | ||
3326 | { | ||
3327 | if (asset != null) | ||
3328 | sop.SculptTextureCallback(asset.FullID, asset); | ||
3329 | } | ||
3330 | } | ||
3331 | |||
3332 | /// <summary> | ||
3333 | /// Set the user group to which this scene object belongs. | 3324 | /// Set the user group to which this scene object belongs. |
3334 | /// </summary> | 3325 | /// </summary> |
3335 | /// <param name="GroupID"></param> | 3326 | /// <param name="GroupID"></param> |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 2026c53..4629757 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -287,8 +287,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
287 | private string m_sitAnimation = "SIT"; | 287 | private string m_sitAnimation = "SIT"; |
288 | private string m_text = String.Empty; | 288 | private string m_text = String.Empty; |
289 | private string m_touchName = String.Empty; | 289 | private string m_touchName = String.Empty; |
290 | private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5); | 290 | private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5); |
291 | private readonly UndoStack<UndoState> m_redo = new UndoStack<UndoState>(5); | 291 | private readonly Stack<UndoState> m_redo = new Stack<UndoState>(5); |
292 | private UUID _creatorID; | 292 | private UUID _creatorID; |
293 | 293 | ||
294 | private bool m_passTouches; | 294 | private bool m_passTouches; |
@@ -414,7 +414,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
414 | CreateSelected = true; | 414 | CreateSelected = true; |
415 | 415 | ||
416 | TrimPermissions(); | 416 | TrimPermissions(); |
417 | //m_undo = new UndoStack<UndoState>(ParentGroup.GetSceneMaxUndo()); | ||
418 | 417 | ||
419 | m_inventory = new SceneObjectPartInventory(this); | 418 | m_inventory = new SceneObjectPartInventory(this); |
420 | } | 419 | } |
@@ -789,7 +788,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
789 | get { return m_offsetPosition; } | 788 | get { return m_offsetPosition; } |
790 | set | 789 | set |
791 | { | 790 | { |
792 | StoreUndoState(); | 791 | // StoreUndoState(); |
793 | m_offsetPosition = value; | 792 | m_offsetPosition = value; |
794 | 793 | ||
795 | if (ParentGroup != null && !ParentGroup.IsDeleted) | 794 | if (ParentGroup != null && !ParentGroup.IsDeleted) |
@@ -1015,15 +1014,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
1015 | get { return m_shape; } | 1014 | get { return m_shape; } |
1016 | set { m_shape = value; } | 1015 | set { m_shape = value; } |
1017 | } | 1016 | } |
1018 | 1017 | ||
1018 | /// <summary> | ||
1019 | /// Change the scale of this part. | ||
1020 | /// </summary> | ||
1019 | public Vector3 Scale | 1021 | public Vector3 Scale |
1020 | { | 1022 | { |
1021 | get { return m_shape.Scale; } | 1023 | get { return m_shape.Scale; } |
1022 | set | 1024 | set |
1023 | { | 1025 | { |
1024 | StoreUndoState(); | ||
1025 | if (m_shape != null) | 1026 | if (m_shape != null) |
1026 | { | 1027 | { |
1028 | StoreUndoState(); | ||
1029 | |||
1027 | m_shape.Scale = value; | 1030 | m_shape.Scale = value; |
1028 | 1031 | ||
1029 | PhysicsActor actor = PhysActor; | 1032 | PhysicsActor actor = PhysActor; |
@@ -1034,11 +1037,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
1034 | if (m_parentGroup.Scene.PhysicsScene != null) | 1037 | if (m_parentGroup.Scene.PhysicsScene != null) |
1035 | { | 1038 | { |
1036 | actor.Size = m_shape.Scale; | 1039 | actor.Size = m_shape.Scale; |
1037 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); | 1040 | |
1041 | if (((OpenMetaverse.SculptType)Shape.SculptType) == SculptType.Mesh) | ||
1042 | CheckSculptAndLoad(); | ||
1043 | else | ||
1044 | ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | ||
1038 | } | 1045 | } |
1039 | } | 1046 | } |
1040 | } | 1047 | } |
1041 | } | 1048 | } |
1049 | |||
1042 | TriggerScriptChangedEvent(Changed.SCALE); | 1050 | TriggerScriptChangedEvent(Changed.SCALE); |
1043 | } | 1051 | } |
1044 | } | 1052 | } |
@@ -1588,17 +1596,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
1588 | // or flexible | 1596 | // or flexible |
1589 | if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible)) | 1597 | if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible)) |
1590 | { | 1598 | { |
1591 | // m_log.DebugFormat("[SCENE OBJECT PART]: Creating PhysActor for {0} {1} {2}", Name, LocalId, UUID); | 1599 | try |
1592 | 1600 | { | |
1593 | PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( | 1601 | PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( |
1594 | LocalId, | 1602 | string.Format("{0}/{1}", Name, UUID), |
1595 | string.Format("{0}/{1}", Name, UUID), | 1603 | Shape, |
1596 | Shape, | 1604 | AbsolutePosition, |
1597 | AbsolutePosition, | 1605 | Scale, |
1598 | Scale, | 1606 | RotationOffset, |
1599 | RotationOffset, | 1607 | RigidBody, |
1600 | RigidBody); | 1608 | m_localId); |
1601 | 1609 | PhysActor.SetMaterial(Material); | |
1610 | } | ||
1611 | catch | ||
1612 | { | ||
1613 | m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid); | ||
1614 | PhysActor = null; | ||
1615 | } | ||
1602 | // Basic Physics returns null.. joy joy joy. | 1616 | // Basic Physics returns null.. joy joy joy. |
1603 | if (PhysActor != null) | 1617 | if (PhysActor != null) |
1604 | { | 1618 | { |
@@ -1615,19 +1629,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1615 | } | 1629 | } |
1616 | } | 1630 | } |
1617 | 1631 | ||
1618 | public void ClearUndoState() | ||
1619 | { | ||
1620 | lock (m_undo) | ||
1621 | { | ||
1622 | m_undo.Clear(); | ||
1623 | } | ||
1624 | lock (m_redo) | ||
1625 | { | ||
1626 | m_redo.Clear(); | ||
1627 | } | ||
1628 | StoreUndoState(); | ||
1629 | } | ||
1630 | |||
1631 | public byte ConvertScriptUintToByte(uint indata) | 1632 | public byte ConvertScriptUintToByte(uint indata) |
1632 | { | 1633 | { |
1633 | byte outdata = (byte)TextureAnimFlags.NONE; | 1634 | byte outdata = (byte)TextureAnimFlags.NONE; |
@@ -1705,7 +1706,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1705 | { | 1706 | { |
1706 | if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero) | 1707 | if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero) |
1707 | { | 1708 | { |
1708 | m_parentGroup.Scene.AssetService.Get(dupe.m_shape.SculptTexture.ToString(), dupe, AssetReceived); | 1709 | ParentGroup.Scene.AssetService.Get( |
1710 | dupe.m_shape.SculptTexture.ToString(), dupe, dupe.AssetReceived); | ||
1709 | } | 1711 | } |
1710 | 1712 | ||
1711 | bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); | 1713 | bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); |
@@ -1719,14 +1721,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
1719 | return dupe; | 1721 | return dupe; |
1720 | } | 1722 | } |
1721 | 1723 | ||
1724 | /// <summary> | ||
1725 | /// Called back by asynchronous asset fetch. | ||
1726 | /// </summary> | ||
1727 | /// <param name="id">ID of asset received</param> | ||
1728 | /// <param name="sender">Register</param> | ||
1729 | /// <param name="asset"></param> | ||
1722 | protected void AssetReceived(string id, Object sender, AssetBase asset) | 1730 | protected void AssetReceived(string id, Object sender, AssetBase asset) |
1723 | { | 1731 | { |
1724 | if (asset != null) | 1732 | if (asset != null) |
1725 | { | 1733 | SculptTextureCallback(asset); |
1726 | SceneObjectPart sop = (SceneObjectPart)sender; | 1734 | else |
1727 | if (sop != null) | 1735 | m_log.WarnFormat( |
1728 | sop.SculptTextureCallback(asset.FullID, asset); | 1736 | "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data", |
1729 | } | 1737 | Name, LocalId, id); |
1730 | } | 1738 | } |
1731 | 1739 | ||
1732 | public static SceneObjectPart Create() | 1740 | public static SceneObjectPart Create() |
@@ -1896,7 +1904,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1896 | } | 1904 | } |
1897 | } | 1905 | } |
1898 | 1906 | ||
1899 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | 1907 | // If this part is a sculpt then delay the physics update until we've asynchronously loaded the |
1908 | // mesh data. | ||
1909 | if (((OpenMetaverse.SculptType)Shape.SculptType) == SculptType.Mesh) | ||
1910 | CheckSculptAndLoad(); | ||
1911 | else | ||
1912 | m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); | ||
1900 | } | 1913 | } |
1901 | } | 1914 | } |
1902 | } | 1915 | } |
@@ -2823,19 +2836,29 @@ namespace OpenSim.Region.Framework.Scenes | |||
2823 | } | 2836 | } |
2824 | 2837 | ||
2825 | /// <summary> | 2838 | /// <summary> |
2826 | /// Resize this part. | 2839 | /// Set the scale of this part. |
2827 | /// </summary> | 2840 | /// </summary> |
2841 | /// <remarks> | ||
2842 | /// Unlike the scale property, this checks the new size against scene limits and schedules a full property | ||
2843 | /// update to viewers. | ||
2844 | /// </remarks> | ||
2828 | /// <param name="scale"></param> | 2845 | /// <param name="scale"></param> |
2829 | public void Resize(Vector3 scale) | 2846 | public void Resize(Vector3 scale) |
2830 | { | 2847 | { |
2831 | StoreUndoState(); | 2848 | scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxNonphys); |
2832 | m_shape.Scale = scale; | 2849 | scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys); |
2850 | scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys); | ||
2833 | 2851 | ||
2834 | // If we're a mesh/sculpt, then we need to tell the physics engine about our new size. To do this, we | 2852 | if (PhysActor != null && PhysActor.IsPhysical) |
2835 | // need to reinsert the sculpt data into the shape, since the physics engine deletes it when done to | 2853 | { |
2836 | // save memory | 2854 | scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys); |
2837 | if (PhysActor != null) | 2855 | scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys); |
2838 | CheckSculptAndLoad(); | 2856 | scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys); |
2857 | } | ||
2858 | |||
2859 | // m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); | ||
2860 | |||
2861 | Scale = scale; | ||
2839 | 2862 | ||
2840 | ParentGroup.HasGroupChanged = true; | 2863 | ParentGroup.HasGroupChanged = true; |
2841 | ScheduleFullUpdate(); | 2864 | ScheduleFullUpdate(); |
@@ -2965,7 +2988,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2965 | } | 2988 | } |
2966 | } | 2989 | } |
2967 | 2990 | ||
2968 | public void SculptTextureCallback(UUID textureID, AssetBase texture) | 2991 | /// <summary> |
2992 | /// Set sculpt and mesh data, and tell the physics engine to process the change. | ||
2993 | /// </summary> | ||
2994 | /// <param name="texture">The mesh itself.</param> | ||
2995 | public void SculptTextureCallback(AssetBase texture) | ||
2969 | { | 2996 | { |
2970 | if (m_shape.SculptEntry) | 2997 | if (m_shape.SculptEntry) |
2971 | { | 2998 | { |
@@ -2991,16 +3018,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2991 | } | 3018 | } |
2992 | } | 3019 | } |
2993 | 3020 | ||
2994 | // /// <summary> | ||
2995 | // /// | ||
2996 | // /// </summary> | ||
2997 | // /// <param name="remoteClient"></param> | ||
2998 | // public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) | ||
2999 | // { | ||
3000 | // m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags); | ||
3001 | // } | ||
3002 | |||
3003 | |||
3004 | /// <summary> | 3021 | /// <summary> |
3005 | /// Send a full update to the client for the given part | 3022 | /// Send a full update to the client for the given part |
3006 | /// </summary> | 3023 | /// </summary> |
@@ -3648,6 +3665,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
3648 | 3665 | ||
3649 | public void StoreUndoState() | 3666 | public void StoreUndoState() |
3650 | { | 3667 | { |
3668 | StoreUndoState(false); | ||
3669 | } | ||
3670 | |||
3671 | public void StoreUndoState(bool forGroup) | ||
3672 | { | ||
3651 | if (!Undoing) | 3673 | if (!Undoing) |
3652 | { | 3674 | { |
3653 | if (!IgnoreUndoUpdate) | 3675 | if (!IgnoreUndoUpdate) |
@@ -3661,24 +3683,138 @@ namespace OpenSim.Region.Framework.Scenes | |||
3661 | UndoState last = m_undo.Peek(); | 3683 | UndoState last = m_undo.Peek(); |
3662 | if (last != null) | 3684 | if (last != null) |
3663 | { | 3685 | { |
3686 | // TODO: May need to fix for group comparison | ||
3664 | if (last.Compare(this)) | 3687 | if (last.Compare(this)) |
3688 | { | ||
3689 | // m_log.DebugFormat( | ||
3690 | // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}", | ||
3691 | // Name, LocalId, m_undo.Count); | ||
3692 | |||
3665 | return; | 3693 | return; |
3694 | } | ||
3666 | } | 3695 | } |
3667 | } | 3696 | } |
3668 | 3697 | ||
3698 | // m_log.DebugFormat( | ||
3699 | // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}", | ||
3700 | // Name, LocalId, forGroup, m_undo.Count); | ||
3701 | |||
3669 | if (m_parentGroup.GetSceneMaxUndo() > 0) | 3702 | if (m_parentGroup.GetSceneMaxUndo() > 0) |
3670 | { | 3703 | { |
3671 | UndoState nUndo = new UndoState(this); | 3704 | UndoState nUndo = new UndoState(this, forGroup); |
3672 | 3705 | ||
3673 | m_undo.Push(nUndo); | 3706 | m_undo.Push(nUndo); |
3707 | |||
3708 | if (m_redo.Count > 0) | ||
3709 | m_redo.Clear(); | ||
3710 | |||
3711 | // m_log.DebugFormat( | ||
3712 | // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", | ||
3713 | // Name, LocalId, forGroup, m_undo.Count); | ||
3674 | } | 3714 | } |
3715 | } | ||
3716 | } | ||
3717 | } | ||
3718 | // else | ||
3719 | // { | ||
3720 | // m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId); | ||
3721 | // } | ||
3722 | } | ||
3723 | // else | ||
3724 | // { | ||
3725 | // m_log.DebugFormat( | ||
3726 | // "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId); | ||
3727 | // } | ||
3728 | } | ||
3729 | |||
3730 | /// <summary> | ||
3731 | /// Return number of undos on the stack. Here temporarily pending a refactor. | ||
3732 | /// </summary> | ||
3733 | public int UndoCount | ||
3734 | { | ||
3735 | get | ||
3736 | { | ||
3737 | lock (m_undo) | ||
3738 | return m_undo.Count; | ||
3739 | } | ||
3740 | } | ||
3675 | 3741 | ||
3742 | public void Undo() | ||
3743 | { | ||
3744 | lock (m_undo) | ||
3745 | { | ||
3746 | // m_log.DebugFormat( | ||
3747 | // "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}", | ||
3748 | // Name, LocalId, m_undo.Count); | ||
3749 | |||
3750 | if (m_undo.Count > 0) | ||
3751 | { | ||
3752 | UndoState goback = m_undo.Pop(); | ||
3753 | |||
3754 | if (goback != null) | ||
3755 | { | ||
3756 | UndoState nUndo = null; | ||
3757 | |||
3758 | if (m_parentGroup.GetSceneMaxUndo() > 0) | ||
3759 | { | ||
3760 | nUndo = new UndoState(this, goback.ForGroup); | ||
3761 | } | ||
3762 | |||
3763 | goback.PlaybackState(this); | ||
3764 | |||
3765 | if (nUndo != null) | ||
3766 | m_redo.Push(nUndo); | ||
3767 | } | ||
3768 | } | ||
3769 | |||
3770 | // m_log.DebugFormat( | ||
3771 | // "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", | ||
3772 | // Name, LocalId, m_undo.Count); | ||
3773 | } | ||
3774 | } | ||
3775 | |||
3776 | public void Redo() | ||
3777 | { | ||
3778 | lock (m_undo) | ||
3779 | { | ||
3780 | // m_log.DebugFormat( | ||
3781 | // "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}", | ||
3782 | // Name, LocalId, m_redo.Count); | ||
3783 | |||
3784 | if (m_redo.Count > 0) | ||
3785 | { | ||
3786 | UndoState gofwd = m_redo.Pop(); | ||
3787 | |||
3788 | if (gofwd != null) | ||
3789 | { | ||
3790 | if (m_parentGroup.GetSceneMaxUndo() > 0) | ||
3791 | { | ||
3792 | UndoState nUndo = new UndoState(this, gofwd.ForGroup); | ||
3793 | |||
3794 | m_undo.Push(nUndo); | ||
3676 | } | 3795 | } |
3796 | |||
3797 | gofwd.PlayfwdState(this); | ||
3677 | } | 3798 | } |
3799 | |||
3800 | // m_log.DebugFormat( | ||
3801 | // "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", | ||
3802 | // Name, LocalId, m_redo.Count); | ||
3678 | } | 3803 | } |
3679 | } | 3804 | } |
3680 | } | 3805 | } |
3681 | 3806 | ||
3807 | public void ClearUndoState() | ||
3808 | { | ||
3809 | // m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); | ||
3810 | |||
3811 | lock (m_undo) | ||
3812 | { | ||
3813 | m_undo.Clear(); | ||
3814 | m_redo.Clear(); | ||
3815 | } | ||
3816 | } | ||
3817 | |||
3682 | public EntityIntersection TestIntersection(Ray iray, Quaternion parentrot) | 3818 | public EntityIntersection TestIntersection(Ray iray, Quaternion parentrot) |
3683 | { | 3819 | { |
3684 | // In this case we're using a sphere with a radius of the largest dimension of the prim | 3820 | // In this case we're using a sphere with a radius of the largest dimension of the prim |
@@ -4139,44 +4275,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
4139 | _nextOwnerMask &= (uint)PermissionMask.All; | 4275 | _nextOwnerMask &= (uint)PermissionMask.All; |
4140 | } | 4276 | } |
4141 | 4277 | ||
4142 | public void Undo() | ||
4143 | { | ||
4144 | lock (m_undo) | ||
4145 | { | ||
4146 | if (m_undo.Count > 0) | ||
4147 | { | ||
4148 | UndoState nUndo = null; | ||
4149 | if (m_parentGroup.GetSceneMaxUndo() > 0) | ||
4150 | { | ||
4151 | nUndo = new UndoState(this); | ||
4152 | } | ||
4153 | UndoState goback = m_undo.Pop(); | ||
4154 | if (goback != null) | ||
4155 | { | ||
4156 | goback.PlaybackState(this); | ||
4157 | if (nUndo != null) | ||
4158 | m_redo.Push(nUndo); | ||
4159 | } | ||
4160 | } | ||
4161 | } | ||
4162 | } | ||
4163 | |||
4164 | public void Redo() | ||
4165 | { | ||
4166 | lock (m_redo) | ||
4167 | { | ||
4168 | if (m_parentGroup.GetSceneMaxUndo() > 0) | ||
4169 | { | ||
4170 | UndoState nUndo = new UndoState(this); | ||
4171 | |||
4172 | m_undo.Push(nUndo); | ||
4173 | } | ||
4174 | UndoState gofwd = m_redo.Pop(); | ||
4175 | if (gofwd != null) | ||
4176 | gofwd.PlayfwdState(this); | ||
4177 | } | ||
4178 | } | ||
4179 | |||
4180 | public void UpdateExtraParam(ushort type, bool inUse, byte[] data) | 4278 | public void UpdateExtraParam(ushort type, bool inUse, byte[] data) |
4181 | { | 4279 | { |
4182 | m_shape.ReadInUpdateExtraParam(type, inUse, data); | 4280 | m_shape.ReadInUpdateExtraParam(type, inUse, data); |
@@ -4435,13 +4533,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
4435 | { | 4533 | { |
4436 | // It's not phantom anymore. So make sure the physics engine get's knowledge of it | 4534 | // It's not phantom anymore. So make sure the physics engine get's knowledge of it |
4437 | PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( | 4535 | PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( |
4438 | LocalId, | ||
4439 | string.Format("{0}/{1}", Name, UUID), | 4536 | string.Format("{0}/{1}", Name, UUID), |
4440 | Shape, | 4537 | Shape, |
4441 | AbsolutePosition, | 4538 | AbsolutePosition, |
4442 | Scale, | 4539 | Scale, |
4443 | RotationOffset, | 4540 | RotationOffset, |
4444 | UsePhysics); | 4541 | UsePhysics, |
4542 | m_localId); | ||
4543 | PhysActor.SetMaterial(Material); | ||
4445 | 4544 | ||
4446 | pa = PhysActor; | 4545 | pa = PhysActor; |
4447 | if (pa != null) | 4546 | if (pa != null) |
@@ -4600,7 +4699,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4600 | /// </remarks> | 4699 | /// </remarks> |
4601 | public void CheckSculptAndLoad() | 4700 | public void CheckSculptAndLoad() |
4602 | { | 4701 | { |
4603 | // m_log.Debug("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); | 4702 | // m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); |
4604 | 4703 | ||
4605 | if (ParentGroup.IsDeleted) | 4704 | if (ParentGroup.IsDeleted) |
4606 | return; | 4705 | return; |
@@ -4611,9 +4710,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
4611 | if (Shape.SculptEntry && Shape.SculptTexture != UUID.Zero) | 4710 | if (Shape.SculptEntry && Shape.SculptTexture != UUID.Zero) |
4612 | { | 4711 | { |
4613 | // check if a previously decoded sculpt map has been cached | 4712 | // check if a previously decoded sculpt map has been cached |
4713 | // We don't read the file here - the meshmerizer will do that later. | ||
4714 | // TODO: Could we simplify the meshmerizer code by reading and setting the data here? | ||
4614 | if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + Shape.SculptTexture.ToString()))) | 4715 | if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + Shape.SculptTexture.ToString()))) |
4615 | { | 4716 | { |
4616 | SculptTextureCallback(Shape.SculptTexture, null); | 4717 | SculptTextureCallback(null); |
4617 | } | 4718 | } |
4618 | else | 4719 | else |
4619 | { | 4720 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index c18c93a..8fb9fad 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs | |||
@@ -102,7 +102,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
102 | sceneObject.AddPart(part); | 102 | sceneObject.AddPart(part); |
103 | part.LinkNum = linkNum; | 103 | part.LinkNum = linkNum; |
104 | part.TrimPermissions(); | 104 | part.TrimPermissions(); |
105 | part.StoreUndoState(); | ||
106 | reader.Close(); | 105 | reader.Close(); |
107 | sr.Close(); | 106 | sr.Close(); |
108 | } | 107 | } |
@@ -236,15 +235,14 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
236 | if (originalLinkNum != 0) | 235 | if (originalLinkNum != 0) |
237 | part.LinkNum = originalLinkNum; | 236 | part.LinkNum = originalLinkNum; |
238 | 237 | ||
239 | part.StoreUndoState(); | ||
240 | reader.Close(); | 238 | reader.Close(); |
241 | sr.Close(); | 239 | sr.Close(); |
242 | } | 240 | } |
243 | 241 | ||
244 | // Script state may, or may not, exist. Not having any, is NOT | 242 | // Script state may, or may not, exist. Not having any, is NOT |
245 | // ever a problem. | 243 | // ever a problem. |
246 | |||
247 | sceneObject.LoadScriptState(doc); | 244 | sceneObject.LoadScriptState(doc); |
245 | |||
248 | return sceneObject; | 246 | return sceneObject; |
249 | } | 247 | } |
250 | catch (Exception e) | 248 | catch (Exception e) |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs new file mode 100644 index 0000000..c4047ee --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Reflection; | ||
30 | using NUnit.Framework; | ||
31 | using OpenMetaverse; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Framework.Communications; | ||
34 | using OpenSim.Region.Framework.Scenes; | ||
35 | using OpenSim.Tests.Common; | ||
36 | using OpenSim.Tests.Common.Mock; | ||
37 | |||
38 | namespace OpenSim.Region.Framework.Scenes.Tests | ||
39 | { | ||
40 | /// <summary> | ||
41 | /// Basic scene object resize tests | ||
42 | /// </summary> | ||
43 | [TestFixture] | ||
44 | public class SceneObjectResizeTests | ||
45 | { | ||
46 | /// <summary> | ||
47 | /// Test resizing an object | ||
48 | /// </summary> | ||
49 | [Test] | ||
50 | public void TestResizeSceneObject() | ||
51 | { | ||
52 | TestHelper.InMethod(); | ||
53 | // log4net.Config.XmlConfigurator.Configure(); | ||
54 | |||
55 | Scene scene = SceneSetupHelpers.SetupScene(); | ||
56 | SceneObjectGroup g1 = SceneSetupHelpers.AddSceneObject(scene).ParentGroup; | ||
57 | |||
58 | g1.GroupResize(new Vector3(2, 3, 4)); | ||
59 | |||
60 | SceneObjectGroup g1Post = scene.GetSceneObjectGroup(g1.UUID); | ||
61 | |||
62 | Assert.That(g1Post.RootPart.Scale.X, Is.EqualTo(2)); | ||
63 | Assert.That(g1Post.RootPart.Scale.Y, Is.EqualTo(3)); | ||
64 | Assert.That(g1Post.RootPart.Scale.Z, Is.EqualTo(4)); | ||
65 | |||
66 | Assert.That(g1Post.RootPart.UndoCount, Is.EqualTo(1)); | ||
67 | } | ||
68 | |||
69 | /// <summary> | ||
70 | /// Test resizing an individual part in a scene object. | ||
71 | /// </summary> | ||
72 | [Test] | ||
73 | public void TestResizeSceneObjectPart() | ||
74 | { | ||
75 | TestHelper.InMethod(); | ||
76 | //log4net.Config.XmlConfigurator.Configure(); | ||
77 | |||
78 | Scene scene = SceneSetupHelpers.SetupScene(); | ||
79 | |||
80 | SceneObjectGroup g1 = SceneSetupHelpers.CreateSceneObject(2, UUID.Zero); | ||
81 | g1.RootPart.Scale = new Vector3(2, 3, 4); | ||
82 | g1.Parts[1].Scale = new Vector3(5, 6, 7); | ||
83 | |||
84 | scene.AddSceneObject(g1); | ||
85 | |||
86 | SceneObjectGroup g1Post = scene.GetSceneObjectGroup(g1.UUID); | ||
87 | |||
88 | g1Post.Parts[1].Resize(new Vector3(8, 9, 10)); | ||
89 | |||
90 | SceneObjectGroup g1PostPost = scene.GetSceneObjectGroup(g1.UUID); | ||
91 | |||
92 | SceneObjectPart g1RootPart = g1PostPost.RootPart; | ||
93 | SceneObjectPart g1ChildPart = g1PostPost.Parts[1]; | ||
94 | |||
95 | Assert.That(g1RootPart.Scale.X, Is.EqualTo(2)); | ||
96 | Assert.That(g1RootPart.Scale.Y, Is.EqualTo(3)); | ||
97 | Assert.That(g1RootPart.Scale.Z, Is.EqualTo(4)); | ||
98 | |||
99 | Assert.That(g1ChildPart.Scale.X, Is.EqualTo(8)); | ||
100 | Assert.That(g1ChildPart.Scale.Y, Is.EqualTo(9)); | ||
101 | Assert.That(g1ChildPart.Scale.Z, Is.EqualTo(10)); | ||
102 | } | ||
103 | } | ||
104 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 55e407e..393f42d 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs | |||
@@ -25,6 +25,9 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | ||
29 | using System.Reflection; | ||
30 | using log4net; | ||
28 | using OpenMetaverse; | 31 | using OpenMetaverse; |
29 | using OpenSim.Region.Framework.Interfaces; | 32 | using OpenSim.Region.Framework.Interfaces; |
30 | 33 | ||
@@ -32,110 +35,199 @@ namespace OpenSim.Region.Framework.Scenes | |||
32 | { | 35 | { |
33 | public class UndoState | 36 | public class UndoState |
34 | { | 37 | { |
38 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
39 | |||
35 | public Vector3 Position = Vector3.Zero; | 40 | public Vector3 Position = Vector3.Zero; |
36 | public Vector3 Scale = Vector3.Zero; | 41 | public Vector3 Scale = Vector3.Zero; |
37 | public Quaternion Rotation = Quaternion.Identity; | 42 | public Quaternion Rotation = Quaternion.Identity; |
38 | 43 | ||
39 | public UndoState(SceneObjectPart part) | 44 | /// <summary> |
45 | /// Is this undo state for an entire group? | ||
46 | /// </summary> | ||
47 | public bool ForGroup; | ||
48 | |||
49 | /// <summary> | ||
50 | /// Constructor. | ||
51 | /// </summary> | ||
52 | /// <param name="part"></param> | ||
53 | /// <param name="forGroup">True if the undo is for an entire group</param> | ||
54 | public UndoState(SceneObjectPart part, bool forGroup) | ||
40 | { | 55 | { |
41 | if (part != null) | 56 | if (part.ParentID == 0) |
42 | { | 57 | { |
43 | if (part.ParentID == 0) | 58 | ForGroup = forGroup; |
44 | { | 59 | |
60 | // if (ForGroup) | ||
45 | Position = part.ParentGroup.AbsolutePosition; | 61 | Position = part.ParentGroup.AbsolutePosition; |
46 | Rotation = part.RotationOffset; | 62 | // else |
47 | Scale = part.Shape.Scale; | 63 | // Position = part.OffsetPosition; |
48 | } | 64 | |
49 | else | 65 | // m_log.DebugFormat( |
50 | { | 66 | // "[UNDO STATE]: Storing undo position {0} for root part", Position); |
51 | Position = part.OffsetPosition; | 67 | |
52 | Rotation = part.RotationOffset; | 68 | Rotation = part.RotationOffset; |
53 | Scale = part.Shape.Scale; | 69 | |
54 | } | 70 | // m_log.DebugFormat( |
71 | // "[UNDO STATE]: Storing undo rotation {0} for root part", Rotation); | ||
72 | |||
73 | Scale = part.Shape.Scale; | ||
74 | |||
75 | // m_log.DebugFormat( | ||
76 | // "[UNDO STATE]: Storing undo scale {0} for root part", Scale); | ||
77 | } | ||
78 | else | ||
79 | { | ||
80 | Position = part.OffsetPosition; | ||
81 | // m_log.DebugFormat( | ||
82 | // "[UNDO STATE]: Storing undo position {0} for child part", Position); | ||
83 | |||
84 | Rotation = part.RotationOffset; | ||
85 | // m_log.DebugFormat( | ||
86 | // "[UNDO STATE]: Storing undo rotation {0} for child part", Rotation); | ||
87 | |||
88 | Scale = part.Shape.Scale; | ||
89 | // m_log.DebugFormat( | ||
90 | // "[UNDO STATE]: Storing undo scale {0} for child part", Scale); | ||
55 | } | 91 | } |
56 | } | 92 | } |
57 | 93 | ||
94 | /// <summary> | ||
95 | /// Compare the relevant state in the given part to this state. | ||
96 | /// </summary> | ||
97 | /// <param name="part"></param> | ||
98 | /// <returns>true if both the part's position, rotation and scale match those in this undo state. False otherwise.</returns> | ||
58 | public bool Compare(SceneObjectPart part) | 99 | public bool Compare(SceneObjectPart part) |
59 | { | 100 | { |
60 | if (part != null) | 101 | if (part != null) |
61 | { | 102 | { |
62 | if (part.ParentID == 0) | 103 | if (part.ParentID == 0) |
63 | { | 104 | return |
64 | if (Position == part.ParentGroup.AbsolutePosition && Rotation == part.ParentGroup.Rotation) | 105 | Position == part.ParentGroup.AbsolutePosition |
65 | return true; | 106 | && Rotation == part.RotationOffset |
66 | else | 107 | && Scale == part.Shape.Scale; |
67 | return false; | ||
68 | } | ||
69 | else | 108 | else |
70 | { | 109 | return |
71 | if (Position == part.OffsetPosition && Rotation == part.RotationOffset && Scale == part.Shape.Scale) | 110 | Position == part.OffsetPosition |
72 | return true; | 111 | && Rotation == part.RotationOffset |
73 | else | 112 | && Scale == part.Shape.Scale; |
74 | return false; | ||
75 | |||
76 | } | ||
77 | } | 113 | } |
114 | |||
78 | return false; | 115 | return false; |
79 | } | 116 | } |
80 | 117 | ||
81 | public void PlaybackState(SceneObjectPart part) | 118 | public void PlaybackState(SceneObjectPart part) |
82 | { | 119 | { |
83 | if (part != null) | 120 | part.Undoing = true; |
121 | |||
122 | if (part.ParentID == 0) | ||
84 | { | 123 | { |
85 | part.Undoing = true; | 124 | // m_log.DebugFormat( |
125 | // "[UNDO STATE]: Undoing position to {0} for root part {1} {2}", | ||
126 | // Position, part.Name, part.LocalId); | ||
86 | 127 | ||
87 | if (part.ParentID == 0) | 128 | if (Position != Vector3.Zero) |
88 | { | 129 | { |
89 | if (Position != Vector3.Zero) | 130 | if (ForGroup) |
90 | part.ParentGroup.AbsolutePosition = Position; | 131 | part.ParentGroup.AbsolutePosition = Position; |
91 | part.RotationOffset = Rotation; | 132 | else |
92 | if (Scale != Vector3.Zero) | 133 | part.ParentGroup.UpdateRootPosition(Position); |
93 | part.Resize(Scale); | ||
94 | part.ParentGroup.ScheduleGroupForTerseUpdate(); | ||
95 | } | 134 | } |
135 | |||
136 | // m_log.DebugFormat( | ||
137 | // "[UNDO STATE]: Undoing rotation {0} to {1} for root part {2} {3}", | ||
138 | // part.RotationOffset, Rotation, part.Name, part.LocalId); | ||
139 | |||
140 | if (ForGroup) | ||
141 | part.UpdateRotation(Rotation); | ||
96 | else | 142 | else |
143 | part.ParentGroup.UpdateRootRotation(Rotation); | ||
144 | |||
145 | if (Scale != Vector3.Zero) | ||
97 | { | 146 | { |
98 | if (Position != Vector3.Zero) | 147 | // m_log.DebugFormat( |
99 | part.OffsetPosition = Position; | 148 | // "[UNDO STATE]: Undoing scale {0} to {1} for root part {2} {3}", |
100 | part.UpdateRotation(Rotation); | 149 | // part.Shape.Scale, Scale, part.Name, part.LocalId); |
101 | if (Scale != Vector3.Zero) | 150 | |
102 | part.Resize(Scale); part.ScheduleTerseUpdate(); | 151 | if (ForGroup) |
152 | part.ParentGroup.GroupResize(Scale); | ||
153 | else | ||
154 | part.Resize(Scale); | ||
103 | } | 155 | } |
104 | part.Undoing = false; | ||
105 | 156 | ||
157 | part.ParentGroup.ScheduleGroupForTerseUpdate(); | ||
106 | } | 158 | } |
159 | else | ||
160 | { | ||
161 | if (Position != Vector3.Zero) | ||
162 | { | ||
163 | // m_log.DebugFormat( | ||
164 | // "[UNDO STATE]: Undoing position {0} to {1} for child part {2} {3}", | ||
165 | // part.OffsetPosition, Position, part.Name, part.LocalId); | ||
166 | |||
167 | part.OffsetPosition = Position; | ||
168 | } | ||
169 | |||
170 | // m_log.DebugFormat( | ||
171 | // "[UNDO STATE]: Undoing rotation {0} to {1} for child part {2} {3}", | ||
172 | // part.RotationOffset, Rotation, part.Name, part.LocalId); | ||
173 | |||
174 | part.UpdateRotation(Rotation); | ||
175 | |||
176 | if (Scale != Vector3.Zero) | ||
177 | { | ||
178 | // m_log.DebugFormat( | ||
179 | // "[UNDO STATE]: Undoing scale {0} to {1} for child part {2} {3}", | ||
180 | // part.Shape.Scale, Scale, part.Name, part.LocalId); | ||
181 | |||
182 | part.Resize(Scale); | ||
183 | } | ||
184 | |||
185 | part.ScheduleTerseUpdate(); | ||
186 | } | ||
187 | |||
188 | part.Undoing = false; | ||
107 | } | 189 | } |
190 | |||
108 | public void PlayfwdState(SceneObjectPart part) | 191 | public void PlayfwdState(SceneObjectPart part) |
109 | { | 192 | { |
110 | if (part != null) | 193 | part.Undoing = true; |
194 | |||
195 | if (part.ParentID == 0) | ||
111 | { | 196 | { |
112 | part.Undoing = true; | 197 | if (Position != Vector3.Zero) |
198 | part.ParentGroup.AbsolutePosition = Position; | ||
113 | 199 | ||
114 | if (part.ParentID == 0) | 200 | if (Rotation != Quaternion.Identity) |
115 | { | 201 | part.UpdateRotation(Rotation); |
116 | if (Position != Vector3.Zero) | 202 | |
117 | part.ParentGroup.AbsolutePosition = Position; | 203 | if (Scale != Vector3.Zero) |
118 | if (Rotation != Quaternion.Identity) | ||
119 | part.UpdateRotation(Rotation); | ||
120 | if (Scale != Vector3.Zero) | ||
121 | part.Resize(Scale); | ||
122 | part.ParentGroup.ScheduleGroupForTerseUpdate(); | ||
123 | } | ||
124 | else | ||
125 | { | 204 | { |
126 | if (Position != Vector3.Zero) | 205 | if (ForGroup) |
127 | part.OffsetPosition = Position; | 206 | part.ParentGroup.GroupResize(Scale); |
128 | if (Rotation != Quaternion.Identity) | 207 | else |
129 | part.UpdateRotation(Rotation); | ||
130 | if (Scale != Vector3.Zero) | ||
131 | part.Resize(Scale); | 208 | part.Resize(Scale); |
132 | part.ScheduleTerseUpdate(); | ||
133 | } | 209 | } |
134 | part.Undoing = false; | ||
135 | 210 | ||
211 | part.ParentGroup.ScheduleGroupForTerseUpdate(); | ||
136 | } | 212 | } |
213 | else | ||
214 | { | ||
215 | if (Position != Vector3.Zero) | ||
216 | part.OffsetPosition = Position; | ||
217 | |||
218 | if (Rotation != Quaternion.Identity) | ||
219 | part.UpdateRotation(Rotation); | ||
220 | |||
221 | if (Scale != Vector3.Zero) | ||
222 | part.Resize(Scale); | ||
223 | |||
224 | part.ScheduleTerseUpdate(); | ||
225 | } | ||
226 | |||
227 | part.Undoing = false; | ||
137 | } | 228 | } |
138 | } | 229 | } |
230 | |||
139 | public class LandUndoState | 231 | public class LandUndoState |
140 | { | 232 | { |
141 | public ITerrainModule m_terrainModule; | 233 | public ITerrainModule m_terrainModule; |
@@ -149,10 +241,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
149 | 241 | ||
150 | public bool Compare(ITerrainChannel terrainChannel) | 242 | public bool Compare(ITerrainChannel terrainChannel) |
151 | { | 243 | { |
152 | if (m_terrainChannel != terrainChannel) | 244 | return m_terrainChannel == terrainChannel; |
153 | return false; | ||
154 | else | ||
155 | return false; | ||
156 | } | 245 | } |
157 | 246 | ||
158 | public void PlaybackState() | 247 | public void PlaybackState() |
@@ -160,4 +249,4 @@ namespace OpenSim.Region.Framework.Scenes | |||
160 | m_terrainModule.UndoTerrain(m_terrainChannel); | 249 | m_terrainModule.UndoTerrain(m_terrainChannel); |
161 | } | 250 | } |
162 | } | 251 | } |
163 | } | 252 | } \ No newline at end of file |