aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/IClientAPI.cs3
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs156
-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.cs213
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs120
-rw-r--r--OpenSim/Region/Framework/Scenes/UndoState.cs283
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs1
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs1
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs6
-rw-r--r--OpenSim/Tests/Common/Mock/TestClient.cs1
11 files changed, 706 insertions, 234 deletions
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 5e156f1..1bd4749 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -130,6 +130,8 @@ namespace OpenSim.Framework
130 130
131 public delegate void UpdateVector(uint localID, Vector3 pos, IClientAPI remoteClient); 131 public delegate void UpdateVector(uint localID, Vector3 pos, IClientAPI remoteClient);
132 132
133 public delegate void ClientChangeObject(uint localID, object data ,IClientAPI remoteClient);
134
133 public delegate void UpdatePrimRotation(uint localID, Quaternion rot, IClientAPI remoteClient); 135 public delegate void UpdatePrimRotation(uint localID, Quaternion rot, IClientAPI remoteClient);
134 136
135 public delegate void UpdatePrimSingleRotation(uint localID, Quaternion rot, IClientAPI remoteClient); 137 public delegate void UpdatePrimSingleRotation(uint localID, Quaternion rot, IClientAPI remoteClient);
@@ -838,6 +840,7 @@ namespace OpenSim.Framework
838 event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 840 event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
839 event UpdatePrimFlags OnUpdatePrimFlags; 841 event UpdatePrimFlags OnUpdatePrimFlags;
840 event UpdatePrimTexture OnUpdatePrimTexture; 842 event UpdatePrimTexture OnUpdatePrimTexture;
843 event ClientChangeObject onClientChangeObject;
841 event UpdateVector OnUpdatePrimGroupPosition; 844 event UpdateVector OnUpdatePrimGroupPosition;
842 event UpdateVector OnUpdatePrimSinglePosition; 845 event UpdateVector OnUpdatePrimSinglePosition;
843 event UpdatePrimRotation OnUpdatePrimGroupRotation; 846 event UpdatePrimRotation OnUpdatePrimGroupRotation;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index d973a06..fcca1bc 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -125,6 +125,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
125 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 125 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
126 public event UpdatePrimFlags OnUpdatePrimFlags; 126 public event UpdatePrimFlags OnUpdatePrimFlags;
127 public event UpdatePrimTexture OnUpdatePrimTexture; 127 public event UpdatePrimTexture OnUpdatePrimTexture;
128 public event ClientChangeObject onClientChangeObject;
128 public event UpdateVector OnUpdatePrimGroupPosition; 129 public event UpdateVector OnUpdatePrimGroupPosition;
129 public event UpdateVector OnUpdatePrimSinglePosition; 130 public event UpdateVector OnUpdatePrimSinglePosition;
130 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 131 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -11492,22 +11493,151 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11492// parts[j].IgnoreUndoUpdate = true; 11493// parts[j].IgnoreUndoUpdate = true;
11493// } 11494// }
11494 11495
11495 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11496// UpdatePrimGroupRotation handlerUpdatePrimGroupRotation;
11496 UpdateVector handlerUpdatePrimGroupScale; 11497// UpdateVector handlerUpdatePrimGroupScale;
11497 11498
11498 Quaternion arot; 11499 ClientChangeObject updatehandler = onClientChangeObject;
11499 Vector3 ascale; 11500
11500 Vector3 apos; 11501 if (updatehandler != null)
11501/*ubit from ll JIRA: 11502 {
11502 * 0x01 position 11503 ObjectChangeData udata = new ObjectChangeData();
11503 * 0x02 rotation 11504
11504 * 0x04 scale 11505 /*ubit from ll JIRA:
11506 * 0x01 position
11507 * 0x02 rotation
11508 * 0x04 scale
11505 11509
11506 * 0x08 LINK_SET 11510 * 0x08 LINK_SET
11507 * 0x10 UNIFORM for scale 11511 * 0x10 UNIFORM for scale
11508 */ 11512 */
11513
11514 // translate to internal changes
11515 // not all cases .. just the ones older code did
11516
11517 switch (block.Type)
11518 {
11519 case 1: //change position sp
11520 udata.position = new Vector3(block.Data, 0);
11521
11522 udata.what = ObjectChangeWhat.primP;
11523 updatehandler(localId, udata, this);
11524 break;
11525
11526 case 2: // rotation sp
11527 udata.rotation = new Quaternion(block.Data, 0, true);
11528
11529 udata.what = ObjectChangeWhat.primR;
11530 updatehandler(localId, udata, this);
11531 break;
11532
11533 case 3: // position plus rotation
11534 udata.position = new Vector3(block.Data, 0);
11535 udata.rotation = new Quaternion(block.Data, 12, true);
11536
11537 udata.what = ObjectChangeWhat.primPR;
11538 updatehandler(localId, udata, this);
11539
11540 break;
11541
11542 case 4: // scale sp
11543 udata.scale = new Vector3(block.Data, 0);
11544 udata.what = ObjectChangeWhat.primS;
11545
11546 updatehandler(localId, udata, this);
11547 break;
11548
11549 case 0x14: // uniform scale sp
11550 udata.scale = new Vector3(block.Data, 0);
11551
11552 udata.what = ObjectChangeWhat.primUS;
11553 updatehandler(localId, udata, this);
11554 break;
11555
11556 case 5: // scale and position sp
11557 udata.position = new Vector3(block.Data, 0);
11558 udata.scale = new Vector3(block.Data, 12);
11559
11560 udata.what = ObjectChangeWhat.primPS;
11561 updatehandler(localId, udata, this);
11562 break;
11563
11564 case 0x15: //uniform scale and position
11565 udata.position = new Vector3(block.Data, 0);
11566 udata.scale = new Vector3(block.Data, 12);
11567
11568 udata.what = ObjectChangeWhat.primPUS;
11569 updatehandler(localId, udata, this);
11570 break;
11509 11571
11572 // now group related (bit 4)
11573 case 9: //( 8 + 1 )group position
11574 udata.position = new Vector3(block.Data, 0);
11510 11575
11576 udata.what = ObjectChangeWhat.groupP;
11577 updatehandler(localId, udata, this);
11578 break;
11579
11580 case 0x0A: // (8 + 2) group rotation
11581 udata.rotation = new Quaternion(block.Data, 0, true);
11582
11583 udata.what = ObjectChangeWhat.groupR;
11584 updatehandler(localId, udata, this);
11585 break;
11586
11587 case 0x0B: //( 8 + 2 + 1) group rotation and position
11588 udata.position = new Vector3(block.Data, 0);
11589 udata.rotation = new Quaternion(block.Data, 12, true);
11590
11591 udata.what = ObjectChangeWhat.groupPR;
11592 updatehandler(localId, udata, this);
11593 break;
11594
11595 case 0x0C: // (8 + 4) group scale
11596 // only afects root prim and only sent by viewer editor object tab scaling
11597 // mouse edition only allows uniform scaling
11598 // SL MAY CHANGE THIS in viewers
11599
11600 udata.scale = new Vector3(block.Data, 0);
11601
11602 // udata.what = ObjectChangeWhat.groupS;
11603 udata.what = ObjectChangeWhat.primS; // to conform to current SL
11604 updatehandler(localId, udata, this);
11605
11606 break;
11607
11608 case 0x0D: //(8 + 4 + 1) group scale and position
11609 // exception as above
11610
11611 udata.position = new Vector3(block.Data, 0);
11612 udata.scale = new Vector3(block.Data, 12);
11613
11614 // udata.what = ObjectChangeWhat.groupPS;
11615 udata.what = ObjectChangeWhat.primPS; // to conform to current SL
11616 updatehandler(localId, udata, this);
11617 break;
11618
11619 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11620 udata.scale = new Vector3(block.Data, 0);
11621
11622 udata.what = ObjectChangeWhat.groupUS;
11623 updatehandler(localId, udata, this);
11624 break;
11625
11626 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11627 udata.position = new Vector3(block.Data, 0);
11628 udata.scale = new Vector3(block.Data, 12);
11629
11630 udata.what = ObjectChangeWhat.groupPUS;
11631 updatehandler(localId, udata, this);
11632 break;
11633
11634 default:
11635 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11636 break;
11637 }
11638 }
11639
11640/*
11511 switch (block.Type) 11641 switch (block.Type)
11512 { 11642 {
11513 case 1: //change position sp 11643 case 1: //change position sp
@@ -11763,7 +11893,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11763 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11893 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11764 break; 11894 break;
11765 } 11895 }
11766 11896*/
11767// for (int j = 0; j < parts.Length; j++) 11897// for (int j = 0; j < parts.Length; j++)
11768// parts[j].IgnoreUndoUpdate = false; 11898// parts[j].IgnoreUndoUpdate = false;
11769 11899
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 2d71372..92f2d54 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2499,6 +2499,11 @@ namespace OpenSim.Region.Framework.Scenes
2499 if (linkPart.PhysActor != null) 2499 if (linkPart.PhysActor != null)
2500 linkPart.PhysActor.Building = true; 2500 linkPart.PhysActor.Building = true;
2501 2501
2502 // physics flags from group to be applied to linked parts
2503 bool grpusephys = UsesPhysics;
2504 bool grptemporary = IsTemporary;
2505 bool gprphantom = IsPhantom;
2506
2502 Vector3 oldGroupPosition = linkPart.GroupPosition; 2507 Vector3 oldGroupPosition = linkPart.GroupPosition;
2503 Quaternion oldRootRotation = linkPart.RotationOffset; 2508 Quaternion oldRootRotation = linkPart.RotationOffset;
2504 2509
@@ -2542,7 +2547,8 @@ namespace OpenSim.Region.Framework.Scenes
2542 linkPart.SetParent(this); 2547 linkPart.SetParent(this);
2543 linkPart.CreateSelected = true; 2548 linkPart.CreateSelected = true;
2544 2549
2545 // let physics know 2550 // let physics know preserve part volume dtc messy since UpdatePrimFlags doesn't look to parent changes for now
2551 linkPart.UpdatePrimFlags(grpusephys, grptemporary, gprphantom, linkPart.VolumeDetectActive, true);
2546 if (linkPart.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical) 2552 if (linkPart.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical)
2547 { 2553 {
2548 linkPart.PhysActor.link(m_rootPart.PhysActor); 2554 linkPart.PhysActor.link(m_rootPart.PhysActor);
@@ -2564,6 +2570,7 @@ namespace OpenSim.Region.Framework.Scenes
2564 { 2570 {
2565 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); 2571 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2566 // let physics know 2572 // let physics know
2573 part.UpdatePrimFlags(grpusephys, grptemporary, gprphantom, part.VolumeDetectActive, true);
2567 if (part.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical) 2574 if (part.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical)
2568 { 2575 {
2569 part.PhysActor.link(m_rootPart.PhysActor); 2576 part.PhysActor.link(m_rootPart.PhysActor);
@@ -3117,10 +3124,6 @@ namespace OpenSim.Region.Framework.Scenes
3117 /// <param name="scale"></param> 3124 /// <param name="scale"></param>
3118 public void GroupResize(Vector3 scale) 3125 public void GroupResize(Vector3 scale)
3119 { 3126 {
3120// m_log.DebugFormat(
3121// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale);
3122// RootPart.StoreUndoState(true);
3123
3124 scale.X = Math.Min(scale.X, Scene.m_maxNonphys); 3127 scale.X = Math.Min(scale.X, Scene.m_maxNonphys);
3125 scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); 3128 scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys);
3126 scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys); 3129 scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys);
@@ -3145,7 +3148,6 @@ namespace OpenSim.Region.Framework.Scenes
3145 SceneObjectPart obPart = parts[i]; 3148 SceneObjectPart obPart = parts[i];
3146 if (obPart.UUID != m_rootPart.UUID) 3149 if (obPart.UUID != m_rootPart.UUID)
3147 { 3150 {
3148// obPart.IgnoreUndoUpdate = true;
3149 Vector3 oldSize = new Vector3(obPart.Scale); 3151 Vector3 oldSize = new Vector3(obPart.Scale);
3150 3152
3151 float f = 1.0f; 3153 float f = 1.0f;
@@ -3209,8 +3211,6 @@ namespace OpenSim.Region.Framework.Scenes
3209 z *= a; 3211 z *= a;
3210 } 3212 }
3211 } 3213 }
3212
3213// obPart.IgnoreUndoUpdate = false;
3214 } 3214 }
3215 } 3215 }
3216 } 3216 }
@@ -3219,9 +3219,8 @@ namespace OpenSim.Region.Framework.Scenes
3219 prevScale.X *= x; 3219 prevScale.X *= x;
3220 prevScale.Y *= y; 3220 prevScale.Y *= y;
3221 prevScale.Z *= z; 3221 prevScale.Z *= z;
3222// RootPart.IgnoreUndoUpdate = true; 3222
3223 RootPart.Resize(prevScale); 3223 RootPart.Resize(prevScale);
3224// RootPart.IgnoreUndoUpdate = false;
3225 3224
3226 parts = m_parts.GetArray(); 3225 parts = m_parts.GetArray();
3227 for (int i = 0; i < parts.Length; i++) 3226 for (int i = 0; i < parts.Length; i++)
@@ -3230,8 +3229,6 @@ namespace OpenSim.Region.Framework.Scenes
3230 3229
3231 if (obPart.UUID != m_rootPart.UUID) 3230 if (obPart.UUID != m_rootPart.UUID)
3232 { 3231 {
3233// obPart.IgnoreUndoUpdate = true;
3234
3235 Vector3 currentpos = new Vector3(obPart.OffsetPosition); 3232 Vector3 currentpos = new Vector3(obPart.OffsetPosition);
3236 currentpos.X *= x; 3233 currentpos.X *= x;
3237 currentpos.Y *= y; 3234 currentpos.Y *= y;
@@ -3244,18 +3241,12 @@ namespace OpenSim.Region.Framework.Scenes
3244 3241
3245 obPart.Resize(newSize); 3242 obPart.Resize(newSize);
3246 obPart.UpdateOffSet(currentpos); 3243 obPart.UpdateOffSet(currentpos);
3247
3248// obPart.IgnoreUndoUpdate = false;
3249 } 3244 }
3250 3245
3251// obPart.IgnoreUndoUpdate = false;
3252 HasGroupChanged = true; 3246 HasGroupChanged = true;
3253 m_rootPart.TriggerScriptChangedEvent(Changed.SCALE); 3247 m_rootPart.TriggerScriptChangedEvent(Changed.SCALE);
3254 ScheduleGroupForTerseUpdate(); 3248 ScheduleGroupForTerseUpdate();
3255 } 3249 }
3256
3257// m_log.DebugFormat(
3258// "[SCENE OBJECT GROUP]: Finished group resizing {0} {1} to {2}", Name, LocalId, RootPart.Scale);
3259 } 3250 }
3260 3251
3261 #endregion 3252 #endregion
@@ -3268,14 +3259,6 @@ namespace OpenSim.Region.Framework.Scenes
3268 /// <param name="pos"></param> 3259 /// <param name="pos"></param>
3269 public void UpdateGroupPosition(Vector3 pos) 3260 public void UpdateGroupPosition(Vector3 pos)
3270 { 3261 {
3271// m_log.DebugFormat("[SCENE OBJECT GROUP]: Updating group position on {0} {1} to {2}", Name, LocalId, pos);
3272
3273// RootPart.StoreUndoState(true);
3274
3275// SceneObjectPart[] parts = m_parts.GetArray();
3276// for (int i = 0; i < parts.Length; i++)
3277// parts[i].StoreUndoState();
3278
3279 if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) 3262 if (m_scene.EventManager.TriggerGroupMove(UUID, pos))
3280 { 3263 {
3281 if (IsAttachment) 3264 if (IsAttachment)
@@ -3307,22 +3290,14 @@ namespace OpenSim.Region.Framework.Scenes
3307 /// </summary> 3290 /// </summary>
3308 /// <param name="pos"></param> 3291 /// <param name="pos"></param>
3309 /// <param name="localID"></param> 3292 /// <param name="localID"></param>
3293 ///
3294
3310 public void UpdateSinglePosition(Vector3 pos, uint localID) 3295 public void UpdateSinglePosition(Vector3 pos, uint localID)
3311 { 3296 {
3312 SceneObjectPart part = GetChildPart(localID); 3297 SceneObjectPart part = GetChildPart(localID);
3313 3298
3314// SceneObjectPart[] parts = m_parts.GetArray();
3315// for (int i = 0; i < parts.Length; i++)
3316// parts[i].StoreUndoState();
3317
3318 if (part != null) 3299 if (part != null)
3319 { 3300 {
3320// m_log.DebugFormat(
3321// "[SCENE OBJECT GROUP]: Updating single position of {0} {1} to {2}", part.Name, part.LocalId, pos);
3322
3323// part.StoreUndoState(false);
3324// part.IgnoreUndoUpdate = true;
3325
3326// unlock parts position change 3301// unlock parts position change
3327 if (m_rootPart.PhysActor != null) 3302 if (m_rootPart.PhysActor != null)
3328 m_rootPart.PhysActor.Building = true; 3303 m_rootPart.PhysActor.Building = true;
@@ -3340,7 +3315,6 @@ namespace OpenSim.Region.Framework.Scenes
3340 m_rootPart.PhysActor.Building = false; 3315 m_rootPart.PhysActor.Building = false;
3341 3316
3342 HasGroupChanged = true; 3317 HasGroupChanged = true;
3343// part.IgnoreUndoUpdate = false;
3344 } 3318 }
3345 } 3319 }
3346 3320
@@ -3350,13 +3324,7 @@ namespace OpenSim.Region.Framework.Scenes
3350 /// <param name="pos"></param> 3324 /// <param name="pos"></param>
3351 public void UpdateRootPosition(Vector3 pos) 3325 public void UpdateRootPosition(Vector3 pos)
3352 { 3326 {
3353// m_log.DebugFormat( 3327 // needs to be called with phys building true
3354// "[SCENE OBJECT GROUP]: Updating root position of {0} {1} to {2}", Name, LocalId, pos);
3355
3356// SceneObjectPart[] parts = m_parts.GetArray();
3357// for (int i = 0; i < parts.Length; i++)
3358// parts[i].StoreUndoState();
3359
3360 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); 3328 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
3361 Vector3 oldPos = 3329 Vector3 oldPos =
3362 new Vector3(AbsolutePosition.X + m_rootPart.OffsetPosition.X, 3330 new Vector3(AbsolutePosition.X + m_rootPart.OffsetPosition.X,
@@ -3376,17 +3344,7 @@ namespace OpenSim.Region.Framework.Scenes
3376 obPart.OffsetPosition = obPart.OffsetPosition + diff; 3344 obPart.OffsetPosition = obPart.OffsetPosition + diff;
3377 } 3345 }
3378 3346
3379 //We have to set undoing here because otherwise an undo state will be saved 3347 AbsolutePosition = newPos;
3380// if (!m_rootPart.Undoing)
3381// {
3382// m_rootPart.Undoing = true;
3383 AbsolutePosition = newPos;
3384// m_rootPart.Undoing = false;
3385// }
3386// else
3387// {
3388// AbsolutePosition = newPos;
3389// }
3390 3348
3391 HasGroupChanged = true; 3349 HasGroupChanged = true;
3392 if (m_rootPart.Undoing) 3350 if (m_rootPart.Undoing)
@@ -3409,17 +3367,6 @@ namespace OpenSim.Region.Framework.Scenes
3409 /// <param name="rot"></param> 3367 /// <param name="rot"></param>
3410 public void UpdateGroupRotationR(Quaternion rot) 3368 public void UpdateGroupRotationR(Quaternion rot)
3411 { 3369 {
3412// m_log.DebugFormat(
3413// "[SCENE OBJECT GROUP]: Updating group rotation R of {0} {1} to {2}", Name, LocalId, rot);
3414
3415// SceneObjectPart[] parts = m_parts.GetArray();
3416// for (int i = 0; i < parts.Length; i++)
3417// parts[i].StoreUndoState();
3418
3419// m_rootPart.StoreUndoState(true);
3420
3421// m_rootPart.UpdateRotation(rot);
3422
3423 PhysicsActor actor = m_rootPart.PhysActor; 3370 PhysicsActor actor = m_rootPart.PhysActor;
3424 if (actor != null) 3371 if (actor != null)
3425 { 3372 {
@@ -3438,16 +3385,6 @@ namespace OpenSim.Region.Framework.Scenes
3438 /// <param name="rot"></param> 3385 /// <param name="rot"></param>
3439 public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) 3386 public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot)
3440 { 3387 {
3441// m_log.DebugFormat(
3442// "[SCENE OBJECT GROUP]: Updating group rotation PR of {0} {1} to {2}", Name, LocalId, rot);
3443
3444// SceneObjectPart[] parts = m_parts.GetArray();
3445// for (int i = 0; i < parts.Length; i++)
3446// parts[i].StoreUndoState();
3447
3448// RootPart.StoreUndoState(true);
3449// RootPart.IgnoreUndoUpdate = true;
3450
3451 m_rootPart.UpdateRotation(rot); 3388 m_rootPart.UpdateRotation(rot);
3452 3389
3453 PhysicsActor actor = m_rootPart.PhysActor; 3390 PhysicsActor actor = m_rootPart.PhysActor;
@@ -3461,8 +3398,6 @@ namespace OpenSim.Region.Framework.Scenes
3461 3398
3462 HasGroupChanged = true; 3399 HasGroupChanged = true;
3463 ScheduleGroupForTerseUpdate(); 3400 ScheduleGroupForTerseUpdate();
3464
3465// RootPart.IgnoreUndoUpdate = false;
3466 } 3401 }
3467 3402
3468 /// <summary> 3403 /// <summary>
@@ -3477,9 +3412,6 @@ namespace OpenSim.Region.Framework.Scenes
3477 3412
3478 if (part != null) 3413 if (part != null)
3479 { 3414 {
3480// m_log.DebugFormat(
3481// "[SCENE OBJECT GROUP]: Updating single rotation of {0} {1} to {2}", part.Name, part.LocalId, rot);
3482
3483 if (m_rootPart.PhysActor != null) 3415 if (m_rootPart.PhysActor != null)
3484 m_rootPart.PhysActor.Building = true; 3416 m_rootPart.PhysActor.Building = true;
3485 3417
@@ -3507,30 +3439,13 @@ namespace OpenSim.Region.Framework.Scenes
3507 SceneObjectPart part = GetChildPart(localID); 3439 SceneObjectPart part = GetChildPart(localID);
3508 if (part != null) 3440 if (part != null)
3509 { 3441 {
3510// m_log.DebugFormat(
3511// "[SCENE OBJECT GROUP]: Updating single position and rotation of {0} {1} to {2}",
3512// part.Name, part.LocalId, rot);
3513
3514// part.StoreUndoState();
3515// part.IgnoreUndoUpdate = true;
3516
3517 if (m_rootPart.PhysActor != null) 3442 if (m_rootPart.PhysActor != null)
3518 m_rootPart.PhysActor.Building = true; 3443 m_rootPart.PhysActor.Building = true;
3519 3444
3520 if (part.UUID == m_rootPart.UUID) 3445 if (part.UUID == m_rootPart.UUID)
3521 { 3446 {
3522 UpdateRootRotation(rot); 3447 UpdateRootRotation(rot);
3523/* if (!m_rootPart.Undoing) 3448 AbsolutePosition = pos;
3524 {
3525 m_rootPart.Undoing = true;
3526 AbsolutePosition = pos;
3527 m_rootPart.Undoing = false;
3528 }
3529 else
3530 {
3531 */
3532 AbsolutePosition = pos;
3533// }
3534 } 3449 }
3535 else 3450 else
3536 { 3451 {
@@ -3540,8 +3455,6 @@ namespace OpenSim.Region.Framework.Scenes
3540 3455
3541 if (m_rootPart.PhysActor != null) 3456 if (m_rootPart.PhysActor != null)
3542 m_rootPart.PhysActor.Building = false; 3457 m_rootPart.PhysActor.Building = false;
3543
3544// part.IgnoreUndoUpdate = false;
3545 } 3458 }
3546 } 3459 }
3547 3460
@@ -3551,13 +3464,9 @@ namespace OpenSim.Region.Framework.Scenes
3551 /// <param name="rot"></param> 3464 /// <param name="rot"></param>
3552 public void UpdateRootRotation(Quaternion rot) 3465 public void UpdateRootRotation(Quaternion rot)
3553 { 3466 {
3554// m_log.DebugFormat( 3467 // needs to be called with phys building true
3555// "[SCENE OBJECT GROUP]: Updating root rotation of {0} {1} to {2}",
3556// Name, LocalId, rot);
3557
3558 Quaternion axRot = rot; 3468 Quaternion axRot = rot;
3559 Quaternion oldParentRot = m_rootPart.RotationOffset; 3469 Quaternion oldParentRot = m_rootPart.RotationOffset;
3560// m_rootPart.StoreUndoState();
3561 3470
3562 //Don't use UpdateRotation because it schedules an update prematurely 3471 //Don't use UpdateRotation because it schedules an update prematurely
3563 m_rootPart.RotationOffset = rot; 3472 m_rootPart.RotationOffset = rot;
@@ -3573,8 +3482,6 @@ namespace OpenSim.Region.Framework.Scenes
3573 SceneObjectPart prim = parts[i]; 3482 SceneObjectPart prim = parts[i];
3574 if (prim.UUID != m_rootPart.UUID) 3483 if (prim.UUID != m_rootPart.UUID)
3575 { 3484 {
3576// prim.IgnoreUndoUpdate = true;
3577
3578 Quaternion NewRot = oldParentRot * prim.RotationOffset; 3485 Quaternion NewRot = oldParentRot * prim.RotationOffset;
3579 NewRot = Quaternion.Inverse(axRot) * NewRot; 3486 NewRot = Quaternion.Inverse(axRot) * NewRot;
3580 prim.RotationOffset = NewRot; 3487 prim.RotationOffset = NewRot;
@@ -3584,26 +3491,88 @@ namespace OpenSim.Region.Framework.Scenes
3584 axPos *= oldParentRot; 3491 axPos *= oldParentRot;
3585 axPos *= Quaternion.Inverse(axRot); 3492 axPos *= Quaternion.Inverse(axRot);
3586 prim.OffsetPosition = axPos; 3493 prim.OffsetPosition = axPos;
3587
3588// prim.IgnoreUndoUpdate = false;
3589 } 3494 }
3590 } 3495 }
3591 3496
3592// for (int i = 0; i < parts.Length; i++)
3593// {
3594// SceneObjectPart childpart = parts[i];
3595// if (childpart != m_rootPart)
3596// {
3597//// childpart.IgnoreUndoUpdate = false;
3598//// childpart.StoreUndoState();
3599// }
3600// }
3601 HasGroupChanged = true; 3497 HasGroupChanged = true;
3602 ScheduleGroupForFullUpdate(); 3498 ScheduleGroupForFullUpdate();
3499 }
3603 3500
3604// m_log.DebugFormat( 3501 public void doChangeObject(SceneObjectPart part, ObjectChangeData data)
3605// "[SCENE OBJECT GROUP]: Updated root rotation of {0} {1} to {2}", 3502 {
3606// 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 }
3607 } 3576 }
3608 3577
3609 #endregion 3578 #endregion
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 6622495..f70b259 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -263,8 +263,7 @@ namespace OpenSim.Region.Framework.Scenes
263 private bool m_occupied; // KF if any av is sitting on this prim 263 private bool m_occupied; // KF if any av is sitting on this prim
264 private string m_text = String.Empty; 264 private string m_text = String.Empty;
265 private string m_touchName = String.Empty; 265 private string m_touchName = String.Empty;
266 private Stack<UndoState> m_undo = new Stack<UndoState>(5); 266 private UndoRedoState m_UndoRedo = new UndoRedoState(5);
267 private Stack<UndoState> m_redo = new Stack<UndoState>(5);
268 267
269 private bool m_passTouches; 268 private bool m_passTouches;
270 269
@@ -1709,8 +1708,8 @@ namespace OpenSim.Region.Framework.Scenes
1709 dupe.Category = Category; 1708 dupe.Category = Category;
1710 dupe.m_rezzed = m_rezzed; 1709 dupe.m_rezzed = m_rezzed;
1711 1710
1712 dupe.m_undo = new Stack<UndoState>(5); 1711 dupe.m_UndoRedo = new UndoRedoState(5);
1713 dupe.m_redo = new Stack<UndoState>(5); 1712
1714 dupe.IgnoreUndoUpdate = false; 1713 dupe.IgnoreUndoUpdate = false;
1715 dupe.Undoing = false; 1714 dupe.Undoing = false;
1716 1715
@@ -1944,6 +1943,7 @@ namespace OpenSim.Region.Framework.Scenes
1944 1943
1945 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 1944 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1946 PhysActor.OnOutOfBounds += PhysicsOutOfBounds; 1945 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1946
1947 if (ParentID != 0 && ParentID != LocalId) 1947 if (ParentID != 0 && ParentID != LocalId)
1948 { 1948 {
1949 if (ParentGroup.RootPart.PhysActor != null) 1949 if (ParentGroup.RootPart.PhysActor != null)
@@ -3657,43 +3657,13 @@ namespace OpenSim.Region.Framework.Scenes
3657 //ParentGroup.ScheduleGroupForFullUpdate(); 3657 //ParentGroup.ScheduleGroupForFullUpdate();
3658 } 3658 }
3659 3659
3660 public void StoreUndoState() 3660 public void StoreUndoState(ObjectChangeWhat what)
3661 {
3662 StoreUndoState(false);
3663 }
3664
3665 public void StoreUndoState(bool forGroup)
3666 { 3661 {
3667 if (!Undoing && !IgnoreUndoUpdate) // just to read better - undo is in progress, or suspended 3662 lock (m_UndoRedo)
3668 { 3663 {
3669 if (ParentGroup != null) 3664 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3670 { 3665 {
3671 lock (m_undo) 3666 m_UndoRedo.StoreUndo(this, what);
3672 {
3673 if (m_undo.Count > 0)
3674 {
3675 // see if we had a change
3676
3677 UndoState last = m_undo.Peek();
3678 if (last != null)
3679 {
3680 if (last.Compare(this, forGroup))
3681 {
3682 return;
3683 }
3684 }
3685 }
3686
3687 if (ParentGroup.GetSceneMaxUndo() > 0)
3688 {
3689 UndoState nUndo = new UndoState(this, forGroup);
3690
3691 m_undo.Push(nUndo);
3692
3693 if (m_redo.Count > 0)
3694 m_redo.Clear();
3695 }
3696 }
3697 } 3667 }
3698 } 3668 }
3699 } 3669 }
@@ -3705,84 +3675,42 @@ namespace OpenSim.Region.Framework.Scenes
3705 { 3675 {
3706 get 3676 get
3707 { 3677 {
3708 lock (m_undo) 3678 lock (m_UndoRedo)
3709 return m_undo.Count; 3679 return m_UndoRedo.Count;
3710 } 3680 }
3711 } 3681 }
3712 3682
3713 public void Undo() 3683 public void Undo()
3714 { 3684 {
3715 lock (m_undo) 3685 lock (m_UndoRedo)
3716 { 3686 {
3717// m_log.DebugFormat( 3687 if (Undoing || ParentGroup == null)
3718// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}", 3688 return;
3719// Name, LocalId, m_undo.Count);
3720
3721 if (m_undo.Count > 0)
3722 {
3723 UndoState goback = m_undo.Pop();
3724
3725 if (goback != null)
3726 {
3727 UndoState nUndo = null;
3728
3729 if (ParentGroup.GetSceneMaxUndo() > 0)
3730 {
3731 nUndo = new UndoState(this, goback.ForGroup);
3732 }
3733
3734 goback.PlayState(this);
3735
3736 if (nUndo != null)
3737 m_redo.Push(nUndo);
3738 }
3739 }
3740 3689
3741// m_log.DebugFormat( 3690 Undoing = true;
3742// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3691 m_UndoRedo.Undo(this);
3743// Name, LocalId, m_undo.Count); 3692 Undoing = false;
3744 } 3693 }
3745 } 3694 }
3746 3695
3747 public void Redo() 3696 public void Redo()
3748 { 3697 {
3749 lock (m_undo) 3698 lock (m_UndoRedo)
3750 { 3699 {
3751// m_log.DebugFormat( 3700 if (Undoing || ParentGroup == null)
3752// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}", 3701 return;
3753// Name, LocalId, m_redo.Count);
3754
3755 if (m_redo.Count > 0)
3756 {
3757 UndoState gofwd = m_redo.Pop();
3758
3759 if (gofwd != null)
3760 {
3761 if (ParentGroup.GetSceneMaxUndo() > 0)
3762 {
3763 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3764
3765 m_undo.Push(nUndo);
3766 }
3767
3768 gofwd.PlayState(this);
3769 }
3770 3702
3771// m_log.DebugFormat( 3703 Undoing = true;
3772// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3704 m_UndoRedo.Redo(this);
3773// Name, LocalId, m_redo.Count); 3705 Undoing = false;
3774 }
3775 } 3706 }
3776 } 3707 }
3777 3708
3778 public void ClearUndoState() 3709 public void ClearUndoState()
3779 { 3710 {
3780// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3711 lock (m_UndoRedo)
3781
3782 lock (m_undo)
3783 { 3712 {
3784 m_undo.Clear(); 3713 m_UndoRedo.Clear();
3785 m_redo.Clear();
3786 } 3714 }
3787 } 3715 }
3788 3716
diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs
index 38474de..668b53b 100644
--- a/OpenSim/Region/Framework/Scenes/UndoState.cs
+++ b/OpenSim/Region/Framework/Scenes/UndoState.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using System.Collections.Generic;
30using log4net; 31using log4net;
31using OpenMetaverse; 32using OpenMetaverse;
32using OpenSim.Region.Framework.Interfaces; 33using OpenSim.Region.Framework.Interfaces;
@@ -34,6 +35,8 @@ using System;
34 35
35namespace OpenSim.Region.Framework.Scenes 36namespace OpenSim.Region.Framework.Scenes
36{ 37{
38
39/*
37 [Flags] 40 [Flags]
38 public enum UndoType 41 public enum UndoType
39 { 42 {
@@ -48,6 +51,7 @@ namespace OpenSim.Region.Framework.Scenes
48 STATE_ALL = 63 51 STATE_ALL = 63
49 } 52 }
50 53
54
51 public class UndoState 55 public class UndoState
52 { 56 {
53 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 57 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -121,9 +125,16 @@ namespace OpenSim.Region.Framework.Scenes
121 public void PlayState(SceneObjectPart part) 125 public void PlayState(SceneObjectPart part)
122 { 126 {
123 part.Undoing = true; 127 part.Undoing = true;
124 128 bool physbuilding = false;
129
125 if (part.ParentID == 0) 130 if (part.ParentID == 0)
126 { 131 {
132 if (!ForGroup && part.PhysActor != null)
133 {
134 part.PhysActor.Building = true;
135 physbuilding = true;
136 }
137
127 if (Position != Vector3.Zero) 138 if (Position != Vector3.Zero)
128 { 139 {
129 if (ForGroup) 140 if (ForGroup)
@@ -139,17 +150,34 @@ namespace OpenSim.Region.Framework.Scenes
139 150
140 if (Scale != Vector3.Zero) 151 if (Scale != Vector3.Zero)
141 { 152 {
153 if (!physbuilding && part.PhysActor != null)
154 {
155 part.PhysActor.Building = true;
156 physbuilding = true;
157 }
158
142 if (ForGroup) 159 if (ForGroup)
143 part.ParentGroup.GroupResize(Scale); 160 part.ParentGroup.GroupResize(Scale);
144 else 161 else
145 part.Resize(Scale); 162 part.Resize(Scale);
146 } 163 }
164
165 if (physbuilding)
166 part.PhysActor.Building = false;
167
147 part.ParentGroup.ScheduleGroupForTerseUpdate(); 168 part.ParentGroup.ScheduleGroupForTerseUpdate();
148 } 169 }
149 else 170 else
150 { 171 {
151 if (ForGroup) // trap for group since seems parts can't do it 172 if (ForGroup) // trap for group since seems parts can't do it
152 return; 173 return;
174
175 // changing a part invalidates entire object physical rep
176 if (part.ParentGroup != null && part.ParentGroup.RootPart != null && part.ParentGroup.RootPart.PhysActor != null)
177 {
178 part.ParentGroup.RootPart.PhysActor.Building = true;
179 physbuilding = true;
180 }
153 181
154 // Note: Updating these properties on sop automatically schedules an update if needed 182 // Note: Updating these properties on sop automatically schedules an update if needed
155 part.OffsetPosition = Position; 183 part.OffsetPosition = Position;
@@ -158,11 +186,264 @@ namespace OpenSim.Region.Framework.Scenes
158 { 186 {
159 part.Resize(Scale); 187 part.Resize(Scale);
160 } 188 }
189
190 if (physbuilding)
191 part.ParentGroup.RootPart.PhysActor.Building = false;
161 } 192 }
162 193
163 part.Undoing = false; 194 part.Undoing = false;
164 } 195 }
165 } 196 }
197*/
198 public class UndoState
199 {
200 const int UNDOEXPIRESECONDS = 300; // undo expire time (nice to have it came from a ini later)
201
202 public ObjectChangeData data;
203 public DateTime creationtime;
204 /// <summary>
205 /// Constructor.
206 /// </summary>
207 /// <param name="part"></param>
208 /// <param name="forGroup">True if the undo is for an entire group</param>
209 /// only for root parts ????
210 public UndoState(SceneObjectPart part, ObjectChangeWhat what)
211 {
212 data = new ObjectChangeData();
213 data.what = what;
214 creationtime = DateTime.UtcNow;
215
216 if (part.ParentGroup.RootPart == part)
217 {
218 if ((what & ObjectChangeWhat.Position) != 0)
219 data.position = part.ParentGroup.AbsolutePosition;
220 if ((what & ObjectChangeWhat.Rotation) != 0)
221 data.rotation = part.RotationOffset;
222 if ((what & ObjectChangeWhat.Scale) != 0)
223 data.scale = part.Shape.Scale;
224 }
225 else
226 {
227 if ((what & ObjectChangeWhat.Position) != 0)
228 data.position = part.OffsetPosition;
229 if ((what & ObjectChangeWhat.Rotation) != 0)
230 data.rotation = part.RotationOffset;
231 if ((what & ObjectChangeWhat.Scale) != 0)
232 data.scale = part.Shape.Scale;
233 }
234 }
235
236 public bool checkExpire()
237 {
238 TimeSpan t = DateTime.UtcNow - creationtime;
239 if (t.Seconds > UNDOEXPIRESECONDS)
240 return true;
241 return false;
242 }
243
244 public void updateExpire()
245 {
246 creationtime = DateTime.UtcNow;
247 }
248
249 /// <summary>
250 /// Compare the relevant state in the given part to this state.
251 /// </summary>
252 /// <param name="part"></param>
253 /// <returns>true if both the part's position, rotation and scale match those in this undo state. False otherwise.</returns>
254 public bool Compare(SceneObjectPart part, ObjectChangeWhat what)
255 {
256 if (data.what != what) // if diferent targets, then they are diferent
257 return false;
258
259 if (part != null)
260 {
261 if (part.ParentID == 0)
262 {
263 if ((what & ObjectChangeWhat.Position) != 0 && data.position != part.ParentGroup.AbsolutePosition)
264 return false;
265 }
266 else
267 {
268 if ((what & ObjectChangeWhat.Position) != 0 && data.position != part.OffsetPosition)
269 return false;
270 }
271
272 if ((what & ObjectChangeWhat.Rotation) != 0 && data.rotation != part.RotationOffset)
273 return false;
274 if ((what & ObjectChangeWhat.Rotation) != 0 && data.scale == part.Shape.Scale)
275 return false;
276 return true;
277
278 }
279 return false;
280 }
281
282 public void PlayState(SceneObjectPart part)
283 {
284 part.Undoing = true;
285
286 SceneObjectGroup grp = part.ParentGroup;
287
288 if (grp != null)
289 {
290 grp.doChangeObject(part, data);
291 }
292 part.Undoing = false;
293 }
294 }
295
296 public class UndoRedoState
297 {
298 int size;
299 public LinkedList<UndoState> m_redo = new LinkedList<UndoState>();
300 public LinkedList<UndoState> m_undo = new LinkedList<UndoState>();
301
302 public UndoRedoState()
303 {
304 size = 5;
305 }
306
307 public UndoRedoState(int _size)
308 {
309 if (_size < 3)
310 size = 3;
311 else
312 size = _size;
313 }
314
315 public int Count
316 {
317 get { return m_undo.Count; }
318 }
319
320 public void Clear()
321 {
322 m_undo.Clear();
323 m_redo.Clear();
324 }
325
326 public void StoreUndo(SceneObjectPart part, ObjectChangeWhat what)
327 {
328 lock (m_undo)
329 {
330 UndoState last;
331
332 if (m_redo.Count > 0) // last code seems to clear redo on every new undo
333 {
334 m_redo.Clear();
335 }
336
337 if (m_undo.Count > 0)
338 {
339 // check expired entry
340 last = m_undo.First.Value;
341 if (last != null && last.checkExpire())
342 m_undo.Clear();
343 else
344 {
345 // see if we actually have a change
346 if (last != null)
347 {
348 if (last.Compare(part, what))
349 return;
350 }
351 }
352 }
353
354 // limite size
355 while (m_undo.Count >= size)
356 m_undo.RemoveLast();
357
358 UndoState nUndo = new UndoState(part, what);
359 m_undo.AddFirst(nUndo);
360 }
361 }
362
363 public void Undo(SceneObjectPart part)
364 {
365 lock (m_undo)
366 {
367 UndoState nUndo;
368
369 // expire redo
370 if (m_redo.Count > 0)
371 {
372 nUndo = m_redo.First.Value;
373 if (nUndo != null && nUndo.checkExpire())
374 m_redo.Clear();
375 }
376
377 if (m_undo.Count > 0)
378 {
379 UndoState goback = m_undo.First.Value;
380 // check expired
381 if (goback != null && goback.checkExpire())
382 {
383 m_undo.Clear();
384 return;
385 }
386
387 if (goback != null)
388 {
389 m_undo.RemoveFirst();
390
391 // redo limite size
392 while (m_redo.Count >= size)
393 m_redo.RemoveLast();
394
395 nUndo = new UndoState(part, goback.data.what); // new value in part should it be full goback copy?
396 m_redo.AddFirst(nUndo);
397
398 goback.PlayState(part);
399 }
400 }
401 }
402 }
403
404 public void Redo(SceneObjectPart part)
405 {
406 lock (m_undo)
407 {
408 UndoState nUndo;
409
410 // expire undo
411 if (m_undo.Count > 0)
412 {
413 nUndo = m_undo.First.Value;
414 if (nUndo != null && nUndo.checkExpire())
415 m_undo.Clear();
416 }
417
418 if (m_redo.Count > 0)
419 {
420 UndoState gofwd = m_redo.First.Value;
421 // check expired
422 if (gofwd != null && gofwd.checkExpire())
423 {
424 m_redo.Clear();
425 return;
426 }
427
428 if (gofwd != null)
429 {
430 m_redo.RemoveFirst();
431
432 // limite undo size
433 while (m_undo.Count >= size)
434 m_undo.RemoveLast();
435
436 nUndo = new UndoState(part, gofwd.data.what); // new value in part should it be full gofwd copy?
437 m_undo.AddFirst(nUndo);
438
439 gofwd.PlayState(part);
440 }
441 }
442 }
443 }
444
445
446 }
166 447
167 public class LandUndoState 448 public class LandUndoState
168 { 449 {
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 0f62b2a..18f8f34 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -714,6 +714,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
714 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 714 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
715 public event UpdatePrimFlags OnUpdatePrimFlags; 715 public event UpdatePrimFlags OnUpdatePrimFlags;
716 public event UpdatePrimTexture OnUpdatePrimTexture; 716 public event UpdatePrimTexture OnUpdatePrimTexture;
717 public event ClientChangeObject onClientChangeObject;
717 public event UpdateVector OnUpdatePrimGroupPosition; 718 public event UpdateVector OnUpdatePrimGroupPosition;
718 public event UpdateVector OnUpdatePrimSinglePosition; 719 public event UpdateVector OnUpdatePrimSinglePosition;
719 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 720 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index d88b2bd..5b9b071 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -243,6 +243,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
243 public event UpdatePrimTexture OnUpdatePrimTexture; 243 public event UpdatePrimTexture OnUpdatePrimTexture;
244 public event UpdateVector OnUpdatePrimGroupPosition; 244 public event UpdateVector OnUpdatePrimGroupPosition;
245 public event UpdateVector OnUpdatePrimSinglePosition; 245 public event UpdateVector OnUpdatePrimSinglePosition;
246 public event ClientChangeObject onClientChangeObject;
246 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 247 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
247 public event UpdatePrimSingleRotationPosition OnUpdatePrimSingleRotationPosition; 248 public event UpdatePrimSingleRotationPosition OnUpdatePrimSingleRotationPosition;
248 public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation; 249 public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation;
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index b105f77..563d527 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -1524,17 +1524,19 @@ namespace OpenSim.Region.Physics.OdePlugin
1524 { 1524 {
1525 prm.m_collisionCategories |= CollisionCategories.Body; 1525 prm.m_collisionCategories |= CollisionCategories.Body;
1526 prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); 1526 prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1527 d.GeomEnable(prm.prim_geom);
1527 } 1528 }
1528 1529
1529 if (prm.m_NoColide) 1530 if (prm.m_NoColide)
1530 { 1531 {
1531 d.GeomSetCategoryBits(prm.prim_geom, 0); 1532 d.GeomSetCategoryBits(prm.prim_geom, 0);
1532 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land); 1533 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
1534 d.GeomEnable(prm.prim_geom);
1533 } 1535 }
1534 else 1536 else
1535 { 1537 {
1536 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); 1538 d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories);
1537 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); 1539 d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags);
1538 } 1540 }
1539 prm.m_collisionscore = 0; 1541 prm.m_collisionscore = 0;
1540 1542
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index fa750ab..be6b81b 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -135,6 +135,7 @@ namespace OpenSim.Tests.Common.Mock
135 public event GenericCall7 OnObjectMaterial; 135 public event GenericCall7 OnObjectMaterial;
136 public event UpdatePrimFlags OnUpdatePrimFlags; 136 public event UpdatePrimFlags OnUpdatePrimFlags;
137 public event UpdatePrimTexture OnUpdatePrimTexture; 137 public event UpdatePrimTexture OnUpdatePrimTexture;
138 public event ClientChangeObject onClientChangeObject;
138 public event UpdateVector OnUpdatePrimGroupPosition; 139 public event UpdateVector OnUpdatePrimGroupPosition;
139 public event UpdateVector OnUpdatePrimSinglePosition; 140 public event UpdateVector OnUpdatePrimSinglePosition;
140 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 141 public event UpdatePrimRotation OnUpdatePrimGroupRotation;