Jump to content

display object from scene 1 in scene 2


Flomotion
 Share

Recommended Posts

Hi again, F-guy!  How's it goin'?  I hope well.

Umm... https://github.com/Wingnutt/misc/blob/master/bi_canvas.zip

Just a test package... babylon.js and hand.js included... unzip'n'go.

Don't be excited, I have failed so far.  I use two engines, two canvas, two scene objects (global, so they can access each other), two separate createScene funcs... and the bottom of the 2nd createScene func... I try to reach-out-and-touch-someone. :D   (ahem, sorry).  I use clone... which means I must also clone its material, because cloning doesn't include materials from the source of the clone.

	var oldbox = scene.meshes[1];
	var oldmat = oldbox.material;
	var newbox = oldbox.clone();
	newbox.position = new BABYLON.Vector3(-3, 10, -3);
	var newmat = oldmat.clone();

	console.log(newmat);

	// console.log(newbox);

	scene2.meshes.push(newbox);
	scene2.materials.push(newmat);

	scene.meshes[2].dispose();

	return scene2;
}

var scene = createScene();
var scene2 = createScene2();

Generally speaking, I pretend that the mesh and the material... are just plain ol' JS objects.  ;)   I try to hand-them across the two scenes. 

And... I fail... nicely.  Sorry.  I just wanted to show you what I've done so far.  (hope the zip link works for you) 

A bounding box DOES show-up in the 2nd (right side) canvas2/scene2... but its just a shell of its former self.  ;)   (I think the material hand-off is failing.  Might need a deeper cloning, or maybe more Wingnut intelligence.)

I will keep troubleshooting, or maybe you can find the problem.  And this is not the ONLY solution.  There's trickery possibilities, too, using viewports (or possibly a renderTargetTexture camera).  Same scene, but it can "look" like two separate canvases.  We'll talk.  

Link to comment
Share on other sites

hey Wingnut,

thank you for your brave effort! I would have guessed that this should work. But indeed.. something is not right.

I noticed that the clone has some things missing, compared to the original. One pretty important one I think is the _geometry. But there are many differences (I made screenshot to compare) I tried to specifically copy the scene.meshes[1]._geometry. But it's not working.

I don't have any brilliant idea's right now.. maybe they'll come to me in the night :-)

 

clone.jpg

Link to comment
Share on other sites

Hey, good troubleshooting activity... thanks for the comparison list.  Well done.  I see that materials and mesh have a ._scene property, too.  Tried it, no go.  :)

Just for fun, let's look at the 5-viewport thing I made long ago.

http://www.babylonjs-playground.com/#13TVWJ#1

Assorted crap going-on, there.  Take some time to play.  The thin blue lines are camera 2 and 4, and viewport 2 and 4.  This was made before the days of Canvas2D, so I needed SOME way to make divider lines between the viewports.  I COULD HAVE used absolute-positioned HTML <img> elements, but rumor has it that Android apps running CocoonJS... can't do DOM things.  SO, I tried to avoid HTML methods, and thus make a decent 3-window-area game-ready viewport-template... that works for everyone.

If you look carefully as you pan the camera, you will see a lit blue plane way out at 500x,500z.  It could be considered TV Studio #2 (Blue Plane Studios Inc). :) Just a camera aiming down at a lit blue plane, and then I defined thin viewports for those divider lines, and it turned out okay.  You can move studio #2 to anywhere you like.  Perhaps best if 10000x ,10000z or beyond.  More on that in a moment.

You could open Studio #3 (Selected Mesh Studios Inc)... maybe out at 10000x,10000z if you wanted.  My camera 3 is already feeding the top-right viewport, so just move cam3 out to 10000,10000, set-up some studio lights out there, and start yelling at the employees.  heh. 

Perhaps set camera1.maxZ to 9000... and nobody would know Studio #2 or #3 exist at all... out there on the prairie, hiding in the tall grass.  ;)

What you would do... (upon click?)... is clone the box, and put the clone out at your new studio #3 all by itself, or maybe studio #3 has a ground of its own.  It HAS TO have a light or you'll need to have an emissiveColor or emissiveTexture on clonebox's material... for self-illumination.  A hemisphericLight... direction 0, 1, 0 (aimed at the sky).... with light.groundColor set to gray... works great for one-light-does-all.

See what I mean about "looking" like 2 canvases?  Canvai?  :)  Just maybe... @Flomotion can fool ALL of the people... ALL of the time.  *shrug*  It's another option.  Party on.

Link to comment
Share on other sites

