diff options
author | David Walter Seikel | 2016-11-03 21:44:39 +1000 |
---|---|---|
committer | David Walter Seikel | 2016-11-03 21:44:39 +1000 |
commit | 134f86e8d5c414409631b25b8c6f0ee45fbd8631 (patch) | |
tree | 216b89d3fb89acfb81be1e440c25c41ab09fa96d /OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |
parent | More changing to production grid. Double oops. (diff) | |
download | opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.zip opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.gz opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.bz2 opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.xz |
Initial update to OpenSim 0.8.2.1 source code.
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPart.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 918 |
1 files changed, 697 insertions, 221 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 44e8fdf..d1c5f72 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -37,11 +37,13 @@ using System.Xml.Serialization; | |||
37 | using log4net; | 37 | using log4net; |
38 | using OpenMetaverse; | 38 | using OpenMetaverse; |
39 | using OpenMetaverse.Packets; | 39 | using OpenMetaverse.Packets; |
40 | using OpenMetaverse.StructuredData; | ||
40 | using OpenSim.Framework; | 41 | using OpenSim.Framework; |
41 | using OpenSim.Region.Framework.Interfaces; | 42 | using OpenSim.Region.Framework.Interfaces; |
42 | using OpenSim.Region.Framework.Scenes.Scripting; | 43 | using OpenSim.Region.Framework.Scenes.Scripting; |
43 | using OpenSim.Region.Framework.Scenes.Serialization; | 44 | using OpenSim.Region.Framework.Scenes.Serialization; |
44 | using OpenSim.Region.Physics.Manager; | 45 | using OpenSim.Region.PhysicsModules.SharedBase; |
46 | using PermissionMask = OpenSim.Framework.PermissionMask; | ||
45 | 47 | ||
46 | namespace OpenSim.Region.Framework.Scenes | 48 | namespace OpenSim.Region.Framework.Scenes |
47 | { | 49 | { |
@@ -115,7 +117,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
115 | 117 | ||
116 | #endregion Enumerations | 118 | #endregion Enumerations |
117 | 119 | ||
118 | public class SceneObjectPart : IScriptHost, ISceneEntity | 120 | public class SceneObjectPart : ISceneEntity |
119 | { | 121 | { |
120 | /// <value> | 122 | /// <value> |
121 | /// Denote all sides of the prim | 123 | /// Denote all sides of the prim |
@@ -124,6 +126,32 @@ namespace OpenSim.Region.Framework.Scenes | |||
124 | 126 | ||
125 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 127 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
126 | 128 | ||
129 | /// <summary> | ||
130 | /// Dynamic attributes can be created and deleted as required. | ||
131 | /// </summary> | ||
132 | public DAMap DynAttrs { get; set; } | ||
133 | |||
134 | private DOMap m_dynObjs; | ||
135 | |||
136 | /// <summary> | ||
137 | /// Dynamic objects that can be created and deleted as required. | ||
138 | /// </summary> | ||
139 | public DOMap DynObjs | ||
140 | { | ||
141 | get | ||
142 | { | ||
143 | if (m_dynObjs == null) | ||
144 | m_dynObjs = new DOMap(); | ||
145 | |||
146 | return m_dynObjs; | ||
147 | } | ||
148 | |||
149 | set | ||
150 | { | ||
151 | m_dynObjs = value; | ||
152 | } | ||
153 | } | ||
154 | |||
127 | /// <value> | 155 | /// <value> |
128 | /// Is this a root part? | 156 | /// Is this a root part? |
129 | /// </value> | 157 | /// </value> |
@@ -158,7 +186,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
158 | 186 | ||
159 | public bool RETURN_AT_EDGE; | 187 | public bool RETURN_AT_EDGE; |
160 | 188 | ||
161 | public bool BlockGrab; | 189 | public bool BlockGrab { get; set; } |
162 | 190 | ||
163 | public bool StatusSandbox; | 191 | public bool StatusSandbox; |
164 | 192 | ||
@@ -191,6 +219,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
191 | 219 | ||
192 | public double SoundRadius; | 220 | public double SoundRadius; |
193 | 221 | ||
222 | /// <summary> | ||
223 | /// Should sounds played from this prim be queued? | ||
224 | /// </summary> | ||
225 | /// <remarks> | ||
226 | /// This should only be changed by sound modules. It is up to sound modules as to how they interpret this setting. | ||
227 | /// </remarks> | ||
228 | public bool SoundQueueing { get; set; } | ||
229 | |||
194 | public uint TimeStampFull; | 230 | public uint TimeStampFull; |
195 | 231 | ||
196 | public uint TimeStampLastActivity; // Will be used for AutoReturn | 232 | public uint TimeStampLastActivity; // Will be used for AutoReturn |
@@ -230,7 +266,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
230 | 266 | ||
231 | public Quaternion SpinOldOrientation = Quaternion.Identity; | 267 | public Quaternion SpinOldOrientation = Quaternion.Identity; |
232 | 268 | ||
233 | protected int m_APIDIterations = 0; | 269 | protected bool m_APIDActive = false; |
234 | protected Quaternion m_APIDTarget = Quaternion.Identity; | 270 | protected Quaternion m_APIDTarget = Quaternion.Identity; |
235 | protected float m_APIDDamp = 0; | 271 | protected float m_APIDDamp = 0; |
236 | protected float m_APIDStrength = 0; | 272 | protected float m_APIDStrength = 0; |
@@ -296,6 +332,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
296 | protected Vector3 m_lastAcceleration; | 332 | protected Vector3 m_lastAcceleration; |
297 | protected Vector3 m_lastAngularVelocity; | 333 | protected Vector3 m_lastAngularVelocity; |
298 | protected int m_lastTerseSent; | 334 | protected int m_lastTerseSent; |
335 | |||
336 | protected byte m_physicsShapeType = (byte)PhysShapeType.prim; | ||
337 | protected float m_density = 1000.0f; // in kg/m^3 | ||
338 | protected float m_gravitymod = 1.0f; | ||
339 | protected float m_friction = 0.6f; // wood | ||
340 | protected float m_bounce = 0.5f; // wood | ||
299 | 341 | ||
300 | /// <summary> | 342 | /// <summary> |
301 | /// Stores media texture data | 343 | /// Stores media texture data |
@@ -312,6 +354,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
312 | private UUID m_collisionSound; | 354 | private UUID m_collisionSound; |
313 | private float m_collisionSoundVolume; | 355 | private float m_collisionSoundVolume; |
314 | 356 | ||
357 | public KeyframeMotion KeyframeMotion | ||
358 | { | ||
359 | get; set; | ||
360 | } | ||
361 | |||
315 | #endregion Fields | 362 | #endregion Fields |
316 | 363 | ||
317 | // ~SceneObjectPart() | 364 | // ~SceneObjectPart() |
@@ -335,6 +382,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
335 | m_particleSystem = Utils.EmptyBytes; | 382 | m_particleSystem = Utils.EmptyBytes; |
336 | Rezzed = DateTime.UtcNow; | 383 | Rezzed = DateTime.UtcNow; |
337 | Description = String.Empty; | 384 | Description = String.Empty; |
385 | DynAttrs = new DAMap(); | ||
338 | 386 | ||
339 | // Prims currently only contain a single folder (Contents). From looking at the Second Life protocol, | 387 | // Prims currently only contain a single folder (Contents). From looking at the Second Life protocol, |
340 | // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from | 388 | // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from |
@@ -389,8 +437,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
389 | private uint _category; | 437 | private uint _category; |
390 | private Int32 _creationDate; | 438 | private Int32 _creationDate; |
391 | private uint _parentID = 0; | 439 | private uint _parentID = 0; |
392 | private uint _baseMask = (uint)PermissionMask.All; | 440 | private uint _baseMask = (uint)(PermissionMask.All | PermissionMask.Export); |
393 | private uint _ownerMask = (uint)PermissionMask.All; | 441 | private uint _ownerMask = (uint)(PermissionMask.All | PermissionMask.Export); |
394 | private uint _groupMask = (uint)PermissionMask.None; | 442 | private uint _groupMask = (uint)PermissionMask.None; |
395 | private uint _everyoneMask = (uint)PermissionMask.None; | 443 | private uint _everyoneMask = (uint)PermissionMask.None; |
396 | private uint _nextOwnerMask = (uint)PermissionMask.All; | 444 | private uint _nextOwnerMask = (uint)PermissionMask.All; |
@@ -425,7 +473,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
425 | { | 473 | { |
426 | get | 474 | get |
427 | { | 475 | { |
428 | if (CreatorData != null && CreatorData != string.Empty) | 476 | if (!string.IsNullOrEmpty(CreatorData)) |
429 | return CreatorID.ToString() + ';' + CreatorData; | 477 | return CreatorID.ToString() + ';' + CreatorData; |
430 | else | 478 | else |
431 | return CreatorID.ToString(); | 479 | return CreatorID.ToString(); |
@@ -455,7 +503,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
455 | CreatorID = uuid; | 503 | CreatorID = uuid; |
456 | } | 504 | } |
457 | if (parts.Length >= 2) | 505 | if (parts.Length >= 2) |
506 | { | ||
458 | CreatorData = parts[1]; | 507 | CreatorData = parts[1]; |
508 | if (!CreatorData.EndsWith("/")) | ||
509 | CreatorData += "/"; | ||
510 | } | ||
459 | if (parts.Length >= 3) | 511 | if (parts.Length >= 3) |
460 | name = parts[2]; | 512 | name = parts[2]; |
461 | 513 | ||
@@ -590,6 +642,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
590 | } | 642 | } |
591 | } | 643 | } |
592 | 644 | ||
645 | protected bool APIDActive | ||
646 | { | ||
647 | get { return m_APIDActive; } | ||
648 | set { m_APIDActive = value; } | ||
649 | } | ||
650 | |||
593 | protected Quaternion APIDTarget | 651 | protected Quaternion APIDTarget |
594 | { | 652 | { |
595 | get { return m_APIDTarget; } | 653 | get { return m_APIDTarget; } |
@@ -729,23 +787,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
729 | } | 787 | } |
730 | 788 | ||
731 | // Tell the physics engines that this prim changed. | 789 | // Tell the physics engines that this prim changed. |
732 | ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); | 790 | if (ParentGroup != null && ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene != null) |
791 | ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); | ||
733 | } | 792 | } |
734 | catch (Exception e) | 793 | catch (Exception e) |
735 | { | 794 | { |
736 | m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e); | 795 | m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e); |
737 | } | 796 | } |
738 | } | 797 | } |
739 | |||
740 | // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too | ||
741 | if (SitTargetAvatar != UUID.Zero) | ||
742 | { | ||
743 | ScenePresence avatar; | ||
744 | if (ParentGroup.Scene.TryGetScenePresence(SitTargetAvatar, out avatar)) | ||
745 | { | ||
746 | avatar.ParentPosition = GetWorldPosition(); | ||
747 | } | ||
748 | } | ||
749 | } | 798 | } |
750 | } | 799 | } |
751 | 800 | ||
@@ -842,7 +891,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
842 | //m_log.Info("[PART]: RO2:" + actor.Orientation.ToString()); | 891 | //m_log.Info("[PART]: RO2:" + actor.Orientation.ToString()); |
843 | } | 892 | } |
844 | 893 | ||
845 | if (ParentGroup != null) | 894 | if (ParentGroup != null && ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene != null) |
846 | ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); | 895 | ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); |
847 | //} | 896 | //} |
848 | } | 897 | } |
@@ -880,14 +929,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
880 | 929 | ||
881 | set | 930 | set |
882 | { | 931 | { |
883 | m_velocity = value; | 932 | if (Util.IsNanOrInfinity(value)) |
933 | m_velocity = Vector3.Zero; | ||
934 | else | ||
935 | m_velocity = value; | ||
884 | 936 | ||
885 | PhysicsActor actor = PhysActor; | 937 | PhysicsActor actor = PhysActor; |
886 | if (actor != null) | 938 | if (actor != null) |
887 | { | 939 | { |
888 | if (actor.IsPhysical) | 940 | if (actor.IsPhysical) |
889 | { | 941 | { |
890 | actor.Velocity = value; | 942 | actor.Velocity = m_velocity; |
891 | ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); | 943 | ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); |
892 | } | 944 | } |
893 | } | 945 | } |
@@ -914,14 +966,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
914 | } | 966 | } |
915 | return m_angularVelocity; | 967 | return m_angularVelocity; |
916 | } | 968 | } |
917 | set { m_angularVelocity = value; } | 969 | set |
970 | { | ||
971 | if (Util.IsNanOrInfinity(value)) | ||
972 | m_angularVelocity = Vector3.Zero; | ||
973 | else | ||
974 | m_angularVelocity = value; | ||
975 | |||
976 | PhysicsActor actor = PhysActor; | ||
977 | if ((actor != null) && actor.IsPhysical) | ||
978 | actor.RotationalVelocity = m_angularVelocity; | ||
979 | } | ||
918 | } | 980 | } |
919 | 981 | ||
920 | /// <summary></summary> | 982 | /// <summary></summary> |
921 | public Vector3 Acceleration | 983 | public Vector3 Acceleration |
922 | { | 984 | { |
923 | get { return m_acceleration; } | 985 | get { return m_acceleration; } |
924 | set { m_acceleration = value; } | 986 | set |
987 | { | ||
988 | if (Util.IsNanOrInfinity(value)) | ||
989 | m_acceleration = Vector3.Zero; | ||
990 | else | ||
991 | m_acceleration = value; | ||
992 | } | ||
925 | } | 993 | } |
926 | 994 | ||
927 | public string Description { get; set; } | 995 | public string Description { get; set; } |
@@ -1028,6 +1096,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1028 | } | 1096 | } |
1029 | 1097 | ||
1030 | public UpdateRequired UpdateFlag { get; set; } | 1098 | public UpdateRequired UpdateFlag { get; set; } |
1099 | public bool UpdatePhysRequired { get; set; } | ||
1031 | 1100 | ||
1032 | /// <summary> | 1101 | /// <summary> |
1033 | /// Used for media on a prim. | 1102 | /// Used for media on a prim. |
@@ -1110,23 +1179,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1110 | // the mappings more consistant. | 1179 | // the mappings more consistant. |
1111 | public Vector3 SitTargetPositionLL | 1180 | public Vector3 SitTargetPositionLL |
1112 | { | 1181 | { |
1113 | get { return new Vector3(m_sitTargetPosition.X, m_sitTargetPosition.Y,m_sitTargetPosition.Z); } | 1182 | get { return m_sitTargetPosition; } |
1114 | set { m_sitTargetPosition = value; } | 1183 | set { m_sitTargetPosition = value; } |
1115 | } | 1184 | } |
1116 | 1185 | ||
1117 | public Quaternion SitTargetOrientationLL | 1186 | public Quaternion SitTargetOrientationLL |
1118 | { | 1187 | { |
1119 | get | 1188 | get { return m_sitTargetOrientation; } |
1120 | { | 1189 | set { m_sitTargetOrientation = value; } |
1121 | return new Quaternion( | ||
1122 | m_sitTargetOrientation.X, | ||
1123 | m_sitTargetOrientation.Y, | ||
1124 | m_sitTargetOrientation.Z, | ||
1125 | m_sitTargetOrientation.W | ||
1126 | ); | ||
1127 | } | ||
1128 | |||
1129 | set { m_sitTargetOrientation = new Quaternion(value.X, value.Y, value.Z, value.W); } | ||
1130 | } | 1190 | } |
1131 | 1191 | ||
1132 | public bool Stopped | 1192 | public bool Stopped |
@@ -1264,7 +1324,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1264 | /// <value> | 1324 | /// <value> |
1265 | /// null if there are no sitting avatars. This is to save us create a hashset for every prim in a scene. | 1325 | /// null if there are no sitting avatars. This is to save us create a hashset for every prim in a scene. |
1266 | /// </value> | 1326 | /// </value> |
1267 | private HashSet<UUID> m_sittingAvatars; | 1327 | private HashSet<ScenePresence> m_sittingAvatars; |
1268 | 1328 | ||
1269 | public virtual UUID RegionID | 1329 | public virtual UUID RegionID |
1270 | { | 1330 | { |
@@ -1315,6 +1375,157 @@ namespace OpenSim.Region.Framework.Scenes | |||
1315 | set { m_collisionSoundVolume = value; } | 1375 | set { m_collisionSoundVolume = value; } |
1316 | } | 1376 | } |
1317 | 1377 | ||
1378 | public byte DefaultPhysicsShapeType() | ||
1379 | { | ||
1380 | byte type; | ||
1381 | |||
1382 | if (Shape != null && (Shape.SculptType == (byte)SculptType.Mesh)) | ||
1383 | type = (byte)PhysShapeType.convex; | ||
1384 | else | ||
1385 | type = (byte)PhysShapeType.prim; | ||
1386 | |||
1387 | return type; | ||
1388 | } | ||
1389 | |||
1390 | public byte PhysicsShapeType | ||
1391 | { | ||
1392 | get { return m_physicsShapeType; } | ||
1393 | set | ||
1394 | { | ||
1395 | byte oldv = m_physicsShapeType; | ||
1396 | |||
1397 | if (value >= 0 && value <= (byte)PhysShapeType.convex) | ||
1398 | { | ||
1399 | if (value == (byte)PhysShapeType.none && ParentGroup != null && ParentGroup.RootPart == this) | ||
1400 | m_physicsShapeType = DefaultPhysicsShapeType(); | ||
1401 | else | ||
1402 | m_physicsShapeType = value; | ||
1403 | } | ||
1404 | else | ||
1405 | m_physicsShapeType = DefaultPhysicsShapeType(); | ||
1406 | |||
1407 | if (m_physicsShapeType != oldv && ParentGroup != null) | ||
1408 | { | ||
1409 | if (m_physicsShapeType == (byte)PhysShapeType.none) | ||
1410 | { | ||
1411 | if (PhysActor != null) | ||
1412 | { | ||
1413 | Velocity = new Vector3(0, 0, 0); | ||
1414 | Acceleration = new Vector3(0, 0, 0); | ||
1415 | if (ParentGroup.RootPart == this) | ||
1416 | AngularVelocity = new Vector3(0, 0, 0); | ||
1417 | ParentGroup.Scene.RemovePhysicalPrim(1); | ||
1418 | RemoveFromPhysics(); | ||
1419 | } | ||
1420 | } | ||
1421 | else if (PhysActor == null) | ||
1422 | { | ||
1423 | ApplyPhysics((uint)Flags, VolumeDetectActive); | ||
1424 | } | ||
1425 | else | ||
1426 | { | ||
1427 | PhysActor.PhysicsShapeType = m_physicsShapeType; | ||
1428 | } | ||
1429 | |||
1430 | if (ParentGroup != null) | ||
1431 | ParentGroup.HasGroupChanged = true; | ||
1432 | } | ||
1433 | |||
1434 | if (m_physicsShapeType != value) | ||
1435 | { | ||
1436 | UpdatePhysRequired = true; | ||
1437 | } | ||
1438 | } | ||
1439 | } | ||
1440 | |||
1441 | public float Density // in kg/m^3 | ||
1442 | { | ||
1443 | get { return m_density; } | ||
1444 | set | ||
1445 | { | ||
1446 | if (value >=1 && value <= 22587.0) | ||
1447 | { | ||
1448 | m_density = value; | ||
1449 | UpdatePhysRequired = true; | ||
1450 | } | ||
1451 | |||
1452 | ScheduleFullUpdateIfNone(); | ||
1453 | |||
1454 | if (ParentGroup != null) | ||
1455 | ParentGroup.HasGroupChanged = true; | ||
1456 | |||
1457 | PhysicsActor pa = PhysActor; | ||
1458 | if (pa != null) | ||
1459 | pa.Density = Density; | ||
1460 | } | ||
1461 | } | ||
1462 | |||
1463 | public float GravityModifier | ||
1464 | { | ||
1465 | get { return m_gravitymod; } | ||
1466 | set | ||
1467 | { | ||
1468 | if( value >= -1 && value <=28.0f) | ||
1469 | { | ||
1470 | m_gravitymod = value; | ||
1471 | UpdatePhysRequired = true; | ||
1472 | } | ||
1473 | |||
1474 | ScheduleFullUpdateIfNone(); | ||
1475 | |||
1476 | if (ParentGroup != null) | ||
1477 | ParentGroup.HasGroupChanged = true; | ||
1478 | |||
1479 | PhysicsActor pa = PhysActor; | ||
1480 | if (pa != null) | ||
1481 | pa.GravModifier = GravityModifier; | ||
1482 | } | ||
1483 | } | ||
1484 | |||
1485 | public float Friction | ||
1486 | { | ||
1487 | get { return m_friction; } | ||
1488 | set | ||
1489 | { | ||
1490 | if (value >= 0 && value <= 255.0f) | ||
1491 | { | ||
1492 | m_friction = value; | ||
1493 | UpdatePhysRequired = true; | ||
1494 | } | ||
1495 | |||
1496 | ScheduleFullUpdateIfNone(); | ||
1497 | |||
1498 | if (ParentGroup != null) | ||
1499 | ParentGroup.HasGroupChanged = true; | ||
1500 | |||
1501 | PhysicsActor pa = PhysActor; | ||
1502 | if (pa != null) | ||
1503 | pa.Friction = Friction; | ||
1504 | } | ||
1505 | } | ||
1506 | |||
1507 | public float Restitution | ||
1508 | { | ||
1509 | get { return m_bounce; } | ||
1510 | set | ||
1511 | { | ||
1512 | if (value >= 0 && value <= 1.0f) | ||
1513 | { | ||
1514 | m_bounce = value; | ||
1515 | UpdatePhysRequired = true; | ||
1516 | } | ||
1517 | |||
1518 | ScheduleFullUpdateIfNone(); | ||
1519 | |||
1520 | if (ParentGroup != null) | ||
1521 | ParentGroup.HasGroupChanged = true; | ||
1522 | |||
1523 | PhysicsActor pa = PhysActor; | ||
1524 | if (pa != null) | ||
1525 | pa.Restitution = Restitution; | ||
1526 | } | ||
1527 | } | ||
1528 | |||
1318 | #endregion Public Properties with only Get | 1529 | #endregion Public Properties with only Get |
1319 | 1530 | ||
1320 | private uint ApplyMask(uint val, bool set, uint mask) | 1531 | private uint ApplyMask(uint val, bool set, uint mask) |
@@ -1403,20 +1614,29 @@ namespace OpenSim.Region.Framework.Scenes | |||
1403 | 1614 | ||
1404 | public void AddTextureAnimation(Primitive.TextureAnimation pTexAnim) | 1615 | public void AddTextureAnimation(Primitive.TextureAnimation pTexAnim) |
1405 | { | 1616 | { |
1406 | byte[] data = new byte[16]; | 1617 | byte[] data; |
1407 | int pos = 0; | ||
1408 | 1618 | ||
1409 | // The flags don't like conversion from uint to byte, so we have to do | 1619 | if (pTexAnim.Flags == Primitive.TextureAnimMode.ANIM_OFF) |
1410 | // it the crappy way. See the above function :( | 1620 | { |
1621 | data = Utils.EmptyBytes; | ||
1622 | } | ||
1623 | else | ||
1624 | { | ||
1625 | data = new byte[16]; | ||
1626 | int pos = 0; | ||
1411 | 1627 | ||
1412 | data[pos] = ConvertScriptUintToByte((uint)pTexAnim.Flags); pos++; | 1628 | // The flags don't like conversion from uint to byte, so we have to do |
1413 | data[pos] = (byte)pTexAnim.Face; pos++; | 1629 | // it the crappy way. See the above function :( |
1414 | data[pos] = (byte)pTexAnim.SizeX; pos++; | ||
1415 | data[pos] = (byte)pTexAnim.SizeY; pos++; | ||
1416 | 1630 | ||
1417 | Utils.FloatToBytes(pTexAnim.Start).CopyTo(data, pos); | 1631 | data[pos] = ConvertScriptUintToByte((uint)pTexAnim.Flags); pos++; |
1418 | Utils.FloatToBytes(pTexAnim.Length).CopyTo(data, pos + 4); | 1632 | data[pos] = (byte)pTexAnim.Face; pos++; |
1419 | Utils.FloatToBytes(pTexAnim.Rate).CopyTo(data, pos + 8); | 1633 | data[pos] = (byte)pTexAnim.SizeX; pos++; |
1634 | data[pos] = (byte)pTexAnim.SizeY; pos++; | ||
1635 | |||
1636 | Utils.FloatToBytes(pTexAnim.Start).CopyTo(data, pos); | ||
1637 | Utils.FloatToBytes(pTexAnim.Length).CopyTo(data, pos + 4); | ||
1638 | Utils.FloatToBytes(pTexAnim.Rate).CopyTo(data, pos + 8); | ||
1639 | } | ||
1420 | 1640 | ||
1421 | m_TextureAnimation = data; | 1641 | m_TextureAnimation = data; |
1422 | } | 1642 | } |
@@ -1511,40 +1731,36 @@ namespace OpenSim.Region.Framework.Scenes | |||
1511 | /// </summary> | 1731 | /// </summary> |
1512 | /// <param name="rootObjectFlags"></param> | 1732 | /// <param name="rootObjectFlags"></param> |
1513 | /// <param name="VolumeDetectActive"></param> | 1733 | /// <param name="VolumeDetectActive"></param> |
1514 | public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive) | 1734 | public void ApplyPhysics(uint rootObjectFlags, bool _VolumeDetectActive) |
1515 | { | 1735 | { |
1736 | VolumeDetectActive = _VolumeDetectActive; | ||
1737 | |||
1516 | if (!ParentGroup.Scene.CollidablePrims) | 1738 | if (!ParentGroup.Scene.CollidablePrims) |
1517 | return; | 1739 | return; |
1518 | 1740 | ||
1519 | // m_log.DebugFormat( | 1741 | if (PhysicsShapeType == (byte)PhysShapeType.none) |
1520 | // "[SCENE OBJECT PART]: Applying physics to {0} {1}, m_physicalPrim {2}", | 1742 | return; |
1521 | // Name, LocalId, UUID, m_physicalPrim); | ||
1522 | 1743 | ||
1523 | bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; | 1744 | bool isPhysical = (rootObjectFlags & (uint) PrimFlags.Physics) != 0; |
1524 | bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; | 1745 | bool isPhantom = (rootObjectFlags & (uint) PrimFlags.Phantom) != 0; |
1525 | 1746 | ||
1747 | if (_VolumeDetectActive) | ||
1748 | isPhantom = true; | ||
1749 | |||
1526 | if (IsJoint()) | 1750 | if (IsJoint()) |
1527 | { | 1751 | { |
1528 | DoPhysicsPropertyUpdate(isPhysical, true); | 1752 | DoPhysicsPropertyUpdate(isPhysical, true); |
1529 | } | 1753 | } |
1530 | else | 1754 | else |
1531 | { | 1755 | { |
1532 | // Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored | 1756 | if ((!isPhantom || isPhysical || _VolumeDetectActive) |
1533 | if (VolumeDetectActive) | 1757 | && !ParentGroup.IsAttachmentCheckFull() |
1534 | isPhantom = false; | 1758 | && !(Shape.PathCurve == (byte)Extrusion.Flexible)) |
1535 | |||
1536 | // 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 | ||
1537 | // or flexible | ||
1538 | if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible)) | ||
1539 | { | 1759 | { |
1540 | // Added clarification.. since A rigid body is an object that you can kick around, etc. | 1760 | AddToPhysics(isPhysical, isPhantom, isPhysical); |
1541 | bool rigidBody = isPhysical && !isPhantom; | ||
1542 | |||
1543 | PhysicsActor pa = AddToPhysics(rigidBody); | ||
1544 | |||
1545 | if (pa != null) | ||
1546 | pa.SetVolumeDetect(VolumeDetectActive ? 1 : 0); | ||
1547 | } | 1761 | } |
1762 | else | ||
1763 | PhysActor = null; // just to be sure | ||
1548 | } | 1764 | } |
1549 | } | 1765 | } |
1550 | 1766 | ||
@@ -1572,7 +1788,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1572 | /// <returns></returns> | 1788 | /// <returns></returns> |
1573 | public SceneObjectPart Copy(uint localID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed) | 1789 | public SceneObjectPart Copy(uint localID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed) |
1574 | { | 1790 | { |
1791 | // FIXME: This is dangerous since it's easy to forget to reset some references when necessary and end up | ||
1792 | // with bugs that only occur in some circumstances (e.g. crossing between regions on the same simulator | ||
1793 | // but not between regions on different simulators). Really, all copying should be done explicitly. | ||
1575 | SceneObjectPart dupe = (SceneObjectPart)MemberwiseClone(); | 1794 | SceneObjectPart dupe = (SceneObjectPart)MemberwiseClone(); |
1795 | |||
1576 | dupe.m_shape = m_shape.Copy(); | 1796 | dupe.m_shape = m_shape.Copy(); |
1577 | dupe.m_regionHandle = m_regionHandle; | 1797 | dupe.m_regionHandle = m_regionHandle; |
1578 | if (userExposed) | 1798 | if (userExposed) |
@@ -1618,6 +1838,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1618 | Array.Copy(Shape.ExtraParams, extraP, extraP.Length); | 1838 | Array.Copy(Shape.ExtraParams, extraP, extraP.Length); |
1619 | dupe.Shape.ExtraParams = extraP; | 1839 | dupe.Shape.ExtraParams = extraP; |
1620 | 1840 | ||
1841 | dupe.m_sittingAvatars = new HashSet<ScenePresence>(); | ||
1842 | |||
1843 | // safeguard actual copy is done in sog.copy | ||
1844 | dupe.KeyframeMotion = null; | ||
1845 | dupe.PayPrice = (int[])PayPrice.Clone(); | ||
1846 | |||
1847 | dupe.DynAttrs.CopyFrom(DynAttrs); | ||
1848 | |||
1621 | if (userExposed) | 1849 | if (userExposed) |
1622 | { | 1850 | { |
1623 | /* | 1851 | /* |
@@ -1816,6 +2044,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1816 | { | 2044 | { |
1817 | if (UsePhysics) | 2045 | if (UsePhysics) |
1818 | { | 2046 | { |
2047 | if (ParentGroup.RootPart.KeyframeMotion != null) | ||
2048 | ParentGroup.RootPart.KeyframeMotion.Stop(); | ||
2049 | ParentGroup.RootPart.KeyframeMotion = null; | ||
1819 | ParentGroup.Scene.AddPhysicalPrim(1); | 2050 | ParentGroup.Scene.AddPhysicalPrim(1); |
1820 | 2051 | ||
1821 | pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; | 2052 | pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; |
@@ -1848,7 +2079,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1848 | /// </summary> | 2079 | /// </summary> |
1849 | /// <param name="xmlReader"></param> | 2080 | /// <param name="xmlReader"></param> |
1850 | /// <returns></returns> | 2081 | /// <returns></returns> |
1851 | public static SceneObjectPart FromXml(XmlTextReader xmlReader) | 2082 | public static SceneObjectPart FromXml(XmlReader xmlReader) |
1852 | { | 2083 | { |
1853 | SceneObjectPart part = SceneObjectSerializer.Xml2ToSOP(xmlReader); | 2084 | SceneObjectPart part = SceneObjectSerializer.Xml2ToSOP(xmlReader); |
1854 | 2085 | ||
@@ -1883,22 +2114,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1883 | ParentGroup.RootPart.RETURN_AT_EDGE = p; | 2114 | ParentGroup.RootPart.RETURN_AT_EDGE = p; |
1884 | } | 2115 | } |
1885 | 2116 | ||
1886 | public bool GetBlockGrab() | ||
1887 | { | ||
1888 | if (ParentGroup.IsDeleted) | ||
1889 | return false; | ||
1890 | |||
1891 | return ParentGroup.RootPart.BlockGrab; | ||
1892 | } | ||
1893 | |||
1894 | public void SetBlockGrab(bool p) | ||
1895 | { | ||
1896 | if (ParentGroup.IsDeleted) | ||
1897 | return; | ||
1898 | |||
1899 | ParentGroup.RootPart.BlockGrab = p; | ||
1900 | } | ||
1901 | |||
1902 | public void SetStatusSandbox(bool p) | 2117 | public void SetStatusSandbox(bool p) |
1903 | { | 2118 | { |
1904 | if (ParentGroup.IsDeleted) | 2119 | if (ParentGroup.IsDeleted) |
@@ -1952,9 +2167,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
1952 | PhysicsActor pa = PhysActor; | 2167 | PhysicsActor pa = PhysActor; |
1953 | 2168 | ||
1954 | if (pa != null) | 2169 | if (pa != null) |
1955 | return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z); | 2170 | return pa.GeometricCenter; |
2171 | else | ||
2172 | return Vector3.Zero; | ||
2173 | } | ||
2174 | |||
2175 | public Vector3 GetCenterOfMass() | ||
2176 | { | ||
2177 | PhysicsActor pa = PhysActor; | ||
2178 | |||
2179 | if (pa != null) | ||
2180 | return pa.CenterOfMass; | ||
1956 | else | 2181 | else |
1957 | return new Vector3(0, 0, 0); | 2182 | return Vector3.Zero; |
1958 | } | 2183 | } |
1959 | 2184 | ||
1960 | public float GetMass() | 2185 | public float GetMass() |
@@ -2030,7 +2255,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2030 | { | 2255 | { |
2031 | if (tau > 0) | 2256 | if (tau > 0) |
2032 | { | 2257 | { |
2033 | ParentGroup.moveToTarget(target, tau); | 2258 | ParentGroup.MoveToTarget(target, tau); |
2034 | } | 2259 | } |
2035 | else | 2260 | else |
2036 | { | 2261 | { |
@@ -2168,7 +2393,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2168 | CollidingMessage = CreateColliderArgs(this, colliders); | 2393 | CollidingMessage = CreateColliderArgs(this, colliders); |
2169 | 2394 | ||
2170 | if (CollidingMessage.Colliders.Count > 0) | 2395 | if (CollidingMessage.Colliders.Count > 0) |
2171 | notify(LocalId, CollidingMessage); | 2396 | DoNotify(notify, LocalId, CollidingMessage); |
2172 | 2397 | ||
2173 | if (PassCollisions) | 2398 | if (PassCollisions) |
2174 | sendToRoot = true; | 2399 | sendToRoot = true; |
@@ -2182,7 +2407,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2182 | { | 2407 | { |
2183 | CollidingMessage = CreateColliderArgs(ParentGroup.RootPart, colliders); | 2408 | CollidingMessage = CreateColliderArgs(ParentGroup.RootPart, colliders); |
2184 | if (CollidingMessage.Colliders.Count > 0) | 2409 | if (CollidingMessage.Colliders.Count > 0) |
2185 | notify(ParentGroup.RootPart.LocalId, CollidingMessage); | 2410 | DoNotify(notify, ParentGroup.RootPart.LocalId, CollidingMessage); |
2186 | } | 2411 | } |
2187 | } | 2412 | } |
2188 | } | 2413 | } |
@@ -2197,7 +2422,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
2197 | colliding.Add(CreateDetObjectForGround()); | 2422 | colliding.Add(CreateDetObjectForGround()); |
2198 | LandCollidingMessage.Colliders = colliding; | 2423 | LandCollidingMessage.Colliders = colliding; |
2199 | 2424 | ||
2200 | notify(LocalId, LandCollidingMessage); | 2425 | DoNotify(notify, LocalId, LandCollidingMessage); |
2426 | } | ||
2427 | } | ||
2428 | |||
2429 | private void DoNotify(ScriptCollidingNotification notify, uint id, ColliderArgs collargs) | ||
2430 | { | ||
2431 | if (m_parentGroup != null && ParentGroup.Scene != null && ParentGroup.Scene.ShouldUseFireAndForgetForCollisions) | ||
2432 | { | ||
2433 | // For those learning C#, FireAndForget takes a function, an object to pass | ||
2434 | // to that function and an ID string. The "oo => {}" construct is a lambda expression | ||
2435 | // for a function with one arguement ('oo'). The 'new Object[] {}" construct creates an Object | ||
2436 | // that is an object array and initializes it with three items (the parameters | ||
2437 | // being passed). The parameters passed are the function to call ('notify') and | ||
2438 | // its two arguements. Finally, once in the function (called later by the FireAndForget | ||
2439 | // thread scheduler), the passed object is cast to an object array and then each | ||
2440 | // of its items (aoo[0] to aoo[2]) are individually cast to what they are and | ||
2441 | // then used in a call of the passed ScriptCollidingNotification function. | ||
2442 | Util.FireAndForget(oo => | ||
2443 | { | ||
2444 | Object[] aoo = (Object[])oo; | ||
2445 | ((ScriptCollidingNotification)aoo[0])((uint)aoo[1], (ColliderArgs)aoo[2]); | ||
2446 | |||
2447 | }, new Object[] { notify, id, collargs }, "SOP.Collision"); | ||
2448 | } | ||
2449 | else | ||
2450 | { | ||
2451 | notify(id, collargs); | ||
2201 | } | 2452 | } |
2202 | } | 2453 | } |
2203 | 2454 | ||
@@ -2244,7 +2495,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2244 | if (soundModule != null) | 2495 | if (soundModule != null) |
2245 | { | 2496 | { |
2246 | soundModule.SendSound(UUID, CollisionSound, | 2497 | soundModule.SendSound(UUID, CollisionSound, |
2247 | CollisionSoundVolume, true, (byte)0, 0, false, | 2498 | CollisionSoundVolume, true, 0, 0, false, |
2248 | false); | 2499 | false); |
2249 | } | 2500 | } |
2250 | } | 2501 | } |
@@ -2254,12 +2505,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2254 | SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); | 2505 | SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); |
2255 | 2506 | ||
2256 | if (startedColliders.Contains(0)) | 2507 | if (startedColliders.Contains(0)) |
2257 | { | 2508 | SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart); |
2258 | if (m_lastColliders.Contains(0)) | 2509 | if (m_lastColliders.Contains(0)) |
2259 | SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding); | 2510 | SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding); |
2260 | else | ||
2261 | SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart); | ||
2262 | } | ||
2263 | if (endedColliders.Contains(0)) | 2511 | if (endedColliders.Contains(0)) |
2264 | SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); | 2512 | SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); |
2265 | } | 2513 | } |
@@ -2282,19 +2530,36 @@ namespace OpenSim.Region.Framework.Scenes | |||
2282 | 2530 | ||
2283 | if (pa != null) | 2531 | if (pa != null) |
2284 | { | 2532 | { |
2285 | Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); | 2533 | Vector3 newpos = pa.Position; |
2286 | 2534 | if (!ParentGroup.Scene.PositionIsInCurrentRegion(newpos)) | |
2287 | if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | ||
2288 | | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | ||
2289 | | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | ||
2290 | | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) | ||
2291 | { | 2535 | { |
2536 | // Setting position outside current region will start region crossing | ||
2292 | ParentGroup.AbsolutePosition = newpos; | 2537 | ParentGroup.AbsolutePosition = newpos; |
2293 | return; | 2538 | return; |
2294 | } | 2539 | } |
2295 | //ParentGroup.RootPart.m_groupPosition = newpos; | 2540 | //ParentGroup.RootPart.m_groupPosition = newpos; |
2296 | } | 2541 | } |
2297 | 2542 | ||
2543 | if (pa != null && ParentID != 0 && ParentGroup != null) | ||
2544 | { | ||
2545 | // Special case where a child object is requesting property updates. | ||
2546 | // This happens when linksets are modified to use flexible links rather than | ||
2547 | // the default links. | ||
2548 | // The simulator code presumes that child parts are only modified by scripts | ||
2549 | // so the logic for changing position/rotation/etc does not take into | ||
2550 | // account the physical object actually moving. | ||
2551 | // This code updates the offset position and rotation of the child and then | ||
2552 | // lets the update code push the update to the viewer. | ||
2553 | // Since physics engines do not normally generate this event for linkset children, | ||
2554 | // this code will not be active unless you have a specially configured | ||
2555 | // physics engine. | ||
2556 | Quaternion invRootRotation = Quaternion.Normalize(Quaternion.Inverse(ParentGroup.RootPart.RotationOffset)); | ||
2557 | m_offsetPosition = pa.Position - m_groupPosition; | ||
2558 | RotationOffset = pa.Orientation * invRootRotation; | ||
2559 | // m_log.DebugFormat("{0} PhysicsRequestingTerseUpdate child: pos={1}, rot={2}, offPos={3}, offRot={4}", | ||
2560 | // "[SCENE OBJECT PART]", pa.Position, pa.Orientation, m_offsetPosition, RotationOffset); | ||
2561 | } | ||
2562 | |||
2298 | ScheduleTerseUpdate(); | 2563 | ScheduleTerseUpdate(); |
2299 | } | 2564 | } |
2300 | 2565 | ||
@@ -2397,7 +2662,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2397 | return; | 2662 | return; |
2398 | } | 2663 | } |
2399 | 2664 | ||
2400 | m_APIDIterations = 1 + (int)(Math.PI * APIDStrength); | 2665 | APIDActive = true; |
2401 | } | 2666 | } |
2402 | 2667 | ||
2403 | // Necessary to get the lookat deltas applied | 2668 | // Necessary to get the lookat deltas applied |
@@ -2411,7 +2676,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
2411 | 2676 | ||
2412 | public void StopLookAt() | 2677 | public void StopLookAt() |
2413 | { | 2678 | { |
2414 | APIDTarget = Quaternion.Identity; | 2679 | APIDActive = false; |
2680 | } | ||
2681 | |||
2682 | |||
2683 | |||
2684 | public void ScheduleFullUpdateIfNone() | ||
2685 | { | ||
2686 | if (ParentGroup == null) | ||
2687 | return; | ||
2688 | |||
2689 | // ??? ParentGroup.HasGroupChanged = true; | ||
2690 | |||
2691 | if (UpdateFlag != UpdateRequired.FULL) | ||
2692 | ScheduleFullUpdate(); | ||
2415 | } | 2693 | } |
2416 | 2694 | ||
2417 | /// <summary> | 2695 | /// <summary> |
@@ -2460,7 +2738,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2460 | return; | 2738 | return; |
2461 | 2739 | ||
2462 | // This was pulled from SceneViewer. Attachments always receive full updates. | 2740 | // This was pulled from SceneViewer. Attachments always receive full updates. |
2463 | // I could not verify if this is a requirement but this maintains existing behavior | 2741 | // This is needed because otherwise if only the root prim changes position, then |
2742 | // it looks as if the entire object has moved (including the other prims). | ||
2464 | if (ParentGroup.IsAttachment) | 2743 | if (ParentGroup.IsAttachment) |
2465 | { | 2744 | { |
2466 | ScheduleFullUpdate(); | 2745 | ScheduleFullUpdate(); |
@@ -2996,6 +3275,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
2996 | /// <param name="events"></param> | 3275 | /// <param name="events"></param> |
2997 | public void SetScriptEvents(UUID scriptid, int events) | 3276 | public void SetScriptEvents(UUID scriptid, int events) |
2998 | { | 3277 | { |
3278 | // m_log.DebugFormat( | ||
3279 | // "[SCENE OBJECT PART]: Set script events for script with id {0} on {1}/{2} to {3} in {4}", | ||
3280 | // scriptid, Name, ParentGroup.Name, events, ParentGroup.Scene.Name); | ||
3281 | |||
2999 | // scriptEvents oldparts; | 3282 | // scriptEvents oldparts; |
3000 | lock (m_scriptEvents) | 3283 | lock (m_scriptEvents) |
3001 | { | 3284 | { |
@@ -3048,10 +3331,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3048 | 3331 | ||
3049 | public void StopMoveToTarget() | 3332 | public void StopMoveToTarget() |
3050 | { | 3333 | { |
3051 | ParentGroup.stopMoveToTarget(); | 3334 | ParentGroup.StopMoveToTarget(); |
3052 | |||
3053 | ParentGroup.ScheduleGroupForTerseUpdate(); | ||
3054 | //ParentGroup.ScheduleGroupForFullUpdate(); | ||
3055 | } | 3335 | } |
3056 | 3336 | ||
3057 | public void StoreUndoState() | 3337 | public void StoreUndoState() |
@@ -3618,6 +3898,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3618 | result.distance = distance2; | 3898 | result.distance = distance2; |
3619 | result.HitTF = true; | 3899 | result.HitTF = true; |
3620 | result.ipoint = q; | 3900 | result.ipoint = q; |
3901 | result.face = i; | ||
3621 | //m_log.Info("[FACE]:" + i.ToString()); | 3902 | //m_log.Info("[FACE]:" + i.ToString()); |
3622 | //m_log.Info("[POINT]: " + q.ToString()); | 3903 | //m_log.Info("[POINT]: " + q.ToString()); |
3623 | //m_log.Info("[DIST]: " + distance2.ToString()); | 3904 | //m_log.Info("[DIST]: " + distance2.ToString()); |
@@ -3664,10 +3945,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3664 | 3945 | ||
3665 | public void TrimPermissions() | 3946 | public void TrimPermissions() |
3666 | { | 3947 | { |
3667 | BaseMask &= (uint)PermissionMask.All; | 3948 | BaseMask &= (uint)(PermissionMask.All | PermissionMask.Export); |
3668 | OwnerMask &= (uint)PermissionMask.All; | 3949 | OwnerMask &= (uint)(PermissionMask.All | PermissionMask.Export); |
3669 | GroupMask &= (uint)PermissionMask.All; | 3950 | GroupMask &= (uint)PermissionMask.All; |
3670 | EveryoneMask &= (uint)PermissionMask.All; | 3951 | EveryoneMask &= (uint)(PermissionMask.All | PermissionMask.Export); |
3671 | NextOwnerMask &= (uint)PermissionMask.All; | 3952 | NextOwnerMask &= (uint)PermissionMask.All; |
3672 | } | 3953 | } |
3673 | 3954 | ||
@@ -3690,30 +3971,31 @@ namespace OpenSim.Region.Framework.Scenes | |||
3690 | } | 3971 | } |
3691 | } | 3972 | } |
3692 | 3973 | ||
3693 | public void UpdateGroupPosition(Vector3 pos) | 3974 | public void UpdateGroupPosition(Vector3 newPos) |
3694 | { | 3975 | { |
3695 | if ((pos.X != GroupPosition.X) || | 3976 | Vector3 oldPos = GroupPosition; |
3696 | (pos.Y != GroupPosition.Y) || | 3977 | |
3697 | (pos.Z != GroupPosition.Z)) | 3978 | if ((newPos.X != oldPos.X) || |
3979 | (newPos.Y != oldPos.Y) || | ||
3980 | (newPos.Z != oldPos.Z)) | ||
3698 | { | 3981 | { |
3699 | Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); | ||
3700 | GroupPosition = newPos; | 3982 | GroupPosition = newPos; |
3701 | ScheduleTerseUpdate(); | 3983 | ScheduleTerseUpdate(); |
3702 | } | 3984 | } |
3703 | } | 3985 | } |
3704 | 3986 | ||
3705 | /// <summary> | 3987 | /// <summary> |
3706 | /// | 3988 | /// Update this part's offset position. |
3707 | /// </summary> | 3989 | /// </summary> |
3708 | /// <param name="pos"></param> | 3990 | /// <param name="pos"></param> |
3709 | public void UpdateOffSet(Vector3 pos) | 3991 | public void UpdateOffSet(Vector3 newPos) |
3710 | { | 3992 | { |
3711 | if ((pos.X != OffsetPosition.X) || | 3993 | Vector3 oldPos = OffsetPosition; |
3712 | (pos.Y != OffsetPosition.Y) || | ||
3713 | (pos.Z != OffsetPosition.Z)) | ||
3714 | { | ||
3715 | Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); | ||
3716 | 3994 | ||
3995 | if ((newPos.X != oldPos.X) || | ||
3996 | (newPos.Y != oldPos.Y) || | ||
3997 | (newPos.Z != oldPos.Z)) | ||
3998 | { | ||
3717 | if (ParentGroup.RootPart.GetStatusSandbox()) | 3999 | if (ParentGroup.RootPart.GetStatusSandbox()) |
3718 | { | 4000 | { |
3719 | if (Util.GetDistanceTo(ParentGroup.RootPart.StatusSandboxPos, newPos) > 10) | 4001 | if (Util.GetDistanceTo(ParentGroup.RootPart.StatusSandboxPos, newPos) > 10) |
@@ -3770,10 +4052,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
3770 | baseMask; | 4052 | baseMask; |
3771 | break; | 4053 | break; |
3772 | case 8: | 4054 | case 8: |
4055 | // Trying to set export permissions - extra checks | ||
4056 | if (set && (mask & (uint)PermissionMask.Export) != 0) | ||
4057 | { | ||
4058 | if ((OwnerMask & (uint)PermissionMask.Export) == 0 || (BaseMask & (uint)PermissionMask.Export) == 0 || (NextOwnerMask & (uint)PermissionMask.All) != (uint)PermissionMask.All) | ||
4059 | mask &= ~(uint)PermissionMask.Export; | ||
4060 | } | ||
3773 | EveryoneMask = ApplyMask(EveryoneMask, set, mask) & | 4061 | EveryoneMask = ApplyMask(EveryoneMask, set, mask) & |
3774 | baseMask; | 4062 | baseMask; |
3775 | break; | 4063 | break; |
3776 | case 16: | 4064 | case 16: |
4065 | // Force full perm if export | ||
4066 | if ((EveryoneMask & (uint)PermissionMask.Export) != 0) | ||
4067 | { | ||
4068 | NextOwnerMask = (uint)PermissionMask.All; | ||
4069 | break; | ||
4070 | } | ||
3777 | NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & | 4071 | NextOwnerMask = ApplyMask(NextOwnerMask, set, mask) & |
3778 | baseMask; | 4072 | baseMask; |
3779 | // Prevent the client from creating no mod, no copy | 4073 | // Prevent the client from creating no mod, no copy |
@@ -3848,7 +4142,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3848 | // For now, we use the NINJA naming scheme for identifying joints. | 4142 | // For now, we use the NINJA naming scheme for identifying joints. |
3849 | // In the future, we can support other joint specification schemes such as a | 4143 | // In the future, we can support other joint specification schemes such as a |
3850 | // custom checkbox in the viewer GUI. | 4144 | // custom checkbox in the viewer GUI. |
3851 | if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) | 4145 | if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) |
3852 | { | 4146 | { |
3853 | return IsHingeJoint() || IsBallJoint(); | 4147 | return IsHingeJoint() || IsBallJoint(); |
3854 | } | 4148 | } |
@@ -3858,6 +4152,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
3858 | } | 4152 | } |
3859 | } | 4153 | } |
3860 | 4154 | ||
4155 | public void UpdateExtraPhysics(ExtraPhysicsData physdata) | ||
4156 | { | ||
4157 | if (physdata.PhysShapeType == PhysShapeType.invalid || ParentGroup == null) | ||
4158 | return; | ||
4159 | |||
4160 | if (PhysicsShapeType != (byte)physdata.PhysShapeType) | ||
4161 | { | ||
4162 | PhysicsShapeType = (byte)physdata.PhysShapeType; | ||
4163 | |||
4164 | } | ||
4165 | |||
4166 | if(Density != physdata.Density) | ||
4167 | Density = physdata.Density; | ||
4168 | if(GravityModifier != physdata.GravitationModifier) | ||
4169 | GravityModifier = physdata.GravitationModifier; | ||
4170 | if(Friction != physdata.Friction) | ||
4171 | Friction = physdata.Friction; | ||
4172 | if(Restitution != physdata.Bounce) | ||
4173 | Restitution = physdata.Bounce; | ||
4174 | } | ||
3861 | /// <summary> | 4175 | /// <summary> |
3862 | /// Update the flags on this prim. This covers properties such as phantom, physics and temporary. | 4176 | /// Update the flags on this prim. This covers properties such as phantom, physics and temporary. |
3863 | /// </summary> | 4177 | /// </summary> |
@@ -3928,7 +4242,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3928 | } | 4242 | } |
3929 | 4243 | ||
3930 | if (SetPhantom | 4244 | if (SetPhantom |
3931 | || ParentGroup.IsAttachment | 4245 | || ParentGroup.IsAttachmentCheckFull() |
4246 | || PhysicsShapeType == (byte)PhysShapeType.none | ||
3932 | || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints | 4247 | || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints |
3933 | { | 4248 | { |
3934 | AddFlag(PrimFlags.Phantom); | 4249 | AddFlag(PrimFlags.Phantom); |
@@ -3948,32 +4263,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
3948 | 4263 | ||
3949 | if (ParentGroup.Scene.CollidablePrims && pa == null) | 4264 | if (ParentGroup.Scene.CollidablePrims && pa == null) |
3950 | { | 4265 | { |
3951 | pa = AddToPhysics(UsePhysics); | 4266 | AddToPhysics(UsePhysics, SetPhantom, false); |
4267 | pa = PhysActor; | ||
3952 | 4268 | ||
3953 | if (pa != null) | 4269 | if (pa != null) |
3954 | { | 4270 | { |
3955 | pa.SetMaterial(Material); | 4271 | pa.SetMaterial(Material); |
4272 | pa.Position = GetWorldPosition(); | ||
4273 | pa.Orientation = GetWorldRotation(); | ||
3956 | DoPhysicsPropertyUpdate(UsePhysics, true); | 4274 | DoPhysicsPropertyUpdate(UsePhysics, true); |
3957 | 4275 | ||
3958 | if ( | 4276 | SubscribeForCollisionEvents(); |
3959 | ((AggregateScriptEvents & scriptEvents.collision) != 0) || | ||
3960 | ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || | ||
3961 | ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || | ||
3962 | ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || | ||
3963 | ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || | ||
3964 | ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || | ||
3965 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) || | ||
3966 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) || | ||
3967 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) || | ||
3968 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || | ||
3969 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) || | ||
3970 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || | ||
3971 | (CollisionSound != UUID.Zero) | ||
3972 | ) | ||
3973 | { | ||
3974 | pa.OnCollisionUpdate += PhysicsCollision; | ||
3975 | pa.SubscribeEvents(1000); | ||
3976 | } | ||
3977 | } | 4277 | } |
3978 | } | 4278 | } |
3979 | else // it already has a physical representation | 4279 | else // it already has a physical representation |
@@ -4028,6 +4328,50 @@ namespace OpenSim.Region.Framework.Scenes | |||
4028 | } | 4328 | } |
4029 | 4329 | ||
4030 | /// <summary> | 4330 | /// <summary> |
4331 | /// Subscribe for physics collision events if needed for scripts and sounds | ||
4332 | /// </summary> | ||
4333 | public void SubscribeForCollisionEvents() | ||
4334 | { | ||
4335 | PhysicsActor pa = PhysActor; | ||
4336 | |||
4337 | if (pa != null) | ||
4338 | { | ||
4339 | if ( | ||
4340 | ((AggregateScriptEvents & scriptEvents.collision) != 0) || | ||
4341 | ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || | ||
4342 | ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || | ||
4343 | ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || | ||
4344 | ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || | ||
4345 | ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || | ||
4346 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) || | ||
4347 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) || | ||
4348 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) || | ||
4349 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || | ||
4350 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) || | ||
4351 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || | ||
4352 | (CollisionSound != UUID.Zero) | ||
4353 | ) | ||
4354 | { | ||
4355 | if (!pa.SubscribedEvents()) | ||
4356 | { | ||
4357 | // If not already subscribed for event, set up for a collision event. | ||
4358 | pa.OnCollisionUpdate += PhysicsCollision; | ||
4359 | pa.SubscribeEvents(1000); | ||
4360 | } | ||
4361 | } | ||
4362 | else | ||
4363 | { | ||
4364 | // There is no need to be subscribed to collisions so, if subscribed, remove subscription | ||
4365 | if (pa.SubscribedEvents()) | ||
4366 | { | ||
4367 | pa.OnCollisionUpdate -= PhysicsCollision; | ||
4368 | pa.UnSubscribeEvents(); | ||
4369 | } | ||
4370 | } | ||
4371 | } | ||
4372 | } | ||
4373 | |||
4374 | /// <summary> | ||
4031 | /// Adds this part to the physics scene. | 4375 | /// Adds this part to the physics scene. |
4032 | /// </summary> | 4376 | /// </summary> |
4033 | /// <remarks>This method also sets the PhysActor property.</remarks> | 4377 | /// <remarks>This method also sets the PhysActor property.</remarks> |
@@ -4035,10 +4379,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
4035 | /// <returns> | 4379 | /// <returns> |
4036 | /// The physics actor. null if there was a failure. | 4380 | /// The physics actor. null if there was a failure. |
4037 | /// </returns> | 4381 | /// </returns> |
4038 | private PhysicsActor AddToPhysics(bool rigidBody) | 4382 | private void AddToPhysics(bool isPhysical, bool isPhantom, bool applyDynamics) |
4039 | { | 4383 | { |
4040 | PhysicsActor pa; | 4384 | PhysicsActor pa; |
4041 | 4385 | ||
4386 | Vector3 velocity = Velocity; | ||
4387 | Vector3 rotationalVelocity = AngularVelocity;; | ||
4388 | |||
4042 | try | 4389 | try |
4043 | { | 4390 | { |
4044 | pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( | 4391 | pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( |
@@ -4046,8 +4393,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
4046 | Shape, | 4393 | Shape, |
4047 | AbsolutePosition, | 4394 | AbsolutePosition, |
4048 | Scale, | 4395 | Scale, |
4049 | RotationOffset, | 4396 | GetWorldRotation(), |
4050 | rigidBody, | 4397 | isPhysical, |
4398 | isPhantom, | ||
4399 | PhysicsShapeType, | ||
4051 | m_localId); | 4400 | m_localId); |
4052 | } | 4401 | } |
4053 | catch (Exception e) | 4402 | catch (Exception e) |
@@ -4056,20 +4405,56 @@ namespace OpenSim.Region.Framework.Scenes | |||
4056 | pa = null; | 4405 | pa = null; |
4057 | } | 4406 | } |
4058 | 4407 | ||
4059 | // FIXME: Ideally we wouldn't set the property here to reduce situations where threads changing physical | ||
4060 | // properties can stop on each other. However, DoPhysicsPropertyUpdate() currently relies on PhysActor | ||
4061 | // being set. | ||
4062 | PhysActor = pa; | ||
4063 | |||
4064 | // Basic Physics can also return null as well as an exception catch. | ||
4065 | if (pa != null) | 4408 | if (pa != null) |
4066 | { | 4409 | { |
4067 | pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info | 4410 | pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info |
4068 | pa.SetMaterial(Material); | 4411 | pa.SetMaterial(Material); |
4069 | DoPhysicsPropertyUpdate(rigidBody, true); | 4412 | |
4413 | pa.Density = Density; | ||
4414 | pa.GravModifier = GravityModifier; | ||
4415 | pa.Friction = Friction; | ||
4416 | pa.Restitution = Restitution; | ||
4417 | |||
4418 | if (VolumeDetectActive) // change if not the default only | ||
4419 | pa.SetVolumeDetect(1); | ||
4420 | // we are going to tell rest of code about physics so better have this here | ||
4421 | PhysActor = pa; | ||
4422 | |||
4423 | if (isPhysical) | ||
4424 | { | ||
4425 | if (ParentGroup.RootPart.KeyframeMotion != null) | ||
4426 | ParentGroup.RootPart.KeyframeMotion.Stop(); | ||
4427 | ParentGroup.RootPart.KeyframeMotion = null; | ||
4428 | ParentGroup.Scene.AddPhysicalPrim(1); | ||
4429 | |||
4430 | pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; | ||
4431 | pa.OnOutOfBounds += PhysicsOutOfBounds; | ||
4432 | |||
4433 | if (ParentID != 0 && ParentID != LocalId) | ||
4434 | { | ||
4435 | PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; | ||
4436 | |||
4437 | if (parentPa != null) | ||
4438 | { | ||
4439 | pa.link(parentPa); | ||
4440 | } | ||
4441 | } | ||
4442 | } | ||
4443 | |||
4444 | if (applyDynamics) | ||
4445 | // do independent of isphysical so parameters get setted (at least some) | ||
4446 | { | ||
4447 | Velocity = velocity; | ||
4448 | AngularVelocity = rotationalVelocity; | ||
4449 | // pa.Velocity = velocity; | ||
4450 | pa.RotationalVelocity = rotationalVelocity; | ||
4451 | } | ||
4452 | |||
4453 | ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa); | ||
4070 | } | 4454 | } |
4071 | 4455 | ||
4072 | return pa; | 4456 | PhysActor = pa; |
4457 | ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this); | ||
4073 | } | 4458 | } |
4074 | 4459 | ||
4075 | /// <summary> | 4460 | /// <summary> |
@@ -4082,7 +4467,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
4082 | /// </remarks> | 4467 | /// </remarks> |
4083 | public void RemoveFromPhysics() | 4468 | public void RemoveFromPhysics() |
4084 | { | 4469 | { |
4085 | ParentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); | 4470 | ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this); |
4471 | if (ParentGroup.Scene.PhysicsScene != null) | ||
4472 | ParentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); | ||
4086 | PhysActor = null; | 4473 | PhysActor = null; |
4087 | } | 4474 | } |
4088 | 4475 | ||
@@ -4255,8 +4642,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
4255 | 4642 | ||
4256 | Changed changeFlags = 0; | 4643 | Changed changeFlags = 0; |
4257 | 4644 | ||
4645 | Primitive.TextureEntryFace fallbackNewFace = newTex.DefaultTexture; | ||
4646 | Primitive.TextureEntryFace fallbackOldFace = oldTex.DefaultTexture; | ||
4647 | |||
4648 | // On Incoming packets, sometimes newText.DefaultTexture is null. The assumption is that all | ||
4649 | // other prim-sides are set, but apparently that's not always the case. Lets assume packet/data corruption at this point. | ||
4650 | if (fallbackNewFace == null) | ||
4651 | { | ||
4652 | fallbackNewFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0); | ||
4653 | newTex.DefaultTexture = fallbackNewFace; | ||
4654 | } | ||
4655 | if (fallbackOldFace == null) | ||
4656 | { | ||
4657 | fallbackOldFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0); | ||
4658 | oldTex.DefaultTexture = fallbackOldFace; | ||
4659 | } | ||
4660 | |||
4661 | // Materials capable viewers can send a ObjectImage packet | ||
4662 | // when nothing in TE has changed. MaterialID should be updated | ||
4663 | // by the RenderMaterials CAP handler, so updating it here may cause a | ||
4664 | // race condtion. Therefore, if no non-materials TE fields have changed, | ||
4665 | // we should ignore any changes and not update Shape.TextureEntry | ||
4666 | |||
4667 | bool otherFieldsChanged = false; | ||
4668 | |||
4258 | for (int i = 0 ; i < GetNumberOfSides(); i++) | 4669 | for (int i = 0 ; i < GetNumberOfSides(); i++) |
4259 | { | 4670 | { |
4671 | |||
4260 | Primitive.TextureEntryFace newFace = newTex.DefaultTexture; | 4672 | Primitive.TextureEntryFace newFace = newTex.DefaultTexture; |
4261 | Primitive.TextureEntryFace oldFace = oldTex.DefaultTexture; | 4673 | Primitive.TextureEntryFace oldFace = oldTex.DefaultTexture; |
4262 | 4674 | ||
@@ -4280,18 +4692,36 @@ namespace OpenSim.Region.Framework.Scenes | |||
4280 | // Max change, skip the rest of testing | 4692 | // Max change, skip the rest of testing |
4281 | if (changeFlags == (Changed.TEXTURE | Changed.COLOR)) | 4693 | if (changeFlags == (Changed.TEXTURE | Changed.COLOR)) |
4282 | break; | 4694 | break; |
4695 | |||
4696 | if (!otherFieldsChanged) | ||
4697 | { | ||
4698 | if (oldFace.Bump != newFace.Bump) otherFieldsChanged = true; | ||
4699 | if (oldFace.Fullbright != newFace.Fullbright) otherFieldsChanged = true; | ||
4700 | if (oldFace.Glow != newFace.Glow) otherFieldsChanged = true; | ||
4701 | if (oldFace.MediaFlags != newFace.MediaFlags) otherFieldsChanged = true; | ||
4702 | if (oldFace.OffsetU != newFace.OffsetU) otherFieldsChanged = true; | ||
4703 | if (oldFace.OffsetV != newFace.OffsetV) otherFieldsChanged = true; | ||
4704 | if (oldFace.RepeatU != newFace.RepeatU) otherFieldsChanged = true; | ||
4705 | if (oldFace.RepeatV != newFace.RepeatV) otherFieldsChanged = true; | ||
4706 | if (oldFace.Rotation != newFace.Rotation) otherFieldsChanged = true; | ||
4707 | if (oldFace.Shiny != newFace.Shiny) otherFieldsChanged = true; | ||
4708 | if (oldFace.TexMapType != newFace.TexMapType) otherFieldsChanged = true; | ||
4709 | } | ||
4283 | } | 4710 | } |
4284 | 4711 | ||
4285 | m_shape.TextureEntry = newTex.GetBytes(); | 4712 | if (changeFlags != 0 || otherFieldsChanged) |
4286 | if (changeFlags != 0) | 4713 | { |
4287 | TriggerScriptChangedEvent(changeFlags); | 4714 | m_shape.TextureEntry = newTex.GetBytes(); |
4288 | UpdateFlag = UpdateRequired.FULL; | 4715 | if (changeFlags != 0) |
4289 | ParentGroup.HasGroupChanged = true; | 4716 | TriggerScriptChangedEvent(changeFlags); |
4717 | UpdateFlag = UpdateRequired.FULL; | ||
4718 | ParentGroup.HasGroupChanged = true; | ||
4290 | 4719 | ||
4291 | //This is madness.. | 4720 | //This is madness.. |
4292 | //ParentGroup.ScheduleGroupForFullUpdate(); | 4721 | //ParentGroup.ScheduleGroupForFullUpdate(); |
4293 | //This is sparta | 4722 | //This is sparta |
4294 | ScheduleFullUpdate(); | 4723 | ScheduleFullUpdate(); |
4724 | } | ||
4295 | } | 4725 | } |
4296 | 4726 | ||
4297 | public void aggregateScriptEvents() | 4727 | public void aggregateScriptEvents() |
@@ -4331,39 +4761,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4331 | objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; | 4761 | objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; |
4332 | } | 4762 | } |
4333 | 4763 | ||
4334 | PhysicsActor pa = PhysActor; | 4764 | SubscribeForCollisionEvents(); |
4335 | |||
4336 | if ( | ||
4337 | ((AggregateScriptEvents & scriptEvents.collision) != 0) || | ||
4338 | ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || | ||
4339 | ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || | ||
4340 | ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || | ||
4341 | ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || | ||
4342 | ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || | ||
4343 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) || | ||
4344 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) || | ||
4345 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) || | ||
4346 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || | ||
4347 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) || | ||
4348 | ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || | ||
4349 | (CollisionSound != UUID.Zero) | ||
4350 | ) | ||
4351 | { | ||
4352 | // subscribe to physics updates. | ||
4353 | if (pa != null) | ||
4354 | { | ||
4355 | pa.OnCollisionUpdate += PhysicsCollision; | ||
4356 | pa.SubscribeEvents(1000); | ||
4357 | } | ||
4358 | } | ||
4359 | else | ||
4360 | { | ||
4361 | if (pa != null) | ||
4362 | { | ||
4363 | pa.UnSubscribeEvents(); | ||
4364 | pa.OnCollisionUpdate -= PhysicsCollision; | ||
4365 | } | ||
4366 | } | ||
4367 | 4765 | ||
4368 | //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) | 4766 | //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) |
4369 | //{ | 4767 | //{ |
@@ -4449,12 +4847,76 @@ namespace OpenSim.Region.Framework.Scenes | |||
4449 | { | 4847 | { |
4450 | ParentGroup.AddScriptLPS(count); | 4848 | ParentGroup.AddScriptLPS(count); |
4451 | } | 4849 | } |
4850 | |||
4851 | /// <summary> | ||
4852 | /// Sets a prim's owner and permissions when it's rezzed. | ||
4853 | /// </summary> | ||
4854 | /// <param name="item">The inventory item from which the item was rezzed</param> | ||
4855 | /// <param name="userInventory">True: the item is being rezzed from the user's inventory. False: from a prim's inventory.</param> | ||
4856 | /// <param name="scene">The scene the prim is being rezzed into</param> | ||
4857 | public void ApplyPermissionsOnRez(InventoryItemBase item, bool userInventory, Scene scene) | ||
4858 | { | ||
4859 | if ((OwnerID != item.Owner) || ((item.CurrentPermissions & SceneObjectGroup.SLAM) != 0) || ((item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)) | ||
4860 | { | ||
4861 | if (scene.Permissions.PropagatePermissions()) | ||
4862 | { | ||
4863 | if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) | ||
4864 | { | ||
4865 | // Apply the item's permissions to the object | ||
4866 | //LogPermissions("Before applying item permissions"); | ||
4867 | if (userInventory) | ||
4868 | { | ||
4869 | EveryoneMask = item.EveryOnePermissions; | ||
4870 | NextOwnerMask = item.NextPermissions; | ||
4871 | } | ||
4872 | else | ||
4873 | { | ||
4874 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) | ||
4875 | EveryoneMask = item.EveryOnePermissions; | ||
4876 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) | ||
4877 | NextOwnerMask = item.NextPermissions; | ||
4878 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) | ||
4879 | GroupMask = item.GroupPermissions; | ||
4880 | } | ||
4881 | //LogPermissions("After applying item permissions"); | ||
4882 | } | ||
4883 | } | ||
4884 | |||
4885 | GroupMask = 0; // DO NOT propagate here | ||
4886 | } | ||
4887 | |||
4888 | if (OwnerID != item.Owner) | ||
4889 | { | ||
4890 | //LogPermissions("Before ApplyNextOwnerPermissions"); | ||
4891 | |||
4892 | if (scene.Permissions.PropagatePermissions()) | ||
4893 | ApplyNextOwnerPermissions(); | ||
4894 | |||
4895 | //LogPermissions("After ApplyNextOwnerPermissions"); | ||
4896 | |||
4897 | LastOwnerID = OwnerID; | ||
4898 | OwnerID = item.Owner; | ||
4899 | Inventory.ChangeInventoryOwner(item.Owner); | ||
4900 | } | ||
4901 | } | ||
4902 | |||
4903 | /// <summary> | ||
4904 | /// Logs the prim's permissions. Useful when debugging permission problems. | ||
4905 | /// </summary> | ||
4906 | /// <param name="message"></param> | ||
4907 | private void LogPermissions(String message) | ||
4908 | { | ||
4909 | PermissionsUtil.LogPermissions(Name, message, BaseMask, OwnerMask, NextOwnerMask); | ||
4910 | } | ||
4452 | 4911 | ||
4453 | public void ApplyNextOwnerPermissions() | 4912 | public void ApplyNextOwnerPermissions() |
4454 | { | 4913 | { |
4455 | BaseMask &= NextOwnerMask; | 4914 | // Export needs to be preserved in the base and everyone |
4915 | // mask, but removed in the owner mask as a next owner | ||
4916 | // can never change the export status | ||
4917 | BaseMask &= NextOwnerMask | (uint)PermissionMask.Export; | ||
4456 | OwnerMask &= NextOwnerMask; | 4918 | OwnerMask &= NextOwnerMask; |
4457 | EveryoneMask &= NextOwnerMask; | 4919 | EveryoneMask &= NextOwnerMask | (uint)PermissionMask.Export; |
4458 | 4920 | ||
4459 | Inventory.ApplyNextOwnerPermissions(); | 4921 | Inventory.ApplyNextOwnerPermissions(); |
4460 | } | 4922 | } |
@@ -4463,20 +4925,34 @@ namespace OpenSim.Region.Framework.Scenes | |||
4463 | { | 4925 | { |
4464 | try | 4926 | try |
4465 | { | 4927 | { |
4466 | if (APIDTarget != Quaternion.Identity) | 4928 | if (APIDActive) |
4467 | { | 4929 | { |
4468 | if (m_APIDIterations <= 1) | 4930 | PhysicsActor pa = ParentGroup.RootPart.PhysActor; |
4931 | if (pa == null || !pa.IsPhysical || APIDStrength < 0.04) | ||
4469 | { | 4932 | { |
4470 | UpdateRotation(APIDTarget); | 4933 | StopLookAt(); |
4471 | APIDTarget = Quaternion.Identity; | ||
4472 | return; | 4934 | return; |
4473 | } | 4935 | } |
4474 | 4936 | ||
4475 | Quaternion rot = Quaternion.Slerp(RotationOffset,APIDTarget,1.0f/(float)m_APIDIterations); | 4937 | Quaternion currRot = GetWorldRotation(); |
4476 | rot.Normalize(); | 4938 | currRot.Normalize(); |
4477 | UpdateRotation(rot); | 4939 | |
4940 | // difference between current orientation and desired orientation | ||
4941 | Quaternion dR = currRot / APIDTarget; | ||
4942 | |||
4943 | // find axis and angle of rotation to rotate to desired orientation | ||
4944 | Vector3 axis = Vector3.UnitX; | ||
4945 | float angle; | ||
4946 | dR.GetAxisAngle(out axis, out angle); | ||
4947 | axis = axis * currRot; | ||
4948 | |||
4949 | // clamp strength to avoid overshoot | ||
4950 | float strength = 1.0f / APIDStrength; | ||
4951 | if (strength > 1.0) strength = 1.0f; | ||
4478 | 4952 | ||
4479 | m_APIDIterations--; | 4953 | // set angular velocity to rotate to desired orientation |
4954 | // with velocity proportional to strength and angle | ||
4955 | AngularVelocity = axis * angle * strength * (float)Math.PI; | ||
4480 | 4956 | ||
4481 | // This ensures that we'll check this object on the next iteration | 4957 | // This ensures that we'll check this object on the next iteration |
4482 | ParentGroup.QueueForUpdateCheck(); | 4958 | ParentGroup.QueueForUpdateCheck(); |
@@ -4502,19 +4978,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
4502 | /// true if the avatar was not already recorded, false otherwise. | 4978 | /// true if the avatar was not already recorded, false otherwise. |
4503 | /// </returns> | 4979 | /// </returns> |
4504 | /// <param name='avatarId'></param> | 4980 | /// <param name='avatarId'></param> |
4505 | protected internal bool AddSittingAvatar(UUID avatarId) | 4981 | protected internal bool AddSittingAvatar(ScenePresence sp) |
4506 | { | 4982 | { |
4507 | lock (ParentGroup.m_sittingAvatars) | 4983 | lock (ParentGroup.m_sittingAvatars) |
4508 | { | 4984 | { |
4509 | if (IsSitTargetSet && SitTargetAvatar == UUID.Zero) | 4985 | if (IsSitTargetSet && SitTargetAvatar == UUID.Zero) |
4510 | SitTargetAvatar = avatarId; | 4986 | SitTargetAvatar = sp.UUID; |
4511 | 4987 | ||
4512 | if (m_sittingAvatars == null) | 4988 | if (m_sittingAvatars == null) |
4513 | m_sittingAvatars = new HashSet<UUID>(); | 4989 | m_sittingAvatars = new HashSet<ScenePresence>(); |
4514 | 4990 | ||
4515 | if (m_sittingAvatars.Add(avatarId)) | 4991 | if (m_sittingAvatars.Add(sp)) |
4516 | { | 4992 | { |
4517 | ParentGroup.m_sittingAvatars.Add(avatarId); | 4993 | ParentGroup.m_sittingAvatars.Add(sp); |
4518 | 4994 | ||
4519 | return true; | 4995 | return true; |
4520 | } | 4996 | } |
@@ -4531,22 +5007,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
4531 | /// true if the avatar was present and removed, false if it was not present. | 5007 | /// true if the avatar was present and removed, false if it was not present. |
4532 | /// </returns> | 5008 | /// </returns> |
4533 | /// <param name='avatarId'></param> | 5009 | /// <param name='avatarId'></param> |
4534 | protected internal bool RemoveSittingAvatar(UUID avatarId) | 5010 | protected internal bool RemoveSittingAvatar(ScenePresence sp) |
4535 | { | 5011 | { |
4536 | lock (ParentGroup.m_sittingAvatars) | 5012 | lock (ParentGroup.m_sittingAvatars) |
4537 | { | 5013 | { |
4538 | if (SitTargetAvatar == avatarId) | 5014 | if (SitTargetAvatar == sp.UUID) |
4539 | SitTargetAvatar = UUID.Zero; | 5015 | SitTargetAvatar = UUID.Zero; |
4540 | 5016 | ||
4541 | if (m_sittingAvatars == null) | 5017 | if (m_sittingAvatars == null) |
4542 | return false; | 5018 | return false; |
4543 | 5019 | ||
4544 | if (m_sittingAvatars.Remove(avatarId)) | 5020 | if (m_sittingAvatars.Remove(sp)) |
4545 | { | 5021 | { |
4546 | if (m_sittingAvatars.Count == 0) | 5022 | if (m_sittingAvatars.Count == 0) |
4547 | m_sittingAvatars = null; | 5023 | m_sittingAvatars = null; |
4548 | 5024 | ||
4549 | ParentGroup.m_sittingAvatars.Remove(avatarId); | 5025 | ParentGroup.m_sittingAvatars.Remove(sp); |
4550 | 5026 | ||
4551 | return true; | 5027 | return true; |
4552 | } | 5028 | } |
@@ -4560,14 +5036,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
4560 | /// </summary> | 5036 | /// </summary> |
4561 | /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks> | 5037 | /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks> |
4562 | /// <returns>A hashset of the sitting avatars. Returns null if there are no sitting avatars.</returns> | 5038 | /// <returns>A hashset of the sitting avatars. Returns null if there are no sitting avatars.</returns> |
4563 | public HashSet<UUID> GetSittingAvatars() | 5039 | public HashSet<ScenePresence> GetSittingAvatars() |
4564 | { | 5040 | { |
4565 | lock (ParentGroup.m_sittingAvatars) | 5041 | lock (ParentGroup.m_sittingAvatars) |
4566 | { | 5042 | { |
4567 | if (m_sittingAvatars == null) | 5043 | if (m_sittingAvatars == null) |
4568 | return null; | 5044 | return null; |
4569 | else | 5045 | else |
4570 | return new HashSet<UUID>(m_sittingAvatars); | 5046 | return new HashSet<ScenePresence>(m_sittingAvatars); |
4571 | } | 5047 | } |
4572 | } | 5048 | } |
4573 | 5049 | ||