2nd sync pass
parent
a37e7970c1
commit
5d7de442e7
|
@ -28,3 +28,4 @@ v4k.code-workspace
|
||||||
tests/out
|
tests/out
|
||||||
tests/diff
|
tests/diff
|
||||||
mtb.ini
|
mtb.ini
|
||||||
|
_fwk
|
||||||
|
|
51
bind/v4k.lua
51
bind/v4k.lua
|
@ -449,33 +449,6 @@ enum AUDIO_FLAGS {
|
||||||
AUDIO_SINGLE_INSTANCE = 512,
|
AUDIO_SINGLE_INSTANCE = 512,
|
||||||
};
|
};
|
||||||
int audio_queue( const void *samples, int num_samples, int flags );
|
int audio_queue( const void *samples, int num_samples, int flags );
|
||||||
typedef struct gjk_support {
|
|
||||||
int aid, bid;
|
|
||||||
vec3 a;
|
|
||||||
vec3 b;
|
|
||||||
} gjk_support;
|
|
||||||
typedef struct gjk_vertex {
|
|
||||||
vec3 a;
|
|
||||||
vec3 b;
|
|
||||||
vec3 p;
|
|
||||||
int aid, bid;
|
|
||||||
} gjk_vertex;
|
|
||||||
typedef struct gjk_simplex {
|
|
||||||
int max_iter, iter;
|
|
||||||
int hit, cnt;
|
|
||||||
gjk_vertex v[4];
|
|
||||||
float bc[4], D;
|
|
||||||
} gjk_simplex;
|
|
||||||
typedef struct gjk_result {
|
|
||||||
int hit;
|
|
||||||
vec3 p0;
|
|
||||||
vec3 p1;
|
|
||||||
float distance_squared;
|
|
||||||
int iterations;
|
|
||||||
} gjk_result;
|
|
||||||
int gjk(gjk_simplex *s, const gjk_support *sup, vec3 *dv);
|
|
||||||
gjk_result gjk_analyze(const gjk_simplex *s);
|
|
||||||
gjk_result gjk_quad(float a_radius, float b_radius);
|
|
||||||
typedef struct line { vec3 a, b; } line;
|
typedef struct line { vec3 a, b; } line;
|
||||||
typedef struct sphere { vec3 c; float r; } sphere;
|
typedef struct sphere { vec3 c; float r; } sphere;
|
||||||
typedef struct aabb { vec3 min, max; } aabb;
|
typedef struct aabb { vec3 min, max; } aabb;
|
||||||
|
@ -483,7 +456,6 @@ typedef struct plane { vec3 p, n; } plane;
|
||||||
typedef struct capsule { vec3 a, b; float r; } capsule;
|
typedef struct capsule { vec3 a, b; float r; } capsule;
|
||||||
typedef struct ray { vec3 p, d; } ray;
|
typedef struct ray { vec3 p, d; } ray;
|
||||||
typedef struct triangle { vec3 p0,p1,p2; } triangle;
|
typedef struct triangle { vec3 p0,p1,p2; } triangle;
|
||||||
typedef struct poly { vec3* verts; int cnt; } poly;
|
|
||||||
typedef union frustum { struct { vec4 l, r, t, b, n, f; }; vec4 pl[6]; float v[24]; } frustum;
|
typedef union frustum { struct { vec4 l, r, t, b, n, f; }; vec4 pl[6]; float v[24]; } frustum;
|
||||||
typedef struct hit {
|
typedef struct hit {
|
||||||
union {
|
union {
|
||||||
|
@ -510,7 +482,6 @@ typedef struct hit {
|
||||||
hit* sphere_hit_sphere(sphere a, sphere b);
|
hit* sphere_hit_sphere(sphere a, sphere b);
|
||||||
int sphere_test_aabb(sphere s, aabb a);
|
int sphere_test_aabb(sphere s, aabb a);
|
||||||
int sphere_test_capsule(sphere s, capsule c);
|
int sphere_test_capsule(sphere s, capsule c);
|
||||||
int sphere_test_poly(sphere s, poly p);
|
|
||||||
int sphere_test_sphere(sphere a, sphere b);
|
int sphere_test_sphere(sphere a, sphere b);
|
||||||
vec3 aabb_closest_point(aabb a, vec3 p);
|
vec3 aabb_closest_point(aabb a, vec3 p);
|
||||||
float aabb_distance2_point(aabb a, vec3 p);
|
float aabb_distance2_point(aabb a, vec3 p);
|
||||||
|
@ -520,7 +491,6 @@ typedef struct hit {
|
||||||
hit* aabb_hit_sphere(aabb a, sphere s);
|
hit* aabb_hit_sphere(aabb a, sphere s);
|
||||||
int aabb_test_aabb(aabb a, aabb b);
|
int aabb_test_aabb(aabb a, aabb b);
|
||||||
int aabb_test_capsule(aabb a, capsule c);
|
int aabb_test_capsule(aabb a, capsule c);
|
||||||
int aabb_test_poly(aabb a, poly p);
|
|
||||||
int aabb_test_sphere(aabb a, sphere s);
|
int aabb_test_sphere(aabb a, sphere s);
|
||||||
float capsule_distance2_point(capsule c, vec3 p);
|
float capsule_distance2_point(capsule c, vec3 p);
|
||||||
vec3 capsule_closest_point(capsule c, vec3 p);
|
vec3 capsule_closest_point(capsule c, vec3 p);
|
||||||
|
@ -529,32 +499,11 @@ typedef struct hit {
|
||||||
hit* capsule_hit_sphere(capsule c, sphere s);
|
hit* capsule_hit_sphere(capsule c, sphere s);
|
||||||
int capsule_test_aabb(capsule c, aabb a);
|
int capsule_test_aabb(capsule c, aabb a);
|
||||||
int capsule_test_capsule(capsule a, capsule b);
|
int capsule_test_capsule(capsule a, capsule b);
|
||||||
int capsule_test_poly(capsule c, poly p);
|
|
||||||
int capsule_test_sphere(capsule c, sphere s);
|
int capsule_test_sphere(capsule c, sphere s);
|
||||||
int poly_test_sphere(poly p, sphere s);
|
|
||||||
int poly_test_aabb(poly p, aabb a);
|
|
||||||
int poly_test_capsule(poly p, capsule c);
|
|
||||||
int poly_test_poly(poly a, poly b);
|
|
||||||
int poly_test_sphere_transform(poly p, vec3 pos3, mat33 rot33, sphere s);
|
|
||||||
int poly_test_aabb_transform(poly p, vec3 apos3, mat33 arot33, aabb a);
|
|
||||||
int poly_test_capsule_transform(poly p, vec3 pos3, mat33 rot33, capsule c);
|
|
||||||
int poly_test_poly_transform(poly a, vec3 apos3, mat33 arot33, poly b, vec3 bpos3, mat33 brot33);
|
|
||||||
int poly_hit_sphere(struct gjk_result *res, poly p, sphere s);
|
|
||||||
int poly_hit_aabb(struct gjk_result *res, poly p, aabb a);
|
|
||||||
int poly_hit_capsule(struct gjk_result *res, poly p, capsule c);
|
|
||||||
int poly_hit_poly(struct gjk_result *res, poly a, poly b);
|
|
||||||
int poly_hit_sphere_transform(struct gjk_result *res, poly p, vec3 pos3, mat33 rot33, sphere s);
|
|
||||||
int poly_hit_aabb_transform(struct gjk_result *res, poly p, vec3 pos3, mat33 rot33, aabb a);
|
|
||||||
int poly_hit_capsule_transform(struct gjk_result *res, poly p, vec3 pos3, mat33 rot33, capsule c);
|
|
||||||
int poly_hit_poly_transform(struct gjk_result *res, poly a, vec3 at3, mat33 ar33, poly b, vec3 bt3, mat33 br33);
|
|
||||||
vec4 plane4(vec3 p, vec3 n);
|
vec4 plane4(vec3 p, vec3 n);
|
||||||
frustum frustum_build(mat44 projview);
|
frustum frustum_build(mat44 projview);
|
||||||
int frustum_test_sphere(frustum f, sphere s);
|
int frustum_test_sphere(frustum f, sphere s);
|
||||||
int frustum_test_aabb(frustum f, aabb a);
|
int frustum_test_aabb(frustum f, aabb a);
|
||||||
poly poly_alloc(int cnt);
|
|
||||||
void poly_free(poly *p);
|
|
||||||
poly pyramid(vec3 from, vec3 to, float size);
|
|
||||||
poly diamond(vec3 from, vec3 to, float size);
|
|
||||||
void collide_demo();
|
void collide_demo();
|
||||||
enum COOK_FLAGS {
|
enum COOK_FLAGS {
|
||||||
COOK_SYNC = 0,
|
COOK_SYNC = 0,
|
||||||
|
|
1319
engine/joint/v4k.h
1319
engine/joint/v4k.h
File diff suppressed because it is too large
Load Diff
|
@ -17193,10 +17193,6 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
|
||||||
if (window->callbacks.focus)
|
if (window->callbacks.focus)
|
||||||
window->callbacks.focus((GLFWwindow*) window, focused);
|
window->callbacks.focus((GLFWwindow*) window, focused);
|
||||||
|
|
||||||
// zak: disable top-most if we lose focus
|
|
||||||
if (window->monitor)
|
|
||||||
_glfwPlatformSetWindowFloating(window, focused);
|
|
||||||
|
|
||||||
if (!focused)
|
if (!focused)
|
||||||
{
|
{
|
||||||
int key, button;
|
int key, button;
|
||||||
|
@ -26038,8 +26034,9 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle)
|
||||||
// It is fine to use C99 in this file because it will not be built with VS
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
|
#ifndef _GNU_SOURCE //< @r-lyeh: add missing guard
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15318,7 +15318,7 @@ int xts_decrypt(
|
||||||
|
|
||||||
void xts_done(symmetric_xts *xts);
|
void xts_done(symmetric_xts *xts);
|
||||||
int xts_test(void);
|
int xts_test(void);
|
||||||
void xts_mult_x(unsigned char *I);
|
void xts_mult_x(unsigned char *); //< @r-lyeh: remove I arg
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int find_cipher(const char *name);
|
int find_cipher(const char *name);
|
||||||
|
@ -15989,7 +15989,7 @@ typedef struct {
|
||||||
#endif
|
#endif
|
||||||
} gcm_state;
|
} gcm_state;
|
||||||
|
|
||||||
void gcm_mult_h(gcm_state *gcm, unsigned char *I);
|
void gcm_mult_h(gcm_state *gcm, unsigned char *); //< @r-lyeh: remove I arg
|
||||||
|
|
||||||
int gcm_init(gcm_state *gcm, int cipher,
|
int gcm_init(gcm_state *gcm, int cipher,
|
||||||
const unsigned char *key, int keylen);
|
const unsigned char *key, int keylen);
|
||||||
|
@ -34216,35 +34216,35 @@ int gcm_process(gcm_state *gcm,
|
||||||
@param gcm The GCM state which holds the H value
|
@param gcm The GCM state which holds the H value
|
||||||
@param I The value to multiply H by
|
@param I The value to multiply H by
|
||||||
*/
|
*/
|
||||||
void gcm_mult_h(gcm_state *gcm, unsigned char *I)
|
void gcm_mult_h(gcm_state *gcm, unsigned char *i) //< @r-lyeh: lowercase I argument
|
||||||
{
|
{
|
||||||
unsigned char T[16];
|
unsigned char T[16];
|
||||||
#ifdef LTC_GCM_TABLES
|
#ifdef LTC_GCM_TABLES
|
||||||
int x, y;
|
int x, y;
|
||||||
#ifdef LTC_GCM_TABLES_SSE2
|
#ifdef LTC_GCM_TABLES_SSE2
|
||||||
asm("movdqa (%0),%%xmm0"::"r"(&gcm->PC[0][I[0]][0]));
|
asm("movdqa (%0),%%xmm0"::"r"(&gcm->PC[0][i[0]][0]));
|
||||||
for (x = 1; x < 16; x++) {
|
for (x = 1; x < 16; x++) {
|
||||||
asm("pxor (%0),%%xmm0"::"r"(&gcm->PC[x][I[x]][0]));
|
asm("pxor (%0),%%xmm0"::"r"(&gcm->PC[x][i[x]][0]));
|
||||||
}
|
}
|
||||||
asm("movdqa %%xmm0,(%0)"::"r"(&T));
|
asm("movdqa %%xmm0,(%0)"::"r"(&T));
|
||||||
#else
|
#else
|
||||||
XMEMCPY(T, &gcm->PC[0][I[0]][0], 16);
|
XMEMCPY(T, &gcm->PC[0][i[0]][0], 16);
|
||||||
for (x = 1; x < 16; x++) {
|
for (x = 1; x < 16; x++) {
|
||||||
#ifdef LTC_FAST
|
#ifdef LTC_FAST
|
||||||
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
|
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
|
||||||
*((LTC_FAST_TYPE *)(T + y)) ^= *((LTC_FAST_TYPE *)(&gcm->PC[x][I[x]][y]));
|
*((LTC_FAST_TYPE *)(T + y)) ^= *((LTC_FAST_TYPE *)(&gcm->PC[x][i[x]][y]));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
for (y = 0; y < 16; y++) {
|
for (y = 0; y < 16; y++) {
|
||||||
T[y] ^= gcm->PC[x][I[x]][y];
|
T[y] ^= gcm->PC[x][i[x]][y];
|
||||||
}
|
}
|
||||||
#endif /* LTC_FAST */
|
#endif /* LTC_FAST */
|
||||||
}
|
}
|
||||||
#endif /* LTC_GCM_TABLES_SSE2 */
|
#endif /* LTC_GCM_TABLES_SSE2 */
|
||||||
#else
|
#else
|
||||||
gcm_gf_mult(gcm->H, I, T);
|
gcm_gf_mult(gcm->H, i, T);
|
||||||
#endif
|
#endif
|
||||||
XMEMCPY(I, T, 16);
|
XMEMCPY(i, T, 16);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,7 @@ static char* luaL_prepbuffsize(luaL_Buffer* B, size_t sz) {
|
||||||
# define ARCH_X86
|
# define ARCH_X86
|
||||||
#elif defined __amd64__ || defined _M_X64
|
#elif defined __amd64__ || defined _M_X64
|
||||||
# define ARCH_X64
|
# define ARCH_X64
|
||||||
#elif defined __arm__ || defined __ARM__ || defined ARM || defined __ARM || defined __arm || defined __arm64__
|
#elif defined __arm__ || defined __ARM__ || defined ARM || defined __ARM || defined __arm
|
||||||
# define ARCH_ARM
|
# define ARCH_ARM
|
||||||
#elif defined OS_LINUX && defined __TINYC__ //< @r-lyeh: tcc+linux
|
#elif defined OS_LINUX && defined __TINYC__ //< @r-lyeh: tcc+linux
|
||||||
# define ARCH_X64 //< @r-lyeh: tcc+linux
|
# define ARCH_X64 //< @r-lyeh: tcc+linux
|
||||||
|
|
|
@ -2414,7 +2414,6 @@ typedef struct {
|
||||||
|
|
||||||
intptr_t SteamClient();
|
intptr_t SteamClient();
|
||||||
|
|
||||||
#ifndef STEAM_API
|
|
||||||
#define STEAM_API(X) \
|
#define STEAM_API(X) \
|
||||||
X(bool,SteamAPI_Init,()) \
|
X(bool,SteamAPI_Init,()) \
|
||||||
X(void,SteamAPI_Shutdown,()) \
|
X(void,SteamAPI_Shutdown,()) \
|
||||||
|
@ -3114,4 +3113,3 @@ X(void*,SteamInternal_CreateInterface,(const char *ver)) \
|
||||||
X(bool,SteamAPI_IsSteamRunning,()) \
|
X(bool,SteamAPI_IsSteamRunning,()) \
|
||||||
X(bool,SteamAPI_InitSafe,()) \
|
X(bool,SteamAPI_InitSafe,()) \
|
||||||
X(void,SteamAPI_RunCallbacks,())
|
X(void,SteamAPI_RunCallbacks,())
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,53 +1,8 @@
|
||||||
/* poly */
|
|
||||||
poly poly_alloc(int cnt) {
|
|
||||||
poly p = {0};
|
|
||||||
p.cnt = cnt;
|
|
||||||
p.verts = REALLOC(p.verts, sizeof(p.verts[0]) * cnt); // array_resize(p.verts, cnt);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void poly_free(poly *p) {
|
|
||||||
REALLOC(p->verts, 0); // array_free(p->verts);
|
|
||||||
poly z = {0};
|
|
||||||
*p = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* plane */
|
/* plane */
|
||||||
vec4 plane4(vec3 p, vec3 n) {
|
vec4 plane4(vec3 p, vec3 n) {
|
||||||
return vec34(n, -dot3(n,p));
|
return vec34(n, -dot3(n,p));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pyramid */
|
|
||||||
poly pyramid(vec3 from, vec3 to, float size) {
|
|
||||||
/* calculate axis */
|
|
||||||
vec3 up, right, forward = norm3( sub3(to, from) );
|
|
||||||
ortho3(&right, &up, forward);
|
|
||||||
|
|
||||||
/* calculate extend */
|
|
||||||
vec3 xext = scale3(right, size);
|
|
||||||
vec3 yext = scale3(up, size);
|
|
||||||
vec3 nxext = scale3(right, -size);
|
|
||||||
vec3 nyext = scale3(up, -size);
|
|
||||||
|
|
||||||
/* calculate base vertices */
|
|
||||||
poly p = {0};
|
|
||||||
p.verts = REALLOC(p.verts, sizeof(p.verts[0]) * (5+1)); p.cnt = 5; /*+1 for diamond case*/ // array_resize(p.verts, 5+1); p.cnt = 5;
|
|
||||||
p.verts[0] = add3(add3(from, xext), yext); /*a*/
|
|
||||||
p.verts[1] = add3(add3(from, xext), nyext); /*b*/
|
|
||||||
p.verts[2] = add3(add3(from, nxext), nyext); /*c*/
|
|
||||||
p.verts[3] = add3(add3(from, nxext), yext); /*d*/
|
|
||||||
p.verts[4] = to; /*r*/
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pyramid */
|
|
||||||
poly diamond(vec3 from, vec3 to, float size) {
|
|
||||||
vec3 mid = add3(from, scale3(sub3(to, from), 0.5f));
|
|
||||||
poly p = pyramid(mid, to, size);
|
|
||||||
p.verts[5] = from; p.cnt = 6;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
static void transform_(vec3 *r, vec3 v, const float *r33, vec3 t3) {
|
static void transform_(vec3 *r, vec3 v, const float *r33, vec3 t3) {
|
||||||
|
@ -358,9 +313,6 @@ hit *sphere_hit_capsule(sphere s, capsule c) {
|
||||||
return h;
|
return h;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
int sphere_test_poly(sphere s, poly p) {
|
|
||||||
return poly_test_sphere(p, s);
|
|
||||||
}
|
|
||||||
void aabb_rebalance_transform(aabb *b, aabb a, mat33 m, vec3 t) {
|
void aabb_rebalance_transform(aabb *b, aabb a, mat33 m, vec3 t) {
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
i[&b->min.x] = i[&b->max.x] = i[&t.x];
|
i[&b->min.x] = i[&b->max.x] = i[&t.x];
|
||||||
|
@ -501,9 +453,6 @@ hit *aabb_hit_capsule(aabb a, capsule c) {
|
||||||
m->contact_point = ap;
|
m->contact_point = ap;
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
int aabb_test_poly(aabb a, poly p) {
|
|
||||||
return poly_test_aabb(p, a);
|
|
||||||
}
|
|
||||||
float capsule_distance2_point(capsule c, vec3 p) {
|
float capsule_distance2_point(capsule c, vec3 p) {
|
||||||
float d2 = line_distance2_point(line(c.a,c.b), p);
|
float d2 = line_distance2_point(line(c.a,c.b), p);
|
||||||
return d2 - (c.r*c.r);
|
return d2 - (c.r*c.r);
|
||||||
|
@ -602,229 +551,6 @@ hit *capsule_hit_aabb(capsule c, aabb a) {
|
||||||
m->contact_point = cp;
|
m->contact_point = cp;
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
int capsule_test_poly(capsule c, poly p) {
|
|
||||||
return poly_test_capsule(p, c);
|
|
||||||
}
|
|
||||||
int line_support(vec3 *support, vec3 d, vec3 a, vec3 b) {
|
|
||||||
int i = 0;
|
|
||||||
float adot = dot3(a, d);
|
|
||||||
float bdot = dot3(b, d);
|
|
||||||
if (adot < bdot) {
|
|
||||||
*support = b;
|
|
||||||
i = 1;
|
|
||||||
} else *support = a;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
int poly_support(vec3 *support, vec3 d, poly p) {
|
|
||||||
int imax = 0;
|
|
||||||
float dmax = dot3(*p.verts, d);
|
|
||||||
for (int i = 1; i < p.cnt; ++i) {
|
|
||||||
/* find vertex with max dot product in direction d */
|
|
||||||
float dot = dot3(p.verts[i], d);
|
|
||||||
if (dot < dmax) continue;
|
|
||||||
imax = i, dmax = dot;
|
|
||||||
} *support = p.verts[imax];
|
|
||||||
return imax;
|
|
||||||
}
|
|
||||||
int poly_hit_sphere(struct gjk_result *res,
|
|
||||||
poly p,
|
|
||||||
sphere s) {
|
|
||||||
/* initial guess */
|
|
||||||
vec3 d = {0};
|
|
||||||
gjk_support gs = {0};
|
|
||||||
gs.a = *p.verts;
|
|
||||||
gs.b = s.c;
|
|
||||||
d = sub3(gs.b, gs.a);
|
|
||||||
|
|
||||||
/* run gjk algorithm */
|
|
||||||
gjk_simplex gsx = {0};
|
|
||||||
while (gjk(&gsx, &gs, &d)) {
|
|
||||||
vec3 n = scale3(d, -1);
|
|
||||||
gs.aid = poly_support(&gs.a, n, p);
|
|
||||||
d = sub3(gs.b, gs.a);
|
|
||||||
}
|
|
||||||
/* check distance between closest points */
|
|
||||||
*res = gjk_analyze(&gsx);
|
|
||||||
return res->distance_squared <= s.r*s.r;
|
|
||||||
}
|
|
||||||
int poly_hit_sphere_transform(struct gjk_result *res, poly p, vec3 pos3, mat33 rot33, sphere s) {
|
|
||||||
/* initial guess */
|
|
||||||
vec3 d = {0};
|
|
||||||
gjk_support gs = {0};
|
|
||||||
gs.a = *p.verts;
|
|
||||||
gs.b = s.c;
|
|
||||||
transformS(&gs.a, rot33, pos3);
|
|
||||||
d = sub3(gs.b, gs.a);
|
|
||||||
|
|
||||||
/* run gjk algorithm */
|
|
||||||
gjk_simplex gsx = {0};
|
|
||||||
while (gjk(&gsx, &gs, &d)) {
|
|
||||||
vec3 n = scale3(d, -1);
|
|
||||||
vec3 da; transformT(&da, n, rot33, pos3);
|
|
||||||
|
|
||||||
gs.aid = poly_support(&gs.a, da, p);
|
|
||||||
transformS(&gs.a, rot33, pos3);
|
|
||||||
d = sub3(gs.b, gs.a);
|
|
||||||
}
|
|
||||||
/* check distance between closest points */
|
|
||||||
*res = gjk_analyze(&gsx);
|
|
||||||
return res->distance_squared <= s.r*s.r;
|
|
||||||
}
|
|
||||||
int poly_test_sphere(poly p, sphere s) {
|
|
||||||
struct gjk_result res;
|
|
||||||
return poly_hit_sphere(&res, p, s);
|
|
||||||
}
|
|
||||||
int poly_test_sphere_transform(poly p, vec3 pos3, mat33 rot33, sphere s) {
|
|
||||||
struct gjk_result res;
|
|
||||||
return poly_hit_sphere_transform(&res, p, pos3, rot33, s);
|
|
||||||
}
|
|
||||||
int poly_hit_capsule(struct gjk_result *res, poly p, capsule c) {
|
|
||||||
/* initial guess */
|
|
||||||
vec3 d = {0};
|
|
||||||
gjk_support s = {0};
|
|
||||||
s.a = *p.verts;
|
|
||||||
s.b = c.a;
|
|
||||||
d = sub3(s.b, s.a);
|
|
||||||
|
|
||||||
/* run gjk algorithm */
|
|
||||||
gjk_simplex gsx = {0};
|
|
||||||
while (gjk(&gsx, &s, &d)) {
|
|
||||||
vec3 n = scale3(d, -1);
|
|
||||||
s.aid = poly_support(&s.a, n, p);
|
|
||||||
s.bid = line_support(&s.b, d, c.a, c.b);
|
|
||||||
d = sub3(s.b, s.a);
|
|
||||||
}
|
|
||||||
/* check distance between closest points */
|
|
||||||
assert(gsx.iter < gsx.max_iter);
|
|
||||||
*res = gjk_analyze(&gsx);
|
|
||||||
return res->distance_squared <= c.r*c.r;
|
|
||||||
}
|
|
||||||
int poly_test_capsule(poly p, capsule c) {
|
|
||||||
struct gjk_result res;
|
|
||||||
return poly_hit_capsule(&res, p, c);
|
|
||||||
}
|
|
||||||
int poly_hit_capsule_transform(struct gjk_result *res, poly p, vec3 pos3, mat33 rot33, capsule c) {
|
|
||||||
/* initial guess */
|
|
||||||
vec3 d = {0};
|
|
||||||
gjk_support gs = {0};
|
|
||||||
gs.a = *p.verts;
|
|
||||||
gs.b = c.a;
|
|
||||||
transformS(&gs.a, rot33, pos3);
|
|
||||||
d = sub3(gs.b, gs.a);
|
|
||||||
|
|
||||||
/* run gjk algorithm */
|
|
||||||
gjk_simplex gsx = {0};
|
|
||||||
while (gjk(&gsx, &gs, &d)) {
|
|
||||||
vec3 n = scale3(d, -1);
|
|
||||||
vec3 da; transformT(&da, n, rot33, pos3);
|
|
||||||
|
|
||||||
gs.aid = poly_support(&gs.a, da, p);
|
|
||||||
gs.bid = line_support(&gs.b, d, c.a, c.b);
|
|
||||||
transformS(&gs.a, rot33, pos3);
|
|
||||||
d = sub3(gs.b, gs.a);
|
|
||||||
}
|
|
||||||
/* check distance between closest points */
|
|
||||||
*res = gjk_analyze(&gsx);
|
|
||||||
return res->distance_squared <= c.r*c.r;
|
|
||||||
}
|
|
||||||
int poly_test_capsule_transform(poly p, vec3 pos3, mat33 rot33, capsule c) {
|
|
||||||
struct gjk_result res;
|
|
||||||
return poly_hit_capsule_transform(&res, p, pos3, rot33, c);
|
|
||||||
}
|
|
||||||
int poly_hit_poly_transform(struct gjk_result *res,
|
|
||||||
poly a, vec3 at3, mat33 ar33,
|
|
||||||
poly b, vec3 bt3, mat33 br33) {
|
|
||||||
/* initial guess */
|
|
||||||
vec3 d = {0};
|
|
||||||
gjk_support gs = {0};
|
|
||||||
gs.a = *a.verts;
|
|
||||||
gs.b = *b.verts;
|
|
||||||
transformS(&gs.a, ar33, at3);
|
|
||||||
transformS(&gs.b, br33, bt3);
|
|
||||||
d = sub3(gs.b, gs.a);
|
|
||||||
|
|
||||||
/* run gjk algorithm */
|
|
||||||
gjk_simplex gsx = {0};
|
|
||||||
while (gjk(&gsx, &gs, &d)) {
|
|
||||||
/* transform direction */
|
|
||||||
vec3 n = scale3(d, -1);
|
|
||||||
vec3 da; transformT(&da, n, ar33, at3);
|
|
||||||
vec3 db; transformT(&db, d, br33, bt3);
|
|
||||||
/* run support function on tranformed directions */
|
|
||||||
gs.aid = poly_support(&gs.a, da, a);
|
|
||||||
gs.bid = poly_support(&gs.b, db, b);
|
|
||||||
/* calculate distance vector on transformed points */
|
|
||||||
transformS(&gs.a, ar33, at3);
|
|
||||||
transformS(&gs.b, br33, bt3);
|
|
||||||
d = sub3(gs.b, gs.a);
|
|
||||||
}
|
|
||||||
*res = gjk_analyze(&gsx);
|
|
||||||
return gsx.hit;
|
|
||||||
}
|
|
||||||
int poly_hit_poly(struct gjk_result *res,
|
|
||||||
poly a,
|
|
||||||
poly b) {
|
|
||||||
/* initial guess */
|
|
||||||
vec3 d = {0};
|
|
||||||
gjk_support gs = {0};
|
|
||||||
gs.a = *a.verts;
|
|
||||||
gs.b = *b.verts;
|
|
||||||
d = sub3(gs.b, gs.a);
|
|
||||||
|
|
||||||
/* run gjk algorithm */
|
|
||||||
gjk_simplex gsx = {0};
|
|
||||||
while (gjk(&gsx, &gs, &d)) {
|
|
||||||
vec3 n = scale3(d, -1);
|
|
||||||
gs.aid = poly_support(&gs.a, n, a);
|
|
||||||
gs.bid = poly_support(&gs.b, d, b);
|
|
||||||
d = sub3(gs.b, gs.a);
|
|
||||||
}
|
|
||||||
*res = gjk_analyze(&gsx);
|
|
||||||
return gsx.hit;
|
|
||||||
}
|
|
||||||
int poly_test_poly(poly a, poly b) {
|
|
||||||
struct gjk_result res;
|
|
||||||
return poly_hit_poly(&res, a, b);
|
|
||||||
}
|
|
||||||
int poly_test_poly_transform(poly a, vec3 apos3, mat33 arot33,
|
|
||||||
poly b, vec3 bpos3, mat33 brot33) {
|
|
||||||
struct gjk_result res;
|
|
||||||
return poly_hit_poly_transform(&res, a, apos3, arot33, b, bpos3, brot33);
|
|
||||||
}
|
|
||||||
int poly_hit_aabb(struct gjk_result *res, poly p, aabb a) {
|
|
||||||
vec3 box[8];
|
|
||||||
box[0] = vec3(a.min.x, a.min.y, a.min.z),
|
|
||||||
box[1] = vec3(a.min.x, a.min.y, a.max.z);
|
|
||||||
box[2] = vec3(a.min.x, a.max.y, a.min.z);
|
|
||||||
box[3] = vec3(a.min.x, a.max.y, a.max.z);
|
|
||||||
box[4] = vec3(a.max.x, a.min.y, a.min.z);
|
|
||||||
box[5] = vec3(a.max.x, a.min.y, a.max.z);
|
|
||||||
box[6] = vec3(a.max.x, a.max.y, a.min.z);
|
|
||||||
box[7] = vec3(a.max.x, a.max.y, a.max.z);
|
|
||||||
return poly_hit_poly(res, p, poly(&box[0], 8));
|
|
||||||
}
|
|
||||||
int poly_hit_aabb_transform(struct gjk_result *res, poly p, vec3 pos3, mat33 rot33, aabb a) {
|
|
||||||
vec3 zero = {0};
|
|
||||||
vec3 id[3] = {{1,0,0},{0,1,0},{0,0,1}};
|
|
||||||
vec3 box[8];
|
|
||||||
box[0] = vec3(a.min.x, a.min.y, a.min.z),
|
|
||||||
box[1] = vec3(a.min.x, a.min.y, a.max.z);
|
|
||||||
box[2] = vec3(a.min.x, a.max.y, a.min.z);
|
|
||||||
box[3] = vec3(a.min.x, a.max.y, a.max.z);
|
|
||||||
box[4] = vec3(a.max.x, a.min.y, a.min.z);
|
|
||||||
box[5] = vec3(a.max.x, a.min.y, a.max.z);
|
|
||||||
box[6] = vec3(a.max.x, a.max.y, a.min.z);
|
|
||||||
box[7] = vec3(a.max.x, a.max.y, a.max.z);
|
|
||||||
return poly_hit_poly_transform(res, p, pos3, rot33, poly(&box[0], 8), zero, id[0].v3);
|
|
||||||
}
|
|
||||||
int poly_test_aabb(poly p, aabb a) {
|
|
||||||
struct gjk_result res;
|
|
||||||
return poly_hit_aabb(&res, p, a);
|
|
||||||
}
|
|
||||||
int poly_test_aabb_transform(poly p, vec3 apos3, mat33 arot33, aabb a) {
|
|
||||||
struct gjk_result res;
|
|
||||||
return poly_hit_aabb_transform(&res, p, apos3, arot33, a);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================================
|
/* ============================================================================
|
||||||
*
|
*
|
||||||
|
@ -911,7 +637,7 @@ int frustum_test_aabb(frustum f, aabb a) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void collide_demo() { // debug draw collisions // @fixme: fix leaks: poly_free()
|
void collide_demo() { // debug draw collisions
|
||||||
|
|
||||||
// animation
|
// animation
|
||||||
static float dx = 0, dy = 0;
|
static float dx = 0, dy = 0;
|
||||||
|
@ -1259,167 +985,4 @@ void collide_demo() { // debug draw collisions // @fixme: fix leaks: poly_free()
|
||||||
ddraw_capsule(vec3(x,y-1.0f,z), vec3(x,y+1.0f,z-1.0f), 0.2f);
|
ddraw_capsule(vec3(x,y-1.0f,z), vec3(x,y+1.0f,z-1.0f), 0.2f);
|
||||||
ddraw_box(vec3(0,0,-8.0f), vec3(1,1,1));
|
ddraw_box(vec3(0,0,-8.0f), vec3(1,1,1));
|
||||||
}
|
}
|
||||||
{
|
|
||||||
// poly(Pyramid)-Sphere (GJK) intersection*/
|
|
||||||
sphere s = sphere(vec3(-10+0.6f*sin(dx), 3.0f*cos(dy),-8), 1);
|
|
||||||
poly pyr = pyramid(vec3(-10.5f,-0.5f,-7.5f), vec3(-10.5f,1.0f,-7.5f), 1.0f);
|
|
||||||
|
|
||||||
gjk_result gjk;
|
|
||||||
if (poly_hit_sphere(&gjk, pyr, s))
|
|
||||||
ddraw_color(RED);
|
|
||||||
else ddraw_color(WHITE);
|
|
||||||
|
|
||||||
ddraw_sphere(s.c, 1);
|
|
||||||
ddraw_pyramid(vec3(-10.5f,-0.5f,-7.5f), 0.5f/*vec3(-10.5f,1.0f,-7.5f)*/, 1.0f);
|
|
||||||
|
|
||||||
poly_free(&pyr);
|
|
||||||
|
|
||||||
ddraw_box(gjk.p0, vec3(0.05f, 0.05f, 0.05f));
|
|
||||||
ddraw_box(gjk.p1, vec3(0.05f, 0.05f, 0.05f));
|
|
||||||
ddraw_line(gjk.p0, gjk.p1);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
// poly(Diamond)-Sphere (GJK) intersection*/
|
|
||||||
|
|
||||||
sphere s = sphere(vec3(-20+0.6f*sin(dx), 3.0f*cos(dy),-8), 1);
|
|
||||||
poly dmd = diamond(vec3(-20.5f,-0.5f,-7.5f), vec3(-20.5f,1.0f,-7.5f), 0.5f);
|
|
||||||
|
|
||||||
gjk_result gjk;
|
|
||||||
if (poly_hit_sphere(&gjk, dmd, s))
|
|
||||||
ddraw_color(RED);
|
|
||||||
else ddraw_color(WHITE);
|
|
||||||
|
|
||||||
ddraw_sphere(s.c, 1);
|
|
||||||
ddraw_diamond(vec3(-20.5f,-0.5f,-7.5f), vec3(-20.5f,1.0f,-7.5f), 0.5f);
|
|
||||||
|
|
||||||
poly_free(&dmd);
|
|
||||||
|
|
||||||
ddraw_box(gjk.p0, vec3(0.05f, 0.05f, 0.05f));
|
|
||||||
ddraw_box(gjk.p1, vec3(0.05f, 0.05f, 0.05f));
|
|
||||||
ddraw_line(gjk.p0, gjk.p1);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
// poly(Pyramid)-Capsule (GJK) intersection*/
|
|
||||||
|
|
||||||
const float x = 0.4f*sin(dx);
|
|
||||||
const float y = 3.0f*cos(dy);
|
|
||||||
const float z = -15;
|
|
||||||
|
|
||||||
capsule c = capsule(vec3(x,y-1.0f,z), vec3(x,y+1.0f,z), 0.2f);
|
|
||||||
poly pyr = pyramid(vec3(-0.5f,-0.5f,-15.5f), vec3(-0.5f,1.0f,-15.5f), 1.0f);
|
|
||||||
|
|
||||||
gjk_result gjk;
|
|
||||||
if (poly_hit_capsule(&gjk, pyr, c))
|
|
||||||
ddraw_color(RED);
|
|
||||||
else ddraw_color(WHITE);
|
|
||||||
|
|
||||||
ddraw_capsule(c.a, c.b, c.r);
|
|
||||||
ddraw_pyramid(vec3(-0.5f,-0.5f,-15.5f), 0.5f/*vec3(-0.5f,1.0f,-15.5f)*/, 1.0f);
|
|
||||||
|
|
||||||
poly_free(&pyr);
|
|
||||||
|
|
||||||
ddraw_box(gjk.p0, vec3(0.05f, 0.05f, 0.05f));
|
|
||||||
ddraw_box(gjk.p1, vec3(0.05f, 0.05f, 0.05f));
|
|
||||||
ddraw_line(gjk.p0, gjk.p1);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// poly(Diamond)-Capsule (GJK) intersection*/
|
|
||||||
|
|
||||||
const float x = -10 + 0.4f*sin(dx);
|
|
||||||
const float y = 3.0f*cos(dy);
|
|
||||||
const float z = -15;
|
|
||||||
|
|
||||||
capsule c = capsule(vec3(x,y-1.0f,z), vec3(x,y+1.0f,z), 0.2f);
|
|
||||||
poly dmd = diamond(vec3(-10.5f,-0.5f,-15.5f), vec3(-10.5f,1.0f,-15.5f), 0.5f);
|
|
||||||
|
|
||||||
gjk_result gjk;
|
|
||||||
if (poly_hit_capsule(&gjk, dmd, c))
|
|
||||||
ddraw_color(RED);
|
|
||||||
else ddraw_color(WHITE);
|
|
||||||
|
|
||||||
ddraw_capsule(c.a, c.b, c.r);
|
|
||||||
ddraw_diamond(vec3(-10.5f,-0.5f,-15.5f), vec3(-10.5f,1.0f,-15.5f), 0.5f);
|
|
||||||
|
|
||||||
poly_free(&dmd);
|
|
||||||
|
|
||||||
ddraw_box(gjk.p0, vec3(0.05f, 0.05f, 0.05f));
|
|
||||||
ddraw_box(gjk.p1, vec3(0.05f, 0.05f, 0.05f));
|
|
||||||
ddraw_line(gjk.p0, gjk.p1);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// poly(Diamond)-poly(Pyramid) (GJK) intersection*/
|
|
||||||
|
|
||||||
const float x = -20 + 0.4f*sin(dx);
|
|
||||||
const float y = 3.0f*cos(dy);
|
|
||||||
const float z = -15;
|
|
||||||
|
|
||||||
poly pyr = pyramid(vec3(x,y-0.5f,z), vec3(x,y+1,z), 0.8f);
|
|
||||||
poly dmd = diamond(vec3(-20.5f,-0.5f,-15.5f), vec3(-20.5f,1.0f,-15.5f), 0.5f);
|
|
||||||
|
|
||||||
gjk_result gjk;
|
|
||||||
if (poly_hit_poly(&gjk, dmd, pyr))
|
|
||||||
ddraw_color(RED);
|
|
||||||
else ddraw_color(WHITE);
|
|
||||||
|
|
||||||
ddraw_pyramid(vec3(x,y-0.5f,z), 1/*vec3(x,y+1,z)*/, 1/*0.8f*/);
|
|
||||||
ddraw_diamond(vec3(-20.5f,-0.5f,-15.5f), vec3(-20.5f,1.0f,-15.5f), 0.5f);
|
|
||||||
|
|
||||||
poly_free(&dmd);
|
|
||||||
poly_free(&pyr);
|
|
||||||
|
|
||||||
ddraw_box(gjk.p0, vec3(0.05f, 0.05f, 0.05f));
|
|
||||||
ddraw_box(gjk.p1, vec3(0.05f, 0.05f, 0.05f));
|
|
||||||
ddraw_line(gjk.p0, gjk.p1);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
// poly(Pyramid)-poly(Diamond) (GJK) intersection*/
|
|
||||||
|
|
||||||
const float x = 10 + 0.4f*sin(dx);
|
|
||||||
const float y = 3.0f*cos(dy);
|
|
||||||
const float z = -15;
|
|
||||||
|
|
||||||
poly dmd = diamond(vec3(x,y-0.5f,z), vec3(x,y+1,z), 0.5f);
|
|
||||||
poly pyr = pyramid(vec3(10.5f,-0.5f,-15.5f), vec3(10.5f,1.0f,-15.5f), 1.0f);
|
|
||||||
|
|
||||||
gjk_result gjk;
|
|
||||||
if (poly_hit_poly(&gjk, dmd, pyr))
|
|
||||||
ddraw_color(RED);
|
|
||||||
else ddraw_color(WHITE);
|
|
||||||
|
|
||||||
ddraw_diamond(vec3(x,y-0.5f,z), vec3(x,y+1,z), 0.5f);
|
|
||||||
ddraw_pyramid(vec3(10.5f,-0.5f,-15.5f), 0.5f/*vec3(10.5f,1.0f,-15.5f)*/, 1.0f);
|
|
||||||
|
|
||||||
poly_free(&dmd);
|
|
||||||
poly_free(&pyr);
|
|
||||||
|
|
||||||
ddraw_box(gjk.p0, vec3(0.05f, 0.05f, 0.05f));
|
|
||||||
ddraw_box(gjk.p1, vec3(0.05f, 0.05f, 0.05f));
|
|
||||||
ddraw_line(gjk.p0, gjk.p1);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
// poly(Diamond)-AABB (GJK) intersection*/
|
|
||||||
|
|
||||||
const float x = 20 + 0.4f*sin(dx);
|
|
||||||
const float y = 3.0f*cos(dy);
|
|
||||||
const float z = -15;
|
|
||||||
|
|
||||||
poly dmd = diamond(vec3(x,y-0.5f,z), vec3(x,y+1,z), 0.5f);
|
|
||||||
aabb a = aabb(vec3(19.5f,-0.5f,-14.5f), vec3(20.5f,0.5f,-15.5f));
|
|
||||||
|
|
||||||
gjk_result gjk;
|
|
||||||
if (poly_hit_aabb(&gjk, dmd, a))
|
|
||||||
ddraw_color(RED);
|
|
||||||
else ddraw_color(WHITE);
|
|
||||||
|
|
||||||
poly_free(&dmd);
|
|
||||||
|
|
||||||
ddraw_diamond(vec3(x,y-0.5f,z), vec3(x,y+1,z), 0.5f);
|
|
||||||
ddraw_box(vec3(20,0,-15), vec3(1,1,1));
|
|
||||||
|
|
||||||
ddraw_box(gjk.p0, vec3(0.05f, 0.05f, 0.05f));
|
|
||||||
ddraw_box(gjk.p1, vec3(0.05f, 0.05f, 0.05f));
|
|
||||||
ddraw_line(gjk.p0, gjk.p1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,44 +3,6 @@
|
||||||
// [src] https://gist.github.com/vurtun/95f088e4889da2474ad1ce82d7911fee
|
// [src] https://gist.github.com/vurtun/95f088e4889da2474ad1ce82d7911fee
|
||||||
// - rlyeh, public domain.
|
// - rlyeh, public domain.
|
||||||
|
|
||||||
#ifndef GJK_H
|
|
||||||
#define GJK_H
|
|
||||||
|
|
||||||
#define GJK_MAX_ITERATIONS 20
|
|
||||||
|
|
||||||
typedef struct gjk_support {
|
|
||||||
int aid, bid;
|
|
||||||
vec3 a;
|
|
||||||
vec3 b;
|
|
||||||
} gjk_support;
|
|
||||||
typedef struct gjk_vertex {
|
|
||||||
vec3 a;
|
|
||||||
vec3 b;
|
|
||||||
vec3 p;
|
|
||||||
int aid, bid;
|
|
||||||
} gjk_vertex;
|
|
||||||
typedef struct gjk_simplex {
|
|
||||||
int max_iter, iter;
|
|
||||||
int hit, cnt;
|
|
||||||
gjk_vertex v[4];
|
|
||||||
float bc[4], D;
|
|
||||||
} gjk_simplex;
|
|
||||||
typedef struct gjk_result {
|
|
||||||
int hit;
|
|
||||||
vec3 p0;
|
|
||||||
vec3 p1;
|
|
||||||
float distance_squared;
|
|
||||||
int iterations;
|
|
||||||
} gjk_result;
|
|
||||||
|
|
||||||
int gjk(gjk_simplex *s, const gjk_support *sup, vec3 *dv);
|
|
||||||
gjk_result gjk_analyze(const gjk_simplex *s);
|
|
||||||
gjk_result gjk_quad(float a_radius, float b_radius);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//typedef struct gjk_result gjk_result;
|
|
||||||
|
|
||||||
typedef struct line { vec3 a, b; } line;
|
typedef struct line { vec3 a, b; } line;
|
||||||
typedef struct sphere { vec3 c; float r; } sphere;
|
typedef struct sphere { vec3 c; float r; } sphere;
|
||||||
typedef struct aabb { vec3 min, max; } aabb;
|
typedef struct aabb { vec3 min, max; } aabb;
|
||||||
|
@ -48,7 +10,6 @@ typedef struct plane { vec3 p, n;
|
||||||
typedef struct capsule { vec3 a, b; float r; } capsule;
|
typedef struct capsule { vec3 a, b; float r; } capsule;
|
||||||
typedef struct ray { vec3 p, d; } ray;
|
typedef struct ray { vec3 p, d; } ray;
|
||||||
typedef struct triangle { vec3 p0,p1,p2; } triangle;
|
typedef struct triangle { vec3 p0,p1,p2; } triangle;
|
||||||
typedef struct poly { vec3* verts; int cnt; } poly;
|
|
||||||
typedef union frustum { struct { vec4 l, r, t, b, n, f; }; vec4 pl[6]; float v[24]; } frustum;
|
typedef union frustum { struct { vec4 l, r, t, b, n, f; }; vec4 pl[6]; float v[24]; } frustum;
|
||||||
|
|
||||||
#define line(...) C_CAST(line, __VA_ARGS__)
|
#define line(...) C_CAST(line, __VA_ARGS__)
|
||||||
|
@ -58,7 +19,6 @@ typedef union frustum { struct { vec4 l, r, t, b, n, f; }; vec4 pl[6]; float v
|
||||||
#define capsule(...) C_CAST(capsule, __VA_ARGS__)
|
#define capsule(...) C_CAST(capsule, __VA_ARGS__)
|
||||||
#define ray(p,normdir) C_CAST(ray, p, normdir)
|
#define ray(p,normdir) C_CAST(ray, p, normdir)
|
||||||
#define triangle(...) C_CAST(triangle, __VA_ARGS__)
|
#define triangle(...) C_CAST(triangle, __VA_ARGS__)
|
||||||
#define poly(...) C_CAST(poly, __VA_ARGS__)
|
|
||||||
#define frustum(...) C_CAST(frustum, __VA_ARGS__)
|
#define frustum(...) C_CAST(frustum, __VA_ARGS__)
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -99,7 +59,6 @@ API hit* sphere_hit_capsule(sphere s, capsule c);
|
||||||
API hit* sphere_hit_sphere(sphere a, sphere b);
|
API hit* sphere_hit_sphere(sphere a, sphere b);
|
||||||
API int sphere_test_aabb(sphere s, aabb a);
|
API int sphere_test_aabb(sphere s, aabb a);
|
||||||
API int sphere_test_capsule(sphere s, capsule c);
|
API int sphere_test_capsule(sphere s, capsule c);
|
||||||
API int sphere_test_poly(sphere s, poly p);
|
|
||||||
API int sphere_test_sphere(sphere a, sphere b);
|
API int sphere_test_sphere(sphere a, sphere b);
|
||||||
/* aabb */
|
/* aabb */
|
||||||
API vec3 aabb_closest_point(aabb a, vec3 p);
|
API vec3 aabb_closest_point(aabb a, vec3 p);
|
||||||
|
@ -110,7 +69,6 @@ API hit* aabb_hit_capsule(aabb a, capsule c);
|
||||||
API hit* aabb_hit_sphere(aabb a, sphere s);
|
API hit* aabb_hit_sphere(aabb a, sphere s);
|
||||||
API int aabb_test_aabb(aabb a, aabb b);
|
API int aabb_test_aabb(aabb a, aabb b);
|
||||||
API int aabb_test_capsule(aabb a, capsule c);
|
API int aabb_test_capsule(aabb a, capsule c);
|
||||||
API int aabb_test_poly(aabb a, poly p);
|
|
||||||
API int aabb_test_sphere(aabb a, sphere s);
|
API int aabb_test_sphere(aabb a, sphere s);
|
||||||
/* capsule */
|
/* capsule */
|
||||||
API float capsule_distance2_point(capsule c, vec3 p);
|
API float capsule_distance2_point(capsule c, vec3 p);
|
||||||
|
@ -120,28 +78,7 @@ API hit* capsule_hit_capsule(capsule a, capsule b);
|
||||||
API hit* capsule_hit_sphere(capsule c, sphere s);
|
API hit* capsule_hit_sphere(capsule c, sphere s);
|
||||||
API int capsule_test_aabb(capsule c, aabb a);
|
API int capsule_test_aabb(capsule c, aabb a);
|
||||||
API int capsule_test_capsule(capsule a, capsule b);
|
API int capsule_test_capsule(capsule a, capsule b);
|
||||||
API int capsule_test_poly(capsule c, poly p);
|
|
||||||
API int capsule_test_sphere(capsule c, sphere s);
|
API int capsule_test_sphere(capsule c, sphere s);
|
||||||
/* poly: query */
|
|
||||||
API int poly_test_sphere(poly p, sphere s);
|
|
||||||
API int poly_test_aabb(poly p, aabb a);
|
|
||||||
API int poly_test_capsule(poly p, capsule c);
|
|
||||||
API int poly_test_poly(poly a, poly b);
|
|
||||||
/* poly: query transformed */
|
|
||||||
API int poly_test_sphere_transform(poly p, vec3 pos3, mat33 rot33, sphere s);
|
|
||||||
API int poly_test_aabb_transform(poly p, vec3 apos3, mat33 arot33, aabb a);
|
|
||||||
API int poly_test_capsule_transform(poly p, vec3 pos3, mat33 rot33, capsule c);
|
|
||||||
API int poly_test_poly_transform(poly a, vec3 apos3, mat33 arot33, poly b, vec3 bpos3, mat33 brot33);
|
|
||||||
/* poly: gjk result */
|
|
||||||
API int poly_hit_sphere(struct gjk_result *res, poly p, sphere s);
|
|
||||||
API int poly_hit_aabb(struct gjk_result *res, poly p, aabb a);
|
|
||||||
API int poly_hit_capsule(struct gjk_result *res, poly p, capsule c);
|
|
||||||
API int poly_hit_poly(struct gjk_result *res, poly a, poly b);
|
|
||||||
/* poly: gjk result transformed */
|
|
||||||
API int poly_hit_sphere_transform(struct gjk_result *res, poly p, vec3 pos3, mat33 rot33, sphere s);
|
|
||||||
API int poly_hit_aabb_transform(struct gjk_result *res, poly p, vec3 pos3, mat33 rot33, aabb a);
|
|
||||||
API int poly_hit_capsule_transform(struct gjk_result *res, poly p, vec3 pos3, mat33 rot33, capsule c);
|
|
||||||
API int poly_hit_poly_transform(struct gjk_result *res, poly a, vec3 at3, mat33 ar33, poly b, vec3 bt3, mat33 br33);
|
|
||||||
|
|
||||||
API vec4 plane4(vec3 p, vec3 n);
|
API vec4 plane4(vec3 p, vec3 n);
|
||||||
|
|
||||||
|
@ -149,10 +86,4 @@ API frustum frustum_build(mat44 projview);
|
||||||
API int frustum_test_sphere(frustum f, sphere s);
|
API int frustum_test_sphere(frustum f, sphere s);
|
||||||
API int frustum_test_aabb(frustum f, aabb a);
|
API int frustum_test_aabb(frustum f, aabb a);
|
||||||
|
|
||||||
API poly poly_alloc(int cnt);
|
|
||||||
API void poly_free(poly *p);
|
|
||||||
|
|
||||||
API poly pyramid(vec3 from, vec3 to, float size); // poly_free() required
|
|
||||||
API poly diamond(vec3 from, vec3 to, float size); // poly_free() required
|
|
||||||
|
|
||||||
API void collide_demo(); // debug draw collisions
|
API void collide_demo(); // debug draw collisions
|
||||||
|
|
|
@ -301,7 +301,7 @@
|
||||||
static void fn(void)
|
static void fn(void)
|
||||||
#elif defined __TINYC__ // tcc...
|
#elif defined __TINYC__ // tcc...
|
||||||
#define AUTORUN_(fn) \
|
#define AUTORUN_(fn) \
|
||||||
__attribute__((constructor)) \
|
__attribute((constructor)) \
|
||||||
static void fn(void)
|
static void fn(void)
|
||||||
#else // gcc,clang,clang-cl...
|
#else // gcc,clang,clang-cl...
|
||||||
#define AUTORUN_(fn) \
|
#define AUTORUN_(fn) \
|
||||||
|
|
|
@ -391,7 +391,7 @@ API void (set_clear)(set* m);
|
||||||
// aliases:
|
// aliases:
|
||||||
|
|
||||||
#ifndef map_init_int
|
#ifndef map_init_int
|
||||||
#define map_init_int(m) map_init((m), less_int, hash_64) // hash_int
|
#define map_init_int(m) map_init((m), less_int, hash_int) // hash_64
|
||||||
#define map_init_str(m) map_init((m), less_str, hash_str)
|
#define map_init_str(m) map_init((m), less_str, hash_str)
|
||||||
#define map_init_ptr(m) map_init((m), less_ptr, hash_ptr)
|
#define map_init_ptr(m) map_init((m), less_ptr, hash_ptr)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -613,7 +613,7 @@ void editor_frame( void (*game)(unsigned, float, double) ) {
|
||||||
UI_MENU_ITEM(ICON_SKIP, editor_send(window_has_pause() ? "frame" : "slomo")) \
|
UI_MENU_ITEM(ICON_SKIP, editor_send(window_has_pause() ? "frame" : "slomo")) \
|
||||||
UI_MENU_ITEM(ICON_MDI_STOP, editor_send("stop")) \
|
UI_MENU_ITEM(ICON_MDI_STOP, editor_send("stop")) \
|
||||||
UI_MENU_ITEM(ICON_MDI_EJECT, editor_send("eject")) \
|
UI_MENU_ITEM(ICON_MDI_EJECT, editor_send("eject")) \
|
||||||
UI_MENU_ITEM(STATS, stats_mode = (++stats_mode) % 3) \
|
UI_MENU_ITEM(STATS, stats_mode = (stats_mode+1) % 3) \
|
||||||
UI_MENU_ALIGN_RIGHT(32+32+32+32+32+32+32 + 32*2*is_borderless + 10, clicked_titlebar = time_ms()) \
|
UI_MENU_ALIGN_RIGHT(32+32+32+32+32+32+32 + 32*2*is_borderless + 10, clicked_titlebar = time_ms()) \
|
||||||
if(ingame) ui_disable(); \
|
if(ingame) ui_disable(); \
|
||||||
UI_MENU_ITEM(ICON_MD_FOLDER_SPECIAL, editor_send("browser")) \
|
UI_MENU_ITEM(ICON_MD_FOLDER_SPECIAL, editor_send("browser")) \
|
||||||
|
|
|
@ -204,8 +204,10 @@ void script_init() {
|
||||||
luaopen_string(L);
|
luaopen_string(L);
|
||||||
luaopen_math(L);
|
luaopen_math(L);
|
||||||
|
|
||||||
|
#if !is(ems)
|
||||||
// enable ffi (via luaffi)
|
// enable ffi (via luaffi)
|
||||||
luaopen_ffi(L);
|
luaopen_ffi(L);
|
||||||
|
#endif
|
||||||
|
|
||||||
// @fixme: workaround that prevents script binding on lua 5.4.3 on top of luajit 2.1.0-beta3 on linux. lua_setglobal() crashing when accessing null L->l_G
|
// @fixme: workaround that prevents script binding on lua 5.4.3 on top of luajit 2.1.0-beta3 on linux. lua_setglobal() crashing when accessing null L->l_G
|
||||||
if(L->l_G) {
|
if(L->l_G) {
|
||||||
|
|
|
@ -1591,8 +1591,8 @@ void font_color(const char *tag, uint32_t color) {
|
||||||
font_t *f = &fonts[i];
|
font_t *f = &fonts[i];
|
||||||
if( f->initialized ) {
|
if( f->initialized ) {
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glBindTexture(GL_TEXTURE_1D, f->texture_colors);
|
glBindTexture(GL_TEXTURE_2D, f->texture_colors);
|
||||||
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, FONT_MAX_COLORS, GL_RGBA, GL_UNSIGNED_BYTE, font_palette);
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, FONT_MAX_COLORS, 1, GL_RGBA, GL_UNSIGNED_BYTE, font_palette);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1879,11 +1879,11 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
|
||||||
// setup color texture
|
// setup color texture
|
||||||
glGenTextures(1, &f->texture_colors);
|
glGenTextures(1, &f->texture_colors);
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glBindTexture(GL_TEXTURE_1D, f->texture_colors);
|
glBindTexture(GL_TEXTURE_2D, f->texture_colors);
|
||||||
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, FONT_MAX_COLORS, 0, GL_RGBA, GL_UNSIGNED_BYTE, font_palette);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FONT_MAX_COLORS, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, font_palette);
|
||||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
|
||||||
// upload constant uniforms
|
// upload constant uniforms
|
||||||
glUseProgram(f->program);
|
glUseProgram(f->program);
|
||||||
|
@ -1942,7 +1942,7 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, f->texture_offsets);
|
glBindTexture(GL_TEXTURE_2D, f->texture_offsets);
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glBindTexture(GL_TEXTURE_1D, f->texture_colors);
|
glBindTexture(GL_TEXTURE_2D, f->texture_colors);
|
||||||
|
|
||||||
// update bindings
|
// update bindings
|
||||||
glBindVertexArray(f->vao);
|
glBindVertexArray(f->vao);
|
||||||
|
@ -1975,7 +1975,7 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, last_texture1);
|
glBindTexture(GL_TEXTURE_2D, last_texture1);
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glBindTexture(GL_TEXTURE_1D, last_texture2);
|
glBindTexture(GL_TEXTURE_2D, last_texture2);
|
||||||
|
|
||||||
glBindVertexArray(last_vertex_array);
|
glBindVertexArray(last_vertex_array);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ int download_file( FILE *out, const char *url ) {
|
||||||
DWORD response_size = 0;
|
DWORD response_size = 0;
|
||||||
|
|
||||||
if( out )
|
if( out )
|
||||||
for( HINTERNET session = InternetOpenA("v4k.download_file", PRE_CONFIG_INTERNET_ACCESS, NULL, INTERNET_INVALID_PORT_NUMBER, 0); session; InternetCloseHandle(session), session = 0 )
|
for( HINTERNET session = InternetOpenA("v4k.download_file", PRE_CONFIG_INTERNET_ACCESS, NULL, INTERNET_INVALID_PORT_NUMBER, 0); session; InternetCloseHandle(session), session = 0 ) // @fixme: download_file
|
||||||
for( HINTERNET request = InternetOpenUrlA(session, url, NULL, 0, INTERNET_FLAG_RELOAD, 0); request; InternetCloseHandle(request), request = 0 )
|
for( HINTERNET request = InternetOpenUrlA(session, url, NULL, 0, INTERNET_FLAG_RELOAD, 0); request; InternetCloseHandle(request), request = 0 )
|
||||||
for(; InternetReadFile(request, buffer, sizeof(buffer), &response_size) != FALSE && response_size > 0; ) {
|
for(; InternetReadFile(request, buffer, sizeof(buffer), &response_size) != FALSE && response_size > 0; ) {
|
||||||
ok = (fwrite(buffer, response_size, 1, out) == 1);
|
ok = (fwrite(buffer, response_size, 1, out) == 1);
|
||||||
|
|
|
@ -466,7 +466,7 @@ void *obj_setmeta(void *o, const char *key, const char *value) {
|
||||||
void *ret = 0;
|
void *ret = 0;
|
||||||
do_threadlock(oms_lock) {
|
do_threadlock(oms_lock) {
|
||||||
if(!oms) map_init_int(oms);
|
if(!oms) map_init_int(oms);
|
||||||
int *q = map_find_or_add(oms, intern(va("%llu-%s",obj_id((obj*)o),key)), 0);
|
int *q = map_find_or_add(oms, intern(va("%p-%s",(void*)obj_id((obj*)o),key)), 0);
|
||||||
if(!*q && !value[0]) {} else *q = intern(value);
|
if(!*q && !value[0]) {} else *q = intern(value);
|
||||||
quark(*q), ret = o;
|
quark(*q), ret = o;
|
||||||
}
|
}
|
||||||
|
@ -476,7 +476,7 @@ const char* obj_meta(const void *o, const char *key) {
|
||||||
const char *ret = 0;
|
const char *ret = 0;
|
||||||
do_threadlock(oms_lock) {
|
do_threadlock(oms_lock) {
|
||||||
if(!oms) map_init_int(oms);
|
if(!oms) map_init_int(oms);
|
||||||
int *q = map_find_or_add(oms, intern(va("%llu-%s",obj_id((obj*)o),key)), 0);
|
int *q = map_find_or_add(oms, intern(va("%p-%s",(void*)obj_id((obj*)o),key)), 0);
|
||||||
ret = quark(*q);
|
ret = quark(*q);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -582,10 +582,10 @@ void test_obj_exact(void *o1, void *o2) {
|
||||||
bool obj_hexdump(const void *oo) {
|
bool obj_hexdump(const void *oo) {
|
||||||
const obj *o = (const obj *)oo;
|
const obj *o = (const obj *)oo;
|
||||||
int header = 1 * sizeof(obj);
|
int header = 1 * sizeof(obj);
|
||||||
printf("; name[%s] type[%s] id[%d..%d] unused[%08x] sizeof[%02d] %llx\n",
|
printf("; name[%s] type[%s] id[%d..%d] unused[%08x] sizeof[%02d] %p\n",
|
||||||
obj_name(o), obj_type(o),
|
obj_name(o), obj_type(o),
|
||||||
(int)o->objid>>16, (int)o->objid&0xffff, (int)o->objunused,
|
(int)o->objid>>16, (int)o->objid&0xffff, (int)o->objunused,
|
||||||
obj_sizeof(o), o->objheader);
|
obj_sizeof(o), (void*)o->objheader);
|
||||||
return hexdump(obj_datac(o) - header, obj_size(o) + header), 1;
|
return hexdump(obj_datac(o) - header, obj_size(o) + header), 1;
|
||||||
}
|
}
|
||||||
int obj_print(const void *o) {
|
int obj_print(const void *o) {
|
||||||
|
@ -633,7 +633,7 @@ const char *p2s(const char *type, void *p) {
|
||||||
else if( !strcmp(type, "unsigned") ) return itoa1(*(unsigned*)p);
|
else if( !strcmp(type, "unsigned") ) return itoa1(*(unsigned*)p);
|
||||||
else if( !strcmp(type, "float") ) return ftoa1(*(float*)p);
|
else if( !strcmp(type, "float") ) return ftoa1(*(float*)p);
|
||||||
else if( !strcmp(type, "double") ) return ftoa1(*(double*)p);
|
else if( !strcmp(type, "double") ) return ftoa1(*(double*)p);
|
||||||
else if( !strcmp(type, "uintptr_t") ) return va("%08llx", *(uintptr_t*)p);
|
else if( !strcmp(type, "uintptr_t") ) return va("%p", (void*)*(uintptr_t*)p);
|
||||||
else if( !strcmp(type, "vec2i") ) return itoa2(*(vec2i*)p);
|
else if( !strcmp(type, "vec2i") ) return itoa2(*(vec2i*)p);
|
||||||
else if( !strcmp(type, "vec3i") ) return itoa3(*(vec3i*)p);
|
else if( !strcmp(type, "vec3i") ) return itoa3(*(vec3i*)p);
|
||||||
else if( !strcmp(type, "vec2") ) return ftoa2(*(vec2*)p);
|
else if( !strcmp(type, "vec2") ) return ftoa2(*(vec2*)p);
|
||||||
|
|
|
@ -206,6 +206,7 @@ void renderstate_apply(const renderstate_t *state) {
|
||||||
glDisable(GL_LINE_SMOOTH);
|
glDisable(GL_LINE_SMOOTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !is(ems)
|
||||||
// Apply point size
|
// Apply point size
|
||||||
if (state->point_size_enabled) {
|
if (state->point_size_enabled) {
|
||||||
glEnable(GL_PROGRAM_POINT_SIZE);
|
glEnable(GL_PROGRAM_POINT_SIZE);
|
||||||
|
@ -216,6 +217,7 @@ void renderstate_apply(const renderstate_t *state) {
|
||||||
|
|
||||||
// Apply polygon mode
|
// Apply polygon mode
|
||||||
glPolygonMode(state->polygon_mode_face, state->polygon_mode_draw);
|
glPolygonMode(state->polygon_mode_face, state->polygon_mode_draw);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Apply scissor test
|
// Apply scissor test
|
||||||
if (state->scissor_test_enabled) {
|
if (state->scissor_test_enabled) {
|
||||||
|
@ -272,13 +274,22 @@ static inline
|
||||||
char *shader_preprocess(const char *src, const char *defines) {
|
char *shader_preprocess(const char *src, const char *defines) {
|
||||||
if (!src) return NULL;
|
if (!src) return NULL;
|
||||||
|
|
||||||
const char *glsl_version = va("#version %s", ifdef(ems, "300 es", "150"));
|
const char *gles = "#version 300 es\n"
|
||||||
|
"#define textureQueryLod(t,uv) vec2(0.,0.)\n" // "#extension GL_EXT_texture_query_lod : enable\n"
|
||||||
|
"#define MEDIUMP mediump\n"
|
||||||
|
"precision MEDIUMP float;\n";
|
||||||
|
const char *desktop = strstr(src, "textureQueryLod") ? "#version 400\n#define MEDIUMP\n" : "#version 330\n#define MEDIUMP\n";
|
||||||
|
const char *glsl_version = ifdef(ems, gles, desktop);
|
||||||
|
|
||||||
// detect GLSL version if set
|
// detect GLSL version if set
|
||||||
if (src[0] == '#' && src[1] == 'v') {
|
if (src[0] == '#' && src[1] == 'v') {
|
||||||
|
#if 0
|
||||||
const char *end = strstri(src, "\n");
|
const char *end = strstri(src, "\n");
|
||||||
glsl_version = va("%.*s", (int)(end-src), src);
|
glsl_version = va("%.*s", (int)(end-src), src);
|
||||||
src = end+1;
|
src = end+1;
|
||||||
|
#else
|
||||||
|
PANIC("!ERROR: shader with #version specified on it. we do not support this anymore.");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return va("%s\n%s\n%s", glsl_version, defines ? defines : "", src);
|
return va("%s\n%s\n%s", glsl_version, defines ? defines : "", src);
|
||||||
|
@ -299,16 +310,6 @@ unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char
|
||||||
vs = shader_preprocess(vs, glsl_defines);
|
vs = shader_preprocess(vs, glsl_defines);
|
||||||
fs = shader_preprocess(fs, glsl_defines);
|
fs = shader_preprocess(fs, glsl_defines);
|
||||||
|
|
||||||
#if is(ems)
|
|
||||||
{
|
|
||||||
char *vs_ = REALLOC( 0, strlen(vs) + 512 ); strcpy(vs_, vs);
|
|
||||||
char *fs_ = REALLOC( 0, strlen(fs) + 512 ); strcpy(fs_, fs);
|
|
||||||
char *gs_ = 0; if (gs) REALLOC( 0, strlen(gs) + 512 ); strcpy(gs_, gs);
|
|
||||||
strrepl(&fs_, "#version 300 es\n", "#version 300 es\nprecision mediump float;\n");
|
|
||||||
vs = vs_; fs = fs_; gs = gs_;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GLuint vert = shader_compile(GL_VERTEX_SHADER, vs);
|
GLuint vert = shader_compile(GL_VERTEX_SHADER, vs);
|
||||||
GLuint frag = shader_compile(GL_FRAGMENT_SHADER, fs);
|
GLuint frag = shader_compile(GL_FRAGMENT_SHADER, fs);
|
||||||
GLuint geom = 0; if (gs) geom = shader_compile(GL_GEOMETRY_SHADER, gs);
|
GLuint geom = 0; if (gs) geom = shader_compile(GL_GEOMETRY_SHADER, gs);
|
||||||
|
@ -719,7 +720,6 @@ static inline void shader_cubemap_(int sampler, unsigned texture) {
|
||||||
static inline void shader_bool_(int uniform, bool x) { glUniform1i(uniform, x); }
|
static inline void shader_bool_(int uniform, bool x) { glUniform1i(uniform, x); }
|
||||||
static inline void shader_uint_(int uniform, unsigned x ) { glUniform1ui(uniform, x); }
|
static inline void shader_uint_(int uniform, unsigned x ) { glUniform1ui(uniform, x); }
|
||||||
static inline void shader_texture_unit_(int sampler, unsigned id, unsigned unit) {
|
static inline void shader_texture_unit_(int sampler, unsigned id, unsigned unit) {
|
||||||
// @todo. if tex.h == 1 ? GL_TEXTURE_1D : GL_TEXTURE_2D
|
|
||||||
glUniform1i(sampler, unit);
|
glUniform1i(sampler, unit);
|
||||||
glActiveTexture(GL_TEXTURE0 + unit);
|
glActiveTexture(GL_TEXTURE0 + unit);
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
|
@ -744,7 +744,6 @@ void shader_bool(const char *uniform, bool x) { glUniform1i(shader_uniform(unifo
|
||||||
void shader_uint(const char *uniform, unsigned x ) { glUniform1ui(shader_uniform(uniform), x); }
|
void shader_uint(const char *uniform, unsigned x ) { glUniform1ui(shader_uniform(uniform), x); }
|
||||||
void shader_texture(const char *sampler, texture_t t) { shader_texture_unit(sampler, t.id, texture_unit()); }
|
void shader_texture(const char *sampler, texture_t t) { shader_texture_unit(sampler, t.id, texture_unit()); }
|
||||||
void shader_texture_unit(const char *sampler, unsigned id, unsigned unit) {
|
void shader_texture_unit(const char *sampler, unsigned id, unsigned unit) {
|
||||||
// @todo. if tex.h == 1 ? GL_TEXTURE_1D : GL_TEXTURE_2D
|
|
||||||
glUniform1i(shader_uniform(sampler), unit);
|
glUniform1i(shader_uniform(sampler), unit);
|
||||||
glActiveTexture(GL_TEXTURE0 + unit);
|
glActiveTexture(GL_TEXTURE0 + unit);
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
|
@ -2789,9 +2788,7 @@ void fx_enable(int pass, int enabled) {
|
||||||
postfx_enable(&fx, pass, enabled);
|
postfx_enable(&fx, pass, enabled);
|
||||||
}
|
}
|
||||||
void fx_enable_all(int enabled) {
|
void fx_enable_all(int enabled) {
|
||||||
for( int i = 0; i < array_count(fx.pass); ++i ) {
|
for( int i = 0; i < array_count(fx.pass); ++i ) fx_enable(i, enabled);
|
||||||
fx_enable(i, enabled);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
char *fx_name(int pass) {
|
char *fx_name(int pass) {
|
||||||
return postfx_name(&fx, pass);
|
return postfx_name(&fx, pass);
|
||||||
|
|
|
@ -524,35 +524,35 @@ void ddraw_cylinder(vec3 center, float height, int segments) {
|
||||||
ddraw_prism(center, 1, -height, vec3(0,1,0), segments);
|
ddraw_prism(center, 1, -height, vec3(0,1,0), segments);
|
||||||
}
|
}
|
||||||
void ddraw_diamond(vec3 from, vec3 to, float size) {
|
void ddraw_diamond(vec3 from, vec3 to, float size) {
|
||||||
poly p = diamond(from, to, size);
|
// poly p = diamond(from, to, size);
|
||||||
vec3 *dmd = p.verts;
|
// vec3 *dmd = p.verts;
|
||||||
|
|
||||||
vec3 *a = dmd + 0;
|
// vec3 *a = dmd + 0;
|
||||||
vec3 *b = dmd + 1;
|
// vec3 *b = dmd + 1;
|
||||||
vec3 *c = dmd + 2;
|
// vec3 *c = dmd + 2;
|
||||||
vec3 *d = dmd + 3;
|
// vec3 *d = dmd + 3;
|
||||||
vec3 *t = dmd + 4;
|
// vec3 *t = dmd + 4;
|
||||||
vec3 *f = dmd + 5;
|
// vec3 *f = dmd + 5;
|
||||||
|
|
||||||
/* draw vertices */
|
// /* draw vertices */
|
||||||
ddraw_line(*a, *b);
|
// ddraw_line(*a, *b);
|
||||||
ddraw_line(*b, *c);
|
// ddraw_line(*b, *c);
|
||||||
ddraw_line(*c, *d);
|
// ddraw_line(*c, *d);
|
||||||
ddraw_line(*d, *a);
|
// ddraw_line(*d, *a);
|
||||||
|
|
||||||
/* draw roof */
|
// /* draw roof */
|
||||||
ddraw_line(*a, *t);
|
// ddraw_line(*a, *t);
|
||||||
ddraw_line(*b, *t);
|
// ddraw_line(*b, *t);
|
||||||
ddraw_line(*c, *t);
|
// ddraw_line(*c, *t);
|
||||||
ddraw_line(*d, *t);
|
// ddraw_line(*d, *t);
|
||||||
|
|
||||||
/* draw floor */
|
// /* draw floor */
|
||||||
ddraw_line(*a, *f);
|
// ddraw_line(*a, *f);
|
||||||
ddraw_line(*b, *f);
|
// ddraw_line(*b, *f);
|
||||||
ddraw_line(*c, *f);
|
// ddraw_line(*c, *f);
|
||||||
ddraw_line(*d, *f);
|
// ddraw_line(*d, *f);
|
||||||
|
|
||||||
poly_free(&p);
|
// poly_free(&p);
|
||||||
}
|
}
|
||||||
void ddraw_cone(vec3 center, vec3 top, float radius) {
|
void ddraw_cone(vec3 center, vec3 top, float radius) {
|
||||||
vec3 diff3 = sub3(top, center);
|
vec3 diff3 = sub3(top, center);
|
||||||
|
|
|
@ -237,20 +237,27 @@ static char **backtrace_symbols(void *const *sym,int num) { return 0; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *callstack( int traces ) {
|
char *callstack( int traces ) {
|
||||||
static __thread char *output = 0;
|
#if is(tcc) && is(linux)
|
||||||
if(!output ) output = SYS_MEM_REALLOC( 0, 128 * (64+2) );
|
return "";
|
||||||
if( output ) output[0] = '\0';
|
#endif
|
||||||
char *ptr = output;
|
#if is(ems) // there is a stack overflow failure somewhere in the impl below
|
||||||
|
static char empty[1]; return empty[0] = '\0', empty;
|
||||||
|
#endif
|
||||||
|
|
||||||
enum { skip = 1 }; /* exclude 1 trace from stack (this function) */
|
enum { skip = 1 }; /* exclude 1 trace from stack (this function) */
|
||||||
enum { maxtraces = 128 };
|
enum { maxtraces = 96 };
|
||||||
|
|
||||||
|
static __thread char *output = 0;
|
||||||
|
if(!output ) output = SYS_MEM_REALLOC( 0, maxtraces * (128+2) );
|
||||||
|
if( output ) output[0] = '\0';
|
||||||
|
char *ptr = output;
|
||||||
|
|
||||||
int inc = 1;
|
int inc = 1;
|
||||||
if( traces < 0 ) traces = -traces, inc = -1;
|
if( traces < 0 ) traces = -traces, inc = -1;
|
||||||
if( traces == 0 ) return "";
|
if( traces == 0 ) return "";
|
||||||
if( traces > maxtraces ) traces = maxtraces;
|
if( traces > maxtraces ) traces = maxtraces;
|
||||||
|
|
||||||
void* stacks[maxtraces/* + 1*/]; // = { 0 };
|
void* stacks[maxtraces + 1]; stacks[maxtraces] = NULL; // = { 0 };
|
||||||
traces = backtrace( stacks, traces );
|
traces = backtrace( stacks, traces );
|
||||||
char **symbols = backtrace_symbols( stacks, traces ); // @todo: optimization: map(void*,char*) cache; and retrieve only symbols not in cache
|
char **symbols = backtrace_symbols( stacks, traces ); // @todo: optimization: map(void*,char*) cache; and retrieve only symbols not in cache
|
||||||
|
|
||||||
|
@ -282,10 +289,11 @@ char *callstack( int traces ) {
|
||||||
ifdef(cpp, __cxa_demangle(info.dli_sname, NULL, 0, NULL), info.dli_sname);
|
ifdef(cpp, __cxa_demangle(info.dli_sname, NULL, 0, NULL), info.dli_sname);
|
||||||
strcpy( demangled, dmgbuf ? dmgbuf : info.dli_sname );
|
strcpy( demangled, dmgbuf ? dmgbuf : info.dli_sname );
|
||||||
symbols[i] = demangled;
|
symbols[i] = demangled;
|
||||||
if( dmgbuf ) free( (void*)dmgbuf );
|
ifdef(cpp, dmgbuf && free( (void*)dmgbuf ) );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ptr += sprintf(ptr, "%03d: %#016llx %s\n", ++L, (unsigned long long)(uintptr_t)stacks[i], symbols[i]); // format gymnastics because %p is not standard when printing pointers
|
if( symbols[i] )
|
||||||
|
ptr += sprintf(ptr, "%03d: %p %s\n", ++L, (void*)(uintptr_t)stacks[i], symbols[i]); // format gymnastics because %p is not standard when printing pointers
|
||||||
}
|
}
|
||||||
|
|
||||||
#if is(linux) || is(osx)
|
#if is(linux) || is(osx)
|
||||||
|
|
|
@ -2194,7 +2194,7 @@ int ui_unsigned2(const char *label, unsigned *v) {
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
char *buffer = ui_num_signs ?
|
char *buffer = ui_num_signs ?
|
||||||
--ui_num_signs, va("%+2u %+2u", v[0], v[1]) :
|
--ui_num_signs, va("+%2u +%2u", v[0], v[1]) :
|
||||||
va("%2u, %2u", v[0], v[1]);
|
va("%2u, %2u", v[0], v[1]);
|
||||||
|
|
||||||
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
||||||
|
@ -2213,7 +2213,7 @@ int ui_unsigned3(const char *label, unsigned *v) {
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
char *buffer = ui_num_signs ?
|
char *buffer = ui_num_signs ?
|
||||||
--ui_num_signs, va("%+2u %+2u %+2u", v[0], v[1], v[2]) :
|
--ui_num_signs, va("+%2u +%2u +%2u", v[0], v[1], v[2]) :
|
||||||
va("%2u, %2u, %2u", v[0], v[1], v[2]);
|
va("%2u, %2u, %2u", v[0], v[1], v[2]);
|
||||||
|
|
||||||
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
||||||
|
|
|
@ -286,21 +286,21 @@ bool window_create_from_handle(void *handle, float scale, unsigned flags) {
|
||||||
if( flag("--fullscreen") ) scale = 100;
|
if( flag("--fullscreen") ) scale = 100;
|
||||||
scale = (scale < 1 ? scale * 100 : scale);
|
scale = (scale < 1 ? scale * 100 : scale);
|
||||||
|
|
||||||
bool FLAGS_FULLSCREEN = scale > 101;
|
bool FLAGS_FULLSCREEN = scale > 100;
|
||||||
bool FLAGS_FULLSCREEN_BORDERLESS = scale == 101;
|
|
||||||
bool FLAGS_FULLSCREEN_DESKTOP = scale == 100;
|
bool FLAGS_FULLSCREEN_DESKTOP = scale == 100;
|
||||||
bool FLAGS_WINDOWED = scale < 100 || FLAGS_FULLSCREEN_BORDERLESS;
|
bool FLAGS_WINDOWED = scale < 100;
|
||||||
flags |= FLAGS_FULLSCREEN_BORDERLESS == 1 ? WINDOW_BORDERLESS : 0;
|
|
||||||
bool FLAGS_TRANSPARENT = flag("--transparent") || (flags & WINDOW_TRANSPARENT);
|
bool FLAGS_TRANSPARENT = flag("--transparent") || (flags & WINDOW_TRANSPARENT);
|
||||||
if( FLAGS_TRANSPARENT ) FLAGS_FULLSCREEN = 0, FLAGS_FULLSCREEN_DESKTOP = 0, FLAGS_WINDOWED = 1;
|
if( FLAGS_TRANSPARENT ) FLAGS_FULLSCREEN = 0, FLAGS_FULLSCREEN_DESKTOP = 0, FLAGS_WINDOWED = 1;
|
||||||
scale = (scale > 100 ? 100 : scale) / 100.f;
|
scale = (scale > 100 ? 100 : scale) / 100.f;
|
||||||
int winWidth = window_canvas().w * scale;
|
int winWidth = window_canvas().w * scale;
|
||||||
int winHeight = window_canvas().h * scale;
|
int winHeight = window_canvas().h * scale;
|
||||||
|
|
||||||
|
/*
|
||||||
if (tests_captureframes()) {
|
if (tests_captureframes()) {
|
||||||
winWidth = 1280;
|
winWidth = 1280;
|
||||||
winHeight = 720;
|
winHeight = 720;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
window_hints(flags);
|
window_hints(flags);
|
||||||
|
|
||||||
|
|
650
engine/v4k
650
engine/v4k
|
@ -13946,7 +13946,6 @@ int gladLoadGL( GLADloadfunc load) {
|
||||||
#define BASE64_C // base64.c
|
#define BASE64_C // base64.c
|
||||||
#define COMPRESS_C // compress.c
|
#define COMPRESS_C // compress.c
|
||||||
#define ENET_IMPLEMENTATION // enet
|
#define ENET_IMPLEMENTATION // enet
|
||||||
#define GJK_C // gjk
|
|
||||||
#define _GLFW_IMPLEMENTATION // glfw337
|
#define _GLFW_IMPLEMENTATION // glfw337
|
||||||
#define GLFW_INCLUDE_NONE // glfw337
|
#define GLFW_INCLUDE_NONE // glfw337
|
||||||
#define HTTPS_IMPLEMENTATION // https
|
#define HTTPS_IMPLEMENTATION // https
|
||||||
|
@ -31228,10 +31227,6 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
|
||||||
if (window->callbacks.focus)
|
if (window->callbacks.focus)
|
||||||
window->callbacks.focus((GLFWwindow*) window, focused);
|
window->callbacks.focus((GLFWwindow*) window, focused);
|
||||||
|
|
||||||
// zak: disable top-most if we lose focus
|
|
||||||
if (window->monitor)
|
|
||||||
_glfwPlatformSetWindowFloating(window, focused);
|
|
||||||
|
|
||||||
if (!focused)
|
if (!focused)
|
||||||
{
|
{
|
||||||
int key, button;
|
int key, button;
|
||||||
|
@ -40073,8 +40068,9 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle)
|
||||||
// It is fine to use C99 in this file because it will not be built with VS
|
// It is fine to use C99 in this file because it will not be built with VS
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
|
#ifndef _GNU_SOURCE //< @r-lyeh: add missing guard
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -181849,6 +181845,10 @@ int main (int argc, char **argv) {
|
||||||
#undef cast
|
#undef cast
|
||||||
#undef G
|
#undef G
|
||||||
//---
|
//---
|
||||||
|
#if !is(ems)
|
||||||
|
#ifdef I
|
||||||
|
#undef I // complex.h
|
||||||
|
#endif
|
||||||
#define LUAFFI_C
|
#define LUAFFI_C
|
||||||
#line 1 "3rd_luaffi.h"
|
#line 1 "3rd_luaffi.h"
|
||||||
#ifndef LUAFFI_H
|
#ifndef LUAFFI_H
|
||||||
|
@ -182001,7 +182001,7 @@ static char* luaL_prepbuffsize(luaL_Buffer* B, size_t sz) {
|
||||||
# define ARCH_X86
|
# define ARCH_X86
|
||||||
#elif defined __amd64__ || defined _M_X64
|
#elif defined __amd64__ || defined _M_X64
|
||||||
# define ARCH_X64
|
# define ARCH_X64
|
||||||
#elif defined __arm__ || defined __ARM__ || defined ARM || defined __ARM || defined __arm || defined __arm64__
|
#elif defined __arm__ || defined __ARM__ || defined ARM || defined __ARM || defined __arm
|
||||||
# define ARCH_ARM
|
# define ARCH_ARM
|
||||||
#elif defined OS_LINUX && defined __TINYC__ //< @r-lyeh: tcc+linux
|
#elif defined OS_LINUX && defined __TINYC__ //< @r-lyeh: tcc+linux
|
||||||
# define ARCH_X64 //< @r-lyeh: tcc+linux
|
# define ARCH_X64 //< @r-lyeh: tcc+linux
|
||||||
|
@ -194368,6 +194368,7 @@ int luaopen_ffi(lua_State* L)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#line 0
|
#line 0
|
||||||
|
#endif
|
||||||
//---
|
//---
|
||||||
#line 1 "3rd_stb_image.h"
|
#line 1 "3rd_stb_image.h"
|
||||||
/* stb_image - v2.28 - public domain image loader - http://nothings.org/stb
|
/* stb_image - v2.28 - public domain image loader - http://nothings.org/stb
|
||||||
|
@ -235952,615 +235953,6 @@ int main() {
|
||||||
|
|
||||||
#endif // JSON5_C
|
#endif // JSON5_C
|
||||||
#line 0
|
#line 0
|
||||||
#line 1 "3rd_gjk.h"
|
|
||||||
// GJK distance algorithm. original code by @vurtun and @randygaul, public domain.
|
|
||||||
// [src] https://gist.github.com/vurtun/29727217c269a2fbf4c0ed9a1d11cb40
|
|
||||||
// - rlyeh, public domain.
|
|
||||||
|
|
||||||
/*
|
|
||||||
Gilbert–Johnson–Keerthi (GJK) 3D distance algorithm
|
|
||||||
The Gilbert–Johnson–Keerthi (GJK) distance algorithm is a method of determining
|
|
||||||
the minimum distance between two convex sets. The algorithm's stability, speed
|
|
||||||
which operates in near-constant time, and small storage footprint make it
|
|
||||||
popular for realtime collision detection.
|
|
||||||
|
|
||||||
Unlike many other distance algorithms, it has no requirments on geometry data
|
|
||||||
to be stored in any specific format, but instead relies solely on a support
|
|
||||||
function to iteratively generate closer simplices to the correct answer using
|
|
||||||
the Minkowski sum (CSO) of two convex shapes.
|
|
||||||
|
|
||||||
GJK algorithms are used incrementally. In this mode, the final simplex from a
|
|
||||||
previous solution is used as the initial guess in the next iteration. If the
|
|
||||||
positions in the new frame are close to those in the old frame, the algorithm
|
|
||||||
will converge in one or two iterations.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef GJK_H
|
|
||||||
#define GJK_H
|
|
||||||
|
|
||||||
#define GJK_MAX_ITERATIONS 20
|
|
||||||
|
|
||||||
typedef struct gjk_support {
|
|
||||||
int aid, bid;
|
|
||||||
vec3 a;
|
|
||||||
vec3 b;
|
|
||||||
} gjk_support;
|
|
||||||
typedef struct gjk_vertex {
|
|
||||||
vec3 a;
|
|
||||||
vec3 b;
|
|
||||||
vec3 p;
|
|
||||||
int aid, bid;
|
|
||||||
} gjk_vertex;
|
|
||||||
typedef struct gjk_simplex {
|
|
||||||
int max_iter, iter;
|
|
||||||
int hit, cnt;
|
|
||||||
gjk_vertex v[4];
|
|
||||||
float bc[4], D;
|
|
||||||
} gjk_simplex;
|
|
||||||
typedef struct gjk_result {
|
|
||||||
int hit;
|
|
||||||
vec3 p0;
|
|
||||||
vec3 p1;
|
|
||||||
float distance_squared;
|
|
||||||
int iterations;
|
|
||||||
} gjk_result;
|
|
||||||
|
|
||||||
int gjk(gjk_simplex *s, const gjk_support *sup, vec3 *dv);
|
|
||||||
gjk_result gjk_analyze(const gjk_simplex *s);
|
|
||||||
gjk_result gjk_quad(float a_radius, float b_radius);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GJK_C
|
|
||||||
//#pragma once
|
|
||||||
#include <math.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#define GJK_FLT_MAX FLT_MAX // 3.40282347E+38F
|
|
||||||
#define GJK_EPSILON FLT_EPSILON // 1.19209290E-07F
|
|
||||||
|
|
||||||
float gjk_inv_sqrt(float n) {
|
|
||||||
union {unsigned u; float f;} conv; conv.f = n;
|
|
||||||
conv.u = 0x5f375A84 - (conv.u >> 1);
|
|
||||||
conv.f = conv.f * (1.5f - (n * 0.5f * conv.f * conv.f));
|
|
||||||
return conv.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
int gjk(gjk_simplex *s, const gjk_support *sup, vec3 *dv) {
|
|
||||||
assert(s);
|
|
||||||
assert(dv);
|
|
||||||
assert(sup);
|
|
||||||
if (!s || !sup || !dv) return 0;
|
|
||||||
if (s->max_iter > 0 && s->iter >= s->max_iter)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* I.) Initialize */
|
|
||||||
if (s->cnt == 0) {
|
|
||||||
s->D = GJK_FLT_MAX;
|
|
||||||
s->max_iter = !s->max_iter ? GJK_MAX_ITERATIONS: s->max_iter;
|
|
||||||
}
|
|
||||||
/* II.) Check for duplications */
|
|
||||||
for (int i = 0; i < s->cnt; ++i) {
|
|
||||||
if (sup->aid != s->v[i].aid) continue;
|
|
||||||
if (sup->bid != s->v[i].bid) continue;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* III.) Add vertex into simplex */
|
|
||||||
gjk_vertex *vert = &s->v[s->cnt];
|
|
||||||
vert->a = sup->a;
|
|
||||||
vert->b = sup->b;
|
|
||||||
vert->p = *dv;
|
|
||||||
vert->aid = sup->aid;
|
|
||||||
vert->bid = sup->bid;
|
|
||||||
s->bc[s->cnt++] = 1.0f;
|
|
||||||
|
|
||||||
/* IV.) Find closest simplex point */
|
|
||||||
switch (s->cnt) {
|
|
||||||
case 1: break;
|
|
||||||
case 2: {
|
|
||||||
/* -------------------- Line ----------------------- */
|
|
||||||
vec3 a = s->v[0].p;
|
|
||||||
vec3 b = s->v[1].p;
|
|
||||||
|
|
||||||
/* compute barycentric coordinates */
|
|
||||||
vec3 ab = sub3(a, b);
|
|
||||||
vec3 ba = sub3(b, a);
|
|
||||||
|
|
||||||
float u = dot3(b, ba);
|
|
||||||
float v = dot3(a, ab);
|
|
||||||
if (v <= 0.0f) {
|
|
||||||
/* region A */
|
|
||||||
s->bc[0] = 1.0f;
|
|
||||||
s->cnt = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (u <= 0.0f) {
|
|
||||||
/* region B */
|
|
||||||
s->v[0] = s->v[1];
|
|
||||||
s->bc[0] = 1.0f;
|
|
||||||
s->cnt = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* region AB */
|
|
||||||
s->bc[0] = u;
|
|
||||||
s->bc[1] = v;
|
|
||||||
s->cnt = 2;
|
|
||||||
} break;
|
|
||||||
case 3: {
|
|
||||||
/* -------------------- Triangle ----------------------- */
|
|
||||||
vec3 a = s->v[0].p;
|
|
||||||
vec3 b = s->v[1].p;
|
|
||||||
vec3 c = s->v[2].p;
|
|
||||||
|
|
||||||
vec3 ab = sub3(a, b);
|
|
||||||
vec3 ba = sub3(b, a);
|
|
||||||
vec3 bc = sub3(b, c);
|
|
||||||
vec3 cb = sub3(c, b);
|
|
||||||
vec3 ca = sub3(c, a);
|
|
||||||
vec3 ac = sub3(a, c);
|
|
||||||
|
|
||||||
/* compute barycentric coordinates */
|
|
||||||
float u_ab = dot3(b, ba);
|
|
||||||
float v_ab = dot3(a, ab);
|
|
||||||
|
|
||||||
float u_bc = dot3(c, cb);
|
|
||||||
float v_bc = dot3(b, bc);
|
|
||||||
|
|
||||||
float u_ca = dot3(a, ac);
|
|
||||||
float v_ca = dot3(c, ca);
|
|
||||||
|
|
||||||
if (v_ab <= 0.0f && u_ca <= 0.0f) {
|
|
||||||
/* region A */
|
|
||||||
s->bc[0] = 1.0f;
|
|
||||||
s->cnt = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (u_ab <= 0.0f && v_bc <= 0.0f) {
|
|
||||||
/* region B */
|
|
||||||
s->v[0] = s->v[1];
|
|
||||||
s->bc[0] = 1.0f;
|
|
||||||
s->cnt = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (u_bc <= 0.0f && v_ca <= 0.0f) {
|
|
||||||
/* region C */
|
|
||||||
s->v[0] = s->v[2];
|
|
||||||
s->bc[0] = 1.0f;
|
|
||||||
s->cnt = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* calculate fractional area */
|
|
||||||
vec3 n; n = cross3(ba, ca);
|
|
||||||
vec3 n1; n1 = cross3(b, c);
|
|
||||||
vec3 n2; n2 = cross3(c, a);
|
|
||||||
vec3 n3; n3 = cross3(a, b);
|
|
||||||
|
|
||||||
float u_abc = dot3(n1, n);
|
|
||||||
float v_abc = dot3(n2, n);
|
|
||||||
float w_abc = dot3(n3, n);
|
|
||||||
|
|
||||||
if (u_ab > 0.0f && v_ab > 0.0f && w_abc <= 0.0f) {
|
|
||||||
/* region AB */
|
|
||||||
s->bc[0] = u_ab;
|
|
||||||
s->bc[1] = v_ab;
|
|
||||||
s->cnt = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (u_bc > 0.0f && v_bc > 0.0f && u_abc <= 0.0f) {
|
|
||||||
/* region BC */
|
|
||||||
s->v[0] = s->v[1];
|
|
||||||
s->v[1] = s->v[2];
|
|
||||||
s->bc[0] = u_bc;
|
|
||||||
s->bc[1] = v_bc;
|
|
||||||
s->cnt = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (u_ca > 0.0f && v_ca > 0.0f && v_abc <= 0.0f) {
|
|
||||||
/* region CA */
|
|
||||||
s->v[1] = s->v[0];
|
|
||||||
s->v[0] = s->v[2];
|
|
||||||
s->bc[0] = u_ca;
|
|
||||||
s->bc[1] = v_ca;
|
|
||||||
s->cnt = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* region ABC */
|
|
||||||
assert(u_abc > 0.0f && v_abc > 0.0f && w_abc > 0.0f);
|
|
||||||
s->bc[0] = u_abc;
|
|
||||||
s->bc[1] = v_abc;
|
|
||||||
s->bc[2] = w_abc;
|
|
||||||
s->cnt = 3;
|
|
||||||
} break;
|
|
||||||
case 4: {
|
|
||||||
/* -------------------- Tetrahedron ----------------------- */
|
|
||||||
vec3 a = s->v[0].p;
|
|
||||||
vec3 b = s->v[1].p;
|
|
||||||
vec3 c = s->v[2].p;
|
|
||||||
vec3 d = s->v[3].p;
|
|
||||||
|
|
||||||
vec3 ab = sub3(a, b);
|
|
||||||
vec3 ba = sub3(b, a);
|
|
||||||
vec3 bc = sub3(b, c);
|
|
||||||
vec3 cb = sub3(c, b);
|
|
||||||
vec3 ca = sub3(c, a);
|
|
||||||
vec3 ac = sub3(a, c);
|
|
||||||
|
|
||||||
vec3 db = sub3(d, b);
|
|
||||||
vec3 bd = sub3(b, d);
|
|
||||||
vec3 dc = sub3(d, c);
|
|
||||||
vec3 cd = sub3(c, d);
|
|
||||||
vec3 da = sub3(d, a);
|
|
||||||
vec3 ad = sub3(a, d);
|
|
||||||
|
|
||||||
/* compute barycentric coordinates */
|
|
||||||
float u_ab = dot3(b, ba);
|
|
||||||
float v_ab = dot3(a, ab);
|
|
||||||
|
|
||||||
float u_bc = dot3(c, cb);
|
|
||||||
float v_bc = dot3(b, bc);
|
|
||||||
|
|
||||||
float u_ca = dot3(a, ac);
|
|
||||||
float v_ca = dot3(c, ca);
|
|
||||||
|
|
||||||
float u_bd = dot3(d, db);
|
|
||||||
float v_bd = dot3(b, bd);
|
|
||||||
|
|
||||||
float u_dc = dot3(c, cd);
|
|
||||||
float v_dc = dot3(d, dc);
|
|
||||||
|
|
||||||
float u_ad = dot3(d, da);
|
|
||||||
float v_ad = dot3(a, ad);
|
|
||||||
|
|
||||||
/* check verticies for closest point */
|
|
||||||
if (v_ab <= 0.0f && u_ca <= 0.0f && v_ad <= 0.0f) {
|
|
||||||
/* region A */
|
|
||||||
s->bc[0] = 1.0f;
|
|
||||||
s->cnt = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (u_ab <= 0.0f && v_bc <= 0.0f && v_bd <= 0.0f) {
|
|
||||||
/* region B */
|
|
||||||
s->v[0] = s->v[1];
|
|
||||||
s->bc[0] = 1.0f;
|
|
||||||
s->cnt = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (u_bc <= 0.0f && v_ca <= 0.0f && u_dc <= 0.0f) {
|
|
||||||
/* region C */
|
|
||||||
s->v[0] = s->v[2];
|
|
||||||
s->bc[0] = 1.0f;
|
|
||||||
s->cnt = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (u_bd <= 0.0f && v_dc <= 0.0f && u_ad <= 0.0f) {
|
|
||||||
/* region D */
|
|
||||||
s->v[0] = s->v[3];
|
|
||||||
s->bc[0] = 1.0f;
|
|
||||||
s->cnt = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* calculate fractional area */
|
|
||||||
vec3 n; n = cross3(da, ba);
|
|
||||||
vec3 n1; n1 = cross3(d, b);
|
|
||||||
vec3 n2; n2 = cross3(b, a);
|
|
||||||
vec3 n3; n3 = cross3(a, d);
|
|
||||||
|
|
||||||
float u_adb = dot3(n1, n);
|
|
||||||
float v_adb = dot3(n2, n);
|
|
||||||
float w_adb = dot3(n3, n);
|
|
||||||
|
|
||||||
n = cross3(ca, da);
|
|
||||||
n1 = cross3(c, d);
|
|
||||||
n2 = cross3(d, a);
|
|
||||||
n3 = cross3(a, c);
|
|
||||||
|
|
||||||
float u_acd = dot3(n1, n);
|
|
||||||
float v_acd = dot3(n2, n);
|
|
||||||
float w_acd = dot3(n3, n);
|
|
||||||
|
|
||||||
n = cross3(bc, dc);
|
|
||||||
n1 = cross3(b, d);
|
|
||||||
n2 = cross3(d, c);
|
|
||||||
n3 = cross3(c, b);
|
|
||||||
|
|
||||||
float u_cbd = dot3(n1, n);
|
|
||||||
float v_cbd = dot3(n2, n);
|
|
||||||
float w_cbd = dot3(n3, n);
|
|
||||||
|
|
||||||
n = cross3(ba, ca);
|
|
||||||
n1 = cross3(b, c);
|
|
||||||
n2 = cross3(c, a);
|
|
||||||
n3 = cross3(a, b);
|
|
||||||
|
|
||||||
float u_abc = dot3(n1, n);
|
|
||||||
float v_abc = dot3(n2, n);
|
|
||||||
float w_abc = dot3(n3, n);
|
|
||||||
|
|
||||||
/* check edges for closest point */
|
|
||||||
if (w_abc <= 0.0f && v_adb <= 0.0f && u_ab > 0.0f && v_ab > 0.0f) {
|
|
||||||
/* region AB */
|
|
||||||
s->bc[0] = u_ab;
|
|
||||||
s->bc[1] = v_ab;
|
|
||||||
s->cnt = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (u_abc <= 0.0f && w_cbd <= 0.0f && u_bc > 0.0f && v_bc > 0.0f) {
|
|
||||||
/* region BC */
|
|
||||||
s->v[0] = s->v[1];
|
|
||||||
s->v[1] = s->v[2];
|
|
||||||
s->bc[0] = u_bc;
|
|
||||||
s->bc[1] = v_bc;
|
|
||||||
s->cnt = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (v_abc <= 0.0f && w_acd <= 0.0f && u_ca > 0.0f && v_ca > 0.0f) {
|
|
||||||
/* region CA */
|
|
||||||
s->v[1] = s->v[0];
|
|
||||||
s->v[0] = s->v[2];
|
|
||||||
s->bc[0] = u_ca;
|
|
||||||
s->bc[1] = v_ca;
|
|
||||||
s->cnt = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (v_cbd <= 0.0f && u_acd <= 0.0f && u_dc > 0.0f && v_dc > 0.0f) {
|
|
||||||
/* region DC */
|
|
||||||
s->v[0] = s->v[3];
|
|
||||||
s->v[1] = s->v[2];
|
|
||||||
s->bc[0] = u_dc;
|
|
||||||
s->bc[1] = v_dc;
|
|
||||||
s->cnt = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (v_acd <= 0.0f && w_adb <= 0.0f && u_ad > 0.0f && v_ad > 0.0f) {
|
|
||||||
/* region AD */
|
|
||||||
s->v[1] = s->v[3];
|
|
||||||
s->bc[0] = u_ad;
|
|
||||||
s->bc[1] = v_ad;
|
|
||||||
s->cnt = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (u_cbd <= 0.0f && u_adb <= 0.0f && u_bd > 0.0f && v_bd > 0.0f) {
|
|
||||||
/* region BD */
|
|
||||||
s->v[0] = s->v[1];
|
|
||||||
s->v[1] = s->v[3];
|
|
||||||
s->bc[0] = u_bd;
|
|
||||||
s->bc[1] = v_bd;
|
|
||||||
s->cnt = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* calculate fractional volume (volume can be negative!) */
|
|
||||||
float denom = dot3(cross3(cb, ab), db); // box3(cb, ab, db)
|
|
||||||
float volume = (denom == 0) ? 1.0f: 1.0f/denom;
|
|
||||||
float u_abcd = dot3(cross3(c, d), b) * volume; // box3(c, d, b)
|
|
||||||
float v_abcd = dot3(cross3(c, a), d) * volume; // box3(c, a, d)
|
|
||||||
float w_abcd = dot3(cross3(d, a), b) * volume; // box3(d, a, b)
|
|
||||||
float x_abcd = dot3(cross3(b, a), c) * volume; // box3(b, a, c)
|
|
||||||
|
|
||||||
/* check faces for closest point */
|
|
||||||
if (x_abcd <= 0.0f && u_abc > 0.0f && v_abc > 0.0f && w_abc > 0.0f) {
|
|
||||||
/* region ABC */
|
|
||||||
s->bc[0] = u_abc;
|
|
||||||
s->bc[1] = v_abc;
|
|
||||||
s->bc[2] = w_abc;
|
|
||||||
s->cnt = 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (u_abcd <= 0.0f && u_cbd > 0.0f && v_cbd > 0.0f && w_cbd > 0.0f) {
|
|
||||||
/* region CBD */
|
|
||||||
s->v[0] = s->v[2];
|
|
||||||
s->v[2] = s->v[3];
|
|
||||||
s->bc[0] = u_cbd;
|
|
||||||
s->bc[1] = v_cbd;
|
|
||||||
s->bc[2] = w_cbd;
|
|
||||||
s->cnt = 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (v_abcd <= 0.0f && u_acd > 0.0f && v_acd > 0.0f && w_acd > 0.0f) {
|
|
||||||
/* region ACD */
|
|
||||||
s->v[1] = s->v[2];
|
|
||||||
s->v[2] = s->v[3];
|
|
||||||
s->bc[0] = u_acd;
|
|
||||||
s->bc[1] = v_acd;
|
|
||||||
s->bc[2] = w_acd;
|
|
||||||
s->cnt = 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (w_abcd <= 0.0f && u_adb > 0.0f && v_adb > 0.0f && w_adb > 0.0f) {
|
|
||||||
/* region ADB */
|
|
||||||
s->v[2] = s->v[1];
|
|
||||||
s->v[1] = s->v[3];
|
|
||||||
s->bc[0] = u_adb;
|
|
||||||
s->bc[1] = v_adb;
|
|
||||||
s->bc[2] = w_adb;
|
|
||||||
s->cnt = 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* region ABCD */
|
|
||||||
// assert(u_abcd > 0.0f && v_abcd > 0.0f && w_abcd > 0.0f && x_abcd > 0.0f); // tcc+linux asserts in here: both u_abcd and v_abcd are negative
|
|
||||||
s->bc[0] = u_abcd;
|
|
||||||
s->bc[1] = v_abcd;
|
|
||||||
s->bc[2] = w_abcd;
|
|
||||||
s->bc[3] = x_abcd;
|
|
||||||
s->cnt = 4;
|
|
||||||
} break;}
|
|
||||||
|
|
||||||
/* V.) Check if origin is enclosed by tetrahedron */
|
|
||||||
if (s->cnt == 4) {
|
|
||||||
s->hit = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* VI.) Ensure closing in on origin to prevent multi-step cycling */
|
|
||||||
vec3 pnt; float denom = 0;
|
|
||||||
for (int i = 0; i < s->cnt; ++i)
|
|
||||||
denom += s->bc[i];
|
|
||||||
denom = 1.0f / denom;
|
|
||||||
|
|
||||||
switch (s->cnt) {
|
|
||||||
case 1: pnt = s->v[0].p; break;
|
|
||||||
case 2: {
|
|
||||||
/* --------- Line -------- */
|
|
||||||
vec3 a = scale3(s->v[0].p, denom * s->bc[0]);
|
|
||||||
vec3 b = scale3(s->v[1].p, denom * s->bc[1]);
|
|
||||||
pnt = add3(a, b);
|
|
||||||
} break;
|
|
||||||
case 3: {
|
|
||||||
/* ------- Triangle ------ */
|
|
||||||
vec3 a = scale3(s->v[0].p, denom * s->bc[0]);
|
|
||||||
vec3 b = scale3(s->v[1].p, denom * s->bc[1]);
|
|
||||||
vec3 c = scale3(s->v[2].p, denom * s->bc[2]);
|
|
||||||
|
|
||||||
pnt = add3(a, b);
|
|
||||||
pnt = add3(pnt, c);
|
|
||||||
} break;
|
|
||||||
case 4: {
|
|
||||||
/* ----- Tetrahedron ----- */
|
|
||||||
vec3 a = scale3(s->v[0].p, denom * s->bc[0]);
|
|
||||||
vec3 b = scale3(s->v[1].p, denom * s->bc[1]);
|
|
||||||
vec3 c = scale3(s->v[2].p, denom * s->bc[2]);
|
|
||||||
vec3 d = scale3(s->v[3].p, denom * s->bc[3]);
|
|
||||||
|
|
||||||
pnt = add3(a, b);
|
|
||||||
pnt = add3(pnt, c);
|
|
||||||
pnt = add3(pnt, d);
|
|
||||||
} break;}
|
|
||||||
|
|
||||||
float d2 = dot3(pnt, pnt);
|
|
||||||
if (d2 >= s->D) return 0;
|
|
||||||
s->D = d2;
|
|
||||||
|
|
||||||
/* VII.) New search direction */
|
|
||||||
switch (s->cnt) {
|
|
||||||
default: assert(0); break;
|
|
||||||
case 1: {
|
|
||||||
/* --------- Point -------- */
|
|
||||||
*dv = scale3(s->v[0].p, -1);
|
|
||||||
} break;
|
|
||||||
case 2: {
|
|
||||||
/* ------ Line segment ---- */
|
|
||||||
vec3 ba = sub3(s->v[1].p, s->v[0].p);
|
|
||||||
vec3 b0 = scale3(s->v[1].p, -1);
|
|
||||||
vec3 t; t = cross3(ba, b0);
|
|
||||||
*dv = cross3(t, ba);
|
|
||||||
} break;
|
|
||||||
case 3: {
|
|
||||||
/* ------- Triangle ------- */
|
|
||||||
vec3 ab = sub3(s->v[1].p, s->v[0].p);
|
|
||||||
vec3 ac = sub3(s->v[2].p, s->v[0].p);
|
|
||||||
vec3 n; n = cross3(ab, ac);
|
|
||||||
if (dot3(n, s->v[0].p) <= 0.0f)
|
|
||||||
*dv = n;
|
|
||||||
else *dv = scale3(n, -1);
|
|
||||||
}}
|
|
||||||
if (dot3(*dv,*dv) < GJK_EPSILON * GJK_EPSILON)
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
gjk_result gjk_analyze(const gjk_simplex *s) {
|
|
||||||
gjk_result r = {0}, *res = &r;
|
|
||||||
|
|
||||||
res->iterations = s->iter;
|
|
||||||
res->hit = s->hit;
|
|
||||||
|
|
||||||
/* calculate normalization denominator */
|
|
||||||
float denom = 0;
|
|
||||||
for (int i = 0; i < s->cnt; ++i)
|
|
||||||
denom += s->bc[i];
|
|
||||||
denom = 1.0f / denom;
|
|
||||||
|
|
||||||
/* compute closest points */
|
|
||||||
switch (s->cnt) {
|
|
||||||
default: assert(0); break;
|
|
||||||
case 1: {
|
|
||||||
/* Point */
|
|
||||||
res->p0 = s->v[0].a;
|
|
||||||
res->p1 = s->v[0].b;
|
|
||||||
} break;
|
|
||||||
case 2: {
|
|
||||||
/* Line */
|
|
||||||
float as = denom * s->bc[0];
|
|
||||||
float bs = denom * s->bc[1];
|
|
||||||
|
|
||||||
vec3 a = scale3(s->v[0].a, as);
|
|
||||||
vec3 b = scale3(s->v[1].a, bs);
|
|
||||||
vec3 c = scale3(s->v[0].b, as);
|
|
||||||
vec3 d = scale3(s->v[1].b, bs);
|
|
||||||
|
|
||||||
res->p0 = add3(a, b);
|
|
||||||
res->p1 = add3(c, d);
|
|
||||||
} break;
|
|
||||||
case 3: {
|
|
||||||
/* Triangle */
|
|
||||||
float as = denom * s->bc[0];
|
|
||||||
float bs = denom * s->bc[1];
|
|
||||||
float cs = denom * s->bc[2];
|
|
||||||
|
|
||||||
vec3 a = scale3(s->v[0].a, as);
|
|
||||||
vec3 b = scale3(s->v[1].a, bs);
|
|
||||||
vec3 c = scale3(s->v[2].a, cs);
|
|
||||||
|
|
||||||
vec3 d = scale3(s->v[0].b, as);
|
|
||||||
vec3 e = scale3(s->v[1].b, bs);
|
|
||||||
vec3 f = scale3(s->v[2].b, cs);
|
|
||||||
|
|
||||||
res->p0 = add3(a, b);
|
|
||||||
res->p0 = add3(res->p0, c);
|
|
||||||
|
|
||||||
res->p1 = add3(d, e);
|
|
||||||
res->p1 = add3(res->p1, f);
|
|
||||||
} break;
|
|
||||||
case 4: {
|
|
||||||
/* Tetrahedron */
|
|
||||||
vec3 a = scale3(s->v[0].a, denom * s->bc[0]);
|
|
||||||
vec3 b = scale3(s->v[1].a, denom * s->bc[1]);
|
|
||||||
vec3 c = scale3(s->v[2].a, denom * s->bc[2]);
|
|
||||||
vec3 d = scale3(s->v[3].a, denom * s->bc[3]);
|
|
||||||
|
|
||||||
res->p0 = add3(a, b);
|
|
||||||
res->p0 = add3(res->p0, c);
|
|
||||||
res->p0 = add3(res->p0, d);
|
|
||||||
res->p1 = res->p0;
|
|
||||||
} break;}
|
|
||||||
|
|
||||||
if (!res->hit) {
|
|
||||||
/* compute distance */
|
|
||||||
vec3 d= sub3(res->p1, res->p0);
|
|
||||||
res->distance_squared = dot3(d, d);
|
|
||||||
} else res->distance_squared = 0;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
gjk_result gjk_quad(float a_radius, float b_radius) {
|
|
||||||
gjk_result r = {0}, *res = &r;
|
|
||||||
float radius = a_radius + b_radius;
|
|
||||||
float radius_squared = radius * radius;
|
|
||||||
if (res->distance_squared > GJK_EPSILON &&
|
|
||||||
res->distance_squared > radius_squared) {
|
|
||||||
res->distance_squared -= radius_squared;
|
|
||||||
|
|
||||||
/* calculate normal */
|
|
||||||
vec3 n = sub3(res->p1, res->p0);
|
|
||||||
float l2 = dot3(n, n);
|
|
||||||
if (l2 != 0.0f) {
|
|
||||||
float il = gjk_inv_sqrt(l2);
|
|
||||||
n = scale3(n,il);
|
|
||||||
}
|
|
||||||
vec3 da = scale3(n, a_radius);
|
|
||||||
vec3 db = scale3(n, b_radius);
|
|
||||||
|
|
||||||
/* calculate new collision points */
|
|
||||||
res->p0 = add3(res->p0, da);
|
|
||||||
res->p1 = sub3(res->p1, db);
|
|
||||||
} else {
|
|
||||||
vec3 p = add3(res->p0, res->p1);
|
|
||||||
res->p0 = scale3(p, 0.5f);
|
|
||||||
res->p1 = res->p0;
|
|
||||||
res->distance_squared = 0;
|
|
||||||
res->hit = 1;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#line 0
|
|
||||||
#line 1 "3rd_compress.h"
|
#line 1 "3rd_compress.h"
|
||||||
// compress.c de/compressors into a single-file header
|
// compress.c de/compressors into a single-file header
|
||||||
// - rlyeh, public domain
|
// - rlyeh, public domain
|
||||||
|
@ -255294,7 +254686,9 @@ void jo_write_mpeg(FILE *fp, const unsigned char *bgrx, int width, int height, i
|
||||||
#endif
|
#endif
|
||||||
#line 0
|
#line 0
|
||||||
//#define _RTL_RUN_ONCE _RTL_RUN_ONCE2 // __MINGW64__
|
//#define _RTL_RUN_ONCE _RTL_RUN_ONCE2 // __MINGW64__
|
||||||
#undef I
|
#ifdef I
|
||||||
|
#undef I // complex.h
|
||||||
|
#endif
|
||||||
#line 1 "3rd_https.h"
|
#line 1 "3rd_https.h"
|
||||||
/*
|
/*
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
@ -270616,7 +270010,7 @@ int xts_decrypt(
|
||||||
|
|
||||||
void xts_done(symmetric_xts *xts);
|
void xts_done(symmetric_xts *xts);
|
||||||
int xts_test(void);
|
int xts_test(void);
|
||||||
void xts_mult_x(unsigned char *I);
|
void xts_mult_x(unsigned char *); //< @r-lyeh: remove I arg
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int find_cipher(const char *name);
|
int find_cipher(const char *name);
|
||||||
|
@ -271287,7 +270681,7 @@ typedef struct {
|
||||||
#endif
|
#endif
|
||||||
} gcm_state;
|
} gcm_state;
|
||||||
|
|
||||||
void gcm_mult_h(gcm_state *gcm, unsigned char *I);
|
void gcm_mult_h(gcm_state *gcm, unsigned char *); //< @r-lyeh: remove I arg
|
||||||
|
|
||||||
int gcm_init(gcm_state *gcm, int cipher,
|
int gcm_init(gcm_state *gcm, int cipher,
|
||||||
const unsigned char *key, int keylen);
|
const unsigned char *key, int keylen);
|
||||||
|
@ -289514,35 +288908,35 @@ int gcm_process(gcm_state *gcm,
|
||||||
@param gcm The GCM state which holds the H value
|
@param gcm The GCM state which holds the H value
|
||||||
@param I The value to multiply H by
|
@param I The value to multiply H by
|
||||||
*/
|
*/
|
||||||
void gcm_mult_h(gcm_state *gcm, unsigned char *I)
|
void gcm_mult_h(gcm_state *gcm, unsigned char *i) //< @r-lyeh: lowercase I argument
|
||||||
{
|
{
|
||||||
unsigned char T[16];
|
unsigned char T[16];
|
||||||
#ifdef LTC_GCM_TABLES
|
#ifdef LTC_GCM_TABLES
|
||||||
int x, y;
|
int x, y;
|
||||||
#ifdef LTC_GCM_TABLES_SSE2
|
#ifdef LTC_GCM_TABLES_SSE2
|
||||||
asm("movdqa (%0),%%xmm0"::"r"(&gcm->PC[0][I[0]][0]));
|
asm("movdqa (%0),%%xmm0"::"r"(&gcm->PC[0][i[0]][0]));
|
||||||
for (x = 1; x < 16; x++) {
|
for (x = 1; x < 16; x++) {
|
||||||
asm("pxor (%0),%%xmm0"::"r"(&gcm->PC[x][I[x]][0]));
|
asm("pxor (%0),%%xmm0"::"r"(&gcm->PC[x][i[x]][0]));
|
||||||
}
|
}
|
||||||
asm("movdqa %%xmm0,(%0)"::"r"(&T));
|
asm("movdqa %%xmm0,(%0)"::"r"(&T));
|
||||||
#else
|
#else
|
||||||
XMEMCPY(T, &gcm->PC[0][I[0]][0], 16);
|
XMEMCPY(T, &gcm->PC[0][i[0]][0], 16);
|
||||||
for (x = 1; x < 16; x++) {
|
for (x = 1; x < 16; x++) {
|
||||||
#ifdef LTC_FAST
|
#ifdef LTC_FAST
|
||||||
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
|
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
|
||||||
*((LTC_FAST_TYPE *)(T + y)) ^= *((LTC_FAST_TYPE *)(&gcm->PC[x][I[x]][y]));
|
*((LTC_FAST_TYPE *)(T + y)) ^= *((LTC_FAST_TYPE *)(&gcm->PC[x][i[x]][y]));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
for (y = 0; y < 16; y++) {
|
for (y = 0; y < 16; y++) {
|
||||||
T[y] ^= gcm->PC[x][I[x]][y];
|
T[y] ^= gcm->PC[x][i[x]][y];
|
||||||
}
|
}
|
||||||
#endif /* LTC_FAST */
|
#endif /* LTC_FAST */
|
||||||
}
|
}
|
||||||
#endif /* LTC_GCM_TABLES_SSE2 */
|
#endif /* LTC_GCM_TABLES_SSE2 */
|
||||||
#else
|
#else
|
||||||
gcm_gf_mult(gcm->H, I, T);
|
gcm_gf_mult(gcm->H, i, T);
|
||||||
#endif
|
#endif
|
||||||
XMEMCPY(I, T, 16);
|
XMEMCPY(i, T, 16);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -345765,7 +345159,6 @@ typedef struct {
|
||||||
|
|
||||||
intptr_t SteamClient();
|
intptr_t SteamClient();
|
||||||
|
|
||||||
#ifndef STEAM_API
|
|
||||||
#define STEAM_API(X) \
|
#define STEAM_API(X) \
|
||||||
X(bool,SteamAPI_Init,()) \
|
X(bool,SteamAPI_Init,()) \
|
||||||
X(void,SteamAPI_Shutdown,()) \
|
X(void,SteamAPI_Shutdown,()) \
|
||||||
|
@ -346465,7 +345858,6 @@ X(void*,SteamInternal_CreateInterface,(const char *ver)) \
|
||||||
X(bool,SteamAPI_IsSteamRunning,()) \
|
X(bool,SteamAPI_IsSteamRunning,()) \
|
||||||
X(bool,SteamAPI_InitSafe,()) \
|
X(bool,SteamAPI_InitSafe,()) \
|
||||||
X(void,SteamAPI_RunCallbacks,())
|
X(void,SteamAPI_RunCallbacks,())
|
||||||
#endif
|
|
||||||
#line 0
|
#line 0
|
||||||
|
|
||||||
#endif // V4K_3RD
|
#endif // V4K_3RD
|
||||||
|
|
Loading…
Reference in New Issue