initial physics constraints
This commit is contained in:
parent
192c253f12
commit
5bdf311da9
|
@ -1245,6 +1245,7 @@ Object.defineProperty(Number.prototype, 'lerp', {
|
||||||
Math.clamp = function (x, l, h) { return x > h ? h : x < l ? l : x; }
|
Math.clamp = function (x, l, h) { return x > h ? h : x < l ? l : x; }
|
||||||
|
|
||||||
Math.random_range = function(min,max) { return Math.random() * (max-min) + min; };
|
Math.random_range = function(min,max) { return Math.random() * (max-min) + min; };
|
||||||
|
Math.rand_int = function(max) { return Math.floor(Math.random()*max); };
|
||||||
|
|
||||||
Math.snap = function(val, grid) {
|
Math.snap = function(val, grid) {
|
||||||
if (!grid || grid === 1) return Math.round(val);
|
if (!grid || grid === 1) return Math.round(val);
|
||||||
|
|
|
@ -193,6 +193,19 @@ var gameobject = {
|
||||||
full_path() {
|
full_path() {
|
||||||
return this.path_from(Primum);
|
return this.path_from(Primum);
|
||||||
},
|
},
|
||||||
|
/* pin this object to the to object */
|
||||||
|
pin(to) {
|
||||||
|
var p = cmd(222,this.body, to.body);
|
||||||
|
},
|
||||||
|
pivot(to, piv) {
|
||||||
|
piv ??= this.worldpos();
|
||||||
|
var p = cmd(221,this.body,to.body,piv);
|
||||||
|
},
|
||||||
|
gear(to, phase, ratio) {
|
||||||
|
phase ??= 1;
|
||||||
|
ratio ??= 1;
|
||||||
|
var p = cmd(223,this.body,to.body,phase,ratio);
|
||||||
|
},
|
||||||
|
|
||||||
path_from(o) {
|
path_from(o) {
|
||||||
var p = this.toString();
|
var p = this.toString();
|
||||||
|
@ -517,6 +530,7 @@ var gameobject = {
|
||||||
Player.do_uncontrol(this);
|
Player.do_uncontrol(this);
|
||||||
Register.unregister_obj(this);
|
Register.unregister_obj(this);
|
||||||
|
|
||||||
|
if (this.__proto__.instances)
|
||||||
this.__proto__.instances.remove(this);
|
this.__proto__.instances.remove(this);
|
||||||
|
|
||||||
for (var key in this.components) {
|
for (var key in this.components) {
|
||||||
|
|
|
@ -213,10 +213,9 @@ struct phys2d_circle *Make2DCircle(gameobject *go) {
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
float phys2d_circle_moi(struct phys2d_circle *c, float m) {
|
float phys2d_circle_moi(struct phys2d_circle *c) {
|
||||||
return 1;
|
float m = c->shape.go->mass;
|
||||||
//TODO: Calculate correctly
|
return cpMomentForCircle(m, 0, cpCircleShapeGetRadius(c->shape.shape), cpCircleShapeGetOffset(c->shape.shape));
|
||||||
//return cpMomentForCircle(m, 0, c->radius, c->offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void phys2d_circledel(struct phys2d_circle *c) {
|
void phys2d_circledel(struct phys2d_circle *c) {
|
||||||
|
@ -233,6 +232,18 @@ void phys2d_dbgdrawcpcirc(cpShape *c) {
|
||||||
draw_circle(pos,radius,radius,color,-1);
|
draw_circle(pos,radius,radius,color,-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void phys2d_shape_apply(struct phys2d_shape *s)
|
||||||
|
{
|
||||||
|
float moment = cpBodyGetMoment(s->go->body);
|
||||||
|
float moi = s->moi(s->data);
|
||||||
|
|
||||||
|
s->apply(s->data);
|
||||||
|
float newmoi = s->moi(s->data);
|
||||||
|
moment-=moi;
|
||||||
|
moment += newmoi;
|
||||||
|
cpBodySetMoment(s->go->body, moment);
|
||||||
|
}
|
||||||
|
|
||||||
void phys2d_dbgdrawcircle(struct phys2d_circle *circle) {
|
void phys2d_dbgdrawcircle(struct phys2d_circle *circle) {
|
||||||
phys2d_dbgdrawcpcirc(circle->shape.shape);
|
phys2d_dbgdrawcpcirc(circle->shape.shape);
|
||||||
}
|
}
|
||||||
|
@ -268,12 +279,16 @@ void phys2d_poly_free(struct phys2d_poly *poly)
|
||||||
free(poly);
|
free(poly);
|
||||||
}
|
}
|
||||||
|
|
||||||
float phys2d_poly_moi(struct phys2d_poly *poly, float m) {
|
float phys2d_poly_moi(struct phys2d_poly *poly) {
|
||||||
float moi = cpMomentForPoly(m, arrlen(poly->points), (cpVect*)poly->points, cpvzero, poly->radius);
|
float m = poly->shape.go->mass;
|
||||||
if (isnan(moi)) {
|
int len = cpPolyShapeGetCount(poly->shape.shape);
|
||||||
// YughError("Polygon MOI returned an error. Returning 0.");
|
cpVect points[len];
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
points[i] = cpPolyShapeGetVert(poly->shape.shape, i);
|
||||||
|
|
||||||
|
float moi = cpMomentForPoly(m, len, points, cpvzero, poly->radius);
|
||||||
|
if (!isfinite(moi))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
return moi;
|
return moi;
|
||||||
}
|
}
|
||||||
|
@ -297,7 +312,7 @@ void phys2d_poly_setverts(struct phys2d_poly *poly, HMM_Vec2 *verts) {
|
||||||
for (int i = 0; i < arrlen(verts); i++)
|
for (int i = 0; i < arrlen(verts); i++)
|
||||||
poly->points[i] = verts[i];
|
poly->points[i] = verts[i];
|
||||||
|
|
||||||
phys2d_applypoly(poly);
|
phys2d_shape_apply(&poly->shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
void phys2d_applypoly(struct phys2d_poly *poly) {
|
void phys2d_applypoly(struct phys2d_poly *poly) {
|
||||||
|
@ -365,7 +380,8 @@ void phys2d_edge_free(struct phys2d_edge *edge)
|
||||||
free(edge);
|
free(edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
float phys2d_edge_moi(struct phys2d_edge *edge, float m) {
|
float phys2d_edge_moi(struct phys2d_edge *edge) {
|
||||||
|
float m = edge->shape.go->mass;
|
||||||
float moi = 0;
|
float moi = 0;
|
||||||
for (int i = 0; i < arrlen(edge->points) - 1; i++)
|
for (int i = 0; i < arrlen(edge->points) - 1; i++)
|
||||||
moi += cpMomentForSegment(m, edge->points[i].cp, edge->points[i + 1].cp, edge->thickness);
|
moi += cpMomentForSegment(m, edge->points[i].cp, edge->points[i + 1].cp, edge->thickness);
|
||||||
|
|
|
@ -23,11 +23,13 @@ struct phys2d_shape {
|
||||||
gameobject *go;
|
gameobject *go;
|
||||||
void *data; /* The specific subtype; phys2d_circle, etc */
|
void *data; /* The specific subtype; phys2d_circle, etc */
|
||||||
void (*debugdraw)(void *data);
|
void (*debugdraw)(void *data);
|
||||||
float (*moi)(void *data, float mass);
|
float (*moi)(void *data);
|
||||||
void (*apply)(void *data);
|
void (*apply)(void *data);
|
||||||
void (*free)(void *data);
|
void (*free)(void *data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void phys2d_shape_apply(struct phys2d_shape *s);
|
||||||
|
|
||||||
/* Circles are the fastest colldier type */
|
/* Circles are the fastest colldier type */
|
||||||
struct phys2d_circle {
|
struct phys2d_circle {
|
||||||
float radius;
|
float radius;
|
||||||
|
@ -56,7 +58,7 @@ struct phys2d_circle *Make2DCircle(gameobject *go);
|
||||||
void phys2d_circledel(struct phys2d_circle *c);
|
void phys2d_circledel(struct phys2d_circle *c);
|
||||||
void phys2d_applycircle(struct phys2d_circle *circle);
|
void phys2d_applycircle(struct phys2d_circle *circle);
|
||||||
void phys2d_dbgdrawcircle(struct phys2d_circle *circle);
|
void phys2d_dbgdrawcircle(struct phys2d_circle *circle);
|
||||||
float phys2d_circle_moi(struct phys2d_circle *c, float m);
|
float phys2d_circle_moi(struct phys2d_circle *c);
|
||||||
|
|
||||||
struct phys2d_poly *Make2DPoly(gameobject *go);
|
struct phys2d_poly *Make2DPoly(gameobject *go);
|
||||||
void phys2d_poly_free(struct phys2d_poly *poly);
|
void phys2d_poly_free(struct phys2d_poly *poly);
|
||||||
|
@ -65,7 +67,7 @@ void phys2d_applypoly(struct phys2d_poly *poly);
|
||||||
void phys2d_dbgdrawpoly(struct phys2d_poly *poly);
|
void phys2d_dbgdrawpoly(struct phys2d_poly *poly);
|
||||||
void phys2d_polyaddvert(struct phys2d_poly *poly);
|
void phys2d_polyaddvert(struct phys2d_poly *poly);
|
||||||
void phys2d_poly_setverts(struct phys2d_poly *poly, HMM_Vec2 *verts);
|
void phys2d_poly_setverts(struct phys2d_poly *poly, HMM_Vec2 *verts);
|
||||||
float phys2d_poly_moi(struct phys2d_poly *poly, float m);
|
float phys2d_poly_moi(struct phys2d_poly *poly);
|
||||||
|
|
||||||
struct phys2d_edge *Make2DEdge(gameobject *go);
|
struct phys2d_edge *Make2DEdge(gameobject *go);
|
||||||
void phys2d_edge_free(struct phys2d_edge *edge);
|
void phys2d_edge_free(struct phys2d_edge *edge);
|
||||||
|
@ -74,7 +76,7 @@ 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, HMM_Vec2 v);
|
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);
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -93,16 +93,16 @@ void go_shape_apply(cpBody *body, cpShape *shape, gameobject *go) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void go_shape_moi(cpBody *body, cpShape *shape, gameobject *go) {
|
void go_shape_moi(cpBody *body, cpShape *shape, gameobject *go) {
|
||||||
float moment = cpBodyGetMoment(go->body);
|
float moment = cpBodyGetMoment(body);
|
||||||
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
||||||
if (!s) {
|
if (!s) {
|
||||||
cpBodySetMoment(go->body, moment + 1);
|
cpBodySetMoment(body, moment + 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
moment += s->moi(s->data, go->mass);
|
moment += s->moi(s->data);
|
||||||
if (moment < 0) moment = 1;
|
if (moment < 0) moment = 0;
|
||||||
cpBodySetMoment(go->body, 1);
|
cpBodySetMoment(body, moment);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gameobject_apply(gameobject *go) {
|
void gameobject_apply(gameobject *go) {
|
||||||
|
|
|
@ -1370,6 +1370,18 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||||
case 220:
|
case 220:
|
||||||
ret = num2js(js2sprite(argv[1])->drawmode);
|
ret = num2js(js2sprite(argv[1])->drawmode);
|
||||||
break;
|
break;
|
||||||
|
case 221:
|
||||||
|
ret = ptr2js(cpPivotJointNew(js2gameobject(argv[1])->body, js2gameobject(argv[2])->body,js2vec2(argv[3]).cp));
|
||||||
|
cpSpaceAddConstraint(space,js2ptr(ret));
|
||||||
|
break;
|
||||||
|
case 222:
|
||||||
|
ret = ptr2js(cpPinJointNew(js2gameobject(argv[1])->body, js2gameobject(argv[2])->body, cpvzero,cpvzero));
|
||||||
|
cpSpaceAddConstraint(space, js2ptr(ret));
|
||||||
|
break;
|
||||||
|
case 223:
|
||||||
|
ret = ptr2js(cpGearJointNew(js2gameobject(argv[1])->body, js2gameobject(argv[2])->body, js2number(argv[3]), js2number(argv[4])));
|
||||||
|
cpSpaceAddConstraint(space,js2ptr(ret));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str)
|
if (str)
|
||||||
|
@ -1706,8 +1718,8 @@ JSValue duk_cmd_circle2d(JSContext *js, JSValueConst this, int argc, JSValueCons
|
||||||
case 3:
|
case 3:
|
||||||
return vec2js(circle->offset);
|
return vec2js(circle->offset);
|
||||||
}
|
}
|
||||||
|
phys2d_shape_apply(&circle->shape);
|
||||||
|
|
||||||
phys2d_applycircle(circle);
|
|
||||||
return JS_UNDEFINED;
|
return JS_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue