sprites are now presorted

This commit is contained in:
John Alanbrook 2024-09-26 23:12:30 -05:00
parent 6f9137746a
commit 4756955c1a
6 changed files with 57 additions and 90 deletions

View file

@ -1556,15 +1556,12 @@ Math.sign = function (n) {
var lodash = {}; var lodash = {};
lodash.get = function (obj, path, defValue) { lodash.get = function (obj, path, defValue) {
if (!path) return undefined if (!path) return undefined;
// Check if path is string or array. Regex : ensure that we do not have '.' and brackets. // Check if path is string or array. Regex : ensure that we do not have '.' and brackets.
var pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g) var pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g);
var result = pathArray.reduce( var result = pathArray.reduce((prevObj, key) => prevObj && prevObj[key], obj);
(prevObj, key) => prevObj && prevObj[key], return result === undefined ? defValue : result;
obj };
)
return result === undefined ? defValue : result
}
return { return {
convert, convert,
@ -1572,5 +1569,5 @@ return {
Vector, Vector,
bbox, bbox,
yaml, yaml,
lodash lodash,
}; };

View file

@ -15,14 +15,17 @@ var make_point_obj = function (o, p) {
var fullrect = [0, 0, 1, 1]; var fullrect = [0, 0, 1, 1];
var sprite_addbucket = function (sprite) { var sprite_addbucket = function (sprite) {
var layer = sprite.gameobject.drawlayer; var layer = 1000000 + sprite.gameobject.drawlayer * 1000 - sprite.gameobject.pos.y;
sprite_buckets[layer] ??= {}; sprite_buckets[layer] ??= {};
sprite_buckets[layer][sprite.path] ??= {}; sprite_buckets[layer][sprite.path] ??= [];
sprite_buckets[layer][sprite.path][sprite.guid] = sprite; sprite_buckets[layer][sprite.path].push(sprite);
sprite._oldlayer = layer;
sprite._oldpath = sprite.path;
}; };
var sprite_rmbucket = function (sprite) { var sprite_rmbucket = function (sprite) {
for (var layer of Object.values(sprite_buckets)) for (var path of Object.values(layer)) delete path[sprite.guid]; if (sprite._oldlayer && sprite._oldpath) sprite_buckets[sprite._oldlayer][sprite._oldpath].remove(sprite);
else for (var layer of Object.values(sprite_buckets)) for (var path of Object.values(layer)) path.remove(sprite);
}; };
var sprite = { var sprite = {
@ -72,7 +75,7 @@ var sprite = {
// self?.anim_done?.(); // self?.anim_done?.();
// if (!self.loop) { self.stop(); return; } // if (!self.loop) { self.stop(); return; }
} }
if (self) stop = self.gameobject.delay(advance, playing.frames[f].time / self.anim_speed); // if (self) stop = self.gameobject.delay(advance, playing.frames[f].time / self.anim_speed);
} }
advance(); advance();
@ -119,7 +122,7 @@ var sprite = {
this.anim = undefined; this.anim = undefined;
this.gameobject = undefined; this.gameobject = undefined;
this.anim_done = undefined; this.anim_done = undefined;
delete allsprites[this.guid]; allsprites.remove(this);
}, },
move(d) { move(d) {
this.pos = this.pos.add(d); this.pos = this.pos.add(d);
@ -130,6 +133,9 @@ var sprite = {
}, },
anchor: [0, 0], anchor: [0, 0],
sync() { sync() {
var layer = 1000000 + this.gameobject.drawlayer * 1000 - this.gameobject.pos.y;
if (layer === this._oldlayer && this.path === this._oldpath) return;
sprite_rmbucket(this); sprite_rmbucket(this);
sprite_addbucket(this); sprite_addbucket(this);
}, },
@ -158,13 +164,15 @@ var sprite = {
return this.dimensions().y; return this.dimensions().y;
}, },
}; };
globalThis.allsprites = {}; globalThis.allsprites = [];
var sprite_buckets = {}; var sprite_buckets = [];
component.sprite_buckets = function () { component.sprite_buckets = function () {
return sprite_buckets; return sprite_buckets;
}; };
component.dynamic_sprites = [];
sprite.doc = { sprite.doc = {
path: "Path to the texture.", path: "Path to the texture.",
color: "Color to mix with the sprite.", color: "Color to mix with the sprite.",
@ -239,7 +247,7 @@ component.sprite = function (obj) {
sp.gameobject = obj; sp.gameobject = obj;
sp.transform = obj.transform; sp.transform = obj.transform;
sp.guid = prosperon.guid(); sp.guid = prosperon.guid();
allsprites[sp.guid] = sp; allsprites.push(sp);
if (component.sprite.make_hook) component.sprite.make_hook(sp); if (component.sprite.make_hook) component.sprite.make_hook(sp);
sprite_addbucket(sp); sprite_addbucket(sp);
return sp; return sp;

View file

@ -61,8 +61,8 @@ function add_callgraph(fn, line, time, alone) {
cc.line = line; cc.line = line;
cc.alone = { cc.alone = {
time: 0, time: 0,
hits: 0 hits: 0,
} };
} }
cc.time += time; cc.time += time;
cc.hits++; cc.hits++;
@ -131,7 +131,7 @@ profile.start_cpu_gather = function (gathertime = 5) {
x.alone.timestr = profile.best_t(x.alone.time); x.alone.timestr = profile.best_t(x.alone.time);
x.alone.timeper = x.alone.time / x.alone.hits; x.alone.timeper = x.alone.time / x.alone.hits;
x.alone.timeperstr = profile.best_t(x.alone.timeper); x.alone.timeperstr = profile.best_t(x.alone.timeper);
x.alone.pct = (profile.secs(x.alone.time)/gathertime*100); x.alone.pct = (profile.secs(x.alone.time) / gathertime) * 100;
x.fncall = get_line(ffs[0], ffs[1]); x.fncall = get_line(ffs[0], ffs[1]);
x.log = x.line + " " + x.fn + " " + x.fncall; x.log = x.line + " " + x.fn + " " + x.fncall;
x.incl = { x.incl = {
@ -289,10 +289,12 @@ profile.cache = function profile_cache(group, title) {
}; };
profile.endcache = function profile_endcache(tag = "") { profile.endcache = function profile_endcache(tag = "") {
return;
addreport(cachegroup, cachetitle + tag, cachest); addreport(cachegroup, cachetitle + tag, cachest);
}; };
function addreport(group, line, start) { function addreport(group, line, start) {
return;
if (typeof group !== "string") group = "UNGROUPED"; if (typeof group !== "string") group = "UNGROUPED";
report_cache[group] ??= {}; report_cache[group] ??= {};
var cache = report_cache[group]; var cache = report_cache[group];
@ -331,14 +333,13 @@ profile.curframe = 0;
profile.snapshot = {}; profile.snapshot = {};
var fps = []; var fps = [];
profile.report_frame = function(t) profile.report_frame = function (t) {
{
fps.push(t); fps.push(t);
if (fps.length > 15) { if (fps.length > 15) {
profile.snapshot.fps = Math.mean(fps); profile.snapshot.fps = Math.mean(fps);
fps = []; fps = [];
} }
} };
function prof_add_stats(obj, stat) { function prof_add_stats(obj, stat) {
for (var i in stat) { for (var i in stat) {
@ -348,7 +349,6 @@ function prof_add_stats(obj, stat) {
} }
profile.pushdata = function (arr, val) { profile.pushdata = function (arr, val) {
if (arr.last() !== val) arr[profile.curframe] = val; if (arr.last() !== val) arr[profile.curframe] = val;
}; };

View file

@ -323,11 +323,21 @@ var Register = {
profile.endcache(); profile.endcache();
}; };
fns.push(dofn); var left = 0;
var right = fns.length - 1;
dofn.layer = fn.layer; dofn.layer = fn.layer;
dofn.layer ??= 0; dofn.layer ??= 0;
fns.sort((a, b) => a.layer > b.layer); while (left <= right) {
var mid = Math.floor((left + right) / 2);
if (fns[mid] === dofn.layer) {
left = mid;
break;
} else if (fns[mid].layer < dofn.layer) left = mid + 1;
else right = mid - 1;
}
fns.splice(left, 0, dofn);
return function () { return function () {
fns.remove(dofn); fns.remove(dofn);

View file

@ -500,67 +500,19 @@ render.draw_hud = true;
render.draw_gui = true; render.draw_gui = true;
render.draw_gizmos = true; render.draw_gizmos = true;
render.buckets = [];
render.sprites = function render_sprites(gridsize = 1) { render.sprites = function render_sprites(gridsize = 1) {
// When y sorting, draw layer is firstly important followed by the gameobject position // When y sorting, draw layer is firstly important followed by the gameobject position
var buckets; //for (var sprite of allsprites)
if (render.y_sort) { // sprite.sync();
profile.frame("y bucketing");
var sps = Object.values(allsprites);
buckets = {};
for (var sprite of sps) {
var layer = sprite.gameobject.drawlayer * 10000 - sprite.gameobject.pos.y;
buckets[layer] ??= {};
if (buckets[layer][sprite.path]) buckets[layer][sprite.path].push(sprite);
else buckets[layer][sprite.path] = [sprite];
}
profile.endframe();
profile.frame("y sorting");
buckets = Object.entries(buckets).sort((a, b) => {
var na = Number(a[0]);
var nb = Number(b[0]);
if (na < nb) return -1;
return 1;
});
profile.endframe();
} else {
profile.frame("sorting");
var sprite_buckets = component.sprite_buckets();
var buckets = Object.entries(sprite_buckets).sort((a, b) => {
var na = Number(a[0]);
var nb = Number(b[0]);
if (na < nb) return -1;
return 1;
});
profile.endframe();
}
/*
profile.frame("bucketing");
var sps = Object.values(allsprites);
var buckets = [];
for (var i = 0; i <= 20; i++)
buckets[i] = {};
for (var sprite of sps) {
var layer = sprite.gameobject.drawlayer+10;
if (buckets[layer][sprite.path])
buckets[layer][sprite.path].push(sprite);
else
buckets[layer][sprite.path] = [sprite];
}
profile.endframe();
*/
profile.frame("drawing"); profile.frame("drawing");
render.use_shader(spritessboshader); render.use_shader(spritessboshader);
for (var layer of buckets) { var buckets = component.sprite_buckets();
for (var img of Object.values(layer[1])) { for (var l in buckets) {
var sparray = Object.values(img); var layer = buckets[l];
for (var img in layer) {
var sparray = layer[img];
if (sparray.length === 0) continue; if (sparray.length === 0) continue;
var ss = sparray[0]; var ss = sparray[0];
render.use_mat(ss); render.use_mat(ss);
@ -1073,7 +1025,7 @@ prosperon.render = function () {
render.flush_text(); render.flush_text();
render.set_camera(prosperon.camera); render.set_camera(prosperon.camera);
if (render.draw_gizmos && prosperon.gizmos) prosperon.gizmos(); //if (render.draw_gizmos && prosperon.gizmos) prosperon.gizmos();
render.flush_text(); render.flush_text();
render.end_pass(); render.end_pass();
@ -1183,7 +1135,6 @@ prosperon.process = function process() {
profile.endframe(); profile.endframe();
profile.capture_data(); profile.capture_data();
}; };
return { render }; return { render };

View file

@ -69,6 +69,7 @@ audio.cry = function (file, bus = audio.bus.sfx) {
// This function is called when every audio source is finished // This function is called when every audio source is finished
var killer = Register.appupdate.register(function () { var killer = Register.appupdate.register(function () {
return;
for (var src of sources) { for (var src of sources) {
if (!src.loop && (src.frame < src.lastframe || src.frame === src.frames())) { if (!src.loop && (src.frame < src.lastframe || src.frame === src.frames())) {
src.unplug(); src.unplug();