Files
ai-images/Source/AIImages/Services/ColorDescriptionService.cs

326 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Linq;
using RimWorld;
using UnityEngine;
using Verse;
namespace AIImages.Services
{
/// <summary>
/// Сервис для умного определения цветов (вместо RGB значений)
/// </summary>
public static class ColorDescriptionService
{
/// <summary>
/// Получает текстовое описание цвета волос
/// </summary>
public static string GetHairColorDescription(Color color)
{
float h,
s,
v;
Color.RGBToHSV(color, out h, out s, out v);
// Проверяем на оттенки серого
if (s < 0.15f)
{
return GetGrayscaleDescription(v);
}
// Определяем оттенок
string hueDescription = GetHueDescription(h);
string brightnessModifier = GetBrightnessModifier(v, s);
return $"{brightnessModifier}{hueDescription}".Trim();
}
/// <summary>
/// Получает текстовое описание цвета кожи, сначала проверяя гены, затем используя цвет как fallback
/// </summary>
public static string GetSkinToneDescription(Pawn pawn)
{
// Сначала проверяем гены цвета кожи
string geneSkinTone = GetSkinToneFromGenes(pawn);
if (!string.IsNullOrEmpty(geneSkinTone))
{
return geneSkinTone;
}
// Fallback к определению по цвету
return GetSkinToneDescription(pawn.story.SkinColor);
}
/// <summary>
/// Получает текстовое описание цвета кожи по RGB цвету (fallback метод)
/// </summary>
public static string GetSkinToneDescription(Color color)
{
// Вычисляем яркость
float brightness = (color.r + color.g + color.b) / 3f;
// Определяем оттенок кожи
if (brightness >= 0.85f)
return "very fair skin";
else if (brightness >= 0.75f)
return "fair skin";
else if (brightness >= 0.65f)
return "light skin";
else if (brightness >= 0.55f)
return "medium skin";
else if (brightness >= 0.45f)
return "olive skin";
else if (brightness >= 0.35f)
return "tan skin";
else if (brightness >= 0.25f)
return "brown skin";
else if (brightness >= 0.15f)
return "dark brown skin";
else
return "very dark skin";
}
/// <summary>
/// Получает текстовое описание цвета кожи по генам
/// </summary>
public static string GetSkinToneFromGenes(Pawn pawn)
{
if (pawn?.genes?.GenesListForReading == null)
return null;
// Ищем активные гены цвета кожи
var skinColorGenes = pawn
.genes.GenesListForReading.Where(gene =>
gene.Active && IsSkinColorGene(gene.def.defName)
)
.ToList();
if (!skinColorGenes.Any())
return null;
// Берем первый найденный ген (обычно у персонажа один ген цвета кожи)
var skinGene = skinColorGenes[0];
return GetSkinToneDescriptionFromGene(skinGene.def.defName);
}
/// <summary>
/// Проверяет, является ли ген геном цвета кожи
/// </summary>
private static bool IsSkinColorGene(string geneDefName)
{
return geneDefName.StartsWith("Skin_")
|| geneDefName.Contains("SkinColor")
|| geneDefName.Contains("SkinTone");
}
/// <summary>
/// Получает описание цвета кожи по названию гена
/// </summary>
private static string GetSkinToneDescriptionFromGene(string geneDefName)
{
// Проверяем стандартные гены
string standardGene = GetStandardGeneSkinTone(geneDefName);
if (!string.IsNullOrEmpty(standardGene))
return standardGene;
// Проверяем дополнительные гены
string additionalGene = GetAdditionalGeneSkinTone(geneDefName);
if (!string.IsNullOrEmpty(additionalGene))
return additionalGene;
// Пытаемся извлечь информацию из названия
return ExtractSkinToneFromGeneName(geneDefName);
}
/// <summary>
/// Получает описание для стандартных генов цвета кожи
/// </summary>
private static string GetStandardGeneSkinTone(string geneDefName)
{
switch (geneDefName)
{
case "Skin_InkBlack":
return "ink black skin";
case "Skin_SlateGray":
return "slate gray skin";
case "Skin_LightGray":
return "light gray skin";
case "Skin_SheerWhite":
return "sheer white skin";
case "Skin_Blue":
return "blue skin";
case "Skin_Purple":
return "purple skin";
case "Skin_PaleRed":
return "pale red skin";
case "Skin_DeepRed":
return "deep red skin";
case "Skin_PaleYellow":
return "pale yellow skin";
case "Skin_DeepYellow":
return "deep yellow skin";
case "Skin_Orange":
return "orange skin";
case "Skin_Green":
return "green skin";
default:
return null;
}
}
/// <summary>
/// Получает описание для дополнительных генов цвета кожи
/// </summary>
private static string GetAdditionalGeneSkinTone(string geneDefName)
{
switch (geneDefName)
{
case "Skin_Dark":
return "dark skin";
case "Skin_Light":
return "light skin";
case "Skin_Medium":
return "medium skin";
case "Skin_Fair":
return "fair skin";
case "Skin_Tan":
return "tan skin";
case "Skin_Olive":
return "olive skin";
case "Skin_Brown":
return "brown skin";
default:
return null;
}
}
/// <summary>
/// Извлекает описание цвета кожи из названия гена
/// </summary>
private static string ExtractSkinToneFromGeneName(string geneDefName)
{
if (geneDefName.Contains("Black"))
return "black skin";
if (geneDefName.Contains("White"))
return "white skin";
if (geneDefName.Contains("Gray") || geneDefName.Contains("Grey"))
return "gray skin";
if (geneDefName.Contains("Blue"))
return "blue skin";
if (geneDefName.Contains("Red"))
return "red skin";
if (geneDefName.Contains("Green"))
return "green skin";
if (geneDefName.Contains("Yellow"))
return "yellow skin";
if (geneDefName.Contains("Purple"))
return "purple skin";
if (geneDefName.Contains("Orange"))
return "orange skin";
return null; // Неизвестный ген
}
/// <summary>
/// Получает описание цвета одежды
/// </summary>
public static string GetApparelColorDescription(Color color)
{
float h,
s,
v;
Color.RGBToHSV(color, out h, out s, out v);
// Проверяем на оттенки серого
if (s < 0.1f)
{
return GetGrayscaleDescription(v);
}
// Определяем оттенок
string hueDescription = GetHueDescription(h);
// Модификаторы насыщенности и яркости
string saturationModifier = "";
if (s < 0.3f)
saturationModifier = "pale ";
else if (s > 0.8f)
saturationModifier = "vivid ";
string brightnessModifier = "";
if (v < 0.3f)
brightnessModifier = "dark ";
else if (v > 0.8f)
brightnessModifier = "bright ";
return $"{brightnessModifier}{saturationModifier}{hueDescription}".Trim();
}
private static string GetGrayscaleDescription(float value)
{
if (value >= 0.95f)
return "white";
else if (value >= 0.8f)
return "light gray";
else if (value >= 0.6f)
return "gray";
else if (value >= 0.4f)
return "dark gray";
else if (value >= 0.2f)
return "charcoal";
else
return "black";
}
private static string GetHueDescription(float hue)
{
// Hue from 0 to 1
if (hue < 0.05f || hue >= 0.95f)
return "red";
if (hue < 0.083f)
return "orange-red";
if (hue < 0.15f)
return "orange";
if (hue < 0.19f)
return "golden";
if (hue < 0.22f)
return "yellow";
if (hue < 0.35f)
return "yellow-green";
if (hue < 0.45f)
return "green";
if (hue < 0.52f)
return "cyan";
if (hue < 0.58f)
return "light blue";
if (hue < 0.65f)
return "blue";
if (hue < 0.72f)
return "deep blue";
if (hue < 0.78f)
return "purple";
if (hue < 0.85f)
return "violet";
if (hue < 0.92f)
return "magenta";
return "pink";
}
private static string GetBrightnessModifier(float value, float saturation)
{
// Для волос используем специальные термины
if (value < 0.2f)
return "jet black ";
else if (value < 0.3f)
return "black ";
else if (value < 0.45f)
return "dark ";
else if (value > 0.85f && saturation < 0.3f)
return "platinum ";
else if (value > 0.75f)
return "light ";
else
return "";
}
}
}