The code here works fine:
However, my application is a configurator and requires that this display be updated each time the user has adjusted parameters. The OBJ format maps perfectly to my problem domain, so my configurator is designed to write OBJ format strings (basically a vertex list and a face list).
My challenge is how to write this code so I can pass in the OBJ data as a parameter and update the display accordingly.
For example, the following playground does not even run:
I have it working pretty much accurately in my development environment using BABYLON.SceneLoader.Append with the code below. However, the code below does not seem to execute the scene.meshes[0] code, probably for two reasons: a) it’s a promise, and the code is not written correctly for that and b) now there are five meshes, not one, so using [0] does not point properly.
I really don’t care about anything pre-existing in the scene. I have no idea why there are now 5 meshes in there according to the Browser inspector. I simply want to wipe it all out and put in a completely new one based on my new OBJ string.
How do I do that?
//**********************************
//This is starting at the top of the script load in the HTML page.
const canvas = document.getElementById("renderCanvas"); // Get the canvas element
const engine = new BABYLON.Engine(canvas, true); // Generate the BABYLON 3D engine
var scene;
const createScene = async function (objData) {
// This creates a basic Babylon Scene object (non-mesh)
scene = new BABYLON.Scene(engine);
alert("Inside CreateScene");
// This creates a light, aiming 0,-1,0 - to the sky (non-mesh)
var light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0), scene);
// Default intensity is 1. Let's dim the light a small amount
light.intensity = 2;
const mtlContent = `
newmtl emerald
Ka 0.7000 0.0000 0.0000
Kd 0.6000 0.5800 0.3900
Ks 0.8000 0.800 0.800
illum 1
Ns 740.0000
Tr 0.3000
`;
const mtlBase64 = "data:;base64," + btoa(mtlContent);
objData = objData.replace("mtllib emerald.mtl", "mtllib " + mtlBase64);
alert("About to append");
//rootURL,sceneFilename,scene,onSuccess
BABYLON.SceneLoader.Append("", "data:;base64," + btoa(objData), scene, scene => {
alert("Inside Append with " + scene.meshes.length);
//THIS IS THE CODE THAT WILL NOT EXECUTE PROPERLY
scene.meshes[0].createNormals();
scene.meshes[0].convertToFlatShadedMesh();
scene.meshes[0].material.backFaceCulling = false;
scene.meshes[0].enableEdgesRendering();
scene.meshes[0].edgesWidth = 200.0;
scene.meshes[0].edgesColor = new BABYLON.Color4(1, 1, 0, 1);
scene.meshes[0].edgesRenderer.lineShader.zOffset = -1;
// THIS IS EVIDENTLY STILL A PROMISE AND NOW THERE ARE 5 MESHES ANYWAY
}, undefined, undefined, ".obj");
//onProgress, onError, pluginExtension
alert("after append");
scene.createDefaultCamera(true, true, true);
var mainCamera = scene.activeCamera;
mainCamera.setPosition(new BABYLON.Vector3(50, 50, 300));
//const pp = new BABYLON.ScreenSpaceCurvaturePostProcess("scpp", scene, 1, mainCamera);
return scene;
};
//*****************
// This function is called by the application based on user actions.
async function Show_Updates() {
alert(“Entering createScene”);
//scene.dispose(); //This does nothing so I commented it out.
//var objData = await Generate_Ridge_OBJ_File(); //The application generates the OBJ string here.
//but since I have not provided the rest of the application, this string could be passed instead:
let objData = `####
mtllib emerald.mtl
usemtl emerald
v 50 50 50
v 0 0 25
v 50 0 0
v 100 0 25
v 100 50 0
v 100 100 25
v 50 100 0
v 0 100 25
v 0 50 0
f 1 3 2
f 1 4 3
f 1 5 4
f 1 6 5
f 1 7 6
f 1 8 7
f 1 9 8
f 1 2 9
End of File
`;
scene = await createScene(objData); //Call the createScene function
alert("afterScene");
// Register a render loop to repeatedly render the scene
engine.runRenderLoop(function () {
scene.render();
});
// Watch for browser/canvas resize events
window.addEventListener("resize", function () {
engine.resize();
});
}