4 using System.Collections.Generic;
11 [SerializeField, HideInInspector]
12 private byte[] m_Data;
14 public byte[]
Data {
get{
return m_Data; } }
21 m_Data = MeshSerializer.SerializeMesh(m_Mesh);
25 if (m_Mesh ==
null && m_Data !=
null)
26 m_Mesh = MeshSerializer.DeserializeMesh(m_Data);
32 public static class MeshSerializer
77 private enum EChunkID :
byte
90 const uint m_Magic = 0x6873654D;
92 public static byte[] SerializeMesh(Mesh aMesh)
94 using (var stream =
new MemoryStream())
96 SerializeMesh(stream, aMesh);
97 return stream.ToArray();
100 public static void SerializeMesh(MemoryStream aStream, Mesh aMesh)
102 using (var writer =
new BinaryWriter(aStream))
103 SerializeMesh(writer, aMesh);
105 public static void SerializeMesh(BinaryWriter aWriter, Mesh aMesh)
107 aWriter.Write(m_Magic);
108 var vertices = aMesh.vertices;
109 int count = vertices.Length;
110 int subMeshCount = aMesh.subMeshCount;
111 aWriter.Write(count);
112 aWriter.Write(subMeshCount);
113 foreach (var v
in vertices)
114 aWriter.WriteVector3(v);
117 if (!
string.IsNullOrEmpty(aMesh.name))
119 aWriter.Write((
byte)EChunkID.Name);
120 aWriter.Write(aMesh.name);
122 var normals = aMesh.normals;
123 if (normals !=
null && normals.Length == count)
125 aWriter.Write((
byte)EChunkID.Normals);
126 foreach (var v
in normals)
127 aWriter.WriteVector3(v);
130 var tangents = aMesh.tangents;
131 if (tangents !=
null && tangents.Length == count)
133 aWriter.Write((
byte)EChunkID.Tangents);
134 foreach (var v
in tangents)
135 aWriter.WriteVector4(v);
138 var colors = aMesh.colors32;
139 if (colors !=
null && colors.Length == count)
141 aWriter.Write((
byte)EChunkID.Colors);
142 foreach (var c
in colors)
143 aWriter.WriteColor32(c);
146 var boneWeights = aMesh.boneWeights;
147 if (boneWeights !=
null && boneWeights.Length == count)
149 aWriter.Write((
byte)EChunkID.BoneWeights);
150 foreach (var w
in boneWeights)
151 aWriter.WriteBoneWeight(w);
154 List<Vector4> uvs =
new List<Vector4>();
155 for (
int i = 0; i < 4; i++)
158 aMesh.GetUVs(i, uvs);
159 if (uvs.Count == count)
161 aWriter.Write((
byte)((
byte)EChunkID.UV0 + i));
162 byte channelCount = 2;
163 foreach (var uv
in uvs)
173 aWriter.Write(channelCount);
174 if (channelCount == 2)
175 foreach (var uv
in uvs)
176 aWriter.WriteVector2(uv);
177 else if (channelCount == 3)
178 foreach (var uv
in uvs)
179 aWriter.WriteVector3(uv);
181 foreach (var uv
in uvs)
182 aWriter.WriteVector4(uv);
185 List<int> indices =
new List<int>(count * 3);
186 for (
int i = 0; i < subMeshCount; i++)
189 aMesh.GetIndices(indices, i);
190 if (indices.Count > 0)
192 aWriter.Write((
byte)EChunkID.Submesh);
193 aWriter.Write((
byte)aMesh.GetTopology(i));
194 aWriter.Write(indices.Count);
195 var max = indices.Max();
198 aWriter.Write((
byte)1);
199 foreach (var index
in indices)
200 aWriter.Write((
byte)index);
202 else if (max < 65536)
204 aWriter.Write((
byte)2);
205 foreach (var index
in indices)
206 aWriter.Write((ushort)index);
210 aWriter.Write((
byte)4);
211 foreach (var index
in indices)
212 aWriter.Write(index);
216 var bindposes = aMesh.bindposes;
217 if (bindposes !=
null && bindposes.Length > 0)
219 aWriter.Write((
byte)EChunkID.Bindposes);
220 aWriter.Write(bindposes.Length);
221 foreach (var b
in bindposes)
222 aWriter.WriteMatrix4x4(b);
225 int blendShapeCount = aMesh.blendShapeCount;
226 if (blendShapeCount > 0)
228 var blendVerts =
new Vector3[count];
229 var blendNormals =
new Vector3[count];
230 var blendTangents =
new Vector3[count];
231 for (
int i = 0; i < blendShapeCount; i++)
233 aWriter.Write((
byte)EChunkID.BlendShape);
234 aWriter.Write(aMesh.GetBlendShapeName(i));
235 var frameCount = aMesh.GetBlendShapeFrameCount(i);
236 aWriter.Write(frameCount);
237 for (
int n = 0; n < frameCount; n++)
239 aMesh.GetBlendShapeFrameVertices(i, n, blendVerts, blendNormals, blendTangents);
240 aWriter.Write(aMesh.GetBlendShapeFrameWeight(i, n));
241 for (
int k = 0; k < count; k++)
243 aWriter.WriteVector3(blendVerts[k]);
244 aWriter.WriteVector3(blendNormals[k]);
245 aWriter.WriteVector3(blendTangents[k]);
250 aWriter.Write((
byte)EChunkID.End);
254 public static Mesh DeserializeMesh(
byte[] aData, Mesh aTarget =
null)
256 using (var stream =
new MemoryStream(aData))
257 return DeserializeMesh(stream, aTarget);
259 public static Mesh DeserializeMesh(MemoryStream aStream, Mesh aTarget =
null)
261 using (var reader =
new BinaryReader(aStream))
262 return DeserializeMesh(reader, aTarget);
264 public static Mesh DeserializeMesh(BinaryReader aReader, Mesh aTarget =
null)
266 if (aReader.BaseStream ==
null || aReader.BaseStream.Length == 0)
269 if (aReader.ReadUInt32() != m_Magic)
272 aTarget =
new Mesh();
274 aTarget.ClearBlendShapes();
275 int count = aReader.ReadInt32();
277 aTarget.indexFormat =
UnityEngine.Rendering.IndexFormat.UInt32;
278 int subMeshCount = aReader.ReadInt32();
280 Vector3[] vector3Array2 =
null;
281 Vector3[] vector3Array3 =
null;
282 List<Vector4> vector4List =
null;
283 for (
int i = 0; i < count; i++)
284 vector3Array[i] = aReader.ReadVector3();
285 aTarget.vertices = vector3Array;
286 aTarget.subMeshCount = subMeshCount;
287 int subMeshIndex = 0;
288 byte componentCount = 0;
291 var stream = aReader.BaseStream;
292 while ((stream.CanSeek && stream.Position < stream.Length) || stream.CanRead)
294 var chunkID = (EChunkID)aReader.ReadByte();
295 if (chunkID == EChunkID.End)
300 aTarget.name = aReader.ReadString();
302 case EChunkID.Normals:
303 for (
int i = 0; i < count; i++)
304 vector3Array[i] = aReader.ReadVector3();
305 aTarget.normals = vector3Array;
307 case EChunkID.Tangents:
308 if (vector4List ==
null)
309 vector4List =
new List<Vector4>(count);
311 for (
int i = 0; i < count; i++)
312 vector4List.Add(aReader.ReadVector4());
313 aTarget.SetTangents(vector4List);
315 case EChunkID.Colors:
316 var colors =
new Color32[count];
317 for (
int i = 0; i < count; i++)
318 colors[i] = aReader.ReadColor32();
319 aTarget.colors32 = colors;
321 case EChunkID.BoneWeights:
322 var boneWeights =
new BoneWeight[count];
323 for (
int i = 0; i < count; i++)
324 boneWeights[i] = aReader.ReadBoneWeight();
325 aTarget.boneWeights = boneWeights;
331 int uvChannel = chunkID - EChunkID.UV0;
332 componentCount = aReader.ReadByte();
333 if (vector4List ==
null)
334 vector4List =
new List<Vector4>(count);
337 if (componentCount == 2)
339 for (
int i = 0; i < count; i++)
340 vector4List.Add(aReader.ReadVector2());
342 else if (componentCount == 3)
344 for (
int i = 0; i < count; i++)
345 vector4List.Add(aReader.ReadVector3());
347 else if (componentCount == 4)
349 for (
int i = 0; i < count; i++)
350 vector4List.Add(aReader.ReadVector4());
352 aTarget.SetUVs(uvChannel, vector4List);
354 case EChunkID.Submesh:
355 var topology = (MeshTopology)aReader.ReadByte();
356 int indexCount = aReader.ReadInt32();
357 var indices =
new int[indexCount];
358 componentCount = aReader.ReadByte();
359 if (componentCount == 1)
361 for (
int i = 0; i < indexCount; i++)
362 indices[i] = aReader.ReadByte();
364 else if (componentCount == 2)
366 for (
int i = 0; i < indexCount; i++)
367 indices[i] = aReader.ReadUInt16();
369 else if (componentCount == 4)
371 for (
int i = 0; i < indexCount; i++)
372 indices[i] = aReader.ReadInt32();
374 aTarget.SetIndices(indices, topology, subMeshIndex++,
false);
376 case EChunkID.Bindposes:
377 int bindposesCount = aReader.ReadInt32();
378 var bindposes =
new Matrix4x4[bindposesCount];
379 for (
int i = 0; i < bindposesCount; i++)
380 bindposes[i] = aReader.ReadMatrix4x4();
381 aTarget.bindposes = bindposes;
383 case EChunkID.BlendShape:
384 var blendShapeName = aReader.ReadString();
385 int frameCount = aReader.ReadInt32();
386 if (vector3Array2 ==
null)
387 vector3Array2 =
new Vector3[count];
388 if (vector3Array3 ==
null)
389 vector3Array3 =
new Vector3[count];
390 for (
int i = 0; i < frameCount; i++)
392 float weight = aReader.ReadSingle();
393 for (
int n = 0; n < count; n++)
395 vector3Array[n] = aReader.ReadVector3();
396 vector3Array2[n] = aReader.ReadVector3();
397 vector3Array3[n] = aReader.ReadVector3();
399 aTarget.AddBlendShapeFrame(blendShapeName, weight, vector3Array, vector3Array2, vector3Array3);
409 public static class BinaryReaderWriterUnityExt
411 public static void WriteVector2(
this BinaryWriter aWriter, Vector2 aVec)
413 aWriter.Write(aVec.x); aWriter.Write(aVec.y);
415 public static Vector2 ReadVector2(
this BinaryReader aReader)
417 return new Vector2(aReader.ReadSingle(), aReader.ReadSingle());
419 public static void WriteVector3(
this BinaryWriter aWriter, Vector3 aVec)
421 aWriter.Write(aVec.x); aWriter.Write(aVec.y); aWriter.Write(aVec.z);
423 public static Vector3 ReadVector3(
this BinaryReader aReader)
425 return new Vector3(aReader.ReadSingle(), aReader.ReadSingle(), aReader.ReadSingle());
427 public static void WriteVector4(
this BinaryWriter aWriter, Vector4 aVec)
429 aWriter.Write(aVec.x); aWriter.Write(aVec.y); aWriter.Write(aVec.z); aWriter.Write(aVec.w);
431 public static Vector4 ReadVector4(
this BinaryReader aReader)
433 return new Vector4(aReader.ReadSingle(), aReader.ReadSingle(), aReader.ReadSingle(), aReader.ReadSingle());
436 public static void WriteColor32(
this BinaryWriter aWriter, Color32 aCol)
438 aWriter.Write(aCol.r); aWriter.Write(aCol.g); aWriter.Write(aCol.b); aWriter.Write(aCol.a);
440 public static Color32 ReadColor32(
this BinaryReader aReader)
442 return new Color32(aReader.ReadByte(), aReader.ReadByte(), aReader.ReadByte(), aReader.ReadByte());
445 public static void WriteMatrix4x4(
this BinaryWriter aWriter, Matrix4x4 aMat)
447 aWriter.Write(aMat.m00); aWriter.Write(aMat.m01); aWriter.Write(aMat.m02); aWriter.Write(aMat.m03);
448 aWriter.Write(aMat.m10); aWriter.Write(aMat.m11); aWriter.Write(aMat.m12); aWriter.Write(aMat.m13);
449 aWriter.Write(aMat.m20); aWriter.Write(aMat.m21); aWriter.Write(aMat.m22); aWriter.Write(aMat.m23);
450 aWriter.Write(aMat.m30); aWriter.Write(aMat.m31); aWriter.Write(aMat.m32); aWriter.Write(aMat.m33);
452 public static Matrix4x4 ReadMatrix4x4(
this BinaryReader aReader)
454 var m =
new Matrix4x4();
455 m.m00 = aReader.ReadSingle(); m.m01 = aReader.ReadSingle(); m.m02 = aReader.ReadSingle(); m.m03 = aReader.ReadSingle();
456 m.m10 = aReader.ReadSingle(); m.m11 = aReader.ReadSingle(); m.m12 = aReader.ReadSingle(); m.m13 = aReader.ReadSingle();
457 m.m20 = aReader.ReadSingle(); m.m21 = aReader.ReadSingle(); m.m22 = aReader.ReadSingle(); m.m23 = aReader.ReadSingle();
458 m.m30 = aReader.ReadSingle(); m.m31 = aReader.ReadSingle(); m.m32 = aReader.ReadSingle(); m.m33 = aReader.ReadSingle();
462 public static void WriteBoneWeight(
this BinaryWriter aWriter, BoneWeight aWeight)
464 aWriter.Write(aWeight.boneIndex0); aWriter.Write(aWeight.weight0);
465 aWriter.Write(aWeight.boneIndex1); aWriter.Write(aWeight.weight1);
466 aWriter.Write(aWeight.boneIndex2); aWriter.Write(aWeight.weight2);
467 aWriter.Write(aWeight.boneIndex3); aWriter.Write(aWeight.weight3);
469 public static BoneWeight ReadBoneWeight(
this BinaryReader aReader)
471 var w =
new BoneWeight();
472 w.boneIndex0 = aReader.ReadInt32(); w.weight0 = aReader.ReadSingle();
473 w.boneIndex1 = aReader.ReadInt32(); w.weight1 = aReader.ReadSingle();
474 w.boneIndex2 = aReader.ReadInt32(); w.weight2 = aReader.ReadSingle();
475 w.boneIndex3 = aReader.ReadInt32(); w.weight3 = aReader.ReadSingle();