LNXSDK/leenkx/Sources/iron/data/WorldData.hx
2025-01-22 16:18:30 +01:00

129 lines
3.0 KiB
Haxe

package iron.data;
import haxe.Json;
import kha.arrays.Float32Array;
import iron.math.Vec4;
import iron.data.SceneFormat;
import iron.system.LnxPack;
using StringTools;
class WorldData {
public var name: String;
public var raw: TWorldData;
public var envmap: kha.Image;
public var probe: Probe;
static var emptyIrr: Float32Array = null;
public function new(raw: TWorldData, done: WorldData->Void) {
this.raw = raw;
this.name = raw.name;
// Parse probes
if (raw.probe != null) {
new Probe(raw.probe, function(self: Probe) {
probe = self;
#if lnx_skip_envmap
done(this);
#else
loadEnvmap(done);
#end
});
}
else {
#if lnx_skip_envmap
done(this);
#else
loadEnvmap(done);
#end
}
}
public function loadEnvmap(done: WorldData->Void) {
if (raw.envmap != null) {
Data.getImage(raw.envmap, function(image: kha.Image) {
envmap = image;
done(this);
});
}
else done(this);
}
public static function parse(name: String, id: String, done: WorldData->Void) {
Data.getSceneRaw(name, function(format: TSceneFormat) {
var raw: TWorldData = Data.getWorldRawByName(format.world_datas, id);
if (raw == null) {
trace('World data "$id" not found!');
done(null);
}
new WorldData(raw, done);
});
}
public static function getEmptyIrradiance(): Float32Array {
if (emptyIrr == null) {
emptyIrr = new Float32Array(28);
for (i in 0...emptyIrr.length) emptyIrr.set(i, 0.0);
}
return emptyIrr;
}
}
class Probe {
public var raw: TProbeData;
public var radiance: kha.Image;
public var radianceMipmaps: Array<kha.Image> = [];
public var irradiance: Float32Array;
public function new(raw: TProbeData, done: Probe->Void) {
this.raw = raw;
setIrradiance(function(irr: Float32Array) {
irradiance = irr;
if (raw.radiance != null) {
Data.getImage(raw.radiance, function(rad: kha.Image) {
radiance = rad;
while (radianceMipmaps.length < raw.radiance_mipmaps) radianceMipmaps.push(null);
var dot = raw.radiance.lastIndexOf(".");
var ext = raw.radiance.substring(dot);
var base = raw.radiance.substring(0, dot);
var mipsLoaded = 0;
for (i in 0...raw.radiance_mipmaps) {
Data.getImage(base + "_" + i + ext, function(mipimg: kha.Image) {
radianceMipmaps[i] = mipimg;
mipsLoaded++;
if (mipsLoaded == raw.radiance_mipmaps) {
radiance.setMipmaps(radianceMipmaps);
done(this);
}
}, true); // Readable
}
});
}
else done(this);
});
}
function setIrradiance(done: Float32Array->Void) {
// Parse probe data
if (raw.irradiance == null) {
done(WorldData.getEmptyIrradiance());
}
else {
var ext = raw.irradiance.endsWith(".json") ? "" : ".lnx";
Data.getBlob(raw.irradiance + ext, function(b: kha.Blob) {
var irradianceParsed: TSceneFormat = ext == "" ?
Json.parse(b.toString()) :
LnxPack.decode(b.toBytes());
var irr = new Float32Array(28); // Align to mult of 4 - 27->28
for (i in 0...27) irr[i] = irradianceParsed.irradiance[i];
done(irr);
});
}
}
}