wwobjloader2
Version:
[](https://github.com/kaisalmen/WWOBJLoader/blob/dev/LICENSE) [](https://github.com/kaisalm
197 lines • 6.44 kB
JavaScript
import { FileLoader } from 'three';
import { applyProperties } from 'wtd-core';
class AssetPipelineLoader {
name;
assetPipeline;
baseObject3d;
onComplete = null;
constructor(name, assetPipeline) {
this.name = name;
this.assetPipeline = assetPipeline;
}
getName() {
return this.name;
}
setBaseObject3d(baseObject3d) {
this.baseObject3d = baseObject3d;
return this;
}
setOnComplete(onComplete) {
this.onComplete = onComplete;
}
run() {
this.assetPipeline.initPipeline(this.name, this.onComplete);
if (this.baseObject3d) {
this.assetPipeline.runPipeline(this.baseObject3d);
}
else {
throw new Error('baseObject3d was not properly specified.');
}
return this;
}
}
/**
* The AssetPipeline defines a set of {@link AssetTask} that need to be executed one after the other and return a {@link Object3D}.
* @constructor
*/
class AssetPipeline {
name = null;
onComplete = null;
assetTasks = new Map();
addAssetTask(assetTask) {
this.assetTasks.set(assetTask.getName(), assetTask);
return this;
}
/**
* Init all {@link AssetTask}
*
* @param {string} name Name of the pipeline
* @param {CallbackCompleteType} onComplete set callback function
* @return {AssetPipeline}
*/
initPipeline(name, onComplete) {
this.name = name;
this.onComplete = onComplete;
let assetTaskBefore = null;
for (const assetTask of this.assetTasks.values()) {
if (assetTaskBefore !== null) {
assetTask.setTaskBefore(assetTaskBefore);
assetTaskBefore.setTaskAfter(assetTask);
}
assetTaskBefore = assetTask;
assetTask.init();
}
return this;
}
/**
* Run the pipeline: First load resources and then execute the parsing functions
* @param {Object3D} baseObject3d
* @return {AssetPipeline}
*/
async runPipeline(baseObject3d) {
const onComplete = this.onComplete ? this.onComplete : (x) => {
console.log('Done loading: ' + x);
};
const loadResources = async (assetTasks) => {
const loadPromises = [];
for (const assetTask of assetTasks.values()) {
if (assetTask.getResourceDescriptor()) {
const promise = assetTask.loadResource();
loadPromises.push(promise);
}
}
console.log('Waiting for completion of loading of all assets!');
return await Promise.all(loadPromises);
};
const processAssets = (loadResults) => {
console.log('Count of loaded resources: ' + loadResults.length);
let assetTask;
for (assetTask of this.assetTasks.values()) {
// TODO: process must be async, so we can process worker based workloads
assetTask.process();
}
// last assetTask
if (assetTask && assetTask.getProcessResult()) {
baseObject3d.add(assetTask.getProcessResult());
}
return baseObject3d;
};
try {
const resourceDescriptor = await loadResources(this.assetTasks);
const object3d = processAssets(resourceDescriptor);
onComplete(this.name, object3d);
}
catch (e) {
console.error(e);
}
}
}
class AssetTask {
name;
resourceDescriptor;
assetLoader = {
loader: {
instance: undefined,
config: {}
},
linker: undefined
};
relations = {
before: undefined,
after: undefined,
};
processResult = undefined;
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
setResourceDescriptor(resourceDescriptor) {
this.resourceDescriptor = resourceDescriptor;
return this;
}
getResourceDescriptor() {
return this.resourceDescriptor;
}
setTaskBefore(assetTask) {
this.relations.before = assetTask;
}
setTaskAfter(assetTask) {
this.relations.after = assetTask;
}
getProcessResult() {
return this.processResult;
}
setLinker(linker) {
this.assetLoader.linker = linker;
}
setLoader(loader, loaderConfig) {
const parser = loader;
if (typeof parser.parse === 'function') {
this.assetLoader.loader.instance = parser;
}
else {
throw new Error('Provide loader has now parse method! Aborting...');
}
this.assetLoader.loader.config = loaderConfig ?? {};
return this;
}
init() {
console.log(this.name + ': Performing init');
applyProperties(this.assetLoader.loader.instance, this.assetLoader.loader.config, false);
}
async loadResource() {
const fileLoader = new FileLoader();
fileLoader.setResponseType('arraybuffer');
if (this.resourceDescriptor) {
const buffer = await fileLoader.loadAsync(this.resourceDescriptor.getUrl().href);
this.resourceDescriptor.setBuffer(buffer);
return Promise.resolve(this.resourceDescriptor);
}
else {
return Promise.reject();
}
}
process() {
if (this.assetLoader.linker) {
const resultBefore = this.relations.before?.processResult;
const nextTask = this.relations.after?.assetLoader.loader.instance;
if (resultBefore) {
this.processResult = this.assetLoader.linker.link(resultBefore, nextTask);
}
}
else if (this.assetLoader.loader.instance) {
if (this.resourceDescriptor?.isNeedStringOutput()) {
const dataAsString = this.resourceDescriptor.getBufferAsString();
this.processResult = this.assetLoader.loader.instance.parse(dataAsString);
}
else {
const dataAsBuffer = this.resourceDescriptor?.getBuffer();
this.processResult = this.assetLoader.loader.instance.parse(dataAsBuffer);
}
}
}
}
export { AssetPipelineLoader, AssetPipeline, AssetTask };
//# sourceMappingURL=AssetPipelineLoader.js.map