diff options
author | John Hurliman | 2009-10-15 16:35:27 -0700 |
---|---|---|
committer | John Hurliman | 2009-10-15 16:35:27 -0700 |
commit | 4b75353cbf50de3cae4c48ec90b55f30c1612c92 (patch) | |
tree | 2b5bf30d2a0c8558437f757e28081cb60a8b5dfc /OpenSim/Region/ClientStack | |
parent | Replaced the update lists with a priority queue implementation in LLClientView (diff) | |
download | opensim-SC_OLD-4b75353cbf50de3cae4c48ec90b55f30c1612c92.zip opensim-SC_OLD-4b75353cbf50de3cae4c48ec90b55f30c1612c92.tar.gz opensim-SC_OLD-4b75353cbf50de3cae4c48ec90b55f30c1612c92.tar.bz2 opensim-SC_OLD-4b75353cbf50de3cae4c48ec90b55f30c1612c92.tar.xz |
Object update prioritization by Jim Greensky of Intel Labs, part one. This implements a simple distance prioritizer based on initial agent positions. Re-prioritizing and more advanced priority algorithms will follow soon
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 344 |
1 files changed, 135 insertions, 209 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 93fdeef..0a7d923 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -320,14 +320,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
320 | private readonly IGroupsModule m_GroupsModule; | 320 | private readonly IGroupsModule m_GroupsModule; |
321 | 321 | ||
322 | private int m_cachedTextureSerial; | 322 | private int m_cachedTextureSerial; |
323 | private Timer m_avatarTerseUpdateTimer; | 323 | private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates = |
324 | private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates_ = | ||
325 | new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | 324 | new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); |
326 | private Timer m_primTerseUpdateTimer; | 325 | private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates = |
327 | private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates_ = | ||
328 | new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | 326 | new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); |
329 | private Timer m_primFullUpdateTimer; | 327 | private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates = |
330 | private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates_ = | ||
331 | new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>(); | 328 | new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>(); |
332 | private int m_moneyBalance; | 329 | private int m_moneyBalance; |
333 | private int m_animationSequenceNumber = 1; | 330 | private int m_animationSequenceNumber = 1; |
@@ -353,9 +350,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
353 | // LL uses these limits, apparently. Compressed terse would be 23, but we don't have that yet | 350 | // LL uses these limits, apparently. Compressed terse would be 23, but we don't have that yet |
354 | protected int m_primTerseUpdatesPerPacket = 10; | 351 | protected int m_primTerseUpdatesPerPacket = 10; |
355 | protected int m_primFullUpdatesPerPacket = 14; | 352 | protected int m_primFullUpdatesPerPacket = 14; |
356 | protected int m_primTerseUpdateRate = 10; | ||
357 | protected int m_primFullUpdateRate = 14; | ||
358 | protected int m_avatarTerseUpdateRate = 50; | ||
359 | protected int m_avatarTerseUpdatesPerPacket = 5; | 353 | protected int m_avatarTerseUpdatesPerPacket = 5; |
360 | /// <summary>Number of texture packets to put on the queue each time the | 354 | /// <summary>Number of texture packets to put on the queue each time the |
361 | /// OnQueueEmpty event is triggered for the texture category</summary> | 355 | /// OnQueueEmpty event is triggered for the texture category</summary> |
@@ -479,25 +473,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
479 | // Remove ourselves from the scene | 473 | // Remove ourselves from the scene |
480 | m_scene.RemoveClient(AgentId); | 474 | m_scene.RemoveClient(AgentId); |
481 | 475 | ||
482 | // Shut down timers. Thread Context of this method is murky. Lock all timers | ||
483 | if (m_avatarTerseUpdateTimer.Enabled) | ||
484 | lock (m_avatarTerseUpdateTimer) | ||
485 | m_avatarTerseUpdateTimer.Stop(); | ||
486 | if (m_primTerseUpdateTimer.Enabled) | ||
487 | lock (m_primTerseUpdateTimer) | ||
488 | m_primTerseUpdateTimer.Stop(); | ||
489 | if (m_primFullUpdateTimer.Enabled) | ||
490 | lock (m_primFullUpdateTimer) | ||
491 | m_primFullUpdateTimer.Stop(); | ||
492 | |||
493 | // We can't reach into other scenes and close the connection | 476 | // We can't reach into other scenes and close the connection |
494 | // We need to do this over grid communications | 477 | // We need to do this over grid communications |
495 | //m_scene.CloseAllAgents(CircuitCode); | 478 | //m_scene.CloseAllAgents(CircuitCode); |
496 | 479 | ||
497 | m_avatarTerseUpdateTimer.Dispose(); | ||
498 | m_primTerseUpdateTimer.Dispose(); | ||
499 | m_primFullUpdateTimer.Dispose(); | ||
500 | |||
501 | // Disable UDP handling for this client | 480 | // Disable UDP handling for this client |
502 | m_udpClient.Shutdown(); | 481 | m_udpClient.Shutdown(); |
503 | 482 | ||
@@ -524,18 +503,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
524 | 503 | ||
525 | public void Stop() | 504 | public void Stop() |
526 | { | 505 | { |
527 | // Shut down timers. Thread Context is Murky, lock all timers! | ||
528 | if (m_avatarTerseUpdateTimer.Enabled) | ||
529 | lock (m_avatarTerseUpdateTimer) | ||
530 | m_avatarTerseUpdateTimer.Stop(); | ||
531 | |||
532 | if (m_primTerseUpdateTimer.Enabled) | ||
533 | lock (m_primTerseUpdateTimer) | ||
534 | m_primTerseUpdateTimer.Stop(); | ||
535 | 506 | ||
536 | if (m_primFullUpdateTimer.Enabled) | ||
537 | lock (m_primFullUpdateTimer) | ||
538 | m_primFullUpdateTimer.Stop(); | ||
539 | } | 507 | } |
540 | 508 | ||
541 | #endregion Client Methods | 509 | #endregion Client Methods |
@@ -631,18 +599,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
631 | 599 | ||
632 | public virtual void Start() | 600 | public virtual void Start() |
633 | { | 601 | { |
634 | m_avatarTerseUpdateTimer = new Timer(m_avatarTerseUpdateRate); | ||
635 | m_avatarTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessAvatarTerseUpdates); | ||
636 | m_avatarTerseUpdateTimer.AutoReset = false; | ||
637 | |||
638 | m_primTerseUpdateTimer = new Timer(m_primTerseUpdateRate); | ||
639 | m_primTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimTerseUpdates); | ||
640 | m_primTerseUpdateTimer.AutoReset = false; | ||
641 | |||
642 | m_primFullUpdateTimer = new Timer(m_primFullUpdateRate); | ||
643 | m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); | ||
644 | m_primFullUpdateTimer.AutoReset = false; | ||
645 | |||
646 | m_scene.AddNewClient(this); | 602 | m_scene.AddNewClient(this); |
647 | 603 | ||
648 | RefreshGroupMembership(); | 604 | RefreshGroupMembership(); |
@@ -3394,28 +3350,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3394 | /// <summary> | 3350 | /// <summary> |
3395 | /// send a objectupdate packet with information about the clients avatar | 3351 | /// send a objectupdate packet with information about the clients avatar |
3396 | /// </summary> | 3352 | /// </summary> |
3397 | public void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, | 3353 | public void SendAvatarData(SendAvatarData data) |
3398 | uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation) | ||
3399 | { | 3354 | { |
3400 | ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | 3355 | ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); |
3401 | // TODO: don't create new blocks if recycling an old packet | 3356 | // TODO: don't create new blocks if recycling an old packet |
3402 | objupdate.RegionData.RegionHandle = regionHandle; | 3357 | objupdate.RegionData.RegionHandle = data.regionHandle; |
3403 | objupdate.RegionData.TimeDilation = ushort.MaxValue; | 3358 | objupdate.RegionData.TimeDilation = ushort.MaxValue; |
3404 | objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | 3359 | objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; |
3405 | objupdate.ObjectData[0] = CreateDefaultAvatarPacket(textureEntry); | 3360 | objupdate.ObjectData[0] = CreateDefaultAvatarPacket(data.textureEntry); |
3406 | 3361 | ||
3407 | //give this avatar object a local id and assign the user a name | 3362 | //give this avatar object a local id and assign the user a name |
3408 | objupdate.ObjectData[0].ID = avatarLocalID; | 3363 | objupdate.ObjectData[0].ID = data.avatarLocalID; |
3409 | objupdate.ObjectData[0].FullID = avatarID; | 3364 | objupdate.ObjectData[0].FullID = data.avatarID; |
3410 | objupdate.ObjectData[0].ParentID = parentID; | 3365 | objupdate.ObjectData[0].ParentID = data.parentID; |
3411 | objupdate.ObjectData[0].NameValue = | 3366 | objupdate.ObjectData[0].NameValue = |
3412 | Utils.StringToBytes("FirstName STRING RW SV " + firstName + "\nLastName STRING RW SV " + lastName + "\nTitle STRING RW SV " + grouptitle); | 3367 | Utils.StringToBytes("FirstName STRING RW SV " + data.firstName + "\nLastName STRING RW SV " + data.lastName + "\nTitle STRING RW SV " + data.grouptitle); |
3413 | 3368 | ||
3414 | Vector3 pos2 = new Vector3(Pos.X, Pos.Y, Pos.Z); | 3369 | Vector3 pos2 = new Vector3(data.Pos.X, data.Pos.Y, data.Pos.Z); |
3415 | byte[] pb = pos2.GetBytes(); | 3370 | byte[] pb = pos2.GetBytes(); |
3416 | Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); | 3371 | Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); |
3417 | 3372 | ||
3418 | byte[] rot = rotation.GetBytes(); | 3373 | byte[] rot = data.rotation.GetBytes(); |
3419 | Array.Copy(rot, 0, objupdate.ObjectData[0].ObjectData, 52, rot.Length); | 3374 | Array.Copy(rot, 0, objupdate.ObjectData[0].ObjectData, 52, rot.Length); |
3420 | 3375 | ||
3421 | objupdate.Header.Zerocoded = true; | 3376 | objupdate.Header.Zerocoded = true; |
@@ -3426,38 +3381,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3426 | /// Send a terse positional/rotation/velocity update about an avatar | 3381 | /// Send a terse positional/rotation/velocity update about an avatar |
3427 | /// to the client. This avatar can be that of the client itself. | 3382 | /// to the client. This avatar can be that of the client itself. |
3428 | /// </summary> | 3383 | /// </summary> |
3429 | public virtual void SendAvatarTerseUpdate(ulong regionHandle, | 3384 | public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) |
3430 | ushort timeDilation, uint localID, Vector3 position, | ||
3431 | Vector3 velocity, Quaternion rotation, UUID agentid) | ||
3432 | { | 3385 | { |
3386 | if (data.priority == double.NaN) | ||
3387 | { | ||
3388 | m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update"); | ||
3389 | return; | ||
3390 | } | ||
3391 | |||
3392 | Quaternion rotation = data.rotation; | ||
3393 | |||
3433 | if (rotation.X == rotation.Y && | 3394 | if (rotation.X == rotation.Y && |
3434 | rotation.Y == rotation.Z && | 3395 | rotation.Y == rotation.Z && |
3435 | rotation.Z == rotation.W && rotation.W == 0) | 3396 | rotation.Z == rotation.W && rotation.W == 0) |
3436 | rotation = Quaternion.Identity; | 3397 | rotation = Quaternion.Identity; |
3437 | 3398 | ||
3438 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = | 3399 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = |
3439 | CreateAvatarImprovedBlock(localID, position, velocity,rotation); | 3400 | CreateAvatarImprovedBlock(data.localID, data.position, data.velocity, rotation); |
3440 | 3401 | ||
3441 | lock (m_avatarTerseUpdates_.SyncRoot) | 3402 | lock (m_avatarTerseUpdates.SyncRoot) |
3442 | { | 3403 | m_avatarTerseUpdates.Enqueue(data.priority, terseBlock, data.localID); |
3443 | m_avatarTerseUpdates_.Enqueue(DateTime.Now.ToOADate(), terseBlock, localID); | ||
3444 | |||
3445 | // If packet is full or own movement packet, send it. | ||
3446 | if (m_avatarTerseUpdates_.Count >= m_avatarTerseUpdatesPerPacket) | ||
3447 | { | ||
3448 | ProcessAvatarTerseUpdates(this, null); | ||
3449 | } | ||
3450 | else if (m_avatarTerseUpdates_.Count == 1) | ||
3451 | { | ||
3452 | lock (m_avatarTerseUpdateTimer) | ||
3453 | m_avatarTerseUpdateTimer.Start(); | ||
3454 | } | ||
3455 | } | ||
3456 | } | 3404 | } |
3457 | 3405 | ||
3458 | private void ProcessAvatarTerseUpdates(object sender, ElapsedEventArgs e) | 3406 | private void ProcessAvatarTerseUpdates() |
3459 | { | 3407 | { |
3460 | lock (m_avatarTerseUpdates_.SyncRoot) | 3408 | lock (m_avatarTerseUpdates.SyncRoot) |
3461 | { | 3409 | { |
3462 | ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); | 3410 | ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); |
3463 | 3411 | ||
@@ -3468,8 +3416,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3468 | (ushort)(Scene.TimeDilation * ushort.MaxValue); | 3416 | (ushort)(Scene.TimeDilation * ushort.MaxValue); |
3469 | 3417 | ||
3470 | int max = m_avatarTerseUpdatesPerPacket; | 3418 | int max = m_avatarTerseUpdatesPerPacket; |
3471 | if (max > m_avatarTerseUpdates_.Count) | 3419 | if (max > m_avatarTerseUpdates.Count) |
3472 | max = m_avatarTerseUpdates_.Count; | 3420 | max = m_avatarTerseUpdates.Count; |
3473 | 3421 | ||
3474 | int count = 0; | 3422 | int count = 0; |
3475 | int size = 0; | 3423 | int size = 0; |
@@ -3482,12 +3430,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3482 | for (count = 0 ; count < max ; count++) | 3430 | for (count = 0 ; count < max ; count++) |
3483 | { | 3431 | { |
3484 | int length = 0; | 3432 | int length = 0; |
3485 | m_avatarTerseUpdates_.Peek().ToBytes(blockbuffer, ref length); | 3433 | m_avatarTerseUpdates.Peek().ToBytes(blockbuffer, ref length); |
3486 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); | 3434 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); |
3487 | if (size + length > Packet.MTU) | 3435 | if (size + length > Packet.MTU) |
3488 | break; | 3436 | break; |
3489 | size += length; | 3437 | size += length; |
3490 | updates.Enqueue(m_avatarTerseUpdates_.Dequeue()); | 3438 | updates.Enqueue(m_avatarTerseUpdates.Dequeue()); |
3491 | } | 3439 | } |
3492 | 3440 | ||
3493 | terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; | 3441 | terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; |
@@ -3497,14 +3445,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3497 | 3445 | ||
3498 | terse.Header.Reliable = false; | 3446 | terse.Header.Reliable = false; |
3499 | terse.Header.Zerocoded = true; | 3447 | terse.Header.Zerocoded = true; |
3500 | // FIXME: Move this to ThrottleOutPacketType.State when the real prioritization code is committed | ||
3501 | OutPacket(terse, ThrottleOutPacketType.Task); | ||
3502 | 3448 | ||
3503 | if (m_avatarTerseUpdates_.Count == 0) | 3449 | OutPacket(terse, ThrottleOutPacketType.State); |
3504 | { | ||
3505 | lock (m_avatarTerseUpdateTimer) | ||
3506 | m_avatarTerseUpdateTimer.Stop(); | ||
3507 | } | ||
3508 | } | 3450 | } |
3509 | } | 3451 | } |
3510 | 3452 | ||
@@ -3569,54 +3511,42 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3569 | OutPacket(attach, ThrottleOutPacketType.Task); | 3511 | OutPacket(attach, ThrottleOutPacketType.Task); |
3570 | } | 3512 | } |
3571 | 3513 | ||
3572 | public void SendPrimitiveToClient( | 3514 | public void SendPrimitiveToClient(SendPrimitiveData data) |
3573 | ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, | ||
3574 | Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, | ||
3575 | uint flags, UUID objectID, UUID ownerID, string text, byte[] color, | ||
3576 | uint parentID, byte[] particleSystem, byte clickAction, byte material) | ||
3577 | { | 3515 | { |
3578 | byte[] textureanim = new byte[0]; | 3516 | if (data.priority == double.NaN) |
3517 | { | ||
3518 | m_log.Error("[LLClientView] SendPrimitiveToClient received a NaN priority, dropping update"); | ||
3519 | return; | ||
3520 | } | ||
3579 | 3521 | ||
3580 | SendPrimitiveToClient(regionHandle, timeDilation, localID, primShape, pos, vel, | 3522 | Quaternion rotation = data.rotation; |
3581 | acc, rotation, rvel, flags, | ||
3582 | objectID, ownerID, text, color, parentID, particleSystem, | ||
3583 | clickAction, material, textureanim, false, 0, UUID.Zero, UUID.Zero, 0, 0, 0); | ||
3584 | } | ||
3585 | 3523 | ||
3586 | public void SendPrimitiveToClient( | 3524 | if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD |
3587 | ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, | ||
3588 | Vector3 pos, Vector3 velocity, Vector3 acceleration, Quaternion rotation, Vector3 rotational_velocity, | ||
3589 | uint flags, | ||
3590 | UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, | ||
3591 | byte clickAction, byte material, byte[] textureanim, bool attachment, uint AttachPoint, UUID AssetId, UUID SoundId, double SoundGain, byte SoundFlags, double SoundRadius) | ||
3592 | { | ||
3593 | |||
3594 | if (AttachPoint > 30 && ownerID != AgentId) // Someone else's HUD | ||
3595 | return; | 3525 | return; |
3596 | if (primShape.PCode == 9 && primShape.State != 0 && parentID == 0) | 3526 | if (data.primShape.PCode == 9 && data.primShape.State != 0 && data.parentID == 0) |
3597 | return; | 3527 | return; |
3598 | 3528 | ||
3599 | if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) | 3529 | if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0.0f) |
3600 | rotation = Quaternion.Identity; | 3530 | rotation = Quaternion.Identity; |
3601 | 3531 | ||
3602 | ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(primShape, flags); | 3532 | ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data.primShape, data.flags); |
3603 | 3533 | ||
3604 | objectData.ID = localID; | 3534 | objectData.ID = data.localID; |
3605 | objectData.FullID = objectID; | 3535 | objectData.FullID = data.objectID; |
3606 | objectData.OwnerID = ownerID; | 3536 | objectData.OwnerID = data.ownerID; |
3607 | 3537 | ||
3608 | objectData.Text = Util.StringToBytes256(text); | 3538 | objectData.Text = Util.StringToBytes256(data.text); |
3609 | objectData.TextColor[0] = color[0]; | 3539 | objectData.TextColor[0] = data.color[0]; |
3610 | objectData.TextColor[1] = color[1]; | 3540 | objectData.TextColor[1] = data.color[1]; |
3611 | objectData.TextColor[2] = color[2]; | 3541 | objectData.TextColor[2] = data.color[2]; |
3612 | objectData.TextColor[3] = color[3]; | 3542 | objectData.TextColor[3] = data.color[3]; |
3613 | objectData.ParentID = parentID; | 3543 | objectData.ParentID = data.parentID; |
3614 | objectData.PSBlock = particleSystem; | 3544 | objectData.PSBlock = data.particleSystem; |
3615 | objectData.ClickAction = clickAction; | 3545 | objectData.ClickAction = data.clickAction; |
3616 | objectData.Material = material; | 3546 | objectData.Material = data.material; |
3617 | objectData.Flags = 0; | 3547 | objectData.Flags = 0; |
3618 | 3548 | ||
3619 | if (attachment) | 3549 | if (data.attachment) |
3620 | { | 3550 | { |
3621 | // Necessary??? | 3551 | // Necessary??? |
3622 | objectData.JointAxisOrAnchor = new Vector3(0, 0, 2); | 3552 | objectData.JointAxisOrAnchor = new Vector3(0, 0, 2); |
@@ -3624,14 +3554,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3624 | 3554 | ||
3625 | // Item from inventory??? | 3555 | // Item from inventory??? |
3626 | objectData.NameValue = | 3556 | objectData.NameValue = |
3627 | Utils.StringToBytes("AttachItemID STRING RW SV " + AssetId.Guid); | 3557 | Utils.StringToBytes("AttachItemID STRING RW SV " + data.AssetId.Guid); |
3628 | objectData.State = (byte)((AttachPoint % 16) * 16 + (AttachPoint / 16)); | 3558 | objectData.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16)); |
3629 | } | 3559 | } |
3630 | 3560 | ||
3631 | // Xantor 20080528: Send sound info as well | 3561 | // Xantor 20080528: Send sound info as well |
3632 | // Xantor 20080530: Zero out everything if there's no SoundId, so zerocompression will work again | 3562 | // Xantor 20080530: Zero out everything if there's no SoundId, so zerocompression will work again |
3633 | objectData.Sound = SoundId; | 3563 | objectData.Sound = data.SoundId; |
3634 | if (SoundId == UUID.Zero) | 3564 | if (data.SoundId == UUID.Zero) |
3635 | { | 3565 | { |
3636 | objectData.OwnerID = UUID.Zero; | 3566 | objectData.OwnerID = UUID.Zero; |
3637 | objectData.Gain = 0.0f; | 3567 | objectData.Gain = 0.0f; |
@@ -3640,39 +3570,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3640 | } | 3570 | } |
3641 | else | 3571 | else |
3642 | { | 3572 | { |
3643 | objectData.OwnerID = ownerID; | 3573 | objectData.OwnerID = data.ownerID; |
3644 | objectData.Gain = (float)SoundGain; | 3574 | objectData.Gain = (float)data.SoundVolume; |
3645 | objectData.Radius = (float)SoundRadius; | 3575 | objectData.Radius = (float)data.SoundRadius; |
3646 | objectData.Flags = SoundFlags; | 3576 | objectData.Flags = data.SoundFlags; |
3647 | } | 3577 | } |
3648 | 3578 | ||
3649 | byte[] pb = pos.GetBytes(); | 3579 | byte[] pb = data.pos.GetBytes(); |
3650 | Array.Copy(pb, 0, objectData.ObjectData, 0, pb.Length); | 3580 | Buffer.BlockCopy(pb, 0, objectData.ObjectData, 0, pb.Length); |
3651 | 3581 | ||
3652 | byte[] vel = velocity.GetBytes(); | 3582 | byte[] vel = data.vel.GetBytes(); |
3653 | Array.Copy(vel, 0, objectData.ObjectData, pb.Length, vel.Length); | 3583 | Buffer.BlockCopy(vel, 0, objectData.ObjectData, pb.Length, vel.Length); |
3654 | 3584 | ||
3655 | byte[] rot = rotation.GetBytes(); | 3585 | byte[] rot = rotation.GetBytes(); |
3656 | Array.Copy(rot, 0, objectData.ObjectData, 36, rot.Length); | 3586 | Buffer.BlockCopy(rot, 0, objectData.ObjectData, 36, rot.Length); |
3657 | 3587 | ||
3658 | byte[] rvel = rotational_velocity.GetBytes(); | 3588 | byte[] rvel = data.rvel.GetBytes(); |
3659 | Array.Copy(rvel, 0, objectData.ObjectData, 36 + rot.Length, rvel.Length); | 3589 | Buffer.BlockCopy(rvel, 0, objectData.ObjectData, 36 + rot.Length, rvel.Length); |
3660 | 3590 | ||
3661 | if (textureanim.Length > 0) | 3591 | if (data.textureanim.Length > 0) |
3662 | { | 3592 | { |
3663 | objectData.TextureAnim = textureanim; | 3593 | objectData.TextureAnim = data.textureanim; |
3664 | } | 3594 | } |
3665 | 3595 | ||
3666 | lock (m_primFullUpdates_.SyncRoot) | 3596 | lock (m_primFullUpdates.SyncRoot) |
3667 | { | 3597 | m_primFullUpdates.Enqueue(data.priority, objectData, data.localID); |
3668 | if (m_primFullUpdates_.Count == 0) | ||
3669 | m_primFullUpdateTimer.Start(); | ||
3670 | |||
3671 | m_primFullUpdates_.Enqueue(DateTime.Now.ToOADate(), objectData, localID); | ||
3672 | |||
3673 | if (m_primFullUpdates_.Count >= m_primFullUpdatesPerPacket) | ||
3674 | ProcessPrimFullUpdates(this, null); | ||
3675 | } | ||
3676 | } | 3598 | } |
3677 | 3599 | ||
3678 | void HandleQueueEmpty(ThrottleOutPacketType queue) | 3600 | void HandleQueueEmpty(ThrottleOutPacketType queue) |
@@ -3682,6 +3604,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3682 | case ThrottleOutPacketType.Texture: | 3604 | case ThrottleOutPacketType.Texture: |
3683 | ProcessTextureRequests(); | 3605 | ProcessTextureRequests(); |
3684 | break; | 3606 | break; |
3607 | case ThrottleOutPacketType.State: | ||
3608 | int count = 0; | ||
3609 | |||
3610 | lock (m_avatarTerseUpdates.SyncRoot) | ||
3611 | count = m_avatarTerseUpdates.Count; | ||
3612 | if (count > 0) | ||
3613 | { | ||
3614 | ProcessAvatarTerseUpdates(); | ||
3615 | return; | ||
3616 | } | ||
3617 | |||
3618 | lock (m_primFullUpdates.SyncRoot) | ||
3619 | count = m_primFullUpdates.Count; | ||
3620 | if (count > 0) | ||
3621 | { | ||
3622 | ProcessPrimFullUpdates(); | ||
3623 | return; | ||
3624 | } | ||
3625 | |||
3626 | lock (m_primTerseUpdates.SyncRoot) | ||
3627 | count = m_primTerseUpdates.Count; | ||
3628 | if (count > 0) | ||
3629 | { | ||
3630 | ProcessPrimTerseUpdates(); | ||
3631 | return; | ||
3632 | } | ||
3633 | break; | ||
3685 | } | 3634 | } |
3686 | } | 3635 | } |
3687 | 3636 | ||
@@ -3691,18 +3640,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3691 | m_imageManager.ProcessImageQueue(m_textureSendLimit); | 3640 | m_imageManager.ProcessImageQueue(m_textureSendLimit); |
3692 | } | 3641 | } |
3693 | 3642 | ||
3694 | void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) | 3643 | void ProcessPrimFullUpdates() |
3695 | { | 3644 | { |
3696 | lock (m_primFullUpdates_.SyncRoot) | 3645 | lock (m_primFullUpdates.SyncRoot) |
3697 | { | 3646 | { |
3698 | if (m_primFullUpdates_.Count == 0 && m_primFullUpdateTimer.Enabled) | ||
3699 | { | ||
3700 | lock (m_primFullUpdateTimer) | ||
3701 | m_primFullUpdateTimer.Stop(); | ||
3702 | |||
3703 | return; | ||
3704 | } | ||
3705 | |||
3706 | ObjectUpdatePacket outPacket = | 3647 | ObjectUpdatePacket outPacket = |
3707 | (ObjectUpdatePacket)PacketPool.Instance.GetPacket( | 3648 | (ObjectUpdatePacket)PacketPool.Instance.GetPacket( |
3708 | PacketType.ObjectUpdate); | 3649 | PacketType.ObjectUpdate); |
@@ -3712,7 +3653,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3712 | outPacket.RegionData.TimeDilation = | 3653 | outPacket.RegionData.TimeDilation = |
3713 | (ushort)(Scene.TimeDilation * ushort.MaxValue); | 3654 | (ushort)(Scene.TimeDilation * ushort.MaxValue); |
3714 | 3655 | ||
3715 | int max = m_primFullUpdates_.Count; | 3656 | int max = m_primFullUpdates.Count; |
3716 | if (max > m_primFullUpdatesPerPacket) | 3657 | if (max > m_primFullUpdatesPerPacket) |
3717 | max = m_primFullUpdatesPerPacket; | 3658 | max = m_primFullUpdatesPerPacket; |
3718 | 3659 | ||
@@ -3727,12 +3668,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3727 | for (count = 0 ; count < max ; count++) | 3668 | for (count = 0 ; count < max ; count++) |
3728 | { | 3669 | { |
3729 | int length = 0; | 3670 | int length = 0; |
3730 | m_primFullUpdates_.Peek().ToBytes(blockbuffer, ref length); | 3671 | m_primFullUpdates.Peek().ToBytes(blockbuffer, ref length); |
3731 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); | 3672 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); |
3732 | if (size + length > Packet.MTU) | 3673 | if (size + length > Packet.MTU) |
3733 | break; | 3674 | break; |
3734 | size += length; | 3675 | size += length; |
3735 | updates.Enqueue(m_primFullUpdates_.Dequeue()); | 3676 | updates.Enqueue(m_primFullUpdates.Dequeue()); |
3736 | } | 3677 | } |
3737 | 3678 | ||
3738 | outPacket.ObjectData = | 3679 | outPacket.ObjectData = |
@@ -3743,53 +3684,42 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3743 | 3684 | ||
3744 | outPacket.Header.Zerocoded = true; | 3685 | outPacket.Header.Zerocoded = true; |
3745 | OutPacket(outPacket, ThrottleOutPacketType.State); | 3686 | OutPacket(outPacket, ThrottleOutPacketType.State); |
3746 | |||
3747 | if (m_primFullUpdates_.Count == 0 && m_primFullUpdateTimer.Enabled) | ||
3748 | lock (m_primFullUpdateTimer) | ||
3749 | m_primFullUpdateTimer.Stop(); | ||
3750 | } | 3687 | } |
3751 | } | 3688 | } |
3752 | 3689 | ||
3753 | /// <summary> | 3690 | /// <summary> |
3754 | /// | 3691 | /// |
3755 | /// </summary> | 3692 | /// </summary> |
3756 | public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, | 3693 | //public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, |
3757 | Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID ownerID, int attachPoint) | 3694 | // Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID ownerID, int attachPoint) |
3695 | public void SendPrimTerseUpdate(SendPrimitiveTerseData data) | ||
3758 | { | 3696 | { |
3759 | if (attachPoint > 30 && ownerID != AgentId) // Someone else's HUD | 3697 | if (data.priority == double.NaN) |
3698 | { | ||
3699 | m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update"); | ||
3700 | return; | ||
3701 | } | ||
3702 | |||
3703 | Quaternion rotation = data.rotation; | ||
3704 | |||
3705 | if (data.attachPoint > 30 && data.owner != AgentId) // Someone else's HUD | ||
3760 | return; | 3706 | return; |
3761 | 3707 | ||
3762 | if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) | 3708 | if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) |
3763 | rotation = Quaternion.Identity; | 3709 | rotation = Quaternion.Identity; |
3764 | 3710 | ||
3765 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = | 3711 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = |
3766 | CreatePrimImprovedBlock(localID, position, rotation, | 3712 | CreatePrimImprovedBlock(data.localID, data.position, rotation, |
3767 | velocity, rotationalvelocity, state); | 3713 | data.velocity, data.rotationalvelocity, data.state); |
3768 | |||
3769 | lock (m_primTerseUpdates_.SyncRoot) | ||
3770 | { | ||
3771 | if (m_primTerseUpdates_.Count == 0) | ||
3772 | m_primTerseUpdateTimer.Start(); | ||
3773 | |||
3774 | m_primTerseUpdates_.Enqueue(DateTime.Now.ToOADate(), objectData, localID); | ||
3775 | 3714 | ||
3776 | if (m_primTerseUpdates_.Count >= m_primTerseUpdatesPerPacket) | 3715 | lock (m_primTerseUpdates.SyncRoot) |
3777 | ProcessPrimTerseUpdates(this, null); | 3716 | m_primTerseUpdates.Enqueue(data.priority, objectData, data.localID); |
3778 | } | ||
3779 | } | 3717 | } |
3780 | 3718 | ||
3781 | void ProcessPrimTerseUpdates(object sender, ElapsedEventArgs e) | 3719 | void ProcessPrimTerseUpdates() |
3782 | { | 3720 | { |
3783 | lock (m_primTerseUpdates_.SyncRoot) | 3721 | lock (m_primTerseUpdates.SyncRoot) |
3784 | { | 3722 | { |
3785 | if (m_primTerseUpdates_.Count == 0) | ||
3786 | { | ||
3787 | lock (m_primTerseUpdateTimer) | ||
3788 | m_primTerseUpdateTimer.Stop(); | ||
3789 | |||
3790 | return; | ||
3791 | } | ||
3792 | |||
3793 | ImprovedTerseObjectUpdatePacket outPacket = | 3723 | ImprovedTerseObjectUpdatePacket outPacket = |
3794 | (ImprovedTerseObjectUpdatePacket) | 3724 | (ImprovedTerseObjectUpdatePacket) |
3795 | PacketPool.Instance.GetPacket( | 3725 | PacketPool.Instance.GetPacket( |
@@ -3800,7 +3730,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3800 | outPacket.RegionData.TimeDilation = | 3730 | outPacket.RegionData.TimeDilation = |
3801 | (ushort)(Scene.TimeDilation * ushort.MaxValue); | 3731 | (ushort)(Scene.TimeDilation * ushort.MaxValue); |
3802 | 3732 | ||
3803 | int max = m_primTerseUpdates_.Count; | 3733 | int max = m_primTerseUpdates.Count; |
3804 | if (max > m_primTerseUpdatesPerPacket) | 3734 | if (max > m_primTerseUpdatesPerPacket) |
3805 | max = m_primTerseUpdatesPerPacket; | 3735 | max = m_primTerseUpdatesPerPacket; |
3806 | 3736 | ||
@@ -3815,12 +3745,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3815 | for (count = 0 ; count < max ; count++) | 3745 | for (count = 0 ; count < max ; count++) |
3816 | { | 3746 | { |
3817 | int length = 0; | 3747 | int length = 0; |
3818 | m_primTerseUpdates_.Peek().ToBytes(blockbuffer, ref length); | 3748 | m_primTerseUpdates.Peek().ToBytes(blockbuffer, ref length); |
3819 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); | 3749 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); |
3820 | if (size + length > Packet.MTU) | 3750 | if (size + length > Packet.MTU) |
3821 | break; | 3751 | break; |
3822 | size += length; | 3752 | size += length; |
3823 | updates.Enqueue(m_primTerseUpdates_.Dequeue()); | 3753 | updates.Enqueue(m_primTerseUpdates.Dequeue()); |
3824 | } | 3754 | } |
3825 | 3755 | ||
3826 | outPacket.ObjectData = | 3756 | outPacket.ObjectData = |
@@ -3833,26 +3763,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3833 | outPacket.Header.Reliable = false; | 3763 | outPacket.Header.Reliable = false; |
3834 | outPacket.Header.Zerocoded = true; | 3764 | outPacket.Header.Zerocoded = true; |
3835 | OutPacket(outPacket, ThrottleOutPacketType.State); | 3765 | OutPacket(outPacket, ThrottleOutPacketType.State); |
3836 | |||
3837 | if (m_primTerseUpdates_.Count == 0) | ||
3838 | lock (m_primTerseUpdateTimer) | ||
3839 | m_primTerseUpdateTimer.Stop(); | ||
3840 | } | 3766 | } |
3841 | } | 3767 | } |
3842 | 3768 | ||
3843 | public void FlushPrimUpdates() | 3769 | public void FlushPrimUpdates() |
3844 | { | 3770 | { |
3845 | while (m_primFullUpdates_.Count > 0) | 3771 | while (m_primFullUpdates.Count > 0) |
3846 | { | 3772 | { |
3847 | ProcessPrimFullUpdates(this, null); | 3773 | ProcessPrimFullUpdates(); |
3848 | } | 3774 | } |
3849 | while (m_primTerseUpdates_.Count > 0) | 3775 | while (m_primTerseUpdates.Count > 0) |
3850 | { | 3776 | { |
3851 | ProcessPrimTerseUpdates(this, null); | 3777 | ProcessPrimTerseUpdates(); |
3852 | } | 3778 | } |
3853 | while (m_avatarTerseUpdates_.Count > 0) | 3779 | while (m_avatarTerseUpdates.Count > 0) |
3854 | { | 3780 | { |
3855 | ProcessAvatarTerseUpdates(this, null); | 3781 | ProcessAvatarTerseUpdates(); |
3856 | } | 3782 | } |
3857 | } | 3783 | } |
3858 | 3784 | ||