Compare commits
	
		
			8 Commits 
		
	
	
		
			master
			...
			slimupdate
		
	
	| Author | SHA1 | Date | 
|---|---|---|
|  John Hurliman | 93469d3d58 | |
|  John Hurliman | 95130df78a | |
|  John Hurliman | d5a5cae58b | |
|  John Hurliman | ce106a0c0b | |
|  John Hurliman | 98a9ae40c5 | |
|  John Hurliman | 91878f79b9 | |
|  John Hurliman | 40df4e7203 | |
|  John Hurliman | 32e9fb2634 | 
|  | @ -1026,28 +1026,17 @@ namespace OpenSim.Client.MXP.ClientStack | |||
|             // Need to translate to MXP somehow | ||||
|         } | ||||
| 
 | ||||
|         public void SendAvatarData(SendAvatarData data) | ||||
|         { | ||||
|             //ScenePresence presence=((Scene)this.Scene).GetScenePresence(avatarID); | ||||
|             UUID ownerID = data.AvatarID; | ||||
|             MXPSendAvatarData(data.FirstName + " " + data.LastName, ownerID, UUID.Zero, data.AvatarID, data.AvatarLocalID, data.Position, data.Rotation); | ||||
|         } | ||||
| 
 | ||||
|         public void SendAvatarTerseUpdate(SendAvatarTerseData data) | ||||
|         { | ||||
|             MovementEventMessage me = new MovementEventMessage(); | ||||
|             me.ObjectIndex = data.LocalID; | ||||
|             me.Location = ToOmVector(data.Position); | ||||
|             me.Orientation = ToOmQuaternion(data.Rotation); | ||||
| 
 | ||||
|             Session.Send(me); | ||||
|         } | ||||
| 
 | ||||
|         public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) | ||||
|         { | ||||
|             // Minimap function, not used. | ||||
|         } | ||||
| 
 | ||||
|         public void SendEntityUpdate(double priority, ISceneEntity entity, PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|             // TODO: Implement this | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||||
|         { | ||||
|             // Need to translate to MXP somehow | ||||
|  | @ -1058,23 +1047,7 @@ namespace OpenSim.Client.MXP.ClientStack | |||
|             // Need to translate to MXP somehow | ||||
|         } | ||||
| 
 | ||||
|         public void SendPrimitiveToClient(SendPrimitiveData data) | ||||
|         { | ||||
|             MXPSendPrimitive(data.localID, data.ownerID, data.acc, data.rvel, data.primShape, data.pos, data.objectID, data.vel, | ||||
|                 data.rotation, (uint)data.flags, data.text, data.color, data.parentID, data.particleSystem, data.clickAction, | ||||
|                 data.material, data.textureanim); | ||||
|         } | ||||
| 
 | ||||
|         public void SendPrimTerseUpdate(SendPrimitiveTerseData data) | ||||
|         { | ||||
|             MovementEventMessage me = new MovementEventMessage(); | ||||
|             me.ObjectIndex = data.LocalID; | ||||
|             me.Location = ToOmVector(data.Position); | ||||
|             me.Orientation = ToOmQuaternion(data.Rotation); | ||||
|             Session.Send(me); | ||||
|         } | ||||
| 
 | ||||
|         public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) | ||||
|         public void ReprioritizeUpdates(UpdatePriorityHandler handler) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -584,21 +584,16 @@ namespace OpenSim.Client.Sirikata.ClientStack | |||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void SendAvatarData(SendAvatarData data) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void SendAvatarTerseUpdate(SendAvatarTerseData data) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void SendEntityUpdate(double priority, ISceneEntity entity, PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|  | @ -609,17 +604,7 @@ namespace OpenSim.Client.Sirikata.ClientStack | |||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void SendPrimitiveToClient(SendPrimitiveData data) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void SendPrimTerseUpdate(SendPrimitiveTerseData data) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) | ||||
|         public void ReprioritizeUpdates(UpdatePriorityHandler handler) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
|  |  | |||
|  | @ -590,21 +590,16 @@ namespace OpenSim.Client.VWoHTTP.ClientStack | |||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void SendAvatarData(SendAvatarData data) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void SendAvatarTerseUpdate(SendAvatarTerseData data) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void SendEntityUpdate(double priority, ISceneEntity entity, PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|  | @ -615,17 +610,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack | |||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void SendPrimitiveToClient(SendPrimitiveData data) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void SendPrimTerseUpdate(SendPrimitiveTerseData data) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
| 
 | ||||
|         public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) | ||||
|         public void ReprioritizeUpdates(UpdatePriorityHandler handler) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
|  |  | |||
|  | @ -245,7 +245,6 @@ namespace OpenSim.Data.Tests | |||
|             pbshap.ProfileEnd = ushort.MaxValue; | ||||
|             pbshap.ProfileHollow = ushort.MaxValue; | ||||
|             Vector3 scale = new Vector3(random.Next(),random.Next(),random.Next()); | ||||
|             byte updatef = (byte) random.Next(127); | ||||
| 
 | ||||
|             RegionInfo regionInfo = new RegionInfo(); | ||||
|             regionInfo.RegionID = region3; | ||||
|  | @ -284,7 +283,6 @@ namespace OpenSim.Data.Tests | |||
|             sop.LinkNum = linknum; | ||||
|             sop.ClickAction = clickaction; | ||||
|             sop.Scale = scale; | ||||
|             sop.UpdateFlag = updatef; | ||||
| 
 | ||||
|             //Tests if local part accepted the parameters: | ||||
|             Assert.That(regionh,Is.EqualTo(sop.RegionHandle), "Assert.That(regionh,Is.EqualTo(sop.RegionHandle))"); | ||||
|  | @ -317,7 +315,6 @@ namespace OpenSim.Data.Tests | |||
|             Assert.That(linknum,Is.EqualTo(sop.LinkNum), "Assert.That(linknum,Is.EqualTo(sop.LinkNum))"); | ||||
|             Assert.That(clickaction,Is.EqualTo(sop.ClickAction), "Assert.That(clickaction,Is.EqualTo(sop.ClickAction))"); | ||||
|             Assert.That(scale,Is.EqualTo(sop.Scale), "Assert.That(scale,Is.EqualTo(sop.Scale))"); | ||||
|             Assert.That(updatef,Is.EqualTo(sop.UpdateFlag), "Assert.That(updatef,Is.EqualTo(sop.UpdateFlag))"); | ||||
|              | ||||
|             // This is necessary or object will not be inserted in DB | ||||
|             sop.ObjectFlags = 0; | ||||
|  | @ -417,7 +414,6 @@ namespace OpenSim.Data.Tests | |||
|             PrimitiveBaseShape pbshap = new PrimitiveBaseShape(); | ||||
|             pbshap = PrimitiveBaseShape.Default; | ||||
|             Vector3 scale = new Vector3(random.Next(),random.Next(),random.Next()); | ||||
|             byte updatef = (byte) random.Next(127); | ||||
|              | ||||
|             // Updates the region with new values | ||||
|             SceneObjectGroup sog2 = FindSOG("Adam  West", region3); | ||||
|  | @ -447,7 +443,6 @@ namespace OpenSim.Data.Tests | |||
|             sog2.RootPart.LinkNum = linknum; | ||||
|             sog2.RootPart.ClickAction = clickaction; | ||||
|             sog2.RootPart.Scale = scale; | ||||
|             sog2.RootPart.UpdateFlag = updatef; | ||||
|              | ||||
|             db.StoreObject(sog2, region3); | ||||
|             List<SceneObjectGroup> sogs = db.LoadObjects(region3); | ||||
|  |  | |||
|  | @ -33,6 +33,52 @@ using OpenMetaverse.Packets; | |||
| 
 | ||||
