Jump to content

Clone or copy a scene


Dad72
 Share

Recommended Posts

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.

 

 

Link to comment
Share on other sites

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();
});	

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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/

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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);


 

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...