Hi, @caroline
Thank you very much for confirming my src code and data!
With this project I was able to look at the buffer on the GPU, and I think it’s actually four floats making up a vertex, not three.
Changing the vertex descriptor to a float4 got this:
It’s weird that changing from float3 to float4 worked somehow.
The app I created using Unity is parsing the binary data into a Vector3 array. and it works well.
I cannot figure out why 4 floats are necessary for one vertex.
I tried to read the demo project you created and investigate the data sent to GPU, and it seems that there’s one vertex data missing.
(The length of float array is 96234, so the number of vertex data is 96234 / 3 = 32078,
so I think the correct last index of vertex data should be 32077, am I wrong?)
I attached the Unity script here, and what I want to do is converting the unity project to iOS native code. (I removed the unnecessary parts) hope it can help.
public class BinaryMeshDataLoader
{
private int[] indices;
private TextAsset indexTextAsset;
private ComputeShader meshGenerateCS;
private int kernelHandle;
private Matrix4x4 transformation;
public void Init(TextAsset textAsset, Matrix4x4 transformation)
{
if (indexTextAsset != textAsset)
{
indexTextAsset = textAsset;
}
this.transformation = transformation;
if(!meshGenerateCS)
{
meshGenerateCS = Resources.Load<ComputeShader>("MeshCompute");
kernelHandle = meshGenerateCS.FindKernel("CSMain");
}
}
public Mesh LoadData(byte[] modelData)
{
if(modelData is null || !indexTextAsset)
{
return null;
}
if (indices == null || indices.Length == 0)
{
indices = ReadIndexFile();
}
var newMesh = GenerateMesh(model.data);
return newMesh;
}
private Mesh GenerateMesh(byte[] buffer)
{
if(buffer == null || buffer.Length == 0)
{
return null;
}
Vector3[] vertexArray = new Vector3[buffer.Length / 12];
ComputeBuffer dataBuf = new ComputeBuffer(buffer.Length / 12, 12);
dataBuf.SetData(buffer);
meshGenerateCS.SetBuffer(kernelHandle, "RawDataBuffer", dataBuf);
meshGenerateCS.SetMatrix("Transformation", transformation);
meshGenerateCS.SetInt("Size", buffer.Length / 12);
meshGenerateCS.Dispatch(kernelHandle, buffer.Length / 12, 1, 1);
dataBuf.GetData(vertexArray);
Mesh newMesh = new Mesh();
newMesh.vertices = vertexArray;
newMesh.triangles = indices;
newMesh.RecalculateNormals();
newMesh.RecalculateBounds();
dataBuf.Dispose();
return newMesh;
}
private int[] ReadIndexFile()
{
List<int> indexList = new List<int>();
var lines = indexTextAsset.text.Split('\n');
foreach(var line in lines)
{
char startLetter = line[0];
if(startLetter == 'g')
{
continue;
}
string _line = line.TrimEnd('\r', '\n');
var indices = GetIndices(_line);
indexList.AddRange(indices);
}
return indexList.ToArray();
}
private int[] GetIndices(string line)
{
var faceElements = line.Split(' ');
var index0 = int.Parse(faceElements[1].Split('/')[0]) - 1;
var index1 = int.Parse(faceElements[2].Split('/')[0]) - 1;
var index2 = int.Parse(faceElements[3].Split('/')[0]) - 1;
var index3 = int.Parse(faceElements[4].Split('/')[0]) - 1;
return new int[] { index0, index1, index2, index0, index2, index3 };
}
}
And compute shader code here:
#pragma kernel CSMain
RWStructuredBuffer<float3> RawDataBuffer;
float4x4 Transformation;
uint Size;
[numthreads(16,1,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
if(id.x < Size)
{
RawDataBuffer[id.x] = mul(Transformation, float4(RawDataBuffer[id.x], 1.0));
}
}