| namespace OpenSim.Framework | ||||
| { | ||||
|     #region Enums | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// Specifies the fields that have been changed when sending a prim or | ||||
|     /// avatar update | ||||
|     /// </summary> | ||||
|     [Flags] | ||||
|     public enum PrimUpdateFlags : uint | ||||
|     { | ||||
|         None = 0, | ||||
|         AttachmentPoint = 1 << 0, | ||||
|         Material = 1 << 1, | ||||
|         ClickAction = 1 << 2, | ||||
|         Scale = 1 << 3, | ||||
|         ParentID = 1 << 4, | ||||
|         PrimFlags = 1 << 5, | ||||
|         PrimData = 1 << 6, | ||||
|         MediaURL = 1 << 7, | ||||
|         ScratchPad = 1 << 8, | ||||
|         Textures = 1 << 9, | ||||
|         TextureAnim = 1 << 10, | ||||
|         NameValue = 1 << 11, | ||||
|         Position = 1 << 12, | ||||
|         Rotation = 1 << 13, | ||||
|         Velocity = 1 << 14, | ||||
|         Acceleration = 1 << 15, | ||||
|         AngularVelocity = 1 << 16, | ||||
|         CollisionPlane = 1 << 17, | ||||
|         Text = 1 << 18, | ||||
|         Particles = 1 << 19, | ||||
|         ExtraData = 1 << 20, | ||||
|         Sound = 1 << 21, | ||||
|         Joint = 1 << 22, | ||||
|         FullUpdate = UInt32.MaxValue | ||||
|     } | ||||
| 
 | ||||
|     public static class PrimUpdateFlagsExtensions | ||||
|     { | ||||
|         public static bool HasFlag(this PrimUpdateFlags updateFlags, PrimUpdateFlags flag) | ||||
|         { | ||||
|             return (updateFlags & flag) == flag; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #endregion Enums | ||||
| 
 | ||||
|     #region Client API Delegate definitions | ||||
| 
 | ||||
|     public delegate void ViewerEffectEventHandler(IClientAPI sender, List<ViewerEffectEventHandlerArg> args); | ||||
|  | @ -571,207 +617,6 @@ namespace OpenSim.Framework | |||
|         public float dwell; | ||||
|     } | ||||
| 
 | ||||
|     public struct SendAvatarData | ||||
|     { | ||||
|         public readonly ulong RegionHandle; | ||||
|         public readonly string FirstName; | ||||
|         public readonly string LastName; | ||||
|         public readonly string GroupTitle; | ||||
|         public readonly UUID AvatarID; | ||||
|         public readonly uint AvatarLocalID; | ||||
|         public readonly Vector3 Position; | ||||
|         public readonly byte[] TextureEntry; | ||||
|         public readonly uint ParentID; | ||||
|         public readonly Quaternion Rotation; | ||||
| 
 | ||||
|         public SendAvatarData(ulong regionHandle, string firstName, string lastName, string groupTitle, UUID avatarID, | ||||
|             uint avatarLocalID, Vector3 position, byte[] textureEntry, uint parentID, Quaternion rotation) | ||||
|         { | ||||
|             RegionHandle = regionHandle; | ||||
|             FirstName = firstName; | ||||
|             LastName = lastName; | ||||
|             GroupTitle = groupTitle; | ||||
|             AvatarID = avatarID; | ||||
|             AvatarLocalID = avatarLocalID; | ||||
|             Position = position; | ||||
|             TextureEntry = textureEntry; | ||||
|             ParentID = parentID; | ||||
|             Rotation = rotation; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public struct SendAvatarTerseData | ||||
|     { | ||||
|         public readonly ulong RegionHandle; | ||||
|         public readonly ushort TimeDilation; | ||||
|         public readonly uint LocalID; | ||||
|         public readonly Vector3 Position; | ||||
|         public readonly Vector3 Velocity; | ||||
|         public readonly Vector3 Acceleration; | ||||
|         public readonly Quaternion Rotation; | ||||
|         public readonly Vector4 CollisionPlane; | ||||
|         public readonly UUID AgentID; | ||||
|         public readonly byte[] TextureEntry; | ||||
|         public readonly double Priority; | ||||
| 
 | ||||
|         public SendAvatarTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Vector3 velocity, | ||||
|             Vector3 acceleration, Quaternion rotation, Vector4 collisionPlane, UUID agentid, byte[] textureEntry, double priority) | ||||
|         { | ||||
|             RegionHandle = regionHandle; | ||||
|             TimeDilation = timeDilation; | ||||
|             LocalID = localID; | ||||
|             Position = position; | ||||
|             Velocity = velocity; | ||||
|             Acceleration = acceleration; | ||||
|             Rotation = rotation; | ||||
|             CollisionPlane = collisionPlane; | ||||
|             AgentID = agentid; | ||||
|             TextureEntry = textureEntry; | ||||
|             Priority = priority; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public struct SendPrimitiveTerseData | ||||
|     { | ||||
|         public readonly ulong RegionHandle; | ||||
|         public readonly ushort TimeDilation; | ||||
|         public readonly uint LocalID; | ||||
|         public readonly Vector3 Position; | ||||
|         public readonly Quaternion Rotation; | ||||
|         public readonly Vector3 Velocity; | ||||
|         public readonly Vector3 Acceleration; | ||||
|         public readonly Vector3 AngularVelocity; | ||||
|         public readonly UUID AssetID; | ||||
|         public readonly UUID OwnerID; | ||||
|         public readonly int AttachPoint; | ||||
|         public readonly byte[] TextureEntry; | ||||
|         public readonly double Priority; | ||||
| 
 | ||||
|         public SendPrimitiveTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, | ||||
|             Quaternion rotation, Vector3 velocity, Vector3 acceleration, Vector3 rotationalvelocity, | ||||
|             UUID assetID, UUID ownerID, int attachPoint, byte[] textureEntry, double priority) | ||||
|         { | ||||
|             RegionHandle = regionHandle; | ||||
|             TimeDilation = timeDilation; | ||||
|             LocalID = localID; | ||||
|             Position = position; | ||||
|             Rotation = rotation; | ||||
|             Velocity = velocity; | ||||
|             Acceleration = acceleration; | ||||
|             AngularVelocity = rotationalvelocity; | ||||
|             AssetID = assetID; | ||||
|             OwnerID = ownerID; | ||||
|             AttachPoint = attachPoint; | ||||
|             TextureEntry = textureEntry; | ||||
|             Priority = priority; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public struct SendPrimitiveData | ||||
|     { | ||||
|         private ulong m_regionHandle; | ||||
|         private ushort m_timeDilation; | ||||
|         private uint m_localID; | ||||
|         private PrimitiveBaseShape m_primShape; | ||||
|         private Vector3 m_pos; | ||||
|         private Vector3 m_vel; | ||||
|         private Vector3 m_acc; | ||||
|         private Quaternion m_rotation; | ||||
|         private Vector3 m_rvel; | ||||
|         private PrimFlags m_flags; | ||||
|         private UUID m_objectID; | ||||
|         private UUID m_ownerID; | ||||
|         private string m_text; | ||||
|         private byte[] m_color; | ||||
|         private uint m_parentID; | ||||
|         private byte[] m_particleSystem; | ||||
|         private byte m_clickAction; | ||||
|         private byte m_material; | ||||
|         private byte[] m_textureanim; | ||||
|         private bool m_attachment; | ||||
|         private uint m_AttachPoint; | ||||
|         private UUID m_AssetId; | ||||
|         private UUID m_SoundId; | ||||
|         private double m_SoundVolume; | ||||
|         private byte m_SoundFlags; | ||||
|         private double m_SoundRadius; | ||||
|         private double m_priority; | ||||
| 
 | ||||
|         public SendPrimitiveData(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, | ||||
|                                    Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, | ||||
|                                    uint flags, UUID objectID, UUID ownerID, string text, byte[] color, | ||||
|                                    uint parentID, byte[] particleSystem, byte clickAction, byte material, double priority) : | ||||
|             this(regionHandle, timeDilation, localID, primShape, pos, vel, acc, rotation, rvel, flags, objectID, | ||||
|             ownerID, text, color, parentID, particleSystem, clickAction, material, new byte[0], false, 0, UUID.Zero, | ||||
|             UUID.Zero, 0, 0, 0, priority) { } | ||||
| 
 | ||||
|         public SendPrimitiveData(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, | ||||
|                                    Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, | ||||
|                                    uint flags, | ||||
|                                    UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, | ||||
|                                    byte[] particleSystem, | ||||
|                                    byte clickAction, byte material, byte[] textureanim, bool attachment, | ||||
|                                    uint AttachPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags, | ||||
|                                    double SoundRadius, double priority) | ||||
|         { | ||||
|             this.m_regionHandle = regionHandle; | ||||
|             this.m_timeDilation = timeDilation; | ||||
|             this.m_localID = localID; | ||||
|             this.m_primShape = primShape; | ||||
|             this.m_pos = pos; | ||||
|             this.m_vel = vel; | ||||
|             this.m_acc = acc; | ||||
|             this.m_rotation = rotation; | ||||
|             this.m_rvel = rvel; | ||||
|             this.m_flags = (PrimFlags)flags; | ||||
|             this.m_objectID = objectID; | ||||
|             this.m_ownerID = ownerID; | ||||
|             this.m_text = text; | ||||
|             this.m_color = color; | ||||
|             this.m_parentID = parentID; | ||||
|             this.m_particleSystem = particleSystem; | ||||
|             this.m_clickAction = clickAction; | ||||
|             this.m_material = material; | ||||
|             this.m_textureanim = textureanim; | ||||
|             this.m_attachment = attachment; | ||||
|             this.m_AttachPoint = AttachPoint; | ||||
|             this.m_AssetId = AssetId; | ||||
|             this.m_SoundId = SoundId; | ||||
|             this.m_SoundVolume = SoundVolume; | ||||
|             this.m_SoundFlags = SoundFlags; | ||||
|             this.m_SoundRadius = SoundRadius; | ||||
|             this.m_priority = priority; | ||||
|         } | ||||
| 
 | ||||
|         public ulong regionHandle { get { return this.m_regionHandle; } } | ||||
|         public ushort timeDilation { get { return this.m_timeDilation; } } | ||||
|         public uint localID { get { return this.m_localID; } } | ||||
|         public PrimitiveBaseShape primShape { get { return this.m_primShape; } } | ||||
|         public Vector3 pos { get { return this.m_pos; } } | ||||
|         public Vector3 vel { get { return this.m_vel; } } | ||||
|         public Vector3 acc { get { return this.m_acc; } } | ||||
|         public Quaternion rotation { get { return this.m_rotation; } } | ||||
|         public Vector3 rvel { get { return this.m_rvel; } } | ||||
|         public PrimFlags flags { get { return this.m_flags; } } | ||||
|         public UUID objectID { get { return this.m_objectID; } } | ||||
|         public UUID ownerID { get { return this.m_ownerID; } } | ||||
|         public string text { get { return this.m_text; } } | ||||
|         public byte[] color { get { return this.m_color; } } | ||||
|         public uint parentID { get { return this.m_parentID; } } | ||||
|         public byte[] particleSystem { get { return this.m_particleSystem; } } | ||||
|         public byte clickAction { get { return this.m_clickAction; } } | ||||
|         public byte material { get { return this.m_material; } } | ||||
|         public byte[] textureanim { get { return this.m_textureanim; } } | ||||
|         public bool attachment { get { return this.m_attachment; } } | ||||
|         public uint AttachPoint { get { return this.m_AttachPoint; } } | ||||
|         public UUID AssetId { get { return this.m_AssetId; } } | ||||
|         public UUID SoundId { get { return this.m_SoundId; } } | ||||
|         public double SoundVolume { get { return this.m_SoundVolume; } } | ||||
|         public byte SoundFlags { get { return this.m_SoundFlags; } } | ||||
|         public double SoundRadius { get { return this.m_SoundRadius; } } | ||||
|         public double priority { get { return this.m_priority; } } | ||||
|     } | ||||
| 
 | ||||
|     public struct UpdatePriorityData { | ||||
|         private double m_priority; | ||||
|         private uint m_localID; | ||||
|  | @ -785,16 +630,6 @@ namespace OpenSim.Framework | |||
|         public uint localID { get { return this.m_localID; } } | ||||
|     } | ||||
| 
 | ||||
|     [Flags] | ||||
|     public enum StateUpdateTypes | ||||
|     { | ||||
|         None = 0, | ||||
|         AvatarTerse = 1, | ||||
|         PrimitiveTerse = AvatarTerse << 1, | ||||
|         PrimitiveFull = PrimitiveTerse << 1, | ||||
|         All = AvatarTerse | PrimitiveTerse | PrimitiveFull, | ||||
|     } | ||||
| 
 | ||||
|     public interface IClientAPI | ||||
|     { | ||||
|         Vector3 StartPos { get; set; } | ||||
|  | @ -1186,20 +1021,14 @@ namespace OpenSim.Framework | |||
|         void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance); | ||||
|         void SendPayPrice(UUID objectID, int[] payPrice); | ||||
| 
 | ||||
|         void SendAvatarData(SendAvatarData data); | ||||
| 
 | ||||
|         void SendAvatarTerseUpdate(SendAvatarTerseData data); | ||||
| 
 | ||||
|         void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations); | ||||
| 
 | ||||
|         void SendEntityUpdate(double priority, ISceneEntity entity, PrimUpdateFlags updateFlags); | ||||
| 
 | ||||
|         void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID); | ||||
|         void SetChildAgentThrottle(byte[] throttle); | ||||
| 
 | ||||
|         void SendPrimitiveToClient(SendPrimitiveData data); | ||||
| 
 | ||||
|         void SendPrimTerseUpdate(SendPrimitiveTerseData data); | ||||
| 
 | ||||
|         void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler); | ||||
|         void ReprioritizeUpdates(UpdatePriorityHandler handler); | ||||
| 
 | ||||
|         void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, | ||||
|                                         List<InventoryFolderBase> folders, int version, bool fetchFolders, | ||||
|  |  | |||
|  | @ -0,0 +1,40 @@ | |||
| /* | ||||
|  * Copyright (c) Contributors, http://opensimulator.org/ | ||||
|  * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions are met: | ||||
|  *     * Redistributions of source code must retain the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer. | ||||
|  *     * Redistributions in binary form must reproduce the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer in the | ||||
|  *       documentation and/or other materials provided with the distribution. | ||||
|  *     * Neither the name of the OpenSimulator Project nor the | ||||
|  *       names of its contributors may be used to endorse or promote products | ||||
|  *       derived from this software without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||||
|  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
|  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||||
|  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
|  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
|  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
|  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
|  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Net; | ||||
| using OpenMetaverse; | ||||
| using OpenMetaverse.Packets; | ||||
| 
 | ||||
| namespace OpenSim.Framework | ||||
| { | ||||
|     public interface ISceneEntity | ||||
|     { | ||||
|         uint LocalId { get; } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,236 @@ | |||
| // | ||||
| // Lazy.cs | ||||
| // | ||||
| // Authors: | ||||
| //  Zoltan Varga (vargaz@gmail.com) | ||||
| //  Marek Safar (marek.safar@gmail.com) | ||||
| // | ||||
| // Copyright (C) 2009 Novell | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person obtaining | ||||
| // a copy of this software and associated documentation files (the | ||||
| // "Software"), to deal in the Software without restriction, including | ||||
| // without limitation the rights to use, copy, modify, merge, publish, | ||||
| // distribute, sublicense, and/or sell copies of the Software, and to | ||||
| // permit persons to whom the Software is furnished to do so, subject to | ||||
| // the following conditions: | ||||
| //  | ||||
| // The above copyright notice and this permission notice shall be | ||||
| // included in all copies or substantial portions of the Software. | ||||
| //  | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
| // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||
| // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||||
| // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||||
| // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
| // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
| // | ||||
| 
 | ||||
| using System; | ||||
| using System.Runtime.Serialization; | ||||
| using System.Runtime.InteropServices; | ||||
| using System.Security.Permissions; | ||||
| using System.Threading; | ||||
| using System.Diagnostics; | ||||
| 
 | ||||
| namespace OpenSim.Framework | ||||
| { | ||||
|     public enum LazyThreadSafetyMode | ||||
|     { | ||||
|         None, | ||||
|         PublicationOnly, | ||||
|         ExecutionAndPublication | ||||
|     } | ||||
| 
 | ||||
|     [SerializableAttribute] | ||||
|     [ComVisibleAttribute(false)] | ||||
|     [HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)] | ||||
|     public class Lazy<T> | ||||
|     { | ||||
|         T value; | ||||
|         bool inited; | ||||
|         LazyThreadSafetyMode mode; | ||||
|         Func<T> factory; | ||||
|         object monitor; | ||||
|         Exception exception; | ||||
| 
 | ||||
|         public Lazy() | ||||
|             : this(LazyThreadSafetyMode.ExecutionAndPublication) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public Lazy(Func<T> valueFactory) | ||||
|             : this(valueFactory, LazyThreadSafetyMode.ExecutionAndPublication) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public Lazy(bool isThreadSafe) | ||||
|             : this(() => Activator.CreateInstance<T>(), isThreadSafe ? LazyThreadSafetyMode.ExecutionAndPublication : LazyThreadSafetyMode.None) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public Lazy(Func<T> valueFactory, bool isThreadSafe) | ||||
|             : this(valueFactory, isThreadSafe ? LazyThreadSafetyMode.ExecutionAndPublication : LazyThreadSafetyMode.None) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public Lazy(LazyThreadSafetyMode mode) | ||||
|             : this(() => Activator.CreateInstance<T>(), mode) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public Lazy(Func<T> valueFactory, LazyThreadSafetyMode mode) | ||||
|         { | ||||
|             if (valueFactory == null) | ||||
|                 throw new ArgumentNullException("valueFactory"); | ||||
|             this.factory = valueFactory; | ||||
|             if (mode != LazyThreadSafetyMode.None) | ||||
|                 monitor = new object(); | ||||
|             this.mode = mode; | ||||
|         } | ||||
| 
 | ||||
|         // Don't trigger expensive initialization | ||||
|         [DebuggerBrowsable(DebuggerBrowsableState.Never)] | ||||
|         public T Value | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if (inited) | ||||
|                     return value; | ||||
|                 if (exception != null) | ||||
|                     throw exception; | ||||
| 
 | ||||
|                 return InitValue(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         T InitValue() | ||||
|         { | ||||
|             switch (mode) | ||||
|             { | ||||
|                 case LazyThreadSafetyMode.None: | ||||
|                 { | ||||
|                     var init_factory = factory; | ||||
|                     if (init_factory == null) | ||||
|                         throw exception = new InvalidOperationException("The initialization function tries to access Value on this instance"); | ||||
|                     try | ||||
|                     { | ||||
|                         factory = null; | ||||
|                         T v = init_factory(); | ||||
|                         value = v; | ||||
|                         Thread.MemoryBarrier(); | ||||
|                         inited = true; | ||||
|                     } | ||||
|                     catch (Exception ex) | ||||
|                     { | ||||
|                         exception = ex; | ||||
|                         throw; | ||||
|                     } | ||||
|                     break; | ||||
|                 } | ||||
|                 case LazyThreadSafetyMode.PublicationOnly: | ||||
|                 { | ||||
|                     var init_factory = factory; | ||||
|                     T v; | ||||
| 
 | ||||
|                     //exceptions are ignored | ||||
|                     if (init_factory != null) | ||||
|                         v = init_factory(); | ||||
|                     else | ||||
|                         v = default(T); | ||||
| 
 | ||||
|                     lock (monitor) | ||||
|                     { | ||||
|                         if (inited) | ||||
|                             return value; | ||||
|                         value = v; | ||||
|                         Thread.MemoryBarrier(); | ||||
|                         inited = true; | ||||
|                         factory = null; | ||||
|                     } | ||||
|                     break; | ||||
|                 } | ||||
|                 case LazyThreadSafetyMode.ExecutionAndPublication: | ||||
|                 { | ||||
|                     lock (monitor) | ||||
|                     { | ||||
|                         if (inited) | ||||
|                             return value; | ||||
| 
 | ||||
|                         if (factory == null) | ||||
|                             throw exception = new InvalidOperationException("The initialization function tries to access Value on this instance"); | ||||
| 
 | ||||
|                         var init_factory = factory; | ||||
|                         try | ||||
|                         { | ||||
|                             factory = null; | ||||
|                             T v = init_factory(); | ||||
|                             value = v; | ||||
|                             Thread.MemoryBarrier(); | ||||
|                             inited = true; | ||||
|                         } | ||||
|                         catch (Exception ex) | ||||
|                         { | ||||
|                             exception = ex; | ||||
|                             throw; | ||||
|                         } | ||||
|                     } | ||||
|                     break; | ||||
|                 } | ||||
|                 default: | ||||
|                     throw new InvalidOperationException("Invalid LazyThreadSafetyMode " + mode); | ||||
|             } | ||||
| 
 | ||||
|             if (monitor == null) | ||||
|             { | ||||
|                 value = factory(); | ||||
|                 inited = true; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 lock (monitor) | ||||
|                 { | ||||
|                     if (inited) | ||||
|                         return value; | ||||
| 
 | ||||
|                     if (factory == null) | ||||
|                         throw new InvalidOperationException("The initialization function tries to access Value on this instance"); | ||||
| 
 | ||||
|                     var init_factory = factory; | ||||
|                     try | ||||
|                     { | ||||
|                         factory = null; | ||||
|                         T v = init_factory(); | ||||
|                         value = v; | ||||
|                         Thread.MemoryBarrier(); | ||||
|                         inited = true; | ||||
|                     } | ||||
|                     catch | ||||
|                     { | ||||
|                         factory = init_factory; | ||||
|                         throw; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return value; | ||||
|         } | ||||
| 
 | ||||
|         public bool IsValueCreated | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 return inited; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public override string ToString() | ||||
|         { | ||||
|             if (inited) | ||||
|                 return value.ToString(); | ||||
|             else | ||||
|                 return "Value is not created"; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -40,6 +40,39 @@ using OpenMetaverse.StructuredData; | |||
| 
 | ||||
| namespace OpenSim.Framework | ||||
| { | ||||
|     /// <summary> | ||||
|     /// A generic HTTP request handler | ||||
|     /// </summary> | ||||
|     public class HttpStreamHandler : IStreamHandler | ||||
|     { | ||||
|         public delegate void HttpStreamCallback(OSHttpRequest httpRequest, OSHttpResponse httpResponse); | ||||
| 
 | ||||
|         private string m_contentType; | ||||
|         private string m_httpMethod; | ||||
|         private string m_path; | ||||
|         private HttpStreamCallback m_callback; | ||||
| 
 | ||||
|         public string ContentType { get { return m_contentType; } } | ||||
|         public string HttpMethod { get { return m_httpMethod; } } | ||||
|         public string Path { get { return m_path; } } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Constructor | ||||
|         /// </summary> | ||||
|         public HttpStreamHandler(string contentType, string httpMethod, string path, HttpStreamCallback callback) | ||||
|         { | ||||
|             m_contentType = contentType; | ||||
|             m_httpMethod = httpMethod; | ||||
|             m_path = path; | ||||
|             m_callback = callback; | ||||
|         } | ||||
| 
 | ||||
|         public void Handle(string path, Stream request, Stream response, OSHttpRequest httpRequest, OSHttpResponse httpResponse) | ||||
|         { | ||||
|             m_callback(httpRequest, httpResponse); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// Miscellaneous static methods and extension methods related to the web | ||||
|     /// </summary> | ||||
|  | @ -176,6 +209,16 @@ namespace OpenSim.Framework | |||
|             return new OSDMap { { "Message", OSD.FromString("Service request failed. " + errorMessage) } }; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Encodes a URL string | ||||
|         /// </summary> | ||||
|         /// <param name="str">Unencoded string to encode</param> | ||||
|         /// <returns>URL-encoded string</returns> | ||||
|         public static string UrlEncode(string str) | ||||
|         { | ||||
|             return HttpUtility.UrlEncode(str).Replace("+", "%20"); | ||||
|         } | ||||
| 
 | ||||
|         #region Uri | ||||
| 
 | ||||
|         /// <summary> | ||||
|  |  | |||
|  | @ -50,43 +50,17 @@ using Nini.Config; | |||
| 
 | ||||
| namespace OpenSim.Region.ClientStack.LindenUDP | ||||
| { | ||||
|     #region Enums | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// Specifies the fields that have been changed when sending a prim or | ||||
|     /// avatar update | ||||
|     /// </summary> | ||||
|     [Flags] | ||||
|     public enum PrimUpdateFlags : uint | ||||
|     public class EntityUpdate | ||||
|     { | ||||
|         None = 0, | ||||
|         AttachmentPoint = 1 << 0, | ||||
|         Material = 1 << 1, | ||||
|         ClickAction = 1 << 2, | ||||
|         Scale = 1 << 3, | ||||
|         ParentID = 1 << 4, | ||||
|         PrimFlags = 1 << 5, | ||||
|         PrimData = 1 << 6, | ||||
|         MediaURL = 1 << 7, | ||||
|         ScratchPad = 1 << 8, | ||||
|         Textures = 1 << 9, | ||||
|         TextureAnim = 1 << 10, | ||||
|         NameValue = 1 << 11, | ||||
|         Position = 1 << 12, | ||||
|         Rotation = 1 << 13, | ||||
|         Velocity = 1 << 14, | ||||
|         Acceleration = 1 << 15, | ||||
|         AngularVelocity = 1 << 16, | ||||
|         CollisionPlane = 1 << 17, | ||||
|         Text = 1 << 18, | ||||
|         Particles = 1 << 19, | ||||
|         ExtraData = 1 << 20, | ||||
|         Sound = 1 << 21, | ||||
|         Joint = 1 << 22, | ||||
|         FullUpdate = UInt32.MaxValue | ||||
|     } | ||||
|         public ISceneEntity Entity; | ||||
|         public PrimUpdateFlags Flags; | ||||
| 
 | ||||
|     #endregion Enums | ||||
|         public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags) | ||||
|         { | ||||
|             Entity = entity; | ||||
|             Flags = flags; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public delegate bool PacketMethod(IClientAPI simClient, Packet packet); | ||||
| 
 | ||||
|  | @ -350,9 +324,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         private readonly IGroupsModule m_GroupsModule; | ||||
| 
 | ||||
|         private int m_cachedTextureSerial; | ||||
|         protected PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates; | ||||
|         private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates; | ||||
|         private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates; | ||||
|         protected PriorityQueue<double, EntityUpdate> m_entityUpdates; | ||||
| 
 | ||||
|         /// <value> | ||||
|         /// List used in construction of data blocks for an object update packet.  This is to stop us having to | ||||
|  | @ -365,7 +337,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         /// thread servicing the m_primFullUpdates queue after a kill.  If this happens the object persists as an | ||||
|         /// ownerless phantom. | ||||
|         /// | ||||
|         /// All manipulation of this set has to occur under a m_primFullUpdate.SyncRoot lock | ||||
|         /// All manipulation of this set has to occur under a m_entityUpdates.SyncRoot lock | ||||
|         ///        | ||||
|         /// </value> | ||||
|         protected HashSet<uint> m_killRecord; | ||||
|  | @ -463,9 +435,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
| 
 | ||||
|             m_scene = scene; | ||||
| 
 | ||||
|             m_avatarTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | ||||
|             m_primTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | ||||
|             m_primFullUpdates = new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>(m_scene.Entities.Count); | ||||
|             m_entityUpdates = new PriorityQueue<double, EntityUpdate>(m_scene.Entities.Count); | ||||
|             m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); | ||||
|             m_killRecord = new HashSet<uint>(); | ||||
| 
 | ||||
|  | @ -1519,7 +1489,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             kill.Header.Reliable = true; | ||||
|             kill.Header.Zerocoded = true; | ||||
| 
 | ||||
|             lock (m_primFullUpdates.SyncRoot) | ||||
|             lock (m_entityUpdates.SyncRoot) | ||||
|             { | ||||
|                 m_killRecord.Add(localID); | ||||
|                 OutPacket(kill, ThrottleOutPacketType.State); | ||||
|  | @ -3414,76 +3384,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
| 
 | ||||
|         #endregion | ||||
| 
 | ||||
|         #region Avatar Packet/Data Sending Methods | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Send an ObjectUpdate packet with information about an avatar | ||||
|         /// </summary> | ||||
|         public void SendAvatarData(SendAvatarData data) | ||||
|         { | ||||
|             ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | ||||
|             objupdate.Header.Zerocoded = true; | ||||
| 
 | ||||
|             objupdate.RegionData.RegionHandle = data.RegionHandle; | ||||
|             objupdate.RegionData.TimeDilation = ushort.MaxValue; | ||||
| 
 | ||||
|             objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||||
|             objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data); | ||||
| 
 | ||||
|             OutPacket(objupdate, ThrottleOutPacketType.Task); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Send a terse positional/rotation/velocity update about an avatar | ||||
|         /// to the client.  This avatar can be that of the client itself. | ||||
|         /// </summary> | ||||
|         public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) | ||||
|         { | ||||
|             if (data.Priority == double.NaN) | ||||
|             { | ||||
|                 m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             Quaternion rotation = data.Rotation; | ||||
|             if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) | ||||
|                 rotation = Quaternion.Identity; | ||||
| 
 | ||||
|             ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateImprovedTerseBlock(data); | ||||
| 
 | ||||
|             lock (m_avatarTerseUpdates.SyncRoot) | ||||
|                 m_avatarTerseUpdates.Enqueue(data.Priority, terseBlock, data.LocalID); | ||||
| 
 | ||||
|             // If we received an update about our own avatar, process the avatar update priority queue immediately | ||||
|             if (data.AgentID == m_agentId) | ||||
|                 ProcessAvatarTerseUpdates(); | ||||
|         } | ||||
| 
 | ||||
|         protected void ProcessAvatarTerseUpdates() | ||||
|         { | ||||
|             ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); | ||||
|             terse.Header.Reliable = false; | ||||
|             terse.Header.Zerocoded = true; | ||||
| 
 | ||||
|             //terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock(); | ||||
|             terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; | ||||
|             terse.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); | ||||
| 
 | ||||
|             lock (m_avatarTerseUpdates.SyncRoot) | ||||
|             { | ||||
|                 int count = Math.Min(m_avatarTerseUpdates.Count, m_udpServer.AvatarTerseUpdatesPerPacket); | ||||
|                 if (count == 0) | ||||
|                     return; | ||||
| 
 | ||||
|                 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; | ||||
|                 for (int i = 0; i < count; i++) | ||||
|                     terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); | ||||
|             } | ||||
| 
 | ||||
|             // HACK: Using the task category until the tiered reprioritization code is in | ||||
|             OutPacket(terse, ThrottleOutPacketType.Task); | ||||
|         } | ||||
| 
 | ||||
|         public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) | ||||
|         { | ||||
|             if (!IsActive) return; // We don't need to update inactive clients. | ||||
|  | @ -3524,176 +3424,182 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             OutPacket(loc, ThrottleOutPacketType.Task); | ||||
|         } | ||||
| 
 | ||||
|         #endregion Avatar Packet/Data Sending Methods | ||||
| 
 | ||||
|         #region Primitive Packet/Data Sending Methods | ||||
| 
 | ||||
|         public void SendPrimitiveToClient(SendPrimitiveData data) | ||||
|         /// <summary> | ||||
|         /// Generate one of the object update packets based on PrimUpdateFlags  | ||||
|         /// and broadcast the packet to clients | ||||
|         /// </summary> | ||||
|         public void SendEntityUpdate(double priority, ISceneEntity entity, PrimUpdateFlags updateFlags) | ||||
|         { | ||||
| //            string text = data.text; | ||||
| //            if (text.IndexOf("\n") >= 0) | ||||
| //                text = text.Remove(text.IndexOf("\n")); | ||||
| //            m_log.DebugFormat( | ||||
| //                "[CLIENT]: Placing request to send full info about prim {0} text {1} to client {2}",  | ||||
| //                data.localID, text, Name); | ||||
|              | ||||
|             if (data.priority == double.NaN) | ||||
|             { | ||||
|                 m_log.Error("[LLClientView] SendPrimitiveToClient received a NaN priority, dropping update"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             Quaternion rotation = data.rotation; | ||||
|             if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) | ||||
|                 rotation = Quaternion.Identity; | ||||
| 
 | ||||
|             if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD | ||||
|                 return; | ||||
|             if (data.primShape.State != 0 && data.parentID == 0 && data.primShape.PCode == 9) | ||||
|                 return; | ||||
| 
 | ||||
|             ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data); | ||||
| 
 | ||||
|             lock (m_primFullUpdates.SyncRoot) | ||||
|                 m_primFullUpdates.Enqueue(data.priority, objectData, data.localID); | ||||
|             lock (m_entityUpdates.SyncRoot) | ||||
|                 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags), entity.LocalId); | ||||
|         } | ||||
| 
 | ||||
|         void ProcessPrimFullUpdates() | ||||
|         private void ProcessEntityUpdates(int maxUpdates) | ||||
|         { | ||||
|             ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | ||||
|             outPacket.Header.Zerocoded = true; | ||||
|             Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); | ||||
|             Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>(); | ||||
|             Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); | ||||
| 
 | ||||
|             outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; | ||||
|             outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); | ||||
|             int updatesThisCall = 0; | ||||
| 
 | ||||
|             lock (m_primFullUpdates.SyncRoot) | ||||
|             lock (m_entityUpdates.SyncRoot) | ||||
|             { | ||||
|                 int count = Math.Min(m_primFullUpdates.Count, m_udpServer.PrimFullUpdatesPerPacket); | ||||
|                 if (count == 0) | ||||
|                     return; | ||||
|                 EntityUpdate update; | ||||
| 
 | ||||
|                 m_fullUpdateDataBlocksBuilder.Clear(); | ||||
|                                  | ||||
|                 for (int i = 0; i < count; i++) | ||||
|                 while ((update = m_entityUpdates.Dequeue()) != null) | ||||
|                 { | ||||
|                     ObjectUpdatePacket.ObjectDataBlock block = m_primFullUpdates.Dequeue(); | ||||
|                     #region UpdateFlags to packet type conversion | ||||
| 
 | ||||
|                     if (!m_killRecord.Contains(block.ID)) | ||||
|                     PrimUpdateFlags updateFlags = update.Flags; | ||||
| 
 | ||||
|                     bool canUseCompressed = true; | ||||
|                     bool canUseImproved = true; | ||||
| 
 | ||||
|                     // Compressed object updates only make sense for LL primitives | ||||
|                     if (!(update.Entity is SceneObjectPart)) | ||||
|                         canUseCompressed = false; | ||||
| 
 | ||||
|                     if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) | ||||
|                     { | ||||
|                         m_fullUpdateDataBlocksBuilder.Add(block); | ||||
|                          | ||||
| //                    string text = Util.FieldToString(outPacket.ObjectData[i].Text); | ||||
| //                    if (text.IndexOf("\n") >= 0) | ||||
| //                        text = text.Remove(text.IndexOf("\n")); | ||||
| //                    m_log.DebugFormat( | ||||
| //                        "[CLIENT]: Sending full info about prim {0} text {1} to client {2}",  | ||||
| //                        outPacket.ObjectData[i].ID, text, Name); | ||||
|                         canUseCompressed = false; | ||||
|                         canUseImproved = false; | ||||
|                     } | ||||
| //                    else | ||||
| //                    { | ||||
| //                        m_log.WarnFormat( | ||||
| //                            "[CLIENT]: Preventing full update for {0} after kill to {1}", block.ID, Name);                         | ||||
| //                    } | ||||
|                     else | ||||
|                     { | ||||
|                         if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || | ||||
|                             updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || | ||||
|                             updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) || | ||||
|                             updateFlags.HasFlag(PrimUpdateFlags.Joint)) | ||||
|                         { | ||||
|                             canUseCompressed = false; | ||||
|                         } | ||||
| 
 | ||||
|                         if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) || | ||||
|                             updateFlags.HasFlag(PrimUpdateFlags.ParentID) || | ||||
|                             updateFlags.HasFlag(PrimUpdateFlags.Scale) || | ||||
|                             updateFlags.HasFlag(PrimUpdateFlags.PrimData) || | ||||
|                             updateFlags.HasFlag(PrimUpdateFlags.Text) || | ||||
|                             updateFlags.HasFlag(PrimUpdateFlags.NameValue) || | ||||
|                             updateFlags.HasFlag(PrimUpdateFlags.ExtraData) || | ||||
|                             updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) || | ||||
|                             updateFlags.HasFlag(PrimUpdateFlags.Sound) || | ||||
|                             updateFlags.HasFlag(PrimUpdateFlags.Particles) || | ||||
|                             updateFlags.HasFlag(PrimUpdateFlags.Material) || | ||||
|                             updateFlags.HasFlag(PrimUpdateFlags.ClickAction) || | ||||
|                             updateFlags.HasFlag(PrimUpdateFlags.MediaURL) || | ||||
|                             updateFlags.HasFlag(PrimUpdateFlags.Joint)) | ||||
|                         { | ||||
|                             canUseImproved = false; | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     #endregion UpdateFlags to packet type conversion | ||||
| 
 | ||||
|                     #region Block Construction | ||||
| 
 | ||||
|                     // TODO: Remove this once we can build compressed updates | ||||
|                     canUseCompressed = false; | ||||
| 
 | ||||
|                     if (!canUseImproved && !canUseCompressed) | ||||
|                     { | ||||
|                         if (update.Entity is ScenePresence) | ||||
|                             objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); | ||||
|                         else | ||||
|                             objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); | ||||
|                     } | ||||
|                     else if (!canUseImproved) | ||||
|                     { | ||||
|                         compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); | ||||
|                     } | ||||
| 
 | ||||
|                     #endregion Block Construction | ||||
| 
 | ||||
|                     ++updatesThisCall; | ||||
|                     if (maxUpdates > 0 && updatesThisCall >= maxUpdates) | ||||
|                         break; | ||||
|                 } | ||||
| 
 | ||||
|                 outPacket.ObjectData = m_fullUpdateDataBlocksBuilder.ToArray(); | ||||
|                  | ||||
|                 OutPacket(outPacket, ThrottleOutPacketType.State); | ||||
|             }             | ||||
|         } | ||||
| 
 | ||||
|         public void SendPrimTerseUpdate(SendPrimitiveTerseData data) | ||||
|         { | ||||
|             if (data.Priority == double.NaN) | ||||
|             { | ||||
|                 m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             Quaternion rotation = data.Rotation; | ||||
|             if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) | ||||
|                 rotation = Quaternion.Identity; | ||||
|             #region Packet Sending | ||||
| 
 | ||||
|             if (data.AttachPoint > 30 && data.OwnerID != AgentId) // Someone else's HUD | ||||
|                 return; | ||||
|             const float TIME_DILATION = 1.0f; | ||||
|             ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); | ||||
| 
 | ||||
|             ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = CreateImprovedTerseBlock(data); | ||||
| 
 | ||||
|             lock (m_primTerseUpdates.SyncRoot) | ||||
|                 m_primTerseUpdates.Enqueue(data.Priority, objectData, data.LocalID); | ||||
|         } | ||||
| 
 | ||||
|         void ProcessPrimTerseUpdates() | ||||
|         { | ||||
|             ImprovedTerseObjectUpdatePacket outPacket = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); | ||||
|             outPacket.Header.Reliable = false; | ||||
|             outPacket.Header.Zerocoded = true; | ||||
| 
 | ||||
|             outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; | ||||
|             outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); | ||||
| 
 | ||||
|             lock (m_primTerseUpdates.SyncRoot) | ||||
|             if (objectUpdateBlocks.IsValueCreated) | ||||
|             { | ||||
|                 int count = Math.Min(m_primTerseUpdates.Count, m_udpServer.PrimTerseUpdatesPerPacket); | ||||
|                 if (count == 0) | ||||
|                     return; | ||||
|                 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; | ||||
| 
 | ||||
|                 outPacket.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; | ||||
|                 for (int i = 0; i < count; i++) | ||||
|                     outPacket.ObjectData[i] = m_primTerseUpdates.Dequeue(); | ||||
|                 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | ||||
|                 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | ||||
|                 packet.RegionData.TimeDilation = timeDilation; | ||||
|                 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; | ||||
| 
 | ||||
|                 for (int i = 0; i < blocks.Count; i++) | ||||
|                     packet.ObjectData[i] = blocks[i]; | ||||
| 
 | ||||
|                 OutPacket(packet, ThrottleOutPacketType.Task, true); | ||||
|             } | ||||
| 
 | ||||
|             OutPacket(outPacket, ThrottleOutPacketType.State); | ||||
|             if (compressedUpdateBlocks.IsValueCreated) | ||||
|             { | ||||
|                 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; | ||||
| 
 | ||||
|                 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); | ||||
|                 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | ||||
|                 packet.RegionData.TimeDilation = timeDilation; | ||||
|                 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; | ||||
| 
 | ||||
|                 for (int i = 0; i < blocks.Count; i++) | ||||
|                     packet.ObjectData[i] = blocks[i]; | ||||
| 
 | ||||
|                 OutPacket(packet, ThrottleOutPacketType.Task, true); | ||||
|             } | ||||
| 
 | ||||
|             if (terseUpdateBlocks.IsValueCreated) | ||||
|             { | ||||
|                 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; | ||||
| 
 | ||||
|                 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); | ||||
|                 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | ||||
|                 packet.RegionData.TimeDilation = timeDilation; | ||||
|                 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; | ||||
| 
 | ||||
|                 for (int i = 0; i < blocks.Count; i++) | ||||
|                     packet.ObjectData[i] = blocks[i]; | ||||
| 
 | ||||
|                 OutPacket(packet, ThrottleOutPacketType.Task, true); | ||||
|             } | ||||
| 
 | ||||
|             #endregion Packet Sending | ||||
|         } | ||||
| 
 | ||||
|         public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) | ||||
|         public void ReprioritizeUpdates(UpdatePriorityHandler handler) | ||||
|         { | ||||
|             PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler terse_update_priority_handler = | ||||
|                 delegate(ref double priority, uint local_id) | ||||
|                 { | ||||
|                     priority = handler(new UpdatePriorityData(priority, local_id)); | ||||
|                     return priority != double.NaN; | ||||
|                 }; | ||||
|             PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler update_priority_handler = | ||||
|             //m_log.Debug("[CLIENT]: Reprioritizing prim updates for " + m_firstName + " " + m_lastName); | ||||
| 
 | ||||
|             PriorityQueue<double, EntityUpdate>.UpdatePriorityHandler update_priority_handler = | ||||
|                 delegate(ref double priority, uint local_id) | ||||
|                 { | ||||
|                     priority = handler(new UpdatePriorityData(priority, local_id)); | ||||
|                     return priority != double.NaN; | ||||
|                 }; | ||||
| 
 | ||||
|             if ((type & StateUpdateTypes.AvatarTerse) != 0) | ||||
|             { | ||||
|                 lock (m_avatarTerseUpdates.SyncRoot) | ||||
|                     m_avatarTerseUpdates.Reprioritize(terse_update_priority_handler); | ||||
|             } | ||||
| 
 | ||||
|             if ((type & StateUpdateTypes.PrimitiveFull) != 0) | ||||
|             { | ||||
|                 lock (m_primFullUpdates.SyncRoot) | ||||
|                     m_primFullUpdates.Reprioritize(update_priority_handler); | ||||
|             } | ||||
| 
 | ||||
|             if ((type & StateUpdateTypes.PrimitiveTerse) != 0) | ||||
|             { | ||||
|                 lock (m_primTerseUpdates.SyncRoot) | ||||
|                     m_primTerseUpdates.Reprioritize(terse_update_priority_handler); | ||||
|             } | ||||
|             lock (m_entityUpdates.SyncRoot) | ||||
|                 m_entityUpdates.Reprioritize(update_priority_handler); | ||||
|         } | ||||
| 
 | ||||
|         public void FlushPrimUpdates() | ||||
|         { | ||||
|             while (m_primFullUpdates.Count > 0) | ||||
|             { | ||||
|                 ProcessPrimFullUpdates(); | ||||
|             } | ||||
|             while (m_primTerseUpdates.Count > 0) | ||||
|             { | ||||
|                 ProcessPrimTerseUpdates(); | ||||
|             } | ||||
|             while (m_avatarTerseUpdates.Count > 0) | ||||
|             { | ||||
|                 ProcessAvatarTerseUpdates(); | ||||
|             } | ||||
|             m_log.Debug("[CLIENT]: Flushing prim updates to " + m_firstName + " " + m_lastName); | ||||
| 
 | ||||
|             while (m_entityUpdates.Count > 0) | ||||
|                 ProcessEntityUpdates(-1); | ||||
|         } | ||||
| 
 | ||||
|         #endregion Primitive Packet/Data Sending Methods | ||||
|  | @ -3724,28 +3630,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
| 
 | ||||
|         void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) | ||||
|         { | ||||
|             if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) | ||||
|             { | ||||
|                 lock (m_avatarTerseUpdates.SyncRoot) | ||||
|                 { | ||||
|                     if (m_avatarTerseUpdates.Count > 0) | ||||
|                         ProcessAvatarTerseUpdates(); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             if ((categories & ThrottleOutPacketTypeFlags.State) != 0) | ||||
|             { | ||||
|                 lock (m_primFullUpdates.SyncRoot) | ||||
|                 { | ||||
|                     if (m_primFullUpdates.Count > 0) | ||||
|                         ProcessPrimFullUpdates(); | ||||
|                 } | ||||
| 
 | ||||
|                 lock (m_primTerseUpdates.SyncRoot) | ||||
|                 { | ||||
|                     if (m_primTerseUpdates.Count > 0) | ||||
|                         ProcessPrimTerseUpdates(); | ||||
|                 } | ||||
|                 if (m_entityUpdates.Count > 0) | ||||
|                     ProcessEntityUpdates(m_udpServer.PrimUpdatesPerCallback); | ||||
|             } | ||||
| 
 | ||||
|             if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) | ||||
|  | @ -4403,22 +4291,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
| 
 | ||||
|         #region Helper Methods | ||||
| 
 | ||||
|         protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendAvatarTerseData data) | ||||
|         protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(ISceneEntity entity, bool sendTexture) | ||||
|         { | ||||
|             return CreateImprovedTerseBlock(true, data.LocalID, 0, data.CollisionPlane, data.Position, data.Velocity, | ||||
|                 data.Acceleration, data.Rotation, Vector3.Zero, data.TextureEntry); | ||||
|         } | ||||
|             #region ScenePresence/SOP Handling | ||||
| 
 | ||||
|         protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendPrimitiveTerseData data) | ||||
|         { | ||||
|             return CreateImprovedTerseBlock(false, data.LocalID, data.AttachPoint, Vector4.Zero, data.Position, data.Velocity, | ||||
|                 data.Acceleration, data.Rotation, data.AngularVelocity, data.TextureEntry); | ||||
|         } | ||||
|             bool avatar = (entity is ScenePresence); | ||||
|             uint localID = entity.LocalId; | ||||
|             uint attachPoint; | ||||
|             Vector4 collisionPlane; | ||||
|             Vector3 position, velocity, acceleration, angularVelocity; | ||||
|             Quaternion rotation; | ||||
|             byte[] textureEntry; | ||||
| 
 | ||||
|             if (entity is ScenePresence) | ||||
|             { | ||||
|                 ScenePresence presence = (ScenePresence)entity; | ||||
| 
 | ||||
|                 attachPoint = 0; | ||||
|                 collisionPlane = presence.CollisionPlane; | ||||
|                 position = presence.OffsetPosition; | ||||
|                 velocity = presence.Velocity; | ||||
|                 acceleration = Vector3.Zero; | ||||
|                 angularVelocity = Vector3.Zero; | ||||
|                 rotation = presence.Rotation; | ||||
| 
 | ||||
|                 if (sendTexture) | ||||
|                     textureEntry = presence.Appearance.Texture.GetBytes(); | ||||
|                 else | ||||
|                     textureEntry = null; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 SceneObjectPart part = (SceneObjectPart)entity; | ||||
| 
 | ||||
|                 attachPoint = part.AttachmentPoint; | ||||
|                 collisionPlane = Vector4.Zero; | ||||
|                 position = part.RelativePosition; | ||||
|                 velocity = part.Velocity; | ||||
|                 acceleration = part.Acceleration; | ||||
|                 angularVelocity = part.AngularVelocity; | ||||
|                 rotation = part.RotationOffset; | ||||
|                 textureEntry = part.Shape.TextureEntry; | ||||
|             } | ||||
| 
 | ||||
|             #endregion ScenePresence/SOP Handling | ||||
| 
 | ||||
|         protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(bool avatar, uint localID, int attachPoint, | ||||
|             Vector4 collisionPlane, Vector3 position, Vector3 velocity, Vector3 acceleration, Quaternion rotation, | ||||
|             Vector3 angularVelocity, byte[] textureEntry) | ||||
|         { | ||||
|             int pos = 0; | ||||
|             byte[] data = new byte[(avatar ? 60 : 44)]; | ||||
| 
 | ||||
|  | @ -4490,12 +4407,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             return block; | ||||
|         } | ||||
| 
 | ||||
|         protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(SendAvatarData data) | ||||
|         protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) | ||||
|         { | ||||
|             byte[] objectData = new byte[76]; | ||||
| 
 | ||||
|             Vector4.UnitW.ToBytes(objectData, 0); // TODO: Collision plane support | ||||
|             data.Position.ToBytes(objectData, 16); | ||||
|             data.CollisionPlane.ToBytes(objectData, 0); | ||||
|             data.OffsetPosition.ToBytes(objectData, 16); | ||||
|             //data.Velocity.ToBytes(objectData, 28); | ||||
|             //data.Acceleration.ToBytes(objectData, 40); | ||||
|             data.Rotation.ToBytes(objectData, 52); | ||||
|  | @ -4505,12 +4422,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
| 
 | ||||
|             update.Data = Utils.EmptyBytes; | ||||
|             update.ExtraParams = new byte[1]; | ||||
|             update.FullID = data.AvatarID; | ||||
|             update.ID = data.AvatarLocalID; | ||||
|             update.FullID = data.UUID; | ||||
|             update.ID = data.LocalId; | ||||
|             update.Material = (byte)Material.Flesh; | ||||
|             update.MediaURL = Utils.EmptyBytes; | ||||
|             update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.FirstName + "\nLastName STRING RW SV " + | ||||
|                 data.LastName + "\nTitle STRING RW SV " + data.GroupTitle); | ||||
|             update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + | ||||
|                 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); | ||||
|             update.ObjectData = objectData; | ||||
|             update.ParentID = data.ParentID; | ||||
|             update.PathCurve = 16; | ||||
|  | @ -4523,98 +4440,112 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             update.Text = Utils.EmptyBytes; | ||||
|             update.TextColor = new byte[4]; | ||||
|             update.TextureAnim = Utils.EmptyBytes; | ||||
|             update.TextureEntry = data.TextureEntry ?? Utils.EmptyBytes; | ||||
|             update.UpdateFlags = (uint)(PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | PrimFlags.ObjectOwnerModify);//61 + (9 << 8) + (130 << 16) + (16 << 24); // TODO: Replace these numbers with PrimFlags | ||||
|             update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; | ||||
|             update.UpdateFlags = (uint)( | ||||
|                 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |  | ||||
|                 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |  | ||||
|                 PrimFlags.ObjectOwnerModify); | ||||
| 
 | ||||
|             return update; | ||||
|         } | ||||
| 
 | ||||
|         protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SendPrimitiveData data) | ||||
|         protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) | ||||
|         { | ||||
|             byte[] objectData = new byte[60]; | ||||
|             data.pos.ToBytes(objectData, 0); | ||||
|             data.vel.ToBytes(objectData, 12); | ||||
|             data.acc.ToBytes(objectData, 24); | ||||
|             data.rotation.ToBytes(objectData, 36); | ||||
|             data.rvel.ToBytes(objectData, 48); | ||||
|             data.RelativePosition.ToBytes(objectData, 0); | ||||
|             data.Velocity.ToBytes(objectData, 12); | ||||
|             data.Acceleration.ToBytes(objectData, 24); | ||||
|             data.RotationOffset.ToBytes(objectData, 36); | ||||
|             data.AngularVelocity.ToBytes(objectData, 48); | ||||
| 
 | ||||
|             ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); | ||||
|             update.ClickAction = (byte)data.clickAction; | ||||
|             update.ClickAction = (byte)data.ClickAction; | ||||
|             update.CRC = 0; | ||||
|             update.ExtraParams = data.primShape.ExtraParams ?? Utils.EmptyBytes; | ||||
|             update.FullID = data.objectID; | ||||
|             update.ID = data.localID; | ||||
|             update.ExtraParams = data.Shape.ExtraParams ?? Utils.EmptyBytes; | ||||
|             update.FullID = data.UUID; | ||||
|             update.ID = data.LocalId; | ||||
|             //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated | ||||
|             //update.JointPivot = Vector3.Zero; | ||||
|             //update.JointType = 0; | ||||
|             update.Material = data.material; | ||||
|             update.Material = data.Material; | ||||
|             update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim | ||||
|             if (data.attachment) | ||||
|             if (data.IsAttachment) | ||||
|             { | ||||
|                 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.AssetId); | ||||
|                 update.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16)); | ||||
|                 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID); | ||||
|                 update.State = (byte)((data.AttachmentPoint % 16) * 16 + (data.AttachmentPoint / 16)); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 update.NameValue = Utils.EmptyBytes; | ||||
|                 update.State = data.primShape.State; | ||||
|                 update.State = data.Shape.State; | ||||
|             } | ||||
|             update.ObjectData = objectData; | ||||
|             update.ParentID = data.parentID; | ||||
|             update.PathBegin = data.primShape.PathBegin; | ||||
|             update.PathCurve = data.primShape.PathCurve; | ||||
|             update.PathEnd = data.primShape.PathEnd; | ||||
|             update.PathRadiusOffset = data.primShape.PathRadiusOffset; | ||||
|             update.PathRevolutions = data.primShape.PathRevolutions; | ||||
|             update.PathScaleX = data.primShape.PathScaleX; | ||||
|             update.PathScaleY = data.primShape.PathScaleY; | ||||
|             update.PathShearX = data.primShape.PathShearX; | ||||
|             update.PathShearY = data.primShape.PathShearY; | ||||
|             update.PathSkew = data.primShape.PathSkew; | ||||
|             update.PathTaperX = data.primShape.PathTaperX; | ||||
|             update.PathTaperY = data.primShape.PathTaperY; | ||||
|             update.PathTwist = data.primShape.PathTwist; | ||||
|             update.PathTwistBegin = data.primShape.PathTwistBegin; | ||||
|             update.PCode = data.primShape.PCode; | ||||
|             update.ProfileBegin = data.primShape.ProfileBegin; | ||||
|             update.ProfileCurve = data.primShape.ProfileCurve; | ||||
|             update.ProfileEnd = data.primShape.ProfileEnd; | ||||
|             update.ProfileHollow = data.primShape.ProfileHollow; | ||||
|             update.PSBlock = data.particleSystem ?? Utils.EmptyBytes; | ||||
|             update.TextColor = data.color ?? Color4.Black.GetBytes(true); | ||||
|             update.TextureAnim = data.textureanim ?? Utils.EmptyBytes; | ||||
|             update.TextureEntry = data.primShape.TextureEntry ?? Utils.EmptyBytes; | ||||
|             update.Scale = data.primShape.Scale; | ||||
|             update.Text = Util.StringToBytes256(data.text); | ||||
|             update.UpdateFlags = (uint)data.flags; | ||||
| 
 | ||||
|             if (data.SoundId != UUID.Zero) | ||||
|             update.ObjectData = objectData; | ||||
|             update.ParentID = data.ParentID; | ||||
|             update.PathBegin = data.Shape.PathBegin; | ||||
|             update.PathCurve = data.Shape.PathCurve; | ||||
|             update.PathEnd = data.Shape.PathEnd; | ||||
|             update.PathRadiusOffset = data.Shape.PathRadiusOffset; | ||||
|             update.PathRevolutions = data.Shape.PathRevolutions; | ||||
|             update.PathScaleX = data.Shape.PathScaleX; | ||||
|             update.PathScaleY = data.Shape.PathScaleY; | ||||
|             update.PathShearX = data.Shape.PathShearX; | ||||
|             update.PathShearY = data.Shape.PathShearY; | ||||
|             update.PathSkew = data.Shape.PathSkew; | ||||
|             update.PathTaperX = data.Shape.PathTaperX; | ||||
|             update.PathTaperY = data.Shape.PathTaperY; | ||||
|             update.PathTwist = data.Shape.PathTwist; | ||||
|             update.PathTwistBegin = data.Shape.PathTwistBegin; | ||||
|             update.PCode = data.Shape.PCode; | ||||
|             update.ProfileBegin = data.Shape.ProfileBegin; | ||||
|             update.ProfileCurve = data.Shape.ProfileCurve; | ||||
|             update.ProfileEnd = data.Shape.ProfileEnd; | ||||
|             update.ProfileHollow = data.Shape.ProfileHollow; | ||||
|             update.PSBlock = data.ParticleSystem ?? Utils.EmptyBytes; | ||||
|             update.TextColor = data.GetTextColor().GetBytes(false); | ||||
|             update.TextureAnim = data.TextureAnimation ?? Utils.EmptyBytes; | ||||
|             update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes; | ||||
|             update.Scale = data.Shape.Scale; | ||||
|             update.Text = Util.StringToBytes256(data.Text); | ||||
| 
 | ||||
|             #region PrimFlags | ||||
| 
 | ||||
|             PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(recipientID, data.UUID); | ||||
| 
 | ||||
|             // Don't send the CreateSelected flag to everyone | ||||
|             flags &= ~PrimFlags.CreateSelected; | ||||
| 
 | ||||
|             if (recipientID == data.OwnerID) | ||||
|             { | ||||
|                 update.Sound = data.SoundId; | ||||
|                 update.OwnerID = data.ownerID; | ||||
|                 update.Gain = (float)data.SoundVolume; | ||||
|                 if ((data.Flags & PrimFlags.CreateSelected) != 0) | ||||
|                 { | ||||
|                     // Only send this flag once, then unset it | ||||
|                     flags |= PrimFlags.CreateSelected; | ||||
|                     data.Flags &= ~PrimFlags.CreateSelected; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             update.UpdateFlags = (uint)flags; | ||||
| 
 | ||||
|             #endregion PrimFlags | ||||
| 
 | ||||
|             if (data.Sound != UUID.Zero) | ||||
|             { | ||||
|                 update.Sound = data.Sound; | ||||
|                 update.OwnerID = data.OwnerID; | ||||
|                 update.Gain = (float)data.SoundGain; | ||||
|                 update.Radius = (float)data.SoundRadius; | ||||
|                 update.Flags = data.SoundFlags; | ||||
|             } | ||||
| 
 | ||||
|             switch ((PCode)data.primShape.PCode) | ||||
|             switch ((PCode)data.Shape.PCode) | ||||
|             { | ||||
|                 case PCode.Grass: | ||||
|                 case PCode.Tree: | ||||
|                 case PCode.NewTree: | ||||
|                     update.Data = new byte[] { data.primShape.State }; | ||||
|                     update.Data = new byte[] { data.Shape.State }; | ||||
|                     break; | ||||
|                 default: | ||||
|                     // TODO: Support ScratchPad | ||||
|                     //if (prim.ScratchPad != null) | ||||
|                     //{ | ||||
|                     //    update.Data = new byte[prim.ScratchPad.Length]; | ||||
|                     //    Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length); | ||||
|                     //} | ||||
|                     //else | ||||
|                     //{ | ||||
|                     //    update.Data = Utils.EmptyBytes; | ||||
|                     //} | ||||
|                     update.Data = Utils.EmptyBytes; | ||||
|                     break; | ||||
|             } | ||||
|  | @ -4622,6 +4553,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             return update; | ||||
|         } | ||||
| 
 | ||||
|         protected ObjectUpdateCompressedPacket.ObjectDataBlock CreateCompressedUpdateBlock(SceneObjectPart part, PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|             // TODO: Implement this | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         public void SendNameReply(UUID profileId, string firstname, string lastname) | ||||
|         { | ||||
|             UUIDNameReplyPacket packet = (UUIDNameReplyPacket)PacketPool.Instance.GetPacket(PacketType.UUIDNameReply); | ||||
|  | @ -11655,7 +11592,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                         return item.Value; | ||||
|                     } | ||||
|                 } | ||||
|                 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); | ||||
|                 return default(TValue); | ||||
|             } | ||||
| 
 | ||||
|             internal void Reprioritize(UpdatePriorityHandler handler) | ||||
|  |  | |||
|  | @ -99,15 +99,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
| 
 | ||||
|         /// <summary>The measured resolution of Environment.TickCount</summary> | ||||
|         public readonly float TickCountResolution; | ||||
|         /// <summary>Number of terse prim updates to put on the queue each time the | ||||
|         /// <summary>Number of prim updates to put on the queue each time the  | ||||
|         /// OnQueueEmpty event is triggered for updates</summary> | ||||
|         public readonly int PrimTerseUpdatesPerPacket; | ||||
|         /// <summary>Number of terse avatar updates to put on the queue each time the | ||||
|         /// OnQueueEmpty event is triggered for updates</summary> | ||||
|         public readonly int AvatarTerseUpdatesPerPacket; | ||||
|         /// <summary>Number of full prim updates to put on the queue each time the | ||||
|         /// OnQueueEmpty event is triggered for updates</summary> | ||||
|         public readonly int PrimFullUpdatesPerPacket; | ||||
|         public readonly int PrimUpdatesPerCallback; | ||||
|         /// <summary>Number of texture packets to put on the queue each time the | ||||
|         /// OnQueueEmpty event is triggered for textures</summary> | ||||
|         public readonly int TextureSendLimit; | ||||
|  | @ -191,9 +185,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                 m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); | ||||
|                 sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); | ||||
| 
 | ||||
|                 PrimTerseUpdatesPerPacket = config.GetInt("PrimTerseUpdatesPerPacket", 25); | ||||
|                 AvatarTerseUpdatesPerPacket = config.GetInt("AvatarTerseUpdatesPerPacket", 10); | ||||
|                 PrimFullUpdatesPerPacket = config.GetInt("PrimFullUpdatesPerPacket", 100); | ||||
|                 PrimUpdatesPerCallback = config.GetInt("PrimUpdatesPerCallback", 100); | ||||
|                 TextureSendLimit = config.GetInt("TextureSendLimit", 20); | ||||
| 
 | ||||
|                 m_defaultRTO = config.GetInt("DefaultRTO", 0); | ||||
|  | @ -201,9 +193,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             } | ||||
|             else | ||||
|             { | ||||
|                 PrimTerseUpdatesPerPacket = 25; | ||||
|                 AvatarTerseUpdatesPerPacket = 10; | ||||
|                 PrimFullUpdatesPerPacket = 100; | ||||
|                 PrimUpdatesPerCallback = 100; | ||||
|                 TextureSendLimit = 20; | ||||
|             } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1446,7 +1446,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
|             if (destination != null && !CrossPrimGroupIntoNewRegion(destination, grp, silent)) | ||||
|             { | ||||
|                 grp.OffsetForNewRegion(oldGroupPosition); | ||||
|                 grp.ScheduleGroupForFullUpdate(); | ||||
|                 grp.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -1465,7 +1465,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
|             //m_log.Debug("  >>> CrossPrimGroupIntoNewRegion <<<"); | ||||
| 
 | ||||
|             bool successYN = false; | ||||
|             grp.RootPart.UpdateFlag = 0; | ||||
|             grp.RootPart.ClearPendingUpdate(); | ||||
|             //int primcrossingXMLmethod = 0; | ||||
| 
 | ||||
|             if (destination != null) | ||||
|  |  | |||
|  | @ -511,7 +511,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
|                     // if not, we set it's position in world. | ||||
|                     if (!attachment) | ||||
|                     { | ||||
|                         group.ScheduleGroupForFullUpdate(); | ||||
|                         group.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); | ||||
|                          | ||||
|                         float offsetHeight = 0; | ||||
|                         pos = m_Scene.GetNewRezLocation( | ||||
|  | @ -603,7 +603,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
|                         group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 0); | ||||
|                         rootPart.ParentGroup.ResumeScripts(); | ||||
| 
 | ||||
|                         rootPart.ScheduleFullUpdate(); | ||||
|                         rootPart.ScheduleUpdate(PrimUpdateFlags.FullUpdate); | ||||
|                     } | ||||
| 
 | ||||
|                     if (!m_Scene.Permissions.BypassPermissions()) | ||||
|  |  | |||
|  | @ -243,7 +243,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
|             if (m_Cache != null) | ||||
|                 m_Cache.Cache(asset); | ||||
|              | ||||
|             if (asset.Temporary || asset.Local) | ||||
|             if (asset.Local) | ||||
|                 return asset.ID; | ||||
|              | ||||
|             return m_AssetService.Store(asset); | ||||
|  |  | |||
|  | @ -528,18 +528,14 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendAvatarData(SendAvatarData data) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendEntityUpdate(double priority, ISceneEntity entity, PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||||
|         { | ||||
|         } | ||||
|  | @ -548,15 +544,7 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendPrimitiveToClient(SendPrimitiveData data) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) | ||||
|         public virtual void ReprioritizeUpdates(UpdatePriorityHandler handler) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ | |||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Region.Framework.Scenes; | ||||
| 
 | ||||
| namespace OpenSim.Region.Framework.Interfaces | ||||
|  | @ -34,7 +35,7 @@ namespace OpenSim.Region.Framework.Interfaces | |||
|     { | ||||
|         void Reset(); | ||||
|         void Close(); | ||||
|         void QueuePartForUpdate(SceneObjectPart part); | ||||
|         void QueuePartForUpdate(SceneObjectPart part, PrimUpdateFlags updateFlags); | ||||
|         void SendPrimUpdates(); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1857,10 +1857,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     { | ||||
|                         group.RootPart.ApplyImpulse((vel * group.GetMass()), false); | ||||
|                         group.Velocity = vel; | ||||
|                         rootPart.ScheduleFullUpdate(); | ||||
|                         rootPart.ScheduleUpdate(PrimUpdateFlags.FullUpdate); | ||||
|                     } | ||||
|                     group.CreateScriptInstances(param, true, DefaultScriptEngine, 2); | ||||
|                     rootPart.ScheduleFullUpdate(); | ||||
|                     rootPart.ScheduleUpdate(PrimUpdateFlags.FullUpdate); | ||||
| 
 | ||||
|                     if (!Permissions.BypassPermissions()) | ||||
|                     { | ||||
|  | @ -1929,7 +1929,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 { | ||||
|                     sog.SetOwnerId(ownerID); | ||||
|                     sog.SetGroup(groupID, remoteClient); | ||||
|                     sog.ScheduleGroupForFullUpdate(); | ||||
|                     sog.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); | ||||
| 
 | ||||
|                     foreach (SceneObjectPart child in sog.Children.Values) | ||||
|                         child.Inventory.ChangeInventoryOwner(ownerID); | ||||
|  |  | |||
|  | @ -124,7 +124,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 { | ||||
|                     if (((SceneObjectGroup)ent).LocalId == primLocalID) | ||||
|                     { | ||||
|                         ((SceneObjectGroup)ent).SendFullUpdateToClient(remoteClient); | ||||
|                         ((SceneObjectGroup)ent).SendUpdateToClient(remoteClient, PrimUpdateFlags.FullUpdate); | ||||
|                         return; | ||||
|                     } | ||||
|                 } | ||||
|  | @ -207,8 +207,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
|              | ||||
|             if (part.ParentGroup.IsAttachment) | ||||
|                 isAttachment = true; | ||||
|             else | ||||
|                 part.ParentGroup.ScheduleGroupForFullUpdate(); | ||||
| 
 | ||||
|             // If it's not an attachment, and we are allowed to move it, | ||||
|             // then we might have done so. If we moved across a parcel | ||||
|  |  | |||
|  | @ -2051,8 +2051,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 sceneObject.SetGroup(groupID, null); | ||||
|             } | ||||
| 
 | ||||
|             sceneObject.ScheduleGroupForFullUpdate(); | ||||
| 
 | ||||
|             return sceneObject; | ||||
|         } | ||||
| 
 | ||||
|  | @ -2541,7 +2539,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                             sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false); | ||||
|                      | ||||
|                     RootPrim.RemFlag(PrimFlags.TemporaryOnRez); | ||||
|                     grp.SendGroupFullUpdate(); | ||||
|                     grp.SendGroupUpdate(PrimUpdateFlags.FullUpdate); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|  | @ -4037,7 +4035,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             { | ||||
|                 if (ent is SceneObjectGroup) | ||||
|                 { | ||||
|                     ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(); | ||||
|                     ((SceneObjectGroup)ent).ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | @ -4538,7 +4536,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 part.GetProperties(remoteClient); | ||||
|                 part.TriggerScriptChangedEvent(Changed.OWNER); | ||||
|                 group.ResumeScripts(); | ||||
|                 part.ScheduleFullUpdate(); | ||||
|                 part.ScheduleUpdate(PrimUpdateFlags.FullUpdate); | ||||
| 
 | ||||
|                 break; | ||||
| 
 | ||||
|  |  | |||
|  | @ -297,7 +297,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             sceneObject.AttachToScene(m_parentScene); | ||||
| 
 | ||||
|             if (sendClientUpdates) | ||||
|                 sceneObject.ScheduleGroupForFullUpdate(); | ||||
|                 sceneObject.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); | ||||
| 
 | ||||
|             lock (sceneObject) | ||||
|             { | ||||
|  | @ -1297,7 +1297,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 // so that if the object is locked the client moving the object | ||||
|                 // get's it's position on the simulator even if it was the same as before | ||||
|                 // This keeps the moving user's client in sync with the rest of the world. | ||||
|                 group.SendGroupTerseUpdate(); | ||||
|                 SceneObjectPart movingPart = group.GetChildPart(objectID); | ||||
|                 if (movingPart != null) | ||||
|                     movingPart.SendUpdateToAllClients(PrimUpdateFlags.Position); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -1338,7 +1340,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 // so that if the object is locked the client moving the object | ||||
|                 // get's it's position on the simulator even if it was the same as before | ||||
|                 // This keeps the moving user's client in sync with the rest of the world. | ||||
|                 group.SendGroupTerseUpdate(); | ||||
|                 SceneObjectPart rotatingPart = group.GetChildPart(objectID); | ||||
|                 if (rotatingPart != null) | ||||
|                     rotatingPart.SendUpdateToAllClients(PrimUpdateFlags.Rotation); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -1508,7 +1512,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); | ||||
|                 parentGroup.TriggerScriptChangedEvent(Changed.LINK); | ||||
|                 parentGroup.HasGroupChanged = true; | ||||
|                 parentGroup.ScheduleGroupForFullUpdate(); | ||||
|                 parentGroup.ScheduleGroupForUpdate(PrimUpdateFlags.ParentID); | ||||
|                  | ||||
|             } | ||||
|             finally | ||||
|  | @ -1608,7 +1612,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                             List<uint> linkIDs = new List<uint>(); | ||||
| 
 | ||||
|                             foreach (SceneObjectPart newChild in newSet) | ||||
|                                 newChild.UpdateFlag = 0; | ||||
|                                 newChild.ClearPendingUpdate(); | ||||
| 
 | ||||
|                             LinkObjects(newRoot, newSet); | ||||
|                             if (!affectedGroups.Contains(newRoot.ParentGroup)) | ||||
|  | @ -1623,7 +1627,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 { | ||||
|                     g.TriggerScriptChangedEvent(Changed.LINK); | ||||
|                     g.HasGroupChanged = true; // Persist | ||||
|                     g.ScheduleGroupForFullUpdate(); | ||||
|                     g.ScheduleGroupForUpdate(PrimUpdateFlags.ParentID); | ||||
|                 } | ||||
|             } | ||||
|             finally | ||||
|  | @ -1731,7 +1735,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
| 
 | ||||
|                     copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 0); | ||||
|                     copy.HasGroupChanged = true; | ||||
|                     copy.ScheduleGroupForFullUpdate(); | ||||
|                     copy.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); | ||||
|                     copy.ResumeScripts(); | ||||
| 
 | ||||
|                     // required for physics to update it's position | ||||
|  |  | |||
|  | @ -1001,7 +1001,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     } | ||||
| 
 | ||||
|                     IsSelected = false; // fudge.... | ||||
|                     ScheduleGroupForFullUpdate(); | ||||
|                     RootPart.ScheduleUpdate(PrimUpdateFlags.ParentID); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|  | @ -1052,7 +1052,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             RootPart.RemFlag(PrimFlags.TemporaryOnRez); | ||||
|             AttachToBackup(); | ||||
|             m_scene.EventManager.TriggerParcelPrimCountTainted(); | ||||
|             m_rootPart.ScheduleFullUpdate(); | ||||
|             m_rootPart.ScheduleUpdate(PrimUpdateFlags.ParentID); | ||||
|             m_rootPart.ClearUndoState(); | ||||
|         } | ||||
| 
 | ||||
|  | @ -1277,7 +1277,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
| 
 | ||||
|                         if (!silent) | ||||
|                         { | ||||
|                             part.UpdateFlag = 0; | ||||
|                             part.ClearPendingUpdate(); | ||||
|                             if (part == m_rootPart) | ||||
|                                 avatar.ControllingClient.SendKillObject(m_regionHandle, part.LocalId); | ||||
|                         } | ||||
|  | @ -1339,7 +1339,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 m_scene.RemoveGroupTarget(this); | ||||
|             } | ||||
| 
 | ||||
|             ScheduleGroupForFullUpdate(); | ||||
|             ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); | ||||
|         } | ||||
| 
 | ||||
|         public override void SetText(string text, Vector3 color, double alpha) | ||||
|  | @ -1351,7 +1351,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             Text = text; | ||||
| 
 | ||||
|             HasGroupChanged = true; | ||||
|             m_rootPart.ScheduleFullUpdate(); | ||||
|             m_rootPart.ScheduleUpdate(PrimUpdateFlags.Text); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -1488,18 +1488,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
| 
 | ||||
|         #endregion | ||||
| 
 | ||||
|         public void SendFullUpdateToClient(IClientAPI remoteClient) | ||||
|         public void SendUpdateToClient(IClientAPI remoteClient, PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|             RootPart.SendFullUpdate( | ||||
|                 remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); | ||||
|             RootPart.SendUpdateToClient(remoteClient, updateFlags); | ||||
| 
 | ||||
|             lock (m_parts) | ||||
|             { | ||||
|                 foreach (SceneObjectPart part in m_parts.Values) | ||||
|                 { | ||||
|                     if (part != RootPart) | ||||
|                         part.SendFullUpdate( | ||||
|                             remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); | ||||
|                         part.SendUpdateToClient(remoteClient, updateFlags); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | @ -1565,7 +1563,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             if (userExposed) | ||||
|             { | ||||
|                 SetRootPartOwner(m_rootPart, cAgentID, cGroupID); | ||||
|                 m_rootPart.ScheduleFullUpdate(); | ||||
|                 m_rootPart.ScheduleUpdate(PrimUpdateFlags.FullUpdate); | ||||
|             } | ||||
|              | ||||
|             List<SceneObjectPart> partList; | ||||
|  | @ -1592,7 +1590,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     if (userExposed) | ||||
|                     { | ||||
|                         SetPartOwner(newPart, cAgentID, cGroupID); | ||||
|                         newPart.ScheduleFullUpdate(); | ||||
|                         newPart.ScheduleUpdate(PrimUpdateFlags.FullUpdate); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | @ -1603,7 +1601,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 dupe.HasGroupChanged = true; | ||||
|                 dupe.AttachToBackup(); | ||||
| 
 | ||||
|                 ScheduleGroupForFullUpdate(); | ||||
|                 ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); | ||||
|             } | ||||
| 
 | ||||
|             return dupe; | ||||
|  | @ -1856,7 +1854,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     ApplyNextOwnerPermissions(); | ||||
|             } | ||||
| 
 | ||||
|             part.ScheduleFullUpdate(); | ||||
|             part.ScheduleUpdate(PrimUpdateFlags.FullUpdate); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -1942,13 +1940,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
| 
 | ||||
|                 if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f)) | ||||
|                 { | ||||
|                     m_rootPart.UpdateFlag = 1; | ||||
|                     m_rootPart.PendingUpdateFlags |= PrimUpdateFlags.Position; | ||||
|                     lastPhysGroupPos = AbsolutePosition; | ||||
|                 } | ||||
| 
 | ||||
|                 if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f)) | ||||
|                 { | ||||
|                     m_rootPart.UpdateFlag = 1; | ||||
|                     m_rootPart.PendingUpdateFlags |= PrimUpdateFlags.Rotation; | ||||
|                     lastPhysGroupRot = GroupRotation; | ||||
|                 } | ||||
| 
 | ||||
|  | @ -1961,31 +1959,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void ScheduleFullUpdateToAvatar(ScenePresence presence) | ||||
|         public void ScheduleUpdateToAvatar(ScenePresence presence, PrimUpdateFlags updateFlags) | ||||
|         { | ||||
| //            m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); | ||||
|              | ||||
|             RootPart.AddFullUpdateToAvatar(presence); | ||||
|             RootPart.AddUpdateToAvatar(presence, updateFlags); | ||||
| 
 | ||||
|             lock (m_parts) | ||||
|             { | ||||
|                 foreach (SceneObjectPart part in m_parts.Values) | ||||
|                 { | ||||
|                     if (part != RootPart) | ||||
|                         part.AddFullUpdateToAvatar(presence); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void ScheduleTerseUpdateToAvatar(ScenePresence presence) | ||||
|         { | ||||
| //            m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); | ||||
|              | ||||
|             lock (m_parts) | ||||
|             { | ||||
|                 foreach (SceneObjectPart part in m_parts.Values) | ||||
|                 { | ||||
|                     part.AddTerseUpdateToAvatar(presence); | ||||
|                         part.AddUpdateToAvatar(presence, updateFlags); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | @ -1993,35 +1978,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         /// <summary> | ||||
|         /// Schedule a full update for this scene object | ||||
|         /// </summary> | ||||
|         public void ScheduleGroupForFullUpdate() | ||||
|         public void ScheduleGroupForUpdate(PrimUpdateFlags updateFlags) | ||||
|         { | ||||
| //            m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID); | ||||
|              | ||||
|             checkAtTargets(); | ||||
|             RootPart.ScheduleFullUpdate(); | ||||
|             RootPart.ScheduleUpdate(updateFlags); | ||||
| 
 | ||||
|             lock (m_parts) | ||||
|             { | ||||
|                 foreach (SceneObjectPart part in m_parts.Values) | ||||
|                 { | ||||
|                     if (part != RootPart) | ||||
|                         part.ScheduleFullUpdate(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Schedule a terse update for this scene object | ||||
|         /// </summary> | ||||
|         public void ScheduleGroupForTerseUpdate() | ||||
|         { | ||||
| //            m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID); | ||||
|              | ||||
|             lock (m_parts) | ||||
|             { | ||||
|                 foreach (SceneObjectPart part in m_parts.Values) | ||||
|                 { | ||||
|                     part.ScheduleTerseUpdate(); | ||||
|                         part.ScheduleUpdate(updateFlags); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | @ -2029,39 +1998,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         /// <summary> | ||||
|         /// Immediately send a full update for this scene object. | ||||
|         /// </summary> | ||||
|         public void SendGroupFullUpdate() | ||||
|         public void SendGroupUpdate(PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|             if (IsDeleted) | ||||
|                 return; | ||||
| 
 | ||||
| //            m_log.DebugFormat("[SOG]: Sending immediate full group update for {0} {1}", Name, UUID); | ||||
|              | ||||
|             RootPart.SendFullUpdateToAllClients(); | ||||
|             RootPart.SendUpdateToAllClients(updateFlags); | ||||
| 
 | ||||
|             lock (m_parts) | ||||
|             { | ||||
|                 foreach (SceneObjectPart part in m_parts.Values) | ||||
|                 { | ||||
|                     if (part != RootPart) | ||||
|                         part.SendFullUpdateToAllClients(); | ||||
|                         part.SendUpdateToAllClients(updateFlags); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Immediately send an update for this scene object's root prim only. | ||||
|         /// This is for updates regarding the object as a whole, and none of its parts in particular. | ||||
|         /// Note: this may not be used by opensim (it probably should) but it's used by | ||||
|         /// external modules. | ||||
|         /// </summary> | ||||
|         public void SendGroupRootTerseUpdate() | ||||
|         { | ||||
|             if (IsDeleted) | ||||
|                 return; | ||||
| 
 | ||||
|             RootPart.SendTerseUpdateToAllClients(); | ||||
|         } | ||||
| 
 | ||||
|         public void QueueForUpdateCheck() | ||||
|         { | ||||
|             if (m_scene == null) // Need to check here as it's null during object creation | ||||
|  | @ -2070,23 +2025,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             m_scene.SceneGraph.AddToUpdateList(this); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Immediately send a terse update for this scene object. | ||||
|         /// </summary> | ||||
|         public void SendGroupTerseUpdate() | ||||
|         { | ||||
|             if (IsDeleted) | ||||
|                 return; | ||||
|              | ||||
|             lock (m_parts) | ||||
|             { | ||||
|                 foreach (SceneObjectPart part in m_parts.Values) | ||||
|                 { | ||||
|                     part.SendTerseUpdateToAllClients(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         #endregion | ||||
| 
 | ||||
|         #region SceneGroupPart Methods | ||||
|  | @ -2492,7 +2430,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         public void NonPhysicalGrabMovement(Vector3 pos) | ||||
|         { | ||||
|             AbsolutePosition = pos; | ||||
|             m_rootPart.SendTerseUpdateToAllClients(); | ||||
|             m_rootPart.SendUpdateToAllClients(PrimUpdateFlags.Position); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -2812,7 +2750,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 //if (part.UUID != m_rootPart.UUID) | ||||
| 
 | ||||
|                 HasGroupChanged = true; | ||||
|                 ScheduleGroupForFullUpdate(); | ||||
|                 ScheduleGroupForUpdate(PrimUpdateFlags.Scale); | ||||
| 
 | ||||
|                 //if (part.UUID == m_rootPart.UUID) | ||||
|                 //{ | ||||
|  | @ -2964,7 +2902,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 part.IgnoreUndoUpdate = false; | ||||
|                 part.StoreUndoState(); | ||||
|                 HasGroupChanged = true; | ||||
|                 ScheduleGroupForTerseUpdate(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -3001,11 +2938,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 AbsolutePosition = pos; | ||||
| 
 | ||||
|                 HasGroupChanged = true; | ||||
|                  | ||||
|             } | ||||
| 
 | ||||
|             //we need to do a terse update even if the move wasn't allowed | ||||
|             // so that the position is reset in the client (the object snaps back) | ||||
|             ScheduleGroupForTerseUpdate(); | ||||
|             m_rootPart.ScheduleUpdate(PrimUpdateFlags.Position); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -3070,7 +3008,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             AbsolutePosition = newPos; | ||||
| 
 | ||||
|             HasGroupChanged = true; | ||||
|             ScheduleGroupForTerseUpdate(); | ||||
|             ScheduleGroupForUpdate(PrimUpdateFlags.Position | PrimUpdateFlags.Rotation); | ||||
|         } | ||||
| 
 | ||||
|         public void OffsetForNewRegion(Vector3 offset) | ||||
|  | @ -3102,7 +3040,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
| 
 | ||||
|             HasGroupChanged = true; | ||||
|             ScheduleGroupForTerseUpdate(); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -3128,7 +3065,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             AbsolutePosition = pos; | ||||
| 
 | ||||
|             HasGroupChanged = true; | ||||
|             ScheduleGroupForTerseUpdate(); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -3214,7 +3150,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                         Quaternion newRot = primsRot * oldParentRot; | ||||
|                         newRot *= Quaternion.Inverse(axRot); | ||||
|                         prim.RotationOffset = newRot; | ||||
|                         prim.ScheduleTerseUpdate(); | ||||
|                         prim.ScheduleUpdate(PrimUpdateFlags.Position | PrimUpdateFlags.Rotation); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | @ -3226,7 +3162,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     childpart.StoreUndoState(); | ||||
|                 } | ||||
|             } | ||||
|             m_rootPart.ScheduleTerseUpdate(); | ||||
|             m_rootPart.ScheduleUpdate(PrimUpdateFlags.Position | PrimUpdateFlags.Rotation); | ||||
|         } | ||||
| 
 | ||||
|         #endregion | ||||
|  |  | |||
|  | @ -104,7 +104,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
| 
 | ||||
|     #endregion Enumerations | ||||
| 
 | ||||
|     public class SceneObjectPart : IScriptHost | ||||
|     public class SceneObjectPart : ISceneEntity, IScriptHost | ||||
|     { | ||||
|         /// <value> | ||||
|         /// Denote all sides of the prim | ||||
|  | @ -168,13 +168,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         public double SoundRadius; | ||||
|          | ||||
|         [XmlIgnore] | ||||
|         public uint TimeStampFull; | ||||
|         public uint TimeStampUpdate; | ||||
|          | ||||
|         [XmlIgnore] | ||||
|         public uint TimeStampLastActivity; // Will be used for AutoReturn | ||||
|          | ||||
|         [XmlIgnore] | ||||
|         public uint TimeStampTerse; | ||||
| 
 | ||||
|         [XmlIgnore] | ||||
|         public UUID FromItemID; | ||||
|  | @ -282,15 +279,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
| 
 | ||||
|         private bool m_passTouches; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Only used internally to schedule client updates. | ||||
|         /// 0 - no update is scheduled | ||||
|         /// 1 - terse update scheduled | ||||
|         /// 2 - full update scheduled | ||||
|         /// | ||||
|         /// TODO - This should be an enumeration | ||||
|         /// </summary> | ||||
|         private byte m_updateFlag; | ||||
|         /// <summary>Modified fields that need to be broadcast</summary> | ||||
|         private PrimUpdateFlags m_pendingUpdateFlags; | ||||
| 
 | ||||
|         protected Vector3 m_acceleration; | ||||
|         protected Vector3 m_angularVelocity; | ||||
|  | @ -712,6 +702,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public Vector3 RelativePosition | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if (IsRoot) | ||||
|                 { | ||||
|                     if (IsAttachment) | ||||
|                         return AttachedPos; | ||||
|                     else | ||||
|                         return AbsolutePosition; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return OffsetPosition; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public Quaternion RotationOffset | ||||
|         { | ||||
|             get | ||||
|  | @ -943,10 +951,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 TriggerScriptChangedEvent(Changed.SCALE); | ||||
|             } | ||||
|         } | ||||
|         public byte UpdateFlag | ||||
|         public PrimUpdateFlags PendingUpdateFlags | ||||
|         { | ||||
|             get { return m_updateFlag; } | ||||
|             set { m_updateFlag = value; } | ||||
|             get { return m_pendingUpdateFlags; } | ||||
|             set { m_pendingUpdateFlags = value; } | ||||
|         } | ||||
| 
 | ||||
|         #endregion | ||||
|  | @ -1187,14 +1195,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Clear all pending updates of parts to clients | ||||
|         /// </summary> | ||||
|         private void ClearUpdateSchedule() | ||||
|         { | ||||
|             m_updateFlag = 0; | ||||
|         } | ||||
| 
 | ||||
|         private void SendObjectPropertiesToClient(UUID AgentID) | ||||
|         { | ||||
|             m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) | ||||
|  | @ -1235,6 +1235,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
| 
 | ||||
|         #region Public Methods | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Clear all pending updates of parts to clients | ||||
|         /// </summary> | ||||
|         public void ClearPendingUpdate() | ||||
|         { | ||||
|             m_pendingUpdateFlags = PrimUpdateFlags.None; | ||||
|         } | ||||
| 
 | ||||
|         public void ResetExpire() | ||||
|         { | ||||
|             Expires = DateTime.Now + new TimeSpan(600000000); | ||||
|  | @ -1257,17 +1265,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         /// <summary> | ||||
|         /// Tell all scene presences that they should send updates for this part to their clients | ||||
|         /// </summary> | ||||
|         public void AddFullUpdateToAllAvatars() | ||||
|         public void AddUpdateToAllAvatars(PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|             m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) | ||||
|             { | ||||
|                 avatar.SceneViewer.QueuePartForUpdate(this); | ||||
|                 avatar.SceneViewer.QueuePartForUpdate(this, updateFlags); | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         public void AddFullUpdateToAvatar(ScenePresence presence) | ||||
|         public void AddUpdateToAvatar(ScenePresence presence, PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|             presence.SceneViewer.QueuePartForUpdate(this); | ||||
|             presence.SceneViewer.QueuePartForUpdate(this, updateFlags); | ||||
|         } | ||||
| 
 | ||||
|         public void AddNewParticleSystem(Primitive.ParticleSystem pSystem) | ||||
|  | @ -1280,20 +1288,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             m_particleSystem = new byte[0]; | ||||
|         } | ||||
| 
 | ||||
|         /// Terse updates | ||||
|         public void AddTerseUpdateToAllAvatars() | ||||
|         { | ||||
|             m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) | ||||
|             { | ||||
|                 avatar.SceneViewer.QueuePartForUpdate(this); | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         public void AddTerseUpdateToAvatar(ScenePresence presence) | ||||
|         { | ||||
|             presence.SceneViewer.QueuePartForUpdate(this); | ||||
|         } | ||||
| 
 | ||||
|         public void AddTextureAnimation(Primitive.TextureAnimation pTexAnim) | ||||
|         { | ||||
|             byte[] data = new byte[16]; | ||||
|  | @ -2570,19 +2564,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         { | ||||
|             if (PhysActor != null) | ||||
|             { | ||||
|                 Vector3 newpos = PhysActor.Position; | ||||
|                  | ||||
|                 Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0); | ||||
|                  | ||||
|                 if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) | ||||
|                 if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | | ||||
|                     m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | | ||||
|                     m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | | ||||
|                     m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) | ||||
|                 { | ||||
|                     m_parentGroup.AbsolutePosition = newpos; | ||||
|                     return; | ||||
|                 } | ||||
|                 //m_parentGroup.RootPart.m_groupPosition = newpos; | ||||
|             } | ||||
|             ScheduleTerseUpdate(); | ||||
| 
 | ||||
|             //SendTerseUpdateToAllClients(); | ||||
|             ScheduleUpdate(PrimUpdateFlags.Position); | ||||
|         } | ||||
| 
 | ||||
|         public void PreloadSound(string sound) | ||||
|  | @ -2670,7 +2664,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             m_shape.Scale = scale; | ||||
| 
 | ||||
|             ParentGroup.HasGroupChanged = true; | ||||
|             ScheduleFullUpdate(); | ||||
|             ScheduleUpdate(PrimUpdateFlags.Scale); | ||||
|         } | ||||
|          | ||||
|         public void RotLookAt(Quaternion target, float strength, float damping) | ||||
|  | @ -2710,58 +2704,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Schedules this prim for a full update | ||||
|         /// Schedules this prim for an update | ||||
|         /// </summary> | ||||
|         public void ScheduleFullUpdate() | ||||
|         public void ScheduleUpdate(PrimUpdateFlags updateFlags) | ||||
|         { | ||||
| //            m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId); | ||||
|              | ||||
|             if (m_parentGroup != null) | ||||
|             { | ||||
|                 m_parentGroup.QueueForUpdateCheck(); | ||||
|             } | ||||
| 
 | ||||
|             int timeNow = Util.UnixTimeSinceEpoch(); | ||||
| 
 | ||||
|             // If multiple updates are scheduled on the same second, we still need to perform all of them | ||||
|             // So we'll force the issue by bumping up the timestamp so that later processing sees these need | ||||
|             // to be performed. | ||||
|             if (timeNow <= TimeStampFull) | ||||
|             { | ||||
|                 TimeStampFull += 1; | ||||
|             } | ||||
|             if (timeNow <= TimeStampUpdate) | ||||
|                 TimeStampUpdate += 1; | ||||
|             else | ||||
|             { | ||||
|                 TimeStampFull = (uint)timeNow; | ||||
|             } | ||||
|                 TimeStampUpdate = (uint)timeNow; | ||||
| 
 | ||||
|             m_updateFlag = 2; | ||||
| 
 | ||||
|             //            m_log.DebugFormat( | ||||
|             //                "[SCENE OBJECT PART]: Scheduling full  update for {0}, {1} at {2}", | ||||
|             //                UUID, Name, TimeStampFull); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Schedule a terse update for this prim.  Terse updates only send position, | ||||
|         /// rotation, velocity, rotational velocity and shape information. | ||||
|         /// </summary> | ||||
|         public void ScheduleTerseUpdate() | ||||
|         { | ||||
|             if (m_updateFlag < 1) | ||||
|             { | ||||
|                 if (m_parentGroup != null) | ||||
|                 { | ||||
|                     m_parentGroup.HasGroupChanged = true; | ||||
|                     m_parentGroup.QueueForUpdateCheck(); | ||||
|                 } | ||||
|                 TimeStampTerse = (uint) Util.UnixTimeSinceEpoch(); | ||||
|                 m_updateFlag = 1; | ||||
| 
 | ||||
|             //                m_log.DebugFormat( | ||||
|             //                    "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1} at {2}", | ||||
|             //                    UUID, Name, TimeStampTerse); | ||||
|             } | ||||
|             m_pendingUpdateFlags |= updateFlags; | ||||
|         } | ||||
| 
 | ||||
|         public void ScriptSetPhantomStatus(bool Phantom) | ||||
|  | @ -2821,51 +2781,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
|         } | ||||
| 
 | ||||
| //        /// <summary> | ||||
| //        /// | ||||
| //        /// </summary> | ||||
| //        /// <param name="remoteClient"></param> | ||||
| //        public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) | ||||
| //        { | ||||
| //            m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags); | ||||
| //        } | ||||
| 
 | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Send a full update to the client for the given part | ||||
|         /// </summary> | ||||
|         /// <param name="remoteClient"></param> | ||||
|         /// <param name="clientFlags"></param> | ||||
|         protected internal void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) | ||||
|         { | ||||
| //            m_log.DebugFormat( | ||||
| //                "[SOG]: Sendinging part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId); | ||||
|              | ||||
|             if (IsRoot) | ||||
|             { | ||||
|                 if (IsAttachment) | ||||
|                 { | ||||
|                     SendFullUpdateToClient(remoteClient, AttachedPos, clientFlags); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     SendFullUpdateToClient(remoteClient, AbsolutePosition, clientFlags); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 SendFullUpdateToClient(remoteClient, clientFlags); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Send a full update for this part to all clients. | ||||
|         /// </summary> | ||||
|         public void SendFullUpdateToAllClients() | ||||
|         public void SendUpdateToAllClients(PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|             m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) | ||||
|             { | ||||
|                 SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID)); | ||||
|                 SendUpdateToClient(avatar.ControllingClient, updateFlags); | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|  | @ -2873,63 +2796,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         /// Send a full update to all clients except the one nominated. | ||||
|         /// </summary> | ||||
|         /// <param name="agentID"></param> | ||||
|         public void SendFullUpdateToAllClientsExcept(UUID agentID) | ||||
|         public void SendUpdateToAllClientsExcept(PrimUpdateFlags updateFlags, UUID agentID) | ||||
|         { | ||||
|             m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) | ||||
|             { | ||||
|                 // Ugly reference :( | ||||
|                 if (avatar.UUID != agentID) | ||||
|                     SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID)); | ||||
|                     SendUpdateToClient(avatar.ControllingClient, updateFlags); | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Sends a full update to the client | ||||
|         /// Sends an update for this object to a client | ||||
|         /// </summary> | ||||
|         /// <param name="remoteClient"></param> | ||||
|         /// <param name="clientFlags"></param> | ||||
|         public void SendFullUpdateToClient(IClientAPI remoteClient, uint clientflags) | ||||
|         public void SendUpdateToClient(IClientAPI remoteClient, PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|             Vector3 lPos; | ||||
|             lPos = OffsetPosition; | ||||
|             SendFullUpdateToClient(remoteClient, lPos, clientflags); | ||||
|         } | ||||
|             // Sanity check | ||||
|             if (ParentGroup == null || ParentGroup.IsDeleted) | ||||
|                 return; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Sends a full update to the client | ||||
|         /// </summary> | ||||
|         /// <param name="remoteClient"></param> | ||||
|         /// <param name="lPos"></param> | ||||
|         /// <param name="clientFlags"></param> | ||||
|         public void SendFullUpdateToClient(IClientAPI remoteClient, Vector3 lPos, uint clientFlags) | ||||
|         { | ||||
|             // Suppress full updates during attachment editing | ||||
|             // | ||||
|             if (ParentGroup.IsSelected && IsAttachment) | ||||
|                 return; | ||||
|              | ||||
|             if (ParentGroup.IsDeleted) | ||||
|             if (ParentGroup.IsSelected && IsAttachment && updateFlags == PrimUpdateFlags.FullUpdate) | ||||
|                 return; | ||||
| 
 | ||||
|             clientFlags &= ~(uint) PrimFlags.CreateSelected; | ||||
| 
 | ||||
|             if (remoteClient.AgentId == _ownerID) | ||||
|             { | ||||
|                 if ((uint) (_flags & PrimFlags.CreateSelected) != 0) | ||||
|                 { | ||||
|                     clientFlags |= (uint) PrimFlags.CreateSelected; | ||||
|                     _flags &= ~PrimFlags.CreateSelected; | ||||
|                 } | ||||
|             } | ||||
|             //bool isattachment = IsAttachment; | ||||
|             //if (LocalId != ParentGroup.RootPart.LocalId) | ||||
|                 //isattachment = ParentGroup.RootPart.IsAttachment; | ||||
| 
 | ||||
|             byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; | ||||
|             remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, m_parentGroup.GetTimeDilation(), LocalId, m_shape, | ||||
|                                                lPos, Velocity, Acceleration, RotationOffset, AngularVelocity, clientFlags, m_uuid, _ownerID, | ||||
|                                                m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, | ||||
|                                                AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, ParentGroup.GetUpdatePriority(remoteClient))); | ||||
|             remoteClient.SendEntityUpdate(ParentGroup.GetUpdatePriority(remoteClient), this, updateFlags); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -2938,50 +2828,59 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         public void SendScheduledUpdates() | ||||
|         { | ||||
|             const float ROTATION_TOLERANCE = 0.01f; | ||||
|             const float VELOCITY_TOLERANCE = 0.001f; | ||||
|             const float POSITION_TOLERANCE = 0.05f; | ||||
|             const int TIME_MS_TOLERANCE = 3000; | ||||
| 
 | ||||
|             if (m_updateFlag == 1) | ||||
|             { | ||||
|                 // Throw away duplicate or insignificant updates | ||||
|                 if (!RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || | ||||
|                     !Acceleration.Equals(m_lastAcceleration) || | ||||
|                     !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || | ||||
|                     Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || | ||||
|                     !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || | ||||
|                     !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || | ||||
|                     Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) | ||||
|                 { | ||||
|                     AddTerseUpdateToAllAvatars(); | ||||
|                     ClearUpdateSchedule(); | ||||
|             #region PrimUpdateFlags Management | ||||
| 
 | ||||
|                     // This causes the Scene to 'poll' physical objects every couple of frames | ||||
|                     // bad, so it's been replaced by an event driven method. | ||||
|                     //if ((ObjectFlags & (uint)PrimFlags.Physics) != 0) | ||||
|                     //{ | ||||
|                     // Only send the constant terse updates on physical objects! | ||||
|                     //ScheduleTerseUpdate(); | ||||
|                     //} | ||||
|             // Check if any of the movement fields changes and set flags accordingly | ||||
|             PrimUpdateFlags updateFlags = m_pendingUpdateFlags; | ||||
| 
 | ||||
|                     // Update the "last" values | ||||
|                     m_lastPosition = OffsetPosition; | ||||
|                     m_lastRotation = RotationOffset; | ||||
|                     m_lastVelocity = Velocity; | ||||
|                     m_lastAcceleration = Acceleration; | ||||
|                     m_lastAngularVelocity = AngularVelocity; | ||||
|                     m_lastTerseSent = Environment.TickCount; | ||||
|                 } | ||||
|             } | ||||
|             if (!RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) | ||||
|                 updateFlags |= PrimUpdateFlags.Rotation; | ||||
|             else | ||||
|                 updateFlags &= ~PrimUpdateFlags.Rotation; | ||||
| 
 | ||||
|             if (!Acceleration.Equals(m_lastAcceleration)) | ||||
|                 updateFlags |= PrimUpdateFlags.Acceleration; | ||||
|             else | ||||
|                 updateFlags &= ~PrimUpdateFlags.Acceleration; | ||||
| 
 | ||||
|             if (!Velocity.Equals(m_lastVelocity)) | ||||
|                 updateFlags |= PrimUpdateFlags.Velocity; | ||||
|             else | ||||
|                 updateFlags &= ~PrimUpdateFlags.Velocity; | ||||
| 
 | ||||
|             if (!AngularVelocity.Equals(m_lastAngularVelocity)) | ||||
|                 updateFlags |= PrimUpdateFlags.AngularVelocity; | ||||
|             else | ||||
|                 updateFlags &= ~PrimUpdateFlags.AngularVelocity; | ||||
| 
 | ||||
|             if (!RelativePosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) | ||||
|                 updateFlags |= PrimUpdateFlags.Position; | ||||
|             else | ||||
|                 updateFlags &= ~PrimUpdateFlags.Position; | ||||
| 
 | ||||
|             // For good measure | ||||
|             //if (Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) | ||||
|             //    updateFlags |= PrimUpdateFlags.Position; | ||||
| 
 | ||||
|             #endregion PrimUpdateFlags Management | ||||
| 
 | ||||
|             if (updateFlags != PrimUpdateFlags.None) | ||||
|             { | ||||
|                 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes | ||||
|                 { | ||||
|                     AddFullUpdateToAllAvatars(); | ||||
|                     ClearUpdateSchedule(); | ||||
|                 } | ||||
|                 AddUpdateToAllAvatars(updateFlags); | ||||
| 
 | ||||
|                 // Update the "last" values | ||||
|                 m_lastPosition = RelativePosition; | ||||
|                 m_lastRotation = RotationOffset; | ||||
|                 m_lastVelocity = Velocity; | ||||
|                 m_lastAcceleration = Acceleration; | ||||
|                 m_lastAngularVelocity = AngularVelocity; | ||||
|                 m_lastTerseSent = Environment.TickCount; | ||||
|             } | ||||
|             ClearUpdateSchedule(); | ||||
| 
 | ||||
|             ClearPendingUpdate(); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -3075,17 +2974,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Send a terse update to all clients | ||||
|         /// </summary> | ||||
|         public void SendTerseUpdateToAllClients() | ||||
|         { | ||||
|             m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) | ||||
|             { | ||||
|                 SendTerseUpdateToClient(avatar.ControllingClient); | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         public void SetAttachmentPoint(uint AttachmentPoint) | ||||
|         { | ||||
|             this.AttachmentPoint = AttachmentPoint; | ||||
|  | @ -3386,7 +3274,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             _groupID = groupID; | ||||
|             if (client != null) | ||||
|                 GetProperties(client); | ||||
|             m_updateFlag = 2; | ||||
|             m_pendingUpdateFlags |= PrimUpdateFlags.FullUpdate; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -3448,14 +3336,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             Text = text; | ||||
| 
 | ||||
|             ParentGroup.HasGroupChanged = true; | ||||
|             ScheduleFullUpdate(); | ||||
|             ScheduleUpdate(PrimUpdateFlags.Text); | ||||
|         } | ||||
|          | ||||
|         public void StopLookAt() | ||||
|         { | ||||
|             m_parentGroup.stopLookAt(); | ||||
| 
 | ||||
|             m_parentGroup.ScheduleGroupForTerseUpdate(); | ||||
|             m_parentGroup.RootPart.ScheduleUpdate(PrimUpdateFlags.Rotation); | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|  | @ -3476,9 +3363,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         public void StopMoveToTarget() | ||||
|         { | ||||
|             m_parentGroup.stopMoveToTarget(); | ||||
| 
 | ||||
|             m_parentGroup.ScheduleGroupForTerseUpdate(); | ||||
|             //m_parentGroup.ScheduleGroupForFullUpdate(); | ||||
|             m_parentGroup.RootPart.ScheduleUpdate(PrimUpdateFlags.Position | PrimUpdateFlags.Rotation); | ||||
|         } | ||||
| 
 | ||||
|         public void StoreUndoState() | ||||
|  | @ -4025,7 +3910,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
| 
 | ||||
|             ParentGroup.HasGroupChanged = true; | ||||
|             ScheduleFullUpdate(); | ||||
|             ScheduleUpdate(PrimUpdateFlags.ExtraData); | ||||
|         } | ||||
| 
 | ||||
|         public void UpdateGroupPosition(Vector3 pos) | ||||
|  | @ -4036,7 +3921,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             { | ||||
|                 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); | ||||
|                 GroupPosition = newPos; | ||||
|                 ScheduleTerseUpdate(); | ||||
|                 ScheduleUpdate(PrimUpdateFlags.Position); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -4054,21 +3939,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 (pos.Y != OffsetPosition.Y) || | ||||
|                 (pos.Z != OffsetPosition.Z)) | ||||
|             { | ||||
|                 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); | ||||
| 
 | ||||
|                 if (ParentGroup.RootPart.GetStatusSandbox()) | ||||
|                 { | ||||
|                     if (Util.GetDistanceTo(ParentGroup.RootPart.StatusSandboxPos, newPos) > 10) | ||||
|                     if (Util.GetDistanceTo(ParentGroup.RootPart.StatusSandboxPos, pos) > 10) | ||||
|                     { | ||||
|                         ParentGroup.RootPart.ScriptSetPhysicsStatus(false); | ||||
|                         newPos = OffsetPosition; | ||||
|                         pos = OffsetPosition; | ||||
|                         ParentGroup.Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"), | ||||
|                               ChatTypeEnum.DebugChannel, 0x7FFFFFFF, ParentGroup.RootPart.AbsolutePosition, Name, UUID, false); | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 OffsetPosition = newPos; | ||||
|                 ScheduleTerseUpdate(); | ||||
|                 OffsetPosition = pos; | ||||
|                 ScheduleUpdate(PrimUpdateFlags.Position); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -4111,10 +3994,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                                 baseMask; | ||||
|                         break; | ||||
|                 } | ||||
|                 SendFullUpdateToAllClients(); | ||||
| 
 | ||||
|                 SendUpdateToAllClients(PrimUpdateFlags.PrimFlags); | ||||
|                 SendObjectPropertiesToClient(AgentID); | ||||
| 
 | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -4349,7 +4231,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             //            m_log.Debug("Update:  PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); | ||||
| 
 | ||||
|             ParentGroup.HasGroupChanged = true; | ||||
|             ScheduleFullUpdate(); | ||||
|             ScheduleUpdate(PrimUpdateFlags.PrimFlags); | ||||
|         } | ||||
| 
 | ||||
|         public void UpdateRotation(Quaternion rot) | ||||
|  | @ -4361,7 +4243,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             { | ||||
|                 RotationOffset = rot; | ||||
|                 ParentGroup.HasGroupChanged = true; | ||||
|                 ScheduleTerseUpdate(); | ||||
|                 ScheduleUpdate(PrimUpdateFlags.Rotation); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -4405,7 +4287,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 ParentGroup.RootPart.Rezzed = DateTime.UtcNow; | ||||
| 
 | ||||
|             ParentGroup.HasGroupChanged = true; | ||||
|             ScheduleFullUpdate(); | ||||
|             ScheduleUpdate(PrimUpdateFlags.PrimData); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -4452,7 +4334,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             //This is madness.. | ||||
|             //ParentGroup.ScheduleGroupForFullUpdate(); | ||||
|             //This is sparta | ||||
|             ScheduleFullUpdate(); | ||||
|             ScheduleUpdate(PrimUpdateFlags.Textures); | ||||
|         } | ||||
| 
 | ||||
|         public void aggregateScriptEvents() | ||||
|  | @ -4520,7 +4402,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             { | ||||
| //                m_log.DebugFormat( | ||||
| //                    "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents() since m_parentGroup == null", Name, LocalId); | ||||
|                 ScheduleFullUpdate(); | ||||
|                 ScheduleUpdate(PrimUpdateFlags.FullUpdate); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|  | @ -4543,7 +4425,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             { | ||||
| //                m_log.DebugFormat( | ||||
| //                    "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents()", Name, LocalId); | ||||
|                 ScheduleFullUpdate(); | ||||
|                 ScheduleUpdate(PrimUpdateFlags.FullUpdate); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -4617,35 +4499,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         } | ||||
| 
 | ||||
|         #endregion Public Methods | ||||
| 
 | ||||
|         public void SendTerseUpdateToClient(IClientAPI remoteClient) | ||||
|         { | ||||
|             if (ParentGroup == null || ParentGroup.IsDeleted) | ||||
|                 return; | ||||
| 
 | ||||
|             Vector3 lPos = OffsetPosition; | ||||
| 
 | ||||
|             if (IsAttachment) | ||||
|             { | ||||
|                 if (ParentGroup.RootPart != this) | ||||
|                     return; | ||||
| 
 | ||||
|                 lPos = ParentGroup.RootPart.AttachedPos; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 if (ParentGroup.RootPart == this) | ||||
|                     lPos = AbsolutePosition; | ||||
|             } | ||||
|              | ||||
|             // Causes this thread to dig into the Client Thread Data. | ||||
|             // Remember your locking here! | ||||
|             remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle, | ||||
|                     m_parentGroup.GetTimeDilation(), LocalId, lPos, | ||||
|                     RotationOffset, Velocity, Acceleration, | ||||
|                     AngularVelocity, FromItemID, | ||||
|                     OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient))); | ||||
|         } | ||||
|                  | ||||
|         public void AddScriptLPS(int count) | ||||
|         { | ||||
|  | @ -4694,7 +4547,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
| 
 | ||||
|         public Color4 GetTextColor() | ||||
|         { | ||||
|             return new Color4((byte)Color.R, (byte)Color.G, (byte)Color.B, (byte)(0xFF - Color.A)); | ||||
|             return new Color4(m_color.R, m_color.G, m_color.B, (byte)(255 - m_color.A)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -278,7 +278,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | ||||
|                         m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); | ||||
|                     m_part.ParentGroup.AddActiveScriptCount(1); | ||||
|                     m_part.ScheduleFullUpdate(); | ||||
|                     m_part.ScheduleUpdate(PrimUpdateFlags.FullUpdate); | ||||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|  | @ -306,7 +306,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | ||||
|                         m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); | ||||
|                     m_part.ParentGroup.AddActiveScriptCount(1); | ||||
|                     m_part.ScheduleFullUpdate(); | ||||
|                     m_part.ScheduleUpdate(PrimUpdateFlags.FullUpdate); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | @ -697,7 +697,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                         m_part.RemFlag(PrimFlags.Scripted); | ||||
|                     } | ||||
| 
 | ||||
|                     m_part.ScheduleFullUpdate(); | ||||
|                     m_part.ScheduleUpdate(PrimUpdateFlags.FullUpdate); | ||||
| 
 | ||||
|                     return type; | ||||
|                 } | ||||
|  |  | |||
|  | @ -67,7 +67,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
| 
 | ||||
|     public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence); | ||||
| 
 | ||||
|     public class ScenePresence : EntityBase | ||||
|     public class ScenePresence : EntityBase, ISceneEntity | ||||
|     { | ||||
| //        ~ScenePresence() | ||||
| //        { | ||||
|  | @ -479,6 +479,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public Vector3 OffsetPosition | ||||
|         { | ||||
|             get { return m_pos; } | ||||
|             set { m_pos = value; } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Current velocity of the avatar. | ||||
|         /// </summary> | ||||
|  | @ -777,15 +783,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         /// <summary> | ||||
|         /// Add the part to the queue of parts for which we need to send an update to the client | ||||
|         /// </summary> | ||||
|         /// <param name="part"></param> | ||||
|         public void QueuePartForUpdate(SceneObjectPart part) | ||||
|         public void QueuePartForUpdate(SceneObjectPart part, PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|             m_sceneViewer.QueuePartForUpdate(part); | ||||
|         } | ||||
| 
 | ||||
|         public uint GenerateClientFlags(UUID ObjectID) | ||||
|         { | ||||
|             return m_scene.Permissions.GenerateClientFlags(m_uuid, ObjectID); | ||||
|             m_sceneViewer.QueuePartForUpdate(part, updateFlags); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -1032,8 +1032,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); | ||||
|             } | ||||
| 
 | ||||
|             ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, | ||||
|                     AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); | ||||
|             CollisionPlane = new Vector4(0f, 0f, 1f, AbsolutePosition.Z - 0.5f); | ||||
| 
 | ||||
|             ControllingClient.SendEntityUpdate(GetUpdatePriority(ControllingClient), this, PrimUpdateFlags.Position | PrimUpdateFlags.Velocity); | ||||
|         } | ||||
| 
 | ||||
|         public void AddNeighbourRegion(ulong regionHandle, string cap) | ||||
|  | @ -1571,7 +1572,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             // Commented out this code since it could never have executed, but might still be informative. | ||||
| //            if (proxyObjectGroup != null) | ||||
| //            { | ||||
|                 proxyObjectGroup.SendGroupFullUpdate(); | ||||
|                 proxyObjectGroup.SendGroupUpdate(PrimUpdateFlags.FullUpdate); | ||||
|                 remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); | ||||
|                 m_scene.DeleteSceneObject(proxyObjectGroup, false); | ||||
| //            } | ||||
|  | @ -2356,8 +2357,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
| 
 | ||||
|                 //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); | ||||
| 
 | ||||
|                 remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, | ||||
|                     pos, velocity, Vector3.Zero, m_bodyRot, CollisionPlane, m_uuid, null, GetUpdatePriority(remoteClient))); | ||||
|                 remoteClient.SendEntityUpdate(GetUpdatePriority(remoteClient), this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation |  | ||||
|                     PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity | PrimUpdateFlags.CollisionPlane); | ||||
| 
 | ||||
|                 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | ||||
|                 m_scene.StatsReporter.AddAgentUpdates(1); | ||||
|  | @ -2453,9 +2454,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             Vector3 pos = m_pos; | ||||
|             pos.Z += m_appearance.HipOffset; | ||||
| 
 | ||||
|             remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, | ||||
|                                                             LocalId, pos, m_appearance.Texture.GetBytes(), | ||||
|                                                             m_parentID, m_bodyRot)); | ||||
|             remoteAvatar.m_controllingClient.SendEntityUpdate(GetUpdatePriority(remoteAvatar.m_controllingClient), this, PrimUpdateFlags.FullUpdate); | ||||
| 
 | ||||
|             m_scene.StatsReporter.AddAgentUpdates(1); | ||||
|         } | ||||
| 
 | ||||
|  | @ -2523,8 +2523,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             Vector3 pos = m_pos; | ||||
|             pos.Z += m_appearance.HipOffset; | ||||
| 
 | ||||
|             m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, | ||||
|                                                pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot)); | ||||
|             m_controllingClient.SendEntityUpdate(GetUpdatePriority(m_controllingClient), this, PrimUpdateFlags.FullUpdate); | ||||
| 
 | ||||
|             SendInitialFullUpdateToAllClients(); | ||||
|             SendAppearanceToAllOtherAgents(); | ||||
|  | @ -2634,9 +2633,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             Vector3 pos = m_pos; | ||||
|             pos.Z += m_appearance.HipOffset; | ||||
| 
 | ||||
|             m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, | ||||
|                 pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot)); | ||||
| 
 | ||||
|             m_controllingClient.SendEntityUpdate(GetUpdatePriority(m_controllingClient), this, PrimUpdateFlags.Textures); | ||||
|         } | ||||
| 
 | ||||
|         public void SetWearable(int wearableId, AvatarWearable wearable) | ||||
|  | @ -3902,7 +3899,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
| 
 | ||||
|         private void Reprioritize(object sender, ElapsedEventArgs e) | ||||
|         { | ||||
|             m_controllingClient.ReprioritizeUpdates(StateUpdateTypes.All, UpdatePriority); | ||||
|             m_controllingClient.ReprioritizeUpdates(UpdatePriority); | ||||
| 
 | ||||
|             lock (m_reprioritization_timer) | ||||
|             { | ||||
|  |  | |||
|  | @ -38,6 +38,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
| { | ||||
|     public class SceneViewer : ISceneViewer | ||||
|     { | ||||
|         public class ScenePartUpdate | ||||
|         { | ||||
|             public UUID FullID; | ||||
|             public uint LastUpdateTime; | ||||
|         } | ||||
| 
 | ||||
|         protected ScenePresence m_presence; | ||||
|         protected UpdateQueue m_partsUpdateQueue = new UpdateQueue(); | ||||
|         protected Queue<SceneObjectGroup> m_pendingObjects; | ||||
|  | @ -56,13 +62,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
|         /// <summary> | ||||
|         /// Add the part to the queue of parts for which we need to send an update to the client | ||||
|         /// </summary> | ||||
|         /// <param name="part"></param> | ||||
|         public void QueuePartForUpdate(SceneObjectPart part) | ||||
|         public void QueuePartForUpdate(SceneObjectPart part, PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|             lock (m_partsUpdateQueue) | ||||
|             { | ||||
|                 m_partsUpdateQueue.Enqueue(part); | ||||
|             } | ||||
|                 m_partsUpdateQueue.Enqueue(part, updateFlags); | ||||
|         } | ||||
| 
 | ||||
|         public void SendPrimUpdates() | ||||
|  | @ -94,14 +97,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                 // Don't even queue if we have sent this one | ||||
|                 // | ||||
|                 if (!m_updateTimes.ContainsKey(g.UUID)) | ||||
|                     g.ScheduleFullUpdateToAvatar(m_presence); | ||||
|                     g.ScheduleUpdateToAvatar(m_presence, PrimUpdateFlags.FullUpdate); | ||||
|             } | ||||
| 
 | ||||
|             while (m_partsUpdateQueue.Count > 0) | ||||
|             SceneObjectPart part; | ||||
|             PrimUpdateFlags updateFlags; | ||||
| 
 | ||||
|             while (m_partsUpdateQueue.TryDequeue(out part, out updateFlags)) | ||||
|             { | ||||
|                 SceneObjectPart part = m_partsUpdateQueue.Dequeue(); | ||||
|                  | ||||
|                 if (part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||||
|                 if (part.ParentGroup.IsDeleted) | ||||
|                     continue; | ||||
|                  | ||||
|                 if (m_updateTimes.ContainsKey(part.UUID)) | ||||
|  | @ -111,15 +115,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     // We deal with the possibility that two updates occur at | ||||
|                     // the same unix time at the update point itself. | ||||
| 
 | ||||
|                     if ((update.LastFullUpdateTime < part.TimeStampFull) || | ||||
|                             part.IsAttachment) | ||||
|                     if ((update.LastUpdateTime < part.TimeStampUpdate) || part.IsAttachment) | ||||
|                     { | ||||
| //                            m_log.DebugFormat( | ||||
| //                                "[SCENE PRESENCE]: Fully   updating prim {0}, {1} - part timestamp {2}", | ||||
| //                                part.Name, part.UUID, part.TimeStampFull); | ||||
| 
 | ||||
|                         part.SendFullUpdate(m_presence.ControllingClient, | ||||
|                                m_presence.GenerateClientFlags(part.UUID)); | ||||
|                         part.SendUpdateToClient(m_presence.ControllingClient, updateFlags); | ||||
| 
 | ||||
|                         // We'll update to the part's timestamp rather than | ||||
|                         // the current time to avoid the race condition | ||||
|  | @ -128,18 +130,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                         // updates which occurred on the same tick or the | ||||
|                         // next tick of the last update would be ignored. | ||||
| 
 | ||||
|                         update.LastFullUpdateTime = part.TimeStampFull; | ||||
| 
 | ||||
|                     } | ||||
|                     else if (update.LastTerseUpdateTime <= part.TimeStampTerse) | ||||
|                     { | ||||
| //                            m_log.DebugFormat( | ||||
| //                                "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", | ||||
| //                                part.Name, part.UUID, part.TimeStampTerse); | ||||
| 
 | ||||
|                         part.SendTerseUpdateToClient(m_presence.ControllingClient); | ||||
| 
 | ||||
|                         update.LastTerseUpdateTime = part.TimeStampTerse; | ||||
|                         update.LastUpdateTime = part.TimeStampUpdate; | ||||
|                     } | ||||
|                 } | ||||
|                 else | ||||
|  | @ -147,7 +138,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                     //never been sent to client before so do full update | ||||
|                     ScenePartUpdate update = new ScenePartUpdate(); | ||||
|                     update.FullID = part.UUID; | ||||
|                     update.LastFullUpdateTime = part.TimeStampFull; | ||||
|                     update.LastUpdateTime = part.TimeStampUpdate; | ||||
|                     m_updateTimes.Add(part.UUID, update); | ||||
| 
 | ||||
|                     // Attachment handling | ||||
|  | @ -157,12 +148,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
|                         if (part != part.ParentGroup.RootPart) | ||||
|                             continue; | ||||
| 
 | ||||
|                         part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient); | ||||
|                         part.ParentGroup.SendUpdateToClient(m_presence.ControllingClient, PrimUpdateFlags.FullUpdate); | ||||
|                         continue; | ||||
|                     } | ||||
| 
 | ||||
|                     part.SendFullUpdate(m_presence.ControllingClient, | ||||
|                             m_presence.GenerateClientFlags(part.UUID)); | ||||
|                     part.SendUpdateToClient(m_presence.ControllingClient, PrimUpdateFlags.FullUpdate); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | @ -192,19 +182,5 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             } | ||||
|             Reset(); | ||||
|         } | ||||
| 
 | ||||
|         public class ScenePartUpdate | ||||
|         { | ||||
|             public UUID FullID; | ||||
|             public uint LastFullUpdateTime; | ||||
|             public uint LastTerseUpdateTime; | ||||
| 
 | ||||
|             public ScenePartUpdate() | ||||
|             { | ||||
|                 FullID = UUID.Zero; | ||||
|                 LastFullUpdateTime = 0; | ||||
|                 LastTerseUpdateTime = 0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -72,8 +72,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
|             grp2.UpdateGroupRotationR(Quaternion.CreateFromEulers(180 * Utils.DEG_TO_RAD, 0, 0)); | ||||
|              | ||||
|             // Required for linking | ||||
|             grp1.RootPart.UpdateFlag = 0; | ||||
|             grp2.RootPart.UpdateFlag = 0; | ||||
|             grp1.RootPart.ClearPendingUpdate(); | ||||
|             grp2.RootPart.ClearPendingUpdate(); | ||||
| 
 | ||||
|             // Link grp2 to grp1.   part2 becomes child prim to grp1. grp2 is eliminated. | ||||
|             grp1.LinkToGroup(grp2); | ||||
|  | @ -165,10 +165,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
|             grp4.UpdateGroupRotationR(Quaternion.CreateFromEulers(0, 90 * Utils.DEG_TO_RAD, 0)); | ||||
| 
 | ||||
|             // Required for linking | ||||
|             grp1.RootPart.UpdateFlag = 0; | ||||
|             grp2.RootPart.UpdateFlag = 0; | ||||
|             grp3.RootPart.UpdateFlag = 0; | ||||
|             grp4.RootPart.UpdateFlag = 0; | ||||
|             grp1.RootPart.ClearPendingUpdate(); | ||||
|             grp2.RootPart.ClearPendingUpdate(); | ||||
|             grp3.RootPart.ClearPendingUpdate(); | ||||
|             grp4.RootPart.ClearPendingUpdate(); | ||||
| 
 | ||||
|             // Link grp2 to grp1.   part2 becomes child prim to grp1. grp2 is eliminated. | ||||
|             grp1.LinkToGroup(grp2); | ||||
|  | @ -199,8 +199,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
|             } | ||||
| 
 | ||||
|             // Required for linking | ||||
|             grp1.RootPart.UpdateFlag = 0; | ||||
|             grp3.RootPart.UpdateFlag = 0; | ||||
|             grp1.RootPart.ClearPendingUpdate(); | ||||
|             grp3.RootPart.ClearPendingUpdate(); | ||||
| 
 | ||||
|             // root part should have no offset position or rotation | ||||
|             Assert.That(part1.OffsetPosition == Vector3.Zero && part1.RotationOffset == Quaternion.Identity, | ||||
|  |  | |||
|  | @ -30,16 +30,21 @@ using System.Collections.Generic; | |||
| using System.Runtime.Serialization; | ||||
| using System.Security.Permissions; | ||||
| using OpenMetaverse; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Region.Framework.Scenes; | ||||
| 
 | ||||
| namespace OpenSim.Region.Framework.Scenes.Types | ||||
| { | ||||
|     public class UpdateQueue | ||||
|     { | ||||
|         private Queue<SceneObjectPart> m_queue; | ||||
| 
 | ||||
|         private Dictionary<UUID, bool> m_ids; | ||||
|         private struct Update | ||||
|         { | ||||
|             public SceneObjectPart Entity; | ||||
|             public PrimUpdateFlags UpdateFlags; | ||||
|         } | ||||
| 
 | ||||
|         private Queue<Update> m_queue; | ||||
|         private HashSet<UUID> m_ids; | ||||
|         private object m_syncObject = new object(); | ||||
| 
 | ||||
|         public int Count | ||||
|  | @ -49,8 +54,8 @@ namespace OpenSim.Region.Framework.Scenes.Types | |||
| 
 | ||||
|         public UpdateQueue() | ||||
|         { | ||||
|             m_queue = new Queue<SceneObjectPart>(); | ||||
|             m_ids = new Dictionary<UUID, bool>(); | ||||
|             m_queue = new Queue<Update>(); | ||||
|             m_ids = new HashSet<UUID>(); | ||||
|         } | ||||
| 
 | ||||
|         public void Clear() | ||||
|  | @ -62,30 +67,33 @@ namespace OpenSim.Region.Framework.Scenes.Types | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void Enqueue(SceneObjectPart part) | ||||
|         public void Enqueue(SceneObjectPart part, PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|             lock (m_syncObject) | ||||
|             { | ||||
|                 if (!m_ids.ContainsKey(part.UUID)) { | ||||
|                     m_ids.Add(part.UUID, true); | ||||
|                     m_queue.Enqueue(part); | ||||
|                 } | ||||
|                 if (m_ids.Add(part.UUID)) | ||||
|                     m_queue.Enqueue(new Update { Entity = part, UpdateFlags = updateFlags }); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public SceneObjectPart Dequeue() | ||||
|         public bool TryDequeue(out SceneObjectPart part, out PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|             SceneObjectPart part = null; | ||||
|             lock (m_syncObject) | ||||
|             { | ||||
|                 if (m_queue.Count > 0) | ||||
|                 { | ||||
|                     part = m_queue.Dequeue(); | ||||
|                     Update update = m_queue.Dequeue(); | ||||
|                     part = update.Entity; | ||||
|                     updateFlags = update.UpdateFlags; | ||||
| 
 | ||||
|                     m_ids.Remove(part.UUID); | ||||
|                     return true; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return part; | ||||
|             part = null; | ||||
|             updateFlags = 0; | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ | |||
|  */ | ||||
| 
 | ||||
| using OpenMetaverse; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Region.Framework.Interfaces; | ||||
| 
 | ||||
| namespace OpenSim.Region.Framework.Scenes | ||||
|  | @ -41,17 +42,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             if (part != null) | ||||
|             { | ||||
|                 if (part.ParentID == 0) | ||||
|                 { | ||||
|                     Position = part.ParentGroup.AbsolutePosition; | ||||
|                     Rotation = part.RotationOffset; | ||||
|                     Scale = part.Shape.Scale; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     Position = part.OffsetPosition; | ||||
|                     Rotation = part.RotationOffset; | ||||
|                     Scale = part.Shape.Scale; | ||||
|                 } | ||||
| 
 | ||||
|                 Rotation = part.RotationOffset; | ||||
|                 Scale = part.Shape.Scale; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -83,56 +79,48 @@ namespace OpenSim.Region.Framework.Scenes | |||
|             if (part != null) | ||||
|             { | ||||
|                 part.Undoing = true; | ||||
|                 PrimUpdateFlags updateFlags = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation; | ||||
| 
 | ||||
|                 if (part.ParentID == 0) | ||||
|                 { | ||||
|                     if (Position != Vector3.Zero) | ||||
|                         part.ParentGroup.AbsolutePosition = Position; | ||||
|                     part.RotationOffset = Rotation; | ||||
|                     if (Scale != Vector3.Zero) | ||||
|                         part.Resize(Scale); | ||||
|                     part.ParentGroup.ScheduleGroupForTerseUpdate(); | ||||
|                 } | ||||
|                     part.ParentGroup.AbsolutePosition = Position; | ||||
|                 else | ||||
|                 { | ||||
|                     if (Position != Vector3.Zero) | ||||
|                         part.OffsetPosition = Position; | ||||
|                     part.UpdateRotation(Rotation); | ||||
|                     if (Scale != Vector3.Zero) | ||||
|                         part.Resize(Scale); part.ScheduleTerseUpdate(); | ||||
|                 } | ||||
|                 part.Undoing = false; | ||||
|                     part.OffsetPosition = Position; | ||||
| 
 | ||||
|                 part.RotationOffset = Rotation; | ||||
| 
 | ||||
|                 if (Scale != part.Scale) | ||||
|                 { | ||||
|                     part.Scale = Scale; | ||||
|                     updateFlags |= PrimUpdateFlags.Scale; | ||||
|                 } | ||||
| 
 | ||||
|                 part.Undoing = false; | ||||
|                 part.ScheduleUpdate(updateFlags); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void PlayfwdState(SceneObjectPart part) | ||||
|         { | ||||
|             if (part != null) | ||||
|             { | ||||
|                 part.Undoing = true; | ||||
|                 PrimUpdateFlags updateFlags = PrimUpdateFlags.Position | PrimUpdateFlags.Rotation; | ||||
| 
 | ||||
|                 if (part.ParentID == 0) | ||||
|                 { | ||||
|                     if (Position != Vector3.Zero) | ||||
|                         part.ParentGroup.AbsolutePosition = Position; | ||||
|                     if (Rotation != Quaternion.Identity) | ||||
|                         part.UpdateRotation(Rotation); | ||||
|                     if (Scale != Vector3.Zero) | ||||
|                         part.Resize(Scale); | ||||
|                     part.ParentGroup.ScheduleGroupForTerseUpdate(); | ||||
|                 } | ||||
|                     part.ParentGroup.AbsolutePosition = Position; | ||||
|                 else | ||||
|                 { | ||||
|                     if (Position != Vector3.Zero) | ||||
|                         part.OffsetPosition = Position; | ||||
|                     if (Rotation != Quaternion.Identity) | ||||
|                         part.UpdateRotation(Rotation); | ||||
|                     if (Scale != Vector3.Zero) | ||||
|                         part.Resize(Scale); | ||||
|                     part.ScheduleTerseUpdate(); | ||||
|                 } | ||||
|                 part.Undoing = false; | ||||
|                     part.OffsetPosition = Position; | ||||
| 
 | ||||
|                 part.RotationOffset = Rotation; | ||||
| 
 | ||||
|                 if (Scale != part.Scale) | ||||
|                 { | ||||
|                     part.Scale = Scale; | ||||
|                     updateFlags |= PrimUpdateFlags.Scale; | ||||
|                 } | ||||
| 
 | ||||
|                 part.Undoing = false; | ||||
|                 part.ScheduleUpdate(updateFlags); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -1045,21 +1045,15 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
|              | ||||
|         } | ||||
| 
 | ||||
|         public void SendAvatarData(SendAvatarData data) | ||||
|         { | ||||
|              | ||||
|         } | ||||
| 
 | ||||
|         public void SendAvatarTerseUpdate(SendAvatarTerseData data) | ||||
|         { | ||||
|              | ||||
|         } | ||||
| 
 | ||||
|         public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) | ||||
|         { | ||||
|              | ||||
|         } | ||||
| 
 | ||||
|         public void SendEntityUpdate(double priority, ISceneEntity entity, PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||||
|         { | ||||
|              | ||||
|  | @ -1070,17 +1064,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
|              | ||||
|         } | ||||
| 
 | ||||
|         public void SendPrimitiveToClient(SendPrimitiveData data) | ||||
|         { | ||||
|              | ||||
|         } | ||||
| 
 | ||||
|         public void SendPrimTerseUpdate(SendPrimitiveTerseData data) | ||||
|         { | ||||
|              | ||||
|         } | ||||
| 
 | ||||
|         public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) | ||||
|         public void ReprioritizeUpdates(UpdatePriorityHandler handler) | ||||
|         { | ||||
| 
 | ||||
|         } | ||||
|  |  | |||
|  | @ -284,7 +284,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
|                         ((SceneObjectGroup)ent).ApplyPhysics(true); | ||||
|                     ((SceneObjectGroup)ent).AttachToBackup(); | ||||
|                     ((SceneObjectGroup)ent).HasGroupChanged = true; // If not true, then attaching to backup does nothing because no change is detected. | ||||
|                     ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(); | ||||
|                     ((SceneObjectGroup)ent).ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); | ||||
|                 } | ||||
|                 catch(Exception e) | ||||
|                 { | ||||
|  |  | |||
|  | @ -193,20 +193,14 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
| 
 | ||||
|         public void SendFullUpdate(IClientAPI client) | ||||
|         { | ||||
|             // Not sure what clientFlags should be but 0 seems to work | ||||
|             SendFullUpdate(client, 0); | ||||
|         } | ||||
| 
 | ||||
|         public void SendFullUpdate(IClientAPI client, uint clientFlags) | ||||
|         { | ||||
|             m_Entity.SendFullUpdateToClient(client); | ||||
|             m_Entity.SendUpdateToClient(client, PrimUpdateFlags.FullUpdate); | ||||
|         } | ||||
| 
 | ||||
|         public void SendFullUpdateToAll() | ||||
|         { | ||||
|             m_Entity.Scene.ForEachClient( | ||||
|                 delegate(IClientAPI controller) | ||||
|                 { m_Entity.SendFullUpdateToClient(controller); } | ||||
|                 delegate(IClientAPI client) | ||||
|                 { m_Entity.SendUpdateToClient(client, PrimUpdateFlags.FullUpdate); } | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -618,18 +618,14 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendAvatarData(SendAvatarData data) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public void SendEntityUpdate(double priority, ISceneEntity entity, PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||||
|         { | ||||
|         } | ||||
|  | @ -638,15 +634,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendPrimitiveToClient(SendPrimitiveData data) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) | ||||
|         public virtual void ReprioritizeUpdates(UpdatePriorityHandler handler) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -641,7 +641,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator | |||
|                             { | ||||
|                                 s_tree.Scale += copse.m_rate; | ||||
|                                 s_tree.ParentGroup.HasGroupChanged = true; | ||||
|                                 s_tree.ScheduleFullUpdate(); | ||||
|                                 s_tree.ScheduleUpdate(PrimUpdateFlags.Scale); | ||||
|                             } | ||||
|                         } | ||||
|                         else | ||||
|  | @ -773,7 +773,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator | |||
| 
 | ||||
|                 tree.Name = copse.ToString(); | ||||
|                 copse.m_trees.Add(tree.UUID); | ||||
|                 tree.SendGroupFullUpdate(); | ||||
|                 tree.SendGroupUpdate(PrimUpdateFlags.FullUpdate); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1329,7 +1329,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             tmp.Y = (float)scale.y; | ||||
|             tmp.Z = (float)scale.z; | ||||
|             part.Scale = tmp; | ||||
|             part.SendFullUpdateToAllClients(); | ||||
|             part.SendUpdateToAllClients(PrimUpdateFlags.Scale); | ||||
|         } | ||||
| 
 | ||||
|         public LSL_Vector llGetScale() | ||||
|  | @ -1343,7 +1343,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             m_host.AddScriptLPS(1); | ||||
|             m_host.ClickAction = (byte)action; | ||||
|             if (m_host.ParentGroup != null) m_host.ParentGroup.HasGroupChanged = true; | ||||
|             m_host.ScheduleFullUpdate(); | ||||
|             m_host.ScheduleUpdate(PrimUpdateFlags.PrimFlags); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|  | @ -1595,7 +1595,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             } | ||||
| 
 | ||||
|             part.ParentGroup.HasGroupChanged = true; | ||||
|             part.ScheduleFullUpdate(); | ||||
|             part.ScheduleUpdate(PrimUpdateFlags.ExtraData); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -1630,7 +1630,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             } | ||||
| 
 | ||||
|             part.ParentGroup.HasGroupChanged = true; | ||||
|             part.ScheduleFullUpdate(); | ||||
|             part.ScheduleUpdate(PrimUpdateFlags.ExtraData); | ||||
|         } | ||||
| 
 | ||||
|         public LSL_Vector llGetColor(int face) | ||||
|  | @ -1913,7 +1913,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                     part.OffsetPosition = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z); | ||||
|                     SceneObjectGroup parent = part.ParentGroup; | ||||
|                     parent.HasGroupChanged = true; | ||||
|                     parent.ScheduleGroupForTerseUpdate(); | ||||
|                     part.ScheduleUpdate(PrimUpdateFlags.Position); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | @ -2245,8 +2245,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             m_host.SoundFlags = 1;      // looping | ||||
|             m_host.SoundRadius = 20;    // Magic number, 20 seems reasonable. Make configurable? | ||||
| 
 | ||||
