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