class ColorValuesData : Managed
{
protected ref array<float> m_Values;
protected int m_Operator;
void ColorValuesData(array<float> values, int operator)
{
m_Values = new array<float>;
m_Values.Copy(values);
m_Operator = operator;
}
void SetValues(array<float> values)
{
m_Values.Copy(values);
}
array<float> GetValues()
{
return m_Values;
}
void SetOperator(int operator)
{
m_Operator = operator;
}
int GetOperator()
{
return m_Operator;
}
}
class PPEMatClassParameterColor extends PPEMatClassParameterCommandData
{
const int VALUE_RED = 0;
const int VALUE_GREEN = 1;
const int VALUE_BLUE = 2;
const int VALUE_ALPHA = 3;
const int VALUES_COUNT = 4; //rgba
protected PPETemplateDefColor m_Color;
protected ref map<int,ref ColorValuesData> m_LayerInfo; //<priority,<<values>,operator>>
float m_ColorDefaults[4];
void PPEMatClassParameterColor(int mat_idx, int parameter_idx, PPEClassBase parent)
{
m_LayerInfo = new map<int,ref ColorValuesData>;
}
override void InitDefaults()
{
m_Color = PPETemplateDefColor.Cast(m_Defaults);
m_ColorDefaults = {m_Color.param2,m_Color.param3,m_Color.param4,m_Color.param5};
}
override void InitCuttent()
{
m_CurrentValues = new Param4<float,float,float,float>(m_ColorDefaults[0],m_ColorDefaults[1],m_ColorDefaults[2],m_ColorDefaults[3]);
}
override int GetParameterVarType()
{
return PPEConstants.VAR_TYPE_COLOR;
}
override void Update(float timeslice, out Param p_total, out bool setting_defaults, int order)
{
super.Update(timeslice,p_total,setting_defaults,order);
int active_request_count = 0;
PPERequestParamDataColor req_data;
bool setting_value_zero = false;
array<float> color_values_total = {0.0,0.0,0.0,0.0};
array<float> color_values_temp = {0.0,0.0,0.0,0.0};
bool color_total_override_set = false;
// param creation
if (p_total == null)
{
p_total = new Param4<float,float,float,float>(0.0,0.0,0.0,0.0);
}
if (m_RequestMap.Count() > 0)
{
m_LayerInfo.Clear();
}
else
{
//DbgPrnt("m_RequestMap.Count() is zero! Using default values. | mat/par: " + m_MaterialIndex + "/" + m_ParameterIndex);
SetParameterValueDefault(p_total); //TODO - redundant?
m_Parent.ParamUpdateRemove(m_ParameterIndex);
return;
}
//get target values, evaluate active and priority conditions, and insert into arrays to later process
for ( int i = 0; i < m_RequestMap.Count(); i++ )
{
req_data = PPERequestParamDataColor.Cast(m_RequestMap.GetElement(i));
if (req_data == null)
{
Error("PPEMatClassParameterColor | req_data not found! | " + this + " | mat/par: " + m_MaterialIndex + "/" + m_ParameterIndex);
continue;
}
setting_value_zero = req_data.IsSettingDefaultValues();
//skips "zero value" defaults
if (setting_value_zero && !req_data.GetUpdatingDataValues() && !req_data.IsDataActive())
{
//DbgPrnt("Is Default, not updating | idx: " + i + " | mat/par/req: " + m_MaterialIndex + "/" + m_ParameterIndex + "/" + req_data.GetRequesterIDX());
continue;
}
active_request_count++; //something is active, though not necessarily setting new values
//evaluation
//--------------------------------
req_data.m_ColorLast = req_data.m_ColorCurrent;
if (!req_data.GetUpdatingDataValues() && req_data.IsDataActive()) //set to exact value, not updating anymore
{
color_values_temp.Copy(req_data.m_ColorCurrent); //already converted from before?
PrepareLayerInfo(req_data.GetPriorityLayer(),{color_values_temp[0],color_values_temp[1],color_values_temp[2],color_values_temp[3]},req_data.GetInteractionMask());
//DbgPrnt("PPEDebug | PPEMatClassParameterColor - UpdateParameterValues | !req_data.m_UpdatingData | mat/par/req: " + m_MaterialIndex + "/" + m_ParameterIndex + "/" + req_data.GetRequesterIDX() + " | not updating, addaing current values into mix: " + req_data.m_ColorCurrent[0] + "," + req_data.m_ColorCurrent[1] + "," + req_data.m_ColorCurrent[2] + "," + req_data.m_ColorCurrent[3]);
continue;
}
if (setting_value_zero)
{
req_data.m_ColorTarget = {0.0,0.0,0.0,0.0}; //color_defaults;
//DbgPrnt("PPEDebug | PPEMatClassParameterColor - UpdateParameterValues | !data.m_DefaultTargetSet | mat/par/req: " + m_MaterialIndex + "/" + m_ParameterIndex + "/" + req_data.GetRequesterIDX() + " | req_data.m_FloatTarget: " + req_data.m_FloatTarget);
}
//DbgPrnt("PPEDebug | PPEMatClassParameterColor - UpdateParameterValues | mat/par/req: " + m_MaterialIndex + "/" + m_ParameterIndex + "/" + req_data.GetRequesterIDX());
req_data.SetUpdatingDataValues(false);
if (setting_value_zero)
{
req_data.SetDataActive(false);
//RemovePriorityInfo(req_data.GetPriorityLayer()); //redundant?
}
else
{
color_values_temp.Copy(req_data.m_ColorTarget);
PrepareLayerInfo(req_data.GetPriorityLayer(),{color_values_temp[0],color_values_temp[1],color_values_temp[2],color_values_temp[3]},req_data.GetInteractionMask());
}
req_data.m_ColorCurrent.Copy(color_values_temp);
//DbgPrnt("PPEDebug | PPEMatClassParameterColor - UpdateParameterValues | current: " + req_data.m_ColorCurrent);
}
//---------------------------
//MASK handling and calculation
array<float> values;
int operator = -1;
bool override_active = false;
color_values_total = {m_ColorDefaults[0],m_ColorDefaults[1],m_ColorDefaults[2],m_ColorDefaults[3]};
for ( i = 0; i < m_LayerInfo.Count(); i++ )
{
if ( override_active )
break;
values = m_LayerInfo.Get(m_CommandLayersArray.Get(i)).GetValues();
operator = m_LayerInfo.Get(m_CommandLayersArray.Get(i)).GetOperator();
switch (operator)
{
case PPOperators.LOWEST:
color_values_total[VALUE_RED] = Math.Min(color_values_total[VALUE_RED], values[VALUE_RED]);
color_values_total[VALUE_GREEN] = Math.Min(color_values_total[VALUE_GREEN], values[VALUE_GREEN]);
color_values_total[VALUE_BLUE] = Math.Min(color_values_total[VALUE_BLUE], values[VALUE_BLUE]);
color_values_total[VALUE_ALPHA] = Math.Min(color_values_total[VALUE_ALPHA], values[VALUE_ALPHA]);
break;
case PPOperators.HIGHEST:
color_values_total[VALUE_RED] = Math.Max(color_values_total[VALUE_RED], values[VALUE_RED]);
color_values_total[VALUE_GREEN] = Math.Max(color_values_total[VALUE_GREEN], values[VALUE_GREEN]);
color_values_total[VALUE_BLUE] = Math.Max(color_values_total[VALUE_BLUE], values[VALUE_BLUE]);
color_values_total[VALUE_ALPHA] = Math.Max(color_values_total[VALUE_ALPHA], values[VALUE_ALPHA]);
break;
case PPOperators.ADD_RELATIVE:
case PPOperators.ADD:
color_values_total[VALUE_RED] = color_values_total[VALUE_RED] + values[VALUE_RED];
color_values_total[VALUE_GREEN] = color_values_total[VALUE_GREEN] + values[VALUE_GREEN];
color_values_total[VALUE_BLUE] = color_values_total[VALUE_BLUE] + values[VALUE_BLUE];
color_values_total[VALUE_ALPHA] = color_values_total[VALUE_ALPHA] + values[VALUE_ALPHA];
break;
/*case PPOperators.ADD_RELATIVE: //no known max values, unusable!
float_value_total = (1 - float_value_total) * value + float_value_total;
break;*/
case PPOperators.SUBSTRACT_RELATIVE:
case PPOperators.SUBSTRACT:
color_values_total[VALUE_RED] = color_values_total[VALUE_RED] - values[VALUE_RED];
color_values_total[VALUE_GREEN] = color_values_total[VALUE_GREEN] - values[VALUE_GREEN];
color_values_total[VALUE_BLUE] = color_values_total[VALUE_BLUE] - values[VALUE_BLUE];
color_values_total[VALUE_ALPHA] = color_values_total[VALUE_ALPHA] - values[VALUE_ALPHA];
break;
/*case PPOperators.SUBSTRACT_RELATIVE: //no known max values, unusable!
float_value_total = float_value_total - value * float_value_total;
break;*/
case PPOperators.SUBSTRACT_REVERSE_RELATIVE:
case PPOperators.SUBSTRACT_REVERSE:
color_values_total[VALUE_RED] = values[VALUE_RED] - color_values_total[VALUE_RED];
color_values_total[VALUE_GREEN] = values[VALUE_GREEN] - color_values_total[VALUE_GREEN];
color_values_total[VALUE_BLUE] = values[VALUE_BLUE] - color_values_total[VALUE_BLUE];
color_values_total[VALUE_ALPHA] = values[VALUE_ALPHA] - color_values_total[VALUE_ALPHA];
break;
/*case PPOperators.SUBSTRACT_REVERSE_RELATIVE: //no known max values, unusable!
float_value_total = value * float_value_total - float_value_total;
break;*/
case PPOperators.MULTIPLICATIVE:
color_values_total[VALUE_RED] = color_values_total[VALUE_RED] * values[VALUE_RED];
color_values_total[VALUE_GREEN] = color_values_total[VALUE_GREEN] * values[VALUE_GREEN];
color_values_total[VALUE_BLUE] = color_values_total[VALUE_BLUE] * values[VALUE_BLUE];
color_values_total[VALUE_ALPHA] = color_values_total[VALUE_ALPHA] * values[VALUE_ALPHA];
break;
case PPOperators.OVERRIDE:
color_values_total.Copy(values);
break;
case PPOperators.SET:
color_values_total.Copy(values);
break;
}
//DbgPrnt("m_LayerInfo | color_values_total pre-clamp: " + color_values_total[VALUE_RED] + "/" + color_values_total[VALUE_GREEN] + "/" + color_values_total[VALUE_BLUE] + "/" + color_values_total[VALUE_ALPHA] + " | i: " + i);
if ( operator == PPOperators.OVERRIDE )
{
//DbgPrnt("m_LayerInfo | PPOperators.OVERRIDE at: " + i);
override_active = true;
}
//RemovePriorityInfo(m_CommandLayersArray.Get(i));
}
m_CommandLayersArray.Clear();
if ( m_MaterialIndex == 15 && m_ParameterIndex == 21 )
{
//Print("m_MaterialIndex: " + m_MaterialIndex + "|m_ParameterIndex: " + m_ParameterIndex);
//Print("PPEMatClassParameterColor values: " + color_values_total[0] + " " + color_values_total[1] + " " + color_values_total[2] + " " + color_values_total[3]);
}
//TODO - consider moving this up, if possible
if ( active_request_count <= 0 )
{
SetParameterValueDefault(p_total);
}
else
{
Param4<float,float,float,float>.Cast(p_total).param1 = color_values_total[0];
Param4<float,float,float,float>.Cast(p_total).param2 = color_values_total[1];
Param4<float,float,float,float>.Cast(p_total).param3 = color_values_total[2];
Param4<float,float,float,float>.Cast(p_total).param4 = color_values_total[3];
}
//DbgPrnt("PPEDebug | PPEMatClassParameterColor - UpdateParameterValues | mat/par/req: " + m_MaterialIndex + "/" + m_ParameterIndex + "/" + req_data.GetRequesterIDX() + " | parameter update end, removing from queue");
m_Parent.ParamUpdateRemove(m_ParameterIndex);
ModifyResultValues(p_total);
m_CurrentValues = p_total;
}
//! Fills relative values into arrays/member variables
void PrepareLayerInfo(int layer, array<float> values, int operator)
{
ColorValuesData tmp;
if (m_LayerInfo.Contains(layer))
{
tmp = m_LayerInfo.Get(layer);
tmp.SetValues(values);
tmp.SetOperator(operator);
}
else
{
tmp = new ColorValuesData(values,operator);
}
m_LayerInfo.Set(layer,tmp);
AddPriorityInfo(layer);
}
override void SetParameterValueDefault(inout Param p_total)
{
if (!p_total)
{
p_total = new Param4<float,float,float,float>(m_ColorDefaults[0],m_ColorDefaults[1],m_ColorDefaults[2],m_ColorDefaults[3]);
}
else
{
Param4<float,float,float,float>.Cast(p_total).param1 = m_ColorDefaults[0];
Param4<float,float,float,float>.Cast(p_total).param2 = m_ColorDefaults[1];
Param4<float,float,float,float>.Cast(p_total).param3 = m_ColorDefaults[2];
Param4<float,float,float,float>.Cast(p_total).param4 = m_ColorDefaults[3];
}
m_CurrentValues = p_total;
}
}
class PPEMatClassParameterColorColorization extends PPEMatClassParameterColor
{
override void ModifyResultValues(inout Param result_values)
{
super.ModifyResultValues(result_values);
//saturation-dependency handling
Param par = PPEManagerStatic.GetPPEManager().GetPostProcessCurrentValues(PostProcessEffectType.Glow,PPEGlow.PARAM_SATURATION);
float saturation_coef = Param1<float>.Cast(par).param1;
float r = Param4<float,float,float,float>.Cast(result_values).param1;
float g = Param4<float,float,float,float>.Cast(result_values).param2;
float b = Param4<float,float,float,float>.Cast(result_values).param3;
float a = Param4<float,float,float,float>.Cast(result_values).param4;
float highest_channel = Math.Max(Math.Max(r,g),b);
saturation_coef = Easing.EaseOutSine(saturation_coef);
r = Math.Lerp(highest_channel,r,saturation_coef);
g = Math.Lerp(highest_channel,g,saturation_coef);
b = Math.Lerp(highest_channel,b,saturation_coef);
a = Math.Lerp(m_ColorDefaults[3],a,saturation_coef);
//
Param4<float,float,float,float>.Cast(result_values).param1 = r;
Param4<float,float,float,float>.Cast(result_values).param2 = g;
Param4<float,float,float,float>.Cast(result_values).param3 = b;
Param4<float,float,float,float>.Cast(result_values).param4 = a;
}
}