|             m_host.ScheduleFullUpdate(); | ||||
|             m_host.SendFullUpdateToAllClients(); | ||||
|             m_host.ScheduleUpdate(PrimUpdateFlags.Sound); | ||||
|             m_host.SendUpdateToAllClients(PrimUpdateFlags.Sound); | ||||
|         } | ||||
| 
 | ||||
|         public void llLoopSoundMaster(string sound, double volume) | ||||
|  | @ -2265,8 +2265,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                     prim.SoundFlags = 1;      // looping | ||||
|                     prim.SoundRadius = 20;    // Magic number, 20 seems reasonable. Make configurable? | ||||
| 
 | ||||
|                     prim.ScheduleFullUpdate(); | ||||
|                     prim.SendFullUpdateToAllClients(); | ||||
|                     prim.ScheduleUpdate(PrimUpdateFlags.Sound); | ||||
|                     prim.SendUpdateToAllClients(PrimUpdateFlags.Sound); | ||||
|                 } | ||||
|             } | ||||
|             if (m_host.Sound != UUID.Zero) | ||||
|  | @ -2277,8 +2277,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             m_host.SoundFlags = 1;      // looping | ||||
|             m_host.SoundRadius = 20;    // Magic number, 20 seems reasonable. Make configurable? | ||||
| 
 | ||||
|             m_host.ScheduleFullUpdate(); | ||||
|             m_host.SendFullUpdateToAllClients(); | ||||
|             m_host.ScheduleUpdate(PrimUpdateFlags.Sound); | ||||
|             m_host.SendUpdateToAllClients(PrimUpdateFlags.Sound); | ||||
|         } | ||||
| 
 | ||||
|         public void llLoopSoundSlave(string sound, double volume) | ||||
|  | @ -2319,8 +2319,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                         part.SoundGain = 0; | ||||
|                         part.SoundFlags = 0; | ||||
|                         part.SoundRadius = 0; | ||||
|                         part.ScheduleFullUpdate(); | ||||
|                         part.SendFullUpdateToAllClients(); | ||||
|                         part.ScheduleUpdate(PrimUpdateFlags.Sound); | ||||
|                         part.SendUpdateToAllClients(PrimUpdateFlags.Sound); | ||||
|                     } | ||||
|                     m_host.ParentGroup.LoopSoundMasterPrim = null; | ||||
|                     m_host.ParentGroup.LoopSoundSlavePrims.Clear(); | ||||
|  | @ -2331,8 +2331,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                     m_host.SoundGain = 0; | ||||
|                     m_host.SoundFlags = 0; | ||||
|                     m_host.SoundRadius = 0; | ||||
|                     m_host.ScheduleFullUpdate(); | ||||
|                     m_host.SendFullUpdateToAllClients(); | ||||
|                     m_host.ScheduleUpdate(PrimUpdateFlags.Sound); | ||||
|                     m_host.SendUpdateToAllClients(PrimUpdateFlags.Sound); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|  | @ -2341,8 +2341,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                 m_host.SoundGain = 0; | ||||
|                 m_host.SoundFlags = 0; | ||||
|                 m_host.SoundRadius = 0; | ||||
|                 m_host.ScheduleFullUpdate(); | ||||
|                 m_host.SendFullUpdateToAllClients(); | ||||
|                 m_host.ScheduleUpdate(PrimUpdateFlags.Sound); | ||||
|                 m_host.SendUpdateToAllClients(PrimUpdateFlags.Sound); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -3240,8 +3240,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|         { | ||||
|             m_host.AddScriptLPS(1); | ||||
|             m_host.AngularVelocity = new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate)); | ||||
|             m_host.ScheduleTerseUpdate(); | ||||
|             m_host.SendTerseUpdateToAllClients(); | ||||
|             m_host.ScheduleUpdate(PrimUpdateFlags.AngularVelocity); | ||||
|             m_host.SendUpdateToAllClients(PrimUpdateFlags.AngularVelocity); | ||||
|             m_host.ParentGroup.HasGroupChanged = true; | ||||
|         } | ||||
| 
 | ||||
