Add code to convert legacy materials stored in DynAttrs to new asset format and store them as assets
parent
d1f16c4b4b
commit
28723beb0c
|
@ -148,6 +148,78 @@ namespace OpenSim.Region.OptionalModules.Materials
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Searches the part for any legacy materials stored in DynAttrs and converts them to assets, replacing
|
||||||
|
/// the MaterialIDs in the TextureEntries for the part.
|
||||||
|
/// Deletes the legacy materials from the part as they are no longer needed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="part"></param>
|
||||||
|
private void ConvertLegacyMaterialsInPart(SceneObjectPart part)
|
||||||
|
{
|
||||||
|
if (part.DynAttrs == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var te = new Primitive.TextureEntry(part.Shape.TextureEntry, 0, part.Shape.TextureEntry.Length);
|
||||||
|
if (te == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
OSD OSMaterials = null;
|
||||||
|
OSDArray matsArr = null;
|
||||||
|
|
||||||
|
lock (part.DynAttrs)
|
||||||
|
{
|
||||||
|
if (part.DynAttrs.ContainsStore("OpenSim", "Materials"))
|
||||||
|
{
|
||||||
|
OSDMap materialsStore = part.DynAttrs.GetStore("OpenSim", "Materials");
|
||||||
|
|
||||||
|
if (materialsStore == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
materialsStore.TryGetValue("Materials", out OSMaterials);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OSMaterials != null && OSMaterials is OSDArray)
|
||||||
|
matsArr = OSMaterials as OSDArray;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matsArr == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (OSD elemOsd in matsArr)
|
||||||
|
{
|
||||||
|
if (elemOsd != null && elemOsd is OSDMap)
|
||||||
|
{
|
||||||
|
OSDMap matMap = elemOsd as OSDMap;
|
||||||
|
if (matMap.ContainsKey("ID") && matMap.ContainsKey("Material"))
|
||||||
|
{
|
||||||
|
UUID id = matMap["ID"].AsUUID();
|
||||||
|
OSDMap material = (OSDMap)matMap["Material"];
|
||||||
|
bool used = false;
|
||||||
|
|
||||||
|
foreach (var face in te.FaceTextures)
|
||||||
|
if (face.MaterialID == id)
|
||||||
|
used = true;
|
||||||
|
|
||||||
|
if (used)
|
||||||
|
{ // store legacy material in new asset format, and update the part texture entry with the new hashed UUID
|
||||||
|
|
||||||
|
var newId = StoreMaterialAsAsset(part.CreatorID, material, part);
|
||||||
|
foreach (var face in te.FaceTextures)
|
||||||
|
if (face.MaterialID == id)
|
||||||
|
face.MaterialID = newId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
part.Shape.TextureEntry = te.GetBytes();
|
||||||
|
|
||||||
|
lock (part.DynAttrs)
|
||||||
|
part.DynAttrs.RemoveStore("OpenSim", "Materials");
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Find the materials used in the SOP, and add them to 'm_regionMaterials'.
|
/// Find the materials used in the SOP, and add them to 'm_regionMaterials'.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -155,6 +227,9 @@ namespace OpenSim.Region.OptionalModules.Materials
|
||||||
{
|
{
|
||||||
if (part.Shape == null)
|
if (part.Shape == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ConvertLegacyMaterialsInPart(part);
|
||||||
|
|
||||||
var te = new Primitive.TextureEntry(part.Shape.TextureEntry, 0, part.Shape.TextureEntry.Length);
|
var te = new Primitive.TextureEntry(part.Shape.TextureEntry, 0, part.Shape.TextureEntry.Length);
|
||||||
if (te == null)
|
if (te == null)
|
||||||
return;
|
return;
|
||||||
|
@ -324,26 +399,7 @@ namespace OpenSim.Region.OptionalModules.Materials
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Material UUID = hash of the material's data.
|
id = StoreMaterialAsAsset(agentID, mat, sop);
|
||||||
// This makes materials deduplicate across the entire grid (but isn't otherwise required).
|
|
||||||
byte[] data = System.Text.Encoding.ASCII.GetBytes(OSDParser.SerializeLLSDXmlString(mat));
|
|
||||||
using (var md5 = MD5.Create())
|
|
||||||
id = new UUID(md5.ComputeHash(data), 0);
|
|
||||||
|
|
||||||
lock (m_regionMaterials)
|
|
||||||
{
|
|
||||||
if (!m_regionMaterials.ContainsKey(id))
|
|
||||||
{
|
|
||||||
m_regionMaterials[id] = mat;
|
|
||||||
|
|
||||||
// This asset might exist already, but it's ok to try to store it again
|
|
||||||
string name = "Material " + ChooseMaterialName(mat, sop);
|
|
||||||
name = name.Substring(0, Math.Min(64, name.Length)).Trim();
|
|
||||||
AssetBase asset = new AssetBase(id, name, (sbyte)OpenSimAssetType.Material, agentID.ToString());
|
|
||||||
asset.Data = data;
|
|
||||||
m_scene.AssetService.Store(asset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -404,6 +460,32 @@ namespace OpenSim.Region.OptionalModules.Materials
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private UUID StoreMaterialAsAsset(UUID agentID, OSDMap mat, SceneObjectPart sop)
|
||||||
|
{
|
||||||
|
UUID id;
|
||||||
|
// Material UUID = hash of the material's data.
|
||||||
|
// This makes materials deduplicate across the entire grid (but isn't otherwise required).
|
||||||
|
byte[] data = System.Text.Encoding.ASCII.GetBytes(OSDParser.SerializeLLSDXmlString(mat));
|
||||||
|
using (var md5 = MD5.Create())
|
||||||
|
id = new UUID(md5.ComputeHash(data), 0);
|
||||||
|
|
||||||
|
lock (m_regionMaterials)
|
||||||
|
{
|
||||||
|
if (!m_regionMaterials.ContainsKey(id))
|
||||||
|
{
|
||||||
|
m_regionMaterials[id] = mat;
|
||||||
|
|
||||||
|
// This asset might exist already, but it's ok to try to store it again
|
||||||
|
string name = "Material " + ChooseMaterialName(mat, sop);
|
||||||
|
name = name.Substring(0, Math.Min(64, name.Length)).Trim();
|
||||||
|
AssetBase asset = new AssetBase(id, name, (sbyte)OpenSimAssetType.Material, agentID.ToString());
|
||||||
|
asset.Data = data;
|
||||||
|
m_scene.AssetService.Store(asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Use heuristics to choose a good name for the material.
|
/// Use heuristics to choose a good name for the material.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Loading…
Reference in New Issue