/// <summary>
        /// Builds and link the texture used to color the body.
        /// </summary>
        private void SetupBodyColorTexture()
        {
            //Generate the body texture to color using the face actual size
            m_tBodyTexture = new Texture2D(
                Mathf.FloorToInt(m_oBody.sharedMesh.bounds.size.x * m_iPixelPerUnit),
                Mathf.FloorToInt(m_oBody.sharedMesh.bounds.size.z * m_iPixelPerUnit),
                TextureFormat.ARGB32,
                false);
            m_tBodyTexture.SetPixels(TextureUtilities.FillTextureWithColor(m_tBodyTexture, m_oBaseColor)); //initialiaze it to white
            m_tBodyTexture.Apply();

            //link the body texture as the material's main texture
            m_oSurfaceRenderer.material.SetTexture("_MainTex", m_tBodyTexture);
        }
        /// <summary>
        /// Builds and link the texture used to color the letter.
        /// </summary>
        private void SetupLetterColorTexture()
        {
            //Generate the texture to color using the letter actual size
            //- Format can be very low, we only need some base color not a full 32 bit but setPixel/Pixels works
            //  only on ARGB32, RGB24 and Alpha8 texture formats
            Vector3[] _meshVertices = m_oLetterMeshCollider.sharedMesh.vertices;
            m_tLetterDynamicTexture = new Texture2D(
                Mathf.FloorToInt(Mathf.Abs(_meshVertices[0].x - _meshVertices[3].x) * m_iPixelPerUnit),
                Mathf.FloorToInt(Mathf.Abs(_meshVertices[0].y - _meshVertices[1].y) * m_iPixelPerUnit),
                TextureFormat.ARGB32,
                false);
            m_tLetterDynamicTexture.SetPixels(TextureUtilities.FillTextureWithColor(m_tLetterDynamicTexture, m_oBaseColor)); //initialiaze it to white
            m_tLetterDynamicTexture.Apply();

            //link the dynamic texture to the TextMeshPro Text as the material's face texture
            m_oTextMeshObject.fontMaterial.SetTexture("_FaceTex", m_tLetterDynamicTexture);
        }
        /// <summary>
        /// Builds the brush to color with by using the stored texture, scaling and color.
        /// Must be called to apply any changes on the brush.
        /// </summary>
        public void BuildBrush()
        {
            if (!m_tBrushShape) //if not given, use a default square
            {
                m_tBrushShape = Texture2D.whiteTexture;
            }

            //Generate the scaled texture
            m_tScaledBrush = new Texture2D(
                Mathf.FloorToInt(m_tBrushShape.width * m_fBrushScaling),
                Mathf.FloorToInt(m_tBrushShape.height * m_fBrushScaling),
                TextureFormat.ARGB32,
                false);

            m_tScaledBrush.SetPixels(TextureUtilities.ScaleTexture(m_tBrushShape, m_tScaledBrush.width, m_tScaledBrush.height));

            m_tScaledBrush.Apply();

            SetBrushColor(m_oDrawingColor);
        }
        /// <summary>
        /// The texture to color and the actual portion of the letter texture are most likely different;
        /// use this to precalculate a scaled texture of the letter to match the sizes 1:1 and avoid
        /// frequent use of GetPixelBilinear() at each frame when accessing letter texture data.
        /// </summary>
        private void SetupLetterShapeTexture()
        {
            //here we setup two textures:
            //(1) - m_tSingleLetterRenderedTextureScaledToDynamic: scale the letter alpha texture to match the size of the dynamic one and having a 1:1 matching on the color coverage
            //(2) - m_tSingleLetterAlphaTextureScaledToDynamic: scale the letter alpha texture with greater dilatation to match the size of the dynamic one and having a 1:1 matching on the check for the hit

            //retrive the letter size and width in pixels on the original texture
            int _iSingleLetterWidthUnscaled  = Mathf.FloorToInt(Mathf.Abs(m_aUVLetterInMainTexture[0].x - m_aUVLetterInMainTexture[3].x) * s_tBaseLetterFullTexture.width);
            int _iSingleLetterHeightUnscaled = Mathf.FloorToInt(Mathf.Abs(m_aUVLetterInMainTexture[0].y - m_aUVLetterInMainTexture[1].y) * s_tBaseLetterFullTexture.height);

            //retrive the colors(shape) of the letter
            Color[] _aColorSingleLetterUnscaled = s_tBaseLetterFullTexture.GetPixels(Mathf.FloorToInt(m_aUVLetterInMainTexture[0].x * s_tBaseLetterFullTexture.width), Mathf.FloorToInt(m_aUVLetterInMainTexture[0].y * s_tBaseLetterFullTexture.height), _iSingleLetterWidthUnscaled, _iSingleLetterHeightUnscaled);

            //generate a texture with the founded size and colors
            Texture2D _tSingleLetterTextureUnscaled = new Texture2D(_iSingleLetterWidthUnscaled, _iSingleLetterHeightUnscaled, TextureFormat.Alpha8, false);

            _tSingleLetterTextureUnscaled.SetPixels(_aColorSingleLetterUnscaled);
            _tSingleLetterTextureUnscaled.Apply();

            //finally scale the texture
            Color[] _aColorSingleLetterScaled = TextureUtilities.ScaleTexture(_tSingleLetterTextureUnscaled, m_tLetterDynamicTexture.width, m_tLetterDynamicTexture.height);

            m_tSingleLetterRenderedTextureScaledToDynamic = new Texture2D(m_tLetterDynamicTexture.width, m_tLetterDynamicTexture.height, TextureFormat.Alpha8, false);

            //Depending on the face dilate property(but also others can influence the letter thickness like bold, softness,...)
            // of the letter material, the final letter rendered can be more thin than the original
            //To estimate the final outcome we set to 0 all the alpha values under such property's value;
            //it ranges from [-1,1], where 1 keeps all alpha values and -1 none
            float _fDilateFactorMapped = (m_oTextMeshObject.fontMaterial.GetFloat("_FaceDilate") + 1.0f) / 2.0f; //map in [0,1]

            m_iTotalShapePixels = 0;

            if (m_fErrorOffsetFactor == 0) //if the error relax is actually 0, use the same texture for both (1) and (2) (to save memory)
            {
                for (int idx = 0; idx < _aColorSingleLetterScaled.Length; ++idx)
                {
                    _aColorSingleLetterScaled[idx].a = Mathf.CeilToInt(_aColorSingleLetterScaled[idx].a - _fDilateFactorMapped + m_fErrorOffsetFactor);

                    //find out how many of the pixels in the texture compose the letter (alpha !=0 in (1))
                    m_iTotalShapePixels += Mathf.CeilToInt(_aColorSingleLetterScaled[idx].a);
                }

                m_tSingleLetterRenderedTextureScaledToDynamic.SetPixels(_aColorSingleLetterScaled);
                m_tSingleLetterRenderedTextureScaledToDynamic.Apply();

                m_tSingleLetterAlphaTextureScaledToDynamic = m_tSingleLetterRenderedTextureScaledToDynamic;
            }

            else //they must be different

            {
                m_tSingleLetterAlphaTextureScaledToDynamic = new Texture2D(m_tLetterDynamicTexture.width, m_tLetterDynamicTexture.height, TextureFormat.Alpha8, false);


                Color[] _aColorSingleLetterScaled_RenderedShape   = new Color[_aColorSingleLetterScaled.Length]; //color for (1)
                Color[] _aColorSingleLetterScaled_ErrorCheckShape = new Color[_aColorSingleLetterScaled.Length]; //color for (2)

                for (int idx = 0; idx < _aColorSingleLetterScaled.Length; ++idx)
                {
                    _aColorSingleLetterScaled_RenderedShape[idx].a = Mathf.CeilToInt(_aColorSingleLetterScaled[idx].a - _fDilateFactorMapped);                          //clamp for (1)

                    _aColorSingleLetterScaled_ErrorCheckShape[idx].a = Mathf.CeilToInt(_aColorSingleLetterScaled[idx].a - _fDilateFactorMapped + m_fErrorOffsetFactor); //clamp for (2)

                    //find out how many of the pixels in the texture compose the letter (alpha !=0 in (1))
                    m_iTotalShapePixels += Mathf.CeilToInt(_aColorSingleLetterScaled_RenderedShape[idx].a);
                }

                m_tSingleLetterRenderedTextureScaledToDynamic.SetPixels(_aColorSingleLetterScaled_RenderedShape);
                m_tSingleLetterRenderedTextureScaledToDynamic.Apply();

                m_tSingleLetterAlphaTextureScaledToDynamic.SetPixels(_aColorSingleLetterScaled_ErrorCheckShape);
                m_tSingleLetterAlphaTextureScaledToDynamic.Apply();
            }
        }