|  | @ -3507,7 +3507,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                     childPrim = m_host.ParentGroup; | ||||
|                 } | ||||
| //                byte uf = childPrim.RootPart.UpdateFlag; | ||||
|                 childPrim.RootPart.UpdateFlag = 0; | ||||
|                 childPrim.RootPart.ClearPendingUpdate(); | ||||
|                 parentPrim.LinkToGroup(childPrim); | ||||
| //                if (uf != (Byte)0) | ||||
| //                    parent.RootPart.UpdateFlag = uf; | ||||
|  | @ -3516,7 +3516,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             parentPrim.TriggerScriptChangedEvent(Changed.LINK); | ||||
|             parentPrim.RootPart.AddFlag(PrimFlags.CreateSelected); | ||||
|             parentPrim.HasGroupChanged = true; | ||||
|             parentPrim.ScheduleGroupForFullUpdate(); | ||||
|             parentPrim.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); | ||||
| 
 | ||||
|             if (client != null) | ||||
|                 parentPrim.GetProperties(client); | ||||
|  | @ -3582,7 +3582,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                     parentPrim.DelinkFromGroup(part.LocalId, true); | ||||
|                 } | ||||
|                 parentPrim.HasGroupChanged = true; | ||||
|                 parentPrim.ScheduleGroupForFullUpdate(); | ||||
|                 parentPrim.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); | ||||
|                 parentPrim.TriggerScriptChangedEvent(Changed.LINK); | ||||
| 
 | ||||
