Stride and offset on a Float32Array

Hi, I created a custom mesh:

var customMesh = new BABYLON.Mesh("custom", scene);

var positions = [-5, 2, -3, -7, -2, -3, -3, -2, -3, 5, 2, 3, 7, -2, 3, 3, -2, 3];
var indices = [0, 1, 2, 3, 4, 5];

var vertexData = new BABYLON.VertexData();

vertexData.positions = positions;
vertexData.indices = indices;
vertexData.applyTo(mesh)

But position values are not correct, I need to use offset and stride.
I see VertexBuffer can do that.

So how to use VertexBuffer with Float32Array and apply it to VertexData.positions ?

you need to call vertexData.applyTo(mesh) :wink:

Please make a playground so we can take a look: https://playground.babylonjs.com/

1 Like

I update my post to add it.
I think I do a wrong copy/paste. ( I already use vertexdata.applyTo(mesh))

See here https://playground.babylonjs.com/#ZJI1KU#1

See also here.

It’s curently what I do.
But I need to apply an offset and stride on Float32Array, before applying to mesh. So how to do that ?

I do not understand your requirements. Why would you need to apply stride on the position buffer? Is it not aways 3? Come to think of it: I do not understand what you mean by “to apply an offset and stride”.

I mean, if you want to work on a float array, instantiate it: new Float32Array(numVertices*3);
Then in terms of stride, you iterate the array by “stride” (i.e. for position buffer → i+=3). You apply an offset by setting the start index to the desired offset. E.g. start at vertex 5 → i=5*3.

Other than that: there is a stride parameter here: Babylon.js docs

If that is not it: Can you somehow indicate what your expected outcome should be? And/Or use the playground I posted above and put in where your “stride” and “offset” come from.


Or do you want to create a custom vertex buffer?

1 Like

I would like to port this from threejs

    const positions = new THREE.InterleavedBuffer(new Float32Array(vertexBuffer), 4);
    geometry.setAttribute('position', new THREE.InterleavedBufferAttribute(positions, 3, 0, false));

    const normals = new THREE.InterleavedBuffer(new Int8Array(vertexBuffer), 16);
    geometry.setAttribute('normal', new THREE.InterleavedBufferAttribute(normals, 4, 12, true));

    // Index Buffer

    const index = new THREE.BufferAttribute(new Uint16Array(indexBuffer), 1, false);
    geometry.setIndex(index);

In the doc, InterleavedBuffer arg get stride and InterleavedBufferAttribute arg get offset.

2 Likes

Oohh, this looks amazing @vana Can we do this in Babylon @all?

InterleavedBuffer :money_mouth_face:

Or even:

This is very useful for packing multiple meshes into a single buffer, since we can start rendering at any point,

(Source2)

Yes we can. We use it extensively in the engine:

  • You have to create an initial buffer (Buffer)
  • Then you can create VertexBuffers on that buffer

Look at the VertexBuffer constructor:
VertexBuffer | Babylon.js Documentation

So something like that should work:

    const data = new Float32Array([ 0.4, 0.4, 0.4, 0,1,0, 
                                    0.6, 0.6, -0.6, 0,1,0,
                                    0, -0.8, 0.8, 0, 1, 0]);
    const buffer = new BABYLON.Buffer(engine, data, false);
    const vertexBufferPosition = new BABYLON.VertexBuffer(engine, buffer, BABYLON.VertexBuffer.PositionKind, false, undefined, 3, undefined, 0, 3);
    const vertexBufferNormals = new BABYLON.VertexBuffer(engine, buffer, BABYLON.VertexBuffer.NormalKind, false, undefined, 3, undefined, 3, 3);

    const geometry = new BABYLON.Geometry("geometry1", scene);
    geometry.setVerticesBuffer(vertexBufferPosition);
    geometry.setVerticesBuffer(vertexBufferNormals);
    geometry.setIndices([0, 1, 2], 3);

    const mesh = new BABYLON.Mesh("toto");
    geometry.applyToMesh(mesh)

Babylon.js Playground

2 Likes

I try your solution, but when applying geometry to mesh, loading mesh fail.

I try to reproduce on Playground Babylon.js Playground

Lol your PG is simply not working. We cannot help you if you do not reproduce correctly :wink:

Please help us helping you

I cannot do better.
I create a custom mesh loader, like gltf loader.
I enable it and load an asset.
If I comment geometry.setVerticesBuffer(positionsBuffer) I get not issue
Get same issue on indices

Please fix the code :wink:

I will not debug the code for you. We are offering free help but you need to do the first steps.

Your PG is simply not working (not even mentioning your issue):

Here is how you can make your code playground-compatible:

  • click on the redish “TS” button to switch to TS
  • copy paste your code again
  • remove all your imports
  • prefix all babylon objects by BABYLON. (ex: new Vector3 => new BABYLON.Vector3)

I remove all my imports, and prefix with BABYLON
Now i get issue when switching to TS, It does not want to save with TS enabled …

Ah weird indeed, maybe fix the syntax error mentionned first and then it might work ^^ (remove all “export” statements)

Now I get bad method definition, but It doesn’t display where is the issue :s

In the playground, the CreateScene function is called automatically, you don’t need to call it yourself. You don’t need to handle engine resize as well, it is taken care of by the PG.

Once you have removed all that, it probably won’t crash anymore :+1:

with removing these 2 calls, it always crash :s, I still cannot save and go back to js with same errors

I can share a GH repo