From 6865f1c67d8f4b6fa44ddd9f3040a29e9e180950 Mon Sep 17 00:00:00 2001
From: Charles Krinke
Date: Sat, 19 Apr 2008 21:01:26 +0000
Subject: Thank you kindly krtaylor for a patch to solve: Linked objects won't
 scale together properly, only the root object scales. This happens with
 scaling both up and down or inputting numbers in the edit dialog.

---
 OpenSim/Region/ClientStack/ClientView.cs           | 30 ++++++++++++---
 OpenSim/Region/Environment/Scenes/InnerScene.cs    | 11 ++++++
 OpenSim/Region/Environment/Scenes/Scene.cs         |  1 +
 .../Region/Environment/Scenes/SceneObjectGroup.cs  | 44 +++++++++++++++++++++-
 .../Region/Examples/SimpleModule/MyNpcCharacter.cs |  1 +
 5 files changed, 80 insertions(+), 7 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs
index 89b0400..292f7f6 100644
--- a/OpenSim/Region/ClientStack/ClientView.cs
+++ b/OpenSim/Region/ClientStack/ClientView.cs
@@ -222,6 +222,7 @@ namespace OpenSim.Region.ClientStack
         private UpdateVector handlerUpdatePrimSinglePosition = null; //OnUpdatePrimSinglePosition;
         private UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = null; //OnUpdatePrimSingleRotation;
         private UpdateVector handlerUpdatePrimScale = null; //OnUpdatePrimScale;
+        private UpdateVector handlerUpdatePrimGroupScale = null; //OnUpdateGroupScale;
         private UpdateVector handlerUpdateVector = null; //OnUpdatePrimGroupPosition;
         private UpdatePrimRotation handlerUpdatePrimRotation = null; //OnUpdatePrimGroupRotation;
         private UpdatePrimGroupRotation handlerUpdatePrimGroupRotation = null; //OnUpdatePrimGroupMouseRotation;
@@ -712,6 +713,7 @@ namespace OpenSim.Region.ClientStack
         public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation;
         public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation;
         public event UpdateVector OnUpdatePrimScale;
+        public event UpdateVector OnUpdatePrimGroupScale;
         public event StatusChange OnChildAgentStatus;
         public event GenericCall2 OnStopMovement;
         public event Action<LLUUID> OnRemoveAvatar;
@@ -2590,6 +2592,7 @@ namespace OpenSim.Region.ClientStack
                             case 5:
 
                                 LLVector3 scale1 = new LLVector3(block.Data, 12);
+                                LLVector3 pos11 = new LLVector3(block.Data, 0);
 
                                 handlerUpdatePrimScale = OnUpdatePrimScale;
                                 if (handlerUpdatePrimScale != null)
@@ -2597,6 +2600,13 @@ namespace OpenSim.Region.ClientStack
 
                                     // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
                                     handlerUpdatePrimScale(localId, scale1, this);
+
+                                    
+                                    handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition;
+                                    if (handlerUpdatePrimSinglePosition != null)
+                                    {
+                                        handlerUpdatePrimSinglePosition(localId, pos11, this);
+                                    }
                                 }
                                 break;
                             case 9:
@@ -2661,27 +2671,35 @@ namespace OpenSim.Region.ClientStack
                                 LLVector3 scale5 = new LLVector3(block.Data, 12);
                                 LLVector3 pos5 = new LLVector3(block.Data, 0);
 
-                                handlerUpdatePrimScale = OnUpdatePrimScale;
-                                if (handlerUpdatePrimScale != null)
+                                handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale;
+                                if (handlerUpdatePrimGroupScale != null)
                                 {
 
                                     // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z );
-                                    handlerUpdatePrimScale(localId, scale5, this);
+                                    handlerUpdatePrimGroupScale(localId, scale5, this);
+                                    handlerUpdateVector = OnUpdatePrimGroupPosition;
 
-                                    handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition;
-                                    if (handlerUpdatePrimSinglePosition != null)
+                                    if (handlerUpdateVector != null)
                                     {
-                                        handlerUpdatePrimSinglePosition(localId, pos5, this);
+
+                                        handlerUpdateVector(localId, pos5, this);
                                     }
                                 }
                                 break;
                             case 21:
                                 LLVector3 scale6 = new LLVector3(block.Data, 12);
+                                LLVector3 pos6 = new LLVector3(block.Data, 0);
+
                                 handlerUpdatePrimScale = OnUpdatePrimScale;
                                 if (handlerUpdatePrimScale != null)
                                 {
                                     // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
                                     handlerUpdatePrimScale(localId, scale6, this);
+                                    handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition;
+                                    if (handlerUpdatePrimSinglePosition != null)
+                                    {
+                                        handlerUpdatePrimSinglePosition(localId, pos6, this);
+                                    }
                                 }
                                 break;
                         }
diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs
index ea4283f..8894db0 100644
--- a/OpenSim/Region/Environment/Scenes/InnerScene.cs
+++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs
@@ -890,6 +890,17 @@ namespace OpenSim.Region.Environment.Scenes
                 }
             }
         }
+        public void UpdatePrimGroupScale(uint localID, LLVector3 scale, IClientAPI remoteClient)
+        {
+            SceneObjectGroup group = GetGroupByPrim(localID);
+            if (group != null)
+            {
+                if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))
+                {
+                    group.GroupResize(scale, localID);
+                }
+            }
+        }
 
         /// <summary>
         /// This handles the nifty little tool tip that you get when you drag your mouse over an object 
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index b81b2d4..c5ed958 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -1513,6 +1513,7 @@ namespace OpenSim.Region.Environment.Scenes
             client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation;
             client.OnUpdatePrimSingleRotation += m_innerScene.UpdatePrimSingleRotation;
             client.OnUpdatePrimScale += m_innerScene.UpdatePrimScale;
+            client.OnUpdatePrimGroupScale += m_innerScene.UpdatePrimGroupScale;
             client.OnUpdateExtraParams += m_innerScene.UpdateExtraParam;
             client.OnUpdatePrimShape += m_innerScene.UpdatePrimShape;
             client.OnRequestMapBlocks += RequestMapBlocks;
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
index 3a9e52a..1f38e4f 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
@@ -1520,7 +1520,7 @@ namespace OpenSim.Region.Environment.Scenes
                             new PhysicsVector(scale.X, scale.Y, scale.Z);
                     m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
                 }
-                if (part.UUID != m_rootPart.UUID)
+                //if (part.UUID != m_rootPart.UUID)
                     ScheduleGroupForFullUpdate();
 
                 //if (part.UUID == m_rootPart.UUID)
@@ -1534,6 +1534,48 @@ namespace OpenSim.Region.Environment.Scenes
                 //}
             }
         }
+        public void GroupResize(LLVector3 scale, uint localID)
+        {
+            SceneObjectPart part = GetChildPart(localID);
+            if (part != null)
+            {
+                float x = (scale.X / part.Scale.X);
+                float y = (scale.Y / part.Scale.Y);
+                float z = (scale.Z / part.Scale.Z);
+                part.Resize(scale);
+                
+                lock (m_parts)
+                {
+                    foreach (SceneObjectPart obPart in m_parts.Values)
+                    {
+                        if (obPart.UUID != m_rootPart.UUID)
+                        {
+                            
+                            LLVector3 currentpos = new LLVector3(obPart.OffsetPosition);
+                            currentpos.X *= x;
+                            currentpos.Y *= y;
+                            currentpos.Z *= z;
+                            LLVector3 newSize = new LLVector3(obPart.Scale);
+                            newSize.X *= x;
+                            newSize.Y *= y;
+                            newSize.Z *= z;
+                            obPart.Resize(newSize);
+                            obPart.UpdateOffSet(currentpos);
+                        }
+                    }
+                }
+            
+                if (part.PhysActor != null)
+                {
+                    part.PhysActor.Size =
+                            new PhysicsVector(scale.X, scale.Y, scale.Z);
+                    m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
+                }
+                
+
+                    ScheduleGroupForTerseUpdate();
+            }
+        }
 
         #endregion
 
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index a9f7fb9..4ce68da 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -109,6 +109,7 @@ namespace OpenSim.Region.Examples.SimpleModule
         public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation;
         public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation;
         public event UpdateVector OnUpdatePrimScale;
+        public event UpdateVector OnUpdatePrimGroupScale;
         public event StatusChange OnChildAgentStatus;
         public event GenericCall2 OnStopMovement;
         public event Action<LLUUID> OnRemoveAvatar;
-- 
cgit v1.1