|                 if (parts.Count > 0) | ||||
|  | @ -3591,11 +3591,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                     parts.Remove(newRoot); | ||||
|                     foreach (SceneObjectPart part in parts) | ||||
|                     { | ||||
|                         part.UpdateFlag = 0; | ||||
|                         part.ClearPendingUpdate(); | ||||
|                         newRoot.ParentGroup.LinkToGroup(part.ParentGroup); | ||||
|                     } | ||||
|                     newRoot.ParentGroup.HasGroupChanged = true; | ||||
|                     newRoot.ParentGroup.ScheduleGroupForFullUpdate(); | ||||
|                     newRoot.ParentGroup.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|  | @ -3605,7 +3605,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
| 
 | ||||
|                 parentPrim.DelinkFromGroup(childPrim.LocalId, true); | ||||
|                 parentPrim.HasGroupChanged = true; | ||||
|                 parentPrim.ScheduleGroupForFullUpdate(); | ||||
|                 parentPrim.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); | ||||
|                 parentPrim.TriggerScriptChangedEvent(Changed.LINK); | ||||
|             } | ||||
|         } | ||||
|  | @ -3626,7 +3626,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                 parentPrim.TriggerScriptChangedEvent(Changed.LINK); | ||||
|             } | ||||
|             parentPrim.HasGroupChanged = true; | ||||
|             parentPrim.ScheduleGroupForFullUpdate(); | ||||
|             parentPrim.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdate); | ||||
|         } | ||||
| 
 | ||||
