diff options
Now merging the core changes.
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 865 |
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 | ||