aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPart.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs1480
1 files changed, 989 insertions, 491 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 347a2b5..9e644aa 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>
@@ -219,12 +231,25 @@ namespace OpenSim.Region.Framework.Scenes
219 231
220 public double SoundRadius; 232 public double SoundRadius;
221 233
234
222 public uint TimeStampFull; 235 public uint TimeStampFull;
223 236
224 public uint TimeStampLastActivity; // Will be used for AutoReturn 237 public uint TimeStampLastActivity; // Will be used for AutoReturn
225 238
226 public uint TimeStampTerse; 239 public uint TimeStampTerse;
227 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]
228 public int STATUS_ROTATE_X; 253 public int STATUS_ROTATE_X;
229 254
230 public int STATUS_ROTATE_Y; 255 public int STATUS_ROTATE_Y;
@@ -251,8 +276,7 @@ namespace OpenSim.Region.Framework.Scenes
251 276
252 public Vector3 RotationAxis = Vector3.One; 277 public Vector3 RotationAxis = Vector3.One;
253 278
254 public bool VolumeDetectActive; // XmlIgnore set to avoid problems with persistance until I come to care for this 279 public bool VolumeDetectActive;
255 // Certainly this must be a persistant setting finally
256 280
257 public bool IsWaitingForFirstSpinUpdatePacket; 281 public bool IsWaitingForFirstSpinUpdatePacket;
258 282
@@ -292,10 +316,10 @@ namespace OpenSim.Region.Framework.Scenes
292 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 316 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
293 private Vector3 m_sitTargetPosition; 317 private Vector3 m_sitTargetPosition;
294 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
295 private string m_text = String.Empty; 320 private string m_text = String.Empty;
296 private string m_touchName = String.Empty; 321 private string m_touchName = String.Empty;
297 private readonly List<UndoState> m_undo = new List<UndoState>(5); 322 private UndoRedoState m_UndoRedo = null;
298 private readonly List<UndoState> m_redo = new List<UndoState>(5);
299 323
300 private bool m_passTouches = false; 324 private bool m_passTouches = false;
301 private bool m_passCollisions = false; 325 private bool m_passCollisions = false;
@@ -323,14 +347,20 @@ namespace OpenSim.Region.Framework.Scenes
323 protected Vector3 m_lastVelocity; 347 protected Vector3 m_lastVelocity;
324 protected Vector3 m_lastAcceleration; 348 protected Vector3 m_lastAcceleration;
325 protected Vector3 m_lastAngularVelocity; 349 protected Vector3 m_lastAngularVelocity;
326 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;
327 354
328 protected byte m_physicsShapeType = (byte)PhysShapeType.prim; 355 protected byte m_physicsShapeType = (byte)PhysShapeType.prim;
329 protected float m_density = 1000.0f; // in kg/m^3 356 protected float m_density = 1000.0f; // in kg/m^3
330 protected float m_gravitymod = 1.0f; 357 protected float m_gravitymod = 1.0f;
331 protected float m_friction = 0.6f; // wood 358 protected float m_friction = 0.6f; // wood
332 protected float m_bounce = 0.5f; // wood 359 protected float m_bounce = 0.5f; // wood
333 360
361
362 protected bool m_isSelected = false;
363
334 /// <summary> 364 /// <summary>
335 /// Stores media texture data 365 /// Stores media texture data
336 /// </summary> 366 /// </summary>
@@ -342,10 +372,25 @@ namespace OpenSim.Region.Framework.Scenes
342 private Vector3 m_cameraAtOffset; 372 private Vector3 m_cameraAtOffset;
343 private bool m_forceMouselook; 373 private bool m_forceMouselook;
344 374
345 // 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;
346 private UUID m_collisionSound; 378 private UUID m_collisionSound;
347 private float m_collisionSoundVolume; 379 private float m_collisionSoundVolume;
348 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
349 #endregion Fields 394 #endregion Fields
350 395
351// ~SceneObjectPart() 396// ~SceneObjectPart()
@@ -375,6 +420,7 @@ namespace OpenSim.Region.Framework.Scenes
375 // 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
376 // 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
377 m_inventory = new SceneObjectPartInventory(this); 422 m_inventory = new SceneObjectPartInventory(this);
423 LastColSoundSentTime = Util.EnvironmentTickCount();
378 } 424 }
379 425
380 /// <summary> 426 /// <summary>
@@ -389,7 +435,7 @@ namespace OpenSim.Region.Framework.Scenes
389 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 435 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
390 Quaternion rotationOffset, Vector3 offsetPosition) : this() 436 Quaternion rotationOffset, Vector3 offsetPosition) : this()
391 { 437 {
392 m_name = "Primitive"; 438 m_name = "Object";
393 439
394 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 440 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
395 LastOwnerID = CreatorID = OwnerID = ownerID; 441 LastOwnerID = CreatorID = OwnerID = ownerID;
@@ -428,7 +474,7 @@ namespace OpenSim.Region.Framework.Scenes
428 private uint _ownerMask = (uint)(PermissionMask.All | PermissionMask.Export); 474 private uint _ownerMask = (uint)(PermissionMask.All | PermissionMask.Export);
429 private uint _groupMask = (uint)PermissionMask.None; 475 private uint _groupMask = (uint)PermissionMask.None;
430 private uint _everyoneMask = (uint)PermissionMask.None; 476 private uint _everyoneMask = (uint)PermissionMask.None;
431 private uint _nextOwnerMask = (uint)PermissionMask.All; 477 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
432 private PrimFlags _flags = PrimFlags.None; 478 private PrimFlags _flags = PrimFlags.None;
433 private DateTime m_expires; 479 private DateTime m_expires;
434 private DateTime m_rezzed; 480 private DateTime m_rezzed;
@@ -522,12 +568,16 @@ namespace OpenSim.Region.Framework.Scenes
522 } 568 }
523 569
524 /// <value> 570 /// <value>
525 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 571 /// Get the inventory list
526 /// </value> 572 /// </value>
527 public TaskInventoryDictionary TaskInventory 573 public TaskInventoryDictionary TaskInventory
528 { 574 {
529 get { return m_inventory.Items; } 575 get {
530 set { m_inventory.Items = value; } 576 return m_inventory.Items;
577 }
578 set {
579 m_inventory.Items = value;
580 }
531 } 581 }
532 582
533 /// <summary> 583 /// <summary>
@@ -577,20 +627,6 @@ namespace OpenSim.Region.Framework.Scenes
577 } 627 }
578 } 628 }
579 629
580 public byte Material
581 {
582 get { return (byte) m_material; }
583 set
584 {
585 m_material = (Material)value;
586
587 PhysicsActor pa = PhysActor;
588
589 if (pa != null)
590 pa.SetMaterial((int)value);
591 }
592 }
593
594 [XmlIgnore] 630 [XmlIgnore]
595 public bool PassTouches 631 public bool PassTouches
596 { 632 {
@@ -616,6 +652,18 @@ namespace OpenSim.Region.Framework.Scenes
616 } 652 }
617 } 653 }
618 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
619 public Dictionary<int, string> CollisionFilter 667 public Dictionary<int, string> CollisionFilter
620 { 668 {
621 get { return m_CollisionFilter; } 669 get { return m_CollisionFilter; }
@@ -684,14 +732,12 @@ namespace OpenSim.Region.Framework.Scenes
684 set { m_LoopSoundSlavePrims = value; } 732 set { m_LoopSoundSlavePrims = value; }
685 } 733 }
686 734
687
688 public Byte[] TextureAnimation 735 public Byte[] TextureAnimation
689 { 736 {
690 get { return m_TextureAnimation; } 737 get { return m_TextureAnimation; }
691 set { m_TextureAnimation = value; } 738 set { m_TextureAnimation = value; }
692 } 739 }
693 740
694
695 public Byte[] ParticleSystem 741 public Byte[] ParticleSystem
696 { 742 {
697 get { return m_particleSystem; } 743 get { return m_particleSystem; }
@@ -728,9 +774,12 @@ namespace OpenSim.Region.Framework.Scenes
728 { 774 {
729 // 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.
730 PhysicsActor actor = PhysActor; 776 PhysicsActor actor = PhysActor;
731 // If physical and the root prim of a linkset, the position of the group is what physics thinks. 777 if (ParentID == 0)
732 if (actor != null && ParentID == 0) 778 {
733 m_groupPosition = actor.Position; 779 if (actor != null)
780 m_groupPosition = actor.Position;
781 return m_groupPosition;
782 }
734 783
735 // 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
736 if (ParentGroup.IsAttachment) 785 if (ParentGroup.IsAttachment)
@@ -740,14 +789,16 @@ namespace OpenSim.Region.Framework.Scenes
740 return sp.AbsolutePosition; 789 return sp.AbsolutePosition;
741 } 790 }
742 791
792 // use root prim's group position. Physics may have updated it
793 if (ParentGroup.RootPart != this)
794 m_groupPosition = ParentGroup.RootPart.GroupPosition;
743 return m_groupPosition; 795 return m_groupPosition;
744 } 796 }
745 set 797 set
746 { 798 {
747 m_groupPosition = value; 799 m_groupPosition = value;
748
749 PhysicsActor actor = PhysActor; 800 PhysicsActor actor = PhysActor;
750 if (actor != null) 801 if (actor != null && ParentGroup.Scene.PhysicsScene != null)
751 { 802 {
752 try 803 try
753 { 804 {
@@ -771,16 +822,6 @@ namespace OpenSim.Region.Framework.Scenes
771 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e); 822 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e);
772 } 823 }
773 } 824 }
774
775 // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
776 if (SitTargetAvatar != UUID.Zero)
777 {
778 ScenePresence avatar;
779 if (ParentGroup.Scene.TryGetScenePresence(SitTargetAvatar, out avatar))
780 {
781 avatar.ParentPosition = GetWorldPosition();
782 }
783 }
784 } 825 }
785 } 826 }
786 827
@@ -789,7 +830,7 @@ namespace OpenSim.Region.Framework.Scenes
789 get { return m_offsetPosition; } 830 get { return m_offsetPosition; }
790 set 831 set
791 { 832 {
792// StoreUndoState(); 833 Vector3 oldpos = m_offsetPosition;
793 m_offsetPosition = value; 834 m_offsetPosition = value;
794 835
795 if (ParentGroup != null && !ParentGroup.IsDeleted) 836 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -801,10 +842,25 @@ namespace OpenSim.Region.Framework.Scenes
801 actor.Orientation = GetWorldRotation(); 842 actor.Orientation = GetWorldRotation();
802 843
803 // Tell the physics engines that this prim changed. 844 // Tell the physics engines that this prim changed.
804 if (ParentGroup.Scene != null) 845 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene != null)
805 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 846 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
806 } 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 }
807 } 862 }
863 TriggerScriptChangedEvent(Changed.POSITION);
808 } 864 }
809 } 865 }
810 866
@@ -855,7 +911,7 @@ namespace OpenSim.Region.Framework.Scenes
855 911
856 set 912 set
857 { 913 {
858 StoreUndoState(); 914// StoreUndoState();
859 m_rotationOffset = value; 915 m_rotationOffset = value;
860 916
861 PhysicsActor actor = PhysActor; 917 PhysicsActor actor = PhysActor;
@@ -943,19 +999,36 @@ namespace OpenSim.Region.Framework.Scenes
943 get 999 get
944 { 1000 {
945 PhysicsActor actor = PhysActor; 1001 PhysicsActor actor = PhysActor;
946 if ((actor != null) && actor.IsPhysical) 1002 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
947 { 1003 {
948 m_angularVelocity = actor.RotationalVelocity; 1004 m_angularVelocity = actor.RotationalVelocity;
949 } 1005 }
950 return m_angularVelocity; 1006 return m_angularVelocity;
951 } 1007 }
952 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 }
953 } 1017 }
954 1018
955 /// <summary></summary> 1019 /// <summary></summary>
956 public Vector3 Acceleration 1020 public Vector3 Acceleration
957 { 1021 {
958 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
959 set { m_acceleration = value; } 1032 set { m_acceleration = value; }
960 } 1033 }
961 1034
@@ -1023,7 +1096,10 @@ namespace OpenSim.Region.Framework.Scenes
1023 public PrimitiveBaseShape Shape 1096 public PrimitiveBaseShape Shape
1024 { 1097 {
1025 get { return m_shape; } 1098 get { return m_shape; }
1026 set { m_shape = value;} 1099 set
1100 {
1101 m_shape = value;
1102 }
1027 } 1103 }
1028 1104
1029 /// <summary> 1105 /// <summary>
@@ -1036,7 +1112,6 @@ namespace OpenSim.Region.Framework.Scenes
1036 { 1112 {
1037 if (m_shape != null) 1113 if (m_shape != null)
1038 { 1114 {
1039 StoreUndoState();
1040 1115
1041 m_shape.Scale = value; 1116 m_shape.Scale = value;
1042 1117
@@ -1104,10 +1179,7 @@ namespace OpenSim.Region.Framework.Scenes
1104 { 1179 {
1105 get 1180 get
1106 { 1181 {
1107 if (ParentGroup.IsAttachment) 1182 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
1108 return GroupPosition;
1109
1110 return m_offsetPosition + m_groupPosition;
1111 } 1183 }
1112 } 1184 }
1113 1185
@@ -1276,6 +1348,13 @@ namespace OpenSim.Region.Framework.Scenes
1276 _flags = value; 1348 _flags = value;
1277 } 1349 }
1278 } 1350 }
1351
1352 [XmlIgnore]
1353 public bool IsOccupied // KF If an av is sittingon this prim
1354 {
1355 get { return m_occupied; }
1356 set { m_occupied = value; }
1357 }
1279 1358
1280 /// <summary> 1359 /// <summary>
1281 /// 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 1360 /// 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
@@ -1326,12 +1405,41 @@ namespace OpenSim.Region.Framework.Scenes
1326 set { m_sitAnimation = value; } 1405 set { m_sitAnimation = value; }
1327 } 1406 }
1328 1407
1408 public UUID invalidCollisionSoundUUID = new UUID("ffffffff-ffff-ffff-ffff-ffffffffffff");
1409
1410 // 0 for default collision sounds, -1 for script disabled sound 1 for script defined sound
1411 // runtime thing.. do not persist
1412 [XmlIgnore]
1413 public sbyte CollisionSoundType
1414 {
1415 get
1416 {
1417 return m_collisionSoundType;
1418 }
1419 set
1420 {
1421 m_collisionSoundType = value;
1422 if (value == -1)
1423 m_collisionSound = invalidCollisionSoundUUID;
1424 else if (value == 0)
1425 m_collisionSound = UUID.Zero;
1426 }
1427 }
1428
1329 public UUID CollisionSound 1429 public UUID CollisionSound
1330 { 1430 {
1331 get { return m_collisionSound; } 1431 get { return m_collisionSound; }
1332 set 1432 set
1333 { 1433 {
1334 m_collisionSound = value; 1434 m_collisionSound = value;
1435
1436 if (value == invalidCollisionSoundUUID)
1437 m_collisionSoundType = -1;
1438 else if (value == UUID.Zero)
1439 m_collisionSoundType = 0;
1440 else
1441 m_collisionSoundType = 1;
1442
1335 aggregateScriptEvents(); 1443 aggregateScriptEvents();
1336 } 1444 }
1337 } 1445 }
@@ -1342,6 +1450,125 @@ namespace OpenSim.Region.Framework.Scenes
1342 set { m_collisionSoundVolume = value; } 1450 set { m_collisionSoundVolume = value; }
1343 } 1451 }
1344 1452
1453 public float Buoyancy
1454 {
1455 get
1456 {
1457 if (ParentGroup.RootPart == this)
1458 return m_buoyancy;
1459
1460 return ParentGroup.RootPart.Buoyancy;
1461 }
1462 set
1463 {
1464 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1465 {
1466 ParentGroup.RootPart.Buoyancy = value;
1467 return;
1468 }
1469 m_buoyancy = value;
1470 if (PhysActor != null)
1471 PhysActor.Buoyancy = value;
1472 }
1473 }
1474
1475 public Vector3 Force
1476 {
1477 get
1478 {
1479 if (ParentGroup.RootPart == this)
1480 return m_force;
1481
1482 return ParentGroup.RootPart.Force;
1483 }
1484
1485 set
1486 {
1487 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1488 {
1489 ParentGroup.RootPart.Force = value;
1490 return;
1491 }
1492 m_force = value;
1493 if (PhysActor != null)
1494 PhysActor.Force = value;
1495 }
1496 }
1497
1498 public Vector3 Torque
1499 {
1500 get
1501 {
1502 if (ParentGroup.RootPart == this)
1503 return m_torque;
1504
1505 return ParentGroup.RootPart.Torque;
1506 }
1507
1508 set
1509 {
1510 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1511 {
1512 ParentGroup.RootPart.Torque = value;
1513 return;
1514 }
1515 m_torque = value;
1516 if (PhysActor != null)
1517 PhysActor.Torque = value;
1518 }
1519 }
1520
1521 public byte Material
1522 {
1523 get { return (byte)m_material; }
1524 set
1525 {
1526 if (value >= 0 && value <= (byte)SOPMaterialData.MaxMaterial)
1527 {
1528 bool update = false;
1529
1530 if (m_material != (Material)value)
1531 {
1532 update = true;
1533 m_material = (Material)value;
1534 }
1535
1536 if (m_friction != SOPMaterialData.friction(m_material))
1537 {
1538 update = true;
1539 m_friction = SOPMaterialData.friction(m_material);
1540 }
1541
1542 if (m_bounce != SOPMaterialData.bounce(m_material))
1543 {
1544 update = true;
1545 m_bounce = SOPMaterialData.bounce(m_material);
1546 }
1547
1548 if (update)
1549 {
1550 if (PhysActor != null)
1551 {
1552 PhysActor.SetMaterial((int)value);
1553 }
1554 if(ParentGroup != null)
1555 ParentGroup.HasGroupChanged = true;
1556 ScheduleFullUpdateIfNone();
1557 UpdatePhysRequired = true;
1558 }
1559 }
1560 }
1561 }
1562
1563 // not a propriety to move to methods place later
1564 private bool HasMesh()
1565 {
1566 if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh))
1567 return true;
1568 return false;
1569 }
1570
1571 // not a propriety to move to methods place later
1345 public byte DefaultPhysicsShapeType() 1572 public byte DefaultPhysicsShapeType()
1346 { 1573 {
1347 byte type; 1574 byte type;
@@ -1354,6 +1581,65 @@ namespace OpenSim.Region.Framework.Scenes
1354 return type; 1581 return type;
1355 } 1582 }
1356 1583
1584 [XmlIgnore]
1585 public bool UsesComplexCost
1586 {
1587 get
1588 {
1589 byte pst = PhysicsShapeType;
1590 if(pst == (byte) PhysShapeType.none || pst == (byte) PhysShapeType.convex || HasMesh())
1591 return true;
1592 return false;
1593 }
1594 }
1595
1596 [XmlIgnore]
1597 public float PhysicsCost
1598 {
1599 get
1600 {
1601 if(PhysicsShapeType == (byte)PhysShapeType.none)
1602 return 0;
1603
1604 float cost = 0.1f;
1605 if (PhysActor != null)
1606 cost = PhysActor.PhysicsCost;
1607 else
1608 cost = 0.1f;
1609
1610 if ((Flags & PrimFlags.Physics) != 0)
1611 cost *= (1.0f + 0.01333f * Scale.LengthSquared()); // 0.01333 == 0.04/3
1612 return cost;
1613 }
1614 }
1615
1616 [XmlIgnore]
1617 public float StreamingCost
1618 {
1619 get
1620 {
1621 float cost;
1622 if (PhysActor != null)
1623 cost = PhysActor.StreamCost;
1624 else
1625 cost = 1.0f;
1626 return 1.0f;
1627 }
1628 }
1629
1630 [XmlIgnore]
1631 public float SimulationCost
1632 {
1633 get
1634 {
1635 // ignoring scripts. Don't like considering them for this
1636 if((Flags & PrimFlags.Physics) != 0)
1637 return 1.0f;
1638
1639 return 0.5f;
1640 }
1641 }
1642
1357 public byte PhysicsShapeType 1643 public byte PhysicsShapeType
1358 { 1644 {
1359 get { return m_physicsShapeType; } 1645 get { return m_physicsShapeType; }
@@ -1387,11 +1673,14 @@ namespace OpenSim.Region.Framework.Scenes
1387 } 1673 }
1388 else if (PhysActor == null) 1674 else if (PhysActor == null)
1389 { 1675 {
1390 ApplyPhysics((uint)Flags, VolumeDetectActive); 1676 ApplyPhysics((uint)Flags, VolumeDetectActive, false);
1677 UpdatePhysicsSubscribedEvents();
1391 } 1678 }
1392 else 1679 else
1393 { 1680 {
1394 PhysActor.PhysicsShapeType = m_physicsShapeType; 1681 PhysActor.PhysicsShapeType = m_physicsShapeType;
1682// if (Shape.SculptEntry)
1683// CheckSculptAndLoad();
1395 } 1684 }
1396 1685
1397 if (ParentGroup != null) 1686 if (ParentGroup != null)
@@ -1493,6 +1782,7 @@ namespace OpenSim.Region.Framework.Scenes
1493 } 1782 }
1494 } 1783 }
1495 1784
1785
1496 #endregion Public Properties with only Get 1786 #endregion Public Properties with only Get
1497 1787
1498 private uint ApplyMask(uint val, bool set, uint mask) 1788 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1638,6 +1928,61 @@ namespace OpenSim.Region.Framework.Scenes
1638 } 1928 }
1639 } 1929 }
1640 1930
1931 // SetVelocity for LSL llSetVelocity.. may need revision if having other uses in future
1932 public void SetVelocity(Vector3 pVel, bool localGlobalTF)
1933 {
1934 if (ParentGroup == null || ParentGroup.IsDeleted)
1935 return;
1936
1937 if (ParentGroup.IsAttachment)
1938 return; // don't work on attachments (for now ??)
1939
1940 SceneObjectPart root = ParentGroup.RootPart;
1941
1942 if (root.VehicleType != (int)Vehicle.TYPE_NONE) // don't mess with vehicles
1943 return;
1944
1945 PhysicsActor pa = root.PhysActor;
1946
1947 if (pa == null || !pa.IsPhysical)
1948 return;
1949
1950 if (localGlobalTF)
1951 {
1952 pVel = pVel * GetWorldRotation();
1953 }
1954
1955 ParentGroup.Velocity = pVel;
1956 }
1957
1958 // SetAngularVelocity for LSL llSetAngularVelocity.. may need revision if having other uses in future
1959 public void SetAngularVelocity(Vector3 pAngVel, bool localGlobalTF)
1960 {
1961 if (ParentGroup == null || ParentGroup.IsDeleted)
1962 return;
1963
1964 if (ParentGroup.IsAttachment)
1965 return; // don't work on attachments (for now ??)
1966
1967 SceneObjectPart root = ParentGroup.RootPart;
1968
1969 if (root.VehicleType != (int)Vehicle.TYPE_NONE) // don't mess with vehicles
1970 return;
1971
1972 PhysicsActor pa = root.PhysActor;
1973
1974 if (pa == null || !pa.IsPhysical)
1975 return;
1976
1977 if (localGlobalTF)
1978 {
1979 pAngVel = pAngVel * GetWorldRotation();
1980 }
1981
1982 root.AngularVelocity = pAngVel;
1983 }
1984
1985
1641 /// <summary> 1986 /// <summary>
1642 /// hook to the physics scene to apply angular impulse 1987 /// hook to the physics scene to apply angular impulse
1643 /// This is sent up to the group, which then finds the root prim 1988 /// This is sent up to the group, which then finds the root prim
@@ -1658,7 +2003,7 @@ namespace OpenSim.Region.Framework.Scenes
1658 impulse = newimpulse; 2003 impulse = newimpulse;
1659 } 2004 }
1660 2005
1661 ParentGroup.applyAngularImpulse(impulse); 2006 ParentGroup.ApplyAngularImpulse(impulse);
1662 } 2007 }
1663 2008
1664 /// <summary> 2009 /// <summary>
@@ -1668,20 +2013,24 @@ namespace OpenSim.Region.Framework.Scenes
1668 /// </summary> 2013 /// </summary>
1669 /// <param name="impulsei">Vector force</param> 2014 /// <param name="impulsei">Vector force</param>
1670 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> 2015 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
1671 public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF) 2016
2017 // this is actualy Set Torque.. keeping naming so not to edit lslapi also
2018 public void SetAngularImpulse(Vector3 torquei, bool localGlobalTF)
1672 { 2019 {
1673 Vector3 impulse = impulsei; 2020 Vector3 torque = torquei;
1674 2021
1675 if (localGlobalTF) 2022 if (localGlobalTF)
1676 { 2023 {
2024/*
1677 Quaternion grot = GetWorldRotation(); 2025 Quaternion grot = GetWorldRotation();
1678 Quaternion AXgrot = grot; 2026 Quaternion AXgrot = grot;
1679 Vector3 AXimpulsei = impulsei; 2027 Vector3 AXimpulsei = impulsei;
1680 Vector3 newimpulse = AXimpulsei * AXgrot; 2028 Vector3 newimpulse = AXimpulsei * AXgrot;
1681 impulse = newimpulse; 2029 */
2030 torque *= GetWorldRotation();
1682 } 2031 }
1683 2032
1684 ParentGroup.setAngularImpulse(impulse); 2033 Torque = torque;
1685 } 2034 }
1686 2035
1687 /// <summary> 2036 /// <summary>
@@ -1689,7 +2038,9 @@ namespace OpenSim.Region.Framework.Scenes
1689 /// </summary> 2038 /// </summary>
1690 /// <param name="rootObjectFlags"></param> 2039 /// <param name="rootObjectFlags"></param>
1691 /// <param name="VolumeDetectActive"></param> 2040 /// <param name="VolumeDetectActive"></param>
1692 public void ApplyPhysics(uint rootObjectFlags, bool _VolumeDetectActive) 2041 /// <param name="building"></param>
2042
2043 public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building)
1693 { 2044 {
1694 VolumeDetectActive = _VolumeDetectActive; 2045 VolumeDetectActive = _VolumeDetectActive;
1695 2046
@@ -1699,8 +2050,8 @@ namespace OpenSim.Region.Framework.Scenes
1699 if (PhysicsShapeType == (byte)PhysShapeType.none) 2050 if (PhysicsShapeType == (byte)PhysShapeType.none)
1700 return; 2051 return;
1701 2052
1702 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 2053 bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0;
1703 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 2054 bool isPhantom = (_ObjectFlags & (uint)PrimFlags.Phantom) != 0;
1704 2055
1705 if (_VolumeDetectActive) 2056 if (_VolumeDetectActive)
1706 isPhantom = true; 2057 isPhantom = true;
@@ -1714,7 +2065,8 @@ namespace OpenSim.Region.Framework.Scenes
1714 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment 2065 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment
1715 && !(Shape.PathCurve == (byte)Extrusion.Flexible)) 2066 && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1716 { 2067 {
1717 AddToPhysics(isPhysical, isPhantom, isPhysical); 2068 AddToPhysics(isPhysical, isPhantom, building, isPhysical);
2069 UpdatePhysicsSubscribedEvents(); // not sure if appliable here
1718 } 2070 }
1719 else 2071 else
1720 PhysActor = null; // just to be sure 2072 PhysActor = null; // just to be sure
@@ -1769,6 +2121,12 @@ namespace OpenSim.Region.Framework.Scenes
1769 dupe.Category = Category; 2121 dupe.Category = Category;
1770 dupe.m_rezzed = m_rezzed; 2122 dupe.m_rezzed = m_rezzed;
1771 2123
2124 dupe.m_UndoRedo = null;
2125 dupe.m_isSelected = false;
2126
2127 dupe.IgnoreUndoUpdate = false;
2128 dupe.Undoing = false;
2129
1772 dupe.m_inventory = new SceneObjectPartInventory(dupe); 2130 dupe.m_inventory = new SceneObjectPartInventory(dupe);
1773 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone(); 2131 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone();
1774 2132
@@ -1784,6 +2142,7 @@ namespace OpenSim.Region.Framework.Scenes
1784 2142
1785 // Move afterwards ResetIDs as it clears the localID 2143 // Move afterwards ResetIDs as it clears the localID
1786 dupe.LocalId = localID; 2144 dupe.LocalId = localID;
2145
1787 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 2146 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1788 dupe.LastOwnerID = OwnerID; 2147 dupe.LastOwnerID = OwnerID;
1789 2148
@@ -1791,6 +2150,9 @@ namespace OpenSim.Region.Framework.Scenes
1791 Array.Copy(Shape.ExtraParams, extraP, extraP.Length); 2150 Array.Copy(Shape.ExtraParams, extraP, extraP.Length);
1792 dupe.Shape.ExtraParams = extraP; 2151 dupe.Shape.ExtraParams = extraP;
1793 2152
2153 // safeguard actual copy is done in sog.copy
2154 dupe.KeyframeMotion = null;
2155
1794 dupe.DynAttrs.CopyFrom(DynAttrs); 2156 dupe.DynAttrs.CopyFrom(DynAttrs);
1795 2157
1796 if (userExposed) 2158 if (userExposed)
@@ -1804,8 +2166,12 @@ namespace OpenSim.Region.Framework.Scenes
1804*/ 2166*/
1805 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 2167 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
1806 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 2168 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
2169// dupe.UpdatePhysicsSubscribedEvents(); // not sure...
1807 } 2170 }
1808 2171
2172 if (dupe.PhysActor != null)
2173 dupe.PhysActor.LocalID = localID;
2174
1809 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 2175 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1810 2176
1811// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); 2177// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
@@ -1824,10 +2190,10 @@ namespace OpenSim.Region.Framework.Scenes
1824 { 2190 {
1825 if (asset != null) 2191 if (asset != null)
1826 SculptTextureCallback(asset); 2192 SculptTextureCallback(asset);
1827 else 2193// else
1828 m_log.WarnFormat( 2194// m_log.WarnFormat(
1829 "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data", 2195// "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
1830 Name, UUID, id); 2196// Name, UUID, id);
1831 } 2197 }
1832*/ 2198*/
1833 /// <summary> 2199 /// <summary>
@@ -1926,6 +2292,7 @@ namespace OpenSim.Region.Framework.Scenes
1926 2292
1927 /// <summary> 2293 /// <summary>
1928 /// Do a physics propery update for this part. 2294 /// Do a physics propery update for this part.
2295 /// now also updates phantom and volume detector
1929 /// </summary> 2296 /// </summary>
1930 /// <param name="UsePhysics"></param> 2297 /// <param name="UsePhysics"></param>
1931 /// <param name="isNew"></param> 2298 /// <param name="isNew"></param>
@@ -1951,61 +2318,69 @@ namespace OpenSim.Region.Framework.Scenes
1951 { 2318 {
1952 if (pa.IsPhysical) // implies UsePhysics==false for this block 2319 if (pa.IsPhysical) // implies UsePhysics==false for this block
1953 { 2320 {
1954 if (!isNew) 2321 if (!isNew) // implies UsePhysics==false for this block
2322 {
1955 ParentGroup.Scene.RemovePhysicalPrim(1); 2323 ParentGroup.Scene.RemovePhysicalPrim(1);
1956 2324
1957 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 2325 Velocity = new Vector3(0, 0, 0);
1958 pa.OnOutOfBounds -= PhysicsOutOfBounds; 2326 Acceleration = new Vector3(0, 0, 0);
1959 pa.delink(); 2327 if (ParentGroup.RootPart == this)
2328 AngularVelocity = new Vector3(0, 0, 0);
1960 2329
1961 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 2330 if (pa.Phantom && !VolumeDetectActive)
1962 { 2331 {
1963 // destroy all joints connected to this now deactivated body 2332 RemoveFromPhysics();
1964 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); 2333 return;
1965 } 2334 }
1966 2335
1967 // stop client-side interpolation of all joint proxy objects that have just been deleted 2336 pa.IsPhysical = UsePhysics;
1968 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback, 2337 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1969 // which stops client-side interpolation of deactivated joint proxy objects. 2338 pa.OnOutOfBounds -= PhysicsOutOfBounds;
2339 pa.delink();
2340 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
2341 {
2342 // destroy all joints connected to this now deactivated body
2343 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa);
2344 }
2345 }
1970 } 2346 }
1971 2347
1972 if (!UsePhysics && !isNew) 2348 if (pa.IsPhysical != UsePhysics)
1973 { 2349 pa.IsPhysical = UsePhysics;
1974 // reset velocity to 0 on physics switch-off. Without that, the client thinks the
1975 // prim still has velocity and continues to interpolate its position along the old
1976 // velocity-vector.
1977 Velocity = new Vector3(0, 0, 0);
1978 Acceleration = new Vector3(0, 0, 0);
1979 AngularVelocity = new Vector3(0, 0, 0);
1980 //RotationalVelocity = new Vector3(0, 0, 0);
1981 }
1982 2350
1983 pa.IsPhysical = UsePhysics; 2351 if (UsePhysics)
2352 {
2353 if (ParentGroup.RootPart.KeyframeMotion != null)
2354 ParentGroup.RootPart.KeyframeMotion.Stop();
2355 ParentGroup.RootPart.KeyframeMotion = null;
2356 ParentGroup.Scene.AddPhysicalPrim(1);
1984 2357
1985 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 2358 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1986 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 2359 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1987 /// that's not wholesome. Had to make Scene public
1988 //PhysActor = null;
1989 2360
1990 if ((Flags & PrimFlags.Phantom) == 0) 2361 if (ParentID != 0 && ParentID != LocalId)
1991 {
1992 if (UsePhysics)
1993 { 2362 {
1994 ParentGroup.Scene.AddPhysicalPrim(1); 2363 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
1995 2364
1996 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 2365 if (parentPa != null)
1997 pa.OnOutOfBounds += PhysicsOutOfBounds;
1998 if (ParentID != 0 && ParentID != LocalId)
1999 { 2366 {
2000 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; 2367 pa.link(parentPa);
2001
2002 if (parentPa != null)
2003 {
2004 pa.link(parentPa);
2005 }
2006 } 2368 }
2007 } 2369 }
2008 } 2370 }
2371 }
2372
2373 bool phan = ((Flags & PrimFlags.Phantom) != 0);
2374 if (pa.Phantom != phan)
2375 pa.Phantom = phan;
2376
2377// some engines dont' have this check still
2378// if (VolumeDetectActive != pa.IsVolumeDtc)
2379 {
2380 if (VolumeDetectActive)
2381 pa.SetVolumeDetect(1);
2382 else
2383 pa.SetVolumeDetect(0);
2009 } 2384 }
2010 2385
2011 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 2386 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
@@ -2124,42 +2499,63 @@ namespace OpenSim.Region.Framework.Scenes
2124 2499
2125 public Vector3 GetGeometricCenter() 2500 public Vector3 GetGeometricCenter()
2126 { 2501 {
2502 // this is not real geometric center but a average of positions relative to root prim acording to
2503 // http://wiki.secondlife.com/wiki/llGetGeometricCenter
2504 // ignoring tortured prims details since sl also seems to ignore
2505 // so no real use in doing it on physics
2506 if (ParentGroup.IsDeleted)
2507 return new Vector3(0, 0, 0);
2508
2509 return ParentGroup.GetGeometricCenter();
2510 }
2511
2512 public float GetMass()
2513 {
2127 PhysicsActor pa = PhysActor; 2514 PhysicsActor pa = PhysActor;
2128 2515
2129 if (pa != null) 2516 if (pa != null)
2130 return pa.GeometricCenter; 2517 return pa.Mass;
2131 else 2518 else
2132 return Vector3.Zero; 2519 return 0;
2133 } 2520 }
2134 2521
2135 public Vector3 GetCenterOfMass() 2522 public Vector3 GetCenterOfMass()
2136 { 2523 {
2524 if (ParentGroup.RootPart == this)
2525 {
2526 if (ParentGroup.IsDeleted)
2527 return AbsolutePosition;
2528 return ParentGroup.GetCenterOfMass();
2529 }
2530
2137 PhysicsActor pa = PhysActor; 2531 PhysicsActor pa = PhysActor;
2138 2532
2139 if (pa != null) 2533 if (pa != null)
2140 return pa.CenterOfMass; 2534 {
2535 Vector3 tmp = pa.CenterOfMass;
2536 return tmp;
2537 }
2141 else 2538 else
2142 return Vector3.Zero; 2539 return AbsolutePosition;
2143 } 2540 }
2144 2541
2145 public float GetMass() 2542 public Vector3 GetPartCenterOfMass()
2146 { 2543 {
2147 PhysicsActor pa = PhysActor; 2544 PhysicsActor pa = PhysActor;
2148 2545
2149 if (pa != null) 2546 if (pa != null)
2150 return pa.Mass; 2547 {
2548 Vector3 tmp = pa.CenterOfMass;
2549 return tmp;
2550 }
2151 else 2551 else
2152 return 0; 2552 return AbsolutePosition;
2153 } 2553 }
2154 2554
2555
2155 public Vector3 GetForce() 2556 public Vector3 GetForce()
2156 { 2557 {
2157 PhysicsActor pa = PhysActor; 2558 return Force;
2158
2159 if (pa != null)
2160 return pa.Force;
2161 else
2162 return Vector3.Zero;
2163 } 2559 }
2164 2560
2165 /// <summary> 2561 /// <summary>
@@ -2374,15 +2770,25 @@ namespace OpenSim.Region.Framework.Scenes
2374 2770
2375 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify) 2771 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify)
2376 { 2772 {
2377 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0) 2773 bool sendToRoot = true;
2378 {
2379 ColliderArgs LandCollidingMessage = new ColliderArgs();
2380 List<DetectedObject> colliding = new List<DetectedObject>();
2381
2382 colliding.Add(CreateDetObjectForGround());
2383 LandCollidingMessage.Colliders = colliding;
2384 2774
2775 ColliderArgs LandCollidingMessage = new ColliderArgs();
2776 List<DetectedObject> colliding = new List<DetectedObject>();
2777
2778 colliding.Add(CreateDetObjectForGround());
2779 LandCollidingMessage.Colliders = colliding;
2780
2781 if (Inventory.ContainsScripts())
2782 {
2783 if (!PassCollisions)
2784 sendToRoot = false;
2785 }
2786 if ((ScriptEvents & ev) != 0)
2385 notify(LocalId, LandCollidingMessage); 2787 notify(LocalId, LandCollidingMessage);
2788
2789 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0 && sendToRoot)
2790 {
2791 notify(ParentGroup.RootPart.LocalId, LandCollidingMessage);
2386 } 2792 }
2387 } 2793 }
2388 2794
@@ -2398,57 +2804,120 @@ namespace OpenSim.Region.Framework.Scenes
2398 List<uint> endedColliders = new List<uint>(); 2804 List<uint> endedColliders = new List<uint>();
2399 List<uint> startedColliders = new List<uint>(); 2805 List<uint> startedColliders = new List<uint>();
2400 2806
2401 // calculate things that started colliding this time 2807 if (collissionswith.Count == 0)
2402 // and build up list of colliders this time
2403 foreach (uint localid in collissionswith.Keys)
2404 { 2808 {
2405 thisHitColliders.Add(localid); 2809 if (m_lastColliders.Count == 0)
2406 if (!m_lastColliders.Contains(localid)) 2810 return; // nothing to do
2407 startedColliders.Add(localid);
2408 }
2409 2811
2410 // calculate things that ended colliding 2812 foreach (uint localID in m_lastColliders)
2411 foreach (uint localID in m_lastColliders) 2813 {
2412 {
2413 if (!thisHitColliders.Contains(localID))
2414 endedColliders.Add(localID); 2814 endedColliders.Add(localID);
2815 }
2816 m_lastColliders.Clear();
2415 } 2817 }
2416 2818
2417 //add the items that started colliding this time to the last colliders list. 2819 else
2418 foreach (uint localID in startedColliders) 2820 {
2419 m_lastColliders.Add(localID); 2821 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
2822
2823 // calculate things that started colliding this time
2824 // and build up list of colliders this time
2825 if (!VolumeDetectActive && CollisionSoundType >= 0)
2826 {
2827 CollisionForSoundInfo soundinfo;
2828 ContactPoint curcontact;
2420 2829
2421 // remove things that ended colliding from the last colliders list 2830 foreach (uint id in collissionswith.Keys)
2422 foreach (uint localID in endedColliders) 2831 {
2423 m_lastColliders.Remove(localID); 2832 thisHitColliders.Add(id);
2833 if (!m_lastColliders.Contains(id))
2834 {
2835 startedColliders.Add(id);
2424 2836
2425 // play the sound. 2837 curcontact = collissionswith[id];
2426 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) 2838 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
2427 { 2839 {
2428 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>(); 2840 soundinfo = new CollisionForSoundInfo();
2429 if (soundModule != null) 2841 soundinfo.colliderID = id;
2842 soundinfo.position = curcontact.Position;
2843 soundinfo.relativeVel = curcontact.RelativeSpeed;
2844 soundinfolist.Add(soundinfo);
2845 }
2846 }
2847 }
2848 }
2849 else
2850 {
2851 foreach (uint id in collissionswith.Keys)
2852 {
2853 thisHitColliders.Add(id);
2854 if (!m_lastColliders.Contains(id))
2855 startedColliders.Add(id);
2856 }
2857 }
2858
2859 // calculate things that ended colliding
2860 foreach (uint localID in m_lastColliders)
2430 { 2861 {
2431 soundModule.SendSound(UUID, CollisionSound, 2862 if (!thisHitColliders.Contains(localID))
2432 CollisionSoundVolume, true, (byte)0, 0, false, 2863 endedColliders.Add(localID);
2433 false);
2434 } 2864 }
2865
2866 //add the items that started colliding this time to the last colliders list.
2867 foreach (uint localID in startedColliders)
2868 m_lastColliders.Add(localID);
2869
2870 // remove things that ended colliding from the last colliders list
2871 foreach (uint localID in endedColliders)
2872 m_lastColliders.Remove(localID);
2873
2874 // play sounds.
2875 if (soundinfolist.Count > 0)
2876 CollisionSounds.PartCollisionSound(this, soundinfolist);
2435 } 2877 }
2436 2878
2437 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart); 2879 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
2438 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding); 2880 if (!VolumeDetectActive)
2881 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
2439 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); 2882 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
2440 2883
2441 if (startedColliders.Contains(0)) 2884 if (startedColliders.Contains(0))
2442 { 2885 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2443 if (m_lastColliders.Contains(0)) 2886 if (m_lastColliders.Contains(0))
2444 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding); 2887 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding);
2445 else
2446 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2447 }
2448 if (endedColliders.Contains(0)) 2888 if (endedColliders.Contains(0))
2449 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); 2889 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2450 } 2890 }
2451 2891
2892 // The Collision sounds code calls this
2893 public void SendCollisionSound(UUID soundID, double volume, Vector3 position)
2894 {
2895 if (soundID == UUID.Zero)
2896 return;
2897
2898 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>();
2899 if (soundModule == null)
2900 return;
2901
2902 if (volume > 1)
2903 volume = 1;
2904 if (volume < 0)
2905 volume = 0;
2906
2907 int now = Util.EnvironmentTickCount();
2908 if(Util.EnvironmentTickCountSubtract(now,LastColSoundSentTime) <200)
2909 return;
2910
2911 LastColSoundSentTime = now;
2912
2913 UUID ownerID = OwnerID;
2914 UUID objectID = ParentGroup.RootPart.UUID;
2915 UUID parentID = ParentGroup.UUID;
2916 ulong regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle;
2917
2918 soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, 0 );
2919 }
2920
2452 public void PhysicsOutOfBounds(Vector3 pos) 2921 public void PhysicsOutOfBounds(Vector3 pos)
2453 { 2922 {
2454 // Note: This is only being called on the root prim at this time. 2923 // Note: This is only being called on the root prim at this time.
@@ -2470,9 +2939,9 @@ namespace OpenSim.Region.Framework.Scenes
2470 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2939 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2471 2940
2472 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2941 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2473 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2942 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2474 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2943 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2475 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2944 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2476 { 2945 {
2477 ParentGroup.AbsolutePosition = newpos; 2946 ParentGroup.AbsolutePosition = newpos;
2478 return; 2947 return;
@@ -2757,6 +3226,14 @@ namespace OpenSim.Region.Framework.Scenes
2757 if (ParentGroup == null) 3226 if (ParentGroup == null)
2758 return; 3227 return;
2759 3228
3229 // Update the "last" values
3230 m_lastPosition = OffsetPosition;
3231 m_lastRotation = RotationOffset;
3232 m_lastVelocity = Velocity;
3233 m_lastAcceleration = Acceleration;
3234 m_lastAngularVelocity = AngularVelocity;
3235 m_lastUpdateSentTime = Environment.TickCount;
3236
2760 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3237 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
2761 { 3238 {
2762 SendFullUpdate(avatar.ControllingClient); 3239 SendFullUpdate(avatar.ControllingClient);
@@ -2815,8 +3292,8 @@ namespace OpenSim.Region.Framework.Scenes
2815 { 3292 {
2816 const float ROTATION_TOLERANCE = 0.01f; 3293 const float ROTATION_TOLERANCE = 0.01f;
2817 const float VELOCITY_TOLERANCE = 0.001f; 3294 const float VELOCITY_TOLERANCE = 0.001f;
2818 const float POSITION_TOLERANCE = 0.05f; 3295 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2819 const int TIME_MS_TOLERANCE = 3000; 3296 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2820 3297
2821 switch (UpdateFlag) 3298 switch (UpdateFlag)
2822 { 3299 {
@@ -2830,17 +3307,10 @@ namespace OpenSim.Region.Framework.Scenes
2830 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || 3307 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) ||
2831 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || 3308 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) ||
2832 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 3309 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
2833 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 3310 Environment.TickCount - m_lastUpdateSentTime > TIME_MS_TOLERANCE)
2834 { 3311 {
2835 SendTerseUpdateToAllClients(); 3312 SendTerseUpdateToAllClients();
2836 3313
2837 // Update the "last" values
2838 m_lastPosition = OffsetPosition;
2839 m_lastRotation = RotationOffset;
2840 m_lastVelocity = Velocity;
2841 m_lastAcceleration = Acceleration;
2842 m_lastAngularVelocity = AngularVelocity;
2843 m_lastTerseSent = Environment.TickCount;
2844 } 3314 }
2845 break; 3315 break;
2846 } 3316 }
@@ -2858,6 +3328,17 @@ namespace OpenSim.Region.Framework.Scenes
2858 /// </summary> 3328 /// </summary>
2859 public void SendTerseUpdateToAllClients() 3329 public void SendTerseUpdateToAllClients()
2860 { 3330 {
3331 if (ParentGroup == null || ParentGroup.Scene == null)
3332 return;
3333
3334 // Update the "last" values
3335 m_lastPosition = OffsetPosition;
3336 m_lastRotation = RotationOffset;
3337 m_lastVelocity = Velocity;
3338 m_lastAcceleration = Acceleration;
3339 m_lastAngularVelocity = AngularVelocity;
3340 m_lastUpdateSentTime = Environment.TickCount;
3341
2861 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3342 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
2862 { 3343 {
2863 SendTerseUpdateToClient(client); 3344 SendTerseUpdateToClient(client);
@@ -2881,10 +3362,13 @@ namespace OpenSim.Region.Framework.Scenes
2881 3362
2882 public void SetBuoyancy(float fvalue) 3363 public void SetBuoyancy(float fvalue)
2883 { 3364 {
2884 PhysicsActor pa = PhysActor; 3365 Buoyancy = fvalue;
2885 3366/*
2886 if (pa != null) 3367 if (PhysActor != null)
2887 pa.Buoyancy = fvalue; 3368 {
3369 PhysActor.Buoyancy = fvalue;
3370 }
3371 */
2888 } 3372 }
2889 3373
2890 public void SetDieAtEdge(bool p) 3374 public void SetDieAtEdge(bool p)
@@ -2900,47 +3384,111 @@ namespace OpenSim.Region.Framework.Scenes
2900 PhysicsActor pa = PhysActor; 3384 PhysicsActor pa = PhysActor;
2901 3385
2902 if (pa != null) 3386 if (pa != null)
2903 pa.FloatOnWater = floatYN == 1; 3387 pa.FloatOnWater = (floatYN == 1);
2904 } 3388 }
2905 3389
2906 public void SetForce(Vector3 force) 3390 public void SetForce(Vector3 force)
2907 { 3391 {
2908 PhysicsActor pa = PhysActor; 3392 Force = force;
3393 }
2909 3394
2910 if (pa != null) 3395 public SOPVehicle VehicleParams
2911 pa.Force = force; 3396 {
3397 get
3398 {
3399 return m_vehicleParams;
3400 }
3401 set
3402 {
3403 m_vehicleParams = value;
3404 }
3405 }
3406
3407
3408 public int VehicleType
3409 {
3410 get
3411 {
3412 if (m_vehicleParams == null)
3413 return (int)Vehicle.TYPE_NONE;
3414 else
3415 return (int)m_vehicleParams.Type;
3416 }
3417 set
3418 {
3419 SetVehicleType(value);
3420 }
2912 } 3421 }
2913 3422
2914 public void SetVehicleType(int type) 3423 public void SetVehicleType(int type)
2915 { 3424 {
2916 PhysicsActor pa = PhysActor; 3425 m_vehicleParams = null;
3426
3427 if (type == (int)Vehicle.TYPE_NONE)
3428 {
3429 if (_parentID ==0 && PhysActor != null)
3430 PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
3431 return;
3432 }
3433 m_vehicleParams = new SOPVehicle();
3434 m_vehicleParams.ProcessTypeChange((Vehicle)type);
3435 {
3436 if (_parentID ==0 && PhysActor != null)
3437 PhysActor.VehicleType = type;
3438 return;
3439 }
3440 }
2917 3441
2918 if (pa != null) 3442 public void SetVehicleFlags(int param, bool remove)
2919 pa.VehicleType = type; 3443 {
3444 if (m_vehicleParams == null)
3445 return;
3446
3447 m_vehicleParams.ProcessVehicleFlags(param, remove);
3448
3449 if (_parentID ==0 && PhysActor != null)
3450 {
3451 PhysActor.VehicleFlags(param, remove);
3452 }
2920 } 3453 }
2921 3454
2922 public void SetVehicleFloatParam(int param, float value) 3455 public void SetVehicleFloatParam(int param, float value)
2923 { 3456 {
2924 PhysicsActor pa = PhysActor; 3457 if (m_vehicleParams == null)
3458 return;
2925 3459
2926 if (pa != null) 3460 m_vehicleParams.ProcessFloatVehicleParam((Vehicle)param, value);
2927 pa.VehicleFloatParam(param, value); 3461
3462 if (_parentID == 0 && PhysActor != null)
3463 {
3464 PhysActor.VehicleFloatParam(param, value);
3465 }
2928 } 3466 }
2929 3467
2930 public void SetVehicleVectorParam(int param, Vector3 value) 3468 public void SetVehicleVectorParam(int param, Vector3 value)
2931 { 3469 {
2932 PhysicsActor pa = PhysActor; 3470 if (m_vehicleParams == null)
3471 return;
2933 3472
2934 if (pa != null) 3473 m_vehicleParams.ProcessVectorVehicleParam((Vehicle)param, value);
2935 pa.VehicleVectorParam(param, value); 3474
3475 if (_parentID == 0 && PhysActor != null)
3476 {
3477 PhysActor.VehicleVectorParam(param, value);
3478 }
2936 } 3479 }
2937 3480
2938 public void SetVehicleRotationParam(int param, Quaternion rotation) 3481 public void SetVehicleRotationParam(int param, Quaternion rotation)
2939 { 3482 {
2940 PhysicsActor pa = PhysActor; 3483 if (m_vehicleParams == null)
3484 return;
2941 3485
2942 if (pa != null) 3486 m_vehicleParams.ProcessRotationVehicleParam((Vehicle)param, rotation);
2943 pa.VehicleRotationParam(param, rotation); 3487
3488 if (_parentID == 0 && PhysActor != null)
3489 {
3490 PhysActor.VehicleRotationParam(param, rotation);
3491 }
2944 } 3492 }
2945 3493
2946 /// <summary> 3494 /// <summary>
@@ -3141,14 +3689,6 @@ namespace OpenSim.Region.Framework.Scenes
3141 hasProfileCut = hasDimple; // is it the same thing? 3689 hasProfileCut = hasDimple; // is it the same thing?
3142 } 3690 }
3143 3691
3144 public void SetVehicleFlags(int param, bool remove)
3145 {
3146 PhysicsActor pa = PhysActor;
3147
3148 if (pa != null)
3149 pa.VehicleFlags(param, remove);
3150 }
3151
3152 public void SetGroup(UUID groupID, IClientAPI client) 3692 public void SetGroup(UUID groupID, IClientAPI client)
3153 { 3693 {
3154 // Scene.AddNewPrims() calls with client == null so can't use this. 3694 // Scene.AddNewPrims() calls with client == null so can't use this.
@@ -3252,71 +3792,20 @@ namespace OpenSim.Region.Framework.Scenes
3252 { 3792 {
3253 ParentGroup.stopMoveToTarget(); 3793 ParentGroup.stopMoveToTarget();
3254 3794
3255 ParentGroup.ScheduleGroupForTerseUpdate(); 3795// ParentGroup.ScheduleGroupForTerseUpdate();
3256 //ParentGroup.ScheduleGroupForFullUpdate(); 3796 //ParentGroup.ScheduleGroupForFullUpdate();
3257 } 3797 }
3258 3798
3259 public void StoreUndoState() 3799 public void StoreUndoState(ObjectChangeType change)
3260 { 3800 {
3261 StoreUndoState(false); 3801 if (m_UndoRedo == null)
3262 } 3802 m_UndoRedo = new UndoRedoState(5);
3263 3803
3264 public void StoreUndoState(bool forGroup) 3804 lock (m_UndoRedo)
3265 {
3266 if (ParentGroup == null || ParentGroup.Scene == null)
3267 return;
3268
3269 if (Undoing)
3270 {
3271// m_log.DebugFormat(
3272// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3273 return;
3274 }
3275
3276 if (IgnoreUndoUpdate)
3277 {
3278// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3279 return;
3280 }
3281
3282 lock (m_undo)
3283 { 3805 {
3284 if (m_undo.Count > 0) 3806 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3285 { 3807 {
3286 UndoState last = m_undo[m_undo.Count - 1]; 3808 m_UndoRedo.StoreUndo(this, change);
3287 if (last != null)
3288 {
3289 // TODO: May need to fix for group comparison
3290 if (last.Compare(this))
3291 {
3292// m_log.DebugFormat(
3293// "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3294// Name, LocalId, m_undo.Count);
3295
3296 return;
3297 }
3298 }
3299 }
3300
3301// m_log.DebugFormat(
3302// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3303// Name, LocalId, forGroup, m_undo.Count);
3304
3305 if (ParentGroup.Scene.MaxUndoCount > 0)
3306 {
3307 UndoState nUndo = new UndoState(this, forGroup);
3308
3309 m_undo.Add(nUndo);
3310
3311 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3312 m_undo.RemoveAt(0);
3313
3314 if (m_redo.Count > 0)
3315 m_redo.Clear();
3316
3317// m_log.DebugFormat(
3318// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3319// Name, LocalId, forGroup, m_undo.Count);
3320 } 3809 }
3321 } 3810 }
3322 } 3811 }
@@ -3328,88 +3817,46 @@ namespace OpenSim.Region.Framework.Scenes
3328 { 3817 {
3329 get 3818 get
3330 { 3819 {
3331 lock (m_undo) 3820 if (m_UndoRedo == null)
3332 return m_undo.Count; 3821 return 0;
3822 return m_UndoRedo.Count;
3333 } 3823 }
3334 } 3824 }
3335 3825
3336 public void Undo() 3826 public void Undo()
3337 { 3827 {
3338 lock (m_undo) 3828 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3339 { 3829 return;
3340// m_log.DebugFormat(
3341// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3342// Name, LocalId, m_undo.Count);
3343
3344 if (m_undo.Count > 0)
3345 {
3346 UndoState goback = m_undo[m_undo.Count - 1];
3347 m_undo.RemoveAt(m_undo.Count - 1);
3348
3349 UndoState nUndo = null;
3350
3351 if (ParentGroup.Scene.MaxUndoCount > 0)
3352 {
3353 nUndo = new UndoState(this, goback.ForGroup);
3354 }
3355
3356 goback.PlaybackState(this);
3357
3358 if (nUndo != null)
3359 {
3360 m_redo.Add(nUndo);
3361
3362 if (m_redo.Count > ParentGroup.Scene.MaxUndoCount)
3363 m_redo.RemoveAt(0);
3364 }
3365 }
3366 3830
3367// m_log.DebugFormat( 3831 lock (m_UndoRedo)
3368// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3832 {
3369// Name, LocalId, m_undo.Count); 3833 Undoing = true;
3834 m_UndoRedo.Undo(this);
3835 Undoing = false;
3370 } 3836 }
3371 } 3837 }
3372 3838
3373 public void Redo() 3839 public void Redo()
3374 { 3840 {
3375 lock (m_undo) 3841 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3376 { 3842 return;
3377// m_log.DebugFormat(
3378// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3379// Name, LocalId, m_redo.Count);
3380
3381 if (m_redo.Count > 0)
3382 {
3383 UndoState gofwd = m_redo[m_redo.Count - 1];
3384 m_redo.RemoveAt(m_redo.Count - 1);
3385
3386 if (ParentGroup.Scene.MaxUndoCount > 0)
3387 {
3388 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3389
3390 m_undo.Add(nUndo);
3391
3392 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3393 m_undo.RemoveAt(0);
3394 }
3395
3396 gofwd.PlayfwdState(this);
3397 3843
3398// m_log.DebugFormat( 3844 lock (m_UndoRedo)
3399// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3845 {
3400// Name, LocalId, m_redo.Count); 3846 Undoing = true;
3401 } 3847 m_UndoRedo.Redo(this);
3848 Undoing = false;
3402 } 3849 }
3403 } 3850 }
3404 3851
3405 public void ClearUndoState() 3852 public void ClearUndoState()
3406 { 3853 {
3407// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3854 if (m_UndoRedo == null || Undoing)
3855 return;
3408 3856
3409 lock (m_undo) 3857 lock (m_UndoRedo)
3410 { 3858 {
3411 m_undo.Clear(); 3859 m_UndoRedo.Clear();
3412 m_redo.Clear();
3413 } 3860 }
3414 } 3861 }
3415 3862
@@ -3961,7 +4408,7 @@ namespace OpenSim.Region.Framework.Scenes
3961 if (god) 4408 if (god)
3962 { 4409 {
3963 BaseMask = ApplyMask(BaseMask, set, mask); 4410 BaseMask = ApplyMask(BaseMask, set, mask);
3964 Inventory.ApplyGodPermissions(_baseMask); 4411 Inventory.ApplyGodPermissions(BaseMask);
3965 } 4412 }
3966 4413
3967 break; 4414 break;
@@ -3992,7 +4439,7 @@ namespace OpenSim.Region.Framework.Scenes
3992 } 4439 }
3993 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & 4440 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) &
3994 baseMask; 4441 baseMask;
3995 // Prevent the client from creating no mod, no copy 4442 // Prevent the client from creating no copy, no transfer
3996 // objects 4443 // objects
3997 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0) 4444 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0)
3998 NextOwnerMask |= (uint)PermissionMask.Transfer; 4445 NextOwnerMask |= (uint)PermissionMask.Transfer;
@@ -4010,20 +4457,20 @@ namespace OpenSim.Region.Framework.Scenes
4010 { 4457 {
4011 bool update = false; 4458 bool update = false;
4012 4459
4013 if (BaseMask != source.BaseMask || 4460 uint prevOwnerMask = OwnerMask;
4014 OwnerMask != source.OwnerMask || 4461 uint prevGroupMask = GroupMask;
4015 GroupMask != source.GroupMask || 4462 uint prevEveryoneMask = EveryoneMask;
4016 EveryoneMask != source.EveryoneMask || 4463 uint prevNextOwnerMask = NextOwnerMask;
4017 NextOwnerMask != source.NextOwnerMask)
4018 update = true;
4019 4464
4020 BaseMask = source.BaseMask; 4465 OwnerMask = source.OwnerMask & BaseMask;
4021 OwnerMask = source.OwnerMask; 4466 GroupMask = source.GroupMask & BaseMask;
4022 GroupMask = source.GroupMask; 4467 EveryoneMask = source.EveryoneMask & BaseMask;
4023 EveryoneMask = source.EveryoneMask; 4468 NextOwnerMask = source.NextOwnerMask & BaseMask;
4024 NextOwnerMask = source.NextOwnerMask;
4025 4469
4026 if (update) 4470 if (OwnerMask != prevOwnerMask ||
4471 GroupMask != prevGroupMask ||
4472 EveryoneMask != prevEveryoneMask ||
4473 NextOwnerMask != prevNextOwnerMask)
4027 SendFullUpdateToAllClients(); 4474 SendFullUpdateToAllClients();
4028 } 4475 }
4029 4476
@@ -4074,6 +4521,7 @@ namespace OpenSim.Region.Framework.Scenes
4074 } 4521 }
4075 } 4522 }
4076 4523
4524
4077 public void UpdateExtraPhysics(ExtraPhysicsData physdata) 4525 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4078 { 4526 {
4079 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null) 4527 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
@@ -4101,7 +4549,7 @@ namespace OpenSim.Region.Framework.Scenes
4101 /// <param name="SetTemporary"></param> 4549 /// <param name="SetTemporary"></param>
4102 /// <param name="SetPhantom"></param> 4550 /// <param name="SetPhantom"></param>
4103 /// <param name="SetVD"></param> 4551 /// <param name="SetVD"></param>
4104 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) 4552 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
4105 { 4553 {
4106 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4554 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4107 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4555 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4111,116 +4559,98 @@ namespace OpenSim.Region.Framework.Scenes
4111 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4559 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4112 return; 4560 return;
4113 4561
4114 PhysicsActor pa = PhysActor; 4562 VolumeDetectActive = SetVD;
4115
4116 // Special cases for VD. VD can only be called from a script
4117 // and can't be combined with changes to other states. So we can rely
4118 // that...
4119 // ... if VD is changed, all others are not.
4120 // ... if one of the others is changed, VD is not.
4121 if (SetVD) // VD is active, special logic applies
4122 {
4123 // State machine logic for VolumeDetect
4124 // More logic below
4125 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4126
4127 if (phanReset) // Phantom changes from on to off switch VD off too
4128 {
4129 SetVD = false; // Switch it of for the course of this routine
4130 VolumeDetectActive = false; // and also permanently
4131
4132 if (pa != null)
4133 pa.SetVolumeDetect(0); // Let physics know about it too
4134 }
4135 else
4136 {
4137 // If volumedetect is active we don't want phantom to be applied.
4138 // If this is a new call to VD out of the state "phantom"
4139 // this will also cause the prim to be visible to physics
4140 SetPhantom = false;
4141 }
4142 }
4143 4563
4144 if (UsePhysics && IsJoint()) 4564 // volume detector implies phantom
4145 { 4565 if (VolumeDetectActive)
4146 SetPhantom = true; 4566 SetPhantom = true;
4147 }
4148 4567
4149 if (UsePhysics) 4568 if (UsePhysics)
4150 {
4151 AddFlag(PrimFlags.Physics); 4569 AddFlag(PrimFlags.Physics);
4152 if (!wasUsingPhysics)
4153 {
4154 DoPhysicsPropertyUpdate(UsePhysics, false);
4155 }
4156 }
4157 else 4570 else
4158 {
4159 RemFlag(PrimFlags.Physics); 4571 RemFlag(PrimFlags.Physics);
4160 if (wasUsingPhysics)
4161 {
4162 DoPhysicsPropertyUpdate(UsePhysics, false);
4163 }
4164 }
4165 4572
4166 if (SetPhantom 4573 if (SetPhantom)
4167 || ParentGroup.IsAttachment
4168 || PhysicsShapeType == (byte)PhysShapeType.none
4169 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4170 {
4171 AddFlag(PrimFlags.Phantom); 4574 AddFlag(PrimFlags.Phantom);
4575 else
4576 RemFlag(PrimFlags.Phantom);
4172 4577
4173 if (PhysActor != null) 4578 if (SetTemporary)
4579 AddFlag(PrimFlags.TemporaryOnRez);
4580 else
4581 RemFlag(PrimFlags.TemporaryOnRez);
4582
4583
4584 if (ParentGroup.Scene == null)
4585 return;
4586
4587 PhysicsActor pa = PhysActor;
4588
4589 if (pa != null && building && pa.Building != building)
4590 pa.Building = building;
4591
4592 if ((SetPhantom && !UsePhysics && !SetVD) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
4593 || (Shape.PathCurve == (byte)Extrusion.Flexible))
4594 {
4595 if (pa != null)
4174 { 4596 {
4597 if(wasUsingPhysics)
4598 ParentGroup.Scene.RemovePhysicalPrim(1);
4175 RemoveFromPhysics(); 4599 RemoveFromPhysics();
4176 pa = null;
4177 } 4600 }
4601
4602 Velocity = new Vector3(0, 0, 0);
4603 Acceleration = new Vector3(0, 0, 0);
4604 if (ParentGroup.RootPart == this)
4605 AngularVelocity = new Vector3(0, 0, 0);
4178 } 4606 }
4179 else // Not phantom 4607
4608 else
4180 { 4609 {
4181 RemFlag(PrimFlags.Phantom); 4610 if (ParentGroup.Scene.CollidablePrims)
4182
4183 if (ParentGroup.Scene == null)
4184 return;
4185
4186 if (ParentGroup.Scene.CollidablePrims && pa == null)
4187 { 4611 {
4188 AddToPhysics(UsePhysics, SetPhantom, false); 4612 if (pa == null)
4189 pa = PhysActor;
4190
4191
4192 if (pa != null)
4193 { 4613 {
4194 pa.SetMaterial(Material); 4614 AddToPhysics(UsePhysics, SetPhantom, building, false);
4195 DoPhysicsPropertyUpdate(UsePhysics, true); 4615 pa = PhysActor;
4196 4616/*
4197 if ( 4617 if (pa != null)
4198 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4199 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4200 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4201 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4202 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4203 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4204 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4205 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4206 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4207 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4208 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4209 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4210 (CollisionSound != UUID.Zero)
4211 )
4212 { 4618 {
4213 pa.OnCollisionUpdate += PhysicsCollision; 4619 if (
4214 pa.SubscribeEvents(1000); 4620// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4621// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4622// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4623// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4624// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4625// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4626 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4627 ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4628 (CollisionSound != UUID.Zero)
4629 )
4630 {
4631 pa.OnCollisionUpdate += PhysicsCollision;
4632 pa.SubscribeEvents(1000);
4633 }
4215 } 4634 }
4635*/
4636 }
4637 else // it already has a physical representation
4638 {
4639 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4640/* moved into DoPhysicsPropertyUpdate
4641 if(VolumeDetectActive)
4642 pa.SetVolumeDetect(1);
4643 else
4644 pa.SetVolumeDetect(0);
4645*/
4646
4647 if (pa.Building != building)
4648 pa.Building = building;
4216 } 4649 }
4217 }
4218 else // it already has a physical representation
4219 {
4220 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4221 }
4222 }
4223 4650
4651 UpdatePhysicsSubscribedEvents();
4652 }
4653 }
4224 if (SetVD) 4654 if (SetVD)
4225 { 4655 {
4226 // If the above logic worked (this is urgent candidate to unit tests!) 4656 // If the above logic worked (this is urgent candidate to unit tests!)
@@ -4234,6 +4664,7 @@ namespace OpenSim.Region.Framework.Scenes
4234 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active 4664 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4235 VolumeDetectActive = true; 4665 VolumeDetectActive = true;
4236 } 4666 }
4667 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4237 } 4668 }
4238 else if (SetVD != wasVD) 4669 else if (SetVD != wasVD)
4239 { 4670 {
@@ -4245,61 +4676,51 @@ namespace OpenSim.Region.Framework.Scenes
4245 RemFlag(PrimFlags.Phantom); 4676 RemFlag(PrimFlags.Phantom);
4246 VolumeDetectActive = false; 4677 VolumeDetectActive = false;
4247 } 4678 }
4248 4679 // and last in case we have a new actor and not building
4249 if (SetTemporary)
4250 {
4251 AddFlag(PrimFlags.TemporaryOnRez);
4252 }
4253 else
4254 {
4255 RemFlag(PrimFlags.TemporaryOnRez);
4256 }
4257
4258 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4259 4680
4260 if (ParentGroup != null) 4681 if (ParentGroup != null)
4261 { 4682 {
4262 ParentGroup.HasGroupChanged = true; 4683 ParentGroup.HasGroupChanged = true;
4263 ScheduleFullUpdate(); 4684 ScheduleFullUpdate();
4264 } 4685 }
4265 4686
4266// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); 4687// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4267 } 4688 }
4268 4689
4269 /// <summary> 4690 /// <summary>
4270 /// Adds this part to the physics scene. 4691 /// Adds this part to the physics scene.
4692 /// and sets the PhysActor property
4271 /// </summary> 4693 /// </summary>
4272 /// <remarks>This method also sets the PhysActor property.</remarks> 4694 /// <param name="isPhysical">Add this prim as physical.</param>
4273 /// <param name="rigidBody">Add this prim with a rigid body.</param> 4695 /// <param name="isPhantom">Add this prim as phantom.</param>
4274 /// <returns> 4696 /// <param name="building">tells physics to delay full construction of object</param>
4275 /// The physics actor. null if there was a failure. 4697 /// <param name="applyDynamics">applies velocities, force and torque</param>
4276 /// </returns> 4698 private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
4277 private void AddToPhysics(bool isPhysical, bool isPhantom, bool applyDynamics) 4699 {
4278 {
4279 PhysicsActor pa; 4700 PhysicsActor pa;
4280 4701
4281 Vector3 velocity = Velocity; 4702 Vector3 velocity = Velocity;
4282 Vector3 rotationalVelocity = AngularVelocity;; 4703 Vector3 rotationalVelocity = AngularVelocity;;
4283 4704
4284 try 4705 try
4285 { 4706 {
4286 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4707 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4287 string.Format("{0}/{1}", Name, UUID), 4708 string.Format("{0}/{1}", Name, UUID),
4288 Shape, 4709 Shape,
4289 AbsolutePosition, 4710 AbsolutePosition,
4290 Scale, 4711 Scale,
4291 GetWorldRotation(), 4712 GetWorldRotation(),
4292 isPhysical, 4713 isPhysical,
4293 isPhantom, 4714 isPhantom,
4294 PhysicsShapeType, 4715 PhysicsShapeType,
4295 m_localId); 4716 m_localId);
4296 } 4717 }
4297 catch (Exception e) 4718 catch (Exception e)
4298 { 4719 {
4299 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e); 4720 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e);
4300 pa = null; 4721 pa = null;
4301 } 4722 }
4302 4723
4303 if (pa != null) 4724 if (pa != null)
4304 { 4725 {
4305 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 4726 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
@@ -4312,11 +4733,21 @@ namespace OpenSim.Region.Framework.Scenes
4312 4733
4313 if (VolumeDetectActive) // change if not the default only 4734 if (VolumeDetectActive) // change if not the default only
4314 pa.SetVolumeDetect(1); 4735 pa.SetVolumeDetect(1);
4736
4737 if (m_vehicleParams != null && LocalId == ParentGroup.RootPart.LocalId)
4738 m_vehicleParams.SetVehicle(pa);
4739
4315 // we are going to tell rest of code about physics so better have this here 4740 // we are going to tell rest of code about physics so better have this here
4316 PhysActor = pa; 4741 PhysActor = pa;
4317 4742
4743 // DoPhysicsPropertyUpdate(isPhysical, true);
4744 // lets expand it here just with what it really needs to do
4745
4318 if (isPhysical) 4746 if (isPhysical)
4319 { 4747 {
4748 if (ParentGroup.RootPart.KeyframeMotion != null)
4749 ParentGroup.RootPart.KeyframeMotion.Stop();
4750 ParentGroup.RootPart.KeyframeMotion = null;
4320 ParentGroup.Scene.AddPhysicalPrim(1); 4751 ParentGroup.Scene.AddPhysicalPrim(1);
4321 4752
4322 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 4753 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
@@ -4333,19 +4764,34 @@ namespace OpenSim.Region.Framework.Scenes
4333 } 4764 }
4334 } 4765 }
4335 4766
4336 if (applyDynamics) 4767 if (applyDynamics)
4337 // do independent of isphysical so parameters get setted (at least some) 4768 // do independent of isphysical so parameters get setted (at least some)
4338 { 4769 {
4339 Velocity = velocity; 4770 Velocity = velocity;
4340 AngularVelocity = rotationalVelocity; 4771 AngularVelocity = rotationalVelocity;
4341// pa.Velocity = velocity; 4772// pa.Velocity = velocity;
4342 pa.RotationalVelocity = rotationalVelocity; 4773 pa.RotationalVelocity = rotationalVelocity;
4774
4775 // if not vehicle and root part apply force and torque
4776 if ((m_vehicleParams == null || m_vehicleParams.Type == Vehicle.TYPE_NONE)
4777 && LocalId == ParentGroup.RootPart.LocalId)
4778 {
4779 pa.Force = Force;
4780 pa.Torque = Torque;
4781 }
4343 } 4782 }
4344 4783
4345 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); 4784// if (Shape.SculptEntry)
4785// CheckSculptAndLoad();
4786// else
4787 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
4788
4789 if (!building)
4790 pa.Building = false;
4346 } 4791 }
4347 4792
4348 PhysActor = pa; 4793 PhysActor = pa;
4794
4349 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this); 4795 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this);
4350 } 4796 }
4351 4797
@@ -4354,13 +4800,21 @@ namespace OpenSim.Region.Framework.Scenes
4354 /// </summary> 4800 /// </summary>
4355 /// <remarks> 4801 /// <remarks>
4356 /// This isn't the same as turning off physical, since even without being physical the prim has a physics 4802 /// This isn't the same as turning off physical, since even without being physical the prim has a physics
4357 /// representation for collision detection. Rather, this would be used in situations such as making a prim 4803 /// representation for collision detection.
4358 /// phantom.
4359 /// </remarks> 4804 /// </remarks>
4360 public void RemoveFromPhysics() 4805 public void RemoveFromPhysics()
4361 { 4806 {
4362 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this); 4807 PhysicsActor pa = PhysActor;
4363 ParentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 4808 if (pa != null)
4809 {
4810 pa.OnCollisionUpdate -= PhysicsCollision;
4811 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
4812 pa.OnOutOfBounds -= PhysicsOutOfBounds;
4813
4814 ParentGroup.Scene.PhysicsScene.RemovePrim(pa);
4815
4816 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this);
4817 }
4364 PhysActor = null; 4818 PhysActor = null;
4365 } 4819 }
4366 4820
@@ -4492,6 +4946,8 @@ namespace OpenSim.Region.Framework.Scenes
4492 { 4946 {
4493// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); 4947// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4494 4948
4949 return;
4950
4495 if (ParentGroup.IsDeleted) 4951 if (ParentGroup.IsDeleted)
4496 return; 4952 return;
4497 4953
@@ -4615,6 +5071,44 @@ namespace OpenSim.Region.Framework.Scenes
4615 } 5071 }
4616 } 5072 }
4617 5073
5074
5075 private void UpdatePhysicsSubscribedEvents()
5076 {
5077 PhysicsActor pa = PhysActor;
5078 if (pa == null)
5079 return;
5080
5081 pa.OnCollisionUpdate -= PhysicsCollision;
5082
5083 bool hassound = (!VolumeDetectActive && CollisionSoundType >= 0 && ((Flags & PrimFlags.Physics) != 0));
5084
5085 scriptEvents CombinedEvents = AggregateScriptEvents;
5086
5087 // merge with root part
5088 if (ParentGroup != null && ParentGroup.RootPart != null)
5089 CombinedEvents |= ParentGroup.RootPart.AggregateScriptEvents;
5090
5091 // submit to this part case
5092 if (VolumeDetectActive)
5093 CombinedEvents &= PhyscicsVolumeDtcSubsEvents;
5094 else if ((Flags & PrimFlags.Phantom) != 0)
5095 CombinedEvents &= PhyscicsPhantonSubsEvents;
5096 else
5097 CombinedEvents &= PhysicsNeededSubsEvents;
5098
5099 if (hassound || CombinedEvents != 0)
5100 {
5101 // subscribe to physics updates.
5102 pa.OnCollisionUpdate += PhysicsCollision;
5103 pa.SubscribeEvents(50); // 20 reports per second
5104 }
5105 else
5106 {
5107 pa.UnSubscribeEvents();
5108 }
5109 }
5110
5111
4618 public void aggregateScriptEvents() 5112 public void aggregateScriptEvents()
4619 { 5113 {
4620 if (ParentGroup == null || ParentGroup.RootPart == null) 5114 if (ParentGroup == null || ParentGroup.RootPart == null)
@@ -4651,40 +5145,32 @@ namespace OpenSim.Region.Framework.Scenes
4651 { 5145 {
4652 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; 5146 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop;
4653 } 5147 }
4654 5148/*
4655 PhysicsActor pa = PhysActor; 5149 PhysicsActor pa = PhysActor;
4656 5150 if (pa != null)
4657 if (
4658 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4659 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4660 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4661 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4662 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4663 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4664 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4665 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4666 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4667 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4668 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4669 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4670 (CollisionSound != UUID.Zero)
4671 )
4672 { 5151 {
4673 // subscribe to physics updates. 5152 if (
4674 if (pa != null) 5153// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
5154// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
5155// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
5156// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5157// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5158// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5159 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5160 )
4675 { 5161 {
5162 // subscribe to physics updates.
4676 pa.OnCollisionUpdate += PhysicsCollision; 5163 pa.OnCollisionUpdate += PhysicsCollision;
4677 pa.SubscribeEvents(1000); 5164 pa.SubscribeEvents(1000);
4678 } 5165 }
4679 } 5166 else
4680 else
4681 {
4682 if (pa != null)
4683 { 5167 {
4684 pa.UnSubscribeEvents(); 5168 pa.UnSubscribeEvents();
4685 pa.OnCollisionUpdate -= PhysicsCollision; 5169 pa.OnCollisionUpdate -= PhysicsCollision;
4686 } 5170 }
4687 } 5171 }
5172 */
5173 UpdatePhysicsSubscribedEvents();
4688 5174
4689 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 5175 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4690 //{ 5176 //{
@@ -4818,6 +5304,18 @@ namespace OpenSim.Region.Framework.Scenes
4818 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 5304 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4819 } 5305 }
4820 5306
5307 public void ResetOwnerChangeFlag()
5308 {
5309 List<UUID> inv = Inventory.GetInventoryList();
5310
5311 foreach (UUID itemID in inv)
5312 {
5313 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
5314 item.OwnerChanged = false;
5315 Inventory.UpdateInventoryItem(item, false, false);
5316 }
5317 }
5318
4821 /// <summary> 5319 /// <summary>
4822 /// Record an avatar sitting on this part. 5320 /// Record an avatar sitting on this part.
4823 /// </summary> 5321 /// </summary>