#define PI 3.141592653589793238 #define KAPPA 0.5522847493f union v2 { struct { real32 x, y; }; real32 E[2]; }; union v2i { struct { int32 x, y; }; int32 E[2]; }; union v3 { struct { real32 r, g, b; }; int32 E[3]; }; union v4 { struct { real32 r, g, b, a; }; real32 E[4]; }; inline v2 V2(real32 x, real32 y) { v2 Result; Result.x = x; Result.y = y; return(Result); } inline v2 V2(real32 x) { v2 Result; Result.x = x; Result.y = x; return(Result); } inline v2 V2(ImVec2 A) { v2 Result; Result.x = A.x; Result.y = A.y; return(Result); } inline ImVec2 IV2(v2 f) { return { f.x, f.y }; } inline v2i V2i(int32 x, int32 y) { v2i Result; Result.x = x; Result.y = y; return(Result); } inline v3 V3(real32 a) { v3 Result; Result.r = a; Result.g = a; Result.b = a; return(Result); } inline v4 V4(real32 r) { v4 Result; Result.r = r; Result.g = r; Result.b = r; Result.a = r; return(Result); } inline v4 powv4(v4 Col, real32 i) { v4 Result; Result.r = pow(Col.r, i); Result.g = pow(Col.g, i); Result.b = pow(Col.b, i); Result.a = pow(Col.a, i); return(Result); } inline v4 powv4(v4 Col, v4 i) { v4 Result; Result.r = pow(Col.r, i.r); Result.g = pow(Col.g, i.g); Result.b = pow(Col.b, i.b); Result.a = pow(Col.a, i.a); return(Result); } inline v4 V4(v3 r, real32 a) { v4 Result; Result.r = r.r; Result.g = r.g; Result.b = r.b; Result.a = a; return(Result); } inline v4 V4(real32 r, real32 g, real32 b, real32 a) { v4 Result; Result.r = r; Result.g = g; Result.b = b; Result.a = a; return(Result); } inline v4 ClipV4(v4 A) { v4 Result; if (A.r < 0.0f) { Result.r = 0.0f; } else if (A.r > 1.0f) { Result.r = 1.0f; } else { Result.r = A.r; } if (A.g < 0.0f) { Result.g = 0.0f; } else if (A.g > 1.0f) { Result.g = 1.0f; } else { Result.g = A.g; } if (A.b < 0.0f) { Result.b = 0.0f; } else if (A.b > 1.0f) { Result.b = 1.0f; } else { Result.b = A.b; } if (A.a < 0.0f) { Result.a = 0.0f; } else if (A.a > 1.0f) { Result.a = 1.0f; } else { Result.a = A.a; } return(Result); } v2i operator+(v2i A, v2i B) { v2i Result; Result.x = A.x + B.x; Result.y = A.y + B.y; return(Result); } v2 operator/(v2 A, real32 B) { v2 Result; Result.x = A.x / B; Result.y = A.y / B; return Result; } v4 operator+(v4 A, v4 B) { v4 Result; Result.r = A.r + B.r; Result.g = A.g + B.g; Result.b = A.b + B.b; Result.a = A.a + B.a; return(Result); } v4 operator-(v4 A, v4 B) { v4 Result; Result.r = A.r - B.r; Result.g = A.g - B.g; Result.b = A.b - B.b; Result.a = A.a - B.a; return(Result); } v4 operator-(real32 A, v4 B) { v4 Result; Result.r = A - B.r; Result.g = A - B.g; Result.b = A - B.b; Result.a = A - B.a; return(Result); } v4 operator-(v4 A, real32 B) { v4 Result; Result.r = A.r - B; Result.g = A.g - B; Result.b = A.b - B; Result.a = A.a - B; return(Result); } v4 operator*(v4 A, v4 B) { v4 Result; Result.r = A.r * B.r; Result.g = A.g * B.g; Result.b = A.b * B.b; Result.a = A.a * B.a; return(Result); } v4 operator/(v4 A, v4 B) { v4 Result; Result.r = A.r / B.r; Result.g = A.g / B.g; Result.b = A.b / B.b; Result.a = A.a / B.a; return(Result); } v4 operator/(real32 A, v4 B) { v4 Result; Result.r = A / B.r; Result.g = A / B.g; Result.b = A / B.b; Result.a = A / B.a; return(Result); } v4 operator*(v4 A, real32 B) { v4 Result; Result.r = A.r * B; Result.g = A.g * B; Result.b = A.b * B; Result.a = A.a * B; return(Result); } v4 operator*(real32 B, v4 A) { v4 Result; Result.r = A.r * B; Result.g = A.g * B; Result.b = A.b * B; Result.a = A.a * B; return(Result); } v2 operator-(v2 A, v2i B) { v2 Result; Result.x = A.x - (real32)B.x; Result.y = A.y - (real32)B.y; return(Result); } v2 operator/(v2 A, v2 B) { v2 Result; Result.x = A.x / B.x; Result.y = A.y / B.y; return(Result); } v2i operator-(v2i A, v2i B) { v2i Result; Result.x = A.x - B.x; Result.y = A.y - B.y; return(Result); } v2i operator-(v2i A, int16 B) { v2i Result; Result.x = A.x - B; Result.y = A.y - B; return(Result); } v2 operator*(real32 A, v2 B) { v2 Result; Result.x = A * B.x; Result.y = A * B.y; return(Result); } v2 operator*(v2 A, real32 B) { v2 Result; Result.x = A.x * B; Result.y = A.y * B; return(Result); } v2 operator-(v2 A, v2 B) { v2 Result; Result.x = A.x - B.x; Result.y = A.y - B.y; return(Result); } v2 operator-(v2 A, real32 B) { v2 Result; Result.x = A.x - B; Result.y = A.y - B; return(Result); } v2 operator-(v2 A) { v2 Result; Result.x = -A.x; Result.y = -A.y; return(Result); } v2 operator+(v2 A, v2 B) { v2 Result; Result.x = A.x + B.x; Result.y = A.y + B.y; return(Result); } v2 operator*(v2 A, v2 B) { v2 Result; Result.x = A.x * B.x; Result.y = A.y * B.y; return(Result); } struct rectangle { v2i Min; v2i Max; }; inline real32 Min(real32 A, real32 B) { return (A > B) ? B : A; } inline real32 Max(real32 A, real32 B) { return (A > B) ? A : B; } inline bool32 TestRectangle(rectangle Rect, v2i Test) { bool32 Result = (Test.x > Rect.Min.x && Test.x < Rect.Max.x && Test.y > Rect.Min.y && Test.y < Rect.Max.y); return(Result); } inline bool32 TestRectangle(ImVec2 Min, ImVec2 Max, ImVec2 Test) { bool32 Result = (Test.x > Min.x && Test.x < Max.x && Test.y > Min.y && Test.y < Max.y); return(Result); } inline rectangle ClipRectangle(rectangle Rect, rectangle BoundRect) { if(Rect.Min.x < BoundRect.Min.x) { Rect.Min.x = BoundRect.Min.x; } if(Rect.Min.y < BoundRect.Min.y) { Rect.Min.y = BoundRect.Min.y; } if(Rect.Max.x > BoundRect.Max.x) { Rect.Max.x = BoundRect.Max.x; } if(Rect.Max.y > BoundRect.Max.y) { Rect.Max.y = BoundRect.Max.y; } return(Rect); } inline rectangle VerifyMinMax(rectangle Rect) { if(Rect.Min.x > Rect.Max.x) { int16 Temp = Rect.Max.x; Rect.Max.x = Rect.Min.x; Rect.Min.x = Temp; } if(Rect.Min.y > Rect.Max.y) { int16 Temp = Rect.Max.y; Rect.Max.y = Rect.Min.y; Rect.Min.y = Temp; } return(Rect); } inline int32 RoundReal32ToInt32(real32 Real32) { int32 Result = (int32)(Real32 + 0.5f); return(Result); } inline uint32 RoundReal32ToUint32(real32 Real32) { uint32 Result = (uint32)(Real32 + 0.5f); return(Result); } inline uint32 ColToUint32(real32 B) { uint32 Result = ((RoundReal32ToUint32(1 * 255.0f) << 24) | (RoundReal32ToUint32(B * 255.0f) << 16) | (RoundReal32ToUint32(B * 255.0f) << 8) | (RoundReal32ToUint32(B * 255.0f) << 0)); return Result; } inline uint32 ColToUint32(v4 Col) { uint32 Result = ((RoundReal32ToUint32(Col.a * 255.0f) << 24) | (RoundReal32ToUint32(Col.r * 255.0f) << 16) | (RoundReal32ToUint32(Col.g * 255.0f) << 8) | (RoundReal32ToUint32(Col.b * 255.0f) << 0)); return Result; } inline real32 Square(real32 A) { real32 Result = A * A; return Result; } inline real32 Inner(v2 A, v2 B) { real32 Result = A.x * B.x + A.y * B.y; return Result; } inline real32 Inner(ImVec2 A, ImVec2 B) { real32 Result = A.x * B.x + A.y * B.y; return Result; } inline real32 LengthSq(v2 A) { real32 Result = Inner(A, A); return Result; } inline real32 Length(v2 A) { return sqrt(Inner(A, A)); } inline real32 Length(ImVec2 A) { return sqrt(Inner(A, A)); } inline uint32 Floor(uint32 A, uint32 B) { if (A < B) { A = B; } return A; } inline uint32 Ceil(uint32 A, uint32 B) { if (A > B) { A = B; } return A; } inline real32 Floor(real32 A, real32 B) { if (A < B) { A = B; } return A; } inline real32 Ceil(real32 A, real32 B) { if (A > B) { A = B; } return A; } inline bool32 TestUV(v2 UV) { return (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f); } inline real32 Clamp(real32 A, real32 B, real32 C) { if (B < A) { B = A; } if (B > C) { B = C; } return B; } inline v4 Clamp(real32 A, v4 B, real32 C) { B.r = Clamp(A, B.r, C); B.g = Clamp(A, B.g, C); B.b = Clamp(A, B.b, C); B.a = Clamp(A, B.a, C); return B; } inline v4 Lerp(v4 A, real32 t, v4 B) { v4 Result = (1.0f - t)*A + t*B; return Result; } inline v4 Uint32ToCol(uint32 LayerPixel) { uint8 A2 = (LayerPixel >> 24); uint8 R2 = (LayerPixel >> 16); uint8 G2 = (LayerPixel >> 8); uint8 B2 = (LayerPixel >> 0); v4 Color = {(real32)R2 / 255.0f, (real32)G2 / 255.0f, (real32)B2 / 255.0f, (real32)A2 / 255.0f}; return Color; } inline v4 Uint32ToCol8(uint32 LayerPixel) { uint8 A2 = (LayerPixel >> 24); uint8 B2 = (LayerPixel >> 16); uint8 G2 = (LayerPixel >> 8); uint8 R2 = (LayerPixel >> 0); v4 Color = {(real32)R2, (real32)G2, (real32)B2, (real32)A2}; return Color; } inline v4 Uint32ToNormalizedCol(uint32 LayerPixel) { uint8 A2 = (LayerPixel >> 24); uint8 R2 = (LayerPixel >> 16); uint8 G2 = (LayerPixel >> 8); uint8 B2 = (LayerPixel >> 0); real32 R = R2 / 255.0f; real32 G = G2 / 255.0f; real32 B = B2 / 255.0f; real32 A = A2 / 255.0f; v4 Result = {R,G,B,A}; return Result; } inline real32 Uint32ToNormalizedBW(uint32 LayerPixel) { uint8 R2 = (LayerPixel >> 16); uint8 G2 = (LayerPixel >> 8); uint8 B2 = (LayerPixel >> 0); real32 R = R2 / 255.0f; real32 G = G2 / 255.0f; real32 B = B2 / 255.0f; real32 Result = (R + G + B) / 3.0f; return Result; } inline uint32 Col8ToUint32(v4 P) { uint8 A2 = P.a; uint8 R2 = P.r; uint8 G2 = P.g; uint8 B2 = P.b; uint32 Result = ((A2 << 24) | (R2 << 16) | (G2 << 8) | (B2 << 0)); return Result; } inline uint8 ClipAdd(uint8 a, uint8 b) { uint8 Result = 0; int16 exp = (int16)a + b; if (exp > 255) { Result = 255; } else if (exp < 0) { Result = 0; } else { Result = a + b; } return Result; } inline real32 Normalize(real32 A) { if (A > 1) { A = 1.0f; } else if (A < 0.0f) { A = 0.0f; } return A; }