I’ve found a solution that works for my project. I’ve updated the example project with the workaround.
Basically, I check the loaded material to see if the diffuseMap is named placeholder. If so, I set a flag and keep checking on the update for it to change. Then I clone after that.
Here is the code…
var AssignClonedMaterial = pc.createScript('assignClonedMaterial');
AssignClonedMaterial.attributes.add('mat', {type: 'asset', assetType: 'material', title: 'Material'});
AssignClonedMaterial.attributes.add('cloneIt', {type: 'boolean', default: false, title: 'Clone it?'});
AssignClonedMaterial.attributes.add('useWorkAround', {type: 'boolean', default: false, title: 'Use work around?'});
// initialize code called once per entity
AssignClonedMaterial.prototype.initialize = function() {
this.shape = this.entity.model.meshInstances[0];
var self = this;
this.checkIsMatLoaded = false; // set to true in workaround below
this.mat.ready(function (asset) {
// asset loaded
if(self.cloneIt){
// use clone of material.
if(self.useWorkAround){
self.checkIsMatLoaded = true; // we'll clone later when the diffuseMap is no longer a placeholder.
}else{
// clone now. This fails because non-preloaded textures are still placeholders at this point
self.shape.material = asset.resource.clone();
}
}else{
// use freshly loaded material.
self.shape.material = asset.resource;
// note: the material is loaded but the textures are still being loaded.
// OK for materials used directly, they will update automatically when fully loaded.
}
});
this.app.assets.load(this.mat);
};
// update code called every frame
AssignClonedMaterial.prototype.update = function(dt) {
if(this.checkIsMatLoaded){ // if true, we need to check to see if the texture has loaded.
var map = this.mat.resource.diffuseMap;
console.log("diffuseMap = " + map.name);
if(map.name != "placeholder"){
// no longer a placeholder.
this.checkIsMatLoaded = false;
this.shape.material = this.mat.resource.clone(); // OK to clone now, diffuseMap texture is loaded.*
// * other textures should be checked but if you know that only a diffuseMap is being used then we are OK.
}
}
};