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.cs1305
1 files changed, 838 insertions, 467 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 046553b..511ab19 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -62,7 +62,8 @@ namespace OpenSim.Region.Framework.Scenes
62 TELEPORT = 512, 62 TELEPORT = 512,
63 REGION_RESTART = 1024, 63 REGION_RESTART = 1024,
64 MEDIA = 2048, 64 MEDIA = 2048,
65 ANIMATION = 16384 65 ANIMATION = 16384,
66 POSITION = 32768
66 } 67 }
67 68
68 // I don't really know where to put this except here. 69 // I don't really know where to put this except here.
@@ -121,6 +122,11 @@ namespace OpenSim.Region.Framework.Scenes
121 /// Denote all sides of the prim 122 /// Denote all sides of the prim
122 /// </value> 123 /// </value>
123 public const int ALL_SIDES = -1; 124 public const int ALL_SIDES = -1;
125
126 private const scriptEvents PhyscicsNeededSubsEvents = (
127 scriptEvents.collision | scriptEvents.collision_start | scriptEvents.collision_end |
128 scriptEvents.land_collision | scriptEvents.land_collision_start | scriptEvents.land_collision_end
129 );
124 130
125 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 131 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
126 132
@@ -182,6 +188,15 @@ namespace OpenSim.Region.Framework.Scenes
182 188
183 public uint TimeStampTerse; 189 public uint TimeStampTerse;
184 190
191 // The following two are to hold the attachment data
192 // while an object is inworld
193 [XmlIgnore]
194 public byte AttachPoint = 0;
195
196 [XmlIgnore]
197 public Vector3 AttachOffset = Vector3.Zero;
198
199 [XmlIgnore]
185 public int STATUS_ROTATE_X; 200 public int STATUS_ROTATE_X;
186 201
187 public int STATUS_ROTATE_Y; 202 public int STATUS_ROTATE_Y;
@@ -208,8 +223,7 @@ namespace OpenSim.Region.Framework.Scenes
208 223
209 public Vector3 RotationAxis = Vector3.One; 224 public Vector3 RotationAxis = Vector3.One;
210 225
211 public bool VolumeDetectActive; // XmlIgnore set to avoid problems with persistance until I come to care for this 226 public bool VolumeDetectActive;
212 // Certainly this must be a persistant setting finally
213 227
214 public bool IsWaitingForFirstSpinUpdatePacket; 228 public bool IsWaitingForFirstSpinUpdatePacket;
215 229
@@ -249,10 +263,10 @@ namespace OpenSim.Region.Framework.Scenes
249 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 263 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
250 private Vector3 m_sitTargetPosition; 264 private Vector3 m_sitTargetPosition;
251 private string m_sitAnimation = "SIT"; 265 private string m_sitAnimation = "SIT";
266 private bool m_occupied; // KF if any av is sitting on this prim
252 private string m_text = String.Empty; 267 private string m_text = String.Empty;
253 private string m_touchName = String.Empty; 268 private string m_touchName = String.Empty;
254 private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5); 269 private UndoRedoState m_UndoRedo = null;
255 private readonly Stack<UndoState> m_redo = new Stack<UndoState>(5);
256 270
257 private bool m_passTouches; 271 private bool m_passTouches;
258 272
@@ -280,7 +294,16 @@ namespace OpenSim.Region.Framework.Scenes
280 protected Vector3 m_lastAcceleration; 294 protected Vector3 m_lastAcceleration;
281 protected Vector3 m_lastAngularVelocity; 295 protected Vector3 m_lastAngularVelocity;
282 protected int m_lastTerseSent; 296 protected int m_lastTerseSent;
283 297 protected float m_buoyancy = 0.0f;
298 protected Vector3 m_force;
299 protected Vector3 m_torque;
300
301 protected byte m_physicsShapeType = (byte)PhysShapeType.prim;
302 protected float m_density = 1000.0f; // in kg/m^3
303 protected float m_gravitymod = 1.0f;
304 protected float m_friction = 0.6f; // wood
305 protected float m_bounce = 0.5f; // wood
306
284 /// <summary> 307 /// <summary>
285 /// Stores media texture data 308 /// Stores media texture data
286 /// </summary> 309 /// </summary>
@@ -296,6 +319,17 @@ namespace OpenSim.Region.Framework.Scenes
296 private UUID m_collisionSound; 319 private UUID m_collisionSound;
297 private float m_collisionSoundVolume; 320 private float m_collisionSoundVolume;
298 321
322
323 private SOPVehicle m_vehicle = null;
324
325 private KeyframeMotion m_keyframeMotion = null;
326
327 public KeyframeMotion KeyframeMotion
328 {
329 get; set;
330 }
331
332
299 #endregion Fields 333 #endregion Fields
300 334
301// ~SceneObjectPart() 335// ~SceneObjectPart()
@@ -338,7 +372,7 @@ namespace OpenSim.Region.Framework.Scenes
338 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 372 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
339 Quaternion rotationOffset, Vector3 offsetPosition) : this() 373 Quaternion rotationOffset, Vector3 offsetPosition) : this()
340 { 374 {
341 m_name = "Primitive"; 375 m_name = "Object";
342 376
343 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 377 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
344 LastOwnerID = CreatorID = OwnerID = ownerID; 378 LastOwnerID = CreatorID = OwnerID = ownerID;
@@ -378,7 +412,7 @@ namespace OpenSim.Region.Framework.Scenes
378 private uint _ownerMask = (uint)PermissionMask.All; 412 private uint _ownerMask = (uint)PermissionMask.All;
379 private uint _groupMask = (uint)PermissionMask.None; 413 private uint _groupMask = (uint)PermissionMask.None;
380 private uint _everyoneMask = (uint)PermissionMask.None; 414 private uint _everyoneMask = (uint)PermissionMask.None;
381 private uint _nextOwnerMask = (uint)PermissionMask.All; 415 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
382 private PrimFlags _flags = PrimFlags.None; 416 private PrimFlags _flags = PrimFlags.None;
383 private DateTime m_expires; 417 private DateTime m_expires;
384 private DateTime m_rezzed; 418 private DateTime m_rezzed;
@@ -472,12 +506,16 @@ namespace OpenSim.Region.Framework.Scenes
472 } 506 }
473 507
474 /// <value> 508 /// <value>
475 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 509 /// Get the inventory list
476 /// </value> 510 /// </value>
477 public TaskInventoryDictionary TaskInventory 511 public TaskInventoryDictionary TaskInventory
478 { 512 {
479 get { return m_inventory.Items; } 513 get {
480 set { m_inventory.Items = value; } 514 return m_inventory.Items;
515 }
516 set {
517 m_inventory.Items = value;
518 }
481 } 519 }
482 520
483 /// <summary> 521 /// <summary>
@@ -527,20 +565,6 @@ namespace OpenSim.Region.Framework.Scenes
527 } 565 }
528 } 566 }
529 567
530 public byte Material
531 {
532 get { return (byte) m_material; }
533 set
534 {
535 m_material = (Material)value;
536
537 PhysicsActor pa = PhysActor;
538
539 if (pa != null)
540 pa.SetMaterial((int)value);
541 }
542 }
543
544 public bool PassTouches 568 public bool PassTouches
545 { 569 {
546 get { return m_passTouches; } 570 get { return m_passTouches; }
@@ -623,14 +647,12 @@ namespace OpenSim.Region.Framework.Scenes
623 set { m_LoopSoundSlavePrims = value; } 647 set { m_LoopSoundSlavePrims = value; }
624 } 648 }
625 649
626
627 public Byte[] TextureAnimation 650 public Byte[] TextureAnimation
628 { 651 {
629 get { return m_TextureAnimation; } 652 get { return m_TextureAnimation; }
630 set { m_TextureAnimation = value; } 653 set { m_TextureAnimation = value; }
631 } 654 }
632 655
633
634 public Byte[] ParticleSystem 656 public Byte[] ParticleSystem
635 { 657 {
636 get { return m_particleSystem; } 658 get { return m_particleSystem; }
@@ -667,8 +689,12 @@ namespace OpenSim.Region.Framework.Scenes
667 { 689 {
668 // If this is a linkset, we don't want the physics engine mucking up our group position here. 690 // If this is a linkset, we don't want the physics engine mucking up our group position here.
669 PhysicsActor actor = PhysActor; 691 PhysicsActor actor = PhysActor;
670 if (actor != null && ParentID == 0) 692 if (ParentID == 0)
671 m_groupPosition = actor.Position; 693 {
694 if (actor != null)
695 m_groupPosition = actor.Position;
696 return m_groupPosition;
697 }
672 698
673 if (ParentGroup.IsAttachment) 699 if (ParentGroup.IsAttachment)
674 { 700 {
@@ -677,12 +703,14 @@ namespace OpenSim.Region.Framework.Scenes
677 return sp.AbsolutePosition; 703 return sp.AbsolutePosition;
678 } 704 }
679 705
706 // use root prim's group position. Physics may have updated it
707 if (ParentGroup.RootPart != this)
708 m_groupPosition = ParentGroup.RootPart.GroupPosition;
680 return m_groupPosition; 709 return m_groupPosition;
681 } 710 }
682 set 711 set
683 { 712 {
684 m_groupPosition = value; 713 m_groupPosition = value;
685
686 PhysicsActor actor = PhysActor; 714 PhysicsActor actor = PhysActor;
687 if (actor != null) 715 if (actor != null)
688 { 716 {
@@ -708,16 +736,6 @@ namespace OpenSim.Region.Framework.Scenes
708 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); 736 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message);
709 } 737 }
710 } 738 }
711
712 // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
713 if (SitTargetAvatar != UUID.Zero)
714 {
715 ScenePresence avatar;
716 if (ParentGroup.Scene.TryGetScenePresence(SitTargetAvatar, out avatar))
717 {
718 avatar.ParentPosition = GetWorldPosition();
719 }
720 }
721 } 739 }
722 } 740 }
723 741
@@ -726,7 +744,7 @@ namespace OpenSim.Region.Framework.Scenes
726 get { return m_offsetPosition; } 744 get { return m_offsetPosition; }
727 set 745 set
728 { 746 {
729// StoreUndoState(); 747 Vector3 oldpos = m_offsetPosition;
730 m_offsetPosition = value; 748 m_offsetPosition = value;
731 749
732 if (ParentGroup != null && !ParentGroup.IsDeleted) 750 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -741,7 +759,22 @@ namespace OpenSim.Region.Framework.Scenes
741 if (ParentGroup.Scene != null) 759 if (ParentGroup.Scene != null)
742 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 760 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
743 } 761 }
762
763 if (!m_parentGroup.m_dupeInProgress)
764 {
765 List<ScenePresence> avs = ParentGroup.GetLinkedAvatars();
766 foreach (ScenePresence av in avs)
767 {
768 if (av.ParentID == m_localId)
769 {
770 Vector3 offset = (m_offsetPosition - oldpos);
771 av.AbsolutePosition += offset;
772 av.SendAvatarDataToAllAgents();
773 }
774 }
775 }
744 } 776 }
777 TriggerScriptChangedEvent(Changed.POSITION);
745 } 778 }
746 } 779 }
747 780
@@ -790,7 +823,7 @@ namespace OpenSim.Region.Framework.Scenes
790 823
791 set 824 set
792 { 825 {
793 StoreUndoState(); 826// StoreUndoState();
794 m_rotationOffset = value; 827 m_rotationOffset = value;
795 828
796 PhysicsActor actor = PhysActor; 829 PhysicsActor actor = PhysActor;
@@ -878,7 +911,7 @@ namespace OpenSim.Region.Framework.Scenes
878 get 911 get
879 { 912 {
880 PhysicsActor actor = PhysActor; 913 PhysicsActor actor = PhysActor;
881 if ((actor != null) && actor.IsPhysical) 914 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
882 { 915 {
883 m_angularVelocity = actor.RotationalVelocity; 916 m_angularVelocity = actor.RotationalVelocity;
884 } 917 }
@@ -890,7 +923,16 @@ namespace OpenSim.Region.Framework.Scenes
890 /// <summary></summary> 923 /// <summary></summary>
891 public Vector3 Acceleration 924 public Vector3 Acceleration
892 { 925 {
893 get { return m_acceleration; } 926 get
927 {
928 PhysicsActor actor = PhysActor;
929 if (actor != null)
930 {
931 m_acceleration = actor.Acceleration;
932 }
933 return m_acceleration;
934 }
935
894 set { m_acceleration = value; } 936 set { m_acceleration = value; }
895 } 937 }
896 938
@@ -947,7 +989,10 @@ namespace OpenSim.Region.Framework.Scenes
947 public PrimitiveBaseShape Shape 989 public PrimitiveBaseShape Shape
948 { 990 {
949 get { return m_shape; } 991 get { return m_shape; }
950 set { m_shape = value;} 992 set
993 {
994 m_shape = value;
995 }
951 } 996 }
952 997
953 /// <summary> 998 /// <summary>
@@ -960,7 +1005,6 @@ namespace OpenSim.Region.Framework.Scenes
960 { 1005 {
961 if (m_shape != null) 1006 if (m_shape != null)
962 { 1007 {
963 StoreUndoState();
964 1008
965 m_shape.Scale = value; 1009 m_shape.Scale = value;
966 1010
@@ -987,6 +1031,7 @@ namespace OpenSim.Region.Framework.Scenes
987 } 1031 }
988 1032
989 public UpdateRequired UpdateFlag { get; set; } 1033 public UpdateRequired UpdateFlag { get; set; }
1034 public bool UpdatePhysRequired { get; set; }
990 1035
991 /// <summary> 1036 /// <summary>
992 /// Used for media on a prim. 1037 /// Used for media on a prim.
@@ -1027,10 +1072,7 @@ namespace OpenSim.Region.Framework.Scenes
1027 { 1072 {
1028 get 1073 get
1029 { 1074 {
1030 if (ParentGroup.IsAttachment) 1075 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
1031 return GroupPosition;
1032
1033 return m_offsetPosition + m_groupPosition;
1034 } 1076 }
1035 } 1077 }
1036 1078
@@ -1208,6 +1250,13 @@ namespace OpenSim.Region.Framework.Scenes
1208 _flags = value; 1250 _flags = value;
1209 } 1251 }
1210 } 1252 }
1253
1254 [XmlIgnore]
1255 public bool IsOccupied // KF If an av is sittingon this prim
1256 {
1257 get { return m_occupied; }
1258 set { m_occupied = value; }
1259 }
1211 1260
1212 /// <summary> 1261 /// <summary>
1213 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero 1262 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero
@@ -1267,6 +1316,316 @@ namespace OpenSim.Region.Framework.Scenes
1267 set { m_collisionSoundVolume = value; } 1316 set { m_collisionSoundVolume = value; }
1268 } 1317 }
1269 1318
1319 public float Buoyancy
1320 {
1321 get
1322 {
1323 if (ParentGroup.RootPart == this)
1324 return m_buoyancy;
1325
1326 return ParentGroup.RootPart.Buoyancy;
1327 }
1328 set
1329 {
1330 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1331 {
1332 ParentGroup.RootPart.Buoyancy = value;
1333 return;
1334 }
1335 m_buoyancy = value;
1336 if (PhysActor != null)
1337 PhysActor.Buoyancy = value;
1338 }
1339 }
1340
1341 public Vector3 Force
1342 {
1343 get
1344 {
1345 if (ParentGroup.RootPart == this)
1346 return m_force;
1347
1348 return ParentGroup.RootPart.Force;
1349 }
1350
1351 set
1352 {
1353 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1354 {
1355 ParentGroup.RootPart.Force = value;
1356 return;
1357 }
1358 m_force = value;
1359 if (PhysActor != null)
1360 PhysActor.Force = value;
1361 }
1362 }
1363
1364 public Vector3 Torque
1365 {
1366 get
1367 {
1368 if (ParentGroup.RootPart == this)
1369 return m_torque;
1370
1371 return ParentGroup.RootPart.Torque;
1372 }
1373
1374 set
1375 {
1376 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1377 {
1378 ParentGroup.RootPart.Torque = value;
1379 return;
1380 }
1381 m_torque = value;
1382 if (PhysActor != null)
1383 PhysActor.Torque = value;
1384 }
1385 }
1386
1387 public byte Material
1388 {
1389 get { return (byte)m_material; }
1390 set
1391 {
1392 if (value >= 0 && value <= (byte)SOPMaterialData.MaxMaterial)
1393 {
1394 bool update = false;
1395
1396 if (m_material != (Material)value)
1397 {
1398 update = true;
1399 m_material = (Material)value;
1400 }
1401
1402 if (m_friction != SOPMaterialData.friction(m_material))
1403 {
1404 update = true;
1405 m_friction = SOPMaterialData.friction(m_material);
1406 }
1407
1408 if (m_bounce != SOPMaterialData.bounce(m_material))
1409 {
1410 update = true;
1411 m_bounce = SOPMaterialData.bounce(m_material);
1412 }
1413
1414 if (update)
1415 {
1416 if (PhysActor != null)
1417 {
1418 PhysActor.SetMaterial((int)value);
1419 }
1420 if(ParentGroup != null)
1421 ParentGroup.HasGroupChanged = true;
1422 ScheduleFullUpdateIfNone();
1423 UpdatePhysRequired = true;
1424 }
1425 }
1426 }
1427 }
1428
1429 // not a propriety to move to methods place later
1430 private bool HasMesh()
1431 {
1432 if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh))
1433 return true;
1434 return false;
1435 }
1436
1437 // not a propriety to move to methods place later
1438 public byte DefaultPhysicsShapeType()
1439 {
1440 byte type;
1441
1442 if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh))
1443 type = (byte)PhysShapeType.convex;
1444 else
1445 type = (byte)PhysShapeType.prim;
1446
1447 return type;
1448 }
1449
1450 [XmlIgnore]
1451 public bool UsesComplexCost
1452 {
1453 get
1454 {
1455 byte pst = PhysicsShapeType;
1456 if(pst == (byte) PhysShapeType.none || pst == (byte) PhysShapeType.convex || HasMesh())
1457 return true;
1458 return false;
1459 }
1460 }
1461
1462 [XmlIgnore]
1463 public float PhysicsCost
1464 {
1465 get
1466 {
1467 if(PhysicsShapeType == (byte)PhysShapeType.none)
1468 return 0;
1469
1470 float cost = 0.1f;
1471 if (PhysActor != null)
1472// cost += PhysActor.Cost;
1473
1474 if ((Flags & PrimFlags.Physics) != 0)
1475 cost *= (1.0f + 0.01333f * Scale.LengthSquared()); // 0.01333 == 0.04/3
1476 return cost;
1477 }
1478 }
1479
1480 [XmlIgnore]
1481 public float StreamingCost
1482 {
1483 get
1484 {
1485
1486
1487 return 0.1f;
1488 }
1489 }
1490
1491 [XmlIgnore]
1492 public float SimulationCost
1493 {
1494 get
1495 {
1496 // ignoring scripts. Don't like considering them for this
1497 if((Flags & PrimFlags.Physics) != 0)
1498 return 1.0f;
1499
1500 return 0.5f;
1501 }
1502 }
1503
1504 public byte PhysicsShapeType
1505 {
1506 get { return m_physicsShapeType; }
1507 set
1508 {
1509 byte oldv = m_physicsShapeType;
1510
1511 if (value >= 0 && value <= (byte)PhysShapeType.convex)
1512 {
1513 if (value == (byte)PhysShapeType.none && ParentGroup != null && ParentGroup.RootPart == this)
1514 m_physicsShapeType = DefaultPhysicsShapeType();
1515 else
1516 m_physicsShapeType = value;
1517 }
1518 else
1519 m_physicsShapeType = DefaultPhysicsShapeType();
1520
1521 if (m_physicsShapeType != oldv && ParentGroup != null)
1522 {
1523 if (m_physicsShapeType == (byte)PhysShapeType.none)
1524 {
1525 if (PhysActor != null)
1526 {
1527 Velocity = new Vector3(0, 0, 0);
1528 Acceleration = new Vector3(0, 0, 0);
1529 if (ParentGroup.RootPart == this)
1530 AngularVelocity = new Vector3(0, 0, 0);
1531 ParentGroup.Scene.RemovePhysicalPrim(1);
1532 RemoveFromPhysics();
1533 }
1534 }
1535 else if (PhysActor == null)
1536 ApplyPhysics((uint)Flags, VolumeDetectActive, false);
1537 else
1538 {
1539 PhysActor.PhysicsShapeType = m_physicsShapeType;
1540 if (Shape.SculptEntry)
1541 CheckSculptAndLoad();
1542 }
1543
1544 if (ParentGroup != null)
1545 ParentGroup.HasGroupChanged = true;
1546 }
1547
1548 if (m_physicsShapeType != value)
1549 {
1550 UpdatePhysRequired = true;
1551 }
1552 }
1553 }
1554
1555 public float Density // in kg/m^3
1556 {
1557 get { return m_density; }
1558 set
1559 {
1560 if (value >=1 && value <= 22587.0)
1561 {
1562 m_density = value;
1563 UpdatePhysRequired = true;
1564 }
1565
1566 ScheduleFullUpdateIfNone();
1567
1568 if (ParentGroup != null)
1569 ParentGroup.HasGroupChanged = true;
1570 }
1571 }
1572
1573 public float GravityModifier
1574 {
1575 get { return m_gravitymod; }
1576 set
1577 {
1578 if( value >= -1 && value <=28.0f)
1579 {
1580 m_gravitymod = value;
1581 UpdatePhysRequired = true;
1582 }
1583
1584 ScheduleFullUpdateIfNone();
1585
1586 if (ParentGroup != null)
1587 ParentGroup.HasGroupChanged = true;
1588
1589 }
1590 }
1591
1592 public float Friction
1593 {
1594 get { return m_friction; }
1595 set
1596 {
1597 if (value >= 0 && value <= 255.0f)
1598 {
1599 m_friction = value;
1600 UpdatePhysRequired = true;
1601 }
1602
1603 ScheduleFullUpdateIfNone();
1604
1605 if (ParentGroup != null)
1606 ParentGroup.HasGroupChanged = true;
1607 }
1608 }
1609
1610 public float Bounciness
1611 {
1612 get { return m_bounce; }
1613 set
1614 {
1615 if (value >= 0 && value <= 1.0f)
1616 {
1617 m_bounce = value;
1618 UpdatePhysRequired = true;
1619 }
1620
1621 ScheduleFullUpdateIfNone();
1622
1623 if (ParentGroup != null)
1624 ParentGroup.HasGroupChanged = true;
1625 }
1626 }
1627
1628
1270 #endregion Public Properties with only Get 1629 #endregion Public Properties with only Get
1271 1630
1272 private uint ApplyMask(uint val, bool set, uint mask) 1631 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1432,7 +1791,7 @@ namespace OpenSim.Region.Framework.Scenes
1432 impulse = newimpulse; 1791 impulse = newimpulse;
1433 } 1792 }
1434 1793
1435 ParentGroup.applyAngularImpulse(impulse); 1794 ParentGroup.ApplyAngularImpulse(impulse);
1436 } 1795 }
1437 1796
1438 /// <summary> 1797 /// <summary>
@@ -1442,20 +1801,24 @@ namespace OpenSim.Region.Framework.Scenes
1442 /// </summary> 1801 /// </summary>
1443 /// <param name="impulsei">Vector force</param> 1802 /// <param name="impulsei">Vector force</param>
1444 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> 1803 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
1445 public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF) 1804
1805 // this is actualy Set Torque.. keeping naming so not to edit lslapi also
1806 public void SetAngularImpulse(Vector3 torquei, bool localGlobalTF)
1446 { 1807 {
1447 Vector3 impulse = impulsei; 1808 Vector3 torque = torquei;
1448 1809
1449 if (localGlobalTF) 1810 if (localGlobalTF)
1450 { 1811 {
1812/*
1451 Quaternion grot = GetWorldRotation(); 1813 Quaternion grot = GetWorldRotation();
1452 Quaternion AXgrot = grot; 1814 Quaternion AXgrot = grot;
1453 Vector3 AXimpulsei = impulsei; 1815 Vector3 AXimpulsei = impulsei;
1454 Vector3 newimpulse = AXimpulsei * AXgrot; 1816 Vector3 newimpulse = AXimpulsei * AXgrot;
1455 impulse = newimpulse; 1817 */
1818 torque *= GetWorldRotation();
1456 } 1819 }
1457 1820
1458 ParentGroup.setAngularImpulse(impulse); 1821 Torque = torque;
1459 } 1822 }
1460 1823
1461 /// <summary> 1824 /// <summary>
@@ -1463,17 +1826,20 @@ namespace OpenSim.Region.Framework.Scenes
1463 /// </summary> 1826 /// </summary>
1464 /// <param name="rootObjectFlags"></param> 1827 /// <param name="rootObjectFlags"></param>
1465 /// <param name="VolumeDetectActive"></param> 1828 /// <param name="VolumeDetectActive"></param>
1466 public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive) 1829 /// <param name="building"></param>
1830
1831 public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building)
1467 { 1832 {
1833 VolumeDetectActive = _VolumeDetectActive; //?? as is used this is redundante
1834
1468 if (!ParentGroup.Scene.CollidablePrims) 1835 if (!ParentGroup.Scene.CollidablePrims)
1469 return; 1836 return;
1470 1837
1471// m_log.DebugFormat( 1838 if (PhysicsShapeType == (byte)PhysShapeType.none)
1472// "[SCENE OBJECT PART]: Applying physics to {0} {1}, m_physicalPrim {2}", 1839 return;
1473// Name, LocalId, UUID, m_physicalPrim);
1474 1840
1475 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 1841 bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0;
1476 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 1842 bool isPhantom = (_ObjectFlags & (uint) PrimFlags.Phantom) != 0;
1477 1843
1478 if (IsJoint()) 1844 if (IsJoint())
1479 { 1845 {
@@ -1481,22 +1847,11 @@ namespace OpenSim.Region.Framework.Scenes
1481 } 1847 }
1482 else 1848 else
1483 { 1849 {
1484 // Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored 1850 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment
1485 if (VolumeDetectActive) 1851 && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1486 isPhantom = false; 1852 AddToPhysics(isPhysical, isPhantom, building, true);
1487 1853 else
1488 // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition 1854 PhysActor = null; // just to be sure
1489 // or flexible
1490 if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1491 {
1492 // Added clarification.. since A rigid body is an object that you can kick around, etc.
1493 bool rigidBody = isPhysical && !isPhantom;
1494
1495 PhysicsActor pa = AddToPhysics(rigidBody);
1496
1497 if (pa != null)
1498 pa.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
1499 }
1500 } 1855 }
1501 } 1856 }
1502 1857
@@ -1548,6 +1903,11 @@ namespace OpenSim.Region.Framework.Scenes
1548 dupe.Category = Category; 1903 dupe.Category = Category;
1549 dupe.m_rezzed = m_rezzed; 1904 dupe.m_rezzed = m_rezzed;
1550 1905
1906 dupe.m_UndoRedo = null;
1907
1908 dupe.IgnoreUndoUpdate = false;
1909 dupe.Undoing = false;
1910
1551 dupe.m_inventory = new SceneObjectPartInventory(dupe); 1911 dupe.m_inventory = new SceneObjectPartInventory(dupe);
1552 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone(); 1912 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone();
1553 1913
@@ -1563,6 +1923,7 @@ namespace OpenSim.Region.Framework.Scenes
1563 1923
1564 // Move afterwards ResetIDs as it clears the localID 1924 // Move afterwards ResetIDs as it clears the localID
1565 dupe.LocalId = localID; 1925 dupe.LocalId = localID;
1926
1566 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 1927 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1567 dupe.LastOwnerID = OwnerID; 1928 dupe.LastOwnerID = OwnerID;
1568 1929
@@ -1582,6 +1943,9 @@ namespace OpenSim.Region.Framework.Scenes
1582 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 1943 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
1583 } 1944 }
1584 1945
1946 if (dupe.PhysActor != null)
1947 dupe.PhysActor.LocalID = localID;
1948
1585 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 1949 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1586 1950
1587// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); 1951// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
@@ -1723,63 +2087,63 @@ namespace OpenSim.Region.Framework.Scenes
1723 { 2087 {
1724 if (pa.IsPhysical) // implies UsePhysics==false for this block 2088 if (pa.IsPhysical) // implies UsePhysics==false for this block
1725 { 2089 {
1726 if (!isNew) 2090 if (!isNew) // implies UsePhysics==false for this block
2091 {
1727 ParentGroup.Scene.RemovePhysicalPrim(1); 2092 ParentGroup.Scene.RemovePhysicalPrim(1);
1728 2093
1729 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 2094 Velocity = new Vector3(0, 0, 0);
1730 pa.OnOutOfBounds -= PhysicsOutOfBounds; 2095 Acceleration = new Vector3(0, 0, 0);
1731 pa.delink(); 2096 if (ParentGroup.RootPart == this)
2097 AngularVelocity = new Vector3(0, 0, 0);
1732 2098
1733 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 2099 if (pa.Phantom)
1734 { 2100 {
1735 // destroy all joints connected to this now deactivated body 2101 RemoveFromPhysics();
1736 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); 2102 return;
1737 } 2103 }
1738 2104
1739 // stop client-side interpolation of all joint proxy objects that have just been deleted 2105 pa.IsPhysical = UsePhysics;
1740 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback, 2106 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1741 // which stops client-side interpolation of deactivated joint proxy objects. 2107 pa.OnOutOfBounds -= PhysicsOutOfBounds;
2108 pa.delink();
2109 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
2110 {
2111 // destroy all joints connected to this now deactivated body
2112 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa);
2113 }
2114 }
1742 } 2115 }
1743 2116
1744 if (!UsePhysics && !isNew) 2117 if (pa.IsPhysical != UsePhysics)
1745 { 2118 pa.IsPhysical = UsePhysics;
1746 // reset velocity to 0 on physics switch-off. Without that, the client thinks the
1747 // prim still has velocity and continues to interpolate its position along the old
1748 // velocity-vector.
1749 Velocity = new Vector3(0, 0, 0);
1750 Acceleration = new Vector3(0, 0, 0);
1751 AngularVelocity = new Vector3(0, 0, 0);
1752 //RotationalVelocity = new Vector3(0, 0, 0);
1753 }
1754 2119
1755 pa.IsPhysical = UsePhysics; 2120 if (UsePhysics)
2121 {
2122 if (ParentGroup.RootPart.KeyframeMotion != null)
2123 ParentGroup.RootPart.KeyframeMotion.Stop();
2124 ParentGroup.RootPart.KeyframeMotion = null;
2125 ParentGroup.Scene.AddPhysicalPrim(1);
1756 2126
1757 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 2127 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1758 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 2128 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1759 /// that's not wholesome. Had to make Scene public
1760 //PhysActor = null;
1761 2129
1762 if ((Flags & PrimFlags.Phantom) == 0) 2130 if (ParentID != 0 && ParentID != LocalId)
1763 {
1764 if (UsePhysics)
1765 { 2131 {
1766 ParentGroup.Scene.AddPhysicalPrim(1); 2132 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
1767 2133
1768 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 2134 if (parentPa != null)
1769 pa.OnOutOfBounds += PhysicsOutOfBounds;
1770 if (ParentID != 0 && ParentID != LocalId)
1771 { 2135 {
1772 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; 2136 pa.link(parentPa);
1773
1774 if (parentPa != null)
1775 {
1776 pa.link(parentPa);
1777 }
1778 } 2137 }
1779 } 2138 }
1780 } 2139 }
1781 } 2140 }
1782 2141
2142 bool phan = ((Flags & PrimFlags.Phantom) != 0);
2143 if (pa.Phantom != phan)
2144 pa.Phantom = phan;
2145
2146
1783 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 2147 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
1784 // mesh data. 2148 // mesh data.
1785 if (Shape.SculptEntry) 2149 if (Shape.SculptEntry)
@@ -1896,15 +2260,29 @@ namespace OpenSim.Region.Framework.Scenes
1896 2260
1897 public Vector3 GetGeometricCenter() 2261 public Vector3 GetGeometricCenter()
1898 { 2262 {
1899 PhysicsActor pa = PhysActor; 2263 // this is not real geometric center but a average of positions relative to root prim acording to
1900 2264 // http://wiki.secondlife.com/wiki/llGetGeometricCenter
1901 if (pa != null) 2265 // ignoring tortured prims details since sl also seems to ignore
1902 return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z); 2266 // so no real use in doing it on physics
1903 else 2267 if (ParentGroup.IsDeleted)
1904 return new Vector3(0, 0, 0); 2268 return new Vector3(0, 0, 0);
2269
2270 return ParentGroup.GetGeometricCenter();
2271
2272 /*
2273 PhysicsActor pa = PhysActor;
2274
2275 if (pa != null)
2276 {
2277 Vector3 vtmp = pa.CenterOfMass;
2278 return vtmp;
2279 }
2280 else
2281 return new Vector3(0, 0, 0);
2282 */
1905 } 2283 }
1906 2284
1907 public float GetMass() 2285 public float GetMass()
1908 { 2286 {
1909 PhysicsActor pa = PhysActor; 2287 PhysicsActor pa = PhysActor;
1910 2288
@@ -1916,12 +2294,7 @@ namespace OpenSim.Region.Framework.Scenes
1916 2294
1917 public Vector3 GetForce() 2295 public Vector3 GetForce()
1918 { 2296 {
1919 PhysicsActor pa = PhysActor; 2297 return Force;
1920
1921 if (pa != null)
1922 return pa.Force;
1923 else
1924 return Vector3.Zero;
1925 } 2298 }
1926 2299
1927 /// <summary> 2300 /// <summary>
@@ -2557,9 +2930,9 @@ namespace OpenSim.Region.Framework.Scenes
2557 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2930 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2558 2931
2559 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2932 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2560 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2933 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2561 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2934 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2562 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2935 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2563 { 2936 {
2564 ParentGroup.AbsolutePosition = newpos; 2937 ParentGroup.AbsolutePosition = newpos;
2565 return; 2938 return;
@@ -2581,17 +2954,18 @@ namespace OpenSim.Region.Framework.Scenes
2581 //Trys to fetch sound id from prim's inventory. 2954 //Trys to fetch sound id from prim's inventory.
2582 //Prim's inventory doesn't support non script items yet 2955 //Prim's inventory doesn't support non script items yet
2583 2956
2584 lock (TaskInventory) 2957 TaskInventory.LockItemsForRead(true);
2958
2959 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2585 { 2960 {
2586 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2961 if (item.Value.Name == sound)
2587 { 2962 {
2588 if (item.Value.Name == sound) 2963 soundID = item.Value.ItemID;
2589 { 2964 break;
2590 soundID = item.Value.ItemID;
2591 break;
2592 }
2593 } 2965 }
2594 } 2966 }
2967
2968 TaskInventory.LockItemsForRead(false);
2595 } 2969 }
2596 2970
2597 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp) 2971 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp)
@@ -2714,6 +3088,19 @@ namespace OpenSim.Region.Framework.Scenes
2714 APIDTarget = Quaternion.Identity; 3088 APIDTarget = Quaternion.Identity;
2715 } 3089 }
2716 3090
3091
3092
3093 public void ScheduleFullUpdateIfNone()
3094 {
3095 if (ParentGroup == null)
3096 return;
3097
3098// ??? ParentGroup.HasGroupChanged = true;
3099
3100 if (UpdateFlag != UpdateRequired.FULL)
3101 ScheduleFullUpdate();
3102 }
3103
2717 /// <summary> 3104 /// <summary>
2718 /// Schedules this prim for a full update 3105 /// Schedules this prim for a full update
2719 /// </summary> 3106 /// </summary>
@@ -2915,8 +3302,8 @@ namespace OpenSim.Region.Framework.Scenes
2915 { 3302 {
2916 const float ROTATION_TOLERANCE = 0.01f; 3303 const float ROTATION_TOLERANCE = 0.01f;
2917 const float VELOCITY_TOLERANCE = 0.001f; 3304 const float VELOCITY_TOLERANCE = 0.001f;
2918 const float POSITION_TOLERANCE = 0.05f; 3305 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2919 const int TIME_MS_TOLERANCE = 3000; 3306 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2920 3307
2921 switch (UpdateFlag) 3308 switch (UpdateFlag)
2922 { 3309 {
@@ -2978,17 +3365,16 @@ namespace OpenSim.Region.Framework.Scenes
2978 if (!UUID.TryParse(sound, out soundID)) 3365 if (!UUID.TryParse(sound, out soundID))
2979 { 3366 {
2980 // search sound file from inventory 3367 // search sound file from inventory
2981 lock (TaskInventory) 3368 TaskInventory.LockItemsForRead(true);
3369 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2982 { 3370 {
2983 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 3371 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
2984 { 3372 {
2985 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 3373 soundID = item.Value.ItemID;
2986 { 3374 break;
2987 soundID = item.Value.ItemID;
2988 break;
2989 }
2990 } 3375 }
2991 } 3376 }
3377 TaskInventory.LockItemsForRead(false);
2992 } 3378 }
2993 3379
2994 if (soundID == UUID.Zero) 3380 if (soundID == UUID.Zero)
@@ -3073,10 +3459,13 @@ namespace OpenSim.Region.Framework.Scenes
3073 3459
3074 public void SetBuoyancy(float fvalue) 3460 public void SetBuoyancy(float fvalue)
3075 { 3461 {
3076 PhysicsActor pa = PhysActor; 3462 Buoyancy = fvalue;
3077 3463/*
3078 if (pa != null) 3464 if (PhysActor != null)
3079 pa.Buoyancy = fvalue; 3465 {
3466 PhysActor.Buoyancy = fvalue;
3467 }
3468 */
3080 } 3469 }
3081 3470
3082 public void SetDieAtEdge(bool p) 3471 public void SetDieAtEdge(bool p)
@@ -3092,47 +3481,111 @@ namespace OpenSim.Region.Framework.Scenes
3092 PhysicsActor pa = PhysActor; 3481 PhysicsActor pa = PhysActor;
3093 3482
3094 if (pa != null) 3483 if (pa != null)
3095 pa.FloatOnWater = floatYN == 1; 3484 pa.FloatOnWater = (floatYN == 1);
3096 } 3485 }
3097 3486
3098 public void SetForce(Vector3 force) 3487 public void SetForce(Vector3 force)
3099 { 3488 {
3100 PhysicsActor pa = PhysActor; 3489 Force = force;
3490 }
3101 3491
3102 if (pa != null) 3492 public SOPVehicle sopVehicle
3103 pa.Force = force; 3493 {
3494 get
3495 {
3496 return m_vehicle;
3497 }
3498 set
3499 {
3500 m_vehicle = value;
3501 }
3502 }
3503
3504
3505 public int VehicleType
3506 {
3507 get
3508 {
3509 if (m_vehicle == null)
3510 return (int)Vehicle.TYPE_NONE;
3511 else
3512 return (int)m_vehicle.Type;
3513 }
3514 set
3515 {
3516 SetVehicleType(value);
3517 }
3104 } 3518 }
3105 3519
3106 public void SetVehicleType(int type) 3520 public void SetVehicleType(int type)
3107 { 3521 {
3108 PhysicsActor pa = PhysActor; 3522 m_vehicle = null;
3523
3524 if (type == (int)Vehicle.TYPE_NONE)
3525 {
3526 if (_parentID ==0 && PhysActor != null)
3527 PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
3528 return;
3529 }
3530 m_vehicle = new SOPVehicle();
3531 m_vehicle.ProcessTypeChange((Vehicle)type);
3532 {
3533 if (_parentID ==0 && PhysActor != null)
3534 PhysActor.VehicleType = type;
3535 return;
3536 }
3537 }
3109 3538
3110 if (pa != null) 3539 public void SetVehicleFlags(int param, bool remove)
3111 pa.VehicleType = type; 3540 {
3541 if (m_vehicle == null)
3542 return;
3543
3544 m_vehicle.ProcessVehicleFlags(param, remove);
3545
3546 if (_parentID ==0 && PhysActor != null)
3547 {
3548 PhysActor.VehicleFlags(param, remove);
3549 }
3112 } 3550 }
3113 3551
3114 public void SetVehicleFloatParam(int param, float value) 3552 public void SetVehicleFloatParam(int param, float value)
3115 { 3553 {
3116 PhysicsActor pa = PhysActor; 3554 if (m_vehicle == null)
3555 return;
3117 3556
3118 if (pa != null) 3557 m_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
3119 pa.VehicleFloatParam(param, value); 3558
3559 if (_parentID == 0 && PhysActor != null)
3560 {
3561 PhysActor.VehicleFloatParam(param, value);
3562 }
3120 } 3563 }
3121 3564
3122 public void SetVehicleVectorParam(int param, Vector3 value) 3565 public void SetVehicleVectorParam(int param, Vector3 value)
3123 { 3566 {
3124 PhysicsActor pa = PhysActor; 3567 if (m_vehicle == null)
3568 return;
3125 3569
3126 if (pa != null) 3570 m_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
3127 pa.VehicleVectorParam(param, value); 3571
3572 if (_parentID == 0 && PhysActor != null)
3573 {
3574 PhysActor.VehicleVectorParam(param, value);
3575 }
3128 } 3576 }
3129 3577
3130 public void SetVehicleRotationParam(int param, Quaternion rotation) 3578 public void SetVehicleRotationParam(int param, Quaternion rotation)
3131 { 3579 {
3132 PhysicsActor pa = PhysActor; 3580 if (m_vehicle == null)
3581 return;
3133 3582
3134 if (pa != null) 3583 m_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
3135 pa.VehicleRotationParam(param, rotation); 3584
3585 if (_parentID == 0 && PhysActor != null)
3586 {
3587 PhysActor.VehicleRotationParam(param, rotation);
3588 }
3136 } 3589 }
3137 3590
3138 /// <summary> 3591 /// <summary>
@@ -3316,13 +3769,6 @@ namespace OpenSim.Region.Framework.Scenes
3316 hasProfileCut = hasDimple; // is it the same thing? 3769 hasProfileCut = hasDimple; // is it the same thing?
3317 } 3770 }
3318 3771
3319 public void SetVehicleFlags(int param, bool remove)
3320 {
3321 if (PhysActor != null)
3322 {
3323 PhysActor.VehicleFlags(param, remove);
3324 }
3325 }
3326 3772
3327 public void SetGroup(UUID groupID, IClientAPI client) 3773 public void SetGroup(UUID groupID, IClientAPI client)
3328 { 3774 {
@@ -3425,68 +3871,18 @@ namespace OpenSim.Region.Framework.Scenes
3425 //ParentGroup.ScheduleGroupForFullUpdate(); 3871 //ParentGroup.ScheduleGroupForFullUpdate();
3426 } 3872 }
3427 3873
3428 public void StoreUndoState() 3874 public void StoreUndoState(ObjectChangeType change)
3429 { 3875 {
3430 StoreUndoState(false); 3876 if (m_UndoRedo == null)
3431 } 3877 m_UndoRedo = new UndoRedoState(5);
3432 3878
3433 public void StoreUndoState(bool forGroup) 3879 lock (m_UndoRedo)
3434 {
3435 if (!Undoing)
3436 { 3880 {
3437 if (!IgnoreUndoUpdate) 3881 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3438 { 3882 {
3439 if (ParentGroup != null) 3883 m_UndoRedo.StoreUndo(this, change);
3440 {
3441 lock (m_undo)
3442 {
3443 if (m_undo.Count > 0)
3444 {
3445 UndoState last = m_undo.Peek();
3446 if (last != null)
3447 {
3448 // TODO: May need to fix for group comparison
3449 if (last.Compare(this))
3450 {
3451 // m_log.DebugFormat(
3452 // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3453 // Name, LocalId, m_undo.Count);
3454
3455 return;
3456 }
3457 }
3458 }
3459
3460 // m_log.DebugFormat(
3461 // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3462 // Name, LocalId, forGroup, m_undo.Count);
3463
3464 if (ParentGroup.GetSceneMaxUndo() > 0)
3465 {
3466 UndoState nUndo = new UndoState(this, forGroup);
3467
3468 m_undo.Push(nUndo);
3469
3470 if (m_redo.Count > 0)
3471 m_redo.Clear();
3472
3473 // m_log.DebugFormat(
3474 // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3475 // Name, LocalId, forGroup, m_undo.Count);
3476 }
3477 }
3478 }
3479 } 3884 }
3480// else
3481// {
3482// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3483// }
3484 } 3885 }
3485// else
3486// {
3487// m_log.DebugFormat(
3488// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3489// }
3490 } 3886 }
3491 3887
3492 /// <summary> 3888 /// <summary>
@@ -3496,84 +3892,46 @@ namespace OpenSim.Region.Framework.Scenes
3496 { 3892 {
3497 get 3893 get
3498 { 3894 {
3499 lock (m_undo) 3895 if (m_UndoRedo == null)
3500 return m_undo.Count; 3896 return 0;
3897 return m_UndoRedo.Count;
3501 } 3898 }
3502 } 3899 }
3503 3900
3504 public void Undo() 3901 public void Undo()
3505 { 3902 {
3506 lock (m_undo) 3903 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3507 { 3904 return;
3508// m_log.DebugFormat(
3509// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3510// Name, LocalId, m_undo.Count);
3511
3512 if (m_undo.Count > 0)
3513 {
3514 UndoState goback = m_undo.Pop();
3515
3516 if (goback != null)
3517 {
3518 UndoState nUndo = null;
3519
3520 if (ParentGroup.GetSceneMaxUndo() > 0)
3521 {
3522 nUndo = new UndoState(this, goback.ForGroup);
3523 }
3524
3525 goback.PlaybackState(this);
3526
3527 if (nUndo != null)
3528 m_redo.Push(nUndo);
3529 }
3530 }
3531 3905
3532// m_log.DebugFormat( 3906 lock (m_UndoRedo)
3533// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3907 {
3534// Name, LocalId, m_undo.Count); 3908 Undoing = true;
3909 m_UndoRedo.Undo(this);
3910 Undoing = false;
3535 } 3911 }
3536 } 3912 }
3537 3913
3538 public void Redo() 3914 public void Redo()
3539 { 3915 {
3540 lock (m_undo) 3916 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3541 { 3917 return;
3542// m_log.DebugFormat(
3543// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3544// Name, LocalId, m_redo.Count);
3545
3546 if (m_redo.Count > 0)
3547 {
3548 UndoState gofwd = m_redo.Pop();
3549
3550 if (gofwd != null)
3551 {
3552 if (ParentGroup.GetSceneMaxUndo() > 0)
3553 {
3554 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3555
3556 m_undo.Push(nUndo);
3557 }
3558
3559 gofwd.PlayfwdState(this);
3560 }
3561 3918
3562// m_log.DebugFormat( 3919 lock (m_UndoRedo)
3563// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3920 {
3564// Name, LocalId, m_redo.Count); 3921 Undoing = true;
3565 } 3922 m_UndoRedo.Redo(this);
3923 Undoing = false;
3566 } 3924 }
3567 } 3925 }
3568 3926
3569 public void ClearUndoState() 3927 public void ClearUndoState()
3570 { 3928 {
3571// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3929 if (m_UndoRedo == null || Undoing)
3930 return;
3572 3931
3573 lock (m_undo) 3932 lock (m_UndoRedo)
3574 { 3933 {
3575 m_undo.Clear(); 3934 m_UndoRedo.Clear();
3576 m_redo.Clear();
3577 } 3935 }
3578 } 3936 }
3579 3937
@@ -4203,6 +4561,27 @@ namespace OpenSim.Region.Framework.Scenes
4203 } 4561 }
4204 } 4562 }
4205 4563
4564
4565 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4566 {
4567 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
4568 return;
4569
4570 if (PhysicsShapeType != (byte)physdata.PhysShapeType)
4571 {
4572 PhysicsShapeType = (byte)physdata.PhysShapeType;
4573
4574 }
4575
4576 if(Density != physdata.Density)
4577 Density = physdata.Density;
4578 if(GravityModifier != physdata.GravitationModifier)
4579 GravityModifier = physdata.GravitationModifier;
4580 if(Friction != physdata.Friction)
4581 Friction = physdata.Friction;
4582 if(Bounciness != physdata.Bounce)
4583 Bounciness = physdata.Bounce;
4584 }
4206 /// <summary> 4585 /// <summary>
4207 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary. 4586 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary.
4208 /// </summary> 4587 /// </summary>
@@ -4210,7 +4589,7 @@ namespace OpenSim.Region.Framework.Scenes
4210 /// <param name="SetTemporary"></param> 4589 /// <param name="SetTemporary"></param>
4211 /// <param name="SetPhantom"></param> 4590 /// <param name="SetPhantom"></param>
4212 /// <param name="SetVD"></param> 4591 /// <param name="SetVD"></param>
4213 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) 4592 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
4214 { 4593 {
4215 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4594 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4216 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4595 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4220,216 +4599,201 @@ namespace OpenSim.Region.Framework.Scenes
4220 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4599 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4221 return; 4600 return;
4222 4601
4223 PhysicsActor pa = PhysActor; 4602 if (UsePhysics)
4603 AddFlag(PrimFlags.Physics);
4604 else
4605 RemFlag(PrimFlags.Physics);
4224 4606
4225 // Special cases for VD. VD can only be called from a script 4607 if (SetPhantom)
4226 // and can't be combined with changes to other states. So we can rely 4608 AddFlag(PrimFlags.Phantom);
4227 // that... 4609 else
4228 // ... if VD is changed, all others are not. 4610 RemFlag(PrimFlags.Phantom);
4229 // ... if one of the others is changed, VD is not.
4230 if (SetVD) // VD is active, special logic applies
4231 {
4232 // State machine logic for VolumeDetect
4233 // More logic below
4234 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4235 4611
4236 if (phanReset) // Phantom changes from on to off switch VD off too 4612 if (SetTemporary)
4237 { 4613 AddFlag(PrimFlags.TemporaryOnRez);
4238 SetVD = false; // Switch it of for the course of this routine 4614 else
4239 VolumeDetectActive = false; // and also permanently 4615 RemFlag(PrimFlags.TemporaryOnRez);
4240 4616
4241 if (pa != null) 4617 VolumeDetectActive = SetVD;
4242 pa.SetVolumeDetect(0); // Let physics know about it too
4243 }
4244 else
4245 {
4246 // If volumedetect is active we don't want phantom to be applied.
4247 // If this is a new call to VD out of the state "phantom"
4248 // this will also cause the prim to be visible to physics
4249 SetPhantom = false;
4250 }
4251 }
4252 4618
4253 if (UsePhysics && IsJoint()) 4619 if (ParentGroup.Scene == null)
4254 { 4620 return;
4255 SetPhantom = true;
4256 }
4257 4621
4258 if (UsePhysics) 4622 PhysicsActor pa = PhysActor;
4259 {
4260 AddFlag(PrimFlags.Physics);
4261 if (!wasUsingPhysics)
4262 {
4263 DoPhysicsPropertyUpdate(UsePhysics, false);
4264 4623
4265 if (!ParentGroup.IsDeleted) 4624 if (pa != null && building && pa.Building != building)
4266 { 4625 pa.Building = building;
4267 if (LocalId == ParentGroup.RootPart.LocalId) 4626
4268 { 4627 if ((SetPhantom && !UsePhysics) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
4269 ParentGroup.CheckSculptAndLoad(); 4628 || (Shape.PathCurve == (byte)Extrusion.Flexible))
4270 }
4271 }
4272 }
4273 }
4274 else
4275 { 4629 {
4276 RemFlag(PrimFlags.Physics); 4630 if (pa != null)
4277 if (wasUsingPhysics)
4278 { 4631 {
4279 DoPhysicsPropertyUpdate(UsePhysics, false); 4632 ParentGroup.Scene.RemovePhysicalPrim(1);
4633 RemoveFromPhysics();
4280 } 4634 }
4281 }
4282 4635
4283 if (SetPhantom 4636 Velocity = new Vector3(0, 0, 0);
4284 || ParentGroup.IsAttachment 4637 Acceleration = new Vector3(0, 0, 0);
4285 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints 4638 if (ParentGroup.RootPart == this)
4286 { 4639 AngularVelocity = new Vector3(0, 0, 0);
4287 AddFlag(PrimFlags.Phantom);
4288
4289 if (PhysActor != null)
4290 RemoveFromPhysics();
4291 } 4640 }
4292 else // Not phantom 4641 else
4293 { 4642 {
4294 RemFlag(PrimFlags.Phantom); 4643 if (ParentGroup.Scene.CollidablePrims)
4295
4296 if (ParentGroup.Scene == null)
4297 return;
4298
4299 if (ParentGroup.Scene.CollidablePrims && pa == null)
4300 { 4644 {
4301 pa = AddToPhysics(UsePhysics); 4645 if (pa == null)
4302
4303 if (pa != null)
4304 { 4646 {
4305 pa.SetMaterial(Material); 4647 AddToPhysics(UsePhysics, SetPhantom, building , false);
4306 DoPhysicsPropertyUpdate(UsePhysics, true); 4648 pa = PhysActor;
4307 4649
4308 if (!ParentGroup.IsDeleted) 4650 if (pa != null)
4309 { 4651 {
4310 if (LocalId == ParentGroup.RootPart.LocalId) 4652 if (
4653// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4654// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4655// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4656// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4657// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4658// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4659 ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
4660// (CollisionSound != UUID.Zero)
4661 )
4311 { 4662 {
4312 ParentGroup.CheckSculptAndLoad(); 4663 pa.OnCollisionUpdate += PhysicsCollision;
4664 pa.SubscribeEvents(1000);
4313 } 4665 }
4314 } 4666 }
4315
4316 if (
4317 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4318 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4319 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4320 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4321 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4322 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4323 (CollisionSound != UUID.Zero)
4324 )
4325 {
4326 pa.OnCollisionUpdate += PhysicsCollision;
4327 pa.SubscribeEvents(1000);
4328 }
4329 } 4667 }
4330 }
4331 else // it already has a physical representation
4332 {
4333 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4334 4668
4335 if (!ParentGroup.IsDeleted) 4669 else // it already has a physical representation
4336 { 4670 {
4337 if (LocalId == ParentGroup.RootPart.LocalId) 4671 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4338 {
4339 ParentGroup.CheckSculptAndLoad();
4340 }
4341 }
4342 }
4343 }
4344
4345 if (SetVD)
4346 {
4347 // If the above logic worked (this is urgent candidate to unit tests!)
4348 // we now have a physicsactor.
4349 // Defensive programming calls for a check here.
4350 // Better would be throwing an exception that could be catched by a unit test as the internal
4351 // logic should make sure, this Physactor is always here.
4352 if (pa != null)
4353 {
4354 pa.SetVolumeDetect(1);
4355 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4356 this.VolumeDetectActive = true;
4357 }
4358 }
4359 else
4360 {
4361 // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like
4362 // (mumbles, well, at least if you have infinte CPU powers :-))
4363 if (pa != null)
4364 PhysActor.SetVolumeDetect(0);
4365 4672
4366 this.VolumeDetectActive = false; 4673 if(VolumeDetectActive)
4367 } 4674 pa.SetVolumeDetect(1);
4675 else
4676 pa.SetVolumeDetect(0);
4368 4677
4369 if (SetTemporary) 4678 if (pa.Building != building)
4370 { 4679 pa.Building = building;
4371 AddFlag(PrimFlags.TemporaryOnRez); 4680 }
4372 } 4681 }
4373 else 4682 }
4374 {
4375 RemFlag(PrimFlags.TemporaryOnRez);
4376 }
4377 4683
4378 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); 4684 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4379 4685
4686 // and last in case we have a new actor and not building
4687
4380 if (ParentGroup != null) 4688 if (ParentGroup != null)
4381 { 4689 {
4382 ParentGroup.HasGroupChanged = true; 4690 ParentGroup.HasGroupChanged = true;
4383 ScheduleFullUpdate(); 4691 ScheduleFullUpdate();
4384 } 4692 }
4385 4693
4386// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); 4694// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4387 } 4695 }
4388 4696
4389 /// <summary> 4697 /// <summary>
4390 /// Adds this part to the physics scene. 4698 /// Adds this part to the physics scene.
4699 /// and sets the PhysActor property
4391 /// </summary> 4700 /// </summary>
4392 /// <remarks>This method also sets the PhysActor property.</remarks> 4701 /// <param name="isPhysical">Add this prim as physical.</param>
4393 /// <param name="rigidBody">Add this prim with a rigid body.</param> 4702 /// <param name="isPhantom">Add this prim as phantom.</param>
4394 /// <returns> 4703 /// <param name="building">tells physics to delay full construction of object</param>
4395 /// The physics actor. null if there was a failure. 4704 /// <param name="applyDynamics">applies velocities, force and torque</param>
4396 /// </returns> 4705 private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
4397 private PhysicsActor AddToPhysics(bool rigidBody) 4706 {
4398 {
4399 PhysicsActor pa; 4707 PhysicsActor pa;
4400 4708
4709 Vector3 velocity = Velocity;
4710 Vector3 rotationalVelocity = AngularVelocity;;
4711
4401 try 4712 try
4402 { 4713 {
4403 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4714 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4404 string.Format("{0}/{1}", Name, UUID), 4715 string.Format("{0}/{1}", Name, UUID),
4405 Shape, 4716 Shape,
4406 AbsolutePosition, 4717 AbsolutePosition,
4407 Scale, 4718 Scale,
4408 RotationOffset, 4719 GetWorldRotation(),
4409 rigidBody, 4720 isPhysical,
4410 m_localId); 4721 isPhantom,
4722 PhysicsShapeType,
4723 m_localId);
4411 } 4724 }
4412 catch 4725 catch (Exception ex)
4413 { 4726 {
4414 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid); 4727 m_log.ErrorFormat("[SCENE]: AddToPhysics object {0} failed: {1}", m_uuid, ex.Message);
4415 pa = null; 4728 pa = null;
4416 } 4729 }
4417 4730
4418 // FIXME: Ideally we wouldn't set the property here to reduce situations where threads changing physical
4419 // properties can stop on each other. However, DoPhysicsPropertyUpdate() currently relies on PhysActor
4420 // being set.
4421 PhysActor = pa;
4422
4423 // Basic Physics can also return null as well as an exception catch.
4424 if (pa != null) 4731 if (pa != null)
4425 { 4732 {
4426 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 4733 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
4427 pa.SetMaterial(Material); 4734 pa.SetMaterial(Material);
4428 DoPhysicsPropertyUpdate(rigidBody, true); 4735
4736 if (VolumeDetectActive) // change if not the default only
4737 pa.SetVolumeDetect(1);
4738
4739 if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
4740 m_vehicle.SetVehicle(pa);
4741
4742 // we are going to tell rest of code about physics so better have this here
4743 PhysActor = pa;
4744
4745 // DoPhysicsPropertyUpdate(isPhysical, true);
4746 // lets expand it here just with what it really needs to do
4747
4748 if (isPhysical)
4749 {
4750 if (ParentGroup.RootPart.KeyframeMotion != null)
4751 ParentGroup.RootPart.KeyframeMotion.Stop();
4752 ParentGroup.RootPart.KeyframeMotion = null;
4753 ParentGroup.Scene.AddPhysicalPrim(1);
4754
4755 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
4756 pa.OnOutOfBounds += PhysicsOutOfBounds;
4757
4758 if (ParentID != 0 && ParentID != LocalId)
4759 {
4760 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
4761
4762 if (parentPa != null)
4763 {
4764 pa.link(parentPa);
4765 }
4766 }
4767 }
4768
4769 if (applyDynamics)
4770 // do independent of isphysical so parameters get setted (at least some)
4771 {
4772 Velocity = velocity;
4773 AngularVelocity = rotationalVelocity;
4774 pa.Velocity = velocity;
4775 pa.RotationalVelocity = rotationalVelocity;
4776
4777 // if not vehicle and root part apply force and torque
4778 if ((m_vehicle == null || m_vehicle.Type == Vehicle.TYPE_NONE)
4779 && LocalId == ParentGroup.RootPart.LocalId)
4780 {
4781 pa.Force = Force;
4782 pa.Torque = Torque;
4783 }
4784 }
4785
4786 if (Shape.SculptEntry)
4787 CheckSculptAndLoad();
4788 else
4789 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
4790
4791 if (!building)
4792 pa.Building = false;
4429 } 4793 }
4430 4794
4431 return pa; 4795 PhysActor = pa;
4432 } 4796 }
4433 4797
4434 /// <summary> 4798 /// <summary>
4435 /// This removes the part from the physics scene. 4799 /// This removes the part from the physics scene.
@@ -4636,33 +5000,28 @@ namespace OpenSim.Region.Framework.Scenes
4636 } 5000 }
4637 5001
4638 PhysicsActor pa = PhysActor; 5002 PhysicsActor pa = PhysActor;
4639 5003 if (pa != null)
4640 if (
4641 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4642 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4643 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4644 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4645 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4646 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4647 (CollisionSound != UUID.Zero)
4648 )
4649 { 5004 {
4650 // subscribe to physics updates. 5005 if (
4651 if (pa != null) 5006// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
5007// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
5008// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
5009// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5010// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5011// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5012 ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5013 )
4652 { 5014 {
5015 // subscribe to physics updates.
4653 pa.OnCollisionUpdate += PhysicsCollision; 5016 pa.OnCollisionUpdate += PhysicsCollision;
4654 pa.SubscribeEvents(1000); 5017 pa.SubscribeEvents(1000);
4655 } 5018 }
4656 } 5019 else
4657 else
4658 {
4659 if (pa != null)
4660 { 5020 {
4661 pa.UnSubscribeEvents(); 5021 pa.UnSubscribeEvents();
4662 pa.OnCollisionUpdate -= PhysicsCollision; 5022 pa.OnCollisionUpdate -= PhysicsCollision;
4663 } 5023 }
4664 } 5024 }
4665
4666 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 5025 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4667 //{ 5026 //{
4668 // ParentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting; 5027 // ParentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting;
@@ -4789,5 +5148,17 @@ namespace OpenSim.Region.Framework.Scenes
4789 Color color = Color; 5148 Color color = Color;
4790 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 5149 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4791 } 5150 }
5151
5152 public void ResetOwnerChangeFlag()
5153 {
5154 List<UUID> inv = Inventory.GetInventoryList();
5155
5156 foreach (UUID itemID in inv)
5157 {
5158 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
5159 item.OwnerChanged = false;
5160 Inventory.UpdateInventoryItem(item, false, false);
5161 }
5162 }
4792 } 5163 }
4793} 5164}