Hi everybody,
I’m trying to access the morphInstances of a model to set its weight values at runtime.
The entity with the glbLoadMorph script has also a model component.
The line (self.entity.model.model.morphInstances[0].setWeight(0, 1)) inside the utils function is working as expected. And the model is showing on screen.
But if I want to do the same thing later in the initialize funtion outside the util, I get the error:
TypeError: Cannot read property ‘morphInstances’ of null.
Does that mean that the model component isn’t set right in the util function? Shouldn’t the line self.entity.model.asset = asset.resource.model; set this references?
How can I access properties of the modelcomponent of a loaded glb model in script after calling the util function? To do something like this this.entity.model.model.morphInstances[0].setWeight(0, 1);
Thanks
var GlbLoadMorph = pc.createScript('glbLoadMorph');
GlbLoadMorph.attributes.add('glbAsset', { type: 'asset', assetType: 'binary'});
// initialize code called once per entity
GlbLoadMorph.prototype.initialize = function() {
var self = this;
utils.loadGlbContainerFromAsset(this.glbAsset, null, this.glbAsset.name, function (err, asset) {
self.entity.model.asset = asset.resource.model;
self.entity.model.model.morphInstances[0].setWeight(0, 1);
});
this.entity.model.model.morphInstances[0].setWeight(0, 1);
};
with the glb-utils.js from the example project:
(function(){
var utils = {};
var app = pc.Application.getApplication();
/**
* @name utils#loadGlbContainerFromAsset
* @function
* @description Load a GLB container from a binary asset that is a GLB.
* @param {pc.Asset} glbBinAsset The binary asset that is the GLB.
* @param {Object} options Optional. Extra options to do extra processing on the GLB.
* @param {String} assetName. Name of the asset.
* @param {Function} callback The callback function for loading the asset. Signature is `function(string:error, asset:containerAsset)`.
* If `error` is null, then the load is successful.
* @returns {pc.Asset} The asset that is created for the container resource.
*/
utils.loadGlbContainerFromAsset = function (glbBinAsset, options, assetName, callback) {
var blob = new Blob([glbBinAsset.resource]);
var data = URL.createObjectURL(blob);
return this.loadGlbContainerFromUrl(data, options, assetName, function(error, asset) {
callback(error, asset);
URL.revokeObjectURL(data);
});
};
/**
* @name utils#loadGlbContainerFromUrl
* @function
* @description Load a GLB container from a URL that returns a `model/gltf-binary` as a GLB.
* @param {String} url The URL for the GLB
* @param {Object} options Optional. Extra options to do extra processing on the GLB.
* @param {String} assetName. Name of the asset.
* @param {Function} callback The callback function for loading the asset. Signature is `function(string:error, asset:containerAsset)`.
* If `error` is null, then the load is successful.
* @returns {pc.Asset} The asset that is created for the container resource.
*/
utils.loadGlbContainerFromUrl = function (url, options, assetName, callback) {
var filename = assetName + '.glb';
var file = {
url: url,
filename: filename
};
var asset = new pc.Asset(filename, 'container', file, null, options);
asset.once('load', function (containerAsset) {
if (callback) {
// As we play animations by name, if we have only one animation, keep it the same name as
// the original container otherwise, postfix it with a number
var animations = containerAsset.resource.animations;
if (animations.length == 1) {
animations[0].name = assetName;
} else if (animations.length > 1) {
for (var i = 0; i < animations.length; ++i) {
animations[i].name = assetName + ' ' + i.toString();
}
}
callback(null, containerAsset);
}
});
app.assets.add(asset);
app.assets.load(asset);
return asset;
};
window.utils = utils;
})();