/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Benjamin Grauer co-programmer: ... */ //#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ #include "color.h" #include //! Red Color const Color Color::red(1,0,0, 1); //! Green Color const Color Color::green(0,1,0, 1) ; //! blue Color const Color Color::blue(0,0,1, 1); //! White Color const Color Color::white(1,1,1, 1); //! Black Color const Color Color::black(0,0,0,1); /** * @brief slerps the Color in the HSV color space into the direction of c * @param c the Color to slerp to * @param v the Value to slerp 0 means stay at *this, 1 means at c. */ void Color::slerpHSV(const Color& c, float v) { this->a() += (c.a() - this->a()) * v; Vector from(r(), g(), b()); Vector to(c.r(), c.g(), c.b()); from = RGBtoHSV(from); to = RGBtoHSV(to); from += (to - from) * v; to = HSVtoRGB(from); this->r() = to.x; this->g() = to.y; this->b() = to.z; } /** * @brief simple slerp wrapper. * @param from from this color * @param to to this one * @param v how much * @see void Color::slerpHSV(const Color& c, float v) */ Color Color::slerpHSVColor(const Color& from, const Color& to, float v) { Color fromColor(from); fromColor.slerpHSV(to, v); return fromColor; } /** * @brief nice and simple debug output for the colors (colorless :) ) */ void Color::debug() const { printf("r:%0.2f g:%0.2f, b:%0.2f, a:%0.2f\n", r(), g(), b(), a()); } /** * @brief transforms from RGB to HSVtoRGB * @param RGB: the RGB-color [0-1] * @returns HSV: with values (h[0-360(degree)],s[0,1],v[0,1]) */ Vector Color::RGBtoHSV(const Vector& RGB) { Vector HSV; RGBtoHSV(RGB, HSV); return HSV; } /** * @brief transforms from RGB to HSVtoRGB * @param RGB: the RGB-color [0-1] * @param HSV: with values (h[0-360(degree)],s[0,1],v[0,1]) */ void Color::RGBtoHSV(const Vector& RGB, Vector& HSV) { float r = RGB.x; float g = RGB.y; float b = RGB.z; float h=0,s=1.0,v=1.0; float max_v,min_v,diff,r_dist,g_dist,b_dist; float undefined = 0.0; max_v = maxrgb(r,g,b); min_v = minrgb(r,g,b); diff = max_v - min_v; v = max_v; if( max_v != 0 ) s = diff/max_v; else s = 0.0; if( s == 0 ) h = undefined; else { r_dist = (max_v - r)/diff; g_dist = (max_v - g)/diff; b_dist = (max_v - b)/diff; if( r == max_v ) h = b_dist - g_dist; else if( g == max_v ) h = 2 + r_dist - b_dist; else if( b == max_v ) h = 4 + g_dist - r_dist; else printf("rgb2hsv::How did I get here?\n"); h *= 60.; if( h < 0) h += 360.0; } HSV = Vector(h, s, v); } /** * @brief converts a Color from HSV to RGBtoHSV * @param HSV: Vector with values (h[0-360(degree)],s[0,1],v[0,1]) * @returns RGB: Vector [0-1] */ Vector Color::HSVtoRGB(const Vector& HSV) { Vector RGB; HSVtoRGB(HSV, RGB); return RGB; } /** * @brief converts a Color from HSV to RGBtoHSV * @param HSV: Vector with values (h[0-360(degree)],s[0,1],v[0,1]) * @param RGB: Vector [0-1] */ void Color::HSVtoRGB(const Vector& HSV, Vector& RGB) { float h = HSV.x; float s = HSV.y; float v = HSV.z; float r=0, g=0, b=0; float f,p,q,t; int i; if( s == 0 ) { r = v; g = v; b = v; } else { if(h >= 360.) h = h - (float)((int)(ceilf(h) / 360.0)); h /= 60.; i = (int) h; f = h - i; p = v*(1-s); q = v*(1-(s*f)); t = v*(1-s*(1-f)); switch(i) { case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; case 5: r = v; g = p; b = q; break; default: r = 1.0; g = 1.0; b = 1.0; //printf("hsv2rgb::How did I get here?\n"); // printf("h: %f, s: %f, v: %f; i: %d\n",hin,s,v,i); break; } } RGB = Vector(r,g,b); } /** * @returns the maximum of r g and a. * @param r Red. * @param g Green * @param b Blue */ float Color::maxrgb(float r, float g, float b) { float max; if( r > g) max = r; else max = g; if( b > max ) max = b; return( max ); } /** * @returns the minimum of r g and a. * @param r Red. * @param g Green * @param b Blue */ float Color::minrgb(float r,float g,float b) { float min; if( r < g) min = r; else min = g; if( b < min ) min = b; return( min ); }