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