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.cs1493
1 files changed, 983 insertions, 510 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 9f602f7..415a82b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -63,7 +63,8 @@ namespace OpenSim.Region.Framework.Scenes
63 TELEPORT = 512, 63 TELEPORT = 512,
64 REGION_RESTART = 1024, 64 REGION_RESTART = 1024,
65 MEDIA = 2048, 65 MEDIA = 2048,
66 ANIMATION = 16384 66 ANIMATION = 16384,
67 POSITION = 32768
67 } 68 }
68 69
69 // I don't really know where to put this except here. 70 // I don't really know where to put this except here.
@@ -122,7 +123,18 @@ namespace OpenSim.Region.Framework.Scenes
122 /// Denote all sides of the prim 123 /// Denote all sides of the prim
123 /// </value> 124 /// </value>
124 public const int ALL_SIDES = -1; 125 public const int ALL_SIDES = -1;
125 126
127 private const scriptEvents PhysicsNeededSubsEvents = (
128 scriptEvents.collision | scriptEvents.collision_start | scriptEvents.collision_end |
129 scriptEvents.land_collision | scriptEvents.land_collision_start | scriptEvents.land_collision_end
130 );
131 private const scriptEvents PhyscicsPhantonSubsEvents = (
132 scriptEvents.land_collision | scriptEvents.land_collision_start | scriptEvents.land_collision_end
133 );
134 private const scriptEvents PhyscicsVolumeDtcSubsEvents = (
135 scriptEvents.collision_start | scriptEvents.collision_end
136 );
137
126 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 138 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
127 139
128 /// <summary> 140 /// <summary>
@@ -138,7 +150,7 @@ namespace OpenSim.Region.Framework.Scenes
138 /// </remarks> 150 /// </remarks>
139 public bool IsRoot 151 public bool IsRoot
140 { 152 {
141 get { return ParentGroup.RootPart == this; } 153 get { return Object.ReferenceEquals(ParentGroup.RootPart, this); }
142 } 154 }
143 155
144 /// <summary> 156 /// <summary>
@@ -197,12 +209,25 @@ namespace OpenSim.Region.Framework.Scenes
197 209
198 public double SoundRadius; 210 public double SoundRadius;
199 211
212
200 public uint TimeStampFull; 213 public uint TimeStampFull;
201 214
202 public uint TimeStampLastActivity; // Will be used for AutoReturn 215 public uint TimeStampLastActivity; // Will be used for AutoReturn
203 216
204 public uint TimeStampTerse; 217 public uint TimeStampTerse;
205 218
219 // The following two are to hold the attachment data
220 // while an object is inworld
221 [XmlIgnore]
222 public byte AttachPoint = 0;
223
224 [XmlIgnore]
225 public Vector3 AttachOffset = Vector3.Zero;
226
227 [XmlIgnore]
228 public Quaternion AttachRotation = Quaternion.Identity;
229
230 [XmlIgnore]
206 public int STATUS_ROTATE_X; 231 public int STATUS_ROTATE_X;
207 232
208 public int STATUS_ROTATE_Y; 233 public int STATUS_ROTATE_Y;
@@ -229,8 +254,7 @@ namespace OpenSim.Region.Framework.Scenes
229 254
230 public Vector3 RotationAxis = Vector3.One; 255 public Vector3 RotationAxis = Vector3.One;
231 256
232 public bool VolumeDetectActive; // XmlIgnore set to avoid problems with persistance until I come to care for this 257 public bool VolumeDetectActive;
233 // Certainly this must be a persistant setting finally
234 258
235 public bool IsWaitingForFirstSpinUpdatePacket; 259 public bool IsWaitingForFirstSpinUpdatePacket;
236 260
@@ -270,10 +294,10 @@ namespace OpenSim.Region.Framework.Scenes
270 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 294 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
271 private Vector3 m_sitTargetPosition; 295 private Vector3 m_sitTargetPosition;
272 private string m_sitAnimation = "SIT"; 296 private string m_sitAnimation = "SIT";
297 private bool m_occupied; // KF if any av is sitting on this prim
273 private string m_text = String.Empty; 298 private string m_text = String.Empty;
274 private string m_touchName = String.Empty; 299 private string m_touchName = String.Empty;
275 private readonly List<UndoState> m_undo = new List<UndoState>(5); 300 private UndoRedoState m_UndoRedo = null;
276 private readonly List<UndoState> m_redo = new List<UndoState>(5);
277 301
278 private bool m_passTouches = false; 302 private bool m_passTouches = false;
279 private bool m_passCollisions = false; 303 private bool m_passCollisions = false;
@@ -301,14 +325,20 @@ namespace OpenSim.Region.Framework.Scenes
301 protected Vector3 m_lastVelocity; 325 protected Vector3 m_lastVelocity;
302 protected Vector3 m_lastAcceleration; 326 protected Vector3 m_lastAcceleration;
303 protected Vector3 m_lastAngularVelocity; 327 protected Vector3 m_lastAngularVelocity;
304 protected int m_lastTerseSent; 328 protected int m_lastUpdateSentTime;
329 protected float m_buoyancy = 0.0f;
330 protected Vector3 m_force;
331 protected Vector3 m_torque;
305 332
306 protected byte m_physicsShapeType = (byte)PhysShapeType.prim; 333 protected byte m_physicsShapeType = (byte)PhysShapeType.prim;
307 protected float m_density = 1000.0f; // in kg/m^3 334 protected float m_density = 1000.0f; // in kg/m^3
308 protected float m_gravitymod = 1.0f; 335 protected float m_gravitymod = 1.0f;
309 protected float m_friction = 0.6f; // wood 336 protected float m_friction = 0.6f; // wood
310 protected float m_bounce = 0.5f; // wood 337 protected float m_bounce = 0.5f; // wood
311 338
339
340 protected bool m_isSelected = false;
341
312 /// <summary> 342 /// <summary>
313 /// Stores media texture data 343 /// Stores media texture data
314 /// </summary> 344 /// </summary>
@@ -320,10 +350,25 @@ namespace OpenSim.Region.Framework.Scenes
320 private Vector3 m_cameraAtOffset; 350 private Vector3 m_cameraAtOffset;
321 private bool m_forceMouselook; 351 private bool m_forceMouselook;
322 352
323 // TODO: Collision sound should have default. 353
354 // 0 for default collision sounds, -1 for script disabled sound 1 for script defined sound
355 private sbyte m_collisionSoundType;
324 private UUID m_collisionSound; 356 private UUID m_collisionSound;
325 private float m_collisionSoundVolume; 357 private float m_collisionSoundVolume;
326 358
359 private int LastColSoundSentTime;
360
361
362 private SOPVehicle m_vehicleParams = null;
363
364 private KeyframeMotion m_keyframeMotion = null;
365
366 public KeyframeMotion KeyframeMotion
367 {
368 get; set;
369 }
370
371
327 #endregion Fields 372 #endregion Fields
328 373
329// ~SceneObjectPart() 374// ~SceneObjectPart()
@@ -353,6 +398,7 @@ namespace OpenSim.Region.Framework.Scenes
353 // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from 398 // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from
354 // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log 399 // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log
355 m_inventory = new SceneObjectPartInventory(this); 400 m_inventory = new SceneObjectPartInventory(this);
401 LastColSoundSentTime = Util.EnvironmentTickCount();
356 } 402 }
357 403
358 /// <summary> 404 /// <summary>
@@ -367,7 +413,7 @@ namespace OpenSim.Region.Framework.Scenes
367 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 413 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
368 Quaternion rotationOffset, Vector3 offsetPosition) : this() 414 Quaternion rotationOffset, Vector3 offsetPosition) : this()
369 { 415 {
370 m_name = "Primitive"; 416 m_name = "Object";
371 417
372 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 418 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
373 LastOwnerID = CreatorID = OwnerID = ownerID; 419 LastOwnerID = CreatorID = OwnerID = ownerID;
@@ -406,7 +452,7 @@ namespace OpenSim.Region.Framework.Scenes
406 private uint _ownerMask = (uint)PermissionMask.All; 452 private uint _ownerMask = (uint)PermissionMask.All;
407 private uint _groupMask = (uint)PermissionMask.None; 453 private uint _groupMask = (uint)PermissionMask.None;
408 private uint _everyoneMask = (uint)PermissionMask.None; 454 private uint _everyoneMask = (uint)PermissionMask.None;
409 private uint _nextOwnerMask = (uint)PermissionMask.All; 455 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
410 private PrimFlags _flags = PrimFlags.None; 456 private PrimFlags _flags = PrimFlags.None;
411 private DateTime m_expires; 457 private DateTime m_expires;
412 private DateTime m_rezzed; 458 private DateTime m_rezzed;
@@ -500,12 +546,16 @@ namespace OpenSim.Region.Framework.Scenes
500 } 546 }
501 547
502 /// <value> 548 /// <value>
503 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 549 /// Get the inventory list
504 /// </value> 550 /// </value>
505 public TaskInventoryDictionary TaskInventory 551 public TaskInventoryDictionary TaskInventory
506 { 552 {
507 get { return m_inventory.Items; } 553 get {
508 set { m_inventory.Items = value; } 554 return m_inventory.Items;
555 }
556 set {
557 m_inventory.Items = value;
558 }
509 } 559 }
510 560
511 /// <summary> 561 /// <summary>
@@ -555,20 +605,6 @@ namespace OpenSim.Region.Framework.Scenes
555 } 605 }
556 } 606 }
557 607
558 public byte Material
559 {
560 get { return (byte) m_material; }
561 set
562 {
563 m_material = (Material)value;
564
565 PhysicsActor pa = PhysActor;
566
567 if (pa != null)
568 pa.SetMaterial((int)value);
569 }
570 }
571
572 [XmlIgnore] 608 [XmlIgnore]
573 public bool PassTouches 609 public bool PassTouches
574 { 610 {
@@ -594,6 +630,18 @@ namespace OpenSim.Region.Framework.Scenes
594 } 630 }
595 } 631 }
596 632
633 public bool IsSelected
634 {
635 get { return m_isSelected; }
636 set
637 {
638 m_isSelected = value;
639 if (ParentGroup != null)
640 ParentGroup.PartSelectChanged(value);
641 }
642 }
643
644
597 public Dictionary<int, string> CollisionFilter 645 public Dictionary<int, string> CollisionFilter
598 { 646 {
599 get { return m_CollisionFilter; } 647 get { return m_CollisionFilter; }
@@ -662,14 +710,12 @@ namespace OpenSim.Region.Framework.Scenes
662 set { m_LoopSoundSlavePrims = value; } 710 set { m_LoopSoundSlavePrims = value; }
663 } 711 }
664 712
665
666 public Byte[] TextureAnimation 713 public Byte[] TextureAnimation
667 { 714 {
668 get { return m_TextureAnimation; } 715 get { return m_TextureAnimation; }
669 set { m_TextureAnimation = value; } 716 set { m_TextureAnimation = value; }
670 } 717 }
671 718
672
673 public Byte[] ParticleSystem 719 public Byte[] ParticleSystem
674 { 720 {
675 get { return m_particleSystem; } 721 get { return m_particleSystem; }
@@ -706,9 +752,12 @@ namespace OpenSim.Region.Framework.Scenes
706 { 752 {
707 // If this is a linkset, we don't want the physics engine mucking up our group position here. 753 // If this is a linkset, we don't want the physics engine mucking up our group position here.
708 PhysicsActor actor = PhysActor; 754 PhysicsActor actor = PhysActor;
709 // If physical and the root prim of a linkset, the position of the group is what physics thinks. 755 if (ParentID == 0)
710 if (actor != null && ParentID == 0) 756 {
711 m_groupPosition = actor.Position; 757 if (actor != null)
758 m_groupPosition = actor.Position;
759 return m_groupPosition;
760 }
712 761
713 // If I'm an attachment, my position is reported as the position of who I'm attached to 762 // If I'm an attachment, my position is reported as the position of who I'm attached to
714 if (ParentGroup.IsAttachment) 763 if (ParentGroup.IsAttachment)
@@ -718,14 +767,16 @@ namespace OpenSim.Region.Framework.Scenes
718 return sp.AbsolutePosition; 767 return sp.AbsolutePosition;
719 } 768 }
720 769
770 // use root prim's group position. Physics may have updated it
771 if (ParentGroup.RootPart != this)
772 m_groupPosition = ParentGroup.RootPart.GroupPosition;
721 return m_groupPosition; 773 return m_groupPosition;
722 } 774 }
723 set 775 set
724 { 776 {
725 m_groupPosition = value; 777 m_groupPosition = value;
726
727 PhysicsActor actor = PhysActor; 778 PhysicsActor actor = PhysActor;
728 if (actor != null) 779 if (actor != null && ParentGroup.Scene.PhysicsScene != null)
729 { 780 {
730 try 781 try
731 { 782 {
@@ -749,16 +800,6 @@ namespace OpenSim.Region.Framework.Scenes
749 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e); 800 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e);
750 } 801 }
751 } 802 }
752
753 // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
754 if (SitTargetAvatar != UUID.Zero)
755 {
756 ScenePresence avatar;
757 if (ParentGroup.Scene.TryGetScenePresence(SitTargetAvatar, out avatar))
758 {
759 avatar.ParentPosition = GetWorldPosition();
760 }
761 }
762 } 803 }
763 } 804 }
764 805
@@ -767,7 +808,7 @@ namespace OpenSim.Region.Framework.Scenes
767 get { return m_offsetPosition; } 808 get { return m_offsetPosition; }
768 set 809 set
769 { 810 {
770// StoreUndoState(); 811 Vector3 oldpos = m_offsetPosition;
771 m_offsetPosition = value; 812 m_offsetPosition = value;
772 813
773 if (ParentGroup != null && !ParentGroup.IsDeleted) 814 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -779,10 +820,25 @@ namespace OpenSim.Region.Framework.Scenes
779 actor.Orientation = GetWorldRotation(); 820 actor.Orientation = GetWorldRotation();
780 821
781 // Tell the physics engines that this prim changed. 822 // Tell the physics engines that this prim changed.
782 if (ParentGroup.Scene != null) 823 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene != null)
783 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 824 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
784 } 825 }
826
827 if (!m_parentGroup.m_dupeInProgress)
828 {
829 List<ScenePresence> avs = ParentGroup.GetLinkedAvatars();
830 foreach (ScenePresence av in avs)
831 {
832 if (av.ParentID == m_localId)
833 {
834 Vector3 offset = (m_offsetPosition - oldpos);
835 av.AbsolutePosition += offset;
836 av.SendAvatarDataToAllAgents();
837 }
838 }
839 }
785 } 840 }
841 TriggerScriptChangedEvent(Changed.POSITION);
786 } 842 }
787 } 843 }
788 844
@@ -833,7 +889,7 @@ namespace OpenSim.Region.Framework.Scenes
833 889
834 set 890 set
835 { 891 {
836 StoreUndoState(); 892// StoreUndoState();
837 m_rotationOffset = value; 893 m_rotationOffset = value;
838 894
839 PhysicsActor actor = PhysActor; 895 PhysicsActor actor = PhysActor;
@@ -921,19 +977,36 @@ namespace OpenSim.Region.Framework.Scenes
921 get 977 get
922 { 978 {
923 PhysicsActor actor = PhysActor; 979 PhysicsActor actor = PhysActor;
924 if ((actor != null) && actor.IsPhysical) 980 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
925 { 981 {
926 m_angularVelocity = actor.RotationalVelocity; 982 m_angularVelocity = actor.RotationalVelocity;
927 } 983 }
928 return m_angularVelocity; 984 return m_angularVelocity;
929 } 985 }
930 set { m_angularVelocity = value; } 986 set
987 {
988 m_angularVelocity = value;
989 PhysicsActor actor = PhysActor;
990 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this && VehicleType == (int)Vehicle.TYPE_NONE)
991 {
992 actor.RotationalVelocity = m_angularVelocity;
993 }
994 }
931 } 995 }
932 996
933 /// <summary></summary> 997 /// <summary></summary>
934 public Vector3 Acceleration 998 public Vector3 Acceleration
935 { 999 {
936 get { return m_acceleration; } 1000 get
1001 {
1002 PhysicsActor actor = PhysActor;
1003 if (actor != null)
1004 {
1005 m_acceleration = actor.Acceleration;
1006 }
1007 return m_acceleration;
1008 }
1009
937 set { m_acceleration = value; } 1010 set { m_acceleration = value; }
938 } 1011 }
939 1012
@@ -1001,7 +1074,10 @@ namespace OpenSim.Region.Framework.Scenes
1001 public PrimitiveBaseShape Shape 1074 public PrimitiveBaseShape Shape
1002 { 1075 {
1003 get { return m_shape; } 1076 get { return m_shape; }
1004 set { m_shape = value;} 1077 set
1078 {
1079 m_shape = value;
1080 }
1005 } 1081 }
1006 1082
1007 /// <summary> 1083 /// <summary>
@@ -1014,7 +1090,6 @@ namespace OpenSim.Region.Framework.Scenes
1014 { 1090 {
1015 if (m_shape != null) 1091 if (m_shape != null)
1016 { 1092 {
1017 StoreUndoState();
1018 1093
1019 m_shape.Scale = value; 1094 m_shape.Scale = value;
1020 1095
@@ -1082,10 +1157,7 @@ namespace OpenSim.Region.Framework.Scenes
1082 { 1157 {
1083 get 1158 get
1084 { 1159 {
1085 if (ParentGroup.IsAttachment) 1160 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
1086 return GroupPosition;
1087
1088 return m_offsetPosition + m_groupPosition;
1089 } 1161 }
1090 } 1162 }
1091 1163
@@ -1263,6 +1335,13 @@ namespace OpenSim.Region.Framework.Scenes
1263 _flags = value; 1335 _flags = value;
1264 } 1336 }
1265 } 1337 }
1338
1339 [XmlIgnore]
1340 public bool IsOccupied // KF If an av is sittingon this prim
1341 {
1342 get { return m_occupied; }
1343 set { m_occupied = value; }
1344 }
1266 1345
1267 /// <summary> 1346 /// <summary>
1268 /// 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 1347 /// 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
@@ -1313,12 +1392,41 @@ namespace OpenSim.Region.Framework.Scenes
1313 set { m_sitAnimation = value; } 1392 set { m_sitAnimation = value; }
1314 } 1393 }
1315 1394
1395 public UUID invalidCollisionSoundUUID = new UUID("ffffffff-ffff-ffff-ffff-ffffffffffff");
1396
1397 // 0 for default collision sounds, -1 for script disabled sound 1 for script defined sound
1398 // runtime thing.. do not persist
1399 [XmlIgnore]
1400 public sbyte CollisionSoundType
1401 {
1402 get
1403 {
1404 return m_collisionSoundType;
1405 }
1406 set
1407 {
1408 m_collisionSoundType = value;
1409 if (value == -1)
1410 m_collisionSound = invalidCollisionSoundUUID;
1411 else if (value == 0)
1412 m_collisionSound = UUID.Zero;
1413 }
1414 }
1415
1316 public UUID CollisionSound 1416 public UUID CollisionSound
1317 { 1417 {
1318 get { return m_collisionSound; } 1418 get { return m_collisionSound; }
1319 set 1419 set
1320 { 1420 {
1321 m_collisionSound = value; 1421 m_collisionSound = value;
1422
1423 if (value == invalidCollisionSoundUUID)
1424 m_collisionSoundType = -1;
1425 else if (value == UUID.Zero)
1426 m_collisionSoundType = 0;
1427 else
1428 m_collisionSoundType = 1;
1429
1322 aggregateScriptEvents(); 1430 aggregateScriptEvents();
1323 } 1431 }
1324 } 1432 }
@@ -1329,6 +1437,125 @@ namespace OpenSim.Region.Framework.Scenes
1329 set { m_collisionSoundVolume = value; } 1437 set { m_collisionSoundVolume = value; }
1330 } 1438 }
1331 1439
1440 public float Buoyancy
1441 {
1442 get
1443 {
1444 if (ParentGroup.RootPart == this)
1445 return m_buoyancy;
1446
1447 return ParentGroup.RootPart.Buoyancy;
1448 }
1449 set
1450 {
1451 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1452 {
1453 ParentGroup.RootPart.Buoyancy = value;
1454 return;
1455 }
1456 m_buoyancy = value;
1457 if (PhysActor != null)
1458 PhysActor.Buoyancy = value;
1459 }
1460 }
1461
1462 public Vector3 Force
1463 {
1464 get
1465 {
1466 if (ParentGroup.RootPart == this)
1467 return m_force;
1468
1469 return ParentGroup.RootPart.Force;
1470 }
1471
1472 set
1473 {
1474 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1475 {
1476 ParentGroup.RootPart.Force = value;
1477 return;
1478 }
1479 m_force = value;
1480 if (PhysActor != null)
1481 PhysActor.Force = value;
1482 }
1483 }
1484
1485 public Vector3 Torque
1486 {
1487 get
1488 {
1489 if (ParentGroup.RootPart == this)
1490 return m_torque;
1491
1492 return ParentGroup.RootPart.Torque;
1493 }
1494
1495 set
1496 {
1497 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1498 {
1499 ParentGroup.RootPart.Torque = value;
1500 return;
1501 }
1502 m_torque = value;
1503 if (PhysActor != null)
1504 PhysActor.Torque = value;
1505 }
1506 }
1507
1508 public byte Material
1509 {
1510 get { return (byte)m_material; }
1511 set
1512 {
1513 if (value >= 0 && value <= (byte)SOPMaterialData.MaxMaterial)
1514 {
1515 bool update = false;
1516
1517 if (m_material != (Material)value)
1518 {
1519 update = true;
1520 m_material = (Material)value;
1521 }
1522
1523 if (m_friction != SOPMaterialData.friction(m_material))
1524 {
1525 update = true;
1526 m_friction = SOPMaterialData.friction(m_material);
1527 }
1528
1529 if (m_bounce != SOPMaterialData.bounce(m_material))
1530 {
1531 update = true;
1532 m_bounce = SOPMaterialData.bounce(m_material);
1533 }
1534
1535 if (update)
1536 {
1537 if (PhysActor != null)
1538 {
1539 PhysActor.SetMaterial((int)value);
1540 }
1541 if(ParentGroup != null)
1542 ParentGroup.HasGroupChanged = true;
1543 ScheduleFullUpdateIfNone();
1544 UpdatePhysRequired = true;
1545 }
1546 }
1547 }
1548 }
1549
1550 // not a propriety to move to methods place later
1551 private bool HasMesh()
1552 {
1553 if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh))
1554 return true;
1555 return false;
1556 }
1557
1558 // not a propriety to move to methods place later
1332 public byte DefaultPhysicsShapeType() 1559 public byte DefaultPhysicsShapeType()
1333 { 1560 {
1334 byte type; 1561 byte type;
@@ -1341,6 +1568,65 @@ namespace OpenSim.Region.Framework.Scenes
1341 return type; 1568 return type;
1342 } 1569 }
1343 1570
1571 [XmlIgnore]
1572 public bool UsesComplexCost
1573 {
1574 get
1575 {
1576 byte pst = PhysicsShapeType;
1577 if(pst == (byte) PhysShapeType.none || pst == (byte) PhysShapeType.convex || HasMesh())
1578 return true;
1579 return false;
1580 }
1581 }
1582
1583 [XmlIgnore]
1584 public float PhysicsCost
1585 {
1586 get
1587 {
1588 if(PhysicsShapeType == (byte)PhysShapeType.none)
1589 return 0;
1590
1591 float cost = 0.1f;
1592 if (PhysActor != null)
1593 cost = PhysActor.PhysicsCost;
1594 else
1595 cost = 0.1f;
1596
1597 if ((Flags & PrimFlags.Physics) != 0)
1598 cost *= (1.0f + 0.01333f * Scale.LengthSquared()); // 0.01333 == 0.04/3
1599 return cost;
1600 }
1601 }
1602
1603 [XmlIgnore]
1604 public float StreamingCost
1605 {
1606 get
1607 {
1608 float cost;
1609 if (PhysActor != null)
1610 cost = PhysActor.StreamCost;
1611 else
1612 cost = 1.0f;
1613 return 1.0f;
1614 }
1615 }
1616
1617 [XmlIgnore]
1618 public float SimulationCost
1619 {
1620 get
1621 {
1622 // ignoring scripts. Don't like considering them for this
1623 if((Flags & PrimFlags.Physics) != 0)
1624 return 1.0f;
1625
1626 return 0.5f;
1627 }
1628 }
1629
1344 public byte PhysicsShapeType 1630 public byte PhysicsShapeType
1345 { 1631 {
1346 get { return m_physicsShapeType; } 1632 get { return m_physicsShapeType; }
@@ -1374,11 +1660,14 @@ namespace OpenSim.Region.Framework.Scenes
1374 } 1660 }
1375 else if (PhysActor == null) 1661 else if (PhysActor == null)
1376 { 1662 {
1377 ApplyPhysics((uint)Flags, VolumeDetectActive); 1663 ApplyPhysics((uint)Flags, VolumeDetectActive, false);
1664 UpdatePhysicsSubscribedEvents();
1378 } 1665 }
1379 else 1666 else
1380 { 1667 {
1381 PhysActor.PhysicsShapeType = m_physicsShapeType; 1668 PhysActor.PhysicsShapeType = m_physicsShapeType;
1669// if (Shape.SculptEntry)
1670// CheckSculptAndLoad();
1382 } 1671 }
1383 1672
1384 if (ParentGroup != null) 1673 if (ParentGroup != null)
@@ -1465,6 +1754,7 @@ namespace OpenSim.Region.Framework.Scenes
1465 } 1754 }
1466 } 1755 }
1467 1756
1757
1468 #endregion Public Properties with only Get 1758 #endregion Public Properties with only Get
1469 1759
1470 private uint ApplyMask(uint val, bool set, uint mask) 1760 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1610,6 +1900,61 @@ namespace OpenSim.Region.Framework.Scenes
1610 } 1900 }
1611 } 1901 }
1612 1902
1903 // SetVelocity for LSL llSetVelocity.. may need revision if having other uses in future
1904 public void SetVelocity(Vector3 pVel, bool localGlobalTF)
1905 {
1906 if (ParentGroup == null || ParentGroup.IsDeleted)
1907 return;
1908
1909 if (ParentGroup.IsAttachment)
1910 return; // don't work on attachments (for now ??)
1911
1912 SceneObjectPart root = ParentGroup.RootPart;
1913
1914 if (root.VehicleType != (int)Vehicle.TYPE_NONE) // don't mess with vehicles
1915 return;
1916
1917 PhysicsActor pa = root.PhysActor;
1918
1919 if (pa == null || !pa.IsPhysical)
1920 return;
1921
1922 if (localGlobalTF)
1923 {
1924 pVel = pVel * GetWorldRotation();
1925 }
1926
1927 ParentGroup.Velocity = pVel;
1928 }
1929
1930 // SetAngularVelocity for LSL llSetAngularVelocity.. may need revision if having other uses in future
1931 public void SetAngularVelocity(Vector3 pAngVel, bool localGlobalTF)
1932 {
1933 if (ParentGroup == null || ParentGroup.IsDeleted)
1934 return;
1935
1936 if (ParentGroup.IsAttachment)
1937 return; // don't work on attachments (for now ??)
1938
1939 SceneObjectPart root = ParentGroup.RootPart;
1940
1941 if (root.VehicleType != (int)Vehicle.TYPE_NONE) // don't mess with vehicles
1942 return;
1943
1944 PhysicsActor pa = root.PhysActor;
1945
1946 if (pa == null || !pa.IsPhysical)
1947 return;
1948
1949 if (localGlobalTF)
1950 {
1951 pAngVel = pAngVel * GetWorldRotation();
1952 }
1953
1954 root.AngularVelocity = pAngVel;
1955 }
1956
1957
1613 /// <summary> 1958 /// <summary>
1614 /// hook to the physics scene to apply angular impulse 1959 /// hook to the physics scene to apply angular impulse
1615 /// This is sent up to the group, which then finds the root prim 1960 /// This is sent up to the group, which then finds the root prim
@@ -1630,7 +1975,7 @@ namespace OpenSim.Region.Framework.Scenes
1630 impulse = newimpulse; 1975 impulse = newimpulse;
1631 } 1976 }
1632 1977
1633 ParentGroup.applyAngularImpulse(impulse); 1978 ParentGroup.ApplyAngularImpulse(impulse);
1634 } 1979 }
1635 1980
1636 /// <summary> 1981 /// <summary>
@@ -1640,20 +1985,24 @@ namespace OpenSim.Region.Framework.Scenes
1640 /// </summary> 1985 /// </summary>
1641 /// <param name="impulsei">Vector force</param> 1986 /// <param name="impulsei">Vector force</param>
1642 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> 1987 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
1643 public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF) 1988
1989 // this is actualy Set Torque.. keeping naming so not to edit lslapi also
1990 public void SetAngularImpulse(Vector3 torquei, bool localGlobalTF)
1644 { 1991 {
1645 Vector3 impulse = impulsei; 1992 Vector3 torque = torquei;
1646 1993
1647 if (localGlobalTF) 1994 if (localGlobalTF)
1648 { 1995 {
1996/*
1649 Quaternion grot = GetWorldRotation(); 1997 Quaternion grot = GetWorldRotation();
1650 Quaternion AXgrot = grot; 1998 Quaternion AXgrot = grot;
1651 Vector3 AXimpulsei = impulsei; 1999 Vector3 AXimpulsei = impulsei;
1652 Vector3 newimpulse = AXimpulsei * AXgrot; 2000 Vector3 newimpulse = AXimpulsei * AXgrot;
1653 impulse = newimpulse; 2001 */
2002 torque *= GetWorldRotation();
1654 } 2003 }
1655 2004
1656 ParentGroup.setAngularImpulse(impulse); 2005 Torque = torque;
1657 } 2006 }
1658 2007
1659 /// <summary> 2008 /// <summary>
@@ -1661,7 +2010,9 @@ namespace OpenSim.Region.Framework.Scenes
1661 /// </summary> 2010 /// </summary>
1662 /// <param name="rootObjectFlags"></param> 2011 /// <param name="rootObjectFlags"></param>
1663 /// <param name="VolumeDetectActive"></param> 2012 /// <param name="VolumeDetectActive"></param>
1664 public void ApplyPhysics(uint rootObjectFlags, bool _VolumeDetectActive) 2013 /// <param name="building"></param>
2014
2015 public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building)
1665 { 2016 {
1666 VolumeDetectActive = _VolumeDetectActive; 2017 VolumeDetectActive = _VolumeDetectActive;
1667 2018
@@ -1671,8 +2022,8 @@ namespace OpenSim.Region.Framework.Scenes
1671 if (PhysicsShapeType == (byte)PhysShapeType.none) 2022 if (PhysicsShapeType == (byte)PhysShapeType.none)
1672 return; 2023 return;
1673 2024
1674 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 2025 bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0;
1675 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 2026 bool isPhantom = (_ObjectFlags & (uint)PrimFlags.Phantom) != 0;
1676 2027
1677 if (_VolumeDetectActive) 2028 if (_VolumeDetectActive)
1678 isPhantom = true; 2029 isPhantom = true;
@@ -1686,7 +2037,8 @@ namespace OpenSim.Region.Framework.Scenes
1686 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment 2037 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment
1687 && !(Shape.PathCurve == (byte)Extrusion.Flexible)) 2038 && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1688 { 2039 {
1689 AddToPhysics(isPhysical, isPhantom, isPhysical); 2040 AddToPhysics(isPhysical, isPhantom, building, isPhysical);
2041 UpdatePhysicsSubscribedEvents(); // not sure if appliable here
1690 } 2042 }
1691 else 2043 else
1692 PhysActor = null; // just to be sure 2044 PhysActor = null; // just to be sure
@@ -1741,6 +2093,12 @@ namespace OpenSim.Region.Framework.Scenes
1741 dupe.Category = Category; 2093 dupe.Category = Category;
1742 dupe.m_rezzed = m_rezzed; 2094 dupe.m_rezzed = m_rezzed;
1743 2095
2096 dupe.m_UndoRedo = null;
2097 dupe.m_isSelected = false;
2098
2099 dupe.IgnoreUndoUpdate = false;
2100 dupe.Undoing = false;
2101
1744 dupe.m_inventory = new SceneObjectPartInventory(dupe); 2102 dupe.m_inventory = new SceneObjectPartInventory(dupe);
1745 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone(); 2103 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone();
1746 2104
@@ -1756,6 +2114,7 @@ namespace OpenSim.Region.Framework.Scenes
1756 2114
1757 // Move afterwards ResetIDs as it clears the localID 2115 // Move afterwards ResetIDs as it clears the localID
1758 dupe.LocalId = localID; 2116 dupe.LocalId = localID;
2117
1759 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 2118 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1760 dupe.LastOwnerID = OwnerID; 2119 dupe.LastOwnerID = OwnerID;
1761 2120
@@ -1763,6 +2122,9 @@ namespace OpenSim.Region.Framework.Scenes
1763 Array.Copy(Shape.ExtraParams, extraP, extraP.Length); 2122 Array.Copy(Shape.ExtraParams, extraP, extraP.Length);
1764 dupe.Shape.ExtraParams = extraP; 2123 dupe.Shape.ExtraParams = extraP;
1765 2124
2125 // safeguard actual copy is done in sog.copy
2126 dupe.KeyframeMotion = null;
2127
1766 dupe.DynAttrs.CopyFrom(DynAttrs); 2128 dupe.DynAttrs.CopyFrom(DynAttrs);
1767 2129
1768 if (userExposed) 2130 if (userExposed)
@@ -1776,8 +2138,12 @@ namespace OpenSim.Region.Framework.Scenes
1776*/ 2138*/
1777 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 2139 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
1778 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 2140 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
2141// dupe.UpdatePhysicsSubscribedEvents(); // not sure...
1779 } 2142 }
1780 2143
2144 if (dupe.PhysActor != null)
2145 dupe.PhysActor.LocalID = localID;
2146
1781 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 2147 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1782 2148
1783// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); 2149// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
@@ -1796,10 +2162,10 @@ namespace OpenSim.Region.Framework.Scenes
1796 { 2162 {
1797 if (asset != null) 2163 if (asset != null)
1798 SculptTextureCallback(asset); 2164 SculptTextureCallback(asset);
1799 else 2165// else
1800 m_log.WarnFormat( 2166// m_log.WarnFormat(
1801 "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data", 2167// "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
1802 Name, UUID, id); 2168// Name, UUID, id);
1803 } 2169 }
1804*/ 2170*/
1805 /// <summary> 2171 /// <summary>
@@ -1898,6 +2264,7 @@ namespace OpenSim.Region.Framework.Scenes
1898 2264
1899 /// <summary> 2265 /// <summary>
1900 /// Do a physics propery update for this part. 2266 /// Do a physics propery update for this part.
2267 /// now also updates phantom and volume detector
1901 /// </summary> 2268 /// </summary>
1902 /// <param name="UsePhysics"></param> 2269 /// <param name="UsePhysics"></param>
1903 /// <param name="isNew"></param> 2270 /// <param name="isNew"></param>
@@ -1923,61 +2290,69 @@ namespace OpenSim.Region.Framework.Scenes
1923 { 2290 {
1924 if (pa.IsPhysical) // implies UsePhysics==false for this block 2291 if (pa.IsPhysical) // implies UsePhysics==false for this block
1925 { 2292 {
1926 if (!isNew) 2293 if (!isNew) // implies UsePhysics==false for this block
2294 {
1927 ParentGroup.Scene.RemovePhysicalPrim(1); 2295 ParentGroup.Scene.RemovePhysicalPrim(1);
1928 2296
1929 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 2297 Velocity = new Vector3(0, 0, 0);
1930 pa.OnOutOfBounds -= PhysicsOutOfBounds; 2298 Acceleration = new Vector3(0, 0, 0);
1931 pa.delink(); 2299 if (ParentGroup.RootPart == this)
2300 AngularVelocity = new Vector3(0, 0, 0);
1932 2301
1933 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 2302 if (pa.Phantom && !VolumeDetectActive)
1934 { 2303 {
1935 // destroy all joints connected to this now deactivated body 2304 RemoveFromPhysics();
1936 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); 2305 return;
1937 } 2306 }
1938 2307
1939 // stop client-side interpolation of all joint proxy objects that have just been deleted 2308 pa.IsPhysical = UsePhysics;
1940 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback, 2309 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1941 // which stops client-side interpolation of deactivated joint proxy objects. 2310 pa.OnOutOfBounds -= PhysicsOutOfBounds;
2311 pa.delink();
2312 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
2313 {
2314 // destroy all joints connected to this now deactivated body
2315 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa);
2316 }
2317 }
1942 } 2318 }
1943 2319
1944 if (!UsePhysics && !isNew) 2320 if (pa.IsPhysical != UsePhysics)
1945 { 2321 pa.IsPhysical = UsePhysics;
1946 // reset velocity to 0 on physics switch-off. Without that, the client thinks the
1947 // prim still has velocity and continues to interpolate its position along the old
1948 // velocity-vector.
1949 Velocity = new Vector3(0, 0, 0);
1950 Acceleration = new Vector3(0, 0, 0);
1951 AngularVelocity = new Vector3(0, 0, 0);
1952 //RotationalVelocity = new Vector3(0, 0, 0);
1953 }
1954 2322
1955 pa.IsPhysical = UsePhysics; 2323 if (UsePhysics)
2324 {
2325 if (ParentGroup.RootPart.KeyframeMotion != null)
2326 ParentGroup.RootPart.KeyframeMotion.Stop();
2327 ParentGroup.RootPart.KeyframeMotion = null;
2328 ParentGroup.Scene.AddPhysicalPrim(1);
1956 2329
1957 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 2330 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1958 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 2331 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1959 /// that's not wholesome. Had to make Scene public
1960 //PhysActor = null;
1961 2332
1962 if ((Flags & PrimFlags.Phantom) == 0) 2333 if (ParentID != 0 && ParentID != LocalId)
1963 {
1964 if (UsePhysics)
1965 { 2334 {
1966 ParentGroup.Scene.AddPhysicalPrim(1); 2335 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
1967 2336
1968 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 2337 if (parentPa != null)
1969 pa.OnOutOfBounds += PhysicsOutOfBounds;
1970 if (ParentID != 0 && ParentID != LocalId)
1971 { 2338 {
1972 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; 2339 pa.link(parentPa);
1973
1974 if (parentPa != null)
1975 {
1976 pa.link(parentPa);
1977 }
1978 } 2340 }
1979 } 2341 }
1980 } 2342 }
2343 }
2344
2345 bool phan = ((Flags & PrimFlags.Phantom) != 0);
2346 if (pa.Phantom != phan)
2347 pa.Phantom = phan;
2348
2349// some engines dont' have this check still
2350// if (VolumeDetectActive != pa.IsVolumeDtc)
2351 {
2352 if (VolumeDetectActive)
2353 pa.SetVolumeDetect(1);
2354 else
2355 pa.SetVolumeDetect(0);
1981 } 2356 }
1982 2357
1983 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 2358 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
@@ -2096,42 +2471,63 @@ namespace OpenSim.Region.Framework.Scenes
2096 2471
2097 public Vector3 GetGeometricCenter() 2472 public Vector3 GetGeometricCenter()
2098 { 2473 {
2474 // this is not real geometric center but a average of positions relative to root prim acording to
2475 // http://wiki.secondlife.com/wiki/llGetGeometricCenter
2476 // ignoring tortured prims details since sl also seems to ignore
2477 // so no real use in doing it on physics
2478 if (ParentGroup.IsDeleted)
2479 return new Vector3(0, 0, 0);
2480
2481 return ParentGroup.GetGeometricCenter();
2482 }
2483
2484 public float GetMass()
2485 {
2099 PhysicsActor pa = PhysActor; 2486 PhysicsActor pa = PhysActor;
2100 2487
2101 if (pa != null) 2488 if (pa != null)
2102 return new Vector3(pa.GeometricCenter.X, pa.GeometricCenter.Y, pa.GeometricCenter.Z); 2489 return pa.Mass;
2103 else 2490 else
2104 return new Vector3(0, 0, 0); 2491 return 0;
2105 } 2492 }
2106 2493
2107 public Vector3 GetCenterOfMass() 2494 public Vector3 GetCenterOfMass()
2108 { 2495 {
2496 if (ParentGroup.RootPart == this)
2497 {
2498 if (ParentGroup.IsDeleted)
2499 return AbsolutePosition;
2500 return ParentGroup.GetCenterOfMass();
2501 }
2502
2109 PhysicsActor pa = PhysActor; 2503 PhysicsActor pa = PhysActor;
2110 2504
2111 if (pa != null) 2505 if (pa != null)
2112 return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z); 2506 {
2507 Vector3 tmp = pa.CenterOfMass;
2508 return tmp;
2509 }
2113 else 2510 else
2114 return new Vector3(0, 0, 0); 2511 return AbsolutePosition;
2115 } 2512 }
2116 2513
2117 public float GetMass() 2514 public Vector3 GetPartCenterOfMass()
2118 { 2515 {
2119 PhysicsActor pa = PhysActor; 2516 PhysicsActor pa = PhysActor;
2120 2517
2121 if (pa != null) 2518 if (pa != null)
2122 return pa.Mass; 2519 {
2520 Vector3 tmp = pa.CenterOfMass;
2521 return tmp;
2522 }
2123 else 2523 else
2124 return 0; 2524 return AbsolutePosition;
2125 } 2525 }
2126 2526
2527
2127 public Vector3 GetForce() 2528 public Vector3 GetForce()
2128 { 2529 {
2129 PhysicsActor pa = PhysActor; 2530 return Force;
2130
2131 if (pa != null)
2132 return pa.Force;
2133 else
2134 return Vector3.Zero;
2135 } 2531 }
2136 2532
2137 /// <summary> 2533 /// <summary>
@@ -2346,15 +2742,25 @@ namespace OpenSim.Region.Framework.Scenes
2346 2742
2347 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify) 2743 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify)
2348 { 2744 {
2349 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0) 2745 bool sendToRoot = true;
2350 {
2351 ColliderArgs LandCollidingMessage = new ColliderArgs();
2352 List<DetectedObject> colliding = new List<DetectedObject>();
2353
2354 colliding.Add(CreateDetObjectForGround());
2355 LandCollidingMessage.Colliders = colliding;
2356 2746
2747 ColliderArgs LandCollidingMessage = new ColliderArgs();
2748 List<DetectedObject> colliding = new List<DetectedObject>();
2749
2750 colliding.Add(CreateDetObjectForGround());
2751 LandCollidingMessage.Colliders = colliding;
2752
2753 if (Inventory.ContainsScripts())
2754 {
2755 if (!PassCollisions)
2756 sendToRoot = false;
2757 }
2758 if ((ScriptEvents & ev) != 0)
2357 notify(LocalId, LandCollidingMessage); 2759 notify(LocalId, LandCollidingMessage);
2760
2761 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0 && sendToRoot)
2762 {
2763 notify(ParentGroup.RootPart.LocalId, LandCollidingMessage);
2358 } 2764 }
2359 } 2765 }
2360 2766
@@ -2370,57 +2776,120 @@ namespace OpenSim.Region.Framework.Scenes
2370 List<uint> endedColliders = new List<uint>(); 2776 List<uint> endedColliders = new List<uint>();
2371 List<uint> startedColliders = new List<uint>(); 2777 List<uint> startedColliders = new List<uint>();
2372 2778
2373 // calculate things that started colliding this time 2779 if (collissionswith.Count == 0)
2374 // and build up list of colliders this time
2375 foreach (uint localid in collissionswith.Keys)
2376 { 2780 {
2377 thisHitColliders.Add(localid); 2781 if (m_lastColliders.Count == 0)
2378 if (!m_lastColliders.Contains(localid)) 2782 return; // nothing to do
2379 startedColliders.Add(localid);
2380 }
2381 2783
2382 // calculate things that ended colliding 2784 foreach (uint localID in m_lastColliders)
2383 foreach (uint localID in m_lastColliders) 2785 {
2384 {
2385 if (!thisHitColliders.Contains(localID))
2386 endedColliders.Add(localID); 2786 endedColliders.Add(localID);
2787 }
2788 m_lastColliders.Clear();
2387 } 2789 }
2388 2790
2389 //add the items that started colliding this time to the last colliders list. 2791 else
2390 foreach (uint localID in startedColliders) 2792 {
2391 m_lastColliders.Add(localID); 2793 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
2794
2795 // calculate things that started colliding this time
2796 // and build up list of colliders this time
2797 if (!VolumeDetectActive && CollisionSoundType >= 0)
2798 {
2799 CollisionForSoundInfo soundinfo;
2800 ContactPoint curcontact;
2392 2801
2393 // remove things that ended colliding from the last colliders list 2802 foreach (uint id in collissionswith.Keys)
2394 foreach (uint localID in endedColliders) 2803 {
2395 m_lastColliders.Remove(localID); 2804 thisHitColliders.Add(id);
2805 if (!m_lastColliders.Contains(id))
2806 {
2807 startedColliders.Add(id);
2396 2808
2397 // play the sound. 2809 curcontact = collissionswith[id];
2398 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) 2810 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
2399 { 2811 {
2400 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>(); 2812 soundinfo = new CollisionForSoundInfo();
2401 if (soundModule != null) 2813 soundinfo.colliderID = id;
2814 soundinfo.position = curcontact.Position;
2815 soundinfo.relativeVel = curcontact.RelativeSpeed;
2816 soundinfolist.Add(soundinfo);
2817 }
2818 }
2819 }
2820 }
2821 else
2822 {
2823 foreach (uint id in collissionswith.Keys)
2824 {
2825 thisHitColliders.Add(id);
2826 if (!m_lastColliders.Contains(id))
2827 startedColliders.Add(id);
2828 }
2829 }
2830
2831 // calculate things that ended colliding
2832 foreach (uint localID in m_lastColliders)
2402 { 2833 {
2403 soundModule.SendSound(UUID, CollisionSound, 2834 if (!thisHitColliders.Contains(localID))
2404 CollisionSoundVolume, true, (byte)0, 0, false, 2835 endedColliders.Add(localID);
2405 false);
2406 } 2836 }
2837
2838 //add the items that started colliding this time to the last colliders list.
2839 foreach (uint localID in startedColliders)
2840 m_lastColliders.Add(localID);
2841
2842 // remove things that ended colliding from the last colliders list
2843 foreach (uint localID in endedColliders)
2844 m_lastColliders.Remove(localID);
2845
2846 // play sounds.
2847 if (soundinfolist.Count > 0)
2848 CollisionSounds.PartCollisionSound(this, soundinfolist);
2407 } 2849 }
2408 2850
2409 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart); 2851 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
2410 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding); 2852 if (!VolumeDetectActive)
2853 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
2411 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); 2854 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
2412 2855
2413 if (startedColliders.Contains(0)) 2856 if (startedColliders.Contains(0))
2414 { 2857 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2415 if (m_lastColliders.Contains(0)) 2858 if (m_lastColliders.Contains(0))
2416 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding); 2859 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding);
2417 else
2418 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2419 }
2420 if (endedColliders.Contains(0)) 2860 if (endedColliders.Contains(0))
2421 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); 2861 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2422 } 2862 }
2423 2863
2864 // The Collision sounds code calls this
2865 public void SendCollisionSound(UUID soundID, double volume, Vector3 position)
2866 {
2867 if (soundID == UUID.Zero)
2868 return;
2869
2870 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>();
2871 if (soundModule == null)
2872 return;
2873
2874 if (volume > 1)
2875 volume = 1;
2876 if (volume < 0)
2877 volume = 0;
2878
2879 int now = Util.EnvironmentTickCount();
2880 if(Util.EnvironmentTickCountSubtract(now,LastColSoundSentTime) <200)
2881 return;
2882
2883 LastColSoundSentTime = now;
2884
2885 UUID ownerID = OwnerID;
2886 UUID objectID = ParentGroup.RootPart.UUID;
2887 UUID parentID = ParentGroup.UUID;
2888 ulong regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle;
2889
2890 soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, 0 );
2891 }
2892
2424 public void PhysicsOutOfBounds(Vector3 pos) 2893 public void PhysicsOutOfBounds(Vector3 pos)
2425 { 2894 {
2426 // Note: This is only being called on the root prim at this time. 2895 // Note: This is only being called on the root prim at this time.
@@ -2442,9 +2911,9 @@ namespace OpenSim.Region.Framework.Scenes
2442 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2911 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2443 2912
2444 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2913 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2445 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2914 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2446 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2915 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2447 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2916 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2448 { 2917 {
2449 ParentGroup.AbsolutePosition = newpos; 2918 ParentGroup.AbsolutePosition = newpos;
2450 return; 2919 return;
@@ -2729,6 +3198,14 @@ namespace OpenSim.Region.Framework.Scenes
2729 if (ParentGroup == null) 3198 if (ParentGroup == null)
2730 return; 3199 return;
2731 3200
3201 // Update the "last" values
3202 m_lastPosition = OffsetPosition;
3203 m_lastRotation = RotationOffset;
3204 m_lastVelocity = Velocity;
3205 m_lastAcceleration = Acceleration;
3206 m_lastAngularVelocity = AngularVelocity;
3207 m_lastUpdateSentTime = Environment.TickCount;
3208
2732 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3209 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
2733 { 3210 {
2734 SendFullUpdate(avatar.ControllingClient); 3211 SendFullUpdate(avatar.ControllingClient);
@@ -2787,8 +3264,8 @@ namespace OpenSim.Region.Framework.Scenes
2787 { 3264 {
2788 const float ROTATION_TOLERANCE = 0.01f; 3265 const float ROTATION_TOLERANCE = 0.01f;
2789 const float VELOCITY_TOLERANCE = 0.001f; 3266 const float VELOCITY_TOLERANCE = 0.001f;
2790 const float POSITION_TOLERANCE = 0.05f; 3267 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2791 const int TIME_MS_TOLERANCE = 3000; 3268 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2792 3269
2793 switch (UpdateFlag) 3270 switch (UpdateFlag)
2794 { 3271 {
@@ -2802,17 +3279,10 @@ namespace OpenSim.Region.Framework.Scenes
2802 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || 3279 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) ||
2803 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || 3280 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) ||
2804 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 3281 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
2805 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 3282 Environment.TickCount - m_lastUpdateSentTime > TIME_MS_TOLERANCE)
2806 { 3283 {
2807 SendTerseUpdateToAllClients(); 3284 SendTerseUpdateToAllClients();
2808 3285
2809 // Update the "last" values
2810 m_lastPosition = OffsetPosition;
2811 m_lastRotation = RotationOffset;
2812 m_lastVelocity = Velocity;
2813 m_lastAcceleration = Acceleration;
2814 m_lastAngularVelocity = AngularVelocity;
2815 m_lastTerseSent = Environment.TickCount;
2816 } 3286 }
2817 break; 3287 break;
2818 } 3288 }
@@ -2830,6 +3300,17 @@ namespace OpenSim.Region.Framework.Scenes
2830 /// </summary> 3300 /// </summary>
2831 public void SendTerseUpdateToAllClients() 3301 public void SendTerseUpdateToAllClients()
2832 { 3302 {
3303 if (ParentGroup == null || ParentGroup.Scene == null)
3304 return;
3305
3306 // Update the "last" values
3307 m_lastPosition = OffsetPosition;
3308 m_lastRotation = RotationOffset;
3309 m_lastVelocity = Velocity;
3310 m_lastAcceleration = Acceleration;
3311 m_lastAngularVelocity = AngularVelocity;
3312 m_lastUpdateSentTime = Environment.TickCount;
3313
2833 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3314 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
2834 { 3315 {
2835 SendTerseUpdateToClient(client); 3316 SendTerseUpdateToClient(client);
@@ -2853,10 +3334,13 @@ namespace OpenSim.Region.Framework.Scenes
2853 3334
2854 public void SetBuoyancy(float fvalue) 3335 public void SetBuoyancy(float fvalue)
2855 { 3336 {
2856 PhysicsActor pa = PhysActor; 3337 Buoyancy = fvalue;
2857 3338/*
2858 if (pa != null) 3339 if (PhysActor != null)
2859 pa.Buoyancy = fvalue; 3340 {
3341 PhysActor.Buoyancy = fvalue;
3342 }
3343 */
2860 } 3344 }
2861 3345
2862 public void SetDieAtEdge(bool p) 3346 public void SetDieAtEdge(bool p)
@@ -2872,47 +3356,111 @@ namespace OpenSim.Region.Framework.Scenes
2872 PhysicsActor pa = PhysActor; 3356 PhysicsActor pa = PhysActor;
2873 3357
2874 if (pa != null) 3358 if (pa != null)
2875 pa.FloatOnWater = floatYN == 1; 3359 pa.FloatOnWater = (floatYN == 1);
2876 } 3360 }
2877 3361
2878 public void SetForce(Vector3 force) 3362 public void SetForce(Vector3 force)
2879 { 3363 {
2880 PhysicsActor pa = PhysActor; 3364 Force = force;
3365 }
2881 3366
2882 if (pa != null) 3367 public SOPVehicle VehicleParams
2883 pa.Force = force; 3368 {
3369 get
3370 {
3371 return m_vehicleParams;
3372 }
3373 set
3374 {
3375 m_vehicleParams = value;
3376 }
3377 }
3378
3379
3380 public int VehicleType
3381 {
3382 get
3383 {
3384 if (m_vehicleParams == null)
3385 return (int)Vehicle.TYPE_NONE;
3386 else
3387 return (int)m_vehicleParams.Type;
3388 }
3389 set
3390 {
3391 SetVehicleType(value);
3392 }
2884 } 3393 }
2885 3394
2886 public void SetVehicleType(int type) 3395 public void SetVehicleType(int type)
2887 { 3396 {
2888 PhysicsActor pa = PhysActor; 3397 m_vehicleParams = null;
3398
3399 if (type == (int)Vehicle.TYPE_NONE)
3400 {
3401 if (_parentID ==0 && PhysActor != null)
3402 PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
3403 return;
3404 }
3405 m_vehicleParams = new SOPVehicle();
3406 m_vehicleParams.ProcessTypeChange((Vehicle)type);
3407 {
3408 if (_parentID ==0 && PhysActor != null)
3409 PhysActor.VehicleType = type;
3410 return;
3411 }
3412 }
2889 3413
2890 if (pa != null) 3414 public void SetVehicleFlags(int param, bool remove)
2891 pa.VehicleType = type; 3415 {
3416 if (m_vehicleParams == null)
3417 return;
3418
3419 m_vehicleParams.ProcessVehicleFlags(param, remove);
3420
3421 if (_parentID ==0 && PhysActor != null)
3422 {
3423 PhysActor.VehicleFlags(param, remove);
3424 }
2892 } 3425 }
2893 3426
2894 public void SetVehicleFloatParam(int param, float value) 3427 public void SetVehicleFloatParam(int param, float value)
2895 { 3428 {
2896 PhysicsActor pa = PhysActor; 3429 if (m_vehicleParams == null)
3430 return;
2897 3431
2898 if (pa != null) 3432 m_vehicleParams.ProcessFloatVehicleParam((Vehicle)param, value);
2899 pa.VehicleFloatParam(param, value); 3433
3434 if (_parentID == 0 && PhysActor != null)
3435 {
3436 PhysActor.VehicleFloatParam(param, value);
3437 }
2900 } 3438 }
2901 3439
2902 public void SetVehicleVectorParam(int param, Vector3 value) 3440 public void SetVehicleVectorParam(int param, Vector3 value)
2903 { 3441 {
2904 PhysicsActor pa = PhysActor; 3442 if (m_vehicleParams == null)
3443 return;
2905 3444
2906 if (pa != null) 3445 m_vehicleParams.ProcessVectorVehicleParam((Vehicle)param, value);
2907 pa.VehicleVectorParam(param, value); 3446
3447 if (_parentID == 0 && PhysActor != null)
3448 {
3449 PhysActor.VehicleVectorParam(param, value);
3450 }
2908 } 3451 }
2909 3452
2910 public void SetVehicleRotationParam(int param, Quaternion rotation) 3453 public void SetVehicleRotationParam(int param, Quaternion rotation)
2911 { 3454 {
2912 PhysicsActor pa = PhysActor; 3455 if (m_vehicleParams == null)
3456 return;
2913 3457
2914 if (pa != null) 3458 m_vehicleParams.ProcessRotationVehicleParam((Vehicle)param, rotation);
2915 pa.VehicleRotationParam(param, rotation); 3459
3460 if (_parentID == 0 && PhysActor != null)
3461 {
3462 PhysActor.VehicleRotationParam(param, rotation);
3463 }
2916 } 3464 }
2917 3465
2918 /// <summary> 3466 /// <summary>
@@ -3113,14 +3661,6 @@ namespace OpenSim.Region.Framework.Scenes
3113 hasProfileCut = hasDimple; // is it the same thing? 3661 hasProfileCut = hasDimple; // is it the same thing?
3114 } 3662 }
3115 3663
3116 public void SetVehicleFlags(int param, bool remove)
3117 {
3118 PhysicsActor pa = PhysActor;
3119
3120 if (pa != null)
3121 pa.VehicleFlags(param, remove);
3122 }
3123
3124 public void SetGroup(UUID groupID, IClientAPI client) 3664 public void SetGroup(UUID groupID, IClientAPI client)
3125 { 3665 {
3126 // Scene.AddNewPrims() calls with client == null so can't use this. 3666 // Scene.AddNewPrims() calls with client == null so can't use this.
@@ -3220,71 +3760,20 @@ namespace OpenSim.Region.Framework.Scenes
3220 { 3760 {
3221 ParentGroup.stopMoveToTarget(); 3761 ParentGroup.stopMoveToTarget();
3222 3762
3223 ParentGroup.ScheduleGroupForTerseUpdate(); 3763// ParentGroup.ScheduleGroupForTerseUpdate();
3224 //ParentGroup.ScheduleGroupForFullUpdate(); 3764 //ParentGroup.ScheduleGroupForFullUpdate();
3225 } 3765 }
3226 3766
3227 public void StoreUndoState() 3767 public void StoreUndoState(ObjectChangeType change)
3228 { 3768 {
3229 StoreUndoState(false); 3769 if (m_UndoRedo == null)
3230 } 3770 m_UndoRedo = new UndoRedoState(5);
3231
3232 public void StoreUndoState(bool forGroup)
3233 {
3234 if (ParentGroup == null || ParentGroup.Scene == null)
3235 return;
3236
3237 if (Undoing)
3238 {
3239// m_log.DebugFormat(
3240// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3241 return;
3242 }
3243
3244 if (IgnoreUndoUpdate)
3245 {
3246// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3247 return;
3248 }
3249 3771
3250 lock (m_undo) 3772 lock (m_UndoRedo)
3251 { 3773 {
3252 if (m_undo.Count > 0) 3774 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3253 { 3775 {
3254 UndoState last = m_undo[m_undo.Count - 1]; 3776 m_UndoRedo.StoreUndo(this, change);
3255 if (last != null)
3256 {
3257 // TODO: May need to fix for group comparison
3258 if (last.Compare(this))
3259 {
3260// m_log.DebugFormat(
3261// "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3262// Name, LocalId, m_undo.Count);
3263
3264 return;
3265 }
3266 }
3267 }
3268
3269// m_log.DebugFormat(
3270// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3271// Name, LocalId, forGroup, m_undo.Count);
3272
3273 if (ParentGroup.Scene.MaxUndoCount > 0)
3274 {
3275 UndoState nUndo = new UndoState(this, forGroup);
3276
3277 m_undo.Add(nUndo);
3278
3279 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3280 m_undo.RemoveAt(0);
3281
3282 if (m_redo.Count > 0)
3283 m_redo.Clear();
3284
3285// m_log.DebugFormat(
3286// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3287// Name, LocalId, forGroup, m_undo.Count);
3288 } 3777 }
3289 } 3778 }
3290 } 3779 }
@@ -3296,88 +3785,46 @@ namespace OpenSim.Region.Framework.Scenes
3296 { 3785 {
3297 get 3786 get
3298 { 3787 {
3299 lock (m_undo) 3788 if (m_UndoRedo == null)
3300 return m_undo.Count; 3789 return 0;
3790 return m_UndoRedo.Count;
3301 } 3791 }
3302 } 3792 }
3303 3793
3304 public void Undo() 3794 public void Undo()
3305 { 3795 {
3306 lock (m_undo) 3796 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3307 { 3797 return;
3308// m_log.DebugFormat(
3309// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3310// Name, LocalId, m_undo.Count);
3311
3312 if (m_undo.Count > 0)
3313 {
3314 UndoState goback = m_undo[m_undo.Count - 1];
3315 m_undo.RemoveAt(m_undo.Count - 1);
3316
3317 UndoState nUndo = null;
3318
3319 if (ParentGroup.Scene.MaxUndoCount > 0)
3320 {
3321 nUndo = new UndoState(this, goback.ForGroup);
3322 }
3323
3324 goback.PlaybackState(this);
3325
3326 if (nUndo != null)
3327 {
3328 m_redo.Add(nUndo);
3329
3330 if (m_redo.Count > ParentGroup.Scene.MaxUndoCount)
3331 m_redo.RemoveAt(0);
3332 }
3333 }
3334 3798
3335// m_log.DebugFormat( 3799 lock (m_UndoRedo)
3336// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3800 {
3337// Name, LocalId, m_undo.Count); 3801 Undoing = true;
3802 m_UndoRedo.Undo(this);
3803 Undoing = false;
3338 } 3804 }
3339 } 3805 }
3340 3806
3341 public void Redo() 3807 public void Redo()
3342 { 3808 {
3343 lock (m_undo) 3809 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3344 { 3810 return;
3345// m_log.DebugFormat(
3346// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3347// Name, LocalId, m_redo.Count);
3348
3349 if (m_redo.Count > 0)
3350 {
3351 UndoState gofwd = m_redo[m_redo.Count - 1];
3352 m_redo.RemoveAt(m_redo.Count - 1);
3353
3354 if (ParentGroup.Scene.MaxUndoCount > 0)
3355 {
3356 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3357
3358 m_undo.Add(nUndo);
3359
3360 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3361 m_undo.RemoveAt(0);
3362 }
3363
3364 gofwd.PlayfwdState(this);
3365 3811
3366// m_log.DebugFormat( 3812 lock (m_UndoRedo)
3367// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3813 {
3368// Name, LocalId, m_redo.Count); 3814 Undoing = true;
3369 } 3815 m_UndoRedo.Redo(this);
3816 Undoing = false;
3370 } 3817 }
3371 } 3818 }
3372 3819
3373 public void ClearUndoState() 3820 public void ClearUndoState()
3374 { 3821 {
3375// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3822 if (m_UndoRedo == null || Undoing)
3823 return;
3376 3824
3377 lock (m_undo) 3825 lock (m_UndoRedo)
3378 { 3826 {
3379 m_undo.Clear(); 3827 m_UndoRedo.Clear();
3380 m_redo.Clear();
3381 } 3828 }
3382 } 3829 }
3383 3830
@@ -3928,7 +4375,7 @@ namespace OpenSim.Region.Framework.Scenes
3928 if (god) 4375 if (god)
3929 { 4376 {
3930 BaseMask = ApplyMask(BaseMask, set, mask); 4377 BaseMask = ApplyMask(BaseMask, set, mask);
3931 Inventory.ApplyGodPermissions(_baseMask); 4378 Inventory.ApplyGodPermissions(BaseMask);
3932 } 4379 }
3933 4380
3934 break; 4381 break;
@@ -3947,7 +4394,7 @@ namespace OpenSim.Region.Framework.Scenes
3947 case 16: 4394 case 16:
3948 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & 4395 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) &
3949 baseMask; 4396 baseMask;
3950 // Prevent the client from creating no mod, no copy 4397 // Prevent the client from creating no copy, no transfer
3951 // objects 4398 // objects
3952 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0) 4399 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0)
3953 NextOwnerMask |= (uint)PermissionMask.Transfer; 4400 NextOwnerMask |= (uint)PermissionMask.Transfer;
@@ -3965,20 +4412,20 @@ namespace OpenSim.Region.Framework.Scenes
3965 { 4412 {
3966 bool update = false; 4413 bool update = false;
3967 4414
3968 if (BaseMask != source.BaseMask || 4415 uint prevOwnerMask = OwnerMask;
3969 OwnerMask != source.OwnerMask || 4416 uint prevGroupMask = GroupMask;
3970 GroupMask != source.GroupMask || 4417 uint prevEveryoneMask = EveryoneMask;
3971 EveryoneMask != source.EveryoneMask || 4418 uint prevNextOwnerMask = NextOwnerMask;
3972 NextOwnerMask != source.NextOwnerMask)
3973 update = true;
3974 4419
3975 BaseMask = source.BaseMask; 4420 OwnerMask = source.OwnerMask & BaseMask;
3976 OwnerMask = source.OwnerMask; 4421 GroupMask = source.GroupMask & BaseMask;
3977 GroupMask = source.GroupMask; 4422 EveryoneMask = source.EveryoneMask & BaseMask;
3978 EveryoneMask = source.EveryoneMask; 4423 NextOwnerMask = source.NextOwnerMask & BaseMask;
3979 NextOwnerMask = source.NextOwnerMask;
3980 4424
3981 if (update) 4425 if (OwnerMask != prevOwnerMask ||
4426 GroupMask != prevGroupMask ||
4427 EveryoneMask != prevEveryoneMask ||
4428 NextOwnerMask != prevNextOwnerMask)
3982 SendFullUpdateToAllClients(); 4429 SendFullUpdateToAllClients();
3983 } 4430 }
3984 4431
@@ -4029,6 +4476,7 @@ namespace OpenSim.Region.Framework.Scenes
4029 } 4476 }
4030 } 4477 }
4031 4478
4479
4032 public void UpdateExtraPhysics(ExtraPhysicsData physdata) 4480 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4033 { 4481 {
4034 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null) 4482 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
@@ -4056,7 +4504,7 @@ namespace OpenSim.Region.Framework.Scenes
4056 /// <param name="SetTemporary"></param> 4504 /// <param name="SetTemporary"></param>
4057 /// <param name="SetPhantom"></param> 4505 /// <param name="SetPhantom"></param>
4058 /// <param name="SetVD"></param> 4506 /// <param name="SetVD"></param>
4059 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) 4507 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
4060 { 4508 {
4061 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4509 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4062 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4510 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4066,195 +4514,145 @@ namespace OpenSim.Region.Framework.Scenes
4066 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4514 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4067 return; 4515 return;
4068 4516
4069 PhysicsActor pa = PhysActor; 4517 VolumeDetectActive = SetVD;
4070
4071 // Special cases for VD. VD can only be called from a script
4072 // and can't be combined with changes to other states. So we can rely
4073 // that...
4074 // ... if VD is changed, all others are not.
4075 // ... if one of the others is changed, VD is not.
4076 if (SetVD) // VD is active, special logic applies
4077 {
4078 // State machine logic for VolumeDetect
4079 // More logic below
4080 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4081
4082 if (phanReset) // Phantom changes from on to off switch VD off too
4083 {
4084 SetVD = false; // Switch it of for the course of this routine
4085 VolumeDetectActive = false; // and also permanently
4086
4087 if (pa != null)
4088 pa.SetVolumeDetect(0); // Let physics know about it too
4089 }
4090 else
4091 {
4092 // If volumedetect is active we don't want phantom to be applied.
4093 // If this is a new call to VD out of the state "phantom"
4094 // this will also cause the prim to be visible to physics
4095 SetPhantom = false;
4096 }
4097 }
4098 4518
4099 if (UsePhysics && IsJoint()) 4519 // volume detector implies phantom
4100 { 4520 if (VolumeDetectActive)
4101 SetPhantom = true; 4521 SetPhantom = true;
4102 }
4103 4522
4104 if (UsePhysics) 4523 if (UsePhysics)
4105 {
4106 AddFlag(PrimFlags.Physics); 4524 AddFlag(PrimFlags.Physics);
4107 if (!wasUsingPhysics)
4108 {
4109 DoPhysicsPropertyUpdate(UsePhysics, false);
4110 }
4111 }
4112 else 4525 else
4113 {
4114 RemFlag(PrimFlags.Physics); 4526 RemFlag(PrimFlags.Physics);
4115 if (wasUsingPhysics)
4116 {
4117 DoPhysicsPropertyUpdate(UsePhysics, false);
4118 }
4119 }
4120 4527
4121 if (SetPhantom 4528 if (SetPhantom)
4122 || ParentGroup.IsAttachment
4123 || PhysicsShapeType == (byte)PhysShapeType.none
4124 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4125 {
4126 AddFlag(PrimFlags.Phantom); 4529 AddFlag(PrimFlags.Phantom);
4127 4530 else
4128 if (PhysActor != null)
4129 {
4130 RemoveFromPhysics();
4131 pa = null;
4132 }
4133 }
4134 else // Not phantom
4135 {
4136 RemFlag(PrimFlags.Phantom); 4531 RemFlag(PrimFlags.Phantom);
4137 4532
4138 if (ParentGroup.Scene == null) 4533 if (SetTemporary)
4139 return; 4534 AddFlag(PrimFlags.TemporaryOnRez);
4535 else
4536 RemFlag(PrimFlags.TemporaryOnRez);
4140 4537
4141 if (ParentGroup.Scene.CollidablePrims && pa == null)
4142 {
4143 AddToPhysics(UsePhysics, SetPhantom, false);
4144 pa = PhysActor;
4145 4538
4539 if (ParentGroup.Scene == null)
4540 return;
4146 4541
4147 if (pa != null) 4542 PhysicsActor pa = PhysActor;
4148 { 4543
4149 pa.SetMaterial(Material); 4544 if (pa != null && building && pa.Building != building)
4150 DoPhysicsPropertyUpdate(UsePhysics, true); 4545 pa.Building = building;
4151
4152 if (
4153 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4154 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4155 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4156 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4157 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4158 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4159 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4160 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4161 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4162 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4163 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4164 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4165 (CollisionSound != UUID.Zero)
4166 )
4167 {
4168 pa.OnCollisionUpdate += PhysicsCollision;
4169 pa.SubscribeEvents(1000);
4170 }
4171 }
4172 }
4173 else // it already has a physical representation
4174 {
4175 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4176 }
4177 }
4178 4546
4179 if (SetVD) 4547 if ((SetPhantom && !UsePhysics && !SetVD) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
4548 || (Shape.PathCurve == (byte)Extrusion.Flexible))
4180 { 4549 {
4181 // If the above logic worked (this is urgent candidate to unit tests!)
4182 // we now have a physicsactor.
4183 // Defensive programming calls for a check here.
4184 // Better would be throwing an exception that could be catched by a unit test as the internal
4185 // logic should make sure, this Physactor is always here.
4186 if (pa != null) 4550 if (pa != null)
4187 { 4551 {
4188 pa.SetVolumeDetect(1); 4552 if(wasUsingPhysics)
4189 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active 4553 ParentGroup.Scene.RemovePhysicalPrim(1);
4190 VolumeDetectActive = true; 4554 RemoveFromPhysics();
4191 } 4555 }
4556
4557 Velocity = new Vector3(0, 0, 0);
4558 Acceleration = new Vector3(0, 0, 0);
4559 if (ParentGroup.RootPart == this)
4560 AngularVelocity = new Vector3(0, 0, 0);
4192 } 4561 }
4193 else if (SetVD != wasVD) 4562 else if (SetVD != wasVD)
4194 { 4563 {
4195 // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like 4564 if (ParentGroup.Scene.CollidablePrims)
4196 // (mumbles, well, at least if you have infinte CPU powers :-)) 4565 {
4197 if (pa != null) 4566 if (pa == null)
4198 pa.SetVolumeDetect(0); 4567 {
4568 AddToPhysics(UsePhysics, SetPhantom, building, false);
4569 pa = PhysActor;
4570/*
4571 if (pa != null)
4572 {
4573 if (
4574// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4575// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4576// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4577// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4578// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4579// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4580 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4581 ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4582 (CollisionSound != UUID.Zero)
4583 )
4584 {
4585 pa.OnCollisionUpdate += PhysicsCollision;
4586 pa.SubscribeEvents(1000);
4587 }
4588 }
4589*/
4590 }
4591 else // it already has a physical representation
4592 {
4593 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4594/* moved into DoPhysicsPropertyUpdate
4595 if(VolumeDetectActive)
4596 pa.SetVolumeDetect(1);
4597 else
4598 pa.SetVolumeDetect(0);
4599*/
4199 4600
4200 RemFlag(PrimFlags.Phantom); 4601 if (pa.Building != building)
4201 VolumeDetectActive = false; 4602 pa.Building = building;
4202 } 4603 }
4203 4604
4204 if (SetTemporary) 4605 UpdatePhysicsSubscribedEvents();
4205 { 4606 }
4206 AddFlag(PrimFlags.TemporaryOnRez); 4607 }
4207 }
4208 else
4209 {
4210 RemFlag(PrimFlags.TemporaryOnRez);
4211 }
4212 4608
4213 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); 4609 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4214 4610
4611 // and last in case we have a new actor and not building
4612
4215 if (ParentGroup != null) 4613 if (ParentGroup != null)
4216 { 4614 {
4217 ParentGroup.HasGroupChanged = true; 4615 ParentGroup.HasGroupChanged = true;
4218 ScheduleFullUpdate(); 4616 ScheduleFullUpdate();
4219 } 4617 }
4220 4618
4221// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); 4619// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4222 } 4620 }
4223 4621
4224 /// <summary> 4622 /// <summary>
4225 /// Adds this part to the physics scene. 4623 /// Adds this part to the physics scene.
4624 /// and sets the PhysActor property
4226 /// </summary> 4625 /// </summary>
4227 /// <remarks>This method also sets the PhysActor property.</remarks> 4626 /// <param name="isPhysical">Add this prim as physical.</param>
4228 /// <param name="rigidBody">Add this prim with a rigid body.</param> 4627 /// <param name="isPhantom">Add this prim as phantom.</param>
4229 /// <returns> 4628 /// <param name="building">tells physics to delay full construction of object</param>
4230 /// The physics actor. null if there was a failure. 4629 /// <param name="applyDynamics">applies velocities, force and torque</param>
4231 /// </returns> 4630 private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
4232 private void AddToPhysics(bool isPhysical, bool isPhantom, bool applyDynamics) 4631 {
4233 {
4234 PhysicsActor pa; 4632 PhysicsActor pa;
4235 4633
4236 Vector3 velocity = Velocity; 4634 Vector3 velocity = Velocity;
4237 Vector3 rotationalVelocity = AngularVelocity;; 4635 Vector3 rotationalVelocity = AngularVelocity;;
4238 4636
4239 try 4637 try
4240 { 4638 {
4241 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4639 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4242 string.Format("{0}/{1}", Name, UUID), 4640 string.Format("{0}/{1}", Name, UUID),
4243 Shape, 4641 Shape,
4244 AbsolutePosition, 4642 AbsolutePosition,
4245 Scale, 4643 Scale,
4246 GetWorldRotation(), 4644 GetWorldRotation(),
4247 isPhysical, 4645 isPhysical,
4248 isPhantom, 4646 isPhantom,
4249 PhysicsShapeType, 4647 PhysicsShapeType,
4250 m_localId); 4648 m_localId);
4251 } 4649 }
4252 catch (Exception e) 4650 catch (Exception e)
4253 { 4651 {
4254 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e); 4652 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e);
4255 pa = null; 4653 pa = null;
4256 } 4654 }
4257 4655
4258 if (pa != null) 4656 if (pa != null)
4259 { 4657 {
4260 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 4658 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
@@ -4262,11 +4660,21 @@ namespace OpenSim.Region.Framework.Scenes
4262 4660
4263 if (VolumeDetectActive) // change if not the default only 4661 if (VolumeDetectActive) // change if not the default only
4264 pa.SetVolumeDetect(1); 4662 pa.SetVolumeDetect(1);
4663
4664 if (m_vehicleParams != null && LocalId == ParentGroup.RootPart.LocalId)
4665 m_vehicleParams.SetVehicle(pa);
4666
4265 // we are going to tell rest of code about physics so better have this here 4667 // we are going to tell rest of code about physics so better have this here
4266 PhysActor = pa; 4668 PhysActor = pa;
4267 4669
4670 // DoPhysicsPropertyUpdate(isPhysical, true);
4671 // lets expand it here just with what it really needs to do
4672
4268 if (isPhysical) 4673 if (isPhysical)
4269 { 4674 {
4675 if (ParentGroup.RootPart.KeyframeMotion != null)
4676 ParentGroup.RootPart.KeyframeMotion.Stop();
4677 ParentGroup.RootPart.KeyframeMotion = null;
4270 ParentGroup.Scene.AddPhysicalPrim(1); 4678 ParentGroup.Scene.AddPhysicalPrim(1);
4271 4679
4272 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 4680 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
@@ -4283,32 +4691,53 @@ namespace OpenSim.Region.Framework.Scenes
4283 } 4691 }
4284 } 4692 }
4285 4693
4286 if (applyDynamics) 4694 if (applyDynamics)
4287 // do independent of isphysical so parameters get setted (at least some) 4695 // do independent of isphysical so parameters get setted (at least some)
4288 { 4696 {
4289 Velocity = velocity; 4697 Velocity = velocity;
4290 AngularVelocity = rotationalVelocity; 4698 AngularVelocity = rotationalVelocity;
4291// pa.Velocity = velocity; 4699// pa.Velocity = velocity;
4292 pa.RotationalVelocity = rotationalVelocity; 4700 pa.RotationalVelocity = rotationalVelocity;
4701
4702 // if not vehicle and root part apply force and torque
4703 if ((m_vehicleParams == null || m_vehicleParams.Type == Vehicle.TYPE_NONE)
4704 && LocalId == ParentGroup.RootPart.LocalId)
4705 {
4706 pa.Force = Force;
4707 pa.Torque = Torque;
4708 }
4293 } 4709 }
4294 4710
4295 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); 4711// if (Shape.SculptEntry)
4712// CheckSculptAndLoad();
4713// else
4714 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
4715
4716 if (!building)
4717 pa.Building = false;
4296 } 4718 }
4297 4719
4298 PhysActor = pa; 4720 PhysActor = pa;
4299 } 4721 }
4300 4722
4301 /// <summary> 4723 /// <summary>
4302 /// This removes the part from the physics scene. 4724 /// This removes the part from the physics scene.
4303 /// </summary> 4725 /// </summary>
4304 /// <remarks> 4726 /// <remarks>
4305 /// This isn't the same as turning off physical, since even without being physical the prim has a physics 4727 /// This isn't the same as turning off physical, since even without being physical the prim has a physics
4306 /// representation for collision detection. Rather, this would be used in situations such as making a prim 4728 /// representation for collision detection.
4307 /// phantom.
4308 /// </remarks> 4729 /// </remarks>
4309 public void RemoveFromPhysics() 4730 public void RemoveFromPhysics()
4310 { 4731 {
4311 ParentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 4732 PhysicsActor pa = PhysActor;
4733 if (pa != null)
4734 {
4735 pa.OnCollisionUpdate -= PhysicsCollision;
4736 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
4737 pa.OnOutOfBounds -= PhysicsOutOfBounds;
4738
4739 ParentGroup.Scene.PhysicsScene.RemovePrim(pa);
4740 }
4312 PhysActor = null; 4741 PhysActor = null;
4313 } 4742 }
4314 4743
@@ -4440,6 +4869,8 @@ namespace OpenSim.Region.Framework.Scenes
4440 { 4869 {
4441// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); 4870// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4442 4871
4872 return;
4873
4443 if (ParentGroup.IsDeleted) 4874 if (ParentGroup.IsDeleted)
4444 return; 4875 return;
4445 4876
@@ -4520,6 +4951,44 @@ namespace OpenSim.Region.Framework.Scenes
4520 ScheduleFullUpdate(); 4951 ScheduleFullUpdate();
4521 } 4952 }
4522 4953
4954
4955 private void UpdatePhysicsSubscribedEvents()
4956 {
4957 PhysicsActor pa = PhysActor;
4958 if (pa == null)
4959 return;
4960
4961 pa.OnCollisionUpdate -= PhysicsCollision;
4962
4963 bool hassound = (!VolumeDetectActive && CollisionSoundType >= 0 && ((Flags & PrimFlags.Physics) != 0));
4964
4965 scriptEvents CombinedEvents = AggregateScriptEvents;
4966
4967 // merge with root part
4968 if (ParentGroup != null && ParentGroup.RootPart != null)
4969 CombinedEvents |= ParentGroup.RootPart.AggregateScriptEvents;
4970
4971 // submit to this part case
4972 if (VolumeDetectActive)
4973 CombinedEvents &= PhyscicsVolumeDtcSubsEvents;
4974 else if ((Flags & PrimFlags.Phantom) != 0)
4975 CombinedEvents &= PhyscicsPhantonSubsEvents;
4976 else
4977 CombinedEvents &= PhysicsNeededSubsEvents;
4978
4979 if (hassound || CombinedEvents != 0)
4980 {
4981 // subscribe to physics updates.
4982 pa.OnCollisionUpdate += PhysicsCollision;
4983 pa.SubscribeEvents(50); // 20 reports per second
4984 }
4985 else
4986 {
4987 pa.UnSubscribeEvents();
4988 }
4989 }
4990
4991
4523 public void aggregateScriptEvents() 4992 public void aggregateScriptEvents()
4524 { 4993 {
4525 if (ParentGroup == null || ParentGroup.RootPart == null) 4994 if (ParentGroup == null || ParentGroup.RootPart == null)
@@ -4556,40 +5025,32 @@ namespace OpenSim.Region.Framework.Scenes
4556 { 5025 {
4557 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; 5026 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop;
4558 } 5027 }
4559 5028/*
4560 PhysicsActor pa = PhysActor; 5029 PhysicsActor pa = PhysActor;
4561 5030 if (pa != null)
4562 if (
4563 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4564 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4565 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4566 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4567 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4568 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4569 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4570 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4571 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4572 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4573 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4574 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4575 (CollisionSound != UUID.Zero)
4576 )
4577 { 5031 {
4578 // subscribe to physics updates. 5032 if (
4579 if (pa != null) 5033// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
5034// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
5035// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
5036// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5037// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5038// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5039 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5040 )
4580 { 5041 {
5042 // subscribe to physics updates.
4581 pa.OnCollisionUpdate += PhysicsCollision; 5043 pa.OnCollisionUpdate += PhysicsCollision;
4582 pa.SubscribeEvents(1000); 5044 pa.SubscribeEvents(1000);
4583 } 5045 }
4584 } 5046 else
4585 else
4586 {
4587 if (pa != null)
4588 { 5047 {
4589 pa.UnSubscribeEvents(); 5048 pa.UnSubscribeEvents();
4590 pa.OnCollisionUpdate -= PhysicsCollision; 5049 pa.OnCollisionUpdate -= PhysicsCollision;
4591 } 5050 }
4592 } 5051 }
5052 */
5053 UpdatePhysicsSubscribedEvents();
4593 5054
4594 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 5055 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4595 //{ 5056 //{
@@ -4720,6 +5181,18 @@ namespace OpenSim.Region.Framework.Scenes
4720 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 5181 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4721 } 5182 }
4722 5183
5184 public void ResetOwnerChangeFlag()
5185 {
5186 List<UUID> inv = Inventory.GetInventoryList();
5187
5188 foreach (UUID itemID in inv)
5189 {
5190 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
5191 item.OwnerChanged = false;
5192 Inventory.UpdateInventoryItem(item, false, false);
5193 }
5194 }
5195
4723 /// <summary> 5196 /// <summary>
4724 /// Record an avatar sitting on this part. 5197 /// Record an avatar sitting on this part.
4725 /// </summary> 5198 /// </summary>