I have a drop-down where the user can select different scenes (.obj with their .mtl) to load, which works great, but if the user selects a new scene while still loading a previously selected one, I gotta abort the previous loading process to start a new one or else I would be loading 2 .obj simultaneously, which is obviously not desired, and this works. I abort the xhr.currentTarget before loading the new one and it successfully loads the newly selected scene, but my problem is that now the scene that had it’s loading process aborted will not load whatsoever.
So, if I select item A from the drop-down, then while loading I select item B it begins loading item B (it could finish loading or I could interrupt it as well), and if I click back to item A the .obj won’t load, thou the .mtl does (same for item B if its loading process was aborted as well)… here’s the code:
const xhrCurrentTarget;
loadScene() {
const {
TJSsetup,
sceneMounted,
selectedScene,
isSceneLoading,
sceneLoadingError
} = this.state;
const { userData } = this.props;
const userId = userData._id;
const { THREE } = window;
console.log('isSceneLoading: ', isSceneLoading);
if (isSceneLoading) {
xhrCurrentTarget.abort();
// this did nothing
xhrCurrentTarget = null;
}
// Check if there was a scene loaded
console.log('TJSsetup: ', TJSsetup);
if (TJSsetup) {
this.clear({ loadScene: true });
return;
}
this.TJSquickSetup();
this.start();
this.enableOrbitControls({ lookAtX: 0, lookAtY: 0, lookAtZ: 0 });
// GET .OBJ AND .MTL URL
const dns = "http://myDNS";
let renderPath = `${dns}/${userId}/${selectedScene._id}/`;
let objUrl = `${selectedScene.name}.obj`;
let mtlUrl = `${selectedScene.name}.mtl`;
const mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath(renderPath);
mtlLoader.setCrossOrigin(true);
// MTL LOADER FUNCTIONS
const MTLonLoad = materials => {
materials.preload();
const objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath(renderPath);
console.log('objUrl: ', objUrl);
console.log('objLoader: ', objLoader);
// here's where everything 'stops' if the .obj was previously aborted
// so below here it doesn't run, I know it because I can't even console.log
// the loading progress of the .obj, which means the .mtl did load
objLoader.load(
objUrl,
OBJonLoad.bind(this),
OBJonProgress.bind(this),
OBJonError.bind(this)
);
};
const MTLonProgress = xhr => {
this.setState({ isSceneLoading: true, sceneLoadingError: "" });
};
const MTLonError = sceneLoadingError => {
const loadingProgress = null;
sceneLoadingError = `
Email: ${userData.email.value} --
sid: ${selectedScene._id} --
On: .mtl --
Status: ${
sceneLoadingError.currentTarget.status
} --
Mssg: ${sceneLoadingError.currentTarget.statusText}`;
this.setState({
loadingProgress,
sceneLoadingError,
isSceneLoading: false,
displayMode: "raw"
});
};
// OBJ LOADER FUNCTIONS
const OBJonProgress = xhr => {
console.log('xhr: ', xhr);
const loadingProgress = Math.round((xhr.loaded / xhr.total) * 100);
xhrCurrentTarget = xhr.currentTarget;
this.setState({
loadingProgress,
sceneLoadingError: ""
});
};
const OBJonError = sceneLoadingError => {
const loadingProgress = null;
sceneLoadingError = `
Email: ${userData.email.value} --
sid: ${selectedScene._id} --
On: .obj --
Status: ${
sceneLoadingError.currentTarget.status
} --
Mssg: ${sceneLoadingError.currentTarget.statusText}`;
this.setState({
loadingProgress,
sceneLoadingError,
isSceneLoading: false,
displayMode: "raw"
});
};
const OBJonLoad = object => {
// Disable loading feedback
const loadingProgress = 0;
object.name = "userLoadedScene";
object.position.set(0, 0, 0);
var material = new THREE.MeshBasicMaterial({ color: 0xffff00 });
object.traverse(function(child) {
if (
child instanceof THREE.Mesh
) {
child.material = material;
}
});
this.scene.add(object);
if (!sceneMounted) {
this.mount.appendChild(this.renderer.domElement);
this.setEventListeners();
this.setPostProcessing();
}
this.setState({
loadingProgress,
sceneLoadingError: "",
sceneMounted: true,
isSceneLoading: false
});
};
mtlLoader.load(
mtlUrl,
MTLonLoad.bind(this),
MTLonProgress.bind(this),
MTLonError.bind(this)
);
}
clear({ loadScene }) {
const { eventListenersSet } = this.state;
this.stop();
// Clear object name from form
var selectedObject = this.scene.getObjectByName("userLoadedScene");
if (eventListenersSet) {
window.removeEventListener("resize", this.onWindowResize, false);
window.removeEventListener("mousemove", this.onTouchMove);
window.removeEventListener("touchmove", this.onTouchMove);
window.removeEventListener("click", this.onObjectClick);
}
if (this.mount && this.renderer) {
if (this.renderer.domElement.parentNode === this.mount) {
this.mount.removeChild(this.renderer.domElement);
}
}
this.controls && this.controls.dispose();
this.scene && this.scene.remove(selectedObject);
this.TJSreset();
this.setState(
{
clickedPlacement: {},
sceneMounted: false,
eventListenersSet: false,
postProcessingSet: false,
sceneLoadingError: "",
isSceneLoading: false
},
() => {
loadScene && this.loadScene();
}
);
}
Note: don’t mind much about the TSJsetup, the problem is that for some reason on the MTLonLoad
function objLoader.load()
won’t work if the object’s been aborted before.
here’s the network tab, see how the scecond time the object A is beign loaded, the .obj is not even fetched.