ArrayMesh How to use Custom0, etc
Asked Answered
P

4

0

I'm trying to understand how the Custom0, etc array are configured in an ArrayMesh.

Issue 1: So the default is for custom arrays to be PackedByteArrays. So even though its not what I want to do ultimately, I have it set up where I put the data into a List<byte>() and then pass it in using ToArray(). However, when I do that I get this runtime error when I call RegenNormalMaps:
NativeCalls.cs:51 @ void Godot.NativeCalls.godot_icall_0_3(nint, nint): Extracting Byte/Half formats is not supported
<C++ Error> Condition "p_arrays[RenderingServer::ARRAY_CUSTOM0 + i].get_type() == Variant::PACKED_BYTE_ARRAY" is true. Continuing.
<C++ Source> scene/resources/surface_tool.cpp:857 @ create_vertex_array_from_triangle_arrays()

If I use anything other than a List<byte>, I instead get a runtime error when I call AddSurfaceFromArrays.

Issue 2: How do I accomplish configuring the format of the Custom arrays? The documentation is obtuse and borderline meaningless without a simple code example. I mean, I get this much:
arrayMesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles,
surfaceArray,
null,
lodDictionary
Mesh.ArrayFormat.FormatVertex |
Mesh.ArrayFormat.FormatNormal |
Mesh.ArrayFormat.FormatTexUV |
Mesh.ArrayFormat.FormatIndex |
Mesh.ArrayFormat.FormatCustom0);

But then you have:
Mesh.ArrayFormat.FormatCustomBits
Mesh.ArrayFormat.FormatCustomMask
Mesh.ArrayFormat.FormatCustom0Shift

But these are somehow used to pass values in, but we're doing a bitwise OR here do how am I using these to pass values? Also where does Mesh.ArrayCustomFormat actually come into play?

Polymorphism answered 13/2 at 18:34 Comment(0)
P
0

Polymorphism Haven't used custom vertex formats but the docs say (if I understood it correctly) that you need to left bit shift non-custom flags for the FormatCustomXShift bits when using custom vertex attributes.

Something like this (not tested):

var format = 
Mesh.ArrayFormat.FormatVertex |
Mesh.ArrayFormat.FormatNormal |
Mesh.ArrayFormat.FormatTexUV |
Mesh.ArrayFormat.FormatIndex ;

format = format << Mesh.ArrayFormat.FormatCustom0Shift;
format = format | Mesh.ArrayFormat.FormatCustom0;
Pull answered 13/2 at 19:25 Comment(0)
P
0

Pull
Yes! That's exactly what I needed. Look forward to trying that later. I'm glad you could make sense of what was written in the docs because this one code snippet says what 1000 words of documentation language can't. Thanks very much!

Polymorphism answered 13/2 at 20:30 Comment(0)
P
0

Polymorphism Please do report back if it worked. I'd like to know if this is actually correct. The wording in the docs could indeed be better and the whole approach of doing it with bitshifts is not ideal either. Hopefully they make this more straightforward in the future.

Pull answered 13/2 at 20:44 Comment(0)
P
0

Actual code appears to be like this:
`

	Mesh.ArrayFormat format = Mesh.ArrayFormat.FormatVertex |
				Mesh.ArrayFormat.FormatNormal |
				Mesh.ArrayFormat.FormatIndex |
				Mesh.ArrayFormat.FormatTexUV |
				Mesh.ArrayFormat.FormatTexUV2 |
				Mesh.ArrayFormat.FormatCustom0;
	
	format |= (Mesh.ArrayFormat)((int)Mesh.ArrayCustomFormat.RgbaFloat << (int)Mesh.ArrayFormat.FormatCustom0Shift);	

`
Everything needs to be typecast as int or the compiler balks at doing a bit shift with an enumeration.

The ArrayFormat.FormatCustom0 flag just tells it you are using a custom0 array, so just treat it normally.

You want to bit shift the ArrayCustomFormat (whichever format you want to use) - and only shift that value, not the entire format.

Thanks again xyz! Your untested code was more than enough to point me in the right direction. Just want to make sure the right answer is here.

Still not sure why I was getting issues with using a PackedByteArray but there is no issue using the format I actually wanted to use. So that will have to be someone else's problem for another day.

Polymorphism answered 13/2 at 20:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.