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.cs1480
1 files changed, 989 insertions, 491 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index a8b63fe..ffde415 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -63,7 +63,8 @@ namespace OpenSim.Region.Framework.Scenes
63 TELEPORT = 512, 63 TELEPORT = 512,
64 REGION_RESTART = 1024, 64 REGION_RESTART = 1024,
65 MEDIA = 2048, 65 MEDIA = 2048,
66 ANIMATION = 16384 66 ANIMATION = 16384,
67 POSITION = 32768
67 } 68 }
68 69
69 // I don't really know where to put this except here. 70 // I don't really know where to put this except here.
@@ -122,7 +123,18 @@ namespace OpenSim.Region.Framework.Scenes
122 /// Denote all sides of the prim 123 /// Denote all sides of the prim
123 /// </value> 124 /// </value>
124 public const int ALL_SIDES = -1; 125 public const int ALL_SIDES = -1;
125 126
127 private const scriptEvents PhysicsNeededSubsEvents = (
128 scriptEvents.collision | scriptEvents.collision_start | scriptEvents.collision_end |
129 scriptEvents.land_collision | scriptEvents.land_collision_start | scriptEvents.land_collision_end
130 );
131 private const scriptEvents PhyscicsPhantonSubsEvents = (
132 scriptEvents.land_collision | scriptEvents.land_collision_start | scriptEvents.land_collision_end
133 );
134 private const scriptEvents PhyscicsVolumeDtcSubsEvents = (
135 scriptEvents.collision_start | scriptEvents.collision_end
136 );
137
126 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 138 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
127 139
128 /// <summary> 140 /// <summary>
@@ -159,7 +171,7 @@ namespace OpenSim.Region.Framework.Scenes
159 /// </remarks> 171 /// </remarks>
160 public bool IsRoot 172 public bool IsRoot
161 { 173 {
162 get { return ParentGroup.RootPart == this; } 174 get { return Object.ReferenceEquals(ParentGroup.RootPart, this); }
163 } 175 }
164 176
165 /// <summary> 177 /// <summary>
@@ -218,12 +230,25 @@ namespace OpenSim.Region.Framework.Scenes
218 230
219 public double SoundRadius; 231 public double SoundRadius;
220 232
233
221 public uint TimeStampFull; 234 public uint TimeStampFull;
222 235
223 public uint TimeStampLastActivity; // Will be used for AutoReturn 236 public uint TimeStampLastActivity; // Will be used for AutoReturn
224 237
225 public uint TimeStampTerse; 238 public uint TimeStampTerse;
226 239
240 // The following two are to hold the attachment data
241 // while an object is inworld
242 [XmlIgnore]
243 public byte AttachPoint = 0;
244
245 [XmlIgnore]
246 public Vector3 AttachOffset = Vector3.Zero;
247
248 [XmlIgnore]
249 public Quaternion AttachRotation = Quaternion.Identity;
250
251 [XmlIgnore]
227 public int STATUS_ROTATE_X; 252 public int STATUS_ROTATE_X;
228 253
229 public int STATUS_ROTATE_Y; 254 public int STATUS_ROTATE_Y;
@@ -250,8 +275,7 @@ namespace OpenSim.Region.Framework.Scenes
250 275
251 public Vector3 RotationAxis = Vector3.One; 276 public Vector3 RotationAxis = Vector3.One;
252 277
253 public bool VolumeDetectActive; // XmlIgnore set to avoid problems with persistance until I come to care for this 278 public bool VolumeDetectActive;
254 // Certainly this must be a persistant setting finally
255 279
256 public bool IsWaitingForFirstSpinUpdatePacket; 280 public bool IsWaitingForFirstSpinUpdatePacket;
257 281
@@ -291,10 +315,10 @@ namespace OpenSim.Region.Framework.Scenes
291 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 315 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
292 private Vector3 m_sitTargetPosition; 316 private Vector3 m_sitTargetPosition;
293 private string m_sitAnimation = "SIT"; 317 private string m_sitAnimation = "SIT";
318 private bool m_occupied; // KF if any av is sitting on this prim
294 private string m_text = String.Empty; 319 private string m_text = String.Empty;
295 private string m_touchName = String.Empty; 320 private string m_touchName = String.Empty;
296 private readonly List<UndoState> m_undo = new List<UndoState>(5); 321 private UndoRedoState m_UndoRedo = null;
297 private readonly List<UndoState> m_redo = new List<UndoState>(5);
298 322
299 private bool m_passTouches = false; 323 private bool m_passTouches = false;
300 private bool m_passCollisions = false; 324 private bool m_passCollisions = false;
@@ -322,14 +346,20 @@ namespace OpenSim.Region.Framework.Scenes
322 protected Vector3 m_lastVelocity; 346 protected Vector3 m_lastVelocity;
323 protected Vector3 m_lastAcceleration; 347 protected Vector3 m_lastAcceleration;
324 protected Vector3 m_lastAngularVelocity; 348 protected Vector3 m_lastAngularVelocity;
325 protected int m_lastTerseSent; 349 protected int m_lastUpdateSentTime;
350 protected float m_buoyancy = 0.0f;
351 protected Vector3 m_force;
352 protected Vector3 m_torque;
326 353
327 protected byte m_physicsShapeType = (byte)PhysShapeType.prim; 354 protected byte m_physicsShapeType = (byte)PhysShapeType.prim;
328 protected float m_density = 1000.0f; // in kg/m^3 355 protected float m_density = 1000.0f; // in kg/m^3
329 protected float m_gravitymod = 1.0f; 356 protected float m_gravitymod = 1.0f;
330 protected float m_friction = 0.6f; // wood 357 protected float m_friction = 0.6f; // wood
331 protected float m_bounce = 0.5f; // wood 358 protected float m_bounce = 0.5f; // wood
332 359
360
361 protected bool m_isSelected = false;
362
333 /// <summary> 363 /// <summary>
334 /// Stores media texture data 364 /// Stores media texture data
335 /// </summary> 365 /// </summary>
@@ -341,10 +371,25 @@ namespace OpenSim.Region.Framework.Scenes
341 private Vector3 m_cameraAtOffset; 371 private Vector3 m_cameraAtOffset;
342 private bool m_forceMouselook; 372 private bool m_forceMouselook;
343 373
344 // TODO: Collision sound should have default. 374
375 // 0 for default collision sounds, -1 for script disabled sound 1 for script defined sound
376 private sbyte m_collisionSoundType;
345 private UUID m_collisionSound; 377 private UUID m_collisionSound;
346 private float m_collisionSoundVolume; 378 private float m_collisionSoundVolume;
347 379
380 private int LastColSoundSentTime;
381
382
383 private SOPVehicle m_vehicleParams = null;
384
385 private KeyframeMotion m_keyframeMotion = null;
386
387 public KeyframeMotion KeyframeMotion
388 {
389 get; set;
390 }
391
392
348 #endregion Fields 393 #endregion Fields
349 394
350// ~SceneObjectPart() 395// ~SceneObjectPart()
@@ -374,6 +419,7 @@ namespace OpenSim.Region.Framework.Scenes
374 // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from 419 // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from
375 // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log 420 // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log
376 m_inventory = new SceneObjectPartInventory(this); 421 m_inventory = new SceneObjectPartInventory(this);
422 LastColSoundSentTime = Util.EnvironmentTickCount();
377 } 423 }
378 424
379 /// <summary> 425 /// <summary>
@@ -388,7 +434,7 @@ namespace OpenSim.Region.Framework.Scenes
388 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 434 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
389 Quaternion rotationOffset, Vector3 offsetPosition) : this() 435 Quaternion rotationOffset, Vector3 offsetPosition) : this()
390 { 436 {
391 m_name = "Primitive"; 437 m_name = "Object";
392 438
393 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 439 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
394 LastOwnerID = CreatorID = OwnerID = ownerID; 440 LastOwnerID = CreatorID = OwnerID = ownerID;
@@ -427,7 +473,7 @@ namespace OpenSim.Region.Framework.Scenes
427 private uint _ownerMask = (uint)PermissionMask.All; 473 private uint _ownerMask = (uint)PermissionMask.All;
428 private uint _groupMask = (uint)PermissionMask.None; 474 private uint _groupMask = (uint)PermissionMask.None;
429 private uint _everyoneMask = (uint)PermissionMask.None; 475 private uint _everyoneMask = (uint)PermissionMask.None;
430 private uint _nextOwnerMask = (uint)PermissionMask.All; 476 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
431 private PrimFlags _flags = PrimFlags.None; 477 private PrimFlags _flags = PrimFlags.None;
432 private DateTime m_expires; 478 private DateTime m_expires;
433 private DateTime m_rezzed; 479 private DateTime m_rezzed;
@@ -521,12 +567,16 @@ namespace OpenSim.Region.Framework.Scenes
521 } 567 }
522 568
523 /// <value> 569 /// <value>
524 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 570 /// Get the inventory list
525 /// </value> 571 /// </value>
526 public TaskInventoryDictionary TaskInventory 572 public TaskInventoryDictionary TaskInventory
527 { 573 {
528 get { return m_inventory.Items; } 574 get {
529 set { m_inventory.Items = value; } 575 return m_inventory.Items;
576 }
577 set {
578 m_inventory.Items = value;
579 }
530 } 580 }
531 581
532 /// <summary> 582 /// <summary>
@@ -576,20 +626,6 @@ namespace OpenSim.Region.Framework.Scenes
576 } 626 }
577 } 627 }
578 628
579 public byte Material
580 {
581 get { return (byte) m_material; }
582 set
583 {
584 m_material = (Material)value;
585
586 PhysicsActor pa = PhysActor;
587
588 if (pa != null)
589 pa.SetMaterial((int)value);
590 }
591 }
592
593 [XmlIgnore] 629 [XmlIgnore]
594 public bool PassTouches 630 public bool PassTouches
595 { 631 {
@@ -615,6 +651,18 @@ namespace OpenSim.Region.Framework.Scenes
615 } 651 }
616 } 652 }
617 653
654 public bool IsSelected
655 {
656 get { return m_isSelected; }
657 set
658 {
659 m_isSelected = value;
660 if (ParentGroup != null)
661 ParentGroup.PartSelectChanged(value);
662 }
663 }
664
665
618 public Dictionary<int, string> CollisionFilter 666 public Dictionary<int, string> CollisionFilter
619 { 667 {
620 get { return m_CollisionFilter; } 668 get { return m_CollisionFilter; }
@@ -683,14 +731,12 @@ namespace OpenSim.Region.Framework.Scenes
683 set { m_LoopSoundSlavePrims = value; } 731 set { m_LoopSoundSlavePrims = value; }
684 } 732 }
685 733
686
687 public Byte[] TextureAnimation 734 public Byte[] TextureAnimation
688 { 735 {
689 get { return m_TextureAnimation; } 736 get { return m_TextureAnimation; }
690 set { m_TextureAnimation = value; } 737 set { m_TextureAnimation = value; }
691 } 738 }
692 739
693
694 public Byte[] ParticleSystem 740 public Byte[] ParticleSystem
695 { 741 {
696 get { return m_particleSystem; } 742 get { return m_particleSystem; }
@@ -727,9 +773,12 @@ namespace OpenSim.Region.Framework.Scenes
727 { 773 {
728 // If this is a linkset, we don't want the physics engine mucking up our group position here. 774 // If this is a linkset, we don't want the physics engine mucking up our group position here.
729 PhysicsActor actor = PhysActor; 775 PhysicsActor actor = PhysActor;
730 // If physical and the root prim of a linkset, the position of the group is what physics thinks. 776 if (ParentID == 0)
731 if (actor != null && ParentID == 0) 777 {
732 m_groupPosition = actor.Position; 778 if (actor != null)
779 m_groupPosition = actor.Position;
780 return m_groupPosition;
781 }
733 782
734 // If I'm an attachment, my position is reported as the position of who I'm attached to 783 // If I'm an attachment, my position is reported as the position of who I'm attached to
735 if (ParentGroup.IsAttachment) 784 if (ParentGroup.IsAttachment)
@@ -739,14 +788,16 @@ namespace OpenSim.Region.Framework.Scenes
739 return sp.AbsolutePosition; 788 return sp.AbsolutePosition;
740 } 789 }
741 790
791 // use root prim's group position. Physics may have updated it
792 if (ParentGroup.RootPart != this)
793 m_groupPosition = ParentGroup.RootPart.GroupPosition;
742 return m_groupPosition; 794 return m_groupPosition;
743 } 795 }
744 set 796 set
745 { 797 {
746 m_groupPosition = value; 798 m_groupPosition = value;
747
748 PhysicsActor actor = PhysActor; 799 PhysicsActor actor = PhysActor;
749 if (actor != null) 800 if (actor != null && ParentGroup.Scene.PhysicsScene != null)
750 { 801 {
751 try 802 try
752 { 803 {
@@ -770,16 +821,6 @@ namespace OpenSim.Region.Framework.Scenes
770 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e); 821 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e);
771 } 822 }
772 } 823 }
773
774 // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
775 if (SitTargetAvatar != UUID.Zero)
776 {
777 ScenePresence avatar;
778 if (ParentGroup.Scene.TryGetScenePresence(SitTargetAvatar, out avatar))
779 {
780 avatar.ParentPosition = GetWorldPosition();
781 }
782 }
783 } 824 }
784 } 825 }
785 826
@@ -788,7 +829,7 @@ namespace OpenSim.Region.Framework.Scenes
788 get { return m_offsetPosition; } 829 get { return m_offsetPosition; }
789 set 830 set
790 { 831 {
791// StoreUndoState(); 832 Vector3 oldpos = m_offsetPosition;
792 m_offsetPosition = value; 833 m_offsetPosition = value;
793 834
794 if (ParentGroup != null && !ParentGroup.IsDeleted) 835 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -800,10 +841,25 @@ namespace OpenSim.Region.Framework.Scenes
800 actor.Orientation = GetWorldRotation(); 841 actor.Orientation = GetWorldRotation();
801 842
802 // Tell the physics engines that this prim changed. 843 // Tell the physics engines that this prim changed.
803 if (ParentGroup.Scene != null) 844 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene != null)
804 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 845 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
805 } 846 }
847
848 if (!m_parentGroup.m_dupeInProgress)
849 {
850 List<ScenePresence> avs = ParentGroup.GetLinkedAvatars();
851 foreach (ScenePresence av in avs)
852 {
853 if (av.ParentID == m_localId)
854 {
855 Vector3 offset = (m_offsetPosition - oldpos);
856 av.AbsolutePosition += offset;
857 av.SendAvatarDataToAllAgents();
858 }
859 }
860 }
806 } 861 }
862 TriggerScriptChangedEvent(Changed.POSITION);
807 } 863 }
808 } 864 }
809 865
@@ -854,7 +910,7 @@ namespace OpenSim.Region.Framework.Scenes
854 910
855 set 911 set
856 { 912 {
857 StoreUndoState(); 913// StoreUndoState();
858 m_rotationOffset = value; 914 m_rotationOffset = value;
859 915
860 PhysicsActor actor = PhysActor; 916 PhysicsActor actor = PhysActor;
@@ -942,19 +998,36 @@ namespace OpenSim.Region.Framework.Scenes
942 get 998 get
943 { 999 {
944 PhysicsActor actor = PhysActor; 1000 PhysicsActor actor = PhysActor;
945 if ((actor != null) && actor.IsPhysical) 1001 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
946 { 1002 {
947 m_angularVelocity = actor.RotationalVelocity; 1003 m_angularVelocity = actor.RotationalVelocity;
948 } 1004 }
949 return m_angularVelocity; 1005 return m_angularVelocity;
950 } 1006 }
951 set { m_angularVelocity = value; } 1007 set
1008 {
1009 m_angularVelocity = value;
1010 PhysicsActor actor = PhysActor;
1011 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this && VehicleType == (int)Vehicle.TYPE_NONE)
1012 {
1013 actor.RotationalVelocity = m_angularVelocity;
1014 }
1015 }
952 } 1016 }
953 1017
954 /// <summary></summary> 1018 /// <summary></summary>
955 public Vector3 Acceleration 1019 public Vector3 Acceleration
956 { 1020 {
957 get { return m_acceleration; } 1021 get
1022 {
1023 PhysicsActor actor = PhysActor;
1024 if (actor != null)
1025 {
1026 m_acceleration = actor.Acceleration;
1027 }
1028 return m_acceleration;
1029 }
1030
958 set { m_acceleration = value; } 1031 set { m_acceleration = value; }
959 } 1032 }
960 1033
@@ -1022,7 +1095,10 @@ namespace OpenSim.Region.Framework.Scenes
1022 public PrimitiveBaseShape Shape 1095 public PrimitiveBaseShape Shape
1023 { 1096 {
1024 get { return m_shape; } 1097 get { return m_shape; }
1025 set { m_shape = value;} 1098 set
1099 {
1100 m_shape = value;
1101 }
1026 } 1102 }
1027 1103
1028 /// <summary> 1104 /// <summary>
@@ -1035,7 +1111,6 @@ namespace OpenSim.Region.Framework.Scenes
1035 { 1111 {
1036 if (m_shape != null) 1112 if (m_shape != null)
1037 { 1113 {
1038 StoreUndoState();
1039 1114
1040 m_shape.Scale = value; 1115 m_shape.Scale = value;
1041 1116
@@ -1103,10 +1178,7 @@ namespace OpenSim.Region.Framework.Scenes
1103 { 1178 {
1104 get 1179 get
1105 { 1180 {
1106 if (ParentGroup.IsAttachment) 1181 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
1107 return GroupPosition;
1108
1109 return m_offsetPosition + m_groupPosition;
1110 } 1182 }
1111 } 1183 }
1112 1184
@@ -1284,6 +1356,13 @@ namespace OpenSim.Region.Framework.Scenes
1284 _flags = value; 1356 _flags = value;
1285 } 1357 }
1286 } 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 }
1287 1366
1288 /// <summary> 1367 /// <summary>
1289 /// 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
@@ -1334,12 +1413,41 @@ namespace OpenSim.Region.Framework.Scenes
1334 set { m_sitAnimation = value; } 1413 set { m_sitAnimation = value; }
1335 } 1414 }
1336 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
1337 public UUID CollisionSound 1437 public UUID CollisionSound
1338 { 1438 {
1339 get { return m_collisionSound; } 1439 get { return m_collisionSound; }
1340 set 1440 set
1341 { 1441 {
1342 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
1343 aggregateScriptEvents(); 1451 aggregateScriptEvents();
1344 } 1452 }
1345 } 1453 }
@@ -1350,6 +1458,125 @@ namespace OpenSim.Region.Framework.Scenes
1350 set { m_collisionSoundVolume = value; } 1458 set { m_collisionSoundVolume = value; }
1351 } 1459 }
1352 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
1353 public byte DefaultPhysicsShapeType() 1580 public byte DefaultPhysicsShapeType()
1354 { 1581 {
1355 byte type; 1582 byte type;
@@ -1362,6 +1589,65 @@ namespace OpenSim.Region.Framework.Scenes
1362 return type; 1589 return type;
1363 } 1590 }
1364 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
1365 public byte PhysicsShapeType 1651 public byte PhysicsShapeType
1366 { 1652 {
1367 get { return m_physicsShapeType; } 1653 get { return m_physicsShapeType; }
@@ -1395,11 +1681,14 @@ namespace OpenSim.Region.Framework.Scenes
1395 } 1681 }
1396 else if (PhysActor == null) 1682 else if (PhysActor == null)
1397 { 1683 {
1398 ApplyPhysics((uint)Flags, VolumeDetectActive); 1684 ApplyPhysics((uint)Flags, VolumeDetectActive, false);
1685 UpdatePhysicsSubscribedEvents();
1399 } 1686 }
1400 else 1687 else
1401 { 1688 {
1402 PhysActor.PhysicsShapeType = m_physicsShapeType; 1689 PhysActor.PhysicsShapeType = m_physicsShapeType;
1690// if (Shape.SculptEntry)
1691// CheckSculptAndLoad();
1403 } 1692 }
1404 1693
1405 if (ParentGroup != null) 1694 if (ParentGroup != null)
@@ -1501,6 +1790,7 @@ namespace OpenSim.Region.Framework.Scenes
1501 } 1790 }
1502 } 1791 }
1503 1792
1793
1504 #endregion Public Properties with only Get 1794 #endregion Public Properties with only Get
1505 1795
1506 private uint ApplyMask(uint val, bool set, uint mask) 1796 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1646,6 +1936,61 @@ namespace OpenSim.Region.Framework.Scenes
1646 } 1936 }
1647 } 1937 }
1648 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
1649 /// <summary> 1994 /// <summary>
1650 /// hook to the physics scene to apply angular impulse 1995 /// hook to the physics scene to apply angular impulse
1651 /// 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
@@ -1666,7 +2011,7 @@ namespace OpenSim.Region.Framework.Scenes
1666 impulse = newimpulse; 2011 impulse = newimpulse;
1667 } 2012 }
1668 2013
1669 ParentGroup.applyAngularImpulse(impulse); 2014 ParentGroup.ApplyAngularImpulse(impulse);
1670 } 2015 }
1671 2016
1672 /// <summary> 2017 /// <summary>
@@ -1676,20 +2021,24 @@ namespace OpenSim.Region.Framework.Scenes
1676 /// </summary> 2021 /// </summary>
1677 /// <param name="impulsei">Vector force</param> 2022 /// <param name="impulsei">Vector force</param>
1678 /// <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>
1679 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)
1680 { 2027 {
1681 Vector3 impulse = impulsei; 2028 Vector3 torque = torquei;
1682 2029
1683 if (localGlobalTF) 2030 if (localGlobalTF)
1684 { 2031 {
2032/*
1685 Quaternion grot = GetWorldRotation(); 2033 Quaternion grot = GetWorldRotation();
1686 Quaternion AXgrot = grot; 2034 Quaternion AXgrot = grot;
1687 Vector3 AXimpulsei = impulsei; 2035 Vector3 AXimpulsei = impulsei;
1688 Vector3 newimpulse = AXimpulsei * AXgrot; 2036 Vector3 newimpulse = AXimpulsei * AXgrot;
1689 impulse = newimpulse; 2037 */
2038 torque *= GetWorldRotation();
1690 } 2039 }
1691 2040
1692 ParentGroup.setAngularImpulse(impulse); 2041 Torque = torque;
1693 } 2042 }
1694 2043
1695 /// <summary> 2044 /// <summary>
@@ -1697,7 +2046,9 @@ namespace OpenSim.Region.Framework.Scenes
1697 /// </summary> 2046 /// </summary>
1698 /// <param name="rootObjectFlags"></param> 2047 /// <param name="rootObjectFlags"></param>
1699 /// <param name="VolumeDetectActive"></param> 2048 /// <param name="VolumeDetectActive"></param>
1700 public void ApplyPhysics(uint rootObjectFlags, bool _VolumeDetectActive) 2049 /// <param name="building"></param>
2050
2051 public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building)
1701 { 2052 {
1702 VolumeDetectActive = _VolumeDetectActive; 2053 VolumeDetectActive = _VolumeDetectActive;
1703 2054
@@ -1707,8 +2058,8 @@ namespace OpenSim.Region.Framework.Scenes
1707 if (PhysicsShapeType == (byte)PhysShapeType.none) 2058 if (PhysicsShapeType == (byte)PhysShapeType.none)
1708 return; 2059 return;
1709 2060
1710 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 2061 bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0;
1711 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 2062 bool isPhantom = (_ObjectFlags & (uint)PrimFlags.Phantom) != 0;
1712 2063
1713 if (_VolumeDetectActive) 2064 if (_VolumeDetectActive)
1714 isPhantom = true; 2065 isPhantom = true;
@@ -1722,7 +2073,8 @@ namespace OpenSim.Region.Framework.Scenes
1722 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment 2073 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment
1723 && !(Shape.PathCurve == (byte)Extrusion.Flexible)) 2074 && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1724 { 2075 {
1725 AddToPhysics(isPhysical, isPhantom, isPhysical); 2076 AddToPhysics(isPhysical, isPhantom, building, isPhysical);
2077 UpdatePhysicsSubscribedEvents(); // not sure if appliable here
1726 } 2078 }
1727 else 2079 else
1728 PhysActor = null; // just to be sure 2080 PhysActor = null; // just to be sure
@@ -1777,6 +2129,12 @@ namespace OpenSim.Region.Framework.Scenes
1777 dupe.Category = Category; 2129 dupe.Category = Category;
1778 dupe.m_rezzed = m_rezzed; 2130 dupe.m_rezzed = m_rezzed;
1779 2131
2132 dupe.m_UndoRedo = null;
2133 dupe.m_isSelected = false;
2134
2135 dupe.IgnoreUndoUpdate = false;
2136 dupe.Undoing = false;
2137
1780 dupe.m_inventory = new SceneObjectPartInventory(dupe); 2138 dupe.m_inventory = new SceneObjectPartInventory(dupe);
1781 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone(); 2139 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone();
1782 2140
@@ -1792,6 +2150,7 @@ namespace OpenSim.Region.Framework.Scenes
1792 2150
1793 // Move afterwards ResetIDs as it clears the localID 2151 // Move afterwards ResetIDs as it clears the localID
1794 dupe.LocalId = localID; 2152 dupe.LocalId = localID;
2153
1795 // 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.
1796 dupe.LastOwnerID = OwnerID; 2155 dupe.LastOwnerID = OwnerID;
1797 2156
@@ -1799,6 +2158,9 @@ namespace OpenSim.Region.Framework.Scenes
1799 Array.Copy(Shape.ExtraParams, extraP, extraP.Length); 2158 Array.Copy(Shape.ExtraParams, extraP, extraP.Length);
1800 dupe.Shape.ExtraParams = extraP; 2159 dupe.Shape.ExtraParams = extraP;
1801 2160
2161 // safeguard actual copy is done in sog.copy
2162 dupe.KeyframeMotion = null;
2163
1802 dupe.DynAttrs.CopyFrom(DynAttrs); 2164 dupe.DynAttrs.CopyFrom(DynAttrs);
1803 2165
1804 if (userExposed) 2166 if (userExposed)
@@ -1812,8 +2174,12 @@ namespace OpenSim.Region.Framework.Scenes
1812*/ 2174*/
1813 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 2175 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
1814 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 2176 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
2177// dupe.UpdatePhysicsSubscribedEvents(); // not sure...
1815 } 2178 }
1816 2179
2180 if (dupe.PhysActor != null)
2181 dupe.PhysActor.LocalID = localID;
2182
1817 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 2183 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1818 2184
1819// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); 2185// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
@@ -1832,10 +2198,10 @@ namespace OpenSim.Region.Framework.Scenes
1832 { 2198 {
1833 if (asset != null) 2199 if (asset != null)
1834 SculptTextureCallback(asset); 2200 SculptTextureCallback(asset);
1835 else 2201// else
1836 m_log.WarnFormat( 2202// m_log.WarnFormat(
1837 "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data", 2203// "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
1838 Name, UUID, id); 2204// Name, UUID, id);
1839 } 2205 }
1840*/ 2206*/
1841 /// <summary> 2207 /// <summary>
@@ -1934,6 +2300,7 @@ namespace OpenSim.Region.Framework.Scenes
1934 2300
1935 /// <summary> 2301 /// <summary>
1936 /// Do a physics propery update for this part. 2302 /// Do a physics propery update for this part.
2303 /// now also updates phantom and volume detector
1937 /// </summary> 2304 /// </summary>
1938 /// <param name="UsePhysics"></param> 2305 /// <param name="UsePhysics"></param>
1939 /// <param name="isNew"></param> 2306 /// <param name="isNew"></param>
@@ -1959,61 +2326,69 @@ namespace OpenSim.Region.Framework.Scenes
1959 { 2326 {
1960 if (pa.IsPhysical) // implies UsePhysics==false for this block 2327 if (pa.IsPhysical) // implies UsePhysics==false for this block
1961 { 2328 {
1962 if (!isNew) 2329 if (!isNew) // implies UsePhysics==false for this block
2330 {
1963 ParentGroup.Scene.RemovePhysicalPrim(1); 2331 ParentGroup.Scene.RemovePhysicalPrim(1);
1964 2332
1965 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 2333 Velocity = new Vector3(0, 0, 0);
1966 pa.OnOutOfBounds -= PhysicsOutOfBounds; 2334 Acceleration = new Vector3(0, 0, 0);
1967 pa.delink(); 2335 if (ParentGroup.RootPart == this)
2336 AngularVelocity = new Vector3(0, 0, 0);
1968 2337
1969 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 2338 if (pa.Phantom && !VolumeDetectActive)
1970 { 2339 {
1971 // destroy all joints connected to this now deactivated body 2340 RemoveFromPhysics();
1972 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); 2341 return;
1973 } 2342 }
1974 2343
1975 // stop client-side interpolation of all joint proxy objects that have just been deleted 2344 pa.IsPhysical = UsePhysics;
1976 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback, 2345 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1977 // which stops client-side interpolation of deactivated joint proxy objects. 2346 pa.OnOutOfBounds -= PhysicsOutOfBounds;
2347 pa.delink();
2348 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
2349 {
2350 // destroy all joints connected to this now deactivated body
2351 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa);
2352 }
2353 }
1978 } 2354 }
1979 2355
1980 if (!UsePhysics && !isNew) 2356 if (pa.IsPhysical != UsePhysics)
1981 { 2357 pa.IsPhysical = UsePhysics;
1982 // reset velocity to 0 on physics switch-off. Without that, the client thinks the
1983 // prim still has velocity and continues to interpolate its position along the old
1984 // velocity-vector.
1985 Velocity = new Vector3(0, 0, 0);
1986 Acceleration = new Vector3(0, 0, 0);
1987 AngularVelocity = new Vector3(0, 0, 0);
1988 //RotationalVelocity = new Vector3(0, 0, 0);
1989 }
1990 2358
1991 pa.IsPhysical = UsePhysics; 2359 if (UsePhysics)
2360 {
2361 if (ParentGroup.RootPart.KeyframeMotion != null)
2362 ParentGroup.RootPart.KeyframeMotion.Stop();
2363 ParentGroup.RootPart.KeyframeMotion = null;
2364 ParentGroup.Scene.AddPhysicalPrim(1);
1992 2365
1993 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 2366 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1994 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 2367 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1995 /// that's not wholesome. Had to make Scene public
1996 //PhysActor = null;
1997 2368
1998 if ((Flags & PrimFlags.Phantom) == 0) 2369 if (ParentID != 0 && ParentID != LocalId)
1999 {
2000 if (UsePhysics)
2001 { 2370 {
2002 ParentGroup.Scene.AddPhysicalPrim(1); 2371 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
2003 2372
2004 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 2373 if (parentPa != null)
2005 pa.OnOutOfBounds += PhysicsOutOfBounds;
2006 if (ParentID != 0 && ParentID != LocalId)
2007 { 2374 {
2008 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; 2375 pa.link(parentPa);
2009
2010 if (parentPa != null)
2011 {
2012 pa.link(parentPa);
2013 }
2014 } 2376 }
2015 } 2377 }
2016 } 2378 }
2379 }
2380
2381 bool phan = ((Flags & PrimFlags.Phantom) != 0);
2382 if (pa.Phantom != phan)
2383 pa.Phantom = phan;
2384
2385// some engines dont' have this check still
2386// if (VolumeDetectActive != pa.IsVolumeDtc)
2387 {
2388 if (VolumeDetectActive)
2389 pa.SetVolumeDetect(1);
2390 else
2391 pa.SetVolumeDetect(0);
2017 } 2392 }
2018 2393
2019 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 2394 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
@@ -2132,42 +2507,63 @@ namespace OpenSim.Region.Framework.Scenes
2132 2507
2133 public Vector3 GetGeometricCenter() 2508 public Vector3 GetGeometricCenter()
2134 { 2509 {
2510 // this is not real geometric center but a average of positions relative to root prim acording to
2511 // http://wiki.secondlife.com/wiki/llGetGeometricCenter
2512 // ignoring tortured prims details since sl also seems to ignore
2513 // so no real use in doing it on physics
2514 if (ParentGroup.IsDeleted)
2515 return new Vector3(0, 0, 0);
2516
2517 return ParentGroup.GetGeometricCenter();
2518 }
2519
2520 public float GetMass()
2521 {
2135 PhysicsActor pa = PhysActor; 2522 PhysicsActor pa = PhysActor;
2136 2523
2137 if (pa != null) 2524 if (pa != null)
2138 return new Vector3(pa.GeometricCenter.X, pa.GeometricCenter.Y, pa.GeometricCenter.Z); 2525 return pa.Mass;
2139 else 2526 else
2140 return new Vector3(0, 0, 0); 2527 return 0;
2141 } 2528 }
2142 2529
2143 public Vector3 GetCenterOfMass() 2530 public Vector3 GetCenterOfMass()
2144 { 2531 {
2532 if (ParentGroup.RootPart == this)
2533 {
2534 if (ParentGroup.IsDeleted)
2535 return AbsolutePosition;
2536 return ParentGroup.GetCenterOfMass();
2537 }
2538
2145 PhysicsActor pa = PhysActor; 2539 PhysicsActor pa = PhysActor;
2146 2540
2147 if (pa != null) 2541 if (pa != null)
2148 return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z); 2542 {
2543 Vector3 tmp = pa.CenterOfMass;
2544 return tmp;
2545 }
2149 else 2546 else
2150 return new Vector3(0, 0, 0); 2547 return AbsolutePosition;
2151 } 2548 }
2152 2549
2153 public float GetMass() 2550 public Vector3 GetPartCenterOfMass()
2154 { 2551 {
2155 PhysicsActor pa = PhysActor; 2552 PhysicsActor pa = PhysActor;
2156 2553
2157 if (pa != null) 2554 if (pa != null)
2158 return pa.Mass; 2555 {
2556 Vector3 tmp = pa.CenterOfMass;
2557 return tmp;
2558 }
2159 else 2559 else
2160 return 0; 2560 return AbsolutePosition;
2161 } 2561 }
2162 2562
2563
2163 public Vector3 GetForce() 2564 public Vector3 GetForce()
2164 { 2565 {
2165 PhysicsActor pa = PhysActor; 2566 return Force;
2166
2167 if (pa != null)
2168 return pa.Force;
2169 else
2170 return Vector3.Zero;
2171 } 2567 }
2172 2568
2173 /// <summary> 2569 /// <summary>
@@ -2382,15 +2778,25 @@ namespace OpenSim.Region.Framework.Scenes
2382 2778
2383 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify) 2779 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify)
2384 { 2780 {
2385 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0) 2781 bool sendToRoot = true;
2386 { 2782
2387 ColliderArgs LandCollidingMessage = new ColliderArgs(); 2783 ColliderArgs LandCollidingMessage = new ColliderArgs();
2388 List<DetectedObject> colliding = new List<DetectedObject>(); 2784 List<DetectedObject> colliding = new List<DetectedObject>();
2389 2785
2390 colliding.Add(CreateDetObjectForGround()); 2786 colliding.Add(CreateDetObjectForGround());
2391 LandCollidingMessage.Colliders = colliding; 2787 LandCollidingMessage.Colliders = colliding;
2392 2788
2789 if (Inventory.ContainsScripts())
2790 {
2791 if (!PassCollisions)
2792 sendToRoot = false;
2793 }
2794 if ((ScriptEvents & ev) != 0)
2393 notify(LocalId, LandCollidingMessage); 2795 notify(LocalId, LandCollidingMessage);
2796
2797 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0 && sendToRoot)
2798 {
2799 notify(ParentGroup.RootPart.LocalId, LandCollidingMessage);
2394 } 2800 }
2395 } 2801 }
2396 2802
@@ -2406,57 +2812,120 @@ namespace OpenSim.Region.Framework.Scenes
2406 List<uint> endedColliders = new List<uint>(); 2812 List<uint> endedColliders = new List<uint>();
2407 List<uint> startedColliders = new List<uint>(); 2813 List<uint> startedColliders = new List<uint>();
2408 2814
2409 // calculate things that started colliding this time 2815 if (collissionswith.Count == 0)
2410 // and build up list of colliders this time
2411 foreach (uint localid in collissionswith.Keys)
2412 { 2816 {
2413 thisHitColliders.Add(localid); 2817 if (m_lastColliders.Count == 0)
2414 if (!m_lastColliders.Contains(localid)) 2818 return; // nothing to do
2415 startedColliders.Add(localid);
2416 }
2417 2819
2418 // calculate things that ended colliding 2820 foreach (uint localID in m_lastColliders)
2419 foreach (uint localID in m_lastColliders) 2821 {
2420 {
2421 if (!thisHitColliders.Contains(localID))
2422 endedColliders.Add(localID); 2822 endedColliders.Add(localID);
2823 }
2824 m_lastColliders.Clear();
2423 } 2825 }
2424 2826
2425 //add the items that started colliding this time to the last colliders list. 2827 else
2426 foreach (uint localID in startedColliders) 2828 {
2427 m_lastColliders.Add(localID); 2829 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
2428 2830
2429 // remove things that ended colliding from the last colliders list 2831 // calculate things that started colliding this time
2430 foreach (uint localID in endedColliders) 2832 // and build up list of colliders this time
2431 m_lastColliders.Remove(localID); 2833 if (!VolumeDetectActive && CollisionSoundType >= 0)
2834 {
2835 CollisionForSoundInfo soundinfo;
2836 ContactPoint curcontact;
2432 2837
2433 // play the sound. 2838 foreach (uint id in collissionswith.Keys)
2434 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) 2839 {
2435 { 2840 thisHitColliders.Add(id);
2436 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>(); 2841 if (!m_lastColliders.Contains(id))
2437 if (soundModule != null) 2842 {
2843 startedColliders.Add(id);
2844
2845 curcontact = collissionswith[id];
2846 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
2847 {
2848 soundinfo = new CollisionForSoundInfo();
2849 soundinfo.colliderID = id;
2850 soundinfo.position = curcontact.Position;
2851 soundinfo.relativeVel = curcontact.RelativeSpeed;
2852 soundinfolist.Add(soundinfo);
2853 }
2854 }
2855 }
2856 }
2857 else
2858 {
2859 foreach (uint id in collissionswith.Keys)
2860 {
2861 thisHitColliders.Add(id);
2862 if (!m_lastColliders.Contains(id))
2863 startedColliders.Add(id);
2864 }
2865 }
2866
2867 // calculate things that ended colliding
2868 foreach (uint localID in m_lastColliders)
2438 { 2869 {
2439 soundModule.SendSound(UUID, CollisionSound, 2870 if (!thisHitColliders.Contains(localID))
2440 CollisionSoundVolume, true, (byte)0, 0, false, 2871 endedColliders.Add(localID);
2441 false);
2442 } 2872 }
2873
2874 //add the items that started colliding this time to the last colliders list.
2875 foreach (uint localID in startedColliders)
2876 m_lastColliders.Add(localID);
2877
2878 // remove things that ended colliding from the last colliders list
2879 foreach (uint localID in endedColliders)
2880 m_lastColliders.Remove(localID);
2881
2882 // play sounds.
2883 if (soundinfolist.Count > 0)
2884 CollisionSounds.PartCollisionSound(this, soundinfolist);
2443 } 2885 }
2444 2886
2445 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart); 2887 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
2446 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding); 2888 if (!VolumeDetectActive)
2889 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
2447 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); 2890 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
2448 2891
2449 if (startedColliders.Contains(0)) 2892 if (startedColliders.Contains(0))
2450 { 2893 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2451 if (m_lastColliders.Contains(0)) 2894 if (m_lastColliders.Contains(0))
2452 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding); 2895 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding);
2453 else
2454 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2455 }
2456 if (endedColliders.Contains(0)) 2896 if (endedColliders.Contains(0))
2457 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); 2897 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2458 } 2898 }
2459 2899
2900 // The Collision sounds code calls this
2901 public void SendCollisionSound(UUID soundID, double volume, Vector3 position)
2902 {
2903 if (soundID == UUID.Zero)
2904 return;
2905
2906 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>();
2907 if (soundModule == null)
2908 return;
2909
2910 if (volume > 1)
2911 volume = 1;
2912 if (volume < 0)
2913 volume = 0;
2914
2915 int now = Util.EnvironmentTickCount();
2916 if(Util.EnvironmentTickCountSubtract(now,LastColSoundSentTime) <200)
2917 return;
2918
2919 LastColSoundSentTime = now;
2920
2921 UUID ownerID = OwnerID;
2922 UUID objectID = ParentGroup.RootPart.UUID;
2923 UUID parentID = ParentGroup.UUID;
2924 ulong regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle;
2925
2926 soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, 0 );
2927 }
2928
2460 public void PhysicsOutOfBounds(Vector3 pos) 2929 public void PhysicsOutOfBounds(Vector3 pos)
2461 { 2930 {
2462 // Note: This is only being called on the root prim at this time. 2931 // Note: This is only being called on the root prim at this time.
@@ -2478,9 +2947,9 @@ namespace OpenSim.Region.Framework.Scenes
2478 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2947 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2479 2948
2480 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2949 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2481 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2950 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2482 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2951 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2483 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2952 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2484 { 2953 {
2485 ParentGroup.AbsolutePosition = newpos; 2954 ParentGroup.AbsolutePosition = newpos;
2486 return; 2955 return;
@@ -2765,6 +3234,14 @@ namespace OpenSim.Region.Framework.Scenes
2765 if (ParentGroup == null) 3234 if (ParentGroup == null)
2766 return; 3235 return;
2767 3236
3237 // Update the "last" values
3238 m_lastPosition = OffsetPosition;
3239 m_lastRotation = RotationOffset;
3240 m_lastVelocity = Velocity;
3241 m_lastAcceleration = Acceleration;
3242 m_lastAngularVelocity = AngularVelocity;
3243 m_lastUpdateSentTime = Environment.TickCount;
3244
2768 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3245 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
2769 { 3246 {
2770 SendFullUpdate(avatar.ControllingClient); 3247 SendFullUpdate(avatar.ControllingClient);
@@ -2823,8 +3300,8 @@ namespace OpenSim.Region.Framework.Scenes
2823 { 3300 {
2824 const float ROTATION_TOLERANCE = 0.01f; 3301 const float ROTATION_TOLERANCE = 0.01f;
2825 const float VELOCITY_TOLERANCE = 0.001f; 3302 const float VELOCITY_TOLERANCE = 0.001f;
2826 const float POSITION_TOLERANCE = 0.05f; 3303 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2827 const int TIME_MS_TOLERANCE = 3000; 3304 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2828 3305
2829 switch (UpdateFlag) 3306 switch (UpdateFlag)
2830 { 3307 {
@@ -2838,17 +3315,10 @@ namespace OpenSim.Region.Framework.Scenes
2838 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || 3315 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) ||
2839 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || 3316 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) ||
2840 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 3317 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
2841 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 3318 Environment.TickCount - m_lastUpdateSentTime > TIME_MS_TOLERANCE)
2842 { 3319 {
2843 SendTerseUpdateToAllClients(); 3320 SendTerseUpdateToAllClients();
2844 3321
2845 // Update the "last" values
2846 m_lastPosition = OffsetPosition;
2847 m_lastRotation = RotationOffset;
2848 m_lastVelocity = Velocity;
2849 m_lastAcceleration = Acceleration;
2850 m_lastAngularVelocity = AngularVelocity;
2851 m_lastTerseSent = Environment.TickCount;
2852 } 3322 }
2853 break; 3323 break;
2854 } 3324 }
@@ -2866,6 +3336,17 @@ namespace OpenSim.Region.Framework.Scenes
2866 /// </summary> 3336 /// </summary>
2867 public void SendTerseUpdateToAllClients() 3337 public void SendTerseUpdateToAllClients()
2868 { 3338 {
3339 if (ParentGroup == null || ParentGroup.Scene == null)
3340 return;
3341
3342 // Update the "last" values
3343 m_lastPosition = OffsetPosition;
3344 m_lastRotation = RotationOffset;
3345 m_lastVelocity = Velocity;
3346 m_lastAcceleration = Acceleration;
3347 m_lastAngularVelocity = AngularVelocity;
3348 m_lastUpdateSentTime = Environment.TickCount;
3349
2869 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3350 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
2870 { 3351 {
2871 SendTerseUpdateToClient(client); 3352 SendTerseUpdateToClient(client);
@@ -2889,10 +3370,13 @@ namespace OpenSim.Region.Framework.Scenes
2889 3370
2890 public void SetBuoyancy(float fvalue) 3371 public void SetBuoyancy(float fvalue)
2891 { 3372 {
2892 PhysicsActor pa = PhysActor; 3373 Buoyancy = fvalue;
2893 3374/*
2894 if (pa != null) 3375 if (PhysActor != null)
2895 pa.Buoyancy = fvalue; 3376 {
3377 PhysActor.Buoyancy = fvalue;
3378 }
3379 */
2896 } 3380 }
2897 3381
2898 public void SetDieAtEdge(bool p) 3382 public void SetDieAtEdge(bool p)
@@ -2908,47 +3392,111 @@ namespace OpenSim.Region.Framework.Scenes
2908 PhysicsActor pa = PhysActor; 3392 PhysicsActor pa = PhysActor;
2909 3393
2910 if (pa != null) 3394 if (pa != null)
2911 pa.FloatOnWater = floatYN == 1; 3395 pa.FloatOnWater = (floatYN == 1);
2912 } 3396 }
2913 3397
2914 public void SetForce(Vector3 force) 3398 public void SetForce(Vector3 force)
2915 { 3399 {
2916 PhysicsActor pa = PhysActor; 3400 Force = force;
3401 }
2917 3402
2918 if (pa != null) 3403 public SOPVehicle VehicleParams
2919 pa.Force = force; 3404 {
3405 get
3406 {
3407 return m_vehicleParams;
3408 }
3409 set
3410 {
3411 m_vehicleParams = value;
3412 }
3413 }
3414
3415
3416 public int VehicleType
3417 {
3418 get
3419 {
3420 if (m_vehicleParams == null)
3421 return (int)Vehicle.TYPE_NONE;
3422 else
3423 return (int)m_vehicleParams.Type;
3424 }
3425 set
3426 {
3427 SetVehicleType(value);
3428 }
2920 } 3429 }
2921 3430
2922 public void SetVehicleType(int type) 3431 public void SetVehicleType(int type)
2923 { 3432 {
2924 PhysicsActor pa = PhysActor; 3433 m_vehicleParams = null;
3434
3435 if (type == (int)Vehicle.TYPE_NONE)
3436 {
3437 if (_parentID ==0 && PhysActor != null)
3438 PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
3439 return;
3440 }
3441 m_vehicleParams = new SOPVehicle();
3442 m_vehicleParams.ProcessTypeChange((Vehicle)type);
3443 {
3444 if (_parentID ==0 && PhysActor != null)
3445 PhysActor.VehicleType = type;
3446 return;
3447 }
3448 }
2925 3449
2926 if (pa != null) 3450 public void SetVehicleFlags(int param, bool remove)
2927 pa.VehicleType = type; 3451 {
3452 if (m_vehicleParams == null)
3453 return;
3454
3455 m_vehicleParams.ProcessVehicleFlags(param, remove);
3456
3457 if (_parentID ==0 && PhysActor != null)
3458 {
3459 PhysActor.VehicleFlags(param, remove);
3460 }
2928 } 3461 }
2929 3462
2930 public void SetVehicleFloatParam(int param, float value) 3463 public void SetVehicleFloatParam(int param, float value)
2931 { 3464 {
2932 PhysicsActor pa = PhysActor; 3465 if (m_vehicleParams == null)
3466 return;
2933 3467
2934 if (pa != null) 3468 m_vehicleParams.ProcessFloatVehicleParam((Vehicle)param, value);
2935 pa.VehicleFloatParam(param, value); 3469
3470 if (_parentID == 0 && PhysActor != null)
3471 {
3472 PhysActor.VehicleFloatParam(param, value);
3473 }
2936 } 3474 }
2937 3475
2938 public void SetVehicleVectorParam(int param, Vector3 value) 3476 public void SetVehicleVectorParam(int param, Vector3 value)
2939 { 3477 {
2940 PhysicsActor pa = PhysActor; 3478 if (m_vehicleParams == null)
3479 return;
2941 3480
2942 if (pa != null) 3481 m_vehicleParams.ProcessVectorVehicleParam((Vehicle)param, value);
2943 pa.VehicleVectorParam(param, value); 3482
3483 if (_parentID == 0 && PhysActor != null)
3484 {
3485 PhysActor.VehicleVectorParam(param, value);
3486 }
2944 } 3487 }
2945 3488
2946 public void SetVehicleRotationParam(int param, Quaternion rotation) 3489 public void SetVehicleRotationParam(int param, Quaternion rotation)
2947 { 3490 {
2948 PhysicsActor pa = PhysActor; 3491 if (m_vehicleParams == null)
3492 return;
2949 3493
2950 if (pa != null) 3494 m_vehicleParams.ProcessRotationVehicleParam((Vehicle)param, rotation);
2951 pa.VehicleRotationParam(param, rotation); 3495
3496 if (_parentID == 0 && PhysActor != null)
3497 {
3498 PhysActor.VehicleRotationParam(param, rotation);
3499 }
2952 } 3500 }
2953 3501
2954 /// <summary> 3502 /// <summary>
@@ -3149,14 +3697,6 @@ namespace OpenSim.Region.Framework.Scenes
3149 hasProfileCut = hasDimple; // is it the same thing? 3697 hasProfileCut = hasDimple; // is it the same thing?
3150 } 3698 }
3151 3699
3152 public void SetVehicleFlags(int param, bool remove)
3153 {
3154 PhysicsActor pa = PhysActor;
3155
3156 if (pa != null)
3157 pa.VehicleFlags(param, remove);
3158 }
3159
3160 public void SetGroup(UUID groupID, IClientAPI client) 3700 public void SetGroup(UUID groupID, IClientAPI client)
3161 { 3701 {
3162 // Scene.AddNewPrims() calls with client == null so can't use this. 3702 // Scene.AddNewPrims() calls with client == null so can't use this.
@@ -3256,71 +3796,20 @@ namespace OpenSim.Region.Framework.Scenes
3256 { 3796 {
3257 ParentGroup.stopMoveToTarget(); 3797 ParentGroup.stopMoveToTarget();
3258 3798
3259 ParentGroup.ScheduleGroupForTerseUpdate(); 3799// ParentGroup.ScheduleGroupForTerseUpdate();
3260 //ParentGroup.ScheduleGroupForFullUpdate(); 3800 //ParentGroup.ScheduleGroupForFullUpdate();
3261 } 3801 }
3262 3802
3263 public void StoreUndoState() 3803 public void StoreUndoState(ObjectChangeType change)
3264 { 3804 {
3265 StoreUndoState(false); 3805 if (m_UndoRedo == null)
3266 } 3806 m_UndoRedo = new UndoRedoState(5);
3267 3807
3268 public void StoreUndoState(bool forGroup) 3808 lock (m_UndoRedo)
3269 {
3270 if (ParentGroup == null || ParentGroup.Scene == null)
3271 return;
3272
3273 if (Undoing)
3274 {
3275// m_log.DebugFormat(
3276// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3277 return;
3278 }
3279
3280 if (IgnoreUndoUpdate)
3281 {
3282// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3283 return;
3284 }
3285
3286 lock (m_undo)
3287 { 3809 {
3288 if (m_undo.Count > 0) 3810 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3289 { 3811 {
3290 UndoState last = m_undo[m_undo.Count - 1]; 3812 m_UndoRedo.StoreUndo(this, change);
3291 if (last != null)
3292 {
3293 // TODO: May need to fix for group comparison
3294 if (last.Compare(this))
3295 {
3296// m_log.DebugFormat(
3297// "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3298// Name, LocalId, m_undo.Count);
3299
3300 return;
3301 }
3302 }
3303 }
3304
3305// m_log.DebugFormat(
3306// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3307// Name, LocalId, forGroup, m_undo.Count);
3308
3309 if (ParentGroup.Scene.MaxUndoCount > 0)
3310 {
3311 UndoState nUndo = new UndoState(this, forGroup);
3312
3313 m_undo.Add(nUndo);
3314
3315 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3316 m_undo.RemoveAt(0);
3317
3318 if (m_redo.Count > 0)
3319 m_redo.Clear();
3320
3321// m_log.DebugFormat(
3322// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3323// Name, LocalId, forGroup, m_undo.Count);
3324 } 3813 }
3325 } 3814 }
3326 } 3815 }
@@ -3332,88 +3821,46 @@ namespace OpenSim.Region.Framework.Scenes
3332 { 3821 {
3333 get 3822 get
3334 { 3823 {
3335 lock (m_undo) 3824 if (m_UndoRedo == null)
3336 return m_undo.Count; 3825 return 0;
3826 return m_UndoRedo.Count;
3337 } 3827 }
3338 } 3828 }
3339 3829
3340 public void Undo() 3830 public void Undo()
3341 { 3831 {
3342 lock (m_undo) 3832 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3343 { 3833 return;
3344// m_log.DebugFormat(
3345// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3346// Name, LocalId, m_undo.Count);
3347
3348 if (m_undo.Count > 0)
3349 {
3350 UndoState goback = m_undo[m_undo.Count - 1];
3351 m_undo.RemoveAt(m_undo.Count - 1);
3352
3353 UndoState nUndo = null;
3354
3355 if (ParentGroup.Scene.MaxUndoCount > 0)
3356 {
3357 nUndo = new UndoState(this, goback.ForGroup);
3358 }
3359
3360 goback.PlaybackState(this);
3361
3362 if (nUndo != null)
3363 {
3364 m_redo.Add(nUndo);
3365
3366 if (m_redo.Count > ParentGroup.Scene.MaxUndoCount)
3367 m_redo.RemoveAt(0);
3368 }
3369 }
3370 3834
3371// m_log.DebugFormat( 3835 lock (m_UndoRedo)
3372// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3836 {
3373// Name, LocalId, m_undo.Count); 3837 Undoing = true;
3838 m_UndoRedo.Undo(this);
3839 Undoing = false;
3374 } 3840 }
3375 } 3841 }
3376 3842
3377 public void Redo() 3843 public void Redo()
3378 { 3844 {
3379 lock (m_undo) 3845 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3380 { 3846 return;
3381// m_log.DebugFormat(
3382// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3383// Name, LocalId, m_redo.Count);
3384
3385 if (m_redo.Count > 0)
3386 {
3387 UndoState gofwd = m_redo[m_redo.Count - 1];
3388 m_redo.RemoveAt(m_redo.Count - 1);
3389
3390 if (ParentGroup.Scene.MaxUndoCount > 0)
3391 {
3392 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3393
3394 m_undo.Add(nUndo);
3395
3396 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3397 m_undo.RemoveAt(0);
3398 }
3399
3400 gofwd.PlayfwdState(this);
3401 3847
3402// m_log.DebugFormat( 3848 lock (m_UndoRedo)
3403// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3849 {
3404// Name, LocalId, m_redo.Count); 3850 Undoing = true;
3405 } 3851 m_UndoRedo.Redo(this);
3852 Undoing = false;
3406 } 3853 }
3407 } 3854 }
3408 3855
3409 public void ClearUndoState() 3856 public void ClearUndoState()
3410 { 3857 {
3411// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3858 if (m_UndoRedo == null || Undoing)
3859 return;
3412 3860
3413 lock (m_undo) 3861 lock (m_UndoRedo)
3414 { 3862 {
3415 m_undo.Clear(); 3863 m_UndoRedo.Clear();
3416 m_redo.Clear();
3417 } 3864 }
3418 } 3865 }
3419 3866
@@ -3964,7 +4411,7 @@ namespace OpenSim.Region.Framework.Scenes
3964 if (god) 4411 if (god)
3965 { 4412 {
3966 BaseMask = ApplyMask(BaseMask, set, mask); 4413 BaseMask = ApplyMask(BaseMask, set, mask);
3967 Inventory.ApplyGodPermissions(_baseMask); 4414 Inventory.ApplyGodPermissions(BaseMask);
3968 } 4415 }
3969 4416
3970 break; 4417 break;
@@ -3983,7 +4430,7 @@ namespace OpenSim.Region.Framework.Scenes
3983 case 16: 4430 case 16:
3984 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & 4431 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) &
3985 baseMask; 4432 baseMask;
3986 // Prevent the client from creating no mod, no copy 4433 // Prevent the client from creating no copy, no transfer
3987 // objects 4434 // objects
3988 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0) 4435 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0)
3989 NextOwnerMask |= (uint)PermissionMask.Transfer; 4436 NextOwnerMask |= (uint)PermissionMask.Transfer;
@@ -4001,20 +4448,20 @@ namespace OpenSim.Region.Framework.Scenes
4001 { 4448 {
4002 bool update = false; 4449 bool update = false;
4003 4450
4004 if (BaseMask != source.BaseMask || 4451 uint prevOwnerMask = OwnerMask;
4005 OwnerMask != source.OwnerMask || 4452 uint prevGroupMask = GroupMask;
4006 GroupMask != source.GroupMask || 4453 uint prevEveryoneMask = EveryoneMask;
4007 EveryoneMask != source.EveryoneMask || 4454 uint prevNextOwnerMask = NextOwnerMask;
4008 NextOwnerMask != source.NextOwnerMask)
4009 update = true;
4010 4455
4011 BaseMask = source.BaseMask; 4456 OwnerMask = source.OwnerMask & BaseMask;
4012 OwnerMask = source.OwnerMask; 4457 GroupMask = source.GroupMask & BaseMask;
4013 GroupMask = source.GroupMask; 4458 EveryoneMask = source.EveryoneMask & BaseMask;
4014 EveryoneMask = source.EveryoneMask; 4459 NextOwnerMask = source.NextOwnerMask & BaseMask;
4015 NextOwnerMask = source.NextOwnerMask;
4016 4460
4017 if (update) 4461 if (OwnerMask != prevOwnerMask ||
4462 GroupMask != prevGroupMask ||
4463 EveryoneMask != prevEveryoneMask ||
4464 NextOwnerMask != prevNextOwnerMask)
4018 SendFullUpdateToAllClients(); 4465 SendFullUpdateToAllClients();
4019 } 4466 }
4020 4467
@@ -4065,6 +4512,7 @@ namespace OpenSim.Region.Framework.Scenes
4065 } 4512 }
4066 } 4513 }
4067 4514
4515
4068 public void UpdateExtraPhysics(ExtraPhysicsData physdata) 4516 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4069 { 4517 {
4070 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null) 4518 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
@@ -4092,7 +4540,7 @@ namespace OpenSim.Region.Framework.Scenes
4092 /// <param name="SetTemporary"></param> 4540 /// <param name="SetTemporary"></param>
4093 /// <param name="SetPhantom"></param> 4541 /// <param name="SetPhantom"></param>
4094 /// <param name="SetVD"></param> 4542 /// <param name="SetVD"></param>
4095 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) 4543 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
4096 { 4544 {
4097 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4545 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4098 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4546 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4102,116 +4550,98 @@ namespace OpenSim.Region.Framework.Scenes
4102 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4550 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4103 return; 4551 return;
4104 4552
4105 PhysicsActor pa = PhysActor; 4553 VolumeDetectActive = SetVD;
4106
4107 // Special cases for VD. VD can only be called from a script
4108 // and can't be combined with changes to other states. So we can rely
4109 // that...
4110 // ... if VD is changed, all others are not.
4111 // ... if one of the others is changed, VD is not.
4112 if (SetVD) // VD is active, special logic applies
4113 {
4114 // State machine logic for VolumeDetect
4115 // More logic below
4116 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4117
4118 if (phanReset) // Phantom changes from on to off switch VD off too
4119 {
4120 SetVD = false; // Switch it of for the course of this routine
4121 VolumeDetectActive = false; // and also permanently
4122
4123 if (pa != null)
4124 pa.SetVolumeDetect(0); // Let physics know about it too
4125 }
4126 else
4127 {
4128 // If volumedetect is active we don't want phantom to be applied.
4129 // If this is a new call to VD out of the state "phantom"
4130 // this will also cause the prim to be visible to physics
4131 SetPhantom = false;
4132 }
4133 }
4134 4554
4135 if (UsePhysics && IsJoint()) 4555 // volume detector implies phantom
4136 { 4556 if (VolumeDetectActive)
4137 SetPhantom = true; 4557 SetPhantom = true;
4138 }
4139 4558
4140 if (UsePhysics) 4559 if (UsePhysics)
4141 {
4142 AddFlag(PrimFlags.Physics); 4560 AddFlag(PrimFlags.Physics);
4143 if (!wasUsingPhysics)
4144 {
4145 DoPhysicsPropertyUpdate(UsePhysics, false);
4146 }
4147 }
4148 else 4561 else
4149 {
4150 RemFlag(PrimFlags.Physics); 4562 RemFlag(PrimFlags.Physics);
4151 if (wasUsingPhysics)
4152 {
4153 DoPhysicsPropertyUpdate(UsePhysics, false);
4154 }
4155 }
4156 4563
4157 if (SetPhantom 4564 if (SetPhantom)
4158 || ParentGroup.IsAttachment
4159 || PhysicsShapeType == (byte)PhysShapeType.none
4160 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4161 {
4162 AddFlag(PrimFlags.Phantom); 4565 AddFlag(PrimFlags.Phantom);
4566 else
4567 RemFlag(PrimFlags.Phantom);
4163 4568
4164 if (PhysActor != null) 4569 if (SetTemporary)
4570 AddFlag(PrimFlags.TemporaryOnRez);
4571 else
4572 RemFlag(PrimFlags.TemporaryOnRez);
4573
4574
4575 if (ParentGroup.Scene == null)
4576 return;
4577
4578 PhysicsActor pa = PhysActor;
4579
4580 if (pa != null && building && pa.Building != building)
4581 pa.Building = building;
4582
4583 if ((SetPhantom && !UsePhysics && !SetVD) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
4584 || (Shape.PathCurve == (byte)Extrusion.Flexible))
4585 {
4586 if (pa != null)
4165 { 4587 {
4588 if(wasUsingPhysics)
4589 ParentGroup.Scene.RemovePhysicalPrim(1);
4166 RemoveFromPhysics(); 4590 RemoveFromPhysics();
4167 pa = null;
4168 } 4591 }
4592
4593 Velocity = new Vector3(0, 0, 0);
4594 Acceleration = new Vector3(0, 0, 0);
4595 if (ParentGroup.RootPart == this)
4596 AngularVelocity = new Vector3(0, 0, 0);
4169 } 4597 }
4170 else // Not phantom 4598
4599 else
4171 { 4600 {
4172 RemFlag(PrimFlags.Phantom); 4601 if (ParentGroup.Scene.CollidablePrims)
4173
4174 if (ParentGroup.Scene == null)
4175 return;
4176
4177 if (ParentGroup.Scene.CollidablePrims && pa == null)
4178 { 4602 {
4179 AddToPhysics(UsePhysics, SetPhantom, false); 4603 if (pa == null)
4180 pa = PhysActor;
4181
4182
4183 if (pa != null)
4184 { 4604 {
4185 pa.SetMaterial(Material); 4605 AddToPhysics(UsePhysics, SetPhantom, building, false);
4186 DoPhysicsPropertyUpdate(UsePhysics, true); 4606 pa = PhysActor;
4187 4607/*
4188 if ( 4608 if (pa != null)
4189 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4190 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4191 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4192 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4193 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4194 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4195 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4196 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4197 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4198 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4199 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4200 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4201 (CollisionSound != UUID.Zero)
4202 )
4203 { 4609 {
4204 pa.OnCollisionUpdate += PhysicsCollision; 4610 if (
4205 pa.SubscribeEvents(1000); 4611// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4612// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4613// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4614// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4615// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4616// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4617 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4618 ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4619 (CollisionSound != UUID.Zero)
4620 )
4621 {
4622 pa.OnCollisionUpdate += PhysicsCollision;
4623 pa.SubscribeEvents(1000);
4624 }
4206 } 4625 }
4626*/
4207 } 4627 }
4208 } 4628 else // it already has a physical representation
4209 else // it already has a physical representation 4629 {
4210 { 4630 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4211 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim 4631/* moved into DoPhysicsPropertyUpdate
4212 } 4632 if(VolumeDetectActive)
4213 } 4633 pa.SetVolumeDetect(1);
4634 else
4635 pa.SetVolumeDetect(0);
4636*/
4214 4637
4638 if (pa.Building != building)
4639 pa.Building = building;
4640 }
4641
4642 UpdatePhysicsSubscribedEvents();
4643 }
4644 }
4215 if (SetVD) 4645 if (SetVD)
4216 { 4646 {
4217 // If the above logic worked (this is urgent candidate to unit tests!) 4647 // If the above logic worked (this is urgent candidate to unit tests!)
@@ -4225,6 +4655,7 @@ namespace OpenSim.Region.Framework.Scenes
4225 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active 4655 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4226 VolumeDetectActive = true; 4656 VolumeDetectActive = true;
4227 } 4657 }
4658 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4228 } 4659 }
4229 else if (SetVD != wasVD) 4660 else if (SetVD != wasVD)
4230 { 4661 {
@@ -4236,61 +4667,51 @@ namespace OpenSim.Region.Framework.Scenes
4236 RemFlag(PrimFlags.Phantom); 4667 RemFlag(PrimFlags.Phantom);
4237 VolumeDetectActive = false; 4668 VolumeDetectActive = false;
4238 } 4669 }
4239 4670 // and last in case we have a new actor and not building
4240 if (SetTemporary)
4241 {
4242 AddFlag(PrimFlags.TemporaryOnRez);
4243 }
4244 else
4245 {
4246 RemFlag(PrimFlags.TemporaryOnRez);
4247 }
4248
4249 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4250 4671
4251 if (ParentGroup != null) 4672 if (ParentGroup != null)
4252 { 4673 {
4253 ParentGroup.HasGroupChanged = true; 4674 ParentGroup.HasGroupChanged = true;
4254 ScheduleFullUpdate(); 4675 ScheduleFullUpdate();
4255 } 4676 }
4256 4677
4257// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); 4678// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4258 } 4679 }
4259 4680
4260 /// <summary> 4681 /// <summary>
4261 /// Adds this part to the physics scene. 4682 /// Adds this part to the physics scene.
4683 /// and sets the PhysActor property
4262 /// </summary> 4684 /// </summary>
4263 /// <remarks>This method also sets the PhysActor property.</remarks> 4685 /// <param name="isPhysical">Add this prim as physical.</param>
4264 /// <param name="rigidBody">Add this prim with a rigid body.</param> 4686 /// <param name="isPhantom">Add this prim as phantom.</param>
4265 /// <returns> 4687 /// <param name="building">tells physics to delay full construction of object</param>
4266 /// The physics actor. null if there was a failure. 4688 /// <param name="applyDynamics">applies velocities, force and torque</param>
4267 /// </returns> 4689 private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
4268 private void AddToPhysics(bool isPhysical, bool isPhantom, bool applyDynamics) 4690 {
4269 {
4270 PhysicsActor pa; 4691 PhysicsActor pa;
4271 4692
4272 Vector3 velocity = Velocity; 4693 Vector3 velocity = Velocity;
4273 Vector3 rotationalVelocity = AngularVelocity;; 4694 Vector3 rotationalVelocity = AngularVelocity;;
4274 4695
4275 try 4696 try
4276 { 4697 {
4277 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4698 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4278 string.Format("{0}/{1}", Name, UUID), 4699 string.Format("{0}/{1}", Name, UUID),
4279 Shape, 4700 Shape,
4280 AbsolutePosition, 4701 AbsolutePosition,
4281 Scale, 4702 Scale,
4282 GetWorldRotation(), 4703 GetWorldRotation(),
4283 isPhysical, 4704 isPhysical,
4284 isPhantom, 4705 isPhantom,
4285 PhysicsShapeType, 4706 PhysicsShapeType,
4286 m_localId); 4707 m_localId);
4287 } 4708 }
4288 catch (Exception e) 4709 catch (Exception e)
4289 { 4710 {
4290 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e); 4711 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e);
4291 pa = null; 4712 pa = null;
4292 } 4713 }
4293 4714
4294 if (pa != null) 4715 if (pa != null)
4295 { 4716 {
4296 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 4717 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
@@ -4303,11 +4724,21 @@ namespace OpenSim.Region.Framework.Scenes
4303 4724
4304 if (VolumeDetectActive) // change if not the default only 4725 if (VolumeDetectActive) // change if not the default only
4305 pa.SetVolumeDetect(1); 4726 pa.SetVolumeDetect(1);
4727
4728 if (m_vehicleParams != null && LocalId == ParentGroup.RootPart.LocalId)
4729 m_vehicleParams.SetVehicle(pa);
4730
4306 // we are going to tell rest of code about physics so better have this here 4731 // we are going to tell rest of code about physics so better have this here
4307 PhysActor = pa; 4732 PhysActor = pa;
4308 4733
4734 // DoPhysicsPropertyUpdate(isPhysical, true);
4735 // lets expand it here just with what it really needs to do
4736
4309 if (isPhysical) 4737 if (isPhysical)
4310 { 4738 {
4739 if (ParentGroup.RootPart.KeyframeMotion != null)
4740 ParentGroup.RootPart.KeyframeMotion.Stop();
4741 ParentGroup.RootPart.KeyframeMotion = null;
4311 ParentGroup.Scene.AddPhysicalPrim(1); 4742 ParentGroup.Scene.AddPhysicalPrim(1);
4312 4743
4313 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 4744 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
@@ -4324,19 +4755,34 @@ namespace OpenSim.Region.Framework.Scenes
4324 } 4755 }
4325 } 4756 }
4326 4757
4327 if (applyDynamics) 4758 if (applyDynamics)
4328 // do independent of isphysical so parameters get setted (at least some) 4759 // do independent of isphysical so parameters get setted (at least some)
4329 { 4760 {
4330 Velocity = velocity; 4761 Velocity = velocity;
4331 AngularVelocity = rotationalVelocity; 4762 AngularVelocity = rotationalVelocity;
4332// pa.Velocity = velocity; 4763// pa.Velocity = velocity;
4333 pa.RotationalVelocity = rotationalVelocity; 4764 pa.RotationalVelocity = rotationalVelocity;
4765
4766 // if not vehicle and root part apply force and torque
4767 if ((m_vehicleParams == null || m_vehicleParams.Type == Vehicle.TYPE_NONE)
4768 && LocalId == ParentGroup.RootPart.LocalId)
4769 {
4770 pa.Force = Force;
4771 pa.Torque = Torque;
4772 }
4334 } 4773 }
4335 4774
4336 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); 4775// if (Shape.SculptEntry)
4776// CheckSculptAndLoad();
4777// else
4778 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
4779
4780 if (!building)
4781 pa.Building = false;
4337 } 4782 }
4338 4783
4339 PhysActor = pa; 4784 PhysActor = pa;
4785
4340 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this); 4786 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this);
4341 } 4787 }
4342 4788
@@ -4345,13 +4791,21 @@ namespace OpenSim.Region.Framework.Scenes
4345 /// </summary> 4791 /// </summary>
4346 /// <remarks> 4792 /// <remarks>
4347 /// This isn't the same as turning off physical, since even without being physical the prim has a physics 4793 /// This isn't the same as turning off physical, since even without being physical the prim has a physics
4348 /// representation for collision detection. Rather, this would be used in situations such as making a prim 4794 /// representation for collision detection.
4349 /// phantom.
4350 /// </remarks> 4795 /// </remarks>
4351 public void RemoveFromPhysics() 4796 public void RemoveFromPhysics()
4352 { 4797 {
4353 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this); 4798 PhysicsActor pa = PhysActor;
4354 ParentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 4799 if (pa != null)
4800 {
4801 pa.OnCollisionUpdate -= PhysicsCollision;
4802 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
4803 pa.OnOutOfBounds -= PhysicsOutOfBounds;
4804
4805 ParentGroup.Scene.PhysicsScene.RemovePrim(pa);
4806
4807 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this);
4808 }
4355 PhysActor = null; 4809 PhysActor = null;
4356 } 4810 }
4357 4811
@@ -4483,6 +4937,8 @@ namespace OpenSim.Region.Framework.Scenes
4483 { 4937 {
4484// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); 4938// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4485 4939
4940 return;
4941
4486 if (ParentGroup.IsDeleted) 4942 if (ParentGroup.IsDeleted)
4487 return; 4943 return;
4488 4944
@@ -4580,6 +5036,44 @@ namespace OpenSim.Region.Framework.Scenes
4580 ScheduleFullUpdate(); 5036 ScheduleFullUpdate();
4581 } 5037 }
4582 5038
5039
5040 private void UpdatePhysicsSubscribedEvents()
5041 {
5042 PhysicsActor pa = PhysActor;
5043 if (pa == null)
5044 return;
5045
5046 pa.OnCollisionUpdate -= PhysicsCollision;
5047
5048 bool hassound = (!VolumeDetectActive && CollisionSoundType >= 0 && ((Flags & PrimFlags.Physics) != 0));
5049
5050 scriptEvents CombinedEvents = AggregateScriptEvents;
5051
5052 // merge with root part
5053 if (ParentGroup != null && ParentGroup.RootPart != null)
5054 CombinedEvents |= ParentGroup.RootPart.AggregateScriptEvents;
5055
5056 // submit to this part case
5057 if (VolumeDetectActive)
5058 CombinedEvents &= PhyscicsVolumeDtcSubsEvents;
5059 else if ((Flags & PrimFlags.Phantom) != 0)
5060 CombinedEvents &= PhyscicsPhantonSubsEvents;
5061 else
5062 CombinedEvents &= PhysicsNeededSubsEvents;
5063
5064 if (hassound || CombinedEvents != 0)
5065 {
5066 // subscribe to physics updates.
5067 pa.OnCollisionUpdate += PhysicsCollision;
5068 pa.SubscribeEvents(50); // 20 reports per second
5069 }
5070 else
5071 {
5072 pa.UnSubscribeEvents();
5073 }
5074 }
5075
5076
4583 public void aggregateScriptEvents() 5077 public void aggregateScriptEvents()
4584 { 5078 {
4585 if (ParentGroup == null || ParentGroup.RootPart == null) 5079 if (ParentGroup == null || ParentGroup.RootPart == null)
@@ -4616,40 +5110,32 @@ namespace OpenSim.Region.Framework.Scenes
4616 { 5110 {
4617 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; 5111 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop;
4618 } 5112 }
4619 5113/*
4620 PhysicsActor pa = PhysActor; 5114 PhysicsActor pa = PhysActor;
4621 5115 if (pa != null)
4622 if (
4623 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4624 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4625 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4626 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4627 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4628 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4629 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4630 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4631 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4632 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4633 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4634 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4635 (CollisionSound != UUID.Zero)
4636 )
4637 { 5116 {
4638 // subscribe to physics updates. 5117 if (
4639 if (pa != null) 5118// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
5119// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
5120// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
5121// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5122// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5123// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5124 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5125 )
4640 { 5126 {
5127 // subscribe to physics updates.
4641 pa.OnCollisionUpdate += PhysicsCollision; 5128 pa.OnCollisionUpdate += PhysicsCollision;
4642 pa.SubscribeEvents(1000); 5129 pa.SubscribeEvents(1000);
4643 } 5130 }
4644 } 5131 else
4645 else
4646 {
4647 if (pa != null)
4648 { 5132 {
4649 pa.UnSubscribeEvents(); 5133 pa.UnSubscribeEvents();
4650 pa.OnCollisionUpdate -= PhysicsCollision; 5134 pa.OnCollisionUpdate -= PhysicsCollision;
4651 } 5135 }
4652 } 5136 }
5137 */
5138 UpdatePhysicsSubscribedEvents();
4653 5139
4654 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 5140 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4655 //{ 5141 //{
@@ -4780,6 +5266,18 @@ namespace OpenSim.Region.Framework.Scenes
4780 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 5266 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4781 } 5267 }
4782 5268
5269 public void ResetOwnerChangeFlag()
5270 {
5271 List<UUID> inv = Inventory.GetInventoryList();
5272
5273 foreach (UUID itemID in inv)
5274 {
5275 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
5276 item.OwnerChanged = false;
5277 Inventory.UpdateInventoryItem(item, false, false);
5278 }
5279 }
5280
4783 /// <summary> 5281 /// <summary>
4784 /// Record an avatar sitting on this part. 5282 /// Record an avatar sitting on this part.
4785 /// </summary> 5283 /// </summary>