private UpdateChangedFlags ChangedTexParams(TextureEntryFace oldTexFace, TextureEntryFace newTexFace)
        {
            UpdateChangedFlags flags = 0;

            if (oldTexFace.Glow != newTexFace.Glow ||
                oldTexFace.Bump != newTexFace.Bump ||
                oldTexFace.FullBright != newTexFace.FullBright ||
                oldTexFace.MaterialID != newTexFace.MaterialID ||
                oldTexFace.OffsetU != newTexFace.OffsetU ||
                oldTexFace.OffsetV != newTexFace.OffsetV ||
                oldTexFace.RepeatU != newTexFace.RepeatU ||
                oldTexFace.RepeatV != newTexFace.RepeatV ||
                oldTexFace.Rotation != newTexFace.Rotation ||
                oldTexFace.Shiny != newTexFace.Shiny ||
                oldTexFace.TexMapType != newTexFace.TexMapType ||
                oldTexFace.TextureID != newTexFace.TextureID)
            {
                flags |= UpdateChangedFlags.Texture;
            }

            if (oldTexFace.TextureColor.R != newTexFace.TextureColor.R ||
                oldTexFace.TextureColor.G != newTexFace.TextureColor.G ||
                oldTexFace.TextureColor.B != newTexFace.TextureColor.B ||
                oldTexFace.TextureColor.A != newTexFace.TextureColor.A)
            {
                flags |= UpdateChangedFlags.Color;
            }

            if (oldTexFace.MediaFlags != newTexFace.MediaFlags)
            {
                flags |= UpdateChangedFlags.Media;
            }
            return(flags);
        }
        private UpdateChangedFlags ChangedTexParams(TextureEntry oldTex, TextureEntry newTex)
        {
            UpdateChangedFlags flags = ChangedTexParams(oldTex.DefaultTexture, newTex.DefaultTexture);
            uint index;

            for (index = 0; index < 32; ++index)
            {
                flags |= ChangedTexParams(oldTex[index], newTex[index]);
            }
            return(flags);
        }
        private void SetTexPrimitiveParams(TextureEntryFace face, PrimitiveParamsType type, AnArray.MarkEnumerator enumerator, ref UpdateChangedFlags flags, ref bool isUpdated, bool updateParams)
        {
            switch (type)
            {
            case PrimitiveParamsType.Texture:
            {
                UUID    textureID = m_Part.GetTextureParam(enumerator, "PRIM_TEXTURE");
                Vector3 repeats   = ParamsHelper.GetVector(enumerator, "PRIM_TEXTURE");
                Vector3 offsets   = ParamsHelper.GetVector(enumerator, "PRIM_TEXTURE");
                float   rot       = (float)ParamsHelper.GetDouble(enumerator, "PRIM_TEXTURE");

                if (updateParams)
                {
                    if (m_Part.TryFetchTexture(textureID))
                    {
                        face.TextureID = textureID;
                    }
                    face.RepeatU  = (float)repeats.X;
                    face.RepeatV  = (float)repeats.Y;
                    face.OffsetU  = (float)offsets.X;
                    face.OffsetV  = (float)offsets.Y;
                    face.Rotation = rot;
                    flags        |= UpdateChangedFlags.Texture;
                    isUpdated     = true;
                }
            }
            break;

            case PrimitiveParamsType.Color:
            {
                Vector3 color = ParamsHelper.GetVector(enumerator, "PRIM_COLOR");
                double  alpha = ParamsHelper.GetDouble(enumerator, "PRIM_COLOR").Clamp(0, 1);
                if (updateParams)
                {
                    face.TextureColor = new ColorAlpha(color, alpha);
                    flags            |= UpdateChangedFlags.Color;
                    isUpdated         = true;
                }
            }
            break;

            case PrimitiveParamsType.Alpha:
            {
                double alpha = ParamsHelper.GetDouble(enumerator, "PRIM_ALPHA").Clamp(0, 1);
                if (updateParams)
                {
                    ColorAlpha color = face.TextureColor;
                    color.A           = alpha;
                    face.TextureColor = color;
                    flags            |= UpdateChangedFlags.Color;
                    isUpdated         = true;
                }
            }
            break;

            case PrimitiveParamsType.BumpShiny:
            {
                Shininess shiny = (Shininess)ParamsHelper.GetInteger(enumerator, "PRIM_BUMP_SHINY");
                Bumpiness bump  = (Bumpiness)ParamsHelper.GetInteger(enumerator, "PRIM_BUMP_SHINY");
                if (updateParams)
                {
                    face.Shiny = shiny;
                    face.Bump  = bump;
                    flags     |= UpdateChangedFlags.Texture;
                    isUpdated  = true;
                }
            }
            break;

            case PrimitiveParamsType.FullBright:
            {
                bool fbright = ParamsHelper.GetBoolean(enumerator, "PRIM_FULLBRIGHT");
                if (updateParams)
                {
                    face.FullBright = fbright;
                    flags          |= UpdateChangedFlags.Color;
                    isUpdated       = true;
                }
            }
            break;

            case PrimitiveParamsType.TexGen:
            {
                MappingType mapType = (MappingType)ParamsHelper.GetInteger(enumerator, "PRIM_TEXGEN");
                if (updateParams)
                {
                    face.TexMapType = mapType;
                    flags          |= UpdateChangedFlags.Texture;
                    isUpdated       = true;
                }
            }
            break;

            case PrimitiveParamsType.Glow:
            {
                float glow = (float)ParamsHelper.GetDouble(enumerator, "PRIM_GLOW").Clamp(0, 1);
                if (updateParams)
                {
                    face.Glow = glow;
                    flags    |= UpdateChangedFlags.Color;
                    isUpdated = true;
                }
            }
            break;

            case PrimitiveParamsType.AlphaMode:
                /* [ PRIM_ALPHA_MODE, integer face, integer alpha_mode, integer mask_cutoff ] */
            {
                Material mat;
                try
                {
                    mat = m_Part.ObjectGroup.Scene.GetMaterial(face.MaterialID);
                }
                catch
                {
                    mat = new Material();
                }
                mat.DiffuseAlphaMode = ParamsHelper.GetInteger(enumerator, "PRIM_ALPHA_MODE");
                mat.AlphaMaskCutoff  = ParamsHelper.GetInteger(enumerator, "PRIM_ALPHA_MODE");

                if (updateParams)
                {
                    mat.DiffuseAlphaMode = mat.DiffuseAlphaMode.Clamp(0, 3);
                    mat.AlphaMaskCutoff  = mat.AlphaMaskCutoff.Clamp(0, 3);
                    mat.MaterialID       = UUID.Random;
                    m_Part.ObjectGroup.Scene.StoreMaterial(mat);
                    face.MaterialID = mat.MaterialID;
                    flags          |= UpdateChangedFlags.Texture;
                    isUpdated       = true;
                }
            }
            break;

            case PrimitiveParamsType.Normal:
                /* [ PRIM_NORMAL, integer face, string texture, vector repeats, vector offsets, float rotation_in_radians ] */
            {
                UUID    texture  = m_Part.GetTextureParam(enumerator, "PRIM_NORMAL");
                Vector3 repeats  = ParamsHelper.GetVector(enumerator, "PRIM_NORMAL");
                Vector3 offsets  = ParamsHelper.GetVector(enumerator, "PRIM_NORMAL");
                double  rotation = ParamsHelper.GetDouble(enumerator, "PRIM_NORMAL");

                if (updateParams)
                {
                    repeats.X *= Material.MATERIALS_MULTIPLIER;
                    repeats.Y *= Material.MATERIALS_MULTIPLIER;
                    offsets.X *= Material.MATERIALS_MULTIPLIER;
                    offsets.Y *= Material.MATERIALS_MULTIPLIER;
                    rotation  %= Math.PI * 2;
                    rotation  *= Material.MATERIALS_MULTIPLIER;

                    Material mat;
                    try
                    {
                        mat = m_Part.ObjectGroup.Scene.GetMaterial(face.MaterialID);
                    }
                    catch
                    {
                        mat = new Material();
                    }
                    mat.NormMap      = texture;
                    mat.NormOffsetX  = (int)Math.Round(offsets.X);
                    mat.NormOffsetY  = (int)Math.Round(offsets.Y);
                    mat.NormRepeatX  = (int)Math.Round(repeats.X);
                    mat.NormRepeatY  = (int)Math.Round(repeats.Y);
                    mat.NormRotation = (int)Math.Round(rotation);
                    mat.MaterialID   = UUID.Random;
                    if (m_Part.TryFetchTexture(texture))
                    {
                        m_Part.ObjectGroup.Scene.StoreMaterial(mat);
                        face.MaterialID = mat.MaterialID;
                    }
                    flags    |= UpdateChangedFlags.Texture;
                    isUpdated = true;
                }
            }
            break;

            case PrimitiveParamsType.Specular:
                /* [ PRIM_SPECULAR, integer face, string texture, vector repeats, vector offsets, float rotation_in_radians, vector color, integer glossiness, integer environment ] */
            {
                UUID    texture = m_Part.GetTextureParam(enumerator, "PRIM_NORMAL");
                Vector3 repeats = ParamsHelper.GetVector(enumerator, "PRIM_SPECULAR");
                Vector3 offsets = ParamsHelper.GetVector(enumerator, "PRIM_SPECULAR");
                repeats *= Material.MATERIALS_MULTIPLIER;
                offsets *= Material.MATERIALS_MULTIPLIER;
                double rotation = ParamsHelper.GetDouble(enumerator, "PRIM_SPECULAR");
                rotation %= Math.PI * 2;
                rotation *= Material.MATERIALS_MULTIPLIER;
                var color       = new ColorAlpha(ParamsHelper.GetVector(enumerator, "PRIM_SPECULAR"), 1);
                int glossiness  = ParamsHelper.GetInteger(enumerator, "PRIM_SPECULAR");
                int environment = ParamsHelper.GetInteger(enumerator, "PRIM_SPECULAR");
                if (updateParams)
                {
                    environment = environment.Clamp(0, 255);
                    glossiness  = glossiness.Clamp(0, 255);
                    Material mat;
                    try
                    {
                        mat = m_Part.ObjectGroup.Scene.GetMaterial(face.MaterialID);
                    }
                    catch
                    {
                        mat = new Material();
                    }
                    mat.SpecColor    = color;
                    mat.SpecMap      = texture;
                    mat.SpecOffsetX  = (int)Math.Round(offsets.X);
                    mat.SpecOffsetY  = (int)Math.Round(offsets.Y);
                    mat.SpecRepeatX  = (int)Math.Round(repeats.X);
                    mat.SpecRepeatY  = (int)Math.Round(repeats.Y);
                    mat.SpecRotation = (int)Math.Round(rotation);
                    mat.EnvIntensity = environment;
                    mat.SpecExp      = glossiness;
                    mat.MaterialID   = UUID.Random;
                    if (m_Part.TryFetchTexture(texture))
                    {
                        m_Part.ObjectGroup.Scene.StoreMaterial(mat);
                        face.MaterialID = mat.MaterialID;
                    }
                    flags    |= UpdateChangedFlags.Texture;
                    isUpdated = true;
                }
            }
            break;

            default:
                throw new ArgumentException($"Internal error! Primitive parameter type {type} should not be passed to PrimitiveFace");
            }
        }
 internal void SetTexPrimitiveParams(PrimitiveParamsType paramtype, AnArray.MarkEnumerator enumerator, ref UpdateChangedFlags flags, ref bool isUpdated, string paramtypename, bool updateParams)
 {
     m_TextureEntryLock.AcquireWriterLock(-1);
     try
     {
         var faces = GetFaces(ParamsHelper.GetInteger(enumerator, paramtypename));
         enumerator.MarkPosition();
         foreach (var face in faces)
         {
             enumerator.GoToMarkPosition();
             SetTexPrimitiveParams(face, paramtype, enumerator, ref flags, ref isUpdated, updateParams);
         }
         m_TextureEntryBytes = m_TextureEntry.GetBytes();
     }
     finally
     {
         m_TextureEntryLock.ReleaseWriterLock();
     }
 }