aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Framework/Interfaces/ISceneViewer.cs28
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneViewer.cs460
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 @@
1using System; 1using System;
2using OpenSim.Region.Framework.Scenes; 2using OpenSim.Region.Framework.Scenes;
3 3
4namespace OpenSim.Region.Framework.Interfaces 4namespace 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
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using OpenMetaverse; 30using OpenMetaverse;
31using log4net; 31using log4net;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Framework.Client; 33using OpenSim.Framework.Client;
34using OpenSim.Framework.Communications.Cache; 34using OpenSim.Framework.Communications.Cache;
35using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes.Types; 36using OpenSim.Region.Framework.Scenes.Types;
37 37
38namespace OpenSim.Region.Framework.Scenes 38namespace 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}