I guess I never got it fully working…
For some reason it does not load my textures in correctly, which I need to load from a blob url.
This is my code to load a texture asset type:
const loadTexture = (
file,
fileName,
data = undefined,
id = undefined
) => {
const app = pc.app;
return new Promise((resolve, reject) => {
//create asset
const asset = new pc.Asset(
fileName,
"texture",
{
url: "",
},
data
);
if (id !== undefined) asset.id = id;
var tex = new pc.Texture(app.graphicsDevice, {
mipmaps: false,
flipY: true,
});
tex.minFilter = pc.FILTER_LINEAR;
tex.magFilter = pc.FILTER_LINEAR;
tex.addressU = pc.ADDRESS_CLAMP_TO_EDGE;
tex.addressV = pc.ADDRESS_CLAMP_TO_EDGE;
var img = document.createElement("img");
img.crossOrigin = "anonymous";
img.onload = function () {
tex.setSource(img);
asset.resource = tex;
asset.fire("load", asset);
asset.loaded = true;
app.assets.add(asset);
};
img.onerror = (e) => {
console.error(e);
reject(e);
throw new Error(e);
};
const blob = bytesToB64Blob(new Uint8Array(file));
const url = window.URL.createObjectURL(blob);
img.src = url;
// const a = document.createElement("a");
// a.href = url;
// a.target = "_blank";
// a.click();
asset.ready((asset) => {
resolve(asset);
URL.revokeObjectURL(url);
});
});
};
Now, I can see a blob url in the network tab and I can call app.assets.get(id)
with the id listed in the material’s json data, but in the app the model is still without texture, and the diffuseMap is null on the material.
Am I doing something wrong here?
This is my complete build-loading script (doing engine-only, with NPM)
for (const key in buildData.assets) {
const element = buildData.assets[key];
if (element.file) {
request.file = element.file.url;
let responseType = "arraybuffer";
if (element.file.filename.split(".")[1] === "json")
responseType = "text";
const file = await axios.post(..., request, {
responseType: responseType,
}); // this returns arraybuffer of file data
if (element.type === "texture") {
console.log(element)
const asset = await loadTexture(
file.data,
element.name,
element.data,
parseInt(element.id, 10)
);
// pc.app.assets.load(asset);
console.log(asset);
} else {
// Turn those assets in a blob reference
const blob = new Blob([JSON.stringify(file.data)]);
const url = URL.createObjectURL(blob);
const assetPromise = new Promise((resolve) => {
///TODO: reject?
const file = {
url: url,
filename: element.name,
};
const newAsset = new pc.Asset(element.name, element.type, file);
newAsset.data = element.data;
newAsset.id = parseInt(element.id, 10);
// tags
newAsset.tags.add(element.tags);
// i18n
if (element.i18n) {
for (let locale in element.i18n) {
newAsset.addLocalizedAssetId(locale, element.i18n[locale]);
}
}
newAsset.once("load", function (modelAsset) {
resolve(modelAsset);
URL.revokeObjectURL(url);
});
pc.app.assets.add(newAsset);
pc.app.assets.load(newAsset);
});
const asset = await assetPromise;
console.log(asset);
}
} else {
// if not, we're a material or something so PC can handle it.
const asset = new pc.Asset(
element.name,
element.type,
element.file,
element.data
);
asset.id = parseInt(element.id, 10);
// asset.preload = element.preload ? element.preload : false;
// tags
asset.tags.add(element.tags);
// i18n
if (element.i18n) {
for (let locale in element.i18n) {
asset.addLocalizedAssetId(locale, element.i18n[locale]);
}
}
pc.app.assets.add(asset);
console.log(asset.name);
}
}