aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
authorMelanie2011-04-17 17:11:33 +0200
committerMelanie2011-04-17 17:11:33 +0200
commit5db8dcb5635ed39c299ff30516fb237767a041a5 (patch)
treef543692082d140d6b5747533f77db63ac8b93b2d /OpenSim/Region/ClientStack
parentMerge branch 'master' into careminster-presence-refactor (diff)
downloadopensim-SC-5db8dcb5635ed39c299ff30516fb237767a041a5.zip
opensim-SC-5db8dcb5635ed39c299ff30516fb237767a041a5.tar.gz
opensim-SC-5db8dcb5635ed39c299ff30516fb237767a041a5.tar.bz2
opensim-SC-5db8dcb5635ed39c299ff30516fb237767a041a5.tar.xz
Fix agent animation updates
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs287
1 files changed, 122 insertions, 165 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 5b2484d..4abb6e2 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -3703,209 +3703,166 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3703 3703
3704 int updatesThisCall = 0; 3704 int updatesThisCall = 0;
3705 3705
3706//<MIC>
3707// DEBUGGING CODE... REMOVE
3708// LogQueueProcessEvent(this.m_agentId,m_entityUpdates,m_maxUpdates);
3709//</MIC>
3710 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3706 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3711 // condition where a kill can be processed before an out-of-date update for the same object. 3707 // condition where a kill can be processed before an out-of-date update for the same object.
3712 float avgTimeDilation = 1.0f; 3708 float avgTimeDilation = 1.0f;
3713 3709
3714 lock (m_killRecord) 3710 EntityUpdate update;
3711 Int32 timeinqueue; // this is just debugging code & can be dropped later
3712
3713 while (updatesThisCall < m_maxUpdates)
3715 { 3714 {
3716 EntityUpdate update; 3715 lock (m_entityUpdates.SyncRoot)
3717 Int32 timeinqueue; // this is just debugging code & can be dropped later 3716 if (!m_entityUpdates.TryDequeue(out update, out timeinqueue))
3718 3717 break;
3719 while (updatesThisCall < m_maxUpdates) 3718 avgTimeDilation += update.TimeDilation;
3720 { 3719 avgTimeDilation *= 0.5f;
3721 lock (m_entityUpdates.SyncRoot) 3720
3722 if (!m_entityUpdates.TryDequeue(out update, out timeinqueue)) 3721 if (update.Entity is SceneObjectPart)
3723 break; 3722 {
3724 avgTimeDilation += update.TimeDilation; 3723 SceneObjectPart part = (SceneObjectPart)update.Entity;
3725 avgTimeDilation *= 0.5f; 3724
3726 3725 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3727 if (update.Entity is SceneObjectPart) 3726 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3727 // safety measure.
3728 //
3729 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3730 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3731 // updates and kills on different threads with different scheduling strategies, hence this protection.
3732 //
3733 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3734 // after the root prim has been deleted.
3735 lock (m_killRecord)
3728 { 3736 {
3729 SceneObjectPart part = (SceneObjectPart)update.Entity; 3737 if (m_killRecord.Contains(part.LocalId))
3730 3738 continue;
3731 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3739 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3732 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3740 continue;
3733 // safety measure. 3741 }
3734 //
3735 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3736 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3737 // updates and kills on different threads with different scheduling strategies, hence this protection.
3738 //
3739 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3740 // after the root prim has been deleted.
3741 lock (m_killRecord)
3742 {
3743 if (m_killRecord.Contains(part.LocalId))
3744 continue;
3745 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3746 continue;
3747 }
3748 3742
3749 if (part.ParentGroup.IsDeleted) 3743 if (part.ParentGroup.IsDeleted)
3744 continue;
3745
3746 if (part.ParentGroup.IsAttachment)
3747 { // Someone else's HUD, why are we getting these?
3748 if (part.ParentGroup.OwnerID != AgentId &&
3749 part.ParentGroup.RootPart.Shape.State >= 30)
3750 continue;
3751 ScenePresence sp;
3752 // Owner is not in the sim, don't update it to
3753 // anyone
3754 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3750 continue; 3755 continue;
3751 3756
3752 if (part.ParentGroup.IsAttachment) 3757 List<SceneObjectGroup> atts = sp.Attachments;
3753 { // Someone else's HUD, why are we getting these? 3758 bool found = false;
3754 if (part.ParentGroup.OwnerID != AgentId && 3759 foreach (SceneObjectGroup att in atts)
3755 part.ParentGroup.RootPart.Shape.State >= 30) 3760 {
3756 continue; 3761 if (att == part.ParentGroup)
3757 ScenePresence sp;
3758 // Owner is not in the sim, don't update it to
3759 // anyone
3760 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3761 continue;
3762
3763 List<SceneObjectGroup> atts = sp.Attachments;
3764 bool found = false;
3765 foreach (SceneObjectGroup att in atts)
3766 { 3762 {
3767 if (att == part.ParentGroup) 3763 found = true;
3768 { 3764 break;
3769 found = true;
3770 break;
3771 }
3772 } 3765 }
3773
3774 // It's an attachment of a valid avatar, but
3775 // doesn't seem to be attached, skip
3776 if (!found)
3777 continue;
3778 } 3766 }
3779 3767
3780 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3768 // It's an attachment of a valid avatar, but
3769 // doesn't seem to be attached, skip
3770 if (!found)
3771 continue;
3772 }
3773
3774 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3775 {
3776 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3777 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3781 { 3778 {
3782 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3779 part.Shape.LightEntry = false;
3783 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3784 {
3785 part.Shape.LightEntry = false;
3786 }
3787 } 3780 }
3788 } 3781 }
3782 }
3783
3784 ++updatesThisCall;
3789 3785
3790 ++updatesThisCall; 3786 #region UpdateFlags to packet type conversion
3791 3787
3792 #region UpdateFlags to packet type conversion 3788 PrimUpdateFlags updateFlags = update.Flags;
3793 3789
3794 PrimUpdateFlags updateFlags = update.Flags; 3790 bool canUseCompressed = true;
3791 bool canUseImproved = true;
3795 3792
3796 bool canUseCompressed = true; 3793 // Compressed object updates only make sense for LL primitives
3797 bool canUseImproved = true; 3794 if (!(update.Entity is SceneObjectPart))
3795 {
3796 canUseCompressed = false;
3797 }
3798 3798
3799 // Compressed object updates only make sense for LL primitives 3799 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3800 if (!(update.Entity is SceneObjectPart)) 3800 {
3801 canUseCompressed = false;
3802 canUseImproved = false;
3803 }
3804 else
3805 {
3806 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3807 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3808 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3809 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3801 { 3810 {
3802 canUseCompressed = false; 3811 canUseCompressed = false;
3803 } 3812 }
3804 3813
3805 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3814 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3815 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3816 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3817 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3818 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3819 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3820 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3821 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3822 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3823 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3824 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3825 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3826 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3827 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3806 { 3828 {
3807 canUseCompressed = false;
3808 canUseImproved = false; 3829 canUseImproved = false;
3809 } 3830 }
3810 else 3831 }
3811 {
3812 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3813 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3814 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3815 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3816 {
3817 if (update.Entity is ScenePresence)
3818 {
3819 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3820 }
3821 else
3822 {
3823 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3824 }
3825 }
3826
3827 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3828 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3829 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3830 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3831 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3832 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3833 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3834 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3835 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3836 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3837 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3838 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3839 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3840 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3841 {
3842 canUseImproved = false;
3843 }
3844 }
3845 3832
3846 #endregion UpdateFlags to packet type conversion 3833 #endregion UpdateFlags to packet type conversion
3847 3834
3848 #region Block Construction 3835 #region Block Construction
3849 3836
3850 // TODO: Remove this once we can build compressed updates 3837 // TODO: Remove this once we can build compressed updates
3851 canUseCompressed = false; 3838 canUseCompressed = false;
3852 3839
3853 if (!canUseImproved && !canUseCompressed) 3840 if (!canUseImproved && !canUseCompressed)
3854 { 3841 {
3855 if (update.Entity is ScenePresence) 3842 if (update.Entity is ScenePresence)
3856 {
3857 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3858 }
3859 else
3860 {
3861 // if (update.Entity is SceneObjectPart && ((SceneObjectPart)update.Entity).IsAttachment)
3862 // {
3863 // SceneObjectPart sop = (SceneObjectPart)update.Entity;
3864 // string text = sop.Text;
3865 // if (text.IndexOf("\n") >= 0)
3866 // text = text.Remove(text.IndexOf("\n"));
3867 //
3868 // if (m_attachmentsSent.Contains(sop.ParentID))
3869 // {
3870 //// m_log.DebugFormat(
3871 //// "[CLIENT]: Sending full info about attached prim {0} text {1}",
3872 //// sop.LocalId, text);
3873 //
3874 // objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock(sop, this.m_agentId));
3875 //
3876 // m_attachmentsSent.Add(sop.LocalId);
3877 // }
3878 // else
3879 // {
3880 // m_log.DebugFormat(
3881 // "[CLIENT]: Requeueing full update of prim {0} text {1} since we haven't sent its parent {2} yet",
3882 // sop.LocalId, text, sop.ParentID);
3883 //
3884 // m_entityUpdates.Enqueue(double.MaxValue, update, sop.LocalId);
3885 // }
3886 // }
3887 // else
3888 // {
3889 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3890 // }
3891 }
3892 }
3893 else if (!canUseImproved)
3894 { 3843 {
3895 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3844 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3896 } 3845 }
3897 else 3846 else
3898 { 3847 {
3899 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3848 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3900 // Self updates go into a special list
3901 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3902 else
3903 // Everything else goes here
3904 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3905 } 3849 }
3906
3907 #endregion Block Construction
3908 } 3850 }
3851 else if (!canUseImproved)
3852 {
3853 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3854 }
3855 else
3856 {
3857 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3858 // Self updates go into a special list
3859 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3860 else
3861 // Everything else goes here
3862 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3863 }
3864
3865 #endregion Block Construction
3909 } 3866 }
3910 3867
3911 #region Packet Sending 3868 #region Packet Sending