spline fixes
This commit is contained in:
parent
a8ee53ec33
commit
a03143463e
2
Makefile
2
Makefile
|
@ -51,7 +51,7 @@ ifdef NQOA
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(DBG),1)
|
ifeq ($(DBG),1)
|
||||||
CPPFLAGS += -g -fsanitize=address
|
CPPFLAGS += -g #-fsanitize=address
|
||||||
INFO += _dbg
|
INFO += _dbg
|
||||||
else
|
else
|
||||||
CPPFLAGS += -DNDEBUG
|
CPPFLAGS += -DNDEBUG
|
||||||
|
|
|
@ -787,12 +787,9 @@ Object.defineProperty(String.prototype, 'pct', {
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.defineProperty(String.prototype, 'uc', { value: function() { return this.toUpperCase(); } });
|
Object.defineProperty(String.prototype, 'uc', { value: function() { return this.toUpperCase(); } });
|
||||||
|
|
||||||
Object.defineProperty(String.prototype, 'lc', {value:function() { return this.toLowerCase(); }});
|
Object.defineProperty(String.prototype, 'lc', {value:function() { return this.toLowerCase(); }});
|
||||||
|
|
||||||
|
|
||||||
/* ARRAY DEFS */
|
/* ARRAY DEFS */
|
||||||
|
|
||||||
Object.defineProperty(Array.prototype, 'copy', {
|
Object.defineProperty(Array.prototype, 'copy', {
|
||||||
value: function() {
|
value: function() {
|
||||||
var c = [];
|
var c = [];
|
||||||
|
@ -1199,6 +1196,10 @@ Math.grab_from_points = function(pos, points, slop) {
|
||||||
return idx;
|
return idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Math.nearest = function(n, incr)
|
||||||
|
{
|
||||||
|
return Math.round(n/incr)*incr;
|
||||||
|
}
|
||||||
|
|
||||||
Number.prec = function(num)
|
Number.prec = function(num)
|
||||||
{
|
{
|
||||||
|
@ -1426,6 +1427,10 @@ var Vector = {
|
||||||
return vec.sub(p.scale(2*Vector.dot(vec, p)));
|
return vec.sub(p.scale(2*Vector.dot(vec, p)));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
reflect_point(vec, point) {
|
||||||
|
return point.add(vec.sub(point).scale(-1));
|
||||||
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* POINT ASSISTANCE */
|
/* POINT ASSISTANCE */
|
||||||
|
|
|
@ -97,14 +97,13 @@ component.sprite.impl = {
|
||||||
set layer(x) { cmd(60, this.id, x); },
|
set layer(x) { cmd(60, this.id, x); },
|
||||||
get layer() { return undefined; },
|
get layer() { return undefined; },
|
||||||
emissive(x) { cmd(170, this.id, x); },
|
emissive(x) { cmd(170, this.id, x); },
|
||||||
|
pick() { return this; },
|
||||||
|
move(d) { this.pos = this.pos.add(d); },
|
||||||
|
|
||||||
boundingbox() {
|
boundingbox() {
|
||||||
return cwh2bb([0,0],[0,0]);
|
|
||||||
var dim = this.dimensions();
|
var dim = this.dimensions();
|
||||||
dim = dim.scale(this.gameobject.scale);
|
dim = dim.scale(this.gameobject.gscale());
|
||||||
var realpos = this.pos.copy();
|
var realpos = dim.scale(0.5).add(this.pos);
|
||||||
realpos.x = realpos.x * dim.x + (dim.x/2);
|
|
||||||
realpos.y = realpos.y * dim.y + (dim.y/2);
|
|
||||||
return cwh2bb(realpos,dim);
|
return cwh2bb(realpos,dim);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -123,6 +122,7 @@ component.model = Object.copy(component, {
|
||||||
component.model.impl = {
|
component.model.impl = {
|
||||||
set path(x) { cmd(149, this.id, x); },
|
set path(x) { cmd(149, this.id, x); },
|
||||||
draw() { cmd(150, this.id); },
|
draw() { cmd(150, this.id); },
|
||||||
|
kill() { cmd(213, this.id); },
|
||||||
};
|
};
|
||||||
|
|
||||||
var sprite = component.sprite;
|
var sprite = component.sprite;
|
||||||
|
@ -134,15 +134,15 @@ sprite.doc = {
|
||||||
};
|
};
|
||||||
|
|
||||||
sprite.inputs = {};
|
sprite.inputs = {};
|
||||||
sprite.inputs.kp9 = function() { this.pos = [0,0]; };
|
sprite.inputs.kp9 = function() { this.pos = this.dimensions().scale([0,0]); };
|
||||||
sprite.inputs.kp8 = function() { this.pos = [-0.5, 0]; };
|
sprite.inputs.kp8 = function() { this.pos = this.dimensions().scale([-0.5, 0]); };
|
||||||
sprite.inputs.kp7 = function() { this.pos = [-1,0]; };
|
sprite.inputs.kp7 = function() { this.pos = this.dimensions().scale([-1,0]); };
|
||||||
sprite.inputs.kp6 = function() { this.pos = [0,-0.5]; };
|
sprite.inputs.kp6 = function() { this.pos = this.dimensions().scale([0,-0.5]); };
|
||||||
sprite.inputs.kp5 = function() { this.pos = [-0.5,-0.5]; };
|
sprite.inputs.kp5 = function() { this.pos = this.dimensions().scale([-0.5,-0.5]); };
|
||||||
sprite.inputs.kp4 = function() { this.pos = [-1,-0.5]; };
|
sprite.inputs.kp4 = function() { this.pos = this.dimensions().scale([-1,-0.5]); };
|
||||||
sprite.inputs.kp3 = function() { this.pos = [0, -1]; };
|
sprite.inputs.kp3 = function() { this.pos = this.dimensions().scale([0, -1]); };
|
||||||
sprite.inputs.kp2 = function() { this.pos = [-0.5,-1]; };
|
sprite.inputs.kp2 = function() { this.pos = this.dimensions().scale([-0.5,-1]); };
|
||||||
sprite.inputs.kp1 = function() { this.pos = [-1,-1]; };
|
sprite.inputs.kp1 = function() { this.pos = this.dimensions().scale([-1,-1]); };
|
||||||
Object.seal(sprite);
|
Object.seal(sprite);
|
||||||
|
|
||||||
var SpriteAnim = {
|
var SpriteAnim = {
|
||||||
|
@ -535,8 +535,6 @@ polygon2d.inputs['C-b'] = function() {
|
||||||
};
|
};
|
||||||
polygon2d.inputs['C-b'].doc = "Freeze mirroring in place.";
|
polygon2d.inputs['C-b'].doc = "Freeze mirroring in place.";
|
||||||
|
|
||||||
//Object.freeze(polygon2d);
|
|
||||||
|
|
||||||
component.edge2d = Object.copy(collider2d, {
|
component.edge2d = Object.copy(collider2d, {
|
||||||
dimensions:2,
|
dimensions:2,
|
||||||
thickness:0,
|
thickness:0,
|
||||||
|
@ -544,7 +542,7 @@ component.edge2d = Object.copy(collider2d, {
|
||||||
type: Spline.type.catmull,
|
type: Spline.type.catmull,
|
||||||
C: 1, /* when in bezier, continuity required. 0, 1 or 2. */
|
C: 1, /* when in bezier, continuity required. 0, 1 or 2. */
|
||||||
looped: false,
|
looped: false,
|
||||||
angle: 3, /* maximum angle between two segments */
|
angle: 0.5, /* smaller for smoother bezier */
|
||||||
|
|
||||||
flipx: false,
|
flipx: false,
|
||||||
flipy: false,
|
flipy: false,
|
||||||
|
@ -559,8 +557,10 @@ component.edge2d = Object.copy(collider2d, {
|
||||||
var spoints = this.cpoints.slice();
|
var spoints = this.cpoints.slice();
|
||||||
|
|
||||||
if (this.flipx) {
|
if (this.flipx) {
|
||||||
var endcap = Spline.is_bezier(this.type) ? spoints.length-2 : spoints.length-1;
|
if (Spline.is_bezier(this.type))
|
||||||
for (var i = endcap; i >= 0; i--) {
|
spoints.push(Vector.reflect_point(spoints.at(-2), spoints.at(-1)));
|
||||||
|
|
||||||
|
for (var i = spoints.length-1; i >= 0; i--) {
|
||||||
var newpoint = spoints[i].slice();
|
var newpoint = spoints[i].slice();
|
||||||
newpoint.x = -newpoint.x;
|
newpoint.x = -newpoint.x;
|
||||||
spoints.push(newpoint);
|
spoints.push(newpoint);
|
||||||
|
@ -568,6 +568,9 @@ component.edge2d = Object.copy(collider2d, {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.flipy) {
|
if (this.flipy) {
|
||||||
|
if (Spline.is_bezier(this.type))
|
||||||
|
spoints.push(Vector.reflect(point(spoints.at(-2),spoints.at(-1))));
|
||||||
|
|
||||||
for (var i = spoints.length-1; i >= 0; i--) {
|
for (var i = spoints.length-1; i >= 0; i--) {
|
||||||
var newpoint = spoints[i].slice();
|
var newpoint = spoints[i].slice();
|
||||||
newpoint.y = -newpoint.y;
|
newpoint.y = -newpoint.y;
|
||||||
|
@ -611,6 +614,9 @@ component.edge2d = Object.copy(collider2d, {
|
||||||
return Spline.sample_angle(this.type, spoints,this.angle);
|
return Spline.sample_angle(this.type, spoints,this.angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.looped && Spline.is_bezier(this.type))
|
||||||
|
spoints = Spline.bezier_loop(spoints);
|
||||||
|
|
||||||
return Spline.sample_angle(this.type, spoints, this.angle);
|
return Spline.sample_angle(this.type, spoints, this.angle);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -875,7 +881,6 @@ component.circle2d = Object.copy(collider2d, {
|
||||||
toString() { return "circle2d"; },
|
toString() { return "circle2d"; },
|
||||||
|
|
||||||
boundingbox() {
|
boundingbox() {
|
||||||
var diameter = this.radius*2*this.gameobject.scale;
|
|
||||||
return cwh2bb(this.offset.scale(this.gameobject.scale), [this.radius,this.radius]);
|
return cwh2bb(this.offset.scale(this.gameobject.scale), [this.radius,this.radius]);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -389,8 +389,6 @@ var editor = {
|
||||||
Debug.boundingbox(bb, Color.Editor.select.alpha(0.1));
|
Debug.boundingbox(bb, Color.Editor.select.alpha(0.1));
|
||||||
Shape.line(bb2points(bb).wrapped(1), Color.white);
|
Shape.line(bb2points(bb).wrapped(1), Color.white);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
gui() {
|
gui() {
|
||||||
|
@ -459,8 +457,8 @@ var editor = {
|
||||||
Object.entries(thiso.objects).forEach(function(x) {
|
Object.entries(thiso.objects).forEach(function(x) {
|
||||||
var p = x[1].namestr();
|
var p = x[1].namestr();
|
||||||
GUI.text(p, x[1].screenpos().add([0,16]),1,editor.color_depths[depth]);
|
GUI.text(p, x[1].screenpos().add([0,16]),1,editor.color_depths[depth]);
|
||||||
Shape.circle(x[1].screenpos(),10,Color.blue);
|
Shape.circle(x[1].screenpos(),10,Color.blue.alpha(0.3));
|
||||||
Shape.arrow(x[1].screenpos(), x[1].screenpos().add([0,50]), Color.red, 10);
|
Shape.arrow(x[1].screenpos(), x[1].screenpos().add(x[1].up().scale(15)), Color.red, 10);
|
||||||
});
|
});
|
||||||
|
|
||||||
var mg = physics.pos_query(Mouse.worldpos,10);
|
var mg = physics.pos_query(Mouse.worldpos,10);
|
||||||
|
@ -470,6 +468,9 @@ var editor = {
|
||||||
GUI.text(p, Mouse.screenpos(),1,Color.teal);
|
GUI.text(p, Mouse.screenpos(),1,Color.teal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.rotlist.length === 1)
|
||||||
|
GUI.text(Math.trunc(this.rotlist[0].obj.angle), Mouse.screenpos(), 1, Color.teal);
|
||||||
|
|
||||||
if (this.selectlist.length === 1) {
|
if (this.selectlist.length === 1) {
|
||||||
var i = 1;
|
var i = 1;
|
||||||
for (var key in this.selectlist[0].components) {
|
for (var key in this.selectlist[0].components) {
|
||||||
|
@ -1143,6 +1144,8 @@ editor.inputs.mouse.move = function(pos, dpos)
|
||||||
editor.rotlist?.forEach(function(x) {
|
editor.rotlist?.forEach(function(x) {
|
||||||
var anglediff = Math.atan2(relpos.y, relpos.x) - x.rotoffset;
|
var anglediff = Math.atan2(relpos.y, relpos.x) - x.rotoffset;
|
||||||
x.obj.angle = x.angle + Math.rad2deg(anglediff);
|
x.obj.angle = x.angle + Math.rad2deg(anglediff);
|
||||||
|
if (Keys.shift())
|
||||||
|
x.obj.angle = Math.nearest(x.obj.angle, 45);
|
||||||
if (x.pos)
|
if (x.pos)
|
||||||
x.obj.pos = x.pos.sub(x.offset).add(x.offset.rotate(anglediff));
|
x.obj.pos = x.pos.sub(x.offset).add(x.offset.rotate(anglediff));
|
||||||
});
|
});
|
||||||
|
@ -1151,7 +1154,6 @@ editor.inputs.mouse.move = function(pos, dpos)
|
||||||
editor.inputs.mouse.scroll = function(scroll)
|
editor.inputs.mouse.scroll = function(scroll)
|
||||||
{
|
{
|
||||||
scroll.y *= -1;
|
scroll.y *= -1;
|
||||||
// editor.grabselect?.forEach(x => x.move(Game.camera.dir_view2world(scroll)));
|
|
||||||
editor.camera.move(Game.camera.dir_view2world(scroll.scale(-3)));
|
editor.camera.move(Game.camera.dir_view2world(scroll.scale(-3)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -234,42 +234,15 @@ register(9, Log.stack, this);
|
||||||
Register.gamepad_playermap[0] = Player.players[0];
|
Register.gamepad_playermap[0] = Player.players[0];
|
||||||
|
|
||||||
var Signal = {
|
var Signal = {
|
||||||
signals: [],
|
|
||||||
obj_begin(fn, obj, go) {
|
obj_begin(fn, obj, go) {
|
||||||
this.signals.push([fn, obj]);
|
|
||||||
register_collide(0, fn, obj, go.body);
|
register_collide(0, fn, obj, go.body);
|
||||||
},
|
},
|
||||||
|
|
||||||
obj_separate(fn, obj, go) {
|
obj_separate(fn, obj, go) {
|
||||||
this.signals.push([fn,obj]);
|
|
||||||
register_collide(3,fn,obj,go.body);
|
register_collide(3,fn,obj,go.body);
|
||||||
},
|
},
|
||||||
|
|
||||||
clear_obj(obj) {
|
|
||||||
this.signals.filter(function(x) { return x[1] !== obj; });
|
|
||||||
},
|
|
||||||
|
|
||||||
c:{},
|
|
||||||
register(name, fn) {
|
|
||||||
if (!this.c[name])
|
|
||||||
this.c[name] = [];
|
|
||||||
|
|
||||||
this.c[name].push(fn);
|
|
||||||
},
|
|
||||||
|
|
||||||
call(name, ...args) {
|
|
||||||
if (this.c[name])
|
|
||||||
this.c[name].forEach(function(fn) { fn.call(this, ...args); });
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var game_quit = function()
|
|
||||||
{
|
|
||||||
Primum.kill();
|
|
||||||
}
|
|
||||||
|
|
||||||
Signal.register("quit", game_quit);
|
|
||||||
|
|
||||||
var Event = {
|
var Event = {
|
||||||
events: {},
|
events: {},
|
||||||
|
|
||||||
|
@ -282,6 +255,10 @@ var Event = {
|
||||||
this.events[name] = this.events[name].filter(x => x[0] !== obj);
|
this.events[name] = this.events[name].filter(x => x[0] !== obj);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
rm_obj(obj) {
|
||||||
|
Object.keys(this.events).forEach(name => Event.unobserve(name,obj));
|
||||||
|
},
|
||||||
|
|
||||||
notify(name) {
|
notify(name) {
|
||||||
if (!this.events[name]) return;
|
if (!this.events[name]) return;
|
||||||
this.events[name].forEach(function(x) {
|
this.events[name].forEach(function(x) {
|
||||||
|
@ -290,6 +267,8 @@ var Event = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Event.observe('quit', undefined, function() { Primum.kill(); });
|
||||||
|
|
||||||
var Window = {
|
var Window = {
|
||||||
fullscreen(f) { cmd(145, f); },
|
fullscreen(f) { cmd(145, f); },
|
||||||
set width(w) { cmd(125, w); },
|
set width(w) { cmd(125, w); },
|
||||||
|
@ -337,6 +316,14 @@ Spline.sample_angle = function(type, points, angle) {
|
||||||
return spline_cmd(0, type, points[0].length, points, angle);
|
return spline_cmd(0, type, points[0].length, points, angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Spline.bezier_loop = function(cp)
|
||||||
|
{
|
||||||
|
cp.push(Vector.reflect_point(cp.at(-2),cp.at(-1)));
|
||||||
|
cp.push(Vector.reflect_point(cp[1],cp[0]));
|
||||||
|
cp.push(cp[0].slice());
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
Spline.is_bezier = function(t) { return t === Spline.type.bezier; }
|
Spline.is_bezier = function(t) { return t === Spline.type.bezier; }
|
||||||
Spline.is_catmull = function(t) { return t === Spline.type.catmull; }
|
Spline.is_catmull = function(t) { return t === Spline.type.catmull; }
|
||||||
|
|
||||||
|
@ -448,6 +435,10 @@ var Game = {
|
||||||
|
|
||||||
edit: true,
|
edit: true,
|
||||||
|
|
||||||
|
object_count() {
|
||||||
|
return cmd(214);
|
||||||
|
},
|
||||||
|
|
||||||
all_objects(fn) {
|
all_objects(fn) {
|
||||||
/* Wind down from Primum */
|
/* Wind down from Primum */
|
||||||
},
|
},
|
||||||
|
@ -463,7 +454,7 @@ var Game = {
|
||||||
},
|
},
|
||||||
|
|
||||||
/* List of all objects spawned that have a specific tag */
|
/* List of all objects spawned that have a specific tag */
|
||||||
find_tag(tag) {
|
find_tag(tag){
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -191,7 +191,7 @@ var gameobject = {
|
||||||
set_gravity(x) { cmd(167, this.body, x); },
|
set_gravity(x) { cmd(167, this.body, x); },
|
||||||
set timescale(x) { cmd(168,this.body,x); },
|
set timescale(x) { cmd(168,this.body,x); },
|
||||||
get timescale() { return cmd(169,this.body); },
|
get timescale() { return cmd(169,this.body); },
|
||||||
set phys(x) { console.warn(`Setting phys to ${x}`); set_body(1, this.body, x); },
|
set phys(x) { set_body(1, this.body, x); },
|
||||||
get phys() { return q_body(0,this.body); },
|
get phys() { return q_body(0,this.body); },
|
||||||
get velocity() { return q_body(3, this.body); },
|
get velocity() { return q_body(3, this.body); },
|
||||||
set velocity(x) { set_body(9, this.body, x); },
|
set velocity(x) { set_body(9, this.body, x); },
|
||||||
|
@ -411,7 +411,12 @@ var gameobject = {
|
||||||
/* Bounding box of the object in world dimensions */
|
/* Bounding box of the object in world dimensions */
|
||||||
boundingbox() {
|
boundingbox() {
|
||||||
var boxes = [];
|
var boxes = [];
|
||||||
boxes.push({t:0, r:0,b:0,l:0});
|
boxes.push({
|
||||||
|
t:0,
|
||||||
|
r:0,
|
||||||
|
b:0,
|
||||||
|
l:0
|
||||||
|
});
|
||||||
|
|
||||||
for (var key in this.components) {
|
for (var key in this.components) {
|
||||||
if ('boundingbox' in this.components[key])
|
if ('boundingbox' in this.components[key])
|
||||||
|
@ -420,23 +425,11 @@ var gameobject = {
|
||||||
for (var key in this.objects)
|
for (var key in this.objects)
|
||||||
boxes.push(this.objects[key].boundingbox());
|
boxes.push(this.objects[key].boundingbox());
|
||||||
|
|
||||||
if (boxes.empty) return cwh2bb([0,0], [0,0]);
|
var bb = boxes.shift();
|
||||||
|
|
||||||
var bb = boxes[0];
|
boxes.forEach(function(x) { bb = bb_expand(bb, x); });
|
||||||
|
|
||||||
boxes.forEach(function(x) {
|
bb = movebb(bb, this.pos);
|
||||||
bb = bb_expand(bb, x);
|
|
||||||
});
|
|
||||||
|
|
||||||
var cwh = bb2cwh(bb);
|
|
||||||
|
|
||||||
if (!bb) return;
|
|
||||||
|
|
||||||
if (this.flipx) cwh.c.x *= -1;
|
|
||||||
if (this.flipy) cwh.c.y *= -1;
|
|
||||||
|
|
||||||
cwh.c = cwh.c.add(this.pos);
|
|
||||||
bb = cwh2bb(cwh.c, cwh.wh);
|
|
||||||
|
|
||||||
return bb ? bb : cwh2bb([0,0], [0,0]);
|
return bb ? bb : cwh2bb([0,0], [0,0]);
|
||||||
},
|
},
|
||||||
|
@ -519,8 +512,6 @@ var gameobject = {
|
||||||
this.level = undefined;
|
this.level = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Player.do_uncontrol(this);
|
Player.do_uncontrol(this);
|
||||||
Register.unregister_obj(this);
|
Register.unregister_obj(this);
|
||||||
|
|
||||||
|
@ -536,6 +527,7 @@ var gameobject = {
|
||||||
|
|
||||||
this.clear();
|
this.clear();
|
||||||
this.objects = undefined;
|
this.objects = undefined;
|
||||||
|
Event.rm_obj(this);
|
||||||
|
|
||||||
if (typeof this.stop === 'function')
|
if (typeof this.stop === 'function')
|
||||||
this.stop();
|
this.stop();
|
||||||
|
@ -633,16 +625,12 @@ var gameobject = {
|
||||||
},
|
},
|
||||||
|
|
||||||
register_hit(fn, obj) {
|
register_hit(fn, obj) {
|
||||||
if (!obj)
|
obj ??= this;
|
||||||
obj = this;
|
|
||||||
|
|
||||||
Signal.obj_begin(fn, obj, this);
|
Signal.obj_begin(fn, obj, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
register_separate(fn, obj) {
|
register_separate(fn, obj) {
|
||||||
if (!obj)
|
obj ??= this;
|
||||||
obj = this;
|
|
||||||
|
|
||||||
Signal.obj_separate(fn,obj,this);
|
Signal.obj_separate(fn,obj,this);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,11 @@ function compile_env(str, env, file)
|
||||||
return cmd(123, str, env, file);
|
return cmd(123, str, env, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
function fcompile_env(file, env)
|
function fcompile_env(file, env) { return compile_env(IO.slurp(file), env, file); }
|
||||||
{
|
|
||||||
return compile_env(IO.slurp(file), env, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
var OS = {
|
var OS = {};
|
||||||
get cwd() { return cmd(144); },
|
OS.cwd = function() { return cmd(144); }
|
||||||
};
|
OS.exec = function(s) { cmd(143, s); }
|
||||||
OS.exec = function(s)
|
|
||||||
{
|
|
||||||
cmd(143, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
var Resources = {};
|
var Resources = {};
|
||||||
Resources.images = ["png", "jpg", "jpeg", "gif"];
|
Resources.images = ["png", "jpg", "jpeg", "gif"];
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#define CGLTF_IMPLEMENTATION
|
#define CGLTF_IMPLEMENTATION
|
||||||
#include <cgltf.h>
|
#include <cgltf.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -32,6 +33,8 @@ static struct {
|
||||||
struct model *value;
|
struct model *value;
|
||||||
} *modelhash = NULL;
|
} *modelhash = NULL;
|
||||||
|
|
||||||
|
struct drawmodel **models = NULL;
|
||||||
|
|
||||||
static void processnode();
|
static void processnode();
|
||||||
static void processmesh();
|
static void processmesh();
|
||||||
static void processtexture();
|
static void processtexture();
|
||||||
|
@ -116,6 +119,8 @@ unsigned short pack_short_texcoord(float x, float y)
|
||||||
return (((unsigned short)yc) << 8) | xc;
|
return (((unsigned short)yc) << 8) | xc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned short pack_short_tex(float c) { return c * USHRT_MAX; }
|
||||||
|
|
||||||
uint32_t pack_int10_n2(float *norm)
|
uint32_t pack_int10_n2(float *norm)
|
||||||
{
|
{
|
||||||
uint32_t ni[3];
|
uint32_t ni[3];
|
||||||
|
@ -157,9 +162,10 @@ void mesh_add_material(mesh *mesh, cgltf_material *mat)
|
||||||
|
|
||||||
sg_buffer texcoord_floats(float *f, int verts, int comp)
|
sg_buffer texcoord_floats(float *f, int verts, int comp)
|
||||||
{
|
{
|
||||||
unsigned short packed[verts];
|
int n = verts*comp;
|
||||||
for (int i = 0, v = 0; v < verts; i+=comp, v++)
|
unsigned short packed[n];
|
||||||
packed[v] = pack_short_texcoord(f[i], f[i+1]);
|
for (int i = 0, v = 0; i < n; i++)
|
||||||
|
packed[i] = pack_short_tex(f[i]);
|
||||||
|
|
||||||
return sg_make_buffer(&(sg_buffer_desc){
|
return sg_make_buffer(&(sg_buffer_desc){
|
||||||
.data.ptr = packed,
|
.data.ptr = packed,
|
||||||
|
@ -390,9 +396,16 @@ struct drawmodel *make_drawmodel(gameobject *go)
|
||||||
dm->model = NULL;
|
dm->model = NULL;
|
||||||
dm->amodel = HMM_M4D(1.f);
|
dm->amodel = HMM_M4D(1.f);
|
||||||
dm->go = go;
|
dm->go = go;
|
||||||
|
arrpush(models,dm);
|
||||||
return dm;
|
return dm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void model_draw_all()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < arrlen(models); i++)
|
||||||
|
draw_drawmodel(models[i]);
|
||||||
|
}
|
||||||
|
|
||||||
void draw_drawmodel(struct drawmodel *dm)
|
void draw_drawmodel(struct drawmodel *dm)
|
||||||
{
|
{
|
||||||
if (!dm->model) return;
|
if (!dm->model) return;
|
||||||
|
@ -401,5 +414,15 @@ void draw_drawmodel(struct drawmodel *dm)
|
||||||
draw_model(dm->model, rst);
|
draw_model(dm->model, rst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_drawmodel(struct drawmodel *dm) { free(dm); }
|
void free_drawmodel(struct drawmodel *dm) {
|
||||||
|
int rm;
|
||||||
|
for (int i = 0; i < arrlen(models); i++)
|
||||||
|
if (models[i] == dm) {
|
||||||
|
rm = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
arrdelswap(models,rm);
|
||||||
|
free(dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ void model_init();
|
||||||
|
|
||||||
struct drawmodel *make_drawmodel(gameobject *go);
|
struct drawmodel *make_drawmodel(gameobject *go);
|
||||||
void draw_drawmodel(struct drawmodel *dm);
|
void draw_drawmodel(struct drawmodel *dm);
|
||||||
|
void model_draw_all();
|
||||||
void free_drawmodel(struct drawmodel *dm);
|
void free_drawmodel(struct drawmodel *dm);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -62,7 +62,7 @@ void mYughLog(int category, int priority, int line, const char *file, const char
|
||||||
char *buffer = malloc(len);
|
char *buffer = malloc(len);
|
||||||
sprintf(buffer, logfmt, file, line, logstr[priority], catstr[category], msg);
|
sprintf(buffer, logfmt, file, line, logstr[priority], catstr[category], msg);
|
||||||
|
|
||||||
fprintf(stderr, buffer);
|
fprintf(stderr, "%s", buffer);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
|
||||||
free(msg);
|
free(msg);
|
||||||
|
|
|
@ -303,7 +303,7 @@ struct boundingbox text_bb(const unsigned char *text, float scale, float lw, flo
|
||||||
|
|
||||||
while (!isspace(*line) && *line != '\0') {
|
while (!isspace(*line) && *line != '\0') {
|
||||||
wordWidth += font->Characters[*line].Advance * tracking * scale;
|
wordWidth += font->Characters[*line].Advance * tracking * scale;
|
||||||
line++;
|
line++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lw > 0 && (cursor.X + wordWidth) >= lw) {
|
if (lw > 0 && (cursor.X + wordWidth) >= lw) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ struct sFont {
|
||||||
int descent;
|
int descent;
|
||||||
int linegap;
|
int linegap;
|
||||||
float emscale;
|
float emscale;
|
||||||
struct Character Characters[127];
|
struct Character Characters[255];
|
||||||
sg_image texID;
|
sg_image texID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
static gameobject **gameobjects;
|
static gameobject **gameobjects;
|
||||||
|
|
||||||
|
int go_count() { return arrlen(gameobjects); }
|
||||||
|
|
||||||
gameobject *body2go(cpBody *body) { return cpBodyGetUserData(body); }
|
gameobject *body2go(cpBody *body) { return cpBodyGetUserData(body); }
|
||||||
gameobject *shape2go(cpShape *shape) { return ((struct phys2d_shape *)cpShapeGetUserData(shape))->go; }
|
gameobject *shape2go(cpShape *shape) { return ((struct phys2d_shape *)cpShapeGetUserData(shape))->go; }
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ struct gameobject {
|
||||||
typedef struct gameobject gameobject;
|
typedef struct gameobject gameobject;
|
||||||
|
|
||||||
gameobject *MakeGameobject();
|
gameobject *MakeGameobject();
|
||||||
|
int go_count();
|
||||||
void gameobject_apply(gameobject *go);
|
void gameobject_apply(gameobject *go);
|
||||||
void gameobject_free(gameobject *go);
|
void gameobject_free(gameobject *go);
|
||||||
void gameobjects_cleanup();
|
void gameobjects_cleanup();
|
||||||
|
|
|
@ -1120,7 +1120,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||||
|
|
||||||
case 143:
|
case 143:
|
||||||
str = JS_ToCString(js, argv[1]);
|
str = JS_ToCString(js, argv[1]);
|
||||||
// system(str);
|
system(str);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 144:
|
case 144:
|
||||||
|
@ -1349,6 +1349,12 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||||
case 212:
|
case 212:
|
||||||
ret = jsdst();
|
ret = jsdst();
|
||||||
break;
|
break;
|
||||||
|
case 213:
|
||||||
|
free_drawmodel(js2ptr(argv[1]));
|
||||||
|
break;
|
||||||
|
case 214:
|
||||||
|
ret = int2js(go_count());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str)
|
if (str)
|
||||||
|
|
|
@ -509,6 +509,7 @@ void full_2d_pass(struct window *window)
|
||||||
hudproj = HMM_Orthographic_LH_ZO(0, window->rwidth, 0, window->rheight, -1.f, 1.f);
|
hudproj = HMM_Orthographic_LH_ZO(0, window->rwidth, 0, window->rheight, -1.f, 1.f);
|
||||||
|
|
||||||
sprite_draw_all();
|
sprite_draw_all();
|
||||||
|
model_draw_all();
|
||||||
call_draw();
|
call_draw();
|
||||||
|
|
||||||
//// DEBUG
|
//// DEBUG
|
||||||
|
|
|
@ -249,7 +249,7 @@ char *slurp_text(const char *filename, size_t *size)
|
||||||
|
|
||||||
int cp(char *p1, char *p2)
|
int cp(char *p1, char *p2)
|
||||||
{
|
{
|
||||||
long len;
|
size_t len;
|
||||||
void *data = slurp_file(p1, &len);
|
void *data = slurp_file(p1, &len);
|
||||||
|
|
||||||
FILE *f = fopen_mkdir(p2, "w");
|
FILE *f = fopen_mkdir(p2, "w");
|
||||||
|
|
|
@ -72,6 +72,7 @@ void script_startup() {
|
||||||
void script_stop()
|
void script_stop()
|
||||||
{
|
{
|
||||||
timers_free();
|
timers_free();
|
||||||
|
script_evalf("Event.notify('quit');");
|
||||||
send_signal("quit",0,NULL);
|
send_signal("quit",0,NULL);
|
||||||
|
|
||||||
for (int i = 0; i < shlen(jsstrs); i++)
|
for (int i = 0; i < shlen(jsstrs); i++)
|
||||||
|
|
|
@ -79,12 +79,9 @@ static int sim_play = SIM_PLAY;
|
||||||
|
|
||||||
int editor_mode = 0;
|
int editor_mode = 0;
|
||||||
|
|
||||||
const char *engine_info()
|
#define ENGINEINFO "Yugine version " VER ", " INFO " build.\nCopyright 2022-2024."
|
||||||
{
|
|
||||||
static char str[100];
|
const char *engine_info() { return ENGINEINFO; }
|
||||||
snprintf(str, 100, "Yugine version %s, %s build.\nCopyright 2022-2023 odplot productions LLC.\n", VER, INFO);
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int argc;
|
static int argc;
|
||||||
static char **args;
|
static char **args;
|
||||||
|
|
|
@ -39,14 +39,6 @@ in float radius;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
if (segsize<0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
float f = atan(coords.y, coords.x) + PI;
|
|
||||||
|
|
||||||
if (mod(f, segsize) < segsize/2)
|
|
||||||
discard;
|
|
||||||
|
|
||||||
float px = 1/radius;
|
float px = 1/radius;
|
||||||
float R1 = 1.f;
|
float R1 = 1.f;
|
||||||
float R2 = 1.0 - fill;
|
float R2 = 1.0 - fill;
|
||||||
|
@ -57,6 +49,14 @@ void main()
|
||||||
float sm2 = smoothstep(R2-px,R2,dist);
|
float sm2 = smoothstep(R2-px,R2,dist);
|
||||||
float a = sm*sm2;
|
float a = sm*sm2;
|
||||||
color = mix(vec4(0,0,0,0), fcolor, a);
|
color = mix(vec4(0,0,0,0), fcolor, a);
|
||||||
|
|
||||||
|
if (segsize<0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float f = atan(coords.y, coords.x) + PI;
|
||||||
|
|
||||||
|
if (mod(f, segsize) < segsize/2)
|
||||||
|
discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
Loading…
Reference in a new issue