aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorTom2011-09-04 08:30:23 -0700
committerTom2011-09-04 08:30:23 -0700
commit9cc2d0b60ae3398cf0a2f2ea144c331fa73d3e76 (patch)
treec1cceaf0ae11f55eb8242cc961b8c3b340a92ef8
parentChange of tactic. Reverting this to the careminster version, then i'll select... (diff)
downloadopensim-SC-9cc2d0b60ae3398cf0a2f2ea144c331fa73d3e76.zip
opensim-SC-9cc2d0b60ae3398cf0a2f2ea144c331fa73d3e76.tar.gz
opensim-SC-9cc2d0b60ae3398cf0a2f2ea144c331fa73d3e76.tar.bz2
opensim-SC-9cc2d0b60ae3398cf0a2f2ea144c331fa73d3e76.tar.xz
Now merging the core changes.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs865
1 files changed, 444 insertions, 421 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 6c47645..88a6232 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -209,27 +209,89 @@ namespace OpenSim.Region.Framework.Scenes
209 return true; 209 return true;
210 return false; 210 return false;
211 } 211 }
212 212
213 /// <value> 213 /// <summary>
214 /// Is this scene object acting as an attachment? 214 /// Is this scene object acting as an attachment?
215 /// 215 /// </summary>
216 /// We return false if the group has already been deleted. 216 public bool IsAttachment { get; set; }
217 /// 217
218 /// TODO: At the moment set must be done on the part itself. There may be a case for doing it here since I 218 /// <summary>
219 /// presume either all or no parts in a linkset can be part of an attachment (in which 219 /// The avatar to which this scene object is attached.
220 /// case the value would get proprogated down into all the descendent parts). 220 /// </summary>
221 /// </value> 221 /// <remarks>
222 public bool IsAttachment 222 /// If we're not attached to an avatar then this is UUID.Zero
223 /// </remarks>
224 public UUID AttachedAvatar { get; set; }
225
226 /// <summary>
227 /// Attachment point of this scene object to an avatar.
228 /// </summary>
229 /// <remarks>
230 /// 0 if we're not attached to anything
231 /// </remarks>
232 public uint AttachmentPoint
223 { 233 {
224 get 234 get
225 { 235 {
226 if (!IsDeleted) 236 return m_rootPart.Shape.State;
227 return m_rootPart.IsAttachment; 237 }
228 238
229 return false; 239 set
240 {
241 IsAttachment = value != 0;
242 m_rootPart.Shape.State = (byte)value;
230 } 243 }
231 } 244 }
232 245
246 public void ClearPartAttachmentData()
247 {
248 AttachmentPoint = 0;
249
250 // Even though we don't use child part state parameters for attachments any more, we still need to set
251 // these to zero since having them non-zero in rezzed scene objects will crash some clients. Even if
252 // we store them correctly, scene objects that we receive from elsewhere might not.
253 foreach (SceneObjectPart part in Parts)
254 part.Shape.State = 0;
255 }
256
257 /// <summary>
258 /// Is this scene object phantom?
259 /// </summary>
260 /// <remarks>
261 /// Updating must currently take place through UpdatePrimFlags()
262 /// </remarks>
263 public bool IsPhantom
264 {
265 get { return (RootPart.Flags & PrimFlags.Phantom) != 0; }
266 }
267
268 /// <summary>
269 /// Does this scene object use physics?
270 /// </summary>
271 /// <remarks>
272 /// Updating must currently take place through UpdatePrimFlags()
273 /// </remarks>
274 public bool UsesPhysics
275 {
276 get { return (RootPart.Flags & PrimFlags.TemporaryOnRez) != 0; }
277 }
278
279 /// <summary>
280 /// Is this scene object temporary?
281 /// </summary>
282 /// <remarks>
283 /// Updating must currently take place through UpdatePrimFlags()
284 /// </remarks>
285 public bool IsTemporary
286 {
287 get { return (RootPart.Flags & PrimFlags.TemporaryOnRez) != 0; }
288 }
289
290 public bool IsVolumeDetect
291 {
292 get { return RootPart.VolumeDetectActive; }
293 }
294
233 public float scriptScore; 295 public float scriptScore;
234 296
235 private Vector3 lastPhysGroupPos; 297 private Vector3 lastPhysGroupPos;
@@ -261,11 +323,7 @@ namespace OpenSim.Region.Framework.Scenes
261 /// </summary> 323 /// </summary>
262 public override string Name 324 public override string Name
263 { 325 {
264 get { 326 get { return RootPart.Name; }
265 if (RootPart == null)
266 return String.Empty;
267 return RootPart.Name;
268 }
269 set { RootPart.Name = value; } 327 set { RootPart.Name = value; }
270 } 328 }
271 329
@@ -305,6 +363,38 @@ namespace OpenSim.Region.Framework.Scenes
305 get { return m_rootPart.RotationOffset; } 363 get { return m_rootPart.RotationOffset; }
306 } 364 }
307 365
366 public Vector3 GroupScale
367 {
368 get
369 {
370 Vector3 minScale = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize);
371 Vector3 maxScale = Vector3.Zero;
372 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
373
374 SceneObjectPart[] parts = m_parts.GetArray();
375 for (int i = 0; i < parts.Length; i++)
376 {
377 SceneObjectPart part = parts[i];
378 Vector3 partscale = part.Scale;
379 Vector3 partoffset = part.OffsetPosition;
380
381 minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X;
382 minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y;
383 minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z;
384
385 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
386 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
387 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
388 }
389
390 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
391 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
392 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
393
394 return finalScale;
395 }
396 }
397
308 public UUID GroupID 398 public UUID GroupID
309 { 399 {
310 get { return m_rootPart.GroupID; } 400 get { return m_rootPart.GroupID; }
@@ -344,11 +434,13 @@ namespace OpenSim.Region.Framework.Scenes
344 /// <summary> 434 /// <summary>
345 /// Check both the attachment property and the relevant properties of the underlying root part. 435 /// Check both the attachment property and the relevant properties of the underlying root part.
346 /// </summary> 436 /// </summary>
437 /// <remarks>
347 /// This is necessary in some cases, particularly when a scene object has just crossed into a region and doesn't 438 /// This is necessary in some cases, particularly when a scene object has just crossed into a region and doesn't
348 /// have the IsAttachment property yet checked. 439 /// have the IsAttachment property yet checked.
349 /// 440 ///
350 /// FIXME: However, this should be fixed so that this property 441 /// FIXME: However, this should be fixed so that this property
351 /// propertly reflects the underlying status. 442 /// propertly reflects the underlying status.
443 /// </remarks>
352 /// <returns></returns> 444 /// <returns></returns>
353 public bool IsAttachmentCheckFull() 445 public bool IsAttachmentCheckFull()
354 { 446 {
@@ -682,7 +774,7 @@ namespace OpenSim.Region.Framework.Scenes
682 part.ParentID = m_rootPart.LocalId; 774 part.ParentID = m_rootPart.LocalId;
683 //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID); 775 //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID);
684 } 776 }
685 777
686 ApplyPhysics(m_scene.m_physicalPrim); 778 ApplyPhysics(m_scene.m_physicalPrim);
687 779
688 if (RootPart.PhysActor != null) 780 if (RootPart.PhysActor != null)
@@ -693,34 +785,6 @@ namespace OpenSim.Region.Framework.Scenes
693 //ScheduleGroupForFullUpdate(); 785 //ScheduleGroupForFullUpdate();
694 } 786 }
695 787
696 public Vector3 GroupScale()
697 {
698 Vector3 minScale = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize);
699 Vector3 maxScale = Vector3.Zero;
700 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
701
702 SceneObjectPart[] parts = m_parts.GetArray();
703 for (int i = 0; i < parts.Length; i++)
704 {
705 SceneObjectPart part = parts[i];
706 Vector3 partscale = part.Scale;
707 Vector3 partoffset = part.OffsetPosition;
708
709 minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X;
710 minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y;
711 minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z;
712
713 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
714 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
715 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
716 }
717
718 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
719 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
720 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
721 return finalScale;
722
723 }
724 public EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly, bool faceCenters) 788 public EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly, bool faceCenters)
725 { 789 {
726 // We got a request from the inner_scene to raytrace along the Ray hRay 790 // We got a request from the inner_scene to raytrace along the Ray hRay
@@ -1324,7 +1388,7 @@ namespace OpenSim.Region.Framework.Scenes
1324 1388
1325 part.LinkNum = m_parts.Count; 1389 part.LinkNum = m_parts.Count;
1326 1390
1327 if (part.LinkNum == 2 && RootPart != null) 1391 if (part.LinkNum == 2)
1328 RootPart.LinkNum = 1; 1392 RootPart.LinkNum = 1;
1329 } 1393 }
1330 1394
@@ -1407,7 +1471,11 @@ namespace OpenSim.Region.Framework.Scenes
1407 1471
1408 public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient) 1472 public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient)
1409 { 1473 {
1410 part.StoreUndoState(UndoType.STATE_PRIM_ALL); 1474// m_log.DebugFormat(
1475// "[SCENE OBJECT GROUP]: Processing OnGrabPart for {0} on {1} {2}, offsetPos {3}",
1476// remoteClient.Name, part.Name, part.LocalId, offsetPos);
1477
1478 part.StoreUndoState();
1411 part.OnGrab(offsetPos, remoteClient); 1479 part.OnGrab(offsetPos, remoteClient);
1412 } 1480 }
1413 1481
@@ -1720,12 +1788,19 @@ namespace OpenSim.Region.Framework.Scenes
1720 1788
1721 // This is only necessary when userExposed is false! 1789 // This is only necessary when userExposed is false!
1722 1790
1723 bool previousAttachmentStatus = dupe.RootPart.IsAttachment; 1791 bool previousAttachmentStatus = dupe.IsAttachment;
1792
1793 if (!userExposed)
1794 dupe.IsAttachment = true;
1724 1795
1725 if (!userExposed) 1796 if (!userExposed)
1726 dupe.RootPart.IsAttachment = true; 1797 dupe.RootPart.IsAttachment = true;
1727 1798
1728 dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); 1799 dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z);
1800 if (!userExposed)
1801 {
1802 dupe.IsAttachment = previousAttachmentStatus;
1803 }
1729 1804
1730 if (!userExposed) 1805 if (!userExposed)
1731 { 1806 {
@@ -1782,6 +1857,22 @@ namespace OpenSim.Region.Framework.Scenes
1782 dupe.AttachToBackup(); 1857 dupe.AttachToBackup();
1783 1858
1784 ScheduleGroupForFullUpdate(); 1859 ScheduleGroupForFullUpdate();
1860 // Need to duplicate the physics actor as well
1861 if (part.PhysActor != null && userExposed)
1862 {
1863 PrimitiveBaseShape pbs = newPart.Shape;
1864
1865 newPart.PhysActor
1866 = m_scene.PhysicsScene.AddPrimShape(
1867 string.Format("{0}/{1}", newPart.Name, newPart.UUID),
1868 pbs,
1869 newPart.AbsolutePosition,
1870 newPart.Scale,
1871 newPart.RotationOffset,
1872 part.PhysActor.IsPhysical,
1873 newPart.LocalId);
1874
1875 newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true);
1785 } 1876 }
1786 } 1877 }
1787 finally 1878 finally
@@ -1802,36 +1893,24 @@ namespace OpenSim.Region.Framework.Scenes
1802 SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed)); 1893 SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed));
1803 } 1894 }
1804 1895
1805 public void ScriptSetPhysicsStatus(bool UsePhysics) 1896 public void ScriptSetPhysicsStatus(bool usePhysics)
1806 { 1897 {
1807 bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0); 1898 UpdatePrimFlags(RootPart.LocalId, usePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
1808 bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
1809 bool IsVolumeDetect = RootPart.VolumeDetectActive;
1810 UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
1811 } 1899 }
1812 1900
1813 public void ScriptSetTemporaryStatus(bool TemporaryStatus) 1901 public void ScriptSetTemporaryStatus(bool makeTemporary)
1814 { 1902 {
1815 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 1903 UpdatePrimFlags(RootPart.LocalId, UsesPhysics, makeTemporary, IsPhantom, IsVolumeDetect);
1816 bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
1817 bool IsVolumeDetect = RootPart.VolumeDetectActive;
1818 UpdatePrimFlags(RootPart.LocalId, UsePhysics, TemporaryStatus, IsPhantom, IsVolumeDetect);
1819 } 1904 }
1820 1905
1821 public void ScriptSetPhantomStatus(bool PhantomStatus) 1906 public void ScriptSetPhantomStatus(bool makePhantom)
1822 { 1907 {
1823 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 1908 UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, makePhantom, IsVolumeDetect);
1824 bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
1825 bool IsVolumeDetect = RootPart.VolumeDetectActive;
1826 UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, PhantomStatus, IsVolumeDetect);
1827 } 1909 }
1828 1910
1829 public void ScriptSetVolumeDetect(bool VDStatus) 1911 public void ScriptSetVolumeDetect(bool makeVolumeDetect)
1830 { 1912 {
1831 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 1913 UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, IsPhantom, makeVolumeDetect);
1832 bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
1833 bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
1834 UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom, VDStatus);
1835 1914
1836 /* 1915 /*
1837 ScriptSetPhantomStatus(false); // What ever it was before, now it's not phantom anymore 1916 ScriptSetPhantomStatus(false); // What ever it was before, now it's not phantom anymore
@@ -1849,120 +1928,80 @@ namespace OpenSim.Region.Framework.Scenes
1849 1928
1850 public void applyImpulse(Vector3 impulse) 1929 public void applyImpulse(Vector3 impulse)
1851 { 1930 {
1852 // We check if rootpart is null here because scripts don't delete if you delete the host. 1931 if (IsAttachment)
1853 // This means that unfortunately, we can pass a null physics actor to Simulate!
1854 // Make sure we don't do that!
1855 SceneObjectPart rootpart = m_rootPart;
1856 if (rootpart != null)
1857 { 1932 {
1858 if (IsAttachment) 1933 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
1934 if (avatar != null)
1859 { 1935 {
1860 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); 1936 avatar.PushForce(impulse);
1861 if (avatar != null)
1862 {
1863 avatar.PushForce(impulse);
1864 }
1865 } 1937 }
1866 else 1938 }
1939 else
1940 {
1941 if (RootPart.PhysActor != null)
1867 { 1942 {
1868 if (rootpart.PhysActor != null) 1943 RootPart.PhysActor.AddForce(impulse, true);
1869 { 1944 m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor);
1870 rootpart.PhysActor.AddForce(impulse, true);
1871 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
1872 }
1873 } 1945 }
1874 } 1946 }
1875 } 1947 }
1876 1948
1877 public void applyAngularImpulse(Vector3 impulse) 1949 public void applyAngularImpulse(Vector3 impulse)
1878 { 1950 {
1879 // We check if rootpart is null here because scripts don't delete if you delete the host. 1951 if (RootPart.PhysActor != null)
1880 // This means that unfortunately, we can pass a null physics actor to Simulate!
1881 // Make sure we don't do that!
1882 SceneObjectPart rootpart = m_rootPart;
1883 if (rootpart != null)
1884 { 1952 {
1885 if (rootpart.PhysActor != null) 1953 if (!IsAttachment)
1886 { 1954 {
1887 if (!IsAttachment) 1955 RootPart.PhysActor.AddAngularForce(impulse, true);
1888 { 1956 m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor);
1889 rootpart.PhysActor.AddAngularForce(impulse, true);
1890 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
1891 }
1892 } 1957 }
1893 } 1958 }
1894 } 1959 }
1895 1960
1896 public void setAngularImpulse(Vector3 impulse) 1961 public void setAngularImpulse(Vector3 impulse)
1897 { 1962 {
1898 // We check if rootpart is null here because scripts don't delete if you delete the host. 1963 if (RootPart.PhysActor != null)
1899 // This means that unfortunately, we can pass a null physics actor to Simulate!
1900 // Make sure we don't do that!
1901 SceneObjectPart rootpart = m_rootPart;
1902 if (rootpart != null)
1903 { 1964 {
1904 if (rootpart.PhysActor != null) 1965 if (!IsAttachment)
1905 { 1966 {
1906 if (!IsAttachment) 1967 RootPart.PhysActor.Torque = impulse;
1907 { 1968 m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor);
1908 rootpart.PhysActor.Torque = impulse;
1909 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
1910 }
1911 } 1969 }
1912 } 1970 }
1913 } 1971 }
1914 1972
1915 public Vector3 GetTorque() 1973 public Vector3 GetTorque()
1916 { 1974 {
1917 // We check if rootpart is null here because scripts don't delete if you delete the host. 1975 if (RootPart.PhysActor != null)
1918 // This means that unfortunately, we can pass a null physics actor to Simulate!
1919 // Make sure we don't do that!
1920 SceneObjectPart rootpart = m_rootPart;
1921 if (rootpart != null)
1922 { 1976 {
1923 if (rootpart.PhysActor != null) 1977 if (!IsAttachment)
1924 { 1978 {
1925 if (!IsAttachment) 1979 Vector3 torque = RootPart.PhysActor.Torque;
1926 { 1980 return torque;
1927 Vector3 torque = rootpart.PhysActor.Torque;
1928 return torque;
1929 }
1930 } 1981 }
1931 } 1982 }
1983
1932 return Vector3.Zero; 1984 return Vector3.Zero;
1933 } 1985 }
1934 1986
1935 // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object 1987 // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object
1936 public void moveToTarget(Vector3 target, float tau) 1988 public void moveToTarget(Vector3 target, float tau)
1937 { 1989 {
1938 SceneObjectPart rootpart = m_rootPart; 1990 if (IsAttachment)
1939 if (rootpart != null)
1940 { 1991 {
1941 if (IsAttachment) 1992 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
1993 if (avatar != null)
1942 { 1994 {
1943 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); 1995 avatar.MoveToTarget(target, false);
1944 if (avatar != null)
1945 {
1946 List<string> coords = new List<string>();
1947 uint regionX = 0;
1948 uint regionY = 0;
1949 Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY);
1950 target.X += regionX;
1951 target.Y += regionY;
1952 coords.Add(target.X.ToString());
1953 coords.Add(target.Y.ToString());
1954 coords.Add(target.Z.ToString());
1955 avatar.DoMoveToPosition(avatar, "", coords);
1956 }
1957 } 1996 }
1958 else 1997 }
1998 else
1999 {
2000 if (RootPart.PhysActor != null)
1959 { 2001 {
1960 if (rootpart.PhysActor != null) 2002 RootPart.PhysActor.PIDTarget = target;
1961 { 2003 RootPart.PhysActor.PIDTau = tau;
1962 rootpart.PhysActor.PIDTarget = target; 2004 RootPart.PhysActor.PIDActive = true;
1963 rootpart.PhysActor.PIDTau = tau;
1964 rootpart.PhysActor.PIDActive = true;
1965 }
1966 } 2005 }
1967 } 2006 }
1968 } 2007 }
@@ -2035,22 +2074,18 @@ namespace OpenSim.Region.Framework.Scenes
2035 /// <param name="tau">Number of seconds over which to reach target</param> 2074 /// <param name="tau">Number of seconds over which to reach target</param>
2036 public void SetHoverHeight(float height, PIDHoverType hoverType, float tau) 2075 public void SetHoverHeight(float height, PIDHoverType hoverType, float tau)
2037 { 2076 {
2038 SceneObjectPart rootpart = m_rootPart; 2077 if (RootPart.PhysActor != null)
2039 if (rootpart != null)
2040 { 2078 {
2041 if (rootpart.PhysActor != null) 2079 if (height != 0f)
2042 { 2080 {
2043 if (height != 0f) 2081 RootPart.PhysActor.PIDHoverHeight = height;
2044 { 2082 RootPart.PhysActor.PIDHoverType = hoverType;
2045 rootpart.PhysActor.PIDHoverHeight = height; 2083 RootPart.PhysActor.PIDTau = tau;
2046 rootpart.PhysActor.PIDHoverType = hoverType; 2084 RootPart.PhysActor.PIDHoverActive = true;
2047 rootpart.PhysActor.PIDTau = tau; 2085 }
2048 rootpart.PhysActor.PIDHoverActive = true; 2086 else
2049 } 2087 {
2050 else 2088 RootPart.PhysActor.PIDHoverActive = false;
2051 {
2052 rootpart.PhysActor.PIDHoverActive = false;
2053 }
2054 } 2089 }
2055 } 2090 }
2056 } 2091 }
@@ -2145,7 +2180,7 @@ namespace OpenSim.Region.Framework.Scenes
2145 // an object has been deleted from a scene before update was processed. 2180 // an object has been deleted from a scene before update was processed.
2146 // A more fundamental overhaul of the update mechanism is required to eliminate all 2181 // A more fundamental overhaul of the update mechanism is required to eliminate all
2147 // the race conditions. 2182 // the race conditions.
2148 if (m_isDeleted) 2183 if (IsDeleted)
2149 return; 2184 return;
2150 2185
2151 // Even temporary objects take part in physics (e.g. temp-on-rez bullets) 2186 // Even temporary objects take part in physics (e.g. temp-on-rez bullets)
@@ -2458,7 +2493,7 @@ namespace OpenSim.Region.Framework.Scenes
2458 } 2493 }
2459 2494
2460 m_scene.UnlinkSceneObject(objectGroup, true); 2495 m_scene.UnlinkSceneObject(objectGroup, true);
2461 objectGroup.m_isDeleted = true; 2496 objectGroup.IsDeleted = true;
2462 2497
2463 objectGroup.m_parts.Clear(); 2498 objectGroup.m_parts.Clear();
2464 2499
@@ -2596,8 +2631,7 @@ namespace OpenSim.Region.Framework.Scenes
2596 public virtual void DetachFromBackup() 2631 public virtual void DetachFromBackup()
2597 { 2632 {
2598 m_scene.SceneGraph.FireDetachFromBackup(this); 2633 m_scene.SceneGraph.FireDetachFromBackup(this);
2599 2634 if (m_isBackedUp && Scene != null)
2600 if (m_isBackedUp)
2601 m_scene.EventManager.OnBackup -= ProcessBackup; 2635 m_scene.EventManager.OnBackup -= ProcessBackup;
2602 2636
2603 m_isBackedUp = false; 2637 m_isBackedUp = false;
@@ -2857,14 +2891,15 @@ namespace OpenSim.Region.Framework.Scenes
2857 /// Update prim flags for this group. 2891 /// Update prim flags for this group.
2858 /// </summary> 2892 /// </summary>
2859 /// <param name="localID"></param> 2893 /// <param name="localID"></param>
2860 /// <param name="type"></param> 2894 /// <param name="UsePhysics"></param>
2861 /// <param name="inUse"></param> 2895 /// <param name="SetTemporary"></param>
2862 /// <param name="data"></param> 2896 /// <param name="SetPhantom"></param>
2863 public void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVolumeDetect) 2897 /// <param name="SetVolumeDetect"></param>
2898 public void UpdatePrimFlags(uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect)
2864 { 2899 {
2865 SceneObjectPart selectionPart = GetChildPart(localID); 2900 SceneObjectPart selectionPart = GetChildPart(localID);
2866 2901
2867 if (IsTemporary) 2902 if (SetTemporary && Scene != null)
2868 { 2903 {
2869 DetachFromBackup(); 2904 DetachFromBackup();
2870 // Remove from database and parcel prim count 2905 // Remove from database and parcel prim count
@@ -2876,23 +2911,27 @@ namespace OpenSim.Region.Framework.Scenes
2876 if (selectionPart != null) 2911 if (selectionPart != null)
2877 { 2912 {
2878 SceneObjectPart[] parts = m_parts.GetArray(); 2913 SceneObjectPart[] parts = m_parts.GetArray();
2879 for (int i = 0; i < parts.Length; i++) 2914
2915 if (Scene != null)
2880 { 2916 {
2881 SceneObjectPart part = parts[i]; 2917 for (int i = 0; i < parts.Length; i++)
2882 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2883 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
2884 part.Scale.Z > m_scene.RegionInfo.PhysPrimMax)
2885 { 2918 {
2886 UsePhysics = false; // Reset physics 2919 SceneObjectPart part = parts[i];
2887 break; 2920 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2921 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
2922 part.Scale.Z > m_scene.RegionInfo.PhysPrimMax)
2923 {
2924 UsePhysics = false; // Reset physics
2925 break;
2926 }
2888 } 2927 }
2889 } 2928 }
2890 2929
2891 RootPart.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2930 RootPart.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, SetVolumeDetect);
2892 for (int i = 0; i < parts.Length; i++) 2931 for (int i = 0; i < parts.Length; i++)
2893 { 2932 {
2894 if (parts[i] != RootPart) 2933 if (parts[i] != RootPart)
2895 parts[i].UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2934 parts[i].UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, SetVolumeDetect);
2896 } 2935 }
2897 } 2936 }
2898 } 2937 }
@@ -2966,202 +3005,152 @@ namespace OpenSim.Region.Framework.Scenes
2966 #region Resize 3005 #region Resize
2967 3006
2968 /// <summary> 3007 /// <summary>
2969 /// Resize the given part 3008 /// Resize the entire group of prims.
2970 /// </summary> 3009 /// </summary>
2971 /// <param name="scale"></param> 3010 /// <param name="scale"></param>
2972 /// <param name="localID"></param> 3011 public void GroupResize(Vector3 scale)
2973 public void Resize(Vector3 scale, uint localID) 3012 {
2974 { 3013// m_log.DebugFormat(
2975 if (scale.X > m_scene.m_maxNonphys) 3014// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale);
2976 scale.X = m_scene.m_maxNonphys; 3015 RootPart.StoreUndoState(true);
2977 if (scale.Y > m_scene.m_maxNonphys)
2978 scale.Y = m_scene.m_maxNonphys;
2979 if (scale.Z > m_scene.m_maxNonphys)
2980 scale.Z = m_scene.m_maxNonphys;
2981 SceneObjectPart part = GetChildPart(localID);
2982 if (part != null)
2983 {
2984 if (part.PhysActor != null)
2985 {
2986 if (part.PhysActor.IsPhysical)
2987 {
2988 if (scale.X > m_scene.m_maxPhys)
2989 scale.X = m_scene.m_maxPhys;
2990 if (scale.Y > m_scene.m_maxPhys)
2991 scale.Y = m_scene.m_maxPhys;
2992 if (scale.Z > m_scene.m_maxPhys)
2993 scale.Z = m_scene.m_maxPhys;
2994 }
2995 part.PhysActor.Size = scale;
2996 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2997 }
2998 part.Resize(scale);
2999 3016
3000 HasGroupChanged = true; 3017 scale.X = Math.Min(scale.X, Scene.m_maxNonphys);
3001 part.TriggerScriptChangedEvent(Changed.SCALE); 3018 scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys);
3002 ScheduleGroupForFullUpdate(); 3019 scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys);
3003 3020
3004 //if (part.UUID == m_rootPart.UUID) 3021 if (RootPart.PhysActor != null && RootPart.PhysActor.IsPhysical)
3005 //{ 3022 {
3006 //if (m_rootPart.PhysActor != null) 3023 scale.X = Math.Min(scale.X, Scene.m_maxPhys);
3007 //{ 3024 scale.Y = Math.Min(scale.Y, Scene.m_maxPhys);
3008 //m_rootPart.PhysActor.Size = 3025 scale.Z = Math.Min(scale.Z, Scene.m_maxPhys);
3009 //new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z);
3010 //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3011 //}
3012 //}
3013 } 3026 }
3014 }
3015 3027
3016 public void GroupResize(Vector3 scale, uint localID) 3028 float x = (scale.X / RootPart.Scale.X);
3017 { 3029 float y = (scale.Y / RootPart.Scale.Y);
3018 SceneObjectPart part = GetChildPart(localID); 3030 float z = (scale.Z / RootPart.Scale.Z);
3019 if (part != null) 3031
3032 SceneObjectPart[] parts;
3033 if (x > 1.0f || y > 1.0f || z > 1.0f)
3020 { 3034 {
3021 if (scale.X > m_scene.m_maxNonphys) 3035 parts = m_parts.GetArray();
3022 scale.X = m_scene.m_maxNonphys; 3036 for (int i = 0; i < parts.Length; i++)
3023 if (scale.Y > m_scene.m_maxNonphys) 3037 {
3024 scale.Y = m_scene.m_maxNonphys; 3038 SceneObjectPart obPart = parts[i];
3025 if (scale.Z > m_scene.m_maxNonphys) 3039 if (obPart.UUID != m_rootPart.UUID)
3026 scale.Z = m_scene.m_maxNonphys;
3027 if (part.PhysActor != null && part.PhysActor.IsPhysical)
3028 {
3029 if (scale.X > m_scene.m_maxPhys)
3030 scale.X = m_scene.m_maxPhys;
3031 if (scale.Y > m_scene.m_maxPhys)
3032 scale.Y = m_scene.m_maxPhys;
3033 if (scale.Z > m_scene.m_maxPhys)
3034 scale.Z = m_scene.m_maxPhys;
3035 }
3036 float x = (scale.X / part.Scale.X);
3037 float y = (scale.Y / part.Scale.Y);
3038 float z = (scale.Z / part.Scale.Z);
3039
3040 SceneObjectPart[] parts;
3041 if (x > 1.0f || y > 1.0f || z > 1.0f)
3042 {
3043 parts = m_parts.GetArray();
3044 for (int i = 0; i < parts.Length; i++)
3045 { 3040 {
3046 SceneObjectPart obPart = parts[i]; 3041// obPart.IgnoreUndoUpdate = true;
3047 if (obPart.UUID != m_rootPart.UUID) 3042 Vector3 oldSize = new Vector3(obPart.Scale);
3043
3044 float f = 1.0f;
3045 float a = 1.0f;
3046
3047 if (RootPart.PhysActor != null && RootPart.PhysActor.IsPhysical)
3048 { 3048 {
3049 obPart.IgnoreUndoUpdate = true; 3049 if (oldSize.X * x > m_scene.m_maxPhys)
3050 Vector3 oldSize = new Vector3(obPart.Scale); 3050 {
3051 f = m_scene.m_maxPhys / oldSize.X;
3052 a = f / x;
3053 x *= a;
3054 y *= a;
3055 z *= a;
3056 }
3051 3057
3052 float f = 1.0f; 3058 if (oldSize.Y * y > m_scene.m_maxPhys)
3053 float a = 1.0f; 3059 {
3060 f = m_scene.m_maxPhys / oldSize.Y;
3061 a = f / y;
3062 x *= a;
3063 y *= a;
3064 z *= a;
3065 }
3054 3066
3055 if (part.PhysActor != null && part.PhysActor.IsPhysical) 3067 if (oldSize.Z * z > m_scene.m_maxPhys)
3056 { 3068 {
3057 if (oldSize.X*x > m_scene.m_maxPhys) 3069 f = m_scene.m_maxPhys / oldSize.Z;
3058 { 3070 a = f / z;
3059 f = m_scene.m_maxPhys / oldSize.X; 3071 x *= a;
3060 a = f / x; 3072 y *= a;
3061 x *= a; 3073 z *= a;
3062 y *= a;
3063 z *= a;
3064 }
3065 if (oldSize.Y*y > m_scene.m_maxPhys)
3066 {
3067 f = m_scene.m_maxPhys / oldSize.Y;
3068 a = f / y;
3069 x *= a;
3070 y *= a;
3071 z *= a;
3072 }
3073 if (oldSize.Z*z > m_scene.m_maxPhys)
3074 {
3075 f = m_scene.m_maxPhys / oldSize.Z;
3076 a = f / z;
3077 x *= a;
3078 y *= a;
3079 z *= a;
3080 }
3081 } 3074 }
3082 else 3075 }
3076 else
3077 {
3078 if (oldSize.X * x > m_scene.m_maxNonphys)
3083 { 3079 {
3084 if (oldSize.X*x > m_scene.m_maxNonphys) 3080 f = m_scene.m_maxNonphys / oldSize.X;
3085 { 3081 a = f / x;
3086 f = m_scene.m_maxNonphys / oldSize.X; 3082 x *= a;
3087 a = f / x; 3083 y *= a;
3088 x *= a; 3084 z *= a;
3089 y *= a; 3085 }
3090 z *= a; 3086
3091 } 3087 if (oldSize.Y * y > m_scene.m_maxNonphys)
3092 if (oldSize.Y*y > m_scene.m_maxNonphys) 3088 {
3093 { 3089 f = m_scene.m_maxNonphys / oldSize.Y;
3094 f = m_scene.m_maxNonphys / oldSize.Y; 3090 a = f / y;
3095 a = f / y; 3091 x *= a;
3096 x *= a; 3092 y *= a;
3097 y *= a; 3093 z *= a;
3098 z *= a; 3094 }
3099 } 3095
3100 if (oldSize.Z*z > m_scene.m_maxNonphys) 3096 if (oldSize.Z * z > m_scene.m_maxNonphys)
3101 { 3097 {
3102 f = m_scene.m_maxNonphys / oldSize.Z; 3098 f = m_scene.m_maxNonphys / oldSize.Z;
3103 a = f / z; 3099 a = f / z;
3104 x *= a; 3100 x *= a;
3105 y *= a; 3101 y *= a;
3106 z *= a; 3102 z *= a;
3107 }
3108 } 3103 }
3109 obPart.IgnoreUndoUpdate = false;
3110 } 3104 }
3105
3106// obPart.IgnoreUndoUpdate = false;
3111 } 3107 }
3112 } 3108 }
3109 }
3113 3110
3114 Vector3 prevScale = part.Scale; 3111 Vector3 prevScale = RootPart.Scale;
3115 prevScale.X *= x; 3112 prevScale.X *= x;
3116 prevScale.Y *= y; 3113 prevScale.Y *= y;
3117 prevScale.Z *= z;; 3114 prevScale.Z *= z;
3118
3119 part.IgnoreUndoUpdate = false;
3120 part.StoreUndoState(UndoType.STATE_GROUP_SCALE);
3121 part.IgnoreUndoUpdate = true;
3122 part.Resize(prevScale);
3123 part.IgnoreUndoUpdate = false; 3115 part.IgnoreUndoUpdate = false;
3124 3116
3125 parts = m_parts.GetArray(); 3117// RootPart.IgnoreUndoUpdate = true;
3126 for (int i = 0; i < parts.Length; i++) 3118 RootPart.Resize(prevScale);
3119// RootPart.IgnoreUndoUpdate = false;
3120
3121 parts = m_parts.GetArray();
3122 for (int i = 0; i < parts.Length; i++)
3123 {
3124 SceneObjectPart obPart = parts[i];
3125
3126 if (obPart.UUID != m_rootPart.UUID)
3127 { 3127 {
3128 SceneObjectPart obPart = parts[i];
3129 obPart.IgnoreUndoUpdate = true; 3128 obPart.IgnoreUndoUpdate = true;
3130 if (obPart.UUID != m_rootPart.UUID)
3131 {
3132 if (obPart.UUID != m_rootPart.UUID)
3133 {
3134 obPart.IgnoreUndoUpdate = false;
3135 obPart.StoreUndoState(UndoType.STATE_GROUP_SCALE);
3136 obPart.IgnoreUndoUpdate = true;
3137
3138 Vector3 currentpos = new Vector3(obPart.OffsetPosition);
3139 currentpos.X *= x;
3140 currentpos.Y *= y;
3141 currentpos.Z *= z;
3142 Vector3 newSize = new Vector3(obPart.Scale);
3143 newSize.X *= x;
3144 newSize.Y *= y;
3145 newSize.Z *= z;
3146 obPart.Resize(newSize);
3147 obPart.UpdateOffSet(currentpos);
3148 }
3149 obPart.IgnoreUndoUpdate = false;
3150 }
3151 obPart.IgnoreUndoUpdate = false;
3152 }
3153 3129
3154 if (part.PhysActor != null) 3130 Vector3 currentpos = new Vector3(obPart.OffsetPosition);
3155 { 3131 currentpos.X *= x;
3156 part.PhysActor.Size = prevScale; 3132 currentpos.Y *= y;
3157 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 3133 currentpos.Z *= z;
3134
3135 Vector3 newSize = new Vector3(obPart.Scale);
3136 newSize.X *= x;
3137 newSize.Y *= y;
3138 newSize.Z *= z;
3139
3140 obPart.Resize(newSize);
3141 obPart.UpdateOffSet(currentpos);
3142
3143 obPart.IgnoreUndoUpdate = false;
3158 } 3144 }
3159 3145
3160 part.IgnoreUndoUpdate = false; 3146// obPart.IgnoreUndoUpdate = false;
3161 HasGroupChanged = true; 3147 HasGroupChanged = true;
3162 m_rootPart.TriggerScriptChangedEvent(Changed.SCALE); 3148 m_rootPart.TriggerScriptChangedEvent(Changed.SCALE);
3163 ScheduleGroupForTerseUpdate(); 3149 ScheduleGroupForTerseUpdate();
3164 } 3150 }
3151
3152// m_log.DebugFormat(
3153// "[SCENE OBJECT GROUP]: Finished group resizing {0} {1} to {2}", Name, LocalId, RootPart.Scale);
3165 } 3154 }
3166 3155
3167 #endregion 3156 #endregion
@@ -3174,6 +3163,14 @@ namespace OpenSim.Region.Framework.Scenes
3174 /// <param name="pos"></param> 3163 /// <param name="pos"></param>
3175 public void UpdateGroupPosition(Vector3 pos) 3164 public void UpdateGroupPosition(Vector3 pos)
3176 { 3165 {
3166// m_log.DebugFormat("[SCENE OBJECT GROUP]: Updating group position on {0} {1} to {2}", Name, LocalId, pos);
3167
3168 RootPart.StoreUndoState(true);
3169
3170// SceneObjectPart[] parts = m_parts.GetArray();
3171// for (int i = 0; i < parts.Length; i++)
3172// parts[i].StoreUndoState();
3173
3177 if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) 3174 if (m_scene.EventManager.TriggerGroupMove(UUID, pos))
3178 { 3175 {
3179 if (IsAttachment) 3176 if (IsAttachment)
@@ -3210,12 +3207,18 @@ namespace OpenSim.Region.Framework.Scenes
3210 { 3207 {
3211 SceneObjectPart part = GetChildPart(localID); 3208 SceneObjectPart part = GetChildPart(localID);
3212 3209
3213 SceneObjectPart[] parts = m_parts.GetArray(); 3210// SceneObjectPart[] parts = m_parts.GetArray();
3214 for (int i = 0; i < parts.Length; i++) 3211// for (int i = 0; i < parts.Length; i++)
3215 parts[i].StoreUndoState(UndoType.STATE_PRIM_POSITION); 3212// parts[i].StoreUndoState();
3216 3213
3217 if (part != null) 3214 if (part != null)
3218 { 3215 {
3216// m_log.DebugFormat(
3217// "[SCENE OBJECT GROUP]: Updating single position of {0} {1} to {2}", part.Name, part.LocalId, pos);
3218
3219 part.StoreUndoState(false);
3220 part.IgnoreUndoUpdate = true;
3221
3219 if (part.UUID == m_rootPart.UUID) 3222 if (part.UUID == m_rootPart.UUID)
3220 { 3223 {
3221 UpdateRootPosition(pos); 3224 UpdateRootPosition(pos);
@@ -3226,18 +3229,22 @@ namespace OpenSim.Region.Framework.Scenes
3226 } 3229 }
3227 3230
3228 HasGroupChanged = true; 3231 HasGroupChanged = true;
3232 part.IgnoreUndoUpdate = false;
3229 } 3233 }
3230 } 3234 }
3231 3235
3232 /// <summary> 3236 /// <summary>
3233 /// 3237 /// Update just the root prim position in a linkset
3234 /// </summary> 3238 /// </summary>
3235 /// <param name="pos"></param> 3239 /// <param name="pos"></param>
3236 private void UpdateRootPosition(Vector3 pos) 3240 public void UpdateRootPosition(Vector3 pos)
3237 { 3241 {
3238 SceneObjectPart[] parts = m_parts.GetArray(); 3242// m_log.DebugFormat(
3239 for (int i = 0; i < parts.Length; i++) 3243// "[SCENE OBJECT GROUP]: Updating root position of {0} {1} to {2}", Name, LocalId, pos);
3240 parts[i].StoreUndoState(UndoType.STATE_PRIM_POSITION); 3244
3245// SceneObjectPart[] parts = m_parts.GetArray();
3246// for (int i = 0; i < parts.Length; i++)
3247// parts[i].StoreUndoState();
3241 3248
3242 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); 3249 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
3243 Vector3 oldPos = 3250 Vector3 oldPos =
@@ -3250,7 +3257,7 @@ namespace OpenSim.Region.Framework.Scenes
3250 axDiff *= Quaternion.Inverse(partRotation); 3257 axDiff *= Quaternion.Inverse(partRotation);
3251 diff = axDiff; 3258 diff = axDiff;
3252 3259
3253 parts = m_parts.GetArray(); 3260 SceneObjectPart[] parts = m_parts.GetArray();
3254 for (int i = 0; i < parts.Length; i++) 3261 for (int i = 0; i < parts.Length; i++)
3255 { 3262 {
3256 SceneObjectPart obPart = parts[i]; 3263 SceneObjectPart obPart = parts[i];
@@ -3296,9 +3303,14 @@ namespace OpenSim.Region.Framework.Scenes
3296 /// <param name="rot"></param> 3303 /// <param name="rot"></param>
3297 public void UpdateGroupRotationR(Quaternion rot) 3304 public void UpdateGroupRotationR(Quaternion rot)
3298 { 3305 {
3299 SceneObjectPart[] parts = m_parts.GetArray(); 3306// m_log.DebugFormat(
3300 for (int i = 0; i < parts.Length; i++) 3307// "[SCENE OBJECT GROUP]: Updating group rotation R of {0} {1} to {2}", Name, LocalId, rot);
3301 parts[i].StoreUndoState(UndoType.STATE_GROUP_ROTATION); 3308
3309// SceneObjectPart[] parts = m_parts.GetArray();
3310// for (int i = 0; i < parts.Length; i++)
3311// parts[i].StoreUndoState();
3312
3313 m_rootPart.StoreUndoState(true);
3302 3314
3303 m_rootPart.UpdateRotation(rot); 3315 m_rootPart.UpdateRotation(rot);
3304 3316
@@ -3320,9 +3332,15 @@ namespace OpenSim.Region.Framework.Scenes
3320 /// <param name="rot"></param> 3332 /// <param name="rot"></param>
3321 public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) 3333 public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot)
3322 { 3334 {
3323 SceneObjectPart[] parts = m_parts.GetArray(); 3335// m_log.DebugFormat(
3324 for (int i = 0; i < parts.Length; i++) 3336// "[SCENE OBJECT GROUP]: Updating group rotation PR of {0} {1} to {2}", Name, LocalId, rot);
3325 parts[i].StoreUndoState(UndoType.STATE_GROUP_ROTATION); 3337
3338// SceneObjectPart[] parts = m_parts.GetArray();
3339// for (int i = 0; i < parts.Length; i++)
3340// parts[i].StoreUndoState();
3341
3342 RootPart.StoreUndoState(true);
3343 RootPart.IgnoreUndoUpdate = true;
3326 3344
3327 m_rootPart.UpdateRotation(rot); 3345 m_rootPart.UpdateRotation(rot);
3328 3346
@@ -3337,6 +3355,8 @@ namespace OpenSim.Region.Framework.Scenes
3337 3355
3338 HasGroupChanged = true; 3356 HasGroupChanged = true;
3339 ScheduleGroupForTerseUpdate(); 3357 ScheduleGroupForTerseUpdate();
3358
3359 RootPart.IgnoreUndoUpdate = false;
3340 } 3360 }
3341 3361
3342 /// <summary> 3362 /// <summary>
@@ -3353,6 +3373,9 @@ namespace OpenSim.Region.Framework.Scenes
3353 3373
3354 if (part != null) 3374 if (part != null)
3355 { 3375 {
3376// m_log.DebugFormat(
3377// "[SCENE OBJECT GROUP]: Updating single rotation of {0} {1} to {2}", part.Name, part.LocalId, rot);
3378
3356 if (part.UUID == m_rootPart.UUID) 3379 if (part.UUID == m_rootPart.UUID)
3357 { 3380 {
3358 UpdateRootRotation(rot); 3381 UpdateRootRotation(rot);
@@ -3374,6 +3397,13 @@ namespace OpenSim.Region.Framework.Scenes
3374 SceneObjectPart part = GetChildPart(localID); 3397 SceneObjectPart part = GetChildPart(localID);
3375 if (part != null) 3398 if (part != null)
3376 { 3399 {
3400// m_log.DebugFormat(
3401// "[SCENE OBJECT GROUP]: Updating single position and rotation of {0} {1} to {2}",
3402// part.Name, part.LocalId, rot);
3403
3404 part.StoreUndoState();
3405 part.IgnoreUndoUpdate = true;
3406
3377 if (part.UUID == m_rootPart.UUID) 3407 if (part.UUID == m_rootPart.UUID)
3378 { 3408 {
3379 UpdateRootRotation(rot); 3409 UpdateRootRotation(rot);
@@ -3390,12 +3420,11 @@ namespace OpenSim.Region.Framework.Scenes
3390 } 3420 }
3391 else 3421 else
3392 { 3422 {
3393 part.StoreUndoState(UndoType.STATE_PRIM_ROTATION);
3394 part.IgnoreUndoUpdate = true;
3395 part.UpdateRotation(rot); 3423 part.UpdateRotation(rot);
3396 part.OffsetPosition = pos; 3424 part.OffsetPosition = pos;
3397 part.IgnoreUndoUpdate = false;
3398 } 3425 }
3426
3427 part.IgnoreUndoUpdate = false;
3399 } 3428 }
3400 } 3429 }
3401 3430
@@ -3403,8 +3432,12 @@ namespace OpenSim.Region.Framework.Scenes
3403 /// 3432 ///
3404 /// </summary> 3433 /// </summary>
3405 /// <param name="rot"></param> 3434 /// <param name="rot"></param>
3406 private void UpdateRootRotation(Quaternion rot) 3435 public void UpdateRootRotation(Quaternion rot)
3407 { 3436 {
3437// m_log.DebugFormat(
3438// "[SCENE OBJECT GROUP]: Updating root rotation of {0} {1} to {2}",
3439// Name, LocalId, rot);
3440
3408 Quaternion axRot = rot; 3441 Quaternion axRot = rot;
3409 Quaternion oldParentRot = m_rootPart.RotationOffset; 3442 Quaternion oldParentRot = m_rootPart.RotationOffset;
3410 3443
@@ -3440,14 +3473,25 @@ namespace OpenSim.Region.Framework.Scenes
3440 prim.RotationOffset *= Quaternion.Inverse(prim.GetWorldRotation()) * (oldParentRot * prim.RotationOffset); 3473 prim.RotationOffset *= Quaternion.Inverse(prim.GetWorldRotation()) * (oldParentRot * prim.RotationOffset);
3441 3474
3442 prim.IgnoreUndoUpdate = false; 3475 prim.IgnoreUndoUpdate = false;
3476 prim.IgnoreUndoUpdate = false;
3443 } 3477 }
3444 } 3478 }
3445 if (cancelUndo == true) 3479
3446 { 3480// for (int i = 0; i < parts.Length; i++)
3447 m_rootPart.Undoing = false; 3481// {
3448 } 3482// SceneObjectPart childpart = parts[i];
3483// if (childpart != m_rootPart)
3484// {
3485//// childpart.IgnoreUndoUpdate = false;
3486//// childpart.StoreUndoState();
3487// }
3488// }
3449 HasGroupChanged = true; 3489 HasGroupChanged = true;
3450 ScheduleGroupForFullUpdate(); 3490 ScheduleGroupForFullUpdate();
3491
3492// m_log.DebugFormat(
3493// "[SCENE OBJECT GROUP]: Updated root rotation of {0} {1} to {2}",
3494// Name, LocalId, rot);
3451 } 3495 }
3452 3496
3453 #endregion 3497 #endregion
@@ -3462,28 +3506,23 @@ namespace OpenSim.Region.Framework.Scenes
3462 int yaxis = 4; 3506 int yaxis = 4;
3463 int zaxis = 8; 3507 int zaxis = 8;
3464 3508
3465 if (m_rootPart != null) 3509 setX = ((axis & xaxis) != 0) ? true : false;
3466 { 3510 setY = ((axis & yaxis) != 0) ? true : false;
3467 setX = ((axis & xaxis) != 0) ? true : false; 3511 setZ = ((axis & zaxis) != 0) ? true : false;
3468 setY = ((axis & yaxis) != 0) ? true : false;
3469 setZ = ((axis & zaxis) != 0) ? true : false;
3470 3512
3471 float setval = (rotate10 > 0) ? 1f : 0f; 3513 float setval = (rotate10 > 0) ? 1f : 0f;
3472 3514
3473 if (setX) 3515 if (setX)
3474 m_rootPart.RotationAxis.X = setval; 3516 RootPart.RotationAxis.X = setval;
3475 if (setY) 3517 if (setY)
3476 m_rootPart.RotationAxis.Y = setval; 3518 RootPart.RotationAxis.Y = setval;
3477 if (setZ) 3519 if (setZ)
3478 m_rootPart.RotationAxis.Z = setval; 3520 RootPart.RotationAxis.Z = setval;
3479 3521
3480 if (setX || setY || setZ) 3522 if (setX || setY || setZ)
3481 { 3523 RootPart.SetPhysicsAxisRotation();
3482 m_rootPart.SetPhysicsAxisRotation();
3483 }
3484
3485 }
3486 } 3524 }
3525
3487 public int registerRotTargetWaypoint(Quaternion target, float tolerance) 3526 public int registerRotTargetWaypoint(Quaternion target, float tolerance)
3488 { 3527 {
3489 scriptRotTarget waypoint = new scriptRotTarget(); 3528 scriptRotTarget waypoint = new scriptRotTarget();
@@ -3611,7 +3650,13 @@ namespace OpenSim.Region.Framework.Scenes
3611 foreach (uint idx in m_rotTargets.Keys) 3650 foreach (uint idx in m_rotTargets.Keys)
3612 { 3651 {
3613 scriptRotTarget target = m_rotTargets[idx]; 3652 scriptRotTarget target = m_rotTargets[idx];
3614 double angle = Math.Acos(target.targetRot.X * m_rootPart.RotationOffset.X + target.targetRot.Y * m_rootPart.RotationOffset.Y + target.targetRot.Z * m_rootPart.RotationOffset.Z + target.targetRot.W * m_rootPart.RotationOffset.W) * 2; 3653 double angle
3654 = Math.Acos(
3655 target.targetRot.X * m_rootPart.RotationOffset.X
3656 + target.targetRot.Y * m_rootPart.RotationOffset.Y
3657 + target.targetRot.Z * m_rootPart.RotationOffset.Z
3658 + target.targetRot.W * m_rootPart.RotationOffset.W)
3659 * 2;
3615 if (angle < 0) angle = -angle; 3660 if (angle < 0) angle = -angle;
3616 if (angle > Math.PI) angle = (Math.PI * 2 - angle); 3661 if (angle > Math.PI) angle = (Math.PI * 2 - angle);
3617 if (angle <= target.tolerance) 3662 if (angle <= target.tolerance)
@@ -3676,43 +3721,28 @@ namespace OpenSim.Region.Framework.Scenes
3676 3721
3677 return retmass; 3722 return retmass;
3678 } 3723 }
3679 3724
3725 /// <summary>
3726 /// If the object is a sculpt/mesh, retrieve the mesh data for each part and reinsert it into each shape so that
3727 /// the physics engine can use it.
3728 /// </summary>
3729 /// <remarks>
3730 /// When the physics engine has finished with it, the sculpt data is discarded to save memory.
3731 /// </remarks>
3680 public void CheckSculptAndLoad() 3732 public void CheckSculptAndLoad()
3681 { 3733 {
3682 if (IsDeleted) 3734 if (IsDeleted)
3683 return; 3735 return;
3736
3684 if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0) 3737 if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0)
3685 return; 3738 return;
3686 3739
3687 SceneObjectPart[] parts = m_parts.GetArray(); 3740// m_log.Debug("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
3688 for (int i = 0; i < parts.Length; i++)
3689 {
3690 SceneObjectPart part = parts[i];
3691 if (part.Shape.SculptEntry && part.Shape.SculptTexture != UUID.Zero)
3692 {
3693 // check if a previously decoded sculpt map has been cached
3694 if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + part.Shape.SculptTexture.ToString())))
3695 {
3696 part.SculptTextureCallback(part.Shape.SculptTexture, null);
3697 }
3698 else
3699 {
3700 m_scene.AssetService.Get(
3701 part.Shape.SculptTexture.ToString(), part, AssetReceived);
3702 }
3703 }
3704 }
3705 }
3706 3741
3707 protected void AssetReceived(string id, Object sender, AssetBase asset) 3742 SceneObjectPart[] parts = m_parts.GetArray();
3708 {
3709 SceneObjectPart sop = (SceneObjectPart)sender;
3710 3743
3711 if (sop != null) 3744 for (int i = 0; i < parts.Length; i++)
3712 { 3745 parts[i].CheckSculptAndLoad();
3713 if (asset != null)
3714 sop.SculptTextureCallback(asset.FullID, asset);
3715 }
3716 } 3746 }
3717 3747
3718 /// <summary> 3748 /// <summary>
@@ -3747,19 +3777,12 @@ namespace OpenSim.Region.Framework.Scenes
3747 return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition); 3777 return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition);
3748 } 3778 }
3749 3779
3750 public void SetAttachmentPoint(byte point)
3751 {
3752 SceneObjectPart[] parts = m_parts.GetArray();
3753 for (int i = 0; i < parts.Length; i++)
3754 parts[i].SetAttachmentPoint(point);
3755 }
3756
3757 #region ISceneObject 3780 #region ISceneObject
3758 3781
3759 public virtual ISceneObject CloneForNewScene() 3782 public virtual ISceneObject CloneForNewScene()
3760 { 3783 {
3761 SceneObjectGroup sog = Copy(false); 3784 SceneObjectGroup sog = Copy(false);
3762 sog.m_isDeleted = false; 3785 sog.IsDeleted = false;
3763 return sog; 3786 return sog;
3764 } 3787 }
3765 3788