Esempio n. 1
0
    //----------------------------------------------------------------------------

    public static PKFxManagerImpl.EImageFormat ResolveImageFormat(Texture2D t, ref byte[] data)
    {
        if (t.format == TextureFormat.DXT1)
        {
            return(PKFxManagerImpl.EImageFormat.DXT1);
        }
        else if (t.format == TextureFormat.DXT5)
        {
            return(PKFxManagerImpl.EImageFormat.DXT5);
        }
        else if (t.format == TextureFormat.ARGB32)
        {
            PKImageConverter.ARGB2BGRA(ref data);
            return(PKFxManagerImpl.EImageFormat.BGRA8);
        }
        else if (t.format == TextureFormat.RGBA32)
        {
            PKImageConverter.RGBA2BGRA(ref data);
            return(PKFxManagerImpl.EImageFormat.BGRA8);
        }
        else if (t.format == TextureFormat.BGRA32)
        {
            return(PKFxManagerImpl.EImageFormat.BGRA8);
        }
        else if (t.format == TextureFormat.RGB24)
        {
            PKImageConverter.RGB2BGR(ref data);
            return(PKFxManagerImpl.EImageFormat.BGR8);
        }
        else if (t.format == TextureFormat.PVRTC_RGB4)
        {
            return(PKFxManagerImpl.EImageFormat.RGB4_PVRTC1);
        }
        else if (t.format == TextureFormat.PVRTC_RGBA4)
        {
            return(PKFxManagerImpl.EImageFormat.RGBA4_PVRTC1);
        }
        else if (t.format == TextureFormat.PVRTC_RGB2)
        {
            return(PKFxManagerImpl.EImageFormat.RGB2_PVRTC1);
        }
        else if (t.format == TextureFormat.PVRTC_RGBA2)
        {
            return(PKFxManagerImpl.EImageFormat.RGBA2_PVRTC1);
        }
        else if (t.format == TextureFormat.ETC_RGB4)
        {
            return(PKFxManagerImpl.EImageFormat.RGB8_ETC1);
        }
        else if (t.format == TextureFormat.ETC2_RGB)
        {
            return(PKFxManagerImpl.EImageFormat.RGB8_ETC2);
        }
        else if (t.format == TextureFormat.ETC2_RGBA8)
        {
            return(PKFxManagerImpl.EImageFormat.RGBA8_ETC2);
        }
        else if (t.format == TextureFormat.ETC2_RGBA1)
        {
            return(PKFxManagerImpl.EImageFormat.RGB8A1_ETC2);
        }
        else if (t.format == TextureFormat.RGBAFloat)
        {
            return(PKFxManagerImpl.EImageFormat.Fp32_RGBA);
        }
        else
        {
            Debug.LogError("[PKFX] " + t.name + " texture format not supported : " +
                           t.format);
            return(PKFxManagerImpl.EImageFormat.Invalid);
        }
    }
