public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { GXLightMask mask = (GXLightMask)parameter; this.m_target = (GXLightMask)value; return((mask & this.m_target) != 0); }
private static string GenerateColorChannel(ColorChannelControl chan, int index, string output_name) { StringBuilder stream = new StringBuilder(); string matColorSource = chan.MaterialSrc == GXColorSrc.Vertex ? $"a_Color{ index }" : $"MaterialColors[{ index }]"; string ambColorSource = chan.AmbientSrc == GXColorSrc.Vertex ? $"a_Color{ index }" : $"AmbientColors[{ index }]"; string generateLightAccum = ""; if (chan.LightingEnabled) { generateLightAccum = $"\tt_LightAccum = { ambColorSource };\n"; generateLightAccum += "\n\t// Lighting calculations! Trig ahoy!\n\n"; for (int i = 0; i < 8; i++) { GXLightMask cur_mask = GXLightMask.Light0 + i; if (!chan.LitMask.HasFlag(cur_mask)) { continue; } string light_name = $"LightParams[{ i }]"; generateLightAccum += "\t// t_LightDelta is a vector pointing from the light to the vertex.\n"; generateLightAccum += "\t// Because the dot product of a vector with itself is the vector's length squared,\n"; generateLightAccum += "\t// we can square root the dot product to get the distance between the light and the vertex.\n"; generateLightAccum += $"\tt_LightDelta = { light_name }.Position.xyz - v_Position.xyz;\n"; generateLightAccum += "\tt_LightDeltaDist2 = dot(t_LightDelta, t_LightDelta);\n"; generateLightAccum += "\tt_LightDeltaDist = sqrt(t_LightDeltaDist2);\n\n"; generateLightAccum += "\t// Dividing a vector by its length normalizes it.\n"; generateLightAccum += "\t// Doing this with our difference vector gives us the direction of the vertex from the light, without the magnitude.\n"; generateLightAccum += "\tt_LightDeltaDir = t_LightDelta / t_LightDeltaDist;\n\n"; generateLightAccum += "\t// This is how much light is hitting the vertex - the cosine of the angle of incidence between the vertex and the light.\n"; generateLightAccum += $"\tdiffuse_coeff = { GetDiffFn(chan) };\n\n"; generateLightAccum += GenerateAttnFn(chan, light_name); generateLightAccum += "\t// The final color is the ambient color (the base or 'black') with the light's color added to it.\n"; generateLightAccum += "\t// But the color of the light is dampened by the angle at which the light is hitting our vertex (diffuse_coeff)\n"; generateLightAccum += "\t// and the ratio of the angle and distance attenuation behaviors (angle / dist).\n"; generateLightAccum += $"\tt_LightAccum += diffuse_coeff * (angle_attenuation / dist_attenuation) * { light_name }.Color;\n"; } } else { generateLightAccum = "\t// Lighting isn't being applied, so instead of calculating it we'll say the vertex is getting a full blast of white light.\n"; generateLightAccum += "\tt_LightAccum = vec4(1.0);"; } stream.AppendLine(generateLightAccum); stream.AppendLine($"\t{ output_name } = { matColorSource } * clamp(t_LightAccum, 0.0, 1.0);"); return(stream.ToString()); }
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { this.m_target ^= (GXLightMask)parameter; return(this.m_target); }