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.cs1105
1 files changed, 781 insertions, 324 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 439b718..cfa3cd4 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.
@@ -184,6 +185,15 @@ namespace OpenSim.Region.Framework.Scenes
184 185
185 public UUID FromFolderID; 186 public UUID FromFolderID;
186 187
188 // The following two are to hold the attachment data
189 // while an object is inworld
190 [XmlIgnore]
191 public byte AttachPoint = 0;
192
193 [XmlIgnore]
194 public Vector3 AttachOffset = Vector3.Zero;
195
196 [XmlIgnore]
187 public int STATUS_ROTATE_X; 197 public int STATUS_ROTATE_X;
188 198
189 public int STATUS_ROTATE_Y; 199 public int STATUS_ROTATE_Y;
@@ -210,8 +220,7 @@ namespace OpenSim.Region.Framework.Scenes
210 220
211 public Vector3 RotationAxis = Vector3.One; 221 public Vector3 RotationAxis = Vector3.One;
212 222
213 public bool VolumeDetectActive; // XmlIgnore set to avoid problems with persistance until I come to care for this 223 public bool VolumeDetectActive;
214 // Certainly this must be a persistant setting finally
215 224
216 public bool IsWaitingForFirstSpinUpdatePacket; 225 public bool IsWaitingForFirstSpinUpdatePacket;
217 226
@@ -251,10 +260,10 @@ namespace OpenSim.Region.Framework.Scenes
251 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 260 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
252 private Vector3 m_sitTargetPosition; 261 private Vector3 m_sitTargetPosition;
253 private string m_sitAnimation = "SIT"; 262 private string m_sitAnimation = "SIT";
263 private bool m_occupied; // KF if any av is sitting on this prim
254 private string m_text = String.Empty; 264 private string m_text = String.Empty;
255 private string m_touchName = String.Empty; 265 private string m_touchName = String.Empty;
256 private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5); 266 private UndoRedoState m_UndoRedo = null;
257 private readonly Stack<UndoState> m_redo = new Stack<UndoState>(5);
258 267
259 private bool m_passTouches; 268 private bool m_passTouches;
260 269
@@ -283,7 +292,16 @@ namespace OpenSim.Region.Framework.Scenes
283 protected Vector3 m_lastAcceleration; 292 protected Vector3 m_lastAcceleration;
284 protected Vector3 m_lastAngularVelocity; 293 protected Vector3 m_lastAngularVelocity;
285 protected int m_lastTerseSent; 294 protected int m_lastTerseSent;
286 295 protected float m_buoyancy = 0.0f;
296 protected Vector3 m_force;
297 protected Vector3 m_torque;
298
299 protected byte m_physicsShapeType = (byte)PhysShapeType.prim;
300 protected float m_density = 1000.0f; // in kg/m^3
301 protected float m_gravitymod = 1.0f;
302 protected float m_friction = 0.6f; // wood
303 protected float m_bounce = 0.5f; // wood
304
287 /// <summary> 305 /// <summary>
288 /// Stores media texture data 306 /// Stores media texture data
289 /// </summary> 307 /// </summary>
@@ -299,6 +317,17 @@ namespace OpenSim.Region.Framework.Scenes
299 private UUID m_collisionSound; 317 private UUID m_collisionSound;
300 private float m_collisionSoundVolume; 318 private float m_collisionSoundVolume;
301 319
320
321 private SOPVehicle m_vehicle = null;
322
323 private KeyframeMotion m_keyframeMotion = null;
324
325 public KeyframeMotion KeyframeMotion
326 {
327 get; set;
328 }
329
330
302 #endregion Fields 331 #endregion Fields
303 332
304// ~SceneObjectPart() 333// ~SceneObjectPart()
@@ -341,7 +370,7 @@ namespace OpenSim.Region.Framework.Scenes
341 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 370 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
342 Quaternion rotationOffset, Vector3 offsetPosition) : this() 371 Quaternion rotationOffset, Vector3 offsetPosition) : this()
343 { 372 {
344 m_name = "Primitive"; 373 m_name = "Object";
345 374
346 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 375 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
347 LastOwnerID = CreatorID = OwnerID = ownerID; 376 LastOwnerID = CreatorID = OwnerID = ownerID;
@@ -381,7 +410,7 @@ namespace OpenSim.Region.Framework.Scenes
381 private uint _ownerMask = (uint)PermissionMask.All; 410 private uint _ownerMask = (uint)PermissionMask.All;
382 private uint _groupMask = (uint)PermissionMask.None; 411 private uint _groupMask = (uint)PermissionMask.None;
383 private uint _everyoneMask = (uint)PermissionMask.None; 412 private uint _everyoneMask = (uint)PermissionMask.None;
384 private uint _nextOwnerMask = (uint)PermissionMask.All; 413 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
385 private PrimFlags _flags = PrimFlags.None; 414 private PrimFlags _flags = PrimFlags.None;
386 private DateTime m_expires; 415 private DateTime m_expires;
387 private DateTime m_rezzed; 416 private DateTime m_rezzed;
@@ -475,12 +504,16 @@ namespace OpenSim.Region.Framework.Scenes
475 } 504 }
476 505
477 /// <value> 506 /// <value>
478 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 507 /// Get the inventory list
479 /// </value> 508 /// </value>
480 public TaskInventoryDictionary TaskInventory 509 public TaskInventoryDictionary TaskInventory
481 { 510 {
482 get { return m_inventory.Items; } 511 get {
483 set { m_inventory.Items = value; } 512 return m_inventory.Items;
513 }
514 set {
515 m_inventory.Items = value;
516 }
484 } 517 }
485 518
486 /// <summary> 519 /// <summary>
@@ -529,19 +562,6 @@ namespace OpenSim.Region.Framework.Scenes
529 } 562 }
530 } 563 }
531 564
532 public byte Material
533 {
534 get { return (byte) m_material; }
535 set
536 {
537 m_material = (Material)value;
538 if (PhysActor != null)
539 {
540 PhysActor.SetMaterial((int)value);
541 }
542 }
543 }
544
545 public bool PassTouches 565 public bool PassTouches
546 { 566 {
547 get { return m_passTouches; } 567 get { return m_passTouches; }
@@ -624,14 +644,12 @@ namespace OpenSim.Region.Framework.Scenes
624 set { m_LoopSoundSlavePrims = value; } 644 set { m_LoopSoundSlavePrims = value; }
625 } 645 }
626 646
627
628 public Byte[] TextureAnimation 647 public Byte[] TextureAnimation
629 { 648 {
630 get { return m_TextureAnimation; } 649 get { return m_TextureAnimation; }
631 set { m_TextureAnimation = value; } 650 set { m_TextureAnimation = value; }
632 } 651 }
633 652
634
635 public Byte[] ParticleSystem 653 public Byte[] ParticleSystem
636 { 654 {
637 get { return m_particleSystem; } 655 get { return m_particleSystem; }
@@ -668,9 +686,11 @@ namespace OpenSim.Region.Framework.Scenes
668 { 686 {
669 // If this is a linkset, we don't want the physics engine mucking up our group position here. 687 // If this is a linkset, we don't want the physics engine mucking up our group position here.
670 PhysicsActor actor = PhysActor; 688 PhysicsActor actor = PhysActor;
671 if (actor != null && ParentID == 0) 689 if (ParentID == 0)
672 { 690 {
673 m_groupPosition = actor.Position; 691 if (actor != null)
692 m_groupPosition = actor.Position;
693 return m_groupPosition;
674 } 694 }
675 695
676 if (ParentGroup.IsAttachment) 696 if (ParentGroup.IsAttachment)
@@ -680,12 +700,14 @@ namespace OpenSim.Region.Framework.Scenes
680 return sp.AbsolutePosition; 700 return sp.AbsolutePosition;
681 } 701 }
682 702
703 // use root prim's group position. Physics may have updated it
704 if (ParentGroup.RootPart != this)
705 m_groupPosition = ParentGroup.RootPart.GroupPosition;
683 return m_groupPosition; 706 return m_groupPosition;
684 } 707 }
685 set 708 set
686 { 709 {
687 m_groupPosition = value; 710 m_groupPosition = value;
688
689 PhysicsActor actor = PhysActor; 711 PhysicsActor actor = PhysActor;
690 if (actor != null) 712 if (actor != null)
691 { 713 {
@@ -711,16 +733,6 @@ namespace OpenSim.Region.Framework.Scenes
711 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); 733 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message);
712 } 734 }
713 } 735 }
714
715 // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
716 if (SitTargetAvatar != UUID.Zero)
717 {
718 ScenePresence avatar;
719 if (ParentGroup.Scene.TryGetScenePresence(SitTargetAvatar, out avatar))
720 {
721 avatar.ParentPosition = GetWorldPosition();
722 }
723 }
724 } 736 }
725 } 737 }
726 738
@@ -729,7 +741,7 @@ namespace OpenSim.Region.Framework.Scenes
729 get { return m_offsetPosition; } 741 get { return m_offsetPosition; }
730 set 742 set
731 { 743 {
732// StoreUndoState(); 744 Vector3 oldpos = m_offsetPosition;
733 m_offsetPosition = value; 745 m_offsetPosition = value;
734 746
735 if (ParentGroup != null && !ParentGroup.IsDeleted) 747 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -744,7 +756,22 @@ namespace OpenSim.Region.Framework.Scenes
744 if (ParentGroup.Scene != null) 756 if (ParentGroup.Scene != null)
745 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 757 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
746 } 758 }
759
760 if (!m_parentGroup.m_dupeInProgress)
761 {
762 List<ScenePresence> avs = ParentGroup.GetLinkedAvatars();
763 foreach (ScenePresence av in avs)
764 {
765 if (av.ParentID == m_localId)
766 {
767 Vector3 offset = (m_offsetPosition - oldpos);
768 av.AbsolutePosition += offset;
769 av.SendAvatarDataToAllAgents();
770 }
771 }
772 }
747 } 773 }
774 TriggerScriptChangedEvent(Changed.POSITION);
748 } 775 }
749 } 776 }
750 777
@@ -793,7 +820,7 @@ namespace OpenSim.Region.Framework.Scenes
793 820
794 set 821 set
795 { 822 {
796 StoreUndoState(); 823// StoreUndoState();
797 m_rotationOffset = value; 824 m_rotationOffset = value;
798 825
799 PhysicsActor actor = PhysActor; 826 PhysicsActor actor = PhysActor;
@@ -881,7 +908,7 @@ namespace OpenSim.Region.Framework.Scenes
881 get 908 get
882 { 909 {
883 PhysicsActor actor = PhysActor; 910 PhysicsActor actor = PhysActor;
884 if ((actor != null) && actor.IsPhysical) 911 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
885 { 912 {
886 m_angularVelocity = actor.RotationalVelocity; 913 m_angularVelocity = actor.RotationalVelocity;
887 } 914 }
@@ -893,7 +920,16 @@ namespace OpenSim.Region.Framework.Scenes
893 /// <summary></summary> 920 /// <summary></summary>
894 public Vector3 Acceleration 921 public Vector3 Acceleration
895 { 922 {
896 get { return m_acceleration; } 923 get
924 {
925 PhysicsActor actor = PhysActor;
926 if (actor != null)
927 {
928 m_acceleration = actor.Acceleration;
929 }
930 return m_acceleration;
931 }
932
897 set { m_acceleration = value; } 933 set { m_acceleration = value; }
898 } 934 }
899 935
@@ -950,7 +986,10 @@ namespace OpenSim.Region.Framework.Scenes
950 public PrimitiveBaseShape Shape 986 public PrimitiveBaseShape Shape
951 { 987 {
952 get { return m_shape; } 988 get { return m_shape; }
953 set { m_shape = value;} 989 set
990 {
991 m_shape = value;
992 }
954 } 993 }
955 994
956 /// <summary> 995 /// <summary>
@@ -963,7 +1002,6 @@ namespace OpenSim.Region.Framework.Scenes
963 { 1002 {
964 if (m_shape != null) 1003 if (m_shape != null)
965 { 1004 {
966 StoreUndoState();
967 1005
968 m_shape.Scale = value; 1006 m_shape.Scale = value;
969 1007
@@ -990,6 +1028,7 @@ namespace OpenSim.Region.Framework.Scenes
990 } 1028 }
991 1029
992 public UpdateRequired UpdateFlag { get; set; } 1030 public UpdateRequired UpdateFlag { get; set; }
1031 public bool UpdatePhysRequired { get; set; }
993 1032
994 /// <summary> 1033 /// <summary>
995 /// Used for media on a prim. 1034 /// Used for media on a prim.
@@ -1030,10 +1069,7 @@ namespace OpenSim.Region.Framework.Scenes
1030 { 1069 {
1031 get 1070 get
1032 { 1071 {
1033 if (ParentGroup.IsAttachment) 1072 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
1034 return GroupPosition;
1035
1036 return m_offsetPosition + m_groupPosition;
1037 } 1073 }
1038 } 1074 }
1039 1075
@@ -1203,6 +1239,13 @@ namespace OpenSim.Region.Framework.Scenes
1203 _flags = value; 1239 _flags = value;
1204 } 1240 }
1205 } 1241 }
1242
1243 [XmlIgnore]
1244 public bool IsOccupied // KF If an av is sittingon this prim
1245 {
1246 get { return m_occupied; }
1247 set { m_occupied = value; }
1248 }
1206 1249
1207 /// <summary> 1250 /// <summary>
1208 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero 1251 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero
@@ -1262,6 +1305,316 @@ namespace OpenSim.Region.Framework.Scenes
1262 set { m_collisionSoundVolume = value; } 1305 set { m_collisionSoundVolume = value; }
1263 } 1306 }
1264 1307
1308 public float Buoyancy
1309 {
1310 get
1311 {
1312 if (ParentGroup.RootPart == this)
1313 return m_buoyancy;
1314
1315 return ParentGroup.RootPart.Buoyancy;
1316 }
1317 set
1318 {
1319 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1320 {
1321 ParentGroup.RootPart.Buoyancy = value;
1322 return;
1323 }
1324 m_buoyancy = value;
1325 if (PhysActor != null)
1326 PhysActor.Buoyancy = value;
1327 }
1328 }
1329
1330 public Vector3 Force
1331 {
1332 get
1333 {
1334 if (ParentGroup.RootPart == this)
1335 return m_force;
1336
1337 return ParentGroup.RootPart.Force;
1338 }
1339
1340 set
1341 {
1342 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1343 {
1344 ParentGroup.RootPart.Force = value;
1345 return;
1346 }
1347 m_force = value;
1348 if (PhysActor != null)
1349 PhysActor.Force = value;
1350 }
1351 }
1352
1353 public Vector3 Torque
1354 {
1355 get
1356 {
1357 if (ParentGroup.RootPart == this)
1358 return m_torque;
1359
1360 return ParentGroup.RootPart.Torque;
1361 }
1362
1363 set
1364 {
1365 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1366 {
1367 ParentGroup.RootPart.Torque = value;
1368 return;
1369 }
1370 m_torque = value;
1371 if (PhysActor != null)
1372 PhysActor.Torque = value;
1373 }
1374 }
1375
1376 public byte Material
1377 {
1378 get { return (byte)m_material; }
1379 set
1380 {
1381 if (value >= 0 && value <= (byte)SOPMaterialData.MaxMaterial)
1382 {
1383 bool update = false;
1384
1385 if (m_material != (Material)value)
1386 {
1387 update = true;
1388 m_material = (Material)value;
1389 }
1390
1391 if (m_friction != SOPMaterialData.friction(m_material))
1392 {
1393 update = true;
1394 m_friction = SOPMaterialData.friction(m_material);
1395 }
1396
1397 if (m_bounce != SOPMaterialData.bounce(m_material))
1398 {
1399 update = true;
1400 m_bounce = SOPMaterialData.bounce(m_material);
1401 }
1402
1403 if (update)
1404 {
1405 if (PhysActor != null)
1406 {
1407 PhysActor.SetMaterial((int)value);
1408 }
1409 if(ParentGroup != null)
1410 ParentGroup.HasGroupChanged = true;
1411 ScheduleFullUpdateIfNone();
1412 UpdatePhysRequired = true;
1413 }
1414 }
1415 }
1416 }
1417
1418 // not a propriety to move to methods place later
1419 private bool HasMesh()
1420 {
1421 if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh))
1422 return true;
1423 return false;
1424 }
1425
1426 // not a propriety to move to methods place later
1427 public byte DefaultPhysicsShapeType()
1428 {
1429 byte type;
1430
1431 if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh))
1432 type = (byte)PhysShapeType.convex;
1433 else
1434 type = (byte)PhysShapeType.prim;
1435
1436 return type;
1437 }
1438
1439 [XmlIgnore]
1440 public bool UsesComplexCost
1441 {
1442 get
1443 {
1444 byte pst = PhysicsShapeType;
1445 if(pst == (byte) PhysShapeType.none || pst == (byte) PhysShapeType.convex || HasMesh())
1446 return true;
1447 return false;
1448 }
1449 }
1450
1451 [XmlIgnore]
1452 public float PhysicsCost
1453 {
1454 get
1455 {
1456 if(PhysicsShapeType == (byte)PhysShapeType.none)
1457 return 0;
1458
1459 float cost = 0.1f;
1460 if (PhysActor != null)
1461// cost += PhysActor.Cost;
1462
1463 if ((Flags & PrimFlags.Physics) != 0)
1464 cost *= (1.0f + 0.01333f * Scale.LengthSquared()); // 0.01333 == 0.04/3
1465 return cost;
1466 }
1467 }
1468
1469 [XmlIgnore]
1470 public float StreamingCost
1471 {
1472 get
1473 {
1474
1475
1476 return 0.1f;
1477 }
1478 }
1479
1480 [XmlIgnore]
1481 public float SimulationCost
1482 {
1483 get
1484 {
1485 // ignoring scripts. Don't like considering them for this
1486 if((Flags & PrimFlags.Physics) != 0)
1487 return 1.0f;
1488
1489 return 0.5f;
1490 }
1491 }
1492
1493 public byte PhysicsShapeType
1494 {
1495 get { return m_physicsShapeType; }
1496 set
1497 {
1498 byte oldv = m_physicsShapeType;
1499
1500 if (value >= 0 && value <= (byte)PhysShapeType.convex)
1501 {
1502 if (value == (byte)PhysShapeType.none && ParentGroup != null && ParentGroup.RootPart == this)
1503 m_physicsShapeType = DefaultPhysicsShapeType();
1504 else
1505 m_physicsShapeType = value;
1506 }
1507 else
1508 m_physicsShapeType = DefaultPhysicsShapeType();
1509
1510 if (m_physicsShapeType != oldv && ParentGroup != null)
1511 {
1512 if (m_physicsShapeType == (byte)PhysShapeType.none)
1513 {
1514 if (PhysActor != null)
1515 {
1516 Velocity = new Vector3(0, 0, 0);
1517 Acceleration = new Vector3(0, 0, 0);
1518 if (ParentGroup.RootPart == this)
1519 AngularVelocity = new Vector3(0, 0, 0);
1520 ParentGroup.Scene.RemovePhysicalPrim(1);
1521 RemoveFromPhysics();
1522 }
1523 }
1524 else if (PhysActor == null)
1525 ApplyPhysics((uint)Flags, VolumeDetectActive, false);
1526 else
1527 {
1528 PhysActor.PhysicsShapeType = m_physicsShapeType;
1529 if (Shape.SculptEntry)
1530 CheckSculptAndLoad();
1531 }
1532
1533 if (ParentGroup != null)
1534 ParentGroup.HasGroupChanged = true;
1535 }
1536
1537 if (m_physicsShapeType != value)
1538 {
1539 UpdatePhysRequired = true;
1540 }
1541 }
1542 }
1543
1544 public float Density // in kg/m^3
1545 {
1546 get { return m_density; }
1547 set
1548 {
1549 if (value >=1 && value <= 22587.0)
1550 {
1551 m_density = value;
1552 UpdatePhysRequired = true;
1553 }
1554
1555 ScheduleFullUpdateIfNone();
1556
1557 if (ParentGroup != null)
1558 ParentGroup.HasGroupChanged = true;
1559 }
1560 }
1561
1562 public float GravityModifier
1563 {
1564 get { return m_gravitymod; }
1565 set
1566 {
1567 if( value >= -1 && value <=28.0f)
1568 {
1569 m_gravitymod = value;
1570 UpdatePhysRequired = true;
1571 }
1572
1573 ScheduleFullUpdateIfNone();
1574
1575 if (ParentGroup != null)
1576 ParentGroup.HasGroupChanged = true;
1577
1578 }
1579 }
1580
1581 public float Friction
1582 {
1583 get { return m_friction; }
1584 set
1585 {
1586 if (value >= 0 && value <= 255.0f)
1587 {
1588 m_friction = value;
1589 UpdatePhysRequired = true;
1590 }
1591
1592 ScheduleFullUpdateIfNone();
1593
1594 if (ParentGroup != null)
1595 ParentGroup.HasGroupChanged = true;
1596 }
1597 }
1598
1599 public float Bounciness
1600 {
1601 get { return m_bounce; }
1602 set
1603 {
1604 if (value >= 0 && value <= 1.0f)
1605 {
1606 m_bounce = value;
1607 UpdatePhysRequired = true;
1608 }
1609
1610 ScheduleFullUpdateIfNone();
1611
1612 if (ParentGroup != null)
1613 ParentGroup.HasGroupChanged = true;
1614 }
1615 }
1616
1617
1265 #endregion Public Properties with only Get 1618 #endregion Public Properties with only Get
1266 1619
1267 private uint ApplyMask(uint val, bool set, uint mask) 1620 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1437,20 +1790,24 @@ namespace OpenSim.Region.Framework.Scenes
1437 /// </summary> 1790 /// </summary>
1438 /// <param name="impulsei">Vector force</param> 1791 /// <param name="impulsei">Vector force</param>
1439 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> 1792 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
1440 public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF) 1793
1794 // this is actualy Set Torque.. keeping naming so not to edit lslapi also
1795 public void SetAngularImpulse(Vector3 torquei, bool localGlobalTF)
1441 { 1796 {
1442 Vector3 impulse = impulsei; 1797 Vector3 torque = torquei;
1443 1798
1444 if (localGlobalTF) 1799 if (localGlobalTF)
1445 { 1800 {
1801/*
1446 Quaternion grot = GetWorldRotation(); 1802 Quaternion grot = GetWorldRotation();
1447 Quaternion AXgrot = grot; 1803 Quaternion AXgrot = grot;
1448 Vector3 AXimpulsei = impulsei; 1804 Vector3 AXimpulsei = impulsei;
1449 Vector3 newimpulse = AXimpulsei * AXgrot; 1805 Vector3 newimpulse = AXimpulsei * AXgrot;
1450 impulse = newimpulse; 1806 */
1807 torque *= GetWorldRotation();
1451 } 1808 }
1452 1809
1453 ParentGroup.setAngularImpulse(impulse); 1810 Torque = torque;
1454 } 1811 }
1455 1812
1456 /// <summary> 1813 /// <summary>
@@ -1458,18 +1815,19 @@ namespace OpenSim.Region.Framework.Scenes
1458 /// </summary> 1815 /// </summary>
1459 /// <param name="rootObjectFlags"></param> 1816 /// <param name="rootObjectFlags"></param>
1460 /// <param name="VolumeDetectActive"></param> 1817 /// <param name="VolumeDetectActive"></param>
1461 public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive) 1818
1819 public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive, bool building)
1462 { 1820 {
1463 if (!ParentGroup.Scene.CollidablePrims) 1821 if (!ParentGroup.Scene.CollidablePrims)
1464 return; 1822 return;
1465 1823
1466// m_log.DebugFormat( 1824 if (PhysicsShapeType == (byte)PhysShapeType.none)
1467// "[SCENE OBJECT PART]: Applying physics to {0} {1}, m_physicalPrim {2}", 1825 return;
1468// Name, LocalId, UUID, m_physicalPrim);
1469 1826
1470 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 1827 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0;
1471 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 1828 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0;
1472 1829
1830
1473 if (IsJoint()) 1831 if (IsJoint())
1474 { 1832 {
1475 DoPhysicsPropertyUpdate(isPhysical, true); 1833 DoPhysicsPropertyUpdate(isPhysical, true);
@@ -1477,16 +1835,19 @@ namespace OpenSim.Region.Framework.Scenes
1477 else 1835 else
1478 { 1836 {
1479 // Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored 1837 // Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored
1480 if (VolumeDetectActive) 1838// if (VolumeDetectActive)
1481 isPhantom = false; 1839// isPhantom = false;
1482 1840
1483 // Added clarification.. since A rigid body is an object that you can kick around, etc. 1841 // Added clarification.. since A rigid body is an object that you can kick around, etc.
1484 bool RigidBody = isPhysical && !isPhantom; 1842// bool RigidBody = isPhysical && !isPhantom;
1485 1843
1486 // 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 1844 // 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
1487 // or flexible 1845 // or flexible
1488 if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible)) 1846 // if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1847 if ((!isPhantom || isPhysical || VolumeDetectActive) && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1489 { 1848 {
1849 Vector3 velocity = Velocity;
1850 Vector3 rotationalVelocity = AngularVelocity;
1490 try 1851 try
1491 { 1852 {
1492 PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape( 1853 PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape(
@@ -1494,8 +1855,10 @@ namespace OpenSim.Region.Framework.Scenes
1494 Shape, 1855 Shape,
1495 AbsolutePosition, 1856 AbsolutePosition,
1496 Scale, 1857 Scale,
1497 RotationOffset, 1858 GetWorldRotation(),
1498 RigidBody, 1859 isPhysical,
1860 isPhantom,
1861 PhysicsShapeType,
1499 m_localId); 1862 m_localId);
1500 } 1863 }
1501 catch 1864 catch
@@ -1509,8 +1872,30 @@ namespace OpenSim.Region.Framework.Scenes
1509 { 1872 {
1510 PhysActor.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info 1873 PhysActor.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
1511 PhysActor.SetMaterial(Material); 1874 PhysActor.SetMaterial(Material);
1512 DoPhysicsPropertyUpdate(RigidBody, true); 1875
1513 PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); 1876 // if root part apply vehicle
1877 if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
1878 m_vehicle.SetVehicle(PhysActor);
1879
1880 DoPhysicsPropertyUpdate(isPhysical, true);
1881 if(VolumeDetectActive) // change if not the default only
1882 PhysActor.SetVolumeDetect(1);
1883
1884 if (!building)
1885 PhysActor.Building = false;
1886
1887 Velocity = velocity;
1888 AngularVelocity = rotationalVelocity;
1889 PhysActor.Velocity = velocity;
1890 PhysActor.RotationalVelocity = rotationalVelocity;
1891
1892 // if not vehicle and root part apply force and torque
1893 if ((m_vehicle == null || m_vehicle.Type == Vehicle.TYPE_NONE)
1894 && LocalId == ParentGroup.RootPart.LocalId)
1895 {
1896 PhysActor.Force = Force;
1897 PhysActor.Torque = Torque;
1898 }
1514 } 1899 }
1515 } 1900 }
1516 } 1901 }
@@ -1564,6 +1949,11 @@ namespace OpenSim.Region.Framework.Scenes
1564 dupe.Category = Category; 1949 dupe.Category = Category;
1565 dupe.m_rezzed = m_rezzed; 1950 dupe.m_rezzed = m_rezzed;
1566 1951
1952 dupe.m_UndoRedo = null;
1953
1954 dupe.IgnoreUndoUpdate = false;
1955 dupe.Undoing = false;
1956
1567 dupe.m_inventory = new SceneObjectPartInventory(dupe); 1957 dupe.m_inventory = new SceneObjectPartInventory(dupe);
1568 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone(); 1958 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone();
1569 1959
@@ -1579,6 +1969,7 @@ namespace OpenSim.Region.Framework.Scenes
1579 1969
1580 // Move afterwards ResetIDs as it clears the localID 1970 // Move afterwards ResetIDs as it clears the localID
1581 dupe.LocalId = localID; 1971 dupe.LocalId = localID;
1972
1582 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 1973 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1583 dupe.LastOwnerID = OwnerID; 1974 dupe.LastOwnerID = OwnerID;
1584 1975
@@ -1598,6 +1989,9 @@ namespace OpenSim.Region.Framework.Scenes
1598 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 1989 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
1599 } 1990 }
1600 1991
1992 if (dupe.PhysActor != null)
1993 dupe.PhysActor.LocalID = localID;
1994
1601 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 1995 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1602 1996
1603// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); 1997// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
@@ -1735,63 +2129,63 @@ namespace OpenSim.Region.Framework.Scenes
1735 { 2129 {
1736 if (UsePhysics != PhysActor.IsPhysical || isNew) 2130 if (UsePhysics != PhysActor.IsPhysical || isNew)
1737 { 2131 {
1738 if (PhysActor.IsPhysical) // implies UsePhysics==false for this block 2132 if (PhysActor.IsPhysical)
1739 { 2133 {
1740 if (!isNew) 2134 if (!isNew) // implies UsePhysics==false for this block
2135 {
1741 ParentGroup.Scene.RemovePhysicalPrim(1); 2136 ParentGroup.Scene.RemovePhysicalPrim(1);
1742 2137
1743 PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 2138 Velocity = new Vector3(0, 0, 0);
1744 PhysActor.OnOutOfBounds -= PhysicsOutOfBounds; 2139 Acceleration = new Vector3(0, 0, 0);
1745 PhysActor.delink(); 2140 if (ParentGroup.RootPart == this)
2141 AngularVelocity = new Vector3(0, 0, 0);
1746 2142
1747 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 2143 if (PhysActor.Phantom)
1748 { 2144 {
1749 // destroy all joints connected to this now deactivated body 2145 RemoveFromPhysics();
1750 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(PhysActor); 2146 return;
1751 } 2147 }
1752 2148
1753 // stop client-side interpolation of all joint proxy objects that have just been deleted 2149 PhysActor.IsPhysical = UsePhysics;
1754 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback, 2150 PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1755 // which stops client-side interpolation of deactivated joint proxy objects. 2151 PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
2152 PhysActor.delink();
2153 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
2154 {
2155 // destroy all joints connected to this now deactivated body
2156 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(PhysActor);
2157 }
2158 }
1756 } 2159 }
1757 2160
1758 if (!UsePhysics && !isNew) 2161 if (PhysActor.IsPhysical != UsePhysics)
1759 { 2162 PhysActor.IsPhysical = UsePhysics;
1760 // reset velocity to 0 on physics switch-off. Without that, the client thinks the
1761 // prim still has velocity and continues to interpolate its position along the old
1762 // velocity-vector.
1763 Velocity = new Vector3(0, 0, 0);
1764 Acceleration = new Vector3(0, 0, 0);
1765 AngularVelocity = new Vector3(0, 0, 0);
1766 //RotationalVelocity = new Vector3(0, 0, 0);
1767 }
1768 2163
1769 PhysActor.IsPhysical = UsePhysics; 2164 if (UsePhysics)
2165 {
2166 if (ParentGroup.RootPart.KeyframeMotion != null)
2167 ParentGroup.RootPart.KeyframeMotion.Stop();
2168 ParentGroup.RootPart.KeyframeMotion = null;
2169 ParentGroup.Scene.AddPhysicalPrim(1);
1770 2170
1771 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 2171 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1772 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 2172 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1773 /// that's not wholesome. Had to make Scene public
1774 //PhysActor = null;
1775 2173
1776 if ((Flags & PrimFlags.Phantom) == 0) 2174 if (ParentID != 0 && ParentID != LocalId)
1777 {
1778 if (UsePhysics)
1779 { 2175 {
1780 ParentGroup.Scene.AddPhysicalPrim(1); 2176 if (ParentGroup.RootPart.PhysActor != null)
1781
1782 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1783 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1784 if (ParentID != 0 && ParentID != LocalId)
1785 { 2177 {
1786 if (ParentGroup.RootPart.PhysActor != null) 2178 PhysActor.link(ParentGroup.RootPart.PhysActor);
1787 {
1788 PhysActor.link(ParentGroup.RootPart.PhysActor);
1789 }
1790 } 2179 }
1791 } 2180 }
1792 } 2181 }
1793 } 2182 }
1794 2183
2184 bool phan = ((Flags & PrimFlags.Phantom) != 0);
2185 if (PhysActor.Phantom != phan)
2186 PhysActor.Phantom = phan;
2187
2188
1795 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 2189 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
1796 // mesh data. 2190 // mesh data.
1797 if (Shape.SculptEntry) 2191 if (Shape.SculptEntry)
@@ -1924,10 +2318,7 @@ namespace OpenSim.Region.Framework.Scenes
1924 2318
1925 public Vector3 GetForce() 2319 public Vector3 GetForce()
1926 { 2320 {
1927 if (PhysActor != null) 2321 return Force;
1928 return PhysActor.Force;
1929 else
1930 return Vector3.Zero;
1931 } 2322 }
1932 2323
1933 /// <summary> 2324 /// <summary>
@@ -2561,9 +2952,9 @@ namespace OpenSim.Region.Framework.Scenes
2561 Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0); 2952 Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0);
2562 2953
2563 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2954 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2564 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2955 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2565 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2956 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2566 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2957 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2567 { 2958 {
2568 ParentGroup.AbsolutePosition = newpos; 2959 ParentGroup.AbsolutePosition = newpos;
2569 return; 2960 return;
@@ -2584,17 +2975,18 @@ namespace OpenSim.Region.Framework.Scenes
2584 //Trys to fetch sound id from prim's inventory. 2975 //Trys to fetch sound id from prim's inventory.
2585 //Prim's inventory doesn't support non script items yet 2976 //Prim's inventory doesn't support non script items yet
2586 2977
2587 lock (TaskInventory) 2978 TaskInventory.LockItemsForRead(true);
2979
2980 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2588 { 2981 {
2589 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2982 if (item.Value.Name == sound)
2590 { 2983 {
2591 if (item.Value.Name == sound) 2984 soundID = item.Value.ItemID;
2592 { 2985 break;
2593 soundID = item.Value.ItemID;
2594 break;
2595 }
2596 } 2986 }
2597 } 2987 }
2988
2989 TaskInventory.LockItemsForRead(false);
2598 } 2990 }
2599 2991
2600 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp) 2992 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp)
@@ -2715,6 +3107,19 @@ namespace OpenSim.Region.Framework.Scenes
2715 APIDTarget = Quaternion.Identity; 3107 APIDTarget = Quaternion.Identity;
2716 } 3108 }
2717 3109
3110
3111
3112 public void ScheduleFullUpdateIfNone()
3113 {
3114 if (ParentGroup == null)
3115 return;
3116
3117// ??? ParentGroup.HasGroupChanged = true;
3118
3119 if (UpdateFlag != UpdateRequired.FULL)
3120 ScheduleFullUpdate();
3121 }
3122
2718 /// <summary> 3123 /// <summary>
2719 /// Schedules this prim for a full update 3124 /// Schedules this prim for a full update
2720 /// </summary> 3125 /// </summary>
@@ -2914,8 +3319,8 @@ namespace OpenSim.Region.Framework.Scenes
2914 { 3319 {
2915 const float ROTATION_TOLERANCE = 0.01f; 3320 const float ROTATION_TOLERANCE = 0.01f;
2916 const float VELOCITY_TOLERANCE = 0.001f; 3321 const float VELOCITY_TOLERANCE = 0.001f;
2917 const float POSITION_TOLERANCE = 0.05f; 3322 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2918 const int TIME_MS_TOLERANCE = 3000; 3323 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2919 3324
2920 switch (UpdateFlag) 3325 switch (UpdateFlag)
2921 { 3326 {
@@ -2977,17 +3382,16 @@ namespace OpenSim.Region.Framework.Scenes
2977 if (!UUID.TryParse(sound, out soundID)) 3382 if (!UUID.TryParse(sound, out soundID))
2978 { 3383 {
2979 // search sound file from inventory 3384 // search sound file from inventory
2980 lock (TaskInventory) 3385 TaskInventory.LockItemsForRead(true);
3386 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2981 { 3387 {
2982 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 3388 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
2983 { 3389 {
2984 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 3390 soundID = item.Value.ItemID;
2985 { 3391 break;
2986 soundID = item.Value.ItemID;
2987 break;
2988 }
2989 } 3392 }
2990 } 3393 }
3394 TaskInventory.LockItemsForRead(false);
2991 } 3395 }
2992 3396
2993 if (soundID == UUID.Zero) 3397 if (soundID == UUID.Zero)
@@ -3072,10 +3476,13 @@ namespace OpenSim.Region.Framework.Scenes
3072 3476
3073 public void SetBuoyancy(float fvalue) 3477 public void SetBuoyancy(float fvalue)
3074 { 3478 {
3479 Buoyancy = fvalue;
3480/*
3075 if (PhysActor != null) 3481 if (PhysActor != null)
3076 { 3482 {
3077 PhysActor.Buoyancy = fvalue; 3483 PhysActor.Buoyancy = fvalue;
3078 } 3484 }
3485 */
3079 } 3486 }
3080 3487
3081 public void SetDieAtEdge(bool p) 3488 public void SetDieAtEdge(bool p)
@@ -3103,23 +3510,83 @@ namespace OpenSim.Region.Framework.Scenes
3103 3510
3104 public void SetForce(Vector3 force) 3511 public void SetForce(Vector3 force)
3105 { 3512 {
3513 Force = force;
3514/*
3106 if (PhysActor != null) 3515 if (PhysActor != null)
3107 { 3516 {
3108 PhysActor.Force = force; 3517 PhysActor.Force = force;
3109 } 3518 }
3519 */
3520 }
3521
3522 public SOPVehicle sopVehicle
3523 {
3524 get
3525 {
3526 return m_vehicle;
3527 }
3528 set
3529 {
3530 m_vehicle = value;
3531 }
3532 }
3533
3534
3535 public int VehicleType
3536 {
3537 get
3538 {
3539 if (m_vehicle == null)
3540 return (int)Vehicle.TYPE_NONE;
3541 else
3542 return (int)m_vehicle.Type;
3543 }
3544 set
3545 {
3546 SetVehicleType(value);
3547 }
3110 } 3548 }
3111 3549
3112 public void SetVehicleType(int type) 3550 public void SetVehicleType(int type)
3113 { 3551 {
3114 if (PhysActor != null) 3552 m_vehicle = null;
3553
3554 if (type == (int)Vehicle.TYPE_NONE)
3555 {
3556 if (_parentID ==0 && PhysActor != null)
3557 PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
3558 return;
3559 }
3560 m_vehicle = new SOPVehicle();
3561 m_vehicle.ProcessTypeChange((Vehicle)type);
3562 {
3563 if (_parentID ==0 && PhysActor != null)
3564 PhysActor.VehicleType = type;
3565 return;
3566 }
3567 }
3568
3569 public void SetVehicleFlags(int param, bool remove)
3570 {
3571 if (m_vehicle == null)
3572 return;
3573
3574 m_vehicle.ProcessVehicleFlags(param, remove);
3575
3576 if (_parentID ==0 && PhysActor != null)
3115 { 3577 {
3116 PhysActor.VehicleType = type; 3578 PhysActor.VehicleFlags(param, remove);
3117 } 3579 }
3118 } 3580 }
3119 3581
3120 public void SetVehicleFloatParam(int param, float value) 3582 public void SetVehicleFloatParam(int param, float value)
3121 { 3583 {
3122 if (PhysActor != null) 3584 if (m_vehicle == null)
3585 return;
3586
3587 m_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
3588
3589 if (_parentID == 0 && PhysActor != null)
3123 { 3590 {
3124 PhysActor.VehicleFloatParam(param, value); 3591 PhysActor.VehicleFloatParam(param, value);
3125 } 3592 }
@@ -3127,7 +3594,12 @@ namespace OpenSim.Region.Framework.Scenes
3127 3594
3128 public void SetVehicleVectorParam(int param, Vector3 value) 3595 public void SetVehicleVectorParam(int param, Vector3 value)
3129 { 3596 {
3130 if (PhysActor != null) 3597 if (m_vehicle == null)
3598 return;
3599
3600 m_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
3601
3602 if (_parentID == 0 && PhysActor != null)
3131 { 3603 {
3132 PhysActor.VehicleVectorParam(param, value); 3604 PhysActor.VehicleVectorParam(param, value);
3133 } 3605 }
@@ -3135,7 +3607,12 @@ namespace OpenSim.Region.Framework.Scenes
3135 3607
3136 public void SetVehicleRotationParam(int param, Quaternion rotation) 3608 public void SetVehicleRotationParam(int param, Quaternion rotation)
3137 { 3609 {
3138 if (PhysActor != null) 3610 if (m_vehicle == null)
3611 return;
3612
3613 m_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
3614
3615 if (_parentID == 0 && PhysActor != null)
3139 { 3616 {
3140 PhysActor.VehicleRotationParam(param, rotation); 3617 PhysActor.VehicleRotationParam(param, rotation);
3141 } 3618 }
@@ -3322,13 +3799,6 @@ namespace OpenSim.Region.Framework.Scenes
3322 hasProfileCut = hasDimple; // is it the same thing? 3799 hasProfileCut = hasDimple; // is it the same thing?
3323 } 3800 }
3324 3801
3325 public void SetVehicleFlags(int param, bool remove)
3326 {
3327 if (PhysActor != null)
3328 {
3329 PhysActor.VehicleFlags(param, remove);
3330 }
3331 }
3332 3802
3333 public void SetGroup(UUID groupID, IClientAPI client) 3803 public void SetGroup(UUID groupID, IClientAPI client)
3334 { 3804 {
@@ -3431,68 +3901,18 @@ namespace OpenSim.Region.Framework.Scenes
3431 //ParentGroup.ScheduleGroupForFullUpdate(); 3901 //ParentGroup.ScheduleGroupForFullUpdate();
3432 } 3902 }
3433 3903
3434 public void StoreUndoState() 3904 public void StoreUndoState(ObjectChangeType change)
3435 { 3905 {
3436 StoreUndoState(false); 3906 if (m_UndoRedo == null)
3437 } 3907 m_UndoRedo = new UndoRedoState(5);
3438 3908
3439 public void StoreUndoState(bool forGroup) 3909 lock (m_UndoRedo)
3440 {
3441 if (!Undoing)
3442 { 3910 {
3443 if (!IgnoreUndoUpdate) 3911 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3444 { 3912 {
3445 if (ParentGroup != null) 3913 m_UndoRedo.StoreUndo(this, change);
3446 {
3447 lock (m_undo)
3448 {
3449 if (m_undo.Count > 0)
3450 {
3451 UndoState last = m_undo.Peek();
3452 if (last != null)
3453 {
3454 // TODO: May need to fix for group comparison
3455 if (last.Compare(this))
3456 {
3457 // m_log.DebugFormat(
3458 // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3459 // Name, LocalId, m_undo.Count);
3460
3461 return;
3462 }
3463 }
3464 }
3465
3466 // m_log.DebugFormat(
3467 // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3468 // Name, LocalId, forGroup, m_undo.Count);
3469
3470 if (ParentGroup.GetSceneMaxUndo() > 0)
3471 {
3472 UndoState nUndo = new UndoState(this, forGroup);
3473
3474 m_undo.Push(nUndo);
3475
3476 if (m_redo.Count > 0)
3477 m_redo.Clear();
3478
3479 // m_log.DebugFormat(
3480 // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3481 // Name, LocalId, forGroup, m_undo.Count);
3482 }
3483 }
3484 }
3485 } 3914 }
3486// else
3487// {
3488// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3489// }
3490 } 3915 }
3491// else
3492// {
3493// m_log.DebugFormat(
3494// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3495// }
3496 } 3916 }
3497 3917
3498 /// <summary> 3918 /// <summary>
@@ -3502,84 +3922,46 @@ namespace OpenSim.Region.Framework.Scenes
3502 { 3922 {
3503 get 3923 get
3504 { 3924 {
3505 lock (m_undo) 3925 if (m_UndoRedo == null)
3506 return m_undo.Count; 3926 return 0;
3927 return m_UndoRedo.Count;
3507 } 3928 }
3508 } 3929 }
3509 3930
3510 public void Undo() 3931 public void Undo()
3511 { 3932 {
3512 lock (m_undo) 3933 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3513 { 3934 return;
3514// m_log.DebugFormat(
3515// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3516// Name, LocalId, m_undo.Count);
3517
3518 if (m_undo.Count > 0)
3519 {
3520 UndoState goback = m_undo.Pop();
3521
3522 if (goback != null)
3523 {
3524 UndoState nUndo = null;
3525
3526 if (ParentGroup.GetSceneMaxUndo() > 0)
3527 {
3528 nUndo = new UndoState(this, goback.ForGroup);
3529 }
3530
3531 goback.PlaybackState(this);
3532
3533 if (nUndo != null)
3534 m_redo.Push(nUndo);
3535 }
3536 }
3537 3935
3538// m_log.DebugFormat( 3936 lock (m_UndoRedo)
3539// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3937 {
3540// Name, LocalId, m_undo.Count); 3938 Undoing = true;
3939 m_UndoRedo.Undo(this);
3940 Undoing = false;
3541 } 3941 }
3542 } 3942 }
3543 3943
3544 public void Redo() 3944 public void Redo()
3545 { 3945 {
3546 lock (m_undo) 3946 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3547 { 3947 return;
3548// m_log.DebugFormat(
3549// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3550// Name, LocalId, m_redo.Count);
3551
3552 if (m_redo.Count > 0)
3553 {
3554 UndoState gofwd = m_redo.Pop();
3555
3556 if (gofwd != null)
3557 {
3558 if (ParentGroup.GetSceneMaxUndo() > 0)
3559 {
3560 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3561
3562 m_undo.Push(nUndo);
3563 }
3564
3565 gofwd.PlayfwdState(this);
3566 }
3567 3948
3568// m_log.DebugFormat( 3949 lock (m_UndoRedo)
3569// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3950 {
3570// Name, LocalId, m_redo.Count); 3951 Undoing = true;
3571 } 3952 m_UndoRedo.Redo(this);
3953 Undoing = false;
3572 } 3954 }
3573 } 3955 }
3574 3956
3575 public void ClearUndoState() 3957 public void ClearUndoState()
3576 { 3958 {
3577// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3959 if (m_UndoRedo == null || Undoing)
3960 return;
3578 3961
3579 lock (m_undo) 3962 lock (m_UndoRedo)
3580 { 3963 {
3581 m_undo.Clear(); 3964 m_UndoRedo.Clear();
3582 m_redo.Clear();
3583 } 3965 }
3584 } 3966 }
3585 3967
@@ -4209,6 +4591,27 @@ namespace OpenSim.Region.Framework.Scenes
4209 } 4591 }
4210 } 4592 }
4211 4593
4594
4595 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4596 {
4597 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
4598 return;
4599
4600 if (PhysicsShapeType != (byte)physdata.PhysShapeType)
4601 {
4602 PhysicsShapeType = (byte)physdata.PhysShapeType;
4603
4604 }
4605
4606 if(Density != physdata.Density)
4607 Density = physdata.Density;
4608 if(GravityModifier != physdata.GravitationModifier)
4609 GravityModifier = physdata.GravitationModifier;
4610 if(Friction != physdata.Friction)
4611 Friction = physdata.Friction;
4612 if(Bounciness != physdata.Bounce)
4613 Bounciness = physdata.Bounce;
4614 }
4212 /// <summary> 4615 /// <summary>
4213 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary. 4616 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary.
4214 /// </summary> 4617 /// </summary>
@@ -4216,7 +4619,8 @@ namespace OpenSim.Region.Framework.Scenes
4216 /// <param name="SetTemporary"></param> 4619 /// <param name="SetTemporary"></param>
4217 /// <param name="SetPhantom"></param> 4620 /// <param name="SetPhantom"></param>
4218 /// <param name="SetVD"></param> 4621 /// <param name="SetVD"></param>
4219 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) 4622// public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD)
4623 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
4220 { 4624 {
4221 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4625 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4222 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4626 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4226,41 +4630,58 @@ namespace OpenSim.Region.Framework.Scenes
4226 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4630 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4227 return; 4631 return;
4228 4632
4633 // do this first
4634 if (building && PhysActor != null && PhysActor.Building != building)
4635 PhysActor.Building = building;
4636
4229 // Special cases for VD. VD can only be called from a script 4637 // Special cases for VD. VD can only be called from a script
4230 // and can't be combined with changes to other states. So we can rely 4638 // and can't be combined with changes to other states. So we can rely
4231 // that... 4639 // that...
4232 // ... if VD is changed, all others are not. 4640 // ... if VD is changed, all others are not.
4233 // ... if one of the others is changed, VD is not. 4641 // ... if one of the others is changed, VD is not.
4642
4643/*
4234 if (SetVD) // VD is active, special logic applies 4644 if (SetVD) // VD is active, special logic applies
4235 {
4236 // State machine logic for VolumeDetect
4237 // More logic below
4238 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4239 4645
4240 if (phanReset) // Phantom changes from on to off switch VD off too 4646 volume detection is now independent of phantom in sl
4241 { 4647
4242 SetVD = false; // Switch it of for the course of this routine 4648 {
4243 VolumeDetectActive = false; // and also permanently 4649 // State machine logic for VolumeDetect
4244 if (PhysActor != null) 4650 // More logic below
4245 PhysActor.SetVolumeDetect(0); // Let physics know about it too 4651
4246 } 4652
4247 else 4653 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4248 { 4654
4249 // If volumedetect is active we don't want phantom to be applied. 4655 if (phanReset) // Phantom changes from on to off switch VD off too
4250 // If this is a new call to VD out of the state "phantom" 4656 {
4251 // this will also cause the prim to be visible to physics 4657 SetVD = false; // Switch it of for the course of this routine
4658 VolumeDetectActive = false; // and also permanently
4659 if (PhysActor != null)
4660 PhysActor.SetVolumeDetect(0); // Let physics know about it too
4661 }
4662 else
4663 {
4664 // If volumedetect is active we don't want phantom to be applied.
4665 // If this is a new call to VD out of the state "phantom"
4666 // this will also cause the prim to be visible to physics
4252 SetPhantom = false; 4667 SetPhantom = false;
4253 } 4668 }
4669 }
4670 else if (wasVD)
4671 {
4672 // Correspondingly, if VD is turned off, also turn off phantom
4673 SetPhantom = false;
4254 } 4674 }
4255 4675
4256 if (UsePhysics && IsJoint()) 4676 if (UsePhysics && IsJoint())
4257 { 4677 {
4258 SetPhantom = true; 4678 SetPhantom = true;
4259 } 4679 }
4260 4680*/
4261 if (UsePhysics) 4681 if (UsePhysics)
4262 { 4682 {
4263 AddFlag(PrimFlags.Physics); 4683 AddFlag(PrimFlags.Physics);
4684/*
4264 if (!wasUsingPhysics) 4685 if (!wasUsingPhysics)
4265 { 4686 {
4266 DoPhysicsPropertyUpdate(UsePhysics, false); 4687 DoPhysicsPropertyUpdate(UsePhysics, false);
@@ -4273,78 +4694,100 @@ namespace OpenSim.Region.Framework.Scenes
4273 } 4694 }
4274 } 4695 }
4275 } 4696 }
4697 */
4276 } 4698 }
4277 else 4699 else
4278 { 4700 {
4279 RemFlag(PrimFlags.Physics); 4701 RemFlag(PrimFlags.Physics);
4702/*
4280 if (wasUsingPhysics) 4703 if (wasUsingPhysics)
4281 { 4704 {
4282 DoPhysicsPropertyUpdate(UsePhysics, false); 4705 DoPhysicsPropertyUpdate(UsePhysics, false);
4283 } 4706 }
4284 } 4707*/
4708 }
4285 4709
4286 if (SetPhantom 4710 if (SetPhantom)
4287 || ParentGroup.IsAttachment 4711 AddFlag(PrimFlags.Phantom);
4712 else
4713 RemFlag(PrimFlags.Phantom);
4714
4715 if ((SetPhantom && !UsePhysics) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
4288 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints 4716 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4289 { 4717 {
4290 AddFlag(PrimFlags.Phantom); 4718// AddFlag(PrimFlags.Phantom);
4719
4720 Velocity = new Vector3(0, 0, 0);
4721 Acceleration = new Vector3(0, 0, 0);
4722 if (ParentGroup.RootPart == this)
4723 AngularVelocity = new Vector3(0, 0, 0);
4291 4724
4292 if (PhysActor != null) 4725 if (PhysActor != null)
4726 {
4727 ParentGroup.Scene.RemovePhysicalPrim(1);
4293 RemoveFromPhysics(); 4728 RemoveFromPhysics();
4729 }
4294 } 4730 }
4295 else // Not phantom 4731 else
4296 { 4732 {
4297 RemFlag(PrimFlags.Phantom);
4298
4299 if (ParentGroup.Scene == null) 4733 if (ParentGroup.Scene == null)
4300 return; 4734 return;
4301 4735
4302 if (ParentGroup.Scene.CollidablePrims && PhysActor == null) 4736 if (ParentGroup.Scene.CollidablePrims)
4303 { 4737 {
4304 // It's not phantom anymore. So make sure the physics engine get's knowledge of it 4738 if (PhysActor == null)
4305 PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4306 string.Format("{0}/{1}", Name, UUID),
4307 Shape,
4308 AbsolutePosition,
4309 Scale,
4310 RotationOffset,
4311 UsePhysics,
4312 m_localId);
4313
4314 PhysActor.SetMaterial(Material);
4315 DoPhysicsPropertyUpdate(UsePhysics, true);
4316
4317 if (!ParentGroup.IsDeleted)
4318 { 4739 {
4319 if (LocalId == ParentGroup.RootPart.LocalId) 4740 PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4741 string.Format("{0}/{1}", Name, UUID),
4742 Shape,
4743 AbsolutePosition,
4744 Scale,
4745 GetWorldRotation(), //physics wants world rotation like all other functions send
4746 UsePhysics,
4747 SetPhantom,
4748 PhysicsShapeType,
4749 m_localId);
4750
4751 PhysActor.SetMaterial(Material);
4752
4753 // if root part apply vehicle
4754 if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
4755 m_vehicle.SetVehicle(PhysActor);
4756
4757 DoPhysicsPropertyUpdate(UsePhysics, true);
4758
4759 if (!ParentGroup.IsDeleted)
4320 { 4760 {
4321 ParentGroup.CheckSculptAndLoad(); 4761 if (LocalId == ParentGroup.RootPart.LocalId)
4762 {
4763 ParentGroup.CheckSculptAndLoad();
4764 }
4322 } 4765 }
4323 }
4324 4766
4325 if ( 4767 if (
4326 ((AggregateScriptEvents & scriptEvents.collision) != 0) || 4768 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4327 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || 4769 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4328 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || 4770 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4329 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || 4771 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4330 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || 4772 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4331 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || 4773 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4332 (CollisionSound != UUID.Zero) 4774 (CollisionSound != UUID.Zero)
4333 ) 4775 )
4334 { 4776 {
4335 PhysActor.OnCollisionUpdate += PhysicsCollision; 4777 PhysActor.OnCollisionUpdate += PhysicsCollision;
4336 PhysActor.SubscribeEvents(1000); 4778 PhysActor.SubscribeEvents(1000);
4779 }
4337 } 4780 }
4338 } 4781 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 { 4782 {
4345 if (LocalId == ParentGroup.RootPart.LocalId) 4783 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4784
4785 if (!ParentGroup.IsDeleted)
4346 { 4786 {
4347 ParentGroup.CheckSculptAndLoad(); 4787 if (LocalId == ParentGroup.RootPart.LocalId)
4788 {
4789 ParentGroup.CheckSculptAndLoad();
4790 }
4348 } 4791 }
4349 } 4792 }
4350 } 4793 }
@@ -4360,7 +4803,7 @@ namespace OpenSim.Region.Framework.Scenes
4360 if (this.PhysActor != null) 4803 if (this.PhysActor != null)
4361 { 4804 {
4362 PhysActor.SetVolumeDetect(1); 4805 PhysActor.SetVolumeDetect(1);
4363 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active 4806// AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4364 this.VolumeDetectActive = true; 4807 this.VolumeDetectActive = true;
4365 } 4808 }
4366 } 4809 }
@@ -4368,8 +4811,7 @@ namespace OpenSim.Region.Framework.Scenes
4368 { 4811 {
4369 // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like 4812 // 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 :-)) 4813 // (mumbles, well, at least if you have infinte CPU powers :-))
4371 PhysicsActor pa = this.PhysActor; 4814 if (this.PhysActor != null)
4372 if (pa != null)
4373 { 4815 {
4374 PhysActor.SetVolumeDetect(0); 4816 PhysActor.SetVolumeDetect(0);
4375 } 4817 }
@@ -4387,12 +4829,15 @@ namespace OpenSim.Region.Framework.Scenes
4387 } 4829 }
4388 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); 4830 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4389 4831
4832 // and last in case we have a new actor and not building
4833 if (PhysActor != null && PhysActor.Building != building)
4834 PhysActor.Building = building;
4390 if (ParentGroup != null) 4835 if (ParentGroup != null)
4391 { 4836 {
4392 ParentGroup.HasGroupChanged = true; 4837 ParentGroup.HasGroupChanged = true;
4393 ScheduleFullUpdate(); 4838 ScheduleFullUpdate();
4394 } 4839 }
4395 4840
4396// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); 4841// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4397 } 4842 }
4398 4843
@@ -4750,5 +5195,17 @@ namespace OpenSim.Region.Framework.Scenes
4750 Color color = Color; 5195 Color color = Color;
4751 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 5196 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4752 } 5197 }
5198
5199 public void ResetOwnerChangeFlag()
5200 {
5201 List<UUID> inv = Inventory.GetInventoryList();
5202
5203 foreach (UUID itemID in inv)
5204 {
5205 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
5206 item.OwnerChanged = false;
5207 Inventory.UpdateInventoryItem(item, false, false);
5208 }
5209 }
4753 } 5210 }
4754} 5211}