SpaceToast

Altering the Vertices of an Imported Mesh

Recommended Posts

Hey crew. I've run up against trouble trying to move the vertices of an imported mesh. (So far I've tried a .babylon file and .glb.) 

Here's a Playground example where I've added a randomize-vertex-positions function to the  glTF Importer (Boombox) example. Upon loading the scene file, we do this:

        //Add a "do this once the mesh loads" function to the example:
        var bb = scene.getMeshByName("BoomBox"); //Get the newly-loaded mesh
        bb.updateable = true; //Not clear if this does anything
    	var positions = bb.getVerticesData(BABYLON.VertexBuffer.PositionKind); //Copy the mesh's vertex positions into an array
        var numberOfVertices = positions.length/3;	//Randomize the vertex coordinates in the array
        for(var i = 0; i<numberOfVertices; i++) {
            positions[i*3] = Math.random()*5;
            positions[i*3+1] = Math.random()*5;
            positions[i*3+2] = Math.random()*5;
        };
        var positionFunction = function() { //Create a function for updateMeshPositions to call...
            bb.updateVerticesData(BABYLON.VertexBuffer.PositionKind, positions); //...where we replace the old vertex data with our array
        };
        bb.updateMeshPositions(positionFunction, true); //Call that updateMeshPositions function
        //And... nothing happens. The boombox remains as it was at import.

No change. Any thoughts on what I might be doing wrong?

Share this post


Link to post
Share on other sites

Very elegant! Is it possible to replace all of the existing vertex positions in a single copy operation, like existingVertices = newPositionArray; or would I always need to loop through the vertex array replacing values one by one?

Share this post


Link to post
Share on other sites

Hmm. Might be a bug. In Chrome and Firefox, at least, only editing the values of the position array in situ appears to work.

Regardless, for anyone using this thread for future reference, you'll need to take the following steps to alter an imported mesh. (Here's a working playground to follow along.)

Kosh (All Kosh?) Thanks again!

  1. Rip out the mesh's vertex position data & stuff it back in, with updateable set to true:
    var pos = bb.getVerticesData(BABYLON.VertexBuffer.PositionKind);
    bb.setVerticesData(BABYLON.VertexBuffer.PositionKind, pos, true);

     

  2. Rip out the mesh's vertex normals & stuff them back in, with updateable set to true:
    var nm = bb.getVerticesData(BABYLON.VertexBuffer.NormalKind);
    bb.setVerticesData(BABYLON.VertexBuffer.NormalKind, nm, true);

     

  3. Call updateMeshPositions() on the mesh:
    bb.updateMeshPositions(positionFunction, true);
  4. Create a function to edit the vertex positions, for updateMeshPositions() to trigger. Note that updateMeshPositions() automatically passes the vertex position array of the mesh that calls it as an argument to your position function:
var positionFunction = function(positions) {
   var numberOfVertices = positions.length/3;
   for (var i = 0; i < numberOfVertices; i++) {
      positions[i*3] = Math.random();
      positions[i*3+1] = Math.random();
      positions[i*3+2] = Math.random();
   };
};

 

 

 

Share this post


Link to post
Share on other sites

Thanks, JC. In other words--to surface the lede from your code--you can replace vertex data directly with object.setVerticesData(), but only if your new data is in an [explicitly created] Float32 array. Is there any advantage to using an object.setVerticesData() function?

Edited by SpaceToast
Wrong

Share this post


Link to post
Share on other sites

setVerticesData() just does it.  updateMeshPositions()  must be calling it.  If there is an advantage it is you are not limited to position data.  you can do normals, UVs, vertexcolors, bone indexes & weights.  Yes @Gijs float32Array is NOT required.  However, if you pass a number array, somewhere along the line it is going to have to be copied to a Float32Array before it can be sent to the GPU.

Share this post


Link to post
Share on other sites

Appreciate the help, crew. (And yeah, my Float32 conclusion came from a coding typo on my part!) What I'm really trying to do is map out the "gotchas" around editing vertex data in bjs. What I'm mostly finding is that the better-documented updateMeshPositions() method is rather delicate and unnecessarily complex--at least in my specific case of using a webworker to generate the new vertex arrays. Possibly in most cases.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.