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.cs1471
1 files changed, 976 insertions, 495 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 482d958..f13f7ab 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -64,7 +64,8 @@ namespace OpenSim.Region.Framework.Scenes
64 TELEPORT = 512, 64 TELEPORT = 512,
65 REGION_RESTART = 1024, 65 REGION_RESTART = 1024,
66 MEDIA = 2048, 66 MEDIA = 2048,
67 ANIMATION = 16384 67 ANIMATION = 16384,
68 POSITION = 32768
68 } 69 }
69 70
70 // I don't really know where to put this except here. 71 // I don't really know where to put this except here.
@@ -123,7 +124,18 @@ namespace OpenSim.Region.Framework.Scenes
123 /// Denote all sides of the prim 124 /// Denote all sides of the prim
124 /// </value> 125 /// </value>
125 public const int ALL_SIDES = -1; 126 public const int ALL_SIDES = -1;
126 127
128 private const scriptEvents PhysicsNeededSubsEvents = (
129 scriptEvents.collision | scriptEvents.collision_start | scriptEvents.collision_end |
130 scriptEvents.land_collision | scriptEvents.land_collision_start | scriptEvents.land_collision_end
131 );
132 private const scriptEvents PhyscicsPhantonSubsEvents = (
133 scriptEvents.land_collision | scriptEvents.land_collision_start | scriptEvents.land_collision_end
134 );
135 private const scriptEvents PhyscicsVolumeDtcSubsEvents = (
136 scriptEvents.collision_start | scriptEvents.collision_end
137 );
138
127 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 139 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
128 140
129 /// <summary> 141 /// <summary>
@@ -160,7 +172,7 @@ namespace OpenSim.Region.Framework.Scenes
160 /// </remarks> 172 /// </remarks>
161 public bool IsRoot 173 public bool IsRoot
162 { 174 {
163 get { return ParentGroup.RootPart == this; } 175 get { return Object.ReferenceEquals(ParentGroup.RootPart, this); }
164 } 176 }
165 177
166 /// <summary> 178 /// <summary>
@@ -233,6 +245,18 @@ namespace OpenSim.Region.Framework.Scenes
233 245
234 public uint TimeStampTerse; 246 public uint TimeStampTerse;
235 247
248 // The following two are to hold the attachment data
249 // while an object is inworld
250 [XmlIgnore]
251 public byte AttachPoint = 0;
252
253 [XmlIgnore]
254 public Vector3 AttachOffset = Vector3.Zero;
255
256 [XmlIgnore]
257 public Quaternion AttachRotation = Quaternion.Identity;
258
259 [XmlIgnore]
236 public int STATUS_ROTATE_X; 260 public int STATUS_ROTATE_X;
237 261
238 public int STATUS_ROTATE_Y; 262 public int STATUS_ROTATE_Y;
@@ -259,8 +283,7 @@ namespace OpenSim.Region.Framework.Scenes
259 283
260 public Vector3 RotationAxis = Vector3.One; 284 public Vector3 RotationAxis = Vector3.One;
261 285
262 public bool VolumeDetectActive; // XmlIgnore set to avoid problems with persistance until I come to care for this 286 public bool VolumeDetectActive;
263 // Certainly this must be a persistant setting finally
264 287
265 public bool IsWaitingForFirstSpinUpdatePacket; 288 public bool IsWaitingForFirstSpinUpdatePacket;
266 289
@@ -300,10 +323,10 @@ namespace OpenSim.Region.Framework.Scenes
300 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 323 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
301 private Vector3 m_sitTargetPosition; 324 private Vector3 m_sitTargetPosition;
302 private string m_sitAnimation = "SIT"; 325 private string m_sitAnimation = "SIT";
326 private bool m_occupied; // KF if any av is sitting on this prim
303 private string m_text = String.Empty; 327 private string m_text = String.Empty;
304 private string m_touchName = String.Empty; 328 private string m_touchName = String.Empty;
305 private readonly List<UndoState> m_undo = new List<UndoState>(5); 329 private UndoRedoState m_UndoRedo = null;
306 private readonly List<UndoState> m_redo = new List<UndoState>(5);
307 330
308 private bool m_passTouches = false; 331 private bool m_passTouches = false;
309 private bool m_passCollisions = false; 332 private bool m_passCollisions = false;
@@ -331,14 +354,20 @@ namespace OpenSim.Region.Framework.Scenes
331 protected Vector3 m_lastVelocity; 354 protected Vector3 m_lastVelocity;
332 protected Vector3 m_lastAcceleration; 355 protected Vector3 m_lastAcceleration;
333 protected Vector3 m_lastAngularVelocity; 356 protected Vector3 m_lastAngularVelocity;
334 protected int m_lastTerseSent; 357 protected int m_lastUpdateSentTime;
358 protected float m_buoyancy = 0.0f;
359 protected Vector3 m_force;
360 protected Vector3 m_torque;
335 361
336 protected byte m_physicsShapeType = (byte)PhysShapeType.prim; 362 protected byte m_physicsShapeType = (byte)PhysShapeType.prim;
337 protected float m_density = 1000.0f; // in kg/m^3 363 protected float m_density = 1000.0f; // in kg/m^3
338 protected float m_gravitymod = 1.0f; 364 protected float m_gravitymod = 1.0f;
339 protected float m_friction = 0.6f; // wood 365 protected float m_friction = 0.6f; // wood
340 protected float m_bounce = 0.5f; // wood 366 protected float m_bounce = 0.5f; // wood
341 367
368
369 protected bool m_isSelected = false;
370
342 /// <summary> 371 /// <summary>
343 /// Stores media texture data 372 /// Stores media texture data
344 /// </summary> 373 /// </summary>
@@ -350,10 +379,17 @@ namespace OpenSim.Region.Framework.Scenes
350 private Vector3 m_cameraAtOffset; 379 private Vector3 m_cameraAtOffset;
351 private bool m_forceMouselook; 380 private bool m_forceMouselook;
352 381
353 // TODO: Collision sound should have default. 382
383 // 0 for default collision sounds, -1 for script disabled sound 1 for script defined sound
384 private sbyte m_collisionSoundType;
354 private UUID m_collisionSound; 385 private UUID m_collisionSound;
355 private float m_collisionSoundVolume; 386 private float m_collisionSoundVolume;
356 387
388 private int LastColSoundSentTime;
389
390
391 private SOPVehicle m_vehicleParams = null;
392
357 private KeyframeMotion m_keyframeMotion = null; 393 private KeyframeMotion m_keyframeMotion = null;
358 394
359 public KeyframeMotion KeyframeMotion 395 public KeyframeMotion KeyframeMotion
@@ -361,6 +397,7 @@ namespace OpenSim.Region.Framework.Scenes
361 get; set; 397 get; set;
362 } 398 }
363 399
400
364 #endregion Fields 401 #endregion Fields
365 402
366// ~SceneObjectPart() 403// ~SceneObjectPart()
@@ -390,6 +427,7 @@ namespace OpenSim.Region.Framework.Scenes
390 // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from 427 // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from
391 // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log 428 // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log
392 m_inventory = new SceneObjectPartInventory(this); 429 m_inventory = new SceneObjectPartInventory(this);
430 LastColSoundSentTime = Util.EnvironmentTickCount();
393 } 431 }
394 432
395 /// <summary> 433 /// <summary>
@@ -404,7 +442,7 @@ namespace OpenSim.Region.Framework.Scenes
404 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 442 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
405 Quaternion rotationOffset, Vector3 offsetPosition) : this() 443 Quaternion rotationOffset, Vector3 offsetPosition) : this()
406 { 444 {
407 m_name = "Primitive"; 445 m_name = "Object";
408 446
409 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 447 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
410 LastOwnerID = CreatorID = OwnerID = ownerID; 448 LastOwnerID = CreatorID = OwnerID = ownerID;
@@ -443,7 +481,7 @@ namespace OpenSim.Region.Framework.Scenes
443 private uint _ownerMask = (uint)(PermissionMask.All | PermissionMask.Export); 481 private uint _ownerMask = (uint)(PermissionMask.All | PermissionMask.Export);
444 private uint _groupMask = (uint)PermissionMask.None; 482 private uint _groupMask = (uint)PermissionMask.None;
445 private uint _everyoneMask = (uint)PermissionMask.None; 483 private uint _everyoneMask = (uint)PermissionMask.None;
446 private uint _nextOwnerMask = (uint)PermissionMask.All; 484 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
447 private PrimFlags _flags = PrimFlags.None; 485 private PrimFlags _flags = PrimFlags.None;
448 private DateTime m_expires; 486 private DateTime m_expires;
449 private DateTime m_rezzed; 487 private DateTime m_rezzed;
@@ -537,12 +575,16 @@ namespace OpenSim.Region.Framework.Scenes
537 } 575 }
538 576
539 /// <value> 577 /// <value>
540 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 578 /// Get the inventory list
541 /// </value> 579 /// </value>
542 public TaskInventoryDictionary TaskInventory 580 public TaskInventoryDictionary TaskInventory
543 { 581 {
544 get { return m_inventory.Items; } 582 get {
545 set { m_inventory.Items = value; } 583 return m_inventory.Items;
584 }
585 set {
586 m_inventory.Items = value;
587 }
546 } 588 }
547 589
548 /// <summary> 590 /// <summary>
@@ -592,20 +634,6 @@ namespace OpenSim.Region.Framework.Scenes
592 } 634 }
593 } 635 }
594 636
595 public byte Material
596 {
597 get { return (byte) m_material; }
598 set
599 {
600 m_material = (Material)value;
601
602 PhysicsActor pa = PhysActor;
603
604 if (pa != null)
605 pa.SetMaterial((int)value);
606 }
607 }
608
609 [XmlIgnore] 637 [XmlIgnore]
610 public bool PassTouches 638 public bool PassTouches
611 { 639 {
@@ -631,6 +659,18 @@ namespace OpenSim.Region.Framework.Scenes
631 } 659 }
632 } 660 }
633 661
662 public bool IsSelected
663 {
664 get { return m_isSelected; }
665 set
666 {
667 m_isSelected = value;
668 if (ParentGroup != null)
669 ParentGroup.PartSelectChanged(value);
670 }
671 }
672
673
634 public Dictionary<int, string> CollisionFilter 674 public Dictionary<int, string> CollisionFilter
635 { 675 {
636 get { return m_CollisionFilter; } 676 get { return m_CollisionFilter; }
@@ -699,14 +739,12 @@ namespace OpenSim.Region.Framework.Scenes
699 set { m_LoopSoundSlavePrims = value; } 739 set { m_LoopSoundSlavePrims = value; }
700 } 740 }
701 741
702
703 public Byte[] TextureAnimation 742 public Byte[] TextureAnimation
704 { 743 {
705 get { return m_TextureAnimation; } 744 get { return m_TextureAnimation; }
706 set { m_TextureAnimation = value; } 745 set { m_TextureAnimation = value; }
707 } 746 }
708 747
709
710 public Byte[] ParticleSystem 748 public Byte[] ParticleSystem
711 { 749 {
712 get { return m_particleSystem; } 750 get { return m_particleSystem; }
@@ -743,9 +781,12 @@ namespace OpenSim.Region.Framework.Scenes
743 { 781 {
744 // If this is a linkset, we don't want the physics engine mucking up our group position here. 782 // If this is a linkset, we don't want the physics engine mucking up our group position here.
745 PhysicsActor actor = PhysActor; 783 PhysicsActor actor = PhysActor;
746 // If physical and the root prim of a linkset, the position of the group is what physics thinks. 784 if (ParentID == 0)
747 if (actor != null && ParentID == 0) 785 {
748 m_groupPosition = actor.Position; 786 if (actor != null)
787 m_groupPosition = actor.Position;
788 return m_groupPosition;
789 }
749 790
750 // If I'm an attachment, my position is reported as the position of who I'm attached to 791 // If I'm an attachment, my position is reported as the position of who I'm attached to
751 if (ParentGroup.IsAttachment) 792 if (ParentGroup.IsAttachment)
@@ -755,14 +796,16 @@ namespace OpenSim.Region.Framework.Scenes
755 return sp.AbsolutePosition; 796 return sp.AbsolutePosition;
756 } 797 }
757 798
799 // use root prim's group position. Physics may have updated it
800 if (ParentGroup.RootPart != this)
801 m_groupPosition = ParentGroup.RootPart.GroupPosition;
758 return m_groupPosition; 802 return m_groupPosition;
759 } 803 }
760 set 804 set
761 { 805 {
762 m_groupPosition = value; 806 m_groupPosition = value;
763
764 PhysicsActor actor = PhysActor; 807 PhysicsActor actor = PhysActor;
765 if (actor != null) 808 if (actor != null && ParentGroup.Scene.PhysicsScene != null)
766 { 809 {
767 try 810 try
768 { 811 {
@@ -787,16 +830,6 @@ namespace OpenSim.Region.Framework.Scenes
787 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e); 830 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e);
788 } 831 }
789 } 832 }
790
791 // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
792 if (SitTargetAvatar != UUID.Zero)
793 {
794 ScenePresence avatar;
795 if (ParentGroup.Scene.TryGetScenePresence(SitTargetAvatar, out avatar))
796 {
797 avatar.ParentPosition = GetWorldPosition();
798 }
799 }
800 } 833 }
801 } 834 }
802 835
@@ -805,7 +838,7 @@ namespace OpenSim.Region.Framework.Scenes
805 get { return m_offsetPosition; } 838 get { return m_offsetPosition; }
806 set 839 set
807 { 840 {
808// StoreUndoState(); 841 Vector3 oldpos = m_offsetPosition;
809 m_offsetPosition = value; 842 m_offsetPosition = value;
810 843
811 if (ParentGroup != null && !ParentGroup.IsDeleted) 844 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -817,10 +850,25 @@ namespace OpenSim.Region.Framework.Scenes
817 actor.Orientation = GetWorldRotation(); 850 actor.Orientation = GetWorldRotation();
818 851
819 // Tell the physics engines that this prim changed. 852 // Tell the physics engines that this prim changed.
820 if (ParentGroup.Scene != null) 853 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene != null)
821 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 854 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
822 } 855 }
856
857 if (!m_parentGroup.m_dupeInProgress)
858 {
859 List<ScenePresence> avs = ParentGroup.GetLinkedAvatars();
860 foreach (ScenePresence av in avs)
861 {
862 if (av.ParentID == m_localId)
863 {
864 Vector3 offset = (m_offsetPosition - oldpos);
865 av.AbsolutePosition += offset;
866 av.SendAvatarDataToAllAgents();
867 }
868 }
869 }
823 } 870 }
871 TriggerScriptChangedEvent(Changed.POSITION);
824 } 872 }
825 } 873 }
826 874
@@ -871,7 +919,7 @@ namespace OpenSim.Region.Framework.Scenes
871 919
872 set 920 set
873 { 921 {
874 StoreUndoState(); 922// StoreUndoState();
875 m_rotationOffset = value; 923 m_rotationOffset = value;
876 924
877 PhysicsActor actor = PhysActor; 925 PhysicsActor actor = PhysActor;
@@ -959,19 +1007,36 @@ namespace OpenSim.Region.Framework.Scenes
959 get 1007 get
960 { 1008 {
961 PhysicsActor actor = PhysActor; 1009 PhysicsActor actor = PhysActor;
962 if ((actor != null) && actor.IsPhysical) 1010 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
963 { 1011 {
964 m_angularVelocity = actor.RotationalVelocity; 1012 m_angularVelocity = actor.RotationalVelocity;
965 } 1013 }
966 return m_angularVelocity; 1014 return m_angularVelocity;
967 } 1015 }
968 set { m_angularVelocity = value; } 1016 set
1017 {
1018 m_angularVelocity = value;
1019 PhysicsActor actor = PhysActor;
1020 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this && VehicleType == (int)Vehicle.TYPE_NONE)
1021 {
1022 actor.RotationalVelocity = m_angularVelocity;
1023 }
1024 }
969 } 1025 }
970 1026
971 /// <summary></summary> 1027 /// <summary></summary>
972 public Vector3 Acceleration 1028 public Vector3 Acceleration
973 { 1029 {
974 get { return m_acceleration; } 1030 get
1031 {
1032 PhysicsActor actor = PhysActor;
1033 if (actor != null)
1034 {
1035 m_acceleration = actor.Acceleration;
1036 }
1037 return m_acceleration;
1038 }
1039
975 set { m_acceleration = value; } 1040 set { m_acceleration = value; }
976 } 1041 }
977 1042
@@ -1039,7 +1104,10 @@ namespace OpenSim.Region.Framework.Scenes
1039 public PrimitiveBaseShape Shape 1104 public PrimitiveBaseShape Shape
1040 { 1105 {
1041 get { return m_shape; } 1106 get { return m_shape; }
1042 set { m_shape = value;} 1107 set
1108 {
1109 m_shape = value;
1110 }
1043 } 1111 }
1044 1112
1045 /// <summary> 1113 /// <summary>
@@ -1052,7 +1120,6 @@ namespace OpenSim.Region.Framework.Scenes
1052 { 1120 {
1053 if (m_shape != null) 1121 if (m_shape != null)
1054 { 1122 {
1055 StoreUndoState();
1056 1123
1057 m_shape.Scale = value; 1124 m_shape.Scale = value;
1058 1125
@@ -1120,10 +1187,7 @@ namespace OpenSim.Region.Framework.Scenes
1120 { 1187 {
1121 get 1188 get
1122 { 1189 {
1123 if (ParentGroup.IsAttachment) 1190 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
1124 return GroupPosition;
1125
1126 return m_offsetPosition + m_groupPosition;
1127 } 1191 }
1128 } 1192 }
1129 1193
@@ -1292,6 +1356,13 @@ namespace OpenSim.Region.Framework.Scenes
1292 _flags = value; 1356 _flags = value;
1293 } 1357 }
1294 } 1358 }
1359
1360 [XmlIgnore]
1361 public bool IsOccupied // KF If an av is sittingon this prim
1362 {
1363 get { return m_occupied; }
1364 set { m_occupied = value; }
1365 }
1295 1366
1296 /// <summary> 1367 /// <summary>
1297 /// ID of the avatar that is sat on us if we have a sit target. If there is no such avatar then is UUID.Zero 1368 /// ID of the avatar that is sat on us if we have a sit target. If there is no such avatar then is UUID.Zero
@@ -1342,12 +1413,41 @@ namespace OpenSim.Region.Framework.Scenes
1342 set { m_sitAnimation = value; } 1413 set { m_sitAnimation = value; }
1343 } 1414 }
1344 1415
1416 public UUID invalidCollisionSoundUUID = new UUID("ffffffff-ffff-ffff-ffff-ffffffffffff");
1417
1418 // 0 for default collision sounds, -1 for script disabled sound 1 for script defined sound
1419 // runtime thing.. do not persist
1420 [XmlIgnore]
1421 public sbyte CollisionSoundType
1422 {
1423 get
1424 {
1425 return m_collisionSoundType;
1426 }
1427 set
1428 {
1429 m_collisionSoundType = value;
1430 if (value == -1)
1431 m_collisionSound = invalidCollisionSoundUUID;
1432 else if (value == 0)
1433 m_collisionSound = UUID.Zero;
1434 }
1435 }
1436
1345 public UUID CollisionSound 1437 public UUID CollisionSound
1346 { 1438 {
1347 get { return m_collisionSound; } 1439 get { return m_collisionSound; }
1348 set 1440 set
1349 { 1441 {
1350 m_collisionSound = value; 1442 m_collisionSound = value;
1443
1444 if (value == invalidCollisionSoundUUID)
1445 m_collisionSoundType = -1;
1446 else if (value == UUID.Zero)
1447 m_collisionSoundType = 0;
1448 else
1449 m_collisionSoundType = 1;
1450
1351 aggregateScriptEvents(); 1451 aggregateScriptEvents();
1352 } 1452 }
1353 } 1453 }
@@ -1358,6 +1458,125 @@ namespace OpenSim.Region.Framework.Scenes
1358 set { m_collisionSoundVolume = value; } 1458 set { m_collisionSoundVolume = value; }
1359 } 1459 }
1360 1460
1461 public float Buoyancy
1462 {
1463 get
1464 {
1465 if (ParentGroup.RootPart == this)
1466 return m_buoyancy;
1467
1468 return ParentGroup.RootPart.Buoyancy;
1469 }
1470 set
1471 {
1472 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1473 {
1474 ParentGroup.RootPart.Buoyancy = value;
1475 return;
1476 }
1477 m_buoyancy = value;
1478 if (PhysActor != null)
1479 PhysActor.Buoyancy = value;
1480 }
1481 }
1482
1483 public Vector3 Force
1484 {
1485 get
1486 {
1487 if (ParentGroup.RootPart == this)
1488 return m_force;
1489
1490 return ParentGroup.RootPart.Force;
1491 }
1492
1493 set
1494 {
1495 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1496 {
1497 ParentGroup.RootPart.Force = value;
1498 return;
1499 }
1500 m_force = value;
1501 if (PhysActor != null)
1502 PhysActor.Force = value;
1503 }
1504 }
1505
1506 public Vector3 Torque
1507 {
1508 get
1509 {
1510 if (ParentGroup.RootPart == this)
1511 return m_torque;
1512
1513 return ParentGroup.RootPart.Torque;
1514 }
1515
1516 set
1517 {
1518 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1519 {
1520 ParentGroup.RootPart.Torque = value;
1521 return;
1522 }
1523 m_torque = value;
1524 if (PhysActor != null)
1525 PhysActor.Torque = value;
1526 }
1527 }
1528
1529 public byte Material
1530 {
1531 get { return (byte)m_material; }
1532 set
1533 {
1534 if (value >= 0 && value <= (byte)SOPMaterialData.MaxMaterial)
1535 {
1536 bool update = false;
1537
1538 if (m_material != (Material)value)
1539 {
1540 update = true;
1541 m_material = (Material)value;
1542 }
1543
1544 if (m_friction != SOPMaterialData.friction(m_material))
1545 {
1546 update = true;
1547 m_friction = SOPMaterialData.friction(m_material);
1548 }
1549
1550 if (m_bounce != SOPMaterialData.bounce(m_material))
1551 {
1552 update = true;
1553 m_bounce = SOPMaterialData.bounce(m_material);
1554 }
1555
1556 if (update)
1557 {
1558 if (PhysActor != null)
1559 {
1560 PhysActor.SetMaterial((int)value);
1561 }
1562 if(ParentGroup != null)
1563 ParentGroup.HasGroupChanged = true;
1564 ScheduleFullUpdateIfNone();
1565 UpdatePhysRequired = true;
1566 }
1567 }
1568 }
1569 }
1570
1571 // not a propriety to move to methods place later
1572 private bool HasMesh()
1573 {
1574 if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh))
1575 return true;
1576 return false;
1577 }
1578
1579 // not a propriety to move to methods place later
1361 public byte DefaultPhysicsShapeType() 1580 public byte DefaultPhysicsShapeType()
1362 { 1581 {
1363 byte type; 1582 byte type;
@@ -1370,6 +1589,65 @@ namespace OpenSim.Region.Framework.Scenes
1370 return type; 1589 return type;
1371 } 1590 }
1372 1591
1592 [XmlIgnore]
1593 public bool UsesComplexCost
1594 {
1595 get
1596 {
1597 byte pst = PhysicsShapeType;
1598 if(pst == (byte) PhysShapeType.none || pst == (byte) PhysShapeType.convex || HasMesh())
1599 return true;
1600 return false;
1601 }
1602 }
1603
1604 [XmlIgnore]
1605 public float PhysicsCost
1606 {
1607 get
1608 {
1609 if(PhysicsShapeType == (byte)PhysShapeType.none)
1610 return 0;
1611
1612 float cost = 0.1f;
1613 if (PhysActor != null)
1614 cost = PhysActor.PhysicsCost;
1615 else
1616 cost = 0.1f;
1617
1618 if ((Flags & PrimFlags.Physics) != 0)
1619 cost *= (1.0f + 0.01333f * Scale.LengthSquared()); // 0.01333 == 0.04/3
1620 return cost;
1621 }
1622 }
1623
1624 [XmlIgnore]
1625 public float StreamingCost
1626 {
1627 get
1628 {
1629 float cost;
1630 if (PhysActor != null)
1631 cost = PhysActor.StreamCost;
1632 else
1633 cost = 1.0f;
1634 return 1.0f;
1635 }
1636 }
1637
1638 [XmlIgnore]
1639 public float SimulationCost
1640 {
1641 get
1642 {
1643 // ignoring scripts. Don't like considering them for this
1644 if((Flags & PrimFlags.Physics) != 0)
1645 return 1.0f;
1646
1647 return 0.5f;
1648 }
1649 }
1650
1373 public byte PhysicsShapeType 1651 public byte PhysicsShapeType
1374 { 1652 {
1375 get { return m_physicsShapeType; } 1653 get { return m_physicsShapeType; }
@@ -1403,11 +1681,14 @@ namespace OpenSim.Region.Framework.Scenes
1403 } 1681 }
1404 else if (PhysActor == null) 1682 else if (PhysActor == null)
1405 { 1683 {
1406 ApplyPhysics((uint)Flags, VolumeDetectActive); 1684 ApplyPhysics((uint)Flags, VolumeDetectActive, false);
1685 UpdatePhysicsSubscribedEvents();
1407 } 1686 }
1408 else 1687 else
1409 { 1688 {
1410 PhysActor.PhysicsShapeType = m_physicsShapeType; 1689 PhysActor.PhysicsShapeType = m_physicsShapeType;
1690// if (Shape.SculptEntry)
1691// CheckSculptAndLoad();
1411 } 1692 }
1412 1693
1413 if (ParentGroup != null) 1694 if (ParentGroup != null)
@@ -1509,6 +1790,7 @@ namespace OpenSim.Region.Framework.Scenes
1509 } 1790 }
1510 } 1791 }
1511 1792
1793
1512 #endregion Public Properties with only Get 1794 #endregion Public Properties with only Get
1513 1795
1514 private uint ApplyMask(uint val, bool set, uint mask) 1796 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1654,6 +1936,61 @@ namespace OpenSim.Region.Framework.Scenes
1654 } 1936 }
1655 } 1937 }
1656 1938
1939 // SetVelocity for LSL llSetVelocity.. may need revision if having other uses in future
1940 public void SetVelocity(Vector3 pVel, bool localGlobalTF)
1941 {
1942 if (ParentGroup == null || ParentGroup.IsDeleted)
1943 return;
1944
1945 if (ParentGroup.IsAttachment)
1946 return; // don't work on attachments (for now ??)
1947
1948 SceneObjectPart root = ParentGroup.RootPart;
1949
1950 if (root.VehicleType != (int)Vehicle.TYPE_NONE) // don't mess with vehicles
1951 return;
1952
1953 PhysicsActor pa = root.PhysActor;
1954
1955 if (pa == null || !pa.IsPhysical)
1956 return;
1957
1958 if (localGlobalTF)
1959 {
1960 pVel = pVel * GetWorldRotation();
1961 }
1962
1963 ParentGroup.Velocity = pVel;
1964 }
1965
1966 // SetAngularVelocity for LSL llSetAngularVelocity.. may need revision if having other uses in future
1967 public void SetAngularVelocity(Vector3 pAngVel, bool localGlobalTF)
1968 {
1969 if (ParentGroup == null || ParentGroup.IsDeleted)
1970 return;
1971
1972 if (ParentGroup.IsAttachment)
1973 return; // don't work on attachments (for now ??)
1974
1975 SceneObjectPart root = ParentGroup.RootPart;
1976
1977 if (root.VehicleType != (int)Vehicle.TYPE_NONE) // don't mess with vehicles
1978 return;
1979
1980 PhysicsActor pa = root.PhysActor;
1981
1982 if (pa == null || !pa.IsPhysical)
1983 return;
1984
1985 if (localGlobalTF)
1986 {
1987 pAngVel = pAngVel * GetWorldRotation();
1988 }
1989
1990 root.AngularVelocity = pAngVel;
1991 }
1992
1993
1657 /// <summary> 1994 /// <summary>
1658 /// hook to the physics scene to apply angular impulse 1995 /// hook to the physics scene to apply angular impulse
1659 /// This is sent up to the group, which then finds the root prim 1996 /// This is sent up to the group, which then finds the root prim
@@ -1674,7 +2011,7 @@ namespace OpenSim.Region.Framework.Scenes
1674 impulse = newimpulse; 2011 impulse = newimpulse;
1675 } 2012 }
1676 2013
1677 ParentGroup.applyAngularImpulse(impulse); 2014 ParentGroup.ApplyAngularImpulse(impulse);
1678 } 2015 }
1679 2016
1680 /// <summary> 2017 /// <summary>
@@ -1684,20 +2021,24 @@ namespace OpenSim.Region.Framework.Scenes
1684 /// </summary> 2021 /// </summary>
1685 /// <param name="impulsei">Vector force</param> 2022 /// <param name="impulsei">Vector force</param>
1686 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> 2023 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
1687 public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF) 2024
2025 // this is actualy Set Torque.. keeping naming so not to edit lslapi also
2026 public void SetAngularImpulse(Vector3 torquei, bool localGlobalTF)
1688 { 2027 {
1689 Vector3 impulse = impulsei; 2028 Vector3 torque = torquei;
1690 2029
1691 if (localGlobalTF) 2030 if (localGlobalTF)
1692 { 2031 {
2032/*
1693 Quaternion grot = GetWorldRotation(); 2033 Quaternion grot = GetWorldRotation();
1694 Quaternion AXgrot = grot; 2034 Quaternion AXgrot = grot;
1695 Vector3 AXimpulsei = impulsei; 2035 Vector3 AXimpulsei = impulsei;
1696 Vector3 newimpulse = AXimpulsei * AXgrot; 2036 Vector3 newimpulse = AXimpulsei * AXgrot;
1697 impulse = newimpulse; 2037 */
2038 torque *= GetWorldRotation();
1698 } 2039 }
1699 2040
1700 ParentGroup.setAngularImpulse(impulse); 2041 Torque = torque;
1701 } 2042 }
1702 2043
1703 /// <summary> 2044 /// <summary>
@@ -1705,7 +2046,9 @@ namespace OpenSim.Region.Framework.Scenes
1705 /// </summary> 2046 /// </summary>
1706 /// <param name="rootObjectFlags"></param> 2047 /// <param name="rootObjectFlags"></param>
1707 /// <param name="VolumeDetectActive"></param> 2048 /// <param name="VolumeDetectActive"></param>
1708 public void ApplyPhysics(uint rootObjectFlags, bool _VolumeDetectActive) 2049 /// <param name="building"></param>
2050
2051 public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building)
1709 { 2052 {
1710 VolumeDetectActive = _VolumeDetectActive; 2053 VolumeDetectActive = _VolumeDetectActive;
1711 2054
@@ -1715,8 +2058,8 @@ namespace OpenSim.Region.Framework.Scenes
1715 if (PhysicsShapeType == (byte)PhysShapeType.none) 2058 if (PhysicsShapeType == (byte)PhysShapeType.none)
1716 return; 2059 return;
1717 2060
1718 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 2061 bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0;
1719 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 2062 bool isPhantom = (_ObjectFlags & (uint)PrimFlags.Phantom) != 0;
1720 2063
1721 if (_VolumeDetectActive) 2064 if (_VolumeDetectActive)
1722 isPhantom = true; 2065 isPhantom = true;
@@ -1730,7 +2073,8 @@ namespace OpenSim.Region.Framework.Scenes
1730 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment 2073 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment
1731 && !(Shape.PathCurve == (byte)Extrusion.Flexible)) 2074 && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1732 { 2075 {
1733 AddToPhysics(isPhysical, isPhantom, isPhysical); 2076 AddToPhysics(isPhysical, isPhantom, building, isPhysical);
2077 UpdatePhysicsSubscribedEvents(); // not sure if appliable here
1734 } 2078 }
1735 else 2079 else
1736 PhysActor = null; // just to be sure 2080 PhysActor = null; // just to be sure
@@ -1785,6 +2129,12 @@ namespace OpenSim.Region.Framework.Scenes
1785 dupe.Category = Category; 2129 dupe.Category = Category;
1786 dupe.m_rezzed = m_rezzed; 2130 dupe.m_rezzed = m_rezzed;
1787 2131
2132 dupe.m_UndoRedo = null;
2133 dupe.m_isSelected = false;
2134
2135 dupe.IgnoreUndoUpdate = false;
2136 dupe.Undoing = false;
2137
1788 dupe.m_inventory = new SceneObjectPartInventory(dupe); 2138 dupe.m_inventory = new SceneObjectPartInventory(dupe);
1789 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone(); 2139 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone();
1790 2140
@@ -1800,6 +2150,7 @@ namespace OpenSim.Region.Framework.Scenes
1800 2150
1801 // Move afterwards ResetIDs as it clears the localID 2151 // Move afterwards ResetIDs as it clears the localID
1802 dupe.LocalId = localID; 2152 dupe.LocalId = localID;
2153
1803 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 2154 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1804 dupe.LastOwnerID = OwnerID; 2155 dupe.LastOwnerID = OwnerID;
1805 2156
@@ -1824,8 +2175,12 @@ namespace OpenSim.Region.Framework.Scenes
1824*/ 2175*/
1825 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 2176 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
1826 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 2177 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
2178// dupe.UpdatePhysicsSubscribedEvents(); // not sure...
1827 } 2179 }
1828 2180
2181 if (dupe.PhysActor != null)
2182 dupe.PhysActor.LocalID = localID;
2183
1829 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 2184 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1830 2185
1831// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); 2186// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
@@ -1844,10 +2199,10 @@ namespace OpenSim.Region.Framework.Scenes
1844 { 2199 {
1845 if (asset != null) 2200 if (asset != null)
1846 SculptTextureCallback(asset); 2201 SculptTextureCallback(asset);
1847 else 2202// else
1848 m_log.WarnFormat( 2203// m_log.WarnFormat(
1849 "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data", 2204// "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
1850 Name, UUID, id); 2205// Name, UUID, id);
1851 } 2206 }
1852*/ 2207*/
1853 /// <summary> 2208 /// <summary>
@@ -1946,6 +2301,7 @@ namespace OpenSim.Region.Framework.Scenes
1946 2301
1947 /// <summary> 2302 /// <summary>
1948 /// Do a physics propery update for this part. 2303 /// Do a physics propery update for this part.
2304 /// now also updates phantom and volume detector
1949 /// </summary> 2305 /// </summary>
1950 /// <param name="UsePhysics"></param> 2306 /// <param name="UsePhysics"></param>
1951 /// <param name="isNew"></param> 2307 /// <param name="isNew"></param>
@@ -1971,64 +2327,69 @@ namespace OpenSim.Region.Framework.Scenes
1971 { 2327 {
1972 if (pa.IsPhysical) // implies UsePhysics==false for this block 2328 if (pa.IsPhysical) // implies UsePhysics==false for this block
1973 { 2329 {
1974 if (!isNew) 2330 if (!isNew) // implies UsePhysics==false for this block
2331 {
1975 ParentGroup.Scene.RemovePhysicalPrim(1); 2332 ParentGroup.Scene.RemovePhysicalPrim(1);
1976 2333
1977 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 2334 Velocity = new Vector3(0, 0, 0);
1978 pa.OnOutOfBounds -= PhysicsOutOfBounds; 2335 Acceleration = new Vector3(0, 0, 0);
1979 pa.delink(); 2336 if (ParentGroup.RootPart == this)
2337 AngularVelocity = new Vector3(0, 0, 0);
1980 2338
1981 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 2339 if (pa.Phantom && !VolumeDetectActive)
1982 { 2340 {
1983 // destroy all joints connected to this now deactivated body 2341 RemoveFromPhysics();
1984 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); 2342 return;
1985 } 2343 }
1986 2344
1987 // stop client-side interpolation of all joint proxy objects that have just been deleted 2345 pa.IsPhysical = UsePhysics;
1988 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback, 2346 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1989 // which stops client-side interpolation of deactivated joint proxy objects. 2347 pa.OnOutOfBounds -= PhysicsOutOfBounds;
2348 pa.delink();
2349 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
2350 {
2351 // destroy all joints connected to this now deactivated body
2352 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa);
2353 }
2354 }
1990 } 2355 }
1991 2356
1992 if (!UsePhysics && !isNew) 2357 if (pa.IsPhysical != UsePhysics)
1993 { 2358 pa.IsPhysical = UsePhysics;
1994 // reset velocity to 0 on physics switch-off. Without that, the client thinks the
1995 // prim still has velocity and continues to interpolate its position along the old
1996 // velocity-vector.
1997 Velocity = new Vector3(0, 0, 0);
1998 Acceleration = new Vector3(0, 0, 0);
1999 AngularVelocity = new Vector3(0, 0, 0);
2000 //RotationalVelocity = new Vector3(0, 0, 0);
2001 }
2002 2359
2003 pa.IsPhysical = UsePhysics; 2360 if (UsePhysics)
2361 {
2362 if (ParentGroup.RootPart.KeyframeMotion != null)
2363 ParentGroup.RootPart.KeyframeMotion.Stop();
2364 ParentGroup.RootPart.KeyframeMotion = null;
2365 ParentGroup.Scene.AddPhysicalPrim(1);
2004 2366
2005 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 2367 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
2006 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 2368 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
2007 /// that's not wholesome. Had to make Scene public
2008 //PhysActor = null;
2009 2369
2010 if ((Flags & PrimFlags.Phantom) == 0) 2370 if (ParentID != 0 && ParentID != LocalId)
2011 {
2012 if (UsePhysics)
2013 { 2371 {
2014 if (ParentGroup.RootPart.KeyframeMotion != null) 2372 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
2015 ParentGroup.RootPart.KeyframeMotion.Stop();
2016 ParentGroup.RootPart.KeyframeMotion = null;
2017 ParentGroup.Scene.AddPhysicalPrim(1);
2018
2019 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
2020 pa.OnOutOfBounds += PhysicsOutOfBounds;
2021 if (ParentID != 0 && ParentID != LocalId)
2022 {
2023 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
2024 2373
2025 if (parentPa != null) 2374 if (parentPa != null)
2026 { 2375 {
2027 pa.link(parentPa); 2376 pa.link(parentPa);
2028 }
2029 } 2377 }
2030 } 2378 }
2031 } 2379 }
2380 }
2381
2382 bool phan = ((Flags & PrimFlags.Phantom) != 0);
2383 if (pa.Phantom != phan)
2384 pa.Phantom = phan;
2385
2386// some engines dont' have this check still
2387// if (VolumeDetectActive != pa.IsVolumeDtc)
2388 {
2389 if (VolumeDetectActive)
2390 pa.SetVolumeDetect(1);
2391 else
2392 pa.SetVolumeDetect(0);
2032 } 2393 }
2033 2394
2034 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 2395 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
@@ -2147,42 +2508,63 @@ namespace OpenSim.Region.Framework.Scenes
2147 2508
2148 public Vector3 GetGeometricCenter() 2509 public Vector3 GetGeometricCenter()
2149 { 2510 {
2511 // this is not real geometric center but a average of positions relative to root prim acording to
2512 // http://wiki.secondlife.com/wiki/llGetGeometricCenter
2513 // ignoring tortured prims details since sl also seems to ignore
2514 // so no real use in doing it on physics
2515 if (ParentGroup.IsDeleted)
2516 return new Vector3(0, 0, 0);
2517
2518 return ParentGroup.GetGeometricCenter();
2519 }
2520
2521 public float GetMass()
2522 {
2150 PhysicsActor pa = PhysActor; 2523 PhysicsActor pa = PhysActor;
2151 2524
2152 if (pa != null) 2525 if (pa != null)
2153 return pa.GeometricCenter; 2526 return pa.Mass;
2154 else 2527 else
2155 return Vector3.Zero; 2528 return 0;
2156 } 2529 }
2157 2530
2158 public Vector3 GetCenterOfMass() 2531 public Vector3 GetCenterOfMass()
2159 { 2532 {
2533 if (ParentGroup.RootPart == this)
2534 {
2535 if (ParentGroup.IsDeleted)
2536 return AbsolutePosition;
2537 return ParentGroup.GetCenterOfMass();
2538 }
2539
2160 PhysicsActor pa = PhysActor; 2540 PhysicsActor pa = PhysActor;
2161 2541
2162 if (pa != null) 2542 if (pa != null)
2163 return pa.CenterOfMass; 2543 {
2544 Vector3 tmp = pa.CenterOfMass;
2545 return tmp;
2546 }
2164 else 2547 else
2165 return Vector3.Zero; 2548 return AbsolutePosition;
2166 } 2549 }
2167 2550
2168 public float GetMass() 2551 public Vector3 GetPartCenterOfMass()
2169 { 2552 {
2170 PhysicsActor pa = PhysActor; 2553 PhysicsActor pa = PhysActor;
2171 2554
2172 if (pa != null) 2555 if (pa != null)
2173 return pa.Mass; 2556 {
2557 Vector3 tmp = pa.CenterOfMass;
2558 return tmp;
2559 }
2174 else 2560 else
2175 return 0; 2561 return AbsolutePosition;
2176 } 2562 }
2177 2563
2564
2178 public Vector3 GetForce() 2565 public Vector3 GetForce()
2179 { 2566 {
2180 PhysicsActor pa = PhysActor; 2567 return Force;
2181
2182 if (pa != null)
2183 return pa.Force;
2184 else
2185 return Vector3.Zero;
2186 } 2568 }
2187 2569
2188 /// <summary> 2570 /// <summary>
@@ -2397,15 +2779,25 @@ namespace OpenSim.Region.Framework.Scenes
2397 2779
2398 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify) 2780 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify)
2399 { 2781 {
2400 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0) 2782 bool sendToRoot = true;
2401 {
2402 ColliderArgs LandCollidingMessage = new ColliderArgs();
2403 List<DetectedObject> colliding = new List<DetectedObject>();
2404
2405 colliding.Add(CreateDetObjectForGround());
2406 LandCollidingMessage.Colliders = colliding;
2407 2783
2784 ColliderArgs LandCollidingMessage = new ColliderArgs();
2785 List<DetectedObject> colliding = new List<DetectedObject>();
2786
2787 colliding.Add(CreateDetObjectForGround());
2788 LandCollidingMessage.Colliders = colliding;
2789
2790 if (Inventory.ContainsScripts())
2791 {
2792 if (!PassCollisions)
2793 sendToRoot = false;
2794 }
2795 if ((ScriptEvents & ev) != 0)
2408 notify(LocalId, LandCollidingMessage); 2796 notify(LocalId, LandCollidingMessage);
2797
2798 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0 && sendToRoot)
2799 {
2800 notify(ParentGroup.RootPart.LocalId, LandCollidingMessage);
2409 } 2801 }
2410 } 2802 }
2411 2803
@@ -2421,57 +2813,120 @@ namespace OpenSim.Region.Framework.Scenes
2421 List<uint> endedColliders = new List<uint>(); 2813 List<uint> endedColliders = new List<uint>();
2422 List<uint> startedColliders = new List<uint>(); 2814 List<uint> startedColliders = new List<uint>();
2423 2815
2424 // calculate things that started colliding this time 2816 if (collissionswith.Count == 0)
2425 // and build up list of colliders this time
2426 foreach (uint localid in collissionswith.Keys)
2427 { 2817 {
2428 thisHitColliders.Add(localid); 2818 if (m_lastColliders.Count == 0)
2429 if (!m_lastColliders.Contains(localid)) 2819 return; // nothing to do
2430 startedColliders.Add(localid);
2431 }
2432 2820
2433 // calculate things that ended colliding 2821 foreach (uint localID in m_lastColliders)
2434 foreach (uint localID in m_lastColliders) 2822 {
2435 {
2436 if (!thisHitColliders.Contains(localID))
2437 endedColliders.Add(localID); 2823 endedColliders.Add(localID);
2824 }
2825 m_lastColliders.Clear();
2438 } 2826 }
2439 2827
2440 //add the items that started colliding this time to the last colliders list. 2828 else
2441 foreach (uint localID in startedColliders) 2829 {
2442 m_lastColliders.Add(localID); 2830 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
2443 2831
2444 // remove things that ended colliding from the last colliders list 2832 // calculate things that started colliding this time
2445 foreach (uint localID in endedColliders) 2833 // and build up list of colliders this time
2446 m_lastColliders.Remove(localID); 2834 if (!VolumeDetectActive && CollisionSoundType >= 0)
2835 {
2836 CollisionForSoundInfo soundinfo;
2837 ContactPoint curcontact;
2447 2838
2448 // play the sound. 2839 foreach (uint id in collissionswith.Keys)
2449 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) 2840 {
2450 { 2841 thisHitColliders.Add(id);
2451 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>(); 2842 if (!m_lastColliders.Contains(id))
2452 if (soundModule != null) 2843 {
2844 startedColliders.Add(id);
2845
2846 curcontact = collissionswith[id];
2847 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
2848 {
2849 soundinfo = new CollisionForSoundInfo();
2850 soundinfo.colliderID = id;
2851 soundinfo.position = curcontact.Position;
2852 soundinfo.relativeVel = curcontact.RelativeSpeed;
2853 soundinfolist.Add(soundinfo);
2854 }
2855 }
2856 }
2857 }
2858 else
2859 {
2860 foreach (uint id in collissionswith.Keys)
2861 {
2862 thisHitColliders.Add(id);
2863 if (!m_lastColliders.Contains(id))
2864 startedColliders.Add(id);
2865 }
2866 }
2867
2868 // calculate things that ended colliding
2869 foreach (uint localID in m_lastColliders)
2453 { 2870 {
2454 soundModule.SendSound(UUID, CollisionSound, 2871 if (!thisHitColliders.Contains(localID))
2455 CollisionSoundVolume, true, 0, 0, false, 2872 endedColliders.Add(localID);
2456 false);
2457 } 2873 }
2874
2875 //add the items that started colliding this time to the last colliders list.
2876 foreach (uint localID in startedColliders)
2877 m_lastColliders.Add(localID);
2878
2879 // remove things that ended colliding from the last colliders list
2880 foreach (uint localID in endedColliders)
2881 m_lastColliders.Remove(localID);
2882
2883 // play sounds.
2884 if (soundinfolist.Count > 0)
2885 CollisionSounds.PartCollisionSound(this, soundinfolist);
2458 } 2886 }
2459 2887
2460 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart); 2888 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
2461 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding); 2889 if (!VolumeDetectActive)
2890 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
2462 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); 2891 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
2463 2892
2464 if (startedColliders.Contains(0)) 2893 if (startedColliders.Contains(0))
2465 { 2894 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2466 if (m_lastColliders.Contains(0)) 2895 if (m_lastColliders.Contains(0))
2467 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding); 2896 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding);
2468 else
2469 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2470 }
2471 if (endedColliders.Contains(0)) 2897 if (endedColliders.Contains(0))
2472 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); 2898 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2473 } 2899 }
2474 2900
2901 // The Collision sounds code calls this
2902 public void SendCollisionSound(UUID soundID, double volume, Vector3 position)
2903 {
2904 if (soundID == UUID.Zero)
2905 return;
2906
2907 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>();
2908 if (soundModule == null)
2909 return;
2910
2911 if (volume > 1)
2912 volume = 1;
2913 if (volume < 0)
2914 volume = 0;
2915
2916 int now = Util.EnvironmentTickCount();
2917 if(Util.EnvironmentTickCountSubtract(now,LastColSoundSentTime) <200)
2918 return;
2919
2920 LastColSoundSentTime = now;
2921
2922 UUID ownerID = OwnerID;
2923 UUID objectID = ParentGroup.RootPart.UUID;
2924 UUID parentID = ParentGroup.UUID;
2925 ulong regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle;
2926
2927 soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, 0 );
2928 }
2929
2475 public void PhysicsOutOfBounds(Vector3 pos) 2930 public void PhysicsOutOfBounds(Vector3 pos)
2476 { 2931 {
2477 // Note: This is only being called on the root prim at this time. 2932 // Note: This is only being called on the root prim at this time.
@@ -2493,9 +2948,9 @@ namespace OpenSim.Region.Framework.Scenes
2493 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2948 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2494 2949
2495 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2950 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2496 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2951 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2497 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2952 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2498 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2953 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2499 { 2954 {
2500 ParentGroup.AbsolutePosition = newpos; 2955 ParentGroup.AbsolutePosition = newpos;
2501 return; 2956 return;
@@ -2780,6 +3235,14 @@ namespace OpenSim.Region.Framework.Scenes
2780 if (ParentGroup == null) 3235 if (ParentGroup == null)
2781 return; 3236 return;
2782 3237
3238 // Update the "last" values
3239 m_lastPosition = OffsetPosition;
3240 m_lastRotation = RotationOffset;
3241 m_lastVelocity = Velocity;
3242 m_lastAcceleration = Acceleration;
3243 m_lastAngularVelocity = AngularVelocity;
3244 m_lastUpdateSentTime = Environment.TickCount;
3245
2783 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3246 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
2784 { 3247 {
2785 SendFullUpdate(avatar.ControllingClient); 3248 SendFullUpdate(avatar.ControllingClient);
@@ -2838,8 +3301,8 @@ namespace OpenSim.Region.Framework.Scenes
2838 { 3301 {
2839 const float ROTATION_TOLERANCE = 0.01f; 3302 const float ROTATION_TOLERANCE = 0.01f;
2840 const float VELOCITY_TOLERANCE = 0.001f; 3303 const float VELOCITY_TOLERANCE = 0.001f;
2841 const float POSITION_TOLERANCE = 0.05f; 3304 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2842 const int TIME_MS_TOLERANCE = 3000; 3305 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2843 3306
2844 switch (UpdateFlag) 3307 switch (UpdateFlag)
2845 { 3308 {
@@ -2853,17 +3316,10 @@ namespace OpenSim.Region.Framework.Scenes
2853 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || 3316 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) ||
2854 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || 3317 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) ||
2855 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 3318 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
2856 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 3319 Environment.TickCount - m_lastUpdateSentTime > TIME_MS_TOLERANCE)
2857 { 3320 {
2858 SendTerseUpdateToAllClients(); 3321 SendTerseUpdateToAllClients();
2859 3322
2860 // Update the "last" values
2861 m_lastPosition = OffsetPosition;
2862 m_lastRotation = RotationOffset;
2863 m_lastVelocity = Velocity;
2864 m_lastAcceleration = Acceleration;
2865 m_lastAngularVelocity = AngularVelocity;
2866 m_lastTerseSent = Environment.TickCount;
2867 } 3323 }
2868 break; 3324 break;
2869 } 3325 }
@@ -2881,6 +3337,17 @@ namespace OpenSim.Region.Framework.Scenes
2881 /// </summary> 3337 /// </summary>
2882 public void SendTerseUpdateToAllClients() 3338 public void SendTerseUpdateToAllClients()
2883 { 3339 {
3340 if (ParentGroup == null || ParentGroup.Scene == null)
3341 return;
3342
3343 // Update the "last" values
3344 m_lastPosition = OffsetPosition;
3345 m_lastRotation = RotationOffset;
3346 m_lastVelocity = Velocity;
3347 m_lastAcceleration = Acceleration;
3348 m_lastAngularVelocity = AngularVelocity;
3349 m_lastUpdateSentTime = Environment.TickCount;
3350
2884 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3351 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
2885 { 3352 {
2886 SendTerseUpdateToClient(client); 3353 SendTerseUpdateToClient(client);
@@ -2904,10 +3371,13 @@ namespace OpenSim.Region.Framework.Scenes
2904 3371
2905 public void SetBuoyancy(float fvalue) 3372 public void SetBuoyancy(float fvalue)
2906 { 3373 {
2907 PhysicsActor pa = PhysActor; 3374 Buoyancy = fvalue;
2908 3375/*
2909 if (pa != null) 3376 if (PhysActor != null)
2910 pa.Buoyancy = fvalue; 3377 {
3378 PhysActor.Buoyancy = fvalue;
3379 }
3380 */
2911 } 3381 }
2912 3382
2913 public void SetDieAtEdge(bool p) 3383 public void SetDieAtEdge(bool p)
@@ -2923,47 +3393,111 @@ namespace OpenSim.Region.Framework.Scenes
2923 PhysicsActor pa = PhysActor; 3393 PhysicsActor pa = PhysActor;
2924 3394
2925 if (pa != null) 3395 if (pa != null)
2926 pa.FloatOnWater = floatYN == 1; 3396 pa.FloatOnWater = (floatYN == 1);
2927 } 3397 }
2928 3398
2929 public void SetForce(Vector3 force) 3399 public void SetForce(Vector3 force)
2930 { 3400 {
2931 PhysicsActor pa = PhysActor; 3401 Force = force;
3402 }
2932 3403
2933 if (pa != null) 3404 public SOPVehicle VehicleParams
2934 pa.Force = force; 3405 {
3406 get
3407 {
3408 return m_vehicleParams;
3409 }
3410 set
3411 {
3412 m_vehicleParams = value;
3413 }
3414 }
3415
3416
3417 public int VehicleType
3418 {
3419 get
3420 {
3421 if (m_vehicleParams == null)
3422 return (int)Vehicle.TYPE_NONE;
3423 else
3424 return (int)m_vehicleParams.Type;
3425 }
3426 set
3427 {
3428 SetVehicleType(value);
3429 }
2935 } 3430 }
2936 3431
2937 public void SetVehicleType(int type) 3432 public void SetVehicleType(int type)
2938 { 3433 {
2939 PhysicsActor pa = PhysActor; 3434 m_vehicleParams = null;
3435
3436 if (type == (int)Vehicle.TYPE_NONE)
3437 {
3438 if (_parentID ==0 && PhysActor != null)
3439 PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
3440 return;
3441 }
3442 m_vehicleParams = new SOPVehicle();
3443 m_vehicleParams.ProcessTypeChange((Vehicle)type);
3444 {
3445 if (_parentID ==0 && PhysActor != null)
3446 PhysActor.VehicleType = type;
3447 return;
3448 }
3449 }
2940 3450
2941 if (pa != null) 3451 public void SetVehicleFlags(int param, bool remove)
2942 pa.VehicleType = type; 3452 {
3453 if (m_vehicleParams == null)
3454 return;
3455
3456 m_vehicleParams.ProcessVehicleFlags(param, remove);
3457
3458 if (_parentID ==0 && PhysActor != null)
3459 {
3460 PhysActor.VehicleFlags(param, remove);
3461 }
2943 } 3462 }
2944 3463
2945 public void SetVehicleFloatParam(int param, float value) 3464 public void SetVehicleFloatParam(int param, float value)
2946 { 3465 {
2947 PhysicsActor pa = PhysActor; 3466 if (m_vehicleParams == null)
3467 return;
2948 3468
2949 if (pa != null) 3469 m_vehicleParams.ProcessFloatVehicleParam((Vehicle)param, value);
2950 pa.VehicleFloatParam(param, value); 3470
3471 if (_parentID == 0 && PhysActor != null)
3472 {
3473 PhysActor.VehicleFloatParam(param, value);
3474 }
2951 } 3475 }
2952 3476
2953 public void SetVehicleVectorParam(int param, Vector3 value) 3477 public void SetVehicleVectorParam(int param, Vector3 value)
2954 { 3478 {
2955 PhysicsActor pa = PhysActor; 3479 if (m_vehicleParams == null)
3480 return;
2956 3481
2957 if (pa != null) 3482 m_vehicleParams.ProcessVectorVehicleParam((Vehicle)param, value);
2958 pa.VehicleVectorParam(param, value); 3483
3484 if (_parentID == 0 && PhysActor != null)
3485 {
3486 PhysActor.VehicleVectorParam(param, value);
3487 }
2959 } 3488 }
2960 3489
2961 public void SetVehicleRotationParam(int param, Quaternion rotation) 3490 public void SetVehicleRotationParam(int param, Quaternion rotation)
2962 { 3491 {
2963 PhysicsActor pa = PhysActor; 3492 if (m_vehicleParams == null)
3493 return;
2964 3494
2965 if (pa != null) 3495 m_vehicleParams.ProcessRotationVehicleParam((Vehicle)param, rotation);
2966 pa.VehicleRotationParam(param, rotation); 3496
3497 if (_parentID == 0 && PhysActor != null)
3498 {
3499 PhysActor.VehicleRotationParam(param, rotation);
3500 }
2967 } 3501 }
2968 3502
2969 /// <summary> 3503 /// <summary>
@@ -3164,14 +3698,6 @@ namespace OpenSim.Region.Framework.Scenes
3164 hasProfileCut = hasDimple; // is it the same thing? 3698 hasProfileCut = hasDimple; // is it the same thing?
3165 } 3699 }
3166 3700
3167 public void SetVehicleFlags(int param, bool remove)
3168 {
3169 PhysicsActor pa = PhysActor;
3170
3171 if (pa != null)
3172 pa.VehicleFlags(param, remove);
3173 }
3174
3175 public void SetGroup(UUID groupID, IClientAPI client) 3701 public void SetGroup(UUID groupID, IClientAPI client)
3176 { 3702 {
3177 // Scene.AddNewPrims() calls with client == null so can't use this. 3703 // Scene.AddNewPrims() calls with client == null so can't use this.
@@ -3275,71 +3801,20 @@ namespace OpenSim.Region.Framework.Scenes
3275 { 3801 {
3276 ParentGroup.stopMoveToTarget(); 3802 ParentGroup.stopMoveToTarget();
3277 3803
3278 ParentGroup.ScheduleGroupForTerseUpdate(); 3804// ParentGroup.ScheduleGroupForTerseUpdate();
3279 //ParentGroup.ScheduleGroupForFullUpdate(); 3805 //ParentGroup.ScheduleGroupForFullUpdate();
3280 } 3806 }
3281 3807
3282 public void StoreUndoState() 3808 public void StoreUndoState(ObjectChangeType change)
3283 { 3809 {
3284 StoreUndoState(false); 3810 if (m_UndoRedo == null)
3285 } 3811 m_UndoRedo = new UndoRedoState(5);
3286
3287 public void StoreUndoState(bool forGroup)
3288 {
3289 if (ParentGroup == null || ParentGroup.Scene == null)
3290 return;
3291
3292 if (Undoing)
3293 {
3294// m_log.DebugFormat(
3295// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3296 return;
3297 }
3298
3299 if (IgnoreUndoUpdate)
3300 {
3301// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3302 return;
3303 }
3304 3812
3305 lock (m_undo) 3813 lock (m_UndoRedo)
3306 { 3814 {
3307 if (m_undo.Count > 0) 3815 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3308 { 3816 {
3309 UndoState last = m_undo[m_undo.Count - 1]; 3817 m_UndoRedo.StoreUndo(this, change);
3310 if (last != null)
3311 {
3312 // TODO: May need to fix for group comparison
3313 if (last.Compare(this))
3314 {
3315// m_log.DebugFormat(
3316// "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3317// Name, LocalId, m_undo.Count);
3318
3319 return;
3320 }
3321 }
3322 }
3323
3324// m_log.DebugFormat(
3325// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3326// Name, LocalId, forGroup, m_undo.Count);
3327
3328 if (ParentGroup.Scene.MaxUndoCount > 0)
3329 {
3330 UndoState nUndo = new UndoState(this, forGroup);
3331
3332 m_undo.Add(nUndo);
3333
3334 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3335 m_undo.RemoveAt(0);
3336
3337 if (m_redo.Count > 0)
3338 m_redo.Clear();
3339
3340// m_log.DebugFormat(
3341// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3342// Name, LocalId, forGroup, m_undo.Count);
3343 } 3818 }
3344 } 3819 }
3345 } 3820 }
@@ -3351,88 +3826,46 @@ namespace OpenSim.Region.Framework.Scenes
3351 { 3826 {
3352 get 3827 get
3353 { 3828 {
3354 lock (m_undo) 3829 if (m_UndoRedo == null)
3355 return m_undo.Count; 3830 return 0;
3831 return m_UndoRedo.Count;
3356 } 3832 }
3357 } 3833 }
3358 3834
3359 public void Undo() 3835 public void Undo()
3360 { 3836 {
3361 lock (m_undo) 3837 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3362 { 3838 return;
3363// m_log.DebugFormat(
3364// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3365// Name, LocalId, m_undo.Count);
3366
3367 if (m_undo.Count > 0)
3368 {
3369 UndoState goback = m_undo[m_undo.Count - 1];
3370 m_undo.RemoveAt(m_undo.Count - 1);
3371
3372 UndoState nUndo = null;
3373
3374 if (ParentGroup.Scene.MaxUndoCount > 0)
3375 {
3376 nUndo = new UndoState(this, goback.ForGroup);
3377 }
3378
3379 goback.PlaybackState(this);
3380
3381 if (nUndo != null)
3382 {
3383 m_redo.Add(nUndo);
3384
3385 if (m_redo.Count > ParentGroup.Scene.MaxUndoCount)
3386 m_redo.RemoveAt(0);
3387 }
3388 }
3389 3839
3390// m_log.DebugFormat( 3840 lock (m_UndoRedo)
3391// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3841 {
3392// Name, LocalId, m_undo.Count); 3842 Undoing = true;
3843 m_UndoRedo.Undo(this);
3844 Undoing = false;
3393 } 3845 }
3394 } 3846 }
3395 3847
3396 public void Redo() 3848 public void Redo()
3397 { 3849 {
3398 lock (m_undo) 3850 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3399 { 3851 return;
3400// m_log.DebugFormat(
3401// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3402// Name, LocalId, m_redo.Count);
3403
3404 if (m_redo.Count > 0)
3405 {
3406 UndoState gofwd = m_redo[m_redo.Count - 1];
3407 m_redo.RemoveAt(m_redo.Count - 1);
3408
3409 if (ParentGroup.Scene.MaxUndoCount > 0)
3410 {
3411 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3412
3413 m_undo.Add(nUndo);
3414
3415 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3416 m_undo.RemoveAt(0);
3417 }
3418
3419 gofwd.PlayfwdState(this);
3420 3852
3421// m_log.DebugFormat( 3853 lock (m_UndoRedo)
3422// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3854 {
3423// Name, LocalId, m_redo.Count); 3855 Undoing = true;
3424 } 3856 m_UndoRedo.Redo(this);
3857 Undoing = false;
3425 } 3858 }
3426 } 3859 }
3427 3860
3428 public void ClearUndoState() 3861 public void ClearUndoState()
3429 { 3862 {
3430// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3863 if (m_UndoRedo == null || Undoing)
3864 return;
3431 3865
3432 lock (m_undo) 3866 lock (m_UndoRedo)
3433 { 3867 {
3434 m_undo.Clear(); 3868 m_UndoRedo.Clear();
3435 m_redo.Clear();
3436 } 3869 }
3437 } 3870 }
3438 3871
@@ -3984,7 +4417,7 @@ namespace OpenSim.Region.Framework.Scenes
3984 if (god) 4417 if (god)
3985 { 4418 {
3986 BaseMask = ApplyMask(BaseMask, set, mask); 4419 BaseMask = ApplyMask(BaseMask, set, mask);
3987 Inventory.ApplyGodPermissions(_baseMask); 4420 Inventory.ApplyGodPermissions(BaseMask);
3988 } 4421 }
3989 4422
3990 break; 4423 break;
@@ -4015,7 +4448,7 @@ namespace OpenSim.Region.Framework.Scenes
4015 } 4448 }
4016 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & 4449 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) &
4017 baseMask; 4450 baseMask;
4018 // Prevent the client from creating no mod, no copy 4451 // Prevent the client from creating no copy, no transfer
4019 // objects 4452 // objects
4020 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0) 4453 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0)
4021 NextOwnerMask |= (uint)PermissionMask.Transfer; 4454 NextOwnerMask |= (uint)PermissionMask.Transfer;
@@ -4033,20 +4466,20 @@ namespace OpenSim.Region.Framework.Scenes
4033 { 4466 {
4034 bool update = false; 4467 bool update = false;
4035 4468
4036 if (BaseMask != source.BaseMask || 4469 uint prevOwnerMask = OwnerMask;
4037 OwnerMask != source.OwnerMask || 4470 uint prevGroupMask = GroupMask;
4038 GroupMask != source.GroupMask || 4471 uint prevEveryoneMask = EveryoneMask;
4039 EveryoneMask != source.EveryoneMask || 4472 uint prevNextOwnerMask = NextOwnerMask;
4040 NextOwnerMask != source.NextOwnerMask)
4041 update = true;
4042 4473
4043 BaseMask = source.BaseMask; 4474 OwnerMask = source.OwnerMask & BaseMask;
4044 OwnerMask = source.OwnerMask; 4475 GroupMask = source.GroupMask & BaseMask;
4045 GroupMask = source.GroupMask; 4476 EveryoneMask = source.EveryoneMask & BaseMask;
4046 EveryoneMask = source.EveryoneMask; 4477 NextOwnerMask = source.NextOwnerMask & BaseMask;
4047 NextOwnerMask = source.NextOwnerMask;
4048 4478
4049 if (update) 4479 if (OwnerMask != prevOwnerMask ||
4480 GroupMask != prevGroupMask ||
4481 EveryoneMask != prevEveryoneMask ||
4482 NextOwnerMask != prevNextOwnerMask)
4050 SendFullUpdateToAllClients(); 4483 SendFullUpdateToAllClients();
4051 } 4484 }
4052 4485
@@ -4097,6 +4530,7 @@ namespace OpenSim.Region.Framework.Scenes
4097 } 4530 }
4098 } 4531 }
4099 4532
4533
4100 public void UpdateExtraPhysics(ExtraPhysicsData physdata) 4534 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4101 { 4535 {
4102 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null) 4536 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
@@ -4124,7 +4558,7 @@ namespace OpenSim.Region.Framework.Scenes
4124 /// <param name="SetTemporary"></param> 4558 /// <param name="SetTemporary"></param>
4125 /// <param name="SetPhantom"></param> 4559 /// <param name="SetPhantom"></param>
4126 /// <param name="SetVD"></param> 4560 /// <param name="SetVD"></param>
4127 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) 4561 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
4128 { 4562 {
4129 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4563 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4130 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4564 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4134,116 +4568,98 @@ namespace OpenSim.Region.Framework.Scenes
4134 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4568 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4135 return; 4569 return;
4136 4570
4137 PhysicsActor pa = PhysActor; 4571 VolumeDetectActive = SetVD;
4138 4572
4139 // Special cases for VD. VD can only be called from a script 4573 // volume detector implies phantom
4140 // and can't be combined with changes to other states. So we can rely 4574 if (VolumeDetectActive)
4141 // that...
4142 // ... if VD is changed, all others are not.
4143 // ... if one of the others is changed, VD is not.
4144 if (SetVD) // VD is active, special logic applies
4145 {
4146 // State machine logic for VolumeDetect
4147 // More logic below
4148 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4149
4150 if (phanReset) // Phantom changes from on to off switch VD off too
4151 {
4152 SetVD = false; // Switch it of for the course of this routine
4153 VolumeDetectActive = false; // and also permanently
4154
4155 if (pa != null)
4156 pa.SetVolumeDetect(0); // Let physics know about it too
4157 }
4158 else
4159 {
4160 // If volumedetect is active we don't want phantom to be applied.
4161 // If this is a new call to VD out of the state "phantom"
4162 // this will also cause the prim to be visible to physics
4163 SetPhantom = false;
4164 }
4165 }
4166
4167 if (UsePhysics && IsJoint())
4168 {
4169 SetPhantom = true; 4575 SetPhantom = true;
4170 }
4171 4576
4172 if (UsePhysics) 4577 if (UsePhysics)
4173 {
4174 AddFlag(PrimFlags.Physics); 4578 AddFlag(PrimFlags.Physics);
4175 if (!wasUsingPhysics)
4176 {
4177 DoPhysicsPropertyUpdate(UsePhysics, false);
4178 }
4179 }
4180 else 4579 else
4181 {
4182 RemFlag(PrimFlags.Physics); 4580 RemFlag(PrimFlags.Physics);
4183 if (wasUsingPhysics)
4184 {
4185 DoPhysicsPropertyUpdate(UsePhysics, false);
4186 }
4187 }
4188 4581
4189 if (SetPhantom 4582 if (SetPhantom)
4190 || ParentGroup.IsAttachment
4191 || PhysicsShapeType == (byte)PhysShapeType.none
4192 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4193 {
4194 AddFlag(PrimFlags.Phantom); 4583 AddFlag(PrimFlags.Phantom);
4584 else
4585 RemFlag(PrimFlags.Phantom);
4195 4586
4196 if (PhysActor != null) 4587 if (SetTemporary)
4588 AddFlag(PrimFlags.TemporaryOnRez);
4589 else
4590 RemFlag(PrimFlags.TemporaryOnRez);
4591
4592
4593 if (ParentGroup.Scene == null)
4594 return;
4595
4596 PhysicsActor pa = PhysActor;
4597
4598 if (pa != null && building && pa.Building != building)
4599 pa.Building = building;
4600
4601 if ((SetPhantom && !UsePhysics && !SetVD) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
4602 || (Shape.PathCurve == (byte)Extrusion.Flexible))
4603 {
4604 if (pa != null)
4197 { 4605 {
4606 if(wasUsingPhysics)
4607 ParentGroup.Scene.RemovePhysicalPrim(1);
4198 RemoveFromPhysics(); 4608 RemoveFromPhysics();
4199 pa = null;
4200 } 4609 }
4610
4611 Velocity = new Vector3(0, 0, 0);
4612 Acceleration = new Vector3(0, 0, 0);
4613 if (ParentGroup.RootPart == this)
4614 AngularVelocity = new Vector3(0, 0, 0);
4201 } 4615 }
4202 else // Not phantom 4616
4617 else
4203 { 4618 {
4204 RemFlag(PrimFlags.Phantom); 4619 if (ParentGroup.Scene.CollidablePrims)
4205
4206 if (ParentGroup.Scene == null)
4207 return;
4208
4209 if (ParentGroup.Scene.CollidablePrims && pa == null)
4210 { 4620 {
4211 AddToPhysics(UsePhysics, SetPhantom, false); 4621 if (pa == null)
4212 pa = PhysActor;
4213
4214
4215 if (pa != null)
4216 { 4622 {
4217 pa.SetMaterial(Material); 4623 AddToPhysics(UsePhysics, SetPhantom, building, false);
4218 DoPhysicsPropertyUpdate(UsePhysics, true); 4624 pa = PhysActor;
4219 4625/*
4220 if ( 4626 if (pa != null)
4221 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4222 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4223 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4224 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4225 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4226 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4227 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4228 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4229 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4230 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4231 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4232 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4233 (CollisionSound != UUID.Zero)
4234 )
4235 { 4627 {
4236 pa.OnCollisionUpdate += PhysicsCollision; 4628 if (
4237 pa.SubscribeEvents(1000); 4629// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4630// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4631// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4632// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4633// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4634// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4635 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4636 ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4637 (CollisionSound != UUID.Zero)
4638 )
4639 {
4640 pa.OnCollisionUpdate += PhysicsCollision;
4641 pa.SubscribeEvents(1000);
4642 }
4238 } 4643 }
4644*/
4645 }
4646 else // it already has a physical representation
4647 {
4648 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4649/* moved into DoPhysicsPropertyUpdate
4650 if(VolumeDetectActive)
4651 pa.SetVolumeDetect(1);
4652 else
4653 pa.SetVolumeDetect(0);
4654*/
4655
4656 if (pa.Building != building)
4657 pa.Building = building;
4239 } 4658 }
4240 }
4241 else // it already has a physical representation
4242 {
4243 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4244 }
4245 }
4246 4659
4660 UpdatePhysicsSubscribedEvents();
4661 }
4662 }
4247 if (SetVD) 4663 if (SetVD)
4248 { 4664 {
4249 // If the above logic worked (this is urgent candidate to unit tests!) 4665 // If the above logic worked (this is urgent candidate to unit tests!)
@@ -4257,6 +4673,7 @@ namespace OpenSim.Region.Framework.Scenes
4257 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active 4673 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4258 VolumeDetectActive = true; 4674 VolumeDetectActive = true;
4259 } 4675 }
4676 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4260 } 4677 }
4261 else if (SetVD != wasVD) 4678 else if (SetVD != wasVD)
4262 { 4679 {
@@ -4268,61 +4685,51 @@ namespace OpenSim.Region.Framework.Scenes
4268 RemFlag(PrimFlags.Phantom); 4685 RemFlag(PrimFlags.Phantom);
4269 VolumeDetectActive = false; 4686 VolumeDetectActive = false;
4270 } 4687 }
4271 4688 // and last in case we have a new actor and not building
4272 if (SetTemporary)
4273 {
4274 AddFlag(PrimFlags.TemporaryOnRez);
4275 }
4276 else
4277 {
4278 RemFlag(PrimFlags.TemporaryOnRez);
4279 }
4280
4281 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4282 4689
4283 if (ParentGroup != null) 4690 if (ParentGroup != null)
4284 { 4691 {
4285 ParentGroup.HasGroupChanged = true; 4692 ParentGroup.HasGroupChanged = true;
4286 ScheduleFullUpdate(); 4693 ScheduleFullUpdate();
4287 } 4694 }
4288 4695
4289// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); 4696// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4290 } 4697 }
4291 4698
4292 /// <summary> 4699 /// <summary>
4293 /// Adds this part to the physics scene. 4700 /// Adds this part to the physics scene.
4701 /// and sets the PhysActor property
4294 /// </summary> 4702 /// </summary>
4295 /// <remarks>This method also sets the PhysActor property.</remarks> 4703 /// <param name="isPhysical">Add this prim as physical.</param>
4296 /// <param name="rigidBody">Add this prim with a rigid body.</param> 4704 /// <param name="isPhantom">Add this prim as phantom.</param>
4297 /// <returns> 4705 /// <param name="building">tells physics to delay full construction of object</param>
4298 /// The physics actor. null if there was a failure. 4706 /// <param name="applyDynamics">applies velocities, force and torque</param>
4299 /// </returns> 4707 private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
4300 private void AddToPhysics(bool isPhysical, bool isPhantom, bool applyDynamics) 4708 {
4301 {
4302 PhysicsActor pa; 4709 PhysicsActor pa;
4303 4710
4304 Vector3 velocity = Velocity; 4711 Vector3 velocity = Velocity;
4305 Vector3 rotationalVelocity = AngularVelocity;; 4712 Vector3 rotationalVelocity = AngularVelocity;;
4306 4713
4307 try 4714 try
4308 { 4715 {
4309 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4716 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4310 string.Format("{0}/{1}", Name, UUID), 4717 string.Format("{0}/{1}", Name, UUID),
4311 Shape, 4718 Shape,
4312 AbsolutePosition, 4719 AbsolutePosition,
4313 Scale, 4720 Scale,
4314 GetWorldRotation(), 4721 GetWorldRotation(),
4315 isPhysical, 4722 isPhysical,
4316 isPhantom, 4723 isPhantom,
4317 PhysicsShapeType, 4724 PhysicsShapeType,
4318 m_localId); 4725 m_localId);
4319 } 4726 }
4320 catch (Exception e) 4727 catch (Exception e)
4321 { 4728 {
4322 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e); 4729 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e);
4323 pa = null; 4730 pa = null;
4324 } 4731 }
4325 4732
4326 if (pa != null) 4733 if (pa != null)
4327 { 4734 {
4328 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 4735 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
@@ -4335,9 +4742,16 @@ namespace OpenSim.Region.Framework.Scenes
4335 4742
4336 if (VolumeDetectActive) // change if not the default only 4743 if (VolumeDetectActive) // change if not the default only
4337 pa.SetVolumeDetect(1); 4744 pa.SetVolumeDetect(1);
4745
4746 if (m_vehicleParams != null && LocalId == ParentGroup.RootPart.LocalId)
4747 m_vehicleParams.SetVehicle(pa);
4748
4338 // we are going to tell rest of code about physics so better have this here 4749 // we are going to tell rest of code about physics so better have this here
4339 PhysActor = pa; 4750 PhysActor = pa;
4340 4751
4752 // DoPhysicsPropertyUpdate(isPhysical, true);
4753 // lets expand it here just with what it really needs to do
4754
4341 if (isPhysical) 4755 if (isPhysical)
4342 { 4756 {
4343 if (ParentGroup.RootPart.KeyframeMotion != null) 4757 if (ParentGroup.RootPart.KeyframeMotion != null)
@@ -4359,19 +4773,34 @@ namespace OpenSim.Region.Framework.Scenes
4359 } 4773 }
4360 } 4774 }
4361 4775
4362 if (applyDynamics) 4776 if (applyDynamics)
4363 // do independent of isphysical so parameters get setted (at least some) 4777 // do independent of isphysical so parameters get setted (at least some)
4364 { 4778 {
4365 Velocity = velocity; 4779 Velocity = velocity;
4366 AngularVelocity = rotationalVelocity; 4780 AngularVelocity = rotationalVelocity;
4367// pa.Velocity = velocity; 4781// pa.Velocity = velocity;
4368 pa.RotationalVelocity = rotationalVelocity; 4782 pa.RotationalVelocity = rotationalVelocity;
4783
4784 // if not vehicle and root part apply force and torque
4785 if ((m_vehicleParams == null || m_vehicleParams.Type == Vehicle.TYPE_NONE)
4786 && LocalId == ParentGroup.RootPart.LocalId)
4787 {
4788 pa.Force = Force;
4789 pa.Torque = Torque;
4790 }
4369 } 4791 }
4370 4792
4371 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); 4793// if (Shape.SculptEntry)
4794// CheckSculptAndLoad();
4795// else
4796 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
4797
4798 if (!building)
4799 pa.Building = false;
4372 } 4800 }
4373 4801
4374 PhysActor = pa; 4802 PhysActor = pa;
4803
4375 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this); 4804 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this);
4376 } 4805 }
4377 4806
@@ -4380,13 +4809,21 @@ namespace OpenSim.Region.Framework.Scenes
4380 /// </summary> 4809 /// </summary>
4381 /// <remarks> 4810 /// <remarks>
4382 /// This isn't the same as turning off physical, since even without being physical the prim has a physics 4811 /// This isn't the same as turning off physical, since even without being physical the prim has a physics
4383 /// representation for collision detection. Rather, this would be used in situations such as making a prim 4812 /// representation for collision detection.
4384 /// phantom.
4385 /// </remarks> 4813 /// </remarks>
4386 public void RemoveFromPhysics() 4814 public void RemoveFromPhysics()
4387 { 4815 {
4388 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this); 4816 PhysicsActor pa = PhysActor;
4389 ParentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 4817 if (pa != null)
4818 {
4819 pa.OnCollisionUpdate -= PhysicsCollision;
4820 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
4821 pa.OnOutOfBounds -= PhysicsOutOfBounds;
4822
4823 ParentGroup.Scene.PhysicsScene.RemovePrim(pa);
4824
4825 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this);
4826 }
4390 PhysActor = null; 4827 PhysActor = null;
4391 } 4828 }
4392 4829
@@ -4518,6 +4955,8 @@ namespace OpenSim.Region.Framework.Scenes
4518 { 4955 {
4519// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); 4956// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4520 4957
4958 return;
4959
4521 if (ParentGroup.IsDeleted) 4960 if (ParentGroup.IsDeleted)
4522 return; 4961 return;
4523 4962
@@ -4641,6 +5080,44 @@ namespace OpenSim.Region.Framework.Scenes
4641 } 5080 }
4642 } 5081 }
4643 5082
5083
5084 private void UpdatePhysicsSubscribedEvents()
5085 {
5086 PhysicsActor pa = PhysActor;
5087 if (pa == null)
5088 return;
5089
5090 pa.OnCollisionUpdate -= PhysicsCollision;
5091
5092 bool hassound = (!VolumeDetectActive && CollisionSoundType >= 0 && ((Flags & PrimFlags.Physics) != 0));
5093
5094 scriptEvents CombinedEvents = AggregateScriptEvents;
5095
5096 // merge with root part
5097 if (ParentGroup != null && ParentGroup.RootPart != null)
5098 CombinedEvents |= ParentGroup.RootPart.AggregateScriptEvents;
5099
5100 // submit to this part case
5101 if (VolumeDetectActive)
5102 CombinedEvents &= PhyscicsVolumeDtcSubsEvents;
5103 else if ((Flags & PrimFlags.Phantom) != 0)
5104 CombinedEvents &= PhyscicsPhantonSubsEvents;
5105 else
5106 CombinedEvents &= PhysicsNeededSubsEvents;
5107
5108 if (hassound || CombinedEvents != 0)
5109 {
5110 // subscribe to physics updates.
5111 pa.OnCollisionUpdate += PhysicsCollision;
5112 pa.SubscribeEvents(50); // 20 reports per second
5113 }
5114 else
5115 {
5116 pa.UnSubscribeEvents();
5117 }
5118 }
5119
5120
4644 public void aggregateScriptEvents() 5121 public void aggregateScriptEvents()
4645 { 5122 {
4646 if (ParentGroup == null || ParentGroup.RootPart == null) 5123 if (ParentGroup == null || ParentGroup.RootPart == null)
@@ -4677,40 +5154,32 @@ namespace OpenSim.Region.Framework.Scenes
4677 { 5154 {
4678 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; 5155 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop;
4679 } 5156 }
4680 5157/*
4681 PhysicsActor pa = PhysActor; 5158 PhysicsActor pa = PhysActor;
4682 5159 if (pa != null)
4683 if (
4684 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4685 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4686 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4687 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4688 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4689 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4690 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4691 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4692 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4693 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4694 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4695 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4696 (CollisionSound != UUID.Zero)
4697 )
4698 { 5160 {
4699 // subscribe to physics updates. 5161 if (
4700 if (pa != null) 5162// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
5163// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
5164// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
5165// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5166// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5167// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5168 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5169 )
4701 { 5170 {
5171 // subscribe to physics updates.
4702 pa.OnCollisionUpdate += PhysicsCollision; 5172 pa.OnCollisionUpdate += PhysicsCollision;
4703 pa.SubscribeEvents(1000); 5173 pa.SubscribeEvents(1000);
4704 } 5174 }
4705 } 5175 else
4706 else
4707 {
4708 if (pa != null)
4709 { 5176 {
4710 pa.UnSubscribeEvents(); 5177 pa.UnSubscribeEvents();
4711 pa.OnCollisionUpdate -= PhysicsCollision; 5178 pa.OnCollisionUpdate -= PhysicsCollision;
4712 } 5179 }
4713 } 5180 }
5181 */
5182 UpdatePhysicsSubscribedEvents();
4714 5183
4715 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 5184 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4716 //{ 5185 //{
@@ -4844,6 +5313,18 @@ namespace OpenSim.Region.Framework.Scenes
4844 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 5313 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4845 } 5314 }
4846 5315
5316 public void ResetOwnerChangeFlag()
5317 {
5318 List<UUID> inv = Inventory.GetInventoryList();
5319
5320 foreach (UUID itemID in inv)
5321 {
5322 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
5323 item.OwnerChanged = false;
5324 Inventory.UpdateInventoryItem(item, false, false);
5325 }
5326 }
5327
4847 /// <summary> 5328 /// <summary>
4848 /// Record an avatar sitting on this part. 5329 /// Record an avatar sitting on this part.
4849 /// </summary> 5330 /// </summary>