public VertexColour(VertexColour vert_col)
		{
			top_left = vert_col.top_left;
			top_right = vert_col.top_right;
			bottom_right = vert_col.bottom_right;
			bottom_left = vert_col.bottom_left;
		}
Beispiel #2
0
 public VertexColour(VertexColour vert_col)
 {
     top_left     = vert_col.top_left;
     top_right    = vert_col.top_right;
     bottom_right = vert_col.bottom_right;
     bottom_left  = vert_col.bottom_left;
 }
		public VertexColour Sub(VertexColour vert_col)
		{
			VertexColour v_col = new VertexColour();
			v_col.bottom_left = bottom_left - vert_col.bottom_left;
			v_col.bottom_right = bottom_right - vert_col.bottom_right;
			v_col.top_left = top_left - vert_col.top_left;
			v_col.top_right = top_right - vert_col.top_right;
			
			return v_col;
		}
		public VertexColour Multiply(float factor)
		{
			VertexColour v_col = new VertexColour();
			v_col.bottom_left = bottom_left * factor;
			v_col.bottom_right = bottom_right * factor;
			v_col.top_left = top_left * factor;
			v_col.top_right = top_right * factor;
			
			return v_col;
		}
		public VertexColour Clone()
		{
			VertexColour vertex_col = new VertexColour();
			vertex_col.top_left = top_left;
			vertex_col.top_right = top_right;
			vertex_col.bottom_right = bottom_right;
			vertex_col.bottom_left = bottom_left;
			
			return vertex_col;
		}
Beispiel #6
0
        public VertexColour Clone()
        {
            VertexColour vertex_col = new VertexColour();

            vertex_col.top_left     = top_left;
            vertex_col.top_right    = top_right;
            vertex_col.bottom_right = bottom_right;
            vertex_col.bottom_left  = bottom_left;

            return(vertex_col);
        }
Beispiel #7
0
        public VertexColour Sub(VertexColour vert_col)
        {
            VertexColour v_col = new VertexColour();

            v_col.bottom_left  = bottom_left - vert_col.bottom_left;
            v_col.bottom_right = bottom_right - vert_col.bottom_right;
            v_col.top_left     = top_left - vert_col.top_left;
            v_col.top_right    = top_right - vert_col.top_right;

            return(v_col);
        }
Beispiel #8
0
        public static JSONValue ExportData(this VertexColour vert_color)
        {
            JSONObject json_data = new JSONObject();

            json_data["bottom_left"]  = vert_color.bottom_left.ExportData();
            json_data["bottom_right"] = vert_color.bottom_right.ExportData();
            json_data["top_left"]     = vert_color.top_left.ExportData();
            json_data["top_right"]    = vert_color.top_right.ExportData();

            return(new JSONValue(json_data));
        }