|         public LSL_String llGetLinkKey(int linknum) | ||||
|  | @ -3866,7 +3866,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                                       Util.Clip((float)color.z, 0.0f, 1.0f)); | ||||
|             m_host.SetText(text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); | ||||
|             m_host.ParentGroup.HasGroupChanged = true; | ||||
|             m_host.ParentGroup.ScheduleGroupForFullUpdate(); | ||||
|             m_host.ScheduleUpdate(PrimUpdateFlags.Text); | ||||
|         } | ||||
| 
 | ||||
|         public LSL_Float llWater(LSL_Vector offset) | ||||
|  | @ -5467,7 +5467,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|             pTexAnim.Start = (float)start; | ||||
| 
 | ||||
|             part.AddTextureAnimation(pTexAnim); | ||||
|             part.SendFullUpdateToAllClients(); | ||||
|             part.SendUpdateToAllClients(PrimUpdateFlags.TextureAnim); | ||||
|             part.ParentGroup.HasGroupChanged = true; | ||||
|         } | ||||
| 
 | ||||
|  | @ -6029,7 +6029,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
|                 part.AddNewParticleSystem(prules); | ||||
|                 part.ParentGroup.HasGroupChanged = true; | ||||
|             } | ||||
|             part.SendFullUpdateToAllClients(); | ||||
|             part.SendUpdateToAllClients(PrimUpdateFlags.Particles); | ||||
|         } | ||||
| 
 | ||||
