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.cs1494
1 files changed, 993 insertions, 501 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index c9ff4f3..cf03d7c 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 { 2785
2404 ColliderArgs LandCollidingMessage = new ColliderArgs(); 2786 ColliderArgs LandCollidingMessage = new ColliderArgs();
2405 List<DetectedObject> colliding = new List<DetectedObject>(); 2787 List<DetectedObject> colliding = new List<DetectedObject>();
2406 2788
2407 colliding.Add(CreateDetObjectForGround()); 2789 colliding.Add(CreateDetObjectForGround());
2408 LandCollidingMessage.Colliders = colliding; 2790 LandCollidingMessage.Colliders = colliding;
2409 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,57 +2815,120 @@ 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>();
2833
2834 // calculate things that started colliding this time
2835 // and build up list of colliders this time
2836 if (!VolumeDetectActive && CollisionSoundType >= 0)
2837 {
2838 CollisionForSoundInfo soundinfo;
2839 ContactPoint curcontact;
2445 2840
2446 // remove things that ended colliding from the last colliders list 2841 foreach (uint id in collissionswith.Keys)
2447 foreach (uint localID in endedColliders) 2842 {
2448 m_lastColliders.Remove(localID); 2843 thisHitColliders.Add(id);
2844 if (!m_lastColliders.Contains(id))
2845 {
2846 startedColliders.Add(id);
2449 2847
2450 // play the sound. 2848 curcontact = collissionswith[id];
2451 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) 2849 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
2452 { 2850 {
2453 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>(); 2851 soundinfo = new CollisionForSoundInfo();
2454 if (soundModule != null) 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))
2467 { 2896 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2468 if (m_lastColliders.Contains(0)) 2897 if (m_lastColliders.Contains(0))
2469 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding); 2898 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding);
2470 else
2471 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2472 }
2473 if (endedColliders.Contains(0)) 2899 if (endedColliders.Contains(0))
2474 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); 2900 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2475 } 2901 }
2476 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
2477 public void PhysicsOutOfBounds(Vector3 pos) 2932 public void PhysicsOutOfBounds(Vector3 pos)
2478 { 2933 {
2479 // 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.
@@ -2495,9 +2950,9 @@ namespace OpenSim.Region.Framework.Scenes
2495 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2950 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2496 2951
2497 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2952 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2498 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2953 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2499 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2954 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2500 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2955 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2501 { 2956 {
2502 ParentGroup.AbsolutePosition = newpos; 2957 ParentGroup.AbsolutePosition = newpos;
2503 return; 2958 return;
@@ -2782,6 +3237,14 @@ namespace OpenSim.Region.Framework.Scenes
2782 if (ParentGroup == null) 3237 if (ParentGroup == null)
2783 return; 3238 return;
2784 3239
3240 // Update the "last" values
3241 m_lastPosition = OffsetPosition;
3242 m_lastRotation = RotationOffset;
3243 m_lastVelocity = Velocity;
3244 m_lastAcceleration = Acceleration;
3245 m_lastAngularVelocity = AngularVelocity;
3246 m_lastUpdateSentTime = Environment.TickCount;
3247
2785 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3248 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
2786 { 3249 {
2787 SendFullUpdate(avatar.ControllingClient); 3250 SendFullUpdate(avatar.ControllingClient);
@@ -2840,8 +3303,8 @@ namespace OpenSim.Region.Framework.Scenes
2840 { 3303 {
2841 const float ROTATION_TOLERANCE = 0.01f; 3304 const float ROTATION_TOLERANCE = 0.01f;
2842 const float VELOCITY_TOLERANCE = 0.001f; 3305 const float VELOCITY_TOLERANCE = 0.001f;
2843 const float POSITION_TOLERANCE = 0.05f; 3306 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2844 const int TIME_MS_TOLERANCE = 3000; 3307 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2845 3308
2846 switch (UpdateFlag) 3309 switch (UpdateFlag)
2847 { 3310 {
@@ -2855,17 +3318,10 @@ namespace OpenSim.Region.Framework.Scenes
2855 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || 3318 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) ||
2856 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || 3319 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) ||
2857 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 3320 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
2858 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 3321 Environment.TickCount - m_lastUpdateSentTime > TIME_MS_TOLERANCE)
2859 { 3322 {
2860 SendTerseUpdateToAllClients(); 3323 SendTerseUpdateToAllClients();
2861 3324
2862 // Update the "last" values
2863 m_lastPosition = OffsetPosition;
2864 m_lastRotation = RotationOffset;
2865 m_lastVelocity = Velocity;
2866 m_lastAcceleration = Acceleration;
2867 m_lastAngularVelocity = AngularVelocity;
2868 m_lastTerseSent = Environment.TickCount;
2869 } 3325 }
2870 break; 3326 break;
2871 } 3327 }
@@ -2883,6 +3339,17 @@ namespace OpenSim.Region.Framework.Scenes
2883 /// </summary> 3339 /// </summary>
2884 public void SendTerseUpdateToAllClients() 3340 public void SendTerseUpdateToAllClients()
2885 { 3341 {
3342 if (ParentGroup == null || ParentGroup.Scene == null)
3343 return;
3344
3345 // Update the "last" values
3346 m_lastPosition = OffsetPosition;
3347 m_lastRotation = RotationOffset;
3348 m_lastVelocity = Velocity;
3349 m_lastAcceleration = Acceleration;
3350 m_lastAngularVelocity = AngularVelocity;
3351 m_lastUpdateSentTime = Environment.TickCount;
3352
2886 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3353 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
2887 { 3354 {
2888 SendTerseUpdateToClient(client); 3355 SendTerseUpdateToClient(client);
@@ -2906,10 +3373,13 @@ namespace OpenSim.Region.Framework.Scenes
2906 3373
2907 public void SetBuoyancy(float fvalue) 3374 public void SetBuoyancy(float fvalue)
2908 { 3375 {
2909 PhysicsActor pa = PhysActor; 3376 Buoyancy = fvalue;
2910 3377/*
2911 if (pa != null) 3378 if (PhysActor != null)
2912 pa.Buoyancy = fvalue; 3379 {
3380 PhysActor.Buoyancy = fvalue;
3381 }
3382 */
2913 } 3383 }
2914 3384
2915 public void SetDieAtEdge(bool p) 3385 public void SetDieAtEdge(bool p)
@@ -2925,47 +3395,111 @@ namespace OpenSim.Region.Framework.Scenes
2925 PhysicsActor pa = PhysActor; 3395 PhysicsActor pa = PhysActor;
2926 3396
2927 if (pa != null) 3397 if (pa != null)
2928 pa.FloatOnWater = floatYN == 1; 3398 pa.FloatOnWater = (floatYN == 1);
2929 } 3399 }
2930 3400
2931 public void SetForce(Vector3 force) 3401 public void SetForce(Vector3 force)
2932 { 3402 {
2933 PhysicsActor pa = PhysActor; 3403 Force = force;
3404 }
2934 3405
2935 if (pa != null) 3406 public SOPVehicle VehicleParams
2936 pa.Force = force; 3407 {
3408 get
3409 {
3410 return m_vehicleParams;
3411 }
3412 set
3413 {
3414 m_vehicleParams = value;
3415 }
3416 }
3417
3418
3419 public int VehicleType
3420 {
3421 get
3422 {
3423 if (m_vehicleParams == null)
3424 return (int)Vehicle.TYPE_NONE;
3425 else
3426 return (int)m_vehicleParams.Type;
3427 }
3428 set
3429 {
3430 SetVehicleType(value);
3431 }
2937 } 3432 }
2938 3433
2939 public void SetVehicleType(int type) 3434 public void SetVehicleType(int type)
2940 { 3435 {
2941 PhysicsActor pa = PhysActor; 3436 m_vehicleParams = null;
3437
3438 if (type == (int)Vehicle.TYPE_NONE)
3439 {
3440 if (_parentID ==0 && PhysActor != null)
3441 PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
3442 return;
3443 }
3444 m_vehicleParams = new SOPVehicle();
3445 m_vehicleParams.ProcessTypeChange((Vehicle)type);
3446 {
3447 if (_parentID ==0 && PhysActor != null)
3448 PhysActor.VehicleType = type;
3449 return;
3450 }
3451 }
2942 3452
2943 if (pa != null) 3453 public void SetVehicleFlags(int param, bool remove)
2944 pa.VehicleType = type; 3454 {
3455 if (m_vehicleParams == null)
3456 return;
3457
3458 m_vehicleParams.ProcessVehicleFlags(param, remove);
3459
3460 if (_parentID ==0 && PhysActor != null)
3461 {
3462 PhysActor.VehicleFlags(param, remove);
3463 }
2945 } 3464 }
2946 3465
2947 public void SetVehicleFloatParam(int param, float value) 3466 public void SetVehicleFloatParam(int param, float value)
2948 { 3467 {
2949 PhysicsActor pa = PhysActor; 3468 if (m_vehicleParams == null)
3469 return;
2950 3470
2951 if (pa != null) 3471 m_vehicleParams.ProcessFloatVehicleParam((Vehicle)param, value);
2952 pa.VehicleFloatParam(param, value); 3472
3473 if (_parentID == 0 && PhysActor != null)
3474 {
3475 PhysActor.VehicleFloatParam(param, value);
3476 }
2953 } 3477 }
2954 3478
2955 public void SetVehicleVectorParam(int param, Vector3 value) 3479 public void SetVehicleVectorParam(int param, Vector3 value)
2956 { 3480 {
2957 PhysicsActor pa = PhysActor; 3481 if (m_vehicleParams == null)
3482 return;
2958 3483
2959 if (pa != null) 3484 m_vehicleParams.ProcessVectorVehicleParam((Vehicle)param, value);
2960 pa.VehicleVectorParam(param, value); 3485
3486 if (_parentID == 0 && PhysActor != null)
3487 {
3488 PhysActor.VehicleVectorParam(param, value);
3489 }
2961 } 3490 }
2962 3491
2963 public void SetVehicleRotationParam(int param, Quaternion rotation) 3492 public void SetVehicleRotationParam(int param, Quaternion rotation)
2964 { 3493 {
2965 PhysicsActor pa = PhysActor; 3494 if (m_vehicleParams == null)
3495 return;
2966 3496
2967 if (pa != null) 3497 m_vehicleParams.ProcessRotationVehicleParam((Vehicle)param, rotation);
2968 pa.VehicleRotationParam(param, rotation); 3498
3499 if (_parentID == 0 && PhysActor != null)
3500 {
3501 PhysActor.VehicleRotationParam(param, rotation);
3502 }
2969 } 3503 }
2970 3504
2971 /// <summary> 3505 /// <summary>
@@ -3166,14 +3700,6 @@ namespace OpenSim.Region.Framework.Scenes
3166 hasProfileCut = hasDimple; // is it the same thing? 3700 hasProfileCut = hasDimple; // is it the same thing?
3167 } 3701 }
3168 3702
3169 public void SetVehicleFlags(int param, bool remove)
3170 {
3171 PhysicsActor pa = PhysActor;
3172
3173 if (pa != null)
3174 pa.VehicleFlags(param, remove);
3175 }
3176
3177 public void SetGroup(UUID groupID, IClientAPI client) 3703 public void SetGroup(UUID groupID, IClientAPI client)
3178 { 3704 {
3179 // Scene.AddNewPrims() calls with client == null so can't use this. 3705 // Scene.AddNewPrims() calls with client == null so can't use this.
@@ -3277,71 +3803,20 @@ namespace OpenSim.Region.Framework.Scenes
3277 { 3803 {
3278 ParentGroup.stopMoveToTarget(); 3804 ParentGroup.stopMoveToTarget();
3279 3805
3280 ParentGroup.ScheduleGroupForTerseUpdate(); 3806// ParentGroup.ScheduleGroupForTerseUpdate();
3281 //ParentGroup.ScheduleGroupForFullUpdate(); 3807 //ParentGroup.ScheduleGroupForFullUpdate();
3282 } 3808 }
3283 3809
3284 public void StoreUndoState() 3810 public void StoreUndoState(ObjectChangeType change)
3285 { 3811 {
3286 StoreUndoState(false); 3812 if (m_UndoRedo == null)
3287 } 3813 m_UndoRedo = new UndoRedoState(5);
3288
3289 public void StoreUndoState(bool forGroup)
3290 {
3291 if (ParentGroup == null || ParentGroup.Scene == null)
3292 return;
3293
3294 if (Undoing)
3295 {
3296// m_log.DebugFormat(
3297// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3298 return;
3299 }
3300
3301 if (IgnoreUndoUpdate)
3302 {
3303// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3304 return;
3305 }
3306 3814
3307 lock (m_undo) 3815 lock (m_UndoRedo)
3308 { 3816 {
3309 if (m_undo.Count > 0) 3817 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3310 { 3818 {
3311 UndoState last = m_undo[m_undo.Count - 1]; 3819 m_UndoRedo.StoreUndo(this, change);
3312 if (last != null)
3313 {
3314 // TODO: May need to fix for group comparison
3315 if (last.Compare(this))
3316 {
3317// m_log.DebugFormat(
3318// "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3319// Name, LocalId, m_undo.Count);
3320
3321 return;
3322 }
3323 }
3324 }
3325
3326// m_log.DebugFormat(
3327// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3328// Name, LocalId, forGroup, m_undo.Count);
3329
3330 if (ParentGroup.Scene.MaxUndoCount > 0)
3331 {
3332 UndoState nUndo = new UndoState(this, forGroup);
3333
3334 m_undo.Add(nUndo);
3335
3336 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3337 m_undo.RemoveAt(0);
3338
3339 if (m_redo.Count > 0)
3340 m_redo.Clear();
3341
3342// m_log.DebugFormat(
3343// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3344// Name, LocalId, forGroup, m_undo.Count);
3345 } 3820 }
3346 } 3821 }
3347 } 3822 }
@@ -3353,88 +3828,46 @@ namespace OpenSim.Region.Framework.Scenes
3353 { 3828 {
3354 get 3829 get
3355 { 3830 {
3356 lock (m_undo) 3831 if (m_UndoRedo == null)
3357 return m_undo.Count; 3832 return 0;
3833 return m_UndoRedo.Count;
3358 } 3834 }
3359 } 3835 }
3360 3836
3361 public void Undo() 3837 public void Undo()
3362 { 3838 {
3363 lock (m_undo) 3839 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3364 { 3840 return;
3365// m_log.DebugFormat(
3366// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3367// Name, LocalId, m_undo.Count);
3368
3369 if (m_undo.Count > 0)
3370 {
3371 UndoState goback = m_undo[m_undo.Count - 1];
3372 m_undo.RemoveAt(m_undo.Count - 1);
3373
3374 UndoState nUndo = null;
3375
3376 if (ParentGroup.Scene.MaxUndoCount > 0)
3377 {
3378 nUndo = new UndoState(this, goback.ForGroup);
3379 }
3380
3381 goback.PlaybackState(this);
3382
3383 if (nUndo != null)
3384 {
3385 m_redo.Add(nUndo);
3386
3387 if (m_redo.Count > ParentGroup.Scene.MaxUndoCount)
3388 m_redo.RemoveAt(0);
3389 }
3390 }
3391 3841
3392// m_log.DebugFormat( 3842 lock (m_UndoRedo)
3393// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3843 {
3394// Name, LocalId, m_undo.Count); 3844 Undoing = true;
3845 m_UndoRedo.Undo(this);
3846 Undoing = false;
3395 } 3847 }
3396 } 3848 }
3397 3849
3398 public void Redo() 3850 public void Redo()
3399 { 3851 {
3400 lock (m_undo) 3852 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3401 { 3853 return;
3402// m_log.DebugFormat(
3403// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3404// Name, LocalId, m_redo.Count);
3405
3406 if (m_redo.Count > 0)
3407 {
3408 UndoState gofwd = m_redo[m_redo.Count - 1];
3409 m_redo.RemoveAt(m_redo.Count - 1);
3410
3411 if (ParentGroup.Scene.MaxUndoCount > 0)
3412 {
3413 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3414
3415 m_undo.Add(nUndo);
3416
3417 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3418 m_undo.RemoveAt(0);
3419 }
3420
3421 gofwd.PlayfwdState(this);
3422 3854
3423// m_log.DebugFormat( 3855 lock (m_UndoRedo)
3424// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3856 {
3425// Name, LocalId, m_redo.Count); 3857 Undoing = true;
3426 } 3858 m_UndoRedo.Redo(this);
3859 Undoing = false;
3427 } 3860 }
3428 } 3861 }
3429 3862
3430 public void ClearUndoState() 3863 public void ClearUndoState()
3431 { 3864 {
3432// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3865 if (m_UndoRedo == null || Undoing)
3866 return;
3433 3867
3434 lock (m_undo) 3868 lock (m_UndoRedo)
3435 { 3869 {
3436 m_undo.Clear(); 3870 m_UndoRedo.Clear();
3437 m_redo.Clear();
3438 } 3871 }
3439 } 3872 }
3440 3873
@@ -3986,7 +4419,7 @@ namespace OpenSim.Region.Framework.Scenes
3986 if (god) 4419 if (god)
3987 { 4420 {
3988 BaseMask = ApplyMask(BaseMask, set, mask); 4421 BaseMask = ApplyMask(BaseMask, set, mask);
3989 Inventory.ApplyGodPermissions(_baseMask); 4422 Inventory.ApplyGodPermissions(BaseMask);
3990 } 4423 }
3991 4424
3992 break; 4425 break;
@@ -4017,7 +4450,7 @@ namespace OpenSim.Region.Framework.Scenes
4017 } 4450 }
4018 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & 4451 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) &
4019 baseMask; 4452 baseMask;
4020 // Prevent the client from creating no mod, no copy 4453 // Prevent the client from creating no copy, no transfer
4021 // objects 4454 // objects
4022 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0) 4455 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0)
4023 NextOwnerMask |= (uint)PermissionMask.Transfer; 4456 NextOwnerMask |= (uint)PermissionMask.Transfer;
@@ -4035,20 +4468,20 @@ namespace OpenSim.Region.Framework.Scenes
4035 { 4468 {
4036 bool update = false; 4469 bool update = false;
4037 4470
4038 if (BaseMask != source.BaseMask || 4471 uint prevOwnerMask = OwnerMask;
4039 OwnerMask != source.OwnerMask || 4472 uint prevGroupMask = GroupMask;
4040 GroupMask != source.GroupMask || 4473 uint prevEveryoneMask = EveryoneMask;
4041 EveryoneMask != source.EveryoneMask || 4474 uint prevNextOwnerMask = NextOwnerMask;
4042 NextOwnerMask != source.NextOwnerMask)
4043 update = true;
4044 4475
4045 BaseMask = source.BaseMask; 4476 OwnerMask = source.OwnerMask & BaseMask;
4046 OwnerMask = source.OwnerMask; 4477 GroupMask = source.GroupMask & BaseMask;
4047 GroupMask = source.GroupMask; 4478 EveryoneMask = source.EveryoneMask & BaseMask;
4048 EveryoneMask = source.EveryoneMask; 4479 NextOwnerMask = source.NextOwnerMask & BaseMask;
4049 NextOwnerMask = source.NextOwnerMask;
4050 4480
4051 if (update) 4481 if (OwnerMask != prevOwnerMask ||
4482 GroupMask != prevGroupMask ||
4483 EveryoneMask != prevEveryoneMask ||
4484 NextOwnerMask != prevNextOwnerMask)
4052 SendFullUpdateToAllClients(); 4485 SendFullUpdateToAllClients();
4053 } 4486 }
4054 4487
@@ -4099,6 +4532,7 @@ namespace OpenSim.Region.Framework.Scenes
4099 } 4532 }
4100 } 4533 }
4101 4534
4535
4102 public void UpdateExtraPhysics(ExtraPhysicsData physdata) 4536 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4103 { 4537 {
4104 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null) 4538 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
@@ -4126,7 +4560,7 @@ namespace OpenSim.Region.Framework.Scenes
4126 /// <param name="SetTemporary"></param> 4560 /// <param name="SetTemporary"></param>
4127 /// <param name="SetPhantom"></param> 4561 /// <param name="SetPhantom"></param>
4128 /// <param name="SetVD"></param> 4562 /// <param name="SetVD"></param>
4129 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) 4563 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
4130 { 4564 {
4131 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4565 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4132 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4566 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4136,97 +4570,103 @@ namespace OpenSim.Region.Framework.Scenes
4136 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4570 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4137 return; 4571 return;
4138 4572
4139 PhysicsActor pa = PhysActor; 4573 VolumeDetectActive = SetVD;
4140
4141 // Special cases for VD. VD can only be called from a script
4142 // and can't be combined with changes to other states. So we can rely
4143 // that...
4144 // ... if VD is changed, all others are not.
4145 // ... if one of the others is changed, VD is not.
4146 if (SetVD) // VD is active, special logic applies
4147 {
4148 // State machine logic for VolumeDetect
4149 // More logic below
4150 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4151 4574
4152 if (phanReset) // Phantom changes from on to off switch VD off too 4575 // volume detector implies phantom
4153 { 4576 if (VolumeDetectActive)
4154 SetVD = false; // Switch it of for the course of this routine
4155 VolumeDetectActive = false; // and also permanently
4156
4157 if (pa != null)
4158 pa.SetVolumeDetect(0); // Let physics know about it too
4159 }
4160 else
4161 {
4162 // If volumedetect is active we don't want phantom to be applied.
4163 // If this is a new call to VD out of the state "phantom"
4164 // this will also cause the prim to be visible to physics
4165 SetPhantom = false;
4166 }
4167 }
4168
4169 if (UsePhysics && IsJoint())
4170 {
4171 SetPhantom = true; 4577 SetPhantom = true;
4172 }
4173 4578
4174 if (UsePhysics) 4579 if (UsePhysics)
4175 {
4176 AddFlag(PrimFlags.Physics); 4580 AddFlag(PrimFlags.Physics);
4177 if (!wasUsingPhysics)
4178 {
4179 DoPhysicsPropertyUpdate(UsePhysics, false);
4180 }
4181 }
4182 else 4581 else
4183 {
4184 RemFlag(PrimFlags.Physics); 4582 RemFlag(PrimFlags.Physics);
4185 if (wasUsingPhysics)
4186 {
4187 DoPhysicsPropertyUpdate(UsePhysics, false);
4188 }
4189 }
4190 4583
4191 if (SetPhantom 4584 if (SetPhantom)
4192 || ParentGroup.IsAttachment
4193 || PhysicsShapeType == (byte)PhysShapeType.none
4194 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4195 {
4196 AddFlag(PrimFlags.Phantom); 4585 AddFlag(PrimFlags.Phantom);
4586 else
4587 RemFlag(PrimFlags.Phantom);
4197 4588
4198 if (PhysActor != null) 4589 if (SetTemporary)
4590 AddFlag(PrimFlags.TemporaryOnRez);
4591 else
4592 RemFlag(PrimFlags.TemporaryOnRez);
4593
4594
4595 if (ParentGroup.Scene == null)
4596 return;
4597
4598 PhysicsActor pa = PhysActor;
4599
4600 if (pa != null && building && pa.Building != building)
4601 pa.Building = building;
4602
4603 if ((SetPhantom && !UsePhysics && !SetVD) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
4604 || (Shape.PathCurve == (byte)Extrusion.Flexible))
4605 {
4606 if (pa != null)
4199 { 4607 {
4608 if(wasUsingPhysics)
4609 ParentGroup.Scene.RemovePhysicalPrim(1);
4200 RemoveFromPhysics(); 4610 RemoveFromPhysics();
4201 pa = null;
4202 } 4611 }
4612
4613 Velocity = new Vector3(0, 0, 0);
4614 Acceleration = new Vector3(0, 0, 0);
4615 if (ParentGroup.RootPart == this)
4616 AngularVelocity = new Vector3(0, 0, 0);
4203 } 4617 }
4204 else // Not phantom 4618
4619 else
4205 { 4620 {
4206 RemFlag(PrimFlags.Phantom); 4621 if (ParentGroup.Scene.CollidablePrims)
4207
4208 if (ParentGroup.Scene == null)
4209 return;
4210
4211 if (ParentGroup.Scene.CollidablePrims && pa == null)
4212 { 4622 {
4213 AddToPhysics(UsePhysics, SetPhantom, false); 4623 if (pa == null)
4214 pa = PhysActor; 4624 {
4215 4625 AddToPhysics(UsePhysics, SetPhantom, building, false);
4216 if (pa != null) 4626 pa = PhysActor;
4627/*
4628 if (pa != null)
4629 {
4630 if (
4631// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4632// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4633// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4634// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4635// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4636// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4637 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4638 ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4639 (CollisionSound != UUID.Zero)
4640 )
4641 {
4642 pa.OnCollisionUpdate += PhysicsCollision;
4643 pa.SubscribeEvents(1000);
4644 }
4645 }
4646*/
4647 if (pa != null)
4648 {
4649 pa.SetMaterial(Material);
4650 DoPhysicsPropertyUpdate(UsePhysics, true);
4651 }
4652 }
4653 else // it already has a physical representation
4217 { 4654 {
4218 pa.SetMaterial(Material); 4655 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4219 DoPhysicsPropertyUpdate(UsePhysics, true); 4656/* moved into DoPhysicsPropertyUpdate
4657 if(VolumeDetectActive)
4658 pa.SetVolumeDetect(1);
4659 else
4660 pa.SetVolumeDetect(0);
4661*/
4220 4662
4221 SubscribeForCollisionEvents(); 4663 if (pa.Building != building)
4664 pa.Building = building;
4222 } 4665 }
4223 }
4224 else // it already has a physical representation
4225 {
4226 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4227 }
4228 }
4229 4666
4667 UpdatePhysicsSubscribedEvents();
4668 }
4669 }
4230 if (SetVD) 4670 if (SetVD)
4231 { 4671 {
4232 // If the above logic worked (this is urgent candidate to unit tests!) 4672 // If the above logic worked (this is urgent candidate to unit tests!)
@@ -4240,6 +4680,7 @@ namespace OpenSim.Region.Framework.Scenes
4240 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active 4680 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4241 VolumeDetectActive = true; 4681 VolumeDetectActive = true;
4242 } 4682 }
4683 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4243 } 4684 }
4244 else if (SetVD != wasVD) 4685 else if (SetVD != wasVD)
4245 { 4686 {
@@ -4251,105 +4692,51 @@ namespace OpenSim.Region.Framework.Scenes
4251 RemFlag(PrimFlags.Phantom); 4692 RemFlag(PrimFlags.Phantom);
4252 VolumeDetectActive = false; 4693 VolumeDetectActive = false;
4253 } 4694 }
4254 4695 // and last in case we have a new actor and not building
4255 if (SetTemporary)
4256 {
4257 AddFlag(PrimFlags.TemporaryOnRez);
4258 }
4259 else
4260 {
4261 RemFlag(PrimFlags.TemporaryOnRez);
4262 }
4263
4264 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4265 4696
4266 if (ParentGroup != null) 4697 if (ParentGroup != null)
4267 { 4698 {
4268 ParentGroup.HasGroupChanged = true; 4699 ParentGroup.HasGroupChanged = true;
4269 ScheduleFullUpdate(); 4700 ScheduleFullUpdate();
4270 } 4701 }
4271 4702
4272// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); 4703// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4273 } 4704 }
4274 4705
4275 /// <summary> 4706 /// <summary>
4276 /// Subscribe for physics collision events if needed for scripts and sounds
4277 /// </summary>
4278 public void SubscribeForCollisionEvents()
4279 {
4280 PhysicsActor pa = PhysActor;
4281
4282 if (pa != null)
4283 {
4284 if (
4285 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4286 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4287 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4288 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4289 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4290 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4291 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4292 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4293 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4294 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4295 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4296 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4297 (CollisionSound != UUID.Zero)
4298 )
4299 {
4300 if (!pa.SubscribedEvents())
4301 {
4302 // If not already subscribed for event, set up for a collision event.
4303 pa.OnCollisionUpdate += PhysicsCollision;
4304 pa.SubscribeEvents(1000);
4305 }
4306 }
4307 else
4308 {
4309 // There is no need to be subscribed to collisions so, if subscribed, remove subscription
4310 if (pa.SubscribedEvents())
4311 {
4312 pa.OnCollisionUpdate -= PhysicsCollision;
4313 pa.UnSubscribeEvents();
4314 }
4315 }
4316 }
4317 }
4318
4319 /// <summary>
4320 /// Adds this part to the physics scene. 4707 /// Adds this part to the physics scene.
4708 /// and sets the PhysActor property
4321 /// </summary> 4709 /// </summary>
4322 /// <remarks>This method also sets the PhysActor property.</remarks> 4710 /// <param name="isPhysical">Add this prim as physical.</param>
4323 /// <param name="rigidBody">Add this prim with a rigid body.</param> 4711 /// <param name="isPhantom">Add this prim as phantom.</param>
4324 /// <returns> 4712 /// <param name="building">tells physics to delay full construction of object</param>
4325 /// The physics actor. null if there was a failure. 4713 /// <param name="applyDynamics">applies velocities, force and torque</param>
4326 /// </returns> 4714 private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
4327 private void AddToPhysics(bool isPhysical, bool isPhantom, bool applyDynamics) 4715 {
4328 {
4329 PhysicsActor pa; 4716 PhysicsActor pa;
4330 4717
4331 Vector3 velocity = Velocity; 4718 Vector3 velocity = Velocity;
4332 Vector3 rotationalVelocity = AngularVelocity;; 4719 Vector3 rotationalVelocity = AngularVelocity;;
4333 4720
4334 try 4721 try
4335 { 4722 {
4336 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4723 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4337 string.Format("{0}/{1}", Name, UUID), 4724 string.Format("{0}/{1}", Name, UUID),
4338 Shape, 4725 Shape,
4339 AbsolutePosition, 4726 AbsolutePosition,
4340 Scale, 4727 Scale,
4341 GetWorldRotation(), 4728 GetWorldRotation(),
4342 isPhysical, 4729 isPhysical,
4343 isPhantom, 4730 isPhantom,
4344 PhysicsShapeType, 4731 PhysicsShapeType,
4345 m_localId); 4732 m_localId);
4346 } 4733 }
4347 catch (Exception e) 4734 catch (Exception e)
4348 { 4735 {
4349 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e); 4736 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e);
4350 pa = null; 4737 pa = null;
4351 } 4738 }
4352 4739
4353 if (pa != null) 4740 if (pa != null)
4354 { 4741 {
4355 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 4742 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
@@ -4362,9 +4749,16 @@ namespace OpenSim.Region.Framework.Scenes
4362 4749
4363 if (VolumeDetectActive) // change if not the default only 4750 if (VolumeDetectActive) // change if not the default only
4364 pa.SetVolumeDetect(1); 4751 pa.SetVolumeDetect(1);
4752
4753 if (m_vehicleParams != null && LocalId == ParentGroup.RootPart.LocalId)
4754 m_vehicleParams.SetVehicle(pa);
4755
4365 // we are going to tell rest of code about physics so better have this here 4756 // we are going to tell rest of code about physics so better have this here
4366 PhysActor = pa; 4757 PhysActor = pa;
4367 4758
4759 // DoPhysicsPropertyUpdate(isPhysical, true);
4760 // lets expand it here just with what it really needs to do
4761
4368 if (isPhysical) 4762 if (isPhysical)
4369 { 4763 {
4370 if (ParentGroup.RootPart.KeyframeMotion != null) 4764 if (ParentGroup.RootPart.KeyframeMotion != null)
@@ -4386,19 +4780,34 @@ namespace OpenSim.Region.Framework.Scenes
4386 } 4780 }
4387 } 4781 }
4388 4782
4389 if (applyDynamics) 4783 if (applyDynamics)
4390 // do independent of isphysical so parameters get setted (at least some) 4784 // do independent of isphysical so parameters get setted (at least some)
4391 { 4785 {
4392 Velocity = velocity; 4786 Velocity = velocity;
4393 AngularVelocity = rotationalVelocity; 4787 AngularVelocity = rotationalVelocity;
4394// pa.Velocity = velocity; 4788// pa.Velocity = velocity;
4395 pa.RotationalVelocity = rotationalVelocity; 4789 pa.RotationalVelocity = rotationalVelocity;
4790
4791 // if not vehicle and root part apply force and torque
4792 if ((m_vehicleParams == null || m_vehicleParams.Type == Vehicle.TYPE_NONE)
4793 && LocalId == ParentGroup.RootPart.LocalId)
4794 {
4795 pa.Force = Force;
4796 pa.Torque = Torque;
4797 }
4396 } 4798 }
4397 4799
4398 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); 4800// if (Shape.SculptEntry)
4801// CheckSculptAndLoad();
4802// else
4803 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
4804
4805 if (!building)
4806 pa.Building = false;
4399 } 4807 }
4400 4808
4401 PhysActor = pa; 4809 PhysActor = pa;
4810
4402 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this); 4811 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this);
4403 } 4812 }
4404 4813
@@ -4407,14 +4816,21 @@ namespace OpenSim.Region.Framework.Scenes
4407 /// </summary> 4816 /// </summary>
4408 /// <remarks> 4817 /// <remarks>
4409 /// This isn't the same as turning off physical, since even without being physical the prim has a physics 4818 /// This isn't the same as turning off physical, since even without being physical the prim has a physics
4410 /// representation for collision detection. Rather, this would be used in situations such as making a prim 4819 /// representation for collision detection.
4411 /// phantom.
4412 /// </remarks> 4820 /// </remarks>
4413 public void RemoveFromPhysics() 4821 public void RemoveFromPhysics()
4414 { 4822 {
4415 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this); 4823 PhysicsActor pa = PhysActor;
4416 if (ParentGroup.Scene.PhysicsScene != null) 4824 if (pa != null)
4417 ParentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 4825 {
4826 pa.OnCollisionUpdate -= PhysicsCollision;
4827 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
4828 pa.OnOutOfBounds -= PhysicsOutOfBounds;
4829
4830 ParentGroup.Scene.PhysicsScene.RemovePrim(pa);
4831
4832 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this);
4833 }
4418 PhysActor = null; 4834 PhysActor = null;
4419 } 4835 }
4420 4836
@@ -4546,6 +4962,8 @@ namespace OpenSim.Region.Framework.Scenes
4546 { 4962 {
4547// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); 4963// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4548 4964
4965 return;
4966
4549 if (ParentGroup.IsDeleted) 4967 if (ParentGroup.IsDeleted)
4550 return; 4968 return;
4551 4969
@@ -4669,6 +5087,44 @@ namespace OpenSim.Region.Framework.Scenes
4669 } 5087 }
4670 } 5088 }
4671 5089
5090
5091 private void UpdatePhysicsSubscribedEvents()
5092 {
5093 PhysicsActor pa = PhysActor;
5094 if (pa == null)
5095 return;
5096
5097 pa.OnCollisionUpdate -= PhysicsCollision;
5098
5099 bool hassound = (!VolumeDetectActive && CollisionSoundType >= 0 && ((Flags & PrimFlags.Physics) != 0));
5100
5101 scriptEvents CombinedEvents = AggregateScriptEvents;
5102
5103 // merge with root part
5104 if (ParentGroup != null && ParentGroup.RootPart != null)
5105 CombinedEvents |= ParentGroup.RootPart.AggregateScriptEvents;
5106
5107 // submit to this part case
5108 if (VolumeDetectActive)
5109 CombinedEvents &= PhyscicsVolumeDtcSubsEvents;
5110 else if ((Flags & PrimFlags.Phantom) != 0)
5111 CombinedEvents &= PhyscicsPhantonSubsEvents;
5112 else
5113 CombinedEvents &= PhysicsNeededSubsEvents;
5114
5115 if (hassound || CombinedEvents != 0)
5116 {
5117 // subscribe to physics updates.
5118 pa.OnCollisionUpdate += PhysicsCollision;
5119 pa.SubscribeEvents(50); // 20 reports per second
5120 }
5121 else
5122 {
5123 pa.UnSubscribeEvents();
5124 }
5125 }
5126
5127
4672 public void aggregateScriptEvents() 5128 public void aggregateScriptEvents()
4673 { 5129 {
4674 if (ParentGroup == null || ParentGroup.RootPart == null) 5130 if (ParentGroup == null || ParentGroup.RootPart == null)
@@ -4705,8 +5161,32 @@ namespace OpenSim.Region.Framework.Scenes
4705 { 5161 {
4706 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; 5162 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop;
4707 } 5163 }
4708 5164/*
4709 SubscribeForCollisionEvents(); 5165 PhysicsActor pa = PhysActor;
5166 if (pa != null)
5167 {
5168 if (
5169// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
5170// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
5171// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
5172// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5173// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5174// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5175 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5176 )
5177 {
5178 // subscribe to physics updates.
5179 pa.OnCollisionUpdate += PhysicsCollision;
5180 pa.SubscribeEvents(1000);
5181 }
5182 else
5183 {
5184 pa.UnSubscribeEvents();
5185 pa.OnCollisionUpdate -= PhysicsCollision;
5186 }
5187 }
5188 */
5189 UpdatePhysicsSubscribedEvents();
4710 5190
4711 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 5191 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4712 //{ 5192 //{
@@ -4840,6 +5320,18 @@ namespace OpenSim.Region.Framework.Scenes
4840 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 5320 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4841 } 5321 }
4842 5322
5323 public void ResetOwnerChangeFlag()
5324 {
5325 List<UUID> inv = Inventory.GetInventoryList();
5326
5327 foreach (UUID itemID in inv)
5328 {
5329 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
5330 item.OwnerChanged = false;
5331 Inventory.UpdateInventoryItem(item, false, false);
5332 }
5333 }
5334
4843 /// <summary> 5335 /// <summary>
4844 /// Record an avatar sitting on this part. 5336 /// Record an avatar sitting on this part.
4845 /// </summary> 5337 /// </summary>