aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs')
-rw-r--r--OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs122
1 files changed, 102 insertions, 20 deletions
diff --git a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs
index 4b635d8..1b5a7a3 100644
--- a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs
+++ b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs
@@ -149,12 +149,87 @@ namespace OpenSim.Region.OptionalModules.Materials
149 } 149 }
150 150
151 /// <summary> 151 /// <summary>
152 /// Searches the part for any legacy materials stored in DynAttrs and converts them to assets, replacing
153 /// the MaterialIDs in the TextureEntries for the part.
154 /// Deletes the legacy materials from the part as they are no longer needed.
155 /// </summary>
156 /// <param name="part"></param>
157 private void ConvertLegacyMaterialsInPart(SceneObjectPart part)
158 {
159 if (part.DynAttrs == null)
160 return;
161
162 var te = new Primitive.TextureEntry(part.Shape.TextureEntry, 0, part.Shape.TextureEntry.Length);
163 if (te == null)
164 return;
165
166 OSD OSMaterials = null;
167 OSDArray matsArr = null;
168
169 lock (part.DynAttrs)
170 {
171 if (part.DynAttrs.ContainsStore("OpenSim", "Materials"))
172 {
173 OSDMap materialsStore = part.DynAttrs.GetStore("OpenSim", "Materials");
174
175 if (materialsStore == null)
176 return;
177
178 materialsStore.TryGetValue("Materials", out OSMaterials);
179 }
180
181 if (OSMaterials != null && OSMaterials is OSDArray)
182 matsArr = OSMaterials as OSDArray;
183 else
184 return;
185 }
186
187 if (matsArr == null)
188 return;
189
190 foreach (OSD elemOsd in matsArr)
191 {
192 if (elemOsd != null && elemOsd is OSDMap)
193 {
194 OSDMap matMap = elemOsd as OSDMap;
195 if (matMap.ContainsKey("ID") && matMap.ContainsKey("Material"))
196 {
197 UUID id = matMap["ID"].AsUUID();
198 OSDMap material = (OSDMap)matMap["Material"];
199 bool used = false;
200
201 foreach (var face in te.FaceTextures)
202 if (face.MaterialID == id)
203 used = true;
204
205 if (used)
206 { // store legacy material in new asset format, and update the part texture entry with the new hashed UUID
207
208 var newId = StoreMaterialAsAsset(part.CreatorID, material, part);
209 foreach (var face in te.FaceTextures)
210 if (face.MaterialID == id)
211 face.MaterialID = newId;
212 }
213 }
214 }
215 }
216
217 part.Shape.TextureEntry = te.GetBytes();
218
219 lock (part.DynAttrs)
220 part.DynAttrs.RemoveStore("OpenSim", "Materials");
221 }
222
223 /// <summary>
152 /// Find the materials used in the SOP, and add them to 'm_regionMaterials'. 224 /// Find the materials used in the SOP, and add them to 'm_regionMaterials'.
153 /// </summary> 225 /// </summary>
154 private void GetStoredMaterialsInPart(SceneObjectPart part) 226 private void GetStoredMaterialsInPart(SceneObjectPart part)
155 { 227 {
156 if (part.Shape == null) 228 if (part.Shape == null)
157 return; 229 return;
230
231 ConvertLegacyMaterialsInPart(part);
232
158 var te = new Primitive.TextureEntry(part.Shape.TextureEntry, 0, part.Shape.TextureEntry.Length); 233 var te = new Primitive.TextureEntry(part.Shape.TextureEntry, 0, part.Shape.TextureEntry.Length);
159 if (te == null) 234 if (te == null)
160 return; 235 return;
@@ -324,26 +399,7 @@ namespace OpenSim.Region.OptionalModules.Materials
324 } 399 }
325 else 400 else
326 { 401 {
327 // Material UUID = hash of the material's data. 402 id = StoreMaterialAsAsset(agentID, mat, sop);
328 // This makes materials deduplicate across the entire grid (but isn't otherwise required).
329 byte[] data = System.Text.Encoding.ASCII.GetBytes(OSDParser.SerializeLLSDXmlString(mat));
330 using (var md5 = MD5.Create())
331 id = new UUID(md5.ComputeHash(data), 0);
332
333 lock (m_regionMaterials)
334 {
335 if (!m_regionMaterials.ContainsKey(id))
336 {
337 m_regionMaterials[id] = mat;
338
339 // This asset might exist already, but it's ok to try to store it again
340 string name = "Material " + ChooseMaterialName(mat, sop);
341 name = name.Substring(0, Math.Min(64, name.Length)).Trim();
342 AssetBase asset = new AssetBase(id, name, (sbyte)OpenSimAssetType.Material, agentID.ToString());
343 asset.Data = data;
344 m_scene.AssetService.Store(asset);
345 }
346 }
347 } 403 }
348 404
349 405
@@ -404,6 +460,32 @@ namespace OpenSim.Region.OptionalModules.Materials
404 return response; 460 return response;
405 } 461 }
406 462
463 private UUID StoreMaterialAsAsset(UUID agentID, OSDMap mat, SceneObjectPart sop)
464 {
465 UUID id;
466 // Material UUID = hash of the material's data.
467 // This makes materials deduplicate across the entire grid (but isn't otherwise required).
468 byte[] data = System.Text.Encoding.ASCII.GetBytes(OSDParser.SerializeLLSDXmlString(mat));
469 using (var md5 = MD5.Create())
470 id = new UUID(md5.ComputeHash(data), 0);
471
472 lock (m_regionMaterials)
473 {
474 if (!m_regionMaterials.ContainsKey(id))
475 {
476 m_regionMaterials[id] = mat;
477
478 // This asset might exist already, but it's ok to try to store it again
479 string name = "Material " + ChooseMaterialName(mat, sop);
480 name = name.Substring(0, Math.Min(64, name.Length)).Trim();
481 AssetBase asset = new AssetBase(id, name, (sbyte)OpenSimAssetType.Material, agentID.ToString());
482 asset.Data = data;
483 m_scene.AssetService.Store(asset);
484 }
485 }
486 return id;
487 }
488
407 /// <summary> 489 /// <summary>
408 /// Use heuristics to choose a good name for the material. 490 /// Use heuristics to choose a good name for the material.
409 /// </summary> 491 /// </summary>