aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs152
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs204
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs47
-rw-r--r--OpenSim/Region/Framework/Scenes/UndoState.cs113
5 files changed, 394 insertions, 126 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 68c05f8..a3358a5 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2811,6 +2811,8 @@ namespace OpenSim.Region.Framework.Scenes
2811 client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition; 2811 client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition;
2812 client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition; 2812 client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition;
2813 2813
2814 client.onClientChangeObject += m_sceneGraph.ClientChangeObject;
2815
2814 client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimGroupRotation; 2816 client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimGroupRotation;
2815 client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation; 2817 client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation;
2816 client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation; 2818 client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation;
@@ -2940,6 +2942,8 @@ namespace OpenSim.Region.Framework.Scenes
2940 client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimGroupPosition; 2942 client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimGroupPosition;
2941 client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition; 2943 client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition;
2942 2944
2945 client.onClientChangeObject -= m_sceneGraph.ClientChangeObject;
2946
2943 client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimGroupRotation; 2947 client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimGroupRotation;
2944 client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimGroupRotation; 2948 client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimGroupRotation;
2945 client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation; 2949 client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation;
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 3cd4a10..5e770ba 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -47,6 +47,57 @@ namespace OpenSim.Region.Framework.Scenes
47 47
48 public delegate void ChangedBackupDelegate(SceneObjectGroup sog); 48 public delegate void ChangedBackupDelegate(SceneObjectGroup sog);
49 49
50
51 public enum ObjectChangeWhat : uint
52 {
53 // bits definitions
54 Position = 0x01,
55 Rotation = 0x02,
56 Scale = 0x04,
57 Group = 0x08,
58 UniformScale = 0x10,
59
60 // macros from above
61 // single prim
62 primP = 0x01,
63 primR = 0x02,
64 primPR = 0x03,
65 primS = 0x04,
66 primPS = 0x05,
67 primRS = 0x06,
68 primPSR = 0x07,
69
70 primUS = 0x14,
71 primPUS = 0x15,
72 primRUS = 0x16,
73 primPUSR = 0x17,
74
75 // group
76 groupP = 0x09,
77 groupR = 0x0A,
78 groupPR = 0x0B,
79 groupS = 0x0C,
80 groupPS = 0x0D,
81 groupRS = 0x0E,
82 groupPSR = 0x0F,
83
84 groupUS = 0x1C,
85 groupPUS = 0x1D,
86 groupRUS = 0x1E,
87 groupPUSR = 0x1F,
88
89 PRSmask = 0x07
90 }
91
92 public struct ObjectChangeData
93 {
94 public Quaternion rotation;
95 public Vector3 position;
96 public Vector3 scale;
97 public ObjectChangeWhat what;
98 }
99
100
50 /// <summary> 101 /// <summary>
51 /// This class used to be called InnerScene and may not yet truly be a SceneGraph. The non scene graph components 102 /// This class used to be called InnerScene and may not yet truly be a SceneGraph. The non scene graph components
52 /// should be migrated out over time. 103 /// should be migrated out over time.
@@ -1289,6 +1340,87 @@ namespace OpenSim.Region.Framework.Scenes
1289 1340
1290 #region Client Event handlers 1341 #region Client Event handlers
1291 1342
1343 protected internal void ClientChangeObject(uint localID, object odata, IClientAPI remoteClient)
1344 {
1345 SceneObjectPart part = GetSceneObjectPart(localID);
1346 ObjectChangeData data = (ObjectChangeData)odata;
1347
1348 if (part != null)
1349 {
1350 SceneObjectGroup grp = part.ParentGroup;
1351 if (grp != null)
1352 {
1353 if (m_parentScene.Permissions.CanEditObject(grp.UUID, remoteClient.AgentId))
1354 {
1355// part.StoreUndoState(data.what | ObjectChangeWhat.PRSmask); // for now save all to keep previus behavour ???
1356 part.StoreUndoState(data.what); // lets test only saving what we changed
1357 grp.doChangeObject(part, (ObjectChangeData)data);
1358 }
1359 }
1360 }
1361 }
1362
1363/* moved to SOG
1364 protected internal void doChangeObject(SceneObjectPart part, ObjectChangeData data)
1365 {
1366 if (part != null && part.ParentGroup != null)
1367 {
1368 ObjectChangeWhat what = data.what;
1369 bool togroup = ((what & ObjectChangeWhat.Group) != 0);
1370// bool uniform = ((what & ObjectChangeWhat.UniformScale) != 0); not in use
1371
1372 SceneObjectGroup group = part.ParentGroup;
1373 PhysicsActor pha = group.RootPart.PhysActor;
1374
1375 if (togroup)
1376 {
1377 // related to group
1378 if ((what & ObjectChangeWhat.Position) != 0)
1379 group.AbsolutePosition = data.position;
1380 if ((what & ObjectChangeWhat.Rotation) != 0)
1381 group.RootPart.UpdateRotation(data.rotation);
1382 if ((what & ObjectChangeWhat.Scale) != 0)
1383 {
1384 if (pha != null)
1385 pha.Building = true;
1386 group.GroupResize(data.scale);
1387 if (pha != null)
1388 pha.Building = false;
1389 }
1390 }
1391 else
1392 {
1393 // related to single prim in a link-set ( ie group)
1394 if (pha != null)
1395 pha.Building = true;
1396
1397 // must deal with root part specially for position and rotation
1398 // so parts offset positions or rotations are fixed
1399
1400 if (part == group.RootPart)
1401 {
1402 if ((what & ObjectChangeWhat.Position) != 0)
1403 group.UpdateRootPosition(data.position);
1404 if ((what & ObjectChangeWhat.Rotation) != 0)
1405 group.UpdateRootRotation(data.rotation);
1406 }
1407 else
1408 {
1409 if ((what & ObjectChangeWhat.Position) != 0)
1410 part.OffsetPosition = data.position;
1411 if ((what & ObjectChangeWhat.Rotation) != 0)
1412 part.UpdateRotation(data.rotation);
1413 }
1414
1415 if ((what & ObjectChangeWhat.Scale) != 0)
1416 part.Resize(data.scale);
1417
1418 if (pha != null)
1419 pha.Building = false;
1420 }
1421 }
1422 }
1423*/
1292 /// <summary> 1424 /// <summary>
1293 /// Update the scale of an individual prim. 1425 /// Update the scale of an individual prim.
1294 /// </summary> 1426 /// </summary>
@@ -1303,7 +1435,17 @@ namespace OpenSim.Region.Framework.Scenes
1303 { 1435 {
1304 if (m_parentScene.Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId)) 1436 if (m_parentScene.Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId))
1305 { 1437 {
1438 bool physbuild = false;
1439 if (part.ParentGroup.RootPart.PhysActor != null)
1440 {
1441 part.ParentGroup.RootPart.PhysActor.Building = true;
1442 physbuild = true;
1443 }
1444
1306 part.Resize(scale); 1445 part.Resize(scale);
1446
1447 if (physbuild)
1448 part.ParentGroup.RootPart.PhysActor.Building = false;
1307 } 1449 }
1308 } 1450 }
1309 } 1451 }
@@ -1315,7 +1457,17 @@ namespace OpenSim.Region.Framework.Scenes
1315 { 1457 {
1316 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1458 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
1317 { 1459 {
1460 bool physbuild = false;
1461 if (group.RootPart.PhysActor != null)
1462 {
1463 group.RootPart.PhysActor.Building = true;
1464 physbuild = true;
1465 }
1466
1318 group.GroupResize(scale); 1467 group.GroupResize(scale);
1468
1469 if (physbuild)
1470 group.RootPart.PhysActor.Building = false;
1319 } 1471 }
1320 } 1472 }
1321 } 1473 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 5818798..92f2d54 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -3124,10 +3124,6 @@ namespace OpenSim.Region.Framework.Scenes
3124 /// <param name="scale"></param> 3124 /// <param name="scale"></param>
3125 public void GroupResize(Vector3 scale) 3125 public void GroupResize(Vector3 scale)
3126 { 3126 {
3127// m_log.DebugFormat(
3128// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale);
3129// RootPart.StoreUndoState(true);
3130
3131 scale.X = Math.Min(scale.X, Scene.m_maxNonphys); 3127 scale.X = Math.Min(scale.X, Scene.m_maxNonphys);
3132 scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); 3128 scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys);
3133 scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys); 3129 scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys);
@@ -3152,7 +3148,6 @@ namespace OpenSim.Region.Framework.Scenes
3152 SceneObjectPart obPart = parts[i]; 3148 SceneObjectPart obPart = parts[i];
3153 if (obPart.UUID != m_rootPart.UUID) 3149 if (obPart.UUID != m_rootPart.UUID)
3154 { 3150 {
3155// obPart.IgnoreUndoUpdate = true;
3156 Vector3 oldSize = new Vector3(obPart.Scale); 3151 Vector3 oldSize = new Vector3(obPart.Scale);
3157 3152
3158 float f = 1.0f; 3153 float f = 1.0f;
@@ -3216,8 +3211,6 @@ namespace OpenSim.Region.Framework.Scenes
3216 z *= a; 3211 z *= a;
3217 } 3212 }
3218 } 3213 }
3219
3220// obPart.IgnoreUndoUpdate = false;
3221 } 3214 }
3222 } 3215 }
3223 } 3216 }
@@ -3226,9 +3219,8 @@ namespace OpenSim.Region.Framework.Scenes
3226 prevScale.X *= x; 3219 prevScale.X *= x;
3227 prevScale.Y *= y; 3220 prevScale.Y *= y;
3228 prevScale.Z *= z; 3221 prevScale.Z *= z;
3229// RootPart.IgnoreUndoUpdate = true; 3222
3230 RootPart.Resize(prevScale); 3223 RootPart.Resize(prevScale);
3231// RootPart.IgnoreUndoUpdate = false;
3232 3224
3233 parts = m_parts.GetArray(); 3225 parts = m_parts.GetArray();
3234 for (int i = 0; i < parts.Length; i++) 3226 for (int i = 0; i < parts.Length; i++)
@@ -3237,8 +3229,6 @@ namespace OpenSim.Region.Framework.Scenes
3237 3229
3238 if (obPart.UUID != m_rootPart.UUID) 3230 if (obPart.UUID != m_rootPart.UUID)
3239 { 3231 {
3240// obPart.IgnoreUndoUpdate = true;
3241
3242 Vector3 currentpos = new Vector3(obPart.OffsetPosition); 3232 Vector3 currentpos = new Vector3(obPart.OffsetPosition);
3243 currentpos.X *= x; 3233 currentpos.X *= x;
3244 currentpos.Y *= y; 3234 currentpos.Y *= y;
@@ -3251,18 +3241,12 @@ namespace OpenSim.Region.Framework.Scenes
3251 3241
3252 obPart.Resize(newSize); 3242 obPart.Resize(newSize);
3253 obPart.UpdateOffSet(currentpos); 3243 obPart.UpdateOffSet(currentpos);
3254
3255// obPart.IgnoreUndoUpdate = false;
3256 } 3244 }
3257 3245
3258// obPart.IgnoreUndoUpdate = false;
3259 HasGroupChanged = true; 3246 HasGroupChanged = true;
3260 m_rootPart.TriggerScriptChangedEvent(Changed.SCALE); 3247 m_rootPart.TriggerScriptChangedEvent(Changed.SCALE);
3261 ScheduleGroupForTerseUpdate(); 3248 ScheduleGroupForTerseUpdate();
3262 } 3249 }
3263
3264// m_log.DebugFormat(
3265// "[SCENE OBJECT GROUP]: Finished group resizing {0} {1} to {2}", Name, LocalId, RootPart.Scale);
3266 } 3250 }
3267 3251
3268 #endregion 3252 #endregion
@@ -3275,14 +3259,6 @@ namespace OpenSim.Region.Framework.Scenes
3275 /// <param name="pos"></param> 3259 /// <param name="pos"></param>
3276 public void UpdateGroupPosition(Vector3 pos) 3260 public void UpdateGroupPosition(Vector3 pos)
3277 { 3261 {
3278// m_log.DebugFormat("[SCENE OBJECT GROUP]: Updating group position on {0} {1} to {2}", Name, LocalId, pos);
3279
3280// RootPart.StoreUndoState(true);
3281
3282// SceneObjectPart[] parts = m_parts.GetArray();
3283// for (int i = 0; i < parts.Length; i++)
3284// parts[i].StoreUndoState();
3285
3286 if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) 3262 if (m_scene.EventManager.TriggerGroupMove(UUID, pos))
3287 { 3263 {
3288 if (IsAttachment) 3264 if (IsAttachment)
@@ -3314,22 +3290,14 @@ namespace OpenSim.Region.Framework.Scenes
3314 /// </summary> 3290 /// </summary>
3315 /// <param name="pos"></param> 3291 /// <param name="pos"></param>
3316 /// <param name="localID"></param> 3292 /// <param name="localID"></param>
3293 ///
3294
3317 public void UpdateSinglePosition(Vector3 pos, uint localID) 3295 public void UpdateSinglePosition(Vector3 pos, uint localID)
3318 { 3296 {
3319 SceneObjectPart part = GetChildPart(localID); 3297 SceneObjectPart part = GetChildPart(localID);
3320 3298
3321// SceneObjectPart[] parts = m_parts.GetArray();
3322// for (int i = 0; i < parts.Length; i++)
3323// parts[i].StoreUndoState();
3324
3325 if (part != null) 3299 if (part != null)
3326 { 3300 {
3327// m_log.DebugFormat(
3328// "[SCENE OBJECT GROUP]: Updating single position of {0} {1} to {2}", part.Name, part.LocalId, pos);
3329
3330// part.StoreUndoState(false);
3331// part.IgnoreUndoUpdate = true;
3332
3333// unlock parts position change 3301// unlock parts position change
3334 if (m_rootPart.PhysActor != null) 3302 if (m_rootPart.PhysActor != null)
3335 m_rootPart.PhysActor.Building = true; 3303 m_rootPart.PhysActor.Building = true;
@@ -3347,7 +3315,6 @@ namespace OpenSim.Region.Framework.Scenes
3347 m_rootPart.PhysActor.Building = false; 3315 m_rootPart.PhysActor.Building = false;
3348 3316
3349 HasGroupChanged = true; 3317 HasGroupChanged = true;
3350// part.IgnoreUndoUpdate = false;
3351 } 3318 }
3352 } 3319 }
3353 3320
@@ -3357,13 +3324,7 @@ namespace OpenSim.Region.Framework.Scenes
3357 /// <param name="pos"></param> 3324 /// <param name="pos"></param>
3358 public void UpdateRootPosition(Vector3 pos) 3325 public void UpdateRootPosition(Vector3 pos)
3359 { 3326 {
3360// m_log.DebugFormat( 3327 // needs to be called with phys building true
3361// "[SCENE OBJECT GROUP]: Updating root position of {0} {1} to {2}", Name, LocalId, pos);
3362
3363// SceneObjectPart[] parts = m_parts.GetArray();
3364// for (int i = 0; i < parts.Length; i++)
3365// parts[i].StoreUndoState();
3366
3367 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); 3328 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
3368 Vector3 oldPos = 3329 Vector3 oldPos =
3369 new Vector3(AbsolutePosition.X + m_rootPart.OffsetPosition.X, 3330 new Vector3(AbsolutePosition.X + m_rootPart.OffsetPosition.X,
@@ -3383,17 +3344,7 @@ namespace OpenSim.Region.Framework.Scenes
3383 obPart.OffsetPosition = obPart.OffsetPosition + diff; 3344 obPart.OffsetPosition = obPart.OffsetPosition + diff;
3384 } 3345 }
3385 3346
3386 //We have to set undoing here because otherwise an undo state will be saved 3347 AbsolutePosition = newPos;
3387// if (!m_rootPart.Undoing)
3388// {
3389// m_rootPart.Undoing = true;
3390 AbsolutePosition = newPos;
3391// m_rootPart.Undoing = false;
3392// }
3393// else
3394// {
3395// AbsolutePosition = newPos;
3396// }
3397 3348
3398 HasGroupChanged = true; 3349 HasGroupChanged = true;
3399 if (m_rootPart.Undoing) 3350 if (m_rootPart.Undoing)
@@ -3416,17 +3367,6 @@ namespace OpenSim.Region.Framework.Scenes
3416 /// <param name="rot"></param> 3367 /// <param name="rot"></param>
3417 public void UpdateGroupRotationR(Quaternion rot) 3368 public void UpdateGroupRotationR(Quaternion rot)
3418 { 3369 {
3419// m_log.DebugFormat(
3420// "[SCENE OBJECT GROUP]: Updating group rotation R of {0} {1} to {2}", Name, LocalId, rot);
3421
3422// SceneObjectPart[] parts = m_parts.GetArray();
3423// for (int i = 0; i < parts.Length; i++)
3424// parts[i].StoreUndoState();
3425
3426// m_rootPart.StoreUndoState(true);
3427
3428// m_rootPart.UpdateRotation(rot);
3429
3430 PhysicsActor actor = m_rootPart.PhysActor; 3370 PhysicsActor actor = m_rootPart.PhysActor;
3431 if (actor != null) 3371 if (actor != null)
3432 { 3372 {
@@ -3445,16 +3385,6 @@ namespace OpenSim.Region.Framework.Scenes
3445 /// <param name="rot"></param> 3385 /// <param name="rot"></param>
3446 public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) 3386 public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot)
3447 { 3387 {
3448// m_log.DebugFormat(
3449// "[SCENE OBJECT GROUP]: Updating group rotation PR of {0} {1} to {2}", Name, LocalId, rot);
3450
3451// SceneObjectPart[] parts = m_parts.GetArray();
3452// for (int i = 0; i < parts.Length; i++)
3453// parts[i].StoreUndoState();
3454
3455// RootPart.StoreUndoState(true);
3456// RootPart.IgnoreUndoUpdate = true;
3457
3458 m_rootPart.UpdateRotation(rot); 3388 m_rootPart.UpdateRotation(rot);
3459 3389
3460 PhysicsActor actor = m_rootPart.PhysActor; 3390 PhysicsActor actor = m_rootPart.PhysActor;
@@ -3468,8 +3398,6 @@ namespace OpenSim.Region.Framework.Scenes
3468 3398
3469 HasGroupChanged = true; 3399 HasGroupChanged = true;
3470 ScheduleGroupForTerseUpdate(); 3400 ScheduleGroupForTerseUpdate();
3471
3472// RootPart.IgnoreUndoUpdate = false;
3473 } 3401 }
3474 3402
3475 /// <summary> 3403 /// <summary>
@@ -3484,9 +3412,6 @@ namespace OpenSim.Region.Framework.Scenes
3484 3412
3485 if (part != null) 3413 if (part != null)
3486 { 3414 {
3487// m_log.DebugFormat(
3488// "[SCENE OBJECT GROUP]: Updating single rotation of {0} {1} to {2}", part.Name, part.LocalId, rot);
3489
3490 if (m_rootPart.PhysActor != null) 3415 if (m_rootPart.PhysActor != null)
3491 m_rootPart.PhysActor.Building = true; 3416 m_rootPart.PhysActor.Building = true;
3492 3417
@@ -3514,30 +3439,13 @@ namespace OpenSim.Region.Framework.Scenes
3514 SceneObjectPart part = GetChildPart(localID); 3439 SceneObjectPart part = GetChildPart(localID);
3515 if (part != null) 3440 if (part != null)
3516 { 3441 {
3517// m_log.DebugFormat(
3518// "[SCENE OBJECT GROUP]: Updating single position and rotation of {0} {1} to {2}",
3519// part.Name, part.LocalId, rot);
3520
3521// part.StoreUndoState();
3522// part.IgnoreUndoUpdate = true;
3523
3524 if (m_rootPart.PhysActor != null) 3442 if (m_rootPart.PhysActor != null)
3525 m_rootPart.PhysActor.Building = true; 3443 m_rootPart.PhysActor.Building = true;
3526 3444
3527 if (part.UUID == m_rootPart.UUID) 3445 if (part.UUID == m_rootPart.UUID)
3528 { 3446 {
3529 UpdateRootRotation(rot); 3447 UpdateRootRotation(rot);
3530/* if (!m_rootPart.Undoing) 3448 AbsolutePosition = pos;
3531 {
3532 m_rootPart.Undoing = true;
3533 AbsolutePosition = pos;
3534 m_rootPart.Undoing = false;
3535 }
3536 else
3537 {
3538 */
3539 AbsolutePosition = pos;
3540// }
3541 } 3449 }
3542 else 3450 else
3543 { 3451 {
@@ -3547,8 +3455,6 @@ namespace OpenSim.Region.Framework.Scenes
3547 3455
3548 if (m_rootPart.PhysActor != null) 3456 if (m_rootPart.PhysActor != null)
3549 m_rootPart.PhysActor.Building = false; 3457 m_rootPart.PhysActor.Building = false;
3550
3551// part.IgnoreUndoUpdate = false;
3552 } 3458 }
3553 } 3459 }
3554 3460
@@ -3558,13 +3464,9 @@ namespace OpenSim.Region.Framework.Scenes
3558 /// <param name="rot"></param> 3464 /// <param name="rot"></param>
3559 public void UpdateRootRotation(Quaternion rot) 3465 public void UpdateRootRotation(Quaternion rot)
3560 { 3466 {
3561// m_log.DebugFormat( 3467 // needs to be called with phys building true
3562// "[SCENE OBJECT GROUP]: Updating root rotation of {0} {1} to {2}",
3563// Name, LocalId, rot);
3564
3565 Quaternion axRot = rot; 3468 Quaternion axRot = rot;
3566 Quaternion oldParentRot = m_rootPart.RotationOffset; 3469 Quaternion oldParentRot = m_rootPart.RotationOffset;
3567// m_rootPart.StoreUndoState();
3568 3470
3569 //Don't use UpdateRotation because it schedules an update prematurely 3471 //Don't use UpdateRotation because it schedules an update prematurely
3570 m_rootPart.RotationOffset = rot; 3472 m_rootPart.RotationOffset = rot;
@@ -3580,8 +3482,6 @@ namespace OpenSim.Region.Framework.Scenes
3580 SceneObjectPart prim = parts[i]; 3482 SceneObjectPart prim = parts[i];
3581 if (prim.UUID != m_rootPart.UUID) 3483 if (prim.UUID != m_rootPart.UUID)
3582 { 3484 {
3583// prim.IgnoreUndoUpdate = true;
3584
3585 Quaternion NewRot = oldParentRot * prim.RotationOffset; 3485 Quaternion NewRot = oldParentRot * prim.RotationOffset;
3586 NewRot = Quaternion.Inverse(axRot) * NewRot; 3486 NewRot = Quaternion.Inverse(axRot) * NewRot;
3587 prim.RotationOffset = NewRot; 3487 prim.RotationOffset = NewRot;
@@ -3591,26 +3491,88 @@ namespace OpenSim.Region.Framework.Scenes
3591 axPos *= oldParentRot; 3491 axPos *= oldParentRot;
3592 axPos *= Quaternion.Inverse(axRot); 3492 axPos *= Quaternion.Inverse(axRot);
3593 prim.OffsetPosition = axPos; 3493 prim.OffsetPosition = axPos;
3594
3595// prim.IgnoreUndoUpdate = false;
3596 } 3494 }
3597 } 3495 }
3598 3496
3599// for (int i = 0; i < parts.Length; i++)
3600// {
3601// SceneObjectPart childpart = parts[i];
3602// if (childpart != m_rootPart)
3603// {
3604//// childpart.IgnoreUndoUpdate = false;
3605//// childpart.StoreUndoState();
3606// }
3607// }
3608 HasGroupChanged = true; 3497 HasGroupChanged = true;
3609 ScheduleGroupForFullUpdate(); 3498 ScheduleGroupForFullUpdate();
3499 }
3610 3500
3611// m_log.DebugFormat( 3501 public void doChangeObject(SceneObjectPart part, ObjectChangeData data)
3612// "[SCENE OBJECT GROUP]: Updated root rotation of {0} {1} to {2}", 3502 {
3613// Name, LocalId, rot); 3503 // TODO this still as excessive ScheduleGroupForTerseUpdate()s
3504
3505 if (part != null && part.ParentGroup != null)
3506 {
3507 ObjectChangeWhat what = data.what;
3508 bool togroup = ((what & ObjectChangeWhat.Group) != 0);
3509 // bool uniform = ((what & ObjectChangeWhat.UniformScale) != 0); not in use
3510
3511 SceneObjectGroup group = part.ParentGroup;
3512 PhysicsActor pha = group.RootPart.PhysActor;
3513
3514 bool needgrpUpdate = false;
3515
3516 if (togroup)
3517 {
3518 // related to group
3519 if ((what & ObjectChangeWhat.Position) != 0)
3520 {
3521 group.AbsolutePosition = data.position;
3522 needgrpUpdate = true;
3523 }
3524 if ((what & ObjectChangeWhat.Rotation) != 0)
3525 group.RootPart.UpdateRotation(data.rotation);
3526 if ((what & ObjectChangeWhat.Scale) != 0)
3527 {
3528 if (pha != null)
3529 pha.Building = true;
3530 group.GroupResize(data.scale);
3531 if (pha != null)
3532 pha.Building = false;
3533 }
3534 }
3535 else
3536 {
3537 // related to single prim in a link-set ( ie group)
3538 if (pha != null)
3539 pha.Building = true;
3540
3541 // must deal with root part specially for position and rotation
3542 // so parts offset positions or rotations are fixed
3543
3544 if (part == group.RootPart)
3545 {
3546 if ((what & ObjectChangeWhat.Position) != 0)
3547 group.UpdateRootPosition(data.position);
3548 if ((what & ObjectChangeWhat.Rotation) != 0)
3549 group.UpdateRootRotation(data.rotation);
3550 }
3551 else
3552 {
3553
3554 if ((what & ObjectChangeWhat.Position) != 0)
3555 {
3556 part.OffsetPosition = data.position;
3557 needgrpUpdate = true;
3558 }
3559 if ((what & ObjectChangeWhat.Rotation) != 0)
3560 part.UpdateRotation(data.rotation);
3561 }
3562
3563 if ((what & ObjectChangeWhat.Scale) != 0)
3564 part.Resize(data.scale);
3565
3566 if (pha != null)
3567 pha.Building = false;
3568 }
3569
3570 if (needgrpUpdate)
3571 {
3572 HasGroupChanged = true;
3573 ScheduleGroupForTerseUpdate();
3574 }
3575 }
3614 } 3576 }
3615 3577
3616 #endregion 3578 #endregion
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 6622495..c806fda 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1944,6 +1944,7 @@ namespace OpenSim.Region.Framework.Scenes
1944 1944
1945 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 1945 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1946 PhysActor.OnOutOfBounds += PhysicsOutOfBounds; 1946 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1947
1947 if (ParentID != 0 && ParentID != LocalId) 1948 if (ParentID != 0 && ParentID != LocalId)
1948 { 1949 {
1949 if (ParentGroup.RootPart.PhysActor != null) 1950 if (ParentGroup.RootPart.PhysActor != null)
@@ -3656,7 +3657,7 @@ namespace OpenSim.Region.Framework.Scenes
3656 ParentGroup.ScheduleGroupForTerseUpdate(); 3657 ParentGroup.ScheduleGroupForTerseUpdate();
3657 //ParentGroup.ScheduleGroupForFullUpdate(); 3658 //ParentGroup.ScheduleGroupForFullUpdate();
3658 } 3659 }
3659 3660/*
3660 public void StoreUndoState() 3661 public void StoreUndoState()
3661 { 3662 {
3662 StoreUndoState(false); 3663 StoreUndoState(false);
@@ -3697,6 +3698,44 @@ namespace OpenSim.Region.Framework.Scenes
3697 } 3698 }
3698 } 3699 }
3699 } 3700 }
3701*/
3702
3703
3704 public void StoreUndoState(ObjectChangeWhat what)
3705 {
3706 if (!Undoing && !IgnoreUndoUpdate) // just to read better - undo is in progress, or suspended
3707 {
3708 if (ParentGroup != null)
3709 {
3710 lock (m_undo)
3711 {
3712 if (m_undo.Count > 0)
3713 {
3714 // see if we had a change
3715
3716 UndoState last = m_undo.Peek();
3717 if (last != null)
3718 {
3719 if (last.Compare(this, what))
3720 {
3721 return;
3722 }
3723 }
3724 }
3725
3726 if (ParentGroup.GetSceneMaxUndo() > 0)
3727 {
3728 UndoState nUndo = new UndoState(this, what);
3729
3730 m_undo.Push(nUndo);
3731
3732 if (m_redo.Count > 0)
3733 m_redo.Clear();
3734 }
3735 }
3736 }
3737 }
3738 }
3700 3739
3701 /// <summary> 3740 /// <summary>
3702 /// Return number of undos on the stack. Here temporarily pending a refactor. 3741 /// Return number of undos on the stack. Here temporarily pending a refactor.
@@ -3725,10 +3764,10 @@ namespace OpenSim.Region.Framework.Scenes
3725 if (goback != null) 3764 if (goback != null)
3726 { 3765 {
3727 UndoState nUndo = null; 3766 UndoState nUndo = null;
3728 3767
3729 if (ParentGroup.GetSceneMaxUndo() > 0) 3768 if (ParentGroup.GetSceneMaxUndo() > 0)
3730 { 3769 {
3731 nUndo = new UndoState(this, goback.ForGroup); 3770 nUndo = new UndoState(this, goback.data.what);
3732 } 3771 }
3733 3772
3734 goback.PlayState(this); 3773 goback.PlayState(this);
@@ -3760,7 +3799,7 @@ namespace OpenSim.Region.Framework.Scenes
3760 { 3799 {
3761 if (ParentGroup.GetSceneMaxUndo() > 0) 3800 if (ParentGroup.GetSceneMaxUndo() > 0)
3762 { 3801 {
3763 UndoState nUndo = new UndoState(this, gofwd.ForGroup); 3802 UndoState nUndo = new UndoState(this, gofwd.data.what);
3764 3803
3765 m_undo.Push(nUndo); 3804 m_undo.Push(nUndo);
3766 } 3805 }
diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs
index 38474de..eb76ca5 100644
--- a/OpenSim/Region/Framework/Scenes/UndoState.cs
+++ b/OpenSim/Region/Framework/Scenes/UndoState.cs
@@ -48,6 +48,7 @@ namespace OpenSim.Region.Framework.Scenes
48 STATE_ALL = 63 48 STATE_ALL = 63
49 } 49 }
50 50
51/*
51 public class UndoState 52 public class UndoState
52 { 53 {
53 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -121,9 +122,16 @@ namespace OpenSim.Region.Framework.Scenes
121 public void PlayState(SceneObjectPart part) 122 public void PlayState(SceneObjectPart part)
122 { 123 {
123 part.Undoing = true; 124 part.Undoing = true;
124 125 bool physbuilding = false;
126
125 if (part.ParentID == 0) 127 if (part.ParentID == 0)
126 { 128 {
129 if (!ForGroup && part.PhysActor != null)
130 {
131 part.PhysActor.Building = true;
132 physbuilding = true;
133 }
134
127 if (Position != Vector3.Zero) 135 if (Position != Vector3.Zero)
128 { 136 {
129 if (ForGroup) 137 if (ForGroup)
@@ -139,17 +147,34 @@ namespace OpenSim.Region.Framework.Scenes
139 147
140 if (Scale != Vector3.Zero) 148 if (Scale != Vector3.Zero)
141 { 149 {
150 if (!physbuilding && part.PhysActor != null)
151 {
152 part.PhysActor.Building = true;
153 physbuilding = true;
154 }
155
142 if (ForGroup) 156 if (ForGroup)
143 part.ParentGroup.GroupResize(Scale); 157 part.ParentGroup.GroupResize(Scale);
144 else 158 else
145 part.Resize(Scale); 159 part.Resize(Scale);
146 } 160 }
161
162 if (physbuilding)
163 part.PhysActor.Building = false;
164
147 part.ParentGroup.ScheduleGroupForTerseUpdate(); 165 part.ParentGroup.ScheduleGroupForTerseUpdate();
148 } 166 }
149 else 167 else
150 { 168 {
151 if (ForGroup) // trap for group since seems parts can't do it 169 if (ForGroup) // trap for group since seems parts can't do it
152 return; 170 return;
171
172 // changing a part invalidates entire object physical rep
173 if (part.ParentGroup != null && part.ParentGroup.RootPart != null && part.ParentGroup.RootPart.PhysActor != null)
174 {
175 part.ParentGroup.RootPart.PhysActor.Building = true;
176 physbuilding = true;
177 }
153 178
154 // Note: Updating these properties on sop automatically schedules an update if needed 179 // Note: Updating these properties on sop automatically schedules an update if needed
155 part.OffsetPosition = Position; 180 part.OffsetPosition = Position;
@@ -158,12 +183,98 @@ namespace OpenSim.Region.Framework.Scenes
158 { 183 {
159 part.Resize(Scale); 184 part.Resize(Scale);
160 } 185 }
186
187 if (physbuilding)
188 part.ParentGroup.RootPart.PhysActor.Building = false;
189 }
190
191 part.Undoing = false;
192 }
193 }
194*/
195 public class UndoState
196 {
197 public ObjectChangeData data;
198 /// <summary>
199 /// Constructor.
200 /// </summary>
201 /// <param name="part"></param>
202 /// <param name="forGroup">True if the undo is for an entire group</param>
203 /// only for root parts ????
204 public UndoState(SceneObjectPart part, ObjectChangeWhat what)
205 {
206 data = new ObjectChangeData();
207
208 data.what = what;
209
210 if (part.ParentGroup.RootPart == part)
211 {
212 if ((what & ObjectChangeWhat.Position) != 0)
213 data.position = part.ParentGroup.AbsolutePosition;
214 if ((what & ObjectChangeWhat.Rotation) != 0)
215 data.rotation = part.RotationOffset;
216 if ((what & ObjectChangeWhat.Scale) != 0)
217 data.scale = part.Shape.Scale;
218 }
219 else
220 {
221 if ((what & ObjectChangeWhat.Position) != 0)
222 data.position = part.OffsetPosition;
223 if ((what & ObjectChangeWhat.Rotation) != 0)
224 data.rotation = part.RotationOffset;
225 if ((what & ObjectChangeWhat.Scale) != 0)
226 data.scale = part.Shape.Scale;
227 }
228 }
229
230 /// <summary>
231 /// Compare the relevant state in the given part to this state.
232 /// </summary>
233 /// <param name="part"></param>
234 /// <returns>true if both the part's position, rotation and scale match those in this undo state. False otherwise.</returns>
235 public bool Compare(SceneObjectPart part, ObjectChangeWhat what)
236 {
237 if (data.what != what) // if diferent targets, then they are diferent
238 return false;
239
240 if (part != null)
241 {
242 if (part.ParentID == 0)
243 {
244 if ((what & ObjectChangeWhat.Position) != 0 && data.position != part.ParentGroup.AbsolutePosition)
245 return false;
246 }
247 else
248 {
249 if ((what & ObjectChangeWhat.Position) != 0 && data.position != part.OffsetPosition)
250 return false;
251 }
252
253 if ((what & ObjectChangeWhat.Rotation) != 0 && data.rotation != part.RotationOffset)
254 return false;
255 if ((what & ObjectChangeWhat.Rotation) != 0 && data.scale == part.Shape.Scale)
256 return false;
257 return true;
258
161 } 259 }
260 return false;
261 }
162 262
263 public void PlayState(SceneObjectPart part)
264 {
265 part.Undoing = true;
266
267 SceneObjectGroup grp = part.ParentGroup;
268
269 if (grp != null)
270 {
271 grp.doChangeObject(part, data);
272 }
163 part.Undoing = false; 273 part.Undoing = false;
164 } 274 }
165 } 275 }
166 276
277
167 public class LandUndoState 278 public class LandUndoState
168 { 279 {
169 public ITerrainModule m_terrainModule; 280 public ITerrainModule m_terrainModule;