speps Posted May 22, 2014 Share Posted May 22, 2014 Hi all, I want to make a game where I will update meshes in real time. I tried some simple code starting from the hello world : var canvas = document.getElementById("renderCanvas"); var engine = new BABYLON.Engine(canvas, true); var scene = new BABYLON.Scene(engine); var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene); var light0 = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 1, 1), scene); scene.activeCamera.attachControl(canvas); var dynMesh = new BABYLON.Mesh("dynMesh", scene); //dynMesh.setVerticesData([-0.5, -0.5, 0.0, 0.5, -0.5, 0.0, 0.5, 0.5, 0.0, -0.5, 0.5, 0.0], BABYLON.VertexBuffer.PositionKind, true); //dynMesh.setVerticesData([0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0], BABYLON.VertexBuffer.NormalKind, true); engine.runRenderLoop(function () { dynMesh.setVerticesData([-0.5, -0.5, 0.0, 0.5, -0.5, 0.0, 0.5, 0.5, 0.0, -0.5, 0.5, 0.0], BABYLON.VertexBuffer.PositionKind, true); dynMesh.setVerticesData([0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0], BABYLON.VertexBuffer.NormalKind, true); dynMesh.setIndices([0, 2, 1, 3, 2, 0]); scene.render(); });As is, I don't see anything (except for one frame when I press F5). However, if I uncomment the 2 setVerticesData then I see the original vertices only and not the modified ones (note how the normals are reversed between the 2 calls). Is this the proper way of updating meshes in real time? Before the render() call seemed appropriate. Cheers, Remi. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted May 22, 2014 Share Posted May 22, 2014 It works for me:http://www.babylonjs.com/playground/#1R2RKA#1 Quote Link to comment Share on other sites More sharing options...
gwenael Posted May 22, 2014 Share Posted May 22, 2014 Works for me too. I love this playground, that is even easier for debugging than with jsfiddle. May I suggest an improvement? Possibility to provide the url for the version of babylon.js that we want to use. Or maybe the playground always uses the latest version of github, does it? Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted May 22, 2014 Share Posted May 22, 2014 it does gwenael 1 Quote Link to comment Share on other sites More sharing options...
speps Posted May 23, 2014 Author Share Posted May 23, 2014 Argh, what version does the playground use? I think I am on 1.11 from GitHub. Quote Link to comment Share on other sites More sharing options...
gwenael Posted May 23, 2014 Share Posted May 23, 2014 The latest one from GitHub according to Deltakosh previous answer. Quote Link to comment Share on other sites More sharing options...
Wingnut Posted May 25, 2014 Share Posted May 25, 2014 Hi Speps, welcome to the forum! I am going to take this a step further, and introduce you to the NEW way to do vertexData. Its not working correctly for me, but this will take you in a new direction, and then maybe the experts will tell me what I am doing wrong. Notice that I stay away from the render loop... which runs fast and continuous. There is no reason to do repeated vertex data setting once per frame. It slows the scene. You should be able to update the vertexData outside of the render loop, and the renderer will see the change on the next frame rendered.<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Speps Dynamic Mesh Test</title> <script src="./js/hand.minified-1.3.7.js"></script> <script src="./js/babylon.1.11.0.js"></script> <style type="text/css"> html,body,#canvas { width:100%; height:100%; padding:0; margin:0; overflow: hidden; background-color: black; } #button { color: white; font-size: 14pt; font-weight: bold; padding-left:4pt; padding-right:4pt; background-color: red; border: red outset 3pt; cursor: pointer; } </style></head><body> <div id="buttonbar" style="background-color: rgb(55, 55, 75);"> <span id="button" onclick="changeit()"> click me </span> </div> <canvas id="canvas"></canvas> <script> var which = "original"; // a global - oh no. var canvas = document.getElementById("canvas"); // Check support if (!BABYLON.Engine.isSupported()) { window.alert('Browser not supported'); } else { var engine = new BABYLON.Engine(canvas, true); var scene = createScene(engine); engine.runRenderLoop(function () { scene.render(); }); // Be ready for a window resize window.addEventListener("resize", function () { engine.resize(); });}// ------------------------------------------function createScene(engine) { var scene = new BABYLON.Scene(engine); var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 5, new BABYLON.Vector3(0, 0, 0), scene); var light0 = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 1, 1), scene); scene.activeCamera.attachControl(canvas); var dynMesh = new BABYLON.Mesh("dynMesh", scene, true); // the basic mesh, made once. original(); return scene;}// ------------------------------------------function changeit() { if (which == "original") { modified(); console.log("changed it to modified"); } else { original(); console.log("changed it to original"); }}// ------------------------------------------ function original() { var scene = engine.scenes[0]; var dynMesh = scene.getMeshByName("dynMesh"); which = "original"; var vertexData = new BABYLON.VertexData(); vertexData.positions = [-0.5, -0.5, 0.0, 0.5, -0.5, 0.0, 0.5, 0.5, 0.0, -0.5, 0.5, 0.0]; vertexData.normals = [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0]; vertexData.indices = [0, 2, 1, 3, 2, 0]; vertexData.applyToMesh(dynMesh, true); }// ------------------------------------------ function modified() { var scene = engine.scenes[0]; var dynMesh = scene.getMeshByName("dynMesh"); which = "modified"; var vertexData = new BABYLON.VertexData(); vertexData.positions = [-0.5, -0.5, 0.0, 0.5, -0.5, 0.0, 0.5, 0.5, 0.0, -0.5, 0.5, 0.0]; vertexData.normals = [0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0]; vertexData.indices = [0, 2, 1, 3, 2, 0]; vertexData.applyToMesh(dynMesh, true); }// ------------------------------------------</script></body></html>Note that I am using 1.11.0. It should work just fine for your experiment... but adjust at will. When I click the button to change between original and modified... I get Error: WebGL: drawElements: no VBO bound to enabled vertex attrib index 0... with Firefox 21. I am newbie, especially to updating vertexData dynamically. But not only is the example above a better way to do it (avoiding the render loop and using functions instead), but it also shows the newest way of setting vertexData for current and future versions of babylon.js. Now if we can get some expert to tell us why I/we cannot update dynMesh with new vertexData... even though it is set to updatable = true ... that would be great. I think Gwenael talked about this once before. The mesh, created in createScene ONCE... should maintain its VBO, and therefore Speps should be able to re-apply modified vertexData as many times as he wishes, right? Can someone tell us why the VBO for dynMesh... fell out of scope/availability, if it did? Thanks. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted May 25, 2014 Share Posted May 25, 2014 Hello, vertexData.applyToMesh if for creation only, you have to use mesh.updateVerticesData to update a dynamic mesh BTW, 1.12 will add a vertexData.updateMesh function for your convenience Quote Link to comment Share on other sites More sharing options...
Wingnut Posted May 25, 2014 Share Posted May 25, 2014 Thanks Deltakosh! Ok, Speps, in order for dynMesh.updateVerticesData to work, I had to revert back to the older way of creating dynMesh... where the mesh carries its data WITH it. (In the newer version that uses a 2-object method, the VertexData object sort of "casts" the data into the shape of the mesh, but the mesh doesn't carry the data with it). (As I understand all this). So, since I have been pasting the thread full of code to this point, I might as well maintain that habit. <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Speps Dynamic Mesh Test</title> <script src="./js/hand.minified-1.3.7.js"></script> <script src="./js/babylon.1.11.0.js"></script> <style type="text/css"> html,body,#canvas { width:100%; height:100%; padding:0; margin:0; overflow: hidden; background-color: black; } #button { color: white; font-size: 14pt; font-weight: bold; padding-left:4pt; padding-right:4pt; background-color: red; border: red outset 3pt; line-height: 2em; cursor: pointer; } </style></head><body> <div id="buttonbar" style="background-color: rgb(55, 55, 75);"> <span id="button" onclick="changeit()"> click me </span> </div> <canvas id="canvas"></canvas> <script> var which = "original"; var canvas = document.getElementById("canvas"); // Check support if (!BABYLON.Engine.isSupported()) { window.alert('Browser not supported'); } else { var engine = new BABYLON.Engine(canvas, true); var scene = createScene(engine); engine.runRenderLoop(function () { scene.render(); }); // Be ready for a window resize window.addEventListener("resize", function () { engine.resize(); });}// ------------------------------------------function createScene(engine) { var scene = new BABYLON.Scene(engine); var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 5, new BABYLON.Vector3(0, 0, 0), scene); var light0 = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 1, 1), scene); scene.activeCamera.attachControl(canvas); createDynMesh(scene); return scene;}// ------------------------------------------function createDynMesh(scene) { var dynMesh = new BABYLON.Mesh("dynMesh", scene, true); dynMesh.setVerticesData([-0.5, -0.5, 0.0, 0.5, -0.5, 0.0, 0.5, 0.5, 0.0, -0.5, 0.5, 0.0], BABYLON.VertexBuffer.PositionKind, true); dynMesh.setVerticesData([0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0], BABYLON.VertexBuffer.NormalKind, true); dynMesh.setIndices([0, 2, 1, 3, 2, 0]);}// ------------------------------------------function changeit() { var scene = engine.scenes[0]; var dynMesh = scene.getMeshByName("dynMesh"); if (which == "modified") { var positions = [-0.5, -0.5, 0.0, 0.5, -0.5, 0.0, 0.5, 0.5, 0.0, -0.5, 0.5, 0.0]; var normals = [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0]; var indices = [0, 2, 1, 3, 2, 0]; dynMesh.updateVerticesData(BABYLON.VertexBuffer.PositionKind, positions); dynMesh.updateVerticesData(BABYLON.VertexBuffer.NormalKind, normals); dynMesh.setIndices(indices); which = "original"; console.log("changed it to original"); } else { var positions = [-0.5, -0.5, 0.0, 0.5, -0.5, 0.0, 0.5, 0.5, 0.0, -0.5, 0.5, 0.0]; var normals = [0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0]; var indices = [0, 2, 1, 3, 2, 0]; dynMesh.updateVerticesData(BABYLON.VertexBuffer.PositionKind, positions); dynMesh.updateVerticesData(BABYLON.VertexBuffer.NormalKind, normals); dynMesh.setIndices(indices); which = "modified"; console.log("changed it to modified"); }}// ------------------------------------------</script></body></html>This seems to work just fine. Thanks for bringing-up this subject, because I was able to learn some things with you. I hope I did not ruin the fun of your experiment by pasting this code. As Deltakosh mentioned, your experiment is also promoting the addition of a new function on the VertexData object... a sister to .applyToMesh() ...called .updateMesh(). Congratulations on your contribution to the babylon.js framework! That is quite a good accomplishment for someone who is so new to the forum! Well done! GameMonetize 1 Quote Link to comment Share on other sites More sharing options...
gwenael Posted May 27, 2014 Share Posted May 27, 2014 I think Gwenael talked about this once before. The mesh, created in createScene ONCE... should maintain its VBO, and therefore Speps should be able to re-apply modified vertexData as many times as he wishes, right? Can someone tell us why the VBO for dynMesh... fell out of scope/availability, if it did? Thanks. Since this talk, the geometry system has been added and some fixes were provided so Wingnut your first solution may work with the latest babylon.js version. Nevertheless, keep in mind that applyToMesh, as mentioned by Deltakosh, should be used for creation since it creates new instances of VBO like setVerticesData does. With the current babylon.js version you can update vertices data by calling setVerticesData even on non updatable meshes BUT each time it creates new VBO and so it's not a good practice. You should use updateVerticesData like you did in your last answer. This function works only for updatable meshes. Wingnut 1 Quote Link to comment Share on other sites More sharing options...
speps Posted May 29, 2014 Author Share Posted May 29, 2014 Thanks Wingnut for the wonderful explanation, I'm excited with Babylon's future support for vertex data, the API looks much nicer. I tried with your second method, unfortunately, I couldn't see it working : http://www.babylonjs.com/playground/#YEUDZ Supposedly, with this code, you should see the square growing and flipping normals every second. In Firefox 29, the console displays the message in the log happily (Updated mesh with counter ##) and doesn't complain. However in SeaMonkey 2.26, I get an error : this._vertexBuffers[a] is undefined (babylon.js line 13). Quote Link to comment Share on other sites More sharing options...
Wingnut Posted May 30, 2014 Share Posted May 30, 2014 My pleasure. Holy cow, Speps, you have quite the mad scientist experiment going in the playground, there. The code I pasted just flipped the plane's normals via a button press. You have taken it into a whole new realm, there. I like looking at your code, though. It is pretty much over my head. Maybe some nearby experts will take a look at it, and have some comments. I'll be watching... and keep us posted here, if you'd be so kind. What you are trying is interesting, and you are certainly not as "newbie" as I first assumed. That playground piece has some advanced stuff going-on... I like it. Your counter and animationFrame stuff is quite fascinating, at least to me. Quote Link to comment Share on other sites More sharing options...
speps Posted May 30, 2014 Author Share Posted May 30, 2014 The animFrame stuff is from Pixi, it's using the API to get accurate timings for game loops. I guess that's also what Babylon uses for the render loop but it's not exposed like it is in Pixi. I wanted some "advanced" code because in my game (and this example illustrates how I will use the API). I will need to update the mesh very often (every couple of frames for example). I will have to create a mesh along a spline (like a tunnel or a road) but if Babylon doesn't support that easily (maybe the next version), I might take a look at other engines. I hope someone can figure this out, I guess the error I get in SeaMonkey is something relevant. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted May 31, 2014 Share Posted May 31, 2014 This is my fault. The setVerticesData function signature is (values, kind, updatable) where updateVerticesData signature is (kind, values). Really sorry about that I will unify that for next update on github (I will keep (kind, values) pattern) 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.