playcanvas
Version:
PlayCanvas WebGL game engine
127 lines (124 loc) • 3.75 kB
JavaScript
import { path } from '../../core/path.js';
import { Http, http } from '../../platform/net/http.js';
import { getDefaultMaterial } from '../../scene/materials/default-material.js';
import { GlbModelParser } from '../parsers/glb-model.js';
import { JsonModelParser } from '../parsers/json-model.js';
import { ResourceHandler } from './handler.js';
class ModelHandler extends ResourceHandler {
load(url, callback, asset) {
if (typeof url === 'string') {
url = {
load: url,
original: url
};
}
var options = {
retry: this.maxRetries > 0,
maxRetries: this.maxRetries
};
if (url.load.startsWith('blob:') || url.load.startsWith('data:')) {
if (path.getExtension(url.original).toLowerCase() === '.glb') {
options.responseType = Http.ResponseType.ARRAY_BUFFER;
} else {
options.responseType = Http.ResponseType.JSON;
}
}
http.get(url.load, options, (err, response)=>{
if (!callback) {
return;
}
if (!err) {
for(var i = 0; i < this._parsers.length; i++){
var p = this._parsers[i];
if (p.decider(url.original, response)) {
p.parser.parse(response, (err, parseResult)=>{
if (err) {
callback(err);
} else {
callback(null, parseResult);
}
}, asset);
return;
}
}
callback('No parsers found');
} else {
callback("Error loading model: " + url.original + " [" + err + "]");
}
});
}
open(url, data) {
return data;
}
patch(asset, assets) {
if (!asset.resource) {
return;
}
var data = asset.data;
var self = this;
asset.resource.meshInstances.forEach((meshInstance, i)=>{
if (data.mapping) {
var handleMaterial = function handleMaterial1(asset) {
if (asset.resource) {
meshInstance.material = asset.resource;
} else {
asset.once('load', handleMaterial);
assets.load(asset);
}
asset.once('remove', (asset)=>{
if (meshInstance.material === asset.resource) {
meshInstance.material = self.defaultMaterial;
}
});
};
if (!data.mapping[i]) {
meshInstance.material = self.defaultMaterial;
return;
}
var id = data.mapping[i].material;
var url = data.mapping[i].path;
var material;
if (id !== undefined) {
if (!id) {
meshInstance.material = self.defaultMaterial;
} else {
material = assets.get(id);
if (material) {
handleMaterial(material);
} else {
assets.once("add:" + id, handleMaterial);
}
}
} else if (url) {
var path = asset.getAbsoluteUrl(data.mapping[i].path);
material = assets.getByUrl(path);
if (material) {
handleMaterial(material);
} else {
assets.once("add:url:" + path, handleMaterial);
}
}
}
});
}
addParser(parser, decider) {
this._parsers.push({
parser: parser,
decider: decider
});
}
constructor(app){
super(app, 'model');
this._parsers = [];
this.device = app.graphicsDevice;
this.assets = app.assets;
this.defaultMaterial = getDefaultMaterial(this.device);
this.addParser(new JsonModelParser(this), (url, data)=>{
return path.getExtension(url) === '.json';
});
this.addParser(new GlbModelParser(this), (url, data)=>{
return path.getExtension(url) === '.glb';
});
}
}
export { ModelHandler };