Whare are verticiesStart and verticiesCount params on SubMesh constructor?

I’m trying to understand this example:

https://playground.babylonjs.com/#T40FK

specifically the near final lines:

	box.subMeshes=[];
	var verticesCount=box.getTotalVertices();
	box.subMeshes.push(new BABYLON.SubMesh(0, 0, verticesCount, 0, 6, box));
	box.subMeshes.push(new BABYLON.SubMesh(1, 1, verticesCount, 6, 6, box));
	box.subMeshes.push(new BABYLON.SubMesh(2, 2, verticesCount, 12, 6, box));
	box.subMeshes.push(new BABYLON.SubMesh(3, 3, verticesCount, 18, 6, box));
	box.subMeshes.push(new BABYLON.SubMesh(4, 4, verticesCount, 24, 6, box));
	box.subMeshes.push(new BABYLON.SubMesh(5, 5, verticesCount, 30, 6, box));

I understand SubMesh’s first constructor parameter is identifying the material to use. I understand that params 4-5 define which indices in the parent mesh’s vertex data the sub mesh constitutes. But I’m not sure what is going on with params 2-3: verticiesStart and verticiesCount. Can someone please expand on their use?

When defining a subMesh, verticesStart identifies the number of the first vertex to begin to draw the mesh and apply the defined material. If you’re not familiar with vertex ordering, all vertices on a mesh are ordered beginning at 0 and ending up at n (the last vertex). By default, these are in numerical sequence across a mesh; although you can reorder them if you like - which often happens in operations such as booleens.

As for verticesCount, this simply defines that you are setting a range between the start and end identifiers of vertices. I personally never understood the need to set verticesCount as a parameter, however it is essential within this operation.

Galen

I guess I don’t understand the difference between vertices and indices then, because I thought that was what the indices do. What is the difference then?

Vertices and Indices are somewhat interchangeable terms… to a point. Vertices generally represent the physical components that exist in space, and Indices are generally the points reference by an indexed number. However, they both represent the same component in a slightly different way.

If you refer the either, you are correct. It’s all in the context. I hope this makes sense.

Galen

A vertex is a point, ie a position in 3D space. A vertex is defined by three numbers x, y, z. The vertex data positions array stores these sets of numbers. An index of a vertex is a number giving its place in this array. Each triangular facet requires three vertices each defined by a set of three indices. Create Custom Meshes - Babylon.js Documentation

In https://playground.babylonjs.com/#T40FK#97 the I have changed all the parameter 2 numbers to 0 and in terms of drawing the mesh you will see no difference. In this case parameters 2 and 3 are giving the full range of vertices from 0 to the last index.

Like Galen I not not fully sure what changing this range achieves. Here I have put in a more random set of ranges for parameters 2 and 3 and the mesh is still drawn as you would expect.

The clue (and for me it is only a clue at the moment) is the sentence (To optimize things for collisions for instance) from Use Multi-Materials - Babylon.js Documentation.

My conclusion is that if you are not doing collisions or raycasts or something else as yet undetermined then stick to 0, verticesCount for parameters 2 and 3.

Here’s where it should make sense.

https://www.babylonjs-playground.com/#2Q4S2S#43

I changed the ending vertex value on line 29 from 900 to 500. Now there is no material assigned to vertices indexed 501 - 899, so the mesh isn’t drawn. If you set this value back to 900, then the entire sphere is drawn. This is not only useful for multi materials, but to draw partial meshes! I love this feature!

Galen

That was sort of my mental model as well. But this raises the question then about why a SubMesh would require information about both to the constructor. They seem to be a restatement of the same information.

I’m not certain what you’re referring to as “both”. But if it’s the start and end, then you do need both. However, as I mentioned before, I still don’t see why verticesCount is set as a parameter.

Galen

No, I mean both the vertices parameters and the indices parameters to the SubMesh constructor. Aren’t they both just saying “these are the points that define the submesh” ? Wouldn’t they always have to be in sync with each other?

I know, it gets a bit confusing. The index is not an index of the mesh, but an index which refers to the material to be applied. If you change the material index to any index that is not defined, then it defaults to the default grey material. However, if you create a new material and push it to the matrial array, you can then call this as a new indexed material to be applied. This is incredibly powerful once you begin to build more complex materials.

Now does it make sense?

Galen

It looks like we can even use -1 for param values 2-3 with no observable effect. It sounds like the bottom line is we don’t know what these parameters do.

https://playground.babylonjs.com/#T40FK#101

Value 2 is a parameter that sets the index of the first vertex, and value 3 is a parameter which sets the # of vertices from the first vertex to be affected. However, this is redundant and affects nothing except when you leave these parameters empty. This must be old code that should be removed from the framework. I’ll take a look at the 4.0 release code and see if I can simplify. No need to leave unused legacy code.

Galen

In looking at the babylon.ts file, modifying this function is a bit more complicated than I expected; verticesStart and verticesCount are called in many draw functions which drawing subMeshes appear to be dependent. So it appears the reason these parameters exist in the function are due to these dependencies in the render loop. It appears to be to much work at this point to modify the hundreds of draw functions called in the render loop.

It’s much easier to simply keep the parameters declared in the function.

Galen

If they are used during rendering, why does setting them to -1 or 0 not impact what we see on the canvas?

In reading the babylon.ts file, the values aren’t obviously used, however the draw function looks for these values to be declared; even though it’s not used to calculate the sub mesh. subMeshes are called 432 times in the babylon.ts file; separate from using the API to create subMeshes within your scene.

Removing these values from the function causes an error in the render loop. So the good news is that we know what these values are and why they exist, and also know that we simply need to include them and we can make use of sub meshes.:grinning:

Galen

This makes is sound like they have an effect on rendering and we should not use arbitrary values.

And this makes it sound like they do not.

I’m still confused as to whether it is safe to just use a constant like 0 or -1 in all cases of constructing SubMesh.

It’s perfectly safe to set these values to any whole # constant in the subMeshes function. They are not considered, but need to exist in the render loop. They are simply overwritten by the vertices you declare in the start and end vertices in parameters 4 & 5.

Just think of these as needed to be declared and the draw function will as always see these as false; regardless of any value set. This is often the case with many functions. The first vertex is necessary in most of the draw functions in the framework. However, the subMeshes function provides for the ability to attach attributes to various regions of a mesh for render.

Galen

Should the constructor’s implementation be changed then to not take these parameters and instead set the internal properties to -1?

As you mention, the only thing that could be reasonably done is to set these parameters in the function without the need to user input. But this is not a good solution, as this only adds to the size of the framework; which we want to keep as small as possible.

Galen