Jump to content

Dynamic mesh not rendering


speps
 Share

Recommended Posts

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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!  :)

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

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