fix camera, spline
This commit is contained in:
parent
a1aff79d5c
commit
dacad57577
|
@ -44,7 +44,7 @@ var component = {
|
||||||
|
|
||||||
make(go) {
|
make(go) {
|
||||||
var nc = Object.create(this);
|
var nc = Object.create(this);
|
||||||
// nc.gameobject = go;
|
nc.gameobject = go;
|
||||||
Object.assign(nc, this._enghook(go.body));
|
Object.assign(nc, this._enghook(go.body));
|
||||||
nc.sync();
|
nc.sync();
|
||||||
assign_impl(nc,this.impl);
|
assign_impl(nc,this.impl);
|
||||||
|
@ -61,9 +61,7 @@ var component = {
|
||||||
|
|
||||||
prepare_center() {},
|
prepare_center() {},
|
||||||
finish_center() {},
|
finish_center() {},
|
||||||
extend(spec) {
|
extend(spec) { return Object.copy(this, spec); },
|
||||||
return Object.copy(this, spec);
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
component.sprite = Object.copy(component, {
|
component.sprite = Object.copy(component, {
|
||||||
|
@ -326,9 +324,7 @@ component.char2dimpl = {
|
||||||
this.timer.stop();
|
this.timer.stop();
|
||||||
},
|
},
|
||||||
|
|
||||||
kill() {
|
kill() { cmd(9, this.id); },
|
||||||
cmd(9, this.id);
|
|
||||||
},
|
|
||||||
|
|
||||||
add_anim(anim,name) {
|
add_anim(anim,name) {
|
||||||
if (name in this) return;
|
if (name in this) return;
|
||||||
|
@ -338,6 +334,7 @@ component.char2dimpl = {
|
||||||
},
|
},
|
||||||
|
|
||||||
post() {
|
post() {
|
||||||
|
/*
|
||||||
this.timer = timer.make(this.advance.bind(this), 1);
|
this.timer = timer.make(this.advance.bind(this), 1);
|
||||||
this.timer.loop = true;
|
this.timer.loop = true;
|
||||||
Object.hide(this,'timer');
|
Object.hide(this,'timer');
|
||||||
|
@ -346,7 +343,7 @@ component.char2dimpl = {
|
||||||
this.anims[k] = run_env(path + ".asset", path);
|
this.anims[k] = run_env(path + ".asset", path);
|
||||||
this.add_anim(this.anims[k], k);
|
this.add_anim(this.anims[k], k);
|
||||||
}
|
}
|
||||||
Object.hide(this, 'acur');
|
Object.hide(this, 'acur');*/
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -452,7 +449,7 @@ component.polygon2d = Object.copy(collider2d, {
|
||||||
flipy: false,
|
flipy: false,
|
||||||
|
|
||||||
boundingbox() {
|
boundingbox() {
|
||||||
return points2bb(this.spoints);
|
return points2bb(this.spoints());
|
||||||
},
|
},
|
||||||
|
|
||||||
hides: ['id', 'shape', 'gameobject'],
|
hides: ['id', 'shape', 'gameobject'],
|
||||||
|
@ -464,7 +461,7 @@ component.polygon2d = Object.copy(collider2d, {
|
||||||
},
|
},
|
||||||
|
|
||||||
/* EDITOR */
|
/* EDITOR */
|
||||||
get spoints() {
|
spoints() {
|
||||||
var spoints = this.points.slice();
|
var spoints = this.points.slice();
|
||||||
|
|
||||||
if (this.flipx) {
|
if (this.flipx) {
|
||||||
|
@ -486,13 +483,8 @@ component.polygon2d = Object.copy(collider2d, {
|
||||||
},
|
},
|
||||||
|
|
||||||
gizmo() {
|
gizmo() {
|
||||||
this.spoints.forEach(function(x) {
|
this.spoints().forEach(x => Shape.point(this.gameobject.this2screen(x), 3, Color.green));
|
||||||
Shape.point(world2screen(this.gameobject.this2world(x)), 3, Color.green);
|
this.points.forEach((x,i)=>Debug.numbered_point(this.gameobject.this2screen(x), i));
|
||||||
}, this);
|
|
||||||
|
|
||||||
this.points.forEach(function(x, i) {
|
|
||||||
Debug.numbered_point(this.gameobject.this2world(x), i);
|
|
||||||
}, this);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
pick(pos) {
|
pick(pos) {
|
||||||
|
@ -509,12 +501,8 @@ component.polygon2d = Object.copy(collider2d, {
|
||||||
});
|
});
|
||||||
|
|
||||||
component.polygon2d.impl = Object.mix(collider2d.impl, {
|
component.polygon2d.impl = Object.mix(collider2d.impl, {
|
||||||
sync() {
|
sync() { cmd_poly2d(0, this.id, this.spoints()); },
|
||||||
cmd_poly2d(0, this.id, this.spoints);
|
query() { return cmd(80, this.shape); },
|
||||||
},
|
|
||||||
query() {
|
|
||||||
return cmd(80, this.shape);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var polygon2d = component.polygon2d;
|
var polygon2d = component.polygon2d;
|
||||||
|
@ -685,11 +673,55 @@ component.edge2d = Object.copy(collider2d, {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
rm_node(idx) {
|
||||||
|
if (idx < 0 || idx >= this.cpoints.length) return;
|
||||||
|
if (Spline.is_catmull(this.type))
|
||||||
|
this.cpoints.splice(idx,1);
|
||||||
|
|
||||||
|
if (Spline.is_bezier(this.type)) {
|
||||||
|
Debug.assert(Spline.bezier_is_node(this.cpoints, idx), 'Attempted to delete a bezier handle.');
|
||||||
|
if (idx === 0)
|
||||||
|
this.cpoints.splice(idx,2);
|
||||||
|
else if (idx === this.cpoints.length-1)
|
||||||
|
this.cpoints.splice(this.cpoints.length-2,2);
|
||||||
|
else
|
||||||
|
this.cpoints.splice(idx-1,3);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
add_node(pos) {
|
||||||
|
pos = this.gameobject.world2this(pos);
|
||||||
|
var idx = 0;
|
||||||
|
if (Spline.is_catmull(this.type)) {
|
||||||
|
if (this.cpoints.length >= 2)
|
||||||
|
idx = cmd(59, pos, this.cpoints, 400);
|
||||||
|
|
||||||
|
if (idx === this.cpoints.length)
|
||||||
|
this.cpoints.push(pos);
|
||||||
|
else
|
||||||
|
this.cpoints.splice(idx, 0, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Spline.is_bezier(this.type)) {
|
||||||
|
idx = cmd(59, pos, Spline.bezier_nodes(this.cpoints),400);
|
||||||
|
idx *= 3;
|
||||||
|
if (idx < 0) return;
|
||||||
|
var adds;
|
||||||
|
|
||||||
|
if (idx === this.cpoints.length)
|
||||||
|
adds = [this.cpoints.at(-1).add([100,0]), pos.add([-100,0]), pos.slice()];
|
||||||
|
else if (idx === 0)
|
||||||
|
adds = [pos.slice(), pos.add([100,0]), this.cpoints[0].add([-100,0])];
|
||||||
|
else
|
||||||
|
adds = [pos.add([-100,0]), pos.slice(), pos.add([100,0])];
|
||||||
|
|
||||||
|
this.cpoints.splice(idx+1, 0, ...adds);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
pick_all() {
|
pick_all() {
|
||||||
var picks = [];
|
var picks = [];
|
||||||
this.cpoints.forEach(function(x) {
|
this.cpoints.forEach(x =>picks.push(make_point_obj(this,x)));
|
||||||
picks.push(make_point_obj(this,x));
|
|
||||||
}, this);
|
|
||||||
return picks;
|
return picks;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -782,32 +814,31 @@ bucket.inputs['C-o'] = function() { this.type = -1; };
|
||||||
bucket.inputs['C-o'].doc = "Set spline to linear.";
|
bucket.inputs['C-o'].doc = "Set spline to linear.";
|
||||||
|
|
||||||
bucket.inputs['C-M-lm'] = function() {
|
bucket.inputs['C-M-lm'] = function() {
|
||||||
var idx = Math.grab_from_points(Mouse.worldpos, this.cpoints.map(p => this.gameobject.this2world(p)), 25);
|
if (Spline.is_catmull(this.type)) {
|
||||||
if (idx === -1) return;
|
var idx = Math.grab_from_points(Mouse.worldpos, this.cpoints.map(p => this.gameobject.this2world(p)), 25);
|
||||||
|
if (idx === -1) return;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
this.cpoints = this.cpoints.newfirst(idx);
|
this.cpoints = this.cpoints.newfirst(idx);
|
||||||
};
|
};
|
||||||
bucket.inputs['C-M-lm'].doc = "Select the given point as the '0' of this spline.";
|
bucket.inputs['C-M-lm'].doc = "Select the given point as the '0' of this spline.";
|
||||||
|
|
||||||
bucket.inputs['C-lm'] = function() {
|
bucket.inputs['C-lm'] = function() { this.add_node(Mouse.worldpos); }
|
||||||
var idx = 0;
|
|
||||||
|
|
||||||
if (this.cpoints.length >= 2)
|
|
||||||
idx = cmd(59, screen2world(Mouse.pos).sub(this.gameobject.pos), this.cpoints, 400);
|
|
||||||
|
|
||||||
if (idx === this.cpoints.length)
|
|
||||||
this.cpoints.push(this.gameobject.world2this(screen2world(Mouse.pos)));
|
|
||||||
else
|
|
||||||
this.cpoints.splice(idx, 0, this.gameobject.world2this(screen2world(Mouse.pos)));
|
|
||||||
};
|
|
||||||
bucket.inputs['C-lm'].doc = "Add a point to the spline at the mouse position.";
|
bucket.inputs['C-lm'].doc = "Add a point to the spline at the mouse position.";
|
||||||
|
|
||||||
bucket.inputs['C-M-lm'] = function() {
|
bucket.inputs['C-M-lm'] = function() {
|
||||||
var idx = Math.grab_from_points(Mouse.worldpos, this.cpoints.map(p => this.gameobject.this2world(p)), 25);
|
var idx = -1;
|
||||||
|
if (Spline.is_catmull(this.type))
|
||||||
|
idx = Math.grab_from_points(Mouse.worldpos, this.cpoints.map(p => this.gameobject.this2world(p)), 25);
|
||||||
|
else {
|
||||||
|
var nodes = Spline.bezier_nodes(this.cpoints);
|
||||||
|
idx = Math.grab_from_points(Mouse.worldpos, nodes.map(p => this.gameobject.this2world(p)), 25);
|
||||||
|
idx *= 3;
|
||||||
|
}
|
||||||
|
|
||||||
if (idx < 0 || idx > this.cpoints.length) return;
|
this.rm_node(idx);
|
||||||
|
|
||||||
this.cpoints.splice(idx, 1);
|
|
||||||
};
|
};
|
||||||
bucket.inputs['C-M-lm'].doc = "Remove point from the spline.";
|
bucket.inputs['C-M-lm'].doc = "Remove point from the spline.";
|
||||||
|
|
||||||
|
|
|
@ -1095,8 +1095,10 @@ editor.inputs.mouse = {};
|
||||||
editor.inputs.mouse.move = function(pos, dpos)
|
editor.inputs.mouse.move = function(pos, dpos)
|
||||||
{
|
{
|
||||||
if (editor.mousejoy) {
|
if (editor.mousejoy) {
|
||||||
if (editor.z_start)
|
if (editor.z_start) {
|
||||||
editor.camera.zoom -= dpos.y/500;
|
editor.camera.zoom -= dpos.y/500;
|
||||||
|
console.say(editor.camera.zoom);
|
||||||
|
}
|
||||||
else if (editor.joystart)
|
else if (editor.joystart)
|
||||||
editor.camera.pos = editor.camera.pos.sub(Game.camera.dir_view2world(dpos));
|
editor.camera.pos = editor.camera.pos.sub(Game.camera.dir_view2world(dpos));
|
||||||
}
|
}
|
||||||
|
|
|
@ -417,6 +417,15 @@ Spline.bezier_point_handles = function(points, i)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Spline.bezier_nodes = function(points)
|
||||||
|
{
|
||||||
|
var c = [];
|
||||||
|
for (var i = 0; i < points.length; i+=3)
|
||||||
|
c.push(points[i].slice());
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
Spline.bezier_is_node = function(points, i) { return i%3 === 0; }
|
Spline.bezier_is_node = function(points, i) { return i%3 === 0; }
|
||||||
Spline.bezier_is_handle = function(points, i) { return !Spline.bezier_is_node(points,i); }
|
Spline.bezier_is_handle = function(points, i) { return !Spline.bezier_is_node(points,i); }
|
||||||
|
|
||||||
|
|
|
@ -100,9 +100,8 @@ var gameobject = {
|
||||||
|
|
||||||
delay(fn, seconds) {
|
delay(fn, seconds) {
|
||||||
var t = timer.delay(fn.bind(this), seconds, false);
|
var t = timer.delay(fn.bind(this), seconds, false);
|
||||||
var killfn = function() { t.kill(); };
|
this.timers.push(t);
|
||||||
this.timers.push(killfn);
|
return t;
|
||||||
return killfn;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
tween(prop, values, def){
|
tween(prop, values, def){
|
||||||
|
@ -300,6 +299,7 @@ var gameobject = {
|
||||||
world2this(pos) { return cmd(70, this.body, pos); },
|
world2this(pos) { return cmd(70, this.body, pos); },
|
||||||
this2world(pos) { return cmd(71, this.body, pos); },
|
this2world(pos) { return cmd(71, this.body, pos); },
|
||||||
this2screen(pos) { return world2screen(this.this2world(pos)); },
|
this2screen(pos) { return world2screen(this.this2world(pos)); },
|
||||||
|
screen2this(pos) { return this.world2this(screen2world(pos)); },
|
||||||
dir_world2this(dir) { return cmd(160, this.body, dir); },
|
dir_world2this(dir) { return cmd(160, this.body, dir); },
|
||||||
dir_this2world(dir) { return cmd(161, this.body, dir); },
|
dir_this2world(dir) { return cmd(161, this.body, dir); },
|
||||||
|
|
||||||
|
@ -511,6 +511,8 @@ var gameobject = {
|
||||||
this.level = undefined;
|
this.level = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Player.do_uncontrol(this);
|
Player.do_uncontrol(this);
|
||||||
Register.unregister_obj(this);
|
Register.unregister_obj(this);
|
||||||
|
|
||||||
|
@ -520,7 +522,7 @@ var gameobject = {
|
||||||
Register.unregister_obj(this.components[key]);
|
Register.unregister_obj(this.components[key]);
|
||||||
(`Destroying component ${key}`);
|
(`Destroying component ${key}`);
|
||||||
this.components[key].kill();
|
this.components[key].kill();
|
||||||
this.components.gameobject = undefined;
|
this.components[key].gameobject = undefined;
|
||||||
delete this.components[key];
|
delete this.components[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,6 +565,7 @@ var gameobject = {
|
||||||
cmd(113, obj.body, obj); // set the internal obj reference to this obj
|
cmd(113, obj.body, obj); // set the internal obj reference to this obj
|
||||||
|
|
||||||
for (var [prop,p] of Object.entries(this)) {
|
for (var [prop,p] of Object.entries(this)) {
|
||||||
|
if (!p) continue;
|
||||||
if (typeof p.make === 'function') {
|
if (typeof p.make === 'function') {
|
||||||
obj[prop] = p.make(obj);
|
obj[prop] = p.make(obj);
|
||||||
obj.components[prop] = obj[prop];
|
obj.components[prop] = obj[prop];
|
||||||
|
@ -589,7 +592,6 @@ var gameobject = {
|
||||||
|
|
||||||
make_objs(objs) {
|
make_objs(objs) {
|
||||||
for (var prop in objs) {
|
for (var prop in objs) {
|
||||||
Log.warn(prop);
|
|
||||||
var newobj = this.spawn_from_instance(objs[prop]);
|
var newobj = this.spawn_from_instance(objs[prop]);
|
||||||
if (!newobj) continue;
|
if (!newobj) continue;
|
||||||
this.rename_obj(newobj.toString(), prop);
|
this.rename_obj(newobj.toString(), prop);
|
||||||
|
|
|
@ -37,13 +37,14 @@ void set_cat_mask(int cat, unsigned int mask) { category_masks[cat] = mask; }
|
||||||
|
|
||||||
cpTransform m3_to_cpt(HMM_Mat3 m)
|
cpTransform m3_to_cpt(HMM_Mat3 m)
|
||||||
{
|
{
|
||||||
|
|
||||||
cpTransform t;
|
cpTransform t;
|
||||||
t.a = m.Columns[0].x;
|
t.a = m.Columns[0].x;
|
||||||
t.c = m.Columns[0].y;
|
t.b = m.Columns[0].y;
|
||||||
t.tx = m.Columns[0].z;
|
t.tx = m.Columns[2].x;
|
||||||
t.b = m.Columns[1].x;
|
t.c = m.Columns[1].x;
|
||||||
t.d = m.Columns[1].y;
|
t.d = m.Columns[1].y;
|
||||||
t.ty = m.Columns[1].z;
|
t.ty = m.Columns[2].y;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,6 +182,7 @@ void phys2d_update(float deltaT) {
|
||||||
void init_phys2dshape(struct phys2d_shape *shape, gameobject *go, void *data) {
|
void init_phys2dshape(struct phys2d_shape *shape, gameobject *go, void *data) {
|
||||||
shape->go = go;
|
shape->go = go;
|
||||||
shape->data = data;
|
shape->data = data;
|
||||||
|
shape->t.scale = (HMM_Vec2){1.0,1.0};
|
||||||
go_shape_apply(go->body, shape->shape, go);
|
go_shape_apply(go->body, shape->shape, go);
|
||||||
cpShapeSetCollisionType(shape->shape, (int)go);
|
cpShapeSetCollisionType(shape->shape, (int)go);
|
||||||
cpShapeSetUserData(shape->shape, shape);
|
cpShapeSetUserData(shape->shape, shape);
|
||||||
|
@ -336,8 +338,8 @@ void phys2d_poly_setverts(struct phys2d_poly *poly, cpVect *verts) {
|
||||||
if (!verts) return;
|
if (!verts) return;
|
||||||
if (poly->points)
|
if (poly->points)
|
||||||
arrfree(poly->points);
|
arrfree(poly->points);
|
||||||
|
|
||||||
arrsetlen(poly->points, arrlen(verts));
|
arrsetlen(poly->points, arrlen(verts));
|
||||||
|
|
||||||
for (int i = 0; i < arrlen(verts); i++) {
|
for (int i = 0; i < arrlen(verts); i++) {
|
||||||
poly->points[i].X = verts[i].x;
|
poly->points[i].X = verts[i].x;
|
||||||
poly->points[i].Y = verts[i].y;
|
poly->points[i].Y = verts[i].y;
|
||||||
|
@ -348,9 +350,10 @@ void phys2d_poly_setverts(struct phys2d_poly *poly, cpVect *verts) {
|
||||||
|
|
||||||
void phys2d_applypoly(struct phys2d_poly *poly) {
|
void phys2d_applypoly(struct phys2d_poly *poly) {
|
||||||
if (arrlen(poly->points) <= 0) return;
|
if (arrlen(poly->points) <= 0) return;
|
||||||
|
assert(sizeof(poly->points[0]) == sizeof(cpVect));
|
||||||
struct gameobject *go = poly->shape.go;
|
struct gameobject *go = poly->shape.go;
|
||||||
cpTransform T = m3_to_cpt(transform2d2mat(poly->t));
|
// cpTransform T = m3_to_cpt(transform2d2mat(poly->t));
|
||||||
cpPolyShapeSetVerts(poly->shape.shape, arrlen(poly->points), poly->points, T);
|
cpPolyShapeSetVerts(poly->shape.shape, arrlen(poly->points), poly->points, cpTransformIdentity);
|
||||||
cpPolyShapeSetRadius(poly->shape.shape, poly->radius);
|
cpPolyShapeSetRadius(poly->shape.shape, poly->radius);
|
||||||
cpSpaceReindexShapesForBody(space, cpShapeGetBody(poly->shape.shape));
|
cpSpaceReindexShapesForBody(space, cpShapeGetBody(poly->shape.shape));
|
||||||
}
|
}
|
||||||
|
@ -400,9 +403,7 @@ float phys2d_edge_moi(struct phys2d_edge *edge, float m) {
|
||||||
return moi;
|
return moi;
|
||||||
}
|
}
|
||||||
|
|
||||||
void phys2d_edgedel(struct phys2d_edge *edge) {
|
void phys2d_edgedel(struct phys2d_edge *edge) { phys2d_shape_del(&edge->shape); }
|
||||||
phys2d_shape_del(&edge->shape);
|
|
||||||
}
|
|
||||||
|
|
||||||
void phys2d_edgeaddvert(struct phys2d_edge *edge, HMM_Vec2 v) {
|
void phys2d_edgeaddvert(struct phys2d_edge *edge, HMM_Vec2 v) {
|
||||||
arrput(edge->points, v);
|
arrput(edge->points, v);
|
||||||
|
@ -567,7 +568,7 @@ void duk_call_phys_cb(HMM_Vec2 norm, struct callee c, gameobject *hit, cpArbiter
|
||||||
|
|
||||||
JSValue obj = JS_NewObject(js);
|
JSValue obj = JS_NewObject(js);
|
||||||
JS_SetPropertyStr(js, obj, "normal", vec2js(norm));
|
JS_SetPropertyStr(js, obj, "normal", vec2js(norm));
|
||||||
JS_SetPropertyStr(js, obj, "hit", hit->ref);
|
JS_SetPropertyStr(js, obj, "obj", hit->ref);
|
||||||
JS_SetPropertyStr(js, obj, "sensor", JS_NewBool(js, cpShapeGetSensor(shape2)));
|
JS_SetPropertyStr(js, obj, "sensor", JS_NewBool(js, cpShapeGetSensor(shape2)));
|
||||||
HMM_Vec2 srfv;
|
HMM_Vec2 srfv;
|
||||||
srfv.cp = cpArbiterGetSurfaceVelocity(arb);
|
srfv.cp = cpArbiterGetSurfaceVelocity(arb);
|
||||||
|
|
|
@ -30,7 +30,7 @@ struct phys2d_shape {
|
||||||
void (*apply)(void *data);
|
void (*apply)(void *data);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Circles are the fastest collier type */
|
/* Circles are the fastest colldier type */
|
||||||
struct phys2d_circle {
|
struct phys2d_circle {
|
||||||
float radius;
|
float radius;
|
||||||
HMM_Vec2 offset;
|
HMM_Vec2 offset;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// odplot productions is a trademarked name. Project Yugh is a copyrighted property. This code, however, is free to be copy and extended as you see fit.
|
|
||||||
|
|
||||||
#include "3pfollow.h"
|
#include "3pfollow.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
|
|
@ -4,29 +4,8 @@
|
||||||
#include "transform.h"
|
#include "transform.h"
|
||||||
#include "HandmadeMath.h"
|
#include "HandmadeMath.h"
|
||||||
|
|
||||||
struct follow {
|
|
||||||
float distance;
|
|
||||||
HMM_Vec3 offset;
|
|
||||||
HMM_Quat target_rot;
|
|
||||||
};
|
|
||||||
|
|
||||||
HMM_Vec3 follow_calccenter();
|
|
||||||
HMM_Vec3 follow_postoffset();
|
|
||||||
HMM_Vec3 extentsoffset();
|
|
||||||
HMM_Vec3 framebasedveclerp();
|
|
||||||
int lerpparam(float offset, float anchorwidth, float floatwidth);
|
|
||||||
HMM_Vec3 vec3lerp(HMM_Vec3 from, HMM_Vec3 to, HMM_Vec3 a);
|
|
||||||
void follow_calctargets();
|
|
||||||
HMM_Vec3 follow_removelockedrot();
|
|
||||||
void follow_targetoffset(struct follow *follow);
|
|
||||||
int float_epsilon(float a, float b, float e);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// A good camera.
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class ThirdPersonFollow {
|
class ThirdPersonFollow {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -108,9 +108,12 @@ cgltf_attribute *get_attr_type(cgltf_primitive *p, cgltf_attribute_type t)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short pack_short_texcoord(float c)
|
unsigned short pack_short_texcoord(float x, float y)
|
||||||
{
|
{
|
||||||
return c * USHRT_MAX;
|
unsigned short s;
|
||||||
|
char xc = x*255;
|
||||||
|
char yc = y*255;
|
||||||
|
return (((unsigned short)yc) << 8) | xc;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t pack_int10_n2(float *norm)
|
uint32_t pack_int10_n2(float *norm)
|
||||||
|
@ -141,15 +144,42 @@ void mesh_add_material(mesh *mesh, cgltf_material *mat)
|
||||||
free(imp);
|
free(imp);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
// Get "no texture" tex
|
|
||||||
mesh->bind.fs.images[0] = texture_pullfromfile("k")->id;
|
mesh->bind.fs.images[0] = texture_pullfromfile("k")->id;
|
||||||
mesh->bind.fs.samplers[0] = sg_make_sampler(&(sg_sampler_desc){});
|
|
||||||
|
|
||||||
|
mesh->bind.fs.samplers[0] = sg_make_sampler(&(sg_sampler_desc){});
|
||||||
|
/*
|
||||||
cgltf_texture *tex;
|
cgltf_texture *tex;
|
||||||
if (tex = mat->normal_texture.texture)
|
if (tex = mat->normal_texture.texture)
|
||||||
mesh->bind.fs.images[1] = texture_pullfromfile(tex->image->uri)->id;
|
mesh->bind.fs.images[1] = texture_pullfromfile(tex->image->uri)->id;
|
||||||
else
|
else
|
||||||
mesh->bind.fs.images[1] = texture_pullfromfile("k")->id;
|
mesh->bind.fs.images[1] = texture_pullfromfile("k")->id;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
sg_buffer texcoord_floats(float *f, int verts, int comp)
|
||||||
|
{
|
||||||
|
unsigned short packed[verts];
|
||||||
|
for (int i = 0, v = 0; v < verts; i+=comp, v++)
|
||||||
|
packed[v] = pack_short_texcoord(f[i], f[i+1]);
|
||||||
|
|
||||||
|
return sg_make_buffer(&(sg_buffer_desc){
|
||||||
|
.data.ptr = packed,
|
||||||
|
.data.size = sizeof(unsigned short) * verts});
|
||||||
|
}
|
||||||
|
|
||||||
|
sg_buffer normal_floats(float *f, int verts, int comp)
|
||||||
|
{
|
||||||
|
uint32_t packed_norms[verts];
|
||||||
|
for (int v = 0, i = 0; v < verts; v++, i+= comp)
|
||||||
|
packed_norms[v] = pack_int10_n2(i);
|
||||||
|
|
||||||
|
return sg_make_buffer(&(sg_buffer_desc){
|
||||||
|
.data.ptr = packed_norms,
|
||||||
|
.data.size = sizeof(uint32_t) * verts});
|
||||||
|
}
|
||||||
|
|
||||||
|
HMM_Vec3 index_to_vert(uint32_t idx, float *f)
|
||||||
|
{
|
||||||
|
return (HMM_Vec3){f[idx*3], f[idx*3+1], f[idx*3+2]};
|
||||||
}
|
}
|
||||||
|
|
||||||
void mesh_add_primitive(mesh *mesh, cgltf_primitive *prim)
|
void mesh_add_primitive(mesh *mesh, cgltf_primitive *prim)
|
||||||
|
@ -165,11 +195,12 @@ void mesh_add_primitive(mesh *mesh, cgltf_primitive *prim)
|
||||||
.data.size = sizeof(uint16_t) * c,
|
.data.size = sizeof(uint16_t) * c,
|
||||||
.type = SG_BUFFERTYPE_INDEXBUFFER});
|
.type = SG_BUFFERTYPE_INDEXBUFFER});
|
||||||
|
|
||||||
mesh->face_count = c;
|
mesh->idx_count = c;
|
||||||
} else {
|
} else {
|
||||||
YughWarn("Model does not have indices. Generating them.");
|
YughWarn("Model does not have indices. Generating them.");
|
||||||
int c = prim->attributes[0].data->count;
|
int c = prim->attributes[0].data->count;
|
||||||
mesh->face_count = c;
|
|
||||||
|
mesh->idx_count = c;
|
||||||
idxs = malloc(sizeof(*idxs)*c);
|
idxs = malloc(sizeof(*idxs)*c);
|
||||||
|
|
||||||
for (int z = 0; z < c; z++)
|
for (int z = 0; z < c; z++)
|
||||||
|
@ -188,17 +219,14 @@ void mesh_add_primitive(mesh *mesh, cgltf_primitive *prim)
|
||||||
for (int k = 0; k < prim->attributes_count; k++) {
|
for (int k = 0; k < prim->attributes_count; k++) {
|
||||||
cgltf_attribute attribute = prim->attributes[k];
|
cgltf_attribute attribute = prim->attributes[k];
|
||||||
|
|
||||||
int n = cgltf_accessor_unpack_floats(attribute.data, NULL, 0); /* floats per element x num elements */
|
int n = cgltf_accessor_unpack_floats(attribute.data, NULL, 0); /* floats per vertex x num elements. In other words, total floats pulled */
|
||||||
float *vs = malloc(sizeof(float)*n);
|
int comp = cgltf_num_components(attribute.data->type);
|
||||||
|
int verts = n/comp;
|
||||||
|
float vs[n];
|
||||||
cgltf_accessor_unpack_floats(attribute.data, vs, n);
|
cgltf_accessor_unpack_floats(attribute.data, vs, n);
|
||||||
|
|
||||||
uint32_t *packed_norms;
|
|
||||||
unsigned short *packed_coords;
|
|
||||||
|
|
||||||
|
|
||||||
switch (attribute.type) {
|
switch (attribute.type) {
|
||||||
case cgltf_attribute_type_position:
|
case cgltf_attribute_type_position:
|
||||||
|
|
||||||
mesh->bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
mesh->bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||||
.data.ptr = vs,
|
.data.ptr = vs,
|
||||||
.data.size = sizeof(float) * n});
|
.data.size = sizeof(float) * n});
|
||||||
|
@ -206,15 +234,7 @@ void mesh_add_primitive(mesh *mesh, cgltf_primitive *prim)
|
||||||
|
|
||||||
case cgltf_attribute_type_normal:
|
case cgltf_attribute_type_normal:
|
||||||
has_norm = 1;
|
has_norm = 1;
|
||||||
packed_norms = malloc(mesh->face_count * sizeof(uint32_t));
|
mesh->bind.vertex_buffers[2] = normal_floats(vs, verts, comp);
|
||||||
for (int i = 0; i < mesh->face_count; i++)
|
|
||||||
packed_norms[i] = pack_int10_n2(vs + i*3);
|
|
||||||
|
|
||||||
mesh->bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){
|
|
||||||
.data.ptr = packed_norms,
|
|
||||||
.data.size = sizeof(uint32_t) * mesh->face_count});
|
|
||||||
|
|
||||||
free (packed_norms);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cgltf_attribute_type_tangent:
|
case cgltf_attribute_type_tangent:
|
||||||
|
@ -230,46 +250,33 @@ void mesh_add_primitive(mesh *mesh, cgltf_primitive *prim)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cgltf_attribute_type_texcoord:
|
case cgltf_attribute_type_texcoord:
|
||||||
packed_coords = malloc(mesh->face_count * 2 * sizeof(unsigned short));
|
mesh->bind.vertex_buffers[1] = texcoord_floats(vs, verts, comp);
|
||||||
for (int i = 0; i < mesh->face_count*2; i++)
|
|
||||||
packed_coords[i] = pack_short_texcoord(vs[i]);
|
|
||||||
|
|
||||||
mesh->bind.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){
|
|
||||||
.data.ptr = packed_coords,
|
|
||||||
.data.size = sizeof(unsigned short) * 2 * mesh->face_count});
|
|
||||||
|
|
||||||
free(packed_coords);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
free(vs);
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
if (!has_norm) {
|
if (!has_norm) {
|
||||||
uint32_t norms[mesh->face_count];
|
|
||||||
|
|
||||||
cgltf_attribute *pa = get_attr_type(prim, cgltf_attribute_type_position);
|
cgltf_attribute *pa = get_attr_type(prim, cgltf_attribute_type_position);
|
||||||
int n = cgltf_accessor_unpack_floats(pa->data, NULL,0);
|
int n = cgltf_accessor_unpack_floats(pa->data, NULL,0);
|
||||||
|
int comp = 3;
|
||||||
|
int verts = n/comp;
|
||||||
|
uint32_t face_norms[verts];
|
||||||
float ps[n];
|
float ps[n];
|
||||||
cgltf_accessor_unpack_floats(pa->data,ps,n);
|
cgltf_accessor_unpack_floats(pa->data,ps,n);
|
||||||
|
|
||||||
for (int i = 0, face=0; i < mesh->face_count/3; i++, face+=9) {
|
for (int i = 0; i < verts; i+=3) {
|
||||||
int o = face;
|
HMM_Vec3 a = index_to_vert(i,ps);
|
||||||
HMM_Vec3 a = {ps[o], ps[o+1],ps[o+2]};
|
HMM_Vec3 b = index_to_vert(i+1,ps);
|
||||||
o += 3;
|
HMM_Vec3 c = index_to_vert(i+2,ps);
|
||||||
HMM_Vec3 b = {ps[o], ps[o+1],ps[o+2]};
|
|
||||||
o += 3;
|
|
||||||
HMM_Vec3 c = {ps[o], ps[o+1],ps[o+2]};
|
|
||||||
HMM_Vec3 norm = HMM_NormV3(HMM_Cross(HMM_SubV3(b,a), HMM_SubV3(c,a)));
|
HMM_Vec3 norm = HMM_NormV3(HMM_Cross(HMM_SubV3(b,a), HMM_SubV3(c,a)));
|
||||||
|
|
||||||
uint32_t packed_norm = pack_int10_n2(norm.Elements);
|
uint32_t packed_norm = pack_int10_n2(norm.Elements);
|
||||||
for (int j = 0; j < 3; j++)
|
face_norms[i] = face_norms[i+1] = face_norms[i+2] = packed_norm;
|
||||||
norms[i*3+j] = packed_norm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh->bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){
|
mesh->bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){
|
||||||
.data.ptr = norms,
|
.data.ptr = face_norms,
|
||||||
.data.size = sizeof(uint32_t) * mesh->face_count
|
.data.size = sizeof(uint32_t) * verts});
|
||||||
});
|
}*/
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void model_add_cgltf_mesh(model *model, cgltf_mesh *gltf_mesh)
|
void model_add_cgltf_mesh(model *model, cgltf_mesh *gltf_mesh)
|
||||||
|
@ -373,7 +380,7 @@ void draw_model(struct model *model, HMM_Mat4 amodel) {
|
||||||
|
|
||||||
for (int i = 0; i < arrlen(model->meshes); i++) {
|
for (int i = 0; i < arrlen(model->meshes); i++) {
|
||||||
sg_apply_bindings(&model->meshes[i].bind);
|
sg_apply_bindings(&model->meshes[i].bind);
|
||||||
sg_draw(0, model->meshes[i].face_count, 1);
|
sg_draw(0, model->meshes[i].idx_count, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct model;
|
||||||
/* A single mesh */
|
/* A single mesh */
|
||||||
typedef struct mesh {
|
typedef struct mesh {
|
||||||
sg_bindings bind; /* Encapsulates material, norms, etc */
|
sg_bindings bind; /* Encapsulates material, norms, etc */
|
||||||
uint32_t face_count;
|
uint32_t idx_count;
|
||||||
struct model *model;
|
struct model *model;
|
||||||
} mesh;
|
} mesh;
|
||||||
|
|
||||||
|
|
|
@ -442,10 +442,8 @@ HMM_Vec2 *inflatepoints(HMM_Vec2 *p, float d, int n)
|
||||||
|
|
||||||
void draw_edge(HMM_Vec2 *points, int n, struct rgba color, int thickness, int closed, int flags, struct rgba line_color, float line_seg)
|
void draw_edge(HMM_Vec2 *points, int n, struct rgba color, int thickness, int closed, int flags, struct rgba line_color, float line_seg)
|
||||||
{
|
{
|
||||||
// static_assert(sizeof(HMM_Vec2) == 2*sizeof(float));
|
if (thickness == 0)
|
||||||
if (thickness == 0) {
|
|
||||||
draw_line(points,n,color,0,closed,0);
|
draw_line(points,n,color,0,closed,0);
|
||||||
}
|
|
||||||
|
|
||||||
/* todo: should be dashed, and filled. use a texture. */
|
/* todo: should be dashed, and filled. use a texture. */
|
||||||
/* draw polygon outline */
|
/* draw polygon outline */
|
||||||
|
@ -503,12 +501,12 @@ void draw_edge(HMM_Vec2 *points, int n, struct rgba color, int thickness, int cl
|
||||||
HMM_Vec2 in_p[n];
|
HMM_Vec2 in_p[n];
|
||||||
HMM_Vec2 out_p[n];
|
HMM_Vec2 out_p[n];
|
||||||
|
|
||||||
for (int i = 0, v = 0; i < n*2+1; i+=2, v++) {
|
for (int i = 1, v = 0; i < n*2+1; i+=2, v++) {
|
||||||
in_p[v].x = vertices[i].pos.x;
|
in_p[v].x = vertices[i].pos.x;
|
||||||
in_p[v].y = vertices[i].pos.y;
|
in_p[v].y = vertices[i].pos.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1, v = 0; i < n*2; i+=2,v++) {
|
for (int i = 0, v = 0; i < n*2; i+=2,v++) {
|
||||||
out_p[v].x = vertices[i].pos.x;
|
out_p[v].x = vertices[i].pos.x;
|
||||||
out_p[v].y = vertices[i].pos.y;
|
out_p[v].y = vertices[i].pos.y;
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,10 +175,6 @@ gameobject *MakeGameobject() {
|
||||||
|
|
||||||
void rm_body_shapes(cpBody *body, cpShape *shape, void *data) {
|
void rm_body_shapes(cpBody *body, cpShape *shape, void *data) {
|
||||||
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
struct phys2d_shape *s = cpShapeGetUserData(shape);
|
||||||
if (s->data) {
|
|
||||||
free(s->data);
|
|
||||||
s->data = NULL;
|
|
||||||
}
|
|
||||||
cpSpaceRemoveShape(space, shape);
|
cpSpaceRemoveShape(space, shape);
|
||||||
cpShapeFree(shape);
|
cpShapeFree(shape);
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ JSValue gos2ref(gameobject **go)
|
||||||
{
|
{
|
||||||
JSValue array = JS_NewArray(js);
|
JSValue array = JS_NewArray(js);
|
||||||
for (int i = 0; i < arrlen(go); i++)
|
for (int i = 0; i < arrlen(go); i++)
|
||||||
js_setprop_num(array,i,go[i]->ref);
|
js_setprop_num(array,i,JS_DupValue(js,go[i]->ref));
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1905,4 +1905,3 @@ void ffi_load() {
|
||||||
QJSCLASSPREP(dsp_node);
|
QJSCLASSPREP(dsp_node);
|
||||||
QJSCLASSPREP(gameobject);
|
QJSCLASSPREP(gameobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@ struct TextureOptions {
|
||||||
int sprite;
|
int sprite;
|
||||||
int mips;
|
int mips;
|
||||||
unsigned int gamma:1;
|
unsigned int gamma:1;
|
||||||
int animation;
|
|
||||||
int wrapx;
|
int wrapx;
|
||||||
int wrapy;
|
int wrapy;
|
||||||
};
|
};
|
||||||
|
@ -65,14 +64,9 @@ void texture_sync(const char *path);
|
||||||
|
|
||||||
char * tex_get_path(struct Texture *tex); // Get image path for texture
|
char * tex_get_path(struct Texture *tex); // Get image path for texture
|
||||||
|
|
||||||
void texanim_fromframes(struct TexAnim *anim, int frames);
|
|
||||||
|
|
||||||
int gif_nframes(const char *path);
|
int gif_nframes(const char *path);
|
||||||
|
|
||||||
struct glrect tex_get_rect(struct Texture *tex);
|
struct glrect tex_get_rect(struct Texture *tex);
|
||||||
HMM_Vec2 tex_get_dimensions(struct Texture *tex);
|
HMM_Vec2 tex_get_dimensions(struct Texture *tex);
|
||||||
struct glrect anim_get_rect(struct anim2d *anim);
|
|
||||||
|
|
||||||
int anim_frames(struct TexAnim *a);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -286,8 +286,8 @@ cpPolyShapeGetRadius(const cpShape *shape)
|
||||||
void
|
void
|
||||||
cpPolyShapeSetVerts(cpShape *shape, int count, cpVect *verts, cpTransform transform)
|
cpPolyShapeSetVerts(cpShape *shape, int count, cpVect *verts, cpTransform transform)
|
||||||
{
|
{
|
||||||
cpVect *hullVerts = (cpVect *)alloca(count*sizeof(cpVect));
|
cpVect hullVerts[count+1];
|
||||||
|
|
||||||
// Transform the verts before building the hull in case of a negative scale.
|
// Transform the verts before building the hull in case of a negative scale.
|
||||||
for(int i=0; i<count; i++) hullVerts[i] = cpTransformPoint(transform, verts[i]);
|
for(int i=0; i<count; i++) hullVerts[i] = cpTransformPoint(transform, verts[i]);
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,9 @@ HMM_Vec3 mat3_t_dir(HMM_Mat4 m, HMM_Vec3 dir)
|
||||||
return mat3_t_pos(m, dir);
|
return mat3_t_pos(m, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
HMM_Mat3 transform2d2mat(transform2d trn) { return HMM_MulM3(HMM_Translate2D(trn.pos), HMM_MulM3(HMM_RotateM3(trn.angle), HMM_ScaleM3(trn.scale))); }
|
HMM_Mat3 transform2d2mat(transform2d trn) {
|
||||||
|
return HMM_MulM3(HMM_Translate2D(trn.pos), HMM_MulM3(HMM_RotateM3(trn.angle), HMM_ScaleM3(trn.scale)));
|
||||||
|
}
|
||||||
|
|
||||||
transform2d mat2transform2d(HMM_Mat3 m)
|
transform2d mat2transform2d(HMM_Mat3 m)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue