aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPart.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs952
1 files changed, 497 insertions, 455 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 037f384..893faf8 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Drawing; 30using System.Drawing;
31using System.IO;
31using System.Reflection; 32using System.Reflection;
32using System.Runtime.Serialization; 33using System.Runtime.Serialization;
33using System.Security.Permissions; 34using System.Security.Permissions;
@@ -216,28 +217,18 @@ namespace OpenSim.Region.Framework.Scenes
216 /// </value> 217 /// </value>
217 private UUID m_fromUserInventoryItemID; 218 private UUID m_fromUserInventoryItemID;
218 219
219
220 public UUID FromUserInventoryItemID 220 public UUID FromUserInventoryItemID
221 { 221 {
222 get { return m_fromUserInventoryItemID; } 222 get { return m_fromUserInventoryItemID; }
223 set { m_fromUserInventoryItemID = value; }
223 } 224 }
224 225
225
226 public bool IsAttachment;
227
228
229 public scriptEvents AggregateScriptEvents; 226 public scriptEvents AggregateScriptEvents;
230 227
231 228
232 public UUID AttachedAvatar;
233
234
235 public Vector3 AttachedPos; 229 public Vector3 AttachedPos;
236 230
237 231
238 public uint AttachmentPoint;
239
240
241 public Vector3 RotationAxis = Vector3.One; 232 public Vector3 RotationAxis = Vector3.One;
242 233
243 234
@@ -269,12 +260,9 @@ namespace OpenSim.Region.Framework.Scenes
269 } 260 }
270 protected SceneObjectPartInventory m_inventory; 261 protected SceneObjectPartInventory m_inventory;
271 262
272
273 public bool Undoing; 263 public bool Undoing;
274
275 264
276 public bool IgnoreUndoUpdate = false; 265 public bool IgnoreUndoUpdate = false;
277
278 266
279 private PrimFlags LocalFlags; 267 private PrimFlags LocalFlags;
280 268
@@ -296,8 +284,8 @@ namespace OpenSim.Region.Framework.Scenes
296 private bool m_occupied; // KF if any av is sitting on this prim 284 private bool m_occupied; // KF if any av is sitting on this prim
297 private string m_text = String.Empty; 285 private string m_text = String.Empty;
298 private string m_touchName = String.Empty; 286 private string m_touchName = String.Empty;
299 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5); 287 private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5);
300 private readonly UndoStack<UndoState> m_redo = new UndoStack<UndoState>(5); 288 private readonly Stack<UndoState> m_redo = new Stack<UndoState>(5);
301 private UUID _creatorID; 289 private UUID _creatorID;
302 290
303 private bool m_passTouches; 291 private bool m_passTouches;
@@ -323,7 +311,6 @@ namespace OpenSim.Region.Framework.Scenes
323 protected string m_name; 311 protected string m_name;
324 protected Vector3 m_offsetPosition; 312 protected Vector3 m_offsetPosition;
325 313
326 // FIXME, TODO, ERROR: 'ParentGroup' can't be in here, move it out.
327 protected SceneObjectGroup m_parentGroup; 314 protected SceneObjectGroup m_parentGroup;
328 protected byte[] m_particleSystem = Utils.EmptyBytes; 315 protected byte[] m_particleSystem = Utils.EmptyBytes;
329 protected ulong m_regionHandle; 316 protected ulong m_regionHandle;
@@ -424,7 +411,6 @@ namespace OpenSim.Region.Framework.Scenes
424 CreateSelected = true; 411 CreateSelected = true;
425 412
426 TrimPermissions(); 413 TrimPermissions();
427 //m_undo = new UndoStack<UndoState>(ParentGroup.GetSceneMaxUndo());
428 414
429 m_inventory = new SceneObjectPartInventory(this); 415 m_inventory = new SceneObjectPartInventory(this);
430 } 416 }
@@ -619,6 +605,7 @@ namespace OpenSim.Region.Framework.Scenes
619 set 605 set
620 { 606 {
621 m_passTouches = value; 607 m_passTouches = value;
608
622 if (ParentGroup != null) 609 if (ParentGroup != null)
623 ParentGroup.HasGroupChanged = true; 610 ParentGroup.HasGroupChanged = true;
624 } 611 }
@@ -744,9 +731,9 @@ namespace OpenSim.Region.Framework.Scenes
744 return m_groupPosition; 731 return m_groupPosition;
745 } 732 }
746 733
747 if (IsAttachment) 734 if (m_parentGroup.IsAttachment)
748 { 735 {
749 ScenePresence sp = m_parentGroup.Scene.GetScenePresence(AttachedAvatar); 736 ScenePresence sp = m_parentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar);
750 if (sp != null) 737 if (sp != null)
751 return sp.AbsolutePosition; 738 return sp.AbsolutePosition;
752 } 739 }
@@ -794,7 +781,6 @@ namespace OpenSim.Region.Framework.Scenes
794 set 781 set
795 { 782 {
796 Vector3 oldpos = m_offsetPosition; 783 Vector3 oldpos = m_offsetPosition;
797 StoreUndoState(UndoType.STATE_PRIM_POSITION);
798 m_offsetPosition = value; 784 m_offsetPosition = value;
799 785
800 if (ParentGroup != null && !ParentGroup.IsDeleted) 786 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -834,7 +820,7 @@ namespace OpenSim.Region.Framework.Scenes
834 { 820 {
835 if (IsRoot) 821 if (IsRoot)
836 { 822 {
837 if (IsAttachment) 823 if (m_parentGroup.IsAttachment)
838 return AttachedPos; 824 return AttachedPos;
839 else 825 else
840 return AbsolutePosition; 826 return AbsolutePosition;
@@ -887,7 +873,9 @@ namespace OpenSim.Region.Framework.Scenes
887 actor.Orientation = resultingrotation; 873 actor.Orientation = resultingrotation;
888 //m_log.Info("[PART]: RO2:" + actor.Orientation.ToString()); 874 //m_log.Info("[PART]: RO2:" + actor.Orientation.ToString());
889 } 875 }
890 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 876
877 if (m_parentGroup != null)
878 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
891 //} 879 //}
892 } 880 }
893 catch (Exception ex) 881 catch (Exception ex)
@@ -895,7 +883,6 @@ namespace OpenSim.Region.Framework.Scenes
895 m_log.Error("[SCENEOBJECTPART]: ROTATIONOFFSET" + ex.Message); 883 m_log.Error("[SCENEOBJECTPART]: ROTATIONOFFSET" + ex.Message);
896 } 884 }
897 } 885 }
898
899 } 886 }
900 } 887 }
901 888
@@ -1044,30 +1031,39 @@ namespace OpenSim.Region.Framework.Scenes
1044 get { return m_shape; } 1031 get { return m_shape; }
1045 set { m_shape = value; } 1032 set { m_shape = value; }
1046 } 1033 }
1047 1034
1035 /// <summary>
1036 /// Change the scale of this part.
1037 /// </summary>
1048 public Vector3 Scale 1038 public Vector3 Scale
1049 { 1039 {
1050 get { return m_shape.Scale; } 1040 get { return m_shape.Scale; }
1051 set 1041 set
1052 { 1042 {
1053 StoreUndoState(UndoType.STATE_PRIM_SCALE);
1054 if (m_shape != null) 1043 if (m_shape != null)
1055 { 1044 {
1045 StoreUndoState();
1046
1056 m_shape.Scale = value; 1047 m_shape.Scale = value;
1057 1048
1058 PhysicsActor actor = PhysActor; 1049 PhysicsActor actor = PhysActor;
1059 if (actor != null && m_parentGroup != null) 1050 if (actor != null)
1060 { 1051 {
1061 if (m_parentGroup.Scene != null) 1052 if (m_parentGroup.Scene != null)
1062 { 1053 {
1063 if (m_parentGroup.Scene.PhysicsScene != null) 1054 if (m_parentGroup.Scene.PhysicsScene != null)
1064 { 1055 {
1065 actor.Size = m_shape.Scale; 1056 actor.Size = m_shape.Scale;
1066 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 1057
1058 if (Shape.SculptEntry)
1059 CheckSculptAndLoad();
1060 else
1061 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
1067 } 1062 }
1068 } 1063 }
1069 } 1064 }
1070 } 1065 }
1066
1071 TriggerScriptChangedEvent(Changed.SCALE); 1067 TriggerScriptChangedEvent(Changed.SCALE);
1072 } 1068 }
1073 } 1069 }
@@ -1092,13 +1088,12 @@ namespace OpenSim.Region.Framework.Scenes
1092 set 1088 set
1093 { 1089 {
1094 m_mediaUrl = value; 1090 m_mediaUrl = value;
1095 1091
1096 if (ParentGroup != null) 1092 if (ParentGroup != null)
1097 ParentGroup.HasGroupChanged = true; 1093 ParentGroup.HasGroupChanged = true;
1098 } 1094 }
1099 } 1095 }
1100 1096
1101
1102 public bool CreateSelected 1097 public bool CreateSelected
1103 { 1098 {
1104 get { return m_createSelected; } 1099 get { return m_createSelected; }
@@ -1118,7 +1113,10 @@ namespace OpenSim.Region.Framework.Scenes
1118 { 1113 {
1119 get 1114 get
1120 { 1115 {
1121 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset); 1116 if (m_parentGroup.IsAttachment)
1117 return GroupPosition;
1118
1119 return m_offsetPosition + m_groupPosition;
1122 } 1120 }
1123 } 1121 }
1124 1122
@@ -1138,7 +1136,6 @@ namespace OpenSim.Region.Framework.Scenes
1138 set { m_sitTargetOrientation = value; } 1136 set { m_sitTargetOrientation = value; }
1139 } 1137 }
1140 1138
1141
1142 public Vector3 SitTargetPosition 1139 public Vector3 SitTargetPosition
1143 { 1140 {
1144 get { return m_sitTargetPosition; } 1141 get { return m_sitTargetPosition; }
@@ -1268,7 +1265,9 @@ namespace OpenSim.Region.Framework.Scenes
1268 /// <summary> 1265 /// <summary>
1269 /// Property flags. See OpenMetaverse.PrimFlags 1266 /// Property flags. See OpenMetaverse.PrimFlags
1270 /// </summary> 1267 /// </summary>
1268 /// <remarks>
1271 /// Example properties are PrimFlags.Phantom and PrimFlags.DieAtEdge 1269 /// Example properties are PrimFlags.Phantom and PrimFlags.DieAtEdge
1270 /// </remarks>
1272 public PrimFlags Flags 1271 public PrimFlags Flags
1273 { 1272 {
1274 get { return _flags; } 1273 get { return _flags; }
@@ -1298,7 +1297,7 @@ namespace OpenSim.Region.Framework.Scenes
1298 { 1297 {
1299 get 1298 get
1300 { 1299 {
1301 if (ParentGroup != null && ParentGroup.Scene != null) 1300 if (ParentGroup.Scene != null)
1302 return ParentGroup.Scene.RegionInfo.RegionID; 1301 return ParentGroup.Scene.RegionInfo.RegionID;
1303 else 1302 else
1304 return UUID.Zero; 1303 return UUID.Zero;
@@ -1313,14 +1312,13 @@ namespace OpenSim.Region.Framework.Scenes
1313 get 1312 get
1314 { 1313 {
1315 if (ParentGroup != null) 1314 if (ParentGroup != null)
1316 {
1317 _parentUUID = ParentGroup.UUID; 1315 _parentUUID = ParentGroup.UUID;
1318 } 1316
1319 return _parentUUID; 1317 return _parentUUID;
1320 } 1318 }
1319
1321 set { _parentUUID = value; } 1320 set { _parentUUID = value; }
1322 } 1321 }
1323
1324 1322
1325 public string SitAnimation 1323 public string SitAnimation
1326 { 1324 {
@@ -1555,10 +1553,7 @@ namespace OpenSim.Region.Framework.Scenes
1555 impulse = newimpulse; 1553 impulse = newimpulse;
1556 } 1554 }
1557 1555
1558 if (m_parentGroup != null) 1556 m_parentGroup.applyAngularImpulse(impulse);
1559 {
1560 m_parentGroup.applyAngularImpulse(impulse);
1561 }
1562 } 1557 }
1563 1558
1564 /// <summary> 1559 /// <summary>
@@ -1581,19 +1576,7 @@ namespace OpenSim.Region.Framework.Scenes
1581 impulse = newimpulse; 1576 impulse = newimpulse;
1582 } 1577 }
1583 1578
1584 if (m_parentGroup != null) 1579 m_parentGroup.setAngularImpulse(impulse);
1585 {
1586 m_parentGroup.setAngularImpulse(impulse);
1587 }
1588 }
1589
1590 public Vector3 GetTorque()
1591 {
1592 if (m_parentGroup != null)
1593 {
1594 m_parentGroup.GetTorque();
1595 }
1596 return Vector3.Zero;
1597 } 1580 }
1598 1581
1599 /// <summary> 1582 /// <summary>
@@ -1623,7 +1606,7 @@ namespace OpenSim.Region.Framework.Scenes
1623 1606
1624 // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition 1607 // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition
1625 // or flexible 1608 // or flexible
1626 if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible)) 1609 if (!isPhantom && !m_parentGroup.IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible))
1627 { 1610 {
1628 try 1611 try
1629 { 1612 {
@@ -1635,7 +1618,6 @@ namespace OpenSim.Region.Framework.Scenes
1635 RotationOffset, 1618 RotationOffset,
1636 RigidBody, 1619 RigidBody,
1637 m_localId); 1620 m_localId);
1638 PhysActor.SetMaterial(Material);
1639 } 1621 }
1640 catch 1622 catch
1641 { 1623 {
@@ -1647,6 +1629,7 @@ namespace OpenSim.Region.Framework.Scenes
1647 { 1629 {
1648 PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info 1630 PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info
1649 PhysActor.SOPDescription = this.Description; 1631 PhysActor.SOPDescription = this.Description;
1632 PhysActor.SetMaterial(Material);
1650 DoPhysicsPropertyUpdate(RigidBody, true); 1633 DoPhysicsPropertyUpdate(RigidBody, true);
1651 PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); 1634 PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
1652 } 1635 }
@@ -1658,19 +1641,6 @@ namespace OpenSim.Region.Framework.Scenes
1658 } 1641 }
1659 } 1642 }
1660 1643
1661 public void ClearUndoState()
1662 {
1663 lock (m_undo)
1664 {
1665 m_undo.Clear();
1666 }
1667 lock (m_redo)
1668 {
1669 m_redo.Clear();
1670 }
1671 StoreUndoState(UndoType.STATE_ALL);
1672 }
1673
1674 public byte ConvertScriptUintToByte(uint indata) 1644 public byte ConvertScriptUintToByte(uint indata)
1675 { 1645 {
1676 byte outdata = (byte)TextureAnimFlags.NONE; 1646 byte outdata = (byte)TextureAnimFlags.NONE;
@@ -1751,7 +1721,8 @@ namespace OpenSim.Region.Framework.Scenes
1751 { 1721 {
1752 if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero) 1722 if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero)
1753 { 1723 {
1754 m_parentGroup.Scene.AssetService.Get(dupe.m_shape.SculptTexture.ToString(), dupe, AssetReceived); 1724 ParentGroup.Scene.AssetService.Get(
1725 dupe.m_shape.SculptTexture.ToString(), dupe, dupe.AssetReceived);
1755 } 1726 }
1756 1727
1757 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 1728 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
@@ -1765,14 +1736,20 @@ namespace OpenSim.Region.Framework.Scenes
1765 return dupe; 1736 return dupe;
1766 } 1737 }
1767 1738
1739 /// <summary>
1740 /// Called back by asynchronous asset fetch.
1741 /// </summary>
1742 /// <param name="id">ID of asset received</param>
1743 /// <param name="sender">Register</param>
1744 /// <param name="asset"></param>
1768 protected void AssetReceived(string id, Object sender, AssetBase asset) 1745 protected void AssetReceived(string id, Object sender, AssetBase asset)
1769 { 1746 {
1770 if (asset != null) 1747 if (asset != null)
1771 { 1748 SculptTextureCallback(asset);
1772 SceneObjectPart sop = (SceneObjectPart)sender; 1749 else
1773 if (sop != null) 1750 m_log.WarnFormat(
1774 sop.SculptTextureCallback(asset.FullID, asset); 1751 "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
1775 } 1752 Name, LocalId, id);
1776 } 1753 }
1777 1754
1778 public static SceneObjectPart Create() 1755 public static SceneObjectPart Create()
@@ -1789,97 +1766,111 @@ namespace OpenSim.Region.Framework.Scenes
1789 return part; 1766 return part;
1790 } 1767 }
1791 1768
1792 public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew) 1769 /// <summary>
1770 /// Do a physics property update for a NINJA joint.
1771 /// </summary>
1772 /// <param name="UsePhysics"></param>
1773 /// <param name="isNew"></param>
1774 protected void DoPhysicsPropertyUpdateForNinjaJoint(bool UsePhysics, bool isNew)
1793 { 1775 {
1794 if (IsJoint()) 1776 if (UsePhysics)
1795 { 1777 {
1796 if (UsePhysics) 1778 // by turning a joint proxy object physical, we cause creation of a joint in the ODE scene.
1797 { 1779 // note that, as a special case, joints have no bodies or geoms in the physics scene, even though they are physical.
1798 // by turning a joint proxy object physical, we cause creation of a joint in the ODE scene.
1799 // note that, as a special case, joints have no bodies or geoms in the physics scene, even though they are physical.
1800 1780
1801 PhysicsJointType jointType; 1781 PhysicsJointType jointType;
1802 if (IsHingeJoint()) 1782 if (IsHingeJoint())
1803 { 1783 {
1804 jointType = PhysicsJointType.Hinge; 1784 jointType = PhysicsJointType.Hinge;
1805 } 1785 }
1806 else if (IsBallJoint()) 1786 else if (IsBallJoint())
1807 { 1787 {
1808 jointType = PhysicsJointType.Ball; 1788 jointType = PhysicsJointType.Ball;
1809 } 1789 }
1810 else 1790 else
1811 { 1791 {
1812 jointType = PhysicsJointType.Ball; 1792 jointType = PhysicsJointType.Ball;
1813 } 1793 }
1814 1794
1815 List<string> bodyNames = new List<string>(); 1795 List<string> bodyNames = new List<string>();
1816 string RawParams = Description; 1796 string RawParams = Description;
1817 string[] jointParams = RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); 1797 string[] jointParams = RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries);
1818 string trackedBodyName = null; 1798 string trackedBodyName = null;
1819 if (jointParams.Length >= 2) 1799 if (jointParams.Length >= 2)
1800 {
1801 for (int iBodyName = 0; iBodyName < 2; iBodyName++)
1820 { 1802 {
1821 for (int iBodyName = 0; iBodyName < 2; iBodyName++) 1803 string bodyName = jointParams[iBodyName];
1804 bodyNames.Add(bodyName);
1805 if (bodyName != "NULL")
1822 { 1806 {
1823 string bodyName = jointParams[iBodyName]; 1807 if (trackedBodyName == null)
1824 bodyNames.Add(bodyName);
1825 if (bodyName != "NULL")
1826 { 1808 {
1827 if (trackedBodyName == null) 1809 trackedBodyName = bodyName;
1828 {
1829 trackedBodyName = bodyName;
1830 }
1831 } 1810 }
1832 } 1811 }
1833 } 1812 }
1813 }
1834 1814
1835 SceneObjectPart trackedBody = m_parentGroup.Scene.GetSceneObjectPart(trackedBodyName); // FIXME: causes a sequential lookup 1815 SceneObjectPart trackedBody = m_parentGroup.Scene.GetSceneObjectPart(trackedBodyName); // FIXME: causes a sequential lookup
1836 Quaternion localRotation = Quaternion.Identity; 1816 Quaternion localRotation = Quaternion.Identity;
1837 if (trackedBody != null) 1817 if (trackedBody != null)
1838 { 1818 {
1839 localRotation = Quaternion.Inverse(trackedBody.RotationOffset) * this.RotationOffset; 1819 localRotation = Quaternion.Inverse(trackedBody.RotationOffset) * this.RotationOffset;
1840 } 1820 }
1841 else 1821 else
1842 { 1822 {
1843 // error, output it below 1823 // error, output it below
1844 } 1824 }
1845
1846 PhysicsJoint joint;
1847 1825
1848 joint = m_parentGroup.Scene.PhysicsScene.RequestJointCreation(Name, jointType, 1826 PhysicsJoint joint;
1849 AbsolutePosition,
1850 this.RotationOffset,
1851 Description,
1852 bodyNames,
1853 trackedBodyName,
1854 localRotation);
1855 1827
1856 if (trackedBody == null) 1828 joint = m_parentGroup.Scene.PhysicsScene.RequestJointCreation(Name, jointType,
1857 { 1829 AbsolutePosition,
1858 ParentGroup.Scene.jointErrorMessage(joint, "warning: tracked body name not found! joint location will not be updated properly. joint: " + Name); 1830 this.RotationOffset,
1859 } 1831 Description,
1832 bodyNames,
1833 trackedBodyName,
1834 localRotation);
1860 1835
1836 if (trackedBody == null)
1837 {
1838 ParentGroup.Scene.jointErrorMessage(joint, "warning: tracked body name not found! joint location will not be updated properly. joint: " + Name);
1839 }
1840 }
1841 else
1842 {
1843 if (isNew)
1844 {
1845 // if the joint proxy is new, and it is not physical, do nothing. There is no joint in ODE to
1846 // delete, and if we try to delete it, due to asynchronous processing, the deletion request
1847 // will get processed later at an indeterminate time, which could cancel a later-arriving
1848 // joint creation request.
1861 } 1849 }
1862 else 1850 else
1863 { 1851 {
1864 if (isNew) 1852 // here we turn off the joint object, so remove the joint from the physics scene
1865 { 1853 m_parentGroup.Scene.PhysicsScene.RequestJointDeletion(Name); // FIXME: what if the name changed?
1866 // if the joint proxy is new, and it is not physical, do nothing. There is no joint in ODE to
1867 // delete, and if we try to delete it, due to asynchronous processing, the deletion request
1868 // will get processed later at an indeterminate time, which could cancel a later-arriving
1869 // joint creation request.
1870 }
1871 else
1872 {
1873 // here we turn off the joint object, so remove the joint from the physics scene
1874 m_parentGroup.Scene.PhysicsScene.RequestJointDeletion(Name); // FIXME: what if the name changed?
1875 1854
1876 // make sure client isn't interpolating the joint proxy object 1855 // make sure client isn't interpolating the joint proxy object
1877 Velocity = Vector3.Zero; 1856 Velocity = Vector3.Zero;
1878 AngularVelocity = Vector3.Zero; 1857 AngularVelocity = Vector3.Zero;
1879 Acceleration = Vector3.Zero; 1858 Acceleration = Vector3.Zero;
1880 }
1881 } 1859 }
1882 } 1860 }
1861 }
1862
1863 /// <summary>
1864 /// Do a physics propery update for this part.
1865 /// </summary>
1866 /// <param name="UsePhysics"></param>
1867 /// <param name="isNew"></param>
1868 public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew)
1869 {
1870 if (IsJoint())
1871 {
1872 DoPhysicsPropertyUpdateForNinjaJoint(UsePhysics, isNew);
1873 }
1883 else 1874 else
1884 { 1875 {
1885 if (PhysActor != null) 1876 if (PhysActor != null)
@@ -1919,7 +1910,6 @@ namespace OpenSim.Region.Framework.Scenes
1919 1910
1920 PhysActor.IsPhysical = UsePhysics; 1911 PhysActor.IsPhysical = UsePhysics;
1921 1912
1922
1923 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 1913 // If we're not what we're supposed to be in the physics scene, recreate ourselves.
1924 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 1914 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor);
1925 /// that's not wholesome. Had to make Scene public 1915 /// that's not wholesome. Had to make Scene public
@@ -1943,7 +1933,13 @@ namespace OpenSim.Region.Framework.Scenes
1943 } 1933 }
1944 } 1934 }
1945 } 1935 }
1946 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 1936
1937 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
1938 // mesh data.
1939 if (Shape.SculptEntry)
1940 CheckSculptAndLoad();
1941 else
1942 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
1947 } 1943 }
1948 } 1944 }
1949 } 1945 }
@@ -1955,22 +1951,11 @@ namespace OpenSim.Region.Framework.Scenes
1955 /// <returns></returns> 1951 /// <returns></returns>
1956 public static SceneObjectPart FromXml(XmlTextReader xmlReader) 1952 public static SceneObjectPart FromXml(XmlTextReader xmlReader)
1957 { 1953 {
1958 return FromXml(UUID.Zero, xmlReader);
1959 }
1960
1961 /// <summary>
1962 /// Restore this part from the serialized xml representation.
1963 /// </summary>
1964 /// <param name="fromUserInventoryItemId">The inventory id from which this part came, if applicable</param>
1965 /// <param name="xmlReader"></param>
1966 /// <returns></returns>
1967 public static SceneObjectPart FromXml(UUID fromUserInventoryItemId, XmlTextReader xmlReader)
1968 {
1969 SceneObjectPart part = SceneObjectSerializer.Xml2ToSOP(xmlReader); 1954 SceneObjectPart part = SceneObjectSerializer.Xml2ToSOP(xmlReader);
1970 part.m_fromUserInventoryItemID = fromUserInventoryItemId;
1971 1955
1972 // for tempOnRez objects, we have to fix the Expire date. 1956 // for tempOnRez objects, we have to fix the Expire date.
1973 if ((part.Flags & PrimFlags.TemporaryOnRez) != 0) part.ResetExpire(); 1957 if ((part.Flags & PrimFlags.TemporaryOnRez) != 0)
1958 part.ResetExpire();
1974 1959
1975 return part; 1960 return part;
1976 } 1961 }
@@ -1982,8 +1967,6 @@ namespace OpenSim.Region.Framework.Scenes
1982 1967
1983 public bool GetDieAtEdge() 1968 public bool GetDieAtEdge()
1984 { 1969 {
1985 if (m_parentGroup == null)
1986 return false;
1987 if (m_parentGroup.IsDeleted) 1970 if (m_parentGroup.IsDeleted)
1988 return false; 1971 return false;
1989 1972
@@ -1992,8 +1975,6 @@ namespace OpenSim.Region.Framework.Scenes
1992 1975
1993 public bool GetReturnAtEdge() 1976 public bool GetReturnAtEdge()
1994 { 1977 {
1995 if (m_parentGroup == null)
1996 return false;
1997 if (m_parentGroup.IsDeleted) 1978 if (m_parentGroup.IsDeleted)
1998 return false; 1979 return false;
1999 1980
@@ -2002,8 +1983,6 @@ namespace OpenSim.Region.Framework.Scenes
2002 1983
2003 public void SetReturnAtEdge(bool p) 1984 public void SetReturnAtEdge(bool p)
2004 { 1985 {
2005 if (m_parentGroup == null)
2006 return;
2007 if (m_parentGroup.IsDeleted) 1986 if (m_parentGroup.IsDeleted)
2008 return; 1987 return;
2009 1988
@@ -2012,8 +1991,6 @@ namespace OpenSim.Region.Framework.Scenes
2012 1991
2013 public bool GetBlockGrab() 1992 public bool GetBlockGrab()
2014 { 1993 {
2015 if (m_parentGroup == null)
2016 return false;
2017 if (m_parentGroup.IsDeleted) 1994 if (m_parentGroup.IsDeleted)
2018 return false; 1995 return false;
2019 1996
@@ -2022,8 +1999,6 @@ namespace OpenSim.Region.Framework.Scenes
2022 1999
2023 public void SetBlockGrab(bool p) 2000 public void SetBlockGrab(bool p)
2024 { 2001 {
2025 if (m_parentGroup == null)
2026 return;
2027 if (m_parentGroup.IsDeleted) 2002 if (m_parentGroup.IsDeleted)
2028 return; 2003 return;
2029 2004
@@ -2032,8 +2007,6 @@ namespace OpenSim.Region.Framework.Scenes
2032 2007
2033 public void SetStatusSandbox(bool p) 2008 public void SetStatusSandbox(bool p)
2034 { 2009 {
2035 if (m_parentGroup == null)
2036 return;
2037 if (m_parentGroup.IsDeleted) 2010 if (m_parentGroup.IsDeleted)
2038 return; 2011 return;
2039 StatusSandboxPos = m_parentGroup.RootPart.AbsolutePosition; 2012 StatusSandboxPos = m_parentGroup.RootPart.AbsolutePosition;
@@ -2042,8 +2015,6 @@ namespace OpenSim.Region.Framework.Scenes
2042 2015
2043 public bool GetStatusSandbox() 2016 public bool GetStatusSandbox()
2044 { 2017 {
2045 if (m_parentGroup == null)
2046 return false;
2047 if (m_parentGroup.IsDeleted) 2018 if (m_parentGroup.IsDeleted)
2048 return false; 2019 return false;
2049 2020
@@ -2085,25 +2056,17 @@ namespace OpenSim.Region.Framework.Scenes
2085 public Vector3 GetGeometricCenter() 2056 public Vector3 GetGeometricCenter()
2086 { 2057 {
2087 if (PhysActor != null) 2058 if (PhysActor != null)
2088 {
2089 return new Vector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z); 2059 return new Vector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z);
2090 }
2091 else 2060 else
2092 {
2093 return new Vector3(0, 0, 0); 2061 return new Vector3(0, 0, 0);
2094 }
2095 } 2062 }
2096 2063
2097 public float GetMass() 2064 public float GetMass()
2098 { 2065 {
2099 if (PhysActor != null) 2066 if (PhysActor != null)
2100 {
2101 return PhysActor.Mass; 2067 return PhysActor.Mass;
2102 }
2103 else 2068 else
2104 {
2105 return 0; 2069 return 0;
2106 }
2107 } 2070 }
2108 2071
2109 public Vector3 GetForce() 2072 public Vector3 GetForce()
@@ -2119,19 +2082,12 @@ namespace OpenSim.Region.Framework.Scenes
2119 client.SendObjectPropertiesReply(this); 2082 client.SendObjectPropertiesReply(this);
2120 } 2083 }
2121 2084
2122 public UUID GetRootPartUUID()
2123 {
2124 if (m_parentGroup != null)
2125 {
2126 return m_parentGroup.UUID;
2127 }
2128 return UUID.Zero;
2129 }
2130
2131 /// <summary> 2085 /// <summary>
2132 /// Method for a prim to get it's world position from the group. 2086 /// Method for a prim to get it's world position from the group.
2133 /// Remember, the Group Position simply gives the position of the group itself
2134 /// </summary> 2087 /// </summary>
2088 /// <remarks>
2089 /// Remember, the Group Position simply gives the position of the group itself
2090 /// </remarks>
2135 /// <returns>A Linked Child Prim objects position in world</returns> 2091 /// <returns>A Linked Child Prim objects position in world</returns>
2136 public Vector3 GetWorldPosition() 2092 public Vector3 GetWorldPosition()
2137 { 2093 {
@@ -2249,8 +2205,6 @@ namespace OpenSim.Region.Framework.Scenes
2249 m_lastColliders.Remove(localID); 2205 m_lastColliders.Remove(localID);
2250 } 2206 }
2251 2207
2252 if (m_parentGroup == null)
2253 return;
2254 if (m_parentGroup.IsDeleted) 2208 if (m_parentGroup.IsDeleted)
2255 return; 2209 return;
2256 2210
@@ -2271,9 +2225,6 @@ namespace OpenSim.Region.Framework.Scenes
2271 { 2225 {
2272 if (localId == 0) 2226 if (localId == 0)
2273 continue; 2227 continue;
2274 // always running this check because if the user deletes the object it would return a null reference.
2275 if (m_parentGroup == null)
2276 return;
2277 2228
2278 if (m_parentGroup.Scene == null) 2229 if (m_parentGroup.Scene == null)
2279 return; 2230 return;
@@ -2282,7 +2233,8 @@ namespace OpenSim.Region.Framework.Scenes
2282 string data = ""; 2233 string data = "";
2283 if (obj != null) 2234 if (obj != null)
2284 { 2235 {
2285 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) 2236 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString())
2237 || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
2286 { 2238 {
2287 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); 2239 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2288 //If it is 1, it is to accept ONLY collisions from this object 2240 //If it is 1, it is to accept ONLY collisions from this object
@@ -2329,7 +2281,8 @@ namespace OpenSim.Region.Framework.Scenes
2329 { 2281 {
2330 if (av.LocalId == localId) 2282 if (av.LocalId == localId)
2331 { 2283 {
2332 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) 2284 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2285 || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2333 { 2286 {
2334 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); 2287 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2335 //If it is 1, it is to accept ONLY collisions from this avatar 2288 //If it is 1, it is to accept ONLY collisions from this avatar
@@ -2377,12 +2330,10 @@ namespace OpenSim.Region.Framework.Scenes
2377 if (colliding.Count > 0) 2330 if (colliding.Count > 0)
2378 { 2331 {
2379 StartCollidingMessage.Colliders = colliding; 2332 StartCollidingMessage.Colliders = colliding;
2380 // always running this check because if the user deletes the object it would return a null reference.
2381 if (m_parentGroup == null)
2382 return;
2383 2333
2384 if (m_parentGroup.Scene == null) 2334 if (m_parentGroup.Scene == null)
2385 return; 2335 return;
2336
2386 if (m_parentGroup.PassCollision == true) 2337 if (m_parentGroup.PassCollision == true)
2387 { 2338 {
2388 //TODO: Add pass to root prim! 2339 //TODO: Add pass to root prim!
@@ -2403,9 +2354,6 @@ namespace OpenSim.Region.Framework.Scenes
2403 // always running this check because if the user deletes the object it would return a null reference. 2354 // always running this check because if the user deletes the object it would return a null reference.
2404 if (localId == 0) 2355 if (localId == 0)
2405 continue; 2356 continue;
2406
2407 if (m_parentGroup == null)
2408 return;
2409 2357
2410 if (m_parentGroup.Scene == null) 2358 if (m_parentGroup.Scene == null)
2411 return; 2359 return;
@@ -2414,7 +2362,8 @@ namespace OpenSim.Region.Framework.Scenes
2414 string data = ""; 2362 string data = "";
2415 if (obj != null) 2363 if (obj != null)
2416 { 2364 {
2417 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) 2365 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString())
2366 || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
2418 { 2367 {
2419 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); 2368 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2420 //If it is 1, it is to accept ONLY collisions from this object 2369 //If it is 1, it is to accept ONLY collisions from this object
@@ -2461,7 +2410,8 @@ namespace OpenSim.Region.Framework.Scenes
2461 { 2410 {
2462 if (av.LocalId == localId) 2411 if (av.LocalId == localId)
2463 { 2412 {
2464 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) 2413 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2414 || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2465 { 2415 {
2466 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); 2416 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2467 //If it is 1, it is to accept ONLY collisions from this avatar 2417 //If it is 1, it is to accept ONLY collisions from this avatar
@@ -2509,9 +2459,6 @@ namespace OpenSim.Region.Framework.Scenes
2509 if (colliding.Count > 0) 2459 if (colliding.Count > 0)
2510 { 2460 {
2511 CollidingMessage.Colliders = colliding; 2461 CollidingMessage.Colliders = colliding;
2512 // always running this check because if the user deletes the object it would return a null reference.
2513 if (m_parentGroup == null)
2514 return;
2515 2462
2516 if (m_parentGroup.Scene == null) 2463 if (m_parentGroup.Scene == null)
2517 return; 2464 return;
@@ -2532,11 +2479,9 @@ namespace OpenSim.Region.Framework.Scenes
2532 if (localId == 0) 2479 if (localId == 0)
2533 continue; 2480 continue;
2534 2481
2535 // always running this check because if the user deletes the object it would return a null reference.
2536 if (m_parentGroup == null)
2537 return;
2538 if (m_parentGroup.Scene == null) 2482 if (m_parentGroup.Scene == null)
2539 return; 2483 return;
2484
2540 SceneObjectPart obj = m_parentGroup.Scene.GetSceneObjectPart(localId); 2485 SceneObjectPart obj = m_parentGroup.Scene.GetSceneObjectPart(localId);
2541 string data = ""; 2486 string data = "";
2542 if (obj != null) 2487 if (obj != null)
@@ -2588,7 +2533,8 @@ namespace OpenSim.Region.Framework.Scenes
2588 { 2533 {
2589 if (av.LocalId == localId) 2534 if (av.LocalId == localId)
2590 { 2535 {
2591 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) 2536 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2537 || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2592 { 2538 {
2593 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); 2539 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2594 //If it is 1, it is to accept ONLY collisions from this avatar 2540 //If it is 1, it is to accept ONLY collisions from this avatar
@@ -2637,9 +2583,6 @@ namespace OpenSim.Region.Framework.Scenes
2637 if (colliding.Count > 0) 2583 if (colliding.Count > 0)
2638 { 2584 {
2639 EndCollidingMessage.Colliders = colliding; 2585 EndCollidingMessage.Colliders = colliding;
2640 // always running this check because if the user deletes the object it would return a null reference.
2641 if (m_parentGroup == null)
2642 return;
2643 2586
2644 if (m_parentGroup.Scene == null) 2587 if (m_parentGroup.Scene == null)
2645 return; 2588 return;
@@ -2648,6 +2591,7 @@ namespace OpenSim.Region.Framework.Scenes
2648 } 2591 }
2649 } 2592 }
2650 } 2593 }
2594
2651 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_start) != 0) 2595 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_start) != 0)
2652 { 2596 {
2653 if (startedColliders.Count > 0) 2597 if (startedColliders.Count > 0)
@@ -2675,9 +2619,6 @@ namespace OpenSim.Region.Framework.Scenes
2675 if (colliding.Count > 0) 2619 if (colliding.Count > 0)
2676 { 2620 {
2677 LandStartCollidingMessage.Colliders = colliding; 2621 LandStartCollidingMessage.Colliders = colliding;
2678 // always running this check because if the user deletes the object it would return a null reference.
2679 if (m_parentGroup == null)
2680 return;
2681 2622
2682 if (m_parentGroup.Scene == null) 2623 if (m_parentGroup.Scene == null)
2683 return; 2624 return;
@@ -2686,6 +2627,7 @@ namespace OpenSim.Region.Framework.Scenes
2686 } 2627 }
2687 } 2628 }
2688 } 2629 }
2630
2689 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision) != 0) 2631 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision) != 0)
2690 { 2632 {
2691 if (m_lastColliders.Count > 0) 2633 if (m_lastColliders.Count > 0)
@@ -2713,9 +2655,6 @@ namespace OpenSim.Region.Framework.Scenes
2713 if (colliding.Count > 0) 2655 if (colliding.Count > 0)
2714 { 2656 {
2715 LandCollidingMessage.Colliders = colliding; 2657 LandCollidingMessage.Colliders = colliding;
2716 // always running this check because if the user deletes the object it would return a null reference.
2717 if (m_parentGroup == null)
2718 return;
2719 2658
2720 if (m_parentGroup.Scene == null) 2659 if (m_parentGroup.Scene == null)
2721 return; 2660 return;
@@ -2724,6 +2663,7 @@ namespace OpenSim.Region.Framework.Scenes
2724 } 2663 }
2725 } 2664 }
2726 } 2665 }
2666
2727 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_end) != 0) 2667 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_end) != 0)
2728 { 2668 {
2729 if (endedColliders.Count > 0) 2669 if (endedColliders.Count > 0)
@@ -2751,9 +2691,6 @@ namespace OpenSim.Region.Framework.Scenes
2751 if (colliding.Count > 0) 2691 if (colliding.Count > 0)
2752 { 2692 {
2753 LandEndCollidingMessage.Colliders = colliding; 2693 LandEndCollidingMessage.Colliders = colliding;
2754 // always running this check because if the user deletes the object it would return a null reference.
2755 if (m_parentGroup == null)
2756 return;
2757 2694
2758 if (m_parentGroup.Scene == null) 2695 if (m_parentGroup.Scene == null)
2759 return; 2696 return;
@@ -2777,10 +2714,12 @@ namespace OpenSim.Region.Framework.Scenes
2777 { 2714 {
2778 if (PhysActor != null) 2715 if (PhysActor != null)
2779 { 2716 {
2780
2781 Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0); 2717 Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0);
2782 2718
2783 if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2719 if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2720 | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2721 | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2722 | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2784 { 2723 {
2785 m_parentGroup.AbsolutePosition = newpos; 2724 m_parentGroup.AbsolutePosition = newpos;
2786 return; 2725 return;
@@ -2869,13 +2808,29 @@ namespace OpenSim.Region.Framework.Scenes
2869 } 2808 }
2870 2809
2871 /// <summary> 2810 /// <summary>
2872 /// Resize this part. 2811 /// Set the scale of this part.
2873 /// </summary> 2812 /// </summary>
2813 /// <remarks>
2814 /// Unlike the scale property, this checks the new size against scene limits and schedules a full property
2815 /// update to viewers.
2816 /// </remarks>
2874 /// <param name="scale"></param> 2817 /// <param name="scale"></param>
2875 public void Resize(Vector3 scale) 2818 public void Resize(Vector3 scale)
2876 { 2819 {
2877 StoreUndoState(UndoType.STATE_PRIM_SCALE); 2820 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxNonphys);
2878 m_shape.Scale = scale; 2821 scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys);
2822 scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys);
2823
2824 if (PhysActor != null && PhysActor.IsPhysical)
2825 {
2826 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys);
2827 scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys);
2828 scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys);
2829 }
2830
2831// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale);
2832
2833 Scale = scale;
2879 2834
2880 ParentGroup.HasGroupChanged = true; 2835 ParentGroup.HasGroupChanged = true;
2881 ScheduleFullUpdate(); 2836 ScheduleFullUpdate();
@@ -2886,20 +2841,48 @@ namespace OpenSim.Region.Framework.Scenes
2886 m_parentGroup.rotLookAt(target, strength, damping); // This calls method in SceneObjectGroup. 2841 m_parentGroup.rotLookAt(target, strength, damping); // This calls method in SceneObjectGroup.
2887 } 2842 }
2888 2843
2844 public void rotLookAt(Quaternion target, float strength, float damping)
2845 {
2846 if (m_parentGroup.IsAttachment)
2847 {
2848 /*
2849 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
2850 if (avatar != null)
2851 {
2852 Rotate the Av?
2853 } */
2854 }
2855 else
2856 {
2857 APIDDamp = damping;
2858 APIDStrength = strength;
2859 APIDTarget = target;
2860 }
2861 }
2862
2863 public void startLookAt(Quaternion rot, float damp, float strength)
2864 {
2865 APIDDamp = damp;
2866 APIDStrength = strength;
2867 APIDTarget = rot;
2868 }
2869
2870 public void stopLookAt()
2871 {
2872 APIDTarget = Quaternion.Identity;
2873 }
2874
2889 /// <summary> 2875 /// <summary>
2890 /// Schedules this prim for a full update 2876 /// Schedules this prim for a full update
2891 /// </summary> 2877 /// </summary>
2892 public void ScheduleFullUpdate() 2878 public void ScheduleFullUpdate()
2893 { 2879 {
2894// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId); 2880// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId);
2895 2881
2896 if (m_parentGroup != null) 2882 if (m_parentGroup == null)
2897 { 2883 return;
2898 if (!m_parentGroup.areUpdatesSuspended) 2884
2899 { 2885 m_parentGroup.QueueForUpdateCheck();
2900 m_parentGroup.QueueForUpdateCheck();
2901 }
2902 }
2903 2886
2904 int timeNow = Util.UnixTimeSinceEpoch(); 2887 int timeNow = Util.UnixTimeSinceEpoch();
2905 2888
@@ -2928,13 +2911,14 @@ namespace OpenSim.Region.Framework.Scenes
2928 /// </summary> 2911 /// </summary>
2929 public void ScheduleTerseUpdate() 2912 public void ScheduleTerseUpdate()
2930 { 2913 {
2914 if (m_parentGroup == null)
2915 return;
2916
2931 if (m_updateFlag < 1) 2917 if (m_updateFlag < 1)
2932 { 2918 {
2933 if (m_parentGroup != null) 2919 m_parentGroup.HasGroupChanged = true;
2934 { 2920 m_parentGroup.QueueForUpdateCheck();
2935 m_parentGroup.HasGroupChanged = true; 2921
2936 m_parentGroup.QueueForUpdateCheck();
2937 }
2938 TimeStampTerse = (uint) Util.UnixTimeSinceEpoch(); 2922 TimeStampTerse = (uint) Util.UnixTimeSinceEpoch();
2939 m_updateFlag = 1; 2923 m_updateFlag = 1;
2940 2924
@@ -2944,40 +2928,16 @@ namespace OpenSim.Region.Framework.Scenes
2944 } 2928 }
2945 } 2929 }
2946 2930
2947 public void ScriptSetPhantomStatus(bool Phantom)
2948 {
2949 if (m_parentGroup != null)
2950 {
2951 m_parentGroup.ScriptSetPhantomStatus(Phantom);
2952 }
2953 }
2954
2955 public void ScriptSetTemporaryStatus(bool Temporary)
2956 {
2957 if (m_parentGroup != null)
2958 {
2959 m_parentGroup.ScriptSetTemporaryStatus(Temporary);
2960 }
2961 }
2962
2963 public void ScriptSetPhysicsStatus(bool UsePhysics) 2931 public void ScriptSetPhysicsStatus(bool UsePhysics)
2964 { 2932 {
2965 if (m_parentGroup == null) 2933 m_parentGroup.ScriptSetPhysicsStatus(UsePhysics);
2966 DoPhysicsPropertyUpdate(UsePhysics, false);
2967 else
2968 m_parentGroup.ScriptSetPhysicsStatus(UsePhysics);
2969 } 2934 }
2970 2935
2971 public void ScriptSetVolumeDetect(bool SetVD) 2936 /// <summary>
2972 { 2937 /// Set sculpt and mesh data, and tell the physics engine to process the change.
2973 2938 /// </summary>
2974 if (m_parentGroup != null) 2939 /// <param name="texture">The mesh itself.</param>
2975 { 2940 public void SculptTextureCallback(AssetBase texture)
2976 m_parentGroup.ScriptSetVolumeDetect(SetVD);
2977 }
2978 }
2979
2980 public void SculptTextureCallback(UUID textureID, AssetBase texture)
2981 { 2941 {
2982 if (m_shape.SculptEntry) 2942 if (m_shape.SculptEntry)
2983 { 2943 {
@@ -2985,14 +2945,17 @@ namespace OpenSim.Region.Framework.Scenes
2985 //if (texture != null) 2945 //if (texture != null)
2986 { 2946 {
2987 if (texture != null) 2947 if (texture != null)
2948 {
2949// m_log.DebugFormat(
2950// "[SCENE OBJECT PART]: Setting sculpt data for {0} on SculptTextureCallback()", Name);
2951
2988 m_shape.SculptData = texture.Data; 2952 m_shape.SculptData = texture.Data;
2953 }
2989 2954
2990 if (PhysActor != null) 2955 if (PhysActor != null)
2991 { 2956 {
2992 // Tricks physics engine into thinking we've changed the part shape. 2957 // Update the physics actor with the new loaded sculpt data and set the taint signal.
2993 PrimitiveBaseShape m_newshape = m_shape.Copy(); 2958 PhysActor.Shape = m_shape;
2994 PhysActor.Shape = m_newshape;
2995 m_shape = m_newshape;
2996 2959
2997 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 2960 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
2998 } 2961 }
@@ -3000,16 +2963,6 @@ namespace OpenSim.Region.Framework.Scenes
3000 } 2963 }
3001 } 2964 }
3002 2965
3003// /// <summary>
3004// ///
3005// /// </summary>
3006// /// <param name="remoteClient"></param>
3007// public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags)
3008// {
3009// m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags);
3010// }
3011
3012
3013 /// <summary> 2966 /// <summary>
3014 /// Send a full update to the client for the given part 2967 /// Send a full update to the client for the given part
3015 /// </summary> 2968 /// </summary>
@@ -3017,12 +2970,15 @@ namespace OpenSim.Region.Framework.Scenes
3017 /// <param name="clientFlags"></param> 2970 /// <param name="clientFlags"></param>
3018 protected internal void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) 2971 protected internal void SendFullUpdate(IClientAPI remoteClient, uint clientFlags)
3019 { 2972 {
2973 if (m_parentGroup == null)
2974 return;
2975
3020// m_log.DebugFormat( 2976// m_log.DebugFormat(
3021// "[SOG]: Sendinging part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId); 2977// "[SOG]: Sendinging part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId);
3022 2978
3023 if (IsRoot) 2979 if (IsRoot)
3024 { 2980 {
3025 if (IsAttachment) 2981 if (m_parentGroup.IsAttachment)
3026 { 2982 {
3027 SendFullUpdateToClient(remoteClient, AttachedPos, clientFlags); 2983 SendFullUpdateToClient(remoteClient, AttachedPos, clientFlags);
3028 } 2984 }
@@ -3042,6 +2998,9 @@ namespace OpenSim.Region.Framework.Scenes
3042 /// </summary> 2998 /// </summary>
3043 public void SendFullUpdateToAllClients() 2999 public void SendFullUpdateToAllClients()
3044 { 3000 {
3001 if (m_parentGroup == null)
3002 return;
3003
3045 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3004 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
3046 { 3005 {
3047 SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID)); 3006 SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID));
@@ -3054,6 +3013,9 @@ namespace OpenSim.Region.Framework.Scenes
3054 /// <param name="agentID"></param> 3013 /// <param name="agentID"></param>
3055 public void SendFullUpdateToAllClientsExcept(UUID agentID) 3014 public void SendFullUpdateToAllClientsExcept(UUID agentID)
3056 { 3015 {
3016 if (m_parentGroup == null)
3017 return;
3018
3057 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3019 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
3058 { 3020 {
3059 // Ugly reference :( 3021 // Ugly reference :(
@@ -3082,9 +3044,12 @@ namespace OpenSim.Region.Framework.Scenes
3082 /// <param name="clientFlags"></param> 3044 /// <param name="clientFlags"></param>
3083 public void SendFullUpdateToClient(IClientAPI remoteClient, Vector3 lPos, uint clientFlags) 3045 public void SendFullUpdateToClient(IClientAPI remoteClient, Vector3 lPos, uint clientFlags)
3084 { 3046 {
3047 if (ParentGroup == null)
3048 return;
3049
3085 // Suppress full updates during attachment editing 3050 // Suppress full updates during attachment editing
3086 // 3051 //
3087 if (ParentGroup.IsSelected && IsAttachment) 3052 if (ParentGroup.IsSelected && ParentGroup.IsAttachment)
3088 return; 3053 return;
3089 3054
3090 if (ParentGroup.IsDeleted) 3055 if (ParentGroup.IsDeleted)
@@ -3177,7 +3142,7 @@ namespace OpenSim.Region.Framework.Scenes
3177 3142
3178 UUID ownerID = _ownerID; 3143 UUID ownerID = _ownerID;
3179 UUID objectID = ParentGroup.RootPart.UUID; 3144 UUID objectID = ParentGroup.RootPart.UUID;
3180 UUID parentID = GetRootPartUUID(); 3145 UUID parentID = ParentGroup.UUID;
3181 3146
3182 UUID soundID = UUID.Zero; 3147 UUID soundID = UUID.Zero;
3183 Vector3 position = AbsolutePosition; // region local 3148 Vector3 position = AbsolutePosition; // region local
@@ -3215,7 +3180,7 @@ namespace OpenSim.Region.Framework.Scenes
3215 ParentGroup.PlaySoundMasterPrim = this; 3180 ParentGroup.PlaySoundMasterPrim = this;
3216 ownerID = _ownerID; 3181 ownerID = _ownerID;
3217 objectID = ParentGroup.RootPart.UUID; 3182 objectID = ParentGroup.RootPart.UUID;
3218 parentID = GetRootPartUUID(); 3183 parentID = ParentGroup.UUID;
3219 position = AbsolutePosition; // region local 3184 position = AbsolutePosition; // region local
3220 regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle; 3185 regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle;
3221 if (triggered) 3186 if (triggered)
@@ -3226,7 +3191,7 @@ namespace OpenSim.Region.Framework.Scenes
3226 { 3191 {
3227 ownerID = prim._ownerID; 3192 ownerID = prim._ownerID;
3228 objectID = prim.ParentGroup.RootPart.UUID; 3193 objectID = prim.ParentGroup.RootPart.UUID;
3229 parentID = prim.GetRootPartUUID(); 3194 parentID = prim.ParentGroup.UUID;
3230 position = prim.AbsolutePosition; // region local 3195 position = prim.AbsolutePosition; // region local
3231 regionHandle = prim.ParentGroup.Scene.RegionInfo.RegionHandle; 3196 regionHandle = prim.ParentGroup.Scene.RegionInfo.RegionHandle;
3232 if (triggered) 3197 if (triggered)
@@ -3263,45 +3228,23 @@ namespace OpenSim.Region.Framework.Scenes
3263 }); 3228 });
3264 } 3229 }
3265 3230
3266 public void SetAttachmentPoint(uint AttachmentPoint)
3267 {
3268 this.AttachmentPoint = AttachmentPoint;
3269
3270 if (AttachmentPoint != 0)
3271 {
3272 IsAttachment = true;
3273 }
3274 else
3275 {
3276 IsAttachment = false;
3277 }
3278
3279 // save the attachment point.
3280 //if (AttachmentPoint != 0)
3281 //{
3282 m_shape.State = (byte)AttachmentPoint;
3283 //}
3284 }
3285
3286 public void SetAxisRotation(int axis, int rotate) 3231 public void SetAxisRotation(int axis, int rotate)
3287 { 3232 {
3288 if (m_parentGroup != null) 3233 m_parentGroup.SetAxisRotation(axis, rotate);
3289 { 3234
3290 m_parentGroup.SetAxisRotation(axis, rotate);
3291 }
3292 //Cannot use ScriptBaseClass constants as no referance to it currently. 3235 //Cannot use ScriptBaseClass constants as no referance to it currently.
3293 if (axis == 2)//STATUS_ROTATE_X 3236 if (axis == 2)//STATUS_ROTATE_X
3294 STATUS_ROTATE_X = rotate; 3237 STATUS_ROTATE_X = rotate;
3238
3295 if (axis == 4)//STATUS_ROTATE_Y 3239 if (axis == 4)//STATUS_ROTATE_Y
3296 STATUS_ROTATE_Y = rotate; 3240 STATUS_ROTATE_Y = rotate;
3241
3297 if (axis == 8)//STATUS_ROTATE_Z 3242 if (axis == 8)//STATUS_ROTATE_Z
3298 STATUS_ROTATE_Z = rotate; 3243 STATUS_ROTATE_Z = rotate;
3299 } 3244 }
3300 3245
3301 public void SetDieAtEdge(bool p) 3246 public void SetDieAtEdge(bool p)
3302 { 3247 {
3303 if (m_parentGroup == null)
3304 return;
3305 if (m_parentGroup.IsDeleted) 3248 if (m_parentGroup.IsDeleted)
3306 return; 3249 return;
3307 3250
@@ -3554,7 +3497,7 @@ namespace OpenSim.Region.Framework.Scenes
3554 } 3497 }
3555 3498
3556 /// <summary> 3499 /// <summary>
3557 /// 3500 /// Set the parent group of this prim.
3558 /// </summary> 3501 /// </summary>
3559 public void SetParent(SceneObjectGroup parent) 3502 public void SetParent(SceneObjectGroup parent)
3560 { 3503 {
@@ -3611,8 +3554,11 @@ namespace OpenSim.Region.Framework.Scenes
3611 { 3554 {
3612 Text = text; 3555 Text = text;
3613 3556
3614 ParentGroup.HasGroupChanged = true; 3557 if (ParentGroup != null)
3615 ScheduleFullUpdate(); 3558 {
3559 ParentGroup.HasGroupChanged = true;
3560 ScheduleFullUpdate();
3561 }
3616 } 3562 }
3617 3563
3618 public void StopLookAt() 3564 public void StopLookAt()
@@ -3646,24 +3592,44 @@ namespace OpenSim.Region.Framework.Scenes
3646 } 3592 }
3647 public void StoreUndoState(UndoType type) 3593 public void StoreUndoState(UndoType type)
3648 { 3594 {
3649 if (!Undoing && (m_parentGroup == null || m_parentGroup.RootPart == null || !m_parentGroup.RootPart.Undoing)) 3595 StoreUndoState(false);
3596 }
3597
3598 public void StoreUndoState(bool forGroup)
3599 {
3600 if (!Undoing)
3650 { 3601 {
3651 if (!IgnoreUndoUpdate) 3602 if (!IgnoreUndoUpdate)
3652 { 3603 {
3653 if (m_parentGroup != null) 3604 if (ParentGroup != null)
3654 { 3605 {
3655 lock (m_undo) 3606 lock (m_undo)
3656 { 3607 {
3657 if (m_undo.Count > 0) 3608 if (m_undo.Count > 0)
3658 { 3609 {
3659 UndoState last = m_undo.Peek(); 3610 UndoState last = m_undo.Peek();
3660 3611 if (last != null)
3612 {
3613 // TODO: May need to fix for group comparison
3614 if (last.Compare(this))
3615 {
3616 // m_log.DebugFormat(
3617 // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3618 // Name, LocalId, m_undo.Count);
3619
3620 return;
3621 }
3622 }
3661 } 3623 }
3662 3624
3625 // m_log.DebugFormat(
3626 // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3627 // Name, LocalId, forGroup, m_undo.Count);
3628
3663 if (m_parentGroup.GetSceneMaxUndo() > 0) 3629 if (m_parentGroup.GetSceneMaxUndo() > 0)
3664 { 3630 {
3665 UndoState lastUndo = m_undo.Peek(); 3631 UndoState nUndo = new UndoState(this, forGroup);
3666 3632
3667 UndoState nUndo = new UndoState(this, type); 3633 UndoState nUndo = new UndoState(this, type);
3668 3634
3669 if (lastUndo != null) 3635 if (lastUndo != null)
@@ -3677,11 +3643,114 @@ namespace OpenSim.Region.Framework.Scenes
3677 } 3643 }
3678 } 3644 }
3679 m_undo.Push(nUndo); 3645 m_undo.Push(nUndo);
3646
3647 if (m_redo.Count > 0)
3648 m_redo.Clear();
3649
3650 // m_log.DebugFormat(
3651 // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3652 // Name, LocalId, forGroup, m_undo.Count);
3680 } 3653 }
3654 }
3655 }
3656 }
3657// else
3658// {
3659// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3660// }
3661 }
3662// else
3663// {
3664// m_log.DebugFormat(
3665// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3666// }
3667 }
3668
3669 /// <summary>
3670 /// Return number of undos on the stack. Here temporarily pending a refactor.
3671 /// </summary>
3672 public int UndoCount
3673 {
3674 get
3675 {
3676 lock (m_undo)
3677 return m_undo.Count;
3678 }
3679 }
3680
3681 public void Undo()
3682 {
3683 lock (m_undo)
3684 {
3685// m_log.DebugFormat(
3686// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3687// Name, LocalId, m_undo.Count);
3688
3689 if (m_undo.Count > 0)
3690 {
3691 UndoState goback = m_undo.Pop();
3681 3692
3693 if (goback != null)
3694 {
3695 UndoState nUndo = null;
3696
3697 if (m_parentGroup.GetSceneMaxUndo() > 0)
3698 {
3699 nUndo = new UndoState(this, goback.ForGroup);
3682 } 3700 }
3701
3702 goback.PlaybackState(this);
3703
3704 if (nUndo != null)
3705 m_redo.Push(nUndo);
3683 } 3706 }
3684 } 3707 }
3708
3709// m_log.DebugFormat(
3710// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}",
3711// Name, LocalId, m_undo.Count);
3712 }
3713 }
3714
3715 public void Redo()
3716 {
3717 lock (m_undo)
3718 {
3719// m_log.DebugFormat(
3720// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3721// Name, LocalId, m_redo.Count);
3722
3723 if (m_redo.Count > 0)
3724 {
3725 UndoState gofwd = m_redo.Pop();
3726
3727 if (gofwd != null)
3728 {
3729 if (m_parentGroup.GetSceneMaxUndo() > 0)
3730 {
3731 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3732
3733 m_undo.Push(nUndo);
3734 }
3735
3736 gofwd.PlayfwdState(this);
3737 }
3738
3739// m_log.DebugFormat(
3740// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}",
3741// Name, LocalId, m_redo.Count);
3742 }
3743 }
3744 }
3745
3746 public void ClearUndoState()
3747 {
3748// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId);
3749
3750 lock (m_undo)
3751 {
3752 m_undo.Clear();
3753 m_redo.Clear();
3685 } 3754 }
3686 } 3755 }
3687 3756
@@ -4145,46 +4214,6 @@ namespace OpenSim.Region.Framework.Scenes
4145 _nextOwnerMask &= (uint)PermissionMask.All; 4214 _nextOwnerMask &= (uint)PermissionMask.All;
4146 } 4215 }
4147 4216
4148 public void Undo()
4149 {
4150 lock (m_undo)
4151 {
4152 if (m_undo.Count > 0)
4153 {
4154 UndoState nUndo = null;
4155 UndoState goback = m_undo.Pop();
4156 if (m_parentGroup.GetSceneMaxUndo() > 0)
4157 {
4158 nUndo = new UndoState(this, goback.Type);
4159 }
4160
4161
4162 if (goback != null)
4163 {
4164 goback.PlaybackState(this);
4165 if (nUndo != null)
4166 m_redo.Push(nUndo);
4167 }
4168 }
4169 }
4170 }
4171
4172 public void Redo()
4173 {
4174 lock (m_redo)
4175 {
4176 UndoState gofwd = m_redo.Pop();
4177 if (m_parentGroup.GetSceneMaxUndo() > 0)
4178 {
4179 UndoState nUndo = new UndoState(this, gofwd.Type);
4180
4181 m_undo.Push(nUndo);
4182 }
4183 if (gofwd != null)
4184 gofwd.PlayfwdState(this);
4185 }
4186 }
4187
4188 public void UpdateExtraParam(ushort type, bool inUse, byte[] data) 4217 public void UpdateExtraParam(ushort type, bool inUse, byte[] data)
4189 { 4218 {
4190 m_shape.ReadInUpdateExtraParam(type, inUse, data); 4219 m_shape.ReadInUpdateExtraParam(type, inUse, data);
@@ -4197,8 +4226,11 @@ namespace OpenSim.Region.Framework.Scenes
4197 } 4226 }
4198 } 4227 }
4199 4228
4200 ParentGroup.HasGroupChanged = true; 4229 if (ParentGroup != null)
4201 ScheduleFullUpdate(); 4230 {
4231 ParentGroup.HasGroupChanged = true;
4232 ScheduleFullUpdate();
4233 }
4202 } 4234 }
4203 4235
4204 public void UpdateGroupPosition(Vector3 pos) 4236 public void UpdateGroupPosition(Vector3 pos)
@@ -4345,14 +4377,21 @@ namespace OpenSim.Region.Framework.Scenes
4345 } 4377 }
4346 } 4378 }
4347 4379
4348 public void UpdatePrimFlags(bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVD) 4380 /// <summary>
4381 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary.
4382 /// </summary>
4383 /// <param name="UsePhysics"></param>
4384 /// <param name="SetTemporary"></param>
4385 /// <param name="SetPhantom"></param>
4386 /// <param name="SetVD"></param>
4387 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD)
4349 { 4388 {
4350 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4389 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4351 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4390 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
4352 bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0); 4391 bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0);
4353 bool wasVD = VolumeDetectActive; 4392 bool wasVD = VolumeDetectActive;
4354 4393
4355 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == IsTemporary) && (wasPhantom == IsPhantom) && (IsVD==wasVD)) 4394 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4356 { 4395 {
4357 return; 4396 return;
4358 } 4397 }
@@ -4362,32 +4401,31 @@ namespace OpenSim.Region.Framework.Scenes
4362 // that... 4401 // that...
4363 // ... if VD is changed, all others are not. 4402 // ... if VD is changed, all others are not.
4364 // ... if one of the others is changed, VD is not. 4403 // ... if one of the others is changed, VD is not.
4365 if (IsVD) // VD is active, special logic applies 4404 if (SetVD) // VD is active, special logic applies
4366 { 4405 {
4367 // State machine logic for VolumeDetect 4406 // State machine logic for VolumeDetect
4368 // More logic below 4407 // More logic below
4369 bool phanReset = (IsPhantom != wasPhantom) && !IsPhantom; 4408 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4370 4409
4371 if (phanReset) // Phantom changes from on to off switch VD off too 4410 if (phanReset) // Phantom changes from on to off switch VD off too
4372 { 4411 {
4373 IsVD = false; // Switch it of for the course of this routine 4412 SetVD = false; // Switch it of for the course of this routine
4374 VolumeDetectActive = false; // and also permanently 4413 VolumeDetectActive = false; // and also permanently
4375 if (PhysActor != null) 4414 if (PhysActor != null)
4376 PhysActor.SetVolumeDetect(0); // Let physics know about it too 4415 PhysActor.SetVolumeDetect(0); // Let physics know about it too
4377 } 4416 }
4378 else 4417 else
4379 { 4418 {
4380 IsPhantom = false;
4381 // If volumedetect is active we don't want phantom to be applied. 4419 // If volumedetect is active we don't want phantom to be applied.
4382 // If this is a new call to VD out of the state "phantom" 4420 // If this is a new call to VD out of the state "phantom"
4383 // this will also cause the prim to be visible to physics 4421 // this will also cause the prim to be visible to physics
4422 SetPhantom = false;
4384 } 4423 }
4385
4386 } 4424 }
4387 4425
4388 if (UsePhysics && IsJoint()) 4426 if (UsePhysics && IsJoint())
4389 { 4427 {
4390 IsPhantom = true; 4428 SetPhantom = true;
4391 } 4429 }
4392 4430
4393 if (UsePhysics) 4431 if (UsePhysics)
@@ -4396,14 +4434,12 @@ namespace OpenSim.Region.Framework.Scenes
4396 if (!wasUsingPhysics) 4434 if (!wasUsingPhysics)
4397 { 4435 {
4398 DoPhysicsPropertyUpdate(UsePhysics, false); 4436 DoPhysicsPropertyUpdate(UsePhysics, false);
4399 if (m_parentGroup != null) 4437
4438 if (!m_parentGroup.IsDeleted)
4400 { 4439 {
4401 if (!m_parentGroup.IsDeleted) 4440 if (LocalId == m_parentGroup.RootPart.LocalId)
4402 { 4441 {
4403 if (LocalId == m_parentGroup.RootPart.LocalId) 4442 m_parentGroup.CheckSculptAndLoad();
4404 {
4405 m_parentGroup.CheckSculptAndLoad();
4406 }
4407 } 4443 }
4408 } 4444 }
4409 } 4445 }
@@ -4417,8 +4453,9 @@ namespace OpenSim.Region.Framework.Scenes
4417 } 4453 }
4418 } 4454 }
4419 4455
4420 4456 if (SetPhantom
4421 if (IsPhantom || IsAttachment || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints 4457 || ParentGroup.IsAttachment
4458 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4422 { 4459 {
4423 AddFlag(PrimFlags.Phantom); 4460 AddFlag(PrimFlags.Phantom);
4424 if (PhysActor != null) 4461 if (PhysActor != null)
@@ -4432,7 +4469,11 @@ namespace OpenSim.Region.Framework.Scenes
4432 { 4469 {
4433 RemFlag(PrimFlags.Phantom); 4470 RemFlag(PrimFlags.Phantom);
4434 4471
4472 if (ParentGroup.Scene == null)
4473 return;
4474
4435 PhysicsActor pa = PhysActor; 4475 PhysicsActor pa = PhysActor;
4476
4436 if (pa == null) 4477 if (pa == null)
4437 { 4478 {
4438 // It's not phantom anymore. So make sure the physics engine get's knowledge of it 4479 // It's not phantom anymore. So make sure the physics engine get's knowledge of it
@@ -4444,22 +4485,21 @@ namespace OpenSim.Region.Framework.Scenes
4444 RotationOffset, 4485 RotationOffset,
4445 UsePhysics, 4486 UsePhysics,
4446 m_localId); 4487 m_localId);
4447 PhysActor.SetMaterial(Material);
4448 4488
4449 pa = PhysActor; 4489 pa = PhysActor;
4450 if (pa != null) 4490 if (pa != null)
4451 { 4491 {
4492 PhysActor.SetMaterial(Material);
4452 DoPhysicsPropertyUpdate(UsePhysics, true); 4493 DoPhysicsPropertyUpdate(UsePhysics, true);
4453 if (m_parentGroup != null) 4494
4495 if (!m_parentGroup.IsDeleted)
4454 { 4496 {
4455 if (!m_parentGroup.IsDeleted) 4497 if (LocalId == m_parentGroup.RootPart.LocalId)
4456 { 4498 {
4457 if (LocalId == m_parentGroup.RootPart.LocalId) 4499 m_parentGroup.CheckSculptAndLoad();
4458 {
4459 m_parentGroup.CheckSculptAndLoad();
4460 }
4461 } 4500 }
4462 } 4501 }
4502
4463 if ( 4503 if (
4464 ((AggregateScriptEvents & scriptEvents.collision) != 0) || 4504 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4465 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || 4505 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
@@ -4470,8 +4510,8 @@ namespace OpenSim.Region.Framework.Scenes
4470 (CollisionSound != UUID.Zero) 4510 (CollisionSound != UUID.Zero)
4471 ) 4511 )
4472 { 4512 {
4473 PhysActor.OnCollisionUpdate += PhysicsCollision; 4513 PhysActor.OnCollisionUpdate += PhysicsCollision;
4474 PhysActor.SubscribeEvents(1000); 4514 PhysActor.SubscribeEvents(1000);
4475 } 4515 }
4476 } 4516 }
4477 } 4517 }
@@ -4480,20 +4520,18 @@ namespace OpenSim.Region.Framework.Scenes
4480 pa.IsPhysical = UsePhysics; 4520 pa.IsPhysical = UsePhysics;
4481 4521
4482 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim 4522 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4483 if (m_parentGroup != null) 4523
4524 if (!m_parentGroup.IsDeleted)
4484 { 4525 {
4485 if (!m_parentGroup.IsDeleted) 4526 if (LocalId == m_parentGroup.RootPart.LocalId)
4486 { 4527 {
4487 if (LocalId == m_parentGroup.RootPart.LocalId) 4528 m_parentGroup.CheckSculptAndLoad();
4488 {
4489 m_parentGroup.CheckSculptAndLoad();
4490 }
4491 } 4529 }
4492 } 4530 }
4493 } 4531 }
4494 } 4532 }
4495 4533
4496 if (IsVD) 4534 if (SetVD)
4497 { 4535 {
4498 // If the above logic worked (this is urgent candidate to unit tests!) 4536 // If the above logic worked (this is urgent candidate to unit tests!)
4499 // we now have a physicsactor. 4537 // we now have a physicsactor.
@@ -4508,18 +4546,19 @@ namespace OpenSim.Region.Framework.Scenes
4508 } 4546 }
4509 } 4547 }
4510 else 4548 else
4511 { // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like 4549 {
4550 // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like
4512 // (mumbles, well, at least if you have infinte CPU powers :-)) 4551 // (mumbles, well, at least if you have infinte CPU powers :-))
4513 PhysicsActor pa = this.PhysActor; 4552 PhysicsActor pa = this.PhysActor;
4514 if (pa != null) 4553 if (pa != null)
4515 { 4554 {
4516 PhysActor.SetVolumeDetect(0); 4555 PhysActor.SetVolumeDetect(0);
4517 } 4556 }
4557
4518 this.VolumeDetectActive = false; 4558 this.VolumeDetectActive = false;
4519 } 4559 }
4520 4560
4521 4561 if (SetTemporary)
4522 if (IsTemporary)
4523 { 4562 {
4524 AddFlag(PrimFlags.TemporaryOnRez); 4563 AddFlag(PrimFlags.TemporaryOnRez);
4525 } 4564 }
@@ -4529,8 +4568,13 @@ namespace OpenSim.Region.Framework.Scenes
4529 } 4568 }
4530 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); 4569 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4531 4570
4532 ParentGroup.HasGroupChanged = true; 4571 if (ParentGroup != null)
4533 ScheduleFullUpdate(); 4572 {
4573 ParentGroup.HasGroupChanged = true;
4574 ScheduleFullUpdate();
4575 }
4576
4577// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4534 } 4578 }
4535 4579
4536 public void UpdateRotation(Quaternion rot) 4580 public void UpdateRotation(Quaternion rot)
@@ -4541,8 +4585,12 @@ namespace OpenSim.Region.Framework.Scenes
4541 (rot.W != RotationOffset.W)) 4585 (rot.W != RotationOffset.W))
4542 { 4586 {
4543 RotationOffset = rot; 4587 RotationOffset = rot;
4544 ParentGroup.HasGroupChanged = true; 4588
4545 ScheduleTerseUpdate(); 4589 if (ParentGroup != null)
4590 {
4591 ParentGroup.HasGroupChanged = true;
4592 ScheduleTerseUpdate();
4593 }
4546 } 4594 }
4547 } 4595 }
4548 4596
@@ -4570,6 +4618,7 @@ namespace OpenSim.Region.Framework.Scenes
4570 m_shape.PathTaperY = shapeBlock.PathTaperY; 4618 m_shape.PathTaperY = shapeBlock.PathTaperY;
4571 m_shape.PathTwist = shapeBlock.PathTwist; 4619 m_shape.PathTwist = shapeBlock.PathTwist;
4572 m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; 4620 m_shape.PathTwistBegin = shapeBlock.PathTwistBegin;
4621
4573 if (PhysActor != null) 4622 if (PhysActor != null)
4574 { 4623 {
4575 PhysActor.Shape = m_shape; 4624 PhysActor.Shape = m_shape;
@@ -4591,11 +4640,46 @@ namespace OpenSim.Region.Framework.Scenes
4591 } 4640 }
4592 4641
4593 /// <summary> 4642 /// <summary>
4643 /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics
4644 /// engine can use it.
4645 /// </summary>
4646 /// <remarks>
4647 /// When the physics engine has finished with it, the sculpt data is discarded to save memory.
4648 /// </remarks>
4649 public void CheckSculptAndLoad()
4650 {
4651// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4652
4653 if (ParentGroup.IsDeleted)
4654 return;
4655
4656 if ((ParentGroup.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0)
4657 return;
4658
4659 if (Shape.SculptEntry && Shape.SculptTexture != UUID.Zero)
4660 {
4661 // check if a previously decoded sculpt map has been cached
4662 // We don't read the file here - the meshmerizer will do that later.
4663 // TODO: Could we simplify the meshmerizer code by reading and setting the data here?
4664 if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + Shape.SculptTexture.ToString())))
4665 {
4666 SculptTextureCallback(null);
4667 }
4668 else
4669 {
4670 ParentGroup.Scene.AssetService.Get(Shape.SculptTexture.ToString(), this, AssetReceived);
4671 }
4672 }
4673 }
4674
4675 /// <summary>
4594 /// Update the textures on the part. 4676 /// Update the textures on the part.
4595 /// </summary> 4677 /// </summary>
4678 /// <remarks>
4596 /// Added to handle bug in libsecondlife's TextureEntry.ToBytes() 4679 /// Added to handle bug in libsecondlife's TextureEntry.ToBytes()
4597 /// not handling RGBA properly. Cycles through, and "fixes" the color 4680 /// not handling RGBA properly. Cycles through, and "fixes" the color
4598 /// info 4681 /// info
4682 /// </remarks>
4599 /// <param name="tex"></param> 4683 /// <param name="tex"></param>
4600 public void UpdateTexture(Primitive.TextureEntry tex) 4684 public void UpdateTexture(Primitive.TextureEntry tex)
4601 { 4685 {
@@ -4687,7 +4771,6 @@ namespace OpenSim.Region.Framework.Scenes
4687 { 4771 {
4688 PhysActor.OnCollisionUpdate += PhysicsCollision; 4772 PhysActor.OnCollisionUpdate += PhysicsCollision;
4689 PhysActor.SubscribeEvents(1000); 4773 PhysActor.SubscribeEvents(1000);
4690
4691 } 4774 }
4692 } 4775 }
4693 else 4776 else
@@ -4699,14 +4782,6 @@ namespace OpenSim.Region.Framework.Scenes
4699 } 4782 }
4700 } 4783 }
4701 4784
4702 if (m_parentGroup == null)
4703 {
4704// m_log.DebugFormat(
4705// "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents() since m_parentGroup == null", Name, LocalId);
4706 ScheduleFullUpdate();
4707 return;
4708 }
4709
4710 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 4785 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4711 //{ 4786 //{
4712 // m_parentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting; 4787 // m_parentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting;
@@ -4716,7 +4791,7 @@ namespace OpenSim.Region.Framework.Scenes
4716 // m_parentGroup.Scene.EventManager.OnScriptTimerEvent -= handleTimerAccounting; 4791 // m_parentGroup.Scene.EventManager.OnScriptTimerEvent -= handleTimerAccounting;
4717 //} 4792 //}
4718 4793
4719 LocalFlags=(PrimFlags)objectflagupdate; 4794 LocalFlags = (PrimFlags)objectflagupdate;
4720 4795
4721 if (m_parentGroup != null && m_parentGroup.RootPart == this) 4796 if (m_parentGroup != null && m_parentGroup.RootPart == this)
4722 { 4797 {
@@ -4730,40 +4805,6 @@ namespace OpenSim.Region.Framework.Scenes
4730 } 4805 }
4731 } 4806 }
4732 4807
4733 public int registerTargetWaypoint(Vector3 target, float tolerance)
4734 {
4735 if (m_parentGroup != null)
4736 {
4737 return m_parentGroup.registerTargetWaypoint(target, tolerance);
4738 }
4739 return 0;
4740 }
4741
4742 public void unregisterTargetWaypoint(int handle)
4743 {
4744 if (m_parentGroup != null)
4745 {
4746 m_parentGroup.unregisterTargetWaypoint(handle);
4747 }
4748 }
4749
4750 public int registerRotTargetWaypoint(Quaternion target, float tolerance)
4751 {
4752 if (m_parentGroup != null)
4753 {
4754 return m_parentGroup.registerRotTargetWaypoint(target, tolerance);
4755 }
4756 return 0;
4757 }
4758
4759 public void unregisterRotTargetWaypoint(int handle)
4760 {
4761 if (m_parentGroup != null)
4762 {
4763 m_parentGroup.unregisterRotTargetWaypoint(handle);
4764 }
4765 }
4766
4767 public void SetCameraAtOffset(Vector3 v) 4808 public void SetCameraAtOffset(Vector3 v)
4768 { 4809 {
4769 m_cameraAtOffset = v; 4810 m_cameraAtOffset = v;
@@ -4803,10 +4844,10 @@ namespace OpenSim.Region.Framework.Scenes
4803 4844
4804 public void SendTerseUpdateToClient(IClientAPI remoteClient) 4845 public void SendTerseUpdateToClient(IClientAPI remoteClient)
4805 { 4846 {
4806 if (ParentGroup == null || ParentGroup.IsDeleted) 4847 if (ParentGroup.IsDeleted)
4807 return; 4848 return;
4808 4849
4809 if (IsAttachment && ParentGroup.RootPart != this) 4850 if (ParentGroup.IsAttachment && ParentGroup.RootPart != this)
4810 return; 4851 return;
4811 4852
4812 // Causes this thread to dig into the Client Thread Data. 4853 // Causes this thread to dig into the Client Thread Data.
@@ -4827,6 +4868,7 @@ namespace OpenSim.Region.Framework.Scenes
4827 4868
4828 Inventory.ApplyNextOwnerPermissions(); 4869 Inventory.ApplyNextOwnerPermissions();
4829 } 4870 }
4871
4830 public void UpdateLookAt() 4872 public void UpdateLookAt()
4831 { 4873 {
4832 try 4874 try