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.cs1378
1 files changed, 901 insertions, 477 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index e3f06f8..6064279 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,18 @@ 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]
200 public Quaternion AttachRotation = Quaternion.Identity;
201
202 [XmlIgnore]
185 public int STATUS_ROTATE_X; 203 public int STATUS_ROTATE_X;
186 204
187 public int STATUS_ROTATE_Y; 205 public int STATUS_ROTATE_Y;
@@ -208,8 +226,7 @@ namespace OpenSim.Region.Framework.Scenes
208 226
209 public Vector3 RotationAxis = Vector3.One; 227 public Vector3 RotationAxis = Vector3.One;
210 228
211 public bool VolumeDetectActive; // XmlIgnore set to avoid problems with persistance until I come to care for this 229 public bool VolumeDetectActive;
212 // Certainly this must be a persistant setting finally
213 230
214 public bool IsWaitingForFirstSpinUpdatePacket; 231 public bool IsWaitingForFirstSpinUpdatePacket;
215 232
@@ -249,10 +266,10 @@ namespace OpenSim.Region.Framework.Scenes
249 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 266 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
250 private Vector3 m_sitTargetPosition; 267 private Vector3 m_sitTargetPosition;
251 private string m_sitAnimation = "SIT"; 268 private string m_sitAnimation = "SIT";
269 private bool m_occupied; // KF if any av is sitting on this prim
252 private string m_text = String.Empty; 270 private string m_text = String.Empty;
253 private string m_touchName = String.Empty; 271 private string m_touchName = String.Empty;
254 private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5); 272 private UndoRedoState m_UndoRedo = null;
255 private readonly Stack<UndoState> m_redo = new Stack<UndoState>(5);
256 273
257 private bool m_passTouches = false; 274 private bool m_passTouches = false;
258 private bool m_passCollisions = false; 275 private bool m_passCollisions = false;
@@ -281,7 +298,19 @@ namespace OpenSim.Region.Framework.Scenes
281 protected Vector3 m_lastAcceleration; 298 protected Vector3 m_lastAcceleration;
282 protected Vector3 m_lastAngularVelocity; 299 protected Vector3 m_lastAngularVelocity;
283 protected int m_lastTerseSent; 300 protected int m_lastTerseSent;
284 301 protected float m_buoyancy = 0.0f;
302 protected Vector3 m_force;
303 protected Vector3 m_torque;
304
305 protected byte m_physicsShapeType = (byte)PhysShapeType.prim;
306 protected float m_density = 1000.0f; // in kg/m^3
307 protected float m_gravitymod = 1.0f;
308 protected float m_friction = 0.6f; // wood
309 protected float m_bounce = 0.5f; // wood
310
311
312 protected bool m_isSelected = false;
313
285 /// <summary> 314 /// <summary>
286 /// Stores media texture data 315 /// Stores media texture data
287 /// </summary> 316 /// </summary>
@@ -297,6 +326,17 @@ namespace OpenSim.Region.Framework.Scenes
297 private UUID m_collisionSound; 326 private UUID m_collisionSound;
298 private float m_collisionSoundVolume; 327 private float m_collisionSoundVolume;
299 328
329
330 private SOPVehicle m_vehicle = null;
331
332 private KeyframeMotion m_keyframeMotion = null;
333
334 public KeyframeMotion KeyframeMotion
335 {
336 get; set;
337 }
338
339
300 #endregion Fields 340 #endregion Fields
301 341
302// ~SceneObjectPart() 342// ~SceneObjectPart()
@@ -339,7 +379,7 @@ namespace OpenSim.Region.Framework.Scenes
339 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 379 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
340 Quaternion rotationOffset, Vector3 offsetPosition) : this() 380 Quaternion rotationOffset, Vector3 offsetPosition) : this()
341 { 381 {
342 m_name = "Primitive"; 382 m_name = "Object";
343 383
344 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 384 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
345 LastOwnerID = CreatorID = OwnerID = ownerID; 385 LastOwnerID = CreatorID = OwnerID = ownerID;
@@ -379,7 +419,7 @@ namespace OpenSim.Region.Framework.Scenes
379 private uint _ownerMask = (uint)PermissionMask.All; 419 private uint _ownerMask = (uint)PermissionMask.All;
380 private uint _groupMask = (uint)PermissionMask.None; 420 private uint _groupMask = (uint)PermissionMask.None;
381 private uint _everyoneMask = (uint)PermissionMask.None; 421 private uint _everyoneMask = (uint)PermissionMask.None;
382 private uint _nextOwnerMask = (uint)PermissionMask.All; 422 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
383 private PrimFlags _flags = PrimFlags.None; 423 private PrimFlags _flags = PrimFlags.None;
384 private DateTime m_expires; 424 private DateTime m_expires;
385 private DateTime m_rezzed; 425 private DateTime m_rezzed;
@@ -473,12 +513,16 @@ namespace OpenSim.Region.Framework.Scenes
473 } 513 }
474 514
475 /// <value> 515 /// <value>
476 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 516 /// Get the inventory list
477 /// </value> 517 /// </value>
478 public TaskInventoryDictionary TaskInventory 518 public TaskInventoryDictionary TaskInventory
479 { 519 {
480 get { return m_inventory.Items; } 520 get {
481 set { m_inventory.Items = value; } 521 return m_inventory.Items;
522 }
523 set {
524 m_inventory.Items = value;
525 }
482 } 526 }
483 527
484 /// <summary> 528 /// <summary>
@@ -528,20 +572,6 @@ namespace OpenSim.Region.Framework.Scenes
528 } 572 }
529 } 573 }
530 574
531 public byte Material
532 {
533 get { return (byte) m_material; }
534 set
535 {
536 m_material = (Material)value;
537
538 PhysicsActor pa = PhysActor;
539
540 if (pa != null)
541 pa.SetMaterial((int)value);
542 }
543 }
544
545 [XmlIgnore] 575 [XmlIgnore]
546 public bool PassTouches 576 public bool PassTouches
547 { 577 {
@@ -567,6 +597,18 @@ namespace OpenSim.Region.Framework.Scenes
567 } 597 }
568 } 598 }
569 599
600 public bool IsSelected
601 {
602 get { return m_isSelected; }
603 set
604 {
605 m_isSelected = value;
606 if (ParentGroup != null)
607 ParentGroup.PartSelectChanged(value);
608 }
609 }
610
611
570 public Dictionary<int, string> CollisionFilter 612 public Dictionary<int, string> CollisionFilter
571 { 613 {
572 get { return m_CollisionFilter; } 614 get { return m_CollisionFilter; }
@@ -635,14 +677,12 @@ namespace OpenSim.Region.Framework.Scenes
635 set { m_LoopSoundSlavePrims = value; } 677 set { m_LoopSoundSlavePrims = value; }
636 } 678 }
637 679
638
639 public Byte[] TextureAnimation 680 public Byte[] TextureAnimation
640 { 681 {
641 get { return m_TextureAnimation; } 682 get { return m_TextureAnimation; }
642 set { m_TextureAnimation = value; } 683 set { m_TextureAnimation = value; }
643 } 684 }
644 685
645
646 public Byte[] ParticleSystem 686 public Byte[] ParticleSystem
647 { 687 {
648 get { return m_particleSystem; } 688 get { return m_particleSystem; }
@@ -679,8 +719,12 @@ namespace OpenSim.Region.Framework.Scenes
679 { 719 {
680 // If this is a linkset, we don't want the physics engine mucking up our group position here. 720 // If this is a linkset, we don't want the physics engine mucking up our group position here.
681 PhysicsActor actor = PhysActor; 721 PhysicsActor actor = PhysActor;
682 if (actor != null && ParentID == 0) 722 if (ParentID == 0)
683 m_groupPosition = actor.Position; 723 {
724 if (actor != null)
725 m_groupPosition = actor.Position;
726 return m_groupPosition;
727 }
684 728
685 if (ParentGroup.IsAttachment) 729 if (ParentGroup.IsAttachment)
686 { 730 {
@@ -689,12 +733,14 @@ namespace OpenSim.Region.Framework.Scenes
689 return sp.AbsolutePosition; 733 return sp.AbsolutePosition;
690 } 734 }
691 735
736 // use root prim's group position. Physics may have updated it
737 if (ParentGroup.RootPart != this)
738 m_groupPosition = ParentGroup.RootPart.GroupPosition;
692 return m_groupPosition; 739 return m_groupPosition;
693 } 740 }
694 set 741 set
695 { 742 {
696 m_groupPosition = value; 743 m_groupPosition = value;
697
698 PhysicsActor actor = PhysActor; 744 PhysicsActor actor = PhysActor;
699 if (actor != null) 745 if (actor != null)
700 { 746 {
@@ -720,16 +766,6 @@ namespace OpenSim.Region.Framework.Scenes
720 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); 766 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message);
721 } 767 }
722 } 768 }
723
724 // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
725 if (SitTargetAvatar != UUID.Zero)
726 {
727 ScenePresence avatar;
728 if (ParentGroup.Scene.TryGetScenePresence(SitTargetAvatar, out avatar))
729 {
730 avatar.ParentPosition = GetWorldPosition();
731 }
732 }
733 } 769 }
734 } 770 }
735 771
@@ -738,7 +774,7 @@ namespace OpenSim.Region.Framework.Scenes
738 get { return m_offsetPosition; } 774 get { return m_offsetPosition; }
739 set 775 set
740 { 776 {
741// StoreUndoState(); 777 Vector3 oldpos = m_offsetPosition;
742 m_offsetPosition = value; 778 m_offsetPosition = value;
743 779
744 if (ParentGroup != null && !ParentGroup.IsDeleted) 780 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -753,7 +789,22 @@ namespace OpenSim.Region.Framework.Scenes
753 if (ParentGroup.Scene != null) 789 if (ParentGroup.Scene != null)
754 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 790 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
755 } 791 }
792
793 if (!m_parentGroup.m_dupeInProgress)
794 {
795 List<ScenePresence> avs = ParentGroup.GetLinkedAvatars();
796 foreach (ScenePresence av in avs)
797 {
798 if (av.ParentID == m_localId)
799 {
800 Vector3 offset = (m_offsetPosition - oldpos);
801 av.AbsolutePosition += offset;
802 av.SendAvatarDataToAllAgents();
803 }
804 }
805 }
756 } 806 }
807 TriggerScriptChangedEvent(Changed.POSITION);
757 } 808 }
758 } 809 }
759 810
@@ -802,7 +853,7 @@ namespace OpenSim.Region.Framework.Scenes
802 853
803 set 854 set
804 { 855 {
805 StoreUndoState(); 856// StoreUndoState();
806 m_rotationOffset = value; 857 m_rotationOffset = value;
807 858
808 PhysicsActor actor = PhysActor; 859 PhysicsActor actor = PhysActor;
@@ -890,7 +941,7 @@ namespace OpenSim.Region.Framework.Scenes
890 get 941 get
891 { 942 {
892 PhysicsActor actor = PhysActor; 943 PhysicsActor actor = PhysActor;
893 if ((actor != null) && actor.IsPhysical) 944 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
894 { 945 {
895 m_angularVelocity = actor.RotationalVelocity; 946 m_angularVelocity = actor.RotationalVelocity;
896 } 947 }
@@ -902,7 +953,16 @@ namespace OpenSim.Region.Framework.Scenes
902 /// <summary></summary> 953 /// <summary></summary>
903 public Vector3 Acceleration 954 public Vector3 Acceleration
904 { 955 {
905 get { return m_acceleration; } 956 get
957 {
958 PhysicsActor actor = PhysActor;
959 if (actor != null)
960 {
961 m_acceleration = actor.Acceleration;
962 }
963 return m_acceleration;
964 }
965
906 set { m_acceleration = value; } 966 set { m_acceleration = value; }
907 } 967 }
908 968
@@ -959,7 +1019,10 @@ namespace OpenSim.Region.Framework.Scenes
959 public PrimitiveBaseShape Shape 1019 public PrimitiveBaseShape Shape
960 { 1020 {
961 get { return m_shape; } 1021 get { return m_shape; }
962 set { m_shape = value;} 1022 set
1023 {
1024 m_shape = value;
1025 }
963 } 1026 }
964 1027
965 /// <summary> 1028 /// <summary>
@@ -972,7 +1035,6 @@ namespace OpenSim.Region.Framework.Scenes
972 { 1035 {
973 if (m_shape != null) 1036 if (m_shape != null)
974 { 1037 {
975 StoreUndoState();
976 1038
977 m_shape.Scale = value; 1039 m_shape.Scale = value;
978 1040
@@ -999,6 +1061,7 @@ namespace OpenSim.Region.Framework.Scenes
999 } 1061 }
1000 1062
1001 public UpdateRequired UpdateFlag { get; set; } 1063 public UpdateRequired UpdateFlag { get; set; }
1064 public bool UpdatePhysRequired { get; set; }
1002 1065
1003 /// <summary> 1066 /// <summary>
1004 /// Used for media on a prim. 1067 /// Used for media on a prim.
@@ -1039,10 +1102,7 @@ namespace OpenSim.Region.Framework.Scenes
1039 { 1102 {
1040 get 1103 get
1041 { 1104 {
1042 if (ParentGroup.IsAttachment) 1105 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
1043 return GroupPosition;
1044
1045 return m_offsetPosition + m_groupPosition;
1046 } 1106 }
1047 } 1107 }
1048 1108
@@ -1220,6 +1280,13 @@ namespace OpenSim.Region.Framework.Scenes
1220 _flags = value; 1280 _flags = value;
1221 } 1281 }
1222 } 1282 }
1283
1284 [XmlIgnore]
1285 public bool IsOccupied // KF If an av is sittingon this prim
1286 {
1287 get { return m_occupied; }
1288 set { m_occupied = value; }
1289 }
1223 1290
1224 /// <summary> 1291 /// <summary>
1225 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero 1292 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero
@@ -1279,6 +1346,316 @@ namespace OpenSim.Region.Framework.Scenes
1279 set { m_collisionSoundVolume = value; } 1346 set { m_collisionSoundVolume = value; }
1280 } 1347 }
1281 1348
1349 public float Buoyancy
1350 {
1351 get
1352 {
1353 if (ParentGroup.RootPart == this)
1354 return m_buoyancy;
1355
1356 return ParentGroup.RootPart.Buoyancy;
1357 }
1358 set
1359 {
1360 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1361 {
1362 ParentGroup.RootPart.Buoyancy = value;
1363 return;
1364 }
1365 m_buoyancy = value;
1366 if (PhysActor != null)
1367 PhysActor.Buoyancy = value;
1368 }
1369 }
1370
1371 public Vector3 Force
1372 {
1373 get
1374 {
1375 if (ParentGroup.RootPart == this)
1376 return m_force;
1377
1378 return ParentGroup.RootPart.Force;
1379 }
1380
1381 set
1382 {
1383 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1384 {
1385 ParentGroup.RootPart.Force = value;
1386 return;
1387 }
1388 m_force = value;
1389 if (PhysActor != null)
1390 PhysActor.Force = value;
1391 }
1392 }
1393
1394 public Vector3 Torque
1395 {
1396 get
1397 {
1398 if (ParentGroup.RootPart == this)
1399 return m_torque;
1400
1401 return ParentGroup.RootPart.Torque;
1402 }
1403
1404 set
1405 {
1406 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1407 {
1408 ParentGroup.RootPart.Torque = value;
1409 return;
1410 }
1411 m_torque = value;
1412 if (PhysActor != null)
1413 PhysActor.Torque = value;
1414 }
1415 }
1416
1417 public byte Material
1418 {
1419 get { return (byte)m_material; }
1420 set
1421 {
1422 if (value >= 0 && value <= (byte)SOPMaterialData.MaxMaterial)
1423 {
1424 bool update = false;
1425
1426 if (m_material != (Material)value)
1427 {
1428 update = true;
1429 m_material = (Material)value;
1430 }
1431
1432 if (m_friction != SOPMaterialData.friction(m_material))
1433 {
1434 update = true;
1435 m_friction = SOPMaterialData.friction(m_material);
1436 }
1437
1438 if (m_bounce != SOPMaterialData.bounce(m_material))
1439 {
1440 update = true;
1441 m_bounce = SOPMaterialData.bounce(m_material);
1442 }
1443
1444 if (update)
1445 {
1446 if (PhysActor != null)
1447 {
1448 PhysActor.SetMaterial((int)value);
1449 }
1450 if(ParentGroup != null)
1451 ParentGroup.HasGroupChanged = true;
1452 ScheduleFullUpdateIfNone();
1453 UpdatePhysRequired = true;
1454 }
1455 }
1456 }
1457 }
1458
1459 // not a propriety to move to methods place later
1460 private bool HasMesh()
1461 {
1462 if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh))
1463 return true;
1464 return false;
1465 }
1466
1467 // not a propriety to move to methods place later
1468 public byte DefaultPhysicsShapeType()
1469 {
1470 byte type;
1471
1472 if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh))
1473 type = (byte)PhysShapeType.convex;
1474 else
1475 type = (byte)PhysShapeType.prim;
1476
1477 return type;
1478 }
1479
1480 [XmlIgnore]
1481 public bool UsesComplexCost
1482 {
1483 get
1484 {
1485 byte pst = PhysicsShapeType;
1486 if(pst == (byte) PhysShapeType.none || pst == (byte) PhysShapeType.convex || HasMesh())
1487 return true;
1488 return false;
1489 }
1490 }
1491
1492 [XmlIgnore]
1493 public float PhysicsCost
1494 {
1495 get
1496 {
1497 if(PhysicsShapeType == (byte)PhysShapeType.none)
1498 return 0;
1499
1500 float cost = 0.1f;
1501 if (PhysActor != null)
1502// cost += PhysActor.Cost;
1503
1504 if ((Flags & PrimFlags.Physics) != 0)
1505 cost *= (1.0f + 0.01333f * Scale.LengthSquared()); // 0.01333 == 0.04/3
1506 return cost;
1507 }
1508 }
1509
1510 [XmlIgnore]
1511 public float StreamingCost
1512 {
1513 get
1514 {
1515
1516
1517 return 0.1f;
1518 }
1519 }
1520
1521 [XmlIgnore]
1522 public float SimulationCost
1523 {
1524 get
1525 {
1526 // ignoring scripts. Don't like considering them for this
1527 if((Flags & PrimFlags.Physics) != 0)
1528 return 1.0f;
1529
1530 return 0.5f;
1531 }
1532 }
1533
1534 public byte PhysicsShapeType
1535 {
1536 get { return m_physicsShapeType; }
1537 set
1538 {
1539 byte oldv = m_physicsShapeType;
1540
1541 if (value >= 0 && value <= (byte)PhysShapeType.convex)
1542 {
1543 if (value == (byte)PhysShapeType.none && ParentGroup != null && ParentGroup.RootPart == this)
1544 m_physicsShapeType = DefaultPhysicsShapeType();
1545 else
1546 m_physicsShapeType = value;
1547 }
1548 else
1549 m_physicsShapeType = DefaultPhysicsShapeType();
1550
1551 if (m_physicsShapeType != oldv && ParentGroup != null)
1552 {
1553 if (m_physicsShapeType == (byte)PhysShapeType.none)
1554 {
1555 if (PhysActor != null)
1556 {
1557 Velocity = new Vector3(0, 0, 0);
1558 Acceleration = new Vector3(0, 0, 0);
1559 if (ParentGroup.RootPart == this)
1560 AngularVelocity = new Vector3(0, 0, 0);
1561 ParentGroup.Scene.RemovePhysicalPrim(1);
1562 RemoveFromPhysics();
1563 }
1564 }
1565 else if (PhysActor == null)
1566 ApplyPhysics((uint)Flags, VolumeDetectActive, false);
1567 else
1568 {
1569 PhysActor.PhysicsShapeType = m_physicsShapeType;
1570 if (Shape.SculptEntry)
1571 CheckSculptAndLoad();
1572 }
1573
1574 if (ParentGroup != null)
1575 ParentGroup.HasGroupChanged = true;
1576 }
1577
1578 if (m_physicsShapeType != value)
1579 {
1580 UpdatePhysRequired = true;
1581 }
1582 }
1583 }
1584
1585 public float Density // in kg/m^3
1586 {
1587 get { return m_density; }
1588 set
1589 {
1590 if (value >=1 && value <= 22587.0)
1591 {
1592 m_density = value;
1593 UpdatePhysRequired = true;
1594 }
1595
1596 ScheduleFullUpdateIfNone();
1597
1598 if (ParentGroup != null)
1599 ParentGroup.HasGroupChanged = true;
1600 }
1601 }
1602
1603 public float GravityModifier
1604 {
1605 get { return m_gravitymod; }
1606 set
1607 {
1608 if( value >= -1 && value <=28.0f)
1609 {
1610 m_gravitymod = value;
1611 UpdatePhysRequired = true;
1612 }
1613
1614 ScheduleFullUpdateIfNone();
1615
1616 if (ParentGroup != null)
1617 ParentGroup.HasGroupChanged = true;
1618
1619 }
1620 }
1621
1622 public float Friction
1623 {
1624 get { return m_friction; }
1625 set
1626 {
1627 if (value >= 0 && value <= 255.0f)
1628 {
1629 m_friction = value;
1630 UpdatePhysRequired = true;
1631 }
1632
1633 ScheduleFullUpdateIfNone();
1634
1635 if (ParentGroup != null)
1636 ParentGroup.HasGroupChanged = true;
1637 }
1638 }
1639
1640 public float Bounciness
1641 {
1642 get { return m_bounce; }
1643 set
1644 {
1645 if (value >= 0 && value <= 1.0f)
1646 {
1647 m_bounce = value;
1648 UpdatePhysRequired = true;
1649 }
1650
1651 ScheduleFullUpdateIfNone();
1652
1653 if (ParentGroup != null)
1654 ParentGroup.HasGroupChanged = true;
1655 }
1656 }
1657
1658
1282 #endregion Public Properties with only Get 1659 #endregion Public Properties with only Get
1283 1660
1284 private uint ApplyMask(uint val, bool set, uint mask) 1661 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1444,7 +1821,7 @@ namespace OpenSim.Region.Framework.Scenes
1444 impulse = newimpulse; 1821 impulse = newimpulse;
1445 } 1822 }
1446 1823
1447 ParentGroup.applyAngularImpulse(impulse); 1824 ParentGroup.ApplyAngularImpulse(impulse);
1448 } 1825 }
1449 1826
1450 /// <summary> 1827 /// <summary>
@@ -1454,20 +1831,24 @@ namespace OpenSim.Region.Framework.Scenes
1454 /// </summary> 1831 /// </summary>
1455 /// <param name="impulsei">Vector force</param> 1832 /// <param name="impulsei">Vector force</param>
1456 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> 1833 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
1457 public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF) 1834
1835 // this is actualy Set Torque.. keeping naming so not to edit lslapi also
1836 public void SetAngularImpulse(Vector3 torquei, bool localGlobalTF)
1458 { 1837 {
1459 Vector3 impulse = impulsei; 1838 Vector3 torque = torquei;
1460 1839
1461 if (localGlobalTF) 1840 if (localGlobalTF)
1462 { 1841 {
1842/*
1463 Quaternion grot = GetWorldRotation(); 1843 Quaternion grot = GetWorldRotation();
1464 Quaternion AXgrot = grot; 1844 Quaternion AXgrot = grot;
1465 Vector3 AXimpulsei = impulsei; 1845 Vector3 AXimpulsei = impulsei;
1466 Vector3 newimpulse = AXimpulsei * AXgrot; 1846 Vector3 newimpulse = AXimpulsei * AXgrot;
1467 impulse = newimpulse; 1847 */
1848 torque *= GetWorldRotation();
1468 } 1849 }
1469 1850
1470 ParentGroup.setAngularImpulse(impulse); 1851 Torque = torque;
1471 } 1852 }
1472 1853
1473 /// <summary> 1854 /// <summary>
@@ -1475,17 +1856,23 @@ namespace OpenSim.Region.Framework.Scenes
1475 /// </summary> 1856 /// </summary>
1476 /// <param name="rootObjectFlags"></param> 1857 /// <param name="rootObjectFlags"></param>
1477 /// <param name="VolumeDetectActive"></param> 1858 /// <param name="VolumeDetectActive"></param>
1478 public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive) 1859 /// <param name="building"></param>
1860
1861 public void ApplyPhysics(uint _ObjectFlags, bool _VolumeDetectActive, bool building)
1479 { 1862 {
1863 VolumeDetectActive = _VolumeDetectActive;
1864
1480 if (!ParentGroup.Scene.CollidablePrims) 1865 if (!ParentGroup.Scene.CollidablePrims)
1481 return; 1866 return;
1482 1867
1483// m_log.DebugFormat( 1868 if (PhysicsShapeType == (byte)PhysShapeType.none)
1484// "[SCENE OBJECT PART]: Applying physics to {0} {1}, m_physicalPrim {2}", 1869 return;
1485// Name, LocalId, UUID, m_physicalPrim); 1870
1871 bool isPhysical = (_ObjectFlags & (uint) PrimFlags.Physics) != 0;
1872 bool isPhantom = (_ObjectFlags & (uint)PrimFlags.Phantom) != 0;
1486 1873
1487 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 1874 if (_VolumeDetectActive)
1488 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 1875 isPhantom = true;
1489 1876
1490 if (IsJoint()) 1877 if (IsJoint())
1491 { 1878 {
@@ -1493,22 +1880,11 @@ namespace OpenSim.Region.Framework.Scenes
1493 } 1880 }
1494 else 1881 else
1495 { 1882 {
1496 // Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored 1883 if ((!isPhantom || isPhysical || _VolumeDetectActive) && !ParentGroup.IsAttachment
1497 if (VolumeDetectActive) 1884 && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1498 isPhantom = false; 1885 AddToPhysics(isPhysical, isPhantom, building, isPhysical);
1499 1886 else
1500 // 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 1887 PhysActor = null; // just to be sure
1501 // or flexible
1502 if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1503 {
1504 // Added clarification.. since A rigid body is an object that you can kick around, etc.
1505 bool rigidBody = isPhysical && !isPhantom;
1506
1507 PhysicsActor pa = AddToPhysics(rigidBody);
1508
1509 if (pa != null)
1510 pa.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
1511 }
1512 } 1888 }
1513 } 1889 }
1514 1890
@@ -1560,6 +1936,12 @@ namespace OpenSim.Region.Framework.Scenes
1560 dupe.Category = Category; 1936 dupe.Category = Category;
1561 dupe.m_rezzed = m_rezzed; 1937 dupe.m_rezzed = m_rezzed;
1562 1938
1939 dupe.m_UndoRedo = null;
1940 dupe.m_isSelected = false;
1941
1942 dupe.IgnoreUndoUpdate = false;
1943 dupe.Undoing = false;
1944
1563 dupe.m_inventory = new SceneObjectPartInventory(dupe); 1945 dupe.m_inventory = new SceneObjectPartInventory(dupe);
1564 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone(); 1946 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone();
1565 1947
@@ -1575,6 +1957,7 @@ namespace OpenSim.Region.Framework.Scenes
1575 1957
1576 // Move afterwards ResetIDs as it clears the localID 1958 // Move afterwards ResetIDs as it clears the localID
1577 dupe.LocalId = localID; 1959 dupe.LocalId = localID;
1960
1578 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 1961 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1579 dupe.LastOwnerID = OwnerID; 1962 dupe.LastOwnerID = OwnerID;
1580 1963
@@ -1594,6 +1977,9 @@ namespace OpenSim.Region.Framework.Scenes
1594 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 1977 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
1595 } 1978 }
1596 1979
1980 if (dupe.PhysActor != null)
1981 dupe.PhysActor.LocalID = localID;
1982
1597 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 1983 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1598 1984
1599// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); 1985// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
@@ -1713,6 +2099,7 @@ namespace OpenSim.Region.Framework.Scenes
1713 2099
1714 /// <summary> 2100 /// <summary>
1715 /// Do a physics propery update for this part. 2101 /// Do a physics propery update for this part.
2102 /// now also updates phantom and volume detector
1716 /// </summary> 2103 /// </summary>
1717 /// <param name="UsePhysics"></param> 2104 /// <param name="UsePhysics"></param>
1718 /// <param name="isNew"></param> 2105 /// <param name="isNew"></param>
@@ -1738,61 +2125,69 @@ namespace OpenSim.Region.Framework.Scenes
1738 { 2125 {
1739 if (pa.IsPhysical) // implies UsePhysics==false for this block 2126 if (pa.IsPhysical) // implies UsePhysics==false for this block
1740 { 2127 {
1741 if (!isNew) 2128 if (!isNew) // implies UsePhysics==false for this block
2129 {
1742 ParentGroup.Scene.RemovePhysicalPrim(1); 2130 ParentGroup.Scene.RemovePhysicalPrim(1);
1743 2131
1744 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 2132 Velocity = new Vector3(0, 0, 0);
1745 pa.OnOutOfBounds -= PhysicsOutOfBounds; 2133 Acceleration = new Vector3(0, 0, 0);
1746 pa.delink(); 2134 if (ParentGroup.RootPart == this)
2135 AngularVelocity = new Vector3(0, 0, 0);
1747 2136
1748 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 2137 if (pa.Phantom && !VolumeDetectActive)
1749 { 2138 {
1750 // destroy all joints connected to this now deactivated body 2139 RemoveFromPhysics();
1751 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); 2140 return;
1752 } 2141 }
1753 2142
1754 // stop client-side interpolation of all joint proxy objects that have just been deleted 2143 pa.IsPhysical = UsePhysics;
1755 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback, 2144 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1756 // which stops client-side interpolation of deactivated joint proxy objects. 2145 pa.OnOutOfBounds -= PhysicsOutOfBounds;
2146 pa.delink();
2147 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
2148 {
2149 // destroy all joints connected to this now deactivated body
2150 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa);
2151 }
2152 }
1757 } 2153 }
1758 2154
1759 if (!UsePhysics && !isNew) 2155 if (pa.IsPhysical != UsePhysics)
1760 { 2156 pa.IsPhysical = UsePhysics;
1761 // reset velocity to 0 on physics switch-off. Without that, the client thinks the
1762 // prim still has velocity and continues to interpolate its position along the old
1763 // velocity-vector.
1764 Velocity = new Vector3(0, 0, 0);
1765 Acceleration = new Vector3(0, 0, 0);
1766 AngularVelocity = new Vector3(0, 0, 0);
1767 //RotationalVelocity = new Vector3(0, 0, 0);
1768 }
1769 2157
1770 pa.IsPhysical = UsePhysics; 2158 if (UsePhysics)
2159 {
2160 if (ParentGroup.RootPart.KeyframeMotion != null)
2161 ParentGroup.RootPart.KeyframeMotion.Stop();
2162 ParentGroup.RootPart.KeyframeMotion = null;
2163 ParentGroup.Scene.AddPhysicalPrim(1);
1771 2164
1772 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 2165 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1773 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 2166 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1774 /// that's not wholesome. Had to make Scene public
1775 //PhysActor = null;
1776 2167
1777 if ((Flags & PrimFlags.Phantom) == 0) 2168 if (ParentID != 0 && ParentID != LocalId)
1778 {
1779 if (UsePhysics)
1780 { 2169 {
1781 ParentGroup.Scene.AddPhysicalPrim(1); 2170 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
1782 2171
1783 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 2172 if (parentPa != null)
1784 pa.OnOutOfBounds += PhysicsOutOfBounds;
1785 if (ParentID != 0 && ParentID != LocalId)
1786 { 2173 {
1787 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; 2174 pa.link(parentPa);
1788
1789 if (parentPa != null)
1790 {
1791 pa.link(parentPa);
1792 }
1793 } 2175 }
1794 } 2176 }
1795 } 2177 }
2178 }
2179
2180 bool phan = ((Flags & PrimFlags.Phantom) != 0);
2181 if (pa.Phantom != phan)
2182 pa.Phantom = phan;
2183
2184// some engines dont' have this check still
2185// if (VolumeDetectActive != pa.IsVolumeDtc)
2186 {
2187 if (VolumeDetectActive)
2188 pa.SetVolumeDetect(1);
2189 else
2190 pa.SetVolumeDetect(0);
1796 } 2191 }
1797 2192
1798 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 2193 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
@@ -1911,12 +2306,26 @@ namespace OpenSim.Region.Framework.Scenes
1911 2306
1912 public Vector3 GetGeometricCenter() 2307 public Vector3 GetGeometricCenter()
1913 { 2308 {
1914 PhysicsActor pa = PhysActor; 2309 // this is not real geometric center but a average of positions relative to root prim acording to
1915 2310 // http://wiki.secondlife.com/wiki/llGetGeometricCenter
1916 if (pa != null) 2311 // ignoring tortured prims details since sl also seems to ignore
1917 return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z); 2312 // so no real use in doing it on physics
1918 else 2313 if (ParentGroup.IsDeleted)
1919 return new Vector3(0, 0, 0); 2314 return new Vector3(0, 0, 0);
2315
2316 return ParentGroup.GetGeometricCenter();
2317
2318 /*
2319 PhysicsActor pa = PhysActor;
2320
2321 if (pa != null)
2322 {
2323 Vector3 vtmp = pa.CenterOfMass;
2324 return vtmp;
2325 }
2326 else
2327 return new Vector3(0, 0, 0);
2328 */
1920 } 2329 }
1921 2330
1922 public float GetMass() 2331 public float GetMass()
@@ -1929,14 +2338,43 @@ namespace OpenSim.Region.Framework.Scenes
1929 return 0; 2338 return 0;
1930 } 2339 }
1931 2340
1932 public Vector3 GetForce() 2341 public Vector3 GetCenterOfMass()
1933 { 2342 {
2343 if (ParentGroup.RootPart == this)
2344 {
2345 if (ParentGroup.IsDeleted)
2346 return AbsolutePosition;
2347 return ParentGroup.GetCenterOfMass();
2348 }
2349
1934 PhysicsActor pa = PhysActor; 2350 PhysicsActor pa = PhysActor;
1935 2351
1936 if (pa != null) 2352 if (pa != null)
1937 return pa.Force; 2353 {
2354 Vector3 tmp = pa.CenterOfMass;
2355 return tmp;
2356 }
1938 else 2357 else
1939 return Vector3.Zero; 2358 return AbsolutePosition;
2359 }
2360
2361 public Vector3 GetPartCenterOfMass()
2362 {
2363 PhysicsActor pa = PhysActor;
2364
2365 if (pa != null)
2366 {
2367 Vector3 tmp = pa.CenterOfMass;
2368 return tmp;
2369 }
2370 else
2371 return AbsolutePosition;
2372 }
2373
2374
2375 public Vector3 GetForce()
2376 {
2377 return Force;
1940 } 2378 }
1941 2379
1942 /// <summary> 2380 /// <summary>
@@ -2228,9 +2666,9 @@ namespace OpenSim.Region.Framework.Scenes
2228 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2666 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2229 2667
2230 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2668 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2231 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2669 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2232 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2670 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2233 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2671 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2234 { 2672 {
2235 ParentGroup.AbsolutePosition = newpos; 2673 ParentGroup.AbsolutePosition = newpos;
2236 return; 2674 return;
@@ -2252,17 +2690,18 @@ namespace OpenSim.Region.Framework.Scenes
2252 //Trys to fetch sound id from prim's inventory. 2690 //Trys to fetch sound id from prim's inventory.
2253 //Prim's inventory doesn't support non script items yet 2691 //Prim's inventory doesn't support non script items yet
2254 2692
2255 lock (TaskInventory) 2693 TaskInventory.LockItemsForRead(true);
2694
2695 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2256 { 2696 {
2257 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2697 if (item.Value.Name == sound)
2258 { 2698 {
2259 if (item.Value.Name == sound) 2699 soundID = item.Value.ItemID;
2260 { 2700 break;
2261 soundID = item.Value.ItemID;
2262 break;
2263 }
2264 } 2701 }
2265 } 2702 }
2703
2704 TaskInventory.LockItemsForRead(false);
2266 } 2705 }
2267 2706
2268 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp) 2707 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp)
@@ -2385,6 +2824,19 @@ namespace OpenSim.Region.Framework.Scenes
2385 APIDTarget = Quaternion.Identity; 2824 APIDTarget = Quaternion.Identity;
2386 } 2825 }
2387 2826
2827
2828
2829 public void ScheduleFullUpdateIfNone()
2830 {
2831 if (ParentGroup == null)
2832 return;
2833
2834// ??? ParentGroup.HasGroupChanged = true;
2835
2836 if (UpdateFlag != UpdateRequired.FULL)
2837 ScheduleFullUpdate();
2838 }
2839
2388 /// <summary> 2840 /// <summary>
2389 /// Schedules this prim for a full update 2841 /// Schedules this prim for a full update
2390 /// </summary> 2842 /// </summary>
@@ -2586,8 +3038,8 @@ namespace OpenSim.Region.Framework.Scenes
2586 { 3038 {
2587 const float ROTATION_TOLERANCE = 0.01f; 3039 const float ROTATION_TOLERANCE = 0.01f;
2588 const float VELOCITY_TOLERANCE = 0.001f; 3040 const float VELOCITY_TOLERANCE = 0.001f;
2589 const float POSITION_TOLERANCE = 0.05f; 3041 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2590 const int TIME_MS_TOLERANCE = 3000; 3042 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2591 3043
2592 switch (UpdateFlag) 3044 switch (UpdateFlag)
2593 { 3045 {
@@ -2649,17 +3101,16 @@ namespace OpenSim.Region.Framework.Scenes
2649 if (!UUID.TryParse(sound, out soundID)) 3101 if (!UUID.TryParse(sound, out soundID))
2650 { 3102 {
2651 // search sound file from inventory 3103 // search sound file from inventory
2652 lock (TaskInventory) 3104 TaskInventory.LockItemsForRead(true);
3105 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2653 { 3106 {
2654 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 3107 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
2655 { 3108 {
2656 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 3109 soundID = item.Value.ItemID;
2657 { 3110 break;
2658 soundID = item.Value.ItemID;
2659 break;
2660 }
2661 } 3111 }
2662 } 3112 }
3113 TaskInventory.LockItemsForRead(false);
2663 } 3114 }
2664 3115
2665 if (soundID == UUID.Zero) 3116 if (soundID == UUID.Zero)
@@ -2744,10 +3195,13 @@ namespace OpenSim.Region.Framework.Scenes
2744 3195
2745 public void SetBuoyancy(float fvalue) 3196 public void SetBuoyancy(float fvalue)
2746 { 3197 {
2747 PhysicsActor pa = PhysActor; 3198 Buoyancy = fvalue;
2748 3199/*
2749 if (pa != null) 3200 if (PhysActor != null)
2750 pa.Buoyancy = fvalue; 3201 {
3202 PhysActor.Buoyancy = fvalue;
3203 }
3204 */
2751 } 3205 }
2752 3206
2753 public void SetDieAtEdge(bool p) 3207 public void SetDieAtEdge(bool p)
@@ -2763,47 +3217,111 @@ namespace OpenSim.Region.Framework.Scenes
2763 PhysicsActor pa = PhysActor; 3217 PhysicsActor pa = PhysActor;
2764 3218
2765 if (pa != null) 3219 if (pa != null)
2766 pa.FloatOnWater = floatYN == 1; 3220 pa.FloatOnWater = (floatYN == 1);
2767 } 3221 }
2768 3222
2769 public void SetForce(Vector3 force) 3223 public void SetForce(Vector3 force)
2770 { 3224 {
2771 PhysicsActor pa = PhysActor; 3225 Force = force;
3226 }
2772 3227
2773 if (pa != null) 3228 public SOPVehicle sopVehicle
2774 pa.Force = force; 3229 {
3230 get
3231 {
3232 return m_vehicle;
3233 }
3234 set
3235 {
3236 m_vehicle = value;
3237 }
3238 }
3239
3240
3241 public int VehicleType
3242 {
3243 get
3244 {
3245 if (m_vehicle == null)
3246 return (int)Vehicle.TYPE_NONE;
3247 else
3248 return (int)m_vehicle.Type;
3249 }
3250 set
3251 {
3252 SetVehicleType(value);
3253 }
2775 } 3254 }
2776 3255
2777 public void SetVehicleType(int type) 3256 public void SetVehicleType(int type)
2778 { 3257 {
2779 PhysicsActor pa = PhysActor; 3258 m_vehicle = null;
3259
3260 if (type == (int)Vehicle.TYPE_NONE)
3261 {
3262 if (_parentID ==0 && PhysActor != null)
3263 PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
3264 return;
3265 }
3266 m_vehicle = new SOPVehicle();
3267 m_vehicle.ProcessTypeChange((Vehicle)type);
3268 {
3269 if (_parentID ==0 && PhysActor != null)
3270 PhysActor.VehicleType = type;
3271 return;
3272 }
3273 }
2780 3274
2781 if (pa != null) 3275 public void SetVehicleFlags(int param, bool remove)
2782 pa.VehicleType = type; 3276 {
3277 if (m_vehicle == null)
3278 return;
3279
3280 m_vehicle.ProcessVehicleFlags(param, remove);
3281
3282 if (_parentID ==0 && PhysActor != null)
3283 {
3284 PhysActor.VehicleFlags(param, remove);
3285 }
2783 } 3286 }
2784 3287
2785 public void SetVehicleFloatParam(int param, float value) 3288 public void SetVehicleFloatParam(int param, float value)
2786 { 3289 {
2787 PhysicsActor pa = PhysActor; 3290 if (m_vehicle == null)
3291 return;
2788 3292
2789 if (pa != null) 3293 m_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
2790 pa.VehicleFloatParam(param, value); 3294
3295 if (_parentID == 0 && PhysActor != null)
3296 {
3297 PhysActor.VehicleFloatParam(param, value);
3298 }
2791 } 3299 }
2792 3300
2793 public void SetVehicleVectorParam(int param, Vector3 value) 3301 public void SetVehicleVectorParam(int param, Vector3 value)
2794 { 3302 {
2795 PhysicsActor pa = PhysActor; 3303 if (m_vehicle == null)
3304 return;
2796 3305
2797 if (pa != null) 3306 m_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
2798 pa.VehicleVectorParam(param, value); 3307
3308 if (_parentID == 0 && PhysActor != null)
3309 {
3310 PhysActor.VehicleVectorParam(param, value);
3311 }
2799 } 3312 }
2800 3313
2801 public void SetVehicleRotationParam(int param, Quaternion rotation) 3314 public void SetVehicleRotationParam(int param, Quaternion rotation)
2802 { 3315 {
2803 PhysicsActor pa = PhysActor; 3316 if (m_vehicle == null)
3317 return;
2804 3318
2805 if (pa != null) 3319 m_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
2806 pa.VehicleRotationParam(param, rotation); 3320
3321 if (_parentID == 0 && PhysActor != null)
3322 {
3323 PhysActor.VehicleRotationParam(param, rotation);
3324 }
2807 } 3325 }
2808 3326
2809 /// <summary> 3327 /// <summary>
@@ -2987,14 +3505,6 @@ namespace OpenSim.Region.Framework.Scenes
2987 hasProfileCut = hasDimple; // is it the same thing? 3505 hasProfileCut = hasDimple; // is it the same thing?
2988 } 3506 }
2989 3507
2990 public void SetVehicleFlags(int param, bool remove)
2991 {
2992 PhysicsActor pa = PhysActor;
2993
2994 if (pa != null)
2995 pa.VehicleFlags(param, remove);
2996 }
2997
2998 public void SetGroup(UUID groupID, IClientAPI client) 3508 public void SetGroup(UUID groupID, IClientAPI client)
2999 { 3509 {
3000 // Scene.AddNewPrims() calls with client == null so can't use this. 3510 // Scene.AddNewPrims() calls with client == null so can't use this.
@@ -3098,68 +3608,18 @@ namespace OpenSim.Region.Framework.Scenes
3098 //ParentGroup.ScheduleGroupForFullUpdate(); 3608 //ParentGroup.ScheduleGroupForFullUpdate();
3099 } 3609 }
3100 3610
3101 public void StoreUndoState() 3611 public void StoreUndoState(ObjectChangeType change)
3102 { 3612 {
3103 StoreUndoState(false); 3613 if (m_UndoRedo == null)
3104 } 3614 m_UndoRedo = new UndoRedoState(5);
3105 3615
3106 public void StoreUndoState(bool forGroup) 3616 lock (m_UndoRedo)
3107 {
3108 if (!Undoing)
3109 { 3617 {
3110 if (!IgnoreUndoUpdate) 3618 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3111 { 3619 {
3112 if (ParentGroup != null) 3620 m_UndoRedo.StoreUndo(this, change);
3113 {
3114 lock (m_undo)
3115 {
3116 if (m_undo.Count > 0)
3117 {
3118 UndoState last = m_undo.Peek();
3119 if (last != null)
3120 {
3121 // TODO: May need to fix for group comparison
3122 if (last.Compare(this))
3123 {
3124 // m_log.DebugFormat(
3125 // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3126 // Name, LocalId, m_undo.Count);
3127
3128 return;
3129 }
3130 }
3131 }
3132
3133 // m_log.DebugFormat(
3134 // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3135 // Name, LocalId, forGroup, m_undo.Count);
3136
3137 if (ParentGroup.GetSceneMaxUndo() > 0)
3138 {
3139 UndoState nUndo = new UndoState(this, forGroup);
3140
3141 m_undo.Push(nUndo);
3142
3143 if (m_redo.Count > 0)
3144 m_redo.Clear();
3145
3146 // m_log.DebugFormat(
3147 // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3148 // Name, LocalId, forGroup, m_undo.Count);
3149 }
3150 }
3151 }
3152 } 3621 }
3153// else
3154// {
3155// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3156// }
3157 } 3622 }
3158// else
3159// {
3160// m_log.DebugFormat(
3161// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3162// }
3163 } 3623 }
3164 3624
3165 /// <summary> 3625 /// <summary>
@@ -3169,84 +3629,46 @@ namespace OpenSim.Region.Framework.Scenes
3169 { 3629 {
3170 get 3630 get
3171 { 3631 {
3172 lock (m_undo) 3632 if (m_UndoRedo == null)
3173 return m_undo.Count; 3633 return 0;
3634 return m_UndoRedo.Count;
3174 } 3635 }
3175 } 3636 }
3176 3637
3177 public void Undo() 3638 public void Undo()
3178 { 3639 {
3179 lock (m_undo) 3640 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3180 { 3641 return;
3181// m_log.DebugFormat(
3182// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3183// Name, LocalId, m_undo.Count);
3184
3185 if (m_undo.Count > 0)
3186 {
3187 UndoState goback = m_undo.Pop();
3188
3189 if (goback != null)
3190 {
3191 UndoState nUndo = null;
3192
3193 if (ParentGroup.GetSceneMaxUndo() > 0)
3194 {
3195 nUndo = new UndoState(this, goback.ForGroup);
3196 }
3197
3198 goback.PlaybackState(this);
3199
3200 if (nUndo != null)
3201 m_redo.Push(nUndo);
3202 }
3203 }
3204 3642
3205// m_log.DebugFormat( 3643 lock (m_UndoRedo)
3206// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3644 {
3207// Name, LocalId, m_undo.Count); 3645 Undoing = true;
3646 m_UndoRedo.Undo(this);
3647 Undoing = false;
3208 } 3648 }
3209 } 3649 }
3210 3650
3211 public void Redo() 3651 public void Redo()
3212 { 3652 {
3213 lock (m_undo) 3653 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3214 { 3654 return;
3215// m_log.DebugFormat(
3216// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3217// Name, LocalId, m_redo.Count);
3218
3219 if (m_redo.Count > 0)
3220 {
3221 UndoState gofwd = m_redo.Pop();
3222
3223 if (gofwd != null)
3224 {
3225 if (ParentGroup.GetSceneMaxUndo() > 0)
3226 {
3227 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3228
3229 m_undo.Push(nUndo);
3230 }
3231
3232 gofwd.PlayfwdState(this);
3233 }
3234 3655
3235// m_log.DebugFormat( 3656 lock (m_UndoRedo)
3236// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3657 {
3237// Name, LocalId, m_redo.Count); 3658 Undoing = true;
3238 } 3659 m_UndoRedo.Redo(this);
3660 Undoing = false;
3239 } 3661 }
3240 } 3662 }
3241 3663
3242 public void ClearUndoState() 3664 public void ClearUndoState()
3243 { 3665 {
3244// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3666 if (m_UndoRedo == null || Undoing)
3667 return;
3245 3668
3246 lock (m_undo) 3669 lock (m_UndoRedo)
3247 { 3670 {
3248 m_undo.Clear(); 3671 m_UndoRedo.Clear();
3249 m_redo.Clear();
3250 } 3672 }
3251 } 3673 }
3252 3674
@@ -3876,6 +4298,27 @@ namespace OpenSim.Region.Framework.Scenes
3876 } 4298 }
3877 } 4299 }
3878 4300
4301
4302 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4303 {
4304 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
4305 return;
4306
4307 if (PhysicsShapeType != (byte)physdata.PhysShapeType)
4308 {
4309 PhysicsShapeType = (byte)physdata.PhysShapeType;
4310
4311 }
4312
4313 if(Density != physdata.Density)
4314 Density = physdata.Density;
4315 if(GravityModifier != physdata.GravitationModifier)
4316 GravityModifier = physdata.GravitationModifier;
4317 if(Friction != physdata.Friction)
4318 Friction = physdata.Friction;
4319 if(Bounciness != physdata.Bounce)
4320 Bounciness = physdata.Bounce;
4321 }
3879 /// <summary> 4322 /// <summary>
3880 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary. 4323 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary.
3881 /// </summary> 4324 /// </summary>
@@ -3883,7 +4326,7 @@ namespace OpenSim.Region.Framework.Scenes
3883 /// <param name="SetTemporary"></param> 4326 /// <param name="SetTemporary"></param>
3884 /// <param name="SetPhantom"></param> 4327 /// <param name="SetPhantom"></param>
3885 /// <param name="SetVD"></param> 4328 /// <param name="SetVD"></param>
3886 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) 4329 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
3887 { 4330 {
3888 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4331 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
3889 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4332 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -3893,225 +4336,205 @@ namespace OpenSim.Region.Framework.Scenes
3893 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4336 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
3894 return; 4337 return;
3895 4338
3896 PhysicsActor pa = PhysActor; 4339 VolumeDetectActive = SetVD;
3897 4340
3898 // Special cases for VD. VD can only be called from a script 4341 // volume detector implies phantom
3899 // and can't be combined with changes to other states. So we can rely 4342 if (VolumeDetectActive)
3900 // that...
3901 // ... if VD is changed, all others are not.
3902 // ... if one of the others is changed, VD is not.
3903 if (SetVD) // VD is active, special logic applies
3904 {
3905 // State machine logic for VolumeDetect
3906 // More logic below
3907 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
3908
3909 if (phanReset) // Phantom changes from on to off switch VD off too
3910 {
3911 SetVD = false; // Switch it of for the course of this routine
3912 VolumeDetectActive = false; // and also permanently
3913
3914 if (pa != null)
3915 pa.SetVolumeDetect(0); // Let physics know about it too
3916 }
3917 else
3918 {
3919 // If volumedetect is active we don't want phantom to be applied.
3920 // If this is a new call to VD out of the state "phantom"
3921 // this will also cause the prim to be visible to physics
3922 SetPhantom = false;
3923 }
3924 }
3925
3926 if (UsePhysics && IsJoint())
3927 {
3928 SetPhantom = true; 4343 SetPhantom = true;
3929 }
3930 4344
3931 if (UsePhysics) 4345 if (UsePhysics)
3932 {
3933 AddFlag(PrimFlags.Physics); 4346 AddFlag(PrimFlags.Physics);
3934 if (!wasUsingPhysics)
3935 {
3936 DoPhysicsPropertyUpdate(UsePhysics, false);
3937
3938 if (!ParentGroup.IsDeleted)
3939 {
3940 if (LocalId == ParentGroup.RootPart.LocalId)
3941 {
3942 ParentGroup.CheckSculptAndLoad();
3943 }
3944 }
3945 }
3946 }
3947 else 4347 else
3948 {
3949 RemFlag(PrimFlags.Physics); 4348 RemFlag(PrimFlags.Physics);
3950 if (wasUsingPhysics)
3951 {
3952 DoPhysicsPropertyUpdate(UsePhysics, false);
3953 }
3954 }
3955 4349
3956 if (SetPhantom 4350 if (SetPhantom)
3957 || ParentGroup.IsAttachment
3958 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
3959 {
3960 AddFlag(PrimFlags.Phantom); 4351 AddFlag(PrimFlags.Phantom);
4352 else
4353 RemFlag(PrimFlags.Phantom);
3961 4354
3962 if (PhysActor != null) 4355 if (SetTemporary)
4356 AddFlag(PrimFlags.TemporaryOnRez);
4357 else
4358 RemFlag(PrimFlags.TemporaryOnRez);
4359
4360
4361 if (ParentGroup.Scene == null)
4362 return;
4363
4364 PhysicsActor pa = PhysActor;
4365
4366 if (pa != null && building && pa.Building != building)
4367 pa.Building = building;
4368
4369 if ((SetPhantom && !UsePhysics && !SetVD) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
4370 || (Shape.PathCurve == (byte)Extrusion.Flexible))
4371 {
4372 if (pa != null)
3963 { 4373 {
4374 ParentGroup.Scene.RemovePhysicalPrim(1);
3964 RemoveFromPhysics(); 4375 RemoveFromPhysics();
3965 pa = null;
3966 } 4376 }
4377
4378 Velocity = new Vector3(0, 0, 0);
4379 Acceleration = new Vector3(0, 0, 0);
4380 if (ParentGroup.RootPart == this)
4381 AngularVelocity = new Vector3(0, 0, 0);
3967 } 4382 }
3968 else // Not phantom 4383 else
3969 { 4384 {
3970 RemFlag(PrimFlags.Phantom); 4385 if (ParentGroup.Scene.CollidablePrims)
3971
3972 if (ParentGroup.Scene == null)
3973 return;
3974
3975 if (ParentGroup.Scene.CollidablePrims && pa == null)
3976 { 4386 {
3977 pa = AddToPhysics(UsePhysics); 4387 if (pa == null)
3978
3979 if (pa != null)
3980 { 4388 {
3981 pa.SetMaterial(Material); 4389 AddToPhysics(UsePhysics, SetPhantom, building , false);
3982 DoPhysicsPropertyUpdate(UsePhysics, true); 4390 pa = PhysActor;
3983 4391
3984 if (!ParentGroup.IsDeleted) 4392 if (pa != null)
3985 { 4393 {
3986 if (LocalId == ParentGroup.RootPart.LocalId) 4394 if (
4395// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4396// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4397// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4398// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4399// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4400// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4401 ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
4402// (CollisionSound != UUID.Zero)
4403 )
3987 { 4404 {
3988 ParentGroup.CheckSculptAndLoad(); 4405 pa.OnCollisionUpdate += PhysicsCollision;
4406 pa.SubscribeEvents(1000);
3989 } 4407 }
3990 } 4408 }
3991
3992 if (
3993 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
3994 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
3995 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
3996 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
3997 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
3998 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
3999 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4000 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4001 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4002 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4003 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4004 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4005 (CollisionSound != UUID.Zero)
4006 )
4007 {
4008 pa.OnCollisionUpdate += PhysicsCollision;
4009 pa.SubscribeEvents(1000);
4010 }
4011 } 4409 }
4012 } 4410 else // it already has a physical representation
4013 else // it already has a physical representation
4014 {
4015 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4016
4017 if (!ParentGroup.IsDeleted)
4018 { 4411 {
4019 if (LocalId == ParentGroup.RootPart.LocalId) 4412 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4020 { 4413 /* moved into DoPhysicsPropertyUpdate
4021 ParentGroup.CheckSculptAndLoad(); 4414 if(VolumeDetectActive)
4022 } 4415 pa.SetVolumeDetect(1);
4416 else
4417 pa.SetVolumeDetect(0);
4418 */
4419 if (pa.Building != building)
4420 pa.Building = building;
4023 } 4421 }
4024 } 4422 }
4025 } 4423 }
4026
4027 if (SetVD)
4028 {
4029 // If the above logic worked (this is urgent candidate to unit tests!)
4030 // we now have a physicsactor.
4031 // Defensive programming calls for a check here.
4032 // Better would be throwing an exception that could be catched by a unit test as the internal
4033 // logic should make sure, this Physactor is always here.
4034 if (pa != null)
4035 {
4036 pa.SetVolumeDetect(1);
4037 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4038 VolumeDetectActive = true;
4039 }
4040 }
4041 else
4042 {
4043 // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like
4044 // (mumbles, well, at least if you have infinte CPU powers :-))
4045 if (pa != null)
4046 pa.SetVolumeDetect(0);
4047
4048 VolumeDetectActive = false;
4049 }
4050
4051 if (SetTemporary)
4052 {
4053 AddFlag(PrimFlags.TemporaryOnRez);
4054 }
4055 else
4056 {
4057 RemFlag(PrimFlags.TemporaryOnRez);
4058 }
4059 4424
4060 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); 4425 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4061 4426
4427 // and last in case we have a new actor and not building
4428
4062 if (ParentGroup != null) 4429 if (ParentGroup != null)
4063 { 4430 {
4064 ParentGroup.HasGroupChanged = true; 4431 ParentGroup.HasGroupChanged = true;
4065 ScheduleFullUpdate(); 4432 ScheduleFullUpdate();
4066 } 4433 }
4067 4434
4068// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); 4435// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4069 } 4436 }
4070 4437
4071 /// <summary> 4438 /// <summary>
4072 /// Adds this part to the physics scene. 4439 /// Adds this part to the physics scene.
4440 /// and sets the PhysActor property
4073 /// </summary> 4441 /// </summary>
4074 /// <remarks>This method also sets the PhysActor property.</remarks> 4442 /// <param name="isPhysical">Add this prim as physical.</param>
4075 /// <param name="rigidBody">Add this prim with a rigid body.</param> 4443 /// <param name="isPhantom">Add this prim as phantom.</param>
4076 /// <returns> 4444 /// <param name="building">tells physics to delay full construction of object</param>
4077 /// The physics actor. null if there was a failure. 4445 /// <param name="applyDynamics">applies velocities, force and torque</param>
4078 /// </returns> 4446 private void AddToPhysics(bool isPhysical, bool isPhantom, bool building, bool applyDynamics)
4079 private PhysicsActor AddToPhysics(bool rigidBody) 4447 {
4080 {
4081 PhysicsActor pa; 4448 PhysicsActor pa;
4082 4449
4450 Vector3 velocity = Velocity;
4451 Vector3 rotationalVelocity = AngularVelocity;;
4452
4083 try 4453 try
4084 { 4454 {
4085 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( 4455 pa = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4086 string.Format("{0}/{1}", Name, UUID), 4456 string.Format("{0}/{1}", Name, UUID),
4087 Shape, 4457 Shape,
4088 AbsolutePosition, 4458 AbsolutePosition,
4089 Scale, 4459 Scale,
4090 RotationOffset, 4460 GetWorldRotation(),
4091 rigidBody, 4461 isPhysical,
4092 m_localId); 4462 isPhantom,
4463 PhysicsShapeType,
4464 m_localId);
4093 } 4465 }
4094 catch 4466 catch (Exception ex)
4095 { 4467 {
4096 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid); 4468 m_log.ErrorFormat("[SCENE]: AddToPhysics object {0} failed: {1}", m_uuid, ex.Message);
4097 pa = null; 4469 pa = null;
4098 } 4470 }
4099 4471
4100 // FIXME: Ideally we wouldn't set the property here to reduce situations where threads changing physical
4101 // properties can stop on each other. However, DoPhysicsPropertyUpdate() currently relies on PhysActor
4102 // being set.
4103 PhysActor = pa;
4104
4105 // Basic Physics can also return null as well as an exception catch.
4106 if (pa != null) 4472 if (pa != null)
4107 { 4473 {
4108 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 4474 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
4109 pa.SetMaterial(Material); 4475 pa.SetMaterial(Material);
4110 DoPhysicsPropertyUpdate(rigidBody, true); 4476
4477 if (VolumeDetectActive) // change if not the default only
4478 pa.SetVolumeDetect(1);
4479
4480 if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
4481 m_vehicle.SetVehicle(pa);
4482
4483 // we are going to tell rest of code about physics so better have this here
4484 PhysActor = pa;
4485
4486 // DoPhysicsPropertyUpdate(isPhysical, true);
4487 // lets expand it here just with what it really needs to do
4488
4489 if (isPhysical)
4490 {
4491 if (ParentGroup.RootPart.KeyframeMotion != null)
4492 ParentGroup.RootPart.KeyframeMotion.Stop();
4493 ParentGroup.RootPart.KeyframeMotion = null;
4494 ParentGroup.Scene.AddPhysicalPrim(1);
4495
4496 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
4497 pa.OnOutOfBounds += PhysicsOutOfBounds;
4498
4499 if (ParentID != 0 && ParentID != LocalId)
4500 {
4501 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
4502
4503 if (parentPa != null)
4504 {
4505 pa.link(parentPa);
4506 }
4507 }
4508 }
4509
4510 if (applyDynamics)
4511 // do independent of isphysical so parameters get setted (at least some)
4512 {
4513 Velocity = velocity;
4514 AngularVelocity = rotationalVelocity;
4515// pa.Velocity = velocity;
4516 pa.RotationalVelocity = rotationalVelocity;
4517
4518 // if not vehicle and root part apply force and torque
4519 if ((m_vehicle == null || m_vehicle.Type == Vehicle.TYPE_NONE)
4520 && LocalId == ParentGroup.RootPart.LocalId)
4521 {
4522 pa.Force = Force;
4523 pa.Torque = Torque;
4524 }
4525 }
4526
4527 if (Shape.SculptEntry)
4528 CheckSculptAndLoad();
4529 else
4530 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
4531
4532 if (!building)
4533 pa.Building = false;
4111 } 4534 }
4112 4535
4113 return pa; 4536 PhysActor = pa;
4114 } 4537 }
4115 4538
4116 /// <summary> 4539 /// <summary>
4117 /// This removes the part from the physics scene. 4540 /// This removes the part from the physics scene.
@@ -4321,39 +4744,28 @@ namespace OpenSim.Region.Framework.Scenes
4321 } 4744 }
4322 4745
4323 PhysicsActor pa = PhysActor; 4746 PhysicsActor pa = PhysActor;
4324 4747 if (pa != null)
4325 if (
4326 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4327 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4328 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4329 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4330 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4331 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4332 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) ||
4333 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4334 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4335 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4336 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4337 ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4338 (CollisionSound != UUID.Zero)
4339 )
4340 { 4748 {
4341 // subscribe to physics updates. 4749 if (
4342 if (pa != null) 4750// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4751// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4752// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4753// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4754// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4755// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4756 ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
4757 )
4343 { 4758 {
4759 // subscribe to physics updates.
4344 pa.OnCollisionUpdate += PhysicsCollision; 4760 pa.OnCollisionUpdate += PhysicsCollision;
4345 pa.SubscribeEvents(1000); 4761 pa.SubscribeEvents(1000);
4346 } 4762 }
4347 } 4763 else
4348 else
4349 {
4350 if (pa != null)
4351 { 4764 {
4352 pa.UnSubscribeEvents(); 4765 pa.UnSubscribeEvents();
4353 pa.OnCollisionUpdate -= PhysicsCollision; 4766 pa.OnCollisionUpdate -= PhysicsCollision;
4354 } 4767 }
4355 } 4768 }
4356
4357 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 4769 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4358 //{ 4770 //{
4359 // ParentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting; 4771 // ParentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting;
@@ -4480,5 +4892,17 @@ namespace OpenSim.Region.Framework.Scenes
4480 Color color = Color; 4892 Color color = Color;
4481 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 4893 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4482 } 4894 }
4895
4896 public void ResetOwnerChangeFlag()
4897 {
4898 List<UUID> inv = Inventory.GetInventoryList();
4899
4900 foreach (UUID itemID in inv)
4901 {
4902 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
4903 item.OwnerChanged = false;
4904 Inventory.UpdateInventoryItem(item, false, false);
4905 }
4906 }
4483 } 4907 }
4484} 4908}