Dad72 Posted January 25, 2018 Share Posted January 25, 2018 Hello, I wish I could clone a complete scene to reuse it in another canvas with a new engine, but I can not do it. Has anyone ever done this kind of thing? how can this be done? On my project I use several camera, don a serves the editor. I wish I could use a glimpse of the scene in another canvas in a dialog using another camera view. So I want to make a copy or clone of this scene temporarily. For the moment I try this without success: let canvasBuild = document.getElementById("buildRenderer"); let engineForBuild = new BABYLON.Engine(canvasBuild, true); let newScene = global.scene; //Copy of the scene newScene.activeCameras[0].dispose();// I do not want to use this camera of the newScene // But : This removes the camera on my main scene and not on the new copy scene. engineForBuild.runRenderLoop(function() { newScene.render(); }); Thanks for your help. Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted January 25, 2018 Share Posted January 25, 2018 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign ? maybe Quote Link to comment Share on other sites More sharing options...
Dad72 Posted January 25, 2018 Author Share Posted January 25, 2018 I try but nothing is displayed in the new canvas. The runRenderLoop does not draw the scene. I also try to serialize the scene, but it sends me an error on scene.render(). let canvasBuild = document.getElementById("buildRenderer"); let engineForBuild = new BABYLON.Engine(canvasBuild, true); var scene = new BABYLON.Scene(engineForBuild); scene = Object.assign(scene, global.scenes[0]); //scene = BABYLON.SceneSerializer.Serialize(global.scenes[0]); engineForBuild.runRenderLoop(function() { scene.render(); }); Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted January 25, 2018 Share Posted January 25, 2018 I tired this: function completeAssign(target, ...sources) { sources.forEach(source => { let descriptors = Object.keys(source).reduce((descriptors, key) => { descriptors[key] = Object.getOwnPropertyDescriptor(source, key); return descriptors; }, {}); // by default, Object.assign copies enumerable Symbols too Object.getOwnPropertySymbols(source).forEach(sym => { let descriptor = Object.getOwnPropertyDescriptor(source, sym); if (descriptor.enumerable) { descriptors[sym] = descriptor; } }); Object.defineProperties(target, descriptors); }); return target; } var sceneClone = completeAssign({}, scene); and it will console log out the correct info, but says sceneClone.render is not a function... odd. Hmm I might have to look into this more. cool problem. Dad72 1 Quote Link to comment Share on other sites More sharing options...
Dad72 Posted January 25, 2018 Author Share Posted January 25, 2018 4 minutes ago, Pryme8 said: Hmm I might have to look into this more. cool problem. thank you for your help Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted January 25, 2018 Share Posted January 25, 2018 I started messing around with this: BABYLON.Scene.prototype.clone = function(){ var s = new BABYLON.Scene(engine); var props = Object.keys(this); for(var i=0; i < props.length; i++){ if(Object.prototype.toString.call(this[props[i]]) == '[object Array]'){ for(var j=0; j<this[props[i]]; j++){ if(this[props[i]][j].clone){ s[props[i]].push(this[props[i]][j].clone()); }else{ s[props[i]].push(this[props[i]][j]); } } } } return s; } which is not even close to perfect, but made me realize we need a method for cloning objects between scene context. so like a clone(name, scene); Cause right now its just cloning it in the old scenes context. Another idea is how about we serialize the scene on a secondary variable then parse that back into a scene. http://www.html5gamedevs.com/topic/6039-exporting-a-babylon-scene-to-a-file/ Quote Link to comment Share on other sites More sharing options...
JCPalmer Posted January 25, 2018 Share Posted January 25, 2018 As long as the scene is in the same engine, could not all the reference arrays in scene (e.g. meshes, lights, cameras, materials, particles) be copied to the new scene, but still contain the same references? Types which refer to a scene within them, Nodes, would need to have the value changed. I am not hopeful, since it will probably fall down on materials. @Pryme8, I know you were trying to do this. Mine is more explicit. Yours also does not take into account the reference of scene in nodes. Pryme8 1 Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted January 25, 2018 Share Posted January 25, 2018 Yeah, I am only half-a**ed lookin at this intermittently while at work. Have not had a chance to really bite into it. @JCPalmer I was looking at serializing then loading the scene again with SceneLoader into a new object. Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted January 25, 2018 Share Posted January 25, 2018 here is a horrible solution... I bet this will never work with a large scene... BABYLON.Scene.prototype.clone = function(){ var scene; var s = BABYLON.SceneSerializer.Serialize(this); var _s = JSON.stringify(s); var loader = BABYLON.SceneLoader.Load('', 'data:'+_s, this.engine, (e)=>{ scene = e; }); function watch(){ if(scene){return scene}else{ setTimeout(function(){watch();},0); } } return watch(); } document.addEventListener("DOMContentLoaded", () => { var canvas = document.getElementById('renderCanvas'); var engine = new BABYLON.Engine(canvas, true); this.engine = engine; var scene = new BABYLON.Scene(engine); this.scene = scene; scene.clearColor = new BABYLON.Color4(1, 0, 0, 1.0); var light = new BABYLON.SpotLight("spotLight", new BABYLON.Vector3(0, 28, 0), new BABYLON.Vector3(0, -1, 0), Math.PI / 2, 20, scene); light.intensity = 0.9; var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 10, -10), scene); camera.setTarget(BABYLON.Vector3.Zero()); console.log(scene); window.addEventListener("resize",()=>{ engine.resize(); }); var sceneClone = scene.clone(); console.log(sceneClone); sceneClone.clearColor = new BABYLON.Color4(0, 0, 1.0, 1.0); engine.runRenderLoop(()=>{ sceneClone.render(); }); },false); Dad72 1 Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted January 25, 2018 Share Posted January 25, 2018 As you want to use it with a new context, I guess the idea of @Pryme8 is the best: just serialize it and reload it Quote Link to comment Share on other sites More sharing options...
Dad72 Posted January 26, 2018 Author Share Posted January 26, 2018 Thank you Pryme, this seems the best solution. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.