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 27325c5..9265805 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; 474 private uint _ownerMask = (uint)PermissionMask.All;
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
@@ -1285,6 +1357,13 @@ namespace OpenSim.Region.Framework.Scenes
1285 _flags = value; 1357 _flags = value;
1286 } 1358 }
1287 } 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 }
1288 1367
1289 /// <summary> 1368 /// <summary>
1290 /// 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
@@ -1335,12 +1414,41 @@ namespace OpenSim.Region.Framework.Scenes
1335 set { m_sitAnimation = value; } 1414 set { m_sitAnimation = value; }
1336 } 1415 }
1337 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
1338 public UUID CollisionSound 1438 public UUID CollisionSound
1339 { 1439 {
1340 get { return m_collisionSound; } 1440 get { return m_collisionSound; }
1341 set 1441 set
1342 { 1442 {
1343 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
1344 aggregateScriptEvents(); 1452 aggregateScriptEvents();
1345 } 1453 }
1346 } 1454 }
@@ -1351,6 +1459,125 @@ namespace OpenSim.Region.Framework.Scenes
1351 set { m_collisionSoundVolume = value; } 1459 set { m_collisionSoundVolume = value; }
1352 } 1460 }
1353 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
1354 public byte DefaultPhysicsShapeType() 1581 public byte DefaultPhysicsShapeType()
1355 { 1582 {
1356 byte type; 1583 byte type;
@@ -1363,6 +1590,65 @@ namespace OpenSim.Region.Framework.Scenes
1363 return type; 1590 return type;
1364 } 1591 }
1365 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
1366 public byte PhysicsShapeType 1652 public byte PhysicsShapeType
1367 { 1653 {
1368 get { return m_physicsShapeType; } 1654 get { return m_physicsShapeType; }
@@ -1396,11 +1682,14 @@ namespace OpenSim.Region.Framework.Scenes
1396 } 1682 }
1397 else if (PhysActor == null) 1683 else if (PhysActor == null)
1398 { 1684 {
1399 ApplyPhysics((uint)Flags, VolumeDetectActive); 1685 ApplyPhysics((uint)Flags, VolumeDetectActive, false);
1686 UpdatePhysicsSubscribedEvents();
1400 } 1687 }
1401 else 1688 else
1402 { 1689 {
1403 PhysActor.PhysicsShapeType = m_physicsShapeType; 1690 PhysActor.PhysicsShapeType = m_physicsShapeType;
1691// if (Shape.SculptEntry)
1692// CheckSculptAndLoad();
1404 } 1693 }
1405 1694
1406 if (ParentGroup != null) 1695 if (ParentGroup != null)
@@ -1502,6 +1791,7 @@ namespace OpenSim.Region.Framework.Scenes
1502 } 1791 }
1503 } 1792 }
1504 1793
1794
1505 #endregion Public Properties with only Get 1795 #endregion Public Properties with only Get
1506 1796
1507 private uint ApplyMask(uint val, bool set, uint mask) 1797 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1647,6 +1937,61 @@ namespace OpenSim.Region.Framework.Scenes
1647 } 1937 }
1648 } 1938 }
1649 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
1650 /// <summary> 1995 /// <summary>
1651 /// hook to the physics scene to apply angular impulse 1996 /// hook to the physics scene to apply angular impulse
1652 /// 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
@@ -1667,7 +2012,7 @@ namespace OpenSim.Region.Framework.Scenes
1667 impulse = newimpulse; 2012 impulse = newimpulse;
1668 } 2013 }
1669 2014
1670 ParentGroup.applyAngularImpulse(impulse); 2015 ParentGroup.ApplyAngularImpulse(impulse);
1671 } 2016 }
1672 2017
1673 /// <summary> 2018 /// <summary>
@@ -1677,20 +2022,24 @@ namespace OpenSim.Region.Framework.Scenes
1677 /// </summary> 2022 /// </summary>
1678 /// <param name="impulsei">Vector force</param> 2023 /// <param name="impulsei">Vector force</param>
1679 /// <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>
1680 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)
1681 { 2028 {
1682 Vector3 impulse = impulsei; 2029 Vector3 torque = torquei;
1683 2030
1684 if (localGlobalTF) 2031 if (localGlobalTF)
1685 { 2032 {
2033/*
1686 Quaternion grot = GetWorldRotation(); 2034 Quaternion grot = GetWorldRotation();
1687 Quaternion AXgrot = grot; 2035 Quaternion AXgrot = grot;
1688 Vector3 AXimpulsei = impulsei; 2036 Vector3 AXimpulsei = impulsei;
1689 Vector3 newimpulse = AXimpulsei * AXgrot; 2037 Vector3 newimpulse = AXimpulsei * AXgrot;
1690 impulse = newimpulse; 2038 */
2039 torque *= GetWorldRotation();
1691 } 2040 }
1692 2041
1693 ParentGroup.setAngularImpulse(impulse); 2042 Torque = torque;
1694 } 2043 }
1695 2044
1696 /// <summary> 2045 /// <summary>
@@ -1698,7 +2047,9 @@ namespace OpenSim.Region.Framework.Scenes
1698 /// </summary> 2047 /// </summary>
1699 /// <param name="rootObjectFlags"></param> 2048 /// <param name="rootObjectFlags"></param>
1700 /// <param name="VolumeDetectActive"></param> 2049 /// <param name="VolumeDetectActive"></param>
1701 public void ApplyPhysics(uint rootObjectFlags, bool _VolumeDetectActive) 2050 /// <param name="building"></param>
2051
2052 public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building)
1702 { 2053 {
1703 VolumeDetectActive = _VolumeDetectActive; 2054 VolumeDetectActive = _VolumeDetectActive;
1704 2055
@@ -1708,8 +2059,8 @@ namespace OpenSim.Region.Framework.Scenes
1708 if (PhysicsShapeType == (byte)PhysShapeType.none) 2059 if (PhysicsShapeType == (byte)PhysShapeType.none)
1709 return; 2060 return;
1710 2061
1711 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 2062 bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0;
1712 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 2063 bool isPhantom = (_ObjectFlags & (uint)PrimFlags.Phantom) != 0;
1713 2064
1714 if (_VolumeDetectActive) 2065 if (_VolumeDetectActive)
1715 isPhantom = true; 2066 isPhantom = true;
@@ -1723,7 +2074,8 @@ namespace OpenSim.Region.Framework.Scenes
1723 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment 2074 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment
1724 && !(Shape.PathCurve == (byte)Extrusion.Flexible)) 2075 && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1725 { 2076 {
1726 AddToPhysics(isPhysical, isPhantom, isPhysical); 2077 AddToPhysics(isPhysical, isPhantom, building, isPhysical);
2078 UpdatePhysicsSubscribedEvents(); // not sure if appliable here
1727 } 2079 }
1728 else 2080 else
1729 PhysActor = null; // just to be sure 2081 PhysActor = null; // just to be sure
@@ -1778,6 +2130,12 @@ namespace OpenSim.Region.Framework.Scenes
1778 dupe.Category = Category; 2130 dupe.Category = Category;
1779 dupe.m_rezzed = m_rezzed; 2131 dupe.m_rezzed = m_rezzed;
1780 2132
2133 dupe.m_UndoRedo = null;
2134 dupe.m_isSelected = false;
2135
2136 dupe.IgnoreUndoUpdate = false;
2137 dupe.Undoing = false;
2138
1781 dupe.m_inventory = new SceneObjectPartInventory(dupe); 2139 dupe.m_inventory = new SceneObjectPartInventory(dupe);
1782 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone(); 2140 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone();
1783 2141
@@ -1793,6 +2151,7 @@ namespace OpenSim.Region.Framework.Scenes
1793 2151
1794 // Move afterwards ResetIDs as it clears the localID 2152 // Move afterwards ResetIDs as it clears the localID
1795 dupe.LocalId = localID; 2153 dupe.LocalId = localID;
2154
1796 // 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.
1797 dupe.LastOwnerID = OwnerID; 2156 dupe.LastOwnerID = OwnerID;
1798 2157
@@ -1800,6 +2159,9 @@ namespace OpenSim.Region.Framework.Scenes
1800 Array.Copy(Shape.ExtraParams, extraP, extraP.Length); 2159 Array.Copy(Shape.ExtraParams, extraP, extraP.Length);
1801 dupe.Shape.ExtraParams = extraP; 2160 dupe.Shape.ExtraParams = extraP;
1802 2161
2162 // safeguard actual copy is done in sog.copy
2163 dupe.KeyframeMotion = null;
2164
1803 dupe.DynAttrs.CopyFrom(DynAttrs); 2165 dupe.DynAttrs.CopyFrom(DynAttrs);
1804 2166
1805 if (userExposed) 2167 if (userExposed)
@@ -1813,8 +2175,12 @@ namespace OpenSim.Region.Framework.Scenes
1813*/ 2175*/
1814 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 2176 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
1815 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 2177 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
2178// dupe.UpdatePhysicsSubscribedEvents(); // not sure...
1816 } 2179 }
1817 2180
2181 if (dupe.PhysActor != null)
2182 dupe.PhysActor.LocalID = localID;
2183
1818 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 2184 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1819 2185
1820// 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);
@@ -1833,10 +2199,10 @@ namespace OpenSim.Region.Framework.Scenes
1833 { 2199 {
1834 if (asset != null) 2200 if (asset != null)
1835 SculptTextureCallback(asset); 2201 SculptTextureCallback(asset);
1836 else 2202// else
1837 m_log.WarnFormat( 2203// m_log.WarnFormat(
1838 "[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",
1839 Name, UUID, id); 2205// Name, UUID, id);
1840 } 2206 }
1841*/ 2207*/
1842 /// <summary> 2208 /// <summary>
@@ -1935,6 +2301,7 @@ namespace OpenSim.Region.Framework.Scenes
1935 2301
1936 /// <summary> 2302 /// <summary>
1937 /// 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
1938 /// </summary> 2305 /// </summary>
1939 /// <param name="UsePhysics"></param> 2306 /// <param name="UsePhysics"></param>
1940 /// <param name="isNew"></param> 2307 /// <param name="isNew"></param>
@@ -1960,61 +2327,69 @@ namespace OpenSim.Region.Framework.Scenes
1960 { 2327 {
1961 if (pa.IsPhysical) // implies UsePhysics==false for this block 2328 if (pa.IsPhysical) // implies UsePhysics==false for this block
1962 { 2329 {
1963 if (!isNew) 2330 if (!isNew) // implies UsePhysics==false for this block
2331 {
1964 ParentGroup.Scene.RemovePhysicalPrim(1); 2332 ParentGroup.Scene.RemovePhysicalPrim(1);
1965 2333
1966 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 2334 Velocity = new Vector3(0, 0, 0);
1967 pa.OnOutOfBounds -= PhysicsOutOfBounds; 2335 Acceleration = new Vector3(0, 0, 0);
1968 pa.delink(); 2336 if (ParentGroup.RootPart == this)
2337 AngularVelocity = new Vector3(0, 0, 0);
1969 2338
1970 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 2339 if (pa.Phantom && !VolumeDetectActive)
1971 { 2340 {
1972 // destroy all joints connected to this now deactivated body 2341 RemoveFromPhysics();
1973 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); 2342 return;
1974 } 2343 }
1975 2344
1976 // stop client-side interpolation of all joint proxy objects that have just been deleted 2345 pa.IsPhysical = UsePhysics;
1977 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback, 2346 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1978 // 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 }
1979 } 2355 }
1980 2356
1981 if (!UsePhysics && !isNew) 2357 if (pa.IsPhysical != UsePhysics)
1982 { 2358 pa.IsPhysical = UsePhysics;
1983 // reset velocity to 0 on physics switch-off. Without that, the client thinks the
1984 // prim still has velocity and continues to interpolate its position along the old
1985 // velocity-vector.
1986 Velocity = new Vector3(0, 0, 0);
1987 Acceleration = new Vector3(0, 0, 0);
1988 AngularVelocity = new Vector3(0, 0, 0);
1989 //RotationalVelocity = new Vector3(0, 0, 0);
1990 }
1991 2359
1992 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);
1993 2366
1994 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 2367 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1995 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 2368 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1996 /// that's not wholesome. Had to make Scene public
1997 //PhysActor = null;
1998 2369
1999 if ((Flags & PrimFlags.Phantom) == 0) 2370 if (ParentID != 0 && ParentID != LocalId)
2000 {
2001 if (UsePhysics)
2002 { 2371 {
2003 ParentGroup.Scene.AddPhysicalPrim(1); 2372 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
2004 2373
2005 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 2374 if (parentPa != null)
2006 pa.OnOutOfBounds += PhysicsOutOfBounds;
2007 if (ParentID != 0 && ParentID != LocalId)
2008 { 2375 {
2009 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; 2376 pa.link(parentPa);
2010
2011 if (parentPa != null)
2012 {
2013 pa.link(parentPa);
2014 }
2015 } 2377 }
2016 } 2378 }
2017 } 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);
2018 } 2393 }
2019 2394
2020 // 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
@@ -2133,42 +2508,63 @@ namespace OpenSim.Region.Framework.Scenes
2133 2508
2134 public Vector3 GetGeometricCenter() 2509 public Vector3 GetGeometricCenter()
2135 { 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 {
2136 PhysicsActor pa = PhysActor; 2523 PhysicsActor pa = PhysActor;
2137 2524
2138 if (pa != null) 2525 if (pa != null)
2139 return new Vector3(pa.GeometricCenter.X, pa.GeometricCenter.Y, pa.GeometricCenter.Z); 2526 return pa.Mass;
2140 else 2527 else
2141 return new Vector3(0, 0, 0); 2528 return 0;
2142 } 2529 }
2143 2530
2144 public Vector3 GetCenterOfMass() 2531 public Vector3 GetCenterOfMass()
2145 { 2532 {
2533 if (ParentGroup.RootPart == this)
2534 {
2535 if (ParentGroup.IsDeleted)
2536 return AbsolutePosition;
2537 return ParentGroup.GetCenterOfMass();
2538 }
2539
2146 PhysicsActor pa = PhysActor; 2540 PhysicsActor pa = PhysActor;
2147 2541
2148 if (pa != null) 2542 if (pa != null)
2149 return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z); 2543 {
2544 Vector3 tmp = pa.CenterOfMass;
2545 return tmp;
2546 }
2150 else 2547 else
2151 return new Vector3(0, 0, 0); 2548 return AbsolutePosition;
2152 } 2549 }
2153 2550
2154 public float GetMass() 2551 public Vector3 GetPartCenterOfMass()
2155 { 2552 {
2156 PhysicsActor pa = PhysActor; 2553 PhysicsActor pa = PhysActor;
2157 2554
2158 if (pa != null) 2555 if (pa != null)
2159 return pa.Mass; 2556 {
2557 Vector3 tmp = pa.CenterOfMass;
2558 return tmp;
2559 }
2160 else 2560 else
2161 return 0; 2561 return AbsolutePosition;
2162 } 2562 }
2163 2563
2564
2164 public Vector3 GetForce() 2565 public Vector3 GetForce()
2165 { 2566 {
2166 PhysicsActor pa = PhysActor; 2567 return Force;
2167
2168 if (pa != null)
2169 return pa.Force;
2170 else
2171 return Vector3.Zero;
2172 } 2568 }
2173 2569
2174 /// <summary> 2570 /// <summary>
@@ -2383,15 +2779,25 @@ namespace OpenSim.Region.Framework.Scenes
2383 2779
2384 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify) 2780 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify)
2385 { 2781 {
2386 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0) 2782 bool sendToRoot = true;
2387 { 2783
2388 ColliderArgs LandCollidingMessage = new ColliderArgs(); 2784 ColliderArgs LandCollidingMessage = new ColliderArgs();
2389 List<DetectedObject> colliding = new List<DetectedObject>(); 2785 List<DetectedObject> colliding = new List<DetectedObject>();
2390 2786
2391 colliding.Add(CreateDetObjectForGround()); 2787 colliding.Add(CreateDetObjectForGround());
2392 LandCollidingMessage.Colliders = colliding; 2788 LandCollidingMessage.Colliders = colliding;
2393 2789
2790 if (Inventory.ContainsScripts())
2791 {
2792 if (!PassCollisions)
2793 sendToRoot = false;
2794 }
2795 if ((ScriptEvents & ev) != 0)
2394 notify(LocalId, LandCollidingMessage); 2796 notify(LocalId, LandCollidingMessage);
2797
2798 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0 && sendToRoot)
2799 {
2800 notify(ParentGroup.RootPart.LocalId, LandCollidingMessage);
2395 } 2801 }
2396 } 2802 }
2397 2803
@@ -2407,57 +2813,120 @@ namespace OpenSim.Region.Framework.Scenes
2407 List<uint> endedColliders = new List<uint>(); 2813 List<uint> endedColliders = new List<uint>();
2408 List<uint> startedColliders = new List<uint>(); 2814 List<uint> startedColliders = new List<uint>();
2409 2815
2410 // calculate things that started colliding this time 2816 if (collissionswith.Count == 0)
2411 // and build up list of colliders this time
2412 foreach (uint localid in collissionswith.Keys)
2413 { 2817 {
2414 thisHitColliders.Add(localid); 2818 if (m_lastColliders.Count == 0)
2415 if (!m_lastColliders.Contains(localid)) 2819 return; // nothing to do
2416 startedColliders.Add(localid);
2417 }
2418 2820
2419 // calculate things that ended colliding 2821 foreach (uint localID in m_lastColliders)
2420 foreach (uint localID in m_lastColliders) 2822 {
2421 {
2422 if (!thisHitColliders.Contains(localID))
2423 endedColliders.Add(localID); 2823 endedColliders.Add(localID);
2824 }
2825 m_lastColliders.Clear();
2424 } 2826 }
2425 2827
2426 //add the items that started colliding this time to the last colliders list. 2828 else
2427 foreach (uint localID in startedColliders) 2829 {
2428 m_lastColliders.Add(localID); 2830 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
2429 2831
2430 // remove things that ended colliding from the last colliders list 2832 // calculate things that started colliding this time
2431 foreach (uint localID in endedColliders) 2833 // and build up list of colliders this time
2432 m_lastColliders.Remove(localID); 2834 if (!VolumeDetectActive && CollisionSoundType >= 0)
2835 {
2836 CollisionForSoundInfo soundinfo;
2837 ContactPoint curcontact;
2433 2838
2434 // play the sound. 2839 foreach (uint id in collissionswith.Keys)
2435 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) 2840 {
2436 { 2841 thisHitColliders.Add(id);
2437 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>(); 2842 if (!m_lastColliders.Contains(id))
2438 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)
2439 { 2870 {
2440 soundModule.SendSound(UUID, CollisionSound, 2871 if (!thisHitColliders.Contains(localID))
2441 CollisionSoundVolume, true, (byte)0, 0, false, 2872 endedColliders.Add(localID);
2442 false);
2443 } 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);
2444 } 2886 }
2445 2887
2446 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart); 2888 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
2447 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding); 2889 if (!VolumeDetectActive)
2890 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
2448 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); 2891 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
2449 2892
2450 if (startedColliders.Contains(0)) 2893 if (startedColliders.Contains(0))
2451 { 2894 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2452 if (m_lastColliders.Contains(0)) 2895 if (m_lastColliders.Contains(0))
2453 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding); 2896 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding);
2454 else
2455 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2456 }
2457 if (endedColliders.Contains(0)) 2897 if (endedColliders.Contains(0))
2458 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); 2898 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2459 } 2899 }
2460 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
2461 public void PhysicsOutOfBounds(Vector3 pos) 2930 public void PhysicsOutOfBounds(Vector3 pos)
2462 { 2931 {
2463 // 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.
@@ -2479,9 +2948,9 @@ namespace OpenSim.Region.Framework.Scenes
2479 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2948 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2480 2949
2481 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2950 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2482 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2951 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2483 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2952 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2484 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2953 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2485 { 2954 {
2486 ParentGroup.AbsolutePosition = newpos; 2955 ParentGroup.AbsolutePosition = newpos;
2487 return; 2956 return;
@@ -2766,6 +3235,14 @@ namespace OpenSim.Region.Framework.Scenes
2766 if (ParentGroup == null) 3235 if (ParentGroup == null)
2767 return; 3236 return;
2768 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
2769 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3246 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
2770 { 3247 {
2771 SendFullUpdate(avatar.ControllingClient); 3248 SendFullUpdate(avatar.ControllingClient);
@@ -2824,8 +3301,8 @@ namespace OpenSim.Region.Framework.Scenes
2824 { 3301 {
2825 const float ROTATION_TOLERANCE = 0.01f; 3302 const float ROTATION_TOLERANCE = 0.01f;
2826 const float VELOCITY_TOLERANCE = 0.001f; 3303 const float VELOCITY_TOLERANCE = 0.001f;
2827 const float POSITION_TOLERANCE = 0.05f; 3304 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2828 const int TIME_MS_TOLERANCE = 3000; 3305 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2829 3306
2830 switch (UpdateFlag) 3307 switch (UpdateFlag)
2831 { 3308 {
@@ -2839,17 +3316,10 @@ namespace OpenSim.Region.Framework.Scenes
2839 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || 3316 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) ||
2840 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || 3317 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) ||
2841 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 3318 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
2842 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 3319 Environment.TickCount - m_lastUpdateSentTime > TIME_MS_TOLERANCE)
2843 { 3320 {
2844 SendTerseUpdateToAllClients(); 3321 SendTerseUpdateToAllClients();
2845 3322
2846 // Update the "last" values
2847 m_lastPosition = OffsetPosition;
2848 m_lastRotation = RotationOffset;
2849 m_lastVelocity = Velocity;
2850 m_lastAcceleration = Acceleration;
2851 m_lastAngularVelocity = AngularVelocity;
2852 m_lastTerseSent = Environment.TickCount;
2853 } 3323 }
2854 break; 3324 break;
2855 } 3325 }
@@ -2867,6 +3337,17 @@ namespace OpenSim.Region.Framework.Scenes
2867 /// </summary> 3337 /// </summary>
2868 public void SendTerseUpdateToAllClients() 3338 public void SendTerseUpdateToAllClients()
2869 { 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
2870 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3351 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
2871 { 3352 {
2872 SendTerseUpdateToClient(client); 3353 SendTerseUpdateToClient(client);
@@ -2890,10 +3371,13 @@ namespace OpenSim.Region.Framework.Scenes
2890 3371
2891 public void SetBuoyancy(float fvalue) 3372 public void SetBuoyancy(float fvalue)
2892 { 3373 {
2893 PhysicsActor pa = PhysActor; 3374 Buoyancy = fvalue;
2894 3375/*
2895 if (pa != null) 3376 if (PhysActor != null)
2896 pa.Buoyancy = fvalue; 3377 {
3378 PhysActor.Buoyancy = fvalue;
3379 }
3380 */
2897 } 3381 }
2898 3382
2899 public void SetDieAtEdge(bool p) 3383 public void SetDieAtEdge(bool p)
@@ -2909,47 +3393,111 @@ namespace OpenSim.Region.Framework.Scenes
2909 PhysicsActor pa = PhysActor; 3393 PhysicsActor pa = PhysActor;
2910 3394
2911 if (pa != null) 3395 if (pa != null)
2912 pa.FloatOnWater = floatYN == 1; 3396 pa.FloatOnWater = (floatYN == 1);
2913 } 3397 }
2914 3398
2915 public void SetForce(Vector3 force) 3399 public void SetForce(Vector3 force)
2916 { 3400 {
2917 PhysicsActor pa = PhysActor; 3401 Force = force;
3402 }
2918 3403
2919 if (pa != null) 3404 public SOPVehicle VehicleParams
2920 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 }
2921 } 3430 }
2922 3431
2923 public void SetVehicleType(int type) 3432 public void SetVehicleType(int type)
2924 { 3433 {
2925 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 }
2926 3450
2927 if (pa != null) 3451 public void SetVehicleFlags(int param, bool remove)
2928 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 }
2929 } 3462 }
2930 3463
2931 public void SetVehicleFloatParam(int param, float value) 3464 public void SetVehicleFloatParam(int param, float value)
2932 { 3465 {
2933 PhysicsActor pa = PhysActor; 3466 if (m_vehicleParams == null)
3467 return;
2934 3468
2935 if (pa != null) 3469 m_vehicleParams.ProcessFloatVehicleParam((Vehicle)param, value);
2936 pa.VehicleFloatParam(param, value); 3470
3471 if (_parentID == 0 && PhysActor != null)
3472 {
3473 PhysActor.VehicleFloatParam(param, value);
3474 }
2937 } 3475 }
2938 3476
2939 public void SetVehicleVectorParam(int param, Vector3 value) 3477 public void SetVehicleVectorParam(int param, Vector3 value)
2940 { 3478 {
2941 PhysicsActor pa = PhysActor; 3479 if (m_vehicleParams == null)
3480 return;
2942 3481
2943 if (pa != null) 3482 m_vehicleParams.ProcessVectorVehicleParam((Vehicle)param, value);
2944 pa.VehicleVectorParam(param, value); 3483
3484 if (_parentID == 0 && PhysActor != null)
3485 {
3486 PhysActor.VehicleVectorParam(param, value);
3487 }
2945 } 3488 }
2946 3489
2947 public void SetVehicleRotationParam(int param, Quaternion rotation) 3490 public void SetVehicleRotationParam(int param, Quaternion rotation)
2948 { 3491 {
2949 PhysicsActor pa = PhysActor; 3492 if (m_vehicleParams == null)
3493 return;
2950 3494
2951 if (pa != null) 3495 m_vehicleParams.ProcessRotationVehicleParam((Vehicle)param, rotation);
2952 pa.VehicleRotationParam(param, rotation); 3496
3497 if (_parentID == 0 && PhysActor != null)
3498 {
3499 PhysActor.VehicleRotationParam(param, rotation);
3500 }
2953 } 3501 }
2954 3502
2955 /// <summary> 3503 /// <summary>
@@ -3150,14 +3698,6 @@ namespace OpenSim.Region.Framework.Scenes
3150 hasProfileCut = hasDimple; // is it the same thing? 3698 hasProfileCut = hasDimple; // is it the same thing?
3151 } 3699 }
3152 3700
3153 public void SetVehicleFlags(int param, bool remove)
3154 {
3155 PhysicsActor pa = PhysActor;
3156
3157 if (pa != null)
3158 pa.VehicleFlags(param, remove);
3159 }
3160
3161 public void SetGroup(UUID groupID, IClientAPI client) 3701 public void SetGroup(UUID groupID, IClientAPI client)
3162 { 3702 {
3163 // Scene.AddNewPrims() calls with client == null so can't use this. 3703 // Scene.AddNewPrims() calls with client == null so can't use this.
@@ -3257,71 +3797,20 @@ namespace OpenSim.Region.Framework.Scenes
3257 { 3797 {
3258 ParentGroup.stopMoveToTarget(); 3798 ParentGroup.stopMoveToTarget();
3259 3799
3260 ParentGroup.ScheduleGroupForTerseUpdate(); 3800// ParentGroup.ScheduleGroupForTerseUpdate();
3261 //ParentGroup.ScheduleGroupForFullUpdate(); 3801 //ParentGroup.ScheduleGroupForFullUpdate();
3262 } 3802 }
3263 3803
3264 public void StoreUndoState() 3804 public void StoreUndoState(ObjectChangeType change)
3265 { 3805 {
3266 StoreUndoState(false); 3806 if (m_UndoRedo == null)
3267 } 3807 m_UndoRedo = new UndoRedoState(5);
3268 3808
3269 public void StoreUndoState(bool forGroup) 3809 lock (m_UndoRedo)
3270 {
3271 if (ParentGroup == null || ParentGroup.Scene == null)
3272 return;
3273
3274 if (Undoing)
3275 {
3276// m_log.DebugFormat(
3277// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3278 return;
3279 }
3280
3281 if (IgnoreUndoUpdate)
3282 {
3283// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3284 return;
3285 }
3286
3287 lock (m_undo)
3288 { 3810 {
3289 if (m_undo.Count > 0) 3811 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3290 { 3812 {
3291 UndoState last = m_undo[m_undo.Count - 1]; 3813 m_UndoRedo.StoreUndo(this, change);
3292 if (last != null)
3293 {
3294 // TODO: May need to fix for group comparison
3295 if (last.Compare(this))
3296 {
3297// m_log.DebugFormat(
3298// "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3299// Name, LocalId, m_undo.Count);
3300
3301 return;
3302 }
3303 }
3304 }
3305
3306// m_log.DebugFormat(
3307// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3308// Name, LocalId, forGroup, m_undo.Count);
3309
3310 if (ParentGroup.Scene.MaxUndoCount > 0)
3311 {
3312 UndoState nUndo = new UndoState(this, forGroup);
3313
3314 m_undo.Add(nUndo);
3315
3316 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3317 m_undo.RemoveAt(0);
3318
3319 if (m_redo.Count > 0)
3320 m_redo.Clear();
3321
3322// m_log.DebugFormat(
3323// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3324// Name, LocalId, forGroup, m_undo.Count);
3325 } 3814 }
3326 } 3815 }
3327 } 3816 }
@@ -3333,88 +3822,46 @@ namespace OpenSim.Region.Framework.Scenes
3333 { 3822 {
3334 get 3823 get
3335 { 3824 {
3336 lock (m_undo) 3825 if (m_UndoRedo == null)
3337 return m_undo.Count; 3826 return 0;
3827 return m_UndoRedo.Count;
3338 } 3828 }
3339 } 3829 }
3340 3830
3341 public void Undo() 3831 public void Undo()
3342 { 3832 {
3343 lock (m_undo) 3833 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3344 { 3834 return;
3345// m_log.DebugFormat(
3346// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3347// Name, LocalId, m_undo.Count);
3348
3349 if (m_undo.Count > 0)
3350 {
3351 UndoState goback = m_undo[m_undo.Count - 1];
3352 m_undo.RemoveAt(m_undo.Count - 1);
3353
3354 UndoState nUndo = null;
3355
3356 if (ParentGroup.Scene.MaxUndoCount > 0)
3357 {
3358 nUndo = new UndoState(this, goback.ForGroup);
3359 }
3360
3361 goback.PlaybackState(this);
3362
3363 if (nUndo != null)
3364 {
3365 m_redo.Add(nUndo);
3366
3367 if (m_redo.Count > ParentGroup.Scene.MaxUndoCount)
3368 m_redo.RemoveAt(0);
3369 }
3370 }
3371 3835
3372// m_log.DebugFormat( 3836 lock (m_UndoRedo)
3373// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3837 {
3374// Name, LocalId, m_undo.Count); 3838 Undoing = true;
3839 m_UndoRedo.Undo(this);
3840 Undoing = false;
3375 } 3841 }
3376 } 3842 }
3377 3843
3378 public void Redo() 3844 public void Redo()
3379 { 3845 {
3380 lock (m_undo) 3846 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3381 { 3847 return;
3382// m_log.DebugFormat(
3383// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3384// Name, LocalId, m_redo.Count);
3385
3386 if (m_redo.Count > 0)
3387 {
3388 UndoState gofwd = m_redo[m_redo.Count - 1];
3389 m_redo.RemoveAt(m_redo.Count - 1);
3390
3391 if (ParentGroup.Scene.MaxUndoCount > 0)
3392 {
3393 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3394
3395 m_undo.Add(nUndo);
3396
3397 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3398 m_undo.RemoveAt(0);
3399 }
3400
3401 gofwd.PlayfwdState(this);
3402 3848
3403// m_log.DebugFormat( 3849 lock (m_UndoRedo)
3404// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3850 {
3405// Name, LocalId, m_redo.Count); 3851 Undoing = true;
3406 } 3852 m_UndoRedo.Redo(this);
3853 Undoing = false;
3407 } 3854 }
3408 } 3855 }
3409 3856
3410 public void ClearUndoState() 3857 public void ClearUndoState()
3411 { 3858 {
3412// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3859 if (m_UndoRedo == null || Undoing)
3860 return;
3413 3861
3414 lock (m_undo) 3862 lock (m_UndoRedo)
3415 { 3863 {
3416 m_undo.Clear(); 3864 m_UndoRedo.Clear();
3417 m_redo.Clear();
3418 } 3865 }
3419 } 3866 }
3420 3867
@@ -3965,7 +4412,7 @@ namespace OpenSim.Region.Framework.Scenes
3965 if (god) 4412 if (god)
3966 { 4413 {
3967 BaseMask = ApplyMask(BaseMask, set, mask); 4414 BaseMask = ApplyMask(BaseMask, set, mask);
3968 Inventory.ApplyGodPermissions(_baseMask); 4415 Inventory.ApplyGodPermissions(BaseMask);
3969 } 4416 }
3970 4417
3971 break; 4418 break;
@@ -3984,7 +4431,7 @@ namespace OpenSim.Region.Framework.Scenes
3984 case 16: 4431 case 16:
3985 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & 4432 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) &
3986 baseMask; 4433 baseMask;
3987 // Prevent the client from creating no mod, no copy 4434 // Prevent the client from creating no copy, no transfer
3988 // objects 4435 // objects
3989 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0) 4436 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0)
3990 NextOwnerMask |= (uint)PermissionMask.Transfer; 4437 NextOwnerMask |= (uint)PermissionMask.Transfer;
@@ -4002,20 +4449,20 @@ namespace OpenSim.Region.Framework.Scenes
4002 { 4449 {
4003 bool update = false; 4450 bool update = false;
4004 4451
4005 if (BaseMask != source.BaseMask || 4452 uint prevOwnerMask = OwnerMask;
4006 OwnerMask != source.OwnerMask || 4453 uint prevGroupMask = GroupMask;
4007 GroupMask != source.GroupMask || 4454 uint prevEveryoneMask = EveryoneMask;
4008 EveryoneMask != source.EveryoneMask || 4455 uint prevNextOwnerMask = NextOwnerMask;
4009 NextOwnerMask != source.NextOwnerMask)
4010 update = true;
4011 4456
4012 BaseMask = source.BaseMask; 4457 OwnerMask = source.OwnerMask & BaseMask;
4013 OwnerMask = source.OwnerMask; 4458 GroupMask = source.GroupMask & BaseMask;
4014 GroupMask = source.GroupMask; 4459 EveryoneMask = source.EveryoneMask & BaseMask;
4015 EveryoneMask = source.EveryoneMask; 4460 NextOwnerMask = source.NextOwnerMask & BaseMask;
4016 NextOwnerMask = source.NextOwnerMask;
4017 4461
4018 if (update) 4462 if (OwnerMask != prevOwnerMask ||
4463 GroupMask != prevGroupMask ||
4464 EveryoneMask != prevEveryoneMask ||
4465 NextOwnerMask != prevNextOwnerMask)
4019 SendFullUpdateToAllClients(); 4466 SendFullUpdateToAllClients();
4020 } 4467 }
4021 4468
@@ -4066,6 +4513,7 @@ namespace OpenSim.Region.Framework.Scenes
4066 } 4513 }
4067 } 4514 }
4068 4515
4516
4069 public void UpdateExtraPhysics(ExtraPhysicsData physdata) 4517 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4070 { 4518 {
4071 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null) 4519 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
@@ -4093,7 +4541,7 @@ namespace OpenSim.Region.Framework.Scenes
4093 /// <param name="SetTemporary"></param> 4541 /// <param name="SetTemporary"></param>
4094 /// <param name="SetPhantom"></param> 4542 /// <param name="SetPhantom"></param>
4095 /// <param name="SetVD"></param> 4543 /// <param name="SetVD"></param>
4096 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)
4097 { 4545 {
4098 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4546 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4099 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4547 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4103,116 +4551,98 @@ namespace OpenSim.Region.Framework.Scenes
4103 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4551 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4104 return; 4552 return;
4105 4553
4106 PhysicsActor pa = PhysActor; 4554 VolumeDetectActive = SetVD;
4107
4108 // Special cases for VD. VD can only be called from a script
4109 // and can't be combined with changes to other states. So we can rely
4110 // that...
4111 // ... if VD is changed, all others are not.
4112 // ... if one of the others is changed, VD is not.
4113 if (SetVD) // VD is active, special logic applies
4114 {
4115 // State machine logic for VolumeDetect
4116 // More logic below
4117 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4118
4119 if (phanReset) // Phantom changes from on to off switch VD off too
4120 {
4121 SetVD = false; // Switch it of for the course of this routine
4122 VolumeDetectActive = false; // and also permanently
4123
4124 if (pa != null)
4125 pa.SetVolumeDetect(0); // Let physics know about it too
4126 }
4127 else
4128 {
4129 // If volumedetect is active we don't want phantom to be applied.
4130 // If this is a new call to VD out of the state "phantom"
4131 // this will also cause the prim to be visible to physics
4132 SetPhantom = false;
4133 }
4134 }
4135 4555
4136 if (UsePhysics && IsJoint()) 4556 // volume detector implies phantom
4137 { 4557 if (VolumeDetectActive)
4138 SetPhantom = true; 4558 SetPhantom = true;
4139 }
4140 4559
4141 if (UsePhysics) 4560 if (UsePhysics)
4142 {
4143 AddFlag(PrimFlags.Physics); 4561 AddFlag(PrimFlags.Physics);
4144 if (!wasUsingPhysics)
4145 {
4146 DoPhysicsPropertyUpdate(UsePhysics, false);
4147 }
4148 }
4149 else 4562 else
4150 {
4151 RemFlag(PrimFlags.Physics); 4563 RemFlag(PrimFlags.Physics);
4152 if (wasUsingPhysics)
4153 {
4154 DoPhysicsPropertyUpdate(UsePhysics, false);
4155 }
4156 }
4157 4564
4158 if (SetPhantom 4565 if (SetPhantom)
4159 || ParentGroup.IsAttachment
4160 || PhysicsShapeType == (byte)PhysShapeType.none
4161 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4162 {
4163 AddFlag(PrimFlags.Phantom); 4566 AddFlag(PrimFlags.Phantom);
4567 else
4568 RemFlag(PrimFlags.Phantom);
4164 4569
4165 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)
4166 { 4588 {
4589 if(wasUsingPhysics)
4590 ParentGroup.Scene.RemovePhysicalPrim(1);
4167 RemoveFromPhysics(); 4591 RemoveFromPhysics();
4168 pa = null;
4169 } 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);
4170 } 4598 }
4171 else // Not phantom 4599
4600 else
4172 { 4601 {
4173 RemFlag(PrimFlags.Phantom); 4602 if (ParentGroup.Scene.CollidablePrims)
4174
4175 if (ParentGroup.Scene == null)
4176 return;
4177
4178 if (ParentGroup.Scene.CollidablePrims && pa == null)
4179 { 4603 {
4180 AddToPhysics(UsePhysics, SetPhantom, false); 4604 if (pa == null)
4181 pa = PhysActor;
4182
4183
4184 if (pa != null)
4185 { 4605 {
4186 pa.SetMaterial(Material); 4606 AddToPhysics(UsePhysics, SetPhantom, building, false);
4187 DoPhysicsPropertyUpdate(UsePhysics, true); 4607 pa = PhysActor;
4188 4608/*
4189 if ( 4609 if (pa != null)
4190 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4191 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4192 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4193 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4194 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4195 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4196 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4197 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4198 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4199 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4200 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4201 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4202 (CollisionSound != UUID.Zero)
4203 )
4204 { 4610 {
4205 pa.OnCollisionUpdate += PhysicsCollision; 4611 if (
4206 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 }
4207 } 4626 }
4627*/
4208 } 4628 }
4209 } 4629 else // it already has a physical representation
4210 else // it already has a physical representation 4630 {
4211 { 4631 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4212 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim 4632/* moved into DoPhysicsPropertyUpdate
4213 } 4633 if(VolumeDetectActive)
4214 } 4634 pa.SetVolumeDetect(1);
4635 else
4636 pa.SetVolumeDetect(0);
4637*/
4215 4638
4639 if (pa.Building != building)
4640 pa.Building = building;
4641 }
4642
4643 UpdatePhysicsSubscribedEvents();
4644 }
4645 }
4216 if (SetVD) 4646 if (SetVD)
4217 { 4647 {
4218 // 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!)
@@ -4226,6 +4656,7 @@ namespace OpenSim.Region.Framework.Scenes
4226 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
4227 VolumeDetectActive = true; 4657 VolumeDetectActive = true;
4228 } 4658 }
4659 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4229 } 4660 }
4230 else if (SetVD != wasVD) 4661 else if (SetVD != wasVD)
4231 { 4662 {
@@ -4237,61 +4668,51 @@ namespace OpenSim.Region.Framework.Scenes
4237 RemFlag(PrimFlags.Phantom); 4668 RemFlag(PrimFlags.Phantom);
4238 VolumeDetectActive = false; 4669 VolumeDetectActive = false;
4239 } 4670 }
4240 4671 // and last in case we have a new actor and not building
4241 if (SetTemporary)
4242 {
4243 AddFlag(PrimFlags.TemporaryOnRez);
4244 }
4245 else
4246 {
4247 RemFlag(PrimFlags.TemporaryOnRez);
4248 }
4249
4250 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4251 4672
4252 if (ParentGroup != null) 4673 if (ParentGroup != null)
4253 { 4674 {
4254 ParentGroup.HasGroupChanged = true; 4675 ParentGroup.HasGroupChanged = true;
4255 ScheduleFullUpdate(); 4676 ScheduleFullUpdate();
4256 } 4677 }
4257 4678
4258// 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);
4259 } 4680 }
4260 4681
4261 /// <summary> 4682 /// <summary>
4262 /// Adds this part to the physics scene. 4683 /// Adds this part to the physics scene.
4684 /// and sets the PhysActor property
4263 /// </summary> 4685 /// </summary>
4264 /// <remarks>This method also sets the PhysActor property.</remarks> 4686 /// <param name="isPhysical">Add this prim as physical.</param>
4265 /// <param name="rigidBody">Add this prim with a rigid body.</param> 4687 /// <param name="isPhantom">Add this prim as phantom.</param>
4266 /// <returns> 4688 /// <param name="building">tells physics to delay full construction of object</param>
4267 /// The physics actor. null if there was a failure. 4689 /// <param name="applyDynamics">applies velocities, force and torque</param>
4268 /// </returns> 4690 private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
4269 private void AddToPhysics(bool isPhysical, bool isPhantom, bool applyDynamics) 4691 {
4270 {
4271 PhysicsActor pa; 4692 PhysicsActor pa;
4272 4693
4273 Vector3 velocity = Velocity; 4694 Vector3 velocity = Velocity;
4274 Vector3 rotationalVelocity = AngularVelocity;; 4695 Vector3 rotationalVelocity = AngularVelocity;;
4275 4696
4276 try 4697 try
4277 { 4698 {
4278 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4699 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4279 string.Format("{0}/{1}", Name, UUID), 4700 string.Format("{0}/{1}", Name, UUID),
4280 Shape, 4701 Shape,
4281 AbsolutePosition, 4702 AbsolutePosition,
4282 Scale, 4703 Scale,
4283 GetWorldRotation(), 4704 GetWorldRotation(),
4284 isPhysical, 4705 isPhysical,
4285 isPhantom, 4706 isPhantom,
4286 PhysicsShapeType, 4707 PhysicsShapeType,
4287 m_localId); 4708 m_localId);
4288 } 4709 }
4289 catch (Exception e) 4710 catch (Exception e)
4290 { 4711 {
4291 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);
4292 pa = null; 4713 pa = null;
4293 } 4714 }
4294 4715
4295 if (pa != null) 4716 if (pa != null)
4296 { 4717 {
4297 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
@@ -4304,11 +4725,21 @@ namespace OpenSim.Region.Framework.Scenes
4304 4725
4305 if (VolumeDetectActive) // change if not the default only 4726 if (VolumeDetectActive) // change if not the default only
4306 pa.SetVolumeDetect(1); 4727 pa.SetVolumeDetect(1);
4728
4729 if (m_vehicleParams != null && LocalId == ParentGroup.RootPart.LocalId)
4730 m_vehicleParams.SetVehicle(pa);
4731
4307 // 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
4308 PhysActor = pa; 4733 PhysActor = pa;
4309 4734
4735 // DoPhysicsPropertyUpdate(isPhysical, true);
4736 // lets expand it here just with what it really needs to do
4737
4310 if (isPhysical) 4738 if (isPhysical)
4311 { 4739 {
4740 if (ParentGroup.RootPart.KeyframeMotion != null)
4741 ParentGroup.RootPart.KeyframeMotion.Stop();
4742 ParentGroup.RootPart.KeyframeMotion = null;
4312 ParentGroup.Scene.AddPhysicalPrim(1); 4743 ParentGroup.Scene.AddPhysicalPrim(1);
4313 4744
4314 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 4745 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
@@ -4325,19 +4756,34 @@ namespace OpenSim.Region.Framework.Scenes
4325 } 4756 }
4326 } 4757 }
4327 4758
4328 if (applyDynamics) 4759 if (applyDynamics)
4329 // do independent of isphysical so parameters get setted (at least some) 4760 // do independent of isphysical so parameters get setted (at least some)
4330 { 4761 {
4331 Velocity = velocity; 4762 Velocity = velocity;
4332 AngularVelocity = rotationalVelocity; 4763 AngularVelocity = rotationalVelocity;
4333// pa.Velocity = velocity; 4764// pa.Velocity = velocity;
4334 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 }
4335 } 4774 }
4336 4775
4337 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;
4338 } 4783 }
4339 4784
4340 PhysActor = pa; 4785 PhysActor = pa;
4786
4341 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this); 4787 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this);
4342 } 4788 }
4343 4789
@@ -4346,13 +4792,21 @@ namespace OpenSim.Region.Framework.Scenes
4346 /// </summary> 4792 /// </summary>
4347 /// <remarks> 4793 /// <remarks>
4348 /// 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
4349 /// representation for collision detection. Rather, this would be used in situations such as making a prim 4795 /// representation for collision detection.
4350 /// phantom.
4351 /// </remarks> 4796 /// </remarks>
4352 public void RemoveFromPhysics() 4797 public void RemoveFromPhysics()
4353 { 4798 {
4354 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this); 4799 PhysicsActor pa = PhysActor;
4355 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 }
4356 PhysActor = null; 4810 PhysActor = null;
4357 } 4811 }
4358 4812
@@ -4484,6 +4938,8 @@ namespace OpenSim.Region.Framework.Scenes
4484 { 4938 {
4485// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); 4939// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4486 4940
4941 return;
4942
4487 if (ParentGroup.IsDeleted) 4943 if (ParentGroup.IsDeleted)
4488 return; 4944 return;
4489 4945
@@ -4581,6 +5037,44 @@ namespace OpenSim.Region.Framework.Scenes
4581 ScheduleFullUpdate(); 5037 ScheduleFullUpdate();
4582 } 5038 }
4583 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
4584 public void aggregateScriptEvents() 5078 public void aggregateScriptEvents()
4585 { 5079 {
4586 if (ParentGroup == null || ParentGroup.RootPart == null) 5080 if (ParentGroup == null || ParentGroup.RootPart == null)
@@ -4617,40 +5111,32 @@ namespace OpenSim.Region.Framework.Scenes
4617 { 5111 {
4618 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; 5112 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop;
4619 } 5113 }
4620 5114/*
4621 PhysicsActor pa = PhysActor; 5115 PhysicsActor pa = PhysActor;
4622 5116 if (pa != null)
4623 if (
4624 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4625 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4626 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4627 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4628 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4629 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4630 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4631 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4632 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4633 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4634 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4635 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4636 (CollisionSound != UUID.Zero)
4637 )
4638 { 5117 {
4639 // subscribe to physics updates. 5118 if (
4640 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 )
4641 { 5127 {
5128 // subscribe to physics updates.
4642 pa.OnCollisionUpdate += PhysicsCollision; 5129 pa.OnCollisionUpdate += PhysicsCollision;
4643 pa.SubscribeEvents(1000); 5130 pa.SubscribeEvents(1000);
4644 } 5131 }
4645 } 5132 else
4646 else
4647 {
4648 if (pa != null)
4649 { 5133 {
4650 pa.UnSubscribeEvents(); 5134 pa.UnSubscribeEvents();
4651 pa.OnCollisionUpdate -= PhysicsCollision; 5135 pa.OnCollisionUpdate -= PhysicsCollision;
4652 } 5136 }
4653 } 5137 }
5138 */
5139 UpdatePhysicsSubscribedEvents();
4654 5140
4655 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 5141 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4656 //{ 5142 //{
@@ -4781,6 +5267,18 @@ namespace OpenSim.Region.Framework.Scenes
4781 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));
4782 } 5268 }
4783 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
4784 /// <summary> 5282 /// <summary>
4785 /// Record an avatar sitting on this part. 5283 /// Record an avatar sitting on this part.
4786 /// </summary> 5284 /// </summary>