Skip to content

Commit 009cb16

Browse files
committed
Added Mesh vertex size and channels
1 parent 3c9fab4 commit 009cb16

File tree

15 files changed

+517
-55
lines changed

15 files changed

+517
-55
lines changed

Analyzer.Tests/ExpectedData/2019.4.0f1/ExpectedValues.json

+24-1
Original file line numberDiff line numberDiff line change
@@ -2386,7 +2386,30 @@
23862386
"Indices": 3840,
23872387
"Vertices": 797,
23882388
"Compression": 0,
2389-
"RwEnabled": false
2389+
"RwEnabled": false,
2390+
"Channels": {
2391+
"$type": "System.Collections.Generic.List`1[[UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer]], System.Private.CoreLib",
2392+
"$values": [
2393+
{
2394+
"$type": "UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer",
2395+
"Usage": 0,
2396+
"Type": 0,
2397+
"Dimension": 3
2398+
},
2399+
{
2400+
"$type": "UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer",
2401+
"Usage": 1,
2402+
"Type": 1,
2403+
"Dimension": 3
2404+
},
2405+
{
2406+
"$type": "UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer",
2407+
"Usage": 4,
2408+
"Type": 1,
2409+
"Dimension": 2
2410+
}
2411+
]
2412+
}
23902413
},
23912414
"AudioClip": {
23922415
"$type": "UnityDataTools.Analyzer.SerializedObjects.AudioClip, Analyzer",

Analyzer.Tests/ExpectedData/2020.3.0f1/ExpectedValues.json

+24-1
Original file line numberDiff line numberDiff line change
@@ -1292,7 +1292,30 @@
12921292
"Indices": 3840,
12931293
"Vertices": 797,
12941294
"Compression": 0,
1295-
"RwEnabled": false
1295+
"RwEnabled": false,
1296+
"Channels": {
1297+
"$type": "System.Collections.Generic.List`1[[UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer]], System.Private.CoreLib",
1298+
"$values": [
1299+
{
1300+
"$type": "UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer",
1301+
"Usage": 0,
1302+
"Type": 0,
1303+
"Dimension": 3
1304+
},
1305+
{
1306+
"$type": "UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer",
1307+
"Usage": 1,
1308+
"Type": 1,
1309+
"Dimension": 3
1310+
},
1311+
{
1312+
"$type": "UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer",
1313+
"Usage": 4,
1314+
"Type": 1,
1315+
"Dimension": 2
1316+
}
1317+
]
1318+
}
12961319
},
12971320
"AudioClip": {
12981321
"$type": "UnityDataTools.Analyzer.SerializedObjects.AudioClip, Analyzer",

Analyzer.Tests/ExpectedData/2021.3.0f1/ExpectedValues.json

+24-1
Original file line numberDiff line numberDiff line change
@@ -1292,7 +1292,30 @@
12921292
"Indices": 3840,
12931293
"Vertices": 797,
12941294
"Compression": 0,
1295-
"RwEnabled": false
1295+
"RwEnabled": false,
1296+
"Channels": {
1297+
"$type": "System.Collections.Generic.List`1[[UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer]], System.Private.CoreLib",
1298+
"$values": [
1299+
{
1300+
"$type": "UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer",
1301+
"Usage": 0,
1302+
"Type": 0,
1303+
"Dimension": 3
1304+
},
1305+
{
1306+
"$type": "UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer",
1307+
"Usage": 1,
1308+
"Type": 1,
1309+
"Dimension": 3
1310+
},
1311+
{
1312+
"$type": "UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer",
1313+
"Usage": 4,
1314+
"Type": 1,
1315+
"Dimension": 2
1316+
}
1317+
]
1318+
}
12961319
},
12971320
"AudioClip": {
12981321
"$type": "UnityDataTools.Analyzer.SerializedObjects.AudioClip, Analyzer",

Analyzer.Tests/ExpectedData/2022.1.20f1/ExpectedValues.json

+30-1
Original file line numberDiff line numberDiff line change
@@ -1292,7 +1292,36 @@
12921292
"Indices": 3840,
12931293
"Vertices": 797,
12941294
"Compression": 0,
1295-
"RwEnabled": false
1295+
"RwEnabled": false,
1296+
"Channels": {
1297+
"$type": "System.Collections.Generic.List`1[[UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer]], System.Private.CoreLib",
1298+
"$values": [
1299+
{
1300+
"$type": "UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer",
1301+
"Usage": 0,
1302+
"Type": 0,
1303+
"Dimension": 3
1304+
},
1305+
{
1306+
"$type": "UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer",
1307+
"Usage": 1,
1308+
"Type": 1,
1309+
"Dimension": 3
1310+
},
1311+
{
1312+
"$type": "UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer",
1313+
"Usage": 2,
1314+
"Type": 1,
1315+
"Dimension": 4
1316+
},
1317+
{
1318+
"$type": "UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer",
1319+
"Usage": 4,
1320+
"Type": 1,
1321+
"Dimension": 2
1322+
}
1323+
]
1324+
}
12961325
},
12971326
"AudioClip": {
12981327
"$type": "UnityDataTools.Analyzer.SerializedObjects.AudioClip, Analyzer",

Analyzer.Tests/ExpectedData/2023.1.0a16/ExpectedValues.json

+24-1
Original file line numberDiff line numberDiff line change
@@ -1457,7 +1457,30 @@
14571457
"Indices": 3840,
14581458
"Vertices": 797,
14591459
"Compression": 0,
1460-
"RwEnabled": false
1460+
"RwEnabled": false,
1461+
"Channels": {
1462+
"$type": "System.Collections.Generic.List`1[[UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer]], System.Private.CoreLib",
1463+
"$values": [
1464+
{
1465+
"$type": "UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer",
1466+
"Usage": 0,
1467+
"Type": 0,
1468+
"Dimension": 3
1469+
},
1470+
{
1471+
"$type": "UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer",
1472+
"Usage": 1,
1473+
"Type": 1,
1474+
"Dimension": 3
1475+
},
1476+
{
1477+
"$type": "UnityDataTools.Analyzer.SerializedObjects.Mesh+Channel, Analyzer",
1478+
"Usage": 4,
1479+
"Type": 1,
1480+
"Dimension": 2
1481+
}
1482+
]
1483+
}
14611484
},
14621485
"AudioClip": {
14631486
"$type": "UnityDataTools.Analyzer.SerializedObjects.AudioClip, Analyzer",

Analyzer.Tests/SerializedObjectsTests.cs

+12
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ public void TestMesh()
130130
Assert.AreEqual(expectedMesh.BlendShapes, mesh.BlendShapes);
131131
Assert.AreEqual(expectedMesh.RwEnabled, mesh.RwEnabled);
132132
Assert.AreEqual(expectedMesh.StreamDataSize, mesh.StreamDataSize);
133+
134+
Assert.AreEqual(expectedMesh.Channels.Count, mesh.Channels.Count);
135+
136+
for (int i = 0; i < mesh.Channels.Count; ++i)
137+
{
138+
var channel = mesh.Channels[i];
139+
var expectedChannel = expectedMesh.Channels[i];
140+
141+
Assert.AreEqual(expectedChannel.Dimension, channel.Dimension);
142+
Assert.AreEqual(expectedChannel.Type, channel.Type);
143+
Assert.AreEqual(expectedChannel.Usage, channel.Usage);
144+
}
133145
}
134146

