fix spline segfault
This commit is contained in:
parent
2083fb6e9e
commit
903ffbc607
|
@ -553,7 +553,7 @@ component.edge2d = Object.copy(collider2d, {
|
||||||
thickness:0,
|
thickness:0,
|
||||||
type: Spline.type.catmull,
|
type: Spline.type.catmull,
|
||||||
looped: false,
|
looped: false,
|
||||||
angle: 5,
|
angle: 3,
|
||||||
|
|
||||||
flipx: false,
|
flipx: false,
|
||||||
flipy: false,
|
flipy: false,
|
||||||
|
@ -605,10 +605,14 @@ component.edge2d = Object.copy(collider2d, {
|
||||||
|
|
||||||
sample(n) {
|
sample(n) {
|
||||||
var spoints = this.spoints();
|
var spoints = this.spoints();
|
||||||
// n = this.samples * this.sample_calc();
|
if (this.looped) {
|
||||||
|
spoints.unshift(spoints[spoints.length-1]);
|
||||||
/* if (this.looped)
|
spoints.push(spoints[1]);
|
||||||
return Spline.sample(degrees, this.dimensions, Spline.type.open, spoints.wrapped(this.degrees), n);*/
|
spoints.push(spoints[2]);
|
||||||
|
} else {
|
||||||
|
spoints.unshift(spoints[0].sub(spoints[1]).add(spoints[0]));
|
||||||
|
spoints.push(spoints[spoints.length-1].sub(spoints[spoints.length-2]).add(spoints[spoints.length-1]));
|
||||||
|
}
|
||||||
|
|
||||||
return Spline.sample_angle(this.type, spoints, this.angle);
|
return Spline.sample_angle(this.type, spoints, this.angle);
|
||||||
},
|
},
|
||||||
|
@ -673,6 +677,7 @@ component.edge2d.impl = Object.mix({
|
||||||
sync() {
|
sync() {
|
||||||
var sensor = this.sensor;
|
var sensor = this.sensor;
|
||||||
var points = this.sample(this.samples);
|
var points = this.sample(this.samples);
|
||||||
|
if (!points) return;
|
||||||
cmd_edge2d(0,this.id,points);
|
cmd_edge2d(0,this.id,points);
|
||||||
this.sensor = sensor;
|
this.sensor = sensor;
|
||||||
},
|
},
|
||||||
|
|
|
@ -387,7 +387,6 @@ struct phys2d_edge *Make2DEdge(gameobject *go) {
|
||||||
new->shape.shape = NULL;
|
new->shape.shape = NULL;
|
||||||
new->shape.apply = NULL;
|
new->shape.apply = NULL;
|
||||||
new->draws = 0;
|
new->draws = 0;
|
||||||
new->closed = 0;
|
|
||||||
phys2d_applyedge(new);
|
phys2d_applyedge(new);
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
|
@ -405,16 +404,14 @@ void phys2d_edgedel(struct phys2d_edge *edge) {
|
||||||
phys2d_shape_del(&edge->shape);
|
phys2d_shape_del(&edge->shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
void phys2d_edgeaddvert(struct phys2d_edge *edge) {
|
void phys2d_edgeaddvert(struct phys2d_edge *edge, HMM_Vec2 v) {
|
||||||
arrput(edge->points, v2zero);
|
arrput(edge->points, v);
|
||||||
if (arrlen(edge->points) > 1)
|
if (arrlen(edge->points) > 1)
|
||||||
arrput(edge->shapes, cpSpaceAddShape(space, cpSegmentShapeNew(edge->shape.go->body, cpvzero, cpvzero, edge->thickness)));
|
arrput(edge->shapes, cpSpaceAddShape(space, cpSegmentShapeNew(edge->shape.go->body, cpvzero, cpvzero, edge->thickness)));
|
||||||
|
|
||||||
phys2d_applyedge(edge);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void phys2d_edge_rmvert(struct phys2d_edge *edge, int index) {
|
void phys2d_edge_rmvert(struct phys2d_edge *edge, int index) {
|
||||||
assert(arrlen(edge->points) > index && index >= 0);
|
if (index>arrlen(edge->points) || index < 0) return;
|
||||||
|
|
||||||
arrdel(edge->points, index);
|
arrdel(edge->points, index);
|
||||||
|
|
||||||
|
@ -424,41 +421,47 @@ void phys2d_edge_rmvert(struct phys2d_edge *edge, int index) {
|
||||||
cpSpaceRemoveShape(space, edge->shapes[index]);
|
cpSpaceRemoveShape(space, edge->shapes[index]);
|
||||||
cpShapeFree(edge->shapes[index]);
|
cpShapeFree(edge->shapes[index]);
|
||||||
arrdel(edge->shapes, index);
|
arrdel(edge->shapes, index);
|
||||||
phys2d_applyedge(edge);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index != arrlen(edge->points)) {
|
if (index != arrlen(edge->points))
|
||||||
cpSegmentShapeSetEndpoints(edge->shapes[index - 1], edge->points[index - 1].cp, edge->points[index].cp);
|
cpSegmentShapeSetEndpoints(edge->shapes[index - 1], edge->points[index - 1].cp, edge->points[index].cp);
|
||||||
}
|
|
||||||
|
|
||||||
cpSpaceRemoveShape(space, edge->shapes[index - 1]);
|
cpSpaceRemoveShape(space, edge->shapes[index - 1]);
|
||||||
cpShapeFree(edge->shapes[index - 1]);
|
cpShapeFree(edge->shapes[index - 1]);
|
||||||
arrdel(edge->shapes, index - 1);
|
arrdel(edge->shapes, index - 1);
|
||||||
|
|
||||||
phys2d_applyedge(edge);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void phys2d_edge_setvert(struct phys2d_edge *edge, int index, cpVect val) {
|
void phys2d_edge_setvert(struct phys2d_edge *edge, int index, cpVect val) {
|
||||||
assert(arrlen(edge->points) > index && index >= 0);
|
assert(arrlen(edge->points) > index && index >= 0);
|
||||||
edge->points[index].cp = val;
|
edge->points[index].cp = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void phys2d_edge_update_verts(struct phys2d_edge *edge, HMM_Vec2 *verts)
|
||||||
|
{
|
||||||
|
if (arrlen(edge->points) == arrlen(verts)) {
|
||||||
|
for (int i = 0; i < arrlen(verts); i++)
|
||||||
|
phys2d_edge_setvert(edge,i,verts[i].cp);
|
||||||
|
} else {
|
||||||
|
int vertchange = arrlen(verts)-arrlen(edge->points);
|
||||||
|
phys2d_edge_clearverts(edge);
|
||||||
|
phys2d_edge_addverts(edge,verts);
|
||||||
|
}
|
||||||
|
|
||||||
phys2d_applyedge(edge);
|
phys2d_applyedge(edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
void phys2d_edge_clearverts(struct phys2d_edge *edge) {
|
void phys2d_edge_clearverts(struct phys2d_edge *edge) {
|
||||||
for (int i = arrlen(edge->points) - 1; i >= 0; i--) {
|
for (int i = arrlen(edge->points) - 1; i >= 0; i--)
|
||||||
phys2d_edge_rmvert(edge, i);
|
phys2d_edge_rmvert(edge, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void phys2d_edge_addverts(struct phys2d_edge *edge, HMM_Vec2 *verts) {
|
||||||
|
for (int i = 0; i < arrlen(verts); i++)
|
||||||
|
phys2d_edgeaddvert(edge, verts[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void phys2d_edge_addverts(struct phys2d_edge *edge, cpVect *verts) {
|
/* Calculates all true positions of verts, links them up, and so on */
|
||||||
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) {
|
void phys2d_applyedge(struct phys2d_edge *edge) {
|
||||||
struct gameobject *go = edge->shape.go;
|
struct gameobject *go = edge->shape.go;
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,6 @@ struct phys2d_edge {
|
||||||
HMM_Vec2 *points; /* Points defined relative to the gameobject */
|
HMM_Vec2 *points; /* Points defined relative to the gameobject */
|
||||||
float thickness;
|
float thickness;
|
||||||
cpShape **shapes;
|
cpShape **shapes;
|
||||||
int closed; /* True if the first and last points should be connected */
|
|
||||||
struct phys2d_shape shape;
|
struct phys2d_shape shape;
|
||||||
int draws;
|
int draws;
|
||||||
};
|
};
|
||||||
|
@ -94,13 +93,15 @@ struct phys2d_edge *Make2DEdge(gameobject *go);
|
||||||
void phys2d_edgedel(struct phys2d_edge *edge);
|
void phys2d_edgedel(struct phys2d_edge *edge);
|
||||||
void phys2d_applyedge(struct phys2d_edge *edge);
|
void phys2d_applyedge(struct phys2d_edge *edge);
|
||||||
void phys2d_dbgdrawedge(struct phys2d_edge *edge);
|
void phys2d_dbgdrawedge(struct phys2d_edge *edge);
|
||||||
void phys2d_edgeaddvert(struct phys2d_edge *edge);
|
void phys2d_edgeaddvert(struct phys2d_edge *edge, HMM_Vec2 v);
|
||||||
void phys2d_edge_rmvert(struct phys2d_edge *edge, int index);
|
void phys2d_edge_rmvert(struct phys2d_edge *edge, int index);
|
||||||
float phys2d_edge_moi(struct phys2d_edge *edge, float m);
|
float phys2d_edge_moi(struct phys2d_edge *edge, float m);
|
||||||
|
|
||||||
void phys2d_edge_setvert(struct phys2d_edge *edge, int index, cpVect val);
|
void phys2d_edge_setvert(struct phys2d_edge *edge, int index, cpVect val);
|
||||||
void phys2d_edge_clearverts(struct phys2d_edge *edge);
|
void phys2d_edge_clearverts(struct phys2d_edge *edge);
|
||||||
void phys2d_edge_addverts(struct phys2d_edge *edge, cpVect *verts);
|
void phys2d_edge_rmvert(struct phys2d_edge *edge, int index);
|
||||||
|
void phys2d_edge_update_verts(struct phys2d_edge *edge, HMM_Vec2 *verts);
|
||||||
|
void phys2d_edge_addverts(struct phys2d_edge *edge, HMM_Vec2 *verts);
|
||||||
void phys2d_edge_set_sensor(struct phys2d_edge *edge, int sensor);
|
void phys2d_edge_set_sensor(struct phys2d_edge *edge, int sensor);
|
||||||
void phys2d_edge_set_enabled(struct phys2d_edge *edge, int enabled);
|
void phys2d_edge_set_enabled(struct phys2d_edge *edge, int enabled);
|
||||||
|
|
||||||
|
|
|
@ -389,6 +389,7 @@ typedef union HMM_Mat3 {
|
||||||
typedef union HMM_Mat4 {
|
typedef union HMM_Mat4 {
|
||||||
float Elements[4][4];
|
float Elements[4][4];
|
||||||
HMM_Vec4 Columns[4];
|
HMM_Vec4 Columns[4];
|
||||||
|
float e[4][4];
|
||||||
|
|
||||||
} HMM_Mat4;
|
} HMM_Mat4;
|
||||||
|
|
||||||
|
|
|
@ -256,3 +256,9 @@ void gameobject_draw_debug(gameobject *go) {
|
||||||
cpVect pos = cpBodyGetPosition(go->body);
|
cpVect pos = cpBodyGetPosition(go->body);
|
||||||
cpBodyEachShape(go->body, body_draw_shapes_dbg, NULL);
|
cpBodyEachShape(go->body, body_draw_shapes_dbg, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gameobject_draw_debugs()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < arrlen(gameobjects); i++)
|
||||||
|
gameobject_draw_debug(gameobjects[i]);
|
||||||
|
}
|
||||||
|
|
|
@ -88,4 +88,5 @@ void gameobject_rotate(gameobject *go, float as);
|
||||||
void gameobject_setangle(gameobject *go, float angle);
|
void gameobject_setangle(gameobject *go, float angle);
|
||||||
void gameobject_setpos(gameobject *go, cpVect vec);
|
void gameobject_setpos(gameobject *go, cpVect vec);
|
||||||
void gameobject_draw_debug(gameobject *go);
|
void gameobject_draw_debug(gameobject *go);
|
||||||
|
void gameobject_draw_debugs();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -266,19 +266,14 @@ cpBitmask js2bitmask(JSValue v) {
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
HMM_Vec2 *cpvecarr = NULL;
|
|
||||||
|
|
||||||
/* Does not need to be freed by returning; but not reentrant */
|
/* Does not need to be freed by returning; but not reentrant */
|
||||||
HMM_Vec2 *js2cpvec2arr(JSValue v) {
|
HMM_Vec2 *js2cpvec2arr(JSValue v) {
|
||||||
if (cpvecarr)
|
HMM_Vec2 *arr = NULL;
|
||||||
arrfree(cpvecarr);
|
|
||||||
|
|
||||||
int n = js_arrlen(v);
|
int n = js_arrlen(v);
|
||||||
|
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
arrput(cpvecarr, js2vec2(js_getpropidx( v, i)));
|
arrput(arr, js2vec2(js_getpropidx( v, i)));
|
||||||
|
|
||||||
return cpvecarr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSValue bitmask2js(cpBitmask mask) {
|
JSValue bitmask2js(cpBitmask mask) {
|
||||||
|
@ -398,15 +393,13 @@ JSValue duk_spline_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst
|
||||||
HMM_Vec2 *points = js2cpvec2arr(argv[3]);
|
HMM_Vec2 *points = js2cpvec2arr(argv[3]);
|
||||||
float param = js2number(argv[4]);
|
float param = js2number(argv[4]);
|
||||||
HMM_Vec2 *samples = catmull_rom_ma_v2(points, param);
|
HMM_Vec2 *samples = catmull_rom_ma_v2(points, param);
|
||||||
|
arrfree(points);
|
||||||
|
|
||||||
if (!samples)
|
if (!samples)
|
||||||
return JS_UNDEFINED;
|
return JS_UNDEFINED;
|
||||||
|
|
||||||
// for (int i = 0; i < arrlen(samples); i++)
|
|
||||||
// YughWarn("%g,%g", samples[i].x, samples[i].y);
|
|
||||||
|
|
||||||
JSValue arr = vecarr2js(samples, arrlen(samples));
|
JSValue arr = vecarr2js(samples, arrlen(samples));
|
||||||
// arrfree(samples);
|
arrfree(samples);
|
||||||
|
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
@ -497,6 +490,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||||
const char *str2 = NULL;
|
const char *str2 = NULL;
|
||||||
const void *d1 = NULL;
|
const void *d1 = NULL;
|
||||||
const void *d2 = NULL;
|
const void *d2 = NULL;
|
||||||
|
const void *v1 = NULL;
|
||||||
gameobject *ids = NULL;
|
gameobject *ids = NULL;
|
||||||
gameobject *go = NULL;
|
gameobject *go = NULL;
|
||||||
JSValue ret = JS_UNDEFINED;
|
JSValue ret = JS_UNDEFINED;
|
||||||
|
@ -759,7 +753,8 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 59:
|
case 59:
|
||||||
ret = JS_NewInt64(js, point2segindex(js2vec2(argv[1]), js2cpvec2arr(argv[2]), js2number(argv[3])));
|
v1 = js2cpvec2arr(argv[2]);
|
||||||
|
ret = JS_NewInt64(js, point2segindex(js2vec2(argv[1]), v1, js2number(argv[3])));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 60:
|
case 60:
|
||||||
|
@ -857,7 +852,8 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 83:
|
case 83:
|
||||||
draw_edge(js2cpvec2arr(argv[1]), js_arrlen(argv[1]), js2color(argv[2]), js2number(argv[3]), 0, 0, js2color(argv[2]), 10);
|
v1 = js2cpvec2arr(argv[1]);
|
||||||
|
draw_edge(v1, js_arrlen(argv[1]), js2color(argv[2]), js2number(argv[3]), 0, 0, js2color(argv[2]), 10);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 84:
|
case 84:
|
||||||
|
@ -869,7 +865,8 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 86:
|
case 86:
|
||||||
ids = phys2d_query_box_points(js2vec2(argv[1]), js2vec2(argv[2]), js2cpvec2arr(argv[3]), js2int(argv[4]));
|
v1 = js2cpvec2arr(argv[3]);
|
||||||
|
ids = phys2d_query_box_points(js2vec2(argv[1]), js2vec2(argv[2]), v1, js2int(argv[4]));
|
||||||
ret = gos2ref(ids);
|
ret = gos2ref(ids);
|
||||||
arrfree(ids);
|
arrfree(ids);
|
||||||
break;
|
break;
|
||||||
|
@ -1354,6 +1351,8 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||||
if (d1) free(d1);
|
if (d1) free(d1);
|
||||||
if (d2) free(d2);
|
if (d2) free(d2);
|
||||||
|
|
||||||
|
if (v1) arrfree(v1);
|
||||||
|
|
||||||
if (!JS_IsNull(ret)) {
|
if (!JS_IsNull(ret)) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1750,14 +1749,17 @@ JSValue duk_make_poly2d(JSContext *js, JSValueConst this, int argc, JSValueConst
|
||||||
JSValue duk_cmd_poly2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
JSValue duk_cmd_poly2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||||
int cmd = js2int(argv[0]);
|
int cmd = js2int(argv[0]);
|
||||||
struct phys2d_poly *poly = js2ptr(argv[1]);
|
struct phys2d_poly *poly = js2ptr(argv[1]);
|
||||||
|
HMM_Vec2 *v1 = NULL;
|
||||||
|
|
||||||
if (!poly) return JS_UNDEFINED;
|
if (!poly) return JS_UNDEFINED;
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case 0:
|
case 0:
|
||||||
phys2d_poly_setverts(poly, js2cpvec2arr(argv[2]));
|
v1 = js2cpvec2arr(argv[2]);
|
||||||
|
phys2d_poly_setverts(poly, v1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (v1) arrfree(v1);
|
||||||
|
|
||||||
return JS_UNDEFINED;
|
return JS_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
@ -1765,15 +1767,9 @@ JSValue duk_cmd_poly2d(JSContext *js, JSValueConst this, int argc, JSValueConst
|
||||||
JSValue duk_make_edge2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
JSValue duk_make_edge2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||||
gameobject *go = js2gameobject(argv[0]);
|
gameobject *go = js2gameobject(argv[0]);
|
||||||
struct phys2d_edge *edge = Make2DEdge(go);
|
struct phys2d_edge *edge = Make2DEdge(go);
|
||||||
|
HMM_Vec2 *points = js2cpvec2arr(argv[1]);
|
||||||
int n = js_arrlen(argv[1]);
|
phys2d_edge_update_verts(edge, points);
|
||||||
HMM_Vec2 points[n];
|
arrfree(points);
|
||||||
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
points[i] = js2vec2(js_getpropidx(argv[1],i));
|
|
||||||
phys2d_edgeaddvert(edge);
|
|
||||||
phys2d_edge_setvert(edge, i, points[i].cp);
|
|
||||||
}
|
|
||||||
|
|
||||||
JSValue edgeval = JS_NewObject(js);
|
JSValue edgeval = JS_NewObject(js);
|
||||||
js_setprop_str(edgeval, "id", ptr2js(edge));
|
js_setprop_str(edgeval, "id", ptr2js(edge));
|
||||||
|
@ -1790,16 +1786,19 @@ JSValue duk_cmd_edge2d(JSContext *js, JSValueConst this, int argc, JSValueConst
|
||||||
return JS_UNDEFINED;
|
return JS_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HMM_Vec2 *v1 = NULL;
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case 0:
|
case 0:
|
||||||
phys2d_edge_clearverts(edge);
|
v1 = js2cpvec2arr(argv[2]);
|
||||||
phys2d_edge_addverts(edge, js2cpvec2arr(argv[2]));
|
phys2d_edge_update_verts(edge,v1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
edge->thickness = js2number(argv[2]);
|
edge->thickness = js2number(argv[2]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (v1) arrfree(v1);
|
||||||
|
|
||||||
return JS_UNDEFINED;
|
return JS_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
@ -1810,7 +1809,9 @@ JSValue duk_inflate_cpv(JSContext *js, JSValueConst this, int argc, JSValueConst
|
||||||
double d = js2number(argv[2]);
|
double d = js2number(argv[2]);
|
||||||
HMM_Vec2 *infl = inflatepoints(points,d,n);
|
HMM_Vec2 *infl = inflatepoints(points,d,n);
|
||||||
JSValue arr = vecarr2js(infl,arrlen(infl));
|
JSValue arr = vecarr2js(infl,arrlen(infl));
|
||||||
|
|
||||||
arrfree(infl);
|
arrfree(infl);
|
||||||
|
arrfree(points);
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -518,8 +518,10 @@ void full_2d_pass(struct window *window)
|
||||||
call_draw();
|
call_draw();
|
||||||
|
|
||||||
//// DEBUG
|
//// DEBUG
|
||||||
if (debugDrawPhysics)
|
if (debugDrawPhysics) {
|
||||||
|
gameobject_draw_debugs();
|
||||||
call_debugs();
|
call_debugs();
|
||||||
|
}
|
||||||
|
|
||||||
debug_flush(&projection);
|
debug_flush(&projection);
|
||||||
text_flush(&projection);
|
text_flush(&projection);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "stb_ds.h"
|
#include "stb_ds.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "transform.h"
|
#include "transform.h"
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
static const HMM_Mat4 cubic_hermite_m = {
|
static const HMM_Mat4 cubic_hermite_m = {
|
||||||
2, -2, 1, 1,
|
2, -2, 1, 1,
|
||||||
|
@ -121,6 +122,14 @@ static const HMM_Mat4 catmull_rom_dddm = {
|
||||||
-9*CAT_S, 18*CAT_S, -18*CAT_S, 6*CAT_S
|
-9*CAT_S, 18*CAT_S, -18*CAT_S, 6*CAT_S
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
[t3 t2 t1 1] B [p1
|
||||||
|
p2 that is, point 1, tangent at point 1, point 2, tan and point 2
|
||||||
|
t1
|
||||||
|
t2]
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
HMM_Vec4 spline_CT(HMM_Mat4 *C, float t)
|
HMM_Vec4 spline_CT(HMM_Mat4 *C, float t)
|
||||||
{
|
{
|
||||||
float t2 = t*t;
|
float t2 = t*t;
|
||||||
|
@ -145,6 +154,11 @@ HMM_Mat4 make_C(HMM_Vec2 p0, HMM_Vec2 p1, HMM_Vec2 p2, HMM_Vec2 p3, HMM_Mat4 *B)
|
||||||
return HMM_MulM4(G, *B);
|
return HMM_MulM4(G, *B);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HMM_Mat4 catmull_C(HMM_Vec2 c0, HMM_Vec2 c1, HMM_Vec2 c2, HMM_Vec2 c3)
|
||||||
|
{
|
||||||
|
return make_C(c0,c1,c2,c3,&catmull_rom_m);
|
||||||
|
}
|
||||||
|
|
||||||
HMM_Vec2 cubic_spline_d(HMM_Vec2 p0, HMM_Vec2 p1, HMM_Vec2 p2, HMM_Vec2 p3, HMM_Mat4 *m, float d)
|
HMM_Vec2 cubic_spline_d(HMM_Vec2 p0, HMM_Vec2 p1, HMM_Vec2 p2, HMM_Vec2 p3, HMM_Mat4 *m, float d)
|
||||||
{
|
{
|
||||||
HMM_Mat4 G = make_G(p0,p1,p2,p3);
|
HMM_Mat4 G = make_G(p0,p1,p2,p3);
|
||||||
|
@ -193,7 +207,7 @@ HMM_Vec2 *catmull_rom_min_seg(HMM_Vec2 *a, HMM_Vec2 *b, HMM_Vec2 *c, HMM_Vec2 *d
|
||||||
HMM_Mat4 G = make_G(p0, *b, *c, p3);
|
HMM_Mat4 G = make_G(p0, *b, *c, p3);
|
||||||
HMM_Mat4 C = HMM_MulM4(G, catmull_rom_m);
|
HMM_Mat4 C = HMM_MulM4(G, catmull_rom_m);
|
||||||
HMM_Vec2 *ret = NULL;
|
HMM_Vec2 *ret = NULL;
|
||||||
arrsetcap(ret, 100);
|
arrsetcap(ret, 1000);
|
||||||
arrput(ret, *b);
|
arrput(ret, *b);
|
||||||
spline2d_min_seg(0, 1, min_seg, &C, ret);
|
spline2d_min_seg(0, 1, min_seg, &C, ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -228,15 +242,32 @@ HMM_Vec##DIM *spline2d_min_angle_##DIM(float u0, float u1, float max_angle, HMM_
|
||||||
arrput(V##DIM##RET,b);\
|
arrput(V##DIM##RET,b);\
|
||||||
}\
|
}\
|
||||||
|
|
||||||
SPLINE_MIN(2)
|
HMM_Vec2 *spline2d_min_angle_2(float u0, float u1, float max_angle, HMM_Mat4 *C, HMM_Vec2 *arr)
|
||||||
|
{
|
||||||
|
float umid = (u0 + u1)/2;
|
||||||
|
HMM_Vec2 a = spline_CT(C, u0)._2;
|
||||||
|
HMM_Vec2 b = spline_CT(C, u1)._2;
|
||||||
|
HMM_Vec2 m = spline_CT(C, umid)._2;
|
||||||
|
if (fabs(HMM_AngleV2(m,b)) > max_angle) {
|
||||||
|
arr = spline2d_min_angle_2(u0, umid, max_angle, C, arr);
|
||||||
|
arr = spline2d_min_angle_2(umid, u1, max_angle, C, arr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
arrput(arr,b);
|
||||||
|
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//SPLINE_MIN(2)
|
||||||
SPLINE_MIN(3)
|
SPLINE_MIN(3)
|
||||||
|
|
||||||
/* Computes non even points to give the best looking curve */
|
/* Computes non even points to give the best looking curve for a given catmull a,b,c,d */
|
||||||
HMM_Vec2 *catmull_rom_min_angle(HMM_Vec2 *a, HMM_Vec2 *b, HMM_Vec2 *c, HMM_Vec2 *d, float min_angle)
|
HMM_Vec2 *catmull_rom_min_angle(HMM_Vec2 *a, HMM_Vec2 *b, HMM_Vec2 *c, HMM_Vec2 *d, float min_angle, HMM_Vec2 *arr)
|
||||||
{
|
{
|
||||||
HMM_Mat4 G = make_G(*a, *b, *c, *d);
|
HMM_Mat4 C = catmull_C(*a,*b,*c,*d);
|
||||||
HMM_Mat4 C = HMM_MulM4(G, catmull_rom_m);
|
arr = spline2d_min_angle_2(0,1,min_angle*M_PI/180.0,&C, arr);
|
||||||
return spline2d_min_angle_2(0,1,min_angle*M_PI/180.0,&C);
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CR_MA(DIM) \
|
#define CR_MA(DIM) \
|
||||||
|
@ -257,9 +288,22 @@ HMM_Vec##DIM *catmull_rom_ma_v##DIM(HMM_Vec##DIM *cp, float ma) \
|
||||||
return arrdup(V##DIM##RET);\
|
return arrdup(V##DIM##RET);\
|
||||||
}\
|
}\
|
||||||
|
|
||||||
CR_MA(2)
|
//CR_MA(2)
|
||||||
CR_MA(3)
|
|
||||||
CR_MA(4)
|
HMM_Vec2 *catmull_rom_ma_v2(HMM_Vec2 *cp, float ma)
|
||||||
|
{
|
||||||
|
if (arrlen(cp) < 4) return NULL;
|
||||||
|
HMM_Vec2 *ret = NULL;
|
||||||
|
int segments = arrlen(cp)-3;
|
||||||
|
arrput(ret, cp[1]);
|
||||||
|
for (int i = 1; i < arrlen(cp)-2; i++)
|
||||||
|
ret = catmull_rom_min_angle(&cp[i-1], &cp[i], &cp[i+1], &cp[i+2], ma, ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//CR_MA(3)
|
||||||
|
//CR_MA(4)
|
||||||
|
|
||||||
HMM_Vec2 catmull_rom_query(HMM_Vec2 *cp, float d, HMM_Mat4 *G)
|
HMM_Vec2 catmull_rom_query(HMM_Vec2 *cp, float d, HMM_Mat4 *G)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue