140 lines
4.3 KiB
C++
140 lines
4.3 KiB
C++
#include "pch.h"
|
|
#include "log.h"
|
|
#include "util.h"
|
|
|
|
bool point_in_rect(const glm::vec2& p, const glm::vec4& r)
|
|
{
|
|
return p.x > r.x && p.x < r.x+r.z && p.y > r.y && p.y < r.y+r.w;
|
|
}
|
|
|
|
// params and returns {origin, size} form
|
|
glm::vec4 rect_intersection(glm::vec4 a, glm::vec4 b)
|
|
{
|
|
// convert from [x,y,w,h] to [x1,y1,x2,y1]
|
|
a = glm::vec4(a.xy(), a.xy() + a.zw());
|
|
b = glm::vec4(b.xy(), b.xy() + b.zw());
|
|
// compute intersection
|
|
auto o = glm::vec4(glm::max(a.xy(), b.xy()), glm::min(a.zw(), b.zw()));
|
|
// back to rect form
|
|
o = glm::vec4(o.xy(), glm::max({ 0, 0 }, o.zw() - o.xy()));
|
|
return o;
|
|
}
|
|
|
|
// params and returns {origin, size} form
|
|
glm::vec4 rect_union(glm::vec4 a, glm::vec4 b)
|
|
{
|
|
// convert from rect [x,y,w,h] to bb [x1,y1,x2,y1]
|
|
a = glm::vec4(a.xy(), a.xy() + a.zw());
|
|
b = glm::vec4(b.xy(), b.xy() + b.zw());
|
|
// compute union
|
|
glm::vec4 o = { glm::min(a.xy(), b.xy()), glm::max(a.zw(), b.zw()) };
|
|
// back to rect form
|
|
o = glm::vec4(o.xy(), glm::max({ 0, 0 }, o.zw() - o.xy()));
|
|
return o;
|
|
}
|
|
|
|
// see: https://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect
|
|
bool segments_intersect(const glm::vec2& p0a, const glm::vec2& p0b,
|
|
const glm::vec2& p1a, const glm::vec2& p1b, glm::vec2& out_pt)
|
|
{
|
|
auto cross2d = [](const glm::vec2& v, const glm::vec2& w)
|
|
{ return (v.x * w.y) - (v.y * w.x); };
|
|
auto p = p0a;
|
|
auto r = p0b - p0a;
|
|
auto q = p1a;
|
|
auto s = p1b - p1a;
|
|
float den = cross2d(r, s);
|
|
if (den == 0.f)
|
|
{
|
|
glm::vec4 is = rect_intersection({p, r}, {q, s});
|
|
out_pt = is.xy + is.zw * 0.5f;
|
|
return glm::all(glm::greaterThan(is.zw(), glm::vec2(0, 0)));
|
|
}
|
|
float t = cross2d(q - p, s) / den;
|
|
float u = cross2d(q - p, r) / den;
|
|
if (t >= 0 && t <= 1 && u >= 0 && u <= 1)
|
|
{
|
|
out_pt = p + t * r;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
glm::vec4 rand_color()
|
|
{
|
|
float r = (rand() % 256) / 256.f;
|
|
float g = (rand() % 256) / 256.f;
|
|
float b = (rand() % 256) / 256.f;
|
|
return { r, g, b, 1.f };
|
|
}
|
|
|
|
glm::vec3 convert_hsv2rgb(const glm::vec3 c)
|
|
{
|
|
glm::vec4 K = glm::vec4(1.0f, 2.0f / 3.0f, 1.0f / 3.0f, 3.0f);
|
|
glm::vec3 p = glm::abs(glm::fract(glm::vec3(c.xxx + K.xyz)) * 6.0f - K.www);
|
|
auto tmp = glm::clamp(glm::vec3(p - K.xxx), 0.0f, 1.0f);
|
|
return c.z * glm::mix(glm::vec3(K.xxx), tmp, c.y);
|
|
}
|
|
|
|
glm::vec3 convert_rgb2hsv(const glm::vec3 c)
|
|
{
|
|
glm::vec4 K = glm::vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
|
//glm::vec4 p = mix(glm::vec4(c.bg, K.wz), glm::vec4(c.gb, K.xy), glm::step(c.b, c.g));
|
|
//glm::vec4 q = mix(glm::vec4(p.xyw, c.r), glm::vec4(c.r, p.yzx), glm::step(p.x, c.r));
|
|
glm::vec4 p = c.g < c.b ? glm::vec4(c.bg, K.wz) : glm::vec4(c.gb, K.xy);
|
|
glm::vec4 q = c.r < p.x ? glm::vec4(p.xyw, c.r) : glm::vec4(c.r, p.yzx);
|
|
float d = q.x - glm::min(q.w, q.y);
|
|
float e = 1.0e-10f;
|
|
return glm::vec3(fabs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
|
}
|
|
|
|
static const char* gl2str(GLenum err)
|
|
{
|
|
switch (err)
|
|
{
|
|
case GL_NO_ERROR: return "GL_NO_ERROR";
|
|
case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
|
|
case GL_INVALID_VALUE: return "GL_INVALID_VALUE";
|
|
case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
|
|
case GL_INVALID_FRAMEBUFFER_OPERATION: return "GL_INVALID_FRAMEBUFFER_OPERATION";
|
|
case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
|
|
default: return "Unknown";
|
|
}
|
|
}
|
|
|
|
double now_seconds()
|
|
{
|
|
time_t timer;
|
|
struct tm y2k = { 0 };
|
|
double seconds;
|
|
|
|
y2k.tm_hour = 0; y2k.tm_min = 0; y2k.tm_sec = 0;
|
|
y2k.tm_year = 100; y2k.tm_mon = 0; y2k.tm_mday = 1;
|
|
|
|
time(&timer); /* get current time; same as: timer = time(NULL) */
|
|
seconds = difftime(timer, mktime(&y2k));
|
|
return seconds;
|
|
}
|
|
|
|
void check_OpenGLError(const char* stmt, const char* fname, int line)
|
|
{
|
|
GLenum err;
|
|
while ((err = glGetError()) != GL_NO_ERROR)
|
|
{
|
|
LOG("OpenGL error %08x (%s), at %s:%i - for %s", err, gl2str(err), fname, line, stmt);
|
|
}
|
|
}
|
|
|
|
size_t curl_data_handler(void *contents, size_t size, size_t nmemb, void *userp)
|
|
{
|
|
auto buffer = reinterpret_cast<std::string*>(userp);
|
|
buffer->append((char*)contents, size * nmemb);
|
|
return size * nmemb;
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
#define GL(stmt) stmt; CheckOpenGLError(#stmt, __FILE__, __LINE__);
|
|
#else
|
|
#define GL(stmt) stmt
|
|
#endif
|