diff --git a/data/gui.xml b/data/gui.xml
index 19d5de131..bd0b977a6 100644
--- a/data/gui.xml
+++ b/data/gui.xml
@@ -925,6 +925,9 @@
-
+ -
+
+
diff --git a/src/app/commands/cmd_set_color_selector.cpp b/src/app/commands/cmd_set_color_selector.cpp
index 1638c592d..a97912c60 100644
--- a/src/app/commands/cmd_set_color_selector.cpp
+++ b/src/app/commands/cmd_set_color_selector.cpp
@@ -55,6 +55,9 @@ void SetColorSelectorCommand::onLoadParams(const Params& params)
else if (type == "ryb-wheel") {
m_type = ColorBar::ColorSelector::RYB_WHEEL;
}
+ else if (type == "normal-map-wheel") {
+ m_type = ColorBar::ColorSelector::NORMAL_MAP_WHEEL;
+ }
}
bool SetColorSelectorCommand::onChecked(Context* context)
@@ -84,6 +87,9 @@ std::string SetColorSelectorCommand::onGetFriendlyName() const
case ColorBar::ColorSelector::RYB_WHEEL:
result += "RYB Color Wheel";
break;
+ case ColorBar::ColorSelector::NORMAL_MAP_WHEEL:
+ result += "Normal Map Color Wheel";
+ break;
default:
result += "Unknown";
break;
diff --git a/src/app/ui/color_bar.cpp b/src/app/ui/color_bar.cpp
index 422d02fb9..a53ea4c7e 100644
--- a/src/app/ui/color_bar.cpp
+++ b/src/app/ui/color_bar.cpp
@@ -341,6 +341,7 @@ void ColorBar::setColorSelector(ColorSelector selector)
case ColorSelector::RGB_WHEEL:
case ColorSelector::RYB_WHEEL:
+ case ColorSelector::NORMAL_MAP_WHEEL:
if (!m_wheel) {
m_wheel = new ColorWheel;
m_wheel->setExpansive(true);
@@ -348,10 +349,15 @@ void ColorBar::setColorSelector(ColorSelector selector)
m_wheel->ColorChange.connect(&ColorBar::onPickSpectrum, this);
m_selectorPlaceholder.addChild(m_wheel);
}
- m_wheel->setColorModel(
- (m_selector == ColorSelector::RGB_WHEEL ?
- ColorWheel::ColorModel::RGB:
- ColorWheel::ColorModel::RYB));
+ if (m_selector == ColorSelector::RGB_WHEEL) {
+ m_wheel->setColorModel(ColorWheel::ColorModel::RGB);
+ }
+ else if (m_selector == ColorSelector::RYB_WHEEL) {
+ m_wheel->setColorModel(ColorWheel::ColorModel::RYB);
+ }
+ else if (m_selector == ColorSelector::NORMAL_MAP_WHEEL) {
+ m_wheel->setColorModel(ColorWheel::ColorModel::NORMAL_MAP);
+ }
m_wheel->setVisible(true);
break;
diff --git a/src/app/ui/color_bar.h b/src/app/ui/color_bar.h
index 2b439107a..5c68bdf5f 100644
--- a/src/app/ui/color_bar.h
+++ b/src/app/ui/color_bar.h
@@ -50,6 +50,7 @@ namespace app {
SPECTRUM,
RGB_WHEEL,
RYB_WHEEL,
+ NORMAL_MAP_WHEEL,
TINT_SHADE_TONE,
};
diff --git a/src/app/ui/color_wheel.cpp b/src/app/ui/color_wheel.cpp
index bde5ab16c..d37c28965 100644
--- a/src/app/ui/color_wheel.cpp
+++ b/src/app/ui/color_wheel.cpp
@@ -84,6 +84,22 @@ app::Color ColorWheel::getColorInClientPos(const gfx::Point& pos)
int v = (pos.y - (m_wheelBounds.y+m_wheelBounds.h/2));
double d = std::sqrt(u*u + v*v);
+ if (m_colorModel == ColorModel::NORMAL_MAP) {
+ float x = float(u) / float(m_wheelBounds.w / 2);
+ float y = -float(v) / float(m_wheelBounds.h / 2);
+ float z = std::sqrt(1 - x*x - y*y);
+ if (z <= 1.f) {
+ return app::Color::fromRgb(
+ int(std::round((x + 1) * 127.5)),
+ int(std::round((y + 1) * 127.5)),
+ int(std::round((z + 1) * 127.5))
+ );
+ }
+ else {
+ return app::Color::fromRgb(128, 128, 255);
+ }
+ }
+
// Pick from the wheel
if (d < m_wheelRadius+2*guiscale()) {
double a = std::atan2(-v, u);
@@ -231,7 +247,7 @@ void ColorWheel::onPaint(ui::PaintEvent& ev)
}
}
- if (m_color.getAlpha() > 0) {
+ if (m_color.getAlpha() > 0 && m_colorModel != ColorModel::NORMAL_MAP) {
int n = getHarmonies();
int boxsize = MIN(rc.w/10, rc.h/10);
@@ -336,16 +352,32 @@ void ColorWheel::onOptions()
menu.addChild(&tetradic);
menu.addChild(&square);
- if (isDiscrete()) discrete.setSelected(true);
- switch (m_harmony) {
- case Harmony::NONE: none.setSelected(true); break;
- case Harmony::COMPLEMENTARY: complementary.setSelected(true); break;
- case Harmony::MONOCHROMATIC: monochromatic.setSelected(true); break;
- case Harmony::ANALOGOUS: analogous.setSelected(true); break;
- case Harmony::SPLIT: split.setSelected(true); break;
- case Harmony::TRIADIC: triadic.setSelected(true); break;
- case Harmony::TETRADIC: tetradic.setSelected(true); break;
- case Harmony::SQUARE: square.setSelected(true); break;
+ if (m_colorModel == ColorModel::NORMAL_MAP) {
+ discrete.setSelected(false);
+ discrete.setEnabled(false);
+
+ none.setSelected(true);
+ none.setEnabled(false);
+ complementary.setEnabled(false);
+ monochromatic.setEnabled(false);
+ analogous.setEnabled(false);
+ split.setEnabled(false);
+ triadic.setEnabled(false);
+ tetradic.setEnabled(false);
+ square.setEnabled(false);
+ }
+ else {
+ if (isDiscrete()) discrete.setSelected(true);
+ switch (m_harmony) {
+ case Harmony::NONE: none.setSelected(true); break;
+ case Harmony::COMPLEMENTARY: complementary.setSelected(true); break;
+ case Harmony::MONOCHROMATIC: monochromatic.setSelected(true); break;
+ case Harmony::ANALOGOUS: analogous.setSelected(true); break;
+ case Harmony::SPLIT: split.setSelected(true); break;
+ case Harmony::TRIADIC: triadic.setSelected(true); break;
+ case Harmony::TETRADIC: tetradic.setSelected(true); break;
+ case Harmony::SQUARE: square.setSelected(true); break;
+ }
}
discrete.Click.connect(base::Bind(&ColorWheel::setDiscrete, this, !isDiscrete()));
diff --git a/src/app/ui/color_wheel.h b/src/app/ui/color_wheel.h
index 5f586b78c..9b157af6c 100644
--- a/src/app/ui/color_wheel.h
+++ b/src/app/ui/color_wheel.h
@@ -18,6 +18,7 @@ namespace app {
enum class ColorModel {
RGB,
RYB,
+ NORMAL_MAP,
};
enum class Harmony {