Blame c++/perspective/src/common.h

Ivan Mahonin 531f67
#ifndef COMMON_H
Ivan Mahonin 531f67
#define COMMON_H
Ivan Mahonin 531f67
Ivan Mahonin fdabb2
Ivan Mahonin 531f67
#include <cmath>
Ivan Mahonin 531f67
#include <cstdlib>
Ivan Mahonin 0662a2
#include <algorithm>
Ivan Mahonin 531f67
Ivan Mahonin fdabb2
#include <glibmm/refptr.h>
Ivan Mahonin fdabb2
Ivan Mahonin 531f67
Ivan Mahonin 531f67
typedef float ColorReal;
Ivan Mahonin 531f67
typedef double Real;
Ivan Mahonin 531f67
typedef int Int;
Ivan Mahonin 531f67
typedef unsigned int UInt;
Ivan Mahonin 531f67
typedef long long int LongInt;
Ivan Mahonin 531f67
typedef unsigned long long int ULongInt;
Ivan Mahonin 531f67
Ivan Mahonin fdabb2
using Glib::RefPtr;
Ivan Mahonin fdabb2
Ivan Mahonin 531f67
Ivan Mahonin fdabb2
const Real real_precision = 1e-10;
Ivan Mahonin 5f2fc2
const Real real_precision_sqr = real_precision * real_precision;
Ivan Mahonin 531f67
Ivan Mahonin 531f67
Ivan Mahonin 531f67
class Shared {
Ivan Mahonin 531f67
private:
Ivan Mahonin 531f67
	int ref_count;
Ivan Mahonin 531f67
public:
Ivan Mahonin fdabb2
	Shared(): ref_count(1) { }
Ivan Mahonin fdabb2
	Shared(const Shared&): ref_count(1) { }
Ivan Mahonin 531f67
	virtual ~Shared() { };
Ivan Mahonin 531f67
	
Ivan Mahonin 531f67
	inline Shared& operator=(const Shared&) { return *this; }
Ivan Mahonin fdabb2
	inline void reference() {
Ivan Mahonin fdabb2
		++ref_count;
Ivan Mahonin fdabb2
	}
Ivan Mahonin fdabb2
	inline void unreference() {
Ivan Mahonin fdabb2
		if (--ref_count <= 0)
Ivan Mahonin fdabb2
			delete this;
Ivan Mahonin fdabb2
	}
Ivan Mahonin 531f67
};
Ivan Mahonin 531f67
Ivan Mahonin 531f67
Ivan Mahonin 531f67
class Color {
Ivan Mahonin 531f67
public:
Ivan Mahonin 531f67
	typedef ColorReal Channel;
Ivan Mahonin 531f67
	union {
Ivan Mahonin 531f67
		struct { Channel channels[4]; };
Ivan Mahonin 531f67
		struct { Channel r, g, b, a; };
Ivan Mahonin 531f67
	};
Ivan Mahonin 531f67
	
Ivan Mahonin 531f67
	inline explicit Color(Channel r = 0.0, Channel g = 0.0, Channel b = 0.0, Channel a = 0.0):
Ivan Mahonin 531f67
		r(r), g(g), b(b), a(a) { }
Ivan Mahonin 4dc49c
	
Ivan Mahonin 4dc49c
	inline Color operator+ (const Color &other) const
Ivan Mahonin 4dc49c
		{ return Color(r + other.r, g + other.g, b + other.b, a + other.a); }
Ivan Mahonin 4dc49c
	inline Color operator- (const Color &other) const
Ivan Mahonin 4dc49c
		{ return Color(r - other.r, g - other.g, b - other.b, a - other.a); }
Ivan Mahonin 4dc49c
	inline Color operator* (Channel k) const
Ivan Mahonin 4dc49c
		{ return Color(r*k, g*k, b*k, a*k); }
Ivan Mahonin 4dc49c
	
Ivan Mahonin 4dc49c
	inline Color& operator+= (const Color &other)
Ivan Mahonin 4dc49c
		{ r += other.r, g += other.g, b += other.b, a += other.a; return *this; }
Ivan Mahonin 4dc49c
	inline Color& operator-= (const Color &other)
Ivan Mahonin 4dc49c
		{ r -= other.r, g -= other.g, b -= other.b, a -= other.a; return *this; }
Ivan Mahonin 4dc49c
	inline Color& operator*= (Channel k)
Ivan Mahonin 4dc49c
		{ r *= k, g *= k, b *= k, a *= k; return *this; }
Ivan Mahonin 4dc49c
	
Ivan Mahonin 4dc49c
	inline Color get_mult_alpha() const
Ivan Mahonin 4dc49c
		{ return Color(r*a, g*a, b*a, a); }
Ivan Mahonin 4dc49c
	inline Color get_demult_alpha() const  {
Ivan Mahonin 4dc49c
		if (fabs(a) < real_precision) return *this;
Ivan Mahonin 4dc49c
		Channel k = 1/a;
Ivan Mahonin 4dc49c
		return Color(r*k, g*k, b*k, a);
Ivan Mahonin 4dc49c
	}
Ivan Mahonin 4dc49c
	
Ivan Mahonin 4dc49c
	inline void mult_alpha()
Ivan Mahonin 4dc49c
		{ r*=a, g*=a, b*=a; }
Ivan Mahonin 4dc49c
	inline void demult_alpha() {
Ivan Mahonin 4dc49c
		if (fabs(a) < real_precision) return;
Ivan Mahonin 4dc49c
		Real k = 1/a;
Ivan Mahonin 4dc49c
		r*=k, g*=k, b*=k;
Ivan Mahonin 4dc49c
	}
Ivan Mahonin 531f67
};
Ivan Mahonin 531f67
Ivan Mahonin a1942e
Ivan Mahonin a1942e
inline bool real_less(const Real &a, const Real &b)
Ivan Mahonin a1942e
	{ return a < b - real_precision; }
