diff options
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 191 |
1 files changed, 121 insertions, 70 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 9136f2d..5d70dc2 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -1722,17 +1722,43 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1722 | m_entityUpdates.Remove(localIDs); | 1722 | m_entityUpdates.Remove(localIDs); |
1723 | 1723 | ||
1724 | KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); | 1724 | KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); |
1725 | // TODO: don't create new blocks if recycling an old packet | 1725 | |
1726 | kill.ObjectData = new KillObjectPacket.ObjectDataBlock[localIDs.Count]; | 1726 | int perpacket = localIDs.Count; |
1727 | if(perpacket > 200) | ||
1728 | perpacket = 200; | ||
1729 | |||
1730 | int nsent = 0; | ||
1731 | |||
1732 | kill.ObjectData = new KillObjectPacket.ObjectDataBlock[perpacket]; | ||
1727 | for (int i = 0 ; i < localIDs.Count ; i++ ) | 1733 | for (int i = 0 ; i < localIDs.Count ; i++ ) |
1728 | { | 1734 | { |
1729 | kill.ObjectData[i] = new KillObjectPacket.ObjectDataBlock(); | 1735 | kill.ObjectData[nsent] = new KillObjectPacket.ObjectDataBlock(); |
1730 | kill.ObjectData[i].ID = localIDs[i]; | 1736 | kill.ObjectData[nsent].ID = localIDs[i]; |
1737 | |||
1738 | if(++nsent >= 200) | ||
1739 | { | ||
1740 | kill.Header.Reliable = true; | ||
1741 | kill.Header.Zerocoded = true; | ||
1742 | OutPacket(kill, ThrottleOutPacketType.Task); | ||
1743 | |||
1744 | perpacket = localIDs.Count - i - 1; | ||
1745 | if(perpacket == 0) | ||
1746 | break; | ||
1747 | if(perpacket > 200) | ||
1748 | perpacket = 200; | ||
1749 | |||
1750 | kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); | ||
1751 | kill.ObjectData = new KillObjectPacket.ObjectDataBlock[perpacket]; | ||
1752 | nsent = 0; | ||
1753 | } | ||
1731 | } | 1754 | } |
1732 | kill.Header.Reliable = true; | ||
1733 | kill.Header.Zerocoded = true; | ||
1734 | 1755 | ||
1735 | OutPacket(kill, ThrottleOutPacketType.Task); | 1756 | if(nsent != 0) |
1757 | { | ||
1758 | kill.Header.Reliable = true; | ||
1759 | kill.Header.Zerocoded = true; | ||
1760 | OutPacket(kill, ThrottleOutPacketType.Task); | ||
1761 | } | ||
1736 | } | 1762 | } |
1737 | 1763 | ||
1738 | /// <summary> | 1764 | /// <summary> |
@@ -4292,17 +4318,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4292 | m_killRecord.Clear(); | 4318 | m_killRecord.Clear(); |
4293 | } | 4319 | } |
4294 | 4320 | ||
4295 | lock(GroupsNeedFullUpdate) | 4321 | if(GroupsNeedFullUpdate.Count > 0) |
4296 | { | 4322 | { |
4297 | if(GroupsNeedFullUpdate.Count > 0) | 4323 | foreach(SceneObjectGroup grp in GroupsNeedFullUpdate) |
4298 | { | 4324 | { |
4299 | foreach(SceneObjectGroup grp in GroupsNeedFullUpdate) | 4325 | grp.ScheduleGroupForFullUpdate(); |
4300 | { | 4326 | lock(GroupsInView) |
4301 | grp.ScheduleGroupForFullUpdate(); | 4327 | GroupsInView.Add(grp); |
4302 | lock(GroupsInView) | ||
4303 | GroupsInView.Add(grp); | ||
4304 | } | ||
4305 | GroupsNeedFullUpdate.Clear(); | ||
4306 | } | 4328 | } |
4307 | } | 4329 | } |
4308 | #endregion | 4330 | #endregion |
@@ -4339,81 +4361,110 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4339 | 4361 | ||
4340 | public void ReprioritizeUpdates() | 4362 | public void ReprioritizeUpdates() |
4341 | { | 4363 | { |
4342 | CheckGroupsInView(); | ||
4343 | lock (m_entityUpdates.SyncRoot) | 4364 | lock (m_entityUpdates.SyncRoot) |
4344 | m_entityUpdates.Reprioritize(UpdatePriorityHandler); | 4365 | m_entityUpdates.Reprioritize(UpdatePriorityHandler); |
4366 | CheckGroupsInView(); | ||
4345 | } | 4367 | } |
4346 | 4368 | ||
4369 | private bool CheckGroupsInViewBusy = false; | ||
4370 | private bool CheckGroupsInViewOverRun = false; | ||
4371 | |||
4347 | public void CheckGroupsInView() | 4372 | public void CheckGroupsInView() |
4348 | { | 4373 | { |
4349 | bool doCulling = m_scene.ObjectsCullingByDistance; | 4374 | bool doCulling = m_scene.ObjectsCullingByDistance; |
4350 | if(!doCulling) | 4375 | if(!doCulling) |
4351 | return; | 4376 | return; |
4352 | float cullingrange = 64.0f; | 4377 | |
4353 | Vector3 mycamera = Vector3.Zero; | 4378 | if(CheckGroupsInViewBusy) |
4354 | Vector3 mypos = Vector3.Zero; | ||
4355 | ScenePresence mysp = (ScenePresence)SceneAgent; | ||
4356 | if(mysp != null && !mysp.IsDeleted) | ||
4357 | { | 4379 | { |
4358 | cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f; | 4380 | CheckGroupsInViewOverRun = true; |
4359 | mycamera = mysp.CameraPosition; | 4381 | return; |
4360 | mypos = mysp.AbsolutePosition; | ||
4361 | } | 4382 | } |
4362 | else | 4383 | CheckGroupsInViewBusy = true; |
4363 | return; | 4384 | do |
4385 | { | ||
4386 | CheckGroupsInViewOverRun = false; | ||
4364 | 4387 | ||
4365 | HashSet<SceneObjectGroup> NewGroupsInView = new HashSet<SceneObjectGroup>(); | 4388 | float cullingrange = 64.0f; |
4366 | HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>(); | 4389 | Vector3 mycamera = Vector3.Zero; |
4367 | List<uint> kills = new List<uint>(); | 4390 | Vector3 mypos = Vector3.Zero; |
4368 | // will this take for ever ? | 4391 | ScenePresence mysp = (ScenePresence)SceneAgent; |
4369 | EntityBase[] entities = m_scene.Entities.GetEntities(); | 4392 | if(mysp != null && !mysp.IsDeleted) |
4370 | foreach (EntityBase e in entities) | 4393 | { |
4371 | { | 4394 | cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f; |
4372 | if (e != null && e is SceneObjectGroup && !((SceneObjectGroup)e).IsAttachment) | 4395 | mycamera = mysp.CameraPosition; |
4373 | { | 4396 | mypos = mysp.AbsolutePosition; |
4374 | SceneObjectGroup grp = (SceneObjectGroup)e; | 4397 | } |
4375 | Vector3 grppos = grp.AbsolutePosition; | 4398 | else |
4376 | float dcam = (grppos - mycamera).LengthSquared(); | 4399 | { |
4377 | float dpos = (grppos - mypos).LengthSquared(); | 4400 | CheckGroupsInViewBusy= false; |
4378 | if(dcam < dpos) | 4401 | return; |
4379 | dpos = dcam; | 4402 | } |
4380 | dpos = (float)Math.Sqrt(dpos) - grp.GetBoundsRadius(); | 4403 | |
4381 | bool inview; | 4404 | HashSet<SceneObjectGroup> NewGroupsInView = new HashSet<SceneObjectGroup>(); |
4382 | lock(GroupsInView) | 4405 | HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>(); |
4383 | inview = GroupsInView.Contains(grp); | 4406 | List<uint> kills = new List<uint>(); |
4384 | if(dpos > cullingrange) | 4407 | |
4408 | EntityBase[] entities = m_scene.Entities.GetEntities(); | ||
4409 | foreach (EntityBase e in entities) | ||
4410 | { | ||
4411 | if(!IsActive) | ||
4412 | return; | ||
4413 | if (e != null && e is SceneObjectGroup && !((SceneObjectGroup)e).IsAttachment) | ||
4385 | { | 4414 | { |
4386 | if(inview) | 4415 | SceneObjectGroup grp = (SceneObjectGroup)e; |
4416 | Vector3 grppos = grp.AbsolutePosition; | ||
4417 | |||
4418 | float dcam = (grppos - mycamera).LengthSquared(); | ||
4419 | float dpos = (grppos - mypos).LengthSquared(); | ||
4420 | if(dcam < dpos) | ||
4421 | dpos = dcam; | ||
4422 | |||
4423 | dpos = (float)Math.Sqrt(dpos) - grp.GetBoundsRadius(); | ||
4424 | |||
4425 | bool inview; | ||
4426 | lock(GroupsInView) | ||
4427 | inview = GroupsInView.Contains(grp); | ||
4428 | |||
4429 | if(dpos > cullingrange) | ||
4387 | { | 4430 | { |
4388 | // GroupsInView.Remove(grp); | 4431 | if(inview) |
4389 | if (!kills.Contains(grp.LocalId)) | 4432 | { |
4390 | kills.Add(grp.LocalId); | 4433 | kills.Add(grp.LocalId); |
4434 | if (kills.Count > 100) | ||
4435 | { | ||
4436 | SendKillObject(kills); | ||
4437 | kills.Clear(); | ||
4438 | Thread.Sleep(50); | ||
4439 | } | ||
4440 | } | ||
4441 | } | ||
4442 | else | ||
4443 | { | ||
4444 | if(!inview) | ||
4445 | GroupsNeedFullUpdate.Add(grp); | ||
4446 | NewGroupsInView.Add(grp); | ||
4391 | } | 4447 | } |
4392 | } | ||
4393 | else | ||
4394 | { | ||
4395 | if(!inview) | ||
4396 | GroupsNeedFullUpdate.Add(grp); | ||
4397 | NewGroupsInView.Add(grp); | ||
4398 | } | 4448 | } |
4399 | } | 4449 | } |
4400 | } | ||
4401 | 4450 | ||
4402 | lock(GroupsInView) | 4451 | lock(GroupsInView) |
4403 | GroupsInView = NewGroupsInView; | 4452 | GroupsInView = NewGroupsInView; |
4404 | 4453 | ||
4405 | if (kills.Count > 0) | 4454 | if (kills.Count > 0) |
4406 | { | 4455 | { |
4407 | SendKillObject(kills); | 4456 | SendKillObject(kills); |
4408 | kills.Clear(); | 4457 | kills.Clear(); |
4409 | } | 4458 | } |
4410 | 4459 | ||
4411 | if(GroupsNeedFullUpdate.Count > 0) | 4460 | if(GroupsNeedFullUpdate.Count > 0) |
4412 | { | 4461 | { |
4413 | foreach(SceneObjectGroup grp in GroupsNeedFullUpdate) | 4462 | foreach(SceneObjectGroup grp in GroupsNeedFullUpdate) |
4414 | grp.ScheduleGroupForFullUpdate(); | 4463 | grp.ScheduleGroupForFullUpdate(); |
4415 | } | 4464 | } |
4416 | GroupsNeedFullUpdate.Clear(); | 4465 | } while(CheckGroupsInViewOverRun); |
4466 | |||
4467 | CheckGroupsInViewBusy = false; | ||
4417 | } | 4468 | } |
4418 | 4469 | ||
4419 | private bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity) | 4470 | private bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity) |