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.cs1495
1 files changed, 985 insertions, 510 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index cce8b21..7cab841 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)
@@ -1480,6 +1769,7 @@ namespace OpenSim.Region.Framework.Scenes
1480 } 1769 }
1481 } 1770 }
1482 1771
1772
1483 #endregion Public Properties with only Get 1773 #endregion Public Properties with only Get
1484 1774
1485 private uint ApplyMask(uint val, bool set, uint mask) 1775 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1625,6 +1915,61 @@ namespace OpenSim.Region.Framework.Scenes
1625 } 1915 }
1626 } 1916 }
1627 1917
1918 // SetVelocity for LSL llSetVelocity.. may need revision if having other uses in future
1919 public void SetVelocity(Vector3 pVel, bool localGlobalTF)
1920 {
1921 if (ParentGroup == null || ParentGroup.IsDeleted)
1922 return;
1923
1924 if (ParentGroup.IsAttachment)
1925 return; // don't work on attachments (for now ??)
1926
1927 SceneObjectPart root = ParentGroup.RootPart;
1928
1929 if (root.VehicleType != (int)Vehicle.TYPE_NONE) // don't mess with vehicles
1930 return;
1931
1932 PhysicsActor pa = root.PhysActor;
1933
1934 if (pa == null || !pa.IsPhysical)
1935 return;
1936
1937 if (localGlobalTF)
1938 {
1939 pVel = pVel * GetWorldRotation();
1940 }
1941
1942 ParentGroup.Velocity = pVel;
1943 }
1944
1945 // SetAngularVelocity for LSL llSetAngularVelocity.. may need revision if having other uses in future
1946 public void SetAngularVelocity(Vector3 pAngVel, bool localGlobalTF)
1947 {
1948 if (ParentGroup == null || ParentGroup.IsDeleted)
1949 return;
1950
1951 if (ParentGroup.IsAttachment)
1952 return; // don't work on attachments (for now ??)
1953
1954 SceneObjectPart root = ParentGroup.RootPart;
1955
1956 if (root.VehicleType != (int)Vehicle.TYPE_NONE) // don't mess with vehicles
1957 return;
1958
1959 PhysicsActor pa = root.PhysActor;
1960
1961 if (pa == null || !pa.IsPhysical)
1962 return;
1963
1964 if (localGlobalTF)
1965 {
1966 pAngVel = pAngVel * GetWorldRotation();
1967 }
1968
1969 root.AngularVelocity = pAngVel;
1970 }
1971
1972
1628 /// <summary> 1973 /// <summary>
1629 /// hook to the physics scene to apply angular impulse 1974 /// hook to the physics scene to apply angular impulse
1630 /// This is sent up to the group, which then finds the root prim 1975 /// This is sent up to the group, which then finds the root prim
@@ -1645,7 +1990,7 @@ namespace OpenSim.Region.Framework.Scenes
1645 impulse = newimpulse; 1990 impulse = newimpulse;
1646 } 1991 }
1647 1992
1648 ParentGroup.applyAngularImpulse(impulse); 1993 ParentGroup.ApplyAngularImpulse(impulse);
1649 } 1994 }
1650 1995
1651 /// <summary> 1996 /// <summary>
@@ -1655,20 +2000,24 @@ namespace OpenSim.Region.Framework.Scenes
1655 /// </summary> 2000 /// </summary>
1656 /// <param name="impulsei">Vector force</param> 2001 /// <param name="impulsei">Vector force</param>
1657 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> 2002 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
1658 public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF) 2003
2004 // this is actualy Set Torque.. keeping naming so not to edit lslapi also
2005 public void SetAngularImpulse(Vector3 torquei, bool localGlobalTF)
1659 { 2006 {
1660 Vector3 impulse = impulsei; 2007 Vector3 torque = torquei;
1661 2008
1662 if (localGlobalTF) 2009 if (localGlobalTF)
1663 { 2010 {
2011/*
1664 Quaternion grot = GetWorldRotation(); 2012 Quaternion grot = GetWorldRotation();
1665 Quaternion AXgrot = grot; 2013 Quaternion AXgrot = grot;
1666 Vector3 AXimpulsei = impulsei; 2014 Vector3 AXimpulsei = impulsei;
1667 Vector3 newimpulse = AXimpulsei * AXgrot; 2015 Vector3 newimpulse = AXimpulsei * AXgrot;
1668 impulse = newimpulse; 2016 */
2017 torque *= GetWorldRotation();
1669 } 2018 }
1670 2019
1671 ParentGroup.setAngularImpulse(impulse); 2020 Torque = torque;
1672 } 2021 }
1673 2022
1674 /// <summary> 2023 /// <summary>
@@ -1676,7 +2025,9 @@ namespace OpenSim.Region.Framework.Scenes
1676 /// </summary> 2025 /// </summary>
1677 /// <param name="rootObjectFlags"></param> 2026 /// <param name="rootObjectFlags"></param>
1678 /// <param name="VolumeDetectActive"></param> 2027 /// <param name="VolumeDetectActive"></param>
1679 public void ApplyPhysics(uint rootObjectFlags, bool _VolumeDetectActive) 2028 /// <param name="building"></param>
2029
2030 public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building)
1680 { 2031 {
1681 VolumeDetectActive = _VolumeDetectActive; 2032 VolumeDetectActive = _VolumeDetectActive;
1682 2033
@@ -1686,8 +2037,8 @@ namespace OpenSim.Region.Framework.Scenes
1686 if (PhysicsShapeType == (byte)PhysShapeType.none) 2037 if (PhysicsShapeType == (byte)PhysShapeType.none)
1687 return; 2038 return;
1688 2039
1689 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 2040 bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0;
1690 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 2041 bool isPhantom = (_ObjectFlags & (uint)PrimFlags.Phantom) != 0;
1691 2042
1692 if (_VolumeDetectActive) 2043 if (_VolumeDetectActive)
1693 isPhantom = true; 2044 isPhantom = true;
@@ -1701,7 +2052,8 @@ namespace OpenSim.Region.Framework.Scenes
1701 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment 2052 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment
1702 && !(Shape.PathCurve == (byte)Extrusion.Flexible)) 2053 && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1703 { 2054 {
1704 AddToPhysics(isPhysical, isPhantom, isPhysical); 2055 AddToPhysics(isPhysical, isPhantom, building, isPhysical);
2056 UpdatePhysicsSubscribedEvents(); // not sure if appliable here
1705 } 2057 }
1706 else 2058 else
1707 PhysActor = null; // just to be sure 2059 PhysActor = null; // just to be sure
@@ -1756,6 +2108,12 @@ namespace OpenSim.Region.Framework.Scenes
1756 dupe.Category = Category; 2108 dupe.Category = Category;
1757 dupe.m_rezzed = m_rezzed; 2109 dupe.m_rezzed = m_rezzed;
1758 2110
2111 dupe.m_UndoRedo = null;
2112 dupe.m_isSelected = false;
2113
2114 dupe.IgnoreUndoUpdate = false;
2115 dupe.Undoing = false;
2116
1759 dupe.m_inventory = new SceneObjectPartInventory(dupe); 2117 dupe.m_inventory = new SceneObjectPartInventory(dupe);
1760 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone(); 2118 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone();
1761 2119
@@ -1771,6 +2129,7 @@ namespace OpenSim.Region.Framework.Scenes
1771 2129
1772 // Move afterwards ResetIDs as it clears the localID 2130 // Move afterwards ResetIDs as it clears the localID
1773 dupe.LocalId = localID; 2131 dupe.LocalId = localID;
2132
1774 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 2133 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1775 dupe.LastOwnerID = OwnerID; 2134 dupe.LastOwnerID = OwnerID;
1776 2135
@@ -1778,6 +2137,9 @@ namespace OpenSim.Region.Framework.Scenes
1778 Array.Copy(Shape.ExtraParams, extraP, extraP.Length); 2137 Array.Copy(Shape.ExtraParams, extraP, extraP.Length);
1779 dupe.Shape.ExtraParams = extraP; 2138 dupe.Shape.ExtraParams = extraP;
1780 2139
2140 // safeguard actual copy is done in sog.copy
2141 dupe.KeyframeMotion = null;
2142
1781 dupe.DynAttrs.CopyFrom(DynAttrs); 2143 dupe.DynAttrs.CopyFrom(DynAttrs);
1782 2144
1783 if (userExposed) 2145 if (userExposed)
@@ -1791,8 +2153,12 @@ namespace OpenSim.Region.Framework.Scenes
1791*/ 2153*/
1792 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 2154 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
1793 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 2155 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
2156// dupe.UpdatePhysicsSubscribedEvents(); // not sure...
1794 } 2157 }
1795 2158
2159 if (dupe.PhysActor != null)
2160 dupe.PhysActor.LocalID = localID;
2161
1796 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 2162 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1797 2163
1798// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); 2164// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
@@ -1811,10 +2177,10 @@ namespace OpenSim.Region.Framework.Scenes
1811 { 2177 {
1812 if (asset != null) 2178 if (asset != null)
1813 SculptTextureCallback(asset); 2179 SculptTextureCallback(asset);
1814 else 2180// else
1815 m_log.WarnFormat( 2181// m_log.WarnFormat(
1816 "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data", 2182// "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
1817 Name, UUID, id); 2183// Name, UUID, id);
1818 } 2184 }
1819*/ 2185*/
1820 /// <summary> 2186 /// <summary>
@@ -1913,6 +2279,7 @@ namespace OpenSim.Region.Framework.Scenes
1913 2279
1914 /// <summary> 2280 /// <summary>
1915 /// Do a physics propery update for this part. 2281 /// Do a physics propery update for this part.
2282 /// now also updates phantom and volume detector
1916 /// </summary> 2283 /// </summary>
1917 /// <param name="UsePhysics"></param> 2284 /// <param name="UsePhysics"></param>
1918 /// <param name="isNew"></param> 2285 /// <param name="isNew"></param>
@@ -1938,61 +2305,69 @@ namespace OpenSim.Region.Framework.Scenes
1938 { 2305 {
1939 if (pa.IsPhysical) // implies UsePhysics==false for this block 2306 if (pa.IsPhysical) // implies UsePhysics==false for this block
1940 { 2307 {
1941 if (!isNew) 2308 if (!isNew) // implies UsePhysics==false for this block
2309 {
1942 ParentGroup.Scene.RemovePhysicalPrim(1); 2310 ParentGroup.Scene.RemovePhysicalPrim(1);
1943 2311
1944 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 2312 Velocity = new Vector3(0, 0, 0);
1945 pa.OnOutOfBounds -= PhysicsOutOfBounds; 2313 Acceleration = new Vector3(0, 0, 0);
1946 pa.delink(); 2314 if (ParentGroup.RootPart == this)
2315 AngularVelocity = new Vector3(0, 0, 0);
1947 2316
1948 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 2317 if (pa.Phantom && !VolumeDetectActive)
1949 { 2318 {
1950 // destroy all joints connected to this now deactivated body 2319 RemoveFromPhysics();
1951 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); 2320 return;
1952 } 2321 }
1953 2322
1954 // stop client-side interpolation of all joint proxy objects that have just been deleted 2323 pa.IsPhysical = UsePhysics;
1955 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback, 2324 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1956 // which stops client-side interpolation of deactivated joint proxy objects. 2325 pa.OnOutOfBounds -= PhysicsOutOfBounds;
2326 pa.delink();
2327 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
2328 {
2329 // destroy all joints connected to this now deactivated body
2330 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa);
2331 }
2332 }
1957 } 2333 }
1958 2334
1959 if (!UsePhysics && !isNew) 2335 if (pa.IsPhysical != UsePhysics)
1960 { 2336 pa.IsPhysical = UsePhysics;
1961 // reset velocity to 0 on physics switch-off. Without that, the client thinks the
1962 // prim still has velocity and continues to interpolate its position along the old
1963 // velocity-vector.
1964 Velocity = new Vector3(0, 0, 0);
1965 Acceleration = new Vector3(0, 0, 0);
1966 AngularVelocity = new Vector3(0, 0, 0);
1967 //RotationalVelocity = new Vector3(0, 0, 0);
1968 }
1969 2337
1970 pa.IsPhysical = UsePhysics; 2338 if (UsePhysics)
2339 {
2340 if (ParentGroup.RootPart.KeyframeMotion != null)
2341 ParentGroup.RootPart.KeyframeMotion.Stop();
2342 ParentGroup.RootPart.KeyframeMotion = null;
2343 ParentGroup.Scene.AddPhysicalPrim(1);
1971 2344
1972 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 2345 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1973 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 2346 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1974 /// that's not wholesome. Had to make Scene public
1975 //PhysActor = null;
1976 2347
1977 if ((Flags & PrimFlags.Phantom) == 0) 2348 if (ParentID != 0 && ParentID != LocalId)
1978 {
1979 if (UsePhysics)
1980 { 2349 {
1981 ParentGroup.Scene.AddPhysicalPrim(1); 2350 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
1982 2351
1983 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 2352 if (parentPa != null)
1984 pa.OnOutOfBounds += PhysicsOutOfBounds;
1985 if (ParentID != 0 && ParentID != LocalId)
1986 { 2353 {
1987 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; 2354 pa.link(parentPa);
1988
1989 if (parentPa != null)
1990 {
1991 pa.link(parentPa);
1992 }
1993 } 2355 }
1994 } 2356 }
1995 } 2357 }
2358 }
2359
2360 bool phan = ((Flags & PrimFlags.Phantom) != 0);
2361 if (pa.Phantom != phan)
2362 pa.Phantom = phan;
2363
2364// some engines dont' have this check still
2365// if (VolumeDetectActive != pa.IsVolumeDtc)
2366 {
2367 if (VolumeDetectActive)
2368 pa.SetVolumeDetect(1);
2369 else
2370 pa.SetVolumeDetect(0);
1996 } 2371 }
1997 2372
1998 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 2373 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
@@ -2111,42 +2486,63 @@ namespace OpenSim.Region.Framework.Scenes
2111 2486
2112 public Vector3 GetGeometricCenter() 2487 public Vector3 GetGeometricCenter()
2113 { 2488 {
2489 // this is not real geometric center but a average of positions relative to root prim acording to
2490 // http://wiki.secondlife.com/wiki/llGetGeometricCenter
2491 // ignoring tortured prims details since sl also seems to ignore
2492 // so no real use in doing it on physics
2493 if (ParentGroup.IsDeleted)
2494 return new Vector3(0, 0, 0);
2495
2496 return ParentGroup.GetGeometricCenter();
2497 }
2498
2499 public float GetMass()
2500 {
2114 PhysicsActor pa = PhysActor; 2501 PhysicsActor pa = PhysActor;
2115 2502
2116 if (pa != null) 2503 if (pa != null)
2117 return new Vector3(pa.GeometricCenter.X, pa.GeometricCenter.Y, pa.GeometricCenter.Z); 2504 return pa.Mass;
2118 else 2505 else
2119 return new Vector3(0, 0, 0); 2506 return 0;
2120 } 2507 }
2121 2508
2122 public Vector3 GetCenterOfMass() 2509 public Vector3 GetCenterOfMass()
2123 { 2510 {
2511 if (ParentGroup.RootPart == this)
2512 {
2513 if (ParentGroup.IsDeleted)
2514 return AbsolutePosition;
2515 return ParentGroup.GetCenterOfMass();
2516 }
2517
2124 PhysicsActor pa = PhysActor; 2518 PhysicsActor pa = PhysActor;
2125 2519
2126 if (pa != null) 2520 if (pa != null)
2127 return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z); 2521 {
2522 Vector3 tmp = pa.CenterOfMass;
2523 return tmp;
2524 }
2128 else 2525 else
2129 return new Vector3(0, 0, 0); 2526 return AbsolutePosition;
2130 } 2527 }
2131 2528
2132 public float GetMass() 2529 public Vector3 GetPartCenterOfMass()
2133 { 2530 {
2134 PhysicsActor pa = PhysActor; 2531 PhysicsActor pa = PhysActor;
2135 2532
2136 if (pa != null) 2533 if (pa != null)
2137 return pa.Mass; 2534 {
2535 Vector3 tmp = pa.CenterOfMass;
2536 return tmp;
2537 }
2138 else 2538 else
2139 return 0; 2539 return AbsolutePosition;
2140 } 2540 }
2141 2541
2542
2142 public Vector3 GetForce() 2543 public Vector3 GetForce()
2143 { 2544 {
2144 PhysicsActor pa = PhysActor; 2545 return Force;
2145
2146 if (pa != null)
2147 return pa.Force;
2148 else
2149 return Vector3.Zero;
2150 } 2546 }
2151 2547
2152 /// <summary> 2548 /// <summary>
@@ -2361,15 +2757,25 @@ namespace OpenSim.Region.Framework.Scenes
2361 2757
2362 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify) 2758 private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify)
2363 { 2759 {
2364 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0) 2760 bool sendToRoot = true;
2365 {
2366 ColliderArgs LandCollidingMessage = new ColliderArgs();
2367 List<DetectedObject> colliding = new List<DetectedObject>();
2368
2369 colliding.Add(CreateDetObjectForGround());
2370 LandCollidingMessage.Colliders = colliding;
2371 2761
2762 ColliderArgs LandCollidingMessage = new ColliderArgs();
2763 List<DetectedObject> colliding = new List<DetectedObject>();
2764
2765 colliding.Add(CreateDetObjectForGround());
2766 LandCollidingMessage.Colliders = colliding;
2767
2768 if (Inventory.ContainsScripts())
2769 {
2770 if (!PassCollisions)
2771 sendToRoot = false;
2772 }
2773 if ((ScriptEvents & ev) != 0)
2372 notify(LocalId, LandCollidingMessage); 2774 notify(LocalId, LandCollidingMessage);
2775
2776 if ((ParentGroup.RootPart.ScriptEvents & ev) != 0 && sendToRoot)
2777 {
2778 notify(ParentGroup.RootPart.LocalId, LandCollidingMessage);
2373 } 2779 }
2374 } 2780 }
2375 2781
@@ -2385,57 +2791,120 @@ namespace OpenSim.Region.Framework.Scenes
2385 List<uint> endedColliders = new List<uint>(); 2791 List<uint> endedColliders = new List<uint>();
2386 List<uint> startedColliders = new List<uint>(); 2792 List<uint> startedColliders = new List<uint>();
2387 2793
2388 // calculate things that started colliding this time 2794 if (collissionswith.Count == 0)
2389 // and build up list of colliders this time
2390 foreach (uint localid in collissionswith.Keys)
2391 { 2795 {
2392 thisHitColliders.Add(localid); 2796 if (m_lastColliders.Count == 0)
2393 if (!m_lastColliders.Contains(localid)) 2797 return; // nothing to do
2394 startedColliders.Add(localid);
2395 }
2396 2798
2397 // calculate things that ended colliding 2799 foreach (uint localID in m_lastColliders)
2398 foreach (uint localID in m_lastColliders) 2800 {
2399 {
2400 if (!thisHitColliders.Contains(localID))
2401 endedColliders.Add(localID); 2801 endedColliders.Add(localID);
2802 }
2803 m_lastColliders.Clear();
2402 } 2804 }
2403 2805
2404 //add the items that started colliding this time to the last colliders list. 2806 else
2405 foreach (uint localID in startedColliders) 2807 {
2406 m_lastColliders.Add(localID); 2808 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
2809
2810 // calculate things that started colliding this time
2811 // and build up list of colliders this time
2812 if (!VolumeDetectActive && CollisionSoundType >= 0)
2813 {
2814 CollisionForSoundInfo soundinfo;
2815 ContactPoint curcontact;
2407 2816
2408 // remove things that ended colliding from the last colliders list 2817 foreach (uint id in collissionswith.Keys)
2409 foreach (uint localID in endedColliders) 2818 {
2410 m_lastColliders.Remove(localID); 2819 thisHitColliders.Add(id);
2820 if (!m_lastColliders.Contains(id))
2821 {
2822 startedColliders.Add(id);
2411 2823
2412 // play the sound. 2824 curcontact = collissionswith[id];
2413 if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) 2825 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
2414 { 2826 {
2415 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>(); 2827 soundinfo = new CollisionForSoundInfo();
2416 if (soundModule != null) 2828 soundinfo.colliderID = id;
2829 soundinfo.position = curcontact.Position;
2830 soundinfo.relativeVel = curcontact.RelativeSpeed;
2831 soundinfolist.Add(soundinfo);
2832 }
2833 }
2834 }
2835 }
2836 else
2837 {
2838 foreach (uint id in collissionswith.Keys)
2839 {
2840 thisHitColliders.Add(id);
2841 if (!m_lastColliders.Contains(id))
2842 startedColliders.Add(id);
2843 }
2844 }
2845
2846 // calculate things that ended colliding
2847 foreach (uint localID in m_lastColliders)
2417 { 2848 {
2418 soundModule.SendSound(UUID, CollisionSound, 2849 if (!thisHitColliders.Contains(localID))
2419 CollisionSoundVolume, true, (byte)0, 0, false, 2850 endedColliders.Add(localID);
2420 false);
2421 } 2851 }
2852
2853 //add the items that started colliding this time to the last colliders list.
2854 foreach (uint localID in startedColliders)
2855 m_lastColliders.Add(localID);
2856
2857 // remove things that ended colliding from the last colliders list
2858 foreach (uint localID in endedColliders)
2859 m_lastColliders.Remove(localID);
2860
2861 // play sounds.
2862 if (soundinfolist.Count > 0)
2863 CollisionSounds.PartCollisionSound(this, soundinfolist);
2422 } 2864 }
2423 2865
2424 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart); 2866 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
2425 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding); 2867 if (!VolumeDetectActive)
2868 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
2426 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); 2869 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
2427 2870
2428 if (startedColliders.Contains(0)) 2871 if (startedColliders.Contains(0))
2429 { 2872 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2430 if (m_lastColliders.Contains(0)) 2873 if (m_lastColliders.Contains(0))
2431 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding); 2874 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding);
2432 else
2433 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
2434 }
2435 if (endedColliders.Contains(0)) 2875 if (endedColliders.Contains(0))
2436 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); 2876 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
2437 } 2877 }
2438 2878
2879 // The Collision sounds code calls this
2880 public void SendCollisionSound(UUID soundID, double volume, Vector3 position)
2881 {
2882 if (soundID == UUID.Zero)
2883 return;
2884
2885 ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface<ISoundModule>();
2886 if (soundModule == null)
2887 return;
2888
2889 if (volume > 1)
2890 volume = 1;
2891 if (volume < 0)
2892 volume = 0;
2893
2894 int now = Util.EnvironmentTickCount();
2895 if(Util.EnvironmentTickCountSubtract(now,LastColSoundSentTime) <200)
2896 return;
2897
2898 LastColSoundSentTime = now;
2899
2900 UUID ownerID = OwnerID;
2901 UUID objectID = ParentGroup.RootPart.UUID;
2902 UUID parentID = ParentGroup.UUID;
2903 ulong regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle;
2904
2905 soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, 0 );
2906 }
2907
2439 public void PhysicsOutOfBounds(Vector3 pos) 2908 public void PhysicsOutOfBounds(Vector3 pos)
2440 { 2909 {
2441 // Note: This is only being called on the root prim at this time. 2910 // Note: This is only being called on the root prim at this time.
@@ -2457,9 +2926,9 @@ namespace OpenSim.Region.Framework.Scenes
2457 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2926 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2458 2927
2459 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2928 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2460 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2929 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2461 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2930 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2462 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2931 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2463 { 2932 {
2464 ParentGroup.AbsolutePosition = newpos; 2933 ParentGroup.AbsolutePosition = newpos;
2465 return; 2934 return;
@@ -2744,6 +3213,14 @@ namespace OpenSim.Region.Framework.Scenes
2744 if (ParentGroup == null) 3213 if (ParentGroup == null)
2745 return; 3214 return;
2746 3215
3216 // Update the "last" values
3217 m_lastPosition = OffsetPosition;
3218 m_lastRotation = RotationOffset;
3219 m_lastVelocity = Velocity;
3220 m_lastAcceleration = Acceleration;
3221 m_lastAngularVelocity = AngularVelocity;
3222 m_lastUpdateSentTime = Environment.TickCount;
3223
2747 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3224 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
2748 { 3225 {
2749 SendFullUpdate(avatar.ControllingClient); 3226 SendFullUpdate(avatar.ControllingClient);
@@ -2802,8 +3279,8 @@ namespace OpenSim.Region.Framework.Scenes
2802 { 3279 {
2803 const float ROTATION_TOLERANCE = 0.01f; 3280 const float ROTATION_TOLERANCE = 0.01f;
2804 const float VELOCITY_TOLERANCE = 0.001f; 3281 const float VELOCITY_TOLERANCE = 0.001f;
2805 const float POSITION_TOLERANCE = 0.05f; 3282 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2806 const int TIME_MS_TOLERANCE = 3000; 3283 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2807 3284
2808 switch (UpdateFlag) 3285 switch (UpdateFlag)
2809 { 3286 {
@@ -2817,17 +3294,10 @@ namespace OpenSim.Region.Framework.Scenes
2817 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || 3294 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) ||
2818 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || 3295 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) ||
2819 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 3296 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
2820 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 3297 Environment.TickCount - m_lastUpdateSentTime > TIME_MS_TOLERANCE)
2821 { 3298 {
2822 SendTerseUpdateToAllClients(); 3299 SendTerseUpdateToAllClients();
2823 3300
2824 // Update the "last" values
2825 m_lastPosition = OffsetPosition;
2826 m_lastRotation = RotationOffset;
2827 m_lastVelocity = Velocity;
2828 m_lastAcceleration = Acceleration;
2829 m_lastAngularVelocity = AngularVelocity;
2830 m_lastTerseSent = Environment.TickCount;
2831 } 3301 }
2832 break; 3302 break;
2833 } 3303 }
@@ -2845,6 +3315,17 @@ namespace OpenSim.Region.Framework.Scenes
2845 /// </summary> 3315 /// </summary>
2846 public void SendTerseUpdateToAllClients() 3316 public void SendTerseUpdateToAllClients()
2847 { 3317 {
3318 if (ParentGroup == null || ParentGroup.Scene == null)
3319 return;
3320
3321 // Update the "last" values
3322 m_lastPosition = OffsetPosition;
3323 m_lastRotation = RotationOffset;
3324 m_lastVelocity = Velocity;
3325 m_lastAcceleration = Acceleration;
3326 m_lastAngularVelocity = AngularVelocity;
3327 m_lastUpdateSentTime = Environment.TickCount;
3328
2848 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3329 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
2849 { 3330 {
2850 SendTerseUpdateToClient(client); 3331 SendTerseUpdateToClient(client);
@@ -2868,10 +3349,13 @@ namespace OpenSim.Region.Framework.Scenes
2868 3349
2869 public void SetBuoyancy(float fvalue) 3350 public void SetBuoyancy(float fvalue)
2870 { 3351 {
2871 PhysicsActor pa = PhysActor; 3352 Buoyancy = fvalue;
2872 3353/*
2873 if (pa != null) 3354 if (PhysActor != null)
2874 pa.Buoyancy = fvalue; 3355 {
3356 PhysActor.Buoyancy = fvalue;
3357 }
3358 */
2875 } 3359 }
2876 3360
2877 public void SetDieAtEdge(bool p) 3361 public void SetDieAtEdge(bool p)
@@ -2887,47 +3371,111 @@ namespace OpenSim.Region.Framework.Scenes
2887 PhysicsActor pa = PhysActor; 3371 PhysicsActor pa = PhysActor;
2888 3372
2889 if (pa != null) 3373 if (pa != null)
2890 pa.FloatOnWater = floatYN == 1; 3374 pa.FloatOnWater = (floatYN == 1);
2891 } 3375 }
2892 3376
2893 public void SetForce(Vector3 force) 3377 public void SetForce(Vector3 force)
2894 { 3378 {
2895 PhysicsActor pa = PhysActor; 3379 Force = force;
3380 }
2896 3381
2897 if (pa != null) 3382 public SOPVehicle VehicleParams
2898 pa.Force = force; 3383 {
3384 get
3385 {
3386 return m_vehicleParams;
3387 }
3388 set
3389 {
3390 m_vehicleParams = value;
3391 }
3392 }
3393
3394
3395 public int VehicleType
3396 {
3397 get
3398 {
3399 if (m_vehicleParams == null)
3400 return (int)Vehicle.TYPE_NONE;
3401 else
3402 return (int)m_vehicleParams.Type;
3403 }
3404 set
3405 {
3406 SetVehicleType(value);
3407 }
2899 } 3408 }
2900 3409
2901 public void SetVehicleType(int type) 3410 public void SetVehicleType(int type)
2902 { 3411 {
2903 PhysicsActor pa = PhysActor; 3412 m_vehicleParams = null;
3413
3414 if (type == (int)Vehicle.TYPE_NONE)
3415 {
3416 if (_parentID ==0 && PhysActor != null)
3417 PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
3418 return;
3419 }
3420 m_vehicleParams = new SOPVehicle();
3421 m_vehicleParams.ProcessTypeChange((Vehicle)type);
3422 {
3423 if (_parentID ==0 && PhysActor != null)
3424 PhysActor.VehicleType = type;
3425 return;
3426 }
3427 }
2904 3428
2905 if (pa != null) 3429 public void SetVehicleFlags(int param, bool remove)
2906 pa.VehicleType = type; 3430 {
3431 if (m_vehicleParams == null)
3432 return;
3433
3434 m_vehicleParams.ProcessVehicleFlags(param, remove);
3435
3436 if (_parentID ==0 && PhysActor != null)
3437 {
3438 PhysActor.VehicleFlags(param, remove);
3439 }
2907 } 3440 }
2908 3441
2909 public void SetVehicleFloatParam(int param, float value) 3442 public void SetVehicleFloatParam(int param, float value)
2910 { 3443 {
2911 PhysicsActor pa = PhysActor; 3444 if (m_vehicleParams == null)
3445 return;
2912 3446
2913 if (pa != null) 3447 m_vehicleParams.ProcessFloatVehicleParam((Vehicle)param, value);
2914 pa.VehicleFloatParam(param, value); 3448
3449 if (_parentID == 0 && PhysActor != null)
3450 {
3451 PhysActor.VehicleFloatParam(param, value);
3452 }
2915 } 3453 }
2916 3454
2917 public void SetVehicleVectorParam(int param, Vector3 value) 3455 public void SetVehicleVectorParam(int param, Vector3 value)
2918 { 3456 {
2919 PhysicsActor pa = PhysActor; 3457 if (m_vehicleParams == null)
3458 return;
2920 3459
2921 if (pa != null) 3460 m_vehicleParams.ProcessVectorVehicleParam((Vehicle)param, value);
2922 pa.VehicleVectorParam(param, value); 3461
3462 if (_parentID == 0 && PhysActor != null)
3463 {
3464 PhysActor.VehicleVectorParam(param, value);
3465 }
2923 } 3466 }
2924 3467
2925 public void SetVehicleRotationParam(int param, Quaternion rotation) 3468 public void SetVehicleRotationParam(int param, Quaternion rotation)
2926 { 3469 {
2927 PhysicsActor pa = PhysActor; 3470 if (m_vehicleParams == null)
3471 return;
2928 3472
2929 if (pa != null) 3473 m_vehicleParams.ProcessRotationVehicleParam((Vehicle)param, rotation);
2930 pa.VehicleRotationParam(param, rotation); 3474
3475 if (_parentID == 0 && PhysActor != null)
3476 {
3477 PhysActor.VehicleRotationParam(param, rotation);
3478 }
2931 } 3479 }
2932 3480
2933 /// <summary> 3481 /// <summary>
@@ -3128,14 +3676,6 @@ namespace OpenSim.Region.Framework.Scenes
3128 hasProfileCut = hasDimple; // is it the same thing? 3676 hasProfileCut = hasDimple; // is it the same thing?
3129 } 3677 }
3130 3678
3131 public void SetVehicleFlags(int param, bool remove)
3132 {
3133 PhysicsActor pa = PhysActor;
3134
3135 if (pa != null)
3136 pa.VehicleFlags(param, remove);
3137 }
3138
3139 public void SetGroup(UUID groupID, IClientAPI client) 3679 public void SetGroup(UUID groupID, IClientAPI client)
3140 { 3680 {
3141 // Scene.AddNewPrims() calls with client == null so can't use this. 3681 // Scene.AddNewPrims() calls with client == null so can't use this.
@@ -3235,71 +3775,20 @@ namespace OpenSim.Region.Framework.Scenes
3235 { 3775 {
3236 ParentGroup.stopMoveToTarget(); 3776 ParentGroup.stopMoveToTarget();
3237 3777
3238 ParentGroup.ScheduleGroupForTerseUpdate(); 3778// ParentGroup.ScheduleGroupForTerseUpdate();
3239 //ParentGroup.ScheduleGroupForFullUpdate(); 3779 //ParentGroup.ScheduleGroupForFullUpdate();
3240 } 3780 }
3241 3781
3242 public void StoreUndoState() 3782 public void StoreUndoState(ObjectChangeType change)
3243 { 3783 {
3244 StoreUndoState(false); 3784 if (m_UndoRedo == null)
3245 } 3785 m_UndoRedo = new UndoRedoState(5);
3246
3247 public void StoreUndoState(bool forGroup)
3248 {
3249 if (ParentGroup == null || ParentGroup.Scene == null)
3250 return;
3251
3252 if (Undoing)
3253 {
3254// m_log.DebugFormat(
3255// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3256 return;
3257 }
3258
3259 if (IgnoreUndoUpdate)
3260 {
3261// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3262 return;
3263 }
3264 3786
3265 lock (m_undo) 3787 lock (m_UndoRedo)
3266 { 3788 {
3267 if (m_undo.Count > 0) 3789 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3268 { 3790 {
3269 UndoState last = m_undo[m_undo.Count - 1]; 3791 m_UndoRedo.StoreUndo(this, change);
3270 if (last != null)
3271 {
3272 // TODO: May need to fix for group comparison
3273 if (last.Compare(this))
3274 {
3275// m_log.DebugFormat(
3276// "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3277// Name, LocalId, m_undo.Count);
3278
3279 return;
3280 }
3281 }
3282 }
3283
3284// m_log.DebugFormat(
3285// "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3286// Name, LocalId, forGroup, m_undo.Count);
3287
3288 if (ParentGroup.Scene.MaxUndoCount > 0)
3289 {
3290 UndoState nUndo = new UndoState(this, forGroup);
3291
3292 m_undo.Add(nUndo);
3293
3294 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3295 m_undo.RemoveAt(0);
3296
3297 if (m_redo.Count > 0)
3298 m_redo.Clear();
3299
3300// m_log.DebugFormat(
3301// "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3302// Name, LocalId, forGroup, m_undo.Count);
3303 } 3792 }
3304 } 3793 }
3305 } 3794 }
@@ -3311,88 +3800,46 @@ namespace OpenSim.Region.Framework.Scenes
3311 { 3800 {
3312 get 3801 get
3313 { 3802 {
3314 lock (m_undo) 3803 if (m_UndoRedo == null)
3315 return m_undo.Count; 3804 return 0;
3805 return m_UndoRedo.Count;
3316 } 3806 }
3317 } 3807 }
3318 3808
3319 public void Undo() 3809 public void Undo()
3320 { 3810 {
3321 lock (m_undo) 3811 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3322 { 3812 return;
3323// m_log.DebugFormat(
3324// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3325// Name, LocalId, m_undo.Count);
3326
3327 if (m_undo.Count > 0)
3328 {
3329 UndoState goback = m_undo[m_undo.Count - 1];
3330 m_undo.RemoveAt(m_undo.Count - 1);
3331
3332 UndoState nUndo = null;
3333
3334 if (ParentGroup.Scene.MaxUndoCount > 0)
3335 {
3336 nUndo = new UndoState(this, goback.ForGroup);
3337 }
3338
3339 goback.PlaybackState(this);
3340
3341 if (nUndo != null)
3342 {
3343 m_redo.Add(nUndo);
3344
3345 if (m_redo.Count > ParentGroup.Scene.MaxUndoCount)
3346 m_redo.RemoveAt(0);
3347 }
3348 }
3349 3813
3350// m_log.DebugFormat( 3814 lock (m_UndoRedo)
3351// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3815 {
3352// Name, LocalId, m_undo.Count); 3816 Undoing = true;
3817 m_UndoRedo.Undo(this);
3818 Undoing = false;
3353 } 3819 }
3354 } 3820 }
3355 3821
3356 public void Redo() 3822 public void Redo()
3357 { 3823 {
3358 lock (m_undo) 3824 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3359 { 3825 return;
3360// m_log.DebugFormat(
3361// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3362// Name, LocalId, m_redo.Count);
3363
3364 if (m_redo.Count > 0)
3365 {
3366 UndoState gofwd = m_redo[m_redo.Count - 1];
3367 m_redo.RemoveAt(m_redo.Count - 1);
3368
3369 if (ParentGroup.Scene.MaxUndoCount > 0)
3370 {
3371 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3372
3373 m_undo.Add(nUndo);
3374
3375 if (m_undo.Count > ParentGroup.Scene.MaxUndoCount)
3376 m_undo.RemoveAt(0);
3377 }
3378
3379 gofwd.PlayfwdState(this);
3380 3826
3381// m_log.DebugFormat( 3827 lock (m_UndoRedo)
3382// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3828 {
3383// Name, LocalId, m_redo.Count); 3829 Undoing = true;
3384 } 3830 m_UndoRedo.Redo(this);
3831 Undoing = false;
3385 } 3832 }
3386 } 3833 }
3387 3834
3388 public void ClearUndoState() 3835 public void ClearUndoState()
3389 { 3836 {
3390// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3837 if (m_UndoRedo == null || Undoing)
3838 return;
3391 3839
3392 lock (m_undo) 3840 lock (m_UndoRedo)
3393 { 3841 {
3394 m_undo.Clear(); 3842 m_UndoRedo.Clear();
3395 m_redo.Clear();
3396 } 3843 }
3397 } 3844 }
3398 3845
@@ -3943,7 +4390,7 @@ namespace OpenSim.Region.Framework.Scenes
3943 if (god) 4390 if (god)
3944 { 4391 {
3945 BaseMask = ApplyMask(BaseMask, set, mask); 4392 BaseMask = ApplyMask(BaseMask, set, mask);
3946 Inventory.ApplyGodPermissions(_baseMask); 4393 Inventory.ApplyGodPermissions(BaseMask);
3947 } 4394 }
3948 4395
3949 break; 4396 break;
@@ -3962,7 +4409,7 @@ namespace OpenSim.Region.Framework.Scenes
3962 case 16: 4409 case 16:
3963 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & 4410 NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) &
3964 baseMask; 4411 baseMask;
3965 // Prevent the client from creating no mod, no copy 4412 // Prevent the client from creating no copy, no transfer
3966 // objects 4413 // objects
3967 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0) 4414 if ((NextOwnerMask & (uint)PermissionMask.Copy) == 0)
3968 NextOwnerMask |= (uint)PermissionMask.Transfer; 4415 NextOwnerMask |= (uint)PermissionMask.Transfer;
@@ -3980,20 +4427,20 @@ namespace OpenSim.Region.Framework.Scenes
3980 { 4427 {
3981 bool update = false; 4428 bool update = false;
3982 4429
3983 if (BaseMask != source.BaseMask || 4430 uint prevOwnerMask = OwnerMask;
3984 OwnerMask != source.OwnerMask || 4431 uint prevGroupMask = GroupMask;
3985 GroupMask != source.GroupMask || 4432 uint prevEveryoneMask = EveryoneMask;
3986 EveryoneMask != source.EveryoneMask || 4433 uint prevNextOwnerMask = NextOwnerMask;
3987 NextOwnerMask != source.NextOwnerMask)
3988 update = true;
3989 4434
3990 BaseMask = source.BaseMask; 4435 OwnerMask = source.OwnerMask & BaseMask;
3991 OwnerMask = source.OwnerMask; 4436 GroupMask = source.GroupMask & BaseMask;
3992 GroupMask = source.GroupMask; 4437 EveryoneMask = source.EveryoneMask & BaseMask;
3993 EveryoneMask = source.EveryoneMask; 4438 NextOwnerMask = source.NextOwnerMask & BaseMask;
3994 NextOwnerMask = source.NextOwnerMask;
3995 4439
3996 if (update) 4440 if (OwnerMask != prevOwnerMask ||
4441 GroupMask != prevGroupMask ||
4442 EveryoneMask != prevEveryoneMask ||
4443 NextOwnerMask != prevNextOwnerMask)
3997 SendFullUpdateToAllClients(); 4444 SendFullUpdateToAllClients();
3998 } 4445 }
3999 4446
@@ -4044,6 +4491,7 @@ namespace OpenSim.Region.Framework.Scenes
4044 } 4491 }
4045 } 4492 }
4046 4493
4494
4047 public void UpdateExtraPhysics(ExtraPhysicsData physdata) 4495 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4048 { 4496 {
4049 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null) 4497 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
@@ -4071,7 +4519,7 @@ namespace OpenSim.Region.Framework.Scenes
4071 /// <param name="SetTemporary"></param> 4519 /// <param name="SetTemporary"></param>
4072 /// <param name="SetPhantom"></param> 4520 /// <param name="SetPhantom"></param>
4073 /// <param name="SetVD"></param> 4521 /// <param name="SetVD"></param>
4074 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) 4522 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
4075 { 4523 {
4076 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4524 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4077 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4525 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4081,195 +4529,145 @@ namespace OpenSim.Region.Framework.Scenes
4081 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4529 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4082 return; 4530 return;
4083 4531
4084 PhysicsActor pa = PhysActor; 4532 VolumeDetectActive = SetVD;
4085
4086 // Special cases for VD. VD can only be called from a script
4087 // and can't be combined with changes to other states. So we can rely
4088 // that...
4089 // ... if VD is changed, all others are not.
4090 // ... if one of the others is changed, VD is not.
4091 if (SetVD) // VD is active, special logic applies
4092 {
4093 // State machine logic for VolumeDetect
4094 // More logic below
4095 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4096
4097 if (phanReset) // Phantom changes from on to off switch VD off too
4098 {
4099 SetVD = false; // Switch it of for the course of this routine
4100 VolumeDetectActive = false; // and also permanently
4101
4102 if (pa != null)
4103 pa.SetVolumeDetect(0); // Let physics know about it too
4104 }
4105 else
4106 {
4107 // If volumedetect is active we don't want phantom to be applied.
4108 // If this is a new call to VD out of the state "phantom"
4109 // this will also cause the prim to be visible to physics
4110 SetPhantom = false;
4111 }
4112 }
4113 4533
4114 if (UsePhysics && IsJoint()) 4534 // volume detector implies phantom
4115 { 4535 if (VolumeDetectActive)
4116 SetPhantom = true; 4536 SetPhantom = true;
4117 }
4118 4537
4119 if (UsePhysics) 4538 if (UsePhysics)
4120 {
4121 AddFlag(PrimFlags.Physics); 4539 AddFlag(PrimFlags.Physics);
4122 if (!wasUsingPhysics)
4123 {
4124 DoPhysicsPropertyUpdate(UsePhysics, false);
4125 }
4126 }
4127 else 4540 else
4128 {
4129 RemFlag(PrimFlags.Physics); 4541 RemFlag(PrimFlags.Physics);
4130 if (wasUsingPhysics)
4131 {
4132 DoPhysicsPropertyUpdate(UsePhysics, false);
4133 }
4134 }
4135 4542
4136 if (SetPhantom 4543 if (SetPhantom)
4137 || ParentGroup.IsAttachment
4138 || PhysicsShapeType == (byte)PhysShapeType.none
4139 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4140 {
4141 AddFlag(PrimFlags.Phantom); 4544 AddFlag(PrimFlags.Phantom);
4142 4545 else
4143 if (PhysActor != null)
4144 {
4145 RemoveFromPhysics();
4146 pa = null;
4147 }
4148 }
4149 else // Not phantom
4150 {
4151 RemFlag(PrimFlags.Phantom); 4546 RemFlag(PrimFlags.Phantom);
4152 4547
4153 if (ParentGroup.Scene == null) 4548 if (SetTemporary)
4154 return; 4549 AddFlag(PrimFlags.TemporaryOnRez);
4550 else
4551 RemFlag(PrimFlags.TemporaryOnRez);
4155 4552
4156 if (ParentGroup.Scene.CollidablePrims && pa == null)
4157 {
4158 AddToPhysics(UsePhysics, SetPhantom, false);
4159 pa = PhysActor;
4160 4553
4554 if (ParentGroup.Scene == null)
4555 return;
4161 4556
4162 if (pa != null) 4557 PhysicsActor pa = PhysActor;
4163 { 4558
4164 pa.SetMaterial(Material); 4559 if (pa != null && building && pa.Building != building)
4165 DoPhysicsPropertyUpdate(UsePhysics, true); 4560 pa.Building = building;
4166
4167 if (
4168 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4169 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4170 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4171 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4172 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4173 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4174 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4175 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4176 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4177 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4178 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4179 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4180 (CollisionSound != UUID.Zero)
4181 )
4182 {
4183 pa.OnCollisionUpdate += PhysicsCollision;
4184 pa.SubscribeEvents(1000);
4185 }
4186 }
4187 }
4188 else // it already has a physical representation
4189 {
4190 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4191 }
4192 }
4193 4561
4194 if (SetVD) 4562 if ((SetPhantom && !UsePhysics && !SetVD) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
4563 || (Shape.PathCurve == (byte)Extrusion.Flexible))
4195 { 4564 {
4196 // If the above logic worked (this is urgent candidate to unit tests!)
4197 // we now have a physicsactor.
4198 // Defensive programming calls for a check here.
4199 // Better would be throwing an exception that could be catched by a unit test as the internal
4200 // logic should make sure, this Physactor is always here.
4201 if (pa != null) 4565 if (pa != null)
4202 { 4566 {
4203 pa.SetVolumeDetect(1); 4567 if(wasUsingPhysics)
4204 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active 4568 ParentGroup.Scene.RemovePhysicalPrim(1);
4205 VolumeDetectActive = true; 4569 RemoveFromPhysics();
4206 } 4570 }
4571
4572 Velocity = new Vector3(0, 0, 0);
4573 Acceleration = new Vector3(0, 0, 0);
4574 if (ParentGroup.RootPart == this)
4575 AngularVelocity = new Vector3(0, 0, 0);
4207 } 4576 }
4208 else if (SetVD != wasVD) 4577 else if (SetVD != wasVD)
4209 { 4578 {
4210 // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like 4579 if (ParentGroup.Scene.CollidablePrims)
4211 // (mumbles, well, at least if you have infinte CPU powers :-)) 4580 {
4212 if (pa != null) 4581 if (pa == null)
4213 pa.SetVolumeDetect(0); 4582 {
4583 AddToPhysics(UsePhysics, SetPhantom, building, false);
4584 pa = PhysActor;
4585/*
4586 if (pa != null)
4587 {
4588 if (
4589// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4590// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4591// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4592// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4593// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4594// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4595 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4596 ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) ||
4597 (CollisionSound != UUID.Zero)
4598 )
4599 {
4600 pa.OnCollisionUpdate += PhysicsCollision;
4601 pa.SubscribeEvents(1000);
4602 }
4603 }
4604*/
4605 }
4606 else // it already has a physical representation
4607 {
4608 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4609/* moved into DoPhysicsPropertyUpdate
4610 if(VolumeDetectActive)
4611 pa.SetVolumeDetect(1);
4612 else
4613 pa.SetVolumeDetect(0);
4614*/
4214 4615
4215 RemFlag(PrimFlags.Phantom); 4616 if (pa.Building != building)
4216 VolumeDetectActive = false; 4617 pa.Building = building;
4217 } 4618 }
4218 4619
4219 if (SetTemporary) 4620 UpdatePhysicsSubscribedEvents();
4220 { 4621 }
4221 AddFlag(PrimFlags.TemporaryOnRez); 4622 }
4222 }
4223 else
4224 {
4225 RemFlag(PrimFlags.TemporaryOnRez);
4226 }
4227 4623
4228 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); 4624 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4229 4625
4626 // and last in case we have a new actor and not building
4627
4230 if (ParentGroup != null) 4628 if (ParentGroup != null)
4231 { 4629 {
4232 ParentGroup.HasGroupChanged = true; 4630 ParentGroup.HasGroupChanged = true;
4233 ScheduleFullUpdate(); 4631 ScheduleFullUpdate();
4234 } 4632 }
4235 4633
4236// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); 4634// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4237 } 4635 }
4238 4636
4239 /// <summary> 4637 /// <summary>
4240 /// Adds this part to the physics scene. 4638 /// Adds this part to the physics scene.
4639 /// and sets the PhysActor property
4241 /// </summary> 4640 /// </summary>
4242 /// <remarks>This method also sets the PhysActor property.</remarks> 4641 /// <param name="isPhysical">Add this prim as physical.</param>
4243 /// <param name="rigidBody">Add this prim with a rigid body.</param> 4642 /// <param name="isPhantom">Add this prim as phantom.</param>
4244 /// <returns> 4643 /// <param name="building">tells physics to delay full construction of object</param>
4245 /// The physics actor. null if there was a failure. 4644 /// <param name="applyDynamics">applies velocities, force and torque</param>
4246 /// </returns> 4645 private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
4247 private void AddToPhysics(bool isPhysical, bool isPhantom, bool applyDynamics) 4646 {
4248 {
4249 PhysicsActor pa; 4647 PhysicsActor pa;
4250 4648
4251 Vector3 velocity = Velocity; 4649 Vector3 velocity = Velocity;
4252 Vector3 rotationalVelocity = AngularVelocity;; 4650 Vector3 rotationalVelocity = AngularVelocity;;
4253 4651
4254 try 4652 try
4255 { 4653 {
4256 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4654 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4257 string.Format("{0}/{1}", Name, UUID), 4655 string.Format("{0}/{1}", Name, UUID),
4258 Shape, 4656 Shape,
4259 AbsolutePosition, 4657 AbsolutePosition,
4260 Scale, 4658 Scale,
4261 GetWorldRotation(), 4659 GetWorldRotation(),
4262 isPhysical, 4660 isPhysical,
4263 isPhantom, 4661 isPhantom,
4264 PhysicsShapeType, 4662 PhysicsShapeType,
4265 m_localId); 4663 m_localId);
4266 } 4664 }
4267 catch (Exception e) 4665 catch (Exception e)
4268 { 4666 {
4269 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e); 4667 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom. e={1}", m_uuid, e);
4270 pa = null; 4668 pa = null;
4271 } 4669 }
4272 4670
4273 if (pa != null) 4671 if (pa != null)
4274 { 4672 {
4275 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 4673 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
@@ -4282,11 +4680,21 @@ namespace OpenSim.Region.Framework.Scenes
4282 4680
4283 if (VolumeDetectActive) // change if not the default only 4681 if (VolumeDetectActive) // change if not the default only
4284 pa.SetVolumeDetect(1); 4682 pa.SetVolumeDetect(1);
4683
4684 if (m_vehicleParams != null && LocalId == ParentGroup.RootPart.LocalId)
4685 m_vehicleParams.SetVehicle(pa);
4686
4285 // we are going to tell rest of code about physics so better have this here 4687 // we are going to tell rest of code about physics so better have this here
4286 PhysActor = pa; 4688 PhysActor = pa;
4287 4689
4690 // DoPhysicsPropertyUpdate(isPhysical, true);
4691 // lets expand it here just with what it really needs to do
4692
4288 if (isPhysical) 4693 if (isPhysical)
4289 { 4694 {
4695 if (ParentGroup.RootPart.KeyframeMotion != null)
4696 ParentGroup.RootPart.KeyframeMotion.Stop();
4697 ParentGroup.RootPart.KeyframeMotion = null;
4290 ParentGroup.Scene.AddPhysicalPrim(1); 4698 ParentGroup.Scene.AddPhysicalPrim(1);
4291 4699
4292 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 4700 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
@@ -4303,19 +4711,34 @@ namespace OpenSim.Region.Framework.Scenes
4303 } 4711 }
4304 } 4712 }
4305 4713
4306 if (applyDynamics) 4714 if (applyDynamics)
4307 // do independent of isphysical so parameters get setted (at least some) 4715 // do independent of isphysical so parameters get setted (at least some)
4308 { 4716 {
4309 Velocity = velocity; 4717 Velocity = velocity;
4310 AngularVelocity = rotationalVelocity; 4718 AngularVelocity = rotationalVelocity;
4311// pa.Velocity = velocity; 4719// pa.Velocity = velocity;
4312 pa.RotationalVelocity = rotationalVelocity; 4720 pa.RotationalVelocity = rotationalVelocity;
4721
4722 // if not vehicle and root part apply force and torque
4723 if ((m_vehicleParams == null || m_vehicleParams.Type == Vehicle.TYPE_NONE)
4724 && LocalId == ParentGroup.RootPart.LocalId)
4725 {
4726 pa.Force = Force;
4727 pa.Torque = Torque;
4728 }
4313 } 4729 }
4314 4730
4315 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); 4731// if (Shape.SculptEntry)
4732// CheckSculptAndLoad();
4733// else
4734 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
4735
4736 if (!building)
4737 pa.Building = false;
4316 } 4738 }
4317 4739
4318 PhysActor = pa; 4740 PhysActor = pa;
4741
4319 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this); 4742 ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this);
4320 } 4743 }
4321 4744
@@ -4324,13 +4747,21 @@ namespace OpenSim.Region.Framework.Scenes
4324 /// </summary> 4747 /// </summary>
4325 /// <remarks> 4748 /// <remarks>
4326 /// This isn't the same as turning off physical, since even without being physical the prim has a physics 4749 /// This isn't the same as turning off physical, since even without being physical the prim has a physics
4327 /// representation for collision detection. Rather, this would be used in situations such as making a prim 4750 /// representation for collision detection.
4328 /// phantom.
4329 /// </remarks> 4751 /// </remarks>
4330 public void RemoveFromPhysics() 4752 public void RemoveFromPhysics()
4331 { 4753 {
4332 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this); 4754 PhysicsActor pa = PhysActor;
4333 ParentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 4755 if (pa != null)
4756 {
4757 pa.OnCollisionUpdate -= PhysicsCollision;
4758 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
4759 pa.OnOutOfBounds -= PhysicsOutOfBounds;
4760
4761 ParentGroup.Scene.PhysicsScene.RemovePrim(pa);
4762
4763 ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this);
4764 }
4334 PhysActor = null; 4765 PhysActor = null;
4335 } 4766 }
4336 4767
@@ -4462,6 +4893,8 @@ namespace OpenSim.Region.Framework.Scenes
4462 { 4893 {
4463// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); 4894// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4464 4895
4896 return;
4897
4465 if (ParentGroup.IsDeleted) 4898 if (ParentGroup.IsDeleted)
4466 return; 4899 return;
4467 4900
@@ -4542,6 +4975,44 @@ namespace OpenSim.Region.Framework.Scenes
4542 ScheduleFullUpdate(); 4975 ScheduleFullUpdate();
4543 } 4976 }
4544 4977
4978
4979 private void UpdatePhysicsSubscribedEvents()
4980 {
4981 PhysicsActor pa = PhysActor;
4982 if (pa == null)
4983 return;
4984
4985 pa.OnCollisionUpdate -= PhysicsCollision;
4986
4987 bool hassound = (!VolumeDetectActive && CollisionSoundType >= 0 && ((Flags & PrimFlags.Physics) != 0));
4988
4989 scriptEvents CombinedEvents = AggregateScriptEvents;
4990
4991 // merge with root part
4992 if (ParentGroup != null && ParentGroup.RootPart != null)
4993 CombinedEvents |= ParentGroup.RootPart.AggregateScriptEvents;
4994
4995 // submit to this part case
4996 if (VolumeDetectActive)
4997 CombinedEvents &= PhyscicsVolumeDtcSubsEvents;
4998 else if ((Flags & PrimFlags.Phantom) != 0)
4999 CombinedEvents &= PhyscicsPhantonSubsEvents;
5000 else
5001 CombinedEvents &= PhysicsNeededSubsEvents;
5002
5003 if (hassound || CombinedEvents != 0)
5004 {
5005 // subscribe to physics updates.
5006 pa.OnCollisionUpdate += PhysicsCollision;
5007 pa.SubscribeEvents(50); // 20 reports per second
5008 }
5009 else
5010 {
5011 pa.UnSubscribeEvents();
5012 }
5013 }
5014
5015
4545 public void aggregateScriptEvents() 5016 public void aggregateScriptEvents()
4546 { 5017 {
4547 if (ParentGroup == null || ParentGroup.RootPart == null) 5018 if (ParentGroup == null || ParentGroup.RootPart == null)
@@ -4578,40 +5049,32 @@ namespace OpenSim.Region.Framework.Scenes
4578 { 5049 {
4579 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; 5050 objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop;
4580 } 5051 }
4581 5052/*
4582 PhysicsActor pa = PhysActor; 5053 PhysicsActor pa = PhysActor;
4583 5054 if (pa != null)
4584 if (
4585 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4586 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4587 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4588 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4589 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4590 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4591 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4592 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4593 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4594 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4595 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4596 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4597 (CollisionSound != UUID.Zero)
4598 )
4599 { 5055 {
4600 // subscribe to physics updates. 5056 if (
4601 if (pa != null) 5057// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
5058// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
5059// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
5060// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5061// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5062// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5063 ((AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhysicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5064 )
4602 { 5065 {
5066 // subscribe to physics updates.
4603 pa.OnCollisionUpdate += PhysicsCollision; 5067 pa.OnCollisionUpdate += PhysicsCollision;
4604 pa.SubscribeEvents(1000); 5068 pa.SubscribeEvents(1000);
4605 } 5069 }
4606 } 5070 else
4607 else
4608 {
4609 if (pa != null)
4610 { 5071 {
4611 pa.UnSubscribeEvents(); 5072 pa.UnSubscribeEvents();
4612 pa.OnCollisionUpdate -= PhysicsCollision; 5073 pa.OnCollisionUpdate -= PhysicsCollision;
4613 } 5074 }
4614 } 5075 }
5076 */
5077 UpdatePhysicsSubscribedEvents();
4615 5078
4616 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 5079 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4617 //{ 5080 //{
@@ -4742,6 +5205,18 @@ namespace OpenSim.Region.Framework.Scenes
4742 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 5205 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4743 } 5206 }
4744 5207
5208 public void ResetOwnerChangeFlag()
5209 {
5210 List<UUID> inv = Inventory.GetInventoryList();
5211
5212 foreach (UUID itemID in inv)
5213 {
5214 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
5215 item.OwnerChanged = false;
5216 Inventory.UpdateInventoryItem(item, false, false);
5217 }
5218 }
5219
4745 /// <summary> 5220 /// <summary>
4746 /// Record an avatar sitting on this part. 5221 /// Record an avatar sitting on this part.
4747 /// </summary> 5222 /// </summary>