diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPart.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 1158 |
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 | } |