Beispiel #9
0
        public VertexColour Multiply(float factor)
        {
            VertexColour v_col = new VertexColour();

            v_col.bottom_left  = bottom_left * factor;
            v_col.bottom_right = bottom_right * factor;
            v_col.top_left     = top_left * factor;
            v_col.top_right    = top_right * factor;

            return(v_col);
        }
		public void CalculateProgressions(int num_progressions, VertexColour[] offset_vert_colours, Color[] offset_colours)
		{
			if(Progression == (int) ValueProgression.Eased || Progression == (int) ValueProgression.EasedCustom || Progression == (int) ValueProgression.Random || (m_is_offset_from_last && ((offset_colours != null && offset_colours.Length > 1) || (offset_vert_colours != null && offset_vert_colours.Length > 1) )))
			{
				bool constant_offset = (offset_colours != null && offset_colours.Length == 1) || (offset_vert_colours != null && offset_vert_colours.Length == 1);
				m_values = new VertexColour[num_progressions];
				
				for(int idx=0; idx < num_progressions; idx++)
				{
					m_values[idx] = m_is_offset_from_last ? 
										(offset_colours != null ? new VertexColour(offset_colours[constant_offset ? 0 : idx]) : offset_vert_colours[constant_offset ? 0 : idx].Clone())
							
										: new VertexColour(new Color(0,0,0,0));
				}
			}
			else
			{
				m_values = new VertexColour[1]{ m_is_offset_from_last ? 
										(offset_colours != null ? new VertexColour(offset_colours[0]) : offset_vert_colours[0].Clone())
							
										: new VertexColour(new Color(0,0,0,0)) };
			}
			
			
			if(Progression == (int) ValueProgression.Random)
			{
				for(int idx=0; idx < num_progressions; idx++)
				{
					m_values[idx] = m_values[idx].Add(m_from.Add(m_to.Sub(m_from).Multiply(UnityEngine.Random.value)));
				}
			}
			else if(Progression == (int) ValueProgression.Eased)
			{
				float progression;
				
				for(int idx=0; idx < num_progressions; idx++)
				{
					progression = num_progressions == 1 ? 0 : (float)idx / ((float)num_progressions - 1f);
				
					if(m_to_to_bool)
					{
						if(progression  <= 0.5f)
						{
							m_values[idx] = m_values[idx].Add(m_from.Add((m_to.Sub(m_from)).Multiply(EasingManager.GetEaseProgress(m_ease_type, progression/0.5f))));
						}
						else
						{
							progression -= 0.5f;
							m_values[idx] = m_values[idx].Add(m_to.Add((m_to_to.Sub(m_to)).Multiply(EasingManager.GetEaseProgress(m_ease_type, progression/0.5f))));
						}
					}
					else
					{
						m_values[idx] = m_values[idx].Add(m_from.Add((m_to.Sub(m_from)).Multiply(EasingManager.GetEaseProgress(m_ease_type, progression))));
					}
				}
			}
			else if(Progression == (int) ValueProgression.EasedCustom)
			{
				float progression;
				
				for(int idx=0; idx < num_progressions; idx++)
				{
					progression = num_progressions == 1 ? 0 : (float)idx / ((float)num_progressions - 1f);
					
					m_values[idx] = m_values[idx].Add(m_from.Add((m_to.Sub(m_from)).Multiply(m_custom_ease_curve.Evaluate(progression))));
				}
			}
			else if(Progression == (int) ValueProgression.Constant)
			{
				for(int idx=0; idx < m_values.Length; idx++)
				{
					m_values[idx] = m_values[idx].Add(m_from);
				}
			}
		}
		public void CalculateUniqueRandom(AnimationProgressionVariables progression_variables, AnimatePerOptions animate_per, VertexColour[] offset_colours)
		{
			int progression_idx = GetProgressionIndex(progression_variables, animate_per);
			bool constant_offset = offset_colours != null && offset_colours.Length == 1;
				
			m_values[progression_idx] = m_is_offset_from_last ? offset_colours[constant_offset ? 0 : progression_idx].Clone() : new VertexColour(new Color(0,0,0,0));
			m_values[progression_idx] = m_values[progression_idx].Add(m_from.Add(m_to.Sub(m_from).Multiply(UnityEngine.Random.value)));
		}
		public void ConvertFromFlatColourProg(ActionColorProgression flat_colour_progression)
		{
			m_progression_idx = flat_colour_progression.Progression;
			m_ease_type = flat_colour_progression.EaseType;
			m_from = new VertexColour(flat_colour_progression.ValueFrom);
			m_to = new VertexColour(flat_colour_progression.ValueTo);
			m_to_to = new VertexColour(flat_colour_progression.ValueThen);
			m_to_to_bool = flat_colour_progression.UsingThirdValue;
			m_is_offset_from_last = flat_colour_progression.IsOffsetFromLast;
			m_unique_randoms = flat_colour_progression.UniqueRandom;
		}
		public ActionVertexColorProgression(VertexColour start_colour)
		{
			m_from = start_colour.Clone();
			m_to = start_colour.Clone();
			m_to_to = start_colour.Clone();
		}
		public void SetEasedCustom ( AnimationCurve easing_curve, VertexColour eased_from, VertexColour eased_to)
		{
			m_progression_idx = (int) ValueProgression.EasedCustom;
			m_from = eased_from;
			m_to = eased_to;
			m_to_to_bool = false;
			
			m_custom_ease_curve = easing_curve;
		}
		public void SetEased( EasingEquation easing_function, VertexColour eased_from, VertexColour eased_to, VertexColour eased_then)
		{
			m_progression_idx = (int) ValueProgression.Eased;
			m_from = eased_from;
			m_to = eased_to;
			m_to_to = eased_then;
			m_to_to_bool = true;
			m_ease_type = easing_function;
		}
		public void SetRandom( VertexColour random_min, VertexColour random_max, bool unique_randoms = false)
		{
			m_progression_idx = (int) ValueProgression.Random;
			m_from = random_min;
			m_to = random_max;
			m_unique_randoms = unique_randoms;
		}
		public void SetConstant( VertexColour constant_value )
		{
			m_progression_idx = (int) ValueProgression.Constant;
			m_from = constant_value;
		}
		public override void ImportData(JSONObject json_data)
		{
			m_from = json_data["m_from"].Obj.JSONtoVertexColour();
			m_to = json_data["m_to"].Obj.JSONtoVertexColour();
			m_to_to = json_data["m_to_to"].Obj.JSONtoVertexColour();
			
			ImportBaseData(json_data);
		}
		void SetupMesh(LetterAction letter_action, LetterAction prev_action, float action_progress, AnimationProgressionVariables progression_variables, AnimatePerOptions animate_per, float linear_progress, EffectManager effect_manager)
		{	
			// construct current anchor offset vector
			m_anchor_offset = letter_action.AnchorOffsetStart;
			m_anchor_offset = new Vector3(	m_anchor_offset.x * m_width, 
											letter_action.m_letter_anchor_start == (int) TextfxTextAnchor.BaselineLeft || letter_action.m_letter_anchor_start == (int) TextfxTextAnchor.BaselineCenter || letter_action.m_letter_anchor_start == (int) TextfxTextAnchor.BaselineRight 
												? 0		// zero because letters are based around the baseline already.
												: (effect_manager.IsFontBaseLineSet 
														? (effect_manager.FontBaseLine + m_y_offset) - (m_anchor_offset.y * -m_height)
														: (m_anchor_offset.y * m_height)),	// Legacy effect support when baseline isn't already set.
											0);
			
			if(letter_action.m_letter_anchor_2_way)
			{
				m_anchor_offset = letter_action.AnchorOffsetEnd;
				m_anchor_offset = Vector3.Lerp(	m_anchor_offset,
												new Vector3(
													m_anchor_offset.x * m_width,
													letter_action.m_letter_anchor_end == (int) TextfxTextAnchor.BaselineLeft || letter_action.m_letter_anchor_end == (int) TextfxTextAnchor.BaselineCenter || letter_action.m_letter_anchor_end == (int) TextfxTextAnchor.BaselineRight
														? 0		// zero because letters are based around the baseline already.
														: (effect_manager.IsFontBaseLineSet
																? (effect_manager.FontBaseLine + m_y_offset) - (m_anchor_offset.y * -m_height)
																: (m_anchor_offset.y * m_height)),	// Legacy effect support when baseline isn't already set.
													0),
												action_progress);
			}
			
			
			// Calculate Scale Vector
			from_vec = letter_action.m_start_scale.GetValue(progression_variables, animate_per);
			to_vec = letter_action.m_end_scale.GetValue(progression_variables, animate_per);
			
			if(letter_action.m_scale_axis_ease_data.m_override_default)
			{
				m_letter_scale = new Vector3(	EffectManager.FloatLerp(from_vec.x, to_vec.x, EasingManager.GetEaseProgress(letter_action.m_scale_axis_ease_data.m_x_ease, linear_progress)),
												EffectManager.FloatLerp(from_vec.y, to_vec.y, EasingManager.GetEaseProgress(letter_action.m_scale_axis_ease_data.m_y_ease, linear_progress)),
												EffectManager.FloatLerp(from_vec.z, to_vec.z, EasingManager.GetEaseProgress(letter_action.m_scale_axis_ease_data.m_z_ease, linear_progress)));
			}
			else
			{
				m_letter_scale = EffectManager.Vector3Lerp(
												from_vec,
												to_vec,
												action_progress);
			}
			
			// Calculate Rotation
			from_vec = letter_action.m_start_euler_rotation.GetValue(progression_variables, animate_per);
			to_vec = letter_action.m_end_euler_rotation.GetValue(progression_variables, animate_per);
			
			if(letter_action.m_rotation_axis_ease_data.m_override_default)
			{
				m_letter_rotation =	Quaternion.Euler
									(
										EffectManager.FloatLerp(from_vec.x, to_vec.x, EasingManager.GetEaseProgress(letter_action.m_rotation_axis_ease_data.m_x_ease, linear_progress)),
										EffectManager.FloatLerp(from_vec.y, to_vec.y, EasingManager.GetEaseProgress(letter_action.m_rotation_axis_ease_data.m_y_ease, linear_progress)),
										EffectManager.FloatLerp(from_vec.z, to_vec.z, EasingManager.GetEaseProgress(letter_action.m_rotation_axis_ease_data.m_z_ease, linear_progress))
									);
			}
			else
			{
				m_letter_rotation = Quaternion.Euler(
											EffectManager.Vector3Lerp(
												from_vec,
												to_vec,
												action_progress)
											);
			}
			
			
			// Calculate Position
			if(letter_action.m_start_pos.Progression == ActionPositionVector3Progression.CURVE_OPTION_INDEX || (letter_action.m_offset_from_last && prev_action != null && prev_action.m_end_pos.Progression == ActionPositionVector3Progression.CURVE_OPTION_INDEX))
				from_vec = new Vector3(-m_anchor_offset.x,m_base_offset.y,0);
			else if(letter_action.m_start_pos.ForcePositionOverride)
				from_vec = new Vector3(-m_anchor_offset.x,0,0);
			else
				from_vec = BaseOffset;
			
			from_vec += letter_action.m_start_pos.GetValue(progression_variables, animate_per);
			
			if(letter_action.m_end_pos.Progression == ActionPositionVector3Progression.CURVE_OPTION_INDEX || (letter_action.m_end_pos.IsOffsetFromLast && letter_action.m_start_pos.Progression == ActionPositionVector3Progression.CURVE_OPTION_INDEX))
				to_vec = new Vector3(-m_anchor_offset.x,m_base_offset.y,0);
			else if(letter_action.m_end_pos.ForcePositionOverride)
				to_vec = new Vector3(-m_anchor_offset.x,0,0);
			else
				to_vec = BaseOffset;
			
			to_vec += letter_action.m_end_pos.GetValue(progression_variables, animate_per);
			
			if(letter_action.m_position_axis_ease_data.m_override_default)
			{
				m_letter_position = new Vector3(	EffectManager.FloatLerp(from_vec.x, to_vec.x, EasingManager.GetEaseProgress(letter_action.m_position_axis_ease_data.m_x_ease, linear_progress)),
													EffectManager.FloatLerp(from_vec.y, to_vec.y, EasingManager.GetEaseProgress(letter_action.m_position_axis_ease_data.m_y_ease, linear_progress)),
													EffectManager.FloatLerp(from_vec.z, to_vec.z, EasingManager.GetEaseProgress(letter_action.m_position_axis_ease_data.m_z_ease, linear_progress)));
			}
			else
			{
				m_letter_position = EffectManager.Vector3Lerp(
					from_vec, 
					to_vec,
					action_progress);
			}
			
			// Calculate letter center position
			m_letter_center = new Vector3(m_width / 2, m_height/2, 0);
			m_letter_center -= m_anchor_offset;
			m_letter_center = Vector3.Scale(m_letter_center, m_letter_scale);
			m_letter_center = m_letter_rotation	* m_letter_center;
			m_letter_center += m_anchor_offset + m_letter_position;
			
			
			if(mesh_verts == null || mesh_verts.Length == 0)
				mesh_verts = new Vector3[4];
			for(int idx=0; idx < 4; idx++)
			{
				mesh_verts[idx] = m_base_vertices[idx];
				
				// normalise vert position to the anchor point before scaling and rotating.
				mesh_verts[idx] -= m_anchor_offset;
				
				// Scale verts
				mesh_verts[idx] = Vector3.Scale(mesh_verts[idx], m_letter_scale);
				
				// Rotate vert
				mesh_verts[idx] = m_letter_rotation	* mesh_verts[idx];
				
				mesh_verts[idx] += m_anchor_offset;
				
				// translate vert
				mesh_verts[idx] += m_letter_position;
			}
			m_mesh.vertices = mesh_verts;
			
			
			
			// Sort out letters colour
			if(letter_action.m_use_gradient_start)
			{
				start_colour = letter_action.m_start_vertex_colour.GetValue(progression_variables, animate_per);
			}
			else
			{
				start_colour = new VertexColour(letter_action.m_start_colour.GetValue(progression_variables, animate_per));
			}
			
			if(letter_action.m_use_gradient_end)
			{
				end_colour = letter_action.m_end_vertex_colour.GetValue(progression_variables, animate_per);
			}
			else
			{
				end_colour = new VertexColour(letter_action.m_end_colour.GetValue(progression_variables, animate_per));
			}
			
			if(!m_flipped)
			{
				m_mesh.colors = new Color[]{ 
					Color.Lerp(start_colour.top_right, end_colour.top_right, action_progress), 
					Color.Lerp(start_colour.top_left, end_colour.top_left, action_progress), 
					Color.Lerp(start_colour.bottom_left, end_colour.bottom_left, action_progress), 
					Color.Lerp(start_colour.bottom_right, end_colour.bottom_right, action_progress)};
			}
			else
			{
				m_mesh.colors = new Color[]{
					Color.Lerp(start_colour.top_left, end_colour.top_left, action_progress),
					Color.Lerp(start_colour.bottom_left, end_colour.bottom_left, action_progress),
					Color.Lerp(start_colour.bottom_right, end_colour.bottom_right, action_progress),
					Color.Lerp(start_colour.top_right, end_colour.top_right, action_progress)
				};
			}
		}
		public void ImportLegacyData(string data_string)
		{
			KeyValuePair<string, string> value_pair;
			List<object> obj_list = data_string.StringToList(';',':');
			
			foreach(object obj in obj_list)
			{
				value_pair = (KeyValuePair<string, string>) obj;
				
				switch(value_pair.Key)
				{
				case "m_from": m_from = value_pair.Value.StringToVertexColor('|','<','^'); break;
				case "m_to": m_to = value_pair.Value.StringToVertexColor('|','<','^'); break;
				case "m_to_to": m_to_to = value_pair.Value.StringToVertexColor('|','<','^'); break;
					
				default :
					ImportBaseLagacyData(value_pair); break;
				}
			}
		}
