diff options
-rw-r--r-- | OpenSim/Region/Framework/Interfaces/ISceneViewer.cs | 28 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneViewer.cs | 460 |
2 files changed, 244 insertions, 244 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs index 1b2cdee..ef3887c 100644 --- a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs +++ b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs | |||
@@ -1,14 +1,14 @@ | |||
1 | using System; | 1 | using System; |
2 | using OpenSim.Region.Framework.Scenes; | 2 | using OpenSim.Region.Framework.Scenes; |
3 | 3 | ||
4 | namespace OpenSim.Region.Framework.Interfaces | 4 | namespace OpenSim.Region.Framework.Interfaces |
5 | { | 5 | { |
6 | public interface ISceneViewer | 6 | public interface ISceneViewer |
7 | { | 7 | { |
8 | void Reset(); | 8 | void Reset(); |
9 | void Close(); | 9 | void Close(); |
10 | int MaxPrimsPerFrame { get; set; } | 10 | int MaxPrimsPerFrame { get; set; } |
11 | void QueuePartForUpdate(SceneObjectPart part); | 11 | void QueuePartForUpdate(SceneObjectPart part); |
12 | void SendPrimUpdates(); | 12 | void SendPrimUpdates(); |
13 | } | 13 | } |
14 | } | 14 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index 42966b1..8ab0552 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs | |||
@@ -1,230 +1,230 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSimulator Project nor the | 12 | * * Neither the name of the OpenSimulator Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using OpenMetaverse; | 30 | using OpenMetaverse; |
31 | using log4net; | 31 | using log4net; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Framework.Client; | 33 | using OpenSim.Framework.Client; |
34 | using OpenSim.Framework.Communications.Cache; | 34 | using OpenSim.Framework.Communications.Cache; |
35 | using OpenSim.Region.Framework.Interfaces; | 35 | using OpenSim.Region.Framework.Interfaces; |
36 | using OpenSim.Region.Framework.Scenes.Types; | 36 | using OpenSim.Region.Framework.Scenes.Types; |
37 | 37 | ||
38 | namespace OpenSim.Region.Framework.Scenes | 38 | namespace OpenSim.Region.Framework.Scenes |
39 | { | 39 | { |
40 | public class SceneViewer : ISceneViewer | 40 | public class SceneViewer : ISceneViewer |
41 | { | 41 | { |
42 | protected ScenePresence m_presence; | 42 | protected ScenePresence m_presence; |
43 | protected UpdateQueue m_partsUpdateQueue = new UpdateQueue(); | 43 | protected UpdateQueue m_partsUpdateQueue = new UpdateQueue(); |
44 | protected Queue<SceneObjectGroup> m_pendingObjects; | 44 | protected Queue<SceneObjectGroup> m_pendingObjects; |
45 | 45 | ||
46 | protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>(); | 46 | protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>(); |
47 | 47 | ||
48 | protected int m_maxPrimsPerFrame = 200; | 48 | protected int m_maxPrimsPerFrame = 200; |
49 | 49 | ||
50 | public int MaxPrimsPerFrame | 50 | public int MaxPrimsPerFrame |
51 | { | 51 | { |
52 | get { return m_maxPrimsPerFrame; } | 52 | get { return m_maxPrimsPerFrame; } |
53 | set { m_maxPrimsPerFrame = value; } | 53 | set { m_maxPrimsPerFrame = value; } |
54 | } | 54 | } |
55 | 55 | ||
56 | public SceneViewer() | 56 | public SceneViewer() |
57 | { | 57 | { |
58 | } | 58 | } |
59 | 59 | ||
60 | public SceneViewer(ScenePresence presence) | 60 | public SceneViewer(ScenePresence presence) |
61 | { | 61 | { |
62 | m_presence = presence; | 62 | m_presence = presence; |
63 | } | 63 | } |
64 | 64 | ||
65 | /// <summary> | 65 | /// <summary> |
66 | /// Add the part to the queue of parts for which we need to send an update to the client | 66 | /// Add the part to the queue of parts for which we need to send an update to the client |
67 | /// </summary> | 67 | /// </summary> |
68 | /// <param name="part"></param> | 68 | /// <param name="part"></param> |
69 | public void QueuePartForUpdate(SceneObjectPart part) | 69 | public void QueuePartForUpdate(SceneObjectPart part) |
70 | { | 70 | { |
71 | lock (m_partsUpdateQueue) | 71 | lock (m_partsUpdateQueue) |
72 | { | 72 | { |
73 | m_partsUpdateQueue.Enqueue(part); | 73 | m_partsUpdateQueue.Enqueue(part); |
74 | } | 74 | } |
75 | } | 75 | } |
76 | 76 | ||
77 | public void SendPrimUpdates() | 77 | public void SendPrimUpdates() |
78 | { | 78 | { |
79 | if (m_pendingObjects == null) | 79 | if (m_pendingObjects == null) |
80 | { | 80 | { |
81 | if (!m_presence.IsChildAgent || (m_presence.Scene.m_seeIntoRegionFromNeighbor)) | 81 | if (!m_presence.IsChildAgent || (m_presence.Scene.m_seeIntoRegionFromNeighbor)) |
82 | { | 82 | { |
83 | m_pendingObjects = new Queue<SceneObjectGroup>(); | 83 | m_pendingObjects = new Queue<SceneObjectGroup>(); |
84 | 84 | ||
85 | List<EntityBase> ents = new List<EntityBase>(m_presence.Scene.Entities); | 85 | List<EntityBase> ents = new List<EntityBase>(m_presence.Scene.Entities); |
86 | if (!m_presence.IsChildAgent) // Proximity sort makes no sense for | 86 | if (!m_presence.IsChildAgent) // Proximity sort makes no sense for |
87 | { // Child agents | 87 | { // Child agents |
88 | ents.Sort(delegate(EntityBase a, EntityBase b) | 88 | ents.Sort(delegate(EntityBase a, EntityBase b) |
89 | { | 89 | { |
90 | return Vector3.Distance(m_presence.AbsolutePosition, a.AbsolutePosition).CompareTo(Vector3.Distance(m_presence.AbsolutePosition, b.AbsolutePosition)); | 90 | return Vector3.Distance(m_presence.AbsolutePosition, a.AbsolutePosition).CompareTo(Vector3.Distance(m_presence.AbsolutePosition, b.AbsolutePosition)); |
91 | }); | 91 | }); |
92 | } | 92 | } |
93 | 93 | ||
94 | foreach (EntityBase e in ents) | 94 | foreach (EntityBase e in ents) |
95 | { | 95 | { |
96 | if (e is SceneObjectGroup) | 96 | if (e is SceneObjectGroup) |
97 | m_pendingObjects.Enqueue((SceneObjectGroup)e); | 97 | m_pendingObjects.Enqueue((SceneObjectGroup)e); |
98 | } | 98 | } |
99 | } | 99 | } |
100 | } | 100 | } |
101 | 101 | ||
102 | while (m_pendingObjects != null && m_pendingObjects.Count > 0 && m_partsUpdateQueue.Count < m_maxPrimsPerFrame) | 102 | while (m_pendingObjects != null && m_pendingObjects.Count > 0 && m_partsUpdateQueue.Count < m_maxPrimsPerFrame) |
103 | { | 103 | { |
104 | SceneObjectGroup g = m_pendingObjects.Dequeue(); | 104 | SceneObjectGroup g = m_pendingObjects.Dequeue(); |
105 | 105 | ||
106 | // This is where we should check for draw distance | 106 | // This is where we should check for draw distance |
107 | // do culling and stuff. Problem with that is that until | 107 | // do culling and stuff. Problem with that is that until |
108 | // we recheck in movement, that won't work right. | 108 | // we recheck in movement, that won't work right. |
109 | // So it's not implemented now. | 109 | // So it's not implemented now. |
110 | // | 110 | // |
111 | 111 | ||
112 | // Don't even queue if we have sent this one | 112 | // Don't even queue if we have sent this one |
113 | // | 113 | // |
114 | if (!m_updateTimes.ContainsKey(g.UUID)) | 114 | if (!m_updateTimes.ContainsKey(g.UUID)) |
115 | g.ScheduleFullUpdateToAvatar(m_presence); | 115 | g.ScheduleFullUpdateToAvatar(m_presence); |
116 | } | 116 | } |
117 | 117 | ||
118 | while (m_partsUpdateQueue.Count > 0) | 118 | while (m_partsUpdateQueue.Count > 0) |
119 | { | 119 | { |
120 | SceneObjectPart part = m_partsUpdateQueue.Dequeue(); | 120 | SceneObjectPart part = m_partsUpdateQueue.Dequeue(); |
121 | 121 | ||
122 | if (part.ParentGroup == null || part.ParentGroup.IsDeleted) | 122 | if (part.ParentGroup == null || part.ParentGroup.IsDeleted) |
123 | continue; | 123 | continue; |
124 | 124 | ||
125 | if (m_updateTimes.ContainsKey(part.UUID)) | 125 | if (m_updateTimes.ContainsKey(part.UUID)) |
126 | { | 126 | { |
127 | ScenePartUpdate update = m_updateTimes[part.UUID]; | 127 | ScenePartUpdate update = m_updateTimes[part.UUID]; |
128 | 128 | ||
129 | // We deal with the possibility that two updates occur at | 129 | // We deal with the possibility that two updates occur at |
130 | // the same unix time at the update point itself. | 130 | // the same unix time at the update point itself. |
131 | 131 | ||
132 | if ((update.LastFullUpdateTime < part.TimeStampFull) || | 132 | if ((update.LastFullUpdateTime < part.TimeStampFull) || |
133 | part.IsAttachment) | 133 | part.IsAttachment) |
134 | { | 134 | { |
135 | // m_log.DebugFormat( | 135 | // m_log.DebugFormat( |
136 | // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", | 136 | // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", |
137 | // part.Name, part.UUID, part.TimeStampFull); | 137 | // part.Name, part.UUID, part.TimeStampFull); |
138 | 138 | ||
139 | part.SendFullUpdate(m_presence.ControllingClient, | 139 | part.SendFullUpdate(m_presence.ControllingClient, |
140 | m_presence.GenerateClientFlags(part.UUID)); | 140 | m_presence.GenerateClientFlags(part.UUID)); |
141 | 141 | ||
142 | // We'll update to the part's timestamp rather than | 142 | // We'll update to the part's timestamp rather than |
143 | // the current time to avoid the race condition | 143 | // the current time to avoid the race condition |
144 | // whereby the next tick occurs while we are doing | 144 | // whereby the next tick occurs while we are doing |
145 | // this update. If this happened, then subsequent | 145 | // this update. If this happened, then subsequent |
146 | // updates which occurred on the same tick or the | 146 | // updates which occurred on the same tick or the |
147 | // next tick of the last update would be ignored. | 147 | // next tick of the last update would be ignored. |
148 | 148 | ||
149 | update.LastFullUpdateTime = part.TimeStampFull; | 149 | update.LastFullUpdateTime = part.TimeStampFull; |
150 | 150 | ||
151 | } | 151 | } |
152 | else if (update.LastTerseUpdateTime <= part.TimeStampTerse) | 152 | else if (update.LastTerseUpdateTime <= part.TimeStampTerse) |
153 | { | 153 | { |
154 | // m_log.DebugFormat( | 154 | // m_log.DebugFormat( |
155 | // "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", | 155 | // "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", |
156 | // part.Name, part.UUID, part.TimeStampTerse); | 156 | // part.Name, part.UUID, part.TimeStampTerse); |
157 | 157 | ||
158 | part.SendTerseUpdateToClient(m_presence.ControllingClient); | 158 | part.SendTerseUpdateToClient(m_presence.ControllingClient); |
159 | 159 | ||
160 | update.LastTerseUpdateTime = part.TimeStampTerse; | 160 | update.LastTerseUpdateTime = part.TimeStampTerse; |
161 | } | 161 | } |
162 | } | 162 | } |
163 | else | 163 | else |
164 | { | 164 | { |
165 | //never been sent to client before so do full update | 165 | //never been sent to client before so do full update |
166 | ScenePartUpdate update = new ScenePartUpdate(); | 166 | ScenePartUpdate update = new ScenePartUpdate(); |
167 | update.FullID = part.UUID; | 167 | update.FullID = part.UUID; |
168 | update.LastFullUpdateTime = part.TimeStampFull; | 168 | update.LastFullUpdateTime = part.TimeStampFull; |
169 | m_updateTimes.Add(part.UUID, update); | 169 | m_updateTimes.Add(part.UUID, update); |
170 | 170 | ||
171 | // Attachment handling | 171 | // Attachment handling |
172 | // | 172 | // |
173 | if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0) | 173 | if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0) |
174 | { | 174 | { |
175 | if (part != part.ParentGroup.RootPart) | 175 | if (part != part.ParentGroup.RootPart) |
176 | continue; | 176 | continue; |
177 | 177 | ||
178 | part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient); | 178 | part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient); |
179 | continue; | 179 | continue; |
180 | } | 180 | } |
181 | 181 | ||
182 | part.SendFullUpdate(m_presence.ControllingClient, | 182 | part.SendFullUpdate(m_presence.ControllingClient, |
183 | m_presence.GenerateClientFlags(part.UUID)); | 183 | m_presence.GenerateClientFlags(part.UUID)); |
184 | } | 184 | } |
185 | } | 185 | } |
186 | 186 | ||
187 | m_presence.ControllingClient.FlushPrimUpdates(); | 187 | m_presence.ControllingClient.FlushPrimUpdates(); |
188 | } | 188 | } |
189 | 189 | ||
190 | public void Reset() | 190 | public void Reset() |
191 | { | 191 | { |
192 | if (m_pendingObjects != null) | 192 | if (m_pendingObjects != null) |
193 | { | 193 | { |
194 | lock (m_pendingObjects) | 194 | lock (m_pendingObjects) |
195 | { | 195 | { |
196 | 196 | ||
197 | m_pendingObjects.Clear(); | 197 | m_pendingObjects.Clear(); |
198 | m_pendingObjects = null; | 198 | m_pendingObjects = null; |
199 | } | 199 | } |
200 | } | 200 | } |
201 | } | 201 | } |
202 | 202 | ||
203 | public void Close() | 203 | public void Close() |
204 | { | 204 | { |
205 | lock (m_updateTimes) | 205 | lock (m_updateTimes) |
206 | { | 206 | { |
207 | m_updateTimes.Clear(); | 207 | m_updateTimes.Clear(); |
208 | } | 208 | } |
209 | lock (m_partsUpdateQueue) | 209 | lock (m_partsUpdateQueue) |
210 | { | 210 | { |
211 | m_partsUpdateQueue.Clear(); | 211 | m_partsUpdateQueue.Clear(); |
212 | } | 212 | } |
213 | Reset(); | 213 | Reset(); |
214 | } | 214 | } |
215 | 215 | ||
216 | public class ScenePartUpdate | 216 | public class ScenePartUpdate |
217 | { | 217 | { |
218 | public UUID FullID; | 218 | public UUID FullID; |
219 | public uint LastFullUpdateTime; | 219 | public uint LastFullUpdateTime; |
220 | public uint LastTerseUpdateTime; | 220 | public uint LastTerseUpdateTime; |
221 | 221 | ||
222 | public ScenePartUpdate() | 222 | public ScenePartUpdate() |
223 | { | 223 | { |
224 | FullID = UUID.Zero; | 224 | FullID = UUID.Zero; |
225 | LastFullUpdateTime = 0; | 225 | LastFullUpdateTime = 0; |
226 | LastTerseUpdateTime = 0; | 226 | LastTerseUpdateTime = 0; |
227 | } | 227 | } |
228 | } | 228 | } |
229 | } | 229 | } |
230 | } | 230 | } |