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.cs1475
1 files changed, 990 insertions, 485 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 1cf7726..ce9baaa 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 {
@@ -797,7 +840,7 @@ namespace OpenSim.Region.Framework.Scenes
797 get { return m_offsetPosition; } 840 get { return m_offsetPosition; }
798 set 841 set
799 { 842 {
800// StoreUndoState(); 843 Vector3 oldpos = m_offsetPosition;
801 m_offsetPosition = value; 844 m_offsetPosition = value;
802 845
803 if (ParentGroup != null && !ParentGroup.IsDeleted) 846 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -809,10 +852,25 @@ namespace OpenSim.Region.Framework.Scenes
809 actor.Orientation = GetWorldRotation(); 852 actor.Orientation = GetWorldRotation();
810 853
811 // Tell the physics engines that this prim changed. 854 // Tell the physics engines that this prim changed.
812 if (ParentGroup.Scene != null) 855 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene != null)
813 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 856 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
814 } 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 }
815 } 872 }
873 TriggerScriptChangedEvent(Changed.POSITION);
816 } 874 }
817 } 875 }
818 876
@@ -863,7 +921,7 @@ namespace OpenSim.Region.Framework.Scenes
863 921
864 set 922 set
865 { 923 {
866 StoreUndoState(); 924// StoreUndoState();
867 m_rotationOffset = value; 925 m_rotationOffset = value;
868 926
869 PhysicsActor actor = PhysActor; 927 PhysicsActor actor = PhysActor;
@@ -951,19 +1009,36 @@ namespace OpenSim.Region.Framework.Scenes
951 get 1009 get
952 { 1010 {
953 PhysicsActor actor = PhysActor; 1011 PhysicsActor actor = PhysActor;
954 if ((actor != null) && actor.IsPhysical) 1012 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
955 { 1013 {
956 m_angularVelocity = actor.RotationalVelocity; 1014 m_angularVelocity = actor.RotationalVelocity;
957 } 1015 }
958 return m_angularVelocity; 1016 return m_angularVelocity;
959 } 1017 }
960 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 }
961 } 1027 }
962 1028
963 /// <summary></summary> 1029 /// <summary></summary>
964 public Vector3 Acceleration 1030 public Vector3 Acceleration
965 { 1031 {
966 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
967 set { m_acceleration = value; } 1042 set { m_acceleration = value; }
968 } 1043 }
969 1044
@@ -1031,7 +1106,10 @@ namespace OpenSim.Region.Framework.Scenes
1031 public PrimitiveBaseShape Shape 1106 public PrimitiveBaseShape Shape
1032 { 1107 {
1033 get { return m_shape; } 1108 get { return m_shape; }
1034 set { m_shape = value;} 1109 set
1110 {
1111 m_shape = value;
1112 }
1035 } 1113 }
1036 1114
1037 /// <summary> 1115 /// <summary>
@@ -1044,7 +1122,6 @@ namespace OpenSim.Region.Framework.Scenes
1044 { 1122 {
1045 if (m_shape != null) 1123 if (m_shape != null)
1046 { 1124 {
1047 StoreUndoState();
1048 1125
1049 m_shape.Scale = value; 1126 m_shape.Scale = value;
1050 1127
@@ -1112,10 +1189,7 @@ namespace OpenSim.Region.Framework.Scenes
1112 { 1189 {
1113 get 1190 get
1114 { 1191 {
1115 if (ParentGroup.IsAttachment) 1192 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
1116 return GroupPosition;
1117
1118 return m_offsetPosition + m_groupPosition;
1119 } 1193 }
1120 } 1194 }
1121 1195
@@ -1284,6 +1358,13 @@ namespace OpenSim.Region.Framework.Scenes
1284 _flags = value; 1358 _flags = value;
1285 } 1359 }
1286 } 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 }
1287 1368
1288 /// <summary> 1369 /// <summary>
1289 /// ID of the avatar that is sat on us if we have a sit target. If there is no such avatar then is UUID.Zero 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
@@ -1334,12 +1415,41 @@ namespace OpenSim.Region.Framework.Scenes
1334 set { m_sitAnimation = value; } 1415 set { m_sitAnimation = value; }
1335 } 1416 }
1336 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
1337 public UUID CollisionSound 1439 public UUID CollisionSound
1338 { 1440 {
1339 get { return m_collisionSound; } 1441 get { return m_collisionSound; }
1340 set 1442 set
1341 { 1443 {
1342 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
1343 aggregateScriptEvents(); 1453 aggregateScriptEvents();
1344 } 1454 }
1345 } 1455 }
@@ -1350,6 +1460,125 @@ namespace OpenSim.Region.Framework.Scenes
1350 set { m_collisionSoundVolume = value; } 1460 set { m_collisionSoundVolume = value; }
1351 } 1461 }
1352 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
1353 public byte DefaultPhysicsShapeType() 1582 public byte DefaultPhysicsShapeType()
1354 { 1583 {
1355 byte type; 1584 byte type;
@@ -1362,6 +1591,65 @@ namespace OpenSim.Region.Framework.Scenes
1362 return type; 1591 return type;
1363 } 1592 }
1364 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
1365 public byte PhysicsShapeType 1653 public byte PhysicsShapeType
1366 { 1654 {
1367 get { return m_physicsShapeType; } 1655 get { return m_physicsShapeType; }
@@ -1395,11 +1683,14 @@ namespace OpenSim.Region.Framework.Scenes
1395 } 1683 }
1396 else if (PhysActor == null) 1684 else if (PhysActor == null)
1397 { 1685 {
1398 ApplyPhysics((uint)Flags, VolumeDetectActive); 1686 ApplyPhysics((uint)Flags, VolumeDetectActive, false);
1687 UpdatePhysicsSubscribedEvents();
1399 } 1688 }
1400 else 1689 else
1401 { 1690 {
1402 PhysActor.PhysicsShapeType = m_physicsShapeType; 1691 PhysActor.PhysicsShapeType = m_physicsShapeType;
1692// if (Shape.SculptEntry)
1693// CheckSculptAndLoad();
1403 } 1694 }
1404 1695
1405 if (ParentGroup != null) 1696 if (ParentGroup != null)
@@ -1501,6 +1792,7 @@ namespace OpenSim.Region.Framework.Scenes
1501 } 1792 }
1502 } 1793 }
1503 1794
1795
1504 #endregion Public Properties with only Get 1796 #endregion Public Properties with only Get
1505 1797
1506 private uint ApplyMask(uint val, bool set, uint mask) 1798 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1646,6 +1938,61 @@ namespace OpenSim.Region.Framework.Scenes
1646 } 1938 }
1647 } 1939 }
1648 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
1649 /// <summary> 1996 /// <summary>
1650 /// hook to the physics scene to apply angular impulse 1997 /// hook to the physics scene to apply angular impulse
1651 /// 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
@@ -1666,7 +2013,7 @@ namespace OpenSim.Region.Framework.Scenes
1666 impulse = newimpulse; 2013 impulse = newimpulse;
1667 } 2014 }
1668 2015
1669 ParentGroup.applyAngularImpulse(impulse); 2016 ParentGroup.ApplyAngularImpulse(impulse);
1670 } 2017 }
1671 2018
1672 /// <summary> 2019 /// <summary>
@@ -1676,20 +2023,24 @@ namespace OpenSim.Region.Framework.Scenes
1676 /// </summary> 2023 /// </summary>
1677 /// <param name="impulsei">Vector force</param> 2024 /// <param name="impulsei">Vector force</param>
1678 /// <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>
1679 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)
1680 { 2029 {
1681 Vector3 impulse = impulsei; 2030 Vector3 torque = torquei;
1682 2031
1683 if (localGlobalTF) 2032 if (localGlobalTF)
1684 { 2033 {
2034/*
1685 Quaternion grot = GetWorldRotation(); 2035 Quaternion grot = GetWorldRotation();
1686 Quaternion AXgrot = grot; 2036 Quaternion AXgrot = grot;
1687 Vector3 AXimpulsei = impulsei; 2037 Vector3 AXimpulsei = impulsei;
1688 Vector3 newimpulse = AXimpulsei * AXgrot; 2038 Vector3 newimpulse = AXimpulsei * AXgrot;
1689 impulse = newimpulse; 2039 */
2040 torque *= GetWorldRotation();
1690 } 2041 }
1691 2042
1692 ParentGroup.setAngularImpulse(impulse); 2043 Torque = torque;
1693 } 2044 }
1694 2045
1695 /// <summary> 2046 /// <summary>
@@ -1697,7 +2048,9 @@ namespace OpenSim.Region.Framework.Scenes
1697 /// </summary> 2048 /// </summary>
1698 /// <param name="rootObjectFlags"></param> 2049 /// <param name="rootObjectFlags"></param>
1699 /// <param name="VolumeDetectActive"></param> 2050 /// <param name="VolumeDetectActive"></param>
1700 public void ApplyPhysics(uint rootObjectFlags, bool _VolumeDetectActive) 2051 /// <param name="building"></param>
2052
2053 public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building)
1701 { 2054 {
1702 VolumeDetectActive = _VolumeDetectActive; 2055 VolumeDetectActive = _VolumeDetectActive;
1703 2056
@@ -1707,8 +2060,8 @@ namespace OpenSim.Region.Framework.Scenes
1707 if (PhysicsShapeType == (byte)PhysShapeType.none) 2060 if (PhysicsShapeType == (byte)PhysShapeType.none)
1708 return; 2061 return;
1709 2062
1710 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 2063 bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0;
1711 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 2064 bool isPhantom = (_ObjectFlags & (uint)PrimFlags.Phantom) != 0;
1712 2065
1713 if (_VolumeDetectActive) 2066 if (_VolumeDetectActive)
1714 isPhantom = true; 2067 isPhantom = true;
@@ -1722,7 +2075,8 @@ namespace OpenSim.Region.Framework.Scenes
1722 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment 2075 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment
1723 && !(Shape.PathCurve == (byte)Extrusion.Flexible)) 2076 && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1724 { 2077 {
1725 AddToPhysics(isPhysical, isPhantom, isPhysical); 2078 AddToPhysics(isPhysical, isPhantom, building, isPhysical);
2079 UpdatePhysicsSubscribedEvents(); // not sure if appliable here
1726 } 2080 }
1727 else 2081 else
1728 PhysActor = null; // just to be sure 2082 PhysActor = null; // just to be sure
@@ -1777,6 +2131,12 @@ namespace OpenSim.Region.Framework.Scenes
1777 dupe.Category = Category; 2131 dupe.Category = Category;
1778 dupe.m_rezzed = m_rezzed; 2132 dupe.m_rezzed = m_rezzed;
1779 2133
2134 dupe.m_UndoRedo = null;
2135 dupe.m_isSelected = false;
2136
2137 dupe.IgnoreUndoUpdate = false;
2138 dupe.Undoing = false;
2139
1780 dupe.m_inventory = new SceneObjectPartInventory(dupe); 2140 dupe.m_inventory = new SceneObjectPartInventory(dupe);
1781 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone(); 2141 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone();
1782 2142
@@ -1792,6 +2152,7 @@ namespace OpenSim.Region.Framework.Scenes
1792 2152
1793 // Move afterwards ResetIDs as it clears the localID 2153 // Move afterwards ResetIDs as it clears the localID
1794 dupe.LocalId = localID; 2154 dupe.LocalId = localID;
2155
1795 // 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.
1796 dupe.LastOwnerID = OwnerID; 2157 dupe.LastOwnerID = OwnerID;
1797 2158
@@ -1816,8 +2177,12 @@ namespace OpenSim.Region.Framework.Scenes
1816*/ 2177*/
1817 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 2178 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
1818 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 2179 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
2180// dupe.UpdatePhysicsSubscribedEvents(); // not sure...
1819 } 2181 }
1820 2182
2183 if (dupe.PhysActor != null)
2184 dupe.PhysActor.LocalID = localID;
2185
1821 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 2186 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1822 2187
1823// 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);
@@ -1836,10 +2201,10 @@ namespace OpenSim.Region.Framework.Scenes
1836 { 2201 {
1837 if (asset != null) 2202 if (asset != null)
1838 SculptTextureCallback(asset); 2203 SculptTextureCallback(asset);
1839 else 2204// else
1840 m_log.WarnFormat( 2205// m_log.WarnFormat(
1841 "[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",
1842 Name, UUID, id); 2207// Name, UUID, id);
1843 } 2208 }
1844*/ 2209*/
1845 /// <summary> 2210 /// <summary>
@@ -1938,6 +2303,7 @@ namespace OpenSim.Region.Framework.Scenes
1938 2303
1939 /// <summary> 2304 /// <summary>
1940 /// 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
1941 /// </summary> 2307 /// </summary>
1942 /// <param name="UsePhysics"></param> 2308 /// <param name="UsePhysics"></param>
1943 /// <param name="isNew"></param> 2309 /// <param name="isNew"></param>
@@ -1963,64 +2329,69 @@ namespace OpenSim.Region.Framework.Scenes
1963 { 2329 {
1964 if (pa.IsPhysical) // implies UsePhysics==false for this block 2330 if (pa.IsPhysical) // implies UsePhysics==false for this block
1965 { 2331 {
1966 if (!isNew) 2332 if (!isNew) // implies UsePhysics==false for this block
2333 {
1967 ParentGroup.Scene.RemovePhysicalPrim(1); 2334 ParentGroup.Scene.RemovePhysicalPrim(1);
1968 2335
1969 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 2336 Velocity = new Vector3(0, 0, 0);
1970 pa.OnOutOfBounds -= PhysicsOutOfBounds; 2337 Acceleration = new Vector3(0, 0, 0);
1971 pa.delink(); 2338 if (ParentGroup.RootPart == this)
2339 AngularVelocity = new Vector3(0, 0, 0);
1972 2340
1973 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 2341 if (pa.Phantom && !VolumeDetectActive)
1974 { 2342 {
1975 // destroy all joints connected to this now deactivated body 2343 RemoveFromPhysics();
1976 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); 2344 return;
1977 } 2345 }
1978 2346
1979 // stop client-side interpolation of all joint proxy objects that have just been deleted 2347 pa.IsPhysical = UsePhysics;
1980 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback, 2348 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1981 // 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 }
1982 } 2357 }
1983 2358
1984 if (!UsePhysics && !isNew) 2359 if (pa.IsPhysical != UsePhysics)
1985 { 2360 pa.IsPhysical = UsePhysics;
1986 // reset velocity to 0 on physics switch-off. Without that, the client thinks the
1987 // prim still has velocity and continues to interpolate its position along the old
1988 // velocity-vector.
1989 Velocity = new Vector3(0, 0, 0);
1990 Acceleration = new Vector3(0, 0, 0);
1991 AngularVelocity = new Vector3(0, 0, 0);
1992 //RotationalVelocity = new Vector3(0, 0, 0);
1993 }
1994 2361
1995 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);
1996 2368
1997 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 2369 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1998 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 2370 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1999 /// that's not wholesome. Had to make Scene public
2000 //PhysActor = null;
2001 2371
2002 if ((Flags & PrimFlags.Phantom) == 0) 2372 if (ParentID != 0 && ParentID != LocalId)
2003 {
2004 if (UsePhysics)
2005 { 2373 {
2006 if (ParentGroup.RootPart.KeyframeMotion != null) 2374 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
2007 ParentGroup.RootPart.KeyframeMotion.Stop();
2008 ParentGroup.RootPart.KeyframeMotion = null;
2009 ParentGroup.Scene.AddPhysicalPrim(1);
2010
2011 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
2012 pa.OnOutOfBounds += PhysicsOutOfBounds;
2013 if (ParentID != 0 && ParentID != LocalId)
2014 {
2015 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
2016 2375
2017 if (parentPa != null) 2376 if (parentPa != null)
2018 { 2377 {
2019 pa.link(parentPa); 2378 pa.link(parentPa);
2020 }
2021 } 2379 }
2022 } 2380 }
2023 } 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);
2024 } 2395 }
2025 2396
2026 // 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
@@ -2139,42 +2510,63 @@ namespace OpenSim.Region.Framework.Scenes
2139 2510
2140 public Vector3 GetGeometricCenter() 2511 public Vector3 GetGeometricCenter()
2141 { 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 {
2142 PhysicsActor pa = PhysActor; 2525 PhysicsActor pa = PhysActor;
2143 2526
2144 if (pa != null) 2527 if (pa != null)
2145 return pa.GeometricCenter; 2528 return pa.Mass;
2146 else 2529 else
2147 return Vector3.Zero; 2530 return 0;
2148 } 2531 }
2149 2532
2150 public Vector3 GetCenterOfMass() 2533 public Vector3 GetCenterOfMass()
2151 { 2534 {
2535 if (ParentGroup.RootPart == this)
2536 {
2537 if (ParentGroup.IsDeleted)
2538 return AbsolutePosition;
2539 return ParentGroup.GetCenterOfMass();
2540 }
2541
2152 PhysicsActor pa = PhysActor; 2542 PhysicsActor pa = PhysActor;
2153 2543
2154 if (pa != null) 2544 if (pa != null)
2155 return pa.CenterOfMass; 2545 {
2546 Vector3 tmp = pa.CenterOfMass;
2547 return tmp;
2548 }
2156 else 2549 else
2157 return Vector3.Zero; 2550 return AbsolutePosition;
2158 } 2551 }
2159 2552
2160 public float GetMass() 2553 public Vector3 GetPartCenterOfMass()
2161 { 2554 {
2162 PhysicsActor pa = PhysActor; 2555 PhysicsActor pa = PhysActor;
2163 2556
2164 if (pa != null) 2557 if (pa != null)
2165 return pa.Mass; 2558 {
2559 Vector3 tmp = pa.CenterOfMass;
2560 return tmp;
2561 }
2166 else 2562 else
2167 return 0; 2563 return AbsolutePosition;
2168 } 2564 }
2169 2565
2566
2170 public Vector3 GetForce() 2567 public Vector3 GetForce()
2171 { 2568 {
2172 PhysicsActor pa = PhysActor; 2569 return Force;
2173
2174 if (pa != null)
2175 return pa.Force;
2176 else
2177 return Vector3.Zero;
2178 } 2570 }
2179 2571
2180 /// <summary> 2572 /// <summary>
@@ -2389,15 +2781,25 @@ namespace OpenSim.Region.Framework.Scenes
2389 2781
2390 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify) 2782 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify)
2391 { 2783 {
2392 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0) 2784 bool sendToRoot = true;
2393 { 2785
2394 ColliderArgs LandCollidingMessage = new ColliderArgs(); 2786 ColliderArgs LandCollidingMessage = new ColliderArgs();
2395 List<DetectedObject> colliding = new List<DetectedObject>(); 2787 List<DetectedObject> colliding = new List<DetectedObject>();
2396 2788
2397 colliding.Add(CreateDetObjectForGround()); 2789 colliding.Add(CreateDetObjectForGround());
2398 LandCollidingMessage.Colliders = colliding; 2790 LandCollidingMessage.Colliders = colliding;
2399 2791
2792 if (Inventory.ContainsScripts())
2793 {
2794 if (!PassCollisions)
2795 sendToRoot = false;
2796 }
2797 if ((ScriptEvents & ev) != 0)
2400 notify(LocalId, LandCollidingMessage); 2798 notify(LocalId, LandCollidingMessage);
2799
2800 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0 && sendToRoot)
2801 {
2802 notify(ParentGroup.RootPart.LocalId, LandCollidingMessage);
2401 } 2803 }
2402 } 2804 }
2403 2805
@@ -2413,44 +2815,81 @@ namespace OpenSim.Region.Framework.Scenes
2413 List<uint> endedColliders = new List<uint>(); 2815 List<uint> endedColliders = new List<uint>();
2414 List<uint> startedColliders = new List<uint>(); 2816 List<uint> startedColliders = new List<uint>();
2415 2817
2416 // calculate things that started colliding this time 2818 if (collissionswith.Count == 0)
2417 // and build up list of colliders this time
2418 foreach (uint localid in collissionswith.Keys)
2419 { 2819 {
2420 thisHitColliders.Add(localid); 2820 if (m_lastColliders.Count == 0)
2421 if (!m_lastColliders.Contains(localid)) 2821 return; // nothing to do
2422 startedColliders.Add(localid);
2423 }
2424 2822
2425 // calculate things that ended colliding 2823 foreach (uint localID in m_lastColliders)
2426 foreach (uint localID in m_lastColliders) 2824 {
2427 {
2428 if (!thisHitColliders.Contains(localID))
2429 endedColliders.Add(localID); 2825 endedColliders.Add(localID);
2826 }
2827 m_lastColliders.Clear();
2430 } 2828 }
2431 2829
2432 //add the items that started colliding this time to the last colliders list. 2830 else
2433 foreach (uint localID in startedColliders) 2831 {
2434 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;
2435 2840
2436 // remove things that ended colliding from the last colliders list 2841 foreach (uint id in collissionswith.Keys)
2437 foreach (uint localID in endedColliders) 2842 {
2438 m_lastColliders.Remove(localID); 2843 thisHitColliders.Add(id);
2844 if (!m_lastColliders.Contains(id))
2845 {
2846 startedColliders.Add(id);
2439 2847
2440 // play the sound. 2848 curcontact = collissionswith[id];
2441 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) 2849 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
2442 { 2850 {
2443 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>(); 2851 soundinfo = new CollisionForSoundInfo();
2444 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
2861 {
2862 foreach (uint id in collissionswith.Keys)
2863 {
2864 thisHitColliders.Add(id);
2865 if (!m_lastColliders.Contains(id))
2866 startedColliders.Add(id);
2867 }
2868 }
2869
2870 // calculate things that ended colliding
2871 foreach (uint localID in m_lastColliders)
2445 { 2872 {
2446 soundModule.SendSound(UUID, CollisionSound, 2873 if (!thisHitColliders.Contains(localID))
2447 CollisionSoundVolume, true, 0, 0, false, 2874 endedColliders.Add(localID);
2448 false);
2449 } 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);
2450 } 2888 }
2451 2889
2452 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart); 2890 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
2453 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding); 2891 if (!VolumeDetectActive)
2892 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
2454 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); 2893 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
2455 2894
2456 if (startedColliders.Contains(0)) 2895 if (startedColliders.Contains(0))
@@ -2461,6 +2900,35 @@ namespace OpenSim.Region.Framework.Scenes
2461 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); 2900 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2462 } 2901 }
2463 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
2464 public void PhysicsOutOfBounds(Vector3 pos) 2932 public void PhysicsOutOfBounds(Vector3 pos)
2465 { 2933 {
2466 // 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.
@@ -2482,9 +2950,9 @@ namespace OpenSim.Region.Framework.Scenes
2482 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2950 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2483 2951
2484 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2952 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2485 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2953 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2486 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2954 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2487 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2955 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2488 { 2956 {
2489 ParentGroup.AbsolutePosition = newpos; 2957 ParentGroup.AbsolutePosition = newpos;
2490 return; 2958 return;
@@ -2790,6 +3258,14 @@ namespace OpenSim.Region.Framework.Scenes
2790 if (ParentGroup == null) 3258 if (ParentGroup == null)
2791 return; 3259 return;
2792 3260
3261 // Update the "last" values
3262 m_lastPosition = OffsetPosition;
3263 m_lastRotation = RotationOffset;
3264 m_lastVelocity = Velocity;
3265 m_lastAcceleration = Acceleration;
3266 m_lastAngularVelocity = AngularVelocity;
3267 m_lastUpdateSentTime = Environment.TickCount;
3268
2793 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3269 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
2794 { 3270 {
2795 SendFullUpdate(avatar.ControllingClient); 3271 SendFullUpdate(avatar.ControllingClient);
@@ -2848,8 +3324,8 @@ namespace OpenSim.Region.Framework.Scenes
2848 { 3324 {
2849 const float ROTATION_TOLERANCE = 0.01f; 3325 const float ROTATION_TOLERANCE = 0.01f;
2850 const float VELOCITY_TOLERANCE = 0.001f; 3326 const float VELOCITY_TOLERANCE = 0.001f;
2851 const float POSITION_TOLERANCE = 0.05f; 3327 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2852 const int TIME_MS_TOLERANCE = 3000; 3328 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2853 3329
2854 switch (UpdateFlag) 3330 switch (UpdateFlag)
2855 { 3331 {
@@ -2863,17 +3339,10 @@ namespace OpenSim.Region.Framework.Scenes
2863 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || 3339 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) ||
2864 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || 3340 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) ||
2865 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 3341 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
2866 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 3342 Environment.TickCount - m_lastUpdateSentTime > TIME_MS_TOLERANCE)
2867 { 3343 {
2868 SendTerseUpdateToAllClients(); 3344 SendTerseUpdateToAllClients();
2869 3345
2870 // Update the "last" values
2871 m_lastPosition = OffsetPosition;
2872 m_lastRotation = RotationOffset;
2873 m_lastVelocity = Velocity;
2874 m_lastAcceleration = Acceleration;
2875 m_lastAngularVelocity = AngularVelocity;
2876 m_lastTerseSent = Environment.TickCount;
2877 } 3346 }
2878 break; 3347 break;
2879 } 3348 }
@@ -2891,6 +3360,17 @@ namespace OpenSim.Region.Framework.Scenes
2891 /// </summary> 3360 /// </summary>
2892 public void SendTerseUpdateToAllClients() 3361 public void SendTerseUpdateToAllClients()
2893 { 3362 {
3363 if (ParentGroup == null || ParentGroup.Scene == null)
3364 return;
3365
3366 // Update the "last" values
3367 m_lastPosition = OffsetPosition;
3368 m_lastRotation = RotationOffset;
3369 m_lastVelocity = Velocity;
3370 m_lastAcceleration = Acceleration;
3371 m_lastAngularVelocity = AngularVelocity;
3372 m_lastUpdateSentTime = Environment.TickCount;
3373
2894 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3374 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
2895 { 3375 {
2896 SendTerseUpdateToClient(client); 3376 SendTerseUpdateToClient(client);
@@ -2914,10 +3394,13 @@ namespace OpenSim.Region.Framework.Scenes
2914 3394
2915 public void SetBuoyancy(float fvalue) 3395 public void SetBuoyancy(float fvalue)
2916 { 3396 {
2917 PhysicsActor pa = PhysActor; 3397 Buoyancy = fvalue;
2918 3398/*
2919 if (pa != null) 3399 if (PhysActor != null)
2920 pa.Buoyancy = fvalue; 3400 {
3401 PhysActor.Buoyancy = fvalue;
3402 }
3403 */
2921 } 3404 }
2922 3405
2923 public void SetDieAtEdge(bool p) 3406 public void SetDieAtEdge(bool p)
@@ -2933,47 +3416,111 @@ namespace OpenSim.Region.Framework.Scenes
2933 PhysicsActor pa = PhysActor; 3416 PhysicsActor pa = PhysActor;
2934 3417
2935 if (pa != null) 3418 if (pa != null)
2936 pa.FloatOnWater = floatYN == 1; 3419 pa.FloatOnWater = (floatYN == 1);
2937 } 3420 }
2938 3421
2939 public void SetForce(Vector3 force) 3422 public void SetForce(Vector3 force)
2940 { 3423 {
2941 PhysicsActor pa = PhysActor; 3424 Force = force;
3425 }
2942 3426
2943 if (pa != null) 3427 public SOPVehicle VehicleParams
2944 pa.Force = force; 3428 {
3429 get
3430 {
3431 return m_vehicleParams;
3432 }
3433 set
3434 {
3435 m_vehicleParams = value;
3436 }
3437 }
3438
3439
3440 public int VehicleType
3441 {
3442 get
3443 {
3444 if (m_vehicleParams == null)
3445 return (int)Vehicle.TYPE_NONE;
3446 else
3447 return (int)m_vehicleParams.Type;
3448 }
3449 set
3450 {
3451 SetVehicleType(value);
3452 }
2945 } 3453 }
2946 3454
2947 public void SetVehicleType(int type) 3455 public void SetVehicleType(int type)
2948 { 3456 {
2949 PhysicsActor pa = PhysActor; 3457 m_vehicleParams = null;
3458
3459 if (type == (int)Vehicle.TYPE_NONE)
3460 {
3461 if (_parentID ==0 && PhysActor != null)
3462 PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
3463 return;
3464 }
3465 m_vehicleParams = new SOPVehicle();
3466 m_vehicleParams.ProcessTypeChange((Vehicle)type);
3467 {
3468 if (_parentID ==0 && PhysActor != null)
3469 PhysActor.VehicleType = type;
3470 return;
3471 }
3472 }
2950 3473
2951 if (pa != null) 3474 public void SetVehicleFlags(int param, bool remove)
2952 pa.VehicleType = type; 3475 {
3476 if (m_vehicleParams == null)
3477 return;
3478
3479 m_vehicleParams.ProcessVehicleFlags(param, remove);
3480
3481 if (_parentID ==0 && PhysActor != null)
3482 {
3483 PhysActor.VehicleFlags(param, remove);
3484 }
2953 } 3485 }
2954 3486
2955 public void SetVehicleFloatParam(int param, float value) 3487 public void SetVehicleFloatParam(int param, float value)
2956 { 3488 {
2957 PhysicsActor pa = PhysActor; 3489 if (m_vehicleParams == null)
3490 return;
2958 3491
2959 if (pa != null) 3492 m_vehicleParams.ProcessFloatVehicleParam((Vehicle)param, value);
2960 pa.VehicleFloatParam(param, value); 3493
3494 if (_parentID == 0 && PhysActor != null)
3495 {
3496 PhysActor.VehicleFloatParam(param, value);
3497 }
2961 } 3498 }
2962 3499
2963 public void SetVehicleVectorParam(int param, Vector3 value) 3500 public void SetVehicleVectorParam(int param, Vector3 value)
2964 { 3501 {
2965 PhysicsActor pa = PhysActor; 3502 if (m_vehicleParams == null)
3503 return;
2966 3504
2967 if (pa != null) 3505 m_vehicleParams.ProcessVectorVehicleParam((Vehicle)param, value);
2968 pa.VehicleVectorParam(param, value); 3506
3507 if (_parentID == 0 && PhysActor != null)
3508 {
3509 PhysActor.VehicleVectorParam(param, value);
3510 }
2969 } 3511 }
2970 3512
2971 public void SetVehicleRotationParam(int param, Quaternion rotation) 3513 public void SetVehicleRotationParam(int param, Quaternion rotation)
2972 { 3514 {
2973 PhysicsActor pa = PhysActor; 3515 if (m_vehicleParams == null)
3516 return;
2974 3517
2975 if (pa != null) 3518 m_vehicleParams.ProcessRotationVehicleParam((Vehicle)param, rotation);
2976 pa.VehicleRotationParam(param, rotation); 3519
3520 if (_parentID == 0 && PhysActor != null)
3521 {
3522 PhysActor.VehicleRotationParam(param, rotation);
3523 }
2977 } 3524 }
2978 3525
2979 /// <summary> 3526 /// <summary>
@@ -3174,14 +3721,6 @@ namespace OpenSim.Region.Framework.Scenes
3174 hasProfileCut = hasDimple; // is it the same thing? 3721 hasProfileCut = hasDimple; // is it the same thing?
3175 } 3722 }
3176 3723
3177 public void SetVehicleFlags(int param, bool remove)
3178 {
3179 PhysicsActor pa = PhysActor;
3180
3181 if (pa != null)
3182 pa.VehicleFlags(param, remove);
3183 }
3184
3185 public void SetGroup(UUID groupID, IClientAPI client) 3724 public void SetGroup(UUID groupID, IClientAPI client)
3186 { 3725 {
3187 // Scene.AddNewPrims() calls with client == null so can't use this. 3726 // Scene.AddNewPrims() calls with client == null so can't use this.
@@ -3285,71 +3824,20 @@ namespace OpenSim.Region.Framework.Scenes
3285 { 3824 {
3286 ParentGroup.stopMoveToTarget(); 3825 ParentGroup.stopMoveToTarget();
3287 3826
3288 ParentGroup.ScheduleGroupForTerseUpdate(); 3827// ParentGroup.ScheduleGroupForTerseUpdate();
3289 //ParentGroup.ScheduleGroupForFullUpdate(); 3828 //ParentGroup.ScheduleGroupForFullUpdate();
3290 } 3829 }
3291 3830
3292 public void StoreUndoState() 3831 public void StoreUndoState(ObjectChangeType change)
3293 {
3294 StoreUndoState(false);
3295 }
3296
3297 public void StoreUndoState(bool forGroup)
3298 { 3832 {
3299 if (ParentGroup == null || ParentGroup.Scene == null) 3833 if (m_UndoRedo == null)
3300 return; 3834 m_UndoRedo = new UndoRedoState(5);
3301
3302 if (Undoing)
3303 {
3304// m_log.DebugFormat(
3305// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3306 return;
3307 }
3308
3309 if (IgnoreUndoUpdate)
3310 {
3311// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3312 return;
3313 }
3314 3835
3315 lock (m_undo) 3836 lock (m_UndoRedo)
3316 { 3837 {
3317 if (m_undo.Count > 0) 3838 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3318 {
3319 UndoState last = m_undo[m_undo.Count - 1];
3320 if (last != null)
3321 {
3322 // TODO: May need to fix for group comparison
3323 if (last.Compare(this))
3324 {
3325// m_log.DebugFormat(
3326// "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3327// Name, LocalId, m_undo.Count);
3328
3329 return;
3330 }
3331 }
3332 }
3333
3334// m_log.DebugFormat(
3335// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3336// Name, LocalId, forGroup, m_undo.Count);
3337
3338 if (ParentGroup.Scene.MaxUndoCount > 0)
3339 { 3839 {
3340 UndoState nUndo = new UndoState(this, forGroup); 3840 m_UndoRedo.StoreUndo(this, change);
3341
3342 m_undo.Add(nUndo);
3343
3344 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3345 m_undo.RemoveAt(0);
3346
3347 if (m_redo.Count > 0)
3348 m_redo.Clear();
3349
3350// m_log.DebugFormat(
3351// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3352// Name, LocalId, forGroup, m_undo.Count);
3353 } 3841 }
3354 } 3842 }
3355 } 3843 }
@@ -3361,88 +3849,46 @@ namespace OpenSim.Region.Framework.Scenes
3361 { 3849 {
3362 get 3850 get
3363 { 3851 {
3364 lock (m_undo) 3852 if (m_UndoRedo == null)
3365 return m_undo.Count; 3853 return 0;
3854 return m_UndoRedo.Count;
3366 } 3855 }
3367 } 3856 }
3368 3857
3369 public void Undo() 3858 public void Undo()
3370 { 3859 {
3371 lock (m_undo) 3860 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3372 { 3861 return;
3373// m_log.DebugFormat(
3374// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3375// Name, LocalId, m_undo.Count);
3376
3377 if (m_undo.Count > 0)
3378 {
3379 UndoState goback = m_undo[m_undo.Count - 1];
3380 m_undo.RemoveAt(m_undo.Count - 1);
3381
3382 UndoState nUndo = null;
3383
3384 if (ParentGroup.Scene.MaxUndoCount > 0)
3385 {
3386 nUndo = new UndoState(this, goback.ForGroup);
3387 }
3388
3389 goback.PlaybackState(this);
3390
3391 if (nUndo != null)
3392 {
3393 m_redo.Add(nUndo);
3394
3395 if (m_redo.Count > ParentGroup.Scene.MaxUndoCount)
3396 m_redo.RemoveAt(0);
3397 }
3398 }
3399 3862
3400// m_log.DebugFormat( 3863 lock (m_UndoRedo)
3401// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3864 {
3402// Name, LocalId, m_undo.Count); 3865 Undoing = true;
3866 m_UndoRedo.Undo(this);
3867 Undoing = false;
3403 } 3868 }
3404 } 3869 }
3405 3870
3406 public void Redo() 3871 public void Redo()
3407 { 3872 {
3408 lock (m_undo) 3873 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3409 { 3874 return;
3410// m_log.DebugFormat(
3411// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3412// Name, LocalId, m_redo.Count);
3413
3414 if (m_redo.Count > 0)
3415 {
3416 UndoState gofwd = m_redo[m_redo.Count - 1];
3417 m_redo.RemoveAt(m_redo.Count - 1);
3418
3419 if (ParentGroup.Scene.MaxUndoCount > 0)
3420 {
3421 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3422
3423 m_undo.Add(nUndo);
3424
3425 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3426 m_undo.RemoveAt(0);
3427 }
3428
3429 gofwd.PlayfwdState(this);
3430 3875
3431// m_log.DebugFormat( 3876 lock (m_UndoRedo)
3432// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3877 {
3433// Name, LocalId, m_redo.Count); 3878 Undoing = true;
3434 } 3879 m_UndoRedo.Redo(this);
3880 Undoing = false;
3435 } 3881 }
3436 } 3882 }
3437 3883
3438 public void ClearUndoState() 3884 public void ClearUndoState()
3439 { 3885 {
3440// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3886 if (m_UndoRedo == null || Undoing)
3887 return;
3441 3888
3442 lock (m_undo) 3889 lock (m_UndoRedo)
3443 { 3890 {
3444 m_undo.Clear(); 3891 m_UndoRedo.Clear();
3445 m_redo.Clear();
3446 } 3892 }
3447 } 3893 }
3448 3894
@@ -3994,7 +4440,7 @@ namespace OpenSim.Region.Framework.Scenes
3994 if (god) 4440 if (god)
3995 { 4441 {
3996 BaseMask = ApplyMask(BaseMask, set, mask); 4442 BaseMask = ApplyMask(BaseMask, set, mask);
3997 Inventory.ApplyGodPermissions(_baseMask); 4443 Inventory.ApplyGodPermissions(BaseMask);
3998 } 4444 }
3999 4445
4000 break; 4446 break;
@@ -4025,7 +4471,7 @@ namespace OpenSim.Region.Framework.Scenes
4025 } 4471 }
4026 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & 4472 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) &
4027 baseMask; 4473 baseMask;
4028 // Prevent the client from creating no mod, no copy 4474 // Prevent the client from creating no copy, no transfer
4029 // objects 4475 // objects
4030 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0) 4476 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0)
4031 NextOwnerMask |= (uint)PermissionMask.Transfer; 4477 NextOwnerMask |= (uint)PermissionMask.Transfer;
@@ -4043,20 +4489,20 @@ namespace OpenSim.Region.Framework.Scenes
4043 { 4489 {
4044 bool update = false; 4490 bool update = false;
4045 4491
4046 if (BaseMask != source.BaseMask || 4492 uint prevOwnerMask = OwnerMask;
4047 OwnerMask != source.OwnerMask || 4493 uint prevGroupMask = GroupMask;
4048 GroupMask != source.GroupMask || 4494 uint prevEveryoneMask = EveryoneMask;
4049 EveryoneMask != source.EveryoneMask || 4495 uint prevNextOwnerMask = NextOwnerMask;
4050 NextOwnerMask != source.NextOwnerMask)
4051 update = true;
4052 4496
4053 BaseMask = source.BaseMask; 4497 OwnerMask = source.OwnerMask & BaseMask;
4054 OwnerMask = source.OwnerMask; 4498 GroupMask = source.GroupMask & BaseMask;
4055 GroupMask = source.GroupMask; 4499 EveryoneMask = source.EveryoneMask & BaseMask;
4056 EveryoneMask = source.EveryoneMask; 4500 NextOwnerMask = source.NextOwnerMask & BaseMask;
4057 NextOwnerMask = source.NextOwnerMask;
4058 4501
4059 if (update) 4502 if (OwnerMask != prevOwnerMask ||
4503 GroupMask != prevGroupMask ||
4504 EveryoneMask != prevEveryoneMask ||
4505 NextOwnerMask != prevNextOwnerMask)
4060 SendFullUpdateToAllClients(); 4506 SendFullUpdateToAllClients();
4061 } 4507 }
4062 4508
@@ -4107,6 +4553,7 @@ namespace OpenSim.Region.Framework.Scenes
4107 } 4553 }
4108 } 4554 }
4109 4555
4556
4110 public void UpdateExtraPhysics(ExtraPhysicsData physdata) 4557 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4111 { 4558 {
4112 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null) 4559 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
@@ -4134,7 +4581,7 @@ namespace OpenSim.Region.Framework.Scenes
4134 /// <param name="SetTemporary"></param> 4581 /// <param name="SetTemporary"></param>
4135 /// <param name="SetPhantom"></param> 4582 /// <param name="SetPhantom"></param>
4136 /// <param name="SetVD"></param> 4583 /// <param name="SetVD"></param>
4137 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) 4584 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
4138 { 4585 {
4139 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4586 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4140 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4587 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4144,97 +4591,103 @@ namespace OpenSim.Region.Framework.Scenes
4144 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4591 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4145 return; 4592 return;
4146 4593
4147 PhysicsActor pa = PhysActor; 4594 VolumeDetectActive = SetVD;
4148
4149 // Special cases for VD. VD can only be called from a script
4150 // and can't be combined with changes to other states. So we can rely
4151 // that...
4152 // ... if VD is changed, all others are not.
4153 // ... if one of the others is changed, VD is not.
4154 if (SetVD) // VD is active, special logic applies
4155 {
4156 // State machine logic for VolumeDetect
4157 // More logic below
4158 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4159
4160 if (phanReset) // Phantom changes from on to off switch VD off too
4161 {
4162 SetVD = false; // Switch it of for the course of this routine
4163 VolumeDetectActive = false; // and also permanently
4164
4165 if (pa != null)
4166 pa.SetVolumeDetect(0); // Let physics know about it too
4167 }
4168 else
4169 {
4170 // If volumedetect is active we don't want phantom to be applied.
4171 // If this is a new call to VD out of the state "phantom"
4172 // this will also cause the prim to be visible to physics
4173 SetPhantom = false;
4174 }
4175 }
4176 4595
4177 if (UsePhysics && IsJoint()) 4596 // volume detector implies phantom
4178 { 4597 if (VolumeDetectActive)
4179 SetPhantom = true; 4598 SetPhantom = true;
4180 }
4181 4599
4182 if (UsePhysics) 4600 if (UsePhysics)
4183 {
4184 AddFlag(PrimFlags.Physics); 4601 AddFlag(PrimFlags.Physics);
4185 if (!wasUsingPhysics)
4186 {
4187 DoPhysicsPropertyUpdate(UsePhysics, false);
4188 }
4189 }
4190 else 4602 else
4191 {
4192 RemFlag(PrimFlags.Physics); 4603 RemFlag(PrimFlags.Physics);
4193 if (wasUsingPhysics)
4194 {
4195 DoPhysicsPropertyUpdate(UsePhysics, false);
4196 }
4197 }
4198 4604
4199 if (SetPhantom 4605 if (SetPhantom)
4200 || ParentGroup.IsAttachment
4201 || PhysicsShapeType == (byte)PhysShapeType.none
4202 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4203 {
4204 AddFlag(PrimFlags.Phantom); 4606 AddFlag(PrimFlags.Phantom);
4607 else
4608 RemFlag(PrimFlags.Phantom);
4205 4609
4206 if (PhysActor != null) 4610 if (SetTemporary)
4611 AddFlag(PrimFlags.TemporaryOnRez);
4612 else
4613 RemFlag(PrimFlags.TemporaryOnRez);
4614
4615
4616 if (ParentGroup.Scene == null)
4617 return;
4618
4619 PhysicsActor pa = PhysActor;
4620
4621 if (pa != null && building && pa.Building != building)
4622 pa.Building = building;
4623
4624 if ((SetPhantom && !UsePhysics && !SetVD) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
4625 || (Shape.PathCurve == (byte)Extrusion.Flexible))
4626 {
4627 if (pa != null)
4207 { 4628 {
4629 if(wasUsingPhysics)
4630 ParentGroup.Scene.RemovePhysicalPrim(1);
4208 RemoveFromPhysics(); 4631 RemoveFromPhysics();
4209 pa = null;
4210 } 4632 }
4633
4634 Velocity = new Vector3(0, 0, 0);
4635 Acceleration = new Vector3(0, 0, 0);
4636 if (ParentGroup.RootPart == this)
4637 AngularVelocity = new Vector3(0, 0, 0);
4211 } 4638 }
4212 else // Not phantom 4639
4640 else
4213 { 4641 {
4214 RemFlag(PrimFlags.Phantom); 4642 if (ParentGroup.Scene.CollidablePrims)
4215
4216 if (ParentGroup.Scene == null)
4217 return;
4218
4219 if (ParentGroup.Scene.CollidablePrims && pa == null)
4220 { 4643 {
4221 AddToPhysics(UsePhysics, SetPhantom, false); 4644 if (pa == null)
4222 pa = PhysActor; 4645 {
4223 4646 AddToPhysics(UsePhysics, SetPhantom, building, false);
4224 if (pa != null) 4647 pa = PhysActor;
4648/*
4649 if (pa != null)
4650 {
4651 if (
4652// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4653// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4654// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4655// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4656// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4657// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4658 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4659 ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4660 (CollisionSound != UUID.Zero)
4661 )
4662 {
4663 pa.OnCollisionUpdate += PhysicsCollision;
4664 pa.SubscribeEvents(1000);
4665 }
4666 }
4667*/
4668 if (pa != null)
4669 {
4670 pa.SetMaterial(Material);
4671 DoPhysicsPropertyUpdate(UsePhysics, true);
4672 }
4673 }
4674 else // it already has a physical representation
4225 { 4675 {
4226 pa.SetMaterial(Material); 4676 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4227 DoPhysicsPropertyUpdate(UsePhysics, true); 4677/* moved into DoPhysicsPropertyUpdate
4678 if(VolumeDetectActive)
4679 pa.SetVolumeDetect(1);
4680 else
4681 pa.SetVolumeDetect(0);
4682*/
4228 4683
4229 SubscribeForCollisionEvents(); 4684 if (pa.Building != building)
4685 pa.Building = building;
4230 } 4686 }
4231 }
4232 else // it already has a physical representation
4233 {
4234 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4235 }
4236 }
4237 4687
4688 UpdatePhysicsSubscribedEvents();
4689 }
4690 }
4238 if (SetVD) 4691 if (SetVD)
4239 { 4692 {
4240 // If the above logic worked (this is urgent candidate to unit tests!) 4693 // If the above logic worked (this is urgent candidate to unit tests!)
@@ -4248,6 +4701,7 @@ namespace OpenSim.Region.Framework.Scenes
4248 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active 4701 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4249 VolumeDetectActive = true; 4702 VolumeDetectActive = true;
4250 } 4703 }
4704 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4251 } 4705 }
4252 else if (SetVD != wasVD) 4706 else if (SetVD != wasVD)
4253 { 4707 {
@@ -4259,105 +4713,51 @@ namespace OpenSim.Region.Framework.Scenes
4259 RemFlag(PrimFlags.Phantom); 4713 RemFlag(PrimFlags.Phantom);
4260 VolumeDetectActive = false; 4714 VolumeDetectActive = false;
4261 } 4715 }
4262 4716 // and last in case we have a new actor and not building
4263 if (SetTemporary)
4264 {
4265 AddFlag(PrimFlags.TemporaryOnRez);
4266 }
4267 else
4268 {
4269 RemFlag(PrimFlags.TemporaryOnRez);
4270 }
4271
4272 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4273 4717
4274 if (ParentGroup != null) 4718 if (ParentGroup != null)
4275 { 4719 {
4276 ParentGroup.HasGroupChanged = true; 4720 ParentGroup.HasGroupChanged = true;
4277 ScheduleFullUpdate(); 4721 ScheduleFullUpdate();
4278 } 4722 }
4279 4723
4280// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); 4724// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4281 } 4725 }
4282 4726
4283 /// <summary> 4727 /// <summary>
4284 /// Subscribe for physics collision events if needed for scripts and sounds
4285 /// </summary>
4286 public void SubscribeForCollisionEvents()
4287 {
4288 PhysicsActor pa = PhysActor;
4289
4290 if (pa != null)
4291 {
4292 if (
4293 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4294 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4295 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4296 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4297 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4298 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4299 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4300 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4301 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4302 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4303 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4304 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4305 (CollisionSound != UUID.Zero)
4306 )
4307 {
4308 if (!pa.SubscribedEvents())
4309 {
4310 // If not already subscribed for event, set up for a collision event.
4311 pa.OnCollisionUpdate += PhysicsCollision;
4312 pa.SubscribeEvents(1000);
4313 }
4314 }
4315 else
4316 {
4317 // There is no need to be subscribed to collisions so, if subscribed, remove subscription
4318 if (pa.SubscribedEvents())
4319 {
4320 pa.OnCollisionUpdate -= PhysicsCollision;
4321 pa.UnSubscribeEvents();
4322 }
4323 }
4324 }
4325 }
4326
4327 /// <summary>
4328 /// Adds this part to the physics scene. 4728 /// Adds this part to the physics scene.
4729 /// and sets the PhysActor property
4329 /// </summary> 4730 /// </summary>
4330 /// <remarks>This method also sets the PhysActor property.</remarks> 4731 /// <param name="isPhysical">Add this prim as physical.</param>
4331 /// <param name="rigidBody">Add this prim with a rigid body.</param> 4732 /// <param name="isPhantom">Add this prim as phantom.</param>
4332 /// <returns> 4733 /// <param name="building">tells physics to delay full construction of object</param>
4333 /// The physics actor. null if there was a failure. 4734 /// <param name="applyDynamics">applies velocities, force and torque</param>
4334 /// </returns> 4735 private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
4335 private void AddToPhysics(bool isPhysical, bool isPhantom, bool applyDynamics) 4736 {
4336 {
4337 PhysicsActor pa; 4737 PhysicsActor pa;
4338 4738
4339 Vector3 velocity = Velocity; 4739 Vector3 velocity = Velocity;
4340 Vector3 rotationalVelocity = AngularVelocity;; 4740 Vector3 rotationalVelocity = AngularVelocity;;
4341 4741
4342 try 4742 try
4343 { 4743 {
4344 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4744 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4345 string.Format("{0}/{1}", Name, UUID), 4745 string.Format("{0}/{1}", Name, UUID),
4346 Shape, 4746 Shape,
4347 AbsolutePosition, 4747 AbsolutePosition,
4348 Scale, 4748 Scale,
4349 GetWorldRotation(), 4749 GetWorldRotation(),
4350 isPhysical, 4750 isPhysical,
4351 isPhantom, 4751 isPhantom,
4352 PhysicsShapeType, 4752 PhysicsShapeType,
4353 m_localId); 4753 m_localId);
4354 } 4754 }
4355 catch (Exception e) 4755 catch (Exception e)
4356 { 4756 {
4357 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e); 4757 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e);
4358 pa = null; 4758 pa = null;
4359 } 4759 }
4360 4760
4361 if (pa != null) 4761 if (pa != null)
4362 { 4762 {
4363 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 4763 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
@@ -4370,9 +4770,16 @@ namespace OpenSim.Region.Framework.Scenes
4370 4770
4371 if (VolumeDetectActive) // change if not the default only 4771 if (VolumeDetectActive) // change if not the default only
4372 pa.SetVolumeDetect(1); 4772 pa.SetVolumeDetect(1);
4773
4774 if (m_vehicleParams != null && LocalId == ParentGroup.RootPart.LocalId)
4775 m_vehicleParams.SetVehicle(pa);
4776
4373 // we are going to tell rest of code about physics so better have this here 4777 // we are going to tell rest of code about physics so better have this here
4374 PhysActor = pa; 4778 PhysActor = pa;
4375 4779
4780 // DoPhysicsPropertyUpdate(isPhysical, true);
4781 // lets expand it here just with what it really needs to do
4782
4376 if (isPhysical) 4783 if (isPhysical)
4377 { 4784 {
4378 if (ParentGroup.RootPart.KeyframeMotion != null) 4785 if (ParentGroup.RootPart.KeyframeMotion != null)
@@ -4394,19 +4801,34 @@ namespace OpenSim.Region.Framework.Scenes
4394 } 4801 }
4395 } 4802 }
4396 4803
4397 if (applyDynamics) 4804 if (applyDynamics)
4398 // do independent of isphysical so parameters get setted (at least some) 4805 // do independent of isphysical so parameters get setted (at least some)
4399 { 4806 {
4400 Velocity = velocity; 4807 Velocity = velocity;
4401 AngularVelocity = rotationalVelocity; 4808 AngularVelocity = rotationalVelocity;
4402// pa.Velocity = velocity; 4809// pa.Velocity = velocity;
4403 pa.RotationalVelocity = rotationalVelocity; 4810 pa.RotationalVelocity = rotationalVelocity;
4811
4812 // if not vehicle and root part apply force and torque
4813 if ((m_vehicleParams == null || m_vehicleParams.Type == Vehicle.TYPE_NONE)
4814 && LocalId == ParentGroup.RootPart.LocalId)
4815 {
4816 pa.Force = Force;
4817 pa.Torque = Torque;
4818 }
4404 } 4819 }
4405 4820
4406 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); 4821// if (Shape.SculptEntry)
4822// CheckSculptAndLoad();
4823// else
4824 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
4825
4826 if (!building)
4827 pa.Building = false;
4407 } 4828 }
4408 4829
4409 PhysActor = pa; 4830 PhysActor = pa;
4831
4410 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this); 4832 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this);
4411 } 4833 }
4412 4834
@@ -4415,14 +4837,21 @@ namespace OpenSim.Region.Framework.Scenes
4415 /// </summary> 4837 /// </summary>
4416 /// <remarks> 4838 /// <remarks>
4417 /// This isn't the same as turning off physical, since even without being physical the prim has a physics 4839 /// This isn't the same as turning off physical, since even without being physical the prim has a physics
4418 /// representation for collision detection. Rather, this would be used in situations such as making a prim 4840 /// representation for collision detection.
4419 /// phantom.
4420 /// </remarks> 4841 /// </remarks>
4421 public void RemoveFromPhysics() 4842 public void RemoveFromPhysics()
4422 { 4843 {
4423 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this); 4844 PhysicsActor pa = PhysActor;
4424 if (ParentGroup.Scene.PhysicsScene != null) 4845 if (pa != null)
4425 ParentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 4846 {
4847 pa.OnCollisionUpdate -= PhysicsCollision;
4848 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
4849 pa.OnOutOfBounds -= PhysicsOutOfBounds;
4850
4851 ParentGroup.Scene.PhysicsScene.RemovePrim(pa);
4852
4853 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this);
4854 }
4426 PhysActor = null; 4855 PhysActor = null;
4427 } 4856 }
4428 4857
@@ -4554,6 +4983,8 @@ namespace OpenSim.Region.Framework.Scenes
4554 { 4983 {
4555// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); 4984// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4556 4985
4986 return;
4987
4557 if (ParentGroup.IsDeleted) 4988 if (ParentGroup.IsDeleted)
4558 return; 4989 return;
4559 4990
@@ -4677,6 +5108,44 @@ namespace OpenSim.Region.Framework.Scenes
4677 } 5108 }
4678 } 5109 }
4679 5110
5111
5112 private void UpdatePhysicsSubscribedEvents()
5113 {
5114 PhysicsActor pa = PhysActor;
5115 if (pa == null)
5116 return;
5117
5118 pa.OnCollisionUpdate -= PhysicsCollision;
5119
5120 bool hassound = (!VolumeDetectActive && CollisionSoundType >= 0 && ((Flags & PrimFlags.Physics) != 0));
5121
5122 scriptEvents CombinedEvents = AggregateScriptEvents;
5123
5124 // merge with root part
5125 if (ParentGroup != null && ParentGroup.RootPart != null)
5126 CombinedEvents |= ParentGroup.RootPart.AggregateScriptEvents;
5127
5128 // submit to this part case
5129 if (VolumeDetectActive)
5130 CombinedEvents &= PhyscicsVolumeDtcSubsEvents;
5131 else if ((Flags & PrimFlags.Phantom) != 0)
5132 CombinedEvents &= PhyscicsPhantonSubsEvents;
5133 else
5134 CombinedEvents &= PhysicsNeededSubsEvents;
5135
5136 if (hassound || CombinedEvents != 0)
5137 {
5138 // subscribe to physics updates.
5139 pa.OnCollisionUpdate += PhysicsCollision;
5140 pa.SubscribeEvents(50); // 20 reports per second
5141 }
5142 else
5143 {
5144 pa.UnSubscribeEvents();
5145 }
5146 }
5147
5148
4680 public void aggregateScriptEvents() 5149 public void aggregateScriptEvents()
4681 { 5150 {
4682 if (ParentGroup == null || ParentGroup.RootPart == null) 5151 if (ParentGroup == null || ParentGroup.RootPart == null)
@@ -4713,8 +5182,32 @@ namespace OpenSim.Region.Framework.Scenes
4713 { 5182 {
4714 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; 5183 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop;
4715 } 5184 }
4716 5185/*
4717 SubscribeForCollisionEvents(); 5186 PhysicsActor pa = PhysActor;
5187 if (pa != null)
5188 {
5189 if (
5190// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
5191// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
5192// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
5193// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5194// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5195// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5196 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5197 )
5198 {
5199 // subscribe to physics updates.
5200 pa.OnCollisionUpdate += PhysicsCollision;
5201 pa.SubscribeEvents(1000);
5202 }
5203 else
5204 {
5205 pa.UnSubscribeEvents();
5206 pa.OnCollisionUpdate -= PhysicsCollision;
5207 }
5208 }
5209 */
5210 UpdatePhysicsSubscribedEvents();
4718 5211
4719 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 5212 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4720 //{ 5213 //{
@@ -4906,6 +5399,18 @@ namespace OpenSim.Region.Framework.Scenes
4906 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 5399 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4907 } 5400 }
4908 5401
5402 public void ResetOwnerChangeFlag()
5403 {
5404 List<UUID> inv = Inventory.GetInventoryList();
5405
5406 foreach (UUID itemID in inv)
5407 {
5408 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
5409 item.OwnerChanged = false;
5410 Inventory.UpdateInventoryItem(item, false, false);
5411 }
5412 }
5413
4909 /// <summary> 5414 /// <summary>
4910 /// Record an avatar sitting on this part. 5415 /// Record an avatar sitting on this part.
4911 /// </summary> 5416 /// </summary>