|         public void llGroundRepel(double height, int water, double tau) | ||||
|  |  | |||
|  | @ -0,0 +1,283 @@ | |||
| /* | ||||
|  * Copyright (c) Contributors, http://opensimulator.org/ | ||||
|  * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions are met: | ||||
|  *     * Redistributions of source code must retain the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer. | ||||
|  *     * Redistributions in binary form must reproduce the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer in the | ||||
|  *       documentation and/or other materials provided with the distribution. | ||||
|  *     * Neither the name of the OpenSimulator Project nor the | ||||
|  *       names of its contributors may be used to endorse or promote products | ||||
|  *       derived from this software without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||||
|  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
|  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||||
|  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
|  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
|  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
|  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
|  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.Specialized; | ||||
| using System.Net; | ||||
| using System.Reflection; | ||||
| using log4net; | ||||
| using Mono.Addins; | ||||
| using Nini.Config; | ||||
| using OpenMetaverse; | ||||
| using OpenMetaverse.StructuredData; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Framework.Client; | ||||
| using OpenSim.Region.Framework.Interfaces; | ||||
| using OpenSim.Region.Framework.Scenes; | ||||
| using OpenSim.Services.Interfaces; | ||||
| using OpenSim.Framework.Servers.HttpServer; | ||||
| 
 | ||||
| using GridRegion = OpenSim.Services.Interfaces.GridRegion; | ||||
| 
 | ||||
| namespace OpenSim.Services.Connectors.SimianGrid | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Handles logins and teleports | ||||
|     /// </summary> | ||||
|     [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] | ||||
|     public class RezAvatar : INonSharedRegionModule | ||||
|     { | ||||
|         private static readonly ILog m_log = | ||||
|                 LogManager.GetLogger( | ||||
|                 MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         private Scene m_scene; | ||||
|         private GridRegion m_gridRegion; | ||||
|         private ISimulationService m_simulationService; | ||||
| 
 | ||||
|         #region INonSharedRegionModule | ||||
| 
 | ||||
|         public Type ReplaceableInterface { get { return null; } } | ||||
|         public void RegionLoaded(Scene scene) { } | ||||
|         public void Close() { } | ||||
| 
 | ||||
|         public RezAvatar() { } | ||||
|         public string Name { get { return "RezAvatar"; } } | ||||
|          | ||||
|         public void AddRegion(Scene scene) | ||||
|         { | ||||
|             m_scene = scene; | ||||
|             m_gridRegion = new GridRegion | ||||
|             { | ||||
|                 RegionID = scene.RegionInfo.RegionID, | ||||
|                 RegionLocX = (int)scene.RegionInfo.RegionLocX, | ||||
|                 RegionLocY = (int)scene.RegionInfo.RegionLocY, | ||||
|                 RegionName = scene.RegionInfo.RegionName | ||||
|             }; | ||||
| 
 | ||||
|             if (Simian.IsSimianEnabled(scene.Config, "UserAccountServices", "SimianUserAccountServiceConnector")) | ||||
|             { | ||||
|                 m_simulationService = scene.RequestModuleInterface<ISimulationService>(); | ||||
|                 if (m_simulationService != null) | ||||
|                     m_simulationService = m_simulationService.GetInnerService(); | ||||
| 
 | ||||
|                 string urlFriendlySceneName = WebUtil.UrlEncode(scene.RegionInfo.RegionName); | ||||
| 
 | ||||
|                 MainServer.Instance.AddStreamHandler(new HttpStreamHandler("application/xml+llsd", "GET", "/scenes/" + urlFriendlySceneName + "/public_region_seed_capability", | ||||
|                     PublicRegionSeedCapabilityHandler)); | ||||
|                 MainServer.Instance.AddStreamHandler(new HttpStreamHandler(null, "POST", "/scenes/" + urlFriendlySceneName + "/rez_avatar/request", | ||||
|                     RezAvatarRequestHandler)); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void RemoveRegion(Scene scene) | ||||
|         { | ||||
|             if (Simian.IsSimianEnabled(scene.Config, "UserAccountServices", this.Name)) | ||||
|             { | ||||
|                 string urlFriendlySceneName = WebUtil.UrlEncode(scene.RegionInfo.RegionName); | ||||
| 
 | ||||
|                 MainServer.Instance.RemoveStreamHandler("GET", "/scenes/" + urlFriendlySceneName + "/public_region_seed_capability"); | ||||
|                 MainServer.Instance.RemoveStreamHandler("GET", "/scenes/" + urlFriendlySceneName + "/rez_avatar/request"); | ||||
|             } | ||||
| 
 | ||||
|             m_scene = null; | ||||
|         } | ||||
| 
 | ||||
|         #endregion INonSharedRegionModule | ||||
| 
 | ||||
|         public RezAvatar(IConfigSource source) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public void Initialise(IConfigSource source) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         private void PublicRegionSeedCapabilityHandler(OSHttpRequest httpRequest, OSHttpResponse httpResponse) | ||||
|         { | ||||
|             // Build a seed capability response that contains the rez_avatar/request capability (a hardcoded URL) | ||||
|             OSDMap responseMap = new OSDMap(); | ||||
| 
 | ||||
|             Uri httpAddress = new Uri("http://" + m_scene.RegionInfo.ExternalHostName + ":" + m_scene.RegionInfo.HttpPort + "/"); | ||||
|             string urlFriendlySceneName = WebUtil.UrlEncode(m_scene.RegionInfo.RegionName); | ||||
| 
 | ||||
|             OSDMap capabilities = new OSDMap(); | ||||
|             capabilities["rez_avatar/request"] = OSD.FromUri(new Uri(httpAddress, "/scenes/" + urlFriendlySceneName + "/rez_avatar/request")); | ||||
| 
 | ||||
|             responseMap["capabilities"] = capabilities; | ||||
| 
 | ||||
|             WebUtil.SendJSONResponse(httpResponse, responseMap); | ||||
|         } | ||||
| 
 | ||||
|         private void RezAvatarRequestHandler(OSHttpRequest httpRequest, OSHttpResponse httpResponse) | ||||
|         { | ||||
|             OSDMap requestMap = null; | ||||
|             try { requestMap = OSDParser.Deserialize(httpRequest.InputStream) as OSDMap; } | ||||
|             catch { } | ||||
| 
 | ||||
|             Vector3 lookAt = Vector3.UnitX; | ||||
|             RegionInfo regInfo = m_scene.RegionInfo; | ||||
| 
 | ||||
|             // Unpack the rez_avatar/request into an AgentCircuitData structure | ||||
|             AgentCircuitData agentCircuit = BuildAgentCircuitFromRezAvatarRequest(requestMap); | ||||
| 
 | ||||
|             OSDMap responseMap = new OSDMap(); | ||||
| 
 | ||||
|             if (agentCircuit != null && agentCircuit.AgentID != UUID.Zero) | ||||
|             { | ||||
|                 if (agentCircuit.startpos == Vector3.Zero) | ||||
|                 { | ||||
|                     m_log.Info("rez_avatar/request did not contain a position, setting to default"); | ||||
|                     agentCircuit.startpos = new Vector3(128f, 128f, 25f); | ||||
|                 } | ||||
| 
 | ||||
|                 // Attempt to create an agent from the AgentCircuitData info | ||||
|                 string reason; | ||||
|                 if (m_simulationService.CreateAgent(m_gridRegion, agentCircuit, agentCircuit.teleportFlags, out reason)) | ||||
|                 { | ||||
|                     // Build the seed capability URL for this agent | ||||
|                     Uri seedCapability = new Uri("http://" + regInfo.ExternalHostName + ":" + regInfo.HttpPort + "/CAPS/" + agentCircuit.CapsPath + "0000/"); | ||||
| 
 | ||||
|                     m_log.Info("rez_avatar/request created agent " + agentCircuit.firstname + " " + agentCircuit.lastname + | ||||
|                         " with circuit code " + agentCircuit.circuitcode + " and seed capability " + seedCapability); | ||||
| 
 | ||||
|                     IPAddress externalAddress = regInfo.ExternalEndPoint.Address; | ||||
|                     uint regionX, regionY; | ||||
|                     Utils.LongToUInts(regInfo.RegionHandle, out regionX, out regionY); | ||||
| 
 | ||||
|                     responseMap["connect"] = OSD.FromBoolean(true); | ||||
|                     responseMap["agent_id"] = OSD.FromUUID(agentCircuit.AgentID); | ||||
|                     responseMap["sim_host"] = OSD.FromString(externalAddress.ToString()); | ||||
|                     responseMap["sim_port"] = OSD.FromInteger(regInfo.ExternalEndPoint.Port); | ||||
|                     responseMap["region_seed_capability"] = OSD.FromUri(seedCapability); | ||||
|                     responseMap["position"] = OSD.FromVector3(agentCircuit.startpos); | ||||
|                     responseMap["look_at"] = OSD.FromVector3(lookAt); | ||||
| 
 | ||||
|                     // Region information | ||||
|                     responseMap["region_id"] = OSD.FromUUID(regInfo.RegionID); | ||||
|                     responseMap["region_x"] = OSD.FromInteger(regionX); | ||||
|                     responseMap["region_y"] = OSD.FromInteger(regionY); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     m_log.Warn("Denied rez_avatar/request for " + agentCircuit.firstname + " " + agentCircuit.lastname + ": " + reason); | ||||
|                     responseMap["message"] = OSD.FromString(reason); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 responseMap["message"] = OSD.FromString("Invalid or incomplete request"); | ||||
|             } | ||||
| 
 | ||||
|             WebUtil.SendJSONResponse(httpResponse, responseMap); | ||||
|         } | ||||
| 
 | ||||
|         private static AgentCircuitData BuildAgentCircuitFromRezAvatarRequest(OSDMap request) | ||||
|         { | ||||
|             AgentCircuitData agentCircuit = new AgentCircuitData(); | ||||
|             agentCircuit.AgentID = request["agent_id"].AsUUID(); | ||||
|             agentCircuit.BaseFolder = request["base_folder"].AsUUID(); | ||||
|             agentCircuit.CapsPath = request["caps_path"].AsString(); | ||||
|             agentCircuit.child = request["child_agent"].AsBoolean(); | ||||
|             agentCircuit.circuitcode = request["circuit_code"].AsUInteger(); | ||||
|             agentCircuit.firstname = request["first_name"].AsString(); | ||||
|             agentCircuit.InventoryFolder = request["inventory_folder"].AsUUID(); | ||||
|             agentCircuit.lastname = request["last_name"].AsString(); | ||||
|             agentCircuit.SecureSessionID = request["secure_session_id"].AsUUID(); | ||||
|             agentCircuit.ServiceSessionID = String.Empty; | ||||
|             agentCircuit.ServiceURLs = new Dictionary<string, object>(0); | ||||
|             agentCircuit.SessionID = request["session_id"].AsUUID(); | ||||
|             agentCircuit.startpos = request["position"].AsVector3(); | ||||
|             agentCircuit.teleportFlags = request["teleport_flags"].AsUInteger(); | ||||
|             if (agentCircuit.teleportFlags == 0) | ||||
|                 agentCircuit.teleportFlags = (uint)TeleportFlags.ViaLogin; | ||||
| 
 | ||||
|             #region Children Seed Caps | ||||
| 
 | ||||
|             if (request["children_seeds"].Type == OSDType.Array) | ||||
|             { | ||||
|                 OSDArray childrenSeeds = (OSDArray)request["children_seeds"]; | ||||
|                 agentCircuit.ChildrenCapSeeds = new Dictionary<ulong, string>(childrenSeeds.Count); | ||||
|                 for (int i = 0; i < childrenSeeds.Count; i++) | ||||
|                 { | ||||
|                     if (childrenSeeds[i].Type == OSDType.Map) | ||||
|                     { | ||||
|                         OSDMap pair = (OSDMap)childrenSeeds[i]; | ||||
|                         ulong handle; | ||||
|                         if (!UInt64.TryParse(pair["handle"].AsString(), out handle)) | ||||
|                             continue; | ||||
|                         string seed = pair["seed"].AsString(); | ||||
|                         if (!agentCircuit.ChildrenCapSeeds.ContainsKey(handle)) | ||||
|                             agentCircuit.ChildrenCapSeeds.Add(handle, seed); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 agentCircuit.ChildrenCapSeeds = new Dictionary<ulong, string>(0); | ||||
|             } | ||||
| 
 | ||||
|             #endregion Children Seed Caps | ||||
| 
 | ||||
|             #region Appearance | ||||
| 
 | ||||
|             agentCircuit.Appearance = new AvatarAppearance(agentCircuit.AgentID); | ||||
|             agentCircuit.Appearance.Serial = request["appearance_serial"].AsInteger(); | ||||
|             if (request["wearables"].Type == OSDType.Array) | ||||
|             { | ||||
|                 OSDArray wearables = (OSDArray)request["wearables"]; | ||||
|                 for (int i = 0; i < wearables.Count / 2; i++) | ||||
|                 { | ||||
|                     agentCircuit.Appearance.Wearables[i].ItemID = wearables[i * 2].AsUUID(); | ||||
|                     agentCircuit.Appearance.Wearables[i].AssetID = wearables[(i * 2) + 1].AsUUID(); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             if (request["attachments"].Type == OSDType.Array) | ||||
|             { | ||||
|                 OSDArray attachArray = (OSDArray)request["attachments"]; | ||||
|                 List<AttachmentData> attachments = new List<AttachmentData>(attachArray.Count); | ||||
|                 for (int i = 0; i < attachArray.Count; i++) | ||||
|                 { | ||||
|                     if (attachArray[i].Type == OSDType.Map) | ||||
|                         attachments.Add(new AttachmentData((OSDMap)attachArray[i])); | ||||
|                 } | ||||
|                 agentCircuit.Appearance.SetAttachments(attachments.ToArray()); | ||||
|             } | ||||
| 
 | ||||
|             #endregion Appearance | ||||
| 
 | ||||
|             return agentCircuit; | ||||
|         } | ||||
| 
 | ||||
|         private static OSDMap BuildRezAvatarRequestFromAgentCircuit(AgentCircuitData agentCircuit) | ||||
|         { | ||||
|             return new OSDMap(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -88,7 +88,7 @@ namespace OpenSim.Services.Connectors.SimianGrid | |||
| 
 | ||||
|         public void Initialise(IConfigSource source) | ||||
|         { | ||||
|             if (Simian.IsSimianEnabled(source, "UserAccountServices", this.Name)) | ||||
|             if (Simian.IsSimianEnabled(source, "UserAccountServices", "SimianUserAccountServiceConnector")) | ||||
|             { | ||||
|                 IConfig gridConfig = source.Configs["UserAccountService"]; | ||||
|                 if (gridConfig == null) | ||||
|  |  | |||
|  | @ -621,18 +621,14 @@ namespace OpenSim.Tests.Common.Mock | |||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendAvatarData(SendAvatarData data) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendEntityUpdate(double priority, ISceneEntity entity, PrimUpdateFlags updateFlags) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||||
|         { | ||||
|         } | ||||
|  | @ -641,15 +637,7 @@ namespace OpenSim.Tests.Common.Mock | |||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendPrimitiveToClient(SendPrimitiveData data) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) | ||||
|         public virtual void ReprioritizeUpdates(UpdatePriorityHandler handler) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -369,18 +369,13 @@ | |||
|     ;asset_limit = 27500 | ||||
|     ;state_limit = 37000 | ||||
| 
 | ||||
|     ; Configures how ObjectUpdates are aggregated. These numbers | ||||
|     ; do not literally mean how many updates will be put in each | ||||
|     ; packet that goes over the wire, as packets are | ||||
|     ; automatically split on a 1400 byte boundary. These control | ||||
|     ; the balance between responsiveness of interest list updates | ||||
|     ; and total throughput. Higher numbers will ensure more full- | ||||
|     ; sized packets and faster sending of data, but more delay in | ||||
|     ; updating interest lists | ||||
|     ; Configures how scene graph updates are sent to clients. | ||||
|     ; This controls the balance between responsiveness of interest  | ||||
|     ; list updates and total throughput. A higher value will ensure  | ||||
|     ; more full-sized packets and faster sending of data, but more  | ||||
|     ; delay in updating client interest lists | ||||
|     ; | ||||
|     ;PrimTerseUpdatesPerPacket = 25 | ||||
|     ;AvatarTerseUpdatesPerPacket = 10 | ||||
|     ;PrimFullUpdatesPerPacket = 100 | ||||
|     PrimUpdatesPerCallback = 100 | ||||
| 
 | ||||
|     ; TextureSendLimit determines how many packets will be put on | ||||
|     ; the outgoing queue each cycle. Like the settings above, this | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue