diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 0cd738daa3..739d23d350 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -4161,6 +4161,103 @@ namespace OpenSim.Region.Framework.Scenes } + public bool GroupResize(double fscale) + { +// m_log.DebugFormat( +// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, fscale); + + if (Scene == null || IsDeleted || inTransit || fscale < 0) + return false; + + // ignore lsl restrictions. let them be done a LSL + PhysicsActor pa = m_rootPart.PhysActor; + + if(RootPart.KeyframeMotion != null) + RootPart.KeyframeMotion.Suspend(); + + float minsize = Scene.m_minNonphys; + float maxsize = Scene.m_maxNonphys; + + // assuming physics is more restrictive + if (pa != null && pa.IsPhysical) + { + minsize = Scene.m_minPhys; + maxsize = Scene.m_maxPhys; + } + + SceneObjectPart[] parts = m_parts.GetArray(); + float tmp; + // check scaling factor so parts don't violate dimensions + for(int i = 0; i < parts.Length; i++) + { + SceneObjectPart obPart = parts[i]; + Vector3 oldSize = new Vector3(obPart.Scale); + tmp = (float)(oldSize.X * fscale); + if(tmp > maxsize) + return false; + if(tmp < minsize) + return false; + + tmp = (float)(oldSize.Y * fscale); + if(tmp > maxsize) + return false; + if(tmp < minsize) + return false; + + tmp = (float)(oldSize.Z * fscale); + if(tmp > maxsize) + return false; + if(tmp < minsize) + return false; + } + + Vector3 newSize = RootPart.Scale; + newSize.X = (float)(newSize.X * fscale); + newSize.Y = (float)(newSize.Y * fscale); + newSize.Z = (float)(newSize.Z * fscale); + + if(pa != null) + pa.Building = true; + + RootPart.Scale = newSize; + + Vector3 currentpos; + for (int i = 0; i < parts.Length; i++) + { + SceneObjectPart obPart = parts[i]; + + if (obPart.UUID != m_rootPart.UUID) + { + currentpos = obPart.OffsetPosition; + currentpos.X = (float)(currentpos.X * fscale); + currentpos.Y = (float)(currentpos.Y * fscale); + currentpos.Z = (float)(currentpos.Z * fscale); + + newSize = obPart.Scale; + newSize.X = (float)(newSize.X * fscale); + newSize.Y = (float)(newSize.Y * fscale); + newSize.Z = (float)(newSize.Z * fscale); + + obPart.Scale = newSize; + obPart.UpdateOffSet(currentpos); + } + } + + if(pa != null) + pa.Building = false; + + InvalidBoundsRadius(); + + HasGroupChanged = true; + m_rootPart.TriggerScriptChangedEvent(Changed.SCALE); + ScheduleGroupForFullUpdate(); + + if(RootPart.KeyframeMotion != null) + RootPart.KeyframeMotion.Resume(); + + return true; + } + #endregion #region Position diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b5abdb597d..c43aef58f4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1808,45 +1808,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); SceneObjectGroup group = m_host.ParentGroup; + if(scaling_factor < 1e-6) + return ScriptBaseClass.FALSE; + if(scaling_factor > 1e6) + return ScriptBaseClass.FALSE; + + if (group == null || group.IsDeleted || group.inTransit) + return ScriptBaseClass.FALSE; + if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical) return ScriptBaseClass.FALSE; if (group.RootPart.KeyframeMotion != null) return ScriptBaseClass.FALSE; - List prims = GetLinkParts(ScriptBaseClass.LINK_SET); - if (prims.Count > 0) - { - foreach (SceneObjectPart prim in prims) - { - LSL_Vector size = new LSL_Vector(prim.Scale.X, prim.Scale.Y, prim.Scale.Z); - LSL_Vector new_size = new LSL_Vector(scaling_factor * size); - - new_size.x = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, new_size.x)); - new_size.y = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, new_size.y)); - new_size.z = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, new_size.z)); - - if (new_size.x != scaling_factor * size.x || new_size.y != scaling_factor * size.y || new_size.z != scaling_factor * size.z) - return ScriptBaseClass.FALSE; - - LSL_Vector position = new LSL_Vector(GetPartLocalPos(prim)); - - if (!prim.IsRoot) - { - position = GetSetPosTarget(prim, scaling_factor * position, position, true); - prim.OffsetPosition = position; - prim.ScheduleTerseUpdate(); - } - - SetScale(prim, new_size); - } - + if(group.GroupResize(scaling_factor)) return ScriptBaseClass.TRUE; - } else - { return ScriptBaseClass.FALSE; - } } public void llSetScale(LSL_Vector scale)