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.cs1332
1 files changed, 865 insertions, 467 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 4bec2d4..37b5554 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,19 @@ 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
307
308 protected bool m_isSelected = false;
309
284 /// <summary> 310 /// <summary>
285 /// Stores media texture data 311 /// Stores media texture data
286 /// </summary> 312 /// </summary>
@@ -296,6 +322,17 @@ namespace OpenSim.Region.Framework.Scenes
296 private UUID m_collisionSound; 322 private UUID m_collisionSound;
297 private float m_collisionSoundVolume; 323 private float m_collisionSoundVolume;
298 324
325
326 private SOPVehicle m_vehicle = null;
327
328 private KeyframeMotion m_keyframeMotion = null;
329
330 public KeyframeMotion KeyframeMotion
331 {
332 get; set;
333 }
334
335
299 #endregion Fields 336 #endregion Fields
300 337
301// ~SceneObjectPart() 338// ~SceneObjectPart()
@@ -338,7 +375,7 @@ namespace OpenSim.Region.Framework.Scenes
338 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 375 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
339 Quaternion rotationOffset, Vector3 offsetPosition) : this() 376 Quaternion rotationOffset, Vector3 offsetPosition) : this()
340 { 377 {
341 m_name = "Primitive"; 378 m_name = "Object";
342 379
343 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 380 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
344 LastOwnerID = CreatorID = OwnerID = ownerID; 381 LastOwnerID = CreatorID = OwnerID = ownerID;
@@ -378,7 +415,7 @@ namespace OpenSim.Region.Framework.Scenes
378 private uint _ownerMask = (uint)PermissionMask.All; 415 private uint _ownerMask = (uint)PermissionMask.All;
379 private uint _groupMask = (uint)PermissionMask.None; 416 private uint _groupMask = (uint)PermissionMask.None;
380 private uint _everyoneMask = (uint)PermissionMask.None; 417 private uint _everyoneMask = (uint)PermissionMask.None;
381 private uint _nextOwnerMask = (uint)PermissionMask.All; 418 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
382 private PrimFlags _flags = PrimFlags.None; 419 private PrimFlags _flags = PrimFlags.None;
383 private DateTime m_expires; 420 private DateTime m_expires;
384 private DateTime m_rezzed; 421 private DateTime m_rezzed;
@@ -472,12 +509,16 @@ namespace OpenSim.Region.Framework.Scenes
472 } 509 }
473 510
474 /// <value> 511 /// <value>
475 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 512 /// Get the inventory list
476 /// </value> 513 /// </value>
477 public TaskInventoryDictionary TaskInventory 514 public TaskInventoryDictionary TaskInventory
478 { 515 {
479 get { return m_inventory.Items; } 516 get {
480 set { m_inventory.Items = value; } 517 return m_inventory.Items;
518 }
519 set {
520 m_inventory.Items = value;
521 }
481 } 522 }
482 523
483 /// <summary> 524 /// <summary>
@@ -527,32 +568,28 @@ namespace OpenSim.Region.Framework.Scenes
527 } 568 }
528 } 569 }
529 570
530 public byte Material 571 public bool PassTouches
531 { 572 {
532 get { return (byte) m_material; } 573 get { return m_passTouches; }
533 set 574 set
534 { 575 {
535 m_material = (Material)value; 576 m_passTouches = value;
536
537 PhysicsActor pa = PhysActor;
538 577
539 if (pa != null) 578 if (ParentGroup != null)
540 pa.SetMaterial((int)value); 579 ParentGroup.HasGroupChanged = true;
541 } 580 }
542 } 581 }
543 582
544 public bool PassTouches 583 public bool IsSelected
545 { 584 {
546 get { return m_passTouches; } 585 get { return m_isSelected; }
547 set 586 set
548 { 587 {
549 m_passTouches = value; 588 m_isSelected = value;
550
551 if (ParentGroup != null) 589 if (ParentGroup != null)
552 ParentGroup.HasGroupChanged = true; 590 ParentGroup.PartSelectChanged(value);
553 } 591 }
554 } 592 }
555
556 593
557 594
558 public Dictionary<int, string> CollisionFilter 595 public Dictionary<int, string> CollisionFilter
@@ -623,14 +660,12 @@ namespace OpenSim.Region.Framework.Scenes
623 set { m_LoopSoundSlavePrims = value; } 660 set { m_LoopSoundSlavePrims = value; }
624 } 661 }
625 662
626
627 public Byte[] TextureAnimation 663 public Byte[] TextureAnimation
628 { 664 {
629 get { return m_TextureAnimation; } 665 get { return m_TextureAnimation; }
630 set { m_TextureAnimation = value; } 666 set { m_TextureAnimation = value; }
631 } 667 }
632 668
633
634 public Byte[] ParticleSystem 669 public Byte[] ParticleSystem
635 { 670 {
636 get { return m_particleSystem; } 671 get { return m_particleSystem; }
@@ -667,8 +702,12 @@ namespace OpenSim.Region.Framework.Scenes
667 { 702 {
668 // If this is a linkset, we don't want the physics engine mucking up our group position here. 703 // If this is a linkset, we don't want the physics engine mucking up our group position here.
669 PhysicsActor actor = PhysActor; 704 PhysicsActor actor = PhysActor;
670 if (actor != null && ParentID == 0) 705 if (ParentID == 0)
671 m_groupPosition = actor.Position; 706 {
707 if (actor != null)
708 m_groupPosition = actor.Position;
709 return m_groupPosition;
710 }
672 711
673 if (ParentGroup.IsAttachment) 712 if (ParentGroup.IsAttachment)
674 { 713 {
@@ -677,12 +716,14 @@ namespace OpenSim.Region.Framework.Scenes
677 return sp.AbsolutePosition; 716 return sp.AbsolutePosition;
678 } 717 }
679 718
719 // use root prim's group position. Physics may have updated it
720 if (ParentGroup.RootPart != this)
721 m_groupPosition = ParentGroup.RootPart.GroupPosition;
680 return m_groupPosition; 722 return m_groupPosition;
681 } 723 }
682 set 724 set
683 { 725 {
684 m_groupPosition = value; 726 m_groupPosition = value;
685
686 PhysicsActor actor = PhysActor; 727 PhysicsActor actor = PhysActor;
687 if (actor != null) 728 if (actor != null)
688 { 729 {
@@ -708,16 +749,6 @@ namespace OpenSim.Region.Framework.Scenes
708 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); 749 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message);
709 } 750 }
710 } 751 }
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 } 752 }
722 } 753 }
723 754
@@ -726,7 +757,7 @@ namespace OpenSim.Region.Framework.Scenes
726 get { return m_offsetPosition; } 757 get { return m_offsetPosition; }
727 set 758 set
728 { 759 {
729// StoreUndoState(); 760 Vector3 oldpos = m_offsetPosition;
730 m_offsetPosition = value; 761 m_offsetPosition = value;
731 762
732 if (ParentGroup != null && !ParentGroup.IsDeleted) 763 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -741,7 +772,22 @@ namespace OpenSim.Region.Framework.Scenes
741 if (ParentGroup.Scene != null) 772 if (ParentGroup.Scene != null)
742 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 773 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
743 } 774 }
775
776 if (!m_parentGroup.m_dupeInProgress)
777 {
778 List<ScenePresence> avs = ParentGroup.GetLinkedAvatars();
779 foreach (ScenePresence av in avs)
780 {
781 if (av.ParentID == m_localId)
782 {
783 Vector3 offset = (m_offsetPosition - oldpos);
784 av.AbsolutePosition += offset;
785 av.SendAvatarDataToAllAgents();
786 }
787 }
788 }
744 } 789 }
790 TriggerScriptChangedEvent(Changed.POSITION);
745 } 791 }
746 } 792 }
747 793
@@ -790,7 +836,7 @@ namespace OpenSim.Region.Framework.Scenes
790 836
791 set 837 set
792 { 838 {
793 StoreUndoState(); 839// StoreUndoState();
794 m_rotationOffset = value; 840 m_rotationOffset = value;
795 841
796 PhysicsActor actor = PhysActor; 842 PhysicsActor actor = PhysActor;
@@ -878,7 +924,7 @@ namespace OpenSim.Region.Framework.Scenes
878 get 924 get
879 { 925 {
880 PhysicsActor actor = PhysActor; 926 PhysicsActor actor = PhysActor;
881 if ((actor != null) && actor.IsPhysical) 927 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
882 { 928 {
883 m_angularVelocity = actor.RotationalVelocity; 929 m_angularVelocity = actor.RotationalVelocity;
884 } 930 }
@@ -890,7 +936,16 @@ namespace OpenSim.Region.Framework.Scenes
890 /// <summary></summary> 936 /// <summary></summary>
891 public Vector3 Acceleration 937 public Vector3 Acceleration
892 { 938 {
893 get { return m_acceleration; } 939 get
940 {
941 PhysicsActor actor = PhysActor;
942 if (actor != null)
943 {
944 m_acceleration = actor.Acceleration;
945 }
946 return m_acceleration;
947 }
948
894 set { m_acceleration = value; } 949 set { m_acceleration = value; }
895 } 950 }
896 951
@@ -947,7 +1002,10 @@ namespace OpenSim.Region.Framework.Scenes
947 public PrimitiveBaseShape Shape 1002 public PrimitiveBaseShape Shape
948 { 1003 {
949 get { return m_shape; } 1004 get { return m_shape; }
950 set { m_shape = value;} 1005 set
1006 {
1007 m_shape = value;
1008 }
951 } 1009 }
952 1010
953 /// <summary> 1011 /// <summary>
@@ -960,7 +1018,6 @@ namespace OpenSim.Region.Framework.Scenes
960 { 1018 {
961 if (m_shape != null) 1019 if (m_shape != null)
962 { 1020 {
963 StoreUndoState();
964 1021
965 m_shape.Scale = value; 1022 m_shape.Scale = value;
966 1023
@@ -987,6 +1044,7 @@ namespace OpenSim.Region.Framework.Scenes
987 } 1044 }
988 1045
989 public UpdateRequired UpdateFlag { get; set; } 1046 public UpdateRequired UpdateFlag { get; set; }
1047 public bool UpdatePhysRequired { get; set; }
990 1048
991 /// <summary> 1049 /// <summary>
992 /// Used for media on a prim. 1050 /// Used for media on a prim.
@@ -1027,10 +1085,7 @@ namespace OpenSim.Region.Framework.Scenes
1027 { 1085 {
1028 get 1086 get
1029 { 1087 {
1030 if (ParentGroup.IsAttachment) 1088 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
1031 return GroupPosition;
1032
1033 return m_offsetPosition + m_groupPosition;
1034 } 1089 }
1035 } 1090 }
1036 1091
@@ -1208,6 +1263,13 @@ namespace OpenSim.Region.Framework.Scenes
1208 _flags = value; 1263 _flags = value;
1209 } 1264 }
1210 } 1265 }
1266
1267 [XmlIgnore]
1268 public bool IsOccupied // KF If an av is sittingon this prim
1269 {
1270 get { return m_occupied; }
1271 set { m_occupied = value; }
1272 }
1211 1273
1212 /// <summary> 1274 /// <summary>
1213 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero 1275 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero
@@ -1267,6 +1329,316 @@ namespace OpenSim.Region.Framework.Scenes
1267 set { m_collisionSoundVolume = value; } 1329 set { m_collisionSoundVolume = value; }
1268 } 1330 }
1269 1331
1332 public float Buoyancy
1333 {
1334 get
1335 {
1336 if (ParentGroup.RootPart == this)
1337 return m_buoyancy;
1338
1339 return ParentGroup.RootPart.Buoyancy;
1340 }
1341 set
1342 {
1343 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1344 {
1345 ParentGroup.RootPart.Buoyancy = value;
1346 return;
1347 }
1348 m_buoyancy = value;
1349 if (PhysActor != null)
1350 PhysActor.Buoyancy = value;
1351 }
1352 }
1353
1354 public Vector3 Force
1355 {
1356 get
1357 {
1358 if (ParentGroup.RootPart == this)
1359 return m_force;
1360
1361 return ParentGroup.RootPart.Force;
1362 }
1363
1364 set
1365 {
1366 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1367 {
1368 ParentGroup.RootPart.Force = value;
1369 return;
1370 }
1371 m_force = value;
1372 if (PhysActor != null)
1373 PhysActor.Force = value;
1374 }
1375 }
1376
1377 public Vector3 Torque
1378 {
1379 get
1380 {
1381 if (ParentGroup.RootPart == this)
1382 return m_torque;
1383
1384 return ParentGroup.RootPart.Torque;
1385 }
1386
1387 set
1388 {
1389 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1390 {
1391 ParentGroup.RootPart.Torque = value;
1392 return;
1393 }
1394 m_torque = value;
1395 if (PhysActor != null)
1396 PhysActor.Torque = value;
1397 }
1398 }
1399
1400 public byte Material
1401 {
1402 get { return (byte)m_material; }
1403 set
1404 {
1405 if (value >= 0 && value <= (byte)SOPMaterialData.MaxMaterial)
1406 {
1407 bool update = false;
1408
1409 if (m_material != (Material)value)
1410 {
1411 update = true;
1412 m_material = (Material)value;
1413 }
1414
1415 if (m_friction != SOPMaterialData.friction(m_material))
1416 {
1417 update = true;
1418 m_friction = SOPMaterialData.friction(m_material);
1419 }
1420
1421 if (m_bounce != SOPMaterialData.bounce(m_material))
1422 {
1423 update = true;
1424 m_bounce = SOPMaterialData.bounce(m_material);
1425 }
1426
1427 if (update)
1428 {
1429 if (PhysActor != null)
1430 {
1431 PhysActor.SetMaterial((int)value);
1432 }
1433 if(ParentGroup != null)
1434 ParentGroup.HasGroupChanged = true;
1435 ScheduleFullUpdateIfNone();
1436 UpdatePhysRequired = true;
1437 }
1438 }
1439 }
1440 }
1441
1442 // not a propriety to move to methods place later
1443 private bool HasMesh()
1444 {
1445 if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh))
1446 return true;
1447 return false;
1448 }
1449
1450 // not a propriety to move to methods place later
1451 public byte DefaultPhysicsShapeType()
1452 {
1453 byte type;
1454
1455 if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh))
1456 type = (byte)PhysShapeType.convex;
1457 else
1458 type = (byte)PhysShapeType.prim;
1459
1460 return type;
1461 }
1462
1463 [XmlIgnore]
1464 public bool UsesComplexCost
1465 {
1466 get
1467 {
1468 byte pst = PhysicsShapeType;
1469 if(pst == (byte) PhysShapeType.none || pst == (byte) PhysShapeType.convex || HasMesh())
1470 return true;
1471 return false;
1472 }
1473 }
1474
1475 [XmlIgnore]
1476 public float PhysicsCost
1477 {
1478 get
1479 {
1480 if(PhysicsShapeType == (byte)PhysShapeType.none)
1481 return 0;
1482
1483 float cost = 0.1f;
1484 if (PhysActor != null)
1485// cost += PhysActor.Cost;
1486
1487 if ((Flags & PrimFlags.Physics) != 0)
1488 cost *= (1.0f + 0.01333f * Scale.LengthSquared()); // 0.01333 == 0.04/3
1489 return cost;
1490 }
1491 }
1492
1493 [XmlIgnore]
1494 public float StreamingCost
1495 {
1496 get
1497 {
1498
1499
1500 return 0.1f;
1501 }
1502 }
1503
1504 [XmlIgnore]
1505 public float SimulationCost
1506 {
1507 get
1508 {
1509 // ignoring scripts. Don't like considering them for this
1510 if((Flags & PrimFlags.Physics) != 0)
1511 return 1.0f;
1512
1513 return 0.5f;
1514 }
1515 }
1516
1517 public byte PhysicsShapeType
1518 {
1519 get { return m_physicsShapeType; }
1520 set
1521 {
1522 byte oldv = m_physicsShapeType;
1523
1524 if (value >= 0 && value <= (byte)PhysShapeType.convex)
1525 {
1526 if (value == (byte)PhysShapeType.none && ParentGroup != null && ParentGroup.RootPart == this)
1527 m_physicsShapeType = DefaultPhysicsShapeType();
1528 else
1529 m_physicsShapeType = value;
1530 }
1531 else
1532 m_physicsShapeType = DefaultPhysicsShapeType();
1533
1534 if (m_physicsShapeType != oldv && ParentGroup != null)
1535 {
1536 if (m_physicsShapeType == (byte)PhysShapeType.none)
1537 {
1538 if (PhysActor != null)
1539 {
1540 Velocity = new Vector3(0, 0, 0);
1541 Acceleration = new Vector3(0, 0, 0);
1542 if (ParentGroup.RootPart == this)
1543 AngularVelocity = new Vector3(0, 0, 0);
1544 ParentGroup.Scene.RemovePhysicalPrim(1);
1545 RemoveFromPhysics();
1546 }
1547 }
1548 else if (PhysActor == null)
1549 ApplyPhysics((uint)Flags, VolumeDetectActive, false);
1550 else
1551 {
1552 PhysActor.PhysicsShapeType = m_physicsShapeType;
1553 if (Shape.SculptEntry)
1554 CheckSculptAndLoad();
1555 }
1556
1557 if (ParentGroup != null)
1558 ParentGroup.HasGroupChanged = true;
1559 }
1560
1561 if (m_physicsShapeType != value)
1562 {
1563 UpdatePhysRequired = true;
1564 }
1565 }
1566 }
1567
1568 public float Density // in kg/m^3
1569 {
1570 get { return m_density; }
1571 set
1572 {
1573 if (value >=1 && value <= 22587.0)
1574 {
1575 m_density = value;
1576 UpdatePhysRequired = true;
1577 }
1578
1579 ScheduleFullUpdateIfNone();
1580
1581 if (ParentGroup != null)
1582 ParentGroup.HasGroupChanged = true;
1583 }
1584 }
1585
1586 public float GravityModifier
1587 {
1588 get { return m_gravitymod; }
1589 set
1590 {
1591 if( value >= -1 && value <=28.0f)
1592 {
1593 m_gravitymod = value;
1594 UpdatePhysRequired = true;
1595 }
1596
1597 ScheduleFullUpdateIfNone();
1598
1599 if (ParentGroup != null)
1600 ParentGroup.HasGroupChanged = true;
1601
1602 }
1603 }
1604
1605 public float Friction
1606 {
1607 get { return m_friction; }
1608 set
1609 {
1610 if (value >= 0 && value <= 255.0f)
1611 {
1612 m_friction = value;
1613 UpdatePhysRequired = true;
1614 }
1615
1616 ScheduleFullUpdateIfNone();
1617
1618 if (ParentGroup != null)
1619 ParentGroup.HasGroupChanged = true;
1620 }
1621 }
1622
1623 public float Bounciness
1624 {
1625 get { return m_bounce; }
1626 set
1627 {
1628 if (value >= 0 && value <= 1.0f)
1629 {
1630 m_bounce = value;
1631 UpdatePhysRequired = true;
1632 }
1633
1634 ScheduleFullUpdateIfNone();
1635
1636 if (ParentGroup != null)
1637 ParentGroup.HasGroupChanged = true;
1638 }
1639 }
1640
1641
1270 #endregion Public Properties with only Get 1642 #endregion Public Properties with only Get
1271 1643
1272 private uint ApplyMask(uint val, bool set, uint mask) 1644 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1432,7 +1804,7 @@ namespace OpenSim.Region.Framework.Scenes
1432 impulse = newimpulse; 1804 impulse = newimpulse;
1433 } 1805 }
1434 1806
1435 ParentGroup.applyAngularImpulse(impulse); 1807 ParentGroup.ApplyAngularImpulse(impulse);
1436 } 1808 }
1437 1809
1438 /// <summary> 1810 /// <summary>
@@ -1442,20 +1814,24 @@ namespace OpenSim.Region.Framework.Scenes
1442 /// </summary> 1814 /// </summary>
1443 /// <param name="impulsei">Vector force</param> 1815 /// <param name="impulsei">Vector force</param>
1444 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> 1816 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
1445 public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF) 1817
1818 // this is actualy Set Torque.. keeping naming so not to edit lslapi also
1819 public void SetAngularImpulse(Vector3 torquei, bool localGlobalTF)
1446 { 1820 {
1447 Vector3 impulse = impulsei; 1821 Vector3 torque = torquei;
1448 1822
1449 if (localGlobalTF) 1823 if (localGlobalTF)
1450 { 1824 {
1825/*
1451 Quaternion grot = GetWorldRotation(); 1826 Quaternion grot = GetWorldRotation();
1452 Quaternion AXgrot = grot; 1827 Quaternion AXgrot = grot;
1453 Vector3 AXimpulsei = impulsei; 1828 Vector3 AXimpulsei = impulsei;
1454 Vector3 newimpulse = AXimpulsei * AXgrot; 1829 Vector3 newimpulse = AXimpulsei * AXgrot;
1455 impulse = newimpulse; 1830 */
1831 torque *= GetWorldRotation();
1456 } 1832 }
1457 1833
1458 ParentGroup.setAngularImpulse(impulse); 1834 Torque = torque;
1459 } 1835 }
1460 1836
1461 /// <summary> 1837 /// <summary>
@@ -1463,17 +1839,23 @@ namespace OpenSim.Region.Framework.Scenes
1463 /// </summary> 1839 /// </summary>
1464 /// <param name="rootObjectFlags"></param> 1840 /// <param name="rootObjectFlags"></param>
1465 /// <param name="VolumeDetectActive"></param> 1841 /// <param name="VolumeDetectActive"></param>
1466 public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive) 1842 /// <param name="building"></param>
1843
1844 public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building)
1467 { 1845 {
1846 VolumeDetectActive = _VolumeDetectActive;
1847
1468 if (!ParentGroup.Scene.CollidablePrims) 1848 if (!ParentGroup.Scene.CollidablePrims)
1469 return; 1849 return;
1470 1850
1471// m_log.DebugFormat( 1851 if (PhysicsShapeType == (byte)PhysShapeType.none)
1472// "[SCENE OBJECT PART]: Applying physics to {0} {1}, m_physicalPrim {2}", 1852 return;
1473// Name, LocalId, UUID, m_physicalPrim); 1853
1854 bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0;
1855 bool isPhantom = (_ObjectFlags & (uint)PrimFlags.Phantom) != 0;
1474 1856
1475 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 1857 if (_VolumeDetectActive)
1476 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 1858 isPhantom = true;
1477 1859
1478 if (IsJoint()) 1860 if (IsJoint())
1479 { 1861 {
@@ -1481,22 +1863,11 @@ namespace OpenSim.Region.Framework.Scenes
1481 } 1863 }
1482 else 1864 else
1483 { 1865 {
1484 // Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored 1866 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment
1485 if (VolumeDetectActive) 1867 && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1486 isPhantom = false; 1868 AddToPhysics(isPhysical, isPhantom, building, true);
1487 1869 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 1870 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 } 1871 }
1501 } 1872 }
1502 1873
@@ -1548,6 +1919,12 @@ namespace OpenSim.Region.Framework.Scenes
1548 dupe.Category = Category; 1919 dupe.Category = Category;
1549 dupe.m_rezzed = m_rezzed; 1920 dupe.m_rezzed = m_rezzed;
1550 1921
1922 dupe.m_UndoRedo = null;
1923 dupe.m_isSelected = false;
1924
1925 dupe.IgnoreUndoUpdate = false;
1926 dupe.Undoing = false;
1927
1551 dupe.m_inventory = new SceneObjectPartInventory(dupe); 1928 dupe.m_inventory = new SceneObjectPartInventory(dupe);
1552 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone(); 1929 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone();
1553 1930
@@ -1563,6 +1940,7 @@ namespace OpenSim.Region.Framework.Scenes
1563 1940
1564 // Move afterwards ResetIDs as it clears the localID 1941 // Move afterwards ResetIDs as it clears the localID
1565 dupe.LocalId = localID; 1942 dupe.LocalId = localID;
1943
1566 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 1944 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1567 dupe.LastOwnerID = OwnerID; 1945 dupe.LastOwnerID = OwnerID;
1568 1946
@@ -1582,6 +1960,9 @@ namespace OpenSim.Region.Framework.Scenes
1582 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 1960 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
1583 } 1961 }
1584 1962
1963 if (dupe.PhysActor != null)
1964 dupe.PhysActor.LocalID = localID;
1965
1585 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 1966 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1586 1967
1587// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); 1968// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
@@ -1701,6 +2082,7 @@ namespace OpenSim.Region.Framework.Scenes
1701 2082
1702 /// <summary> 2083 /// <summary>
1703 /// Do a physics propery update for this part. 2084 /// Do a physics propery update for this part.
2085 /// now also updates phantom and volume detector
1704 /// </summary> 2086 /// </summary>
1705 /// <param name="UsePhysics"></param> 2087 /// <param name="UsePhysics"></param>
1706 /// <param name="isNew"></param> 2088 /// <param name="isNew"></param>
@@ -1726,61 +2108,69 @@ namespace OpenSim.Region.Framework.Scenes
1726 { 2108 {
1727 if (pa.IsPhysical) // implies UsePhysics==false for this block 2109 if (pa.IsPhysical) // implies UsePhysics==false for this block
1728 { 2110 {
1729 if (!isNew) 2111 if (!isNew) // implies UsePhysics==false for this block
2112 {
1730 ParentGroup.Scene.RemovePhysicalPrim(1); 2113 ParentGroup.Scene.RemovePhysicalPrim(1);
1731 2114
1732 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 2115 Velocity = new Vector3(0, 0, 0);
1733 pa.OnOutOfBounds -= PhysicsOutOfBounds; 2116 Acceleration = new Vector3(0, 0, 0);
1734 pa.delink(); 2117 if (ParentGroup.RootPart == this)
2118 AngularVelocity = new Vector3(0, 0, 0);
1735 2119
1736 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 2120 if (pa.Phantom && !VolumeDetectActive)
1737 { 2121 {
1738 // destroy all joints connected to this now deactivated body 2122 RemoveFromPhysics();
1739 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); 2123 return;
1740 } 2124 }
1741 2125
1742 // stop client-side interpolation of all joint proxy objects that have just been deleted 2126 pa.IsPhysical = UsePhysics;
1743 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback, 2127 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1744 // which stops client-side interpolation of deactivated joint proxy objects. 2128 pa.OnOutOfBounds -= PhysicsOutOfBounds;
2129 pa.delink();
2130 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
2131 {
2132 // destroy all joints connected to this now deactivated body
2133 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa);
2134 }
2135 }
1745 } 2136 }
1746 2137
1747 if (!UsePhysics && !isNew) 2138 if (pa.IsPhysical != UsePhysics)
1748 { 2139 pa.IsPhysical = UsePhysics;
1749 // reset velocity to 0 on physics switch-off. Without that, the client thinks the
1750 // prim still has velocity and continues to interpolate its position along the old
1751 // velocity-vector.
1752 Velocity = new Vector3(0, 0, 0);
1753 Acceleration = new Vector3(0, 0, 0);
1754 AngularVelocity = new Vector3(0, 0, 0);
1755 //RotationalVelocity = new Vector3(0, 0, 0);
1756 }
1757 2140
1758 pa.IsPhysical = UsePhysics; 2141 if (UsePhysics)
2142 {
2143 if (ParentGroup.RootPart.KeyframeMotion != null)
2144 ParentGroup.RootPart.KeyframeMotion.Stop();
2145 ParentGroup.RootPart.KeyframeMotion = null;
2146 ParentGroup.Scene.AddPhysicalPrim(1);
1759 2147
1760 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 2148 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1761 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 2149 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1762 /// that's not wholesome. Had to make Scene public
1763 //PhysActor = null;
1764 2150
1765 if ((Flags & PrimFlags.Phantom) == 0) 2151 if (ParentID != 0 && ParentID != LocalId)
1766 {
1767 if (UsePhysics)
1768 { 2152 {
1769 ParentGroup.Scene.AddPhysicalPrim(1); 2153 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
1770 2154
1771 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 2155 if (parentPa != null)
1772 pa.OnOutOfBounds += PhysicsOutOfBounds;
1773 if (ParentID != 0 && ParentID != LocalId)
1774 { 2156 {
1775 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; 2157 pa.link(parentPa);
1776
1777 if (parentPa != null)
1778 {
1779 pa.link(parentPa);
1780 }
1781 } 2158 }
1782 } 2159 }
1783 } 2160 }
2161 }
2162
2163 bool phan = ((Flags & PrimFlags.Phantom) != 0);
2164 if (pa.Phantom != phan)
2165 pa.Phantom = phan;
2166
2167// some engines dont' have this check still
2168// if (VolumeDetectActive != pa.IsVolumeDtc)
2169 {
2170 if (VolumeDetectActive)
2171 pa.SetVolumeDetect(1);
2172 else
2173 pa.SetVolumeDetect(0);
1784 } 2174 }
1785 2175
1786 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 2176 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
@@ -1899,15 +2289,29 @@ namespace OpenSim.Region.Framework.Scenes
1899 2289
1900 public Vector3 GetGeometricCenter() 2290 public Vector3 GetGeometricCenter()
1901 { 2291 {
1902 PhysicsActor pa = PhysActor; 2292 // this is not real geometric center but a average of positions relative to root prim acording to
1903 2293 // http://wiki.secondlife.com/wiki/llGetGeometricCenter
1904 if (pa != null) 2294 // ignoring tortured prims details since sl also seems to ignore
1905 return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z); 2295 // so no real use in doing it on physics
1906 else 2296 if (ParentGroup.IsDeleted)
1907 return new Vector3(0, 0, 0); 2297 return new Vector3(0, 0, 0);
2298
2299 return ParentGroup.GetGeometricCenter();
2300
2301 /*
2302 PhysicsActor pa = PhysActor;
2303
2304 if (pa != null)
2305 {
2306 Vector3 vtmp = pa.CenterOfMass;
2307 return vtmp;
2308 }
2309 else
2310 return new Vector3(0, 0, 0);
2311 */
1908 } 2312 }
1909 2313
1910 public float GetMass() 2314 public float GetMass()
1911 { 2315 {
1912 PhysicsActor pa = PhysActor; 2316 PhysicsActor pa = PhysActor;
1913 2317
@@ -1919,12 +2323,7 @@ namespace OpenSim.Region.Framework.Scenes
1919 2323
1920 public Vector3 GetForce() 2324 public Vector3 GetForce()
1921 { 2325 {
1922 PhysicsActor pa = PhysActor; 2326 return Force;
1923
1924 if (pa != null)
1925 return pa.Force;
1926 else
1927 return Vector3.Zero;
1928 } 2327 }
1929 2328
1930 /// <summary> 2329 /// <summary>
@@ -2560,9 +2959,9 @@ namespace OpenSim.Region.Framework.Scenes
2560 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2959 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2561 2960
2562 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2961 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2563 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2962 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2564 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2963 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2565 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2964 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2566 { 2965 {
2567 ParentGroup.AbsolutePosition = newpos; 2966 ParentGroup.AbsolutePosition = newpos;
2568 return; 2967 return;
@@ -2584,17 +2983,18 @@ namespace OpenSim.Region.Framework.Scenes
2584 //Trys to fetch sound id from prim's inventory. 2983 //Trys to fetch sound id from prim's inventory.
2585 //Prim's inventory doesn't support non script items yet 2984 //Prim's inventory doesn't support non script items yet
2586 2985
2587 lock (TaskInventory) 2986 TaskInventory.LockItemsForRead(true);
2987
2988 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2588 { 2989 {
2589 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2990 if (item.Value.Name == sound)
2590 { 2991 {
2591 if (item.Value.Name == sound) 2992 soundID = item.Value.ItemID;
2592 { 2993 break;
2593 soundID = item.Value.ItemID;
2594 break;
2595 }
2596 } 2994 }
2597 } 2995 }
2996
2997 TaskInventory.LockItemsForRead(false);
2598 } 2998 }
2599 2999
2600 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp) 3000 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp)
@@ -2717,6 +3117,19 @@ namespace OpenSim.Region.Framework.Scenes
2717 APIDTarget = Quaternion.Identity; 3117 APIDTarget = Quaternion.Identity;
2718 } 3118 }
2719 3119
3120
3121
3122 public void ScheduleFullUpdateIfNone()
3123 {
3124 if (ParentGroup == null)
3125 return;
3126
3127// ??? ParentGroup.HasGroupChanged = true;
3128
3129 if (UpdateFlag != UpdateRequired.FULL)
3130 ScheduleFullUpdate();
3131 }
3132
2720 /// <summary> 3133 /// <summary>
2721 /// Schedules this prim for a full update 3134 /// Schedules this prim for a full update
2722 /// </summary> 3135 /// </summary>
@@ -2918,8 +3331,8 @@ namespace OpenSim.Region.Framework.Scenes
2918 { 3331 {
2919 const float ROTATION_TOLERANCE = 0.01f; 3332 const float ROTATION_TOLERANCE = 0.01f;
2920 const float VELOCITY_TOLERANCE = 0.001f; 3333 const float VELOCITY_TOLERANCE = 0.001f;
2921 const float POSITION_TOLERANCE = 0.05f; 3334 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2922 const int TIME_MS_TOLERANCE = 3000; 3335 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2923 3336
2924 switch (UpdateFlag) 3337 switch (UpdateFlag)
2925 { 3338 {
@@ -2981,17 +3394,16 @@ namespace OpenSim.Region.Framework.Scenes
2981 if (!UUID.TryParse(sound, out soundID)) 3394 if (!UUID.TryParse(sound, out soundID))
2982 { 3395 {
2983 // search sound file from inventory 3396 // search sound file from inventory
2984 lock (TaskInventory) 3397 TaskInventory.LockItemsForRead(true);
3398 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2985 { 3399 {
2986 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 3400 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
2987 { 3401 {
2988 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 3402 soundID = item.Value.ItemID;
2989 { 3403 break;
2990 soundID = item.Value.ItemID;
2991 break;
2992 }
2993 } 3404 }
2994 } 3405 }
3406 TaskInventory.LockItemsForRead(false);
2995 } 3407 }
2996 3408
2997 if (soundID == UUID.Zero) 3409 if (soundID == UUID.Zero)
@@ -3076,10 +3488,13 @@ namespace OpenSim.Region.Framework.Scenes
3076 3488
3077 public void SetBuoyancy(float fvalue) 3489 public void SetBuoyancy(float fvalue)
3078 { 3490 {
3079 PhysicsActor pa = PhysActor; 3491 Buoyancy = fvalue;
3080 3492/*
3081 if (pa != null) 3493 if (PhysActor != null)
3082 pa.Buoyancy = fvalue; 3494 {
3495 PhysActor.Buoyancy = fvalue;
3496 }
3497 */
3083 } 3498 }
3084 3499
3085 public void SetDieAtEdge(bool p) 3500 public void SetDieAtEdge(bool p)
@@ -3095,47 +3510,111 @@ namespace OpenSim.Region.Framework.Scenes
3095 PhysicsActor pa = PhysActor; 3510 PhysicsActor pa = PhysActor;
3096 3511
3097 if (pa != null) 3512 if (pa != null)
3098 pa.FloatOnWater = floatYN == 1; 3513 pa.FloatOnWater = (floatYN == 1);
3099 } 3514 }
3100 3515
3101 public void SetForce(Vector3 force) 3516 public void SetForce(Vector3 force)
3102 { 3517 {
3103 PhysicsActor pa = PhysActor; 3518 Force = force;
3519 }
3104 3520
3105 if (pa != null) 3521 public SOPVehicle sopVehicle
3106 pa.Force = force; 3522 {
3523 get
3524 {
3525 return m_vehicle;
3526 }
3527 set
3528 {
3529 m_vehicle = value;
3530 }
3531 }
3532
3533
3534 public int VehicleType
3535 {
3536 get
3537 {
3538 if (m_vehicle == null)
3539 return (int)Vehicle.TYPE_NONE;
3540 else
3541 return (int)m_vehicle.Type;
3542 }
3543 set
3544 {
3545 SetVehicleType(value);
3546 }
3107 } 3547 }
3108 3548
3109 public void SetVehicleType(int type) 3549 public void SetVehicleType(int type)
3110 { 3550 {
3111 PhysicsActor pa = PhysActor; 3551 m_vehicle = null;
3552
3553 if (type == (int)Vehicle.TYPE_NONE)
3554 {
3555 if (_parentID ==0 && PhysActor != null)
3556 PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
3557 return;
3558 }
3559 m_vehicle = new SOPVehicle();
3560 m_vehicle.ProcessTypeChange((Vehicle)type);
3561 {
3562 if (_parentID ==0 && PhysActor != null)
3563 PhysActor.VehicleType = type;
3564 return;
3565 }
3566 }
3112 3567
3113 if (pa != null) 3568 public void SetVehicleFlags(int param, bool remove)
3114 pa.VehicleType = type; 3569 {
3570 if (m_vehicle == null)
3571 return;
3572
3573 m_vehicle.ProcessVehicleFlags(param, remove);
3574
3575 if (_parentID ==0 && PhysActor != null)
3576 {
3577 PhysActor.VehicleFlags(param, remove);
3578 }
3115 } 3579 }
3116 3580
3117 public void SetVehicleFloatParam(int param, float value) 3581 public void SetVehicleFloatParam(int param, float value)
3118 { 3582 {
3119 PhysicsActor pa = PhysActor; 3583 if (m_vehicle == null)
3584 return;
3120 3585
3121 if (pa != null) 3586 m_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
3122 pa.VehicleFloatParam(param, value); 3587
3588 if (_parentID == 0 && PhysActor != null)
3589 {
3590 PhysActor.VehicleFloatParam(param, value);
3591 }
3123 } 3592 }
3124 3593
3125 public void SetVehicleVectorParam(int param, Vector3 value) 3594 public void SetVehicleVectorParam(int param, Vector3 value)
3126 { 3595 {
3127 PhysicsActor pa = PhysActor; 3596 if (m_vehicle == null)
3597 return;
3128 3598
3129 if (pa != null) 3599 m_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
3130 pa.VehicleVectorParam(param, value); 3600
3601 if (_parentID == 0 && PhysActor != null)
3602 {
3603 PhysActor.VehicleVectorParam(param, value);
3604 }
3131 } 3605 }
3132 3606
3133 public void SetVehicleRotationParam(int param, Quaternion rotation) 3607 public void SetVehicleRotationParam(int param, Quaternion rotation)
3134 { 3608 {
3135 PhysicsActor pa = PhysActor; 3609 if (m_vehicle == null)
3610 return;
3136 3611
3137 if (pa != null) 3612 m_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
3138 pa.VehicleRotationParam(param, rotation); 3613
3614 if (_parentID == 0 && PhysActor != null)
3615 {
3616 PhysActor.VehicleRotationParam(param, rotation);
3617 }
3139 } 3618 }
3140 3619
3141 /// <summary> 3620 /// <summary>
@@ -3319,13 +3798,6 @@ namespace OpenSim.Region.Framework.Scenes
3319 hasProfileCut = hasDimple; // is it the same thing? 3798 hasProfileCut = hasDimple; // is it the same thing?
3320 } 3799 }
3321 3800
3322 public void SetVehicleFlags(int param, bool remove)
3323 {
3324 if (PhysActor != null)
3325 {
3326 PhysActor.VehicleFlags(param, remove);
3327 }
3328 }
3329 3801
3330 public void SetGroup(UUID groupID, IClientAPI client) 3802 public void SetGroup(UUID groupID, IClientAPI client)
3331 { 3803 {
@@ -3428,68 +3900,18 @@ namespace OpenSim.Region.Framework.Scenes
3428 //ParentGroup.ScheduleGroupForFullUpdate(); 3900 //ParentGroup.ScheduleGroupForFullUpdate();
3429 } 3901 }
3430 3902
3431 public void StoreUndoState() 3903 public void StoreUndoState(ObjectChangeType change)
3432 { 3904 {
3433 StoreUndoState(false); 3905 if (m_UndoRedo == null)
3434 } 3906 m_UndoRedo = new UndoRedoState(5);
3435 3907
3436 public void StoreUndoState(bool forGroup) 3908 lock (m_UndoRedo)
3437 {
3438 if (!Undoing)
3439 { 3909 {
3440 if (!IgnoreUndoUpdate) 3910 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3441 { 3911 {
3442 if (ParentGroup != null) 3912 m_UndoRedo.StoreUndo(this, change);
3443 {
3444 lock (m_undo)
3445 {
3446 if (m_undo.Count > 0)
3447 {
3448 UndoState last = m_undo.Peek();
3449 if (last != null)
3450 {
3451 // TODO: May need to fix for group comparison
3452 if (last.Compare(this))
3453 {
3454 // m_log.DebugFormat(
3455 // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3456 // Name, LocalId, m_undo.Count);
3457
3458 return;
3459 }
3460 }
3461 }
3462
3463 // m_log.DebugFormat(
3464 // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3465 // Name, LocalId, forGroup, m_undo.Count);
3466
3467 if (ParentGroup.GetSceneMaxUndo() > 0)
3468 {
3469 UndoState nUndo = new UndoState(this, forGroup);
3470
3471 m_undo.Push(nUndo);
3472
3473 if (m_redo.Count > 0)
3474 m_redo.Clear();
3475
3476 // m_log.DebugFormat(
3477 // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3478 // Name, LocalId, forGroup, m_undo.Count);
3479 }
3480 }
3481 }
3482 } 3913 }
3483// else
3484// {
3485// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3486// }
3487 } 3914 }
3488// else
3489// {
3490// m_log.DebugFormat(
3491// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3492// }
3493 } 3915 }
3494 3916
3495 /// <summary> 3917 /// <summary>
@@ -3499,84 +3921,46 @@ namespace OpenSim.Region.Framework.Scenes
3499 { 3921 {
3500 get 3922 get
3501 { 3923 {
3502 lock (m_undo) 3924 if (m_UndoRedo == null)
3503 return m_undo.Count; 3925 return 0;
3926 return m_UndoRedo.Count;
3504 } 3927 }
3505 } 3928 }
3506 3929
3507 public void Undo() 3930 public void Undo()
3508 { 3931 {
3509 lock (m_undo) 3932 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3510 { 3933 return;
3511// m_log.DebugFormat(
3512// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3513// Name, LocalId, m_undo.Count);
3514
3515 if (m_undo.Count > 0)
3516 {
3517 UndoState goback = m_undo.Pop();
3518
3519 if (goback != null)
3520 {
3521 UndoState nUndo = null;
3522
3523 if (ParentGroup.GetSceneMaxUndo() > 0)
3524 {
3525 nUndo = new UndoState(this, goback.ForGroup);
3526 }
3527
3528 goback.PlaybackState(this);
3529
3530 if (nUndo != null)
3531 m_redo.Push(nUndo);
3532 }
3533 }
3534 3934
3535// m_log.DebugFormat( 3935 lock (m_UndoRedo)
3536// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3936 {
3537// Name, LocalId, m_undo.Count); 3937 Undoing = true;
3938 m_UndoRedo.Undo(this);
3939 Undoing = false;
3538 } 3940 }
3539 } 3941 }
3540 3942
3541 public void Redo() 3943 public void Redo()
3542 { 3944 {
3543 lock (m_undo) 3945 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3544 { 3946 return;
3545// m_log.DebugFormat(
3546// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3547// Name, LocalId, m_redo.Count);
3548
3549 if (m_redo.Count > 0)
3550 {
3551 UndoState gofwd = m_redo.Pop();
3552
3553 if (gofwd != null)
3554 {
3555 if (ParentGroup.GetSceneMaxUndo() > 0)
3556 {
3557 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3558
3559 m_undo.Push(nUndo);
3560 }
3561
3562 gofwd.PlayfwdState(this);
3563 }
3564 3947
3565// m_log.DebugFormat( 3948 lock (m_UndoRedo)
3566// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3949 {
3567// Name, LocalId, m_redo.Count); 3950 Undoing = true;
3568 } 3951 m_UndoRedo.Redo(this);
3952 Undoing = false;
3569 } 3953 }
3570 } 3954 }
3571 3955
3572 public void ClearUndoState() 3956 public void ClearUndoState()
3573 { 3957 {
3574// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3958 if (m_UndoRedo == null || Undoing)
3959 return;
3575 3960
3576 lock (m_undo) 3961 lock (m_UndoRedo)
3577 { 3962 {
3578 m_undo.Clear(); 3963 m_UndoRedo.Clear();
3579 m_redo.Clear();
3580 } 3964 }
3581 } 3965 }
3582 3966
@@ -4206,6 +4590,27 @@ namespace OpenSim.Region.Framework.Scenes
4206 } 4590 }
4207 } 4591 }
4208 4592
4593
4594 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4595 {
4596 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
4597 return;
4598
4599 if (PhysicsShapeType != (byte)physdata.PhysShapeType)
4600 {
4601 PhysicsShapeType = (byte)physdata.PhysShapeType;
4602
4603 }
4604
4605 if(Density != physdata.Density)
4606 Density = physdata.Density;
4607 if(GravityModifier != physdata.GravitationModifier)
4608 GravityModifier = physdata.GravitationModifier;
4609 if(Friction != physdata.Friction)
4610 Friction = physdata.Friction;
4611 if(Bounciness != physdata.Bounce)
4612 Bounciness = physdata.Bounce;
4613 }
4209 /// <summary> 4614 /// <summary>
4210 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary. 4615 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary.
4211 /// </summary> 4616 /// </summary>
@@ -4213,7 +4618,7 @@ namespace OpenSim.Region.Framework.Scenes
4213 /// <param name="SetTemporary"></param> 4618 /// <param name="SetTemporary"></param>
4214 /// <param name="SetPhantom"></param> 4619 /// <param name="SetPhantom"></param>
4215 /// <param name="SetVD"></param> 4620 /// <param name="SetVD"></param>
4216 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) 4621 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
4217 { 4622 {
4218 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4623 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4219 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4624 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4223,219 +4628,205 @@ namespace OpenSim.Region.Framework.Scenes
4223 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4628 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4224 return; 4629 return;
4225 4630
4226 PhysicsActor pa = PhysActor; 4631 VolumeDetectActive = SetVD;
4227 4632
4228 // Special cases for VD. VD can only be called from a script 4633 // volume detector implies phantom
4229 // and can't be combined with changes to other states. So we can rely 4634 if (VolumeDetectActive)
4230 // that...
4231 // ... if VD is changed, all others are not.
4232 // ... if one of the others is changed, VD is not.
4233 if (SetVD) // VD is active, special logic applies
4234 {
4235 // State machine logic for VolumeDetect
4236 // More logic below
4237 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4238
4239 if (phanReset) // Phantom changes from on to off switch VD off too
4240 {
4241 SetVD = false; // Switch it of for the course of this routine
4242 VolumeDetectActive = false; // and also permanently
4243
4244 if (pa != null)
4245 pa.SetVolumeDetect(0); // Let physics know about it too
4246 }
4247 else
4248 {
4249 // If volumedetect is active we don't want phantom to be applied.
4250 // If this is a new call to VD out of the state "phantom"
4251 // this will also cause the prim to be visible to physics
4252 SetPhantom = false;
4253 }
4254 }
4255
4256 if (UsePhysics && IsJoint())
4257 {
4258 SetPhantom = true; 4635 SetPhantom = true;
4259 }
4260 4636
4261 if (UsePhysics) 4637 if (UsePhysics)
4262 {
4263 AddFlag(PrimFlags.Physics); 4638 AddFlag(PrimFlags.Physics);
4264 if (!wasUsingPhysics)
4265 {
4266 DoPhysicsPropertyUpdate(UsePhysics, false);
4267
4268 if (!ParentGroup.IsDeleted)
4269 {
4270 if (LocalId == ParentGroup.RootPart.LocalId)
4271 {
4272 ParentGroup.CheckSculptAndLoad();
4273 }
4274 }
4275 }
4276 }
4277 else 4639 else
4278 {
4279 RemFlag(PrimFlags.Physics); 4640 RemFlag(PrimFlags.Physics);
4280 if (wasUsingPhysics)
4281 {
4282 DoPhysicsPropertyUpdate(UsePhysics, false);
4283 }
4284 }
4285 4641
4286 if (SetPhantom 4642 if (SetPhantom)
4287 || ParentGroup.IsAttachment
4288 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4289 {
4290 AddFlag(PrimFlags.Phantom); 4643 AddFlag(PrimFlags.Phantom);
4644 else
4645 RemFlag(PrimFlags.Phantom);
4291 4646
4292 if (PhysActor != null) 4647 if (SetTemporary)
4648 AddFlag(PrimFlags.TemporaryOnRez);
4649 else
4650 RemFlag(PrimFlags.TemporaryOnRez);
4651
4652
4653 if (ParentGroup.Scene == null)
4654 return;
4655
4656 PhysicsActor pa = PhysActor;
4657
4658 if (pa != null && building && pa.Building != building)
4659 pa.Building = building;
4660
4661 if ((SetPhantom && !UsePhysics && !SetVD) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
4662 || (Shape.PathCurve == (byte)Extrusion.Flexible))
4663 {
4664 if (pa != null)
4293 { 4665 {
4666 ParentGroup.Scene.RemovePhysicalPrim(1);
4294 RemoveFromPhysics(); 4667 RemoveFromPhysics();
4295 pa = null;
4296 } 4668 }
4669
4670 Velocity = new Vector3(0, 0, 0);
4671 Acceleration = new Vector3(0, 0, 0);
4672 if (ParentGroup.RootPart == this)
4673 AngularVelocity = new Vector3(0, 0, 0);
4297 } 4674 }
4298 else // Not phantom 4675 else
4299 { 4676 {
4300 RemFlag(PrimFlags.Phantom); 4677 if (ParentGroup.Scene.CollidablePrims)
4301
4302 if (ParentGroup.Scene == null)
4303 return;
4304
4305 if (ParentGroup.Scene.CollidablePrims && pa == null)
4306 { 4678 {
4307 pa = AddToPhysics(UsePhysics); 4679 if (pa == null)
4308
4309 if (pa != null)
4310 { 4680 {
4311 pa.SetMaterial(Material); 4681 AddToPhysics(UsePhysics, SetPhantom, building , false);
4312 DoPhysicsPropertyUpdate(UsePhysics, true); 4682 pa = PhysActor;
4313 4683
4314 if (!ParentGroup.IsDeleted) 4684 if (pa != null)
4315 { 4685 {
4316 if (LocalId == ParentGroup.RootPart.LocalId) 4686 if (
4687// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4688// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4689// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4690// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4691// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4692// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4693 ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
4694// (CollisionSound != UUID.Zero)
4695 )
4317 { 4696 {
4318 ParentGroup.CheckSculptAndLoad(); 4697 pa.OnCollisionUpdate += PhysicsCollision;
4698 pa.SubscribeEvents(1000);
4319 } 4699 }
4320 } 4700 }
4321
4322 if (
4323 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4324 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4325 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4326 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4327 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4328 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4329 (CollisionSound != UUID.Zero)
4330 )
4331 {
4332 pa.OnCollisionUpdate += PhysicsCollision;
4333 pa.SubscribeEvents(1000);
4334 }
4335 } 4701 }
4336 } 4702 else // it already has a physical representation
4337 else // it already has a physical representation
4338 {
4339 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4340
4341 if (!ParentGroup.IsDeleted)
4342 { 4703 {
4343 if (LocalId == ParentGroup.RootPart.LocalId) 4704 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4344 { 4705 /* moved into DoPhysicsPropertyUpdate
4345 ParentGroup.CheckSculptAndLoad(); 4706 if(VolumeDetectActive)
4346 } 4707 pa.SetVolumeDetect(1);
4708 else
4709 pa.SetVolumeDetect(0);
4710 */
4711 if (pa.Building != building)
4712 pa.Building = building;
4347 } 4713 }
4348 } 4714 }
4349 } 4715 }
4350
4351 if (SetVD)
4352 {
4353 // If the above logic worked (this is urgent candidate to unit tests!)
4354 // we now have a physicsactor.
4355 // Defensive programming calls for a check here.
4356 // Better would be throwing an exception that could be catched by a unit test as the internal
4357 // logic should make sure, this Physactor is always here.
4358 if (pa != null)
4359 {
4360 pa.SetVolumeDetect(1);
4361 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4362 VolumeDetectActive = true;
4363 }
4364 }
4365 else
4366 {
4367 // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like
4368 // (mumbles, well, at least if you have infinte CPU powers :-))
4369 if (pa != null)
4370 pa.SetVolumeDetect(0);
4371
4372 VolumeDetectActive = false;
4373 }
4374
4375 if (SetTemporary)
4376 {
4377 AddFlag(PrimFlags.TemporaryOnRez);
4378 }
4379 else
4380 {
4381 RemFlag(PrimFlags.TemporaryOnRez);
4382 }
4383 4716
4384 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); 4717 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4385 4718
4719 // and last in case we have a new actor and not building
4720
4386 if (ParentGroup != null) 4721 if (ParentGroup != null)
4387 { 4722 {
4388 ParentGroup.HasGroupChanged = true; 4723 ParentGroup.HasGroupChanged = true;
4389 ScheduleFullUpdate(); 4724 ScheduleFullUpdate();
4390 } 4725 }
4391 4726
4392// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); 4727// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4393 } 4728 }
4394 4729
4395 /// <summary> 4730 /// <summary>
4396 /// Adds this part to the physics scene. 4731 /// Adds this part to the physics scene.
4732 /// and sets the PhysActor property
4397 /// </summary> 4733 /// </summary>
4398 /// <remarks>This method also sets the PhysActor property.</remarks> 4734 /// <param name="isPhysical">Add this prim as physical.</param>
4399 /// <param name="rigidBody">Add this prim with a rigid body.</param> 4735 /// <param name="isPhantom">Add this prim as phantom.</param>
4400 /// <returns> 4736 /// <param name="building">tells physics to delay full construction of object</param>
4401 /// The physics actor. null if there was a failure. 4737 /// <param name="applyDynamics">applies velocities, force and torque</param>
4402 /// </returns> 4738 private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
4403 private PhysicsActor AddToPhysics(bool rigidBody) 4739 {
4404 {
4405 PhysicsActor pa; 4740 PhysicsActor pa;
4406 4741
4742 Vector3 velocity = Velocity;
4743 Vector3 rotationalVelocity = AngularVelocity;;
4744
4407 try 4745 try
4408 { 4746 {
4409 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4747 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4410 string.Format("{0}/{1}", Name, UUID), 4748 string.Format("{0}/{1}", Name, UUID),
4411 Shape, 4749 Shape,
4412 AbsolutePosition, 4750 AbsolutePosition,
4413 Scale, 4751 Scale,
4414 RotationOffset, 4752 GetWorldRotation(),
4415 rigidBody, 4753 isPhysical,
4416 m_localId); 4754 isPhantom,
4755 PhysicsShapeType,
4756 m_localId);
4417 } 4757 }
4418 catch 4758 catch (Exception ex)
4419 { 4759 {
4420 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid); 4760 m_log.ErrorFormat("[SCENE]: AddToPhysics object {0} failed: {1}", m_uuid, ex.Message);
4421 pa = null; 4761 pa = null;
4422 } 4762 }
4423 4763
4424 // FIXME: Ideally we wouldn't set the property here to reduce situations where threads changing physical
4425 // properties can stop on each other. However, DoPhysicsPropertyUpdate() currently relies on PhysActor
4426 // being set.
4427 PhysActor = pa;
4428
4429 // Basic Physics can also return null as well as an exception catch.
4430 if (pa != null) 4764 if (pa != null)
4431 { 4765 {
4432 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 4766 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
4433 pa.SetMaterial(Material); 4767 pa.SetMaterial(Material);
4434 DoPhysicsPropertyUpdate(rigidBody, true); 4768
4769 if (VolumeDetectActive) // change if not the default only
4770 pa.SetVolumeDetect(1);
4771
4772 if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
4773 m_vehicle.SetVehicle(pa);
4774
4775 // we are going to tell rest of code about physics so better have this here
4776 PhysActor = pa;
4777
4778 // DoPhysicsPropertyUpdate(isPhysical, true);
4779 // lets expand it here just with what it really needs to do
4780
4781 if (isPhysical)
4782 {
4783 if (ParentGroup.RootPart.KeyframeMotion != null)
4784 ParentGroup.RootPart.KeyframeMotion.Stop();
4785 ParentGroup.RootPart.KeyframeMotion = null;
4786 ParentGroup.Scene.AddPhysicalPrim(1);
4787
4788 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
4789 pa.OnOutOfBounds += PhysicsOutOfBounds;
4790
4791 if (ParentID != 0 && ParentID != LocalId)
4792 {
4793 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
4794
4795 if (parentPa != null)
4796 {
4797 pa.link(parentPa);
4798 }
4799 }
4800 }
4801
4802 if (applyDynamics)
4803 // do independent of isphysical so parameters get setted (at least some)
4804 {
4805 Velocity = velocity;
4806 AngularVelocity = rotationalVelocity;
4807 pa.Velocity = velocity;
4808 pa.RotationalVelocity = rotationalVelocity;
4809
4810 // if not vehicle and root part apply force and torque
4811 if ((m_vehicle == null || m_vehicle.Type == Vehicle.TYPE_NONE)
4812 && LocalId == ParentGroup.RootPart.LocalId)
4813 {
4814 pa.Force = Force;
4815 pa.Torque = Torque;
4816 }
4817 }
4818
4819 if (Shape.SculptEntry)
4820 CheckSculptAndLoad();
4821 else
4822 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
4823
4824 if (!building)
4825 pa.Building = false;
4435 } 4826 }
4436 4827
4437 return pa; 4828 PhysActor = pa;
4438 } 4829 }
4439 4830
4440 /// <summary> 4831 /// <summary>
4441 /// This removes the part from the physics scene. 4832 /// This removes the part from the physics scene.
@@ -4642,33 +5033,28 @@ namespace OpenSim.Region.Framework.Scenes
4642 } 5033 }
4643 5034
4644 PhysicsActor pa = PhysActor; 5035 PhysicsActor pa = PhysActor;
4645 5036 if (pa != null)
4646 if (
4647 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4648 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4649 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4650 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4651 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4652 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4653 (CollisionSound != UUID.Zero)
4654 )
4655 { 5037 {
4656 // subscribe to physics updates. 5038 if (
4657 if (pa != null) 5039// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
5040// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
5041// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
5042// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5043// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5044// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5045 ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5046 )
4658 { 5047 {
5048 // subscribe to physics updates.
4659 pa.OnCollisionUpdate += PhysicsCollision; 5049 pa.OnCollisionUpdate += PhysicsCollision;
4660 pa.SubscribeEvents(1000); 5050 pa.SubscribeEvents(1000);
4661 } 5051 }
4662 } 5052 else
4663 else
4664 {
4665 if (pa != null)
4666 { 5053 {
4667 pa.UnSubscribeEvents(); 5054 pa.UnSubscribeEvents();
4668 pa.OnCollisionUpdate -= PhysicsCollision; 5055 pa.OnCollisionUpdate -= PhysicsCollision;
4669 } 5056 }
4670 } 5057 }
4671
4672 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 5058 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4673 //{ 5059 //{
4674 // ParentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting; 5060 // ParentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting;
@@ -4795,5 +5181,17 @@ namespace OpenSim.Region.Framework.Scenes
4795 Color color = Color; 5181 Color color = Color;
4796 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 5182 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4797 } 5183 }
5184
5185 public void ResetOwnerChangeFlag()
5186 {
5187 List<UUID> inv = Inventory.GetInventoryList();
5188
5189 foreach (UUID itemID in inv)
5190 {
5191 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
5192 item.OwnerChanged = false;
5193 Inventory.UpdateInventoryItem(item, false, false);
5194 }
5195 }
4798 } 5196 }
4799} 5197}