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.cs1485
1 files changed, 990 insertions, 495 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index b3e6b67..66b42a1 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,15 +379,23 @@ 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 public KeyframeMotion KeyframeMotion 393 public KeyframeMotion KeyframeMotion
358 { 394 {
359 get; set; 395 get; set;
360 } 396 }
361 397
398
362 #endregion Fields 399 #endregion Fields
363 400
364// ~SceneObjectPart() 401// ~SceneObjectPart()
@@ -388,6 +425,7 @@ namespace OpenSim.Region.Framework.Scenes
388 // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from 425 // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from
389 // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log 426 // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log
390 m_inventory = new SceneObjectPartInventory(this); 427 m_inventory = new SceneObjectPartInventory(this);
428 LastColSoundSentTime = Util.EnvironmentTickCount();
391 } 429 }
392 430
393 /// <summary> 431 /// <summary>
@@ -402,7 +440,7 @@ namespace OpenSim.Region.Framework.Scenes
402 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 440 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
403 Quaternion rotationOffset, Vector3 offsetPosition) : this() 441 Quaternion rotationOffset, Vector3 offsetPosition) : this()
404 { 442 {
405 m_name = "Primitive"; 443 m_name = "Object";
406 444
407 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 445 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
408 LastOwnerID = CreatorID = OwnerID = ownerID; 446 LastOwnerID = CreatorID = OwnerID = ownerID;
@@ -441,7 +479,7 @@ namespace OpenSim.Region.Framework.Scenes
441 private uint _ownerMask = (uint)(PermissionMask.All | PermissionMask.Export); 479 private uint _ownerMask = (uint)(PermissionMask.All | PermissionMask.Export);
442 private uint _groupMask = (uint)PermissionMask.None; 480 private uint _groupMask = (uint)PermissionMask.None;
443 private uint _everyoneMask = (uint)PermissionMask.None; 481 private uint _everyoneMask = (uint)PermissionMask.None;
444 private uint _nextOwnerMask = (uint)PermissionMask.All; 482 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
445 private PrimFlags _flags = PrimFlags.None; 483 private PrimFlags _flags = PrimFlags.None;
446 private DateTime m_expires; 484 private DateTime m_expires;
447 private DateTime m_rezzed; 485 private DateTime m_rezzed;
@@ -539,12 +577,16 @@ namespace OpenSim.Region.Framework.Scenes
539 } 577 }
540 578
541 /// <value> 579 /// <value>
542 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 580 /// Get the inventory list
543 /// </value> 581 /// </value>
544 public TaskInventoryDictionary TaskInventory 582 public TaskInventoryDictionary TaskInventory
545 { 583 {
546 get { return m_inventory.Items; } 584 get {
547 set { m_inventory.Items = value; } 585 return m_inventory.Items;
586 }
587 set {
588 m_inventory.Items = value;
589 }
548 } 590 }
549 591
550 /// <summary> 592 /// <summary>
@@ -594,20 +636,6 @@ namespace OpenSim.Region.Framework.Scenes
594 } 636 }
595 } 637 }
596 638
597 public byte Material
598 {
599 get { return (byte) m_material; }
600 set
601 {
602 m_material = (Material)value;
603
604 PhysicsActor pa = PhysActor;
605
606 if (pa != null)
607 pa.SetMaterial((int)value);
608 }
609 }
610
611 [XmlIgnore] 639 [XmlIgnore]
612 public bool PassTouches 640 public bool PassTouches
613 { 641 {
@@ -633,6 +661,18 @@ namespace OpenSim.Region.Framework.Scenes
633 } 661 }
634 } 662 }
635 663
664 public bool IsSelected
665 {
666 get { return m_isSelected; }
667 set
668 {
669 m_isSelected = value;
670 if (ParentGroup != null)
671 ParentGroup.PartSelectChanged(value);
672 }
673 }
674
675
636 public Dictionary<int, string> CollisionFilter 676 public Dictionary<int, string> CollisionFilter
637 { 677 {
638 get { return m_CollisionFilter; } 678 get { return m_CollisionFilter; }
@@ -701,14 +741,12 @@ namespace OpenSim.Region.Framework.Scenes
701 set { m_LoopSoundSlavePrims = value; } 741 set { m_LoopSoundSlavePrims = value; }
702 } 742 }
703 743
704
705 public Byte[] TextureAnimation 744 public Byte[] TextureAnimation
706 { 745 {
707 get { return m_TextureAnimation; } 746 get { return m_TextureAnimation; }
708 set { m_TextureAnimation = value; } 747 set { m_TextureAnimation = value; }
709 } 748 }
710 749
711
712 public Byte[] ParticleSystem 750 public Byte[] ParticleSystem
713 { 751 {
714 get { return m_particleSystem; } 752 get { return m_particleSystem; }
@@ -745,9 +783,12 @@ namespace OpenSim.Region.Framework.Scenes
745 { 783 {
746 // If this is a linkset, we don't want the physics engine mucking up our group position here. 784 // If this is a linkset, we don't want the physics engine mucking up our group position here.
747 PhysicsActor actor = PhysActor; 785 PhysicsActor actor = PhysActor;
748 // If physical and the root prim of a linkset, the position of the group is what physics thinks. 786 if (ParentID == 0)
749 if (actor != null && ParentID == 0) 787 {
750 m_groupPosition = actor.Position; 788 if (actor != null)
789 m_groupPosition = actor.Position;
790 return m_groupPosition;
791 }
751 792
752 // If I'm an attachment, my position is reported as the position of who I'm attached to 793 // If I'm an attachment, my position is reported as the position of who I'm attached to
753 if (ParentGroup.IsAttachment) 794 if (ParentGroup.IsAttachment)
@@ -757,14 +798,16 @@ namespace OpenSim.Region.Framework.Scenes
757 return sp.AbsolutePosition; 798 return sp.AbsolutePosition;
758 } 799 }
759 800
801 // use root prim's group position. Physics may have updated it
802 if (ParentGroup.RootPart != this)
803 m_groupPosition = ParentGroup.RootPart.GroupPosition;
760 return m_groupPosition; 804 return m_groupPosition;
761 } 805 }
762 set 806 set
763 { 807 {
764 m_groupPosition = value; 808 m_groupPosition = value;
765
766 PhysicsActor actor = PhysActor; 809 PhysicsActor actor = PhysActor;
767 if (actor != null) 810 if (actor != null && ParentGroup.Scene.PhysicsScene != null)
768 { 811 {
769 try 812 try
770 { 813 {
@@ -789,16 +832,6 @@ namespace OpenSim.Region.Framework.Scenes
789 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e); 832 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e);
790 } 833 }
791 } 834 }
792
793 // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
794 if (SitTargetAvatar != UUID.Zero)
795 {
796 ScenePresence avatar;
797 if (ParentGroup.Scene.TryGetScenePresence(SitTargetAvatar, out avatar))
798 {
799 avatar.ParentPosition = GetWorldPosition();
800 }
801 }
802 } 835 }
803 } 836 }
804 837
@@ -807,7 +840,7 @@ namespace OpenSim.Region.Framework.Scenes
807 get { return m_offsetPosition; } 840 get { return m_offsetPosition; }
808 set 841 set
809 { 842 {
810// StoreUndoState(); 843 Vector3 oldpos = m_offsetPosition;
811 m_offsetPosition = value; 844 m_offsetPosition = value;
812 845
813 if (ParentGroup != null && !ParentGroup.IsDeleted) 846 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -819,10 +852,25 @@ namespace OpenSim.Region.Framework.Scenes
819 actor.Orientation = GetWorldRotation(); 852 actor.Orientation = GetWorldRotation();
820 853
821 // Tell the physics engines that this prim changed. 854 // Tell the physics engines that this prim changed.
822 if (ParentGroup.Scene != null) 855 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene != null)
823 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 856 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
824 } 857 }
858
859 if (!m_parentGroup.m_dupeInProgress)
860 {
861 List<ScenePresence> avs = ParentGroup.GetLinkedAvatars();
862 foreach (ScenePresence av in avs)
863 {
864 if (av.ParentID == m_localId)
865 {
866 Vector3 offset = (m_offsetPosition - oldpos);
867 av.AbsolutePosition += offset;
868 av.SendAvatarDataToAllAgents();
869 }
870 }
871 }
825 } 872 }
873 TriggerScriptChangedEvent(Changed.POSITION);
826 } 874 }
827 } 875 }
828 876
@@ -873,7 +921,7 @@ namespace OpenSim.Region.Framework.Scenes
873 921
874 set 922 set
875 { 923 {
876 StoreUndoState(); 924// StoreUndoState();
877 m_rotationOffset = value; 925 m_rotationOffset = value;
878 926
879 PhysicsActor actor = PhysActor; 927 PhysicsActor actor = PhysActor;
@@ -961,19 +1009,36 @@ namespace OpenSim.Region.Framework.Scenes
961 get 1009 get
962 { 1010 {
963 PhysicsActor actor = PhysActor; 1011 PhysicsActor actor = PhysActor;
964 if ((actor != null) && actor.IsPhysical) 1012 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
965 { 1013 {
966 m_angularVelocity = actor.RotationalVelocity; 1014 m_angularVelocity = actor.RotationalVelocity;
967 } 1015 }
968 return m_angularVelocity; 1016 return m_angularVelocity;
969 } 1017 }
970 set { m_angularVelocity = value; } 1018 set
1019 {
1020 m_angularVelocity = value;
1021 PhysicsActor actor = PhysActor;
1022 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this && VehicleType == (int)Vehicle.TYPE_NONE)
1023 {
1024 actor.RotationalVelocity = m_angularVelocity;
1025 }
1026 }
971 } 1027 }
972 1028
973 /// <summary></summary> 1029 /// <summary></summary>
974 public Vector3 Acceleration 1030 public Vector3 Acceleration
975 { 1031 {
976 get { return m_acceleration; } 1032 get
1033 {
1034 PhysicsActor actor = PhysActor;
1035 if (actor != null)
1036 {
1037 m_acceleration = actor.Acceleration;
1038 }
1039 return m_acceleration;
1040 }
1041
977 set { m_acceleration = value; } 1042 set { m_acceleration = value; }
978 } 1043 }
979 1044
@@ -1041,7 +1106,10 @@ namespace OpenSim.Region.Framework.Scenes
1041 public PrimitiveBaseShape Shape 1106 public PrimitiveBaseShape Shape
1042 { 1107 {
1043 get { return m_shape; } 1108 get { return m_shape; }
1044 set { m_shape = value;} 1109 set
1110 {
1111 m_shape = value;
1112 }
1045 } 1113 }
1046 1114
1047 /// <summary> 1115 /// <summary>
@@ -1054,7 +1122,6 @@ namespace OpenSim.Region.Framework.Scenes
1054 { 1122 {
1055 if (m_shape != null) 1123 if (m_shape != null)
1056 { 1124 {
1057 StoreUndoState();
1058 1125
1059 m_shape.Scale = value; 1126 m_shape.Scale = value;
1060 1127
@@ -1122,10 +1189,7 @@ namespace OpenSim.Region.Framework.Scenes
1122 { 1189 {
1123 get 1190 get
1124 { 1191 {
1125 if (ParentGroup.IsAttachment) 1192 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
1126 return GroupPosition;
1127
1128 return m_offsetPosition + m_groupPosition;
1129 } 1193 }
1130 } 1194 }
1131 1195
@@ -1294,6 +1358,13 @@ namespace OpenSim.Region.Framework.Scenes
1294 _flags = value; 1358 _flags = value;
1295 } 1359 }
1296 } 1360 }
1361
1362 [XmlIgnore]
1363 public bool IsOccupied // KF If an av is sittingon this prim
1364 {
1365 get { return m_occupied; }
1366 set { m_occupied = value; }
1367 }
1297 1368
1298 /// <summary> 1369 /// <summary>
1299 /// 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 1370 /// 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
@@ -1344,12 +1415,41 @@ namespace OpenSim.Region.Framework.Scenes
1344 set { m_sitAnimation = value; } 1415 set { m_sitAnimation = value; }
1345 } 1416 }
1346 1417
1418 public UUID invalidCollisionSoundUUID = new UUID("ffffffff-ffff-ffff-ffff-ffffffffffff");
1419
1420 // 0 for default collision sounds, -1 for script disabled sound 1 for script defined sound
1421 // runtime thing.. do not persist
1422 [XmlIgnore]
1423 public sbyte CollisionSoundType
1424 {
1425 get
1426 {
1427 return m_collisionSoundType;
1428 }
1429 set
1430 {
1431 m_collisionSoundType = value;
1432 if (value == -1)
1433 m_collisionSound = invalidCollisionSoundUUID;
1434 else if (value == 0)
1435 m_collisionSound = UUID.Zero;
1436 }
1437 }
1438
1347 public UUID CollisionSound 1439 public UUID CollisionSound
1348 { 1440 {
1349 get { return m_collisionSound; } 1441 get { return m_collisionSound; }
1350 set 1442 set
1351 { 1443 {
1352 m_collisionSound = value; 1444 m_collisionSound = value;
1445
1446 if (value == invalidCollisionSoundUUID)
1447 m_collisionSoundType = -1;
1448 else if (value == UUID.Zero)
1449 m_collisionSoundType = 0;
1450 else
1451 m_collisionSoundType = 1;
1452
1353 aggregateScriptEvents(); 1453 aggregateScriptEvents();
1354 } 1454 }
1355 } 1455 }
@@ -1360,6 +1460,125 @@ namespace OpenSim.Region.Framework.Scenes
1360 set { m_collisionSoundVolume = value; } 1460 set { m_collisionSoundVolume = value; }
1361 } 1461 }
1362 1462
1463 public float Buoyancy
1464 {
1465 get
1466 {
1467 if (ParentGroup.RootPart == this)
1468 return m_buoyancy;
1469
1470 return ParentGroup.RootPart.Buoyancy;
1471 }
1472 set
1473 {
1474 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1475 {
1476 ParentGroup.RootPart.Buoyancy = value;
1477 return;
1478 }
1479 m_buoyancy = value;
1480 if (PhysActor != null)
1481 PhysActor.Buoyancy = value;
1482 }
1483 }
1484
1485 public Vector3 Force
1486 {
1487 get
1488 {
1489 if (ParentGroup.RootPart == this)
1490 return m_force;
1491
1492 return ParentGroup.RootPart.Force;
1493 }
1494
1495 set
1496 {
1497 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1498 {
1499 ParentGroup.RootPart.Force = value;
1500 return;
1501 }
1502 m_force = value;
1503 if (PhysActor != null)
1504 PhysActor.Force = value;
1505 }
1506 }
1507
1508 public Vector3 Torque
1509 {
1510 get
1511 {
1512 if (ParentGroup.RootPart == this)
1513 return m_torque;
1514
1515 return ParentGroup.RootPart.Torque;
1516 }
1517
1518 set
1519 {
1520 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1521 {
1522 ParentGroup.RootPart.Torque = value;
1523 return;
1524 }
1525 m_torque = value;
1526 if (PhysActor != null)
1527 PhysActor.Torque = value;
1528 }
1529 }
1530
1531 public byte Material
1532 {
1533 get { return (byte)m_material; }
1534 set
1535 {
1536 if (value >= 0 && value <= (byte)SOPMaterialData.MaxMaterial)
1537 {
1538 bool update = false;
1539
1540 if (m_material != (Material)value)
1541 {
1542 update = true;
1543 m_material = (Material)value;
1544 }
1545
1546 if (m_friction != SOPMaterialData.friction(m_material))
1547 {
1548 update = true;
1549 m_friction = SOPMaterialData.friction(m_material);
1550 }
1551
1552 if (m_bounce != SOPMaterialData.bounce(m_material))
1553 {
1554 update = true;
1555 m_bounce = SOPMaterialData.bounce(m_material);
1556 }
1557
1558 if (update)
1559 {
1560 if (PhysActor != null)
1561 {
1562 PhysActor.SetMaterial((int)value);
1563 }
1564 if(ParentGroup != null)
1565 ParentGroup.HasGroupChanged = true;
1566 ScheduleFullUpdateIfNone();
1567 UpdatePhysRequired = true;
1568 }
1569 }
1570 }
1571 }
1572
1573 // not a propriety to move to methods place later
1574 private bool HasMesh()
1575 {
1576 if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh))
1577 return true;
1578 return false;
1579 }
1580
1581 // not a propriety to move to methods place later
1363 public byte DefaultPhysicsShapeType() 1582 public byte DefaultPhysicsShapeType()
1364 { 1583 {
1365 byte type; 1584 byte type;
@@ -1372,6 +1591,65 @@ namespace OpenSim.Region.Framework.Scenes
1372 return type; 1591 return type;
1373 } 1592 }
1374 1593
1594 [XmlIgnore]
1595 public bool UsesComplexCost
1596 {
1597 get
1598 {
1599 byte pst = PhysicsShapeType;
1600 if(pst == (byte) PhysShapeType.none || pst == (byte) PhysShapeType.convex || HasMesh())
1601 return true;
1602 return false;
1603 }
1604 }
1605
1606 [XmlIgnore]
1607 public float PhysicsCost
1608 {
1609 get
1610 {
1611 if(PhysicsShapeType == (byte)PhysShapeType.none)
1612 return 0;
1613
1614 float cost = 0.1f;
1615 if (PhysActor != null)
1616 cost = PhysActor.PhysicsCost;
1617 else
1618 cost = 0.1f;
1619
1620 if ((Flags & PrimFlags.Physics) != 0)
1621 cost *= (1.0f + 0.01333f * Scale.LengthSquared()); // 0.01333 == 0.04/3
1622 return cost;
1623 }
1624 }
1625
1626 [XmlIgnore]
1627 public float StreamingCost
1628 {
1629 get
1630 {
1631 float cost;
1632 if (PhysActor != null)
1633 cost = PhysActor.StreamCost;
1634 else
1635 cost = 1.0f;
1636 return 1.0f;
1637 }
1638 }
1639
1640 [XmlIgnore]
1641 public float SimulationCost
1642 {
1643 get
1644 {
1645 // ignoring scripts. Don't like considering them for this
1646 if((Flags & PrimFlags.Physics) != 0)
1647 return 1.0f;
1648
1649 return 0.5f;
1650 }
1651 }
1652
1375 public byte PhysicsShapeType 1653 public byte PhysicsShapeType
1376 { 1654 {
1377 get { return m_physicsShapeType; } 1655 get { return m_physicsShapeType; }
@@ -1405,11 +1683,14 @@ namespace OpenSim.Region.Framework.Scenes
1405 } 1683 }
1406 else if (PhysActor == null) 1684 else if (PhysActor == null)
1407 { 1685 {
1408 ApplyPhysics((uint)Flags, VolumeDetectActive); 1686 ApplyPhysics((uint)Flags, VolumeDetectActive, false);
1687 UpdatePhysicsSubscribedEvents();
1409 } 1688 }
1410 else 1689 else
1411 { 1690 {
1412 PhysActor.PhysicsShapeType = m_physicsShapeType; 1691 PhysActor.PhysicsShapeType = m_physicsShapeType;
1692// if (Shape.SculptEntry)
1693// CheckSculptAndLoad();
1413 } 1694 }
1414 1695
1415 if (ParentGroup != null) 1696 if (ParentGroup != null)
@@ -1511,6 +1792,7 @@ namespace OpenSim.Region.Framework.Scenes
1511 } 1792 }
1512 } 1793 }
1513 1794
1795
1514 #endregion Public Properties with only Get 1796 #endregion Public Properties with only Get
1515 1797
1516 private uint ApplyMask(uint val, bool set, uint mask) 1798 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1656,6 +1938,61 @@ namespace OpenSim.Region.Framework.Scenes
1656 } 1938 }
1657 } 1939 }
1658 1940
1941 // SetVelocity for LSL llSetVelocity.. may need revision if having other uses in future
1942 public void SetVelocity(Vector3 pVel, bool localGlobalTF)
1943 {
1944 if (ParentGroup == null || ParentGroup.IsDeleted)
1945 return;
1946
1947 if (ParentGroup.IsAttachment)
1948 return; // don't work on attachments (for now ??)
1949
1950 SceneObjectPart root = ParentGroup.RootPart;
1951
1952 if (root.VehicleType != (int)Vehicle.TYPE_NONE) // don't mess with vehicles
1953 return;
1954
1955 PhysicsActor pa = root.PhysActor;
1956
1957 if (pa == null || !pa.IsPhysical)
1958 return;
1959
1960 if (localGlobalTF)
1961 {
1962 pVel = pVel * GetWorldRotation();
1963 }
1964
1965 ParentGroup.Velocity = pVel;
1966 }
1967
1968 // SetAngularVelocity for LSL llSetAngularVelocity.. may need revision if having other uses in future
1969 public void SetAngularVelocity(Vector3 pAngVel, bool localGlobalTF)
1970 {
1971 if (ParentGroup == null || ParentGroup.IsDeleted)
1972 return;
1973
1974 if (ParentGroup.IsAttachment)
1975 return; // don't work on attachments (for now ??)
1976
1977 SceneObjectPart root = ParentGroup.RootPart;
1978
1979 if (root.VehicleType != (int)Vehicle.TYPE_NONE) // don't mess with vehicles
1980 return;
1981
1982 PhysicsActor pa = root.PhysActor;
1983
1984 if (pa == null || !pa.IsPhysical)
1985 return;
1986
1987 if (localGlobalTF)
1988 {
1989 pAngVel = pAngVel * GetWorldRotation();
1990 }
1991
1992 root.AngularVelocity = pAngVel;
1993 }
1994
1995
1659 /// <summary> 1996 /// <summary>
1660 /// hook to the physics scene to apply angular impulse 1997 /// hook to the physics scene to apply angular impulse
1661 /// This is sent up to the group, which then finds the root prim 1998 /// This is sent up to the group, which then finds the root prim
@@ -1676,7 +2013,7 @@ namespace OpenSim.Region.Framework.Scenes
1676 impulse = newimpulse; 2013 impulse = newimpulse;
1677 } 2014 }
1678 2015
1679 ParentGroup.applyAngularImpulse(impulse); 2016 ParentGroup.ApplyAngularImpulse(impulse);
1680 } 2017 }
1681 2018
1682 /// <summary> 2019 /// <summary>
@@ -1686,20 +2023,24 @@ namespace OpenSim.Region.Framework.Scenes
1686 /// </summary> 2023 /// </summary>
1687 /// <param name="impulsei">Vector force</param> 2024 /// <param name="impulsei">Vector force</param>
1688 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> 2025 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
1689 public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF) 2026
2027 // this is actualy Set Torque.. keeping naming so not to edit lslapi also
2028 public void SetAngularImpulse(Vector3 torquei, bool localGlobalTF)
1690 { 2029 {
1691 Vector3 impulse = impulsei; 2030 Vector3 torque = torquei;
1692 2031
1693 if (localGlobalTF) 2032 if (localGlobalTF)
1694 { 2033 {
2034/*
1695 Quaternion grot = GetWorldRotation(); 2035 Quaternion grot = GetWorldRotation();
1696 Quaternion AXgrot = grot; 2036 Quaternion AXgrot = grot;
1697 Vector3 AXimpulsei = impulsei; 2037 Vector3 AXimpulsei = impulsei;
1698 Vector3 newimpulse = AXimpulsei * AXgrot; 2038 Vector3 newimpulse = AXimpulsei * AXgrot;
1699 impulse = newimpulse; 2039 */
2040 torque *= GetWorldRotation();
1700 } 2041 }
1701 2042
1702 ParentGroup.setAngularImpulse(impulse); 2043 Torque = torque;
1703 } 2044 }
1704 2045
1705 /// <summary> 2046 /// <summary>
@@ -1707,7 +2048,9 @@ namespace OpenSim.Region.Framework.Scenes
1707 /// </summary> 2048 /// </summary>
1708 /// <param name="rootObjectFlags"></param> 2049 /// <param name="rootObjectFlags"></param>
1709 /// <param name="VolumeDetectActive"></param> 2050 /// <param name="VolumeDetectActive"></param>
1710 public void ApplyPhysics(uint rootObjectFlags, bool _VolumeDetectActive) 2051 /// <param name="building"></param>
2052
2053 public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building)
1711 { 2054 {
1712 VolumeDetectActive = _VolumeDetectActive; 2055 VolumeDetectActive = _VolumeDetectActive;
1713 2056
@@ -1717,8 +2060,8 @@ namespace OpenSim.Region.Framework.Scenes
1717 if (PhysicsShapeType == (byte)PhysShapeType.none) 2060 if (PhysicsShapeType == (byte)PhysShapeType.none)
1718 return; 2061 return;
1719 2062
1720 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 2063 bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0;
1721 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 2064 bool isPhantom = (_ObjectFlags & (uint)PrimFlags.Phantom) != 0;
1722 2065
1723 if (_VolumeDetectActive) 2066 if (_VolumeDetectActive)
1724 isPhantom = true; 2067 isPhantom = true;
@@ -1732,7 +2075,8 @@ namespace OpenSim.Region.Framework.Scenes
1732 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment 2075 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment
1733 && !(Shape.PathCurve == (byte)Extrusion.Flexible)) 2076 && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1734 { 2077 {
1735 AddToPhysics(isPhysical, isPhantom, isPhysical); 2078 AddToPhysics(isPhysical, isPhantom, building, isPhysical);
2079 UpdatePhysicsSubscribedEvents(); // not sure if appliable here
1736 } 2080 }
1737 else 2081 else
1738 PhysActor = null; // just to be sure 2082 PhysActor = null; // just to be sure
@@ -1787,6 +2131,12 @@ namespace OpenSim.Region.Framework.Scenes
1787 dupe.Category = Category; 2131 dupe.Category = Category;
1788 dupe.m_rezzed = m_rezzed; 2132 dupe.m_rezzed = m_rezzed;
1789 2133
2134 dupe.m_UndoRedo = null;
2135 dupe.m_isSelected = false;
2136
2137 dupe.IgnoreUndoUpdate = false;
2138 dupe.Undoing = false;
2139
1790 dupe.m_inventory = new SceneObjectPartInventory(dupe); 2140 dupe.m_inventory = new SceneObjectPartInventory(dupe);
1791 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone(); 2141 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone();
1792 2142
@@ -1802,6 +2152,7 @@ namespace OpenSim.Region.Framework.Scenes
1802 2152
1803 // Move afterwards ResetIDs as it clears the localID 2153 // Move afterwards ResetIDs as it clears the localID
1804 dupe.LocalId = localID; 2154 dupe.LocalId = localID;
2155
1805 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 2156 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1806 dupe.LastOwnerID = OwnerID; 2157 dupe.LastOwnerID = OwnerID;
1807 2158
@@ -1826,8 +2177,12 @@ namespace OpenSim.Region.Framework.Scenes
1826*/ 2177*/
1827 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 2178 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
1828 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 2179 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
2180// dupe.UpdatePhysicsSubscribedEvents(); // not sure...
1829 } 2181 }
1830 2182
2183 if (dupe.PhysActor != null)
2184 dupe.PhysActor.LocalID = localID;
2185
1831 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 2186 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1832 2187
1833// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); 2188// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
@@ -1846,10 +2201,10 @@ namespace OpenSim.Region.Framework.Scenes
1846 { 2201 {
1847 if (asset != null) 2202 if (asset != null)
1848 SculptTextureCallback(asset); 2203 SculptTextureCallback(asset);
1849 else 2204// else
1850 m_log.WarnFormat( 2205// m_log.WarnFormat(
1851 "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data", 2206// "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
1852 Name, UUID, id); 2207// Name, UUID, id);
1853 } 2208 }
1854*/ 2209*/
1855 /// <summary> 2210 /// <summary>
@@ -1948,6 +2303,7 @@ namespace OpenSim.Region.Framework.Scenes
1948 2303
1949 /// <summary> 2304 /// <summary>
1950 /// Do a physics propery update for this part. 2305 /// Do a physics propery update for this part.
2306 /// now also updates phantom and volume detector
1951 /// </summary> 2307 /// </summary>
1952 /// <param name="UsePhysics"></param> 2308 /// <param name="UsePhysics"></param>
1953 /// <param name="isNew"></param> 2309 /// <param name="isNew"></param>
@@ -1973,64 +2329,69 @@ namespace OpenSim.Region.Framework.Scenes
1973 { 2329 {
1974 if (pa.IsPhysical) // implies UsePhysics==false for this block 2330 if (pa.IsPhysical) // implies UsePhysics==false for this block
1975 { 2331 {
1976 if (!isNew) 2332 if (!isNew) // implies UsePhysics==false for this block
2333 {
1977 ParentGroup.Scene.RemovePhysicalPrim(1); 2334 ParentGroup.Scene.RemovePhysicalPrim(1);
1978 2335
1979 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 2336 Velocity = new Vector3(0, 0, 0);
1980 pa.OnOutOfBounds -= PhysicsOutOfBounds; 2337 Acceleration = new Vector3(0, 0, 0);
1981 pa.delink(); 2338 if (ParentGroup.RootPart == this)
2339 AngularVelocity = new Vector3(0, 0, 0);
1982 2340
1983 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 2341 if (pa.Phantom && !VolumeDetectActive)
1984 { 2342 {
1985 // destroy all joints connected to this now deactivated body 2343 RemoveFromPhysics();
1986 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); 2344 return;
1987 } 2345 }
1988 2346
1989 // stop client-side interpolation of all joint proxy objects that have just been deleted 2347 pa.IsPhysical = UsePhysics;
1990 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback, 2348 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1991 // which stops client-side interpolation of deactivated joint proxy objects. 2349 pa.OnOutOfBounds -= PhysicsOutOfBounds;
2350 pa.delink();
2351 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
2352 {
2353 // destroy all joints connected to this now deactivated body
2354 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa);
2355 }
2356 }
1992 } 2357 }
1993 2358
1994 if (!UsePhysics && !isNew) 2359 if (pa.IsPhysical != UsePhysics)
1995 { 2360 pa.IsPhysical = UsePhysics;
1996 // reset velocity to 0 on physics switch-off. Without that, the client thinks the
1997 // prim still has velocity and continues to interpolate its position along the old
1998 // velocity-vector.
1999 Velocity = new Vector3(0, 0, 0);
2000 Acceleration = new Vector3(0, 0, 0);
2001 AngularVelocity = new Vector3(0, 0, 0);
2002 //RotationalVelocity = new Vector3(0, 0, 0);
2003 }
2004 2361
2005 pa.IsPhysical = UsePhysics; 2362 if (UsePhysics)
2363 {
2364 if (ParentGroup.RootPart.KeyframeMotion != null)
2365 ParentGroup.RootPart.KeyframeMotion.Stop();
2366 ParentGroup.RootPart.KeyframeMotion = null;
2367 ParentGroup.Scene.AddPhysicalPrim(1);
2006 2368
2007 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 2369 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
2008 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 2370 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
2009 /// that's not wholesome. Had to make Scene public
2010 //PhysActor = null;
2011 2371
2012 if ((Flags & PrimFlags.Phantom) == 0) 2372 if (ParentID != 0 && ParentID != LocalId)
2013 {
2014 if (UsePhysics)
2015 { 2373 {
2016 if (ParentGroup.RootPart.KeyframeMotion != null) 2374 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
2017 ParentGroup.RootPart.KeyframeMotion.Stop();
2018 ParentGroup.RootPart.KeyframeMotion = null;
2019 ParentGroup.Scene.AddPhysicalPrim(1);
2020
2021 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
2022 pa.OnOutOfBounds += PhysicsOutOfBounds;
2023 if (ParentID != 0 && ParentID != LocalId)
2024 {
2025 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
2026 2375
2027 if (parentPa != null) 2376 if (parentPa != null)
2028 { 2377 {
2029 pa.link(parentPa); 2378 pa.link(parentPa);
2030 }
2031 } 2379 }
2032 } 2380 }
2033 } 2381 }
2382 }
2383
2384 bool phan = ((Flags & PrimFlags.Phantom) != 0);
2385 if (pa.Phantom != phan)
2386 pa.Phantom = phan;
2387
2388// some engines dont' have this check still
2389// if (VolumeDetectActive != pa.IsVolumeDtc)
2390 {
2391 if (VolumeDetectActive)
2392 pa.SetVolumeDetect(1);
2393 else
2394 pa.SetVolumeDetect(0);
2034 } 2395 }
2035 2396
2036 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 2397 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
@@ -2149,42 +2510,63 @@ namespace OpenSim.Region.Framework.Scenes
2149 2510
2150 public Vector3 GetGeometricCenter() 2511 public Vector3 GetGeometricCenter()
2151 { 2512 {
2513 // this is not real geometric center but a average of positions relative to root prim acording to
2514 // http://wiki.secondlife.com/wiki/llGetGeometricCenter
2515 // ignoring tortured prims details since sl also seems to ignore
2516 // so no real use in doing it on physics
2517 if (ParentGroup.IsDeleted)
2518 return new Vector3(0, 0, 0);
2519
2520 return ParentGroup.GetGeometricCenter();
2521 }
2522
2523 public float GetMass()
2524 {
2152 PhysicsActor pa = PhysActor; 2525 PhysicsActor pa = PhysActor;
2153 2526
2154 if (pa != null) 2527 if (pa != null)
2155 return pa.GeometricCenter; 2528 return pa.Mass;
2156 else 2529 else
2157 return Vector3.Zero; 2530 return 0;
2158 } 2531 }
2159 2532
2160 public Vector3 GetCenterOfMass() 2533 public Vector3 GetCenterOfMass()
2161 { 2534 {
2535 if (ParentGroup.RootPart == this)
2536 {
2537 if (ParentGroup.IsDeleted)
2538 return AbsolutePosition;
2539 return ParentGroup.GetCenterOfMass();
2540 }
2541
2162 PhysicsActor pa = PhysActor; 2542 PhysicsActor pa = PhysActor;
2163 2543
2164 if (pa != null) 2544 if (pa != null)
2165 return pa.CenterOfMass; 2545 {
2546 Vector3 tmp = pa.CenterOfMass;
2547 return tmp;
2548 }
2166 else 2549 else
2167 return Vector3.Zero; 2550 return AbsolutePosition;
2168 } 2551 }
2169 2552
2170 public float GetMass() 2553 public Vector3 GetPartCenterOfMass()
2171 { 2554 {
2172 PhysicsActor pa = PhysActor; 2555 PhysicsActor pa = PhysActor;
2173 2556
2174 if (pa != null) 2557 if (pa != null)
2175 return pa.Mass; 2558 {
2559 Vector3 tmp = pa.CenterOfMass;
2560 return tmp;
2561 }
2176 else 2562 else
2177 return 0; 2563 return AbsolutePosition;
2178 } 2564 }
2179 2565
2566
2180 public Vector3 GetForce() 2567 public Vector3 GetForce()
2181 { 2568 {
2182 PhysicsActor pa = PhysActor; 2569 return Force;
2183
2184 if (pa != null)
2185 return pa.Force;
2186 else
2187 return Vector3.Zero;
2188 } 2570 }
2189 2571
2190 /// <summary> 2572 /// <summary>
@@ -2399,15 +2781,25 @@ namespace OpenSim.Region.Framework.Scenes
2399 2781
2400 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify) 2782 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify)
2401 { 2783 {
2402 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0) 2784 bool sendToRoot = true;
2403 {
2404 ColliderArgs LandCollidingMessage = new ColliderArgs();
2405 List<DetectedObject> colliding = new List<DetectedObject>();
2406
2407 colliding.Add(CreateDetObjectForGround());
2408 LandCollidingMessage.Colliders = colliding;
2409 2785
2786 ColliderArgs LandCollidingMessage = new ColliderArgs();
2787 List<DetectedObject> colliding = new List<DetectedObject>();
2788
2789 colliding.Add(CreateDetObjectForGround());
2790 LandCollidingMessage.Colliders = colliding;
2791
2792 if (Inventory.ContainsScripts())
2793 {
2794 if (!PassCollisions)
2795 sendToRoot = false;
2796 }
2797 if ((ScriptEvents & ev) != 0)
2410 notify(LocalId, LandCollidingMessage); 2798 notify(LocalId, LandCollidingMessage);
2799
2800 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0 && sendToRoot)
2801 {
2802 notify(ParentGroup.RootPart.LocalId, LandCollidingMessage);
2411 } 2803 }
2412 } 2804 }
2413 2805
@@ -2423,44 +2815,81 @@ namespace OpenSim.Region.Framework.Scenes
2423 List<uint> endedColliders = new List<uint>(); 2815 List<uint> endedColliders = new List<uint>();
2424 List<uint> startedColliders = new List<uint>(); 2816 List<uint> startedColliders = new List<uint>();
2425 2817
2426 // calculate things that started colliding this time 2818 if (collissionswith.Count == 0)
2427 // and build up list of colliders this time
2428 foreach (uint localid in collissionswith.Keys)
2429 { 2819 {
2430 thisHitColliders.Add(localid); 2820 if (m_lastColliders.Count == 0)
2431 if (!m_lastColliders.Contains(localid)) 2821 return; // nothing to do
2432 startedColliders.Add(localid);
2433 }
2434 2822
2435 // calculate things that ended colliding 2823 foreach (uint localID in m_lastColliders)
2436 foreach (uint localID in m_lastColliders) 2824 {
2437 {
2438 if (!thisHitColliders.Contains(localID))
2439 endedColliders.Add(localID); 2825 endedColliders.Add(localID);
2826 }
2827 m_lastColliders.Clear();
2440 } 2828 }
2441 2829
2442 //add the items that started colliding this time to the last colliders list. 2830 else
2443 foreach (uint localID in startedColliders) 2831 {
2444 m_lastColliders.Add(localID); 2832 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
2445 2833
2446 // remove things that ended colliding from the last colliders list 2834 // calculate things that started colliding this time
2447 foreach (uint localID in endedColliders) 2835 // and build up list of colliders this time
2448 m_lastColliders.Remove(localID); 2836 if (!VolumeDetectActive && CollisionSoundType >= 0)
2837 {
2838 CollisionForSoundInfo soundinfo;
2839 ContactPoint curcontact;
2449 2840
2450 // play the sound. 2841 foreach (uint id in collissionswith.Keys)
2451 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) 2842 {
2452 { 2843 thisHitColliders.Add(id);
2453 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>(); 2844 if (!m_lastColliders.Contains(id))
2454 if (soundModule != null) 2845 {
2846 startedColliders.Add(id);
2847
2848 curcontact = collissionswith[id];
2849 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
2850 {
2851 soundinfo = new CollisionForSoundInfo();
2852 soundinfo.colliderID = id;
2853 soundinfo.position = curcontact.Position;
2854 soundinfo.relativeVel = curcontact.RelativeSpeed;
2855 soundinfolist.Add(soundinfo);
2856 }
2857 }
2858 }
2859 }
2860 else
2455 { 2861 {
2456 soundModule.SendSound(UUID, CollisionSound, 2862 foreach (uint id in collissionswith.Keys)
2457 CollisionSoundVolume, true, 0, 0, false, 2863 {
2458 false); 2864 thisHitColliders.Add(id);
2865 if (!m_lastColliders.Contains(id))
2866 startedColliders.Add(id);
2867 }
2459 } 2868 }
2869
2870 // calculate things that ended colliding
2871 foreach (uint localID in m_lastColliders)
2872 {
2873 if (!thisHitColliders.Contains(localID))
2874 endedColliders.Add(localID);
2875 }
2876
2877 //add the items that started colliding this time to the last colliders list.
2878 foreach (uint localID in startedColliders)
2879 m_lastColliders.Add(localID);
2880
2881 // remove things that ended colliding from the last colliders list
2882 foreach (uint localID in endedColliders)
2883 m_lastColliders.Remove(localID);
2884
2885 // play sounds.
2886 if (soundinfolist.Count > 0)
2887 CollisionSounds.PartCollisionSound(this, soundinfolist);
2460 } 2888 }
2461 2889
2462 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart); 2890 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
2463 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding); 2891 if (!VolumeDetectActive)
2892 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
2464 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); 2893 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
2465 2894
2466 if (startedColliders.Contains(0)) 2895 if (startedColliders.Contains(0))
@@ -2471,6 +2900,35 @@ namespace OpenSim.Region.Framework.Scenes
2471 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); 2900 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2472 } 2901 }
2473 2902
2903 // The Collision sounds code calls this
2904 public void SendCollisionSound(UUID soundID, double volume, Vector3 position)
2905 {
2906 if (soundID == UUID.Zero)
2907 return;
2908
2909 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>();
2910 if (soundModule == null)
2911 return;
2912
2913 if (volume > 1)
2914 volume = 1;
2915 if (volume < 0)
2916 volume = 0;
2917
2918 int now = Util.EnvironmentTickCount();
2919 if(Util.EnvironmentTickCountSubtract(now,LastColSoundSentTime) <200)
2920 return;
2921
2922 LastColSoundSentTime = now;
2923
2924 UUID ownerID = OwnerID;
2925 UUID objectID = ParentGroup.RootPart.UUID;
2926 UUID parentID = ParentGroup.UUID;
2927 ulong regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle;
2928
2929 soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, 0 );
2930 }
2931
2474 public void PhysicsOutOfBounds(Vector3 pos) 2932 public void PhysicsOutOfBounds(Vector3 pos)
2475 { 2933 {
2476 // Note: This is only being called on the root prim at this time. 2934 // Note: This is only being called on the root prim at this time.
@@ -2492,9 +2950,9 @@ namespace OpenSim.Region.Framework.Scenes
2492 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2950 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2493 2951
2494 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2952 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2495 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2953 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2496 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2954 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2497 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2955 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2498 { 2956 {
2499 ParentGroup.AbsolutePosition = newpos; 2957 ParentGroup.AbsolutePosition = newpos;
2500 return; 2958 return;
@@ -2799,6 +3257,14 @@ namespace OpenSim.Region.Framework.Scenes
2799 if (ParentGroup == null) 3257 if (ParentGroup == null)
2800 return; 3258 return;
2801 3259
3260 // Update the "last" values
3261 m_lastPosition = OffsetPosition;
3262 m_lastRotation = RotationOffset;
3263 m_lastVelocity = Velocity;
3264 m_lastAcceleration = Acceleration;
3265 m_lastAngularVelocity = AngularVelocity;
3266 m_lastUpdateSentTime = Environment.TickCount;
3267
2802 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3268 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
2803 { 3269 {
2804 SendFullUpdate(avatar.ControllingClient); 3270 SendFullUpdate(avatar.ControllingClient);
@@ -2857,8 +3323,8 @@ namespace OpenSim.Region.Framework.Scenes
2857 { 3323 {
2858 const float ROTATION_TOLERANCE = 0.01f; 3324 const float ROTATION_TOLERANCE = 0.01f;
2859 const float VELOCITY_TOLERANCE = 0.001f; 3325 const float VELOCITY_TOLERANCE = 0.001f;
2860 const float POSITION_TOLERANCE = 0.05f; 3326 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2861 const int TIME_MS_TOLERANCE = 3000; 3327 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2862 3328
2863 switch (UpdateFlag) 3329 switch (UpdateFlag)
2864 { 3330 {
@@ -2872,17 +3338,10 @@ namespace OpenSim.Region.Framework.Scenes
2872 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || 3338 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) ||
2873 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || 3339 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) ||
2874 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 3340 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
2875 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 3341 Environment.TickCount - m_lastUpdateSentTime > TIME_MS_TOLERANCE)
2876 { 3342 {
2877 SendTerseUpdateToAllClients(); 3343 SendTerseUpdateToAllClients();
2878 3344
2879 // Update the "last" values
2880 m_lastPosition = OffsetPosition;
2881 m_lastRotation = RotationOffset;
2882 m_lastVelocity = Velocity;
2883 m_lastAcceleration = Acceleration;
2884 m_lastAngularVelocity = AngularVelocity;
2885 m_lastTerseSent = Environment.TickCount;
2886 } 3345 }
2887 break; 3346 break;
2888 } 3347 }
@@ -2900,6 +3359,17 @@ namespace OpenSim.Region.Framework.Scenes
2900 /// </summary> 3359 /// </summary>
2901 public void SendTerseUpdateToAllClients() 3360 public void SendTerseUpdateToAllClients()
2902 { 3361 {
3362 if (ParentGroup == null || ParentGroup.Scene == null)
3363 return;
3364
3365 // Update the "last" values
3366 m_lastPosition = OffsetPosition;
3367 m_lastRotation = RotationOffset;
3368 m_lastVelocity = Velocity;
3369 m_lastAcceleration = Acceleration;
3370 m_lastAngularVelocity = AngularVelocity;
3371 m_lastUpdateSentTime = Environment.TickCount;
3372
2903 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3373 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
2904 { 3374 {
2905 SendTerseUpdateToClient(client); 3375 SendTerseUpdateToClient(client);
@@ -2923,10 +3393,13 @@ namespace OpenSim.Region.Framework.Scenes
2923 3393
2924 public void SetBuoyancy(float fvalue) 3394 public void SetBuoyancy(float fvalue)
2925 { 3395 {
2926 PhysicsActor pa = PhysActor; 3396 Buoyancy = fvalue;
2927 3397/*
2928 if (pa != null) 3398 if (PhysActor != null)
2929 pa.Buoyancy = fvalue; 3399 {
3400 PhysActor.Buoyancy = fvalue;
3401 }
3402 */
2930 } 3403 }
2931 3404
2932 public void SetDieAtEdge(bool p) 3405 public void SetDieAtEdge(bool p)
@@ -2942,47 +3415,111 @@ namespace OpenSim.Region.Framework.Scenes
2942 PhysicsActor pa = PhysActor; 3415 PhysicsActor pa = PhysActor;
2943 3416
2944 if (pa != null) 3417 if (pa != null)
2945 pa.FloatOnWater = floatYN == 1; 3418 pa.FloatOnWater = (floatYN == 1);
2946 } 3419 }
2947 3420
2948 public void SetForce(Vector3 force) 3421 public void SetForce(Vector3 force)
2949 { 3422 {
2950 PhysicsActor pa = PhysActor; 3423 Force = force;
3424 }
2951 3425
2952 if (pa != null) 3426 public SOPVehicle VehicleParams
2953 pa.Force = force; 3427 {
3428 get
3429 {
3430 return m_vehicleParams;
3431 }
3432 set
3433 {
3434 m_vehicleParams = value;
3435 }
3436 }
3437
3438
3439 public int VehicleType
3440 {
3441 get
3442 {
3443 if (m_vehicleParams == null)
3444 return (int)Vehicle.TYPE_NONE;
3445 else
3446 return (int)m_vehicleParams.Type;
3447 }
3448 set
3449 {
3450 SetVehicleType(value);
3451 }
2954 } 3452 }
2955 3453
2956 public void SetVehicleType(int type) 3454 public void SetVehicleType(int type)
2957 { 3455 {
2958 PhysicsActor pa = PhysActor; 3456 m_vehicleParams = null;
3457
3458 if (type == (int)Vehicle.TYPE_NONE)
3459 {
3460 if (_parentID ==0 && PhysActor != null)
3461 PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
3462 return;
3463 }
3464 m_vehicleParams = new SOPVehicle();
3465 m_vehicleParams.ProcessTypeChange((Vehicle)type);
3466 {
3467 if (_parentID ==0 && PhysActor != null)
3468 PhysActor.VehicleType = type;
3469 return;
3470 }
3471 }
2959 3472
2960 if (pa != null) 3473 public void SetVehicleFlags(int param, bool remove)
2961 pa.VehicleType = type; 3474 {
3475 if (m_vehicleParams == null)
3476 return;
3477
3478 m_vehicleParams.ProcessVehicleFlags(param, remove);
3479
3480 if (_parentID ==0 && PhysActor != null)
3481 {
3482 PhysActor.VehicleFlags(param, remove);
3483 }
2962 } 3484 }
2963 3485
2964 public void SetVehicleFloatParam(int param, float value) 3486 public void SetVehicleFloatParam(int param, float value)
2965 { 3487 {
2966 PhysicsActor pa = PhysActor; 3488 if (m_vehicleParams == null)
3489 return;
2967 3490
2968 if (pa != null) 3491 m_vehicleParams.ProcessFloatVehicleParam((Vehicle)param, value);
2969 pa.VehicleFloatParam(param, value); 3492
3493 if (_parentID == 0 && PhysActor != null)
3494 {
3495 PhysActor.VehicleFloatParam(param, value);
3496 }
2970 } 3497 }
2971 3498
2972 public void SetVehicleVectorParam(int param, Vector3 value) 3499 public void SetVehicleVectorParam(int param, Vector3 value)
2973 { 3500 {
2974 PhysicsActor pa = PhysActor; 3501 if (m_vehicleParams == null)
3502 return;
2975 3503
2976 if (pa != null) 3504 m_vehicleParams.ProcessVectorVehicleParam((Vehicle)param, value);
2977 pa.VehicleVectorParam(param, value); 3505
3506 if (_parentID == 0 && PhysActor != null)
3507 {
3508 PhysActor.VehicleVectorParam(param, value);
3509 }
2978 } 3510 }
2979 3511
2980 public void SetVehicleRotationParam(int param, Quaternion rotation) 3512 public void SetVehicleRotationParam(int param, Quaternion rotation)
2981 { 3513 {
2982 PhysicsActor pa = PhysActor; 3514 if (m_vehicleParams == null)
3515 return;
2983 3516
2984 if (pa != null) 3517 m_vehicleParams.ProcessRotationVehicleParam((Vehicle)param, rotation);
2985 pa.VehicleRotationParam(param, rotation); 3518
3519 if (_parentID == 0 && PhysActor != null)
3520 {
3521 PhysActor.VehicleRotationParam(param, rotation);
3522 }
2986 } 3523 }
2987 3524
2988 /// <summary> 3525 /// <summary>
@@ -3183,14 +3720,6 @@ namespace OpenSim.Region.Framework.Scenes
3183 hasProfileCut = hasDimple; // is it the same thing? 3720 hasProfileCut = hasDimple; // is it the same thing?
3184 } 3721 }
3185 3722
3186 public void SetVehicleFlags(int param, bool remove)
3187 {
3188 PhysicsActor pa = PhysActor;
3189
3190 if (pa != null)
3191 pa.VehicleFlags(param, remove);
3192 }
3193
3194 public void SetGroup(UUID groupID, IClientAPI client) 3723 public void SetGroup(UUID groupID, IClientAPI client)
3195 { 3724 {
3196 // Scene.AddNewPrims() calls with client == null so can't use this. 3725 // Scene.AddNewPrims() calls with client == null so can't use this.
@@ -3294,71 +3823,20 @@ namespace OpenSim.Region.Framework.Scenes
3294 { 3823 {
3295 ParentGroup.stopMoveToTarget(); 3824 ParentGroup.stopMoveToTarget();
3296 3825
3297 ParentGroup.ScheduleGroupForTerseUpdate(); 3826// ParentGroup.ScheduleGroupForTerseUpdate();
3298 //ParentGroup.ScheduleGroupForFullUpdate(); 3827 //ParentGroup.ScheduleGroupForFullUpdate();
3299 } 3828 }
3300 3829
3301 public void StoreUndoState() 3830 public void StoreUndoState(ObjectChangeType change)
3302 { 3831 {
3303 StoreUndoState(false); 3832 if (m_UndoRedo == null)
3304 } 3833 m_UndoRedo = new UndoRedoState(5);
3305
3306 public void StoreUndoState(bool forGroup)
3307 {
3308 if (ParentGroup == null || ParentGroup.Scene == null)
3309 return;
3310
3311 if (Undoing)
3312 {
3313// m_log.DebugFormat(
3314// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3315 return;
3316 }
3317
3318 if (IgnoreUndoUpdate)
3319 {
3320// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3321 return;
3322 }
3323 3834
3324 lock (m_undo) 3835 lock (m_UndoRedo)
3325 { 3836 {
3326 if (m_undo.Count > 0) 3837 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3327 {
3328 UndoState last = m_undo[m_undo.Count - 1];
3329 if (last != null)
3330 {
3331 // TODO: May need to fix for group comparison
3332 if (last.Compare(this))
3333 {
3334// m_log.DebugFormat(
3335// "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3336// Name, LocalId, m_undo.Count);
3337
3338 return;
3339 }
3340 }
3341 }
3342
3343// m_log.DebugFormat(
3344// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3345// Name, LocalId, forGroup, m_undo.Count);
3346
3347 if (ParentGroup.Scene.MaxUndoCount > 0)
3348 { 3838 {
3349 UndoState nUndo = new UndoState(this, forGroup); 3839 m_UndoRedo.StoreUndo(this, change);
3350
3351 m_undo.Add(nUndo);
3352
3353 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3354 m_undo.RemoveAt(0);
3355
3356 if (m_redo.Count > 0)
3357 m_redo.Clear();
3358
3359// m_log.DebugFormat(
3360// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3361// Name, LocalId, forGroup, m_undo.Count);
3362 } 3840 }
3363 } 3841 }
3364 } 3842 }
@@ -3370,88 +3848,46 @@ namespace OpenSim.Region.Framework.Scenes
3370 { 3848 {
3371 get 3849 get
3372 { 3850 {
3373 lock (m_undo) 3851 if (m_UndoRedo == null)
3374 return m_undo.Count; 3852 return 0;
3853 return m_UndoRedo.Count;
3375 } 3854 }
3376 } 3855 }
3377 3856
3378 public void Undo() 3857 public void Undo()
3379 { 3858 {
3380 lock (m_undo) 3859 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3381 { 3860 return;
3382// m_log.DebugFormat(
3383// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3384// Name, LocalId, m_undo.Count);
3385
3386 if (m_undo.Count > 0)
3387 {
3388 UndoState goback = m_undo[m_undo.Count - 1];
3389 m_undo.RemoveAt(m_undo.Count - 1);
3390
3391 UndoState nUndo = null;
3392
3393 if (ParentGroup.Scene.MaxUndoCount > 0)
3394 {
3395 nUndo = new UndoState(this, goback.ForGroup);
3396 }
3397
3398 goback.PlaybackState(this);
3399
3400 if (nUndo != null)
3401 {
3402 m_redo.Add(nUndo);
3403
3404 if (m_redo.Count > ParentGroup.Scene.MaxUndoCount)
3405 m_redo.RemoveAt(0);
3406 }
3407 }
3408 3861
3409// m_log.DebugFormat( 3862 lock (m_UndoRedo)
3410// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3863 {
3411// Name, LocalId, m_undo.Count); 3864 Undoing = true;
3865 m_UndoRedo.Undo(this);
3866 Undoing = false;
3412 } 3867 }
3413 } 3868 }
3414 3869
3415 public void Redo() 3870 public void Redo()
3416 { 3871 {
3417 lock (m_undo) 3872 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3418 { 3873 return;
3419// m_log.DebugFormat(
3420// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3421// Name, LocalId, m_redo.Count);
3422
3423 if (m_redo.Count > 0)
3424 {
3425 UndoState gofwd = m_redo[m_redo.Count - 1];
3426 m_redo.RemoveAt(m_redo.Count - 1);
3427
3428 if (ParentGroup.Scene.MaxUndoCount > 0)
3429 {
3430 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3431
3432 m_undo.Add(nUndo);
3433
3434 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3435 m_undo.RemoveAt(0);
3436 }
3437
3438 gofwd.PlayfwdState(this);
3439 3874
3440// m_log.DebugFormat( 3875 lock (m_UndoRedo)
3441// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3876 {
3442// Name, LocalId, m_redo.Count); 3877 Undoing = true;
3443 } 3878 m_UndoRedo.Redo(this);
3879 Undoing = false;
3444 } 3880 }
3445 } 3881 }
3446 3882
3447 public void ClearUndoState() 3883 public void ClearUndoState()
3448 { 3884 {
3449// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3885 if (m_UndoRedo == null || Undoing)
3886 return;
3450 3887
3451 lock (m_undo) 3888 lock (m_UndoRedo)
3452 { 3889 {
3453 m_undo.Clear(); 3890 m_UndoRedo.Clear();
3454 m_redo.Clear();
3455 } 3891 }
3456 } 3892 }
3457 3893
@@ -4003,7 +4439,7 @@ namespace OpenSim.Region.Framework.Scenes
4003 if (god) 4439 if (god)
4004 { 4440 {
4005 BaseMask = ApplyMask(BaseMask, set, mask); 4441 BaseMask = ApplyMask(BaseMask, set, mask);
4006 Inventory.ApplyGodPermissions(_baseMask); 4442 Inventory.ApplyGodPermissions(BaseMask);
4007 } 4443 }
4008 4444
4009 break; 4445 break;
@@ -4034,7 +4470,7 @@ namespace OpenSim.Region.Framework.Scenes
4034 } 4470 }
4035 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & 4471 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) &
4036 baseMask; 4472 baseMask;
4037 // Prevent the client from creating no mod, no copy 4473 // Prevent the client from creating no copy, no transfer
4038 // objects 4474 // objects
4039 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0) 4475 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0)
4040 NextOwnerMask |= (uint)PermissionMask.Transfer; 4476 NextOwnerMask |= (uint)PermissionMask.Transfer;
@@ -4052,20 +4488,20 @@ namespace OpenSim.Region.Framework.Scenes
4052 { 4488 {
4053 bool update = false; 4489 bool update = false;
4054 4490
4055 if (BaseMask != source.BaseMask || 4491 uint prevOwnerMask = OwnerMask;
4056 OwnerMask != source.OwnerMask || 4492 uint prevGroupMask = GroupMask;
4057 GroupMask != source.GroupMask || 4493 uint prevEveryoneMask = EveryoneMask;
4058 EveryoneMask != source.EveryoneMask || 4494 uint prevNextOwnerMask = NextOwnerMask;
4059 NextOwnerMask != source.NextOwnerMask)
4060 update = true;
4061 4495
4062 BaseMask = source.BaseMask; 4496 OwnerMask = source.OwnerMask & BaseMask;
4063 OwnerMask = source.OwnerMask; 4497 GroupMask = source.GroupMask & BaseMask;
4064 GroupMask = source.GroupMask; 4498 EveryoneMask = source.EveryoneMask & BaseMask;
4065 EveryoneMask = source.EveryoneMask; 4499 NextOwnerMask = source.NextOwnerMask & BaseMask;
4066 NextOwnerMask = source.NextOwnerMask;
4067 4500
4068 if (update) 4501 if (OwnerMask != prevOwnerMask ||
4502 GroupMask != prevGroupMask ||
4503 EveryoneMask != prevEveryoneMask ||
4504 NextOwnerMask != prevNextOwnerMask)
4069 SendFullUpdateToAllClients(); 4505 SendFullUpdateToAllClients();
4070 } 4506 }
4071 4507
@@ -4116,6 +4552,7 @@ namespace OpenSim.Region.Framework.Scenes
4116 } 4552 }
4117 } 4553 }
4118 4554
4555
4119 public void UpdateExtraPhysics(ExtraPhysicsData physdata) 4556 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4120 { 4557 {
4121 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null) 4558 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
@@ -4143,7 +4580,7 @@ namespace OpenSim.Region.Framework.Scenes
4143 /// <param name="SetTemporary"></param> 4580 /// <param name="SetTemporary"></param>
4144 /// <param name="SetPhantom"></param> 4581 /// <param name="SetPhantom"></param>
4145 /// <param name="SetVD"></param> 4582 /// <param name="SetVD"></param>
4146 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) 4583 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
4147 { 4584 {
4148 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4585 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4149 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4586 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4153,97 +4590,103 @@ namespace OpenSim.Region.Framework.Scenes
4153 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4590 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4154 return; 4591 return;
4155 4592
4156 PhysicsActor pa = PhysActor; 4593 VolumeDetectActive = SetVD;
4157
4158 // Special cases for VD. VD can only be called from a script
4159 // and can't be combined with changes to other states. So we can rely
4160 // that...
4161 // ... if VD is changed, all others are not.
4162 // ... if one of the others is changed, VD is not.
4163 if (SetVD) // VD is active, special logic applies
4164 {
4165 // State machine logic for VolumeDetect
4166 // More logic below
4167 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4168 4594
4169 if (phanReset) // Phantom changes from on to off switch VD off too 4595 // volume detector implies phantom
4170 { 4596 if (VolumeDetectActive)
4171 SetVD = false; // Switch it of for the course of this routine
4172 VolumeDetectActive = false; // and also permanently
4173
4174 if (pa != null)
4175 pa.SetVolumeDetect(0); // Let physics know about it too
4176 }
4177 else
4178 {
4179 // If volumedetect is active we don't want phantom to be applied.
4180 // If this is a new call to VD out of the state "phantom"
4181 // this will also cause the prim to be visible to physics
4182 SetPhantom = false;
4183 }
4184 }
4185
4186 if (UsePhysics && IsJoint())
4187 {
4188 SetPhantom = true; 4597 SetPhantom = true;
4189 }
4190 4598
4191 if (UsePhysics) 4599 if (UsePhysics)
4192 {
4193 AddFlag(PrimFlags.Physics); 4600 AddFlag(PrimFlags.Physics);
4194 if (!wasUsingPhysics)
4195 {
4196 DoPhysicsPropertyUpdate(UsePhysics, false);
4197 }
4198 }
4199 else 4601 else
4200 {
4201 RemFlag(PrimFlags.Physics); 4602 RemFlag(PrimFlags.Physics);
4202 if (wasUsingPhysics)
4203 {
4204 DoPhysicsPropertyUpdate(UsePhysics, false);
4205 }
4206 }
4207 4603
4208 if (SetPhantom 4604 if (SetPhantom)
4209 || ParentGroup.IsAttachment
4210 || PhysicsShapeType == (byte)PhysShapeType.none
4211 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4212 {
4213 AddFlag(PrimFlags.Phantom); 4605 AddFlag(PrimFlags.Phantom);
4606 else
4607 RemFlag(PrimFlags.Phantom);
4214 4608
4215 if (PhysActor != null) 4609 if (SetTemporary)
4610 AddFlag(PrimFlags.TemporaryOnRez);
4611 else
4612 RemFlag(PrimFlags.TemporaryOnRez);
4613
4614
4615 if (ParentGroup.Scene == null)
4616 return;
4617
4618 PhysicsActor pa = PhysActor;
4619
4620 if (pa != null && building && pa.Building != building)
4621 pa.Building = building;
4622
4623 if ((SetPhantom && !UsePhysics && !SetVD) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
4624 || (Shape.PathCurve == (byte)Extrusion.Flexible))
4625 {
4626 if (pa != null)
4216 { 4627 {
4628 if(wasUsingPhysics)
4629 ParentGroup.Scene.RemovePhysicalPrim(1);
4217 RemoveFromPhysics(); 4630 RemoveFromPhysics();
4218 pa = null;
4219 } 4631 }
4632
4633 Velocity = new Vector3(0, 0, 0);
4634 Acceleration = new Vector3(0, 0, 0);
4635 if (ParentGroup.RootPart == this)
4636 AngularVelocity = new Vector3(0, 0, 0);
4220 } 4637 }
4221 else // Not phantom 4638
4639 else
4222 { 4640 {
4223 RemFlag(PrimFlags.Phantom); 4641 if (ParentGroup.Scene.CollidablePrims)
4224
4225 if (ParentGroup.Scene == null)
4226 return;
4227
4228 if (ParentGroup.Scene.CollidablePrims && pa == null)
4229 { 4642 {
4230 AddToPhysics(UsePhysics, SetPhantom, false); 4643 if (pa == null)
4231 pa = PhysActor; 4644 {
4232 4645 AddToPhysics(UsePhysics, SetPhantom, building, false);
4233 if (pa != null) 4646 pa = PhysActor;
4647/*
4648 if (pa != null)
4649 {
4650 if (
4651// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4652// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4653// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4654// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4655// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4656// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4657 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4658 ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4659 (CollisionSound != UUID.Zero)
4660 )
4661 {
4662 pa.OnCollisionUpdate += PhysicsCollision;
4663 pa.SubscribeEvents(1000);
4664 }
4665 }
4666*/
4667 if (pa != null)
4668 {
4669 pa.SetMaterial(Material);
4670 DoPhysicsPropertyUpdate(UsePhysics, true);
4671 }
4672 }
4673 else // it already has a physical representation
4234 { 4674 {
4235 pa.SetMaterial(Material); 4675 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4236 DoPhysicsPropertyUpdate(UsePhysics, true); 4676/* moved into DoPhysicsPropertyUpdate
4677 if(VolumeDetectActive)
4678 pa.SetVolumeDetect(1);
4679 else
4680 pa.SetVolumeDetect(0);
4681*/
4237 4682
4238 SubscribeForCollisionEvents(); 4683 if (pa.Building != building)
4684 pa.Building = building;
4239 } 4685 }
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 4686
4687 UpdatePhysicsSubscribedEvents();
4688 }
4689 }
4247 if (SetVD) 4690 if (SetVD)
4248 { 4691 {
4249 // If the above logic worked (this is urgent candidate to unit tests!) 4692 // If the above logic worked (this is urgent candidate to unit tests!)
@@ -4257,6 +4700,7 @@ namespace OpenSim.Region.Framework.Scenes
4257 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active 4700 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4258 VolumeDetectActive = true; 4701 VolumeDetectActive = true;
4259 } 4702 }
4703 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4260 } 4704 }
4261 else if (SetVD != wasVD) 4705 else if (SetVD != wasVD)
4262 { 4706 {
@@ -4268,105 +4712,51 @@ namespace OpenSim.Region.Framework.Scenes
4268 RemFlag(PrimFlags.Phantom); 4712 RemFlag(PrimFlags.Phantom);
4269 VolumeDetectActive = false; 4713 VolumeDetectActive = false;
4270 } 4714 }
4271 4715 // 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 4716
4283 if (ParentGroup != null) 4717 if (ParentGroup != null)
4284 { 4718 {
4285 ParentGroup.HasGroupChanged = true; 4719 ParentGroup.HasGroupChanged = true;
4286 ScheduleFullUpdate(); 4720 ScheduleFullUpdate();
4287 } 4721 }
4288 4722
4289// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); 4723// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4290 } 4724 }
4291 4725
4292 /// <summary> 4726 /// <summary>
4293 /// Subscribe for physics collision events if needed for scripts and sounds
4294 /// </summary>
4295 public void SubscribeForCollisionEvents()
4296 {
4297 PhysicsActor pa = PhysActor;
4298
4299 if (pa != null)
4300 {
4301 if (
4302 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4303 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4304 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4305 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4306 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4307 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4308 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4309 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4310 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4311 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4312 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4313 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4314 (CollisionSound != UUID.Zero)
4315 )
4316 {
4317 if (!pa.SubscribedEvents())
4318 {
4319 // If not already subscribed for event, set up for a collision event.
4320 pa.OnCollisionUpdate += PhysicsCollision;
4321 pa.SubscribeEvents(1000);
4322 }
4323 }
4324 else
4325 {
4326 // There is no need to be subscribed to collisions so, if subscribed, remove subscription
4327 if (pa.SubscribedEvents())
4328 {
4329 pa.OnCollisionUpdate -= PhysicsCollision;
4330 pa.UnSubscribeEvents();
4331 }
4332 }
4333 }
4334 }
4335
4336 /// <summary>
4337 /// Adds this part to the physics scene. 4727 /// Adds this part to the physics scene.
4728 /// and sets the PhysActor property
4338 /// </summary> 4729 /// </summary>
4339 /// <remarks>This method also sets the PhysActor property.</remarks> 4730 /// <param name="isPhysical">Add this prim as physical.</param>
4340 /// <param name="rigidBody">Add this prim with a rigid body.</param> 4731 /// <param name="isPhantom">Add this prim as phantom.</param>
4341 /// <returns> 4732 /// <param name="building">tells physics to delay full construction of object</param>
4342 /// The physics actor. null if there was a failure. 4733 /// <param name="applyDynamics">applies velocities, force and torque</param>
4343 /// </returns> 4734 private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
4344 private void AddToPhysics(bool isPhysical, bool isPhantom, bool applyDynamics) 4735 {
4345 {
4346 PhysicsActor pa; 4736 PhysicsActor pa;
4347 4737
4348 Vector3 velocity = Velocity; 4738 Vector3 velocity = Velocity;
4349 Vector3 rotationalVelocity = AngularVelocity;; 4739 Vector3 rotationalVelocity = AngularVelocity;;
4350 4740
4351 try 4741 try
4352 { 4742 {
4353 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4743 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4354 string.Format("{0}/{1}", Name, UUID), 4744 string.Format("{0}/{1}", Name, UUID),
4355 Shape, 4745 Shape,
4356 AbsolutePosition, 4746 AbsolutePosition,
4357 Scale, 4747 Scale,
4358 GetWorldRotation(), 4748 GetWorldRotation(),
4359 isPhysical, 4749 isPhysical,
4360 isPhantom, 4750 isPhantom,
4361 PhysicsShapeType, 4751 PhysicsShapeType,
4362 m_localId); 4752 m_localId);
4363 } 4753 }
4364 catch (Exception e) 4754 catch (Exception e)
4365 { 4755 {
4366 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e); 4756 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e);
4367 pa = null; 4757 pa = null;
4368 } 4758 }
4369 4759
4370 if (pa != null) 4760 if (pa != null)
4371 { 4761 {
4372 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 4762 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
@@ -4379,9 +4769,16 @@ namespace OpenSim.Region.Framework.Scenes
4379 4769
4380 if (VolumeDetectActive) // change if not the default only 4770 if (VolumeDetectActive) // change if not the default only
4381 pa.SetVolumeDetect(1); 4771 pa.SetVolumeDetect(1);
4772
4773 if (m_vehicleParams != null && LocalId == ParentGroup.RootPart.LocalId)
4774 m_vehicleParams.SetVehicle(pa);
4775
4382 // we are going to tell rest of code about physics so better have this here 4776 // we are going to tell rest of code about physics so better have this here
4383 PhysActor = pa; 4777 PhysActor = pa;
4384 4778
4779 // DoPhysicsPropertyUpdate(isPhysical, true);
4780 // lets expand it here just with what it really needs to do
4781
4385 if (isPhysical) 4782 if (isPhysical)
4386 { 4783 {
4387 if (ParentGroup.RootPart.KeyframeMotion != null) 4784 if (ParentGroup.RootPart.KeyframeMotion != null)
@@ -4403,19 +4800,34 @@ namespace OpenSim.Region.Framework.Scenes
4403 } 4800 }
4404 } 4801 }
4405 4802
4406 if (applyDynamics) 4803 if (applyDynamics)
4407 // do independent of isphysical so parameters get setted (at least some) 4804 // do independent of isphysical so parameters get setted (at least some)
4408 { 4805 {
4409 Velocity = velocity; 4806 Velocity = velocity;
4410 AngularVelocity = rotationalVelocity; 4807 AngularVelocity = rotationalVelocity;
4411// pa.Velocity = velocity; 4808// pa.Velocity = velocity;
4412 pa.RotationalVelocity = rotationalVelocity; 4809 pa.RotationalVelocity = rotationalVelocity;
4810
4811 // if not vehicle and root part apply force and torque
4812 if ((m_vehicleParams == null || m_vehicleParams.Type == Vehicle.TYPE_NONE)
4813 && LocalId == ParentGroup.RootPart.LocalId)
4814 {
4815 pa.Force = Force;
4816 pa.Torque = Torque;
4817 }
4413 } 4818 }
4414 4819
4415 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); 4820// if (Shape.SculptEntry)
4821// CheckSculptAndLoad();
4822// else
4823 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
4824
4825 if (!building)
4826 pa.Building = false;
4416 } 4827 }
4417 4828
4418 PhysActor = pa; 4829 PhysActor = pa;
4830
4419 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this); 4831 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this);
4420 } 4832 }
4421 4833
@@ -4424,14 +4836,21 @@ namespace OpenSim.Region.Framework.Scenes
4424 /// </summary> 4836 /// </summary>
4425 /// <remarks> 4837 /// <remarks>
4426 /// This isn't the same as turning off physical, since even without being physical the prim has a physics 4838 /// This isn't the same as turning off physical, since even without being physical the prim has a physics
4427 /// representation for collision detection. Rather, this would be used in situations such as making a prim 4839 /// representation for collision detection.
4428 /// phantom.
4429 /// </remarks> 4840 /// </remarks>
4430 public void RemoveFromPhysics() 4841 public void RemoveFromPhysics()
4431 { 4842 {
4432 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this); 4843 PhysicsActor pa = PhysActor;
4433 if (ParentGroup.Scene.PhysicsScene != null) 4844 if (pa != null)
4434 ParentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 4845 {
4846 pa.OnCollisionUpdate -= PhysicsCollision;
4847 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
4848 pa.OnOutOfBounds -= PhysicsOutOfBounds;
4849
4850 ParentGroup.Scene.PhysicsScene.RemovePrim(pa);
4851
4852 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this);
4853 }
4435 PhysActor = null; 4854 PhysActor = null;
4436 } 4855 }
4437 4856
@@ -4563,6 +4982,8 @@ namespace OpenSim.Region.Framework.Scenes
4563 { 4982 {
4564// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); 4983// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4565 4984
4985 return;
4986
4566 if (ParentGroup.IsDeleted) 4987 if (ParentGroup.IsDeleted)
4567 return; 4988 return;
4568 4989
@@ -4686,6 +5107,44 @@ namespace OpenSim.Region.Framework.Scenes
4686 } 5107 }
4687 } 5108 }
4688 5109
5110
5111 private void UpdatePhysicsSubscribedEvents()
5112 {
5113 PhysicsActor pa = PhysActor;
5114 if (pa == null)
5115 return;
5116
5117 pa.OnCollisionUpdate -= PhysicsCollision;
5118
5119 bool hassound = (!VolumeDetectActive && CollisionSoundType >= 0 && ((Flags & PrimFlags.Physics) != 0));
5120
5121 scriptEvents CombinedEvents = AggregateScriptEvents;
5122
5123 // merge with root part
5124 if (ParentGroup != null && ParentGroup.RootPart != null)
5125 CombinedEvents |= ParentGroup.RootPart.AggregateScriptEvents;
5126
5127 // submit to this part case
5128 if (VolumeDetectActive)
5129 CombinedEvents &= PhyscicsVolumeDtcSubsEvents;
5130 else if ((Flags & PrimFlags.Phantom) != 0)
5131 CombinedEvents &= PhyscicsPhantonSubsEvents;
5132 else
5133 CombinedEvents &= PhysicsNeededSubsEvents;
5134
5135 if (hassound || CombinedEvents != 0)
5136 {
5137 // subscribe to physics updates.
5138 pa.OnCollisionUpdate += PhysicsCollision;
5139 pa.SubscribeEvents(50); // 20 reports per second
5140 }
5141 else
5142 {
5143 pa.UnSubscribeEvents();
5144 }
5145 }
5146
5147
4689 public void aggregateScriptEvents() 5148 public void aggregateScriptEvents()
4690 { 5149 {
4691 if (ParentGroup == null || ParentGroup.RootPart == null) 5150 if (ParentGroup == null || ParentGroup.RootPart == null)
@@ -4722,8 +5181,32 @@ namespace OpenSim.Region.Framework.Scenes
4722 { 5181 {
4723 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; 5182 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop;
4724 } 5183 }
4725 5184/*
4726 SubscribeForCollisionEvents(); 5185 PhysicsActor pa = PhysActor;
5186 if (pa != null)
5187 {
5188 if (
5189// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
5190// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
5191// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
5192// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5193// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5194// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5195 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5196 )
5197 {
5198 // subscribe to physics updates.
5199 pa.OnCollisionUpdate += PhysicsCollision;
5200 pa.SubscribeEvents(1000);
5201 }
5202 else
5203 {
5204 pa.UnSubscribeEvents();
5205 pa.OnCollisionUpdate -= PhysicsCollision;
5206 }
5207 }
5208 */
5209 UpdatePhysicsSubscribedEvents();
4727 5210
4728 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 5211 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4729 //{ 5212 //{
@@ -4857,6 +5340,18 @@ namespace OpenSim.Region.Framework.Scenes
4857 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 5340 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4858 } 5341 }
4859 5342
5343 public void ResetOwnerChangeFlag()
5344 {
5345 List<UUID> inv = Inventory.GetInventoryList();
5346
5347 foreach (UUID itemID in inv)
5348 {
5349 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
5350 item.OwnerChanged = false;
5351 Inventory.UpdateInventoryItem(item, false, false);
5352 }
5353 }
5354
4860 /// <summary> 5355 /// <summary>
4861 /// Record an avatar sitting on this part. 5356 /// Record an avatar sitting on this part.
4862 /// </summary> 5357 /// </summary>