Beispiel #21
0
        void SetupMesh(LetterAction letter_action, LetterAction prev_action, float action_progress, AnimationProgressionVariables progression_variables, AnimatePerOptions animate_per, float linear_progress, EffectManager effect_manager)
        {
            // construct current anchor offset vector
            m_anchor_offset = letter_action.AnchorOffsetStart;
            m_anchor_offset = new Vector3(m_anchor_offset.x * m_width,
                                          letter_action.m_letter_anchor_start == (int)TextfxTextAnchor.BaselineLeft || letter_action.m_letter_anchor_start == (int)TextfxTextAnchor.BaselineCenter || letter_action.m_letter_anchor_start == (int)TextfxTextAnchor.BaselineRight
                                                                                                ? 0             // zero because letters are based around the baseline already.
                                                                                                : (effect_manager.IsFontBaseLineSet
                                                                                                                ? (effect_manager.FontBaseLine + m_y_offset) - (m_anchor_offset.y * -m_height)
                                                                                                                : (m_anchor_offset.y * m_height)),      // Legacy effect support when baseline isn't already set.
                                          0);

            if (letter_action.m_letter_anchor_2_way)
            {
                m_anchor_offset = letter_action.AnchorOffsetEnd;
                m_anchor_offset = Vector3.Lerp(m_anchor_offset,
                                               new Vector3(
                                                   m_anchor_offset.x * m_width,
                                                   letter_action.m_letter_anchor_end == (int)TextfxTextAnchor.BaselineLeft || letter_action.m_letter_anchor_end == (int)TextfxTextAnchor.BaselineCenter || letter_action.m_letter_anchor_end == (int)TextfxTextAnchor.BaselineRight
                                                                                                                ? 0             // zero because letters are based around the baseline already.
                                                                                                                : (effect_manager.IsFontBaseLineSet
                                                                                                                                ? (effect_manager.FontBaseLine + m_y_offset) - (m_anchor_offset.y * -m_height)
                                                                                                                                : (m_anchor_offset.y * m_height)),      // Legacy effect support when baseline isn't already set.
                                                   0),
                                               action_progress);
            }


            // Calculate Scale Vector
            from_vec = letter_action.m_start_scale.GetValue(progression_variables, animate_per);
            to_vec   = letter_action.m_end_scale.GetValue(progression_variables, animate_per);

            if (letter_action.m_scale_axis_ease_data.m_override_default)
            {
                m_letter_scale = new Vector3(EffectManager.FloatLerp(from_vec.x, to_vec.x, EasingManager.GetEaseProgress(letter_action.m_scale_axis_ease_data.m_x_ease, linear_progress)),
                                             EffectManager.FloatLerp(from_vec.y, to_vec.y, EasingManager.GetEaseProgress(letter_action.m_scale_axis_ease_data.m_y_ease, linear_progress)),
                                             EffectManager.FloatLerp(from_vec.z, to_vec.z, EasingManager.GetEaseProgress(letter_action.m_scale_axis_ease_data.m_z_ease, linear_progress)));
            }
            else
            {
                m_letter_scale = EffectManager.Vector3Lerp(
                    from_vec,
                    to_vec,
                    action_progress);
            }

            // Calculate Rotation
            from_vec = letter_action.m_start_euler_rotation.GetValue(progression_variables, animate_per);
            to_vec   = letter_action.m_end_euler_rotation.GetValue(progression_variables, animate_per);

            if (letter_action.m_rotation_axis_ease_data.m_override_default)
            {
                m_letter_rotation = Quaternion.Euler
                                    (
                    EffectManager.FloatLerp(from_vec.x, to_vec.x, EasingManager.GetEaseProgress(letter_action.m_rotation_axis_ease_data.m_x_ease, linear_progress)),
                    EffectManager.FloatLerp(from_vec.y, to_vec.y, EasingManager.GetEaseProgress(letter_action.m_rotation_axis_ease_data.m_y_ease, linear_progress)),
                    EffectManager.FloatLerp(from_vec.z, to_vec.z, EasingManager.GetEaseProgress(letter_action.m_rotation_axis_ease_data.m_z_ease, linear_progress))
                                    );
            }
            else
            {
                m_letter_rotation = Quaternion.Euler(
                    EffectManager.Vector3Lerp(
                        from_vec,
                        to_vec,
                        action_progress)
                    );
            }


            // Calculate Position
            if (letter_action.m_start_pos.Progression == ActionPositionVector3Progression.CURVE_OPTION_INDEX || (letter_action.m_offset_from_last && prev_action != null && prev_action.m_end_pos.Progression == ActionPositionVector3Progression.CURVE_OPTION_INDEX))
            {
                from_vec = new Vector3(-m_anchor_offset.x, m_base_offset.y, 0);
            }
            else if (letter_action.m_start_pos.ForcePositionOverride)
            {
                from_vec = new Vector3(-m_anchor_offset.x, 0, 0);
            }
            else
            {
                from_vec = BaseOffset;
            }

            from_vec += letter_action.m_start_pos.GetValue(progression_variables, animate_per);

            if (letter_action.m_end_pos.Progression == ActionPositionVector3Progression.CURVE_OPTION_INDEX || (letter_action.m_end_pos.IsOffsetFromLast && letter_action.m_start_pos.Progression == ActionPositionVector3Progression.CURVE_OPTION_INDEX))
            {
                to_vec = new Vector3(-m_anchor_offset.x, m_base_offset.y, 0);
            }
            else if (letter_action.m_end_pos.ForcePositionOverride)
            {
                to_vec = new Vector3(-m_anchor_offset.x, 0, 0);
            }
            else
            {
                to_vec = BaseOffset;
            }

            to_vec += letter_action.m_end_pos.GetValue(progression_variables, animate_per);

            if (letter_action.m_position_axis_ease_data.m_override_default)
            {
                m_letter_position = new Vector3(EffectManager.FloatLerp(from_vec.x, to_vec.x, EasingManager.GetEaseProgress(letter_action.m_position_axis_ease_data.m_x_ease, linear_progress)),
                                                EffectManager.FloatLerp(from_vec.y, to_vec.y, EasingManager.GetEaseProgress(letter_action.m_position_axis_ease_data.m_y_ease, linear_progress)),
                                                EffectManager.FloatLerp(from_vec.z, to_vec.z, EasingManager.GetEaseProgress(letter_action.m_position_axis_ease_data.m_z_ease, linear_progress)));
            }
            else
            {
                m_letter_position = EffectManager.Vector3Lerp(
                    from_vec,
                    to_vec,
                    action_progress);
            }

            // Calculate letter center position
            m_letter_center  = new Vector3(m_width / 2, m_height / 2, 0);
            m_letter_center -= m_anchor_offset;
            m_letter_center  = Vector3.Scale(m_letter_center, m_letter_scale);
            m_letter_center  = m_letter_rotation * m_letter_center;
            m_letter_center += m_anchor_offset + m_letter_position;


            if (mesh_verts == null || mesh_verts.Length == 0)
            {
                mesh_verts = new Vector3[4];
            }
            for (int idx = 0; idx < 4; idx++)
            {
                mesh_verts[idx] = m_base_vertices[idx];

                // normalise vert position to the anchor point before scaling and rotating.
                mesh_verts[idx] -= m_anchor_offset;

                // Scale verts
                mesh_verts[idx] = Vector3.Scale(mesh_verts[idx], m_letter_scale);

                // Rotate vert
                mesh_verts[idx] = m_letter_rotation * mesh_verts[idx];

                mesh_verts[idx] += m_anchor_offset;

                // translate vert
                mesh_verts[idx] += m_letter_position;
            }
            m_mesh.vertices = mesh_verts;



            // Sort out letters colour
            if (letter_action.m_use_gradient_start)
            {
                start_colour = letter_action.m_start_vertex_colour.GetValue(progression_variables, animate_per);
            }
            else
            {
                start_colour = new VertexColour(letter_action.m_start_colour.GetValue(progression_variables, animate_per));
            }

            if (letter_action.m_use_gradient_end)
            {
                end_colour = letter_action.m_end_vertex_colour.GetValue(progression_variables, animate_per);
            }
            else
            {
                end_colour = new VertexColour(letter_action.m_end_colour.GetValue(progression_variables, animate_per));
            }

            if (!m_flipped)
            {
                m_mesh.colors = new Color[] {
                    Color.Lerp(start_colour.top_right, end_colour.top_right, action_progress),
                    Color.Lerp(start_colour.top_left, end_colour.top_left, action_progress),
                    Color.Lerp(start_colour.bottom_left, end_colour.bottom_left, action_progress),
                    Color.Lerp(start_colour.bottom_right, end_colour.bottom_right, action_progress)
                };
            }
            else
            {
                m_mesh.colors = new Color[] {
                    Color.Lerp(start_colour.top_left, end_colour.top_left, action_progress),
                    Color.Lerp(start_colour.bottom_left, end_colour.bottom_left, action_progress),
                    Color.Lerp(start_colour.bottom_right, end_colour.bottom_right, action_progress),
                    Color.Lerp(start_colour.top_right, end_colour.top_right, action_progress)
                };
            }
        }