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.cs1158
1 files changed, 817 insertions, 341 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 046553b..969ddaf 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.
@@ -182,6 +183,15 @@ namespace OpenSim.Region.Framework.Scenes
182 183
183 public uint TimeStampTerse; 184 public uint TimeStampTerse;
184 185
186 // The following two are to hold the attachment data
187 // while an object is inworld
188 [XmlIgnore]
189 public byte AttachPoint = 0;
190
191 [XmlIgnore]
192 public Vector3 AttachOffset = Vector3.Zero;
193
194 [XmlIgnore]
185 public int STATUS_ROTATE_X; 195 public int STATUS_ROTATE_X;
186 196
187 public int STATUS_ROTATE_Y; 197 public int STATUS_ROTATE_Y;
@@ -208,8 +218,7 @@ namespace OpenSim.Region.Framework.Scenes
208 218
209 public Vector3 RotationAxis = Vector3.One; 219 public Vector3 RotationAxis = Vector3.One;
210 220
211 public bool VolumeDetectActive; // XmlIgnore set to avoid problems with persistance until I come to care for this 221 public bool VolumeDetectActive;
212 // Certainly this must be a persistant setting finally
213 222
214 public bool IsWaitingForFirstSpinUpdatePacket; 223 public bool IsWaitingForFirstSpinUpdatePacket;
215 224
@@ -249,10 +258,10 @@ namespace OpenSim.Region.Framework.Scenes
249 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 258 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
250 private Vector3 m_sitTargetPosition; 259 private Vector3 m_sitTargetPosition;
251 private string m_sitAnimation = "SIT"; 260 private string m_sitAnimation = "SIT";
261 private bool m_occupied; // KF if any av is sitting on this prim
252 private string m_text = String.Empty; 262 private string m_text = String.Empty;
253 private string m_touchName = String.Empty; 263 private string m_touchName = String.Empty;
254 private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5); 264 private UndoRedoState m_UndoRedo = null;
255 private readonly Stack<UndoState> m_redo = new Stack<UndoState>(5);
256 265
257 private bool m_passTouches; 266 private bool m_passTouches;
258 267
@@ -280,7 +289,16 @@ namespace OpenSim.Region.Framework.Scenes
280 protected Vector3 m_lastAcceleration; 289 protected Vector3 m_lastAcceleration;
281 protected Vector3 m_lastAngularVelocity; 290 protected Vector3 m_lastAngularVelocity;
282 protected int m_lastTerseSent; 291 protected int m_lastTerseSent;
283 292 protected float m_buoyancy = 0.0f;
293 protected Vector3 m_force;
294 protected Vector3 m_torque;
295
296 protected byte m_physicsShapeType = (byte)PhysShapeType.prim;
297 protected float m_density = 1000.0f; // in kg/m^3
298 protected float m_gravitymod = 1.0f;
299 protected float m_friction = 0.6f; // wood
300 protected float m_bounce = 0.5f; // wood
301
284 /// <summary> 302 /// <summary>
285 /// Stores media texture data 303 /// Stores media texture data
286 /// </summary> 304 /// </summary>
@@ -296,6 +314,17 @@ namespace OpenSim.Region.Framework.Scenes
296 private UUID m_collisionSound; 314 private UUID m_collisionSound;
297 private float m_collisionSoundVolume; 315 private float m_collisionSoundVolume;
298 316
317
318 private SOPVehicle m_vehicle = null;
319
320 private KeyframeMotion m_keyframeMotion = null;
321
322 public KeyframeMotion KeyframeMotion
323 {
324 get; set;
325 }
326
327
299 #endregion Fields 328 #endregion Fields
300 329
301// ~SceneObjectPart() 330// ~SceneObjectPart()
@@ -338,7 +367,7 @@ namespace OpenSim.Region.Framework.Scenes
338 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 367 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
339 Quaternion rotationOffset, Vector3 offsetPosition) : this() 368 Quaternion rotationOffset, Vector3 offsetPosition) : this()
340 { 369 {
341 m_name = "Primitive"; 370 m_name = "Object";
342 371
343 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 372 CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
344 LastOwnerID = CreatorID = OwnerID = ownerID; 373 LastOwnerID = CreatorID = OwnerID = ownerID;
@@ -378,7 +407,7 @@ namespace OpenSim.Region.Framework.Scenes
378 private uint _ownerMask = (uint)PermissionMask.All; 407 private uint _ownerMask = (uint)PermissionMask.All;
379 private uint _groupMask = (uint)PermissionMask.None; 408 private uint _groupMask = (uint)PermissionMask.None;
380 private uint _everyoneMask = (uint)PermissionMask.None; 409 private uint _everyoneMask = (uint)PermissionMask.None;
381 private uint _nextOwnerMask = (uint)PermissionMask.All; 410 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
382 private PrimFlags _flags = PrimFlags.None; 411 private PrimFlags _flags = PrimFlags.None;
383 private DateTime m_expires; 412 private DateTime m_expires;
384 private DateTime m_rezzed; 413 private DateTime m_rezzed;
@@ -472,12 +501,16 @@ namespace OpenSim.Region.Framework.Scenes
472 } 501 }
473 502
474 /// <value> 503 /// <value>
475 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 504 /// Get the inventory list
476 /// </value> 505 /// </value>
477 public TaskInventoryDictionary TaskInventory 506 public TaskInventoryDictionary TaskInventory
478 { 507 {
479 get { return m_inventory.Items; } 508 get {
480 set { m_inventory.Items = value; } 509 return m_inventory.Items;
510 }
511 set {
512 m_inventory.Items = value;
513 }
481 } 514 }
482 515
483 /// <summary> 516 /// <summary>
@@ -527,20 +560,6 @@ namespace OpenSim.Region.Framework.Scenes
527 } 560 }
528 } 561 }
529 562
530 public byte Material
531 {
532 get { return (byte) m_material; }
533 set
534 {
535 m_material = (Material)value;
536
537 PhysicsActor pa = PhysActor;
538
539 if (pa != null)
540 pa.SetMaterial((int)value);
541 }
542 }
543
544 public bool PassTouches 563 public bool PassTouches
545 { 564 {
546 get { return m_passTouches; } 565 get { return m_passTouches; }
@@ -623,14 +642,12 @@ namespace OpenSim.Region.Framework.Scenes
623 set { m_LoopSoundSlavePrims = value; } 642 set { m_LoopSoundSlavePrims = value; }
624 } 643 }
625 644
626
627 public Byte[] TextureAnimation 645 public Byte[] TextureAnimation
628 { 646 {
629 get { return m_TextureAnimation; } 647 get { return m_TextureAnimation; }
630 set { m_TextureAnimation = value; } 648 set { m_TextureAnimation = value; }
631 } 649 }
632 650
633
634 public Byte[] ParticleSystem 651 public Byte[] ParticleSystem
635 { 652 {
636 get { return m_particleSystem; } 653 get { return m_particleSystem; }
@@ -667,8 +684,12 @@ namespace OpenSim.Region.Framework.Scenes
667 { 684 {
668 // If this is a linkset, we don't want the physics engine mucking up our group position here. 685 // If this is a linkset, we don't want the physics engine mucking up our group position here.
669 PhysicsActor actor = PhysActor; 686 PhysicsActor actor = PhysActor;
670 if (actor != null && ParentID == 0) 687 if (ParentID == 0)
671 m_groupPosition = actor.Position; 688 {
689 if (actor != null)
690 m_groupPosition = actor.Position;
691 return m_groupPosition;
692 }
672 693
673 if (ParentGroup.IsAttachment) 694 if (ParentGroup.IsAttachment)
674 { 695 {
@@ -677,12 +698,14 @@ namespace OpenSim.Region.Framework.Scenes
677 return sp.AbsolutePosition; 698 return sp.AbsolutePosition;
678 } 699 }
679 700
701 // use root prim's group position. Physics may have updated it
702 if (ParentGroup.RootPart != this)
703 m_groupPosition = ParentGroup.RootPart.GroupPosition;
680 return m_groupPosition; 704 return m_groupPosition;
681 } 705 }
682 set 706 set
683 { 707 {
684 m_groupPosition = value; 708 m_groupPosition = value;
685
686 PhysicsActor actor = PhysActor; 709 PhysicsActor actor = PhysActor;
687 if (actor != null) 710 if (actor != null)
688 { 711 {
@@ -708,16 +731,6 @@ namespace OpenSim.Region.Framework.Scenes
708 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); 731 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message);
709 } 732 }
710 } 733 }
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 } 734 }
722 } 735 }
723 736
@@ -726,7 +739,7 @@ namespace OpenSim.Region.Framework.Scenes
726 get { return m_offsetPosition; } 739 get { return m_offsetPosition; }
727 set 740 set
728 { 741 {
729// StoreUndoState(); 742 Vector3 oldpos = m_offsetPosition;
730 m_offsetPosition = value; 743 m_offsetPosition = value;
731 744
732 if (ParentGroup != null && !ParentGroup.IsDeleted) 745 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -741,7 +754,22 @@ namespace OpenSim.Region.Framework.Scenes
741 if (ParentGroup.Scene != null) 754 if (ParentGroup.Scene != null)
742 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 755 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
743 } 756 }
757
758 if (!m_parentGroup.m_dupeInProgress)
759 {
760 List<ScenePresence> avs = ParentGroup.GetLinkedAvatars();
761 foreach (ScenePresence av in avs)
762 {
763 if (av.ParentID == m_localId)
764 {
765 Vector3 offset = (m_offsetPosition - oldpos);
766 av.AbsolutePosition += offset;
767 av.SendAvatarDataToAllAgents();
768 }
769 }
770 }
744 } 771 }
772 TriggerScriptChangedEvent(Changed.POSITION);
745 } 773 }
746 } 774 }
747 775
@@ -790,7 +818,7 @@ namespace OpenSim.Region.Framework.Scenes
790 818
791 set 819 set
792 { 820 {
793 StoreUndoState(); 821// StoreUndoState();
794 m_rotationOffset = value; 822 m_rotationOffset = value;
795 823
796 PhysicsActor actor = PhysActor; 824 PhysicsActor actor = PhysActor;
@@ -878,7 +906,7 @@ namespace OpenSim.Region.Framework.Scenes
878 get 906 get
879 { 907 {
880 PhysicsActor actor = PhysActor; 908 PhysicsActor actor = PhysActor;
881 if ((actor != null) && actor.IsPhysical) 909 if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this)
882 { 910 {
883 m_angularVelocity = actor.RotationalVelocity; 911 m_angularVelocity = actor.RotationalVelocity;
884 } 912 }
@@ -890,7 +918,16 @@ namespace OpenSim.Region.Framework.Scenes
890 /// <summary></summary> 918 /// <summary></summary>
891 public Vector3 Acceleration 919 public Vector3 Acceleration
892 { 920 {
893 get { return m_acceleration; } 921 get
922 {
923 PhysicsActor actor = PhysActor;
924 if (actor != null)
925 {
926 m_acceleration = actor.Acceleration;
927 }
928 return m_acceleration;
929 }
930
894 set { m_acceleration = value; } 931 set { m_acceleration = value; }
895 } 932 }
896 933
@@ -947,7 +984,10 @@ namespace OpenSim.Region.Framework.Scenes
947 public PrimitiveBaseShape Shape 984 public PrimitiveBaseShape Shape
948 { 985 {
949 get { return m_shape; } 986 get { return m_shape; }
950 set { m_shape = value;} 987 set
988 {
989 m_shape = value;
990 }
951 } 991 }
952 992
953 /// <summary> 993 /// <summary>
@@ -960,7 +1000,6 @@ namespace OpenSim.Region.Framework.Scenes
960 { 1000 {
961 if (m_shape != null) 1001 if (m_shape != null)
962 { 1002 {
963 StoreUndoState();
964 1003
965 m_shape.Scale = value; 1004 m_shape.Scale = value;
966 1005
@@ -987,6 +1026,7 @@ namespace OpenSim.Region.Framework.Scenes
987 } 1026 }
988 1027
989 public UpdateRequired UpdateFlag { get; set; } 1028 public UpdateRequired UpdateFlag { get; set; }
1029 public bool UpdatePhysRequired { get; set; }
990 1030
991 /// <summary> 1031 /// <summary>
992 /// Used for media on a prim. 1032 /// Used for media on a prim.
@@ -1027,10 +1067,7 @@ namespace OpenSim.Region.Framework.Scenes
1027 { 1067 {
1028 get 1068 get
1029 { 1069 {
1030 if (ParentGroup.IsAttachment) 1070 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
1031 return GroupPosition;
1032
1033 return m_offsetPosition + m_groupPosition;
1034 } 1071 }
1035 } 1072 }
1036 1073
@@ -1208,6 +1245,13 @@ namespace OpenSim.Region.Framework.Scenes
1208 _flags = value; 1245 _flags = value;
1209 } 1246 }
1210 } 1247 }
1248
1249 [XmlIgnore]
1250 public bool IsOccupied // KF If an av is sittingon this prim
1251 {
1252 get { return m_occupied; }
1253 set { m_occupied = value; }
1254 }
1211 1255
1212 /// <summary> 1256 /// <summary>
1213 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero 1257 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero
@@ -1267,6 +1311,316 @@ namespace OpenSim.Region.Framework.Scenes
1267 set { m_collisionSoundVolume = value; } 1311 set { m_collisionSoundVolume = value; }
1268 } 1312 }
1269 1313
1314 public float Buoyancy
1315 {
1316 get
1317 {
1318 if (ParentGroup.RootPart == this)
1319 return m_buoyancy;
1320
1321 return ParentGroup.RootPart.Buoyancy;
1322 }
1323 set
1324 {
1325 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1326 {
1327 ParentGroup.RootPart.Buoyancy = value;
1328 return;
1329 }
1330 m_buoyancy = value;
1331 if (PhysActor != null)
1332 PhysActor.Buoyancy = value;
1333 }
1334 }
1335
1336 public Vector3 Force
1337 {
1338 get
1339 {
1340 if (ParentGroup.RootPart == this)
1341 return m_force;
1342
1343 return ParentGroup.RootPart.Force;
1344 }
1345
1346 set
1347 {
1348 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1349 {
1350 ParentGroup.RootPart.Force = value;
1351 return;
1352 }
1353 m_force = value;
1354 if (PhysActor != null)
1355 PhysActor.Force = value;
1356 }
1357 }
1358
1359 public Vector3 Torque
1360 {
1361 get
1362 {
1363 if (ParentGroup.RootPart == this)
1364 return m_torque;
1365
1366 return ParentGroup.RootPart.Torque;
1367 }
1368
1369 set
1370 {
1371 if (ParentGroup != null && ParentGroup.RootPart != null && ParentGroup.RootPart != this)
1372 {
1373 ParentGroup.RootPart.Torque = value;
1374 return;
1375 }
1376 m_torque = value;
1377 if (PhysActor != null)
1378 PhysActor.Torque = value;
1379 }
1380 }
1381
1382 public byte Material
1383 {
1384 get { return (byte)m_material; }
1385 set
1386 {
1387 if (value >= 0 && value <= (byte)SOPMaterialData.MaxMaterial)
1388 {
1389 bool update = false;
1390
1391 if (m_material != (Material)value)
1392 {
1393 update = true;
1394 m_material = (Material)value;
1395 }
1396
1397 if (m_friction != SOPMaterialData.friction(m_material))
1398 {
1399 update = true;
1400 m_friction = SOPMaterialData.friction(m_material);
1401 }
1402
1403 if (m_bounce != SOPMaterialData.bounce(m_material))
1404 {
1405 update = true;
1406 m_bounce = SOPMaterialData.bounce(m_material);
1407 }
1408
1409 if (update)
1410 {
1411 if (PhysActor != null)
1412 {
1413 PhysActor.SetMaterial((int)value);
1414 }
1415 if(ParentGroup != null)
1416 ParentGroup.HasGroupChanged = true;
1417 ScheduleFullUpdateIfNone();
1418 UpdatePhysRequired = true;
1419 }
1420 }
1421 }
1422 }
1423
1424 // not a propriety to move to methods place later
1425 private bool HasMesh()
1426 {
1427 if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh))
1428 return true;
1429 return false;
1430 }
1431
1432 // not a propriety to move to methods place later
1433 public byte DefaultPhysicsShapeType()
1434 {
1435 byte type;
1436
1437 if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh))
1438 type = (byte)PhysShapeType.convex;
1439 else
1440 type = (byte)PhysShapeType.prim;
1441
1442 return type;
1443 }
1444
1445 [XmlIgnore]
1446 public bool UsesComplexCost
1447 {
1448 get
1449 {
1450 byte pst = PhysicsShapeType;
1451 if(pst == (byte) PhysShapeType.none || pst == (byte) PhysShapeType.convex || HasMesh())
1452 return true;
1453 return false;
1454 }
1455 }
1456
1457 [XmlIgnore]
1458 public float PhysicsCost
1459 {
1460 get
1461 {
1462 if(PhysicsShapeType == (byte)PhysShapeType.none)
1463 return 0;
1464
1465 float cost = 0.1f;
1466 if (PhysActor != null)
1467// cost += PhysActor.Cost;
1468
1469 if ((Flags & PrimFlags.Physics) != 0)
1470 cost *= (1.0f + 0.01333f * Scale.LengthSquared()); // 0.01333 == 0.04/3
1471 return cost;
1472 }
1473 }
1474
1475 [XmlIgnore]
1476 public float StreamingCost
1477 {
1478 get
1479 {
1480
1481
1482 return 0.1f;
1483 }
1484 }
1485
1486 [XmlIgnore]
1487 public float SimulationCost
1488 {
1489 get
1490 {
1491 // ignoring scripts. Don't like considering them for this
1492 if((Flags & PrimFlags.Physics) != 0)
1493 return 1.0f;
1494
1495 return 0.5f;
1496 }
1497 }
1498
1499 public byte PhysicsShapeType
1500 {
1501 get { return m_physicsShapeType; }
1502 set
1503 {
1504 byte oldv = m_physicsShapeType;
1505
1506 if (value >= 0 && value <= (byte)PhysShapeType.convex)
1507 {
1508 if (value == (byte)PhysShapeType.none && ParentGroup != null && ParentGroup.RootPart == this)
1509 m_physicsShapeType = DefaultPhysicsShapeType();
1510 else
1511 m_physicsShapeType = value;
1512 }
1513 else
1514 m_physicsShapeType = DefaultPhysicsShapeType();
1515
1516 if (m_physicsShapeType != oldv && ParentGroup != null)
1517 {
1518 if (m_physicsShapeType == (byte)PhysShapeType.none)
1519 {
1520 if (PhysActor != null)
1521 {
1522 Velocity = new Vector3(0, 0, 0);
1523 Acceleration = new Vector3(0, 0, 0);
1524 if (ParentGroup.RootPart == this)
1525 AngularVelocity = new Vector3(0, 0, 0);
1526 ParentGroup.Scene.RemovePhysicalPrim(1);
1527 RemoveFromPhysics();
1528 }
1529 }
1530 else if (PhysActor == null)
1531 ApplyPhysics((uint)Flags, VolumeDetectActive, false);
1532 else
1533 {
1534 PhysActor.PhysicsShapeType = m_physicsShapeType;
1535 if (Shape.SculptEntry)
1536 CheckSculptAndLoad();
1537 }
1538
1539 if (ParentGroup != null)
1540 ParentGroup.HasGroupChanged = true;
1541 }
1542
1543 if (m_physicsShapeType != value)
1544 {
1545 UpdatePhysRequired = true;
1546 }
1547 }
1548 }
1549
1550 public float Density // in kg/m^3
1551 {
1552 get { return m_density; }
1553 set
1554 {
1555 if (value >=1 && value <= 22587.0)
1556 {
1557 m_density = value;
1558 UpdatePhysRequired = true;
1559 }
1560
1561 ScheduleFullUpdateIfNone();
1562
1563 if (ParentGroup != null)
1564 ParentGroup.HasGroupChanged = true;
1565 }
1566 }
1567
1568 public float GravityModifier
1569 {
1570 get { return m_gravitymod; }
1571 set
1572 {
1573 if( value >= -1 && value <=28.0f)
1574 {
1575 m_gravitymod = value;
1576 UpdatePhysRequired = true;
1577 }
1578
1579 ScheduleFullUpdateIfNone();
1580
1581 if (ParentGroup != null)
1582 ParentGroup.HasGroupChanged = true;
1583
1584 }
1585 }
1586
1587 public float Friction
1588 {
1589 get { return m_friction; }
1590 set
1591 {
1592 if (value >= 0 && value <= 255.0f)
1593 {
1594 m_friction = value;
1595 UpdatePhysRequired = true;
1596 }
1597
1598 ScheduleFullUpdateIfNone();
1599
1600 if (ParentGroup != null)
1601 ParentGroup.HasGroupChanged = true;
1602 }
1603 }
1604
1605 public float Bounciness
1606 {
1607 get { return m_bounce; }
1608 set
1609 {
1610 if (value >= 0 && value <= 1.0f)
1611 {
1612 m_bounce = value;
1613 UpdatePhysRequired = true;
1614 }
1615
1616 ScheduleFullUpdateIfNone();
1617
1618 if (ParentGroup != null)
1619 ParentGroup.HasGroupChanged = true;
1620 }
1621 }
1622
1623
1270 #endregion Public Properties with only Get 1624 #endregion Public Properties with only Get
1271 1625
1272 private uint ApplyMask(uint val, bool set, uint mask) 1626 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1432,7 +1786,7 @@ namespace OpenSim.Region.Framework.Scenes
1432 impulse = newimpulse; 1786 impulse = newimpulse;
1433 } 1787 }
1434 1788
1435 ParentGroup.applyAngularImpulse(impulse); 1789 ParentGroup.ApplyAngularImpulse(impulse);
1436 } 1790 }
1437 1791
1438 /// <summary> 1792 /// <summary>
@@ -1442,20 +1796,24 @@ namespace OpenSim.Region.Framework.Scenes
1442 /// </summary> 1796 /// </summary>
1443 /// <param name="impulsei">Vector force</param> 1797 /// <param name="impulsei">Vector force</param>
1444 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param> 1798 /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
1445 public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF) 1799
1800 // this is actualy Set Torque.. keeping naming so not to edit lslapi also
1801 public void SetAngularImpulse(Vector3 torquei, bool localGlobalTF)
1446 { 1802 {
1447 Vector3 impulse = impulsei; 1803 Vector3 torque = torquei;
1448 1804
1449 if (localGlobalTF) 1805 if (localGlobalTF)
1450 { 1806 {
1807/*
1451 Quaternion grot = GetWorldRotation(); 1808 Quaternion grot = GetWorldRotation();
1452 Quaternion AXgrot = grot; 1809 Quaternion AXgrot = grot;
1453 Vector3 AXimpulsei = impulsei; 1810 Vector3 AXimpulsei = impulsei;
1454 Vector3 newimpulse = AXimpulsei * AXgrot; 1811 Vector3 newimpulse = AXimpulsei * AXgrot;
1455 impulse = newimpulse; 1812 */
1813 torque *= GetWorldRotation();
1456 } 1814 }
1457 1815
1458 ParentGroup.setAngularImpulse(impulse); 1816 Torque = torque;
1459 } 1817 }
1460 1818
1461 /// <summary> 1819 /// <summary>
@@ -1463,18 +1821,19 @@ namespace OpenSim.Region.Framework.Scenes
1463 /// </summary> 1821 /// </summary>
1464 /// <param name="rootObjectFlags"></param> 1822 /// <param name="rootObjectFlags"></param>
1465 /// <param name="VolumeDetectActive"></param> 1823 /// <param name="VolumeDetectActive"></param>
1466 public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive) 1824
1825 public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive, bool building)
1467 { 1826 {
1468 if (!ParentGroup.Scene.CollidablePrims) 1827 if (!ParentGroup.Scene.CollidablePrims)
1469 return; 1828 return;
1470 1829
1471// m_log.DebugFormat( 1830 if (PhysicsShapeType == (byte)PhysShapeType.none)
1472// "[SCENE OBJECT PART]: Applying physics to {0} {1}, m_physicalPrim {2}", 1831 return;
1473// Name, LocalId, UUID, m_physicalPrim);
1474 1832
1475 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; 1833 bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0;
1476 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; 1834 bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0;
1477 1835
1836
1478 if (IsJoint()) 1837 if (IsJoint())
1479 { 1838 {
1480 DoPhysicsPropertyUpdate(isPhysical, true); 1839 DoPhysicsPropertyUpdate(isPhysical, true);
@@ -1482,20 +1841,66 @@ namespace OpenSim.Region.Framework.Scenes
1482 else 1841 else
1483 { 1842 {
1484 // Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored 1843 // Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored
1485 if (VolumeDetectActive) 1844// if (VolumeDetectActive)
1486 isPhantom = false; 1845// isPhantom = false;
1487 1846
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 1847 // 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
1489 // or flexible 1848 // or flexible
1490 if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible)) 1849 // if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1850 if ((!isPhantom || isPhysical || VolumeDetectActive) && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible))
1491 { 1851 {
1492 // Added clarification.. since A rigid body is an object that you can kick around, etc. 1852 Vector3 velocity = Velocity;
1493 bool rigidBody = isPhysical && !isPhantom; 1853 Vector3 rotationalVelocity = AngularVelocity;
1854 try
1855 {
1856 PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape(
1857 string.Format("{0}/{1}", Name, UUID),
1858 Shape,
1859 AbsolutePosition,
1860 Scale,
1861 GetWorldRotation(),
1862 isPhysical,
1863 isPhantom,
1864 PhysicsShapeType,
1865 m_localId);
1866 }
1867 catch
1868 {
1869 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid);
1870 PhysActor = null;
1871 }
1494 1872
1495 PhysicsActor pa = AddToPhysics(rigidBody); 1873 PhysicsActor pa = PhysActor;
1496 1874
1497 if (pa != null) 1875 if (pa != null)
1498 pa.SetVolumeDetect(VolumeDetectActive ? 1 : 0); 1876 {
1877 pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
1878 pa.SetMaterial(Material);
1879
1880 // if root part apply vehicle
1881 if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
1882 m_vehicle.SetVehicle(pa);
1883
1884 DoPhysicsPropertyUpdate(isPhysical, true);
1885 if(VolumeDetectActive) // change if not the default only
1886 pa.SetVolumeDetect(1);
1887
1888 if (!building)
1889 pa.Building = false;
1890
1891 Velocity = velocity;
1892 AngularVelocity = rotationalVelocity;
1893 pa.Velocity = velocity;
1894 pa.RotationalVelocity = rotationalVelocity;
1895
1896 // if not vehicle and root part apply force and torque
1897 if ((m_vehicle == null || m_vehicle.Type == Vehicle.TYPE_NONE)
1898 && LocalId == ParentGroup.RootPart.LocalId)
1899 {
1900 pa.Force = Force;
1901 pa.Torque = Torque;
1902 }
1903 }
1499 } 1904 }
1500 } 1905 }
1501 } 1906 }
@@ -1548,6 +1953,11 @@ namespace OpenSim.Region.Framework.Scenes
1548 dupe.Category = Category; 1953 dupe.Category = Category;
1549 dupe.m_rezzed = m_rezzed; 1954 dupe.m_rezzed = m_rezzed;
1550 1955
1956 dupe.m_UndoRedo = null;
1957
1958 dupe.IgnoreUndoUpdate = false;
1959 dupe.Undoing = false;
1960
1551 dupe.m_inventory = new SceneObjectPartInventory(dupe); 1961 dupe.m_inventory = new SceneObjectPartInventory(dupe);
1552 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone(); 1962 dupe.m_inventory.Items = (TaskInventoryDictionary)m_inventory.Items.Clone();
1553 1963
@@ -1563,6 +1973,7 @@ namespace OpenSim.Region.Framework.Scenes
1563 1973
1564 // Move afterwards ResetIDs as it clears the localID 1974 // Move afterwards ResetIDs as it clears the localID
1565 dupe.LocalId = localID; 1975 dupe.LocalId = localID;
1976
1566 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 1977 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1567 dupe.LastOwnerID = OwnerID; 1978 dupe.LastOwnerID = OwnerID;
1568 1979
@@ -1582,6 +1993,9 @@ namespace OpenSim.Region.Framework.Scenes
1582 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 1993 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
1583 } 1994 }
1584 1995
1996 if (dupe.PhysActor != null)
1997 dupe.PhysActor.LocalID = localID;
1998
1585 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 1999 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1586 2000
1587// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); 2001// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
@@ -1723,63 +2137,63 @@ namespace OpenSim.Region.Framework.Scenes
1723 { 2137 {
1724 if (pa.IsPhysical) // implies UsePhysics==false for this block 2138 if (pa.IsPhysical) // implies UsePhysics==false for this block
1725 { 2139 {
1726 if (!isNew) 2140 if (!isNew) // implies UsePhysics==false for this block
2141 {
1727 ParentGroup.Scene.RemovePhysicalPrim(1); 2142 ParentGroup.Scene.RemovePhysicalPrim(1);
1728 2143
1729 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 2144 Velocity = new Vector3(0, 0, 0);
1730 pa.OnOutOfBounds -= PhysicsOutOfBounds; 2145 Acceleration = new Vector3(0, 0, 0);
1731 pa.delink(); 2146 if (ParentGroup.RootPart == this)
2147 AngularVelocity = new Vector3(0, 0, 0);
1732 2148
1733 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 2149 if (pa.Phantom)
1734 { 2150 {
1735 // destroy all joints connected to this now deactivated body 2151 RemoveFromPhysics();
1736 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa); 2152 return;
1737 } 2153 }
1738 2154
1739 // stop client-side interpolation of all joint proxy objects that have just been deleted 2155 pa.IsPhysical = UsePhysics;
1740 // this is done because RemoveAllJointsConnectedToActor invokes the OnJointDeactivated callback, 2156 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1741 // which stops client-side interpolation of deactivated joint proxy objects. 2157 pa.OnOutOfBounds -= PhysicsOutOfBounds;
2158 pa.delink();
2159 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
2160 {
2161 // destroy all joints connected to this now deactivated body
2162 ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa);
2163 }
2164 }
1742 } 2165 }
1743 2166
1744 if (!UsePhysics && !isNew) 2167 if (pa.IsPhysical != UsePhysics)
1745 { 2168 pa.IsPhysical = UsePhysics;
1746 // reset velocity to 0 on physics switch-off. Without that, the client thinks the
1747 // prim still has velocity and continues to interpolate its position along the old
1748 // velocity-vector.
1749 Velocity = new Vector3(0, 0, 0);
1750 Acceleration = new Vector3(0, 0, 0);
1751 AngularVelocity = new Vector3(0, 0, 0);
1752 //RotationalVelocity = new Vector3(0, 0, 0);
1753 }
1754 2169
1755 pa.IsPhysical = UsePhysics; 2170 if (UsePhysics)
2171 {
2172 if (ParentGroup.RootPart.KeyframeMotion != null)
2173 ParentGroup.RootPart.KeyframeMotion.Stop();
2174 ParentGroup.RootPart.KeyframeMotion = null;
2175 ParentGroup.Scene.AddPhysicalPrim(1);
1756 2176
1757 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 2177 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1758 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 2178 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
1759 /// that's not wholesome. Had to make Scene public
1760 //PhysActor = null;
1761 2179
1762 if ((Flags & PrimFlags.Phantom) == 0) 2180 if (ParentID != 0 && ParentID != LocalId)
1763 {
1764 if (UsePhysics)
1765 { 2181 {
1766 ParentGroup.Scene.AddPhysicalPrim(1); 2182 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
1767 2183
1768 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 2184 if (parentPa != null)
1769 pa.OnOutOfBounds += PhysicsOutOfBounds;
1770 if (ParentID != 0 && ParentID != LocalId)
1771 { 2185 {
1772 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; 2186 pa.link(parentPa);
1773
1774 if (parentPa != null)
1775 {
1776 pa.link(parentPa);
1777 }
1778 } 2187 }
1779 } 2188 }
1780 } 2189 }
1781 } 2190 }
1782 2191
2192 bool phan = ((Flags & PrimFlags.Phantom) != 0);
2193 if (pa.Phantom != phan)
2194 pa.Phantom = phan;
2195
2196
1783 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the 2197 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
1784 // mesh data. 2198 // mesh data.
1785 if (Shape.SculptEntry) 2199 if (Shape.SculptEntry)
@@ -1899,7 +2313,10 @@ namespace OpenSim.Region.Framework.Scenes
1899 PhysicsActor pa = PhysActor; 2313 PhysicsActor pa = PhysActor;
1900 2314
1901 if (pa != null) 2315 if (pa != null)
1902 return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z); 2316 {
2317 Vector3 vtmp = pa.CenterOfMass;
2318 return vtmp;
2319 }
1903 else 2320 else
1904 return new Vector3(0, 0, 0); 2321 return new Vector3(0, 0, 0);
1905 } 2322 }
@@ -1916,12 +2333,7 @@ namespace OpenSim.Region.Framework.Scenes
1916 2333
1917 public Vector3 GetForce() 2334 public Vector3 GetForce()
1918 { 2335 {
1919 PhysicsActor pa = PhysActor; 2336 return Force;
1920
1921 if (pa != null)
1922 return pa.Force;
1923 else
1924 return Vector3.Zero;
1925 } 2337 }
1926 2338
1927 /// <summary> 2339 /// <summary>
@@ -2557,9 +2969,9 @@ namespace OpenSim.Region.Framework.Scenes
2557 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2969 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2558 2970
2559 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) 2971 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2560 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) 2972 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2561 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) 2973 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2562 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2974 || ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2563 { 2975 {
2564 ParentGroup.AbsolutePosition = newpos; 2976 ParentGroup.AbsolutePosition = newpos;
2565 return; 2977 return;
@@ -2581,17 +2993,18 @@ namespace OpenSim.Region.Framework.Scenes
2581 //Trys to fetch sound id from prim's inventory. 2993 //Trys to fetch sound id from prim's inventory.
2582 //Prim's inventory doesn't support non script items yet 2994 //Prim's inventory doesn't support non script items yet
2583 2995
2584 lock (TaskInventory) 2996 TaskInventory.LockItemsForRead(true);
2997
2998 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2585 { 2999 {
2586 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 3000 if (item.Value.Name == sound)
2587 { 3001 {
2588 if (item.Value.Name == sound) 3002 soundID = item.Value.ItemID;
2589 { 3003 break;
2590 soundID = item.Value.ItemID;
2591 break;
2592 }
2593 } 3004 }
2594 } 3005 }
3006
3007 TaskInventory.LockItemsForRead(false);
2595 } 3008 }
2596 3009
2597 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp) 3010 ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp)
@@ -2714,6 +3127,19 @@ namespace OpenSim.Region.Framework.Scenes
2714 APIDTarget = Quaternion.Identity; 3127 APIDTarget = Quaternion.Identity;
2715 } 3128 }
2716 3129
3130
3131
3132 public void ScheduleFullUpdateIfNone()
3133 {
3134 if (ParentGroup == null)
3135 return;
3136
3137// ??? ParentGroup.HasGroupChanged = true;
3138
3139 if (UpdateFlag != UpdateRequired.FULL)
3140 ScheduleFullUpdate();
3141 }
3142
2717 /// <summary> 3143 /// <summary>
2718 /// Schedules this prim for a full update 3144 /// Schedules this prim for a full update
2719 /// </summary> 3145 /// </summary>
@@ -2915,8 +3341,8 @@ namespace OpenSim.Region.Framework.Scenes
2915 { 3341 {
2916 const float ROTATION_TOLERANCE = 0.01f; 3342 const float ROTATION_TOLERANCE = 0.01f;
2917 const float VELOCITY_TOLERANCE = 0.001f; 3343 const float VELOCITY_TOLERANCE = 0.001f;
2918 const float POSITION_TOLERANCE = 0.05f; 3344 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2919 const int TIME_MS_TOLERANCE = 3000; 3345 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2920 3346
2921 switch (UpdateFlag) 3347 switch (UpdateFlag)
2922 { 3348 {
@@ -2978,17 +3404,16 @@ namespace OpenSim.Region.Framework.Scenes
2978 if (!UUID.TryParse(sound, out soundID)) 3404 if (!UUID.TryParse(sound, out soundID))
2979 { 3405 {
2980 // search sound file from inventory 3406 // search sound file from inventory
2981 lock (TaskInventory) 3407 TaskInventory.LockItemsForRead(true);
3408 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2982 { 3409 {
2983 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 3410 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
2984 { 3411 {
2985 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 3412 soundID = item.Value.ItemID;
2986 { 3413 break;
2987 soundID = item.Value.ItemID;
2988 break;
2989 }
2990 } 3414 }
2991 } 3415 }
3416 TaskInventory.LockItemsForRead(false);
2992 } 3417 }
2993 3418
2994 if (soundID == UUID.Zero) 3419 if (soundID == UUID.Zero)
@@ -3073,10 +3498,13 @@ namespace OpenSim.Region.Framework.Scenes
3073 3498
3074 public void SetBuoyancy(float fvalue) 3499 public void SetBuoyancy(float fvalue)
3075 { 3500 {
3076 PhysicsActor pa = PhysActor; 3501 Buoyancy = fvalue;
3077 3502/*
3078 if (pa != null) 3503 if (PhysActor != null)
3079 pa.Buoyancy = fvalue; 3504 {
3505 PhysActor.Buoyancy = fvalue;
3506 }
3507 */
3080 } 3508 }
3081 3509
3082 public void SetDieAtEdge(bool p) 3510 public void SetDieAtEdge(bool p)
@@ -3092,47 +3520,111 @@ namespace OpenSim.Region.Framework.Scenes
3092 PhysicsActor pa = PhysActor; 3520 PhysicsActor pa = PhysActor;
3093 3521
3094 if (pa != null) 3522 if (pa != null)
3095 pa.FloatOnWater = floatYN == 1; 3523 pa.FloatOnWater = (floatYN == 1);
3096 } 3524 }
3097 3525
3098 public void SetForce(Vector3 force) 3526 public void SetForce(Vector3 force)
3099 { 3527 {
3100 PhysicsActor pa = PhysActor; 3528 Force = force;
3529 }
3101 3530
3102 if (pa != null) 3531 public SOPVehicle sopVehicle
3103 pa.Force = force; 3532 {
3533 get
3534 {
3535 return m_vehicle;
3536 }
3537 set
3538 {
3539 m_vehicle = value;
3540 }
3541 }
3542
3543
3544 public int VehicleType
3545 {
3546 get
3547 {
3548 if (m_vehicle == null)
3549 return (int)Vehicle.TYPE_NONE;
3550 else
3551 return (int)m_vehicle.Type;
3552 }
3553 set
3554 {
3555 SetVehicleType(value);
3556 }
3104 } 3557 }
3105 3558
3106 public void SetVehicleType(int type) 3559 public void SetVehicleType(int type)
3107 { 3560 {
3108 PhysicsActor pa = PhysActor; 3561 m_vehicle = null;
3562
3563 if (type == (int)Vehicle.TYPE_NONE)
3564 {
3565 if (_parentID ==0 && PhysActor != null)
3566 PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
3567 return;
3568 }
3569 m_vehicle = new SOPVehicle();
3570 m_vehicle.ProcessTypeChange((Vehicle)type);
3571 {
3572 if (_parentID ==0 && PhysActor != null)
3573 PhysActor.VehicleType = type;
3574 return;
3575 }
3576 }
3109 3577
3110 if (pa != null) 3578 public void SetVehicleFlags(int param, bool remove)
3111 pa.VehicleType = type; 3579 {
3580 if (m_vehicle == null)
3581 return;
3582
3583 m_vehicle.ProcessVehicleFlags(param, remove);
3584
3585 if (_parentID ==0 && PhysActor != null)
3586 {
3587 PhysActor.VehicleFlags(param, remove);
3588 }
3112 } 3589 }
3113 3590
3114 public void SetVehicleFloatParam(int param, float value) 3591 public void SetVehicleFloatParam(int param, float value)
3115 { 3592 {
3116 PhysicsActor pa = PhysActor; 3593 if (m_vehicle == null)
3594 return;
3117 3595
3118 if (pa != null) 3596 m_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
3119 pa.VehicleFloatParam(param, value); 3597
3598 if (_parentID == 0 && PhysActor != null)
3599 {
3600 PhysActor.VehicleFloatParam(param, value);
3601 }
3120 } 3602 }
3121 3603
3122 public void SetVehicleVectorParam(int param, Vector3 value) 3604 public void SetVehicleVectorParam(int param, Vector3 value)
3123 { 3605 {
3124 PhysicsActor pa = PhysActor; 3606 if (m_vehicle == null)
3607 return;
3125 3608
3126 if (pa != null) 3609 m_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
3127 pa.VehicleVectorParam(param, value); 3610
3611 if (_parentID == 0 && PhysActor != null)
3612 {
3613 PhysActor.VehicleVectorParam(param, value);
3614 }
3128 } 3615 }
3129 3616
3130 public void SetVehicleRotationParam(int param, Quaternion rotation) 3617 public void SetVehicleRotationParam(int param, Quaternion rotation)
3131 { 3618 {
3132 PhysicsActor pa = PhysActor; 3619 if (m_vehicle == null)
3620 return;
3133 3621
3134 if (pa != null) 3622 m_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
3135 pa.VehicleRotationParam(param, rotation); 3623
3624 if (_parentID == 0 && PhysActor != null)
3625 {
3626 PhysActor.VehicleRotationParam(param, rotation);
3627 }
3136 } 3628 }
3137 3629
3138 /// <summary> 3630 /// <summary>
@@ -3316,13 +3808,6 @@ namespace OpenSim.Region.Framework.Scenes
3316 hasProfileCut = hasDimple; // is it the same thing? 3808 hasProfileCut = hasDimple; // is it the same thing?
3317 } 3809 }
3318 3810
3319 public void SetVehicleFlags(int param, bool remove)
3320 {
3321 if (PhysActor != null)
3322 {
3323 PhysActor.VehicleFlags(param, remove);
3324 }
3325 }
3326 3811
3327 public void SetGroup(UUID groupID, IClientAPI client) 3812 public void SetGroup(UUID groupID, IClientAPI client)
3328 { 3813 {
@@ -3425,68 +3910,18 @@ namespace OpenSim.Region.Framework.Scenes
3425 //ParentGroup.ScheduleGroupForFullUpdate(); 3910 //ParentGroup.ScheduleGroupForFullUpdate();
3426 } 3911 }
3427 3912
3428 public void StoreUndoState() 3913 public void StoreUndoState(ObjectChangeType change)
3429 { 3914 {
3430 StoreUndoState(false); 3915 if (m_UndoRedo == null)
3431 } 3916 m_UndoRedo = new UndoRedoState(5);
3432 3917
3433 public void StoreUndoState(bool forGroup) 3918 lock (m_UndoRedo)
3434 {
3435 if (!Undoing)
3436 { 3919 {
3437 if (!IgnoreUndoUpdate) 3920 if (!Undoing && !IgnoreUndoUpdate && ParentGroup != null) // just to read better - undo is in progress, or suspended
3438 { 3921 {
3439 if (ParentGroup != null) 3922 m_UndoRedo.StoreUndo(this, change);
3440 {
3441 lock (m_undo)
3442 {
3443 if (m_undo.Count > 0)
3444 {
3445 UndoState last = m_undo.Peek();
3446 if (last != null)
3447 {
3448 // TODO: May need to fix for group comparison
3449 if (last.Compare(this))
3450 {
3451 // m_log.DebugFormat(
3452 // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3453 // Name, LocalId, m_undo.Count);
3454
3455 return;
3456 }
3457 }
3458 }
3459
3460 // m_log.DebugFormat(
3461 // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3462 // Name, LocalId, forGroup, m_undo.Count);
3463
3464 if (ParentGroup.GetSceneMaxUndo() > 0)
3465 {
3466 UndoState nUndo = new UndoState(this, forGroup);
3467
3468 m_undo.Push(nUndo);
3469
3470 if (m_redo.Count > 0)
3471 m_redo.Clear();
3472
3473 // m_log.DebugFormat(
3474 // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3475 // Name, LocalId, forGroup, m_undo.Count);
3476 }
3477 }
3478 }
3479 } 3923 }
3480// else
3481// {
3482// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3483// }
3484 } 3924 }
3485// else
3486// {
3487// m_log.DebugFormat(
3488// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3489// }
3490 } 3925 }
3491 3926
3492 /// <summary> 3927 /// <summary>
@@ -3496,84 +3931,46 @@ namespace OpenSim.Region.Framework.Scenes
3496 { 3931 {
3497 get 3932 get
3498 { 3933 {
3499 lock (m_undo) 3934 if (m_UndoRedo == null)
3500 return m_undo.Count; 3935 return 0;
3936 return m_UndoRedo.Count;
3501 } 3937 }
3502 } 3938 }
3503 3939
3504 public void Undo() 3940 public void Undo()
3505 { 3941 {
3506 lock (m_undo) 3942 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3507 { 3943 return;
3508// m_log.DebugFormat(
3509// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3510// Name, LocalId, m_undo.Count);
3511
3512 if (m_undo.Count > 0)
3513 {
3514 UndoState goback = m_undo.Pop();
3515
3516 if (goback != null)
3517 {
3518 UndoState nUndo = null;
3519
3520 if (ParentGroup.GetSceneMaxUndo() > 0)
3521 {
3522 nUndo = new UndoState(this, goback.ForGroup);
3523 }
3524
3525 goback.PlaybackState(this);
3526
3527 if (nUndo != null)
3528 m_redo.Push(nUndo);
3529 }
3530 }
3531 3944
3532// m_log.DebugFormat( 3945 lock (m_UndoRedo)
3533// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}", 3946 {
3534// Name, LocalId, m_undo.Count); 3947 Undoing = true;
3948 m_UndoRedo.Undo(this);
3949 Undoing = false;
3535 } 3950 }
3536 } 3951 }
3537 3952
3538 public void Redo() 3953 public void Redo()
3539 { 3954 {
3540 lock (m_undo) 3955 if (m_UndoRedo == null || Undoing || ParentGroup == null)
3541 { 3956 return;
3542// m_log.DebugFormat(
3543// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3544// Name, LocalId, m_redo.Count);
3545
3546 if (m_redo.Count > 0)
3547 {
3548 UndoState gofwd = m_redo.Pop();
3549
3550 if (gofwd != null)
3551 {
3552 if (ParentGroup.GetSceneMaxUndo() > 0)
3553 {
3554 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3555
3556 m_undo.Push(nUndo);
3557 }
3558
3559 gofwd.PlayfwdState(this);
3560 }
3561 3957
3562// m_log.DebugFormat( 3958 lock (m_UndoRedo)
3563// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}", 3959 {
3564// Name, LocalId, m_redo.Count); 3960 Undoing = true;
3565 } 3961 m_UndoRedo.Redo(this);
3962 Undoing = false;
3566 } 3963 }
3567 } 3964 }
3568 3965
3569 public void ClearUndoState() 3966 public void ClearUndoState()
3570 { 3967 {
3571// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId); 3968 if (m_UndoRedo == null || Undoing)
3969 return;
3572 3970
3573 lock (m_undo) 3971 lock (m_UndoRedo)
3574 { 3972 {
3575 m_undo.Clear(); 3973 m_UndoRedo.Clear();
3576 m_redo.Clear();
3577 } 3974 }
3578 } 3975 }
3579 3976
@@ -4203,6 +4600,27 @@ namespace OpenSim.Region.Framework.Scenes
4203 } 4600 }
4204 } 4601 }
4205 4602
4603
4604 public void UpdateExtraPhysics(ExtraPhysicsData physdata)
4605 {
4606 if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null)
4607 return;
4608
4609 if (PhysicsShapeType != (byte)physdata.PhysShapeType)
4610 {
4611 PhysicsShapeType = (byte)physdata.PhysShapeType;
4612
4613 }
4614
4615 if(Density != physdata.Density)
4616 Density = physdata.Density;
4617 if(GravityModifier != physdata.GravitationModifier)
4618 GravityModifier = physdata.GravitationModifier;
4619 if(Friction != physdata.Friction)
4620 Friction = physdata.Friction;
4621 if(Bounciness != physdata.Bounce)
4622 Bounciness = physdata.Bounce;
4623 }
4206 /// <summary> 4624 /// <summary>
4207 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary. 4625 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary.
4208 /// </summary> 4626 /// </summary>
@@ -4210,7 +4628,8 @@ namespace OpenSim.Region.Framework.Scenes
4210 /// <param name="SetTemporary"></param> 4628 /// <param name="SetTemporary"></param>
4211 /// <param name="SetPhantom"></param> 4629 /// <param name="SetPhantom"></param>
4212 /// <param name="SetVD"></param> 4630 /// <param name="SetVD"></param>
4213 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD) 4631// public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD)
4632 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
4214 { 4633 {
4215 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4634 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4216 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4635 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4220,44 +4639,58 @@ namespace OpenSim.Region.Framework.Scenes
4220 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD)) 4639 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4221 return; 4640 return;
4222 4641
4223 PhysicsActor pa = PhysActor; 4642 // do this first
4643 if (building && PhysActor != null && PhysActor.Building != building)
4644 PhysActor.Building = building;
4224 4645
4225 // Special cases for VD. VD can only be called from a script 4646 // Special cases for VD. VD can only be called from a script
4226 // and can't be combined with changes to other states. So we can rely 4647 // and can't be combined with changes to other states. So we can rely
4227 // that... 4648 // that...
4228 // ... if VD is changed, all others are not. 4649 // ... if VD is changed, all others are not.
4229 // ... if one of the others is changed, VD is not. 4650 // ... if one of the others is changed, VD is not.
4651
4652/*
4230 if (SetVD) // VD is active, special logic applies 4653 if (SetVD) // VD is active, special logic applies
4231 {
4232 // State machine logic for VolumeDetect
4233 // More logic below
4234 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4235 4654
4236 if (phanReset) // Phantom changes from on to off switch VD off too 4655 volume detection is now independent of phantom in sl
4237 {
4238 SetVD = false; // Switch it of for the course of this routine
4239 VolumeDetectActive = false; // and also permanently
4240 4656
4241 if (pa != null) 4657 {
4242 pa.SetVolumeDetect(0); // Let physics know about it too 4658 // State machine logic for VolumeDetect
4243 } 4659 // More logic below
4244 else 4660
4245 { 4661
4246 // If volumedetect is active we don't want phantom to be applied. 4662 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4247 // If this is a new call to VD out of the state "phantom" 4663
4248 // this will also cause the prim to be visible to physics 4664 if (phanReset) // Phantom changes from on to off switch VD off too
4665 {
4666 SetVD = false; // Switch it of for the course of this routine
4667 VolumeDetectActive = false; // and also permanently
4668 if (PhysActor != null)
4669 PhysActor.SetVolumeDetect(0); // Let physics know about it too
4670 }
4671 else
4672 {
4673 // If volumedetect is active we don't want phantom to be applied.
4674 // If this is a new call to VD out of the state "phantom"
4675 // this will also cause the prim to be visible to physics
4249 SetPhantom = false; 4676 SetPhantom = false;
4250 } 4677 }
4678 }
4679 else if (wasVD)
4680 {
4681 // Correspondingly, if VD is turned off, also turn off phantom
4682 SetPhantom = false;
4251 } 4683 }
4252 4684
4253 if (UsePhysics && IsJoint()) 4685 if (UsePhysics && IsJoint())
4254 { 4686 {
4255 SetPhantom = true; 4687 SetPhantom = true;
4256 } 4688 }
4257 4689*/
4258 if (UsePhysics) 4690 if (UsePhysics)
4259 { 4691 {
4260 AddFlag(PrimFlags.Physics); 4692 AddFlag(PrimFlags.Physics);
4693/*
4261 if (!wasUsingPhysics) 4694 if (!wasUsingPhysics)
4262 { 4695 {
4263 DoPhysicsPropertyUpdate(UsePhysics, false); 4696 DoPhysicsPropertyUpdate(UsePhysics, false);
@@ -4270,41 +4703,68 @@ namespace OpenSim.Region.Framework.Scenes
4270 } 4703 }
4271 } 4704 }
4272 } 4705 }
4706 */
4273 } 4707 }
4274 else 4708 else
4275 { 4709 {
4276 RemFlag(PrimFlags.Physics); 4710 RemFlag(PrimFlags.Physics);
4711/*
4277 if (wasUsingPhysics) 4712 if (wasUsingPhysics)
4278 { 4713 {
4279 DoPhysicsPropertyUpdate(UsePhysics, false); 4714 DoPhysicsPropertyUpdate(UsePhysics, false);
4280 } 4715 }
4281 } 4716*/
4717 }
4718
4719 if (SetPhantom)
4720 AddFlag(PrimFlags.Phantom);
4721 else
4722 RemFlag(PrimFlags.Phantom);
4282 4723
4283 if (SetPhantom 4724 if ((SetPhantom && !UsePhysics) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
4284 || ParentGroup.IsAttachment
4285 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints 4725 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4286 { 4726 {
4287 AddFlag(PrimFlags.Phantom); 4727// AddFlag(PrimFlags.Phantom);
4728
4729 Velocity = new Vector3(0, 0, 0);
4730 Acceleration = new Vector3(0, 0, 0);
4731 if (ParentGroup.RootPart == this)
4732 AngularVelocity = new Vector3(0, 0, 0);
4288 4733
4289 if (PhysActor != null) 4734 if (PhysActor != null)
4735 {
4736 ParentGroup.Scene.RemovePhysicalPrim(1);
4290 RemoveFromPhysics(); 4737 RemoveFromPhysics();
4738 }
4291 } 4739 }
4292 else // Not phantom 4740 else
4293 { 4741 {
4294 RemFlag(PrimFlags.Phantom);
4295
4296 if (ParentGroup.Scene == null) 4742 if (ParentGroup.Scene == null)
4297 return; 4743 return;
4298 4744
4299 if (ParentGroup.Scene.CollidablePrims && pa == null) 4745 if (ParentGroup.Scene.CollidablePrims)
4300 { 4746 {
4301 pa = AddToPhysics(UsePhysics); 4747 if (PhysActor == null)
4302
4303 if (pa != null)
4304 { 4748 {
4305 pa.SetMaterial(Material); 4749 PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape(
4750 string.Format("{0}/{1}", Name, UUID),
4751 Shape,
4752 AbsolutePosition,
4753 Scale,
4754 GetWorldRotation(), //physics wants world rotation like all other functions send
4755 UsePhysics,
4756 SetPhantom,
4757 PhysicsShapeType,
4758 m_localId);
4759
4760 PhysActor.SetMaterial(Material);
4761
4762 // if root part apply vehicle
4763 if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
4764 m_vehicle.SetVehicle(PhysActor);
4765
4306 DoPhysicsPropertyUpdate(UsePhysics, true); 4766 DoPhysicsPropertyUpdate(UsePhysics, true);
4307 4767
4308 if (!ParentGroup.IsDeleted) 4768 if (!ParentGroup.IsDeleted)
4309 { 4769 {
4310 if (LocalId == ParentGroup.RootPart.LocalId) 4770 if (LocalId == ParentGroup.RootPart.LocalId)
@@ -4312,7 +4772,7 @@ namespace OpenSim.Region.Framework.Scenes
4312 ParentGroup.CheckSculptAndLoad(); 4772 ParentGroup.CheckSculptAndLoad();
4313 } 4773 }
4314 } 4774 }
4315 4775
4316 if ( 4776 if (
4317 ((AggregateScriptEvents & scriptEvents.collision) != 0) || 4777 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4318 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || 4778 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
@@ -4323,25 +4783,26 @@ namespace OpenSim.Region.Framework.Scenes
4323 (CollisionSound != UUID.Zero) 4783 (CollisionSound != UUID.Zero)
4324 ) 4784 )
4325 { 4785 {
4326 pa.OnCollisionUpdate += PhysicsCollision; 4786 PhysActor.OnCollisionUpdate += PhysicsCollision;
4327 pa.SubscribeEvents(1000); 4787 PhysActor.SubscribeEvents(1000);
4328 } 4788 }
4329 } 4789 }
4330 } 4790 else // it already has a physical representation
4331 else // it already has a physical representation
4332 {
4333 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4334
4335 if (!ParentGroup.IsDeleted)
4336 { 4791 {
4337 if (LocalId == ParentGroup.RootPart.LocalId) 4792 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
4793
4794 if (!ParentGroup.IsDeleted)
4338 { 4795 {
4339 ParentGroup.CheckSculptAndLoad(); 4796 if (LocalId == ParentGroup.RootPart.LocalId)
4797 {
4798 ParentGroup.CheckSculptAndLoad();
4799 }
4340 } 4800 }
4341 } 4801 }
4342 } 4802 }
4343 } 4803 }
4344 4804
4805 PhysicsActor pa = PhysActor;
4345 if (SetVD) 4806 if (SetVD)
4346 { 4807 {
4347 // If the above logic worked (this is urgent candidate to unit tests!) 4808 // If the above logic worked (this is urgent candidate to unit tests!)
@@ -4352,7 +4813,7 @@ namespace OpenSim.Region.Framework.Scenes
4352 if (pa != null) 4813 if (pa != null)
4353 { 4814 {
4354 pa.SetVolumeDetect(1); 4815 pa.SetVolumeDetect(1);
4355 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active 4816// AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
4356 this.VolumeDetectActive = true; 4817 this.VolumeDetectActive = true;
4357 } 4818 }
4358 } 4819 }
@@ -4361,9 +4822,10 @@ namespace OpenSim.Region.Framework.Scenes
4361 // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like 4822 // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like
4362 // (mumbles, well, at least if you have infinte CPU powers :-)) 4823 // (mumbles, well, at least if you have infinte CPU powers :-))
4363 if (pa != null) 4824 if (pa != null)
4364 PhysActor.SetVolumeDetect(0); 4825 {
4365 4826 pa.SetVolumeDetect(0);
4366 this.VolumeDetectActive = false; 4827 this.VolumeDetectActive = false;
4828 }
4367 } 4829 }
4368 4830
4369 if (SetTemporary) 4831 if (SetTemporary)
@@ -4377,12 +4839,15 @@ namespace OpenSim.Region.Framework.Scenes
4377 4839
4378 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); 4840 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4379 4841
4842 // and last in case we have a new actor and not building
4843 if (pa != null && pa.Building != building)
4844 pa.Building = building;
4380 if (ParentGroup != null) 4845 if (ParentGroup != null)
4381 { 4846 {
4382 ParentGroup.HasGroupChanged = true; 4847 ParentGroup.HasGroupChanged = true;
4383 ScheduleFullUpdate(); 4848 ScheduleFullUpdate();
4384 } 4849 }
4385 4850
4386// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); 4851// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4387 } 4852 }
4388 4853
@@ -4636,33 +5101,32 @@ namespace OpenSim.Region.Framework.Scenes
4636 } 5101 }
4637 5102
4638 PhysicsActor pa = PhysActor; 5103 PhysicsActor pa = PhysActor;
4639 5104 if (pa != null)
4640 if (
4641 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4642 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
4643 ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
4644 ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
4645 ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
4646 ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
4647 (CollisionSound != UUID.Zero)
4648 )
4649 { 5105 {
4650 // subscribe to physics updates. 5106 const scriptEvents NeededSubsEvents = (
4651 if (pa != null) 5107 scriptEvents.collision | scriptEvents.collision_start| scriptEvents.collision_end |
5108 scriptEvents.land_collision | scriptEvents.land_collision_start | scriptEvents.land_collision_end
5109 );
5110 if (
5111// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
5112// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
5113// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
5114// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
5115// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
5116// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
5117 ((AggregateScriptEvents & NeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
5118 )
4652 { 5119 {
5120 // subscribe to physics updates.
4653 pa.OnCollisionUpdate += PhysicsCollision; 5121 pa.OnCollisionUpdate += PhysicsCollision;
4654 pa.SubscribeEvents(1000); 5122 pa.SubscribeEvents(1000);
4655 } 5123 }
4656 } 5124 else
4657 else
4658 {
4659 if (pa != null)
4660 { 5125 {
4661 pa.UnSubscribeEvents(); 5126 pa.UnSubscribeEvents();
4662 pa.OnCollisionUpdate -= PhysicsCollision; 5127 pa.OnCollisionUpdate -= PhysicsCollision;
4663 } 5128 }
4664 } 5129 }
4665
4666 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 5130 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4667 //{ 5131 //{
4668 // ParentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting; 5132 // ParentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting;
@@ -4789,5 +5253,17 @@ namespace OpenSim.Region.Framework.Scenes
4789 Color color = Color; 5253 Color color = Color;
4790 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 5254 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4791 } 5255 }
5256
5257 public void ResetOwnerChangeFlag()
5258 {
5259 List<UUID> inv = Inventory.GetInventoryList();
5260
5261 foreach (UUID itemID in inv)
5262 {
5263 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
5264 item.OwnerChanged = false;
5265 Inventory.UpdateInventoryItem(item, false, false);
5266 }
5267 }
4792 } 5268 }
4793} 5269}