@Deltakosh, what a great idea!  Darn... I should have thought of that myself.  Thanks DK!

https://github.com/Wingnutt/misc/blob/master/bi_canvas2.zip

	var oldbox = scene.meshes[1];

	var serMesh = BABYLON.SceneSerializer.SerializeMesh(oldbox, false, false);

	serMesh = JSON.stringify(serMesh);

/*
	BABYLON.SceneLoader.Load("", "data:" + serMesh, scene2, function (newMeshes) {
		console.log("newMeshes: " + newMeshes);
	});
*/
/*
	BABYLON.SceneLoader.Append("", "data:" + serMesh, scene2);
	scene.onReadyObservable.add(function (d) {
		console.log("d: " + d);
	});
*/
	BABYLON.SceneLoader.ImportMesh("", "", "data:" + serMesh, scene2, function (newMeshes) {
		console.log("newMeshes: " + newMeshes);
	});

As you can see, I tried the import using Load, and then with Append... neither worked, but I could have been screwing-up.  Then I tried importMesh, and it worked just fine.  The append would probably work, too... IF I would have used scene2.onReadyObservable.add  (a mistake I noticed just now)  :o

Wanna hear something weird?  I knew ya did.  When we tried the other non-serializing methods, we got ONLY the boundingBox to transfer... because .showBoundingBox = true on the source mesh.  Using this serialize/import method, all went fine, even the material got transferred automatically, but... not the .showBoundingBox = true.  heh.  Too funny!

Me thinks maybe .showBoundingBox is not included in the serialization, for some reason.  When I put serMesh in my browser object inspector, I could not see any .showBoundingBox property on it.  But, maybe that is by design. 

All in all, this is cooooool.  I learned stuff.  thx agn, dk!   Well thunk.  Flomo might want to do edits to the object, and then put it back into scene1.  This same method will work for the put-back, too (after a dispose of the original).  PARTY!!!

I wonder if a mesh.dispose()... also disposes it's material... IF that was the only mesh in the scene... using that material. 

Early tests say no.  It's interesting that scene1.materials has 3 items, when only 2 materials were defined.  hmm.  Anyway, scene.materials[2] === oldbox.material, and after a test oldbox.dispose()... scene.materials.length is still 3.  But it COULD be a "lazy dispose".  Is there such a thing?  Done during browser GC?  I dunno.  I'm only the bass player in the band.  :D

Anyone else running this test zip in firefox 47.0.1?  Seeing lots of...

Error: WebGL: drawArrays: Drawing to a destination rect smaller than the viewport rect. (This warning will only be given once) -- babylon.js:5:27955
Error: WebGL: Exceeded 16 live WebGL contexts for this principal, losing the least recently used one. -- babylon.js:4:6955

????  I sure do.  They don't get in my way, but they sure clutter-up my JS console.

Link to comment
Share on other sites

Hey all :)

 

I am late to the party, but is there any new functionality that permit to add a mesh from scene 1 to scene 2 easily ? Or serializing is still the best way ?

 

By the way I was wondering if lodash _.cloneDeep() would work. But it seems the cloning is taking exponentially more time at each cloning :

var tilesArray = [];
for (var i = 0; i < taskObject.assets.tiles.length; i++) {
  var tile = _.cloneDeep(taskObject.assets.tiles[i]);
  tile._scene = scene;
  scene.addMesh(tile);
  tilesArray.push(tile);
}

Around the 8th clone I am above the minute...

Link to comment
Share on other sites

Ok so I had a problem with the serialization, with this code :

