Add vector swizzling; custom velocity function; per object gravity disabling; max velocities
This commit is contained in:
parent
5ee444465e
commit
1a6dbfaa88
|
@ -573,14 +573,93 @@ function arrsetelem(str, n)
|
|||
Object.defineProperty(Array.prototype, str, setelem(n));
|
||||
}
|
||||
|
||||
Object.defineProperty(Array.prototype, 'x', setelem(0));
|
||||
Object.defineProperty(Array.prototype, 'y', setelem(1));
|
||||
Object.defineProperty(Array.prototype, 'z', setelem(2));
|
||||
Object.defineProperty(Array.prototype, 'w', setelem(3));
|
||||
arrsetelem('r', 0);
|
||||
arrsetelem('g', 1);
|
||||
arrsetelem('b', 2);
|
||||
arrsetelem('a', 3);
|
||||
var arr_elems = ['x', 'y', 'z', 'w'];
|
||||
var quat_elems = ['i', 'j', 'k'];
|
||||
var color_elems = ['r', 'g', 'b', 'a'];
|
||||
|
||||
arr_elems.forEach(function(x, i) { arrsetelem(x,i); });
|
||||
quat_elems.forEach(function(x, i) { arrsetelem(x,i); });
|
||||
color_elems.forEach(function(x, i) { arrsetelem(x,i); });
|
||||
|
||||
var nums = [0,1,2,3];
|
||||
|
||||
var swizz = [];
|
||||
|
||||
for (var i of nums)
|
||||
for (var j of nums)
|
||||
swizz.push([i,j]);
|
||||
|
||||
swizz.forEach(function(x) {
|
||||
var str = "";
|
||||
for (var i of x)
|
||||
str += arr_elems[i];
|
||||
|
||||
Object.defineProperty(Array.prototype, str, {
|
||||
get() { return [this[x[0]], this[x[1]]]; },
|
||||
set(j) { this[x[0]] = j[0]; this[x[1]] = j[1]; },
|
||||
});
|
||||
|
||||
str = "";
|
||||
for (var i of x) str += color_elems[i];
|
||||
Object.defineProperty(Array.prototype, str, {
|
||||
get() { return [this[x[0]], this[x[1]]]; },
|
||||
set(j) { this[x[0]] = j[0]; this[x[1]] = j[1]; },
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
swizz = [];
|
||||
for (var i of nums)
|
||||
for (var j of nums)
|
||||
for (var k of nums)
|
||||
swizz.push([i,j,k]);
|
||||
|
||||
swizz.forEach(function(x) {
|
||||
var str = "";
|
||||
for (var i of x)
|
||||
str += arr_elems[i];
|
||||
|
||||
Object.defineProperty(Array.prototype, str, {
|
||||
get() { return [this[x[0]], this[x[1]], this[x[2]]]; },
|
||||
set(j) { this[x[0]] = j[0]; this[x[1]] = j[1]; this[x[2]] = j[2];},
|
||||
});
|
||||
|
||||
str = "";
|
||||
for (var i of x) str += color_elems[i];
|
||||
Object.defineProperty(Array.prototype, str, {
|
||||
get() { return [this[x[0]], this[x[1]], this[x[2]]]; },
|
||||
set(j) { this[x[0]] = j[0]; this[x[1]] = j[1]; this[x[2]] = j[2];},
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
swizz = [];
|
||||
for (var i of nums)
|
||||
for (var j of nums)
|
||||
for (var k of nums)
|
||||
for (var w of nums)
|
||||
swizz.push([i,j,k,w]);
|
||||
|
||||
swizz.forEach(function(x) {
|
||||
var str = "";
|
||||
for (var i of x)
|
||||
str += arr_elems[i];
|
||||
|
||||
Object.defineProperty(Array.prototype, str, {
|
||||
get() { return [this[x[0]], this[x[1]], this[x[2]], this[x[3]]];},
|
||||
set(j) { this[x[0]] = j[0]; this[x[1]] = j[1]; this[x[2]] = j[2]; this[x[3]] = j[3];},
|
||||
});
|
||||
|
||||
str = "";
|
||||
for (var i of x) str += color_elems[i];
|
||||
Object.defineProperty(Array.prototype, str, {
|
||||
get() { return [this[x[0]], this[x[1]], this[x[2]], this[x[3]]];},
|
||||
set(j) { this[x[0]] = j[0]; this[x[1]] = j[1]; this[x[2]] = j[2]; this[x[3]] = j[3];},
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
Object.defineProperty(Array.prototype, 'add', {
|
||||
value: function(b) {
|
||||
|
|
|
@ -560,6 +560,10 @@ component.edge2d = Object.copy(collider2d, {
|
|||
return spoints;
|
||||
},
|
||||
|
||||
post() {
|
||||
this.cpoints = [];
|
||||
},
|
||||
|
||||
sample(n) {
|
||||
var spoints = this.spoints();
|
||||
|
||||
|
@ -729,12 +733,12 @@ bucket.inputs['C-lm'] = function() {
|
|||
bucket.inputs['C-lm'].doc = "Add a point to the spline at the mouse position.";
|
||||
|
||||
bucket.inputs['C-M-lm'] = function() {
|
||||
// var idx = grab_from_points(screen2world(Mouse.pos), this.cpoints.map(function(x) {return x.sub(this.gameobject.worldpos()); }, this), 25);
|
||||
var idx = cmd(59, Mouse.worldpos.sub(this.gameobject.pos), this.cpoints, 250);
|
||||
Log.warn(idx);
|
||||
// var idx = grab_from_points(screen2world(Mouse.pos), this.cpoints.map(function(x) {return x.add(this.gameobject.pos); }, this), 25);
|
||||
if (idx === -1) return;
|
||||
|
||||
this.cpoints.splice(idx, 1);
|
||||
if (idx <= 0 || idx > this.cpoints.length) return;
|
||||
|
||||
this.cpoints.splice(idx-1, 1);
|
||||
};
|
||||
bucket.inputs['C-M-lm'].doc = "Remove point from the spline.";
|
||||
|
||||
|
|
|
@ -168,8 +168,11 @@ function ediff(from,to)
|
|||
if (typeof v === 'undefined') return;
|
||||
|
||||
if (Array.isArray(v)) {
|
||||
if (!Array.isArray(to[key]) || v.length !== to[key].length)
|
||||
ret[key] = Object.values(ediff(v, []));
|
||||
if (!Array.isArray(to[key]) || v.length !== to[key].length) {
|
||||
var r = ediff(v,[]);
|
||||
if (r) ret[key] = Object.values(r);
|
||||
return;
|
||||
}
|
||||
|
||||
var diff = ediff(from[key], to[key]);
|
||||
if (diff && !diff.empty)
|
||||
|
|
|
@ -7,7 +7,18 @@ prototypes.generate_ur('.');
|
|||
var editor_config = {
|
||||
grid_size: 100,
|
||||
ruler_mark_px: 100,
|
||||
grid_color: [99, 255, 128, 100],
|
||||
grid_color: Color.green.alpha(0.3),
|
||||
|
||||
};
|
||||
|
||||
var Device = {
|
||||
pc: [1920,1080],
|
||||
macbook_m2: [2560,1664],
|
||||
ds_top: [400,240],
|
||||
ds_bottom: [320,240],
|
||||
switch: [1280,720],
|
||||
ipad_air_m2: [2360,1640],
|
||||
iphone_se: [1334, 750],
|
||||
};
|
||||
|
||||
var configs = {
|
||||
|
@ -209,6 +220,7 @@ var editor = {
|
|||
Player.players[0].control(limited_editor);
|
||||
Register.unregister_obj(this);
|
||||
editor.dbg_play = Primum.spawn(this.dbg_ur);
|
||||
editor.dbg_play.pos = [0,0];
|
||||
load("debug.js");
|
||||
},
|
||||
|
||||
|
@ -538,6 +550,9 @@ var editor = {
|
|||
Debug.boundingbox(bb, Color.Editor.select.alpha(0.1));
|
||||
Debug.line(bb2points(bb).wrapped(1), Color.white);
|
||||
}
|
||||
|
||||
/* 1920x1080 */
|
||||
Debug.line(bb2points(cwh2bb(world2screen([0,0]),[1920/Game.camera.zoom,1080/Game.camera.zoom])).wrapped(1), Color.yellow);
|
||||
|
||||
if (this.curpanel && this.curpanel.on)
|
||||
this.curpanel.gui();
|
||||
|
@ -676,6 +691,32 @@ editor.inputs['C-a'].doc = "Select all objects.";
|
|||
editor.inputs['C-`'] = function() { editor.openpanel(replpanel); }
|
||||
editor.inputs['C-`'].doc = "Open or close the repl.";
|
||||
|
||||
editor.inputs.n = function() {
|
||||
if (editor.selectlist.length !== 1) return;
|
||||
var o = editor.try_select();
|
||||
if (!o) return;
|
||||
if (o === editor.selectlist[0]) return;
|
||||
if (o.level !== editor.selectlist[0].level) return;
|
||||
|
||||
var tpos = editor.selectlist[0].pos;
|
||||
tpos.x *= -1;
|
||||
o.pos = tpos;
|
||||
};
|
||||
editor.inputs.n.doc = "Set the hovered object's position to mirror the selected object's position on the X axis."
|
||||
editor.inputs['M-n'] = function()
|
||||
{
|
||||
if (editor.selectlist.length !== 1) return;
|
||||
var o = editor.try_select();
|
||||
if (!o) return;
|
||||
if (o === editor.selectlist[0]) return;
|
||||
if (o.level !== editor.selectlist[0].level) return;
|
||||
|
||||
var tpos = editor.selectlist[0].pos;
|
||||
tpos.y *= -1;
|
||||
o.pos = tpos;
|
||||
};
|
||||
editor.inputs.n.doc = "Set the hovered object's position to mirror the selected object's position on the Y axis."
|
||||
|
||||
/* Return if selected component. */
|
||||
editor.inputs['h'] = function() {
|
||||
var visible = true;
|
||||
|
|
|
@ -34,6 +34,12 @@ var gameobject = {
|
|||
};
|
||||
this.objects = {};
|
||||
},
|
||||
|
||||
set max_velocity(x) { cmd(151, this.body, x); },
|
||||
get max_velocity() { return cmd(152, this.body); },
|
||||
set max_angularvelocity(x) { cmd(154, this.body, Math.deg2rad(x)); },
|
||||
get max_angularvelocity() { return Math.rad2deg(cmd(155, this.body)); },
|
||||
set torque(x) { if (!(x >= 0 && x <= Infinity)) return; cmd(153, this.body, x); },
|
||||
gscale() { return cmd(103,this.body); },
|
||||
sgscale(x) { cmd(36,this.body,x) },
|
||||
get scale() {
|
||||
|
@ -99,6 +105,8 @@ var gameobject = {
|
|||
|
||||
return q_body(5, this.body);
|
||||
},
|
||||
set gravity(x) { cmd(158,this.body, x); },
|
||||
get gravity() { return cmd(159,this.body); },
|
||||
|
||||
set phys(x) { set_body(1, this.body, x); },
|
||||
get phys() { return q_body(0,this.body); },
|
||||
|
@ -199,9 +207,20 @@ var gameobject = {
|
|||
components: {},
|
||||
objects: {},
|
||||
level: undefined,
|
||||
get_moi() { return q_body(6, this.body); },
|
||||
|
||||
set_moi(x) {
|
||||
if(x <= 0) {
|
||||
Log.error("Cannot set moment of inertia to 0 or less.");
|
||||
return;
|
||||
}
|
||||
set_body(13, this.body, x);
|
||||
},
|
||||
|
||||
pulse(vec) { set_body(4, this.body, vec);},
|
||||
shove(vec) { set_body(12,this.body,vec);},
|
||||
shove_at(vec, at) { set_body(14,this.body,vec,at); },
|
||||
torque(val) { cmd(153, this.body, val); },
|
||||
world2this(pos) { return cmd(70, this.body, pos); },
|
||||
this2world(pos) { return cmd(71, this.body,pos); },
|
||||
set layer(x) { cmd(75,this.body,x); },
|
||||
|
@ -272,12 +291,19 @@ var gameobject = {
|
|||
register_collide(1, x.collide, x, obj.body, x.shape);
|
||||
});
|
||||
},
|
||||
pos: [0,0],
|
||||
angle:0,
|
||||
velocity:[0,0],
|
||||
angularvelocity:0,
|
||||
phys:Physics.static,
|
||||
flipx:false,
|
||||
flipy:false,
|
||||
scale:1,
|
||||
elasticity:0.5,
|
||||
friction:1,
|
||||
gravity: true,
|
||||
max_velocity: Infinity,
|
||||
max_angularvelocity: Infinity,
|
||||
mass:1,
|
||||
layer:0,
|
||||
worldpos() { return [0,0]; },
|
||||
|
@ -520,6 +546,7 @@ var gameobject = {
|
|||
if (data)
|
||||
Object.dainty_assign(obj,data);
|
||||
|
||||
if (typeof obj.warmup === 'function') obj.warmup();
|
||||
if (Game.playing() && typeof obj.start === 'function') obj.start();
|
||||
|
||||
return obj;
|
||||
|
@ -586,6 +613,7 @@ gameobject.doc = {
|
|||
flipy: "Set the object to be flipped on its y axis.",
|
||||
elasticity: `When two objects collide, their elasticities are multiplied together. Their velocities are then multiplied by this value to find their resultant velocities.`,
|
||||
friction: `When one object touches another, friction slows them down.`,
|
||||
gravity: 'True if this object should be affected by gravity.',
|
||||
mass: `The higher the mass of the object, the less forces will affect it.`,
|
||||
phys: `Set to 0, 1, or 2, representing static, kinematic, and dynamic.`,
|
||||
worldpos: `Function returns the world position of the object.`,
|
||||
|
@ -594,6 +622,9 @@ gameobject.doc = {
|
|||
rotate: `Function to rotate this object by x degrees.`,
|
||||
pulse: `Apply an impulse to this body in world coordinates. Impulse is a short force.`,
|
||||
shove: `Apply a force to this body in world coordinates. Should be used over many frames.`,
|
||||
shove_at: 'Apply a force to this body, at a position relative to itself.',
|
||||
max_velocity: 'The max linear velocity this object can travel.',
|
||||
max_angularvelocity: 'The max angular velocity this object can rotate.',
|
||||
in_air: `Return true if the object is in the air.`,
|
||||
on_ground: `Return true if the object is on the ground.`,
|
||||
spawn: `Create an instance of a supplied ur-type on this object. Optionally provide a data object to modify the created entity.`,
|
||||
|
|
|
@ -141,11 +141,33 @@ static void gameobject_setpickcolor(struct gameobject *go) {
|
|||
*/
|
||||
}
|
||||
|
||||
static void velocityFn(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
|
||||
{
|
||||
struct gameobject *go = id2go(cpBodyGetUserData(body));
|
||||
if (!go)
|
||||
cpBodyUpdateVelocity(body,gravity,damping,dt);
|
||||
|
||||
// cpFloat d = isnan(go->damping) ? damping : d;
|
||||
cpVect g = go->gravity ? gravity : cpvzero;
|
||||
|
||||
cpBodyUpdateVelocity(body,g,damping,dt);
|
||||
if (!isinf(go->maxvelocity))
|
||||
cpBodySetVelocity(body, cpvclamp(cpBodyGetVelocity(body), go->maxvelocity));
|
||||
|
||||
if (!isinf(go->maxangularvelocity)) {
|
||||
float av = cpBodyGetAngularVelocity(body);
|
||||
if (fabs(av) > go->maxangularvelocity)
|
||||
cpBodySetAngularVelocity(body, copysignf(go->maxangularvelocity, av));
|
||||
}
|
||||
}
|
||||
|
||||
int MakeGameobject() {
|
||||
struct gameobject go = {
|
||||
.scale = 1.f,
|
||||
.scale3 = (HMM_Vec3){1.f,1.f,1.f},
|
||||
.bodytype = CP_BODY_TYPE_STATIC,
|
||||
.maxvelocity = INFINITY,
|
||||
.maxangularvelocity = INFINITY,
|
||||
.mass = 1.f,
|
||||
.next = -1,
|
||||
.sensor = 0,
|
||||
|
@ -157,6 +179,7 @@ int MakeGameobject() {
|
|||
go.cbs.separate.obj = JS_NULL;
|
||||
|
||||
go.body = cpSpaceAddBody(space, cpBodyNew(go.mass, 1.f));
|
||||
cpBodySetVelocityUpdateFunc(go.body, velocityFn);
|
||||
|
||||
int retid;
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@ struct gameobject {
|
|||
float mass;
|
||||
float f; /* friction */
|
||||
float e; /* elasticity */
|
||||
float maxvelocity;
|
||||
float maxangularvelocity;
|
||||
int gravity;
|
||||
float damping;
|
||||
int flipx; /* 1 or -1 */
|
||||
int flipy;
|
||||
int sensor;
|
||||
|
|
|
@ -1131,7 +1131,36 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
case 150:
|
||||
draw_drawmodel(js2ptr(argv[1]));
|
||||
break;
|
||||
|
||||
|
||||
case 151:
|
||||
js2go(argv[1])->maxvelocity = js2number(argv[2]);
|
||||
break;
|
||||
case 152:
|
||||
ret = num2js(js2go(argv[1])->maxvelocity);
|
||||
break;
|
||||
case 153:
|
||||
cpBodySetTorque(js2go(argv[1])->body, js2number(argv[2]));
|
||||
break;
|
||||
|
||||
case 154:
|
||||
js2go(argv[1])->maxangularvelocity = js2number(argv[2]);
|
||||
break;
|
||||
case 155:
|
||||
ret = num2js(js2go(argv[1])->maxangularvelocity);
|
||||
break;
|
||||
|
||||
case 156:
|
||||
js2go(argv[1])->damping = js2number(argv[2]);
|
||||
break;
|
||||
case 157:
|
||||
ret = num2js(js2go(argv[1])->damping);
|
||||
break;
|
||||
case 158:
|
||||
js2go(argv[1])->gravity = js2bool(argv[2]);
|
||||
break;
|
||||
case 159:
|
||||
ret = bool2js(js2go(argv[1])->gravity);
|
||||
break;
|
||||
}
|
||||
|
||||
if (str)
|
||||
|
@ -1375,6 +1404,9 @@ JSValue duk_set_body(JSContext *js, JSValueConst this, int argc, JSValueConst *a
|
|||
case 13:
|
||||
cpBodySetMoment(go->body, js2number(argv[2]));
|
||||
return JS_NULL;
|
||||
case 14:
|
||||
cpBodyApplyForceAtLocalPoint(go->body, js2vec2(argv[2]), js2vec2(argv[3]));
|
||||
return JS_NULL;
|
||||
}
|
||||
|
||||
cpSpaceReindexShapesForBody(space, go->body);
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "jsffi.h"
|
||||
#include "font.h"
|
||||
|
||||
#include "gameobject.h"
|
||||
|
||||
#include "ftw.h"
|
||||
|
||||
#include "stb_ds.h"
|
||||
|
@ -304,7 +306,9 @@ void call_nk_gui() { js_callee_exec(&nk_gui_callee, 0, NULL); }
|
|||
|
||||
static struct callee physupdate_callee;
|
||||
void register_physics(struct callee c) { physupdate_callee = c; }
|
||||
void call_physics(double dt) { callee_dbl(physupdate_callee, dt); }
|
||||
void call_physics(double dt) {
|
||||
callee_dbl(physupdate_callee, dt);
|
||||
}
|
||||
|
||||
struct callee debug_callee;
|
||||
void register_debug(struct callee c) { debug_callee = c; }
|
||||
|
|
Loading…
Reference in a new issue