# BufferGeometry not working

I’d like to draw thousands of cubes a time, `InstancedMesh` just allows to set the position (not the size of the cube), so I decided to use `BufferGeometry` and set the vertices and indices myself, but it’s not working.
It gives the error `Uncaught TypeError: t.onUploadCallback is not a function`.

My code is the following:

``````const geometry = new BufferGeometry();

// vertices per cuboid * 3 / 2
const coordinates = new Float32Array(12 * coords.length);
// polygons per cuboid * 3 / 2
const indices = new Int16Array(18 * coords.length);

for (let i = 0; i < coords.length / 2; i++) {
const startCoordinate = new Vector3(...coords[i * 2]);
const endCoordinate = new Vector3(...coords[i * 2 + 1]);

// vertex 0
coordinates[i * 24] = startCoordinate.x;
coordinates[i * 24 + 1] = startCoordinate.y;
coordinates[i * 24 + 2] = startCoordinate.z;
// vextex 1
coordinates[i * 24 + 3] = endCoordinate.x;
coordinates[i * 24 + 4] = startCoordinate.y;
coordinates[i * 24 + 5] = startCoordinate.z;
// vextex 2
coordinates[i * 24 + 6] = startCoordinate.x;
coordinates[i * 24 + 7] = endCoordinate.y;
coordinates[i * 24 + 8] = startCoordinate.z;
// vextex 3
coordinates[i * 24 + 9] = endCoordinate.x;
coordinates[i * 24 + 10] = endCoordinate.y;
coordinates[i * 24 + 11] = startCoordinate.z;
// vextex 4
coordinates[i * 24 + 12] = startCoordinate.x;
coordinates[i * 24 + 13] = startCoordinate.y;
coordinates[i * 24 + 14] = endCoordinate.z;
// vextex 5
coordinates[i * 24 + 15] = endCoordinate.x;
coordinates[i * 24 + 16] = startCoordinate.y;
coordinates[i * 24 + 17] = endCoordinate.z;
// vextex 6
coordinates[i * 24 + 18] = startCoordinate.x;
coordinates[i * 24 + 19] = endCoordinate.y;
coordinates[i * 24 + 20] = endCoordinate.z;
// vextex 7
coordinates[i * 24 + 21] = endCoordinate.x;
coordinates[i * 24 + 22] = endCoordinate.y;
coordinates[i * 24 + 23] = endCoordinate.z;

// polygon 0
indices[i * 36] = i * 8;
indices[i * 36 + 1] = i * 8 + 1;
indices[i * 36 + 2] = i * 8 + 2;
// polygon 1
indices[i * 36 + 3] = i * 8 + 1;
indices[i * 36 + 4] = i * 8 + 2;
indices[i * 36 + 5] = i * 8 + 3;
// polygon 2
indices[i * 36 + 6] = i * 8 + 4;
indices[i * 36 + 7] = i * 8 + 5;
indices[i * 36 + 8] = i * 8 + 6;
// polygon 3
indices[i * 36 + 9] = i * 8 + 5;
indices[i * 36 + 10] = i * 8 + 6;
indices[i * 36 + 11] = i * 8 + 7;
// polygon 4
indices[i * 36 + 12] = i * 8 + 4;
indices[i * 36 + 13] = i * 8;
indices[i * 36 + 14] = i * 8 + 2;
// polygon 5
indices[i * 36 + 15] = i * 8;
indices[i * 36 + 16] = i * 8 + 6;
indices[i * 36 + 17] = i * 8 + 2;
// polygon 6
indices[i * 36 + 18] = i * 8 + 5;
indices[i * 36 + 19] = i * 8 + 1;
indices[i * 36 + 20] = i * 8 + 7;
// polygon 7
indices[i * 36 + 21] = i * 8 + 1;
indices[i * 36 + 22] = i * 8 + 7;
indices[i * 36 + 23] = i * 8 + 3;
// polygon 8
indices[i * 36 + 24] = i * 8 + 4;
indices[i * 36 + 25] = i * 8 + 5;
indices[i * 36 + 26] = i * 8;
// polygon 9
indices[i * 36 + 27] = i * 8 + 5;
indices[i * 36 + 28] = i * 8;
indices[i * 36 + 29] = i * 8 + 1;
// polygon 10
indices[i * 36 + 30] = i * 8 + 6;
indices[i * 36 + 31] = i * 8 + 7;
indices[i * 36 + 32] = i * 8 + 2;
// polygon 11
indices[i * 36 + 33] = i * 8 + 7;
indices[i * 36 + 34] = i * 8 + 2;
indices[i * 36 + 35] = i * 8 + 3;
}

geometry.setAttribute(
'position',
new BufferAttribute(coordinates, 3)
);

geometry.setIndex(indices);

return new Mesh(
geometry,
new MeshLambertMaterial({
color: new Color(1, 1, 1).getHex()
})
);
``````

`coords` is an array of the corners of the cube (e.g: `[(x1min, y1min, z1min), (x1max, y1max, z1max), (x2min, y2min, z2min), (x2max, y2max, z2max)]`).

I’m using r124.

What am I doing wrong?

Do you mind demonstrating with a live example the runtime error? Use this as a starter template: https://jsfiddle.net/vy29n6aj/

@Mugen87 this is the live example: https://jsfiddle.net/gwqcj29f/2/

Use a box 1 x 1 x 1 and scale each instance of it individually.

Example: https://jsfiddle.net/prisoner849/qyj43wLn/
Picture:

@prisoner849 really thanks, but I’d love to know what is wrong with my polygon by polygon `BufferGeometry` (also, I guess that’d be faster). Anyway, if I didn’t discover how to do it (and anyone which read this post too) I’ll use your approach.

`indices` has to be `Array`, so instantiate it like this: `const indices = [];`
As internally. three.js has that check in `.setIndex()` method. So, when you pass `Int16Array`, `Array.isArray()` returns `false` and a buffer attribute for `.index` won’t be created.

Fixed example: https://jsfiddle.net/prisoner849/yocuesz6/

2 Likes

Thanks @prisoner849 this solved my problem, now I just need to fix the weird behavior, I guess that was my mistake when creating the indices.

The strange behavior is shown in the following live example: https://jsfiddle.net/jmc2edzL/

Yes, my mistake in creating the indices, working great now!

1 Like