public void RenderMaterial_ToFromOSDPreservesValues() { RenderMaterial mat = new RenderMaterial(); mat.NormalID = UUID.Random(); mat.NormalOffsetX = 2.0f; mat.NormalOffsetY = 2.0f; mat.NormalRepeatX = 2.0f; mat.NormalRepeatY = 2.0f; mat.NormalRotation = 180.0f; mat.SpecularID = UUID.Random(); mat.SpecularOffsetX = 2.0f; mat.SpecularOffsetY = 2.0f; mat.SpecularRepeatX = 2.0f; mat.SpecularRepeatY = 2.0f; mat.SpecularRotation = 180.0f; mat.SpecularLightColorR = 127; mat.SpecularLightColorG = 127; mat.SpecularLightColorB = 127; mat.SpecularLightColorA = 255; mat.SpecularLightExponent = 2; mat.EnvironmentIntensity = 2; mat.DiffuseAlphaMode = (byte)RenderMaterial.eDiffuseAlphaMode.DIFFUSE_ALPHA_MODE_MASK; mat.AlphaMaskCutoff = 2; OSD map = mat.GetOSD(); RenderMaterial newmat = RenderMaterial.FromOSD(map); Assert.That(newmat, Is.EqualTo(mat)); }
public void RenderMaterial_OSDFromToTest() { RenderMaterial mat = new RenderMaterial(UUID.Zero, UUID.Zero); OSD map = mat.GetOSD(); RenderMaterial matFromOSD = RenderMaterial.FromOSD(map); Assert.That(mat, Is.EqualTo(matFromOSD)); Assert.That(matFromOSD.NormalID, Is.EqualTo(UUID.Zero)); Assert.That(matFromOSD.NormalOffsetX, Is.EqualTo(0.0f)); Assert.That(matFromOSD.NormalOffsetY, Is.EqualTo(0.0f)); Assert.That(matFromOSD.NormalRepeatX, Is.EqualTo(1.0f)); Assert.That(matFromOSD.NormalRepeatY, Is.EqualTo(1.0f)); Assert.That(matFromOSD.NormalRotation, Is.EqualTo(0.0f)); Assert.That(matFromOSD.SpecularID, Is.EqualTo(UUID.Zero)); Assert.That(matFromOSD.SpecularOffsetX, Is.EqualTo(0.0f)); Assert.That(matFromOSD.SpecularOffsetY, Is.EqualTo(0.0f)); Assert.That(matFromOSD.SpecularRepeatX, Is.EqualTo(1.0f)); Assert.That(matFromOSD.SpecularRepeatY, Is.EqualTo(1.0f)); Assert.That(matFromOSD.SpecularRotation, Is.EqualTo(0.0f)); Assert.That(matFromOSD.SpecularLightColorR, Is.EqualTo(255)); Assert.That(matFromOSD.SpecularLightColorG, Is.EqualTo(255)); Assert.That(matFromOSD.SpecularLightColorB, Is.EqualTo(255)); Assert.That(matFromOSD.SpecularLightColorA, Is.EqualTo(255)); Assert.That(matFromOSD.SpecularLightExponent, Is.EqualTo(RenderMaterial.DEFAULT_SPECULAR_LIGHT_EXPONENT)); Assert.That(matFromOSD.EnvironmentIntensity, Is.EqualTo(RenderMaterial.DEFAULT_ENV_INTENSITY)); Assert.That(matFromOSD.DiffuseAlphaMode, Is.EqualTo((byte)RenderMaterial.eDiffuseAlphaMode.DIFFUSE_ALPHA_MODE_BLEND)); Assert.That(matFromOSD.AlphaMaskCutoff, Is.EqualTo(0)); }
/// <summary> /// Assign a single material value. Based on the values passed we'll either set (or clear) the materials for a SOP. /// </summary> /// <param name="sop">The SOP being affected.</param> /// <param name="face">The face to assign, or -1 if the default texture is being set.</param> /// <param name="id">The ID assigned to this material. Setting a Zero UUID clears it.</param> /// <param name="material">If not null, the material to set. Otherwise we are clearing.</param> private void AssignSingleMaterial(SceneObjectPart sop, int face, OSDMap matData) { UUID id = UUID.Zero; // If there is a material being set, see if we've seen it before. // If not we'll add it to the Shape RenderMaterials and the region cache if (matData != null) { RenderMaterial material = RenderMaterial.FromOSD(matData); id = sop.Shape.RenderMaterials.AddMaterial(material); m_scene.EventManager.TriggerRenderMaterialAddedToPrim(sop, id, material); m_log.DebugFormat("[RenderMaterials]: SOP {0}, Face {1}, Adding RenderMaterial {2}", sop.LocalId, face, material.ToString()); } // If the new material is replacing one lets record it so we can clean up UUID oldMaterialID = UUID.Zero; /// Get a copy of the texture entry so we can make changes. var te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length); // Set the Material ID in the TextureEntry. If face is ALL_SIDES then // set the default entry, otherwise fetch the face and set it there. if (face < 0) { oldMaterialID = te.DefaultTexture.MaterialID; te.DefaultTexture.MaterialID = id; } else { var faceEntry = te.CreateFace((uint)face); oldMaterialID = faceEntry.MaterialID; faceEntry.MaterialID = id; } // Update the texture entry which will force an update to connected clients sop.UpdateTexture(te); // If the material has changed and it wasn't previously Zero // Deallocate the old value if its not in use and signal the change if ((oldMaterialID != id) && (oldMaterialID != UUID.Zero)) { var currentMaterialIDs = sop.Shape.GetMaterialIDs(); if (currentMaterialIDs.Contains(oldMaterialID) == false) { if (sop.Shape.RenderMaterials.ContainsMaterial(oldMaterialID) == true) { sop.Shape.RenderMaterials.RemoveMaterial(oldMaterialID); } m_scene.EventManager.TriggerRenderMaterialRemovedFromPrim(sop, oldMaterialID); } } }
private UUID ExtractMaterial(Guid matId, RenderMaterials mats) { byte[] osdBlob = m_assetResolver.ResolveAsset(matId); if (osdBlob != null) { OSD osd = OSDParser.DeserializeLLSDXml(osdBlob); return(mats.AddMaterial(RenderMaterial.FromOSD(osd))); } return(UUID.Zero); }
/// <summary> /// Assign a single material value. Based on the values passed we'll either set (or clear) the materials for a SOP. /// </summary> /// <param name="sop">The SOP being affected.</param> /// <param name="face">The face to assign, or -1 if the default texture is being set.</param> /// <param name="id">The ID assigned to this material. Setting a Zero UUID clears it.</param> /// <param name="material">If not null, the material to set. Otherwise we are clearing.</param> private void AssignSingleMaterial(SceneObjectPart sop, int face, OSDMap matData) { /// Get a copy of the texture entry so we can make changes. var te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length); if (te == null) { m_log.Warn("[RenderMaterials]: null TextureEntry for localId: " + sop.LocalId.ToString()); return; } lock (m_knownMaterials) { UUID id = UUID.Zero; // Record what we currently have var currentMaterialIDs = getMaterialIDsFromTextureEntry(te); // If there is a material being set see if we've seen it before. // If not we'll add it to the region cache if (matData != null) { RenderMaterial material = RenderMaterial.FromOSD(matData); id = sop.Shape.RenderMaterials.AddMaterial(material); if (m_knownMaterials.ContainsKey(id)) { material = m_knownMaterials[id].material; var entry = m_knownMaterials[id]; if (entry.partIds.Contains(sop.LocalId) == false) { entry.partIds.Add(sop.LocalId); } } else { m_knownMaterials[id] = new RenderMaterialEntry(material, sop.LocalId); } m_log.DebugFormat("[RenderMaterials]: SOP {0}, Face {1}, Adding RenderMaterial {2}", sop.LocalId, face, material.ToString()); } // Set the Material ID in the sop texture entry. If there's a face defined // use that else use the Default entry. ID can either be a material ID // we set from the lookup above or Zero when we are clearing a material. if (face < 0) { te.DefaultTexture.MaterialID = id; } else { var faceEntry = te.CreateFace((uint)face); faceEntry.MaterialID = id; } // Get the updated list of Materials from the TextureEntry. We will // Use that to rebuild the RenderMaterials for the part. We'll also get a list // of entries that have been removed based on what we fetched initially so we // can clean that up in our cache. var newMaterialIDs = getMaterialIDsFromTextureEntry(te); // If there was an update and the material id has changed, clean up the old value. // Have to be careful here. It might still be in use in another slot. So we build // a list of keys and walk the texture entries subtracting keys in use. Whatever // is left are candidates to clean up. foreach (var entry in newMaterialIDs) { if (currentMaterialIDs.Contains(entry)) { currentMaterialIDs.Remove(entry); } if (sop.Shape.RenderMaterials.ContainsMaterial(entry) == false) { m_log.WarnFormat("[RenderMaterials]: SOP {0}, Face {1}, RenderMaterials {2} should be present but isn't!", sop.LocalId, face, entry.ToString()); } } // currentMaterialsIDs contains orphans if any. Remove them from the sop.Shape and the cache (if needed) foreach (var entry in currentMaterialIDs) { if (sop.Shape.RenderMaterials.ContainsMaterial(entry) == true) { m_log.DebugFormat("[RenderMaterials]: SOP {0}, Face {1}, Removing unused RenderMaterials {2} from shape.", sop.LocalId, face, entry.ToString()); sop.Shape.RenderMaterials.RemoveMaterial(entry); } else { m_log.WarnFormat("[RenderMaterials]: SOP {0}, Face {1}, ORPHANED RenderMaterials {2} should be present but isn't!", sop.LocalId, face, entry.ToString()); } if (m_knownMaterials.ContainsKey(entry)) { m_knownMaterials[entry].partIds.Remove(sop.LocalId); if (m_knownMaterials[entry].partIds.Count <= 0) { m_log.DebugFormat("[RenderMaterials]: Removing unused RenderMaterials {0} from region cache.", entry.ToString()); m_knownMaterials.Remove(entry); } } } } // Update the texture entry which will force an update to connected clients sop.UpdateTextureEntry(te.GetBytes()); }