spline editing works; hollow, etc; add M-g for move all points
This commit is contained in:
parent
0fcc2286fa
commit
6eefa95546
|
@ -2,10 +2,11 @@
|
||||||
|
|
||||||
Script hooks exist to allow to modification of the game.
|
Script hooks exist to allow to modification of the game.
|
||||||
|
|
||||||
|config.js|called before any game play|
|
|config.js|called before any game play, including play from editor|
|
||||||
|game.js|called to start the game|
|
|game.js|called to start the game|
|
||||||
|editorconfig.js|called when the editor is loaded, used to personalize|
|
|editorconfig.js|called when the editor is loaded, used to personalize|
|
||||||
|debug.js|called when play in editor is selected|
|
|debug.js|called when play in editor is selected|
|
||||||
|
|dbgret.js|called when play in editor returns to editor|
|
||||||
|
|
||||||
All objects in the Yugine can have an associated script. This script can perform setup, teardown, and handles responses for the object.
|
All objects in the Yugine can have an associated script. This script can perform setup, teardown, and handles responses for the object.
|
||||||
|
|
||||||
|
|
|
@ -460,7 +460,6 @@ polygon2d.inputs['C-b'].doc = "Freeze mirroring in place.";
|
||||||
//Object.freeze(polygon2d);
|
//Object.freeze(polygon2d);
|
||||||
|
|
||||||
component.edge2d = Object.copy(collider2d, {
|
component.edge2d = Object.copy(collider2d, {
|
||||||
degrees:2,
|
|
||||||
dimensions:2,
|
dimensions:2,
|
||||||
thickness:0,
|
thickness:0,
|
||||||
/* open: 0
|
/* open: 0
|
||||||
|
@ -468,13 +467,8 @@ component.edge2d = Object.copy(collider2d, {
|
||||||
beziers: 2
|
beziers: 2
|
||||||
looped: 3
|
looped: 3
|
||||||
*/
|
*/
|
||||||
type: 3,
|
type: Spline.type.clamped,
|
||||||
typeid: {
|
looped: false,
|
||||||
open: 0,
|
|
||||||
clamped: 1,
|
|
||||||
beziers: 2,
|
|
||||||
looped: 3
|
|
||||||
},
|
|
||||||
|
|
||||||
flipx: false,
|
flipx: false,
|
||||||
flipy: false,
|
flipy: false,
|
||||||
|
@ -483,7 +477,7 @@ component.edge2d = Object.copy(collider2d, {
|
||||||
|
|
||||||
hollow: false,
|
hollow: false,
|
||||||
hollowt: 0,
|
hollowt: 0,
|
||||||
|
|
||||||
spoints() {
|
spoints() {
|
||||||
if (!this.cpoints) return [];
|
if (!this.cpoints) return [];
|
||||||
var spoints = this.cpoints.slice();
|
var spoints = this.cpoints.slice();
|
||||||
|
@ -504,15 +498,12 @@ component.edge2d = Object.copy(collider2d, {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return spoints;
|
|
||||||
|
|
||||||
if (this.hollow) {
|
if (this.hollow) {
|
||||||
var hpoints = [];
|
var hpoints = inflate_cpv(spoints, spoints.length, this.hollowt);
|
||||||
var inflatep = inflate_cpv(spoints, spoints.length, this.hollowt);
|
if (hpoints.length === spoints.length) return spoints;
|
||||||
inflatep[0].slice().reverse().forEach(function(x) { hpoints.push(x); });
|
var arr1 = hpoints.filter(function(x,i) { return i % 2 === 0; });
|
||||||
|
var arr2 = hpoints.filter(function(x,i) { return i % 2 !== 0; });
|
||||||
inflatep[1].forEach(function(x) { hpoints.push(x); });
|
return arr1.concat(arr2.reverse());
|
||||||
return hpoints;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return spoints;
|
return spoints;
|
||||||
|
@ -521,29 +512,29 @@ component.edge2d = Object.copy(collider2d, {
|
||||||
sample(n) {
|
sample(n) {
|
||||||
var spoints = this.spoints();
|
var spoints = this.spoints();
|
||||||
|
|
||||||
this.degrees = Math.clamp(this.degrees, 1, spoints.length-1);
|
var degrees = 2;
|
||||||
|
|
||||||
|
if (n < spoints.length) n = spoints.length;
|
||||||
|
|
||||||
if (spoints.length === 2)
|
if (spoints.length === 2)
|
||||||
return spoints;
|
return spoints;
|
||||||
if (spoints.length < 2)
|
if (spoints.length < 2)
|
||||||
return [];
|
return [];
|
||||||
if (this.degrees < 2) {
|
if (this.samples === spoints.length) {
|
||||||
if (this.type === 3)
|
if (this.looped) return spoints.wrapped(1);
|
||||||
return spoints.wrapped(1);
|
|
||||||
|
|
||||||
return spoints;
|
return spoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
order = degrees+1
|
order = degrees+1
|
||||||
knots = spoints.length + order
|
knots = spoints.length + order
|
||||||
assert knots%order != 0
|
assert knots%order != 0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (this.type === component.edge2d.typeid.this.looped)
|
if (this.looped)
|
||||||
return spline_cmd(0, this.degrees, this.dimensions, 0, spoints.wrapped(this.degrees), n);
|
return Spline.sample(degrees, this.dimensions, Spline.type.open, spoints.wrapped(this.degrees), n);
|
||||||
|
|
||||||
return spline_cmd(0, this.degrees, this.dimensions, this.type, spoints, n);
|
return Spline.sample(degrees, this.dimensions, this.type, spoints, n);
|
||||||
},
|
},
|
||||||
|
|
||||||
samples: 10,
|
samples: 10,
|
||||||
|
@ -580,6 +571,18 @@ component.edge2d = Object.copy(collider2d, {
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
pick_all() {
|
||||||
|
var picks = [];
|
||||||
|
this.cpoints.forEach(function(x) {
|
||||||
|
picks.push({
|
||||||
|
set pos(n) { x.x = n.x; x.y = n.y; },
|
||||||
|
get pos() { return x; },
|
||||||
|
sync: this.sync.bind(this),
|
||||||
|
});
|
||||||
|
}, this);
|
||||||
|
return picks;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
component.edge2d.impl = {
|
component.edge2d.impl = {
|
||||||
|
@ -591,6 +594,7 @@ component.edge2d.impl = {
|
||||||
},
|
},
|
||||||
get thickness() { return cmd(112,this.id); },
|
get thickness() { return cmd(112,this.id); },
|
||||||
sync() {
|
sync() {
|
||||||
|
if (this.samples < this.spoints().length) this.samples = this.spoints().length;
|
||||||
var sensor = this.sensor;
|
var sensor = this.sensor;
|
||||||
var points = this.sample(this.samples);
|
var points = this.sample(this.samples);
|
||||||
cmd_edge2d(0,this.id,points);
|
cmd_edge2d(0,this.id,points);
|
||||||
|
@ -599,64 +603,58 @@ component.edge2d.impl = {
|
||||||
};
|
};
|
||||||
|
|
||||||
var bucket = component.edge2d;
|
var bucket = component.edge2d;
|
||||||
|
bucket.spoints.doc = "Returns the controls points after modifiers are applied, such as it being hollow or mirrored on its axises.";
|
||||||
bucket.inputs = {};
|
bucket.inputs = {};
|
||||||
|
bucket.inputs.post = function() { this.sync(); };
|
||||||
bucket.inputs.h = function() { this.hollow = !this.hollow; };
|
bucket.inputs.h = function() { this.hollow = !this.hollow; };
|
||||||
bucket.inputs.h.doc = "Toggle hollow.";
|
bucket.inputs.h.doc = "Toggle hollow.";
|
||||||
|
|
||||||
bucket.inputs['C-g'] = function() {
|
bucket.inputs['C-g'] = function() { if (this.hollowt > 0) this.hollowt--; };
|
||||||
this.hollowt--;
|
|
||||||
if (this.hollowt < 0) this.hollowt = 0;
|
|
||||||
};
|
|
||||||
bucket.inputs['C-g'].doc = "Thin the hollow thickness.";
|
bucket.inputs['C-g'].doc = "Thin the hollow thickness.";
|
||||||
|
bucket.inputs['C-g'].rep = true;
|
||||||
|
|
||||||
bucket.inputs['C-f'] = function() { this.hollowt++; };
|
bucket.inputs['C-f'] = function() { this.hollowt++; };
|
||||||
bucket.inputs['C-f'].doc = "Increase the hollow thickness.";
|
bucket.inputs['C-f'].doc = "Increase the hollow thickness.";
|
||||||
|
bucket.inputs['C-f'].rep = true;
|
||||||
|
|
||||||
bucket.inputs['M-v'] = function() { this.thickness--; };
|
bucket.inputs['M-v'] = function() { if (this.thickness > 0) this.thickness--; };
|
||||||
bucket.inputs['M-v'].doc = "Decrease spline thickness.";
|
bucket.inputs['M-v'].doc = "Decrease spline thickness.";
|
||||||
bucket.inputs['M-v'].rep = true;
|
bucket.inputs['M-v'].rep = true;
|
||||||
|
|
||||||
bucket.inputs['C-b'] = function() {
|
bucket.inputs['C-y'] = function() {
|
||||||
this.cpoints = this.spoints();
|
this.cpoints = this.spoints();
|
||||||
this.flipx = false;
|
this.flipx = false;
|
||||||
this.flipy = false;
|
this.flipy = false;
|
||||||
|
this.hollow = false;
|
||||||
};
|
};
|
||||||
bucket.inputs['C-b'].doc = "Freeze mirroring,";
|
bucket.inputs['C-y'].doc = "Freeze mirroring,";
|
||||||
bucket.inputs['M-b'] = function() { this.thickness++; };
|
bucket.inputs['M-b'] = function() { this.thickness++; };
|
||||||
bucket.inputs['M-b'].doc = "Increase spline thickness.";
|
bucket.inputs['M-b'].doc = "Increase spline thickness.";
|
||||||
bucket.inputs['M-b'].rep = true;
|
bucket.inputs['M-b'].rep = true;
|
||||||
|
|
||||||
bucket.inputs['C-plus'] = function() { this.degrees++; };
|
|
||||||
bucket.inputs['C-plus'].doc = "Increase the degrees of this spline.";
|
|
||||||
bucket.inputs['C-plus'].rep = true;
|
|
||||||
|
|
||||||
bucket.inputs.plus = function() { this.samples++; };
|
bucket.inputs.plus = function() { this.samples++; };
|
||||||
bucket.inputs.plus.doc = "Increase the number of samples of this spline.";
|
bucket.inputs.plus.doc = "Increase the number of samples of this spline.";
|
||||||
bucket.inputs.plus.rep = true;
|
bucket.inputs.plus.rep = true;
|
||||||
|
|
||||||
bucket.inputs.minus = function() {
|
bucket.inputs.minus = function() { if (this.samples > this.spoints().length) this.samples--;};
|
||||||
this.samples--;
|
|
||||||
if (this.samples < 1) this.samples = 1;
|
|
||||||
};
|
|
||||||
bucket.inputs.minus.doc = "Decrease the number of samples on this spline.";
|
bucket.inputs.minus.doc = "Decrease the number of samples on this spline.";
|
||||||
bucket.inputs.minus.rep = true;
|
bucket.inputs.minus.rep = true;
|
||||||
|
|
||||||
bucket.inputs['C-minus'] = function() { this.degrees--; };
|
|
||||||
bucket.inputs['C-minus'].doc = "Decrease the number of degrees of this spline.";
|
|
||||||
bucket.inputs['C-minus'].rep = true;
|
|
||||||
|
|
||||||
bucket.inputs['C-r'] = function() { this.cpoints = this.cpoints.reverse(); };
|
bucket.inputs['C-r'] = function() { this.cpoints = this.cpoints.reverse(); };
|
||||||
bucket.inputs['C-r'].doc = "Reverse the order of the spline's points.";
|
bucket.inputs['C-r'].doc = "Reverse the order of the spline's points.";
|
||||||
|
|
||||||
bucket.inputs['C-l'] = function() { this.type = 3; };
|
bucket.inputs['C-l'] = function() { this.looped = !this.looped};
|
||||||
bucket.inputs['C-l'].doc = "Set type of spline to clamped.";
|
bucket.inputs['C-l'].doc = "Toggle spline being looped.";
|
||||||
|
|
||||||
bucket.inputs['C-c'] = function() { this.type = 1; };
|
bucket.inputs['C-c'] = function() { this.type = Spline.type.clamped; };
|
||||||
bucket.inputs['C-c'].doc = "Set type of spline to closed.";
|
bucket.inputs['C-c'].doc = "Set type of spline to clamped.";
|
||||||
|
|
||||||
bucket.inputs['C-o'] = function() { this.type = 0; };
|
bucket.inputs['C-o'] = function() { this.type = Spline.type.open; };
|
||||||
bucket.inputs['C-o'].doc = "Set spline to open.";
|
bucket.inputs['C-o'].doc = "Set spline to open.";
|
||||||
|
|
||||||
|
bucket.inputs['C-b'] = function() { this.type = Spline.type.bezier; };
|
||||||
|
bucket.inputs['C-b'].doc = "Set spline to bezier.";
|
||||||
|
|
||||||
bucket.inputs['C-M-lm'] = function() {
|
bucket.inputs['C-M-lm'] = function() {
|
||||||
var idx = grab_from_points(Mouse.worldpos, this.cpoints.map(this.gameobject.world2this,this.gameobject), 25);
|
var idx = grab_from_points(Mouse.worldpos, this.cpoints.map(this.gameobject.world2this,this.gameobject), 25);
|
||||||
if (idx === -1) return;
|
if (idx === -1) return;
|
||||||
|
|
|
@ -568,6 +568,7 @@ var editor = {
|
||||||
|
|
||||||
GUI.text(JSON.stringify(o._ed.urdiff,null,1), [500,500]);
|
GUI.text(JSON.stringify(o._ed.urdiff,null,1), [500,500]);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
ed_debug() {
|
ed_debug() {
|
||||||
|
@ -662,6 +663,9 @@ var editor = {
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.inputs = {};
|
editor.inputs = {};
|
||||||
|
editor.inputs.post = function() {
|
||||||
|
if (editor.sel_comp && 'sync' in editor.sel_comp) editor.sel_comp.sync();
|
||||||
|
};
|
||||||
editor.inputs.release_post = function() {
|
editor.inputs.release_post = function() {
|
||||||
editor.snapshot();
|
editor.snapshot();
|
||||||
editor.edit_level.check_dirty();
|
editor.edit_level.check_dirty();
|
||||||
|
@ -710,7 +714,7 @@ editor.inputs['C-d'].doc = "Duplicate all selected objects.";
|
||||||
|
|
||||||
editor.inputs['C-m'] = function() {
|
editor.inputs['C-m'] = function() {
|
||||||
if (editor.sel_comp) {
|
if (editor.sel_comp) {
|
||||||
if (editor.sel_comp.flipy)
|
if ('flipy' in editor.sel_comp)
|
||||||
editor.sel_comp.flipy = !editor.sel_comp.flipy;
|
editor.sel_comp.flipy = !editor.sel_comp.flipy;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -722,7 +726,7 @@ editor.inputs['C-m'].doc = "Mirror selected objects on the Y axis.";
|
||||||
|
|
||||||
editor.inputs.m = function() {
|
editor.inputs.m = function() {
|
||||||
if (editor.sel_comp) {
|
if (editor.sel_comp) {
|
||||||
if (editor.sel_comp.flipx)
|
if ('flipx' in editor.sel_comp)
|
||||||
editor.sel_comp.flipx = !editor.sel_comp.flipx;
|
editor.sel_comp.flipx = !editor.sel_comp.flipx;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1187,17 +1191,22 @@ editor.inputs['M-u'].doc = "Make selected objects unique.";
|
||||||
editor.inputs['C-S-g'] = function() { editor.openpanel(groupsaveaspanel); };
|
editor.inputs['C-S-g'] = function() { editor.openpanel(groupsaveaspanel); };
|
||||||
editor.inputs['C-S-g'].doc = "Save selected objects as a new level.";
|
editor.inputs['C-S-g'].doc = "Save selected objects as a new level.";
|
||||||
|
|
||||||
editor.inputs.g = editor.inputs.mm;/*
|
|
||||||
editor.inputs.g = function() {
|
editor.inputs.g = function() {
|
||||||
if (editor.selectlist.length === 0) {
|
if (editor.selectlist.length === 0) {
|
||||||
var o = editor.try_pick();
|
var o = editor.try_pick();
|
||||||
if (!o) return;
|
if (!o) return;
|
||||||
editor.selectlist = [o];
|
editor.selectlist = [o];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (editor.sel_comp && 'pick' in editor.sel_comp) {
|
||||||
|
var o = editor.sel_comp.pick(Mouse.worldpos);
|
||||||
|
if (o) editor.grabselect = [o];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
editor.grabselect = editor.selectlist.slice();
|
editor.grabselect = editor.selectlist.slice();
|
||||||
};
|
};
|
||||||
*/
|
|
||||||
editor.inputs.g.doc = "Move selected objects.";
|
editor.inputs.g.doc = "Move selected objects.";
|
||||||
editor.inputs.g.released = function() { editor.grabselect = []; Mouse.normal(); };
|
editor.inputs.g.released = function() { editor.grabselect = []; Mouse.normal(); };
|
||||||
|
|
||||||
|
@ -1238,6 +1247,13 @@ editor.inputs['C-g'] = function() {
|
||||||
};
|
};
|
||||||
editor.inputs['C-g'].doc = "Duplicate selected objects, then move them.";
|
editor.inputs['C-g'].doc = "Duplicate selected objects, then move them.";
|
||||||
|
|
||||||
|
editor.inputs['M-g'] = function()
|
||||||
|
{
|
||||||
|
if (this.sel_comp && 'pick_all' in this.sel_comp)
|
||||||
|
this.grabselect = this.sel_comp.pick_all();
|
||||||
|
}
|
||||||
|
editor.inputs['M-g'].doc = "Move all.";
|
||||||
|
|
||||||
editor.inputs['C-lb'] = function() {
|
editor.inputs['C-lb'] = function() {
|
||||||
editor_config.grid_size -= Keys.shift() ? 10 : 1;
|
editor_config.grid_size -= Keys.shift() ? 10 : 1;
|
||||||
if (editor_config.grid_size <= 0) editor_config.grid_size = 1;
|
if (editor_config.grid_size <= 0) editor_config.grid_size = 1;
|
||||||
|
@ -1989,6 +2005,7 @@ limited_editor.inputs['C-q'] = function()
|
||||||
{
|
{
|
||||||
Sound.killall();
|
Sound.killall();
|
||||||
Primum.clear();
|
Primum.clear();
|
||||||
|
load("dbgret.js");
|
||||||
|
|
||||||
editor.enter_editor();
|
editor.enter_editor();
|
||||||
}
|
}
|
||||||
|
|
|
@ -595,6 +595,18 @@ function Color(from) {
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var Spline = {};
|
||||||
|
Spline.sample = function(degrees, dimensions, type, ctrl_points, nsamples)
|
||||||
|
{
|
||||||
|
var s = spline_cmd(0, degrees,dimensions,type,ctrl_points,nsamples);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
Spline.type = {
|
||||||
|
open: 0,
|
||||||
|
clamped: 1,
|
||||||
|
beziers: 2
|
||||||
|
};
|
||||||
|
|
||||||
load("scripts/components.js");
|
load("scripts/components.js");
|
||||||
|
|
||||||
function find_com(objects)
|
function find_com(objects)
|
||||||
|
@ -853,3 +865,4 @@ Game.view_camera = function(cam)
|
||||||
Window.name = "Primum Machinam (V0.1)";
|
Window.name = "Primum Machinam (V0.1)";
|
||||||
Window.width = 1280;
|
Window.width = 1280;
|
||||||
Window.height = 720;
|
Window.height = 720;
|
||||||
|
|
||||||
|
|
|
@ -414,7 +414,7 @@ var gameobject = {
|
||||||
this.level = undefined;
|
this.level = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
Player.uncontrol(this);
|
Player.do_uncontrol(this);
|
||||||
Register.unregister_obj(this);
|
Register.unregister_obj(this);
|
||||||
// ur[this.ur].instances.remove(this);
|
// ur[this.ur].instances.remove(this);
|
||||||
this.body = -1;
|
this.body = -1;
|
||||||
|
|
|
@ -165,7 +165,7 @@ var Player = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
uncontrol(pawn) {
|
do_uncontrol(pawn) {
|
||||||
this.players.forEach(function(p) {
|
this.players.forEach(function(p) {
|
||||||
p.pawns = p.pawns.filter(x => x !== pawn);
|
p.pawns = p.pawns.filter(x => x !== pawn);
|
||||||
});
|
});
|
||||||
|
|
|
@ -370,51 +370,45 @@ float vecs2m(cpVect a, cpVect b)
|
||||||
return (b.y-a.y)/(b.x-a.x);
|
return (b.y-a.y)/(b.x-a.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
cpVect inflatepoint(cpVect a, cpVect b, cpVect c, float d)
|
cpVect *inflatepoints(cpVect *p, float d, int n)
|
||||||
{
|
|
||||||
cpVect ba = cpvnormalize(cpvsub(a,b));
|
|
||||||
cpVect bc = cpvnormalize(cpvsub(c,b));
|
|
||||||
cpVect avg = cpvadd(ba, bc);
|
|
||||||
avg = cpvmult(avg, 0.5);
|
|
||||||
float dot = cpvdot(ba, bc);
|
|
||||||
dot /= cpvlength(ba);
|
|
||||||
dot /= cpvlength(bc);
|
|
||||||
float mid = acos(dot)/2;
|
|
||||||
avg = cpvnormalize(avg);
|
|
||||||
return cpvadd(b, cpvmult(avg, d/sin(mid)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void inflatepoints(cpVect *r, cpVect *p, float d, int n)
|
|
||||||
{
|
{
|
||||||
if (d == 0) {
|
if (d == 0) {
|
||||||
|
cpVect *ret = NULL;
|
||||||
|
arraddn(ret,n);
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
r[i] = p[i];
|
ret[i] = p[i];
|
||||||
|
|
||||||
return;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpveql(p[0], p[n-1])) {
|
parsl_position par_v[n];
|
||||||
r[0] = inflatepoint(p[n-2],p[0],p[1],d);
|
uint16_t spine_lens[] = {n};
|
||||||
r[n-1] = r[0];
|
for (int i = 0; i < n; i++) {
|
||||||
} else {
|
par_v[i].x = p[i].x;
|
||||||
cpVect outdir = cpvmult(cpvnormalize(cpvsub(p[0],p[1])),fabs(d));
|
par_v[i].y = p[i].y;
|
||||||
cpVect perp;
|
};
|
||||||
if (d > 0)
|
|
||||||
perp = cpvperp(outdir);
|
|
||||||
else
|
|
||||||
perp = cpvrperp(outdir);
|
|
||||||
r[0] = cpvadd(p[0],cpvadd(outdir,perp));
|
|
||||||
|
|
||||||
outdir = cpvmult(cpvnormalize(cpvsub(p[n-1],p[n-2])),fabs(d));
|
|
||||||
if (d > 0)
|
|
||||||
perp = cpvrperp(outdir);
|
|
||||||
else
|
|
||||||
perp = cpvperp(outdir);
|
|
||||||
r[n-1] = cpvadd(p[n-1],cpvadd(outdir,perp));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < n-2; i++)
|
parsl_context *par_ctx = parsl_create_context((parsl_config){
|
||||||
r[i+1] = inflatepoint(p[i],p[i+1],p[i+2], d);
|
.thickness = d,
|
||||||
|
.flags= PARSL_FLAG_ANNOTATIONS,
|
||||||
|
.u_mode = PAR_U_MODE_DISTANCE
|
||||||
|
});
|
||||||
|
|
||||||
|
parsl_mesh *mesh = parsl_mesh_from_lines(par_ctx, (parsl_spine_list){
|
||||||
|
.num_vertices = n,
|
||||||
|
.num_spines = 1,
|
||||||
|
.vertices = par_v,
|
||||||
|
.spine_lengths = spine_lens,
|
||||||
|
.closed = 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
cpVect *ret = NULL;
|
||||||
|
arraddn(ret,mesh->num_vertices);
|
||||||
|
for (int i = 0; i < mesh->num_vertices; i++) {
|
||||||
|
ret[i].x = mesh->positions[i].x;
|
||||||
|
ret[i].y = mesh->positions[i].y;
|
||||||
|
};
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_edge(cpVect *points, int n, struct rgba color, int thickness, int closed, int flags, struct rgba line_color, float line_seg)
|
void draw_edge(cpVect *points, int n, struct rgba color, int thickness, int closed, int flags, struct rgba line_color, float line_seg)
|
||||||
|
@ -443,7 +437,6 @@ void draw_edge(cpVect *points, int n, struct rgba color, int thickness, int clos
|
||||||
parsl_context *par_ctx = parsl_create_context((parsl_config){
|
parsl_context *par_ctx = parsl_create_context((parsl_config){
|
||||||
.thickness = thickness,
|
.thickness = thickness,
|
||||||
.flags = PARSL_FLAG_ANNOTATIONS,
|
.flags = PARSL_FLAG_ANNOTATIONS,
|
||||||
.u_mode = PAR_U_MODE_DISTANCE,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
parsl_mesh *mesh = parsl_mesh_from_lines(par_ctx, (parsl_spine_list){
|
parsl_mesh *mesh = parsl_mesh_from_lines(par_ctx, (parsl_spine_list){
|
||||||
|
|
|
@ -24,7 +24,6 @@ void debug_flush(HMM_Mat4 *view);
|
||||||
void debug_newframe();
|
void debug_newframe();
|
||||||
void debug_nextpass();
|
void debug_nextpass();
|
||||||
|
|
||||||
cpVect inflatepoint(cpVect a, cpVect b, cpVect c, float d);
|
cpVect *inflatepoints(cpVect *p, float d, int n);
|
||||||
void inflatepoints(cpVect *r, cpVect *p, float d, int n);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -237,7 +237,7 @@ cpBitmask js2bitmask(JSValue v) {
|
||||||
|
|
||||||
cpVect *cpvecarr = NULL;
|
cpVect *cpvecarr = NULL;
|
||||||
|
|
||||||
/* Must be freed */
|
/* Does not need to be freed by returning; but not reentrant */
|
||||||
cpVect *js2cpvec2arr(JSValue v) {
|
cpVect *js2cpvec2arr(JSValue v) {
|
||||||
if (cpvecarr)
|
if (cpvecarr)
|
||||||
arrfree(cpvecarr);
|
arrfree(cpvecarr);
|
||||||
|
@ -362,30 +362,24 @@ JSValue duk_spline_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst
|
||||||
|
|
||||||
tsBSpline spline;
|
tsBSpline spline;
|
||||||
|
|
||||||
int d = js2int(argv[2]); /* dimensions */
|
|
||||||
int degrees = js2int(argv[1]);
|
int degrees = js2int(argv[1]);
|
||||||
|
int d = js2int(argv[2]); /* dimensions */
|
||||||
int type = js2int(argv[3]);
|
int type = js2int(argv[3]);
|
||||||
JSValue ctrl_pts = argv[4];
|
cpVect *points = js2cpvec2arr(argv[4]);
|
||||||
int n = js_arrlen(ctrl_pts);
|
|
||||||
size_t nsamples = js2int(argv[5]);
|
size_t nsamples = js2int(argv[5]);
|
||||||
|
|
||||||
cpVect points[n];
|
|
||||||
|
|
||||||
tsStatus status;
|
tsStatus status;
|
||||||
ts_bspline_new(n, d, degrees, type, &spline, &status);
|
ts_bspline_new(arrlen(points), d, degrees, type, &spline, &status);
|
||||||
|
|
||||||
if (status.code)
|
if (status.code)
|
||||||
YughCritical("Spline creation error %d: %s", status.code, status.message);
|
YughCritical("Spline creation error %d: %s", status.code, status.message);
|
||||||
|
|
||||||
for (int i = 0; i < n; i++)
|
ts_bspline_set_control_points(&spline, (tsReal*)points, &status);
|
||||||
points[i] = js2vec2(js_getpropidx( ctrl_pts, i));
|
|
||||||
|
|
||||||
ts_bspline_set_control_points(&spline, (tsReal *)points, &status);
|
|
||||||
|
|
||||||
if (status.code)
|
if (status.code)
|
||||||
YughCritical("Spline creation error %d: %s", status.code, status.message);
|
YughCritical("Spline creation error %d: %s", status.code, status.message);
|
||||||
|
|
||||||
cpVect samples[nsamples];
|
cpVect *samples = malloc(nsamples*sizeof(cpVect));
|
||||||
|
|
||||||
size_t rsamples;
|
size_t rsamples;
|
||||||
/* TODO: This does not work with Clang/GCC due to UB */
|
/* TODO: This does not work with Clang/GCC due to UB */
|
||||||
|
@ -394,16 +388,10 @@ JSValue duk_spline_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst
|
||||||
if (status.code)
|
if (status.code)
|
||||||
YughCritical("Spline creation error %d: %s", status.code, status.message);
|
YughCritical("Spline creation error %d: %s", status.code, status.message);
|
||||||
|
|
||||||
JSValue arr = JS_NewArray(js);
|
JSValue arr = vecarr2js(samples, nsamples);
|
||||||
|
|
||||||
for (int i = 0; i < nsamples; i++) {
|
|
||||||
JSValue psample = JS_NewArray(js);
|
|
||||||
js_setprop_num(psample, 0, float2js(samples[i].x));
|
|
||||||
js_setprop_num(psample, 1, float2js(samples[i].y));
|
|
||||||
js_setprop_num(arr, i, psample);
|
|
||||||
}
|
|
||||||
|
|
||||||
ts_bspline_free(&spline);
|
ts_bspline_free(&spline);
|
||||||
|
free(samples);
|
||||||
|
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
@ -1587,16 +1575,9 @@ JSValue duk_inflate_cpv(JSContext *js, JSValueConst this, int argc, JSValueConst
|
||||||
cpVect *points = js2cpvec2arr(argv[0]);
|
cpVect *points = js2cpvec2arr(argv[0]);
|
||||||
int n = js2int(argv[1]);
|
int n = js2int(argv[1]);
|
||||||
double d = js2number(argv[2]);
|
double d = js2number(argv[2]);
|
||||||
|
cpVect *infl = inflatepoints(points,d,n);
|
||||||
cpVect inflate_out[n];
|
JSValue arr = vecarr2js(infl,arrlen(infl));
|
||||||
cpVect inflate_in[n];
|
arrfree(infl);
|
||||||
|
|
||||||
inflatepoints(inflate_out, points, d, n);
|
|
||||||
inflatepoints(inflate_in, points, -d, n);
|
|
||||||
|
|
||||||
JSValue arr = JS_NewArray(js);
|
|
||||||
js_setprop_num(arr, 0, vecarr2js(inflate_out, n));
|
|
||||||
js_setprop_num(arr, 1, vecarr2js(inflate_in, n));
|
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -263,6 +263,10 @@ const char *keyname_extd(int key) {
|
||||||
return "space";
|
return "space";
|
||||||
case SAPP_KEYCODE_KP_ADD:
|
case SAPP_KEYCODE_KP_ADD:
|
||||||
return "plus";
|
return "plus";
|
||||||
|
case '=':
|
||||||
|
return "plus";
|
||||||
|
case '-':
|
||||||
|
return "minus";
|
||||||
case SAPP_KEYCODE_KP_SUBTRACT:
|
case SAPP_KEYCODE_KP_SUBTRACT:
|
||||||
return "minus";
|
return "minus";
|
||||||
case SAPP_KEYCODE_GRAVE_ACCENT:
|
case SAPP_KEYCODE_GRAVE_ACCENT:
|
||||||
|
|
Loading…
Reference in a new issue