add llSetRenderMaterial (ugly code)
This commit is contained in:
@@ -25,8 +25,9 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using static OpenMetaverse.Primitive.RenderMaterials;
|
||||
|
||||
namespace OpenSim.Region.Framework.Interfaces
|
||||
{
|
||||
@@ -36,5 +37,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
FaceMaterial GetMaterialCopy(UUID ID);
|
||||
UUID AddNewMaterial(FaceMaterial fm);
|
||||
void RemoveMaterial(UUID id);
|
||||
bool CleanMaterialOverrides(ref RenderMaterialOverrideEntry[] overrides, int side, bool removeTransforms = false);
|
||||
bool RemoveMaterialEntry(ref RenderMaterialEntry[] entries, int side);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1025,7 +1025,8 @@ namespace OpenSim.Region.OptionalModules.Materials
|
||||
|
||||
public static readonly byte[] XMLkeyMaterialSucess = osUTF8.GetASCIIBytes("<llsd><map><key>success</key><integer>1</integer></map></llsd>\r\n");
|
||||
public static readonly byte[] XMLkeyMaterialFail = osUTF8.GetASCIIBytes("<llsd><map><key>success</key><integer>0</integer></map></llsd>\r\n");
|
||||
private static bool RemoveMaterialEntry(ref RenderMaterialEntry[] entries, int side)
|
||||
|
||||
public bool RemoveMaterialEntry(ref RenderMaterialEntry[] entries, int side)
|
||||
{
|
||||
if (entries is null || entries.Length == 0)
|
||||
return false;
|
||||
@@ -1386,5 +1387,90 @@ namespace OpenSim.Region.OptionalModules.Materials
|
||||
overrides[indx].data = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ClearOverrideData(OSDMap facemat, out OSDMap changedmat)
|
||||
{
|
||||
if(facemat is not null && facemat.TryGetOSDArray("ti", out OSDArray transforms))
|
||||
{
|
||||
changedmat = new OSDMap()
|
||||
{
|
||||
["ti"] = transforms
|
||||
};
|
||||
return facemat.Count > 1;
|
||||
}
|
||||
|
||||
changedmat = null;
|
||||
return facemat is not null;
|
||||
}
|
||||
|
||||
public bool CleanMaterialOverrides(ref RenderMaterialOverrideEntry[] overrides, int side, bool removeTransforms = false)
|
||||
{
|
||||
if (overrides is null || overrides.Length == 0)
|
||||
return false;
|
||||
|
||||
bool changed = false;
|
||||
if(removeTransforms && side < 0)
|
||||
{
|
||||
overrides = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
List<RenderMaterialOverrideEntry> newoverrides = new(overrides.Length);
|
||||
|
||||
for(int indx = 0; indx < overrides.Length; indx++)
|
||||
{
|
||||
if(side >= 0 && side != overrides[indx].te_index)
|
||||
{
|
||||
newoverrides.Add(overrides[indx]);
|
||||
}
|
||||
else if (removeTransforms)
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(string.IsNullOrEmpty(overrides[indx].data))
|
||||
{
|
||||
changed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
int tiindx = overrides[indx].data.IndexOf("ti");
|
||||
if(tiindx < 0)
|
||||
{
|
||||
changed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
StringBuilder sb = osStringBuilderCache.Acquire();
|
||||
sb.Append("{'");
|
||||
int brk = 0;
|
||||
do
|
||||
{
|
||||
char c = overrides[indx].data[tiindx];
|
||||
sb.Append(c);
|
||||
if(c=='[')
|
||||
brk++;
|
||||
else if(c==']')
|
||||
{
|
||||
brk--;
|
||||
if(brk == 0)
|
||||
break;
|
||||
}
|
||||
tiindx++;
|
||||
}
|
||||
while (tiindx < overrides[indx].data.Length);
|
||||
|
||||
sb.Append('}');
|
||||
string newdata = osStringBuilderCache.GetStringAndRelease(sb);
|
||||
changed = !newdata.Equals(overrides[indx].data);
|
||||
overrides[indx].data = newdata;
|
||||
newoverrides.Add(overrides[indx]);
|
||||
}
|
||||
}
|
||||
|
||||
overrides = newoverrides.Count > 0 ? [.. newoverrides] : null;
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19612,6 +19612,123 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void llSetRenderMaterial(LSL_String materialstr, LSL_Integer lsl_face)
|
||||
{
|
||||
if(m_materialsModule is null)
|
||||
return;
|
||||
|
||||
if(string.IsNullOrEmpty(materialstr.m_string))
|
||||
{
|
||||
Error("llSetRenderMaterial", "material \"\" not found");
|
||||
return;
|
||||
}
|
||||
|
||||
int face = lsl_face.value;
|
||||
bool changed;
|
||||
|
||||
if(UUID.ZeroString.Equals(materialstr.m_string, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if(m_host.Shape.RenderMaterials is null || m_host.Shape.RenderMaterials.entries is null || m_host.Shape.RenderMaterials.entries.Length == 0)
|
||||
return;
|
||||
|
||||
changed = m_materialsModule.CleanMaterialOverrides(ref m_host.Shape.RenderMaterials.overrides, face);
|
||||
if(face == ScriptBaseClass.ALL_SIDES)
|
||||
{
|
||||
m_host.Shape.RenderMaterials.entries = null;
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
changed |= m_materialsModule.RemoveMaterialEntry(ref m_host.Shape.RenderMaterials.entries, face);
|
||||
|
||||
if(changed)
|
||||
{
|
||||
m_host.ParentGroup.HasGroupChanged = true;
|
||||
m_host.ScheduleUpdate(PrimUpdateFlags.MaterialOvr | PrimUpdateFlags.FullUpdate);
|
||||
m_host.TriggerScriptChangedEvent(Changed.MATERIAL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
UUID matID = ScriptUtils.GetAssetIdFromItemName(m_host, materialstr.m_string, (int)AssetType.Material);
|
||||
if (matID.IsZero())
|
||||
{
|
||||
if (!UUID.TryParse(materialstr.m_string, out matID) || matID.IsZero())
|
||||
{
|
||||
Error("llSetRenderMaterial", $"material \"{materialstr.m_string}\" not found");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int nsides = GetNumberOfSides(m_host);
|
||||
if(face >= nsides)
|
||||
return;
|
||||
|
||||
m_host.Shape.RenderMaterials ??= new();
|
||||
m_host.Shape.RenderMaterials.entries ??= new Primitive.RenderMaterials.RenderMaterialEntry[1];
|
||||
|
||||
changed = m_materialsModule.CleanMaterialOverrides(ref m_host.Shape.RenderMaterials.overrides, face);
|
||||
if(face == ScriptBaseClass.ALL_SIDES)
|
||||
{
|
||||
if(m_host.Shape.RenderMaterials.entries is null || m_host.Shape.RenderMaterials.entries.Length != nsides)
|
||||
{
|
||||
m_host.Shape.RenderMaterials.entries = new Primitive.RenderMaterials.RenderMaterialEntry[nsides];
|
||||
for (int i = 0; i < m_host.Shape.RenderMaterials.entries.Length; i++)
|
||||
{
|
||||
m_host.Shape.RenderMaterials.entries[i] = new()
|
||||
{
|
||||
te_index = (byte)i,
|
||||
id = matID
|
||||
};
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < m_host.Shape.RenderMaterials.entries.Length; i++)
|
||||
{
|
||||
if(matID.NotEqual(m_host.Shape.RenderMaterials.entries[i].id))
|
||||
{
|
||||
changed = true;
|
||||
m_host.Shape.RenderMaterials.entries[i].id = matID;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int indx = 0;
|
||||
for( ; indx < m_host.Shape.RenderMaterials.entries.Length; indx++)
|
||||
{
|
||||
if (m_host.Shape.RenderMaterials.entries[indx].te_index == face)
|
||||
{
|
||||
if(matID.NotEqual(m_host.Shape.RenderMaterials.entries[indx].id))
|
||||
{
|
||||
changed = true;
|
||||
m_host.Shape.RenderMaterials.entries[indx].id = matID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(indx == m_host.Shape.RenderMaterials.entries.Length)
|
||||
{
|
||||
Array.Resize(ref m_host.Shape.RenderMaterials.entries, m_host.Shape.RenderMaterials.entries.Length + 1);
|
||||
|
||||
m_host.Shape.RenderMaterials.entries[indx] = new()
|
||||
{
|
||||
te_index = (byte)face,
|
||||
id = matID
|
||||
};
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if(changed)
|
||||
{
|
||||
m_host.ParentGroup.HasGroupChanged = true;
|
||||
m_host.ScheduleUpdate(PrimUpdateFlags.MaterialOvr | PrimUpdateFlags.FullUpdate);
|
||||
m_host.TriggerScriptChangedEvent(Changed.MATERIAL);
|
||||
}
|
||||
}
|
||||
|
||||
public LSL_Vector llWorldPosToHUD(LSL_Vector wp)
|
||||
{
|
||||
if(!m_host.ParentGroup.IsAttachment)
|
||||
|
||||
@@ -537,5 +537,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||
LSL_String llGetRenderMaterial(LSL_Integer face);
|
||||
LSL_Integer llIsLinkGLTFMaterial(LSL_Integer linknum, LSL_Integer face);
|
||||
LSL_Vector llWorldPosToHUD(LSL_Vector WorldPosition);
|
||||
void llSetRenderMaterial(LSL_String material, LSL_Integer face);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2899,5 +2899,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||
{
|
||||
return m_LSL_Functions.llWorldPosToHUD(WorldPosition);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void llSetRenderMaterial(LSL_String material, LSL_Integer face)
|
||||
{
|
||||
m_LSL_Functions.llSetRenderMaterial(material, face);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user