135147
[Test]

Analyzer/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ the *object_view*, with the addition of:
108108
* vertices: the number of vertices
109109
* compression: 1 if compressed, 0 otherwise
110110
* rw_enabled: 1 if the mesh has the *R/W Enabled* option, 0 otherwise
111+
* vertex_size: number of bytes used by each vertex
112+
* channels: name and type of the vertex channels
111113

112114
## texture_view (Texture2DProcessor)
113115

Analyzer/Resources/Mesh.sql

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
vertices INTEGER,
88
compression INTEGER,
99
rw_enabled INTEGER,
10+
vertex_size INTEGER,
11+
channels TEXT,
1012
PRIMARY KEY (id)
1113
);
1214

@@ -19,6 +21,8 @@ SELECT
1921
m.indices,
2022
m.vertices,
2123
m.compression,
22-
m.rw_enabled
24+
m.rw_enabled,
25+
m.vertex_size,
26+
m.channels
2327
FROM meshes m
2428
INNER JOIN object_view o ON o.id = m.id;

Analyzer/SQLite/Handlers/MeshHandler.cs

+18-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Data;
44
using System.Data.SQLite;
5+
using System.Text;
56
using UnityDataTools.Analyzer.SerializedObjects;
67
using UnityDataTools.FileSystem.TypeTreeReaders;
78

@@ -19,7 +20,7 @@ public void Init(SQLiteConnection db)
1920
command.ExecuteNonQuery();
2021

2122
m_InsertCommand = new SQLiteCommand(db);
22-
m_InsertCommand.CommandText = "INSERT INTO meshes(id, sub_meshes, blend_shapes, bones, indices, vertices, compression, rw_enabled) VALUES(@id, @sub_meshes, @blend_shapes, @bones, @indices, @vertices, @compression, @rw_enabled)";
23+
m_InsertCommand.CommandText = "INSERT INTO meshes(id, sub_meshes, blend_shapes, bones, indices, vertices, compression, rw_enabled, vertex_size, channels) VALUES(@id, @sub_meshes, @blend_shapes, @bones, @indices, @vertices, @compression, @rw_enabled, @vertex_size, @channels)";
2324
m_InsertCommand.Parameters.Add("@id", DbType.Int64);
2425
m_InsertCommand.Parameters.Add("@sub_meshes", DbType.Int32);
2526
m_InsertCommand.Parameters.Add("@blend_shapes", DbType.Int32);
@@ -28,6 +29,8 @@ public void Init(SQLiteConnection db)
2829
m_InsertCommand.Parameters.Add("@vertices", DbType.Int32);
2930
m_InsertCommand.Parameters.Add("@compression", DbType.Int32);
3031
m_InsertCommand.Parameters.Add("@rw_enabled", DbType.Int32);
32+
m_InsertCommand.Parameters.Add("@vertex_size", DbType.Int32);
33+
m_InsertCommand.Parameters.Add("@channels", DbType.String);
3134
}
3235