var serMesh = BABYLON.SceneSerializer.SerializeMesh(taskObject.assets.tiles, false, false);
serMesh = JSON.stringify(serMesh);
BABYLON.SceneLoader.ImportMesh("", "", "data:" + serMesh, scene, function (newMeshes) {
console.log("newMeshes: " + newMeshes);
}

if I serialized the mesh twice the geometries in the serialized object would disapear and I would get a warning on the second time :

BJS - [18:57:46]: Geometry not found for mesh e4889621-49bb-4dd5-87a6-48b38720fcdd

 

The problem came from line 48339 babylon.max

var BABYLON;
(function (BABYLON) {
  var serializedGeometries = [];
  var serializeGeometry = function (geometry, serializationGeometries) {
    if (serializedGeometries[geometry.id]) {
     return;
    }

...

}

 

If I comment out the if statement, geometries are serialized both times and I dont get the geometry error.

Although I do not have errors anymore, I couldnt make the loading work, the ImportMesh callback is never called.

The only message I get from babylon is :

BJS - [18:44:21]: importMesh of unknown

 

My goal is to load all the meshes and material in a first scene, then be able to reuse them across multiple scenes. 

Link to comment
Share on other sites

The next roadblock is coming from the line 25103 babylon.max:

if (!materialFound) {
                  loadedMaterialsIds.push(parsedMesh.materialId);
                  var mat = parseMaterialById(parsedMesh.materialId, parsedData, scene, rootUrl);

***

}

The BABYLON.SceneSerializer.SerializeMesh(mesh,false/true,false) does not seem to serialize the material and there is not materials array in the serialized mesh.

The parseMaterialById returns an uncaught error :

babylon.max.js:24983 Uncaught TypeError: Cannot read property 'length' of undefined(…)

 

Link to comment
Share on other sites

Hi @AlbertTJames - interesting testing!  In my tiny little test scene, the material DID copy.  https://github.com/Wingnutt/misc/blob/master/bi_canvas.zip

But it is a simple test with non-imported mesh, so it might not apply.  The other issues you raise... I'm not experienced enough to comment-on.  A bit over my head.  We'll ping-up @Deltakosh and see if he has words.  (thx DK) 

And thanks for telling us about your tests, ATJ!  Very interesting.

Link to comment
Share on other sites

Hey! I was able to clone mesh from first scene into second.

var loaderScene = new BABYLON.Scene(engine);
var loader = new BABYLON.AssetsManager(loaderScene);
var assets = {
"your_mesh_name":loader.addMeshTask("name", "", "/static/models/hand/", "hand.babylon")
};
loader.load();
loader.onFinish = function (tasks) {
    scene = createScene();
};

var clone = function (name) {
    var clone = assets[name].loadedMeshes[0].clone("");
    clone._scene = scene;
    
    if(clone.material)
    {
        clone.material._scene = scene;
        if(clone.material.subMaterials)
        {
            for (var i = 0; i < clone.material.subMaterials.length; i++) {
                clone.material.subMaterials[i]._scene = scene;
            }
        }
    }
    scene.addMesh(clone);
    
    return clone;
}

var mesh = clone('your_mesh_name');

 

Link to comment
Share on other sites

@Athelios Man ! Thank you a lot ! Changing the scene of the materials was the problem. After testing your solution I had problems when changing scenes several times because the material was passed by reference and not cloned. 

So the final code I am using based on your solution :

cloneAssetIntoScene(asset = mandatory(), scene = mandatory()) {
  var clone = asset.clone();
  clone._scene = scene;

  if (clone.material) {
    clone.material = clone.material.clone();
    clone.material._scene = scene;
    if (clone.material.subMaterials) {
      for (var i = 0; i < clone.material.subMaterials.length; i++) {
        clone.material.subMaterials[i] = clone.material.subMaterials[i].clone();
        clone.material.subMaterials[i]._scene = scene;
      }
    }
  }
  scene.addMesh(clone);

  return clone;
}

...

var tilesArray = []; 
for (var i = 0; i < taskObject.assets.tiles.length; i++) {
  var tile = taskObject.cloneAssetIntoScene(taskObject.assets.tiles[i], scene);
  tile.isVisible = false;
  tilesArray.push(tile);
}

 

* * * 

To finish on serialization maybe for those who would be interested :

So serialization it seems does not serialize the material but pass by ID on line 48413 Babylon.max:

// Material
if (mesh.material) {
  serializationObject.materialId = mesh.material.id;
} else {
  mesh.material = null;
}

// Skeleton
if (mesh.skeleton) {
  serializationObject.skeletonId = mesh.skeleton.id;
}

 

@Wingnut Thank you for your support and good energy ! :) 

Link to comment
Share on other sites

I do not want to lead you on, but soon there will a way as good any listed, coming from Blender anyway.  If your mesh was self contained its own Mesh sub-class with in-line geometry (and even in-line textures:)), you could just say:

var myMesh = new moduleNme.meshClass("name", scene);

in both scenes.  It is brutally fast.

Link to comment
Share on other sites

Hi F.  Sorry for the bad links. This one should work... http://webpages.charter.net/wingthing/misc/bi-canvas2.zip

The forum software doesn't like those github zip links?raw=true, or maybe its me.  :)

Good to see that you survived the burial!  :)  Yeah, we got a lot of help from other posters, eh?  I learned a ton of stuff from the thread joiners.  Good good good.

Link to comment
Share on other sites

  • 4 months later...

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...