Esempio n. 2
0
    public void UpdateAttributes(bool forceUpdate)
    {
        int attrCount = -1;
        int smpCount  = -1;

        if (m_FxAttributesList.Count <= 0 && m_FxSamplersList.Count <= 0)
        {
            return;
        }

        AllocAttributesCacheIFN();
        AllocCurvesDataCacheIFN();

        // Attributes
        for (int i = 0; i < m_FxAttributesList.Count; i++)
        {
            PKFxManager.Attribute srcAttr = m_FxAttributesList[i];

            bool wasChanged = m_AttributesCache[i].m_Value0 != srcAttr.m_Value0 ||
                              m_AttributesCache[i].m_Value1 != srcAttr.m_Value1 ||
                              m_AttributesCache[i].m_Value2 != srcAttr.m_Value2 ||
                              m_AttributesCache[i].m_Value3 != srcAttr.m_Value3;

            if (wasChanged || forceUpdate || m_ForceUpdateAttributes)
            {
                m_AttributesCache[i].m_Type   = (int)(m_FxAttributesList[i].m_Descriptor.Type);
                m_AttributesCache[i].m_Value0 = srcAttr.m_Value0;
                m_AttributesCache[i].m_Value1 = srcAttr.m_Value1;
                m_AttributesCache[i].m_Value2 = srcAttr.m_Value2;
                m_AttributesCache[i].m_Value3 = srcAttr.m_Value3;
                attrCount = i;
            }
        }
        if (attrCount >= 0)
        {
            if (!PKFxManager.EffectSetAttributes(this.m_FXGUID, attrCount + 1, this.m_AttributesHandler))
            {
                Debug.LogError("[PKFX] Attribute through pinned memory failed.");
                Debug.LogError("[PKFX] Did you try to change an FX without stopping it beforehand?");
            }
        }
        // Samplers
        int samplerCurveOffset = 0;

        for (int i = 0; i < m_FxSamplersList.Count; i++)
        {
            PKFxManager.Sampler srcAttr = m_FxSamplersList[i];
            int     smpType             = (int)(m_FxSamplersList[i].m_Descriptor.Type);
            Vector3 smpPos  = new Vector3(m_SamplersCache[i].m_PosX, m_SamplersCache[i].m_PosY, m_SamplersCache[i].m_PosZ);
            Vector3 smpEul  = new Vector3(m_SamplersCache[i].m_EulX, m_SamplersCache[i].m_EulY, m_SamplersCache[i].m_EulZ);
            Vector3 smpSize = new Vector3(m_SamplersCache[i].m_SizeX, m_SamplersCache[i].m_SizeY, m_SamplersCache[i].m_SizeZ);
            bool    wasChanged;

            m_SamplersCache[i].m_Type1 = smpType;
            if (m_SamplersCache[i].m_Type1 == (int)PKFxManager.ESamplerType.SamplerShape)
            {
                bool isMesh = (srcAttr.m_ShapeType == (int)PKFxManager.EShapeType.MeshShape ||
                               srcAttr.m_ShapeType == (int)PKFxManager.EShapeType.SkinnedMeshShape);

                bool withSkinning = srcAttr.m_ShapeType == (int)PKFxManager.EShapeType.SkinnedMeshShape &&
                                    srcAttr.m_SkinnedMeshRenderer != null;

                if (srcAttr.m_EditorShapeType == (int)PKFxManager.EShapeType.MeshShape + 1)                 //MeshFilter
                {
                    if (srcAttr.m_MeshFilter == null)
                    {
                        srcAttr.m_Mesh = null;
                    }
                    else if (srcAttr.m_Mesh != srcAttr.m_MeshFilter.sharedMesh)
                    {
                        srcAttr.m_Mesh = srcAttr.m_MeshFilter.sharedMesh;
                        if (srcAttr.m_Mesh != null)
                        {
                            srcAttr.m_MeshHashCode = srcAttr.m_Mesh.name.GetHashCode();
                        }
                        else
                        {
                            srcAttr.m_MeshHashCode = 0;
                        }
                    }
                }

                wasChanged = srcAttr.m_MeshHashCode != m_SamplersCache[i].m_HashCode ||
                             smpSize != srcAttr.m_Dimensions ||
                             m_SamplersCache[i].m_Type2 != srcAttr.m_ShapeType ||
                             smpPos != srcAttr.m_ShapeCenter ||
                             smpEul != srcAttr.m_EulerOrientation;

                if (m_SamplersCache[i].m_MeshChanged != 0 && m_SamplersCache[i].m_Data != IntPtr.Zero &&
                    !srcAttr.m_InSkinning)
                {
                    Marshal.FreeHGlobal(m_SamplersCache[i].m_Data);
                    m_SamplersCache[i].m_Data = IntPtr.Zero;
                }
                m_SamplersCache[i].m_MeshChanged = 0;

                if (wasChanged || forceUpdate || m_ForceUpdateAttributes)
                {
                    if (isMesh && srcAttr.m_Mesh != null)
                    {
                        int boneCount = withSkinning ? srcAttr.m_SkinnedMeshRenderer.bones.Length : 0;

                        int triangleSize     = srcAttr.m_Mesh.triangles.Length * sizeof(int);
                        int verticesSize     = (srcAttr.m_SamplingChannels & (int)PKFxManager.EMeshChannels.Channel_Position) != 0 ? srcAttr.m_Mesh.vertexCount * sizeof(float) * 3 : 0;
                        int normalsSize      = (srcAttr.m_SamplingChannels & (int)PKFxManager.EMeshChannels.Channel_Normal) != 0 ? srcAttr.m_Mesh.vertexCount * sizeof(float) * 3 : 0;
                        int tangentsSize     = (srcAttr.m_SamplingChannels & (int)PKFxManager.EMeshChannels.Channel_Tangent) != 0 ? srcAttr.m_Mesh.vertexCount * sizeof(float) * 4 : 0;
                        int uvsSize          = (srcAttr.m_SamplingChannels & (int)PKFxManager.EMeshChannels.Channel_UV) != 0 ? srcAttr.m_Mesh.vertexCount * sizeof(float) * 2 : 0;
                        int vertexColorsSize = (srcAttr.m_SamplingChannels & (int)PKFxManager.EMeshChannels.Channel_VertexColor) != 0 ? srcAttr.m_Mesh.vertexCount * sizeof(float) * 4 : 0;
                        int boneWeightsSize  = boneCount != 0 ? srcAttr.m_Mesh.boneWeights.Length * sizeof(float) * 8 : 0;

                        int totalSize = triangleSize + verticesSize + normalsSize + tangentsSize + uvsSize + vertexColorsSize + boneWeightsSize;

                        m_SamplersCache[i].m_IndexCount       = srcAttr.m_Mesh.triangles.Length;
                        m_SamplersCache[i].m_VertexCount      = srcAttr.m_Mesh.vertices.Length;
                        m_SamplersCache[i].m_BoneCount        = boneCount;
                        m_SamplersCache[i].m_SamplingChannels = srcAttr.m_SamplingChannels;

                        if (totalSize > 0 &&
                            (forceUpdate || m_SamplersCache[i].m_HashCode != srcAttr.m_MeshHashCode ||
                             m_SamplersCache[i].m_Type2 != (int)m_FxSamplersList[i].m_ShapeType))
                        {
                            if (m_SamplersCache[i].m_Data != IntPtr.Zero)
                            {
                                Marshal.FreeHGlobal(m_SamplersCache[i].m_Data);
                            }
                            m_SamplersCache[i].m_Data = Marshal.AllocHGlobal(totalSize);
                            UpdateMesh(m_SamplersCache[i].m_Data, srcAttr.m_Mesh, srcAttr.m_SamplingChannels, withSkinning);
                            m_SamplersCache[i].m_MeshChanged = 0x2A;                             // nonzero, why not 42?
                            m_SamplersCache[i].m_HashCode    = srcAttr.m_MeshHashCode;
                            srcAttr.m_InSkinning             = false;
                        }
                    }
                    else
                    {
                        if (m_SamplersCache[i].m_Data != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(m_SamplersCache[i].m_Data);
                            m_SamplersCache[i].m_Data = IntPtr.Zero;
                        }
                        m_SamplersCache[i].m_IndexCount  = 0;
                        m_SamplersCache[i].m_VertexCount = 0;
                        m_SamplersCache[i].m_MeshChanged = 0x2A;                         // nonzero, why not 42?
                        m_SamplersCache[i].m_HashCode    = 0;
                        m_SamplersCache[i].m_BoneCount   = 0;
                    }
                    srcAttr.m_TextureChanged = false;
                    smpCount = i;
                }
                m_SamplersCache[i].m_Type2 = (int)(m_FxSamplersList[i].m_ShapeType);
                m_SamplersCache[i].m_SizeX = srcAttr.m_Dimensions.x;
                m_SamplersCache[i].m_SizeY = srcAttr.m_Dimensions.y;
                m_SamplersCache[i].m_SizeZ = srcAttr.m_Dimensions.z;
                m_SamplersCache[i].m_PosX  = srcAttr.m_ShapeCenter.x;
                m_SamplersCache[i].m_PosY  = srcAttr.m_ShapeCenter.y;
                m_SamplersCache[i].m_PosZ  = srcAttr.m_ShapeCenter.z;
                m_SamplersCache[i].m_EulX  = srcAttr.m_EulerOrientation.x;
                m_SamplersCache[i].m_EulY  = srcAttr.m_EulerOrientation.y;
                m_SamplersCache[i].m_EulZ  = srcAttr.m_EulerOrientation.z;
            }
            else if (m_SamplersCache[i].m_Type1 == (int)PKFxManager.ESamplerType.SamplerImage)
            {
                wasChanged = srcAttr.m_TextureChanged ||
                             (int)srcAttr.m_TextureTexcoordMode != (int)m_SamplersCache[i].m_PosX;
                if (wasChanged || forceUpdate || m_ForceUpdateAttributes)
                {
                    if (srcAttr.m_Texture == null)
                    {
                        m_SamplersCache[i].m_SizeX = 0;
                        m_SamplersCache[i].m_SizeY = 0;
                        if (m_SamplersCache[i].m_Data != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(m_SamplersCache[i].m_Data);
                        }
                        m_SamplersCache[i].m_Data = IntPtr.Zero;
                        int size = 0;
                        m_SamplersCache[i].m_SizeZ = size;
                        m_SamplersCache[i].m_PosX  = 0;
                    }
                    else
                    {
                        byte[] data = srcAttr.m_Texture.GetRawTextureData();
                        if (data.Length == 0)
                        {
                            Debug.LogError("[PKFX] Sampler " + srcAttr.m_Descriptor.Name + " : Could not get raw texture data. Enable read/write in import settings.");
                        }

                        if (srcAttr.m_Texture.format == TextureFormat.DXT1)
                        {
                            m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.DXT1;
                        }
                        else if (srcAttr.m_Texture.format == TextureFormat.DXT5)
                        {
                            m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.DXT5;
                        }
                        else if (srcAttr.m_Texture.format == TextureFormat.ARGB32)
                        {
                            PKImageConverter.ARGB2BGRA(ref data);
                            m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.BGRA8;
                        }
                        else if (srcAttr.m_Texture.format == TextureFormat.RGBA32)
                        {
                            PKImageConverter.RGBA2BGRA(ref data);
                            m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.BGRA8;
                        }
                        else if (srcAttr.m_Texture.format == TextureFormat.BGRA32)
                        {
                            m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.BGRA8;
                        }
                        else if (srcAttr.m_Texture.format == TextureFormat.RGB24)
                        {
                            PKImageConverter.RGB2BGR(ref data);
                            m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.BGR8;
                        }
                        else if (srcAttr.m_Texture.format == TextureFormat.PVRTC_RGB4)
                        {
                            m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.RGB4_PVRTC1;
                        }
                        else if (srcAttr.m_Texture.format == TextureFormat.PVRTC_RGBA4)
                        {
                            m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.RGBA4_PVRTC1;
                        }
                        else if (srcAttr.m_Texture.format == TextureFormat.PVRTC_RGB2)
                        {
                            m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.RGB2_PVRTC1;
                        }
                        else if (srcAttr.m_Texture.format == TextureFormat.PVRTC_RGBA2)
                        {
                            m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.RGBA2_PVRTC1;
                        }
                        else if (srcAttr.m_Texture.format == TextureFormat.ETC_RGB4)
                        {
                            m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.RGB8_ETC1;
                        }
                        else if (srcAttr.m_Texture.format == TextureFormat.ETC2_RGB)
                        {
                            m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.RGB8_ETC2;
                        }
                        else if (srcAttr.m_Texture.format == TextureFormat.ETC2_RGBA8)
                        {
                            m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.RGBA8_ETC2;
                        }
                        else if (srcAttr.m_Texture.format == TextureFormat.ETC2_RGBA1)
                        {
                            m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.RGB8A1_ETC2;
                        }
                        else
                        {
                            m_SamplersCache[i].m_Type2 = (int)PKFxManager.EImageFormat.Invalid;
                            Debug.LogError("[PKFX] Sampler " + srcAttr.m_Descriptor.Name + " texture format not supported : " +
                                           srcAttr.m_Texture.format);
                        }

                        m_SamplersCache[i].m_SizeX = srcAttr.m_Texture.width;
                        m_SamplersCache[i].m_SizeY = srcAttr.m_Texture.height;
                        if (m_SamplersCache[i].m_Data != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(m_SamplersCache[i].m_Data);
                        }
                        int size = data.Length;
                        m_SamplersCache[i].m_Data = Marshal.AllocHGlobal(size);
                        Marshal.Copy(data, 0, m_SamplersCache[i].m_Data, size);
                        m_SamplersCache[i].m_SizeZ = size;
                        m_SamplersCache[i].m_PosX  = (int)srcAttr.m_TextureTexcoordMode;
                    }
                    srcAttr.m_TextureChanged = false;
                    smpCount = i;
                }
            }
            else if (m_SamplersCache[i].m_Type1 == (int)PKFxManager.ESamplerType.SamplerCurve)
            {
                int timeKeysCount = srcAttr.m_CurvesTimeKeys == null ? 0 : srcAttr.m_CurvesTimeKeys.Length;

                if (timeKeysCount == 0 && timeKeysCount != m_SamplersCache[i].m_SizeX)
                {
                    if (this.m_SamplersCurvesDataGCH.IsAllocated)
                    {
                        this.m_SamplersCurvesDataGCH.Free();
                    }
                    m_SamplersCurvesDataCache  = null;
                    m_SamplersCache[i].m_Data  = IntPtr.Zero;
                    m_SamplersCache[i].m_SizeX = 0;
                    smpCount = i;
                }
                else if (srcAttr.m_CurvesArray != null)
                {
                    int curvesCount   = srcAttr.m_CurvesArray.Length;
                    int keyDataOffset = (1 + curvesCount * 3);

                    wasChanged = timeKeysCount != m_SamplersCache[i].m_SizeX;

                    //check key times changed
                    if (!wasChanged && !forceUpdate && !m_ForceUpdateAttributes)
                    {
                        for (int keyId = 0; keyId < timeKeysCount; ++keyId)
                        {
                            if (m_SamplersCache[i].m_Data != IntPtr.Zero)
                            {
                                int   realId = samplerCurveOffset + (keyId * keyDataOffset);
                                float key    = srcAttr.m_CurvesTimeKeys[keyId];
                                if (key != m_SamplersCurvesDataCache[realId])
                                {
                                    wasChanged = true;
                                    break;
                                }
                            }
                        }
                    }
                    ////check values changed
                    if (!wasChanged && !forceUpdate && !m_ForceUpdateAttributes)
                    {
                        for (int curveId = 0; curveId < srcAttr.m_CurvesArray.Length; ++curveId)
                        {
                            if (m_SamplersCache[i].m_Data != IntPtr.Zero)
                            {
                                var curve = srcAttr.m_CurvesArray[curveId];
                                for (int keyId = 0; keyId < curve.keys.Length; ++keyId)
                                {
                                    int realId = samplerCurveOffset + (keyId * keyDataOffset) + 1 + curveId * 3;
                                    var key    = curve.keys[keyId];
                                    if (key.value != m_SamplersCurvesDataCache[realId + 0] ||
                                        key.inTangent != m_SamplersCurvesDataCache[realId + 1] ||
                                        key.outTangent != m_SamplersCurvesDataCache[realId + 2])
                                    {
                                        wasChanged = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    if (wasChanged || forceUpdate || m_ForceUpdateAttributes)
                    {
                        m_SamplersCache[i].m_Data = new IntPtr(m_SamplersCurvesDataHandler.ToInt64() + samplerCurveOffset);
                        // copy values
                        for (int keyId = 0; keyId < srcAttr.m_CurvesTimeKeys.Length; ++keyId)
                        {
                            int realId = samplerCurveOffset + (keyId * keyDataOffset);
                            m_SamplersCurvesDataCache[realId] = srcAttr.m_CurvesTimeKeys[keyId];
                            for (int curveId = 0; curveId < srcAttr.m_CurvesArray.Length; ++curveId)
                            {
                                var curve       = srcAttr.m_CurvesArray[curveId];
                                int curveRealId = realId + 1 + curveId * 3;
                                var key         = curve.keys[keyId];                         //Check if key exist
                                m_SamplersCurvesDataCache[curveRealId + 0] = key.value;
                                m_SamplersCurvesDataCache[curveRealId + 1] = key.inTangent;
                                m_SamplersCurvesDataCache[curveRealId + 2] = key.outTangent;
                            }
                        }
                        samplerCurveOffset        += timeKeysCount * keyDataOffset;
                        m_SamplersCache[i].m_SizeX = timeKeysCount;                         //key count
                        m_SamplersCache[i].m_SizeY = srcAttr.m_CurvesArray.Length;          //dimension
                        smpCount = i;
                    }
                }
            }
            else if (m_SamplersCache[i].m_Type1 == (int)PKFxManager.ESamplerType.SamplerText)
            {
                wasChanged = srcAttr.m_Text.Length != m_SamplersCache[i].m_SizeX;

                if (!wasChanged && srcAttr.m_Text.Length > 0 && m_SamplersCache[i].m_Data == IntPtr.Zero)
                {
                    wasChanged = true;
                }

                if (!wasChanged && m_SamplersCache[i].m_Data != IntPtr.Zero &&
                    Marshal.PtrToStringAnsi(m_SamplersCache[i].m_Data) != srcAttr.m_Text)
                {
                    wasChanged = true;
                }

                if (wasChanged || forceUpdate || m_ForceUpdateAttributes)
                {
                    if (m_SamplersCache[i].m_Data != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(m_SamplersCache[i].m_Data);
                        m_SamplersCache[i].m_Data = IntPtr.Zero;
                    }
                    int size = srcAttr.m_Text.Length;
                    if (size > 0)
                    {
                        m_SamplersCache[i].m_Data = Marshal.StringToHGlobalAnsi(srcAttr.m_Text);
                    }
                    m_SamplersCache[i].m_SizeX = size;
                    smpCount = i;
                }
            }
        }
        if (smpCount >= 0)
        {
            if (!PKFxManager.EffectSetSamplers(this.m_FXGUID, smpCount + 1, this.m_SamplersHandler))
            {
                Debug.LogError("[PKFX] Sampler through pinned memory failed.");
                Debug.LogError("[PKFX] Did you try to change an FX without stopping it beforehand?");
            }
        }
        for (int i = 0; i < m_FxSamplersList.Count; i++)
        {
            PKFxManager.Sampler srcAttr = m_FxSamplersList[i];

            bool withSkinning = m_FxSamplersList[i].m_ShapeType == (int)PKFxManager.EShapeType.SkinnedMeshShape &&
                                m_FxSamplersList[i].m_SkinnedMeshRenderer != null;

            if (withSkinning)
            {
                int boneCount = srcAttr.m_SkinnedMeshRenderer != null ? srcAttr.m_SkinnedMeshRenderer.bones.Length : 0;

                if (!srcAttr.m_InSkinning)
                {
                    int skeletonSize = boneCount != 0 ? srcAttr.m_SkinnedMeshRenderer.bones.Length * sizeof(float) * 16 : 0;

                    if (m_SamplersCache[i].m_Data != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(m_SamplersCache[i].m_Data);
                    }
                    m_SamplersCache[i].m_Data = Marshal.AllocHGlobal(skeletonSize);
                    srcAttr.m_InSkinning      = true;
                }

                UpdateBones(m_SamplersCache[i].m_Data, srcAttr.m_SkinnedMeshRenderer);
                if (!PKFxManager.EffectUpdateSamplerSkinning(this.m_FXGUID, i, this.m_SamplersHandler, Time.deltaTime))
                {
                    Debug.LogError("[PKFX] Skinning through pinned memory failed.");
                }
            }
        }
        m_ForceUpdateAttributes = false;
    }