aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs')
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs383
1 files changed, 383 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
new file mode 100644
index 0000000..4d65038
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
@@ -0,0 +1,383 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#region Header
29
30// ContentManagementEntity.cs
31// User: bongiojp
32//
33//
34
35#endregion Header
36
37using System;
38using System.Collections.Generic;
39using System.Drawing;
40
41using OpenMetaverse;
42
43using Nini.Config;
44
45using OpenSim.Framework;
46using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Region.Physics.Manager;
49
50using log4net;
51
52namespace OpenSim.Region.OptionalModules.ContentManagement
53{
54 public class ContentManagementEntity : MetaEntity
55 {
56 #region Static Fields
57
58// static float TimeToDiff = 0;
59// static float TimeToCreateEntities = 0;
60
61 #endregion Static Fields
62
63 #region Fields
64
65 protected Dictionary<UUID, AuraMetaEntity> m_AuraEntities = new Dictionary<UUID, AuraMetaEntity>();
66 protected Dictionary<UUID, BeamMetaEntity> m_BeamEntities = new Dictionary<UUID, BeamMetaEntity>();
67
68 // The LinkNum of parts in m_Entity and m_UnchangedEntity are the same though UUID and LocalId are different.
69 // This can come in handy.
70 protected SceneObjectGroup m_UnchangedEntity = null;
71
72 /// <value>
73 /// Should be set to true when there is a difference between m_UnchangedEntity and the corresponding scene object group in the scene entity list.
74 /// </value>
75 bool DiffersFromSceneGroup = false;
76
77 #endregion Fields
78
79 #region Constructors
80
81 public ContentManagementEntity(SceneObjectGroup Unchanged, bool physics)
82 : base(Unchanged, false)
83 {
84 m_UnchangedEntity = Unchanged.Copy(Unchanged.RootPart.OwnerID, Unchanged.RootPart.GroupID, false);
85 }
86
87 public ContentManagementEntity(string objectXML, Scene scene, bool physics)
88 : base(objectXML, scene, false)
89 {
90 m_UnchangedEntity = new SceneObjectGroup(objectXML);
91 }
92
93 #endregion Constructors
94
95 #region Public Properties
96
97 public SceneObjectGroup UnchangedEntity
98 {
99 get { return m_UnchangedEntity; }
100 }
101
102 #endregion Public Properties
103
104 #region Private Methods
105
106 /// <summary>
107 /// Check if an entitybase list (like that returned by scene.GetEntities()) contains a group with the rootpart uuid that matches the current uuid.
108 /// </summary>
109 private bool ContainsKey(List<EntityBase> list, UUID uuid)
110 {
111 foreach (EntityBase part in list)
112 if (part.UUID == uuid)
113 return true;
114 return false;
115 }
116
117 private SceneObjectGroup GetGroupByUUID(System.Collections.Generic.List<EntityBase> list, UUID uuid)
118 {
119 foreach (EntityBase ent in list)
120 {
121 if (ent is SceneObjectGroup)
122 if (ent.UUID == uuid)
123 return (SceneObjectGroup)ent;
124 }
125 return null;
126 }
127
128 #endregion Private Methods
129
130 #region Public Methods
131
132 /// <summary>
133 /// Search for a corresponding group UUID in the scene. If not found, then the revisioned group this CMEntity represents has been deleted. Mark the metaentity appropriately.
134 /// If a matching UUID is found in a scene object group, compare the two for differences. If differences exist, Mark the metaentity appropriately.
135 /// </summary>
136 public void FindDifferences()
137 {
138 System.Collections.Generic.List<EntityBase> sceneEntityList = m_Entity.Scene.GetEntities();
139 DiffersFromSceneGroup = false;
140 // if group is not contained in scene's list
141 if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID))
142 {
143 foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
144 {
145 // if scene list no longer contains this part, display translucent part and mark with red aura
146 if (!ContainsKey(sceneEntityList, part.UUID))
147 {
148 // if already displaying a red aura over part, make sure its red
149 if (m_AuraEntities.ContainsKey(part.UUID))
150 {
151 m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale);
152 }
153 else
154 {
155 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
156 part.GetWorldPosition(),
157 MetaEntity.TRANSLUCENT,
158 new Vector3(254,0,0),
159 part.Scale
160 );
161 m_AuraEntities.Add(part.UUID, auraGroup);
162 }
163 SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum);
164 SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT);
165 }
166 // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
167 }
168
169 // a deleted part has no where to point a beam particle system,
170 // if a metapart had a particle system (maybe it represented a moved part) remove it
171 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
172 {
173 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
174 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
175 }
176
177 DiffersFromSceneGroup = true;
178 }
179 // if scene list does contain group, compare each part in group for differences and display beams and auras appropriately
180 else
181 {
182 MarkWithDifferences((SceneObjectGroup)GetGroupByUUID(sceneEntityList, m_UnchangedEntity.UUID));
183 }
184 }
185
186 /// <summary>
187 /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given UUID.
188 /// </summary>
189 public bool HasChildPrim(UUID uuid)
190 {
191 if (m_UnchangedEntity.Children.ContainsKey(uuid))
192 return true;
193 return false;
194 }
195
196 /// <summary>
197 /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given LocalId.
198 /// </summary>
199 public bool HasChildPrim(uint localID)
200 {
201 foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
202 if (part.LocalId == localID)
203 return true;
204 return false;
205 }
206
207 public override void Hide(IClientAPI client)
208 {
209 base.Hide(client);
210 foreach (MetaEntity group in m_AuraEntities.Values)
211 group.Hide(client);
212 foreach (MetaEntity group in m_BeamEntities.Values)
213 group.Hide(client);
214 }
215
216 public override void HideFromAll()
217 {
218 base.HideFromAll();
219 foreach (MetaEntity group in m_AuraEntities.Values)
220 group.HideFromAll();
221 foreach (MetaEntity group in m_BeamEntities.Values)
222 group.HideFromAll();
223 }
224
225 /// <summary>
226 /// Returns true if there was a change between meta entity and the entity group, false otherwise.
227 /// If true is returned, it is assumed the metaentity's appearance has changed to reflect the difference (though clients haven't been updated).
228 /// </summary>
229 public bool MarkWithDifferences(SceneObjectGroup sceneEntityGroup)
230 {
231 SceneObjectPart sceneEntityPart;
232 SceneObjectPart metaEntityPart;
233 Diff differences;
234 bool changed = false;
235
236 // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user
237 // had originally saved.
238 // m_Entity will NOT necessarily be the same entity as the user had saved.
239 foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values)
240 {
241 //This is the part that we use to show changes.
242 metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
243 if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID))
244 {
245 sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID];
246 differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart);
247 if (differences != Diff.NONE)
248 metaEntityPart.Text = "CHANGE: " + differences.ToString();
249 if (differences != 0)
250 {
251 // Root Part that has been modified
252 if ((differences&Diff.POSITION) > 0)
253 {
254 // If the position of any part has changed, make sure the RootPart of the
255 // meta entity is pointing with a beam particle system
256 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
257 {
258 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
259 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
260 }
261 BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene,
262 m_UnchangedEntity.RootPart.GetWorldPosition(),
263 MetaEntity.TRANSLUCENT,
264 sceneEntityPart,
265 new Vector3(0,0,254)
266 );
267 m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
268 }
269
270 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
271 {
272 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
273 m_AuraEntities.Remove(UnchangedPart.UUID);
274 }
275 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
276 UnchangedPart.GetWorldPosition(),
277 MetaEntity.TRANSLUCENT,
278 new Vector3(0,0,254),
279 UnchangedPart.Scale
280 );
281 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
282 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
283
284 DiffersFromSceneGroup = true;
285 }
286 else // no differences between scene part and meta part
287 {
288 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
289 {
290 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
291 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
292 }
293 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
294 {
295 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
296 m_AuraEntities.Remove(UnchangedPart.UUID);
297 }
298 SetPartTransparency(metaEntityPart, MetaEntity.NONE);
299 }
300 }
301 else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
302 {
303 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
304 {
305 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
306 m_AuraEntities.Remove(UnchangedPart.UUID);
307 }
308 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
309 UnchangedPart.GetWorldPosition(),
310 MetaEntity.TRANSLUCENT,
311 new Vector3(254,0,0),
312 UnchangedPart.Scale
313 );
314 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
315 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
316
317 DiffersFromSceneGroup = true;
318 }
319 }
320 return changed;
321 }
322
323 public void SendFullAuraUpdate(IClientAPI client)
324 {
325 if (DiffersFromSceneGroup)
326 {
327 foreach (AuraMetaEntity group in m_AuraEntities.Values)
328 group.SendFullUpdate(client);
329 }
330 }
331
332 public void SendFullAuraUpdateToAll()
333 {
334 if (DiffersFromSceneGroup)
335 {
336 foreach (AuraMetaEntity group in m_AuraEntities.Values)
337 group.SendFullUpdateToAll();
338 }
339 }
340
341 public void SendFullBeamUpdate(IClientAPI client)
342 {
343 if (DiffersFromSceneGroup)
344 {
345 foreach (BeamMetaEntity group in m_BeamEntities.Values)
346 group.SendFullUpdate(client);
347 }
348 }
349
350 public void SendFullBeamUpdateToAll()
351 {
352 if (DiffersFromSceneGroup)
353 {
354 foreach (BeamMetaEntity group in m_BeamEntities.Values)
355 group.SendFullUpdateToAll();
356 }
357 }
358
359 public void SendFullDiffUpdate(IClientAPI client)
360 {
361 FindDifferences();
362 if (DiffersFromSceneGroup)
363 {
364 SendFullUpdate(client);
365 SendFullAuraUpdate(client);
366 SendFullBeamUpdate(client);
367 }
368 }
369
370 public void SendFullDiffUpdateToAll()
371 {
372 FindDifferences();
373 if (DiffersFromSceneGroup)
374 {
375 SendFullUpdateToAll();
376 SendFullAuraUpdateToAll();
377 SendFullBeamUpdateToAll();
378 }
379 }
380
381 #endregion Public Methods
382 }
383}