mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2026-04-06 19:06:21 +00:00
async shape resource loading
This commit is contained in:
parent
f79a633322
commit
92d59ec1b6
9 changed files with 197 additions and 82 deletions
|
|
@ -56,8 +56,8 @@ class Main extends hxd.App {
|
|||
});
|
||||
#end
|
||||
|
||||
Settings.init();
|
||||
ResourceLoader.init(s2d, () -> {
|
||||
Settings.init();
|
||||
AudioManager.init();
|
||||
AudioManager.playShell();
|
||||
marbleGame = new MarbleGame(s2d, s3d);
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ import src.Marble;
|
|||
import src.Resource;
|
||||
import src.ProfilerUI;
|
||||
import src.ResourceLoaderWorker;
|
||||
import haxe.io.Path;
|
||||
|
||||
class MarbleWorld extends Scheduler {
|
||||
public var collisionWorld:CollisionWorld;
|
||||
|
|
@ -234,16 +235,16 @@ class MarbleWorld extends Scheduler {
|
|||
|
||||
public function postInit() {
|
||||
// Add the sky at the last so that cubemap reflections work
|
||||
this.scene.addChild(this.sky);
|
||||
|
||||
this._ready = true;
|
||||
this.playGui.init(this.scene2d);
|
||||
var musicFileName = 'data/sound/music/' + this.mission.missionInfo.music;
|
||||
AudioManager.playMusic(ResourceLoader.getResource(musicFileName, ResourceLoader.getAudio, this.soundResources), this.mission.missionInfo.music);
|
||||
MarbleGame.canvas.clearContent();
|
||||
this.endPad.generateCollider();
|
||||
this.playGui.formatGemCounter(this.gemCount, this.totalGems);
|
||||
start();
|
||||
this.playGui.init(this.scene2d, () -> {
|
||||
this.scene.addChild(this.sky);
|
||||
this._ready = true;
|
||||
var musicFileName = 'data/sound/music/' + this.mission.missionInfo.music;
|
||||
AudioManager.playMusic(ResourceLoader.getResource(musicFileName, ResourceLoader.getAudio, this.soundResources), this.mission.missionInfo.music);
|
||||
MarbleGame.canvas.clearContent();
|
||||
this.endPad.generateCollider();
|
||||
this.playGui.formatGemCounter(this.gemCount, this.totalGems);
|
||||
start();
|
||||
});
|
||||
}
|
||||
|
||||
public function initScene(onFinish:Void->Void) {
|
||||
|
|
@ -331,8 +332,14 @@ class MarbleWorld extends Scheduler {
|
|||
"sound/set.wav",
|
||||
"sound/go.wav",
|
||||
"sound/alarm.wav",
|
||||
"sound/alarm_timeout.wav"
|
||||
"sound/alarm_timeout.wav",
|
||||
"shapes/images/glow_bounce.dts",
|
||||
"shapes/images/glow_bounce.png",
|
||||
"shapes/images/helicopter.dts",
|
||||
"shapes/images/helicopter.jpg"
|
||||
];
|
||||
marblefiles.push(StringTools.replace(Settings.optionsSettings.marbleModel, "data/", ""));
|
||||
marblefiles.push("shapes/balls/" + Settings.optionsSettings.marbleSkin + ".marble.png");
|
||||
for (file in marblefiles) {
|
||||
worker.loadFile(file);
|
||||
}
|
||||
|
|
@ -917,25 +924,89 @@ class MarbleWorld extends Scheduler {
|
|||
}
|
||||
|
||||
public function addDtsObject(obj:DtsObject, onFinish:Void->Void) {
|
||||
obj.idInLevel = this.dtsObjects.length; // Set the id of the thing
|
||||
this.dtsObjects.push(obj);
|
||||
if (obj is ForceObject) {
|
||||
this.forceObjects.push(cast obj);
|
||||
}
|
||||
obj.init(cast this, () -> {
|
||||
obj.update(this.timeState);
|
||||
if (obj.useInstancing) {
|
||||
this.instanceManager.addObject(obj);
|
||||
} else
|
||||
this.scene.addChild(obj);
|
||||
for (collider in obj.colliders) {
|
||||
if (collider != null)
|
||||
this.collisionWorld.addEntity(collider);
|
||||
}
|
||||
if (obj.isBoundingBoxCollideable)
|
||||
this.collisionWorld.addEntity(obj.boundingCollider);
|
||||
function parseIfl(path:String, onFinish:Array<String>->Void) {
|
||||
ResourceLoader.load(path).entry.load(() -> {
|
||||
var text = ResourceLoader.fileSystem.get(path).getText();
|
||||
var lines = text.split('\n');
|
||||
var keyframes = [];
|
||||
for (line in lines) {
|
||||
line = StringTools.trim(line);
|
||||
if (line.substr(0, 2) == "//")
|
||||
continue;
|
||||
if (line == "")
|
||||
continue;
|
||||
|
||||
onFinish();
|
||||
var parts = line.split(' ');
|
||||
var count = parts.length > 1 ? Std.parseInt(parts[1]) : 1;
|
||||
|
||||
for (i in 0...count) {
|
||||
keyframes.push(parts[0]);
|
||||
}
|
||||
}
|
||||
|
||||
onFinish(keyframes);
|
||||
});
|
||||
}
|
||||
|
||||
ResourceLoader.load(obj.dtsPath).entry.load(() -> {
|
||||
var dtsFile = ResourceLoader.loadDts(obj.dtsPath);
|
||||
var directoryPath = haxe.io.Path.directory(obj.dtsPath);
|
||||
var texToLoad = [];
|
||||
for (i in 0...dtsFile.resource.matNames.length) {
|
||||
var matName = obj.matNameOverride.exists(dtsFile.resource.matNames[i]) ? obj.matNameOverride.get(dtsFile.resource.matNames[i]) : dtsFile.resource.matNames[i];
|
||||
var fullNames = ResourceLoader.getFullNamesOf(directoryPath + '/' + matName).filter(x -> haxe.io.Path.extension(x) != "dts");
|
||||
var fullName = fullNames.length > 0 ? fullNames[0] : null;
|
||||
if (fullName != null) {
|
||||
texToLoad.push(fullName);
|
||||
}
|
||||
}
|
||||
|
||||
var worker = new ResourceLoaderWorker(() -> {
|
||||
obj.idInLevel = this.dtsObjects.length; // Set the id of the thing
|
||||
this.dtsObjects.push(obj);
|
||||
if (obj is ForceObject) {
|
||||
this.forceObjects.push(cast obj);
|
||||
}
|
||||
obj.init(cast this, () -> {
|
||||
obj.update(this.timeState);
|
||||
if (obj.useInstancing) {
|
||||
this.instanceManager.addObject(obj);
|
||||
} else
|
||||
this.scene.addChild(obj);
|
||||
for (collider in obj.colliders) {
|
||||
if (collider != null)
|
||||
this.collisionWorld.addEntity(collider);
|
||||
}
|
||||
if (obj.isBoundingBoxCollideable)
|
||||
this.collisionWorld.addEntity(obj.boundingCollider);
|
||||
|
||||
onFinish();
|
||||
});
|
||||
});
|
||||
|
||||
for (texPath in texToLoad) {
|
||||
if (haxe.io.Path.extension(texPath) == "ifl") {
|
||||
worker.addTask(fwd -> {
|
||||
parseIfl(texPath, keyframes -> {
|
||||
var innerWorker = new ResourceLoaderWorker(() -> {
|
||||
fwd();
|
||||
});
|
||||
var loadedkf = [];
|
||||
for (kf in keyframes) {
|
||||
if (!loadedkf.contains(kf)) {
|
||||
innerWorker.loadFile(directoryPath + '/' + kf);
|
||||
loadedkf.push(kf);
|
||||
}
|
||||
}
|
||||
innerWorker.run();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
worker.loadFile(texPath);
|
||||
}
|
||||
}
|
||||
|
||||
worker.run();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1077,6 +1148,8 @@ class MarbleWorld extends Scheduler {
|
|||
}
|
||||
}
|
||||
|
||||
var postInited = false;
|
||||
|
||||
function asyncLoadResources() {
|
||||
if (this.resourceLoadFuncs.length != 0) {
|
||||
if (lock)
|
||||
|
|
@ -1101,8 +1174,10 @@ class MarbleWorld extends Scheduler {
|
|||
} else {
|
||||
if (this._resourcesLoaded < _loadingLength)
|
||||
return;
|
||||
if (!_ready)
|
||||
if (!_ready && !postInited) {
|
||||
postInited = true;
|
||||
postInit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import hxd.res.Loader;
|
|||
import src.Resource;
|
||||
import src.ResourceLoaderWorker;
|
||||
import fs.TorqueFileSystem;
|
||||
import src.Settings;
|
||||
|
||||
class ResourceLoader {
|
||||
#if (hl && !android)
|
||||
|
|
@ -191,33 +192,36 @@ class ResourceLoader {
|
|||
}
|
||||
|
||||
static function preloadShapes(onFinish:Void->Void) {
|
||||
var toloadfiles = [];
|
||||
var toloaddirs = [];
|
||||
var filestats = fileSystem.dir("shapes");
|
||||
for (file in filestats) {
|
||||
if (file.isDirectory) {
|
||||
toloaddirs.push(file);
|
||||
} else {
|
||||
toloadfiles.push(file);
|
||||
}
|
||||
}
|
||||
while (toloaddirs.length > 0) {
|
||||
var nextdir = toloaddirs.pop();
|
||||
for (file in fileSystem.dir(nextdir.path.substring(2))) {
|
||||
if (file.isDirectory) {
|
||||
toloaddirs.push(file);
|
||||
} else {
|
||||
toloadfiles.push(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
var teleportPad = fileSystem.get("interiors_mbp/teleportpad.dts");
|
||||
var teleportTexture = fileSystem.get("interiors_mbp/repairbay.jpg");
|
||||
toloadfiles.push(teleportPad); // Because its not in the shapes folder like wtf
|
||||
toloadfiles.push(teleportTexture);
|
||||
var toloadfiles = [
|
||||
StringTools.replace(Settings.optionsSettings.marbleModel, "data/", ""),
|
||||
"shapes/balls/" + Settings.optionsSettings.marbleSkin + ".marble.png"
|
||||
];
|
||||
// var toloaddirs = [];
|
||||
// var filestats = fileSystem.dir("shapes");
|
||||
// for (file in filestats) {
|
||||
// if (file.isDirectory) {
|
||||
// toloaddirs.push(file);
|
||||
// } else {
|
||||
// toloadfiles.push(file);
|
||||
// }
|
||||
// }
|
||||
// while (toloaddirs.length > 0) {
|
||||
// var nextdir = toloaddirs.pop();
|
||||
// for (file in fileSystem.dir(nextdir.path.substring(2))) {
|
||||
// if (file.isDirectory) {
|
||||
// toloaddirs.push(file);
|
||||
// } else {
|
||||
// toloadfiles.push(file);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// var teleportPad = fileSystem.get("interiors_mbp/teleportpad.dts");
|
||||
// var teleportTexture = fileSystem.get("interiors_mbp/repairbay.jpg");
|
||||
// toloadfiles.push(teleportPad); // Because its not in the shapes folder like wtf
|
||||
// toloadfiles.push(teleportTexture);
|
||||
var worker = new ResourceLoaderWorker(onFinish);
|
||||
for (file in toloadfiles) {
|
||||
worker.addTaskParallel((fwd) -> file.load(fwd));
|
||||
worker.loadFile(file);
|
||||
}
|
||||
worker.run();
|
||||
}
|
||||
|
|
@ -244,6 +248,9 @@ class ResourceLoader {
|
|||
if (!StringTools.startsWith(path, "data/"))
|
||||
path = "data/" + path;
|
||||
#end
|
||||
#if (js || android)
|
||||
path = StringTools.replace(path, "data/", "");
|
||||
#end
|
||||
return ResourceLoader.loader.load(path);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -288,11 +288,13 @@ class Settings {
|
|||
levelStatistics.set(key, value);
|
||||
}
|
||||
}
|
||||
#if js
|
||||
if (optionsSettings.marbleIndex == null) {
|
||||
optionsSettings.marbleIndex = 0;
|
||||
optionsSettings.marbleSkin = "base";
|
||||
optionsSettings.marbleModel = "data/shapes/balls/ball-superball.dts";
|
||||
}
|
||||
#end
|
||||
highscoreName = json.highscoreName;
|
||||
} else {
|
||||
save();
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import h3d.Vector;
|
|||
import src.ResourceLoader;
|
||||
import src.DtsObject;
|
||||
import src.Settings;
|
||||
import src.ResourceLoaderWorker;
|
||||
|
||||
class MarbleSelectGui extends GuiImage {
|
||||
public function new() {
|
||||
|
|
@ -94,7 +95,8 @@ class MarbleSelectGui extends GuiImage {
|
|||
}
|
||||
this.addChild(selectBtn);
|
||||
|
||||
var marbleShow = buildObjectShow(marbleData[curSelection].dts, new Vector(171, 97), new Vector(150, 150), 2.6, 0);
|
||||
var marbleShow = buildObjectShow(marbleData[curSelection].dts, new Vector(171, 97), new Vector(150, 150), 2.6, 0,
|
||||
["base.marble" => marbleData[curSelection].skin + ".marble"]);
|
||||
marbleShow.horizSizing = Center;
|
||||
marbleShow.vertSizing = Bottom;
|
||||
marbleShow.visible = true;
|
||||
|
|
@ -144,14 +146,36 @@ class MarbleSelectGui extends GuiImage {
|
|||
dtsObj.showSequences = false;
|
||||
dtsObj.useInstancing = false;
|
||||
dtsObj.matNameOverride.set("base.marble", marble.skin + ".marble");
|
||||
dtsObj.init(null, () -> {}); // The lambda is not gonna run async anyway
|
||||
for (mat in dtsObj.materials) {
|
||||
mat.mainPass.enableLights = false;
|
||||
mat.mainPass.culling = None;
|
||||
if (mat.blendMode != Alpha && mat.blendMode != Add)
|
||||
mat.mainPass.addShader(new AlphaChannel());
|
||||
}
|
||||
marbleShow.changeObject(dtsObj);
|
||||
|
||||
ResourceLoader.load(dtsObj.dtsPath).entry.load(() -> {
|
||||
var dtsFile = ResourceLoader.loadDts(dtsObj.dtsPath);
|
||||
var directoryPath = haxe.io.Path.directory(dtsObj.dtsPath);
|
||||
var texToLoad = [];
|
||||
for (i in 0...dtsFile.resource.matNames.length) {
|
||||
var matName = dtsObj.matNameOverride.exists(dtsFile.resource.matNames[i]) ? dtsObj.matNameOverride.get(dtsFile.resource.matNames[i]) : dtsFile.resource.matNames[i];
|
||||
var fullNames = ResourceLoader.getFullNamesOf(directoryPath + '/' + matName).filter(x -> haxe.io.Path.extension(x) != "dts");
|
||||
var fullName = fullNames.length > 0 ? fullNames[0] : null;
|
||||
if (fullName != null) {
|
||||
texToLoad.push(fullName);
|
||||
}
|
||||
}
|
||||
|
||||
var worker = new ResourceLoaderWorker(() -> {
|
||||
dtsObj.init(null, () -> {}); // The lambda is not gonna run async anyway
|
||||
for (mat in dtsObj.materials) {
|
||||
mat.mainPass.enableLights = false;
|
||||
mat.mainPass.culling = None;
|
||||
if (mat.blendMode != Alpha && mat.blendMode != Add)
|
||||
mat.mainPass.addShader(new AlphaChannel());
|
||||
}
|
||||
marbleShow.changeObject(dtsObj);
|
||||
});
|
||||
|
||||
for (texPath in texToLoad) {
|
||||
worker.loadFile(texPath);
|
||||
}
|
||||
worker.run();
|
||||
});
|
||||
}
|
||||
|
||||
var nextBtn = new GuiButton(loadButtonImages("data/ui/marbleSelect/next"));
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ class PlayGui {
|
|||
}
|
||||
}
|
||||
|
||||
public function init(scene2d:h2d.Scene) {
|
||||
public function init(scene2d:h2d.Scene, onFinish:Void->Void) {
|
||||
this.scene2d = scene2d;
|
||||
this._init = true;
|
||||
|
||||
|
|
@ -138,7 +138,9 @@ class PlayGui {
|
|||
|
||||
powerupBox = new GuiImage(ResourceLoader.getResource('data/ui/game/powerup.png', ResourceLoader.getImage, this.imageResources).toTile());
|
||||
initTimer();
|
||||
initGemCounter();
|
||||
initGemCounter(() -> {
|
||||
onFinish();
|
||||
});
|
||||
initCenterText();
|
||||
initPowerupBox();
|
||||
initTexts();
|
||||
|
|
@ -254,7 +256,7 @@ class PlayGui {
|
|||
}
|
||||
}
|
||||
|
||||
public function initGemCounter() {
|
||||
public function initGemCounter(onFinish:Void->Void) {
|
||||
gemCountNumbers[0].position = new Vector(30, 0);
|
||||
gemCountNumbers[0].extent = new Vector(43, 55);
|
||||
|
||||
|
|
@ -301,21 +303,24 @@ class PlayGui {
|
|||
// gemImageObject.matNameOverride.set("base.gem", "base.gem.");
|
||||
gemImageObject.ambientSpinFactor /= -2;
|
||||
// ["base.gem"] = color + ".gem";
|
||||
gemImageObject.init(null, () -> {
|
||||
for (mat in gemImageObject.materials) {
|
||||
mat.mainPass.enableLights = false;
|
||||
ResourceLoader.load("shapes/items/" + gemColor + ".gem.png").entry.load(() -> {
|
||||
gemImageObject.init(null, () -> {
|
||||
for (mat in gemImageObject.materials) {
|
||||
mat.mainPass.enableLights = false;
|
||||
|
||||
// Huge hacks
|
||||
if (mat.blendMode != Add) {
|
||||
var alphaShader = new h3d.shader.AlphaChannel();
|
||||
mat.mainPass.addShader(alphaShader);
|
||||
// Huge hacks
|
||||
if (mat.blendMode != Add) {
|
||||
var alphaShader = new h3d.shader.AlphaChannel();
|
||||
mat.mainPass.addShader(alphaShader);
|
||||
}
|
||||
}
|
||||
}
|
||||
gemImageScene.addChild(gemImageObject);
|
||||
var gemImageCenter = gemImageObject.getBounds().getCenter();
|
||||
gemImageScene.addChild(gemImageObject);
|
||||
var gemImageCenter = gemImageObject.getBounds().getCenter();
|
||||
|
||||
gemImageScene.camera.pos = new Vector(0, 3, gemImageCenter.z);
|
||||
gemImageScene.camera.target = new Vector(gemImageCenter.x, gemImageCenter.y, gemImageCenter.z);
|
||||
gemImageScene.camera.pos = new Vector(0, 3, gemImageCenter.z);
|
||||
gemImageScene.camera.target = new Vector(gemImageCenter.x, gemImageCenter.y, gemImageCenter.z);
|
||||
onFinish();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ class EndPad extends DtsObject {
|
|||
public function new() {
|
||||
super();
|
||||
this.dtsPath = "data/shapes/pads/endarea.dts";
|
||||
this.useInstancing = false;
|
||||
this.isCollideable = true;
|
||||
this.identifier = "EndPad";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,13 @@ import mis.MissionElement.MissionElementItem;
|
|||
import src.TimeState;
|
||||
import src.DtsObject;
|
||||
import src.ResourceLoaderWorker;
|
||||
import src.ResourceLoader;
|
||||
|
||||
class Gem extends DtsObject {
|
||||
public var pickedUp:Bool;
|
||||
|
||||
var gemColor:String;
|
||||
|
||||
public function new(element:MissionElementItem) {
|
||||
super();
|
||||
dtsPath = "data/shapes/items/gem.dts";
|
||||
|
|
@ -25,6 +28,7 @@ class Gem extends DtsObject {
|
|||
color = GEM_COLORS[Math.floor(Math.random() * GEM_COLORS.length)];
|
||||
this.identifier = "Gem" + color;
|
||||
this.matNameOverride.set('base.gem', color + ".gem");
|
||||
gemColor = color + ".gem";
|
||||
}
|
||||
|
||||
public override function init(level:MarbleWorld, onFinish:Void->Void) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ class StartPad extends DtsObject {
|
|||
public function new() {
|
||||
super();
|
||||
dtsPath = "data/shapes/pads/startarea.dts";
|
||||
useInstancing = false;
|
||||
isCollideable = true;
|
||||
identifier = "StartPad";
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue