diff options
Diffstat (limited to 'OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementEntity.cs')
-rw-r--r-- | OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementEntity.cs | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementEntity.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementEntity.cs new file mode 100644 index 0000000..fb9df8f --- /dev/null +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/ContentManagementEntity.cs | |||
@@ -0,0 +1,326 @@ | |||
1 | // ContentManagementEntity.cs | ||
2 | // User: bongiojp | ||
3 | // | ||
4 | // | ||
5 | |||
6 | using System; | ||
7 | using System.Collections.Generic; | ||
8 | using System.Drawing; | ||
9 | using libsecondlife; | ||
10 | using Nini.Config; | ||
11 | using OpenSim.Framework; | ||
12 | using OpenSim.Region.Environment.Interfaces; | ||
13 | using OpenSim.Region.Environment.Scenes; | ||
14 | using log4net; | ||
15 | using OpenSim.Region.Physics.Manager; | ||
16 | using Axiom.Math; | ||
17 | |||
18 | namespace OpenSim.Region.Environment.Modules.ContentManagement | ||
19 | { | ||
20 | public class ContentManagementEntity : MetaEntity | ||
21 | { | ||
22 | static float TimeToDiff = 0; | ||
23 | static float TimeToCreateEntities = 0; | ||
24 | |||
25 | // The LinkNum of parts in m_Entity and m_UnchangedEntity are the same though UUID and LocalId are different. | ||
26 | // This can come in handy. | ||
27 | protected SceneObjectGroup m_UnchangedEntity = null; | ||
28 | protected Dictionary<LLUUID, BeamMetaEntity> m_BeamEntities = new Dictionary<LLUUID, BeamMetaEntity>(); | ||
29 | protected Dictionary<LLUUID, AuraMetaEntity> m_AuraEntities = new Dictionary<LLUUID, AuraMetaEntity>(); | ||
30 | |||
31 | /// <value> | ||
32 | /// Should be set to true when there is a difference between m_UnchangedEntity and the corresponding scene object group in the scene entity list. | ||
33 | /// </value> | ||
34 | bool DiffersFromSceneGroup = false; | ||
35 | |||
36 | public SceneObjectGroup UnchangedEntity | ||
37 | { | ||
38 | get { return m_UnchangedEntity; } | ||
39 | } | ||
40 | |||
41 | public ContentManagementEntity(SceneObjectGroup Unchanged, bool physics) : base(Unchanged, false) | ||
42 | { | ||
43 | m_UnchangedEntity = Unchanged.Copy(Unchanged.RootPart.OwnerID, Unchanged.RootPart.GroupID, false); | ||
44 | } | ||
45 | |||
46 | public ContentManagementEntity(string objectXML, Scene scene, bool physics) : base(objectXML, scene, false) | ||
47 | { | ||
48 | m_UnchangedEntity = new SceneObjectGroup(objectXML); | ||
49 | } | ||
50 | |||
51 | public override void Hide(IClientAPI client) | ||
52 | { | ||
53 | base.Hide(client); | ||
54 | foreach(MetaEntity group in m_AuraEntities.Values) | ||
55 | group.Hide(client); | ||
56 | foreach(MetaEntity group in m_BeamEntities.Values) | ||
57 | group.Hide(client); | ||
58 | } | ||
59 | |||
60 | public override void HideFromAll() | ||
61 | { | ||
62 | base.HideFromAll(); | ||
63 | foreach(MetaEntity group in m_AuraEntities.Values) | ||
64 | group.HideFromAll(); | ||
65 | foreach(MetaEntity group in m_BeamEntities.Values) | ||
66 | group.HideFromAll(); | ||
67 | } | ||
68 | |||
69 | public void SendFullDiffUpdateToAll() | ||
70 | { | ||
71 | FindDifferences(); | ||
72 | if (DiffersFromSceneGroup) | ||
73 | { | ||
74 | SendFullUpdateToAll(); | ||
75 | SendFullAuraUpdateToAll(); | ||
76 | SendFullBeamUpdateToAll(); | ||
77 | } | ||
78 | } | ||
79 | |||
80 | public void SendFullDiffUpdate(IClientAPI client) | ||
81 | { | ||
82 | FindDifferences(); | ||
83 | if (DiffersFromSceneGroup) | ||
84 | { | ||
85 | SendFullUpdate(client); | ||
86 | SendFullAuraUpdate(client); | ||
87 | SendFullBeamUpdate(client); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | public void SendFullBeamUpdate(IClientAPI client) | ||
92 | { | ||
93 | if (DiffersFromSceneGroup) | ||
94 | { | ||
95 | foreach(BeamMetaEntity group in m_BeamEntities.Values) | ||
96 | group.SendFullUpdate(client); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | public void SendFullAuraUpdate(IClientAPI client) | ||
101 | { | ||
102 | if (DiffersFromSceneGroup) | ||
103 | { | ||
104 | foreach(AuraMetaEntity group in m_AuraEntities.Values) | ||
105 | group.SendFullUpdate(client); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | public void SendFullBeamUpdateToAll() | ||
110 | { | ||
111 | if (DiffersFromSceneGroup) | ||
112 | { | ||
113 | foreach(BeamMetaEntity group in m_BeamEntities.Values) | ||
114 | group.SendFullUpdateToAll(); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | public void SendFullAuraUpdateToAll() | ||
119 | { | ||
120 | if (DiffersFromSceneGroup) | ||
121 | { | ||
122 | foreach(AuraMetaEntity group in m_AuraEntities.Values) | ||
123 | group.SendFullUpdateToAll(); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | /// <summary> | ||
128 | /// 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. | ||
129 | /// If a matching UUID is found in a scene object group, compare the two for differences. If differences exist, Mark the metaentity appropriately. | ||
130 | /// </summary> | ||
131 | public void FindDifferences() | ||
132 | { | ||
133 | System.Collections.Generic.List<EntityBase> sceneEntityList = m_Entity.Scene.GetEntities(); | ||
134 | DiffersFromSceneGroup = false; | ||
135 | // if group is not contained in scene's list | ||
136 | if(!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID)) | ||
137 | { | ||
138 | foreach(SceneObjectPart part in m_UnchangedEntity.Children.Values) | ||
139 | { | ||
140 | // if scene list no longer contains this part, display translucent part and mark with red aura | ||
141 | if(! ContainsKey(sceneEntityList, part.UUID)) | ||
142 | { | ||
143 | // if already displaying a red aura over part, make sure its red | ||
144 | if (m_AuraEntities.ContainsKey(part.UUID)) | ||
145 | { | ||
146 | m_AuraEntities[part.UUID].SetAura(new LLVector3(254,0,0), part.Scale); | ||
147 | } | ||
148 | else | ||
149 | { | ||
150 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | ||
151 | m_Entity.Scene.PrimIDAllocate(), | ||
152 | part.GetWorldPosition(), | ||
153 | MetaEntity.TRANSLUCENT, | ||
154 | new LLVector3(254,0,0), | ||
155 | part.Scale | ||
156 | ); | ||
157 | m_AuraEntities.Add(part.UUID, auraGroup); | ||
158 | } | ||
159 | SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum); | ||
160 | SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT); | ||
161 | } | ||
162 | // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id | ||
163 | } | ||
164 | |||
165 | // a deleted part has no where to point a beam particle system, | ||
166 | // if a metapart had a particle system (maybe it represented a moved part) remove it | ||
167 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) | ||
168 | { | ||
169 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); | ||
170 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); | ||
171 | } | ||
172 | |||
173 | DiffersFromSceneGroup = true; | ||
174 | } | ||
175 | // if scene list does contain group, compare each part in group for differences and display beams and auras appropriately | ||
176 | else | ||
177 | { | ||
178 | MarkWithDifferences((SceneObjectGroup)GetGroupByUUID(sceneEntityList, m_UnchangedEntity.UUID)); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | /// <summary> | ||
183 | /// Returns true if there was a change between meta entity and the entity group, false otherwise. | ||
184 | /// If true is returned, it is assumed the metaentity's appearance has changed to reflect the difference (though clients haven't been updated). | ||
185 | /// </summary> | ||
186 | public bool MarkWithDifferences(SceneObjectGroup sceneEntityGroup) | ||
187 | { | ||
188 | SceneObjectPart sceneEntityPart; | ||
189 | SceneObjectPart metaEntityPart; | ||
190 | Diff differences; | ||
191 | bool changed = false; | ||
192 | |||
193 | // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user | ||
194 | // had originally saved. | ||
195 | // m_Entity will NOT necessarily be the same entity as the user had saved. | ||
196 | foreach(SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values) | ||
197 | { | ||
198 | //This is the part that we use to show changes. | ||
199 | metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum); | ||
200 | if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID)) | ||
201 | { | ||
202 | sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID]; | ||
203 | differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart); | ||
204 | if (differences != Diff.NONE) | ||
205 | metaEntityPart.Text = "CHANGE: " + differences.ToString(); | ||
206 | if (differences != 0) | ||
207 | { | ||
208 | // Root Part that has been modified | ||
209 | if ((differences&Diff.POSITION) > 0) | ||
210 | { | ||
211 | // If the position of any part has changed, make sure the RootPart of the | ||
212 | // meta entity is pointing with a beam particle system | ||
213 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) | ||
214 | { | ||
215 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); | ||
216 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); | ||
217 | } | ||
218 | BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene, | ||
219 | m_Entity.Scene.PrimIDAllocate(), | ||
220 | m_UnchangedEntity.RootPart.GetWorldPosition(), | ||
221 | MetaEntity.TRANSLUCENT, | ||
222 | sceneEntityPart, | ||
223 | new LLVector3(0,0,254) | ||
224 | ); | ||
225 | m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup); | ||
226 | } | ||
227 | |||
228 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | ||
229 | { | ||
230 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | ||
231 | m_AuraEntities.Remove(UnchangedPart.UUID); | ||
232 | } | ||
233 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | ||
234 | m_Entity.Scene.PrimIDAllocate(), | ||
235 | UnchangedPart.GetWorldPosition(), | ||
236 | MetaEntity.TRANSLUCENT, | ||
237 | new LLVector3(0,0,254), | ||
238 | UnchangedPart.Scale | ||
239 | ); | ||
240 | m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); | ||
241 | SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); | ||
242 | |||
243 | DiffersFromSceneGroup = true; | ||
244 | } | ||
245 | else // no differences between scene part and meta part | ||
246 | { | ||
247 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) | ||
248 | { | ||
249 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); | ||
250 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); | ||
251 | } | ||
252 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | ||
253 | { | ||
254 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | ||
255 | m_AuraEntities.Remove(UnchangedPart.UUID); | ||
256 | } | ||
257 | SetPartTransparency(metaEntityPart, MetaEntity.NONE); | ||
258 | } | ||
259 | } | ||
260 | else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted. | ||
261 | { | ||
262 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | ||
263 | { | ||
264 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | ||
265 | m_AuraEntities.Remove(UnchangedPart.UUID); | ||
266 | } | ||
267 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | ||
268 | m_Entity.Scene.PrimIDAllocate(), | ||
269 | UnchangedPart.GetWorldPosition(), | ||
270 | MetaEntity.TRANSLUCENT, | ||
271 | new LLVector3(254,0,0), | ||
272 | UnchangedPart.Scale | ||
273 | ); | ||
274 | m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); | ||
275 | SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); | ||
276 | |||
277 | DiffersFromSceneGroup = true; | ||
278 | } | ||
279 | } | ||
280 | return changed; | ||
281 | } | ||
282 | |||
283 | private SceneObjectGroup GetGroupByUUID(System.Collections.Generic.List<EntityBase> list, LLUUID uuid) | ||
284 | { | ||
285 | foreach (EntityBase ent in list) | ||
286 | { | ||
287 | if (ent is SceneObjectGroup) | ||
288 | if (ent.UUID == uuid) | ||
289 | return (SceneObjectGroup)ent; | ||
290 | } | ||
291 | return null; | ||
292 | } | ||
293 | |||
294 | /// <summary> | ||
295 | /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given UUID. | ||
296 | /// </summary> | ||
297 | public bool HasChildPrim(LLUUID uuid) | ||
298 | { | ||
299 | if (m_UnchangedEntity.Children.ContainsKey(uuid)) | ||
300 | return true; | ||
301 | return false; | ||
302 | } | ||
303 | |||
304 | /// <summary> | ||
305 | /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given LocalId. | ||
306 | /// </summary> | ||
307 | public bool HasChildPrim(uint localID) | ||
308 | { | ||
309 | foreach( SceneObjectPart part in m_UnchangedEntity.Children.Values) | ||
310 | if ( part.LocalId == localID ) | ||
311 | return true; | ||
312 | return false; | ||
313 | } | ||
314 | |||
315 | /// <summary> | ||
316 | /// Check if an entitybase list (like that returned by scene.GetEntities() ) contains a group with the rootpart uuid that matches the current uuid. | ||
317 | /// </summary> | ||
318 | private bool ContainsKey(List<EntityBase> list, LLUUID uuid) | ||
319 | { | ||
320 | foreach( EntityBase part in list) | ||
321 | if (part.UUID == uuid) | ||
322 | return true; | ||
323 | return false; | ||
324 | } | ||
325 | } | ||
326 | } | ||