3336
public void Process(Context ctx, long objectId, RandomAccessReader reader, out string name, out long streamDataSize)
@@ -42,6 +45,20 @@ public void Process(Context ctx, long objectId, RandomAccessReader reader, out s
4245
m_InsertCommand.Parameters["@bones"].Value = mesh.Bones;
4346
m_InsertCommand.Parameters["@compression"].Value = mesh.Compression;
4447
m_InsertCommand.Parameters["@rw_enabled"].Value = mesh.RwEnabled;
48+
m_InsertCommand.Parameters["@vertex_size"].Value = mesh.VertexSize;
49+
50+
StringBuilder channels = new StringBuilder();
51+
foreach (var channel in mesh.Channels)
52+
{
53+
channels.Append(channel.Usage.ToString());
54+
channels.Append(' ');
55+
channels.Append(channel.Type.ToString());
56+
channels.Append('[');
57+
channels.Append(channel.Dimension);
58+
channels.AppendLine("]");
59+
}
60+
61+
m_InsertCommand.Parameters["@channels"].Value = channels;
4562

4663
m_InsertCommand.ExecuteNonQuery();
4764

Analyzer/SerializedObjects/Mesh.cs

+97-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,52 @@
1+
using System;
2+
using System.Collections.Generic;
13
using UnityDataTools.FileSystem.TypeTreeReaders;
24

35
namespace UnityDataTools.Analyzer.SerializedObjects;
46

57
public class Mesh
68
{
9+
public enum ChannelUsage
10+
{
11+
Vertex,
12+
Normal,
13+
Tangent,
14+
Color,
15+
TexCoord0,
16+
TexCoord1,
17+
TexCoord2,
18+
TexCoord3,
19+
TexCoord4,
20+
TexCoord5,
21+
TexCoord6,
22+
TexCoord7,
23+
BlendWeights,
24+
BlendIndices,
25+
};
26+
27+
public enum ChannelType
28+
{
29+
Float,
30+
Float16,
31+
UNorm8,
32+
SNorm8,
33+
UNorm16,
34+
SNorm16,
35+
UInt8,
36+
SInt8,
37+
UInt16,
38+
SInt16,
39+
UInt32,
40+
SInt32,
41+
};
42+
43+
public class Channel
44+
{
45+
public ChannelUsage Usage;
46+
public ChannelType Type;
47+
public int Dimension;
48+
}
49+
750
public string Name { get; init; }
851
public int StreamDataSize { get; init; }
952
public int SubMeshes { get; init; }
@@ -13,16 +56,38 @@ public class Mesh
1356
public int Vertices { get; init; }
1457
public int Compression { get; init; }
1558
public bool RwEnabled { get; init; }
59+
60+
public IReadOnlyList<Channel> Channels { get; init; }
61+
62+
public int VertexSize { get; init; }
63+
64+
private static readonly int[] s_ChannelTypeSizes =
65+
{
66+
4, // Float
67+
2, // Float16
68+
1, // UNorm8
69+
1, // SNorm8
70+
2, // UNorm16
71+
2, // SNorm16
72+
1, // UInt8
73+
1, // SInt8
74+
2, // UInt16
75+
2, // SInt16
76+
4, // UInt32
77+
4, // SInt32
78+
};
1679

1780
private Mesh() {}
1881

1982
public static Mesh Read(RandomAccessReader reader)
2083
{
2184
var name = reader["m_Name"].GetValue<string>();
2285
var compression = reader["m_MeshCompression"].GetValue<byte>();
86+
var channels = new List<Channel>();
2387
int indices;
2488
int vertices;
2589
int streamDataSize = 0;
90+
int vertexSize = 0;
2691

2792
if (compression == 0)
2893
{
@@ -36,6 +101,35 @@ public static Mesh Read(RandomAccessReader reader)
36101
{
37102
streamDataSize = reader["m_StreamData"]["size"].GetValue<int>();
38103
}
104+
105+
int i = 0;
106+
foreach (var channel in reader["m_VertexData"]["m_Channels"])
107+
{
108+
int dimension = channel["dimension"].GetValue<byte>();
109+
110+
if (dimension != 0)
111+
{
112+
// The dimension can be padded. In that case, the real dimension
113+
// is encoded in the top nibble.
114+
int originalDim = (dimension >> 4) & 0xF;
115+
if (originalDim != 0)
116+
{
117+
dimension = originalDim;
118+
}
119+
120+
var c = new Channel()
121+
{
122+
Dimension = dimension,
123+
Type = (ChannelType)channel["format"].GetValue<byte>(),
124+
Usage = (ChannelUsage)i,
125+
};
126+
127+
channels.Add(c);
128+
vertexSize += dimension * s_ChannelTypeSizes[(int)c.Type];
129+
}
130+
131+
++i;
132+
}
39133
}
40134
else
41135
{
@@ -52,7 +146,9 @@ public static Mesh Read(RandomAccessReader reader)
52146
SubMeshes = reader["m_SubMeshes"].GetArraySize(),
53147
BlendShapes = reader["m_Shapes"]["shapes"].GetArraySize(),
54148
Bones = reader["m_BoneNameHashes"].GetArraySize(),
55-
RwEnabled = reader["m_IsReadable"].GetValue<int>() != 0
149+
RwEnabled = reader["m_IsReadable"].GetValue<int>() != 0,
150+
Channels = channels,
151+
VertexSize = vertexSize,
56152
};
57153
}
58154
}

0 commit comments

Comments
 (0)