Ivan Mahonin a1942e
inline bool real_greater(const Real &a, const Real &b)
Ivan Mahonin a1942e
	{ return real_less(b, a); }
Ivan Mahonin a1942e
inline bool real_less_or_equal(const Real &a, const Real &b)
Ivan Mahonin a1942e
	{ return !real_less(b, a); }
Ivan Mahonin a1942e
inline bool real_greater_or_equal(const Real &a, const Real &b)
Ivan Mahonin a1942e
	{ return !real_less(a, b); }
Ivan Mahonin a1942e
inline bool real_equal(const Real &a, const Real &b)
Ivan Mahonin a1942e
	{ return !real_less(a, b) && !real_less(b, a); }
Ivan Mahonin a1942e
inline bool real_not_equal(const Real &a, const Real &b)
Ivan Mahonin a1942e
	{ return real_less(a, b) || real_less(b, a); }
Ivan Mahonin a1942e
Ivan Mahonin a1942e
	
Ivan Mahonin 531f67
inline int clz(const Int &x)
Ivan Mahonin 531f67
	{ return x ? __builtin_clz(x) : 32; }
Ivan Mahonin 531f67
inline int clz(const UInt &x)
Ivan Mahonin 531f67
	{ return x ? __builtin_clz(x) : 32; }
Ivan Mahonin 531f67
inline int clz(const LongInt &x)
Ivan Mahonin 531f67
	{ return x ? __builtin_clzll(x) : 64; }
Ivan Mahonin 531f67
inline int clz(const ULongInt &x)
Ivan Mahonin 531f67
	{ return x ? __builtin_clzll(x) : 64; }
Ivan Mahonin 531f67
Ivan Mahonin 531f67
Ivan Mahonin 0662a2
inline Real clamp(Real x, Real min, Real max)
Ivan Mahonin 0662a2
	{ return std::max(min, std::min(max, x)); }
Ivan Mahonin 0662a2
inline int iclamp(int x, int min, int max)
Ivan Mahonin 0662a2
	{ return std::max(min, std::min(max, x)); }
Ivan Mahonin 0662a2
	
Ivan Mahonin 531f67
inline Real flip_clamp(Real x) {
Ivan Mahonin 531f67
	x -= floor(0.5*x)*2.0;
Ivan Mahonin 531f67
	return 1.0 - fabs(1.0 - x);
Ivan Mahonin 538bb7
};
Ivan Mahonin 531f67
Ivan Mahonin 531f67
#endif