How to set custom stride and offset for NativeSlice

Hi. Is there any method for changing/set custom stride for NativeSlice?

In detail, I’m trying to copy/modify of low level Mesh data, via VertexBufferData. But need to be handled as dynamically, so I can’t pre-declare struct type for VertexBufferData and need to handle as NativeArray.

In this case, how to get NativeSlice which has specific stride and offset?

Data layout of source NativeArray:
|position(12byte)|normal(12byte)| other fields (x bytes)|position(12byte)|normal(12byte)| other fields (x bytes)| …

How to get NativeSlice for normal from above NativeArray?
I think that it should have 24+x stride and 12 offset, but how?

Any ideas are welcome.

Thanks.

1 Like

NativeSlice is looks like it’s just a ‘SubArray’ a ‘window’ into another array. So NativeSlice(myarray, 0, 2) would mean when I access the array there’s 2 float3’s at the start of the array (and myarray would be NativeArray). I haven’t tested this yet, but it looks like that’s what it’s meant for.

But you could always use interop structs possibly? Using [StructLayout(LayoutKind.Explicit)] on the class and [FieldOffset(byteOffset)] on the fields?

Thanks for reply. The problem is that [StructLayout] and [FieldOffset] need to be declared into struct type, so it can’t be used dynamically.

So if I want to manipulate mesh data which is combination of multiple data type, it should be declared as struct for all combination like:
struct MeshVertexPositionFloat16Normal16 {}
struct MeshVertexPositionFloat16Normal32 {}
struct MeshVertexPositionFloat32Normal16 {}
struct MeshVertexPositionFloat32Normal32 {}

[StructLayout(LayoutKind.Explicit)]
struct MeshVertexPosition {
  [FieldOffset(0)] public float4 f_normals;
  [FieldOffset(0)] public double4 d_normals;
} // Struct //

Then use myPos.f_normals if you want to use the float version or d_normals for the doubles? Or am I misunderstanding something? (and if so I apologize!)

Your approach has not problem if the vertex has single element (position only or normal only):slight_smile:

But if the vertex has multiple element, like both position+normal or position+normal+tangent, if I change data size of position, the offset of normal should be changed too for being packed tightly.

My goal is that using SetVertexBufferData dynamically.
https://docs.unity3d.com/ScriptReference/Mesh.SetVertexBufferData.html

Currently, I split stream number so each element can be set separately but I can’t sure it is safe and performant.

Oh I see, you want to use it with SetVertexBufferData… Well, that’s really not gonna happen unfortunately… Internally (if I remember correctly from when I made a Game Engine with OpenGL 3), it sets stride parameters in the vertex buffer data… So it’ll always need a specific size. If you need a different struct, you’ll have to set it again with the new type.

Will just have to do a switch/case or lookup based on enum or similar? That’s what I would do. When enum changed, it will select the array that holds the struct necessary, then call SetVertexBufferData with it. Then maybe have a getter to retrieve the struct type and enum?

It’s a bit late for me haha, but I hope you manage to solve your problem!

1 Like