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.cs1471
1 files changed, 976 insertions, 495 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index ff3f738..8c6450d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -64,7 +64,8 @@ namespace OpenSim.Region.Framework.Scenes
64 TELEPORT = 512, 64 TELEPORT = 512,
65 REGION_RESTART = 1024, 65 REGION_RESTART = 1024,
66 MEDIA = 2048, 66 MEDIA = 2048,
67 ANIMATION = 16384 67 ANIMATION = 16384,
68 POSITION = 32768
68 } 69 }
69 70
70 // I don't really know where to put this except here. 71 // I don't really know where to put this except here.
@@ -123,7 +124,18 @@ namespace OpenSim.Region.Framework.Scenes
123 /// Denote all sides of the prim 124 /// Denote all sides of the prim
124 /// </value> 125 /// </value>
125 public const int ALL_SIDES = -1; 126 public const int ALL_SIDES = -1;
126 127
128 private const scriptEvents PhysicsNeededSubsEvents = (
129 scriptEvents.collision | scriptEvents.collision_start | scriptEvents.collision_end |
130 scriptEvents.land_collision | scriptEvents.land_collision_start | scriptEvents.land_collision_end
131 );
132 private const scriptEvents PhyscicsPhantonSubsEvents = (
133 scriptEvents.land_collision | scriptEvents.land_collision_start | scriptEvents.land_collision_end
134 );
135 private const scriptEvents PhyscicsVolumeDtcSubsEvents = (
136 scriptEvents.collision_start | scriptEvents.collision_end
137 );
138
127 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 139 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
128 140
129 /// <summary> 141 /// <summary>
@@ -160,7 +172,7 @@ namespace OpenSim.Region.Framework.Scenes
160 /// </remarks> 172 /// </remarks>
161 public bool IsRoot 173 public bool IsRoot
162 { 174 {
163 get { return ParentGroup.RootPart == this; } 175 get { return Object.ReferenceEquals(ParentGroup.RootPart, this); }
164 } 176 }
165 177
166 /// <summary> 178 /// <summary>
@@ -233,6 +245,18 @@ namespace OpenSim.Region.Framework.Scenes
233 245
234 public uint TimeStampTerse; 246 public uint TimeStampTerse;
235 247
248 // The following two are to hold the attachment data
249 // while an object is inworld
250 [XmlIgnore]
251 public byte AttachPoint = 0;
252
253 [XmlIgnore]
254 public Vector3 AttachOffset = Vector3.Zero;
255
256 [XmlIgnore]
257 public Quaternion AttachRotation = Quaternion.Identity;
258
259 [XmlIgnore]
236 public int STATUS_ROTATE_X; 260 public int STATUS_ROTATE_X;
237 261
238 public int STATUS_ROTATE_Y; 262 public int STATUS_ROTATE_Y;
@@ -259,8 +283,7 @@ namespace OpenSim.Region.Framework.Scenes
259 283
260 public Vector3 RotationAxis = Vector3.One; 284 public Vector3 RotationAxis = Vector3.One;
261 285
262 public bool VolumeDetectActive; // XmlIgnore set to avoid problems with persistance until I come to care for this 286 public bool VolumeDetectActive;
263 // Certainly this must be a persistant setting finally
264 287
265 public bool IsWaitingForFirstSpinUpdatePacket; 288 public bool IsWaitingForFirstSpinUpdatePacket;
266 289
@@ -300,10 +323,10 @@ namespace OpenSim.Region.Framework.Scenes
300 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 323 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
301 private Vector3 m_sitTargetPosition; 324 private Vector3 m_sitTargetPosition;
302 private string m_sitAnimation = "SIT"; 325 private string m_sitAnimation = "SIT";
326 private bool m_occupied; // KF if any av is sitting on this prim
303 private string m_text = String.Empty; 327 private string m_text = String.Empty;
304 private string m_touchName = String.Empty; 328 private string m_touchName = String.Empty;
305 private readonly List<UndoState> m_undo = new List<UndoState>(5); 329 private UndoRedoState m_UndoRedo = null;
306 private readonly List<UndoState> m_redo = new List<UndoState>(5);
307 330
308 private bool m_passTouches = false; 331 private bool m_passTouches = false;
309 private bool m_passCollisions = false; 332 private bool m_passCollisions = false;
@@ -331,14 +354,20 @@ namespace OpenSim.Region.Framework.Scenes
331 protected Vector3 m_lastVelocity; 354 protected Vector3 m_lastVelocity;
332 protected Vector3 m_lastAcceleration; 355 protected Vector3 m_lastAcceleration;
333 protected Vector3 m_lastAngularVelocity; 356 protected Vector3 m_lastAngularVelocity;
334 protected int m_lastTerseSent; 357 protected int m_lastUpdateSentTime;
358 protected float m_buoyancy = 0.0f;
359 protected Vector3 m_force;
360 protected Vector3 m_torque;
335 361
336 protected byte m_physicsShapeType = (byte)PhysShapeType.prim; 362 protected byte m_physicsShapeType = (byte)PhysShapeType.prim;
337 protected float m_density = 1000.0f; // in kg/m^3 363 protected float m_density = 1000.0f; // in kg/m^3
338 protected float m_gravitymod = 1.0f; 364 protected float m_gravitymod = 1.0f;
339 protected float m_friction = 0.6f; // wood 365 protected float m_friction = 0.6f; // wood
340 protected float m_bounce = 0.5f; // wood 366 protected float m_bounce = 0.5f; // wood
341 367
368
369 protected bool m_isSelected = false;
370
342 /// <summary> 371 /// <summary>
343 /// Stores media texture data 372 /// Stores media texture data
344 /// </summary> 373 /// </summary>
@@ -350,10 +379,17 @@ namespace OpenSim.Region.Framework.Scenes
350 private Vector3 m_cameraAtOffset; 379 private Vector3 m_cameraAtOffset;
351 private bool m_forceMouselook; 380 private bool m_forceMouselook;
352 381
353 // TODO: Collision sound should have default. 382
383 // 0 for default collision sounds, -1 for script disabled sound 1 for script defined sound
384 private sbyte m_collisionSoundType;
354 private UUID m_collisionSound; 385 private UUID m_collisionSound;
355 private float m_collisionSoundVolume; 386 private float m_collisionSoundVolume;
356 387
388 private int LastColSoundSentTime;
389
390
391 private SOPVehicle m_vehicleParams = null;
392
357 private KeyframeMotion m_keyframeMotion = null; 393 private KeyframeMotion m_keyframeMotion = null;
358 394
359 public KeyframeMotion KeyframeMotion 395 public KeyframeMotion KeyframeMotion
@@ -361,6 +397,7 @@ namespace OpenSim.Region.Framework.Scenes
361 get; set; 397 get; set;
362 } 398 }
363 399
400
364 #endregion Fields 401 #endregion Fields
365 402
366// ~SceneObjectPart() 403// ~SceneObjectPart()
@@ -390,6 +427,7 @@ namespace OpenSim.Region.Framework.Scenes
390 // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from 427 // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from
391 // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log 428 // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log
392 m_inventory = new SceneObjectPartInventory(this); 429 m_inventory = new SceneObjectPartInventory(this);
430 LastColSoundSentTime = Util.EnvironmentTickCount();
393 } 431 }
394 432
395 /// <summary> 433 /// <summary>
@@ -404,7 +442,7 @@ namespace OpenSim.Region.Framework.Scenes
404 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 442 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
405 Quaternion rotationOffset, Vector3 offsetPosition) : this() 443 Quaternion rotationOffset, Vector3 offsetPosition) : this()
406 { 444 {
407 m_name = "Primitive"; 445 m_name = "Object";
408 446
409 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 447 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
410 LastOwnerID = CreatorID = OwnerID = ownerID; 448 LastOwnerID = CreatorID = OwnerID = ownerID;
@@ -443,7 +481,7 @@ namespace OpenSim.Region.Framework.Scenes
443 private uint _ownerMask = (uint)(PermissionMask.All | PermissionMask.Export); 481 private uint _ownerMask = (uint)(PermissionMask.All | PermissionMask.Export);
444 private uint _groupMask = (uint)PermissionMask.None; 482 private uint _groupMask = (uint)PermissionMask.None;
445 private uint _everyoneMask = (uint)PermissionMask.None; 483 private uint _everyoneMask = (uint)PermissionMask.None;
446 private uint _nextOwnerMask = (uint)PermissionMask.All; 484 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
447 private PrimFlags _flags = PrimFlags.None; 485 private PrimFlags _flags = PrimFlags.None;
448 private DateTime m_expires; 486 private DateTime m_expires;
449 private DateTime m_rezzed; 487 private DateTime m_rezzed;
@@ -537,12 +575,16 @@ namespace OpenSim.Region.Framework.Scenes
537 } 575 }
538 576
539 /// <value> 577 /// <value>
540 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 578 /// Get the inventory list
541 /// </value> 579 /// </value>
542 public TaskInventoryDictionary TaskInventory 580 public TaskInventoryDictionary TaskInventory
543 { 581 {
544 get { return m_inventory.Items; } 582 get {
545 set { m_inventory.Items = value; } 583 return m_inventory.Items;
584 }
585 set {
586 m_inventory.Items = value;
587 }
546 } 588 }
547 589
548 /// <summary> 590 /// <summary>
@@ -592,20 +634,6 @@ namespace OpenSim.Region.Framework.Scenes
592 } 634 }
593 } 635 }
594 636
595 public byte Material
596 {
597 get { return (byte) m_material; }
598 set
599 {
600 m_material = (Material)value;
601
602 PhysicsActor pa = PhysActor;
603
604 if (pa != null)
605 pa.SetMaterial((int)value);
606 }
607 }
608
609 [XmlIgnore] 637 [XmlIgnore]
610 public bool PassTouches 638 public bool PassTouches
611 { 639 {
@@ -631,6 +659,18 @@ namespace OpenSim.Region.Framework.Scenes
631 } 659 }
632 } 660 }
633 661
662 public bool IsSelected
663 {
664 get { return m_isSelected; }
665 set
666 {
667 m_isSelected = value;
668 if (ParentGroup != null)
669 ParentGroup.PartSelectChanged(value);
670 }
671 }
672
673
634 public Dictionary<int, string> CollisionFilter 674 public Dictionary<int, string> CollisionFilter
635 { 675 {
636 get { return m_CollisionFilter; } 676 get { return m_CollisionFilter; }
@@ -699,14 +739,12 @@ namespace OpenSim.Region.Framework.Scenes
699 set { m_LoopSoundSlavePrims = value; } 739 set { m_LoopSoundSlavePrims = value; }
700 } 740 }
701 741
702
703 public Byte[] TextureAnimation 742 public Byte[] TextureAnimation
704 { 743 {
705 get { return m_TextureAnimation; } 744 get { return m_TextureAnimation; }
706 set { m_TextureAnimation = value; } 745 set { m_TextureAnimation = value; }
707 } 746 }
708 747
709
710 public Byte[] ParticleSystem 748 public Byte[] ParticleSystem
711 { 749 {
712 get { return m_particleSystem; } 750 get { return m_particleSystem; }
@@ -743,9 +781,12 @@ namespace OpenSim.Region.Framework.Scenes
743 { 781 {
744 // If this is a linkset, we don't want the physics engine mucking up our group position here. 782 // If this is a linkset, we don't want the physics engine mucking up our group position here.
745 PhysicsActor actor = PhysActor; 783 PhysicsActor actor = PhysActor;
746 // If physical and the root prim of a linkset, the position of the group is what physics thinks. 784 if (ParentID == 0)
747 if (actor != null && ParentID == 0) 785 {
748 m_groupPosition = actor.Position; 786 if (actor != null)
787 m_groupPosition = actor.Position;
788 return m_groupPosition;
789 }
749 790
750 // If I'm an attachment, my position is reported as the position of who I'm attached to 791 // If I'm an attachment, my position is reported as the position of who I'm attached to
751 if (ParentGroup.IsAttachment) 792 if (ParentGroup.IsAttachment)
@@ -755,14 +796,16 @@ namespace OpenSim.Region.Framework.Scenes
755 return sp.AbsolutePosition; 796 return sp.AbsolutePosition;
756 } 797 }
757 798
799 // use root prim's group position. Physics may have updated it
800 if (ParentGroup.RootPart != this)
801 m_groupPosition = ParentGroup.RootPart.GroupPosition;
758 return m_groupPosition; 802 return m_groupPosition;
759 } 803 }
760 set 804 set
761 { 805 {
762 m_groupPosition = value; 806 m_groupPosition = value;
763
764 PhysicsActor actor = PhysActor; 807 PhysicsActor actor = PhysActor;
765 if (actor != null) 808 if (actor != null && ParentGroup.Scene.PhysicsScene != null)
766 { 809 {
767 try 810 try
768 { 811 {
@@ -786,16 +829,6 @@ namespace OpenSim.Region.Framework.Scenes
786 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e); 829 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e);
787 } 830 }
788 } 831 }
789
790 // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
791 if (SitTargetAvatar != UUID.Zero)
792 {
793 ScenePresence avatar;
794 if (ParentGroup.Scene.TryGetScenePresence(SitTargetAvatar, out avatar))
795 {
796 avatar.ParentPosition = GetWorldPosition();
797 }
798 }
799 } 832 }
800 } 833 }
801 834
@@ -804,7 +837,7 @@ namespace OpenSim.Region.Framework.Scenes
804 get { return m_offsetPosition; } 837 get { return m_offsetPosition; }
805 set 838 set
806 { 839 {
807// StoreUndoState(); 840 Vector3 oldpos = m_offsetPosition;
808 m_offsetPosition = value; 841 m_offsetPosition = value;
809 842
810 if (ParentGroup != null && !ParentGroup.IsDeleted) 843 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -816,10 +849,25 @@ namespace OpenSim.Region.Framework.Scenes
816 actor.Orientation = GetWorldRotation(); 849 actor.Orientation = GetWorldRotation();
817 850
818 // Tell the physics engines that this prim changed. 851 // Tell the physics engines that this prim changed.
819 if (ParentGroup.Scene != null) 852 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene != null)
820 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 853 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
821 } 854 }
855
856 if (!m_parentGroup.m_dupeInProgress)
857 {
858 List<ScenePresence> avs = ParentGroup.GetLinkedAvatars();
859 foreach (ScenePresence av in avs)
860 {
861 if (av.ParentID == m_localId)
862 {
863 Vector3 offset = (m_offsetPosition - oldpos);
864 av.AbsolutePosition += offset;
865 av.SendAvatarDataToAllAgents();
866 }
867 }
868 }
822 } 869 }
870 TriggerScriptChangedEvent(Changed.POSITION);
823 } 871 }
824 } 872 }
825 873
@@ -870,7 +918,7 @@ namespace OpenSim.Region.Framework.Scenes
870 918
871 set 919 set
872 { 920 {
873 StoreUndoState(); 921// StoreUndoState();
874 m_rotationOffset = value; 922 m_rotationOffset = value;
875 923
876 PhysicsActor actor = PhysActor; 924 PhysicsActor actor = PhysActor;
@@ -958,19 +1006,36 @@ namespace OpenSim.Region.Framework.Scenes
958 get 1006 get
959 { 1007 {
960 PhysicsActor actor = PhysActor; 1008 PhysicsActor actor = PhysActor;
961 if ((actor != null) && actor.IsPhysical) 1009 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
962 { 1010 {
963 m_angularVelocity = actor.RotationalVelocity; 1011 m_angularVelocity = actor.RotationalVelocity;
964 } 1012 }
965 return m_angularVelocity; 1013 return m_angularVelocity;
966 } 1014 }
967 set { m_angularVelocity = value; } 1015 set
1016 {
1017 m_angularVelocity = value;
1018 PhysicsActor actor = PhysActor;
1019 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this && VehicleType == (int)Vehicle.TYPE_NONE)
1020 {
1021 actor.RotationalVelocity = m_angularVelocity;
1022 }
1023 }
968 } 1024 }
969 1025
970 /// <summary></summary> 1026 /// <summary></summary>
971 public Vector3 Acceleration 1027 public Vector3 Acceleration
972 { 1028 {
973 get { return m_acceleration; } 1029 get
1030 {
1031 PhysicsActor actor = PhysActor;
1032 if (actor != null)
1033 {
1034 m_acceleration = actor.Acceleration;
1035 }
1036 return m_acceleration;
1037 }
1038
974 set { m_acceleration = value; } 1039 set { m_acceleration = value; }
975 } 1040 }
976 1041
@@ -1038,7 +1103,10 @@ namespace OpenSim.Region.Framework.Scenes
1038 public PrimitiveBaseShape Shape 1103 public PrimitiveBaseShape Shape
1039 { 1104 {
1040 get { return m_shape; } 1105 get { return m_shape; }
1041 set { m_shape = value;} 1106 set
1107 {
1108 m_shape = value;
1109 }
1042 } 1110 }
1043 1111
1044 /// <summary> 1112 /// <summary>
@@ -1051,7 +1119,6 @@ namespace OpenSim.Region.Framework.Scenes
1051 { 1119 {
1052 if (m_shape != null) 1120 if (m_shape != null)
1053 { 1121 {
1054 StoreUndoState();
1055 1122
1056 m_shape.Scale = value; 1123 m_shape.Scale = value;
1057 1124
@@ -1119,10 +1186,7 @@ namespace OpenSim.Region.Framework.Scenes
1119 { 1186 {
1120 get 1187 get
1121 { 1188 {
1122 if (ParentGroup.IsAttachment) 1189 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
1123 return GroupPosition;
1124
1125 return m_offsetPosition + m_groupPosition;
1126 } 1190 }
1127 } 1191 }
1128 1192
@@ -1291,6 +1355,13 @@ namespace OpenSim.Region.Framework.Scenes
1291 _flags = value; 1355 _flags = value;
1292 } 1356 }
1293 } 1357 }
1358
1359 [XmlIgnore]
1360 public bool IsOccupied // KF If an av is sittingon this prim
1361 {
1362 get { return m_occupied; }
1363 set { m_occupied = value; }
1364 }
1294 1365
1295 /// <summary> 1366 /// <summary>
1296 /// 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 1367 /// 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
@@ -1341,12 +1412,41 @@ namespace OpenSim.Region.Framework.Scenes
1341 set { m_sitAnimation = value; } 1412 set { m_sitAnimation = value; }
1342 } 1413 }
1343 1414
1415 public UUID invalidCollisionSoundUUID = new UUID("ffffffff-ffff-ffff-ffff-ffffffffffff");
1416
1417 // 0 for default collision sounds, -1 for script disabled sound 1 for script defined sound
1418 // runtime thing.. do not persist
1419 [XmlIgnore]
1420 public sbyte CollisionSoundType
1421 {
1422 get
1423 {
1424 return m_collisionSoundType;
1425 }
1426 set
1427 {
1428 m_collisionSoundType = value;
1429 if (value == -1)
1430 m_collisionSound = invalidCollisionSoundUUID;
1431 else if (value == 0)
1432 m_collisionSound = UUID.Zero;
1433 }
1434 }
1435
1344 public UUID CollisionSound 1436 public UUID CollisionSound
1345 { 1437 {
1346 get { return m_collisionSound; } 1438 get { return m_collisionSound; }
1347 set 1439 set
1348 { 1440 {
1349 m_collisionSound = value; 1441 m_collisionSound = value;
1442
1443 if (value == invalidCollisionSoundUUID)
1444 m_collisionSoundType = -1;
1445 else if (value == UUID.Zero)
1446 m_collisionSoundType = 0;
1447 else
1448 m_collisionSoundType = 1;
1449
1350 aggregateScriptEvents(); 1450 aggregateScriptEvents();
1351 } 1451 }
1352 } 1452 }
@@ -1357,6 +1457,125 @@ namespace OpenSim.Region.Framework.Scenes
1357 set { m_collisionSoundVolume = value; } 1457 set { m_collisionSoundVolume = value; }
1358 } 1458 }
1359 1459
1460 public float Buoyancy
1461 {
1462 get
1463 {
1464 if (ParentGroup.RootPart == this)
1465 return m_buoyancy;
1466
1467 return ParentGroup.RootPart.Buoyancy;
1468 }
1469 set
1470 {
1471 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1472 {
1473 ParentGroup.RootPart.Buoyancy = value;
1474 return;
1475 }
1476 m_buoyancy = value;
1477 if (PhysActor != null)
1478 PhysActor.Buoyancy = value;
1479 }
1480 }
1481
1482 public Vector3 Force
1483 {
1484 get
1485 {
1486 if (ParentGroup.RootPart == this)
1487 return m_force;
1488
1489 return ParentGroup.RootPart.Force;
1490 }
1491
1492 set
1493 {
1494 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1495 {
1496 ParentGroup.RootPart.Force = value;
1497 return;
1498 }
1499 m_force = value;
1500 if (PhysActor != null)
1501 PhysActor.Force = value;
1502 }
1503 }
1504
1505 public Vector3 Torque
1506 {
1507 get
1508 {
1509 if (ParentGroup.RootPart == this)
1510 return m_torque;
1511
1512 return ParentGroup.RootPart.Torque;
1513 }
1514
1515 set
1516 {
1517 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1518 {
1519 ParentGroup.RootPart.Torque = value;
1520 return;
1521 }
1522 m_torque = value;
1523 if (PhysActor != null)
1524 PhysActor.Torque = value;
1525 }
1526 }
1527
1528 public byte Material
1529 {
1530 get { return (byte)m_material; }
1531 set
1532 {
1533 if (value >= 0 && value <= (byte)SOPMaterialData.MaxMaterial)
1534 {
1535 bool update = false;
1536
1537 if (m_material != (Material)value)
1538 {
1539 update = true;
1540 m_material = (Material)value;
1541 }
1542
1543 if (m_friction != SOPMaterialData.friction(m_material))
1544 {
1545 update = true;
1546 m_friction = SOPMaterialData.friction(m_material);
1547 }
1548
1549 if (m_bounce != SOPMaterialData.bounce(m_material))
1550 {
1551 update = true;
1552 m_bounce = SOPMaterialData.bounce(m_material);
1553 }
1554
1555 if (update)
1556 {
1557 if (PhysActor != null)
1558 {
1559 PhysActor.SetMaterial((int)value);
1560 }
1561 if(ParentGroup != null)
1562 ParentGroup.HasGroupChanged = true;
1563 ScheduleFullUpdateIfNone();
1564 UpdatePhysRequired = true;
1565 }
1566 }
1567 }
1568 }
1569
1570 // not a propriety to move to methods place later
1571 private bool HasMesh()
1572 {
1573 if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh))
1574 return true;
1575 return false;
1576 }
1577
1578 // not a propriety to move to methods place later
1360 public byte DefaultPhysicsShapeType() 1579 public byte DefaultPhysicsShapeType()
1361 { 1580 {
1362 byte type; 1581 byte type;
@@ -1369,6 +1588,65 @@ namespace OpenSim.Region.Framework.Scenes
1369 return type; 1588 return type;
1370 } 1589 }
1371 1590
1591 [XmlIgnore]
1592 public bool UsesComplexCost
1593 {
1594 get
1595 {
1596 byte pst = PhysicsShapeType;
1597 if(pst == (byte) PhysShapeType.none || pst == (byte) PhysShapeType.convex || HasMesh())
1598 return true;
1599 return false;
1600 }
1601 }
1602
1603 [XmlIgnore]
1604 public float PhysicsCost
1605 {
1606 get
1607 {
1608 if(PhysicsShapeType == (byte)PhysShapeType.none)
1609 return 0;
1610
1611 float cost = 0.1f;
1612 if (PhysActor != null)
1613 cost = PhysActor.PhysicsCost;
1614 else
1615 cost = 0.1f;
1616
1617 if ((Flags & PrimFlags.Physics) != 0)
1618 cost *= (1.0f + 0.01333f * Scale.LengthSquared()); // 0.01333 == 0.04/3
1619 return cost;
1620 }
1621 }
1622
1623 [XmlIgnore]
1624 public float StreamingCost
1625 {
1626 get
1627 {
1628 float cost;
1629 if (PhysActor != null)
1630 cost = PhysActor.StreamCost;
1631 else
1632 cost = 1.0f;
1633 return 1.0f;
1634 }
1635 }
1636
1637 [XmlIgnore]
1638 public float SimulationCost
1639 {
1640 get
1641 {
1642 // ignoring scripts. Don't like considering them for this
1643 if((Flags & PrimFlags.Physics) != 0)
1644 return 1.0f;
1645
1646 return 0.5f;
1647 }
1648 }
1649
1372 public byte PhysicsShapeType 1650 public byte PhysicsShapeType
1373 { 1651 {
1374 get { return m_physicsShapeType; } 1652 get { return m_physicsShapeType; }
@@ -1402,11 +1680,14 @@ namespace OpenSim.Region.Framework.Scenes
1402 } 1680 }
1403 else if (PhysActor == null) 1681 else if (PhysActor == null)
1404 { 1682 {
1405 ApplyPhysics((uint)Flags, VolumeDetectActive); 1683 ApplyPhysics((uint)Flags, VolumeDetectActive, false);
1684 UpdatePhysicsSubscribedEvents();
1406 } 1685 }
1407 else 1686 else
1408 { 1687 {
1409 PhysActor.PhysicsShapeType = m_physicsShapeType; 1688 PhysActor.PhysicsShapeType = m_physicsShapeType;
1689// if (Shape.SculptEntry)
1690// CheckSculptAndLoad();
1410 } 1691 }
1411 1692
1412 if (ParentGroup != null) 1693 if (ParentGroup != null)
@@ -1508,6 +1789,7 @@ namespace OpenSim.Region.Framework.Scenes
1508 } 1789 }
1509 } 1790 }
1510 1791
1792
1511 #endregion Public Properties with only Get 1793 #endregion Public Properties with only Get
1512 1794
1513 private uint ApplyMask(uint val, bool set, uint mask) 1795 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1653,6 +1935,61 @@ namespace OpenSim.Region.Framework.Scenes
1653 } 1935 }
1654 } 1936 }
1655 1937
1938 // SetVelocity for LSL llSetVelocity.. may need revision if having other uses in future
1939 public void SetVelocity(Vector3 pVel, bool localGlobalTF)
1940 {
1941 if (ParentGroup == null || ParentGroup.IsDeleted)
1942 return;
1943
1944 if (ParentGroup.IsAttachment)
1945 return; // don't work on attachments (for now ??)
1946
1947 SceneObjectPart root = ParentGroup.RootPart;
1948
1949 if (root.VehicleType != (int)Vehicle.TYPE_NONE) // don't mess with vehicles
1950 return;
1951
1952 PhysicsActor pa = root.PhysActor;
1953
1954 if (pa == null || !pa.IsPhysical)
1955 return;
1956
1957 if (localGlobalTF)
1958 {
1959 pVel = pVel * GetWorldRotation();
1960 }
1961
1962 ParentGroup.Velocity = pVel;
1963 }
1964
1965 // SetAngularVelocity for LSL llSetAngularVelocity.. may need revision if having other uses in future
1966 public void SetAngularVelocity(Vector3 pAngVel, bool localGlobalTF)
1967 {
1968 if (ParentGroup == null || ParentGroup.IsDeleted)
1969 return;
1970
1971 if (ParentGroup.IsAttachment)
1972 return; // don't work on attachments (for now ??)
1973
1974 SceneObjectPart root = ParentGroup.RootPart;
1975
1976 if (root.VehicleType != (int)Vehicle.TYPE_NONE) // don't mess with vehicles
1977 return;
1978
1979 PhysicsActor pa = root.PhysActor;
1980
1981 if (pa == null || !pa.IsPhysical)
1982 return;
1983
1984 if (localGlobalTF)
1985 {
1986 pAngVel = pAngVel * GetWorldRotation();
1987 }
1988
1989 root.AngularVelocity = pAngVel;
1990 }
1991
1992
1656 /// <summary> 1993 /// <summary>
1657 /// hook to the physics scene to apply angular impulse 1994 /// hook to the physics scene to apply angular impulse
1658 /// This is sent up to the group, which then finds the root prim 1995 /// This is sent up to the group, which then finds the root prim
@@ -1673,7 +2010,7 @@ namespace OpenSim.Region.Framework.Scenes
1673 impulse = newimpulse; 2010 impulse = newimpulse;
1674 } 2011 }
1675 2012
1676 ParentGroup.applyAngularImpulse(impulse); 2013 ParentGroup.ApplyAngularImpulse(impulse);
1677 } 2014 }
1678 2015
1679 /// <summary> 2016 /// <summary>
@@ -1683,20 +2020,24 @@ namespace OpenSim.Region.Framework.Scenes
1683 /// </summary> 2020 /// </summary>
1684 /// <param name="impulsei">Vector force</param> 2021 /// <param name="impulsei">Vector force</param>
1685 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> 2022 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
1686 public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF) 2023
2024 // this is actualy Set Torque.. keeping naming so not to edit lslapi also
2025 public void SetAngularImpulse(Vector3 torquei, bool localGlobalTF)
1687 { 2026 {
1688 Vector3 impulse = impulsei; 2027 Vector3 torque = torquei;
1689 2028
1690 if (localGlobalTF) 2029 if (localGlobalTF)
1691 { 2030 {
2031/*
1692 Quaternion grot = GetWorldRotation(); 2032 Quaternion grot = GetWorldRotation();
1693 Quaternion AXgrot = grot; 2033 Quaternion AXgrot = grot;
1694 Vector3 AXimpulsei = impulsei; 2034 Vector3 AXimpulsei = impulsei;
1695 Vector3 newimpulse = AXimpulsei * AXgrot; 2035 Vector3 newimpulse = AXimpulsei * AXgrot;
1696 impulse = newimpulse; 2036 */
2037 torque *= GetWorldRotation();
1697 } 2038 }
1698 2039
1699 ParentGroup.setAngularImpulse(impulse); 2040 Torque = torque;
1700 } 2041 }
1701 2042
1702 /// <summary> 2043 /// <summary>
@@ -1704,7 +2045,9 @@ namespace OpenSim.Region.Framework.Scenes
1704 /// </summary> 2045 /// </summary>
1705 /// <param name="rootObjectFlags"></param> 2046 /// <param name="rootObjectFlags"></param>
1706 /// <param name="VolumeDetectActive"></param> 2047 /// <param name="VolumeDetectActive"></param>
1707 public void ApplyPhysics(uint rootObjectFlags, bool _VolumeDetectActive) 2048 /// <param name="building"></param>
2049
2050 public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building)
1708 { 2051 {
1709 VolumeDetectActive = _VolumeDetectActive; 2052 VolumeDetectActive = _VolumeDetectActive;
1710 2053
@@ -1714,8 +2057,8 @@ namespace OpenSim.Region.Framework.Scenes
1714 if (PhysicsShapeType == (byte)PhysShapeType.none) 2057 if (PhysicsShapeType == (byte)PhysShapeType.none)
1715 return; 2058 return;
1716 2059
1717 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 2060 bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0;
1718 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 2061 bool isPhantom = (_ObjectFlags & (uint)PrimFlags.Phantom) != 0;
1719 2062
1720 if (_VolumeDetectActive) 2063 if (_VolumeDetectActive)
1721 isPhantom = true; 2064 isPhantom = true;
@@ -1729,7 +2072,8 @@ namespace OpenSim.Region.Framework.Scenes
1729 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment 2072 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment
1730 && !(Shape.PathCurve == (byte)Extrusion.Flexible)) 2073 && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1731 { 2074 {
1732 AddToPhysics(isPhysical, isPhantom, isPhysical); 2075 AddToPhysics(isPhysical, isPhantom, building, isPhysical);
2076 UpdatePhysicsSubscribedEvents(); // not sure if appliable here
1733 } 2077 }
1734 else 2078 else
1735 PhysActor = null; // just to be sure 2079 PhysActor = null; // just to be sure
@@ -1784,6 +2128,12 @@ namespace OpenSim.Region.Framework.Scenes
1784 dupe.Category = Category; 2128 dupe.Category = Category;
1785 dupe.m_rezzed = m_rezzed; 2129 dupe.m_rezzed = m_rezzed;
1786 2130
2131 dupe.m_UndoRedo = null;
2132 dupe.m_isSelected = false;
2133
2134 dupe.IgnoreUndoUpdate = false;
2135 dupe.Undoing = false;
2136
1787 dupe.m_inventory = new SceneObjectPartInventory(dupe); 2137 dupe.m_inventory = new SceneObjectPartInventory(dupe);
1788 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone(); 2138 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone();
1789 2139
@@ -1799,6 +2149,7 @@ namespace OpenSim.Region.Framework.Scenes
1799 2149
1800 // Move afterwards ResetIDs as it clears the localID 2150 // Move afterwards ResetIDs as it clears the localID
1801 dupe.LocalId = localID; 2151 dupe.LocalId = localID;
2152
1802 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 2153 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1803 dupe.LastOwnerID = OwnerID; 2154 dupe.LastOwnerID = OwnerID;
1804 2155
@@ -1823,8 +2174,12 @@ namespace OpenSim.Region.Framework.Scenes
1823*/ 2174*/
1824 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 2175 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
1825 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 2176 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
2177// dupe.UpdatePhysicsSubscribedEvents(); // not sure...
1826 } 2178 }
1827 2179
2180 if (dupe.PhysActor != null)
2181 dupe.PhysActor.LocalID = localID;
2182
1828 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 2183 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1829 2184
1830// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); 2185// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
@@ -1843,10 +2198,10 @@ namespace OpenSim.Region.Framework.Scenes
1843 { 2198 {
1844 if (asset != null) 2199 if (asset != null)
1845 SculptTextureCallback(asset); 2200 SculptTextureCallback(asset);
1846 else 2201// else
1847 m_log.WarnFormat( 2202// m_log.WarnFormat(
1848 "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data", 2203// "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
1849 Name, UUID, id); 2204// Name, UUID, id);
1850 } 2205 }
1851*/ 2206*/
1852 /// <summary> 2207 /// <summary>
@@ -1945,6 +2300,7 @@ namespace OpenSim.Region.Framework.Scenes
1945 2300
1946 /// <summary> 2301 /// <summary>
1947 /// Do a physics propery update for this part. 2302 /// Do a physics propery update for this part.
2303 /// now also updates phantom and volume detector
1948 /// </summary> 2304 /// </summary>
1949 /// <param name="UsePhysics"></param> 2305 /// <param name="UsePhysics"></param>
1950 /// <param name="isNew"></param> 2306 /// <param name="isNew"></param>
@@ -1970,64 +2326,69 @@ namespace OpenSim.Region.Framework.Scenes
1970 { 2326 {
1971 if (pa.IsPhysical) // implies UsePhysics==false for this block 2327 if (pa.IsPhysical) // implies UsePhysics==false for this block
1972 { 2328 {
1973 if (!isNew) 2329 if (!isNew) // implies UsePhysics==false for this block
2330 {
1974 ParentGroup.Scene.RemovePhysicalPrim(1); 2331 ParentGroup.Scene.RemovePhysicalPrim(1);
1975 2332
1976 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 2333 Velocity = new Vector3(0, 0, 0);
1977 pa.OnOutOfBounds -= PhysicsOutOfBounds; 2334 Acceleration = new Vector3(0, 0, 0);
1978 pa.delink(); 2335 if (ParentGroup.RootPart == this)
2336 AngularVelocity = new Vector3(0, 0, 0);
1979 2337
1980 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 2338 if (pa.Phantom && !VolumeDetectActive)
1981 { 2339 {
1982 // destroy all joints connected to this now deactivated body 2340 RemoveFromPhysics();
1983 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); 2341 return;
1984 } 2342 }
1985 2343
1986 // stop client-side interpolation of all joint proxy objects that have just been deleted 2344 pa.IsPhysical = UsePhysics;
1987 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback, 2345 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1988 // which stops client-side interpolation of deactivated joint proxy objects. 2346 pa.OnOutOfBounds -= PhysicsOutOfBounds;
2347 pa.delink();
2348 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
2349 {
2350 // destroy all joints connected to this now deactivated body
2351 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa);
2352 }
2353 }
1989 } 2354 }
1990 2355
1991 if (!UsePhysics && !isNew) 2356 if (pa.IsPhysical != UsePhysics)
1992 { 2357 pa.IsPhysical = UsePhysics;
1993 // reset velocity to 0 on physics switch-off. Without that, the client thinks the
1994 // prim still has velocity and continues to interpolate its position along the old
1995 // velocity-vector.
1996 Velocity = new Vector3(0, 0, 0);
1997 Acceleration = new Vector3(0, 0, 0);
1998 AngularVelocity = new Vector3(0, 0, 0);
1999 //RotationalVelocity = new Vector3(0, 0, 0);
2000 }
2001 2358
2002 pa.IsPhysical = UsePhysics; 2359 if (UsePhysics)
2360 {
2361 if (ParentGroup.RootPart.KeyframeMotion != null)
2362 ParentGroup.RootPart.KeyframeMotion.Stop();
2363 ParentGroup.RootPart.KeyframeMotion = null;
2364 ParentGroup.Scene.AddPhysicalPrim(1);
2003 2365
2004 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 2366 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
2005 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 2367 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
2006 /// that's not wholesome. Had to make Scene public
2007 //PhysActor = null;
2008 2368
2009 if ((Flags & PrimFlags.Phantom) == 0) 2369 if (ParentID != 0 && ParentID != LocalId)
2010 {
2011 if (UsePhysics)
2012 { 2370 {
2013 if (ParentGroup.RootPart.KeyframeMotion != null) 2371 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
2014 ParentGroup.RootPart.KeyframeMotion.Stop();
2015 ParentGroup.RootPart.KeyframeMotion = null;
2016 ParentGroup.Scene.AddPhysicalPrim(1);
2017
2018 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
2019 pa.OnOutOfBounds += PhysicsOutOfBounds;
2020 if (ParentID != 0 && ParentID != LocalId)
2021 {
2022 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
2023 2372
2024 if (parentPa != null) 2373 if (parentPa != null)
2025 { 2374 {
2026 pa.link(parentPa); 2375 pa.link(parentPa);
2027 }
2028 } 2376 }
2029 } 2377 }
2030 } 2378 }
2379 }
2380
2381 bool phan = ((Flags & PrimFlags.Phantom) != 0);
2382 if (pa.Phantom != phan)
2383 pa.Phantom = phan;
2384
2385// some engines dont' have this check still
2386// if (VolumeDetectActive != pa.IsVolumeDtc)
2387 {
2388 if (VolumeDetectActive)
2389 pa.SetVolumeDetect(1);
2390 else
2391 pa.SetVolumeDetect(0);
2031 } 2392 }
2032 2393
2033 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 2394 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
@@ -2146,42 +2507,63 @@ namespace OpenSim.Region.Framework.Scenes
2146 2507
2147 public Vector3 GetGeometricCenter() 2508 public Vector3 GetGeometricCenter()
2148 { 2509 {
2510 // this is not real geometric center but a average of positions relative to root prim acording to
2511 // http://wiki.secondlife.com/wiki/llGetGeometricCenter
2512 // ignoring tortured prims details since sl also seems to ignore
2513 // so no real use in doing it on physics
2514 if (ParentGroup.IsDeleted)
2515 return new Vector3(0, 0, 0);
2516
2517 return ParentGroup.GetGeometricCenter();
2518 }
2519
2520 public float GetMass()
2521 {
2149 PhysicsActor pa = PhysActor; 2522 PhysicsActor pa = PhysActor;
2150 2523
2151 if (pa != null) 2524 if (pa != null)
2152 return pa.GeometricCenter; 2525 return pa.Mass;
2153 else 2526 else
2154 return Vector3.Zero; 2527 return 0;
2155 } 2528 }
2156 2529
2157 public Vector3 GetCenterOfMass() 2530 public Vector3 GetCenterOfMass()
2158 { 2531 {
2532 if (ParentGroup.RootPart == this)
2533 {
2534 if (ParentGroup.IsDeleted)
2535 return AbsolutePosition;
2536 return ParentGroup.GetCenterOfMass();
2537 }
2538
2159 PhysicsActor pa = PhysActor; 2539 PhysicsActor pa = PhysActor;
2160 2540
2161 if (pa != null) 2541 if (pa != null)
2162 return pa.CenterOfMass; 2542 {
2543 Vector3 tmp = pa.CenterOfMass;
2544 return tmp;
2545 }
2163 else 2546 else
2164 return Vector3.Zero; 2547 return AbsolutePosition;
2165 } 2548 }
2166 2549
2167 public float GetMass() 2550 public Vector3 GetPartCenterOfMass()
2168 { 2551 {
2169 PhysicsActor pa = PhysActor; 2552 PhysicsActor pa = PhysActor;
2170 2553
2171 if (pa != null) 2554 if (pa != null)
2172 return pa.Mass; 2555 {
2556 Vector3 tmp = pa.CenterOfMass;
2557 return tmp;
2558 }
2173 else 2559 else
2174 return 0; 2560 return AbsolutePosition;
2175 } 2561 }
2176 2562
2563
2177 public Vector3 GetForce() 2564 public Vector3 GetForce()
2178 { 2565 {
2179 PhysicsActor pa = PhysActor; 2566 return Force;
2180
2181 if (pa != null)
2182 return pa.Force;
2183 else
2184 return Vector3.Zero;
2185 } 2567 }
2186 2568
2187 /// <summary> 2569 /// <summary>
@@ -2396,15 +2778,25 @@ namespace OpenSim.Region.Framework.Scenes
2396 2778
2397 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify) 2779 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify)
2398 { 2780 {
2399 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0) 2781 bool sendToRoot = true;
2400 {
2401 ColliderArgs LandCollidingMessage = new ColliderArgs();
2402 List<DetectedObject> colliding = new List<DetectedObject>();
2403
2404 colliding.Add(CreateDetObjectForGround());
2405 LandCollidingMessage.Colliders = colliding;
2406 2782
2783 ColliderArgs LandCollidingMessage = new ColliderArgs();
2784 List<DetectedObject> colliding = new List<DetectedObject>();
2785
2786 colliding.Add(CreateDetObjectForGround());
2787 LandCollidingMessage.Colliders = colliding;
2788
2789 if (Inventory.ContainsScripts())
2790 {
2791 if (!PassCollisions)
2792 sendToRoot = false;
2793 }
2794 if ((ScriptEvents & ev) != 0)
2407 notify(LocalId, LandCollidingMessage); 2795 notify(LocalId, LandCollidingMessage);
2796
2797 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0 && sendToRoot)
2798 {
2799 notify(ParentGroup.RootPart.LocalId, LandCollidingMessage);
2408 } 2800 }
2409 } 2801 }
2410 2802
@@ -2420,57 +2812,120 @@ namespace OpenSim.Region.Framework.Scenes
2420 List<uint> endedColliders = new List<uint>(); 2812 List<uint> endedColliders = new List<uint>();
2421 List<uint> startedColliders = new List<uint>(); 2813 List<uint> startedColliders = new List<uint>();
2422 2814
2423 // calculate things that started colliding this time 2815 if (collissionswith.Count == 0)
2424 // and build up list of colliders this time
2425 foreach (uint localid in collissionswith.Keys)
2426 { 2816 {
2427 thisHitColliders.Add(localid); 2817 if (m_lastColliders.Count == 0)
2428 if (!m_lastColliders.Contains(localid)) 2818 return; // nothing to do
2429 startedColliders.Add(localid);
2430 }
2431 2819
2432 // calculate things that ended colliding 2820 foreach (uint localID in m_lastColliders)
2433 foreach (uint localID in m_lastColliders) 2821 {
2434 {
2435 if (!thisHitColliders.Contains(localID))
2436 endedColliders.Add(localID); 2822 endedColliders.Add(localID);
2823 }
2824 m_lastColliders.Clear();
2437 } 2825 }
2438 2826
2439 //add the items that started colliding this time to the last colliders list. 2827 else
2440 foreach (uint localID in startedColliders) 2828 {
2441 m_lastColliders.Add(localID); 2829 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
2442 2830
2443 // remove things that ended colliding from the last colliders list 2831 // calculate things that started colliding this time
2444 foreach (uint localID in endedColliders) 2832 // and build up list of colliders this time
2445 m_lastColliders.Remove(localID); 2833 if (!VolumeDetectActive && CollisionSoundType >= 0)
2834 {
2835 CollisionForSoundInfo soundinfo;
2836 ContactPoint curcontact;
2446 2837
2447 // play the sound. 2838 foreach (uint id in collissionswith.Keys)
2448 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) 2839 {
2449 { 2840 thisHitColliders.Add(id);
2450 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>(); 2841 if (!m_lastColliders.Contains(id))
2451 if (soundModule != null) 2842 {
2843 startedColliders.Add(id);
2844
2845 curcontact = collissionswith[id];
2846 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
2847 {
2848 soundinfo = new CollisionForSoundInfo();
2849 soundinfo.colliderID = id;
2850 soundinfo.position = curcontact.Position;
2851 soundinfo.relativeVel = curcontact.RelativeSpeed;
2852 soundinfolist.Add(soundinfo);
2853 }
2854 }
2855 }
2856 }
2857 else
2858 {
2859 foreach (uint id in collissionswith.Keys)
2860 {
2861 thisHitColliders.Add(id);
2862 if (!m_lastColliders.Contains(id))
2863 startedColliders.Add(id);
2864 }
2865 }
2866
2867 // calculate things that ended colliding
2868 foreach (uint localID in m_lastColliders)
2452 { 2869 {
2453 soundModule.SendSound(UUID, CollisionSound, 2870 if (!thisHitColliders.Contains(localID))
2454 CollisionSoundVolume, true, 0, 0, false, 2871 endedColliders.Add(localID);
2455 false);
2456 } 2872 }
2873
2874 //add the items that started colliding this time to the last colliders list.
2875 foreach (uint localID in startedColliders)
2876 m_lastColliders.Add(localID);
2877
2878 // remove things that ended colliding from the last colliders list
2879 foreach (uint localID in endedColliders)
2880 m_lastColliders.Remove(localID);
2881
2882 // play sounds.
2883 if (soundinfolist.Count > 0)
2884 CollisionSounds.PartCollisionSound(this, soundinfolist);
2457 } 2885 }
2458 2886
2459 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart); 2887 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
2460 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding); 2888 if (!VolumeDetectActive)
2889 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
2461 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); 2890 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
2462 2891
2463 if (startedColliders.Contains(0)) 2892 if (startedColliders.Contains(0))
2464 { 2893 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2465 if (m_lastColliders.Contains(0)) 2894 if (m_lastColliders.Contains(0))
2466 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding); 2895 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding);
2467 else
2468 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2469 }
2470 if (endedColliders.Contains(0)) 2896 if (endedColliders.Contains(0))
2471 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); 2897 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2472 } 2898 }
2473 2899
2900 // The Collision sounds code calls this
2901 public void SendCollisionSound(UUID soundID, double volume, Vector3 position)
2902 {
2903 if (soundID == UUID.Zero)
2904 return;
2905
2906 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>();
2907 if (soundModule == null)
2908 return;
2909
2910 if (volume > 1)
2911 volume = 1;
2912 if (volume < 0)
2913 volume = 0;
2914
2915 int now = Util.EnvironmentTickCount();
2916 if(Util.EnvironmentTickCountSubtract(now,LastColSoundSentTime) <200)
2917 return;
2918
2919 LastColSoundSentTime = now;
2920
2921 UUID ownerID = OwnerID;
2922 UUID objectID = ParentGroup.RootPart.UUID;
2923 UUID parentID = ParentGroup.UUID;
2924 ulong regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle;
2925
2926 soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, 0 );
2927 }
2928
2474 public void PhysicsOutOfBounds(Vector3 pos) 2929 public void PhysicsOutOfBounds(Vector3 pos)
2475 { 2930 {
2476 // Note: This is only being called on the root prim at this time. 2931 // Note: This is only being called on the root prim at this time.
@@ -2492,9 +2947,9 @@ namespace OpenSim.Region.Framework.Scenes
2492 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2947 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2493 2948
2494 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2949 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2495 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2950 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2496 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2951 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2497 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2952 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2498 { 2953 {
2499 ParentGroup.AbsolutePosition = newpos; 2954 ParentGroup.AbsolutePosition = newpos;
2500 return; 2955 return;
@@ -2779,6 +3234,14 @@ namespace OpenSim.Region.Framework.Scenes
2779 if (ParentGroup == null) 3234 if (ParentGroup == null)
2780 return; 3235 return;
2781 3236
3237 // Update the "last" values
3238 m_lastPosition = OffsetPosition;
3239 m_lastRotation = RotationOffset;
3240 m_lastVelocity = Velocity;
3241 m_lastAcceleration = Acceleration;
3242 m_lastAngularVelocity = AngularVelocity;
3243 m_lastUpdateSentTime = Environment.TickCount;
3244
2782 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3245 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
2783 { 3246 {
2784 SendFullUpdate(avatar.ControllingClient); 3247 SendFullUpdate(avatar.ControllingClient);
@@ -2837,8 +3300,8 @@ namespace OpenSim.Region.Framework.Scenes
2837 { 3300 {
2838 const float ROTATION_TOLERANCE = 0.01f; 3301 const float ROTATION_TOLERANCE = 0.01f;
2839 const float VELOCITY_TOLERANCE = 0.001f; 3302 const float VELOCITY_TOLERANCE = 0.001f;
2840 const float POSITION_TOLERANCE = 0.05f; 3303 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2841 const int TIME_MS_TOLERANCE = 3000; 3304 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2842 3305
2843 switch (UpdateFlag) 3306 switch (UpdateFlag)
2844 { 3307 {
@@ -2852,17 +3315,10 @@ namespace OpenSim.Region.Framework.Scenes
2852 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || 3315 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) ||
2853 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || 3316 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) ||
2854 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 3317 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
2855 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 3318 Environment.TickCount - m_lastUpdateSentTime > TIME_MS_TOLERANCE)
2856 { 3319 {
2857 SendTerseUpdateToAllClients(); 3320 SendTerseUpdateToAllClients();
2858 3321
2859 // Update the "last" values
2860 m_lastPosition = OffsetPosition;
2861 m_lastRotation = RotationOffset;
2862 m_lastVelocity = Velocity;
2863 m_lastAcceleration = Acceleration;
2864 m_lastAngularVelocity = AngularVelocity;
2865 m_lastTerseSent = Environment.TickCount;
2866 } 3322 }
2867 break; 3323 break;
2868 } 3324 }
@@ -2880,6 +3336,17 @@ namespace OpenSim.Region.Framework.Scenes
2880 /// </summary> 3336 /// </summary>
2881 public void SendTerseUpdateToAllClients() 3337 public void SendTerseUpdateToAllClients()
2882 { 3338 {
3339 if (ParentGroup == null || ParentGroup.Scene == null)
3340 return;
3341
3342 // Update the "last" values
3343 m_lastPosition = OffsetPosition;
3344 m_lastRotation = RotationOffset;
3345 m_lastVelocity = Velocity;
3346 m_lastAcceleration = Acceleration;
3347 m_lastAngularVelocity = AngularVelocity;
3348 m_lastUpdateSentTime = Environment.TickCount;
3349
2883 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3350 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
2884 { 3351 {
2885 SendTerseUpdateToClient(client); 3352 SendTerseUpdateToClient(client);
@@ -2903,10 +3370,13 @@ namespace OpenSim.Region.Framework.Scenes
2903 3370
2904 public void SetBuoyancy(float fvalue) 3371 public void SetBuoyancy(float fvalue)
2905 { 3372 {
2906 PhysicsActor pa = PhysActor; 3373 Buoyancy = fvalue;
2907 3374/*
2908 if (pa != null) 3375 if (PhysActor != null)
2909 pa.Buoyancy = fvalue; 3376 {
3377 PhysActor.Buoyancy = fvalue;
3378 }
3379 */
2910 } 3380 }
2911 3381
2912 public void SetDieAtEdge(bool p) 3382 public void SetDieAtEdge(bool p)
@@ -2922,47 +3392,111 @@ namespace OpenSim.Region.Framework.Scenes
2922 PhysicsActor pa = PhysActor; 3392 PhysicsActor pa = PhysActor;
2923 3393
2924 if (pa != null) 3394 if (pa != null)
2925 pa.FloatOnWater = floatYN == 1; 3395 pa.FloatOnWater = (floatYN == 1);
2926 } 3396 }
2927 3397
2928 public void SetForce(Vector3 force) 3398 public void SetForce(Vector3 force)
2929 { 3399 {
2930 PhysicsActor pa = PhysActor; 3400 Force = force;
3401 }
2931 3402
2932 if (pa != null) 3403 public SOPVehicle VehicleParams
2933 pa.Force = force; 3404 {
3405 get
3406 {
3407 return m_vehicleParams;
3408 }
3409 set
3410 {
3411 m_vehicleParams = value;
3412 }
3413 }
3414
3415
3416 public int VehicleType
3417 {
3418 get
3419 {
3420 if (m_vehicleParams == null)
3421 return (int)Vehicle.TYPE_NONE;
3422 else
3423 return (int)m_vehicleParams.Type;
3424 }
3425 set
3426 {
3427 SetVehicleType(value);
3428 }
2934 } 3429 }
2935 3430
2936 public void SetVehicleType(int type) 3431 public void SetVehicleType(int type)
2937 { 3432 {
2938 PhysicsActor pa = PhysActor; 3433 m_vehicleParams = null;
3434
3435 if (type == (int)Vehicle.TYPE_NONE)
3436 {
3437 if (_parentID ==0 && PhysActor != null)
3438 PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
3439 return;
3440 }
3441 m_vehicleParams = new SOPVehicle();
3442 m_vehicleParams.ProcessTypeChange((Vehicle)type);
3443 {
3444 if (_parentID ==0 && PhysActor != null)
3445 PhysActor.VehicleType = type;
3446 return;
3447 }
3448 }
2939 3449
2940 if (pa != null) 3450 public void SetVehicleFlags(int param, bool remove)
2941 pa.VehicleType = type; 3451 {
3452 if (m_vehicleParams == null)
3453 return;
3454
3455 m_vehicleParams.ProcessVehicleFlags(param, remove);
3456
3457 if (_parentID ==0 && PhysActor != null)
3458 {
3459 PhysActor.VehicleFlags(param, remove);
3460 }
2942 } 3461 }
2943 3462
2944 public void SetVehicleFloatParam(int param, float value) 3463 public void SetVehicleFloatParam(int param, float value)
2945 { 3464 {
2946 PhysicsActor pa = PhysActor; 3465 if (m_vehicleParams == null)
3466 return;
2947 3467
2948 if (pa != null) 3468 m_vehicleParams.ProcessFloatVehicleParam((Vehicle)param, value);
2949 pa.VehicleFloatParam(param, value); 3469
3470 if (_parentID == 0 && PhysActor != null)
3471 {
3472 PhysActor.VehicleFloatParam(param, value);
3473 }
2950 } 3474 }
2951 3475
2952 public void SetVehicleVectorParam(int param, Vector3 value) 3476 public void SetVehicleVectorParam(int param, Vector3 value)
2953 { 3477 {
2954 PhysicsActor pa = PhysActor; 3478 if (m_vehicleParams == null)
3479 return;
2955 3480
2956 if (pa != null) 3481 m_vehicleParams.ProcessVectorVehicleParam((Vehicle)param, value);
2957 pa.VehicleVectorParam(param, value); 3482
3483 if (_parentID == 0 && PhysActor != null)
3484 {
3485 PhysActor.VehicleVectorParam(param, value);
3486 }
2958 } 3487 }
2959 3488
2960 public void SetVehicleRotationParam(int param, Quaternion rotation) 3489 public void SetVehicleRotationParam(int param, Quaternion rotation)
2961 { 3490 {
2962 PhysicsActor pa = PhysActor; 3491 if (m_vehicleParams == null)
3492 return;
2963 3493
2964 if (pa != null) 3494 m_vehicleParams.ProcessRotationVehicleParam((Vehicle)param, rotation);
2965 pa.VehicleRotationParam(param, rotation); 3495
3496 if (_parentID == 0 && PhysActor != null)
3497 {
3498 PhysActor.VehicleRotationParam(param, rotation);
3499 }
2966 } 3500 }
2967 3501
2968 /// <summary> 3502 /// <summary>
@@ -3163,14 +3697,6 @@ namespace OpenSim.Region.Framework.Scenes
3163 hasProfileCut = hasDimple; // is it the same thing? 3697 hasProfileCut = hasDimple; // is it the same thing?
3164 } 3698 }
3165 3699
3166 public void SetVehicleFlags(int param, bool remove)
3167 {
3168 PhysicsActor pa = PhysActor;
3169
3170 if (pa != null)
3171 pa.VehicleFlags(param, remove);
3172 }
3173
3174 public void SetGroup(UUID groupID, IClientAPI client) 3700 public void SetGroup(UUID groupID, IClientAPI client)
3175 { 3701 {
3176 // Scene.AddNewPrims() calls with client == null so can't use this. 3702 // Scene.AddNewPrims() calls with client == null so can't use this.
@@ -3274,71 +3800,20 @@ namespace OpenSim.Region.Framework.Scenes
3274 { 3800 {
3275 ParentGroup.stopMoveToTarget(); 3801 ParentGroup.stopMoveToTarget();
3276 3802
3277 ParentGroup.ScheduleGroupForTerseUpdate(); 3803// ParentGroup.ScheduleGroupForTerseUpdate();
3278 //ParentGroup.ScheduleGroupForFullUpdate(); 3804 //ParentGroup.ScheduleGroupForFullUpdate();
3279 } 3805 }
3280 3806
3281 public void StoreUndoState() 3807 public void StoreUndoState(ObjectChangeType change)
3282 { 3808 {
3283 StoreUndoState(false); 3809 if (m_UndoRedo == null)
3284 } 3810 m_UndoRedo = new UndoRedoState(5);
3285
3286 public void StoreUndoState(bool forGroup)
3287 {
3288 if (ParentGroup == null || ParentGroup.Scene == null)
3289 return;
3290
3291 if (Undoing)
3292 {
3293// m_log.DebugFormat(
3294// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3295 return;
3296 }
3297
3298 if (IgnoreUndoUpdate)
3299 {
3300// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3301 return;
3302 }
3303 3811
3304 lock (m_undo) 3812 lock (m_UndoRedo)
3305 { 3813 {
3306 if (m_undo.Count > 0) 3814 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3307 { 3815 {
3308 UndoState last = m_undo[m_undo.Count - 1]; 3816 m_UndoRedo.StoreUndo(this, change);
3309 if (last != null)
3310 {
3311 // TODO: May need to fix for group comparison
3312 if (last.Compare(this))
3313 {
3314// m_log.DebugFormat(
3315// "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3316// Name, LocalId, m_undo.Count);
3317
3318 return;
3319 }
3320 }
3321 }
3322
3323// m_log.DebugFormat(
3324// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3325// Name, LocalId, forGroup, m_undo.Count);
3326
3327 if (ParentGroup.Scene.MaxUndoCount > 0)
3328 {
3329 UndoState nUndo = new UndoState(this, forGroup);
3330
3331 m_undo.Add(nUndo);
3332
3333 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3334 m_undo.RemoveAt(0);
3335
3336 if (m_redo.Count > 0)
3337 m_redo.Clear();
3338
3339// m_log.DebugFormat(
3340// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3341// Name, LocalId, forGroup, m_undo.Count);
3342 } 3817 }
3343 } 3818 }
3344 } 3819 }
@@ -3350,88 +3825,46 @@ namespace OpenSim.Region.Framework.Scenes
3350 { 3825 {
3351 get 3826 get
3352 { 3827 {
3353 lock (m_undo) 3828 if (m_UndoRedo == null)
3354 return m_undo.Count; 3829 return 0;
3830 return m_UndoRedo.Count;
3355 } 3831 }
3356 } 3832 }
3357 3833
3358 public void Undo() 3834 public void Undo()
3359 { 3835 {
3360 lock (m_undo) 3836 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3361 { 3837 return;
3362// m_log.DebugFormat(
3363// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3364// Name, LocalId, m_undo.Count);
3365
3366 if (m_undo.Count > 0)
3367 {
3368 UndoState goback = m_undo[m_undo.Count - 1];
3369 m_undo.RemoveAt(m_undo.Count - 1);
3370
3371 UndoState nUndo = null;
3372
3373 if (ParentGroup.Scene.MaxUndoCount > 0)
3374 {
3375 nUndo = new UndoState(this, goback.ForGroup);
3376 }
3377
3378 goback.PlaybackState(this);
3379
3380 if (nUndo != null)
3381 {
3382 m_redo.Add(nUndo);
3383
3384 if (m_redo.Count > ParentGroup.Scene.MaxUndoCount)
3385 m_redo.RemoveAt(0);
3386 }
3387 }
3388 3838
3389// m_log.DebugFormat( 3839 lock (m_UndoRedo)
3390// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3840 {
3391// Name, LocalId, m_undo.Count); 3841 Undoing = true;
3842 m_UndoRedo.Undo(this);
3843 Undoing = false;
3392 } 3844 }
3393 } 3845 }
3394 3846
3395 public void Redo() 3847 public void Redo()
3396 { 3848 {
3397 lock (m_undo) 3849 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3398 { 3850 return;
3399// m_log.DebugFormat(
3400// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3401// Name, LocalId, m_redo.Count);
3402
3403 if (m_redo.Count > 0)
3404 {
3405 UndoState gofwd = m_redo[m_redo.Count - 1];
3406 m_redo.RemoveAt(m_redo.Count - 1);
3407
3408 if (ParentGroup.Scene.MaxUndoCount > 0)
3409 {
3410 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3411
3412 m_undo.Add(nUndo);
3413
3414 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3415 m_undo.RemoveAt(0);
3416 }
3417
3418 gofwd.PlayfwdState(this);
3419 3851
3420// m_log.DebugFormat( 3852 lock (m_UndoRedo)
3421// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3853 {
3422// Name, LocalId, m_redo.Count); 3854 Undoing = true;
3423 } 3855 m_UndoRedo.Redo(this);
3856 Undoing = false;
3424 } 3857 }
3425 } 3858 }
3426 3859
3427 public void ClearUndoState() 3860 public void ClearUndoState()
3428 { 3861 {
3429// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3862 if (m_UndoRedo == null || Undoing)
3863 return;
3430 3864
3431 lock (m_undo) 3865 lock (m_UndoRedo)
3432 { 3866 {
3433 m_undo.Clear(); 3867 m_UndoRedo.Clear();
3434 m_redo.Clear();
3435 } 3868 }
3436 } 3869 }
3437 3870
@@ -3983,7 +4416,7 @@ namespace OpenSim.Region.Framework.Scenes
3983 if (god) 4416 if (god)
3984 { 4417 {
3985 BaseMask = ApplyMask(BaseMask, set, mask); 4418 BaseMask = ApplyMask(BaseMask, set, mask);
3986 Inventory.ApplyGodPermissions(_baseMask); 4419 Inventory.ApplyGodPermissions(BaseMask);
3987 } 4420 }
3988 4421
3989 break; 4422 break;
@@ -4014,7 +4447,7 @@ namespace OpenSim.Region.Framework.Scenes
4014 } 4447 }
4015 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & 4448 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) &
4016 baseMask; 4449 baseMask;
4017 // Prevent the client from creating no mod, no copy 4450 // Prevent the client from creating no copy, no transfer
4018 // objects 4451 // objects
4019 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0) 4452 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0)
4020 NextOwnerMask |= (uint)PermissionMask.Transfer; 4453 NextOwnerMask |= (uint)PermissionMask.Transfer;
@@ -4032,20 +4465,20 @@ namespace OpenSim.Region.Framework.Scenes
4032 { 4465 {
4033 bool update = false; 4466 bool update = false;
4034 4467
4035 if (BaseMask != source.BaseMask || 4468 uint prevOwnerMask = OwnerMask;
4036 OwnerMask != source.OwnerMask || 4469 uint prevGroupMask = GroupMask;
4037 GroupMask != source.GroupMask || 4470 uint prevEveryoneMask = EveryoneMask;
4038 EveryoneMask != source.EveryoneMask || 4471 uint prevNextOwnerMask = NextOwnerMask;
4039 NextOwnerMask != source.NextOwnerMask)
4040 update = true;
4041 4472
4042 BaseMask = source.BaseMask; 4473 OwnerMask = source.OwnerMask & BaseMask;
4043 OwnerMask = source.OwnerMask; 4474 GroupMask = source.GroupMask & BaseMask;
4044 GroupMask = source.GroupMask; 4475 EveryoneMask = source.EveryoneMask & BaseMask;
4045 EveryoneMask = source.EveryoneMask; 4476 NextOwnerMask = source.NextOwnerMask & BaseMask;
4046 NextOwnerMask = source.NextOwnerMask;
4047 4477
4048 if (update) 4478 if (OwnerMask != prevOwnerMask ||
4479 GroupMask != prevGroupMask ||
4480 EveryoneMask != prevEveryoneMask ||
4481 NextOwnerMask != prevNextOwnerMask)
4049 SendFullUpdateToAllClients(); 4482 SendFullUpdateToAllClients();
4050 } 4483 }
4051 4484
@@ -4096,6 +4529,7 @@ namespace OpenSim.Region.Framework.Scenes
4096 } 4529 }
4097 } 4530 }
4098 4531
4532
4099 public void UpdateExtraPhysics(ExtraPhysicsData physdata) 4533 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4100 { 4534 {
4101 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null) 4535 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
@@ -4123,7 +4557,7 @@ namespace OpenSim.Region.Framework.Scenes
4123 /// <param name="SetTemporary"></param> 4557 /// <param name="SetTemporary"></param>
4124 /// <param name="SetPhantom"></param> 4558 /// <param name="SetPhantom"></param>
4125 /// <param name="SetVD"></param> 4559 /// <param name="SetVD"></param>
4126 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) 4560 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
4127 { 4561 {
4128 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4562 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4129 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4563 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4133,116 +4567,98 @@ namespace OpenSim.Region.Framework.Scenes
4133 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4567 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4134 return; 4568 return;
4135 4569
4136 PhysicsActor pa = PhysActor; 4570 VolumeDetectActive = SetVD;
4137 4571
4138 // Special cases for VD. VD can only be called from a script 4572 // volume detector implies phantom
4139 // and can't be combined with changes to other states. So we can rely 4573 if (VolumeDetectActive)
4140 // that...
4141 // ... if VD is changed, all others are not.
4142 // ... if one of the others is changed, VD is not.
4143 if (SetVD) // VD is active, special logic applies
4144 {
4145 // State machine logic for VolumeDetect
4146 // More logic below
4147 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4148
4149 if (phanReset) // Phantom changes from on to off switch VD off too
4150 {
4151 SetVD = false; // Switch it of for the course of this routine
4152 VolumeDetectActive = false; // and also permanently
4153
4154 if (pa != null)
4155 pa.SetVolumeDetect(0); // Let physics know about it too
4156 }
4157 else
4158 {
4159 // If volumedetect is active we don't want phantom to be applied.
4160 // If this is a new call to VD out of the state "phantom"
4161 // this will also cause the prim to be visible to physics
4162 SetPhantom = false;
4163 }
4164 }
4165
4166 if (UsePhysics && IsJoint())
4167 {
4168 SetPhantom = true; 4574 SetPhantom = true;
4169 }
4170 4575
4171 if (UsePhysics) 4576 if (UsePhysics)
4172 {
4173 AddFlag(PrimFlags.Physics); 4577 AddFlag(PrimFlags.Physics);
4174 if (!wasUsingPhysics)
4175 {
4176 DoPhysicsPropertyUpdate(UsePhysics, false);
4177 }
4178 }
4179 else 4578 else
4180 {
4181 RemFlag(PrimFlags.Physics); 4579 RemFlag(PrimFlags.Physics);
4182 if (wasUsingPhysics)
4183 {
4184 DoPhysicsPropertyUpdate(UsePhysics, false);
4185 }
4186 }
4187 4580
4188 if (SetPhantom 4581 if (SetPhantom)
4189 || ParentGroup.IsAttachment
4190 || PhysicsShapeType == (byte)PhysShapeType.none
4191 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4192 {
4193 AddFlag(PrimFlags.Phantom); 4582 AddFlag(PrimFlags.Phantom);
4583 else
4584 RemFlag(PrimFlags.Phantom);
4194 4585
4195 if (PhysActor != null) 4586 if (SetTemporary)
4587 AddFlag(PrimFlags.TemporaryOnRez);
4588 else
4589 RemFlag(PrimFlags.TemporaryOnRez);
4590
4591
4592 if (ParentGroup.Scene == null)
4593 return;
4594
4595 PhysicsActor pa = PhysActor;
4596
4597 if (pa != null && building && pa.Building != building)
4598 pa.Building = building;
4599
4600 if ((SetPhantom && !UsePhysics && !SetVD) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
4601 || (Shape.PathCurve == (byte)Extrusion.Flexible))
4602 {
4603 if (pa != null)
4196 { 4604 {
4605 if(wasUsingPhysics)
4606 ParentGroup.Scene.RemovePhysicalPrim(1);
4197 RemoveFromPhysics(); 4607 RemoveFromPhysics();
4198 pa = null;
4199 } 4608 }
4609
4610 Velocity = new Vector3(0, 0, 0);
4611 Acceleration = new Vector3(0, 0, 0);
4612 if (ParentGroup.RootPart == this)
4613 AngularVelocity = new Vector3(0, 0, 0);
4200 } 4614 }
4201 else // Not phantom 4615
4616 else
4202 { 4617 {
4203 RemFlag(PrimFlags.Phantom); 4618 if (ParentGroup.Scene.CollidablePrims)
4204
4205 if (ParentGroup.Scene == null)
4206 return;
4207
4208 if (ParentGroup.Scene.CollidablePrims && pa == null)
4209 { 4619 {
4210 AddToPhysics(UsePhysics, SetPhantom, false); 4620 if (pa == null)
4211 pa = PhysActor;
4212
4213
4214 if (pa != null)
4215 { 4621 {
4216 pa.SetMaterial(Material); 4622 AddToPhysics(UsePhysics, SetPhantom, building, false);
4217 DoPhysicsPropertyUpdate(UsePhysics, true); 4623 pa = PhysActor;
4218 4624/*
4219 if ( 4625 if (pa != null)
4220 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4221 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4222 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4223 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4224 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4225 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4226 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4227 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4228 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4229 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4230 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4231 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4232 (CollisionSound != UUID.Zero)
4233 )
4234 { 4626 {
4235 pa.OnCollisionUpdate += PhysicsCollision; 4627 if (
4236 pa.SubscribeEvents(1000); 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 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4635 ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4636 (CollisionSound != UUID.Zero)
4637 )
4638 {
4639 pa.OnCollisionUpdate += PhysicsCollision;
4640 pa.SubscribeEvents(1000);
4641 }
4237 } 4642 }
4643*/
4644 }
4645 else // it already has a physical representation
4646 {
4647 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4648/* moved into DoPhysicsPropertyUpdate
4649 if(VolumeDetectActive)
4650 pa.SetVolumeDetect(1);
4651 else
4652 pa.SetVolumeDetect(0);
4653*/
4654
4655 if (pa.Building != building)
4656 pa.Building = building;
4238 } 4657 }
4239 }
4240 else // it already has a physical representation
4241 {
4242 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4243 }
4244 }
4245 4658
4659 UpdatePhysicsSubscribedEvents();
4660 }
4661 }
4246 if (SetVD) 4662 if (SetVD)
4247 { 4663 {
4248 // If the above logic worked (this is urgent candidate to unit tests!) 4664 // If the above logic worked (this is urgent candidate to unit tests!)
@@ -4256,6 +4672,7 @@ namespace OpenSim.Region.Framework.Scenes
4256 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active 4672 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4257 VolumeDetectActive = true; 4673 VolumeDetectActive = true;
4258 } 4674 }
4675 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4259 } 4676 }
4260 else if (SetVD != wasVD) 4677 else if (SetVD != wasVD)
4261 { 4678 {
@@ -4267,61 +4684,51 @@ namespace OpenSim.Region.Framework.Scenes
4267 RemFlag(PrimFlags.Phantom); 4684 RemFlag(PrimFlags.Phantom);
4268 VolumeDetectActive = false; 4685 VolumeDetectActive = false;
4269 } 4686 }
4270 4687 // and last in case we have a new actor and not building
4271 if (SetTemporary)
4272 {
4273 AddFlag(PrimFlags.TemporaryOnRez);
4274 }
4275 else
4276 {
4277 RemFlag(PrimFlags.TemporaryOnRez);
4278 }
4279
4280 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4281 4688
4282 if (ParentGroup != null) 4689 if (ParentGroup != null)
4283 { 4690 {
4284 ParentGroup.HasGroupChanged = true; 4691 ParentGroup.HasGroupChanged = true;
4285 ScheduleFullUpdate(); 4692 ScheduleFullUpdate();
4286 } 4693 }
4287 4694
4288// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); 4695// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4289 } 4696 }
4290 4697
4291 /// <summary> 4698 /// <summary>
4292 /// Adds this part to the physics scene. 4699 /// Adds this part to the physics scene.
4700 /// and sets the PhysActor property
4293 /// </summary> 4701 /// </summary>
4294 /// <remarks>This method also sets the PhysActor property.</remarks> 4702 /// <param name="isPhysical">Add this prim as physical.</param>
4295 /// <param name="rigidBody">Add this prim with a rigid body.</param> 4703 /// <param name="isPhantom">Add this prim as phantom.</param>
4296 /// <returns> 4704 /// <param name="building">tells physics to delay full construction of object</param>
4297 /// The physics actor. null if there was a failure. 4705 /// <param name="applyDynamics">applies velocities, force and torque</param>
4298 /// </returns> 4706 private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
4299 private void AddToPhysics(bool isPhysical, bool isPhantom, bool applyDynamics) 4707 {
4300 {
4301 PhysicsActor pa; 4708 PhysicsActor pa;
4302 4709
4303 Vector3 velocity = Velocity; 4710 Vector3 velocity = Velocity;
4304 Vector3 rotationalVelocity = AngularVelocity;; 4711 Vector3 rotationalVelocity = AngularVelocity;;
4305 4712
4306 try 4713 try
4307 { 4714 {
4308 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4715 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4309 string.Format("{0}/{1}", Name, UUID), 4716 string.Format("{0}/{1}", Name, UUID),
4310 Shape, 4717 Shape,
4311 AbsolutePosition, 4718 AbsolutePosition,
4312 Scale, 4719 Scale,
4313 GetWorldRotation(), 4720 GetWorldRotation(),
4314 isPhysical, 4721 isPhysical,
4315 isPhantom, 4722 isPhantom,
4316 PhysicsShapeType, 4723 PhysicsShapeType,
4317 m_localId); 4724 m_localId);
4318 } 4725 }
4319 catch (Exception e) 4726 catch (Exception e)
4320 { 4727 {
4321 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e); 4728 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e);
4322 pa = null; 4729 pa = null;
4323 } 4730 }
4324 4731
4325 if (pa != null) 4732 if (pa != null)
4326 { 4733 {
4327 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 4734 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
@@ -4334,9 +4741,16 @@ namespace OpenSim.Region.Framework.Scenes
4334 4741
4335 if (VolumeDetectActive) // change if not the default only 4742 if (VolumeDetectActive) // change if not the default only
4336 pa.SetVolumeDetect(1); 4743 pa.SetVolumeDetect(1);
4744
4745 if (m_vehicleParams != null && LocalId == ParentGroup.RootPart.LocalId)
4746 m_vehicleParams.SetVehicle(pa);
4747
4337 // we are going to tell rest of code about physics so better have this here 4748 // we are going to tell rest of code about physics so better have this here
4338 PhysActor = pa; 4749 PhysActor = pa;
4339 4750
4751 // DoPhysicsPropertyUpdate(isPhysical, true);
4752 // lets expand it here just with what it really needs to do
4753
4340 if (isPhysical) 4754 if (isPhysical)
4341 { 4755 {
4342 if (ParentGroup.RootPart.KeyframeMotion != null) 4756 if (ParentGroup.RootPart.KeyframeMotion != null)
@@ -4358,19 +4772,34 @@ namespace OpenSim.Region.Framework.Scenes
4358 } 4772 }
4359 } 4773 }
4360 4774
4361 if (applyDynamics) 4775 if (applyDynamics)
4362 // do independent of isphysical so parameters get setted (at least some) 4776 // do independent of isphysical so parameters get setted (at least some)
4363 { 4777 {
4364 Velocity = velocity; 4778 Velocity = velocity;
4365 AngularVelocity = rotationalVelocity; 4779 AngularVelocity = rotationalVelocity;
4366// pa.Velocity = velocity; 4780// pa.Velocity = velocity;
4367 pa.RotationalVelocity = rotationalVelocity; 4781 pa.RotationalVelocity = rotationalVelocity;
4782
4783 // if not vehicle and root part apply force and torque
4784 if ((m_vehicleParams == null || m_vehicleParams.Type == Vehicle.TYPE_NONE)
4785 && LocalId == ParentGroup.RootPart.LocalId)
4786 {
4787 pa.Force = Force;
4788 pa.Torque = Torque;
4789 }
4368 } 4790 }
4369 4791
4370 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); 4792// if (Shape.SculptEntry)
4793// CheckSculptAndLoad();
4794// else
4795 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
4796
4797 if (!building)
4798 pa.Building = false;
4371 } 4799 }
4372 4800
4373 PhysActor = pa; 4801 PhysActor = pa;
4802
4374 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this); 4803 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this);
4375 } 4804 }
4376 4805
@@ -4379,13 +4808,21 @@ namespace OpenSim.Region.Framework.Scenes
4379 /// </summary> 4808 /// </summary>
4380 /// <remarks> 4809 /// <remarks>
4381 /// This isn't the same as turning off physical, since even without being physical the prim has a physics 4810 /// This isn't the same as turning off physical, since even without being physical the prim has a physics
4382 /// representation for collision detection. Rather, this would be used in situations such as making a prim 4811 /// representation for collision detection.
4383 /// phantom.
4384 /// </remarks> 4812 /// </remarks>
4385 public void RemoveFromPhysics() 4813 public void RemoveFromPhysics()
4386 { 4814 {
4387 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this); 4815 PhysicsActor pa = PhysActor;
4388 ParentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 4816 if (pa != null)
4817 {
4818 pa.OnCollisionUpdate -= PhysicsCollision;
4819 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
4820 pa.OnOutOfBounds -= PhysicsOutOfBounds;
4821
4822 ParentGroup.Scene.PhysicsScene.RemovePrim(pa);
4823
4824 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this);
4825 }
4389 PhysActor = null; 4826 PhysActor = null;
4390 } 4827 }
4391 4828
@@ -4517,6 +4954,8 @@ namespace OpenSim.Region.Framework.Scenes
4517 { 4954 {
4518// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); 4955// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4519 4956
4957 return;
4958
4520 if (ParentGroup.IsDeleted) 4959 if (ParentGroup.IsDeleted)
4521 return; 4960 return;
4522 4961
@@ -4640,6 +5079,44 @@ namespace OpenSim.Region.Framework.Scenes
4640 } 5079 }
4641 } 5080 }
4642 5081
5082
5083 private void UpdatePhysicsSubscribedEvents()
5084 {
5085 PhysicsActor pa = PhysActor;
5086 if (pa == null)
5087 return;
5088
5089 pa.OnCollisionUpdate -= PhysicsCollision;
5090
5091 bool hassound = (!VolumeDetectActive && CollisionSoundType >= 0 && ((Flags & PrimFlags.Physics) != 0));
5092
5093 scriptEvents CombinedEvents = AggregateScriptEvents;
5094
5095 // merge with root part
5096 if (ParentGroup != null && ParentGroup.RootPart != null)
5097 CombinedEvents |= ParentGroup.RootPart.AggregateScriptEvents;
5098
5099 // submit to this part case
5100 if (VolumeDetectActive)
5101 CombinedEvents &= PhyscicsVolumeDtcSubsEvents;
5102 else if ((Flags & PrimFlags.Phantom) != 0)
5103 CombinedEvents &= PhyscicsPhantonSubsEvents;
5104 else
5105 CombinedEvents &= PhysicsNeededSubsEvents;
5106
5107 if (hassound || CombinedEvents != 0)
5108 {
5109 // subscribe to physics updates.
5110 pa.OnCollisionUpdate += PhysicsCollision;
5111 pa.SubscribeEvents(50); // 20 reports per second
5112 }
5113 else
5114 {
5115 pa.UnSubscribeEvents();
5116 }
5117 }
5118
5119
4643 public void aggregateScriptEvents() 5120 public void aggregateScriptEvents()
4644 { 5121 {
4645 if (ParentGroup == null || ParentGroup.RootPart == null) 5122 if (ParentGroup == null || ParentGroup.RootPart == null)
@@ -4676,40 +5153,32 @@ namespace OpenSim.Region.Framework.Scenes
4676 { 5153 {
4677 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; 5154 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop;
4678 } 5155 }
4679 5156/*
4680 PhysicsActor pa = PhysActor; 5157 PhysicsActor pa = PhysActor;
4681 5158 if (pa != null)
4682 if (
4683 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4684 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4685 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4686 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4687 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4688 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4689 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4690 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4691 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4692 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4693 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4694 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4695 (CollisionSound != UUID.Zero)
4696 )
4697 { 5159 {
4698 // subscribe to physics updates. 5160 if (
4699 if (pa != null) 5161// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
5162// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
5163// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
5164// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5165// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5166// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5167 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5168 )
4700 { 5169 {
5170 // subscribe to physics updates.
4701 pa.OnCollisionUpdate += PhysicsCollision; 5171 pa.OnCollisionUpdate += PhysicsCollision;
4702 pa.SubscribeEvents(1000); 5172 pa.SubscribeEvents(1000);
4703 } 5173 }
4704 } 5174 else
4705 else
4706 {
4707 if (pa != null)
4708 { 5175 {
4709 pa.UnSubscribeEvents(); 5176 pa.UnSubscribeEvents();
4710 pa.OnCollisionUpdate -= PhysicsCollision; 5177 pa.OnCollisionUpdate -= PhysicsCollision;
4711 } 5178 }
4712 } 5179 }
5180 */
5181 UpdatePhysicsSubscribedEvents();
4713 5182
4714 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 5183 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4715 //{ 5184 //{
@@ -4843,6 +5312,18 @@ namespace OpenSim.Region.Framework.Scenes
4843 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 5312 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4844 } 5313 }
4845 5314
5315 public void ResetOwnerChangeFlag()
5316 {
5317 List<UUID> inv = Inventory.GetInventoryList();
5318
5319 foreach (UUID itemID in inv)
5320 {
5321 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
5322 item.OwnerChanged = false;
5323 Inventory.UpdateInventoryItem(item, false, false);
5324 }
5325 }
5326
4846 /// <summary> 5327 /// <summary>
4847 /// Record an avatar sitting on this part. 5328 /// Record an avatar sitting on this part.
4848 /// </summary> 5329 /// </summary>