private Color4 GetColorFromParams(List<ColorParamInfo> param)
{
// Start off with a blank slate, black, fully transparent
Color4 res = new Color4(0, 0, 0, 0);
// Apply color modification from each color parameter
foreach (ColorParamInfo p in param)
{
int n = p.VisualColorParam.Colors.Length;
Color4 paramColor = new Color4(0, 0, 0, 0);
if (n == 1)
{
// We got only one color in this param, use it for application
// to the final color
paramColor = p.VisualColorParam.Colors[0];
}
else if (n > 1)
{
// We have an array of colors in this parameter
// First, we need to find out, based on param value
// between which two elements of the array our value lands
// Size of the step using which we iterate from Min to Max
float step = (p.VisualParam.MaxValue - p.VisualParam.MinValue) / ((float)n - 1);
// Our color should land inbetween colors in the array with index a and b
int indexa = 0;
int indexb = 0;
int i = 0;
for (float a = p.VisualParam.MinValue; a <= p.VisualParam.MaxValue; a += step)
{
if (a <= p.Value)
{
indexa = i;
}
else
{
break;
}
i++;
}
// Sanity check that we don't go outside bounds of the array
if (indexa > n - 1)
indexa = n - 1;
indexb = (indexa == n - 1) ? indexa : indexa + 1;
// How far is our value from Index A on the
// line from Index A to Index B
float distance = p.Value - (float)indexa * step;
// We are at Index A (allowing for some floating point math fuzz),
// use the color on that index
if (distance < 0.00001f || indexa == indexb)
{
paramColor = p.VisualColorParam.Colors[indexa];
}
else
{
// Not so simple as being precisely on the index eh? No problem.
// We take the two colors that our param value places us between
// and then find the value for each ARGB element that is
// somewhere on the line between color1 and color2 at some
// distance from the first color
Color4 c1 = paramColor = p.VisualColorParam.Colors[indexa];
Color4 c2 = paramColor = p.VisualColorParam.Colors[indexb];
// Distance is some fraction of the step, use that fraction
// to find the value in the range from color1 to color2
paramColor = Color4.Lerp(c1, c2, distance / step);
}
// Please leave this fragment even if its commented out
// might prove useful should ($deity forbid) there be bugs in this code
//string carray = "";
//foreach (Color c in p.VisualColorParam.Colors)
//{
// carray += c.ToString() + " - ";
//}
//Logger.DebugLog("Calculating color for " + p.WearableType + " from " + p.VisualParam.Name + ", value is " + p.Value + " in range " + p.VisualParam.MinValue + " - " + p.VisualParam.MaxValue + " step " + step + " with " + n + " elements " + carray + " A: " + indexa + " B: " + indexb + " at distance " + distance);
}
// Now that we have calculated color from the scale of colors
// that visual params provided, lets apply it to the result
switch (p.VisualColorParam.Operation)
{
case VisualColorOperation.Add:
res += paramColor;
break;
case VisualColorOperation.Multiply:
res *= paramColor;
break;
case VisualColorOperation.Blend:
res = Color4.Lerp(res, paramColor, p.Value);
break;
}
}
return res;
}