aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
authorUbitUmarov2012-03-10 20:32:19 +0000
committerUbitUmarov2012-03-10 20:32:19 +0000
commit908abb1c3dded307e769abac71f660b835875975 (patch)
tree755d4e532a94346fe1960e3870f07767fbcfdd4a /OpenSim/Region/Framework
parentubitOde bug (diff)
downloadopensim-SC-908abb1c3dded307e769abac71f660b835875975.zip
opensim-SC-908abb1c3dded307e769abac71f660b835875975.tar.gz
opensim-SC-908abb1c3dded307e769abac71f660b835875975.tar.bz2
opensim-SC-908abb1c3dded307e769abac71f660b835875975.tar.xz
BIG MESS. changed Iclient interface so only one event is used to inform scene about position scale or rotation change by client (others can be added). Its served at SceneGraph that does permition checks, undostore and sends down to SOG. changed values are stored in a class (ObjectChangeData) and what is changed as a enum (ObjectChangeWhat) with bit fields and 'macros' of this for better readability (at top of scenegraph.cs lasy to find better place for now) this can be extended for other things clients changes and need undo/redo. SOG process acording to what is changed. Changed UNDO/redo to use this also (warning is only storing what is changed, previus stored all, this must be checked for side efects. to save all PRS change commented line in scenegraph). Still have excessive calls to ScheduleGroupForTerseUpdate. **** UNTESTED ****
Diffstat (limited to 'OpenSim/Region/Framework')
-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;