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.cs1510
1 files changed, 1012 insertions, 498 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 847df03..261e958 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;
@@ -424,11 +470,11 @@ namespace OpenSim.Region.Framework.Scenes
424 private uint _category; 470 private uint _category;
425 private Int32 _creationDate; 471 private Int32 _creationDate;
426 private uint _parentID = 0; 472 private uint _parentID = 0;
427 private uint _baseMask = (uint)PermissionMask.All; 473 private uint _baseMask = (uint)(PermissionMask.All | PermissionMask.Export);
428 private uint _ownerMask = (uint)PermissionMask.All; 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
@@ -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,10 @@ 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 dupe.PayPrice = (int[])PayPrice.Clone();
2165
1803 dupe.DynAttrs.CopyFrom(DynAttrs); 2166 dupe.DynAttrs.CopyFrom(DynAttrs);
1804 2167
1805 if (userExposed) 2168 if (userExposed)
@@ -1813,8 +2176,12 @@ namespace OpenSim.Region.Framework.Scenes
1813*/ 2176*/
1814 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 2177 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
1815 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 2178 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
2179// dupe.UpdatePhysicsSubscribedEvents(); // not sure...
1816 } 2180 }
1817 2181
2182 if (dupe.PhysActor != null)
2183 dupe.PhysActor.LocalID = localID;
2184
1818 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 2185 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1819 2186
1820// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); 2187// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
@@ -1833,10 +2200,10 @@ namespace OpenSim.Region.Framework.Scenes
1833 { 2200 {
1834 if (asset != null) 2201 if (asset != null)
1835 SculptTextureCallback(asset); 2202 SculptTextureCallback(asset);
1836 else 2203// else
1837 m_log.WarnFormat( 2204// 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", 2205// "[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); 2206// Name, UUID, id);
1840 } 2207 }
1841*/ 2208*/
1842 /// <summary> 2209 /// <summary>
@@ -1935,6 +2302,7 @@ namespace OpenSim.Region.Framework.Scenes
1935 2302
1936 /// <summary> 2303 /// <summary>
1937 /// Do a physics propery update for this part. 2304 /// Do a physics propery update for this part.
2305 /// now also updates phantom and volume detector
1938 /// </summary> 2306 /// </summary>
1939 /// <param name="UsePhysics"></param> 2307 /// <param name="UsePhysics"></param>
1940 /// <param name="isNew"></param> 2308 /// <param name="isNew"></param>
@@ -1960,61 +2328,69 @@ namespace OpenSim.Region.Framework.Scenes
1960 { 2328 {
1961 if (pa.IsPhysical) // implies UsePhysics==false for this block 2329 if (pa.IsPhysical) // implies UsePhysics==false for this block
1962 { 2330 {
1963 if (!isNew) 2331 if (!isNew) // implies UsePhysics==false for this block
2332 {
1964 ParentGroup.Scene.RemovePhysicalPrim(1); 2333 ParentGroup.Scene.RemovePhysicalPrim(1);
1965 2334
1966 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 2335 Velocity = new Vector3(0, 0, 0);
1967 pa.OnOutOfBounds -= PhysicsOutOfBounds; 2336 Acceleration = new Vector3(0, 0, 0);
1968 pa.delink(); 2337 if (ParentGroup.RootPart == this)
2338 AngularVelocity = new Vector3(0, 0, 0);
1969 2339
1970 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 2340 if (pa.Phantom && !VolumeDetectActive)
1971 { 2341 {
1972 // destroy all joints connected to this now deactivated body 2342 RemoveFromPhysics();
1973 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); 2343 return;
1974 } 2344 }
1975 2345
1976 // stop client-side interpolation of all joint proxy objects that have just been deleted 2346 pa.IsPhysical = UsePhysics;
1977 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback, 2347 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1978 // which stops client-side interpolation of deactivated joint proxy objects. 2348 pa.OnOutOfBounds -= PhysicsOutOfBounds;
2349 pa.delink();
2350 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
2351 {
2352 // destroy all joints connected to this now deactivated body
2353 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa);
2354 }
2355 }
1979 } 2356 }
1980 2357
1981 if (!UsePhysics && !isNew) 2358 if (pa.IsPhysical != UsePhysics)
1982 { 2359 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 2360
1992 pa.IsPhysical = UsePhysics; 2361 if (UsePhysics)
2362 {
2363 if (ParentGroup.RootPart.KeyframeMotion != null)
2364 ParentGroup.RootPart.KeyframeMotion.Stop();
2365 ParentGroup.RootPart.KeyframeMotion = null;
2366 ParentGroup.Scene.AddPhysicalPrim(1);
1993 2367
1994 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 2368 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1995 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 2369 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1996 /// that's not wholesome. Had to make Scene public
1997 //PhysActor = null;
1998 2370
1999 if ((Flags & PrimFlags.Phantom) == 0) 2371 if (ParentID != 0 && ParentID != LocalId)
2000 {
2001 if (UsePhysics)
2002 { 2372 {
2003 ParentGroup.Scene.AddPhysicalPrim(1); 2373 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
2004 2374
2005 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 2375 if (parentPa != null)
2006 pa.OnOutOfBounds += PhysicsOutOfBounds;
2007 if (ParentID != 0 && ParentID != LocalId)
2008 { 2376 {
2009 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; 2377 pa.link(parentPa);
2010
2011 if (parentPa != null)
2012 {
2013 pa.link(parentPa);
2014 }
2015 } 2378 }
2016 } 2379 }
2017 } 2380 }
2381 }
2382
2383 bool phan = ((Flags & PrimFlags.Phantom) != 0);
2384 if (pa.Phantom != phan)
2385 pa.Phantom = phan;
2386
2387// some engines dont' have this check still
2388// if (VolumeDetectActive != pa.IsVolumeDtc)
2389 {
2390 if (VolumeDetectActive)
2391 pa.SetVolumeDetect(1);
2392 else
2393 pa.SetVolumeDetect(0);
2018 } 2394 }
2019 2395
2020 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 2396 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
@@ -2133,42 +2509,63 @@ namespace OpenSim.Region.Framework.Scenes
2133 2509
2134 public Vector3 GetGeometricCenter() 2510 public Vector3 GetGeometricCenter()
2135 { 2511 {
2512 // this is not real geometric center but a average of positions relative to root prim acording to
2513 // http://wiki.secondlife.com/wiki/llGetGeometricCenter
2514 // ignoring tortured prims details since sl also seems to ignore
2515 // so no real use in doing it on physics
2516 if (ParentGroup.IsDeleted)
2517 return new Vector3(0, 0, 0);
2518
2519 return ParentGroup.GetGeometricCenter();
2520 }
2521
2522 public float GetMass()
2523 {
2136 PhysicsActor pa = PhysActor; 2524 PhysicsActor pa = PhysActor;
2137 2525
2138 if (pa != null) 2526 if (pa != null)
2139 return new Vector3(pa.GeometricCenter.X, pa.GeometricCenter.Y, pa.GeometricCenter.Z); 2527 return pa.Mass;
2140 else 2528 else
2141 return new Vector3(0, 0, 0); 2529 return 0;
2142 } 2530 }
2143 2531
2144 public Vector3 GetCenterOfMass() 2532 public Vector3 GetCenterOfMass()
2145 { 2533 {
2534 if (ParentGroup.RootPart == this)
2535 {
2536 if (ParentGroup.IsDeleted)
2537 return AbsolutePosition;
2538 return ParentGroup.GetCenterOfMass();
2539 }
2540
2146 PhysicsActor pa = PhysActor; 2541 PhysicsActor pa = PhysActor;
2147 2542
2148 if (pa != null) 2543 if (pa != null)
2149 return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z); 2544 {
2545 Vector3 tmp = pa.CenterOfMass;
2546 return tmp;
2547 }
2150 else 2548 else
2151 return new Vector3(0, 0, 0); 2549 return AbsolutePosition;
2152 } 2550 }
2153 2551
2154 public float GetMass() 2552 public Vector3 GetPartCenterOfMass()
2155 { 2553 {
2156 PhysicsActor pa = PhysActor; 2554 PhysicsActor pa = PhysActor;
2157 2555
2158 if (pa != null) 2556 if (pa != null)
2159 return pa.Mass; 2557 {
2558 Vector3 tmp = pa.CenterOfMass;
2559 return tmp;
2560 }
2160 else 2561 else
2161 return 0; 2562 return AbsolutePosition;
2162 } 2563 }
2163 2564
2565
2164 public Vector3 GetForce() 2566 public Vector3 GetForce()
2165 { 2567 {
2166 PhysicsActor pa = PhysActor; 2568 return Force;
2167
2168 if (pa != null)
2169 return pa.Force;
2170 else
2171 return Vector3.Zero;
2172 } 2569 }
2173 2570
2174 /// <summary> 2571 /// <summary>
@@ -2383,15 +2780,25 @@ namespace OpenSim.Region.Framework.Scenes
2383 2780
2384 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify) 2781 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify)
2385 { 2782 {
2386 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0) 2783 bool sendToRoot = true;
2387 {
2388 ColliderArgs LandCollidingMessage = new ColliderArgs();
2389 List<DetectedObject> colliding = new List<DetectedObject>();
2390
2391 colliding.Add(CreateDetObjectForGround());
2392 LandCollidingMessage.Colliders = colliding;
2393 2784
2785 ColliderArgs LandCollidingMessage = new ColliderArgs();
2786 List<DetectedObject> colliding = new List<DetectedObject>();
2787
2788 colliding.Add(CreateDetObjectForGround());
2789 LandCollidingMessage.Colliders = colliding;
2790
2791 if (Inventory.ContainsScripts())
2792 {
2793 if (!PassCollisions)
2794 sendToRoot = false;
2795 }
2796 if ((ScriptEvents & ev) != 0)
2394 notify(LocalId, LandCollidingMessage); 2797 notify(LocalId, LandCollidingMessage);
2798
2799 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0 && sendToRoot)
2800 {
2801 notify(ParentGroup.RootPart.LocalId, LandCollidingMessage);
2395 } 2802 }
2396 } 2803 }
2397 2804
@@ -2407,57 +2814,120 @@ namespace OpenSim.Region.Framework.Scenes
2407 List<uint> endedColliders = new List<uint>(); 2814 List<uint> endedColliders = new List<uint>();
2408 List<uint> startedColliders = new List<uint>(); 2815 List<uint> startedColliders = new List<uint>();
2409 2816
2410 // calculate things that started colliding this time 2817 if (collissionswith.Count == 0)
2411 // and build up list of colliders this time
2412 foreach (uint localid in collissionswith.Keys)
2413 { 2818 {
2414 thisHitColliders.Add(localid); 2819 if (m_lastColliders.Count == 0)
2415 if (!m_lastColliders.Contains(localid)) 2820 return; // nothing to do
2416 startedColliders.Add(localid);
2417 }
2418 2821
2419 // calculate things that ended colliding 2822 foreach (uint localID in m_lastColliders)
2420 foreach (uint localID in m_lastColliders) 2823 {
2421 {
2422 if (!thisHitColliders.Contains(localID))
2423 endedColliders.Add(localID); 2824 endedColliders.Add(localID);
2825 }
2826 m_lastColliders.Clear();
2424 } 2827 }
2425 2828
2426 //add the items that started colliding this time to the last colliders list. 2829 else
2427 foreach (uint localID in startedColliders) 2830 {
2428 m_lastColliders.Add(localID); 2831 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
2832
2833 // calculate things that started colliding this time
2834 // and build up list of colliders this time
2835 if (!VolumeDetectActive && CollisionSoundType >= 0)
2836 {
2837 CollisionForSoundInfo soundinfo;
2838 ContactPoint curcontact;
2429 2839
2430 // remove things that ended colliding from the last colliders list 2840 foreach (uint id in collissionswith.Keys)
2431 foreach (uint localID in endedColliders) 2841 {
2432 m_lastColliders.Remove(localID); 2842 thisHitColliders.Add(id);
2843 if (!m_lastColliders.Contains(id))
2844 {
2845 startedColliders.Add(id);
2433 2846
2434 // play the sound. 2847 curcontact = collissionswith[id];
2435 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) 2848 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
2436 { 2849 {
2437 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>(); 2850 soundinfo = new CollisionForSoundInfo();
2438 if (soundModule != null) 2851 soundinfo.colliderID = id;
2852 soundinfo.position = curcontact.Position;
2853 soundinfo.relativeVel = curcontact.RelativeSpeed;
2854 soundinfolist.Add(soundinfo);
2855 }
2856 }
2857 }
2858 }
2859 else
2860 {
2861 foreach (uint id in collissionswith.Keys)
2862 {
2863 thisHitColliders.Add(id);
2864 if (!m_lastColliders.Contains(id))
2865 startedColliders.Add(id);
2866 }
2867 }
2868
2869 // calculate things that ended colliding
2870 foreach (uint localID in m_lastColliders)
2439 { 2871 {
2440 soundModule.SendSound(UUID, CollisionSound, 2872 if (!thisHitColliders.Contains(localID))
2441 CollisionSoundVolume, true, (byte)0, 0, false, 2873 endedColliders.Add(localID);
2442 false);
2443 } 2874 }
2875
2876 //add the items that started colliding this time to the last colliders list.
2877 foreach (uint localID in startedColliders)
2878 m_lastColliders.Add(localID);
2879
2880 // remove things that ended colliding from the last colliders list
2881 foreach (uint localID in endedColliders)
2882 m_lastColliders.Remove(localID);
2883
2884 // play sounds.
2885 if (soundinfolist.Count > 0)
2886 CollisionSounds.PartCollisionSound(this, soundinfolist);
2444 } 2887 }
2445 2888
2446 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart); 2889 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
2447 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding); 2890 if (!VolumeDetectActive)
2891 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
2448 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); 2892 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
2449 2893
2450 if (startedColliders.Contains(0)) 2894 if (startedColliders.Contains(0))
2451 { 2895 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2452 if (m_lastColliders.Contains(0)) 2896 if (m_lastColliders.Contains(0))
2453 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding); 2897 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)) 2898 if (endedColliders.Contains(0))
2458 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); 2899 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2459 } 2900 }
2460 2901
2902 // The Collision sounds code calls this
2903 public void SendCollisionSound(UUID soundID, double volume, Vector3 position)
2904 {
2905 if (soundID == UUID.Zero)
2906 return;
2907
2908 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>();
2909 if (soundModule == null)
2910 return;
2911
2912 if (volume > 1)
2913 volume = 1;
2914 if (volume < 0)
2915 volume = 0;
2916
2917 int now = Util.EnvironmentTickCount();
2918 if(Util.EnvironmentTickCountSubtract(now,LastColSoundSentTime) <200)
2919 return;
2920
2921 LastColSoundSentTime = now;
2922
2923 UUID ownerID = OwnerID;
2924 UUID objectID = ParentGroup.RootPart.UUID;
2925 UUID parentID = ParentGroup.UUID;
2926 ulong regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle;
2927
2928 soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, 0 );
2929 }
2930
2461 public void PhysicsOutOfBounds(Vector3 pos) 2931 public void PhysicsOutOfBounds(Vector3 pos)
2462 { 2932 {
2463 // Note: This is only being called on the root prim at this time. 2933 // Note: This is only being called on the root prim at this time.
@@ -2479,9 +2949,9 @@ namespace OpenSim.Region.Framework.Scenes
2479 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2949 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2480 2950
2481 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2951 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2482 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2952 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2483 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2953 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2484 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2954 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2485 { 2955 {
2486 ParentGroup.AbsolutePosition = newpos; 2956 ParentGroup.AbsolutePosition = newpos;
2487 return; 2957 return;
@@ -2766,6 +3236,14 @@ namespace OpenSim.Region.Framework.Scenes
2766 if (ParentGroup == null) 3236 if (ParentGroup == null)
2767 return; 3237 return;
2768 3238
3239 // Update the "last" values
3240 m_lastPosition = OffsetPosition;
3241 m_lastRotation = RotationOffset;
3242 m_lastVelocity = Velocity;
3243 m_lastAcceleration = Acceleration;
3244 m_lastAngularVelocity = AngularVelocity;
3245 m_lastUpdateSentTime = Environment.TickCount;
3246
2769 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3247 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
2770 { 3248 {
2771 SendFullUpdate(avatar.ControllingClient); 3249 SendFullUpdate(avatar.ControllingClient);
@@ -2824,8 +3302,8 @@ namespace OpenSim.Region.Framework.Scenes
2824 { 3302 {
2825 const float ROTATION_TOLERANCE = 0.01f; 3303 const float ROTATION_TOLERANCE = 0.01f;
2826 const float VELOCITY_TOLERANCE = 0.001f; 3304 const float VELOCITY_TOLERANCE = 0.001f;
2827 const float POSITION_TOLERANCE = 0.05f; 3305 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2828 const int TIME_MS_TOLERANCE = 3000; 3306 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2829 3307
2830 switch (UpdateFlag) 3308 switch (UpdateFlag)
2831 { 3309 {
@@ -2839,17 +3317,10 @@ namespace OpenSim.Region.Framework.Scenes
2839 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || 3317 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) ||
2840 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || 3318 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) ||
2841 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 3319 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
2842 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 3320 Environment.TickCount - m_lastUpdateSentTime > TIME_MS_TOLERANCE)
2843 { 3321 {
2844 SendTerseUpdateToAllClients(); 3322 SendTerseUpdateToAllClients();
2845 3323
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 } 3324 }
2854 break; 3325 break;
2855 } 3326 }
@@ -2867,6 +3338,17 @@ namespace OpenSim.Region.Framework.Scenes
2867 /// </summary> 3338 /// </summary>
2868 public void SendTerseUpdateToAllClients() 3339 public void SendTerseUpdateToAllClients()
2869 { 3340 {
3341 if (ParentGroup == null || ParentGroup.Scene == null)
3342 return;
3343
3344 // Update the "last" values
3345 m_lastPosition = OffsetPosition;
3346 m_lastRotation = RotationOffset;
3347 m_lastVelocity = Velocity;
3348 m_lastAcceleration = Acceleration;
3349 m_lastAngularVelocity = AngularVelocity;
3350 m_lastUpdateSentTime = Environment.TickCount;
3351
2870 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3352 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
2871 { 3353 {
2872 SendTerseUpdateToClient(client); 3354 SendTerseUpdateToClient(client);
@@ -2890,10 +3372,13 @@ namespace OpenSim.Region.Framework.Scenes
2890 3372
2891 public void SetBuoyancy(float fvalue) 3373 public void SetBuoyancy(float fvalue)
2892 { 3374 {
2893 PhysicsActor pa = PhysActor; 3375 Buoyancy = fvalue;
2894 3376/*
2895 if (pa != null) 3377 if (PhysActor != null)
2896 pa.Buoyancy = fvalue; 3378 {
3379 PhysActor.Buoyancy = fvalue;
3380 }
3381 */
2897 } 3382 }
2898 3383
2899 public void SetDieAtEdge(bool p) 3384 public void SetDieAtEdge(bool p)
@@ -2909,47 +3394,111 @@ namespace OpenSim.Region.Framework.Scenes
2909 PhysicsActor pa = PhysActor; 3394 PhysicsActor pa = PhysActor;
2910 3395
2911 if (pa != null) 3396 if (pa != null)
2912 pa.FloatOnWater = floatYN == 1; 3397 pa.FloatOnWater = (floatYN == 1);
2913 } 3398 }
2914 3399
2915 public void SetForce(Vector3 force) 3400 public void SetForce(Vector3 force)
2916 { 3401 {
2917 PhysicsActor pa = PhysActor; 3402 Force = force;
3403 }
2918 3404
2919 if (pa != null) 3405 public SOPVehicle VehicleParams
2920 pa.Force = force; 3406 {
3407 get
3408 {
3409 return m_vehicleParams;
3410 }
3411 set
3412 {
3413 m_vehicleParams = value;
3414 }
3415 }
3416
3417
3418 public int VehicleType
3419 {
3420 get
3421 {
3422 if (m_vehicleParams == null)
3423 return (int)Vehicle.TYPE_NONE;
3424 else
3425 return (int)m_vehicleParams.Type;
3426 }
3427 set
3428 {
3429 SetVehicleType(value);
3430 }
2921 } 3431 }
2922 3432
2923 public void SetVehicleType(int type) 3433 public void SetVehicleType(int type)
2924 { 3434 {
2925 PhysicsActor pa = PhysActor; 3435 m_vehicleParams = null;
3436
3437 if (type == (int)Vehicle.TYPE_NONE)
3438 {
3439 if (_parentID ==0 && PhysActor != null)
3440 PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
3441 return;
3442 }
3443 m_vehicleParams = new SOPVehicle();
3444 m_vehicleParams.ProcessTypeChange((Vehicle)type);
3445 {
3446 if (_parentID ==0 && PhysActor != null)
3447 PhysActor.VehicleType = type;
3448 return;
3449 }
3450 }
2926 3451
2927 if (pa != null) 3452 public void SetVehicleFlags(int param, bool remove)
2928 pa.VehicleType = type; 3453 {
3454 if (m_vehicleParams == null)
3455 return;
3456
3457 m_vehicleParams.ProcessVehicleFlags(param, remove);
3458
3459 if (_parentID ==0 && PhysActor != null)
3460 {
3461 PhysActor.VehicleFlags(param, remove);
3462 }
2929 } 3463 }
2930 3464
2931 public void SetVehicleFloatParam(int param, float value) 3465 public void SetVehicleFloatParam(int param, float value)
2932 { 3466 {
2933 PhysicsActor pa = PhysActor; 3467 if (m_vehicleParams == null)
3468 return;
2934 3469
2935 if (pa != null) 3470 m_vehicleParams.ProcessFloatVehicleParam((Vehicle)param, value);
2936 pa.VehicleFloatParam(param, value); 3471
3472 if (_parentID == 0 && PhysActor != null)
3473 {
3474 PhysActor.VehicleFloatParam(param, value);
3475 }
2937 } 3476 }
2938 3477
2939 public void SetVehicleVectorParam(int param, Vector3 value) 3478 public void SetVehicleVectorParam(int param, Vector3 value)
2940 { 3479 {
2941 PhysicsActor pa = PhysActor; 3480 if (m_vehicleParams == null)
3481 return;
2942 3482
2943 if (pa != null) 3483 m_vehicleParams.ProcessVectorVehicleParam((Vehicle)param, value);
2944 pa.VehicleVectorParam(param, value); 3484
3485 if (_parentID == 0 && PhysActor != null)
3486 {
3487 PhysActor.VehicleVectorParam(param, value);
3488 }
2945 } 3489 }
2946 3490
2947 public void SetVehicleRotationParam(int param, Quaternion rotation) 3491 public void SetVehicleRotationParam(int param, Quaternion rotation)
2948 { 3492 {
2949 PhysicsActor pa = PhysActor; 3493 if (m_vehicleParams == null)
3494 return;
2950 3495
2951 if (pa != null) 3496 m_vehicleParams.ProcessRotationVehicleParam((Vehicle)param, rotation);
2952 pa.VehicleRotationParam(param, rotation); 3497
3498 if (_parentID == 0 && PhysActor != null)
3499 {
3500 PhysActor.VehicleRotationParam(param, rotation);
3501 }
2953 } 3502 }
2954 3503
2955 /// <summary> 3504 /// <summary>
@@ -3150,14 +3699,6 @@ namespace OpenSim.Region.Framework.Scenes
3150 hasProfileCut = hasDimple; // is it the same thing? 3699 hasProfileCut = hasDimple; // is it the same thing?
3151 } 3700 }
3152 3701
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) 3702 public void SetGroup(UUID groupID, IClientAPI client)
3162 { 3703 {
3163 // Scene.AddNewPrims() calls with client == null so can't use this. 3704 // Scene.AddNewPrims() calls with client == null so can't use this.
@@ -3261,71 +3802,20 @@ namespace OpenSim.Region.Framework.Scenes
3261 { 3802 {
3262 ParentGroup.stopMoveToTarget(); 3803 ParentGroup.stopMoveToTarget();
3263 3804
3264 ParentGroup.ScheduleGroupForTerseUpdate(); 3805// ParentGroup.ScheduleGroupForTerseUpdate();
3265 //ParentGroup.ScheduleGroupForFullUpdate(); 3806 //ParentGroup.ScheduleGroupForFullUpdate();
3266 } 3807 }
3267 3808
3268 public void StoreUndoState() 3809 public void StoreUndoState(ObjectChangeType change)
3269 { 3810 {
3270 StoreUndoState(false); 3811 if (m_UndoRedo == null)
3271 } 3812 m_UndoRedo = new UndoRedoState(5);
3272
3273 public void StoreUndoState(bool forGroup)
3274 {
3275 if (ParentGroup == null || ParentGroup.Scene == null)
3276 return;
3277
3278 if (Undoing)
3279 {
3280// m_log.DebugFormat(
3281// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3282 return;
3283 }
3284
3285 if (IgnoreUndoUpdate)
3286 {
3287// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3288 return;
3289 }
3290 3813
3291 lock (m_undo) 3814 lock (m_UndoRedo)
3292 { 3815 {
3293 if (m_undo.Count > 0) 3816 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3294 { 3817 {
3295 UndoState last = m_undo[m_undo.Count - 1]; 3818 m_UndoRedo.StoreUndo(this, change);
3296 if (last != null)
3297 {
3298 // TODO: May need to fix for group comparison
3299 if (last.Compare(this))
3300 {
3301// m_log.DebugFormat(
3302// "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3303// Name, LocalId, m_undo.Count);
3304
3305 return;
3306 }
3307 }
3308 }
3309
3310// m_log.DebugFormat(
3311// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3312// Name, LocalId, forGroup, m_undo.Count);
3313
3314 if (ParentGroup.Scene.MaxUndoCount > 0)
3315 {
3316 UndoState nUndo = new UndoState(this, forGroup);
3317
3318 m_undo.Add(nUndo);
3319
3320 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3321 m_undo.RemoveAt(0);
3322
3323 if (m_redo.Count > 0)
3324 m_redo.Clear();
3325
3326// m_log.DebugFormat(
3327// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3328// Name, LocalId, forGroup, m_undo.Count);
3329 } 3819 }
3330 } 3820 }
3331 } 3821 }
@@ -3337,88 +3827,46 @@ namespace OpenSim.Region.Framework.Scenes
3337 { 3827 {
3338 get 3828 get
3339 { 3829 {
3340 lock (m_undo) 3830 if (m_UndoRedo == null)
3341 return m_undo.Count; 3831 return 0;
3832 return m_UndoRedo.Count;
3342 } 3833 }
3343 } 3834 }
3344 3835
3345 public void Undo() 3836 public void Undo()
3346 { 3837 {
3347 lock (m_undo) 3838 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3348 { 3839 return;
3349// m_log.DebugFormat(
3350// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3351// Name, LocalId, m_undo.Count);
3352
3353 if (m_undo.Count > 0)
3354 {
3355 UndoState goback = m_undo[m_undo.Count - 1];
3356 m_undo.RemoveAt(m_undo.Count - 1);
3357
3358 UndoState nUndo = null;
3359
3360 if (ParentGroup.Scene.MaxUndoCount > 0)
3361 {
3362 nUndo = new UndoState(this, goback.ForGroup);
3363 }
3364
3365 goback.PlaybackState(this);
3366
3367 if (nUndo != null)
3368 {
3369 m_redo.Add(nUndo);
3370
3371 if (m_redo.Count > ParentGroup.Scene.MaxUndoCount)
3372 m_redo.RemoveAt(0);
3373 }
3374 }
3375 3840
3376// m_log.DebugFormat( 3841 lock (m_UndoRedo)
3377// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3842 {
3378// Name, LocalId, m_undo.Count); 3843 Undoing = true;
3844 m_UndoRedo.Undo(this);
3845 Undoing = false;
3379 } 3846 }
3380 } 3847 }
3381 3848
3382 public void Redo() 3849 public void Redo()
3383 { 3850 {
3384 lock (m_undo) 3851 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3385 { 3852 return;
3386// m_log.DebugFormat(
3387// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3388// Name, LocalId, m_redo.Count);
3389
3390 if (m_redo.Count > 0)
3391 {
3392 UndoState gofwd = m_redo[m_redo.Count - 1];
3393 m_redo.RemoveAt(m_redo.Count - 1);
3394
3395 if (ParentGroup.Scene.MaxUndoCount > 0)
3396 {
3397 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3398
3399 m_undo.Add(nUndo);
3400
3401 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3402 m_undo.RemoveAt(0);
3403 }
3404
3405 gofwd.PlayfwdState(this);
3406 3853
3407// m_log.DebugFormat( 3854 lock (m_UndoRedo)
3408// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3855 {
3409// Name, LocalId, m_redo.Count); 3856 Undoing = true;
3410 } 3857 m_UndoRedo.Redo(this);
3858 Undoing = false;
3411 } 3859 }
3412 } 3860 }
3413 3861
3414 public void ClearUndoState() 3862 public void ClearUndoState()
3415 { 3863 {
3416// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3864 if (m_UndoRedo == null || Undoing)
3865 return;
3417 3866
3418 lock (m_undo) 3867 lock (m_UndoRedo)
3419 { 3868 {
3420 m_undo.Clear(); 3869 m_UndoRedo.Clear();
3421 m_redo.Clear();
3422 } 3870 }
3423 } 3871 }
3424 3872
@@ -3876,10 +4324,10 @@ namespace OpenSim.Region.Framework.Scenes
3876 4324
3877 public void TrimPermissions() 4325 public void TrimPermissions()
3878 { 4326 {
3879 BaseMask &= (uint)PermissionMask.All; 4327 BaseMask &= (uint)(PermissionMask.All | PermissionMask.Export);
3880 OwnerMask &= (uint)PermissionMask.All; 4328 OwnerMask &= (uint)(PermissionMask.All | PermissionMask.Export);
3881 GroupMask &= (uint)PermissionMask.All; 4329 GroupMask &= (uint)PermissionMask.All;
3882 EveryoneMask &= (uint)PermissionMask.All; 4330 EveryoneMask &= (uint)(PermissionMask.All | PermissionMask.Export);
3883 NextOwnerMask &= (uint)PermissionMask.All; 4331 NextOwnerMask &= (uint)PermissionMask.All;
3884 } 4332 }
3885 4333
@@ -3969,7 +4417,7 @@ namespace OpenSim.Region.Framework.Scenes
3969 if (god) 4417 if (god)
3970 { 4418 {
3971 BaseMask = ApplyMask(BaseMask, set, mask); 4419 BaseMask = ApplyMask(BaseMask, set, mask);
3972 Inventory.ApplyGodPermissions(_baseMask); 4420 Inventory.ApplyGodPermissions(BaseMask);
3973 } 4421 }
3974 4422
3975 break; 4423 break;
@@ -3982,13 +4430,25 @@ namespace OpenSim.Region.Framework.Scenes
3982 baseMask; 4430 baseMask;
3983 break; 4431 break;
3984 case 8: 4432 case 8:
4433 // Trying to set export permissions - extra checks
4434 if (set && (mask & (uint)PermissionMask.Export) != 0)
4435 {
4436 if ((OwnerMask & (uint)PermissionMask.Export) == 0 || (BaseMask & (uint)PermissionMask.Export) == 0 || (NextOwnerMask & (uint)PermissionMask.All) != (uint)PermissionMask.All)
4437 mask &= ~(uint)PermissionMask.Export;
4438 }
3985 EveryoneMask = ApplyMask(EveryoneMask, set, mask) & 4439 EveryoneMask = ApplyMask(EveryoneMask, set, mask) &
3986 baseMask; 4440 baseMask;
3987 break; 4441 break;
3988 case 16: 4442 case 16:
4443 // Force full perm if export
4444 if ((EveryoneMask & (uint)PermissionMask.Export) != 0)
4445 {
4446 NextOwnerMask = (uint)PermissionMask.All;
4447 break;
4448 }
3989 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & 4449 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) &
3990 baseMask; 4450 baseMask;
3991 // Prevent the client from creating no mod, no copy 4451 // Prevent the client from creating no copy, no transfer
3992 // objects 4452 // objects
3993 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0) 4453 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0)
3994 NextOwnerMask |= (uint)PermissionMask.Transfer; 4454 NextOwnerMask |= (uint)PermissionMask.Transfer;
@@ -4006,20 +4466,20 @@ namespace OpenSim.Region.Framework.Scenes
4006 { 4466 {
4007 bool update = false; 4467 bool update = false;
4008 4468
4009 if (BaseMask != source.BaseMask || 4469 uint prevOwnerMask = OwnerMask;
4010 OwnerMask != source.OwnerMask || 4470 uint prevGroupMask = GroupMask;
4011 GroupMask != source.GroupMask || 4471 uint prevEveryoneMask = EveryoneMask;
4012 EveryoneMask != source.EveryoneMask || 4472 uint prevNextOwnerMask = NextOwnerMask;
4013 NextOwnerMask != source.NextOwnerMask)
4014 update = true;
4015 4473
4016 BaseMask = source.BaseMask; 4474 OwnerMask = source.OwnerMask & BaseMask;
4017 OwnerMask = source.OwnerMask; 4475 GroupMask = source.GroupMask & BaseMask;
4018 GroupMask = source.GroupMask; 4476 EveryoneMask = source.EveryoneMask & BaseMask;
4019 EveryoneMask = source.EveryoneMask; 4477 NextOwnerMask = source.NextOwnerMask & BaseMask;
4020 NextOwnerMask = source.NextOwnerMask;
4021 4478
4022 if (update) 4479 if (OwnerMask != prevOwnerMask ||
4480 GroupMask != prevGroupMask ||
4481 EveryoneMask != prevEveryoneMask ||
4482 NextOwnerMask != prevNextOwnerMask)
4023 SendFullUpdateToAllClients(); 4483 SendFullUpdateToAllClients();
4024 } 4484 }
4025 4485
@@ -4070,6 +4530,7 @@ namespace OpenSim.Region.Framework.Scenes
4070 } 4530 }
4071 } 4531 }
4072 4532
4533
4073 public void UpdateExtraPhysics(ExtraPhysicsData physdata) 4534 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4074 { 4535 {
4075 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null) 4536 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
@@ -4097,7 +4558,7 @@ namespace OpenSim.Region.Framework.Scenes
4097 /// <param name="SetTemporary"></param> 4558 /// <param name="SetTemporary"></param>
4098 /// <param name="SetPhantom"></param> 4559 /// <param name="SetPhantom"></param>
4099 /// <param name="SetVD"></param> 4560 /// <param name="SetVD"></param>
4100 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) 4561 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
4101 { 4562 {
4102 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4563 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4103 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4564 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4107,116 +4568,98 @@ namespace OpenSim.Region.Framework.Scenes
4107 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4568 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4108 return; 4569 return;
4109 4570
4110 PhysicsActor pa = PhysActor; 4571 VolumeDetectActive = SetVD;
4111
4112 // Special cases for VD. VD can only be called from a script
4113 // and can't be combined with changes to other states. So we can rely
4114 // that...
4115 // ... if VD is changed, all others are not.
4116 // ... if one of the others is changed, VD is not.
4117 if (SetVD) // VD is active, special logic applies
4118 {
4119 // State machine logic for VolumeDetect
4120 // More logic below
4121 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4122
4123 if (phanReset) // Phantom changes from on to off switch VD off too
4124 {
4125 SetVD = false; // Switch it of for the course of this routine
4126 VolumeDetectActive = false; // and also permanently
4127
4128 if (pa != null)
4129 pa.SetVolumeDetect(0); // Let physics know about it too
4130 }
4131 else
4132 {
4133 // If volumedetect is active we don't want phantom to be applied.
4134 // If this is a new call to VD out of the state "phantom"
4135 // this will also cause the prim to be visible to physics
4136 SetPhantom = false;
4137 }
4138 }
4139 4572
4140 if (UsePhysics && IsJoint()) 4573 // volume detector implies phantom
4141 { 4574 if (VolumeDetectActive)
4142 SetPhantom = true; 4575 SetPhantom = true;
4143 }
4144 4576
4145 if (UsePhysics) 4577 if (UsePhysics)
4146 {
4147 AddFlag(PrimFlags.Physics); 4578 AddFlag(PrimFlags.Physics);
4148 if (!wasUsingPhysics)
4149 {
4150 DoPhysicsPropertyUpdate(UsePhysics, false);
4151 }
4152 }
4153 else 4579 else
4154 {
4155 RemFlag(PrimFlags.Physics); 4580 RemFlag(PrimFlags.Physics);
4156 if (wasUsingPhysics)
4157 {
4158 DoPhysicsPropertyUpdate(UsePhysics, false);
4159 }
4160 }
4161 4581
4162 if (SetPhantom 4582 if (SetPhantom)
4163 || ParentGroup.IsAttachment
4164 || PhysicsShapeType == (byte)PhysShapeType.none
4165 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4166 {
4167 AddFlag(PrimFlags.Phantom); 4583 AddFlag(PrimFlags.Phantom);
4584 else
4585 RemFlag(PrimFlags.Phantom);
4168 4586
4169 if (PhysActor != null) 4587 if (SetTemporary)
4588 AddFlag(PrimFlags.TemporaryOnRez);
4589 else
4590 RemFlag(PrimFlags.TemporaryOnRez);
4591
4592
4593 if (ParentGroup.Scene == null)
4594 return;
4595
4596 PhysicsActor pa = PhysActor;
4597
4598 if (pa != null && building && pa.Building != building)
4599 pa.Building = building;
4600
4601 if ((SetPhantom && !UsePhysics && !SetVD) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
4602 || (Shape.PathCurve == (byte)Extrusion.Flexible))
4603 {
4604 if (pa != null)
4170 { 4605 {
4606 if(wasUsingPhysics)
4607 ParentGroup.Scene.RemovePhysicalPrim(1);
4171 RemoveFromPhysics(); 4608 RemoveFromPhysics();
4172 pa = null;
4173 } 4609 }
4610
4611 Velocity = new Vector3(0, 0, 0);
4612 Acceleration = new Vector3(0, 0, 0);
4613 if (ParentGroup.RootPart == this)
4614 AngularVelocity = new Vector3(0, 0, 0);
4174 } 4615 }
4175 else // Not phantom 4616
4617 else
4176 { 4618 {
4177 RemFlag(PrimFlags.Phantom); 4619 if (ParentGroup.Scene.CollidablePrims)
4178
4179 if (ParentGroup.Scene == null)
4180 return;
4181
4182 if (ParentGroup.Scene.CollidablePrims && pa == null)
4183 { 4620 {
4184 AddToPhysics(UsePhysics, SetPhantom, false); 4621 if (pa == null)
4185 pa = PhysActor;
4186
4187
4188 if (pa != null)
4189 { 4622 {
4190 pa.SetMaterial(Material); 4623 AddToPhysics(UsePhysics, SetPhantom, building, false);
4191 DoPhysicsPropertyUpdate(UsePhysics, true); 4624 pa = PhysActor;
4192 4625/*
4193 if ( 4626 if (pa != null)
4194 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4195 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4196 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4197 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4198 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4199 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4200 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4201 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4202 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4203 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4204 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4205 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4206 (CollisionSound != UUID.Zero)
4207 )
4208 { 4627 {
4209 pa.OnCollisionUpdate += PhysicsCollision; 4628 if (
4210 pa.SubscribeEvents(1000); 4629// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4630// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4631// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4632// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4633// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4634// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4635 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4636 ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4637 (CollisionSound != UUID.Zero)
4638 )
4639 {
4640 pa.OnCollisionUpdate += PhysicsCollision;
4641 pa.SubscribeEvents(1000);
4642 }
4211 } 4643 }
4644*/
4212 } 4645 }
4213 } 4646 else // it already has a physical representation
4214 else // it already has a physical representation 4647 {
4215 { 4648 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4216 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim 4649/* moved into DoPhysicsPropertyUpdate
4217 } 4650 if(VolumeDetectActive)
4218 } 4651 pa.SetVolumeDetect(1);
4652 else
4653 pa.SetVolumeDetect(0);
4654*/
4219 4655
4656 if (pa.Building != building)
4657 pa.Building = building;
4658 }
4659
4660 UpdatePhysicsSubscribedEvents();
4661 }
4662 }
4220 if (SetVD) 4663 if (SetVD)
4221 { 4664 {
4222 // If the above logic worked (this is urgent candidate to unit tests!) 4665 // If the above logic worked (this is urgent candidate to unit tests!)
@@ -4230,6 +4673,7 @@ namespace OpenSim.Region.Framework.Scenes
4230 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active 4673 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4231 VolumeDetectActive = true; 4674 VolumeDetectActive = true;
4232 } 4675 }
4676 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4233 } 4677 }
4234 else if (SetVD != wasVD) 4678 else if (SetVD != wasVD)
4235 { 4679 {
@@ -4241,61 +4685,51 @@ namespace OpenSim.Region.Framework.Scenes
4241 RemFlag(PrimFlags.Phantom); 4685 RemFlag(PrimFlags.Phantom);
4242 VolumeDetectActive = false; 4686 VolumeDetectActive = false;
4243 } 4687 }
4244 4688 // and last in case we have a new actor and not building
4245 if (SetTemporary)
4246 {
4247 AddFlag(PrimFlags.TemporaryOnRez);
4248 }
4249 else
4250 {
4251 RemFlag(PrimFlags.TemporaryOnRez);
4252 }
4253
4254 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4255 4689
4256 if (ParentGroup != null) 4690 if (ParentGroup != null)
4257 { 4691 {
4258 ParentGroup.HasGroupChanged = true; 4692 ParentGroup.HasGroupChanged = true;
4259 ScheduleFullUpdate(); 4693 ScheduleFullUpdate();
4260 } 4694 }
4261 4695
4262// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); 4696// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4263 } 4697 }
4264 4698
4265 /// <summary> 4699 /// <summary>
4266 /// Adds this part to the physics scene. 4700 /// Adds this part to the physics scene.
4701 /// and sets the PhysActor property
4267 /// </summary> 4702 /// </summary>
4268 /// <remarks>This method also sets the PhysActor property.</remarks> 4703 /// <param name="isPhysical">Add this prim as physical.</param>
4269 /// <param name="rigidBody">Add this prim with a rigid body.</param> 4704 /// <param name="isPhantom">Add this prim as phantom.</param>
4270 /// <returns> 4705 /// <param name="building">tells physics to delay full construction of object</param>
4271 /// The physics actor. null if there was a failure. 4706 /// <param name="applyDynamics">applies velocities, force and torque</param>
4272 /// </returns> 4707 private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
4273 private void AddToPhysics(bool isPhysical, bool isPhantom, bool applyDynamics) 4708 {
4274 {
4275 PhysicsActor pa; 4709 PhysicsActor pa;
4276 4710
4277 Vector3 velocity = Velocity; 4711 Vector3 velocity = Velocity;
4278 Vector3 rotationalVelocity = AngularVelocity;; 4712 Vector3 rotationalVelocity = AngularVelocity;;
4279 4713
4280 try 4714 try
4281 { 4715 {
4282 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4716 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4283 string.Format("{0}/{1}", Name, UUID), 4717 string.Format("{0}/{1}", Name, UUID),
4284 Shape, 4718 Shape,
4285 AbsolutePosition, 4719 AbsolutePosition,
4286 Scale, 4720 Scale,
4287 GetWorldRotation(), 4721 GetWorldRotation(),
4288 isPhysical, 4722 isPhysical,
4289 isPhantom, 4723 isPhantom,
4290 PhysicsShapeType, 4724 PhysicsShapeType,
4291 m_localId); 4725 m_localId);
4292 } 4726 }
4293 catch (Exception e) 4727 catch (Exception e)
4294 { 4728 {
4295 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e); 4729 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e);
4296 pa = null; 4730 pa = null;
4297 } 4731 }
4298 4732
4299 if (pa != null) 4733 if (pa != null)
4300 { 4734 {
4301 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 4735 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
@@ -4308,11 +4742,21 @@ namespace OpenSim.Region.Framework.Scenes
4308 4742
4309 if (VolumeDetectActive) // change if not the default only 4743 if (VolumeDetectActive) // change if not the default only
4310 pa.SetVolumeDetect(1); 4744 pa.SetVolumeDetect(1);
4745
4746 if (m_vehicleParams != null && LocalId == ParentGroup.RootPart.LocalId)
4747 m_vehicleParams.SetVehicle(pa);
4748
4311 // we are going to tell rest of code about physics so better have this here 4749 // we are going to tell rest of code about physics so better have this here
4312 PhysActor = pa; 4750 PhysActor = pa;
4313 4751
4752 // DoPhysicsPropertyUpdate(isPhysical, true);
4753 // lets expand it here just with what it really needs to do
4754
4314 if (isPhysical) 4755 if (isPhysical)
4315 { 4756 {
4757 if (ParentGroup.RootPart.KeyframeMotion != null)
4758 ParentGroup.RootPart.KeyframeMotion.Stop();
4759 ParentGroup.RootPart.KeyframeMotion = null;
4316 ParentGroup.Scene.AddPhysicalPrim(1); 4760 ParentGroup.Scene.AddPhysicalPrim(1);
4317 4761
4318 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 4762 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
@@ -4329,19 +4773,34 @@ namespace OpenSim.Region.Framework.Scenes
4329 } 4773 }
4330 } 4774 }
4331 4775
4332 if (applyDynamics) 4776 if (applyDynamics)
4333 // do independent of isphysical so parameters get setted (at least some) 4777 // do independent of isphysical so parameters get setted (at least some)
4334 { 4778 {
4335 Velocity = velocity; 4779 Velocity = velocity;
4336 AngularVelocity = rotationalVelocity; 4780 AngularVelocity = rotationalVelocity;
4337// pa.Velocity = velocity; 4781// pa.Velocity = velocity;
4338 pa.RotationalVelocity = rotationalVelocity; 4782 pa.RotationalVelocity = rotationalVelocity;
4783
4784 // if not vehicle and root part apply force and torque
4785 if ((m_vehicleParams == null || m_vehicleParams.Type == Vehicle.TYPE_NONE)
4786 && LocalId == ParentGroup.RootPart.LocalId)
4787 {
4788 pa.Force = Force;
4789 pa.Torque = Torque;
4790 }
4339 } 4791 }
4340 4792
4341 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); 4793// if (Shape.SculptEntry)
4794// CheckSculptAndLoad();
4795// else
4796 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
4797
4798 if (!building)
4799 pa.Building = false;
4342 } 4800 }
4343 4801
4344 PhysActor = pa; 4802 PhysActor = pa;
4803
4345 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this); 4804 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this);
4346 } 4805 }
4347 4806
@@ -4350,13 +4809,21 @@ namespace OpenSim.Region.Framework.Scenes
4350 /// </summary> 4809 /// </summary>
4351 /// <remarks> 4810 /// <remarks>
4352 /// This isn't the same as turning off physical, since even without being physical the prim has a physics 4811 /// This isn't the same as turning off physical, since even without being physical the prim has a physics
4353 /// representation for collision detection. Rather, this would be used in situations such as making a prim 4812 /// representation for collision detection.
4354 /// phantom.
4355 /// </remarks> 4813 /// </remarks>
4356 public void RemoveFromPhysics() 4814 public void RemoveFromPhysics()
4357 { 4815 {
4358 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this); 4816 PhysicsActor pa = PhysActor;
4359 ParentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 4817 if (pa != null)
4818 {
4819 pa.OnCollisionUpdate -= PhysicsCollision;
4820 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
4821 pa.OnOutOfBounds -= PhysicsOutOfBounds;
4822
4823 ParentGroup.Scene.PhysicsScene.RemovePrim(pa);
4824
4825 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this);
4826 }
4360 PhysActor = null; 4827 PhysActor = null;
4361 } 4828 }
4362 4829
@@ -4488,6 +4955,8 @@ namespace OpenSim.Region.Framework.Scenes
4488 { 4955 {
4489// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); 4956// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4490 4957
4958 return;
4959
4491 if (ParentGroup.IsDeleted) 4960 if (ParentGroup.IsDeleted)
4492 return; 4961 return;
4493 4962
@@ -4585,6 +5054,44 @@ namespace OpenSim.Region.Framework.Scenes
4585 ScheduleFullUpdate(); 5054 ScheduleFullUpdate();
4586 } 5055 }
4587 5056
5057
5058 private void UpdatePhysicsSubscribedEvents()
5059 {
5060 PhysicsActor pa = PhysActor;
5061 if (pa == null)
5062 return;
5063
5064 pa.OnCollisionUpdate -= PhysicsCollision;
5065
5066 bool hassound = (!VolumeDetectActive && CollisionSoundType >= 0 && ((Flags & PrimFlags.Physics) != 0));
5067
5068 scriptEvents CombinedEvents = AggregateScriptEvents;
5069
5070 // merge with root part
5071 if (ParentGroup != null && ParentGroup.RootPart != null)
5072 CombinedEvents |= ParentGroup.RootPart.AggregateScriptEvents;
5073
5074 // submit to this part case
5075 if (VolumeDetectActive)
5076 CombinedEvents &= PhyscicsVolumeDtcSubsEvents;
5077 else if ((Flags & PrimFlags.Phantom) != 0)
5078 CombinedEvents &= PhyscicsPhantonSubsEvents;
5079 else
5080 CombinedEvents &= PhysicsNeededSubsEvents;
5081
5082 if (hassound || CombinedEvents != 0)
5083 {
5084 // subscribe to physics updates.
5085 pa.OnCollisionUpdate += PhysicsCollision;
5086 pa.SubscribeEvents(50); // 20 reports per second
5087 }
5088 else
5089 {
5090 pa.UnSubscribeEvents();
5091 }
5092 }
5093
5094
4588 public void aggregateScriptEvents() 5095 public void aggregateScriptEvents()
4589 { 5096 {
4590 if (ParentGroup == null || ParentGroup.RootPart == null) 5097 if (ParentGroup == null || ParentGroup.RootPart == null)
@@ -4621,40 +5128,32 @@ namespace OpenSim.Region.Framework.Scenes
4621 { 5128 {
4622 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; 5129 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop;
4623 } 5130 }
4624 5131/*
4625 PhysicsActor pa = PhysActor; 5132 PhysicsActor pa = PhysActor;
4626 5133 if (pa != null)
4627 if (
4628 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4629 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4630 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4631 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4632 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4633 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4634 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4635 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4636 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4637 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4638 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4639 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4640 (CollisionSound != UUID.Zero)
4641 )
4642 { 5134 {
4643 // subscribe to physics updates. 5135 if (
4644 if (pa != null) 5136// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
5137// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
5138// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
5139// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5140// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5141// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5142 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5143 )
4645 { 5144 {
5145 // subscribe to physics updates.
4646 pa.OnCollisionUpdate += PhysicsCollision; 5146 pa.OnCollisionUpdate += PhysicsCollision;
4647 pa.SubscribeEvents(1000); 5147 pa.SubscribeEvents(1000);
4648 } 5148 }
4649 } 5149 else
4650 else
4651 {
4652 if (pa != null)
4653 { 5150 {
4654 pa.UnSubscribeEvents(); 5151 pa.UnSubscribeEvents();
4655 pa.OnCollisionUpdate -= PhysicsCollision; 5152 pa.OnCollisionUpdate -= PhysicsCollision;
4656 } 5153 }
4657 } 5154 }
5155 */
5156 UpdatePhysicsSubscribedEvents();
4658 5157
4659 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 5158 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4660 //{ 5159 //{
@@ -4743,9 +5242,12 @@ namespace OpenSim.Region.Framework.Scenes
4743 5242
4744 public void ApplyNextOwnerPermissions() 5243 public void ApplyNextOwnerPermissions()
4745 { 5244 {
4746 BaseMask &= NextOwnerMask; 5245 // Export needs to be preserved in the base and everyone
5246 // mask, but removed in the owner mask as a next owner
5247 // can never change the export status
5248 BaseMask &= NextOwnerMask | (uint)PermissionMask.Export;
4747 OwnerMask &= NextOwnerMask; 5249 OwnerMask &= NextOwnerMask;
4748 EveryoneMask &= NextOwnerMask; 5250 EveryoneMask &= NextOwnerMask | (uint)PermissionMask.Export;
4749 5251
4750 Inventory.ApplyNextOwnerPermissions(); 5252 Inventory.ApplyNextOwnerPermissions();
4751 } 5253 }
@@ -4785,6 +5287,18 @@ namespace OpenSim.Region.Framework.Scenes
4785 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 5287 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4786 } 5288 }
4787 5289
5290 public void ResetOwnerChangeFlag()
5291 {
5292 List<UUID> inv = Inventory.GetInventoryList();
5293
5294 foreach (UUID itemID in inv)
5295 {
5296 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
5297 item.OwnerChanged = false;
5298 Inventory.UpdateInventoryItem(item, false, false);
5299 }
5300 }
5301
4788 /// <summary> 5302 /// <summary>
4789 /// Record an avatar sitting on this part. 5303 /// Record an avatar sitting on this part.
4790 /// </summary> 5304 /// </summary>