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.cs480
1 files changed, 358 insertions, 122 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 439b718..cce606a 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -62,7 +62,8 @@ namespace OpenSim.Region.Framework.Scenes
62 TELEPORT = 512, 62 TELEPORT = 512,
63 REGION_RESTART = 1024, 63 REGION_RESTART = 1024,
64 MEDIA = 2048, 64 MEDIA = 2048,
65 ANIMATION = 16384 65 ANIMATION = 16384,
66 POSITION = 32768
66 } 67 }
67 68
68 // I don't really know where to put this except here. 69 // I don't really know where to put this except here.
@@ -184,6 +185,15 @@ namespace OpenSim.Region.Framework.Scenes
184 185
185 public UUID FromFolderID; 186 public UUID FromFolderID;
186 187
188 // The following two are to hold the attachment data
189 // while an object is inworld
190 [XmlIgnore]
191 public byte AttachPoint = 0;
192
193 [XmlIgnore]
194 public Vector3 AttachOffset = Vector3.Zero;
195
196 [XmlIgnore]
187 public int STATUS_ROTATE_X; 197 public int STATUS_ROTATE_X;
188 198
189 public int STATUS_ROTATE_Y; 199 public int STATUS_ROTATE_Y;
@@ -210,8 +220,7 @@ namespace OpenSim.Region.Framework.Scenes
210 220
211 public Vector3 RotationAxis = Vector3.One; 221 public Vector3 RotationAxis = Vector3.One;
212 222
213 public bool VolumeDetectActive; // XmlIgnore set to avoid problems with persistance until I come to care for this 223 public bool VolumeDetectActive;
214 // Certainly this must be a persistant setting finally
215 224
216 public bool IsWaitingForFirstSpinUpdatePacket; 225 public bool IsWaitingForFirstSpinUpdatePacket;
217 226
@@ -251,10 +260,11 @@ namespace OpenSim.Region.Framework.Scenes
251 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 260 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
252 private Vector3 m_sitTargetPosition; 261 private Vector3 m_sitTargetPosition;
253 private string m_sitAnimation = "SIT"; 262 private string m_sitAnimation = "SIT";
263 private bool m_occupied; // KF if any av is sitting on this prim
254 private string m_text = String.Empty; 264 private string m_text = String.Empty;
255 private string m_touchName = String.Empty; 265 private string m_touchName = String.Empty;
256 private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5); 266 private Stack<UndoState> m_undo = new Stack<UndoState>(5);
257 private readonly Stack<UndoState> m_redo = new Stack<UndoState>(5); 267 private Stack<UndoState> m_redo = new Stack<UndoState>(5);
258 268
259 private bool m_passTouches; 269 private bool m_passTouches;
260 270
@@ -283,6 +293,9 @@ namespace OpenSim.Region.Framework.Scenes
283 protected Vector3 m_lastAcceleration; 293 protected Vector3 m_lastAcceleration;
284 protected Vector3 m_lastAngularVelocity; 294 protected Vector3 m_lastAngularVelocity;
285 protected int m_lastTerseSent; 295 protected int m_lastTerseSent;
296 protected float m_buoyancy = 0.0f;
297 protected Vector3 m_force;
298 protected Vector3 m_torque;
286 299
287 /// <summary> 300 /// <summary>
288 /// Stores media texture data 301 /// Stores media texture data
@@ -299,6 +312,17 @@ namespace OpenSim.Region.Framework.Scenes
299 private UUID m_collisionSound; 312 private UUID m_collisionSound;
300 private float m_collisionSoundVolume; 313 private float m_collisionSoundVolume;
301 314
315
316 private SOPVehicle m_vehicle = null;
317
318 private KeyframeMotion m_keyframeMotion = null;
319
320 public KeyframeMotion KeyframeMotion
321 {
322 get; set;
323 }
324
325
302 #endregion Fields 326 #endregion Fields
303 327
304// ~SceneObjectPart() 328// ~SceneObjectPart()
@@ -341,7 +365,7 @@ namespace OpenSim.Region.Framework.Scenes
341 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 365 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
342 Quaternion rotationOffset, Vector3 offsetPosition) : this() 366 Quaternion rotationOffset, Vector3 offsetPosition) : this()
343 { 367 {
344 m_name = "Primitive"; 368 m_name = "Object";
345 369
346 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 370 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
347 LastOwnerID = CreatorID = OwnerID = ownerID; 371 LastOwnerID = CreatorID = OwnerID = ownerID;
@@ -381,7 +405,7 @@ namespace OpenSim.Region.Framework.Scenes
381 private uint _ownerMask = (uint)PermissionMask.All; 405 private uint _ownerMask = (uint)PermissionMask.All;
382 private uint _groupMask = (uint)PermissionMask.None; 406 private uint _groupMask = (uint)PermissionMask.None;
383 private uint _everyoneMask = (uint)PermissionMask.None; 407 private uint _everyoneMask = (uint)PermissionMask.None;
384 private uint _nextOwnerMask = (uint)PermissionMask.All; 408 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
385 private PrimFlags _flags = PrimFlags.None; 409 private PrimFlags _flags = PrimFlags.None;
386 private DateTime m_expires; 410 private DateTime m_expires;
387 private DateTime m_rezzed; 411 private DateTime m_rezzed;
@@ -475,12 +499,16 @@ namespace OpenSim.Region.Framework.Scenes
475 } 499 }
476 500
477 /// <value> 501 /// <value>
478 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 502 /// Get the inventory list
479 /// </value> 503 /// </value>
480 public TaskInventoryDictionary TaskInventory 504 public TaskInventoryDictionary TaskInventory
481 { 505 {
482 get { return m_inventory.Items; } 506 get {
483 set { m_inventory.Items = value; } 507 return m_inventory.Items;
508 }
509 set {
510 m_inventory.Items = value;
511 }
484 } 512 }
485 513
486 /// <summary> 514 /// <summary>
@@ -624,14 +652,12 @@ namespace OpenSim.Region.Framework.Scenes
624 set { m_LoopSoundSlavePrims = value; } 652 set { m_LoopSoundSlavePrims = value; }
625 } 653 }
626 654
627
628 public Byte[] TextureAnimation 655 public Byte[] TextureAnimation
629 { 656 {
630 get { return m_TextureAnimation; } 657 get { return m_TextureAnimation; }
631 set { m_TextureAnimation = value; } 658 set { m_TextureAnimation = value; }
632 } 659 }
633 660
634
635 public Byte[] ParticleSystem 661 public Byte[] ParticleSystem
636 { 662 {
637 get { return m_particleSystem; } 663 get { return m_particleSystem; }
@@ -668,9 +694,11 @@ namespace OpenSim.Region.Framework.Scenes
668 { 694 {
669 // If this is a linkset, we don't want the physics engine mucking up our group position here. 695 // If this is a linkset, we don't want the physics engine mucking up our group position here.
670 PhysicsActor actor = PhysActor; 696 PhysicsActor actor = PhysActor;
671 if (actor != null && ParentID == 0) 697 if (ParentID == 0)
672 { 698 {
673 m_groupPosition = actor.Position; 699 if (actor != null)
700 m_groupPosition = actor.Position;
701 return m_groupPosition;
674 } 702 }
675 703
676 if (ParentGroup.IsAttachment) 704 if (ParentGroup.IsAttachment)
@@ -680,12 +708,14 @@ namespace OpenSim.Region.Framework.Scenes
680 return sp.AbsolutePosition; 708 return sp.AbsolutePosition;
681 } 709 }
682 710
711 // use root prim's group position. Physics may have updated it
712 if (ParentGroup.RootPart != this)
713 m_groupPosition = ParentGroup.RootPart.GroupPosition;
683 return m_groupPosition; 714 return m_groupPosition;
684 } 715 }
685 set 716 set
686 { 717 {
687 m_groupPosition = value; 718 m_groupPosition = value;
688
689 PhysicsActor actor = PhysActor; 719 PhysicsActor actor = PhysActor;
690 if (actor != null) 720 if (actor != null)
691 { 721 {
@@ -711,16 +741,6 @@ namespace OpenSim.Region.Framework.Scenes
711 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); 741 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message);
712 } 742 }
713 } 743 }
714
715 // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
716 if (SitTargetAvatar != UUID.Zero)
717 {
718 ScenePresence avatar;
719 if (ParentGroup.Scene.TryGetScenePresence(SitTargetAvatar, out avatar))
720 {
721 avatar.ParentPosition = GetWorldPosition();
722 }
723 }
724 } 744 }
725 } 745 }
726 746
@@ -729,7 +749,7 @@ namespace OpenSim.Region.Framework.Scenes
729 get { return m_offsetPosition; } 749 get { return m_offsetPosition; }
730 set 750 set
731 { 751 {
732// StoreUndoState(); 752 Vector3 oldpos = m_offsetPosition;
733 m_offsetPosition = value; 753 m_offsetPosition = value;
734 754
735 if (ParentGroup != null && !ParentGroup.IsDeleted) 755 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -744,7 +764,22 @@ namespace OpenSim.Region.Framework.Scenes
744 if (ParentGroup.Scene != null) 764 if (ParentGroup.Scene != null)
745 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 765 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
746 } 766 }
767
768 if (!m_parentGroup.m_dupeInProgress)
769 {
770 List<ScenePresence> avs = ParentGroup.GetLinkedAvatars();
771 foreach (ScenePresence av in avs)
772 {
773 if (av.ParentID == m_localId)
774 {
775 Vector3 offset = (m_offsetPosition - oldpos);
776 av.AbsolutePosition += offset;
777 av.SendAvatarDataToAllAgents();
778 }
779 }
780 }
747 } 781 }
782 TriggerScriptChangedEvent(Changed.POSITION);
748 } 783 }
749 } 784 }
750 785
@@ -881,7 +916,7 @@ namespace OpenSim.Region.Framework.Scenes
881 get 916 get
882 { 917 {
883 PhysicsActor actor = PhysActor; 918 PhysicsActor actor = PhysActor;
884 if ((actor != null) && actor.IsPhysical) 919 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
885 { 920 {
886 m_angularVelocity = actor.RotationalVelocity; 921 m_angularVelocity = actor.RotationalVelocity;
887 } 922 }
@@ -893,7 +928,16 @@ namespace OpenSim.Region.Framework.Scenes
893 /// <summary></summary> 928 /// <summary></summary>
894 public Vector3 Acceleration 929 public Vector3 Acceleration
895 { 930 {
896 get { return m_acceleration; } 931 get
932 {
933 PhysicsActor actor = PhysActor;
934 if (actor != null)
935 {
936 m_acceleration = actor.Acceleration;
937 }
938 return m_acceleration;
939 }
940
897 set { m_acceleration = value; } 941 set { m_acceleration = value; }
898 } 942 }
899 943
@@ -1030,10 +1074,7 @@ namespace OpenSim.Region.Framework.Scenes
1030 { 1074 {
1031 get 1075 get
1032 { 1076 {
1033 if (ParentGroup.IsAttachment) 1077 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
1034 return GroupPosition;
1035
1036 return m_offsetPosition + m_groupPosition;
1037 } 1078 }
1038 } 1079 }
1039 1080
@@ -1203,6 +1244,13 @@ namespace OpenSim.Region.Framework.Scenes
1203 _flags = value; 1244 _flags = value;
1204 } 1245 }
1205 } 1246 }
1247
1248 [XmlIgnore]
1249 public bool IsOccupied // KF If an av is sittingon this prim
1250 {
1251 get { return m_occupied; }
1252 set { m_occupied = value; }
1253 }
1206 1254
1207 /// <summary> 1255 /// <summary>
1208 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero 1256 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero
@@ -1262,6 +1310,74 @@ namespace OpenSim.Region.Framework.Scenes
1262 set { m_collisionSoundVolume = value; } 1310 set { m_collisionSoundVolume = value; }
1263 } 1311 }
1264 1312
1313 public float Buoyancy
1314 {
1315 get
1316 {
1317 if (ParentGroup.RootPart == this)
1318 return m_buoyancy;
1319
1320 return ParentGroup.RootPart.Buoyancy;
1321 }
1322 set
1323 {
1324 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1325 {
1326 ParentGroup.RootPart.Buoyancy = value;
1327 return;
1328 }
1329 m_buoyancy = value;
1330 if (PhysActor != null)
1331 PhysActor.Buoyancy = value;
1332 }
1333 }
1334
1335 public Vector3 Force
1336 {
1337 get
1338 {
1339 if (ParentGroup.RootPart == this)
1340 return m_force;
1341
1342 return ParentGroup.RootPart.Force;
1343 }
1344
1345 set
1346 {
1347 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1348 {
1349 ParentGroup.RootPart.Force = value;
1350 return;
1351 }
1352 m_force = value;
1353 if (PhysActor != null)
1354 PhysActor.Force = value;
1355 }
1356 }
1357
1358 public Vector3 Torque
1359 {
1360 get
1361 {
1362 if (ParentGroup.RootPart == this)
1363 return m_torque;
1364
1365 return ParentGroup.RootPart.Torque;
1366 }
1367
1368 set
1369 {
1370 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1371 {
1372 ParentGroup.RootPart.Torque = value;
1373 return;
1374 }
1375 m_torque = value;
1376 if (PhysActor != null)
1377 PhysActor.Torque = value;
1378 }
1379 }
1380
1265 #endregion Public Properties with only Get 1381 #endregion Public Properties with only Get
1266 1382
1267 private uint ApplyMask(uint val, bool set, uint mask) 1383 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1437,20 +1553,24 @@ namespace OpenSim.Region.Framework.Scenes
1437 /// </summary> 1553 /// </summary>
1438 /// <param name="impulsei">Vector force</param> 1554 /// <param name="impulsei">Vector force</param>
1439 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> 1555 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
1440 public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF) 1556
1557 // this is actualy Set Torque.. keeping naming so not to edit lslapi also
1558 public void SetAngularImpulse(Vector3 torquei, bool localGlobalTF)
1441 { 1559 {
1442 Vector3 impulse = impulsei; 1560 Vector3 torque = torquei;
1443 1561
1444 if (localGlobalTF) 1562 if (localGlobalTF)
1445 { 1563 {
1564/*
1446 Quaternion grot = GetWorldRotation(); 1565 Quaternion grot = GetWorldRotation();
1447 Quaternion AXgrot = grot; 1566 Quaternion AXgrot = grot;
1448 Vector3 AXimpulsei = impulsei; 1567 Vector3 AXimpulsei = impulsei;
1449 Vector3 newimpulse = AXimpulsei * AXgrot; 1568 Vector3 newimpulse = AXimpulsei * AXgrot;
1450 impulse = newimpulse; 1569 */
1570 torque *= GetWorldRotation();
1451 } 1571 }
1452 1572
1453 ParentGroup.setAngularImpulse(impulse); 1573 Torque = torque;
1454 } 1574 }
1455 1575
1456 /// <summary> 1576 /// <summary>
@@ -1458,7 +1578,8 @@ namespace OpenSim.Region.Framework.Scenes
1458 /// </summary> 1578 /// </summary>
1459 /// <param name="rootObjectFlags"></param> 1579 /// <param name="rootObjectFlags"></param>
1460 /// <param name="VolumeDetectActive"></param> 1580 /// <param name="VolumeDetectActive"></param>
1461 public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive) 1581// public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive)
1582 public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive, bool building)
1462 { 1583 {
1463 if (!ParentGroup.Scene.CollidablePrims) 1584 if (!ParentGroup.Scene.CollidablePrims)
1464 return; 1585 return;
@@ -1487,6 +1608,8 @@ namespace OpenSim.Region.Framework.Scenes
1487 // or flexible 1608 // or flexible
1488 if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible)) 1609 if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1489 { 1610 {
1611 Vector3 velocity = Velocity;
1612 Vector3 rotationalVelocity = AngularVelocity;
1490 try 1613 try
1491 { 1614 {
1492 PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape( 1615 PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape(
@@ -1494,7 +1617,8 @@ namespace OpenSim.Region.Framework.Scenes
1494 Shape, 1617 Shape,
1495 AbsolutePosition, 1618 AbsolutePosition,
1496 Scale, 1619 Scale,
1497 RotationOffset, 1620// RotationOffset,
1621 GetWorldRotation(), // physics wants world rotation
1498 RigidBody, 1622 RigidBody,
1499 m_localId); 1623 m_localId);
1500 } 1624 }
@@ -1509,8 +1633,29 @@ namespace OpenSim.Region.Framework.Scenes
1509 { 1633 {
1510 PhysActor.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 1634 PhysActor.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
1511 PhysActor.SetMaterial(Material); 1635 PhysActor.SetMaterial(Material);
1636
1637 // if root part apply vehicle
1638 if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
1639 m_vehicle.SetVehicle(PhysActor);
1640
1512 DoPhysicsPropertyUpdate(RigidBody, true); 1641 DoPhysicsPropertyUpdate(RigidBody, true);
1513 PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); 1642 PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
1643
1644 if (!building)
1645 PhysActor.Building = false;
1646
1647 Velocity = velocity;
1648 AngularVelocity = rotationalVelocity;
1649 PhysActor.Velocity = velocity;
1650 PhysActor.RotationalVelocity = rotationalVelocity;
1651
1652 // if not vehicle and root part apply force and torque
1653 if ((m_vehicle == null || m_vehicle.Type == Vehicle.TYPE_NONE)
1654 && LocalId == ParentGroup.RootPart.LocalId)
1655 {
1656 PhysActor.Force = Force;
1657 PhysActor.Torque = Torque;
1658 }
1514 } 1659 }
1515 } 1660 }
1516 } 1661 }
@@ -1564,6 +1709,11 @@ namespace OpenSim.Region.Framework.Scenes
1564 dupe.Category = Category; 1709 dupe.Category = Category;
1565 dupe.m_rezzed = m_rezzed; 1710 dupe.m_rezzed = m_rezzed;
1566 1711
1712 dupe.m_undo = new Stack<UndoState>(5);
1713 dupe.m_redo = new Stack<UndoState>(5);
1714 dupe.IgnoreUndoUpdate = false;
1715 dupe.Undoing = false;
1716
1567 dupe.m_inventory = new SceneObjectPartInventory(dupe); 1717 dupe.m_inventory = new SceneObjectPartInventory(dupe);
1568 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone(); 1718 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone();
1569 1719
@@ -1579,6 +1729,7 @@ namespace OpenSim.Region.Framework.Scenes
1579 1729
1580 // Move afterwards ResetIDs as it clears the localID 1730 // Move afterwards ResetIDs as it clears the localID
1581 dupe.LocalId = localID; 1731 dupe.LocalId = localID;
1732
1582 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 1733 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1583 dupe.LastOwnerID = OwnerID; 1734 dupe.LastOwnerID = OwnerID;
1584 1735
@@ -1598,6 +1749,9 @@ namespace OpenSim.Region.Framework.Scenes
1598 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 1749 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
1599 } 1750 }
1600 1751
1752 if (dupe.PhysActor != null)
1753 dupe.PhysActor.LocalID = localID;
1754
1601 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 1755 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1602 1756
1603// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); 1757// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
@@ -1740,6 +1894,11 @@ namespace OpenSim.Region.Framework.Scenes
1740 if (!isNew) 1894 if (!isNew)
1741 ParentGroup.Scene.RemovePhysicalPrim(1); 1895 ParentGroup.Scene.RemovePhysicalPrim(1);
1742 1896
1897 Velocity = new Vector3(0, 0, 0);
1898 Acceleration = new Vector3(0, 0, 0);
1899 if (ParentGroup.RootPart == this)
1900 AngularVelocity = new Vector3(0, 0, 0);
1901
1743 PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 1902 PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1744 PhysActor.OnOutOfBounds -= PhysicsOutOfBounds; 1903 PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
1745 PhysActor.delink(); 1904 PhysActor.delink();
@@ -1762,7 +1921,8 @@ namespace OpenSim.Region.Framework.Scenes
1762 // velocity-vector. 1921 // velocity-vector.
1763 Velocity = new Vector3(0, 0, 0); 1922 Velocity = new Vector3(0, 0, 0);
1764 Acceleration = new Vector3(0, 0, 0); 1923 Acceleration = new Vector3(0, 0, 0);
1765 AngularVelocity = new Vector3(0, 0, 0); 1924 if (ParentGroup.RootPart == this)
1925 AngularVelocity = new Vector3(0, 0, 0);
1766 //RotationalVelocity = new Vector3(0, 0, 0); 1926 //RotationalVelocity = new Vector3(0, 0, 0);
1767 } 1927 }
1768 1928
@@ -1777,6 +1937,9 @@ namespace OpenSim.Region.Framework.Scenes
1777 { 1937 {
1778 if (UsePhysics) 1938 if (UsePhysics)
1779 { 1939 {
1940 if (ParentGroup.RootPart.KeyframeMotion != null)
1941 ParentGroup.RootPart.KeyframeMotion.Stop();
1942 ParentGroup.RootPart.KeyframeMotion = null;
1780 ParentGroup.Scene.AddPhysicalPrim(1); 1943 ParentGroup.Scene.AddPhysicalPrim(1);
1781 1944
1782 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 1945 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
@@ -1924,10 +2087,7 @@ namespace OpenSim.Region.Framework.Scenes
1924 2087
1925 public Vector3 GetForce() 2088 public Vector3 GetForce()
1926 { 2089 {
1927 if (PhysActor != null) 2090 return Force;
1928 return PhysActor.Force;
1929 else
1930 return Vector3.Zero;
1931 } 2091 }
1932 2092
1933 /// <summary> 2093 /// <summary>
@@ -2561,9 +2721,9 @@ namespace OpenSim.Region.Framework.Scenes
2561 Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0); 2721 Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0);
2562 2722
2563 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2723 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2564 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2724 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2565 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2725 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2566 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2726 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2567 { 2727 {
2568 ParentGroup.AbsolutePosition = newpos; 2728 ParentGroup.AbsolutePosition = newpos;
2569 return; 2729 return;
@@ -2584,17 +2744,18 @@ namespace OpenSim.Region.Framework.Scenes
2584 //Trys to fetch sound id from prim's inventory. 2744 //Trys to fetch sound id from prim's inventory.
2585 //Prim's inventory doesn't support non script items yet 2745 //Prim's inventory doesn't support non script items yet
2586 2746
2587 lock (TaskInventory) 2747 TaskInventory.LockItemsForRead(true);
2748
2749 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2588 { 2750 {
2589 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2751 if (item.Value.Name == sound)
2590 { 2752 {
2591 if (item.Value.Name == sound) 2753 soundID = item.Value.ItemID;
2592 { 2754 break;
2593 soundID = item.Value.ItemID;
2594 break;
2595 }
2596 } 2755 }
2597 } 2756 }
2757
2758 TaskInventory.LockItemsForRead(false);
2598 } 2759 }
2599 2760
2600 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp) 2761 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp)
@@ -2914,8 +3075,8 @@ namespace OpenSim.Region.Framework.Scenes
2914 { 3075 {
2915 const float ROTATION_TOLERANCE = 0.01f; 3076 const float ROTATION_TOLERANCE = 0.01f;
2916 const float VELOCITY_TOLERANCE = 0.001f; 3077 const float VELOCITY_TOLERANCE = 0.001f;
2917 const float POSITION_TOLERANCE = 0.05f; 3078 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2918 const int TIME_MS_TOLERANCE = 3000; 3079 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2919 3080
2920 switch (UpdateFlag) 3081 switch (UpdateFlag)
2921 { 3082 {
@@ -2977,17 +3138,16 @@ namespace OpenSim.Region.Framework.Scenes
2977 if (!UUID.TryParse(sound, out soundID)) 3138 if (!UUID.TryParse(sound, out soundID))
2978 { 3139 {
2979 // search sound file from inventory 3140 // search sound file from inventory
2980 lock (TaskInventory) 3141 TaskInventory.LockItemsForRead(true);
3142 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2981 { 3143 {
2982 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 3144 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
2983 { 3145 {
2984 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 3146 soundID = item.Value.ItemID;
2985 { 3147 break;
2986 soundID = item.Value.ItemID;
2987 break;
2988 }
2989 } 3148 }
2990 } 3149 }
3150 TaskInventory.LockItemsForRead(false);
2991 } 3151 }
2992 3152
2993 if (soundID == UUID.Zero) 3153 if (soundID == UUID.Zero)
@@ -3072,10 +3232,13 @@ namespace OpenSim.Region.Framework.Scenes
3072 3232
3073 public void SetBuoyancy(float fvalue) 3233 public void SetBuoyancy(float fvalue)
3074 { 3234 {
3235 Buoyancy = fvalue;
3236/*
3075 if (PhysActor != null) 3237 if (PhysActor != null)
3076 { 3238 {
3077 PhysActor.Buoyancy = fvalue; 3239 PhysActor.Buoyancy = fvalue;
3078 } 3240 }
3241 */
3079 } 3242 }
3080 3243
3081 public void SetDieAtEdge(bool p) 3244 public void SetDieAtEdge(bool p)
@@ -3103,23 +3266,83 @@ namespace OpenSim.Region.Framework.Scenes
3103 3266
3104 public void SetForce(Vector3 force) 3267 public void SetForce(Vector3 force)
3105 { 3268 {
3269 Force = force;
3270/*
3106 if (PhysActor != null) 3271 if (PhysActor != null)
3107 { 3272 {
3108 PhysActor.Force = force; 3273 PhysActor.Force = force;
3109 } 3274 }
3275 */
3276 }
3277
3278 public SOPVehicle sopVehicle
3279 {
3280 get
3281 {
3282 return m_vehicle;
3283 }
3284 set
3285 {
3286 m_vehicle = value;
3287 }
3288 }
3289
3290
3291 public int VehicleType
3292 {
3293 get
3294 {
3295 if (m_vehicle == null)
3296 return (int)Vehicle.TYPE_NONE;
3297 else
3298 return (int)m_vehicle.Type;
3299 }
3300 set
3301 {
3302 SetVehicleType(value);
3303 }
3110 } 3304 }
3111 3305
3112 public void SetVehicleType(int type) 3306 public void SetVehicleType(int type)
3113 { 3307 {
3114 if (PhysActor != null) 3308 m_vehicle = null;
3309
3310 if (type == (int)Vehicle.TYPE_NONE)
3311 {
3312 if (_parentID ==0 && PhysActor != null)
3313 PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
3314 return;
3315 }
3316 m_vehicle = new SOPVehicle();
3317 m_vehicle.ProcessTypeChange((Vehicle)type);
3318 {
3319 if (_parentID ==0 && PhysActor != null)
3320 PhysActor.VehicleType = type;
3321 return;
3322 }
3323 }
3324
3325 public void SetVehicleFlags(int param, bool remove)
3326 {
3327 if (m_vehicle == null)
3328 return;
3329
3330 m_vehicle.ProcessVehicleFlags(param, remove);
3331
3332 if (_parentID ==0 && PhysActor != null)
3115 { 3333 {
3116 PhysActor.VehicleType = type; 3334 PhysActor.VehicleFlags(param, remove);
3117 } 3335 }
3118 } 3336 }
3119 3337
3120 public void SetVehicleFloatParam(int param, float value) 3338 public void SetVehicleFloatParam(int param, float value)
3121 { 3339 {
3122 if (PhysActor != null) 3340 if (m_vehicle == null)
3341 return;
3342
3343 m_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
3344
3345 if (_parentID == 0 && PhysActor != null)
3123 { 3346 {
3124 PhysActor.VehicleFloatParam(param, value); 3347 PhysActor.VehicleFloatParam(param, value);
3125 } 3348 }
@@ -3127,7 +3350,12 @@ namespace OpenSim.Region.Framework.Scenes
3127 3350
3128 public void SetVehicleVectorParam(int param, Vector3 value) 3351 public void SetVehicleVectorParam(int param, Vector3 value)
3129 { 3352 {
3130 if (PhysActor != null) 3353 if (m_vehicle == null)
3354 return;
3355
3356 m_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
3357
3358 if (_parentID == 0 && PhysActor != null)
3131 { 3359 {
3132 PhysActor.VehicleVectorParam(param, value); 3360 PhysActor.VehicleVectorParam(param, value);
3133 } 3361 }
@@ -3135,7 +3363,12 @@ namespace OpenSim.Region.Framework.Scenes
3135 3363
3136 public void SetVehicleRotationParam(int param, Quaternion rotation) 3364 public void SetVehicleRotationParam(int param, Quaternion rotation)
3137 { 3365 {
3138 if (PhysActor != null) 3366 if (m_vehicle == null)
3367 return;
3368
3369 m_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
3370
3371 if (_parentID == 0 && PhysActor != null)
3139 { 3372 {
3140 PhysActor.VehicleRotationParam(param, rotation); 3373 PhysActor.VehicleRotationParam(param, rotation);
3141 } 3374 }
@@ -3322,13 +3555,6 @@ namespace OpenSim.Region.Framework.Scenes
3322 hasProfileCut = hasDimple; // is it the same thing? 3555 hasProfileCut = hasDimple; // is it the same thing?
3323 } 3556 }
3324 3557
3325 public void SetVehicleFlags(int param, bool remove)
3326 {
3327 if (PhysActor != null)
3328 {
3329 PhysActor.VehicleFlags(param, remove);
3330 }
3331 }
3332 3558
3333 public void SetGroup(UUID groupID, IClientAPI client) 3559 public void SetGroup(UUID groupID, IClientAPI client)
3334 { 3560 {
@@ -3438,61 +3664,38 @@ namespace OpenSim.Region.Framework.Scenes
3438 3664
3439 public void StoreUndoState(bool forGroup) 3665 public void StoreUndoState(bool forGroup)
3440 { 3666 {
3441 if (!Undoing) 3667 if (!Undoing && !IgnoreUndoUpdate) // just to read better - undo is in progress, or suspended
3442 { 3668 {
3443 if (!IgnoreUndoUpdate) 3669 if (ParentGroup != null)
3444 { 3670 {
3445 if (ParentGroup != null) 3671 lock (m_undo)
3446 { 3672 {
3447 lock (m_undo) 3673 if (m_undo.Count > 0)
3448 { 3674 {
3449 if (m_undo.Count > 0) 3675 // see if we had a change
3450 { 3676
3451 UndoState last = m_undo.Peek(); 3677 UndoState last = m_undo.Peek();
3452 if (last != null) 3678 if (last != null)
3679 {
3680 if (last.Compare(this, forGroup))
3453 { 3681 {
3454 // TODO: May need to fix for group comparison 3682 return;
3455 if (last.Compare(this))
3456 {
3457 // m_log.DebugFormat(
3458 // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3459 // Name, LocalId, m_undo.Count);
3460
3461 return;
3462 }
3463 } 3683 }
3464 } 3684 }
3465 3685 }
3466 // m_log.DebugFormat( 3686
3467 // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}", 3687 if (ParentGroup.GetSceneMaxUndo() > 0)
3468 // Name, LocalId, forGroup, m_undo.Count); 3688 {
3469 3689 UndoState nUndo = new UndoState(this, forGroup);
3470 if (ParentGroup.GetSceneMaxUndo() > 0) 3690
3471 { 3691 m_undo.Push(nUndo);
3472 UndoState nUndo = new UndoState(this, forGroup); 3692
3473 3693 if (m_redo.Count > 0)
3474 m_undo.Push(nUndo); 3694 m_redo.Clear();
3475
3476 if (m_redo.Count > 0)
3477 m_redo.Clear();
3478
3479 // m_log.DebugFormat(
3480 // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3481 // Name, LocalId, forGroup, m_undo.Count);
3482 }
3483 } 3695 }
3484 } 3696 }
3485 } 3697 }
3486// else
3487// {
3488// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3489// }
3490 } 3698 }
3491// else
3492// {
3493// m_log.DebugFormat(
3494// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3495// }
3496 } 3699 }
3497 3700
3498 /// <summary> 3701 /// <summary>
@@ -3528,7 +3731,7 @@ namespace OpenSim.Region.Framework.Scenes
3528 nUndo = new UndoState(this, goback.ForGroup); 3731 nUndo = new UndoState(this, goback.ForGroup);
3529 } 3732 }
3530 3733
3531 goback.PlaybackState(this); 3734 goback.PlayState(this);
3532 3735
3533 if (nUndo != null) 3736 if (nUndo != null)
3534 m_redo.Push(nUndo); 3737 m_redo.Push(nUndo);
@@ -3562,7 +3765,7 @@ namespace OpenSim.Region.Framework.Scenes
3562 m_undo.Push(nUndo); 3765 m_undo.Push(nUndo);
3563 } 3766 }
3564 3767
3565 gofwd.PlayfwdState(this); 3768 gofwd.PlayState(this);
3566 } 3769 }
3567 3770
3568// m_log.DebugFormat( 3771// m_log.DebugFormat(
@@ -4216,13 +4419,17 @@ namespace OpenSim.Region.Framework.Scenes
4216 /// <param name="SetTemporary"></param> 4419 /// <param name="SetTemporary"></param>
4217 /// <param name="SetPhantom"></param> 4420 /// <param name="SetPhantom"></param>
4218 /// <param name="SetVD"></param> 4421 /// <param name="SetVD"></param>
4219 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) 4422// public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD)
4423 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
4220 { 4424 {
4221 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4425 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4222 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4426 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
4223 bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0); 4427 bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0);
4224 bool wasVD = VolumeDetectActive; 4428 bool wasVD = VolumeDetectActive;
4225 4429
4430// m_log.DebugFormat("[SOP]: Old states: phys: {0} temp: {1} phan: {2} vd: {3}", wasUsingPhysics, wasTemporary, wasPhantom, wasVD);
4431// m_log.DebugFormat("[SOP]: New states: phys: {0} temp: {1} phan: {2} vd: {3}", UsePhysics, SetTemporary, SetPhantom, SetVD);
4432
4226 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4433 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4227 return; 4434 return;
4228 4435
@@ -4231,6 +4438,9 @@ namespace OpenSim.Region.Framework.Scenes
4231 // that... 4438 // that...
4232 // ... if VD is changed, all others are not. 4439 // ... if VD is changed, all others are not.
4233 // ... if one of the others is changed, VD is not. 4440 // ... if one of the others is changed, VD is not.
4441 // do this first
4442 if (building && PhysActor != null && PhysActor.Building != building)
4443 PhysActor.Building = building;
4234 if (SetVD) // VD is active, special logic applies 4444 if (SetVD) // VD is active, special logic applies
4235 { 4445 {
4236 // State machine logic for VolumeDetect 4446 // State machine logic for VolumeDetect
@@ -4252,6 +4462,11 @@ namespace OpenSim.Region.Framework.Scenes
4252 SetPhantom = false; 4462 SetPhantom = false;
4253 } 4463 }
4254 } 4464 }
4465 else if (wasVD)
4466 {
4467 // Correspondingly, if VD is turned off, also turn off phantom
4468 SetPhantom = false;
4469 }
4255 4470
4256 if (UsePhysics && IsJoint()) 4471 if (UsePhysics && IsJoint())
4257 { 4472 {
@@ -4307,11 +4522,17 @@ namespace OpenSim.Region.Framework.Scenes
4307 Shape, 4522 Shape,
4308 AbsolutePosition, 4523 AbsolutePosition,
4309 Scale, 4524 Scale,
4310 RotationOffset, 4525// RotationOffset,
4526 GetWorldRotation(), //physics wants world rotation like all other functions send
4311 UsePhysics, 4527 UsePhysics,
4312 m_localId); 4528 m_localId);
4313 4529
4314 PhysActor.SetMaterial(Material); 4530 PhysActor.SetMaterial(Material);
4531
4532 // if root part apply vehicle
4533 if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
4534 m_vehicle.SetVehicle(PhysActor);
4535
4315 DoPhysicsPropertyUpdate(UsePhysics, true); 4536 DoPhysicsPropertyUpdate(UsePhysics, true);
4316 4537
4317 if (!ParentGroup.IsDeleted) 4538 if (!ParentGroup.IsDeleted)
@@ -4387,6 +4608,9 @@ namespace OpenSim.Region.Framework.Scenes
4387 } 4608 }
4388 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); 4609 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4389 4610
4611 // and last in case we have a new actor and not building
4612 if (PhysActor != null && PhysActor.Building != building)
4613 PhysActor.Building = building;
4390 if (ParentGroup != null) 4614 if (ParentGroup != null)
4391 { 4615 {
4392 ParentGroup.HasGroupChanged = true; 4616 ParentGroup.HasGroupChanged = true;
@@ -4750,5 +4974,17 @@ namespace OpenSim.Region.Framework.Scenes
4750 Color color = Color; 4974 Color color = Color;
4751 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 4975 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4752 } 4976 }
4977
4978 public void ResetOwnerChangeFlag()
4979 {
4980 List<UUID> inv = Inventory.GetInventoryList();
4981
4982 foreach (UUID itemID in inv)
4983 {
4984 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
4985 item.OwnerChanged = false;
4986 Inventory.UpdateInventoryItem(item, false, false);
4987 }
4988 }
4753 } 4989 }
4754} 4990}