Jump to content

Why Int32Array instead of Uint32Array for mesh indices?


Kesshi
 Share

Recommended Posts

Why BabylonJs uses Int32Array for mesh indices?
WebGL (the OES_element_index_uint extension) requires unsigned values. Currently the Int32Array will be copied to an Uint32Array before it can be used:
https://github.com/BabylonJS/Babylon.js/blob/master/src/babylon.engine.ts#L1328
Wouldn't it be better to change it to Uint32Array? The array could be used directly then. ... or is ther any use for indices with negative value?

Link to comment
Share on other sites

Int32Array,Uint32Array,Float32Array,etc are all backed by a slab of bytes in memory (you can create an Uint32Array object that refers to the same memory as another Int32Array). OpenGL (that WebGL is ultimately based on and mostly implemented upon with the exception of libangle) is also a C api meaning that it doesn't really care about the type of data and will just consume it. If you fed data you've written through a Float32Array you'd get errornous results (or more probably nothing since GL is a tad bad at reporting errors).

In machine representation however Int32 and Uint32 are identical as long as the value is below 2147483648 (=2^31), the representations only different when dealing with numbers that has the highest bit set (the sign bit) but for all practical purposes you're not going to be dealing with meshes with over 2 billion vertices for the forseeable future.

Link to comment
Share on other sites

I know that :) Please read: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/TypedArray

Quote

When called with a typedArray argument, which can be an object of any of the typed array types (such as Int32Array), the typedArray gets copied into a new typed array. Each value in typedArray is converted to the corresponding type of the constructor before being copied into the new array. Then length of the new typedArray object will be same of length of the typedArray argument.

It seems that the Int32 values are not just interpreted as UInt32. The whole Int32 array will be copied into a new Uint32 array and the values are converted if you use the constructor like this. Thats why i'm asking this question. It would be faster to use an Uint32Array directly.

Link to comment
Share on other sites

WebGL will call out to C/C++ code and will just use the underlying buffer regardless of if your JavaScript code sees it as Uint32Array or Int32Array so no copies will be made. Buffers are just flat slabs of bytes and can be viewed in different ways.

If buffers are created or copied depends on what constructor you use(see the page you linked), if you use the typed array directly (as with regular arrays) you get a copy BUT if you use the underlying buffer object instead then you're instead given a view. The example below should show the difference in usage (you can test it in chrome,firefox or node)

var x=new Uint32Array([123]); // array copy construction
var y=new Int32Array(x);    // typed array copy construction 
y[0]=-44;
console.log(x[0]+","+y[0]);  // prints 123,-44

var z=new Int32Array(x.buffer); // using the view creation constructor (notice the buffer)
z[0]=145;
console.log(x[0]+","+y[0]+","+z[0]);  // prints 145,-44,145

z[0]=-145;
console.log(x[0]+","+y[0]+","+z[0]);  // prints 4294967151,-44,-145

In the first printout x[0] retains it's value since y got a separate buffer via the copy constructor.

For the second printout however x[0] has changed the value when we changed z[0] since they share the same underlying buffer, in this example you see why one can use either Int32Array or Uint32Array since the representation is the same for positive integers below 2^31.

The third printout again changes x[0] when z[0] is changed due to using the same buffer but this time the values shown are different, this is because negative numbers has the top sign bit set and this is where the unsigned and signed representations of 32bit integers differ.

For unsigned numbers the top bit means that the value is between 2^31 and 2^32-1 (2147483648 to 4294967295) whereas for signed numbers this means that the number is negative.

Anyhow, as i said before. For mesh indices you're unlikely to have 2147483648 indices or more so using Int32 or Uint32 won't matter much today.

Edited by whizzter
(wrote the wrong variable name in the text)
Link to comment
Share on other sites

Thank you for your explanation ... but i know this already before, i'm programming in c++ for many years.
I know that i don't need the full 32 bit integer range nowadays. The point is that currently the array will get copied (because the copy constructor is used) and this is wasting perfomance and memory in my opinion. Especially for big meshes.

 

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