New Mesh functions

Since the UI uses meshes now, my thoughts went like this: “OK, it uses meshes, that’s cool. But wait…CanvasRenderer.SetVertices can use Lists. We have to go back to fixed arrays? Surely not…” And indeed, the Mesh class now has stuff like SetVertices, which takes a List. So my questions are:

  1. Shouldn’t this be mentioned in the release notes? (And be in the docs?) It’s kind of a big deal for meshes in general, never mind the UI.
  2. Shouldn’t there be SetUV3 and SetUV4 functions?

–Eric

3 Likes

It should be and I’m doing that doc work today :wink:

We are doing a sanity check on the API atm, to make sure it’s what we want, when we are sure all the api points will be there.

1 Like

FYI:
It’s probably going to look like this:

void SetUVs (int channel /*1 - 4*/, List<Vector2> uvs)
2 Likes

Yep, that makes more sense. Cool!

–Eric

1 Like

While you’re in the Mesh code how about adding some methods that take a length. Please!

http://feedback.unity3d.com/suggestions/allow-mesh-data-to-have-a-length

2 Likes

Using Lists will make that redundant, no? A list is just an array+size internally anyway…

CanvasRenderer.SetVertices did have the ability to use both a List and an array with a length, so yes, it would be ideal for Mesh to have that as well. It’s not really redundant, since Lists are good for some use-cases but fixed-length arrays are significantly faster. (Yes, Lists are backed by arrays anyway, but for whatever reason, they’re slower.)

–Eric

1 Like

If there is a version that takes a size you can allocate a single static array for all your source data and use it for different target meshes. No garbage.

2 Likes
  • 100 on adding the ability to use Arrays with length.
1 Like

[quote=“Eric5h5, post:7, topic: 588569, username:Eric5h5”]
It’s not really redundant, since Lists are good for some use-cases but fixed-length arrays are significantly faster. (Yes, Lists are backed by arrays anyway, but for whatever reason, they’re slower.)
[/quote]I think we should probably just fix that. Faster for which operations?

(My guess is that accessing list elements incurs two bounds checks - one against the list size and one against the underlying array - but if that’s the cause then there’s got to be some way to eliminate that and just guarantee that the list size is always less than or equal to the array size).

[quote=“ecurtz, post:8, topic: 588569, username:ecurtz”]
If there is a version that takes a size you can allocate a single static array for all your source data and use it for different target meshes. No garbage.
[/quote]You can do exactly the same thing with a List.

Faster for accessing the elements in the collection, both reading and writing. How much faster depends on the type; e.g. int[ ] is 5-6X faster than List, and Vector3[ ] is about 2X faster than List. The more “complex” the type, the less of a difference there is.

–Eric

[quote=“Eric5h5, post:12, topic: 588569, username:Eric5h5”]
Faster for accessing the elements in the collection, both reading and writing. How much faster depends on the type; e.g. int[ ] is 5-6X faster than List, and Vector3[ ] is about 2X faster than List. The more “complex” the type, the less of a difference there is.
[/quote]Interesting. I’m going to have to try some experiments on that… my guess is that the more complex types are less cache-friendly so they’re more expensive to access overall, and as that cost goes up, the overhead of doing the extra bounds check becomes less significant. But we’ll see - 5-6x faster for basic int sounds more severe than the extra bounds check would really account for…

Why would you be bounds checking each element anyway? This should be the C# equivalent of a memcpy().

i need the ability to have a big static array and assign only a part of it dynamically to the mesh. currently i have to copy it to a garbage array with the desired length. most flexibility would be to have setvertices(buffer, offset, length) and so on

I don’t think bounds checking is the problem. Arrays in c# are bounds checked in order to throw index out of range exceptions.

I can see this being a design paradigm that Unity struggles with often. Do they make the interface that is easier to use or the one that is more efficient. In this case, I feel that this would primarily be used by power users and thus the more efficient interface would be preferred.

How would you do that with a list?

A list is a static array. The amount of memory used will not change unless you add more items than the list capacity (which is 4 items by default), in which case the items are copied to a new array that’s double the size of the old one, and the old array is garbage collected. Reducing the number of items in a list doesn’t change the array size at all (unless you manually call TrimExcess). So if you have code like

var verts = new List<Vector3>(1000);

then you have a static array with 1000 entries. Adding/removing items won’t change this, unless you exceed 1000 entries, in which case you then have a static array with 2000 entries. All of this happens behind the scenes, so it looks like lists are dynamic, but they’re really not; they’re just arrays. (But slower for some reason.)

–Eric

2 Likes

Yeah, but when you rebuild your mesh dynamically you’d have to use List.Add() instead of accessing via an index (which is much more flexible, readable and debuggable). I’d prefer a memcopy-like syntax.

1 Like

+1 on array with length syntax. List<T> is just a specific case of that, and it’s inefficient if you are doing a ton of dynamic mesh updates in realtime. Also, I’m using my own version of List<T>, so that’d automatically mean I won’t be able to use it for mesh data. At the very least, make it IList<T>, not just List<T>.