spline and edge commands
This commit is contained in:
parent
4d7d665a5e
commit
99e9807552
|
@ -61,7 +61,16 @@ int *qhits;
|
|||
|
||||
void querylist(cpShape *shape, cpContactPointSet *points, void *data)
|
||||
{
|
||||
arrput(qhits, shape2gameobject(shape));
|
||||
int go = shape2gameobject(shape);
|
||||
int in = 0;
|
||||
for (int i = 0; i < arrlen(qhits); i++) {
|
||||
if (qhits[i] == go) {
|
||||
in = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!in) arrput(qhits, go);
|
||||
}
|
||||
|
||||
void querylistbodies(cpBody *body, void *data)
|
||||
|
@ -412,7 +421,21 @@ void phys2d_edge_rmvert(struct phys2d_edge *edge, int index)
|
|||
assert(arrlen(edge->points) > index && index >= 0);
|
||||
|
||||
arrdel(edge->points, index);
|
||||
cpSegmentShapeSetEndpoints(edge->shapes[index-1], edge->points[index-1], edge->points[index]);
|
||||
|
||||
if (arrlen(edge->points) == 0) return;
|
||||
|
||||
|
||||
if (index == 0) {
|
||||
cpSpaceRemoveShape(space, edge->shapes[index]);
|
||||
arrdel(edge->shapes, index);
|
||||
phys2d_applyedge(edge);
|
||||
return;
|
||||
}
|
||||
|
||||
if (index != arrlen(edge->points)) {
|
||||
cpSegmentShapeSetEndpoints(edge->shapes[index-1], edge->points[index-1], edge->points[index]);
|
||||
}
|
||||
|
||||
cpSpaceRemoveShape(space, edge->shapes[index-1]);
|
||||
arrdel(edge->shapes, index-1);
|
||||
|
||||
|
@ -427,6 +450,21 @@ void phys2d_edge_setvert(struct phys2d_edge *edge, int index, cpVect val)
|
|||
phys2d_applyedge(edge);
|
||||
}
|
||||
|
||||
void phys2d_edge_clearverts(struct phys2d_edge *edge)
|
||||
{
|
||||
for (int i = arrlen(edge->points)-1; i>=0; i--) {
|
||||
phys2d_edge_rmvert(edge, i);
|
||||
}
|
||||
}
|
||||
|
||||
void phys2d_edge_addverts(struct phys2d_edge *edge, cpVect *verts)
|
||||
{
|
||||
for (int i = 0; i < arrlen(verts); i++) {
|
||||
phys2d_edgeaddvert(edge);
|
||||
phys2d_edge_setvert(edge, i, verts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void phys2d_applyedge(struct phys2d_edge *edge)
|
||||
{
|
||||
float s = id2go(edge->shape.go)->scale;
|
||||
|
|
|
@ -90,8 +90,11 @@ void phys2d_applyedge(struct phys2d_edge *edge);
|
|||
void phys2d_dbgdrawedge(struct phys2d_edge *edge);
|
||||
void phys2d_edgeaddvert(struct phys2d_edge *edge);
|
||||
void phys2d_edge_rmvert(struct phys2d_edge *edge, int index);
|
||||
|
||||
void edge_gui(struct phys2d_edge *edge);
|
||||
void phys2d_edge_setvert(struct phys2d_edge *edge, int index, cpVect val);
|
||||
void phys2d_edge_clearverts(struct phys2d_edge *edge);
|
||||
void phys2d_edge_addverts(struct phys2d_edge *edge, cpVect *verts);
|
||||
|
||||
void phys2d_init();
|
||||
void phys2d_update(float deltaT);
|
||||
|
|
|
@ -96,6 +96,20 @@ cpBitmask duk2bitmask(duk_context *duk, int p)
|
|||
return mask;
|
||||
}
|
||||
|
||||
cpVect *duk2cpvec2arr(duk_context *duk, int p)
|
||||
{
|
||||
int n = duk_get_length(duk, p);
|
||||
cpVect *points = NULL;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
duk_get_prop_index(duk, p, i);
|
||||
|
||||
arrput(points, duk2vec2(duk, -1));
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
void bitmask2duk(duk_context *duk, cpBitmask mask)
|
||||
{
|
||||
int arr = duk_push_array(duk);
|
||||
|
@ -240,12 +254,10 @@ duk_ret_t duk_spline_cmd(duk_context *duk)
|
|||
|
||||
int n = duk_get_length(duk, 4);
|
||||
int d = duk_to_int(duk, 2);
|
||||
cpVect points[n*d];
|
||||
cpVect points[n*d];
|
||||
|
||||
ts_bspline_new(n, d, duk_to_int(duk, 1), duk_to_int(duk, 3), &spline, NULL);
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
duk_get_prop_index(duk, 4, i);
|
||||
|
||||
|
@ -268,8 +280,6 @@ duk_ret_t duk_spline_cmd(duk_context *duk)
|
|||
|
||||
for (int i = 0; i < nsamples; i++) {
|
||||
int pidx = duk_push_array(duk);
|
||||
|
||||
|
||||
duk_push_number(duk, samples[i].x);
|
||||
duk_put_prop_index(duk, pidx, 0);
|
||||
duk_push_number(duk, samples[i].y);
|
||||
|
@ -292,6 +302,48 @@ void ints2duk(int *ints)
|
|||
}
|
||||
}
|
||||
|
||||
int point2segindex(cpVect p, cpVect *segs, double slop)
|
||||
{
|
||||
float shortest = slop;
|
||||
int best = -1;
|
||||
|
||||
for (int i = 0; i < arrlen(segs)-1; i++)
|
||||
{
|
||||
float a = (segs[i+1].y - segs[i].y) / (segs[i+1].x - segs[i].x);
|
||||
float c = segs[i].y - (a * segs[i].x);
|
||||
float b = -1;
|
||||
|
||||
float dist = abs(a*p.x + b*p.y + c) / sqrt(pow(a,2) + 1);
|
||||
|
||||
if (dist < shortest) {
|
||||
shortest = dist;
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (best == 0) {
|
||||
cpVect n;
|
||||
n.x = segs[1].x-segs[0].x;
|
||||
n.y = segs[1].y-segs[0].y;
|
||||
n = cpvnormalize(n);
|
||||
if (cpvdot(n, cpvsub(p, segs[0])) < 0 && cpvdist(p, segs[0]) >= slop)
|
||||
best = -1;
|
||||
}
|
||||
|
||||
if (best == arrlen(segs)-1) {
|
||||
cpVect n;
|
||||
n.x = segs[best-1].x-segs[best].x;
|
||||
n.y = segs[best-1].y-segs[best-1].y;
|
||||
n = cpvnormalize(n);
|
||||
|
||||
if (cpvdot(n, cpvsub(p, segs[best])) < 0 && cpvdist(p, segs[best]) >= slop)
|
||||
best = -1;
|
||||
}
|
||||
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
duk_ret_t duk_cmd(duk_context *duk) {
|
||||
int cmd = duk_to_int(duk, 0);
|
||||
|
||||
|
@ -538,6 +590,10 @@ duk_ret_t duk_cmd(duk_context *duk) {
|
|||
case 58:
|
||||
duk_push_boolean(duk, duk2go(duk, 1)->flipy == -1 ? 1 : 0);
|
||||
return 1;
|
||||
|
||||
case 59:
|
||||
duk_push_int(duk, point2segindex(duk2vec2(duk, 1), duk2cpvec2arr(duk, 2), duk_to_number(duk, 3)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -917,6 +973,16 @@ duk_ret_t duk_make_edge2d(duk_context *duk)
|
|||
|
||||
duk_ret_t duk_cmd_edge2d(duk_context *duk)
|
||||
{
|
||||
int cmd = duk_to_int(duk, 0);
|
||||
struct phys2d_edge *edge = duk_to_pointer(duk, 1);
|
||||
|
||||
switch(cmd) {
|
||||
case 0:
|
||||
phys2d_edge_clearverts(edge);
|
||||
phys2d_edge_addverts(edge, duk2cpvec2arr(duk, 2));
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ static void mb_cb(GLFWwindow *w, int button, int action, int mods)
|
|||
case GLFW_RELEASE:
|
||||
act = "released";
|
||||
rm_downkey(button);
|
||||
call_input_signal("input_any_released");
|
||||
break;
|
||||
|
||||
case GLFW_REPEAT:
|
||||
|
@ -124,9 +125,7 @@ void call_input_signal(char *signal) {
|
|||
|
||||
const char *keyname_extd(int key, int scancode) {
|
||||
char keybuf[50];
|
||||
const char *kkey = glfwGetKeyName(key, scancode);
|
||||
|
||||
if (kkey) return kkey;
|
||||
const char *kkey = NULL;
|
||||
|
||||
if (key > 289 && key < 302) {
|
||||
sprintf(keybuf, "f%d", key-289);
|
||||
|
@ -208,12 +207,24 @@ const char *keyname_extd(int key, int scancode) {
|
|||
case GLFW_MOUSE_BUTTON_MIDDLE:
|
||||
kkey = "mmouse";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_KP_ADD:
|
||||
kkey = "plus";
|
||||
break;
|
||||
|
||||
case GLFW_KEY_KP_SUBTRACT:
|
||||
kkey = "minus";
|
||||
break;
|
||||
}
|
||||
|
||||
if (kkey) return kkey;
|
||||
|
||||
}
|
||||
|
||||
kkey = glfwGetKeyName(key, scancode);
|
||||
|
||||
if (kkey) return kkey;
|
||||
|
||||
return "NULL";
|
||||
}
|
||||
|
||||
|
@ -251,6 +262,7 @@ void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods
|
|||
case GLFW_RELEASE:
|
||||
snprintf(keystr, 50, "input_%s_released", kkey);
|
||||
rm_downkey(key);
|
||||
call_input_signal("input_any_released");
|
||||
break;
|
||||
|
||||
case GLFW_REPEAT:
|
||||
|
|
|
@ -17,10 +17,10 @@ static struct {
|
|||
} *texhash = NULL;
|
||||
|
||||
struct Texture *tex_default;
|
||||
|
||||
/* If an empty string or null is put for path, loads default texture */
|
||||
struct Texture *texture_pullfromfile(const char *path)
|
||||
{
|
||||
if (!path) { YughError("Tried to pull a texture with a NULL path."); return NULL; }
|
||||
if (!path || path[0] == '\0') { return NULL; }
|
||||
|
||||
int index = shgeti(texhash, path);
|
||||
if (index != -1)
|
||||
|
@ -47,7 +47,7 @@ struct Texture *texture_pullfromfile(const char *path)
|
|||
|
||||
unsigned char *data = stbi_load(path, &tex->width, &tex->height, &n, 4);
|
||||
|
||||
while (data == NULL) {
|
||||
if (data == NULL) {
|
||||
YughError("STBI failed to load file %s with message: %s", path, stbi_failure_reason());
|
||||
return NULL;
|
||||
}
|
||||
|
@ -120,10 +120,7 @@ struct Texture *texture_loadfromfile(const char *path)
|
|||
{
|
||||
struct Texture *new = texture_pullfromfile(path);
|
||||
|
||||
if (new == NULL) {
|
||||
YughError("Texture %s not loaded! Loading the default instead ...", path);
|
||||
new = texture_pullfromfile("./ph.png");
|
||||
}
|
||||
if (new == NULL) { new = texture_pullfromfile("./ph.png"); }
|
||||
|
||||
if (new->id == 0) {
|
||||
glGenTextures(1, &new->id);
|
||||
|
@ -188,7 +185,9 @@ struct TexAnim *anim2d_from_tex(const char *path, int frames, int fps)
|
|||
|
||||
void texanim_fromframes(struct TexAnim *anim, int frames)
|
||||
{
|
||||
if (anim->st_frames) free(anim->st_frames);
|
||||
if (anim->st_frames) {
|
||||
free(anim->st_frames);
|
||||
}
|
||||
|
||||
arrsetlen(anim->st_frames, frames);
|
||||
|
||||
|
|
Loading…
Reference in a new issue