Flomotion Posted August 28, 2016 Share Posted August 28, 2016 Hi, I have 2 canvasses next to eachother. I'd like to display a selected object from scene 1 in scene 2 on the other canvas. I should duplicate it into scene 2..But I don't know how to do that. Is there a way to display a mesh from a scene into another scene? Quote Link to comment Share on other sites More sharing options...
Wingnut Posted August 28, 2016 Share Posted August 28, 2016 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. (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. Blax 1 Quote Link to comment Share on other sites More sharing options...
Flomotion Posted August 28, 2016 Author Share Posted August 28, 2016 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 :-) Wingnut 1 Quote Link to comment Share on other sites More sharing options...
Wingnut Posted August 28, 2016 Share Posted August 28, 2016 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. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted August 29, 2016 Share Posted August 29, 2016 What about serializing the mesh from scene1 and importing it to scene2 ? Quote Link to comment Share on other sites More sharing options...
Wingnut Posted August 29, 2016 Share Posted August 29, 2016 @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) 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. 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. Flomotion 1 Quote Link to comment Share on other sites More sharing options...
AlbertTJames Posted August 31, 2016 Share Posted August 31, 2016 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... Quote Link to comment Share on other sites More sharing options...
AlbertTJames Posted August 31, 2016 Share Posted August 31, 2016 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. Wingnut 1 Quote Link to comment Share on other sites More sharing options...
AlbertTJames Posted August 31, 2016 Share Posted August 31, 2016 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(…) Quote Link to comment Share on other sites More sharing options...
Wingnut Posted August 31, 2016 Share Posted August 31, 2016 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. Quote Link to comment Share on other sites More sharing options...
Athelios Posted August 31, 2016 Share Posted August 31, 2016 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'); Flomotion and Wingnut 2 Quote Link to comment Share on other sites More sharing options...
AlbertTJames Posted August 31, 2016 Share Posted August 31, 2016 @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 ! Flomotion, Wingnut and Athelios 3 Quote Link to comment Share on other sites More sharing options...
JCPalmer Posted August 31, 2016 Share Posted August 31, 2016 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. AlbertTJames 1 Quote Link to comment Share on other sites More sharing options...
Flomotion Posted September 3, 2016 Author Share Posted September 3, 2016 Thanks everyone for the solutions! I was buried in work this week and didn't find the time to reply. @Wingnut I don't really understand the serialise method. Unfortunately your link doesn't work anymore. Could you repost it? I'll use the method of AlbertTJames. Thanks again!! Quote Link to comment Share on other sites More sharing options...
Wingnut Posted September 3, 2016 Share Posted September 3, 2016 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. Quote Link to comment Share on other sites More sharing options...
AlbertTJames Posted January 18, 2017 Share Posted January 18, 2017 I was wondering if any new solutions exists for this beside the one proposed in this post ? 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.