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.cs1478
1 files changed, 987 insertions, 491 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index ea8c3c5..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,25 @@ 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
393 private KeyframeMotion m_keyframeMotion = null;
394
395 public KeyframeMotion KeyframeMotion
396 {
397 get; set;
398 }
399
400
357 #endregion Fields 401 #endregion Fields
358 402
359// ~SceneObjectPart() 403// ~SceneObjectPart()
@@ -383,6 +427,7 @@ namespace OpenSim.Region.Framework.Scenes
383 // 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
384 // 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
385 m_inventory = new SceneObjectPartInventory(this); 429 m_inventory = new SceneObjectPartInventory(this);
430 LastColSoundSentTime = Util.EnvironmentTickCount();
386 } 431 }
387 432
388 /// <summary> 433 /// <summary>
@@ -397,7 +442,7 @@ namespace OpenSim.Region.Framework.Scenes
397 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 442 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
398 Quaternion rotationOffset, Vector3 offsetPosition) : this() 443 Quaternion rotationOffset, Vector3 offsetPosition) : this()
399 { 444 {
400 m_name = "Primitive"; 445 m_name = "Object";
401 446
402 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 447 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
403 LastOwnerID = CreatorID = OwnerID = ownerID; 448 LastOwnerID = CreatorID = OwnerID = ownerID;
@@ -436,7 +481,7 @@ namespace OpenSim.Region.Framework.Scenes
436 private uint _ownerMask = (uint)(PermissionMask.All | PermissionMask.Export); 481 private uint _ownerMask = (uint)(PermissionMask.All | PermissionMask.Export);
437 private uint _groupMask = (uint)PermissionMask.None; 482 private uint _groupMask = (uint)PermissionMask.None;
438 private uint _everyoneMask = (uint)PermissionMask.None; 483 private uint _everyoneMask = (uint)PermissionMask.None;
439 private uint _nextOwnerMask = (uint)PermissionMask.All; 484 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
440 private PrimFlags _flags = PrimFlags.None; 485 private PrimFlags _flags = PrimFlags.None;
441 private DateTime m_expires; 486 private DateTime m_expires;
442 private DateTime m_rezzed; 487 private DateTime m_rezzed;
@@ -530,12 +575,16 @@ namespace OpenSim.Region.Framework.Scenes
530 } 575 }
531 576
532 /// <value> 577 /// <value>
533 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 578 /// Get the inventory list
534 /// </value> 579 /// </value>
535 public TaskInventoryDictionary TaskInventory 580 public TaskInventoryDictionary TaskInventory
536 { 581 {
537 get { return m_inventory.Items; } 582 get {
538 set { m_inventory.Items = value; } 583 return m_inventory.Items;
584 }
585 set {
586 m_inventory.Items = value;
587 }
539 } 588 }
540 589
541 /// <summary> 590 /// <summary>
@@ -585,20 +634,6 @@ namespace OpenSim.Region.Framework.Scenes
585 } 634 }
586 } 635 }
587 636
588 public byte Material
589 {
590 get { return (byte) m_material; }
591 set
592 {
593 m_material = (Material)value;
594
595 PhysicsActor pa = PhysActor;
596
597 if (pa != null)
598 pa.SetMaterial((int)value);
599 }
600 }
601
602 [XmlIgnore] 637 [XmlIgnore]
603 public bool PassTouches 638 public bool PassTouches
604 { 639 {
@@ -624,6 +659,18 @@ namespace OpenSim.Region.Framework.Scenes
624 } 659 }
625 } 660 }
626 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
627 public Dictionary<int, string> CollisionFilter 674 public Dictionary<int, string> CollisionFilter
628 { 675 {
629 get { return m_CollisionFilter; } 676 get { return m_CollisionFilter; }
@@ -692,14 +739,12 @@ namespace OpenSim.Region.Framework.Scenes
692 set { m_LoopSoundSlavePrims = value; } 739 set { m_LoopSoundSlavePrims = value; }
693 } 740 }
694 741
695
696 public Byte[] TextureAnimation 742 public Byte[] TextureAnimation
697 { 743 {
698 get { return m_TextureAnimation; } 744 get { return m_TextureAnimation; }
699 set { m_TextureAnimation = value; } 745 set { m_TextureAnimation = value; }
700 } 746 }
701 747
702
703 public Byte[] ParticleSystem 748 public Byte[] ParticleSystem
704 { 749 {
705 get { return m_particleSystem; } 750 get { return m_particleSystem; }
@@ -736,9 +781,12 @@ namespace OpenSim.Region.Framework.Scenes
736 { 781 {
737 // 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.
738 PhysicsActor actor = PhysActor; 783 PhysicsActor actor = PhysActor;
739 // If physical and the root prim of a linkset, the position of the group is what physics thinks. 784 if (ParentID == 0)
740 if (actor != null && ParentID == 0) 785 {
741 m_groupPosition = actor.Position; 786 if (actor != null)
787 m_groupPosition = actor.Position;
788 return m_groupPosition;
789 }
742 790
743 // 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
744 if (ParentGroup.IsAttachment) 792 if (ParentGroup.IsAttachment)
@@ -748,14 +796,16 @@ namespace OpenSim.Region.Framework.Scenes
748 return sp.AbsolutePosition; 796 return sp.AbsolutePosition;
749 } 797 }
750 798
799 // use root prim's group position. Physics may have updated it
800 if (ParentGroup.RootPart != this)
801 m_groupPosition = ParentGroup.RootPart.GroupPosition;
751 return m_groupPosition; 802 return m_groupPosition;
752 } 803 }
753 set 804 set
754 { 805 {
755 m_groupPosition = value; 806 m_groupPosition = value;
756
757 PhysicsActor actor = PhysActor; 807 PhysicsActor actor = PhysActor;
758 if (actor != null) 808 if (actor != null && ParentGroup.Scene.PhysicsScene != null)
759 { 809 {
760 try 810 try
761 { 811 {
@@ -779,16 +829,6 @@ namespace OpenSim.Region.Framework.Scenes
779 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e); 829 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e);
780 } 830 }
781 } 831 }
782
783 // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
784 if (SitTargetAvatar != UUID.Zero)
785 {
786 ScenePresence avatar;
787 if (ParentGroup.Scene.TryGetScenePresence(SitTargetAvatar, out avatar))
788 {
789 avatar.ParentPosition = GetWorldPosition();
790 }
791 }
792 } 832 }
793 } 833 }
794 834
@@ -797,7 +837,7 @@ namespace OpenSim.Region.Framework.Scenes
797 get { return m_offsetPosition; } 837 get { return m_offsetPosition; }
798 set 838 set
799 { 839 {
800// StoreUndoState(); 840 Vector3 oldpos = m_offsetPosition;
801 m_offsetPosition = value; 841 m_offsetPosition = value;
802 842
803 if (ParentGroup != null && !ParentGroup.IsDeleted) 843 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -809,10 +849,25 @@ namespace OpenSim.Region.Framework.Scenes
809 actor.Orientation = GetWorldRotation(); 849 actor.Orientation = GetWorldRotation();
810 850
811 // Tell the physics engines that this prim changed. 851 // Tell the physics engines that this prim changed.
812 if (ParentGroup.Scene != null) 852 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene != null)
813 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 853 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
814 } 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 }
815 } 869 }
870 TriggerScriptChangedEvent(Changed.POSITION);
816 } 871 }
817 } 872 }
818 873
@@ -863,7 +918,7 @@ namespace OpenSim.Region.Framework.Scenes
863 918
864 set 919 set
865 { 920 {
866 StoreUndoState(); 921// StoreUndoState();
867 m_rotationOffset = value; 922 m_rotationOffset = value;
868 923
869 PhysicsActor actor = PhysActor; 924 PhysicsActor actor = PhysActor;
@@ -951,19 +1006,36 @@ namespace OpenSim.Region.Framework.Scenes
951 get 1006 get
952 { 1007 {
953 PhysicsActor actor = PhysActor; 1008 PhysicsActor actor = PhysActor;
954 if ((actor != null) && actor.IsPhysical) 1009 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
955 { 1010 {
956 m_angularVelocity = actor.RotationalVelocity; 1011 m_angularVelocity = actor.RotationalVelocity;
957 } 1012 }
958 return m_angularVelocity; 1013 return m_angularVelocity;
959 } 1014 }
960 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 }
961 } 1024 }
962 1025
963 /// <summary></summary> 1026 /// <summary></summary>
964 public Vector3 Acceleration 1027 public Vector3 Acceleration
965 { 1028 {
966 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
967 set { m_acceleration = value; } 1039 set { m_acceleration = value; }
968 } 1040 }
969 1041
@@ -1031,7 +1103,10 @@ namespace OpenSim.Region.Framework.Scenes
1031 public PrimitiveBaseShape Shape 1103 public PrimitiveBaseShape Shape
1032 { 1104 {
1033 get { return m_shape; } 1105 get { return m_shape; }
1034 set { m_shape = value;} 1106 set
1107 {
1108 m_shape = value;
1109 }
1035 } 1110 }
1036 1111
1037 /// <summary> 1112 /// <summary>
@@ -1044,7 +1119,6 @@ namespace OpenSim.Region.Framework.Scenes
1044 { 1119 {
1045 if (m_shape != null) 1120 if (m_shape != null)
1046 { 1121 {
1047 StoreUndoState();
1048 1122
1049 m_shape.Scale = value; 1123 m_shape.Scale = value;
1050 1124
@@ -1112,10 +1186,7 @@ namespace OpenSim.Region.Framework.Scenes
1112 { 1186 {
1113 get 1187 get
1114 { 1188 {
1115 if (ParentGroup.IsAttachment) 1189 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
1116 return GroupPosition;
1117
1118 return m_offsetPosition + m_groupPosition;
1119 } 1190 }
1120 } 1191 }
1121 1192
@@ -1284,6 +1355,13 @@ namespace OpenSim.Region.Framework.Scenes
1284 _flags = value; 1355 _flags = value;
1285 } 1356 }
1286 } 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 }
1287 1365
1288 /// <summary> 1366 /// <summary>
1289 /// ID of the avatar that is sat on us if we have a sit target. If there is no such avatar then is UUID.Zero 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
@@ -1334,12 +1412,41 @@ namespace OpenSim.Region.Framework.Scenes
1334 set { m_sitAnimation = value; } 1412 set { m_sitAnimation = value; }
1335 } 1413 }
1336 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
1337 public UUID CollisionSound 1436 public UUID CollisionSound
1338 { 1437 {
1339 get { return m_collisionSound; } 1438 get { return m_collisionSound; }
1340 set 1439 set
1341 { 1440 {
1342 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
1343 aggregateScriptEvents(); 1450 aggregateScriptEvents();
1344 } 1451 }
1345 } 1452 }
@@ -1350,6 +1457,125 @@ namespace OpenSim.Region.Framework.Scenes
1350 set { m_collisionSoundVolume = value; } 1457 set { m_collisionSoundVolume = value; }
1351 } 1458 }
1352 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
1353 public byte DefaultPhysicsShapeType() 1579 public byte DefaultPhysicsShapeType()
1354 { 1580 {
1355 byte type; 1581 byte type;
@@ -1362,6 +1588,65 @@ namespace OpenSim.Region.Framework.Scenes
1362 return type; 1588 return type;
1363 } 1589 }
1364 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
1365 public byte PhysicsShapeType 1650 public byte PhysicsShapeType
1366 { 1651 {
1367 get { return m_physicsShapeType; } 1652 get { return m_physicsShapeType; }
@@ -1395,11 +1680,14 @@ namespace OpenSim.Region.Framework.Scenes
1395 } 1680 }
1396 else if (PhysActor == null) 1681 else if (PhysActor == null)
1397 { 1682 {
1398 ApplyPhysics((uint)Flags, VolumeDetectActive); 1683 ApplyPhysics((uint)Flags, VolumeDetectActive, false);
1684 UpdatePhysicsSubscribedEvents();
1399 } 1685 }
1400 else 1686 else
1401 { 1687 {
1402 PhysActor.PhysicsShapeType = m_physicsShapeType; 1688 PhysActor.PhysicsShapeType = m_physicsShapeType;
1689// if (Shape.SculptEntry)
1690// CheckSculptAndLoad();
1403 } 1691 }
1404 1692
1405 if (ParentGroup != null) 1693 if (ParentGroup != null)
@@ -1501,6 +1789,7 @@ namespace OpenSim.Region.Framework.Scenes
1501 } 1789 }
1502 } 1790 }
1503 1791
1792
1504 #endregion Public Properties with only Get 1793 #endregion Public Properties with only Get
1505 1794
1506 private uint ApplyMask(uint val, bool set, uint mask) 1795 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1646,6 +1935,61 @@ namespace OpenSim.Region.Framework.Scenes
1646 } 1935 }
1647 } 1936 }
1648 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
1649 /// <summary> 1993 /// <summary>
1650 /// hook to the physics scene to apply angular impulse 1994 /// hook to the physics scene to apply angular impulse
1651 /// 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
@@ -1666,7 +2010,7 @@ namespace OpenSim.Region.Framework.Scenes
1666 impulse = newimpulse; 2010 impulse = newimpulse;
1667 } 2011 }
1668 2012
1669 ParentGroup.applyAngularImpulse(impulse); 2013 ParentGroup.ApplyAngularImpulse(impulse);
1670 } 2014 }
1671 2015
1672 /// <summary> 2016 /// <summary>
@@ -1676,20 +2020,24 @@ namespace OpenSim.Region.Framework.Scenes
1676 /// </summary> 2020 /// </summary>
1677 /// <param name="impulsei">Vector force</param> 2021 /// <param name="impulsei">Vector force</param>
1678 /// <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>
1679 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)
1680 { 2026 {
1681 Vector3 impulse = impulsei; 2027 Vector3 torque = torquei;
1682 2028
1683 if (localGlobalTF) 2029 if (localGlobalTF)
1684 { 2030 {
2031/*
1685 Quaternion grot = GetWorldRotation(); 2032 Quaternion grot = GetWorldRotation();
1686 Quaternion AXgrot = grot; 2033 Quaternion AXgrot = grot;
1687 Vector3 AXimpulsei = impulsei; 2034 Vector3 AXimpulsei = impulsei;
1688 Vector3 newimpulse = AXimpulsei * AXgrot; 2035 Vector3 newimpulse = AXimpulsei * AXgrot;
1689 impulse = newimpulse; 2036 */
2037 torque *= GetWorldRotation();
1690 } 2038 }
1691 2039
1692 ParentGroup.setAngularImpulse(impulse); 2040 Torque = torque;
1693 } 2041 }
1694 2042
1695 /// <summary> 2043 /// <summary>
@@ -1697,7 +2045,9 @@ namespace OpenSim.Region.Framework.Scenes
1697 /// </summary> 2045 /// </summary>
1698 /// <param name="rootObjectFlags"></param> 2046 /// <param name="rootObjectFlags"></param>
1699 /// <param name="VolumeDetectActive"></param> 2047 /// <param name="VolumeDetectActive"></param>
1700 public void ApplyPhysics(uint rootObjectFlags, bool _VolumeDetectActive) 2048 /// <param name="building"></param>
2049
2050 public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building)
1701 { 2051 {
1702 VolumeDetectActive = _VolumeDetectActive; 2052 VolumeDetectActive = _VolumeDetectActive;
1703 2053
@@ -1707,8 +2057,8 @@ namespace OpenSim.Region.Framework.Scenes
1707 if (PhysicsShapeType == (byte)PhysShapeType.none) 2057 if (PhysicsShapeType == (byte)PhysShapeType.none)
1708 return; 2058 return;
1709 2059
1710 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 2060 bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0;
1711 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 2061 bool isPhantom = (_ObjectFlags & (uint)PrimFlags.Phantom) != 0;
1712 2062
1713 if (_VolumeDetectActive) 2063 if (_VolumeDetectActive)
1714 isPhantom = true; 2064 isPhantom = true;
@@ -1722,7 +2072,8 @@ namespace OpenSim.Region.Framework.Scenes
1722 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment 2072 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment
1723 && !(Shape.PathCurve == (byte)Extrusion.Flexible)) 2073 && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1724 { 2074 {
1725 AddToPhysics(isPhysical, isPhantom, isPhysical); 2075 AddToPhysics(isPhysical, isPhantom, building, isPhysical);
2076 UpdatePhysicsSubscribedEvents(); // not sure if appliable here
1726 } 2077 }
1727 else 2078 else
1728 PhysActor = null; // just to be sure 2079 PhysActor = null; // just to be sure
@@ -1777,6 +2128,12 @@ namespace OpenSim.Region.Framework.Scenes
1777 dupe.Category = Category; 2128 dupe.Category = Category;
1778 dupe.m_rezzed = m_rezzed; 2129 dupe.m_rezzed = m_rezzed;
1779 2130
2131 dupe.m_UndoRedo = null;
2132 dupe.m_isSelected = false;
2133
2134 dupe.IgnoreUndoUpdate = false;
2135 dupe.Undoing = false;
2136
1780 dupe.m_inventory = new SceneObjectPartInventory(dupe); 2137 dupe.m_inventory = new SceneObjectPartInventory(dupe);
1781 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone(); 2138 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone();
1782 2139
@@ -1792,6 +2149,7 @@ namespace OpenSim.Region.Framework.Scenes
1792 2149
1793 // Move afterwards ResetIDs as it clears the localID 2150 // Move afterwards ResetIDs as it clears the localID
1794 dupe.LocalId = localID; 2151 dupe.LocalId = localID;
2152
1795 // 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.
1796 dupe.LastOwnerID = OwnerID; 2154 dupe.LastOwnerID = OwnerID;
1797 2155
@@ -1799,6 +2157,8 @@ namespace OpenSim.Region.Framework.Scenes
1799 Array.Copy(Shape.ExtraParams, extraP, extraP.Length); 2157 Array.Copy(Shape.ExtraParams, extraP, extraP.Length);
1800 dupe.Shape.ExtraParams = extraP; 2158 dupe.Shape.ExtraParams = extraP;
1801 2159
2160 // safeguard actual copy is done in sog.copy
2161 dupe.KeyframeMotion = null;
1802 dupe.PayPrice = (int[])PayPrice.Clone(); 2162 dupe.PayPrice = (int[])PayPrice.Clone();
1803 2163
1804 dupe.DynAttrs.CopyFrom(DynAttrs); 2164 dupe.DynAttrs.CopyFrom(DynAttrs);
@@ -1814,8 +2174,12 @@ namespace OpenSim.Region.Framework.Scenes
1814*/ 2174*/
1815 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 2175 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
1816 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 2176 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
2177// dupe.UpdatePhysicsSubscribedEvents(); // not sure...
1817 } 2178 }
1818 2179
2180 if (dupe.PhysActor != null)
2181 dupe.PhysActor.LocalID = localID;
2182
1819 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 2183 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1820 2184
1821// 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);
@@ -1834,10 +2198,10 @@ namespace OpenSim.Region.Framework.Scenes
1834 { 2198 {
1835 if (asset != null) 2199 if (asset != null)
1836 SculptTextureCallback(asset); 2200 SculptTextureCallback(asset);
1837 else 2201// else
1838 m_log.WarnFormat( 2202// m_log.WarnFormat(
1839 "[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",
1840 Name, UUID, id); 2204// Name, UUID, id);
1841 } 2205 }
1842*/ 2206*/
1843 /// <summary> 2207 /// <summary>
@@ -1936,6 +2300,7 @@ namespace OpenSim.Region.Framework.Scenes
1936 2300
1937 /// <summary> 2301 /// <summary>
1938 /// 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
1939 /// </summary> 2304 /// </summary>
1940 /// <param name="UsePhysics"></param> 2305 /// <param name="UsePhysics"></param>
1941 /// <param name="isNew"></param> 2306 /// <param name="isNew"></param>
@@ -1961,61 +2326,69 @@ namespace OpenSim.Region.Framework.Scenes
1961 { 2326 {
1962 if (pa.IsPhysical) // implies UsePhysics==false for this block 2327 if (pa.IsPhysical) // implies UsePhysics==false for this block
1963 { 2328 {
1964 if (!isNew) 2329 if (!isNew) // implies UsePhysics==false for this block
2330 {
1965 ParentGroup.Scene.RemovePhysicalPrim(1); 2331 ParentGroup.Scene.RemovePhysicalPrim(1);
1966 2332
1967 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 2333 Velocity = new Vector3(0, 0, 0);
1968 pa.OnOutOfBounds -= PhysicsOutOfBounds; 2334 Acceleration = new Vector3(0, 0, 0);
1969 pa.delink(); 2335 if (ParentGroup.RootPart == this)
2336 AngularVelocity = new Vector3(0, 0, 0);
1970 2337
1971 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 2338 if (pa.Phantom && !VolumeDetectActive)
1972 { 2339 {
1973 // destroy all joints connected to this now deactivated body 2340 RemoveFromPhysics();
1974 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); 2341 return;
1975 } 2342 }
1976 2343
1977 // stop client-side interpolation of all joint proxy objects that have just been deleted 2344 pa.IsPhysical = UsePhysics;
1978 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback, 2345 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1979 // 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 }
1980 } 2354 }
1981 2355
1982 if (!UsePhysics && !isNew) 2356 if (pa.IsPhysical != UsePhysics)
1983 { 2357 pa.IsPhysical = UsePhysics;
1984 // reset velocity to 0 on physics switch-off. Without that, the client thinks the
1985 // prim still has velocity and continues to interpolate its position along the old
1986 // velocity-vector.
1987 Velocity = new Vector3(0, 0, 0);
1988 Acceleration = new Vector3(0, 0, 0);
1989 AngularVelocity = new Vector3(0, 0, 0);
1990 //RotationalVelocity = new Vector3(0, 0, 0);
1991 }
1992 2358
1993 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);
1994 2365
1995 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 2366 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1996 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 2367 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1997 /// that's not wholesome. Had to make Scene public
1998 //PhysActor = null;
1999 2368
2000 if ((Flags & PrimFlags.Phantom) == 0) 2369 if (ParentID != 0 && ParentID != LocalId)
2001 {
2002 if (UsePhysics)
2003 { 2370 {
2004 ParentGroup.Scene.AddPhysicalPrim(1); 2371 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
2005 2372
2006 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 2373 if (parentPa != null)
2007 pa.OnOutOfBounds += PhysicsOutOfBounds;
2008 if (ParentID != 0 && ParentID != LocalId)
2009 { 2374 {
2010 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; 2375 pa.link(parentPa);
2011
2012 if (parentPa != null)
2013 {
2014 pa.link(parentPa);
2015 }
2016 } 2376 }
2017 } 2377 }
2018 } 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);
2019 } 2392 }
2020 2393
2021 // 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
@@ -2134,42 +2507,63 @@ namespace OpenSim.Region.Framework.Scenes
2134 2507
2135 public Vector3 GetGeometricCenter() 2508 public Vector3 GetGeometricCenter()
2136 { 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 {
2137 PhysicsActor pa = PhysActor; 2522 PhysicsActor pa = PhysActor;
2138 2523
2139 if (pa != null) 2524 if (pa != null)
2140 return pa.GeometricCenter; 2525 return pa.Mass;
2141 else 2526 else
2142 return Vector3.Zero; 2527 return 0;
2143 } 2528 }
2144 2529
2145 public Vector3 GetCenterOfMass() 2530 public Vector3 GetCenterOfMass()
2146 { 2531 {
2532 if (ParentGroup.RootPart == this)
2533 {
2534 if (ParentGroup.IsDeleted)
2535 return AbsolutePosition;
2536 return ParentGroup.GetCenterOfMass();
2537 }
2538
2147 PhysicsActor pa = PhysActor; 2539 PhysicsActor pa = PhysActor;
2148 2540
2149 if (pa != null) 2541 if (pa != null)
2150 return pa.CenterOfMass; 2542 {
2543 Vector3 tmp = pa.CenterOfMass;
2544 return tmp;
2545 }
2151 else 2546 else
2152 return Vector3.Zero; 2547 return AbsolutePosition;
2153 } 2548 }
2154 2549
2155 public float GetMass() 2550 public Vector3 GetPartCenterOfMass()
2156 { 2551 {
2157 PhysicsActor pa = PhysActor; 2552 PhysicsActor pa = PhysActor;
2158 2553
2159 if (pa != null) 2554 if (pa != null)
2160 return pa.Mass; 2555 {
2556 Vector3 tmp = pa.CenterOfMass;
2557 return tmp;
2558 }
2161 else 2559 else
2162 return 0; 2560 return AbsolutePosition;
2163 } 2561 }
2164 2562
2563
2165 public Vector3 GetForce() 2564 public Vector3 GetForce()
2166 { 2565 {
2167 PhysicsActor pa = PhysActor; 2566 return Force;
2168
2169 if (pa != null)
2170 return pa.Force;
2171 else
2172 return Vector3.Zero;
2173 } 2567 }
2174 2568
2175 /// <summary> 2569 /// <summary>
@@ -2384,15 +2778,25 @@ namespace OpenSim.Region.Framework.Scenes
2384 2778
2385 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify) 2779 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify)
2386 { 2780 {
2387 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0) 2781 bool sendToRoot = true;
2388 {
2389 ColliderArgs LandCollidingMessage = new ColliderArgs();
2390 List<DetectedObject> colliding = new List<DetectedObject>();
2391
2392 colliding.Add(CreateDetObjectForGround());
2393 LandCollidingMessage.Colliders = colliding;
2394 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)
2395 notify(LocalId, LandCollidingMessage); 2795 notify(LocalId, LandCollidingMessage);
2796
2797 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0 && sendToRoot)
2798 {
2799 notify(ParentGroup.RootPart.LocalId, LandCollidingMessage);
2396 } 2800 }
2397 } 2801 }
2398 2802
@@ -2408,57 +2812,120 @@ namespace OpenSim.Region.Framework.Scenes
2408 List<uint> endedColliders = new List<uint>(); 2812 List<uint> endedColliders = new List<uint>();
2409 List<uint> startedColliders = new List<uint>(); 2813 List<uint> startedColliders = new List<uint>();
2410 2814
2411 // calculate things that started colliding this time 2815 if (collissionswith.Count == 0)
2412 // and build up list of colliders this time
2413 foreach (uint localid in collissionswith.Keys)
2414 { 2816 {
2415 thisHitColliders.Add(localid); 2817 if (m_lastColliders.Count == 0)
2416 if (!m_lastColliders.Contains(localid)) 2818 return; // nothing to do
2417 startedColliders.Add(localid);
2418 }
2419 2819
2420 // calculate things that ended colliding 2820 foreach (uint localID in m_lastColliders)
2421 foreach (uint localID in m_lastColliders) 2821 {
2422 {
2423 if (!thisHitColliders.Contains(localID))
2424 endedColliders.Add(localID); 2822 endedColliders.Add(localID);
2823 }
2824 m_lastColliders.Clear();
2425 } 2825 }
2426 2826
2427 //add the items that started colliding this time to the last colliders list. 2827 else
2428 foreach (uint localID in startedColliders) 2828 {
2429 m_lastColliders.Add(localID); 2829 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
2430 2830
2431 // remove things that ended colliding from the last colliders list 2831 // calculate things that started colliding this time
2432 foreach (uint localID in endedColliders) 2832 // and build up list of colliders this time
2433 m_lastColliders.Remove(localID); 2833 if (!VolumeDetectActive && CollisionSoundType >= 0)
2834 {
2835 CollisionForSoundInfo soundinfo;
2836 ContactPoint curcontact;
2434 2837
2435 // play the sound. 2838 foreach (uint id in collissionswith.Keys)
2436 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) 2839 {
2437 { 2840 thisHitColliders.Add(id);
2438 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>(); 2841 if (!m_lastColliders.Contains(id))
2439 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)
2440 { 2869 {
2441 soundModule.SendSound(UUID, CollisionSound, 2870 if (!thisHitColliders.Contains(localID))
2442 CollisionSoundVolume, true, 0, 0, false, 2871 endedColliders.Add(localID);
2443 false);
2444 } 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);
2445 } 2885 }
2446 2886
2447 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart); 2887 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
2448 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding); 2888 if (!VolumeDetectActive)
2889 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
2449 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); 2890 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
2450 2891
2451 if (startedColliders.Contains(0)) 2892 if (startedColliders.Contains(0))
2452 { 2893 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2453 if (m_lastColliders.Contains(0)) 2894 if (m_lastColliders.Contains(0))
2454 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding); 2895 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding);
2455 else
2456 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2457 }
2458 if (endedColliders.Contains(0)) 2896 if (endedColliders.Contains(0))
2459 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); 2897 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2460 } 2898 }
2461 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
2462 public void PhysicsOutOfBounds(Vector3 pos) 2929 public void PhysicsOutOfBounds(Vector3 pos)
2463 { 2930 {
2464 // 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.
@@ -2480,9 +2947,9 @@ namespace OpenSim.Region.Framework.Scenes
2480 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2947 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2481 2948
2482 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2949 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2483 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2950 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2484 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2951 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2485 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2952 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2486 { 2953 {
2487 ParentGroup.AbsolutePosition = newpos; 2954 ParentGroup.AbsolutePosition = newpos;
2488 return; 2955 return;
@@ -2767,6 +3234,14 @@ namespace OpenSim.Region.Framework.Scenes
2767 if (ParentGroup == null) 3234 if (ParentGroup == null)
2768 return; 3235 return;
2769 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
2770 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3245 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
2771 { 3246 {
2772 SendFullUpdate(avatar.ControllingClient); 3247 SendFullUpdate(avatar.ControllingClient);
@@ -2825,8 +3300,8 @@ namespace OpenSim.Region.Framework.Scenes
2825 { 3300 {
2826 const float ROTATION_TOLERANCE = 0.01f; 3301 const float ROTATION_TOLERANCE = 0.01f;
2827 const float VELOCITY_TOLERANCE = 0.001f; 3302 const float VELOCITY_TOLERANCE = 0.001f;
2828 const float POSITION_TOLERANCE = 0.05f; 3303 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2829 const int TIME_MS_TOLERANCE = 3000; 3304 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2830 3305
2831 switch (UpdateFlag) 3306 switch (UpdateFlag)
2832 { 3307 {
@@ -2840,17 +3315,10 @@ namespace OpenSim.Region.Framework.Scenes
2840 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || 3315 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) ||
2841 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || 3316 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) ||
2842 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 3317 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
2843 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 3318 Environment.TickCount - m_lastUpdateSentTime > TIME_MS_TOLERANCE)
2844 { 3319 {
2845 SendTerseUpdateToAllClients(); 3320 SendTerseUpdateToAllClients();
2846 3321
2847 // Update the "last" values
2848 m_lastPosition = OffsetPosition;
2849 m_lastRotation = RotationOffset;
2850 m_lastVelocity = Velocity;
2851 m_lastAcceleration = Acceleration;
2852 m_lastAngularVelocity = AngularVelocity;
2853 m_lastTerseSent = Environment.TickCount;
2854 } 3322 }
2855 break; 3323 break;
2856 } 3324 }
@@ -2868,6 +3336,17 @@ namespace OpenSim.Region.Framework.Scenes
2868 /// </summary> 3336 /// </summary>
2869 public void SendTerseUpdateToAllClients() 3337 public void SendTerseUpdateToAllClients()
2870 { 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
2871 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3350 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
2872 { 3351 {
2873 SendTerseUpdateToClient(client); 3352 SendTerseUpdateToClient(client);
@@ -2891,10 +3370,13 @@ namespace OpenSim.Region.Framework.Scenes
2891 3370
2892 public void SetBuoyancy(float fvalue) 3371 public void SetBuoyancy(float fvalue)
2893 { 3372 {
2894 PhysicsActor pa = PhysActor; 3373 Buoyancy = fvalue;
2895 3374/*
2896 if (pa != null) 3375 if (PhysActor != null)
2897 pa.Buoyancy = fvalue; 3376 {
3377 PhysActor.Buoyancy = fvalue;
3378 }
3379 */
2898 } 3380 }
2899 3381
2900 public void SetDieAtEdge(bool p) 3382 public void SetDieAtEdge(bool p)
@@ -2910,47 +3392,111 @@ namespace OpenSim.Region.Framework.Scenes
2910 PhysicsActor pa = PhysActor; 3392 PhysicsActor pa = PhysActor;
2911 3393
2912 if (pa != null) 3394 if (pa != null)
2913 pa.FloatOnWater = floatYN == 1; 3395 pa.FloatOnWater = (floatYN == 1);
2914 } 3396 }
2915 3397
2916 public void SetForce(Vector3 force) 3398 public void SetForce(Vector3 force)
2917 { 3399 {
2918 PhysicsActor pa = PhysActor; 3400 Force = force;
3401 }
2919 3402
2920 if (pa != null) 3403 public SOPVehicle VehicleParams
2921 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 }
2922 } 3429 }
2923 3430
2924 public void SetVehicleType(int type) 3431 public void SetVehicleType(int type)
2925 { 3432 {
2926 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 }
2927 3449
2928 if (pa != null) 3450 public void SetVehicleFlags(int param, bool remove)
2929 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 }
2930 } 3461 }
2931 3462
2932 public void SetVehicleFloatParam(int param, float value) 3463 public void SetVehicleFloatParam(int param, float value)
2933 { 3464 {
2934 PhysicsActor pa = PhysActor; 3465 if (m_vehicleParams == null)
3466 return;
2935 3467
2936 if (pa != null) 3468 m_vehicleParams.ProcessFloatVehicleParam((Vehicle)param, value);
2937 pa.VehicleFloatParam(param, value); 3469
3470 if (_parentID == 0 && PhysActor != null)
3471 {
3472 PhysActor.VehicleFloatParam(param, value);
3473 }
2938 } 3474 }
2939 3475
2940 public void SetVehicleVectorParam(int param, Vector3 value) 3476 public void SetVehicleVectorParam(int param, Vector3 value)
2941 { 3477 {
2942 PhysicsActor pa = PhysActor; 3478 if (m_vehicleParams == null)
3479 return;
2943 3480
2944 if (pa != null) 3481 m_vehicleParams.ProcessVectorVehicleParam((Vehicle)param, value);
2945 pa.VehicleVectorParam(param, value); 3482
3483 if (_parentID == 0 && PhysActor != null)
3484 {
3485 PhysActor.VehicleVectorParam(param, value);
3486 }
2946 } 3487 }
2947 3488
2948 public void SetVehicleRotationParam(int param, Quaternion rotation) 3489 public void SetVehicleRotationParam(int param, Quaternion rotation)
2949 { 3490 {
2950 PhysicsActor pa = PhysActor; 3491 if (m_vehicleParams == null)
3492 return;
2951 3493
2952 if (pa != null) 3494 m_vehicleParams.ProcessRotationVehicleParam((Vehicle)param, rotation);
2953 pa.VehicleRotationParam(param, rotation); 3495
3496 if (_parentID == 0 && PhysActor != null)
3497 {
3498 PhysActor.VehicleRotationParam(param, rotation);
3499 }
2954 } 3500 }
2955 3501
2956 /// <summary> 3502 /// <summary>
@@ -3151,14 +3697,6 @@ namespace OpenSim.Region.Framework.Scenes
3151 hasProfileCut = hasDimple; // is it the same thing? 3697 hasProfileCut = hasDimple; // is it the same thing?
3152 } 3698 }
3153 3699
3154 public void SetVehicleFlags(int param, bool remove)
3155 {
3156 PhysicsActor pa = PhysActor;
3157
3158 if (pa != null)
3159 pa.VehicleFlags(param, remove);
3160 }
3161
3162 public void SetGroup(UUID groupID, IClientAPI client) 3700 public void SetGroup(UUID groupID, IClientAPI client)
3163 { 3701 {
3164 // Scene.AddNewPrims() calls with client == null so can't use this. 3702 // Scene.AddNewPrims() calls with client == null so can't use this.
@@ -3262,71 +3800,20 @@ namespace OpenSim.Region.Framework.Scenes
3262 { 3800 {
3263 ParentGroup.stopMoveToTarget(); 3801 ParentGroup.stopMoveToTarget();
3264 3802
3265 ParentGroup.ScheduleGroupForTerseUpdate(); 3803// ParentGroup.ScheduleGroupForTerseUpdate();
3266 //ParentGroup.ScheduleGroupForFullUpdate(); 3804 //ParentGroup.ScheduleGroupForFullUpdate();
3267 } 3805 }
3268 3806
3269 public void StoreUndoState() 3807 public void StoreUndoState(ObjectChangeType change)
3270 {
3271 StoreUndoState(false);
3272 }
3273
3274 public void StoreUndoState(bool forGroup)
3275 { 3808 {
3276 if (ParentGroup == null || ParentGroup.Scene == null) 3809 if (m_UndoRedo == null)
3277 return; 3810 m_UndoRedo = new UndoRedoState(5);
3278
3279 if (Undoing)
3280 {
3281// m_log.DebugFormat(
3282// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3283 return;
3284 }
3285
3286 if (IgnoreUndoUpdate)
3287 {
3288// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3289 return;
3290 }
3291 3811
3292 lock (m_undo) 3812 lock (m_UndoRedo)
3293 { 3813 {
3294 if (m_undo.Count > 0) 3814 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3295 { 3815 {
3296 UndoState last = m_undo[m_undo.Count - 1]; 3816 m_UndoRedo.StoreUndo(this, change);
3297 if (last != null)
3298 {
3299 // TODO: May need to fix for group comparison
3300 if (last.Compare(this))
3301 {
3302// m_log.DebugFormat(
3303// "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3304// Name, LocalId, m_undo.Count);
3305
3306 return;
3307 }
3308 }
3309 }
3310
3311// m_log.DebugFormat(
3312// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3313// Name, LocalId, forGroup, m_undo.Count);
3314
3315 if (ParentGroup.Scene.MaxUndoCount > 0)
3316 {
3317 UndoState nUndo = new UndoState(this, forGroup);
3318
3319 m_undo.Add(nUndo);
3320
3321 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3322 m_undo.RemoveAt(0);
3323
3324 if (m_redo.Count > 0)
3325 m_redo.Clear();
3326
3327// m_log.DebugFormat(
3328// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3329// Name, LocalId, forGroup, m_undo.Count);
3330 } 3817 }
3331 } 3818 }
3332 } 3819 }
@@ -3338,88 +3825,46 @@ namespace OpenSim.Region.Framework.Scenes
3338 { 3825 {
3339 get 3826 get
3340 { 3827 {
3341 lock (m_undo) 3828 if (m_UndoRedo == null)
3342 return m_undo.Count; 3829 return 0;
3830 return m_UndoRedo.Count;
3343 } 3831 }
3344 } 3832 }
3345 3833
3346 public void Undo() 3834 public void Undo()
3347 { 3835 {
3348 lock (m_undo) 3836 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3349 { 3837 return;
3350// m_log.DebugFormat(
3351// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3352// Name, LocalId, m_undo.Count);
3353
3354 if (m_undo.Count > 0)
3355 {
3356 UndoState goback = m_undo[m_undo.Count - 1];
3357 m_undo.RemoveAt(m_undo.Count - 1);
3358
3359 UndoState nUndo = null;
3360
3361 if (ParentGroup.Scene.MaxUndoCount > 0)
3362 {
3363 nUndo = new UndoState(this, goback.ForGroup);
3364 }
3365
3366 goback.PlaybackState(this);
3367
3368 if (nUndo != null)
3369 {
3370 m_redo.Add(nUndo);
3371
3372 if (m_redo.Count > ParentGroup.Scene.MaxUndoCount)
3373 m_redo.RemoveAt(0);
3374 }
3375 }
3376 3838
3377// m_log.DebugFormat( 3839 lock (m_UndoRedo)
3378// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3840 {
3379// Name, LocalId, m_undo.Count); 3841 Undoing = true;
3842 m_UndoRedo.Undo(this);
3843 Undoing = false;
3380 } 3844 }
3381 } 3845 }
3382 3846
3383 public void Redo() 3847 public void Redo()
3384 { 3848 {
3385 lock (m_undo) 3849 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3386 { 3850 return;
3387// m_log.DebugFormat(
3388// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3389// Name, LocalId, m_redo.Count);
3390
3391 if (m_redo.Count > 0)
3392 {
3393 UndoState gofwd = m_redo[m_redo.Count - 1];
3394 m_redo.RemoveAt(m_redo.Count - 1);
3395
3396 if (ParentGroup.Scene.MaxUndoCount > 0)
3397 {
3398 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3399
3400 m_undo.Add(nUndo);
3401
3402 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3403 m_undo.RemoveAt(0);
3404 }
3405
3406 gofwd.PlayfwdState(this);
3407 3851
3408// m_log.DebugFormat( 3852 lock (m_UndoRedo)
3409// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3853 {
3410// Name, LocalId, m_redo.Count); 3854 Undoing = true;
3411 } 3855 m_UndoRedo.Redo(this);
3856 Undoing = false;
3412 } 3857 }
3413 } 3858 }
3414 3859
3415 public void ClearUndoState() 3860 public void ClearUndoState()
3416 { 3861 {
3417// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3862 if (m_UndoRedo == null || Undoing)
3863 return;
3418 3864
3419 lock (m_undo) 3865 lock (m_UndoRedo)
3420 { 3866 {
3421 m_undo.Clear(); 3867 m_UndoRedo.Clear();
3422 m_redo.Clear();
3423 } 3868 }
3424 } 3869 }
3425 3870
@@ -3971,7 +4416,7 @@ namespace OpenSim.Region.Framework.Scenes
3971 if (god) 4416 if (god)
3972 { 4417 {
3973 BaseMask = ApplyMask(BaseMask, set, mask); 4418 BaseMask = ApplyMask(BaseMask, set, mask);
3974 Inventory.ApplyGodPermissions(_baseMask); 4419 Inventory.ApplyGodPermissions(BaseMask);
3975 } 4420 }
3976 4421
3977 break; 4422 break;
@@ -4002,7 +4447,7 @@ namespace OpenSim.Region.Framework.Scenes
4002 } 4447 }
4003 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & 4448 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) &
4004 baseMask; 4449 baseMask;
4005 // Prevent the client from creating no mod, no copy 4450 // Prevent the client from creating no copy, no transfer
4006 // objects 4451 // objects
4007 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0) 4452 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0)
4008 NextOwnerMask |= (uint)PermissionMask.Transfer; 4453 NextOwnerMask |= (uint)PermissionMask.Transfer;
@@ -4020,20 +4465,20 @@ namespace OpenSim.Region.Framework.Scenes
4020 { 4465 {
4021 bool update = false; 4466 bool update = false;
4022 4467
4023 if (BaseMask != source.BaseMask || 4468 uint prevOwnerMask = OwnerMask;
4024 OwnerMask != source.OwnerMask || 4469 uint prevGroupMask = GroupMask;
4025 GroupMask != source.GroupMask || 4470 uint prevEveryoneMask = EveryoneMask;
4026 EveryoneMask != source.EveryoneMask || 4471 uint prevNextOwnerMask = NextOwnerMask;
4027 NextOwnerMask != source.NextOwnerMask)
4028 update = true;
4029 4472
4030 BaseMask = source.BaseMask; 4473 OwnerMask = source.OwnerMask & BaseMask;
4031 OwnerMask = source.OwnerMask; 4474 GroupMask = source.GroupMask & BaseMask;
4032 GroupMask = source.GroupMask; 4475 EveryoneMask = source.EveryoneMask & BaseMask;
4033 EveryoneMask = source.EveryoneMask; 4476 NextOwnerMask = source.NextOwnerMask & BaseMask;
4034 NextOwnerMask = source.NextOwnerMask;
4035 4477
4036 if (update) 4478 if (OwnerMask != prevOwnerMask ||
4479 GroupMask != prevGroupMask ||
4480 EveryoneMask != prevEveryoneMask ||
4481 NextOwnerMask != prevNextOwnerMask)
4037 SendFullUpdateToAllClients(); 4482 SendFullUpdateToAllClients();
4038 } 4483 }
4039 4484
@@ -4084,6 +4529,7 @@ namespace OpenSim.Region.Framework.Scenes
4084 } 4529 }
4085 } 4530 }
4086 4531
4532
4087 public void UpdateExtraPhysics(ExtraPhysicsData physdata) 4533 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4088 { 4534 {
4089 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null) 4535 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
@@ -4111,7 +4557,7 @@ namespace OpenSim.Region.Framework.Scenes
4111 /// <param name="SetTemporary"></param> 4557 /// <param name="SetTemporary"></param>
4112 /// <param name="SetPhantom"></param> 4558 /// <param name="SetPhantom"></param>
4113 /// <param name="SetVD"></param> 4559 /// <param name="SetVD"></param>
4114 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)
4115 { 4561 {
4116 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4562 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4117 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4563 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4121,116 +4567,98 @@ namespace OpenSim.Region.Framework.Scenes
4121 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4567 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4122 return; 4568 return;
4123 4569
4124 PhysicsActor pa = PhysActor; 4570 VolumeDetectActive = SetVD;
4125
4126 // Special cases for VD. VD can only be called from a script
4127 // and can't be combined with changes to other states. So we can rely
4128 // that...
4129 // ... if VD is changed, all others are not.
4130 // ... if one of the others is changed, VD is not.
4131 if (SetVD) // VD is active, special logic applies
4132 {
4133 // State machine logic for VolumeDetect
4134 // More logic below
4135 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4136
4137 if (phanReset) // Phantom changes from on to off switch VD off too
4138 {
4139 SetVD = false; // Switch it of for the course of this routine
4140 VolumeDetectActive = false; // and also permanently
4141
4142 if (pa != null)
4143 pa.SetVolumeDetect(0); // Let physics know about it too
4144 }
4145 else
4146 {
4147 // If volumedetect is active we don't want phantom to be applied.
4148 // If this is a new call to VD out of the state "phantom"
4149 // this will also cause the prim to be visible to physics
4150 SetPhantom = false;
4151 }
4152 }
4153 4571
4154 if (UsePhysics && IsJoint()) 4572 // volume detector implies phantom
4155 { 4573 if (VolumeDetectActive)
4156 SetPhantom = true; 4574 SetPhantom = true;
4157 }
4158 4575
4159 if (UsePhysics) 4576 if (UsePhysics)
4160 {
4161 AddFlag(PrimFlags.Physics); 4577 AddFlag(PrimFlags.Physics);
4162 if (!wasUsingPhysics)
4163 {
4164 DoPhysicsPropertyUpdate(UsePhysics, false);
4165 }
4166 }
4167 else 4578 else
4168 {
4169 RemFlag(PrimFlags.Physics); 4579 RemFlag(PrimFlags.Physics);
4170 if (wasUsingPhysics)
4171 {
4172 DoPhysicsPropertyUpdate(UsePhysics, false);
4173 }
4174 }
4175 4580
4176 if (SetPhantom 4581 if (SetPhantom)
4177 || ParentGroup.IsAttachment
4178 || PhysicsShapeType == (byte)PhysShapeType.none
4179 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4180 {
4181 AddFlag(PrimFlags.Phantom); 4582 AddFlag(PrimFlags.Phantom);
4583 else
4584 RemFlag(PrimFlags.Phantom);
4182 4585
4183 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)
4184 { 4604 {
4605 if(wasUsingPhysics)
4606 ParentGroup.Scene.RemovePhysicalPrim(1);
4185 RemoveFromPhysics(); 4607 RemoveFromPhysics();
4186 pa = null;
4187 } 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);
4188 } 4614 }
4189 else // Not phantom 4615
4616 else
4190 { 4617 {
4191 RemFlag(PrimFlags.Phantom); 4618 if (ParentGroup.Scene.CollidablePrims)
4192
4193 if (ParentGroup.Scene == null)
4194 return;
4195
4196 if (ParentGroup.Scene.CollidablePrims && pa == null)
4197 { 4619 {
4198 AddToPhysics(UsePhysics, SetPhantom, false); 4620 if (pa == null)
4199 pa = PhysActor;
4200
4201
4202 if (pa != null)
4203 { 4621 {
4204 pa.SetMaterial(Material); 4622 AddToPhysics(UsePhysics, SetPhantom, building, false);
4205 DoPhysicsPropertyUpdate(UsePhysics, true); 4623 pa = PhysActor;
4206 4624/*
4207 if ( 4625 if (pa != null)
4208 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4209 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4210 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4211 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4212 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4213 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4214 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4215 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4216 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4217 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4218 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4219 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4220 (CollisionSound != UUID.Zero)
4221 )
4222 { 4626 {
4223 pa.OnCollisionUpdate += PhysicsCollision; 4627 if (
4224 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 }
4225 } 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;
4226 } 4657 }
4227 }
4228 else // it already has a physical representation
4229 {
4230 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4231 }
4232 }
4233 4658
4659 UpdatePhysicsSubscribedEvents();
4660 }
4661 }
4234 if (SetVD) 4662 if (SetVD)
4235 { 4663 {
4236 // 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!)
@@ -4244,6 +4672,7 @@ namespace OpenSim.Region.Framework.Scenes
4244 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
4245 VolumeDetectActive = true; 4673 VolumeDetectActive = true;
4246 } 4674 }
4675 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4247 } 4676 }
4248 else if (SetVD != wasVD) 4677 else if (SetVD != wasVD)
4249 { 4678 {
@@ -4255,61 +4684,51 @@ namespace OpenSim.Region.Framework.Scenes
4255 RemFlag(PrimFlags.Phantom); 4684 RemFlag(PrimFlags.Phantom);
4256 VolumeDetectActive = false; 4685 VolumeDetectActive = false;
4257 } 4686 }
4258 4687 // and last in case we have a new actor and not building
4259 if (SetTemporary)
4260 {
4261 AddFlag(PrimFlags.TemporaryOnRez);
4262 }
4263 else
4264 {
4265 RemFlag(PrimFlags.TemporaryOnRez);
4266 }
4267
4268 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4269 4688
4270 if (ParentGroup != null) 4689 if (ParentGroup != null)
4271 { 4690 {
4272 ParentGroup.HasGroupChanged = true; 4691 ParentGroup.HasGroupChanged = true;
4273 ScheduleFullUpdate(); 4692 ScheduleFullUpdate();
4274 } 4693 }
4275 4694
4276// 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);
4277 } 4696 }
4278 4697
4279 /// <summary> 4698 /// <summary>
4280 /// Adds this part to the physics scene. 4699 /// Adds this part to the physics scene.
4700 /// and sets the PhysActor property
4281 /// </summary> 4701 /// </summary>
4282 /// <remarks>This method also sets the PhysActor property.</remarks> 4702 /// <param name="isPhysical">Add this prim as physical.</param>
4283 /// <param name="rigidBody">Add this prim with a rigid body.</param> 4703 /// <param name="isPhantom">Add this prim as phantom.</param>
4284 /// <returns> 4704 /// <param name="building">tells physics to delay full construction of object</param>
4285 /// The physics actor. null if there was a failure. 4705 /// <param name="applyDynamics">applies velocities, force and torque</param>
4286 /// </returns> 4706 private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
4287 private void AddToPhysics(bool isPhysical, bool isPhantom, bool applyDynamics) 4707 {
4288 {
4289 PhysicsActor pa; 4708 PhysicsActor pa;
4290 4709
4291 Vector3 velocity = Velocity; 4710 Vector3 velocity = Velocity;
4292 Vector3 rotationalVelocity = AngularVelocity;; 4711 Vector3 rotationalVelocity = AngularVelocity;;
4293 4712
4294 try 4713 try
4295 { 4714 {
4296 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4715 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4297 string.Format("{0}/{1}", Name, UUID), 4716 string.Format("{0}/{1}", Name, UUID),
4298 Shape, 4717 Shape,
4299 AbsolutePosition, 4718 AbsolutePosition,
4300 Scale, 4719 Scale,
4301 GetWorldRotation(), 4720 GetWorldRotation(),
4302 isPhysical, 4721 isPhysical,
4303 isPhantom, 4722 isPhantom,
4304 PhysicsShapeType, 4723 PhysicsShapeType,
4305 m_localId); 4724 m_localId);
4306 } 4725 }
4307 catch (Exception e) 4726 catch (Exception e)
4308 { 4727 {
4309 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);
4310 pa = null; 4729 pa = null;
4311 } 4730 }
4312 4731
4313 if (pa != null) 4732 if (pa != null)
4314 { 4733 {
4315 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
@@ -4322,11 +4741,21 @@ namespace OpenSim.Region.Framework.Scenes
4322 4741
4323 if (VolumeDetectActive) // change if not the default only 4742 if (VolumeDetectActive) // change if not the default only
4324 pa.SetVolumeDetect(1); 4743 pa.SetVolumeDetect(1);
4744
4745 if (m_vehicleParams != null && LocalId == ParentGroup.RootPart.LocalId)
4746 m_vehicleParams.SetVehicle(pa);
4747
4325 // 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
4326 PhysActor = pa; 4749 PhysActor = pa;
4327 4750
4751 // DoPhysicsPropertyUpdate(isPhysical, true);
4752 // lets expand it here just with what it really needs to do
4753
4328 if (isPhysical) 4754 if (isPhysical)
4329 { 4755 {
4756 if (ParentGroup.RootPart.KeyframeMotion != null)
4757 ParentGroup.RootPart.KeyframeMotion.Stop();
4758 ParentGroup.RootPart.KeyframeMotion = null;
4330 ParentGroup.Scene.AddPhysicalPrim(1); 4759 ParentGroup.Scene.AddPhysicalPrim(1);
4331 4760
4332 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 4761 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
@@ -4343,19 +4772,34 @@ namespace OpenSim.Region.Framework.Scenes
4343 } 4772 }
4344 } 4773 }
4345 4774
4346 if (applyDynamics) 4775 if (applyDynamics)
4347 // do independent of isphysical so parameters get setted (at least some) 4776 // do independent of isphysical so parameters get setted (at least some)
4348 { 4777 {
4349 Velocity = velocity; 4778 Velocity = velocity;
4350 AngularVelocity = rotationalVelocity; 4779 AngularVelocity = rotationalVelocity;
4351// pa.Velocity = velocity; 4780// pa.Velocity = velocity;
4352 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 }
4353 } 4790 }
4354 4791
4355 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;
4356 } 4799 }
4357 4800
4358 PhysActor = pa; 4801 PhysActor = pa;
4802
4359 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this); 4803 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this);
4360 } 4804 }
4361 4805
@@ -4364,13 +4808,21 @@ namespace OpenSim.Region.Framework.Scenes
4364 /// </summary> 4808 /// </summary>
4365 /// <remarks> 4809 /// <remarks>
4366 /// 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
4367 /// representation for collision detection. Rather, this would be used in situations such as making a prim 4811 /// representation for collision detection.
4368 /// phantom.
4369 /// </remarks> 4812 /// </remarks>
4370 public void RemoveFromPhysics() 4813 public void RemoveFromPhysics()
4371 { 4814 {
4372 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this); 4815 PhysicsActor pa = PhysActor;
4373 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 }
4374 PhysActor = null; 4826 PhysActor = null;
4375 } 4827 }
4376 4828
@@ -4502,6 +4954,8 @@ namespace OpenSim.Region.Framework.Scenes
4502 { 4954 {
4503// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); 4955// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4504 4956
4957 return;
4958
4505 if (ParentGroup.IsDeleted) 4959 if (ParentGroup.IsDeleted)
4506 return; 4960 return;
4507 4961
@@ -4625,6 +5079,44 @@ namespace OpenSim.Region.Framework.Scenes
4625 } 5079 }
4626 } 5080 }
4627 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
4628 public void aggregateScriptEvents() 5120 public void aggregateScriptEvents()
4629 { 5121 {
4630 if (ParentGroup == null || ParentGroup.RootPart == null) 5122 if (ParentGroup == null || ParentGroup.RootPart == null)
@@ -4661,40 +5153,32 @@ namespace OpenSim.Region.Framework.Scenes
4661 { 5153 {
4662 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; 5154 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop;
4663 } 5155 }
4664 5156/*
4665 PhysicsActor pa = PhysActor; 5157 PhysicsActor pa = PhysActor;
4666 5158 if (pa != null)
4667 if (
4668 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4669 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4670 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4671 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4672 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4673 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4674 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4675 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4676 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4677 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4678 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4679 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4680 (CollisionSound != UUID.Zero)
4681 )
4682 { 5159 {
4683 // subscribe to physics updates. 5160 if (
4684 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 )
4685 { 5169 {
5170 // subscribe to physics updates.
4686 pa.OnCollisionUpdate += PhysicsCollision; 5171 pa.OnCollisionUpdate += PhysicsCollision;
4687 pa.SubscribeEvents(1000); 5172 pa.SubscribeEvents(1000);
4688 } 5173 }
4689 } 5174 else
4690 else
4691 {
4692 if (pa != null)
4693 { 5175 {
4694 pa.UnSubscribeEvents(); 5176 pa.UnSubscribeEvents();
4695 pa.OnCollisionUpdate -= PhysicsCollision; 5177 pa.OnCollisionUpdate -= PhysicsCollision;
4696 } 5178 }
4697 } 5179 }
5180 */
5181 UpdatePhysicsSubscribedEvents();
4698 5182
4699 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 5183 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4700 //{ 5184 //{
@@ -4828,6 +5312,18 @@ namespace OpenSim.Region.Framework.Scenes
4828 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));
4829 } 5313 }
4830 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
4831 /// <summary> 5327 /// <summary>
4832 /// Record an avatar sitting on this part. 5328 /// Record an avatar sitting on this part.
4833 /// </summary> 5329 /// </summary>