public TextAsset(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); if (readSwitch) { m_Script = a_Stream.ReadBytes(a_Stream.ReadInt32()); } else { preloadData.extension = ".txt"; preloadData.Text = m_Name; } }
public BuildSettings(AssetPreloadData preloadData) { AssetsFile sourceFile = preloadData.sourceFile; EndianStream stream = preloadData.sourceFile.a_Stream; stream.Position = preloadData.Offset; int num = stream.ReadInt32(); for (int i = 0; i < num; i++) { string str = stream.ReadAlignedString(stream.ReadInt32()); } if (sourceFile.version[0] == 5) { int num3 = stream.ReadInt32(); for (int j = 0; j < num3; j++) { string str2 = stream.ReadAlignedString(stream.ReadInt32()); } } stream.Position += 4L; if (sourceFile.fileGen >= 8) { stream.Position += 4L; } if (sourceFile.fileGen >= 9) { stream.Position += 4L; } if ((sourceFile.version[0] == 5) || ((sourceFile.version[0] == 4) && ((sourceFile.version[1] >= 3) || ((sourceFile.version[1] == 2) && (sourceFile.buildType[0] != "a"))))) { stream.Position += 4L; } this.m_Version = stream.ReadAlignedString(stream.ReadInt32()); }
public MonoBehaviour(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; var m_GameObject = sourceFile.ReadPPtr(); var m_Enabled = a_Stream.ReadByte(); a_Stream.AlignStream(4); var m_Script = sourceFile.ReadPPtr(); var m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); if (readSwitch) { if ((serializedText = preloadData.ViewStruct()) == null) { var str = "PPtr<GameObject> m_GameObject\n"; str += "\tint m_FileID = " + m_GameObject.m_FileID + "\n"; str += "\tint64 m_PathID = " + m_GameObject.m_PathID + "\n"; str += "UInt8 m_Enabled = " + m_Enabled + "\n"; str += "PPtr<MonoScript> m_Script\n"; str += "\tint m_FileID = " + m_Script.m_FileID + "\n"; str += "\tint64 m_PathID = " + m_Script.m_PathID + "\n"; str += "string m_Name = \"" + m_Name + "\"\n"; serializedText = str; } } else { preloadData.extension = ".snaa"; preloadData.Text = m_Name; } }
public PlayerSettings(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; if (sourceFile.version[0] >= 3) { if (sourceFile.version[0] == 3 && sourceFile.version[1] <2) { string AndroidLicensePublicKey = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); } else { bool AndroidProfiler = a_Stream.ReadBoolean(); a_Stream.AlignStream(4); } int defaultScreenOrientation = a_Stream.ReadInt32(); int targetDevice = a_Stream.ReadInt32(); if (sourceFile.version[0] < 5 || (sourceFile.version[0] == 5 && sourceFile.version[1] < 1)) { int targetGlesGraphics = a_Stream.ReadInt32(); } if ((sourceFile.version[0] == 5 && sourceFile.version[1] < 1) || (sourceFile.version[0] == 4 && sourceFile.version[1] == 6 && sourceFile.version[2] >= 3)) { int targetIOSGraphics = a_Stream.ReadInt32(); } if (sourceFile.version[0] == 5 && (sourceFile.version[1] > 2 || (sourceFile.version[1] == 2 && sourceFile.version[2] >= 1))) { bool useOnDemandResources = a_Stream.ReadBoolean(); a_Stream.AlignStream(4); } int targetResolution = a_Stream.ReadInt32(); if (sourceFile.version[0] == 3 && sourceFile.version[1] <= 1) { bool OverrideIPodMusic = a_Stream.ReadBoolean(); a_Stream.AlignStream(4); } else if (sourceFile.version[0] == 3 && sourceFile.version[1] <= 4) { } else { int accelerometerFrequency = a_Stream.ReadInt32(); }//3.5.0 and up } //fail in Unity 5 beta companyName = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); productName = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); }
private void ExportText(Unity_Studio.AssetPreloadData asset) { Unity_Studio.TextAsset m_TextAsset = new Unity_Studio.TextAsset(asset, false); Directory.CreateDirectory(ContentData.ContentPath()); Directory.CreateDirectory(ContentData.ContentPath() + gameType); Directory.CreateDirectory(ContentData.ContentPath() + gameType + "/ffg"); Directory.CreateDirectory(ContentData.ContentPath() + gameType + "/ffg/text"); string fileCandidate = ContentData.ContentPath() + gameType + "/ffg/text/" + asset.Text; string fileName = fileCandidate + asset.extension; m_TextAsset = new Unity_Studio.TextAsset(asset, true); while (File.Exists(fileName)) { return;// Fixme; } using (BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create))) { writer.Write(m_TextAsset.Deobfuscate(finder.ObfuscateKey())); writer.Close(); } // Run monster data extration tool if in dev if (Application.isEditor && asset.Text.Equals("Localization")) { if (finder is MoMFinder) { ExtractDataTool.MoM(m_TextAsset.Deobfuscate(finder.ObfuscateKey())); } } }
private void ExportFont(Unity_Studio.AssetPreloadData asset) { Unity_Studio.unityFont m_Font = new Unity_Studio.unityFont(asset, false); Directory.CreateDirectory(ContentData.ContentPath()); Directory.CreateDirectory(ContentData.ContentPath() + gameType); Directory.CreateDirectory(ContentData.ContentPath() + gameType + "/ffg"); Directory.CreateDirectory(ContentData.ContentPath() + gameType + "/ffg/fonts"); string fileCandidate = ContentData.ContentPath() + gameType + "/ffg/fonts/" + asset.Text; string fileName = fileCandidate + ".ttf"; m_Font = new Unity_Studio.unityFont(asset, true); if (m_Font.m_FontData == null) { return; } while (File.Exists(fileName)) { return;// Fixme; } using (BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create))) { writer.Write(m_Font.m_FontData); writer.Close(); } }
public AssetBundle(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; var m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); var size = a_Stream.ReadInt32(); for (int i = 0; i < size; i++) { sourceFile.ReadPPtr(); } size = a_Stream.ReadInt32(); for (int i = 0; i < size; i++) { var temp = new ContainerData(); temp.first = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); temp.second = new AssetInfo(); temp.second.preloadIndex = a_Stream.ReadInt32(); temp.second.preloadSize = a_Stream.ReadInt32(); temp.second.asset = sourceFile.ReadPPtr(); m_Container.Add(temp); } }
public PPtr m_Father = new PPtr();//can be transform or type 224 (as seen in Minions) public Transform(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_GameObject = sourceFile.ReadPPtr(); m_LocalRotation = new[] { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }; m_LocalPosition = new[] { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }; m_LocalScale = new[] { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }; int m_ChildrenCount = a_Stream.ReadInt32(); for (int j = 0; j < m_ChildrenCount; j++) { m_Children.Add(sourceFile.ReadPPtr()); } m_Father = sourceFile.ReadPPtr(); }
// Save text to file private void ExportText(Unity_Studio.AssetPreloadData asset) { Unity_Studio.TextAsset m_TextAsset = new Unity_Studio.TextAsset(asset, false); Directory.CreateDirectory(ContentData.ContentPath()); Directory.CreateDirectory(ContentData.ContentPath() + gameType); Directory.CreateDirectory(ContentData.ContentPath() + gameType + "/ffg"); Directory.CreateDirectory(ContentData.ContentPath() + gameType + "/ffg/text"); string fileCandidate = ContentData.ContentPath() + gameType + "/ffg/text/" + asset.Text; string fileName = fileCandidate + asset.extension; m_TextAsset = new Unity_Studio.TextAsset(asset, true); // This should apend a postfix to the name to avoid collisions, but as we import multiple times // This is broken while (File.Exists(fileName)) { return;// Fixme; } // Write to disk using (BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create))) { // Pass the Deobfuscate key to decrypt writer.Write(m_TextAsset.Deobfuscate(finder.ObfuscateKey())); writer.Close(); } // Run monster data extration tool if in dev if (Application.isEditor && asset.Text.Equals("Localization")) { if (finder is MoMFinder) { ExtractDataTool.MoM(m_TextAsset.Deobfuscate(finder.ObfuscateKey())); } } }
// Save TTF font to dist private void ExportFont(Unity_Studio.AssetPreloadData asset) { Unity_Studio.unityFont m_Font = new Unity_Studio.unityFont(asset, false); Directory.CreateDirectory(ContentData.ContentPath()); Directory.CreateDirectory(ContentData.ContentPath() + gameType); Directory.CreateDirectory(ContentData.ContentPath() + gameType + "/ffg"); Directory.CreateDirectory(ContentData.ContentPath() + gameType + "/ffg/fonts"); string fileCandidate = ContentData.ContentPath() + gameType + "/ffg/fonts/" + asset.Text; string fileName = fileCandidate + ".ttf"; m_Font = new Unity_Studio.unityFont(asset, true); if (m_Font.m_FontData == null) { return; } // This should apend a postfix to the name to avoid collisions, but as we import multiple times // This is broken while (File.Exists(fileName)) { return;// Fixme; } // Write to disk using (BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create))) { writer.Write(m_Font.m_FontData); writer.Close(); } }
public Renderer(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_GameObject = sourceFile.ReadPPtr(); m_Enabled = a_Stream.ReadBoolean(); m_CastShadows = a_Stream.ReadByte(); m_ReceiveShadows = a_Stream.ReadBoolean(); if (sourceFile.version[0] < 5) { m_LightmapIndex = a_Stream.ReadByte(); } else { a_Stream.Position += 5; //suspicious alignment, could be 2 alignments between bools m_LightmapIndex = a_Stream.ReadUInt16(); m_LightmapIndexDynamic = a_Stream.ReadUInt16(); } if (sourceFile.version[0] >= 3) { a_Stream.Position += 16; } //Vector4f m_LightmapTilingOffset if (sourceFile.version[0] >= 5) { a_Stream.Position += 16; } //Vector4f m_LightmapTilingOffsetDynamic m_Materials = new PPtr[a_Stream.ReadInt32()]; for (int m = 0; m < m_Materials.Length; m++) { m_Materials[m] = sourceFile.ReadPPtr(); } }
public BuildSettings(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; int levels = a_Stream.ReadInt32(); for (int l = 0; l < levels; l++) { string level = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); } if (sourceFile.version[0] == 5) { int preloadedPlugins = a_Stream.ReadInt32(); for (int l = 0; l < preloadedPlugins; l++) { string preloadedPlugin = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); } } a_Stream.Position += 4; //bool flags if (sourceFile.fileGen >= 8) { a_Stream.Position += 4; } //bool flags if (sourceFile.fileGen >= 9) { a_Stream.Position += 4; } //bool flags if (sourceFile.version[0] == 5 || (sourceFile.version[0] == 4 && (sourceFile.version[1] >= 3 || (sourceFile.version[1] == 2 && sourceFile.buildType[0] != "a")))) { a_Stream.Position += 4; } //bool flags m_Version = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); }
// Save TTF font to dist private void ExportFont(Unity_Studio.AssetPreloadData asset) { if (asset == null) { throw new ArgumentNullException("asset"); } var font = new Unity_Studio.unityFont(asset, false); string fontsPath = Path.Combine(contentPath, "fonts"); Directory.CreateDirectory(fontsPath); string fileCandidate = Path.Combine(fontsPath, asset.Text); font = new Unity_Studio.unityFont(asset, true); if (font.m_FontData == null) { return; } // This should apends a postfix to the name to avoid collisions string fileName = GetAvailableFileName(fileCandidate, ".ttf"); // Write to disk File.WriteAllBytes(fileName, font.m_FontData); }
// Save text to file private void ExportText(Unity_Studio.AssetPreloadData asset) { Unity_Studio.TextAsset m_TextAsset = new Unity_Studio.TextAsset(asset, false); Directory.CreateDirectory(contentPath); Directory.CreateDirectory(contentPath + "/text"); string fileCandidate = contentPath + "/text/" + asset.Text; string fileName = fileCandidate + asset.extension; m_TextAsset = new Unity_Studio.TextAsset(asset, true); // This should apend a postfix to the name to avoid collisions, but as we import multiple times // This is broken while (File.Exists(fileName)) { return;// Fixme; } // Write to disk using (BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create))) { // Pass the Deobfuscate key to decrypt writer.Write(m_TextAsset.Deobfuscate(finder.ObfuscateKey())); writer.Close(); } // Need to trim new lines from old D2E format if (asset.Text.Equals("Localization")) { string[] locFix = File.ReadAllLines(fileName); List <string> locOut = new List <string>(); string currentLine = ""; for (int i = 0; i < locFix.Length; i++) { if (locFix[i].Split('\"').Length % 2 == 0) { if (currentLine.Length == 0) { currentLine = locFix[i]; } else { locOut.Add(currentLine + "\\n" + locFix[i]); currentLine = ""; } } else { if (currentLine.Length == 0) { locOut.Add(locFix[i]); } else { currentLine += "\\n" + locFix[i]; } } } File.WriteAllLines(fileName, locOut.ToArray()); } }
public TextAsset(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; preloadData.extension = ".txt"; if (sourceFile.platform == -2) { a_Stream.ReadUInt32(); sourceFile.ReadPPtr(); sourceFile.ReadPPtr(); } m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); int m_Script_size = a_Stream.ReadInt32(); if (readSwitch) //asset is read for preview or export { m_Script = new byte[m_Script_size]; a_Stream.Read(m_Script, 0, m_Script_size); if (m_Script[0] == 60 || (m_Script[0] == 239 && m_Script[1] == 187 && m_Script[2] == 191 && m_Script[3] == 60)) { preloadData.extension = ".xml"; } } else { byte lzmaTest = a_Stream.ReadByte(); if (lzmaTest == 93) { a_Stream.Position += 4; preloadData.exportSize = a_Stream.ReadInt32(); //actualy int64 a_Stream.Position -= 8; } else { preloadData.exportSize = m_Script_size; } a_Stream.Position += m_Script_size - 1; if (m_Name != "") { preloadData.Text = m_Name; } else { preloadData.Text = preloadData.TypeString + " #" + preloadData.uniqueID; } preloadData.subItems.AddRange(new string[] { preloadData.TypeString, preloadData.exportSize.ToString() }); } a_Stream.AlignStream(4); m_PathName = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); }
public TextAsset(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; preloadData.extension = ".txt"; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); int m_Script_size = a_Stream.ReadInt32(); if (readSwitch) //asset is read for preview or export { m_Script = new byte[m_Script_size]; a_Stream.Read(m_Script, 0, m_Script_size); if (m_Script[0] == 93) { try { m_Script = SevenZip.Compression.LZMA.SevenZipHelper.Decompress(m_Script); } catch { } } if (m_Script[0] == 60 || (m_Script[0] == 239 && m_Script[1] == 187 && m_Script[2] == 191 && m_Script[3] == 60)) { preloadData.extension = ".xml"; } } else { byte lzmaTest = a_Stream.ReadByte(); a_Stream.Position += m_Script_size - 1; if (m_Name != "") { preloadData.Text = m_Name; } else { preloadData.Text = preloadData.TypeString + " #" + preloadData.uniqueID; } preloadData.SubItems.AddRange(new[] { preloadData.TypeString, preloadData.Size.ToString() }); } a_Stream.AlignStream(4); m_PathName = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); }
public static void AddPPtrSpriteReference(AssetPreloadData Texture, Sprite Sprite) { if (!Sprites.ContainsKey(Texture)) { Sprites.Add(Texture, new List <Sprite>()); } List <Sprite> SpriteReferences = Sprites[Texture]; SpriteReferences.Add(Sprite); }
// Save text to file private void ExportText(Unity_Studio.AssetPreloadData asset) { if (asset == null) { throw new ArgumentNullException("asset"); } var textAsset = new Unity_Studio.TextAsset(asset, false); string textPath = Path.Combine(contentPath, "text"); Directory.CreateDirectory(textPath); string fileCandidate = Path.Combine(textPath, asset.Text); textAsset = new Unity_Studio.TextAsset(asset, true); // This should apends a postfix to the name to avoid collisions string fileName = GetAvailableFileName(fileCandidate, asset.extension); // Write to disk, pass the Deobfuscate key to decrypt File.WriteAllBytes(fileName, textAsset.Deobfuscate(finder.ObfuscateKey())); // Need to trim new lines from old D2E format if (asset.Text.Equals("Localization")) { string[] locFix = File.ReadAllLines(fileName); var locOut = new List <string>(); string currentLine = ""; for (int i = 0; i < locFix.Length; i++) { if (locFix[i].Split('\"').Length % 2 == 0) { if (currentLine.Length == 0) { currentLine = locFix[i]; } else { locOut.Add(currentLine + "\\n" + locFix[i]); currentLine = ""; } } else { if (currentLine.Length == 0) { locOut.Add(locFix[i]); } else { currentLine += "\\n" + locFix[i]; } } } File.WriteAllLines(fileName, locOut.ToArray()); } }
public GameObject(AssetPreloadData preloadData) { if (preloadData == null) { AssetsFile sourceFile = preloadData.sourceFile; EndianStream stream = preloadData.sourceFile.a_Stream; stream.Position = preloadData.Offset; this.uniqueID = preloadData.uniqueID; if (sourceFile.platform == -2) { uint num3 = stream.ReadUInt32(); PPtr ptr = sourceFile.ReadPPtr(); PPtr ptr2 = sourceFile.ReadPPtr(); } int num = stream.ReadInt32(); for (int i = 0; i < num; i++) { switch (stream.ReadInt32()) { case 4: this.m_Transform = sourceFile.ReadPPtr(); break; case 0x17: this.m_Renderer = sourceFile.ReadPPtr(); break; case 0x21: this.m_MeshFilter = sourceFile.ReadPPtr(); break; case 0x89: this.m_SkinnedMeshRenderer = sourceFile.ReadPPtr(); break; default: { PPtr ptr3 = sourceFile.ReadPPtr(); break; } } } this.m_Layer = stream.ReadInt32(); int length = stream.ReadInt32(); this.m_Name = stream.ReadAlignedString(length); if (this.m_Name == "") { this.m_Name = "GameObject #" + this.uniqueID; } this.m_Tag = stream.ReadUInt16(); this.m_IsActive = stream.ReadBoolean(); this.Text = this.m_Name; this.Name = this.uniqueID; } }
public TextAsset(AssetPreloadData preloadData, bool readSwitch) { AssetsFile sourceFile = preloadData.sourceFile; EndianStream stream = preloadData.sourceFile.a_Stream; stream.Position = preloadData.Offset; preloadData.extension = ".txt"; if (sourceFile.platform == -2) { uint num2 = stream.ReadUInt32(); PPtr ptr = sourceFile.ReadPPtr(); PPtr ptr2 = sourceFile.ReadPPtr(); } this.m_Name = stream.ReadAlignedString(stream.ReadInt32()); if (this.m_Name != "") { preloadData.Name = this.m_Name; } else { preloadData.Name = preloadData.TypeString + " #" + preloadData.uniqueID; } int count = stream.ReadInt32(); if (readSwitch) { this.m_Script = new byte[count]; stream.Read(this.m_Script, 0, count); if (this.m_Script[0] == 0x5d) { this.m_Script = SevenZipHelper.Decompress(this.m_Script); } if ((this.m_Script[0] == 60) || ((((this.m_Script[0] == 0xef) && (this.m_Script[1] == 0xbb)) && (this.m_Script[2] == 0xbf)) && (this.m_Script[3] == 60))) { preloadData.extension = ".xml"; } } else { if (stream.ReadByte() == 0x5d) { stream.Position += 4L; preloadData.exportSize = stream.ReadInt32(); stream.Position -= 8L; } else { preloadData.exportSize = count; } stream.Position += count - 1; } stream.AlignStream(4); this.m_PathName = stream.ReadAlignedString(stream.ReadInt32()); }
public string uniqueID = "0";//this way file and folder TreeNodes will be treated as FBX scene public GameObject(AssetPreloadData preloadData) { if (preloadData != null) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; uniqueID = preloadData.uniqueID; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } int m_Component_size = a_Stream.ReadInt32(); for (int j = 0; j < m_Component_size; j++) { int m_Component_type = a_Stream.ReadInt32(); switch (m_Component_type) { case 4: m_Transform = sourceFile.ReadPPtr(); break; case 23: m_Renderer = sourceFile.ReadPPtr(); break; case 33: m_MeshFilter = sourceFile.ReadPPtr(); break; case 137: m_SkinnedMeshRenderer = sourceFile.ReadPPtr(); break; default: PPtr m_Component = sourceFile.ReadPPtr(); break; } } m_Layer = a_Stream.ReadInt32(); int namesize = a_Stream.ReadInt32(); m_Name = a_Stream.ReadAlignedString(namesize); if (m_Name == "") { m_Name = "GameObject #" + uniqueID; } m_Tag = a_Stream.ReadUInt16(); m_IsActive = a_Stream.ReadBoolean(); base.Text = m_Name; //name should be unique base.Name = uniqueID; } }
public static string ViewStruct(this AssetPreloadData asset) { var a_Stream = asset.sourceFile.a_Stream; a_Stream.Position = asset.Offset; if (asset.sourceFile.ClassStructures.TryGetValue(asset.Type1, out var classStructure)) { var sb = new StringBuilder(); ReadClassStruct(sb, classStructure.members, a_Stream); return(sb.ToString()); } return(null); }
public SpriteAtlas(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; var reader = preloadData.sourceFile.a_Stream; reader.Position = preloadData.Offset; var m_Name = reader.ReadAlignedString(reader.ReadInt32()); //vector m_PackedSprites var size = reader.ReadInt32(); for (int i = 0; i < size; i++) { //PPtr<Sprite> data sourceFile.ReadPPtr(); } //vector m_PackedSpriteNamesToIndex size = reader.ReadInt32(); for (int i = 0; i < size; i++) { var data = reader.ReadAlignedString(reader.ReadInt32()); } //map m_RenderDataMap size = reader.ReadInt32(); for (int i = 0; i < size; i++) { //pair first guids.Add(new Guid(reader.ReadBytes(16))); var second = reader.ReadInt64(); //SpriteAtlasData second // PPtr<Texture2D> texture textures.Add(sourceFile.ReadPPtr()); // PPtr<Texture2D> alphaTexture var alphaTexture = sourceFile.ReadPPtr(); // Rectf textureRect textureRects.Add(new RectangleF(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); // Vector2f textureRectOffset reader.Position += 8; if (sourceFile.version[0] > 2017 || (sourceFile.version[0] == 2017 && sourceFile.version[1] >= 2))//2017.2 and up { // Vector2f atlasRectOffset reader.Position += 8; } // Vector4f uvTransform // float downscaleMultiplier // unsigned int settingsRaw reader.Position += 24; } //string m_Tag //bool m_IsVariant }
public static bool TryGetPD(this List<AssetsFile> assetsfileList, PPtr m_elm, out AssetPreloadData result) { result = null; if (m_elm != null && m_elm.m_FileID >= 0 && m_elm.m_FileID < assetsfileList.Count) { AssetsFile sourceFile = assetsfileList[m_elm.m_FileID]; //TryGetValue should be safe because m_PathID is 0 when initialized and PathID values range from 1 if (sourceFile.preloadTable.TryGetValue(m_elm.m_PathID, out result)) { return true; } } return false; }
public Renderer(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_GameObject = sourceFile.ReadPPtr(); if (sourceFile.version[0] < 5) { m_Enabled = a_Stream.ReadBoolean(); m_CastShadows = a_Stream.ReadByte(); m_ReceiveShadows = a_Stream.ReadBoolean(); m_LightmapIndex = a_Stream.ReadByte(); } else { m_Enabled = a_Stream.ReadBoolean(); a_Stream.AlignStream(4); m_CastShadows = a_Stream.ReadByte(); m_ReceiveShadows = a_Stream.ReadBoolean(); a_Stream.AlignStream(4); m_LightmapIndex = a_Stream.ReadUInt16(); m_LightmapIndexDynamic = a_Stream.ReadUInt16(); } if (sourceFile.version[0] >= 3) { a_Stream.Position += 16; } //Vector4f m_LightmapTilingOffset if (sourceFile.version[0] >= 5) { a_Stream.Position += 16; } //Vector4f m_LightmapTilingOffsetDynamic m_Materials = new PPtr[a_Stream.ReadInt32()]; for (int m = 0; m < m_Materials.Length; m++) { m_Materials[m] = sourceFile.ReadPPtr(); } }
public RectTransform(AssetPreloadData preloadData) { m_Transform = new Transform(preloadData); //var sourceFile = preloadData.sourceFile; //var a_Stream = preloadData.sourceFile.a_Stream; /* * float[2] AnchorsMin * float[2] AnchorsMax * float[2] Pivod * float Width * float Height * float[2] ? */ }
public MeshFilter(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_GameObject = sourceFile.ReadPPtr(); m_Mesh = sourceFile.ReadPPtr(); }
public TextAsset(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; preloadData.extension = ".txt"; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); int m_Script_size = a_Stream.ReadInt32(); if (readSwitch) //asset is read for preview or export { m_Script = new byte[m_Script_size]; a_Stream.Read(m_Script, 0, m_Script_size); if (m_Script[0] == 93) { m_Script = SevenZip.Compression.LZMA.SevenZipHelper.Decompress(m_Script); } if (m_Script[0] == 60 || (m_Script[0] == 239 && m_Script[1] == 187 && m_Script[2] == 191 && m_Script[3] == 60)) { preloadData.extension = ".xml"; } } else { byte lzmaTest = a_Stream.ReadByte(); if (lzmaTest == 93) { a_Stream.Position += 4; preloadData.exportSize = a_Stream.ReadInt32(); //actualy int64 a_Stream.Position -= 8; } else { preloadData.exportSize = m_Script_size; } a_Stream.Position += m_Script_size - 1; if (m_Name != "") { preloadData.Text = m_Name; } else { preloadData.Text = preloadData.TypeString + " #" + preloadData.uniqueID; } preloadData.SubItems.AddRange(new string[] { preloadData.TypeString, preloadData.exportSize.ToString() }); } a_Stream.AlignStream(4); m_PathName = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); }
public string uniqueID = "0";//this way file and folder TreeNodes will be treated as FBX scene public GameObject(AssetPreloadData preloadData) { if (preloadData != null) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; uniqueID = preloadData.uniqueID; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } int m_Component_size = a_Stream.ReadInt32(); for (int j = 0; j < m_Component_size; j++) { if ((sourceFile.version[0] == 5 && sourceFile.version[1] >= 5) || sourceFile.version[0] > 5)//5.5.0 and up { m_Components.Add(sourceFile.ReadPPtr()); } else { int first = a_Stream.ReadInt32(); m_Components.Add(sourceFile.ReadPPtr()); } } m_Layer = a_Stream.ReadInt32(); int namesize = a_Stream.ReadInt32(); m_Name = a_Stream.ReadAlignedString(namesize); if (m_Name == "") { m_Name = "GameObject #" + uniqueID; } m_Tag = a_Stream.ReadUInt16(); m_IsActive = a_Stream.ReadBoolean(); Text = m_Name; preloadData.Text = m_Name; //name should be unique Name = uniqueID; } }
public RectTransform(AssetPreloadData preloadData) { m_Transform = new Transform(preloadData); //var sourceFile = preloadData.sourceFile; //var a_Stream = preloadData.sourceFile.a_Stream; /* float[2] AnchorsMin float[2] AnchorsMax float[2] Pivod float Width float Height float[2] ? */ }
public MonoBehaviour(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; var m_GameObject = sourceFile.ReadPPtr(); var m_Enabled = a_Stream.ReadByte(); a_Stream.AlignStream(4); var m_Script = sourceFile.ReadPPtr(); var m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); if (readSwitch) { preloadData.extension = ".txt"; if ((serializedText = preloadData.ViewStruct()) == null) { var str = "PPtr<GameObject> m_GameObject\r\n"; str += "\tint m_FileID = " + m_GameObject.m_FileID + "\r\n"; str += "\tint64 m_PathID = " + m_GameObject.m_PathID + "\r\n"; str += "UInt8 m_Enabled = " + m_Enabled + "\r\n"; str += "PPtr<MonoScript> m_Script\r\n"; str += "\tint m_FileID = " + m_Script.m_FileID + "\r\n"; str += "\tint64 m_PathID = " + m_Script.m_PathID + "\r\n"; str += "string m_Name = \"" + m_Name + "\"\r\n"; serializedText = str; } } else { if (m_Name != "") { preloadData.Text = m_Name; } else { preloadData.Text = preloadData.TypeString + " #" + preloadData.uniqueID; } preloadData.SubItems.AddRange(new[] { preloadData.TypeString, preloadData.Size.ToString() }); } }
// Save audio to file private void ExportAudioClip(Unity_Studio.AssetPreloadData asset) { if (asset == null) { throw new ArgumentNullException("asset"); } var audioClip = new Unity_Studio.AudioClip(asset, false); string audioPath = Path.Combine(contentPath, "audio"); Directory.CreateDirectory(audioPath); string fileCandidate = Path.Combine(audioPath, asset.Text); // This should apends a postfix to the name to avoid collisions string fileName = GetAvailableFileName(fileCandidate, ".ogg"); // Pass to FSB Export audioClip = new Unity_Studio.AudioClip(asset, true); FSBExport.Write(audioClip.m_AudioData, fileName); }
// Save audio to file private void ExportAudioClip(Unity_Studio.AssetPreloadData asset) { Unity_Studio.AudioClip m_AudioClip = new Unity_Studio.AudioClip(asset, false); Directory.CreateDirectory(contentPath); Directory.CreateDirectory(contentPath + "/audio"); string fileCandidate = contentPath + "/audio/" + asset.Text; string fileName = fileCandidate + ".ogg"; // This should apend a postfix to the name to avoid collisions, but as we import multiple times // This is broken while (File.Exists(fileName)) { return;// Fixme; } // Pass to FSB Export m_AudioClip = new Unity_Studio.AudioClip(asset, true); FSBExport.Write(m_AudioClip.m_AudioData, fileName); }
public TextAsset(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); if (readSwitch) { if (false) //Using preview structure instead of raw content { var str1 = preloadData.ViewStruct(); if (str1 == null) { m_Script = Encoding.UTF8.GetBytes("Serialized Shader can't be read"); } else { m_Script = Encoding.UTF8.GetBytes(str1); } } else { m_Script = a_Stream.ReadBytes(a_Stream.ReadInt32()); } } else { preloadData.extension = ".txt"; preloadData.Text = m_Name; } }
public BuildSettings(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; int levels = a_Stream.ReadInt32(); for (int l = 0; l < levels; l++) { a_Stream.ReadAlignedString(a_Stream.ReadInt32()); } if (sourceFile.version[0] == 5) { int preloadedPlugins = a_Stream.ReadInt32(); for (int l = 0; l < preloadedPlugins; l++) { a_Stream.ReadAlignedString(a_Stream.ReadInt32()); } } a_Stream.Position += 4; //bool flags if (sourceFile.fileGen >= 8) { a_Stream.Position += 4; } //bool flags if (sourceFile.fileGen >= 9) { a_Stream.Position += 4; } //bool flags if (sourceFile.version[0] == 5 || (sourceFile.version[0] == 4 && (sourceFile.version[1] >= 3 || (sourceFile.version[1] == 2 && sourceFile.buildType[0] != "a")))) { a_Stream.Position += 4; } //bool flags m_Version = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); }
private void ExportAudioClip(Unity_Studio.AssetPreloadData asset) { Unity_Studio.AudioClip m_AudioClip = new Unity_Studio.AudioClip(asset, false); Directory.CreateDirectory(ContentData.ContentPath()); Directory.CreateDirectory(ContentData.ContentPath() + gameType); Directory.CreateDirectory(ContentData.ContentPath() + gameType + "/ffg"); Directory.CreateDirectory(ContentData.ContentPath() + gameType + "/ffg/audio"); string fileCandidate = ContentData.ContentPath() + gameType + "/ffg/audio/" + asset.Text; string fileName = fileCandidate + asset.extension; m_AudioClip = new Unity_Studio.AudioClip(asset, true); while (File.Exists(fileName)) { return;// Fixme; } using (BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create))) { writer.Write(m_AudioClip.m_AudioData); writer.Close(); } }
public MovieTexture(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); if (readSwitch) { var m_Loop = a_Stream.ReadBoolean(); a_Stream.AlignStream(4); //PPtr<AudioClip> sourceFile.ReadPPtr(); var size = a_Stream.ReadInt32(); m_MovieData = a_Stream.ReadBytes(size); var m_ColorSpace = a_Stream.ReadInt32(); } else { preloadData.extension = ".ogv"; preloadData.Text = m_Name; } }
public PPtr m_Father = new PPtr();//can be transform or type 224 (as seen in Minions) public Transform(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_GameObject = sourceFile.ReadPPtr(); m_LocalRotation = new float[] { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }; m_LocalPosition = new float[] { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }; m_LocalScale = new float[] { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }; int m_ChildrenCount = a_Stream.ReadInt32(); for (int j = 0; j < m_ChildrenCount; j++) { m_Children.Add(sourceFile.ReadPPtr()); } m_Father = sourceFile.ReadPPtr(); }
public AudioClip(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); if (sourceFile.version[0] < 5) { m_Format = a_Stream.ReadInt32(); //channels? m_Type = a_Stream.ReadInt32(); m_3D = a_Stream.ReadBoolean(); m_UseHardware = a_Stream.ReadBoolean(); a_Stream.Position += 2; //4 byte alignment if (sourceFile.version[0] >= 4 || (sourceFile.version[0] == 3 && sourceFile.version[1] >= 2)) //3.2.0 to 5 { int m_Stream = a_Stream.ReadInt32(); m_Size = a_Stream.ReadInt32(); if (m_Stream > 1) { m_Offset = a_Stream.ReadInt32(); m_Source = sourceFile.filePath + ".resS"; } } else { m_Size = a_Stream.ReadInt32(); } } else { m_LoadType = a_Stream.ReadInt32();//Decompress on load, Compressed in memory, Streaming m_Channels = a_Stream.ReadInt32(); m_Frequency = a_Stream.ReadInt32(); m_BitsPerSample = a_Stream.ReadInt32(); m_Length = a_Stream.ReadSingle(); m_IsTrackerFormat = a_Stream.ReadBoolean(); a_Stream.Position += 3; m_SubsoundIndex = a_Stream.ReadInt32(); m_PreloadAudioData = a_Stream.ReadBoolean(); m_LoadInBackground = a_Stream.ReadBoolean(); m_Legacy3D = a_Stream.ReadBoolean(); a_Stream.Position += 1; m_3D = m_Legacy3D; m_Source = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); //m_Source = Path.GetFileName(m_Source); m_Source = Path.Combine(Path.GetDirectoryName(sourceFile.filePath), m_Source.Replace("archive:/","")); m_Offset = a_Stream.ReadInt64(); m_Size = a_Stream.ReadInt64(); m_CompressionFormat = a_Stream.ReadInt32(); } if (readSwitch) { m_AudioData = new byte[m_Size]; if (m_Source == null) { a_Stream.Read(m_AudioData, 0, (int)m_Size); } else if (File.Exists(m_Source)) { using (BinaryReader reader = new BinaryReader(File.OpenRead(m_Source))) { reader.BaseStream.Position = m_Offset; reader.Read(m_AudioData, 0, (int)m_Size); reader.Close(); } } } else { preloadData.InfoText = "Compression format: "; switch (m_Type) { case 2: preloadData.extension = ".aif"; preloadData.InfoText += "AIFF"; break; case 13: preloadData.extension = ".mp3"; preloadData.InfoText += "MP3"; break; case 14: preloadData.extension = ".ogg"; preloadData.InfoText += "Ogg Vorbis"; break; case 20: preloadData.extension = ".wav"; preloadData.InfoText += "WAV"; break; case 22: //xbox encoding preloadData.extension = ".wav"; preloadData.InfoText += "Xbox360 WAV"; break; } switch (m_CompressionFormat) { case 0: preloadData.extension = ".fsb"; preloadData.InfoText += "PCM"; break; case 1: preloadData.extension = ".fsb"; preloadData.InfoText += "Vorbis"; break; case 2: preloadData.extension = ".fsb"; preloadData.InfoText += "ADPCM"; break; case 3: preloadData.extension = ".fsb"; preloadData.InfoText += "MP3";//not sure break; } if (preloadData.extension == "") { preloadData.extension = ".AudioClip"; preloadData.InfoText += "Unknown"; } preloadData.InfoText += "\n3D: " + m_3D.ToString(); if (m_Name != "") { preloadData.Text = m_Name; } else { preloadData.Text = preloadData.TypeString + " #" + preloadData.uniqueID; } preloadData.exportSize = (int)m_Size; preloadData.SubItems.AddRange(new string[] { preloadData.TypeString, m_Size.ToString() }); } }
private void enablePreview_Check(object sender, EventArgs e) { if (lastLoadedAsset != null) { switch (lastLoadedAsset.Type2) { case 28: { if (enablePreview.Checked && imageTexture != null) { previewPanel.BackgroundImage = imageTexture; previewPanel.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; } else { previewPanel.BackgroundImage = global::Unity_Studio.Properties.Resources.preview; previewPanel.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; } } break; case 48: case 49: textPreviewBox.Visible = !textPreviewBox.Visible; break; case 128: fontPreviewBox.Visible = !fontPreviewBox.Visible; break; case 83: { FMODpanel.Visible = !FMODpanel.Visible; if (sound != null && channel != null) { FMOD.RESULT result; bool playing = false; result = channel.isPlaying(out playing); if ((result != FMOD.RESULT.OK) && (result != FMOD.RESULT.ERR_INVALID_HANDLE)) { ERRCHECK(result); } if (playing) //stop previous sound { result = channel.stop(); ERRCHECK(result); FMODreset(); } else if (enablePreview.Checked) { result = system.playSound(sound, null, false, out channel); ERRCHECK(result); timer.Start(); FMODstatusLabel.Text = "Playing"; //FMODinfoLabel.Text = FMODfrequency.ToString(); } } break; } } } else if (lastSelectedItem != null && enablePreview.Checked) { lastLoadedAsset = lastSelectedItem; PreviewAsset(lastLoadedAsset); } Properties.Settings.Default["enablePreview"] = enablePreview.Checked; Properties.Settings.Default.Save(); }
private void resetForm() { /*Properties.Settings.Default["uniqueNames"] = uniqueNamesMenuItem.Checked; Properties.Settings.Default["enablePreview"] = enablePreviewMenuItem.Checked; Properties.Settings.Default["displayInfo"] = displayAssetInfoMenuItem.Checked; Properties.Settings.Default.Save();*/ base.Text = "Unity Studio"; unityFiles.Clear(); assetsfileList.Clear(); exportableAssets.Clear(); visibleAssets.Clear(); sceneTreeView.Nodes.Clear(); assetListView.VirtualListSize = 0; assetListView.Items.Clear(); //assetListView.Groups.Clear(); classesListView.Items.Clear(); classesListView.Groups.Clear(); previewPanel.BackgroundImage = global::Unity_Studio.Properties.Resources.preview; previewPanel.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; assetInfoLabel.Visible = false; assetInfoLabel.Text = null; textPreviewBox.Visible = false; fontPreviewBox.Visible = false; lastSelectedItem = null; lastLoadedAsset = null; firstSortColumn = -1; secondSortColumn = 0; reverseSort = false; enableFiltering = false; //FMODinit(); FMODreset(); }
private int ExportAsset(AssetPreloadData asset, string exportPath) { int exportCount = 0; switch (asset.Type2) { #region Texture2D case 28: //Texture2D { Texture2D m_Texture2D = new Texture2D(asset, true); string texPath = exportPath + "\\" + asset.Text; if (uniqueNames.Checked) { texPath += " #" + asset.uniqueID; } if (m_Texture2D.m_TextureFormat < 30) { texPath += ".dds"; } else if (m_Texture2D.m_TextureFormat < 35) { texPath += ".pvr"; } else { texPath += "_" + m_Texture2D.m_Width.ToString() + "x" + m_Texture2D.m_Height.ToString() + "." + m_Texture2D.m_TextureFormat.ToString() + ".tex"; } if (File.Exists(texPath)) { StatusStripUpdate("Texture file " + Path.GetFileName(texPath) + " already exists"); } else { StatusStripUpdate("Exporting Texture2D: " + Path.GetFileName(texPath)); exportCount += 1; switch (m_Texture2D.m_TextureFormat) { case 1: //Alpha8 case 2: //A4R4G4B4 case 3: //B8G8R8 //confirmed on X360, iOS //PS3 unsure case 4: //G8R8A8B8 //confirmed on X360, iOS case 5: //B8G8R8A8 //confirmed on X360, PS3, Web, iOS case 7: //R5G6B5 //confirmed switched on X360; confirmed on iOS case 10: //DXT1 case 12: //DXT5 case 13: //R4G4B4A4, iOS (only?) WriteDDS(texPath, m_Texture2D); break; case 30: //PVRTC_RGB2 case 31: //PVRTC_RGBA2 case 32: //PVRTC_RGB4 case 33: //PVRTC_RGBA4 case 34: //ETC_RGB4 WritePVR(texPath, m_Texture2D); break; default: { using (BinaryWriter writer = new BinaryWriter(File.Open(texPath, FileMode.Create))) { writer.Write(m_Texture2D.image_data); writer.Close(); } break; } } } break; } #endregion #region AudioClip case 83: //AudioClip { AudioClip m_AudioClip = new AudioClip(asset, true); string audPath = exportPath + "\\" + asset.Text; if (uniqueNames.Checked) { audPath += " #" + asset.uniqueID; } audPath += m_AudioClip.extension; if (File.Exists(audPath)) { StatusStripUpdate("Audio file " + Path.GetFileName(audPath) + " already exists"); } else { StatusStripUpdate("Exporting AudioClip: " + Path.GetFileName(audPath)); exportCount += 1; using (BinaryWriter writer = new BinaryWriter(File.Open(audPath, FileMode.Create))) { writer.Write(m_AudioClip.m_AudioData); writer.Close(); } } break; } #endregion #region Shader & TextAsset case 48: //Shader case 49: //TextAsset { TextAsset m_TextAsset = new TextAsset(asset, true); string textAssetPath = exportPath + "\\" + asset.Text; if (uniqueNames.Checked) { textAssetPath += " #" + asset.uniqueID; } textAssetPath += m_TextAsset.extension; if (File.Exists(textAssetPath)) { StatusStripUpdate("TextAsset file " + Path.GetFileName(textAssetPath) + " already exists"); } else { StatusStripUpdate("Exporting TextAsset: " + Path.GetFileName(textAssetPath)); exportCount += 1; using (BinaryWriter writer = new BinaryWriter(File.Open(textAssetPath, FileMode.Create))) { writer.Write(m_TextAsset.m_Script); writer.Close(); } } break; } #endregion #region Font case 128: //Font { unityFont m_Font = new unityFont(asset); if (m_Font.m_FontData != null) { string fontPath = exportPath + "\\" + asset.Text; if (uniqueNames.Checked) { fontPath += " #" + asset.uniqueID; } fontPath += m_Font.extension; if (File.Exists(fontPath)) { StatusStripUpdate("Font file " + Path.GetFileName(fontPath) + " already exists"); } else { StatusStripUpdate("Exporting Font: " + Path.GetFileName(fontPath)); using (BinaryWriter writer = new BinaryWriter(File.Open(fontPath, FileMode.Create))) { writer.Write(m_Font.m_FontData); writer.Close(); } exportCount += 1; } } break; } #endregion /*default: { string assetPath = exportPath + "\\" + asset.Name + "." + asset.TypeString; byte[] assetData = new byte[asset.Size]; Stream.Read(assetData, 0, asset.Size); using (BinaryWriter writer = new BinaryWriter(File.Open(assetPath, FileMode.Create))) { writer.Write(assetData); writer.Close(); } exportCount += 1; break; }*/ } return exportCount; }
private void PreviewAsset(AssetPreloadData asset) { switch (asset.Type2) { #region Texture2D case 28: //Texture2D { Texture2D m_Texture2D = new Texture2D(asset, true); if (m_Texture2D.m_TextureFormat < 30) { byte[] imageBuffer = new byte[128 + m_Texture2D.image_data_size]; imageBuffer[0] = 0x44; imageBuffer[1] = 0x44; imageBuffer[2] = 0x53; imageBuffer[3] = 0x20; imageBuffer[4] = 0x7c; BitConverter.GetBytes(m_Texture2D.dwFlags).CopyTo(imageBuffer, 8); BitConverter.GetBytes(m_Texture2D.m_Height).CopyTo(imageBuffer, 12); BitConverter.GetBytes(m_Texture2D.m_Width).CopyTo(imageBuffer, 16); BitConverter.GetBytes(m_Texture2D.dwPitchOrLinearSize).CopyTo(imageBuffer, 20); BitConverter.GetBytes(m_Texture2D.dwMipMapCount).CopyTo(imageBuffer, 28); BitConverter.GetBytes(m_Texture2D.dwSize).CopyTo(imageBuffer, 76); BitConverter.GetBytes(m_Texture2D.dwFlags2).CopyTo(imageBuffer, 80); BitConverter.GetBytes(m_Texture2D.dwFourCC).CopyTo(imageBuffer, 84); BitConverter.GetBytes(m_Texture2D.dwRGBBitCount).CopyTo(imageBuffer, 88); BitConverter.GetBytes(m_Texture2D.dwRBitMask).CopyTo(imageBuffer, 92); BitConverter.GetBytes(m_Texture2D.dwGBitMask).CopyTo(imageBuffer, 96); BitConverter.GetBytes(m_Texture2D.dwBBitMask).CopyTo(imageBuffer, 100); BitConverter.GetBytes(m_Texture2D.dwABitMask).CopyTo(imageBuffer, 104); BitConverter.GetBytes(m_Texture2D.dwCaps).CopyTo(imageBuffer, 108); BitConverter.GetBytes(m_Texture2D.dwCaps2).CopyTo(imageBuffer, 112); m_Texture2D.image_data.CopyTo(imageBuffer, 128); imageTexture = DDSDataToBMP(imageBuffer); imageTexture.RotateFlip(RotateFlipType.RotateNoneFlipY); previewPanel.BackgroundImage = imageTexture; previewPanel.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; } else { StatusStripUpdate("Unsupported image for preview. Try to export."); } break; } #endregion #region AudioClip case 83: //AudioClip { AudioClip m_AudioClip = new AudioClip(asset, true); //MemoryStream memoryStream = new MemoryStream(m_AudioData, true); //System.Media.SoundPlayer soundPlayer = new System.Media.SoundPlayer(memoryStream); //soundPlayer.Play(); FMOD.RESULT result; FMOD.CREATESOUNDEXINFO exinfo = new FMOD.CREATESOUNDEXINFO(); exinfo.cbsize = Marshal.SizeOf(exinfo); exinfo.length = (uint)m_AudioClip.m_Size; result = system.createSound(m_AudioClip.m_AudioData, (FMOD.MODE.OPENMEMORY | loopMode), ref exinfo, out sound); if (ERRCHECK(result)) { break; } result = sound.getLength(out FMODlenms, FMOD.TIMEUNIT.MS); if ((result != FMOD.RESULT.OK) && (result != FMOD.RESULT.ERR_INVALID_HANDLE)) { if (ERRCHECK(result)) { break; } } result = system.playSound(sound, null, false, out channel); if (ERRCHECK(result)) { break; } timer.Start(); FMODstatusLabel.Text = "Playing"; FMODpanel.Visible = true; //result = channel.getChannelGroup(out channelGroup); //if (ERRCHECK(result)) { break; } result = channel.getFrequency(out FMODfrequency); ERRCHECK(result); FMODinfoLabel.Text = FMODfrequency.ToString() + " Hz"; break; } #endregion #region Shader & TextAsset case 48: case 49: { TextAsset m_TextAsset = new TextAsset(asset, true); string m_Script_Text = UnicodeEncoding.UTF8.GetString(m_TextAsset.m_Script); m_Script_Text = Regex.Replace(m_Script_Text, "(?<!\r)\n", "\r\n"); textPreviewBox.Text = m_Script_Text; textPreviewBox.Visible = true; break; } #endregion #region Font case 128: //Font { unityFont m_Font = new unityFont(asset); if (m_Font.extension != ".otf" && m_Font.m_FontData != null) { IntPtr data = Marshal.AllocCoTaskMem(m_Font.m_FontData.Length); Marshal.Copy(m_Font.m_FontData, 0, data, m_Font.m_FontData.Length); System.Drawing.Text.PrivateFontCollection pfc = new System.Drawing.Text.PrivateFontCollection(); // We HAVE to do this to register the font to the system (Weird .NET bug !) uint cFonts = 0; AddFontMemResourceEx(data, (uint)m_Font.m_FontData.Length, IntPtr.Zero, ref cFonts); pfc.AddMemoryFont(data, m_Font.m_FontData.Length); System.Runtime.InteropServices.Marshal.FreeCoTaskMem(data); //textPreviewBox.Font = new Font(pfc.Families[0], 16, FontStyle.Regular); //textPreviewBox.Text = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWYZ\r\n1234567890.:,;'\"(!?)+-*/=\r\nThe quick brown fox jumps over the lazy dog. 1234567890"; fontPreviewBox.SelectionStart = 0; fontPreviewBox.SelectionLength = 80; fontPreviewBox.SelectionFont = new Font(pfc.Families[0], 16, FontStyle.Regular); fontPreviewBox.SelectionStart = 81; fontPreviewBox.SelectionLength = 56; fontPreviewBox.SelectionFont = new Font(pfc.Families[0], 12, FontStyle.Regular); fontPreviewBox.SelectionStart = 138; fontPreviewBox.SelectionLength = 56; fontPreviewBox.SelectionFont = new Font(pfc.Families[0], 18, FontStyle.Regular); fontPreviewBox.SelectionStart = 195; fontPreviewBox.SelectionLength = 56; fontPreviewBox.SelectionFont = new Font(pfc.Families[0], 24, FontStyle.Regular); fontPreviewBox.SelectionStart = 252; fontPreviewBox.SelectionLength = 56; fontPreviewBox.SelectionFont = new Font(pfc.Families[0], 36, FontStyle.Regular); fontPreviewBox.SelectionStart = 309; fontPreviewBox.SelectionLength = 56; fontPreviewBox.SelectionFont = new Font(pfc.Families[0], 48, FontStyle.Regular); fontPreviewBox.SelectionStart = 366; fontPreviewBox.SelectionLength = 56; fontPreviewBox.SelectionFont = new Font(pfc.Families[0], 60, FontStyle.Regular); fontPreviewBox.SelectionStart = 423; fontPreviewBox.SelectionLength = 55; fontPreviewBox.SelectionFont = new Font(pfc.Families[0], 72, FontStyle.Regular); fontPreviewBox.Visible = true; } else { StatusStripUpdate("Unsupported font for preview. Try to export."); } break; } #endregion } }
private void selectAsset(object sender, ListViewItemSelectionChangedEventArgs e) { previewPanel.BackgroundImage = global::Unity_Studio.Properties.Resources.preview; previewPanel.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; assetInfoLabel.Visible = false; assetInfoLabel.Text = null; textPreviewBox.Visible = false; fontPreviewBox.Visible = false; FMODpanel.Visible = false; lastLoadedAsset = null; StatusStripUpdate(""); FMODreset(); lastSelectedItem = (AssetPreloadData)e.Item; if (e.IsSelected) { assetInfoLabel.Text = lastSelectedItem.InfoText; if (displayInfo.Checked && assetInfoLabel.Text != null) { assetInfoLabel.Visible = true; } //only display the label if asset has info text if (enablePreview.Checked) { lastLoadedAsset = lastSelectedItem; PreviewAsset(lastLoadedAsset); } } }
public Material(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); m_Shader = sourceFile.ReadPPtr(); if (sourceFile.version[0] == 4 && (sourceFile.version[1] >= 2 || (sourceFile.version[1] == 1 && sourceFile.buildType[0] != "a"))) { m_ShaderKeywords = new string[a_Stream.ReadInt32()]; for (int i = 0; i < m_ShaderKeywords.Length; i++) { m_ShaderKeywords[i] = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); } } else if (sourceFile.version[0] == 5) { m_ShaderKeywords = new string[1] { a_Stream.ReadAlignedString(a_Stream.ReadInt32()) }; uint m_LightmapFlags = a_Stream.ReadUInt32(); } if (sourceFile.version[0] > 4 || (sourceFile.version[0] == 4 && sourceFile.version[1] >= 3)) { m_CustomRenderQueue = a_Stream.ReadInt32(); } if (sourceFile.version[0] == 5 && sourceFile.version[1] >= 1) { string[][] stringTagMap = new string[a_Stream.ReadInt32()][]; for (int i = 0; i < stringTagMap.Length; i++) { stringTagMap[i] = new string[2] { a_Stream.ReadAlignedString(a_Stream.ReadInt32()), a_Stream.ReadAlignedString(a_Stream.ReadInt32()) }; } } //m_SavedProperties m_TexEnvs = new TexEnv[a_Stream.ReadInt32()]; for (int i = 0; i < m_TexEnvs.Length; i++) { TexEnv m_TexEnv = new TexEnv() { name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()), m_Texture = sourceFile.ReadPPtr(), m_Scale = new float[2] { a_Stream.ReadSingle(), a_Stream.ReadSingle() }, m_Offset = new float[2] { a_Stream.ReadSingle(), a_Stream.ReadSingle() } }; m_TexEnvs[i] = m_TexEnv; } m_Floats = new strFloatPair[a_Stream.ReadInt32()]; for (int i = 0; i < m_Floats.Length; i++) { strFloatPair m_Float = new strFloatPair() { first = a_Stream.ReadAlignedString(a_Stream.ReadInt32()), second = a_Stream.ReadSingle() }; m_Floats[i] = m_Float; } m_Colors = new strColorPair[a_Stream.ReadInt32()]; for (int i = 0; i < m_Colors.Length; i++) { strColorPair m_Color = new strColorPair() { first = a_Stream.ReadAlignedString(a_Stream.ReadInt32()), second = new float[4] { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() } }; m_Colors[i] = m_Color; } }
public Texture2D(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); m_Width = a_Stream.ReadInt32(); m_Height = a_Stream.ReadInt32(); m_CompleteImageSize = a_Stream.ReadInt32(); m_TextureFormat = a_Stream.ReadInt32(); if (m_TextureFormat < 30) { extension = ".dds"; } else if (m_TextureFormat < 35) { extension = ".pvr"; } else { extension = "_" + m_Width.ToString() + "x" + m_Height.ToString() + "." + m_TextureFormat.ToString() + ".tex"; } m_MipMap = a_Stream.ReadBoolean(); m_IsReadable = a_Stream.ReadBoolean(); //2.6.0 and up m_ReadAllowed = a_Stream.ReadBoolean(); //3.0.0 and up a_Stream.Position += 1; //4 byte alignment m_ImageCount = a_Stream.ReadInt32(); m_TextureDimension = a_Stream.ReadInt32(); //m_TextureSettings m_FilterMode = a_Stream.ReadInt32(); m_Aniso = a_Stream.ReadInt32(); m_MipBias = a_Stream.ReadSingle(); m_WrapMode = a_Stream.ReadInt32(); if (sourceFile.version[0] >= 3) { m_LightmapFormat = a_Stream.ReadInt32(); if (sourceFile.version[0] >= 4 || sourceFile.version[1] >= 5) { m_ColorSpace = a_Stream.ReadInt32(); } //3.5.0 and up } image_data_size = a_Stream.ReadInt32(); if (m_MipMap) { dwFlags += 0x20000; dwMipMapCount = Convert.ToInt32(Math.Log(Math.Max(m_Width, m_Height)) / Math.Log(2)); dwCaps += 0x400008; } if (readSwitch) { image_data = new byte[image_data_size]; a_Stream.Read(image_data, 0, image_data_size); switch (m_TextureFormat) { case 1: //Alpha8 { dwFlags2 = 0x2; dwRGBBitCount = 0x8; dwRBitMask = 0x0; dwGBitMask = 0x0; dwBBitMask = 0x0; dwABitMask = 0xFF; break; } case 2: //A4R4G4B4 { if (sourceFile.platform == 11) //swap bytes for Xbox confirmed, PS3 not encountered { for (int i = 0; i < (image_data_size / 2); i++) { byte b0 = image_data[i * 2]; image_data[i * 2] = image_data[i * 2 + 1]; image_data[i * 2 + 1] = b0; } } else if (sourceFile.platform == 13) //swap bits for android { for (int i = 0; i < (image_data_size / 2); i++) { byte[] argb = BitConverter.GetBytes((BitConverter.ToInt32((new byte[4] { image_data[i * 2], image_data[i * 2 + 1], image_data[i * 2], image_data[i * 2 + 1] }), 0)) >> 4); image_data[i * 2] = argb[0]; image_data[i * 2 + 1] = argb[1]; } } dwFlags2 = 0x41; dwRGBBitCount = 0x10; dwRBitMask = 0xF00; dwGBitMask = 0xF0; dwBBitMask = 0xF; dwABitMask = 0xF000; break; } case 3: //B8G8R8 //confirmed on X360, iOS //PS3 unsure { for (int i = 0; i < (image_data_size / 3); i++) { byte b0 = image_data[i * 3]; image_data[i * 3] = image_data[i * 3 + 2]; //image_data[i * 3 + 1] stays the same image_data[i * 3 + 2] = b0; } dwFlags2 = 0x40; dwRGBBitCount = 0x18; dwRBitMask = 0xFF0000; dwGBitMask = 0xFF00; dwBBitMask = 0xFF; dwABitMask = 0x0; break; } case 4: //G8R8A8B8 //confirmed on X360, iOS { for (int i = 0; i < (image_data_size / 4); i++) { byte b0 = image_data[i * 4]; image_data[i * 4] = image_data[i * 4 + 2]; //image_data[i * 4 + 1] stays the same image_data[i * 4 + 2] = b0; //image_data[i * 4 + 3] stays the same } dwFlags2 = 0x41; dwRGBBitCount = 0x20; dwRBitMask = 0xFF0000; dwGBitMask = 0xFF00; dwBBitMask = 0xFF; dwABitMask = -16777216; break; } case 5: //B8G8R8A8 //confirmed on X360, PS3, Web, iOS { for (int i = 0; i < (image_data_size / 4); i++) { byte b0 = image_data[i * 4]; byte b1 = image_data[i * 4 + 1]; image_data[i * 4] = image_data[i * 4 + 3]; image_data[i * 4 + 1] = image_data[i * 4 + 2]; image_data[i * 4 + 2] = b1; image_data[i * 4 + 3] = b0; } dwFlags2 = 0x41; dwRGBBitCount = 0x20; dwRBitMask = 0xFF0000; dwGBitMask = 0xFF00; dwBBitMask = 0xFF; dwABitMask = -16777216; break; } case 7: //R5G6B5 //confirmed switched on X360; confirmed on iOS { if (sourceFile.platform == 11) { for (int i = 0; i < (image_data_size / 2); i++) { byte b0 = image_data[i * 2]; image_data[i * 2] = image_data[i * 2 + 1]; image_data[i * 2 + 1] = b0; } } dwFlags2 = 0x40; dwRGBBitCount = 0x10; dwRBitMask = 0xF800; dwGBitMask = 0x7E0; dwBBitMask = 0x1F; dwABitMask = 0x0; break; } case 10: //DXT1 { if (sourceFile.platform == 11) //X360 only, PS3 not { for (int i = 0; i < (image_data_size / 2); i++) { byte b0 = image_data[i * 2]; image_data[i * 2] = image_data[i * 2 + 1]; image_data[i * 2 + 1] = b0; } } if (m_MipMap) { dwPitchOrLinearSize = m_Height * m_Width / 2; } dwFlags2 = 0x4; dwFourCC = 0x31545844; dwRGBBitCount = 0x0; dwRBitMask = 0x0; dwGBitMask = 0x0; dwBBitMask = 0x0; dwABitMask = 0x0; break; } case 12: //DXT5 { if (sourceFile.platform == 11) //X360, PS3 not { for (int i = 0; i < (image_data_size / 2); i++) { byte b0 = image_data[i * 2]; image_data[i * 2] = image_data[i * 2 + 1]; image_data[i * 2 + 1] = b0; } } if (m_MipMap) { dwPitchOrLinearSize = m_Height * m_Width / 2; } dwFlags2 = 0x4; dwFourCC = 0x35545844; dwRGBBitCount = 0x0; dwRBitMask = 0x0; dwGBitMask = 0x0; dwBBitMask = 0x0; dwABitMask = 0x0; break; } case 13: //R4G4B4A4, iOS (only?) { for (int i = 0; i < (image_data_size / 2); i++) { byte[] argb = BitConverter.GetBytes((BitConverter.ToInt32((new byte[4] { image_data[i * 2], image_data[i * 2 + 1], image_data[i * 2], image_data[i * 2 + 1] }), 0)) >> 4); image_data[i * 2] = argb[0]; image_data[i * 2 + 1] = argb[1]; } dwFlags2 = 0x41; dwRGBBitCount = 0x10; dwRBitMask = 0xF00; dwGBitMask = 0xF0; dwBBitMask = 0xF; dwABitMask = 0xF000; break; } case 30: //PVRTC_RGB2 { pvrPixelFormat = 0x0; break; } case 31: //PVRTC_RGBA2 { pvrPixelFormat = 0x1; break; } case 32: //PVRTC_RGB4 { pvrPixelFormat = 0x2; break; } case 33: //PVRTC_RGBA4 { pvrPixelFormat = 0x3; break; } case 34: //ETC_RGB4 { pvrPixelFormat = 0x16; break; } } } }
public Mesh(AssetPreloadData MeshPD) { //Stream = new EndianStream(File.OpenRead(sourceFile.filePath), sourceFile.endianType); //Stream.endian = sourceFile.endianType; var version = MeshPD.sourceFile.version; a_Stream = MeshPD.sourceFile.a_Stream; a_Stream.Position = MeshPD.Offset; bool m_Use16BitIndices = true; //3.5.0 and newer always uses 16bit indices uint m_MeshCompression = 0; if (MeshPD.sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = MeshPD.sourceFile.ReadPPtr(); PPtr m_PrefabInternal = MeshPD.sourceFile.ReadPPtr(); } m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); if (version[0] < 3 || (version[0] == 3 && version[1] < 5)) { m_Use16BitIndices = a_Stream.ReadBoolean(); a_Stream.Position += 3; } #region Index Buffer for 2.5.1 and earlier if (version[0] == 2 && version[1] <= 5) { int m_IndexBuffer_size = a_Stream.ReadInt32(); if (m_Use16BitIndices) { m_IndexBuffer = new uint[m_IndexBuffer_size / 2]; for (int i = 0; i < m_IndexBuffer_size / 2; i++) { m_IndexBuffer[i] = a_Stream.ReadUInt16(); } a_Stream.AlignStream(4); } else { m_IndexBuffer = new uint[m_IndexBuffer_size / 4]; for (int i = 0; i < m_IndexBuffer_size / 4; i++) { m_IndexBuffer[i] = a_Stream.ReadUInt32(); } } } #endregion #region subMeshes int m_SubMeshes_size = a_Stream.ReadInt32(); for (int s = 0; s < m_SubMeshes_size; s++) { m_SubMeshes.Add(new SubMesh()); m_SubMeshes[s].firstByte = a_Stream.ReadUInt32(); m_SubMeshes[s].indexCount = a_Stream.ReadUInt32(); //what is this in case of triangle strips? m_SubMeshes[s].topology = a_Stream.ReadInt32(); //isTriStrip if (version[0] < 4) { m_SubMeshes[s].triangleCount = a_Stream.ReadUInt32(); } if (version[0] >= 3) { m_SubMeshes[s].firstVertex = a_Stream.ReadUInt32(); m_SubMeshes[s].vertexCount = a_Stream.ReadUInt32(); a_Stream.Position += 24; //Axis-Aligned Bounding Box } } #endregion #region BlendShapeData for 4.1.0 to 4.2.x, excluding 4.1.0 alpha if (version[0] == 4 && ((version[1] == 1 && MeshPD.sourceFile.buildType[0] != "a") || (version[1] > 1 && version[1] <= 2))) { int m_Shapes_size = a_Stream.ReadInt32(); if (m_Shapes_size > 0) { bool stop = true; } for (int s = 0; s < m_Shapes_size; s++) //untested { string shape_name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); a_Stream.Position += 36; //uint firstVertex, vertexCount; Vector3f aabbMinDelta, aabbMaxDelta; bool hasNormals, hasTangents } int m_ShapeVertices_size = a_Stream.ReadInt32(); a_Stream.Position += m_ShapeVertices_size * 40; //vertex positions, normals, tangents & uint index } #endregion #region BlendShapeData and BindPose for 4.3.0 and later else if (version[0] >= 5 || (version[0] == 4 && version[1] >= 3)) { int m_ShapeVertices_size = a_Stream.ReadInt32(); if (m_ShapeVertices_size > 0) { bool stop = true; } a_Stream.Position += m_ShapeVertices_size * 40; //vertex positions, normals, tangents & uint index int shapes_size = a_Stream.ReadInt32(); a_Stream.Position += shapes_size * 12; //uint firstVertex, vertexCount; bool hasNormals, hasTangents int channels_size = a_Stream.ReadInt32(); for (int c = 0; c < channels_size; c++) { string channel_name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); a_Stream.Position += 12; //uint nameHash; int frameIndex, frameCount } int fullWeights_size = a_Stream.ReadInt32(); a_Stream.Position += fullWeights_size * 4; //floats m_BindPose = new float[a_Stream.ReadInt32()][,]; for (int i = 0; i < m_BindPose.Length; i++) { m_BindPose[i] = new float[4,4] { { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }, { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }, { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }, { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() } }; } int m_BoneNameHashes_size = a_Stream.ReadInt32(); a_Stream.Position += m_BoneNameHashes_size * 4; //uints uint m_RootBoneNameHash = a_Stream.ReadUInt32(); } #endregion #region Index Buffer for 2.6.0 and later if (version[0] >= 3 || (version[0] == 2 && version[1] >= 6)) { m_MeshCompression = a_Stream.ReadByte(); if (version[0] >= 4) { if (version[0] < 5) { uint m_StreamCompression = a_Stream.ReadByte(); } bool m_IsReadable = a_Stream.ReadBoolean(); bool m_KeepVertices = a_Stream.ReadBoolean(); bool m_KeepIndices = a_Stream.ReadBoolean(); } a_Stream.AlignStream(4); int m_IndexBuffer_size = a_Stream.ReadInt32(); if (m_Use16BitIndices) { m_IndexBuffer = new uint[m_IndexBuffer_size / 2]; for (int i = 0; i < m_IndexBuffer_size / 2; i++) { m_IndexBuffer[i] = a_Stream.ReadUInt16(); } a_Stream.AlignStream(4); } else { m_IndexBuffer = new uint[m_IndexBuffer_size / 4]; for (int i = 0; i < m_IndexBuffer_size / 4; i++) { m_IndexBuffer[i] = a_Stream.ReadUInt32(); } a_Stream.AlignStream(4);//untested } } #endregion #region Vertex Buffer for 3.4.2 and earlier if (version[0] < 3 || (version[0] == 3 && version[1] < 5)) { m_VertexCount = a_Stream.ReadInt32(); m_Vertices = new float[m_VertexCount * 3]; for (int v = 0; v < m_VertexCount * 3; v++) { m_Vertices[v] = a_Stream.ReadSingle(); } m_Skin = new List<BoneInfluence>[a_Stream.ReadInt32()]; //m_Skin = new Dictionary<int, float>[a_Stream.ReadInt32()]; for (int s = 0; s < m_Skin.Length; s++) { m_Skin[s] = new List<BoneInfluence>(); for (int i = 0; i < 4; i++) { m_Skin[s].Add(new BoneInfluence() { weight = a_Stream.ReadSingle() }); } for (int i = 0; i < 4; i++) { m_Skin[s][i].boneIndex = a_Stream.ReadInt32(); } /*m_Skin[s] = new Dictionary<int, float>(); float[] weights = new float[4] { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }; for (int i = 0; i < 4; i++) { int boneIndex = a_Stream.ReadInt32(); m_Skin[s][boneIndex] = weights[i]; }*/ } m_BindPose = new float[a_Stream.ReadInt32()][,]; for (int i = 0; i < m_BindPose.Length; i++) { m_BindPose[i] = new float[4, 4] { { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }, { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }, { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }, { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() } }; } int m_UV1_size = a_Stream.ReadInt32(); m_UV1 = new float[m_UV1_size * 2]; for (int v = 0; v < m_UV1_size * 2; v++) { m_UV1[v] = a_Stream.ReadSingle(); } int m_UV2_size = a_Stream.ReadInt32(); m_UV2 = new float[m_UV2_size * 2]; for (int v = 0; v < m_UV2_size * 2; v++) { m_UV2[v] = a_Stream.ReadSingle(); } if (version[0] == 2 && version[1] <= 5) { int m_TangentSpace_size = a_Stream.ReadInt32(); m_Normals = new float[m_TangentSpace_size * 3]; for (int v = 0; v < m_TangentSpace_size; v++) { m_Normals[v * 3] = a_Stream.ReadSingle(); m_Normals[v * 3 + 1] = a_Stream.ReadSingle(); m_Normals[v * 3 + 2] = a_Stream.ReadSingle(); a_Stream.Position += 16; //Vector3f tangent & float handedness } } else //2.6.0 and later { int m_Tangents_size = a_Stream.ReadInt32(); a_Stream.Position += m_Tangents_size * 16; //Vector4f int m_Normals_size = a_Stream.ReadInt32(); m_Normals = new float[m_Normals_size * 3]; for (int v = 0; v < m_Normals_size * 3; v++) { m_Normals[v] = a_Stream.ReadSingle(); } } } #endregion #region Vertex Buffer for 3.5.0 and later else { #region read vertex stream m_Skin = new List<BoneInfluence>[a_Stream.ReadInt32()]; //m_Skin = new Dictionary<int, float>[a_Stream.ReadInt32()]; for (int s = 0; s < m_Skin.Length; s++) { m_Skin[s] = new List<BoneInfluence>(); for (int i = 0; i < 4; i++) { m_Skin[s].Add(new BoneInfluence() { weight = a_Stream.ReadSingle() }); } for (int i = 0; i < 4; i++) { m_Skin[s][i].boneIndex = a_Stream.ReadInt32(); } /*m_Skin[s] = new Dictionary<int, float>(); float[] weights = new float[4] { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }; for (int i = 0; i < 4; i++) { int boneIndex = a_Stream.ReadInt32(); m_Skin[s][boneIndex] = weights[i]; }*/ } if (version[0] == 3 || (version[0] == 4 && version[1] <= 2)) { m_BindPose = new float[a_Stream.ReadInt32()][,]; for (int i = 0; i < m_BindPose.Length; i++) { m_BindPose[i] = new float[4, 4] { { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }, { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }, { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }, { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() } }; } } BitArray m_CurrentChannels = new BitArray(new int[1] { a_Stream.ReadInt32() }); m_VertexCount = a_Stream.ReadInt32(); //int singleStreamStride = 0;//used tor unity 5 int streamCount = 0; #region streams for 3.5.0 - 3.5.7 if (version[0] < 4) { if (m_MeshCompression != 0 && version[2] == 0) //special case not just on platform 9 { a_Stream.Position += 12; } else { m_Streams = new StreamInfo[4]; for (int s = 0; s < 4; s++) { m_Streams[s] = new StreamInfo(); m_Streams[s].channelMask = new BitArray(new int[1] { a_Stream.ReadInt32() }); m_Streams[s].offset = a_Stream.ReadInt32(); m_Streams[s].stride = a_Stream.ReadInt32(); m_Streams[s].align = a_Stream.ReadUInt32(); } } } #endregion #region channels and streams for 4.0.0 and later else { m_Channels = new ChannelInfo[a_Stream.ReadInt32()]; for (int c = 0; c < m_Channels.Length; c++) { m_Channels[c] = new ChannelInfo(); m_Channels[c].stream = a_Stream.ReadByte(); m_Channels[c].offset = a_Stream.ReadByte(); m_Channels[c].format = a_Stream.ReadByte(); m_Channels[c].dimension = a_Stream.ReadByte(); //calculate stride for Unity 5 //singleStreamStride += m_Channels[c].dimension * (4 / (int)Math.Pow(2, m_Channels[c].format)); if (m_Channels[c].stream >= streamCount) { streamCount = m_Channels[c].stream + 1; } } if (version[0] < 5) { m_Streams = new StreamInfo[a_Stream.ReadInt32()]; for (int s = 0; s < m_Streams.Length; s++) { m_Streams[s] = new StreamInfo(); m_Streams[s].channelMask = new BitArray(new int[1] { a_Stream.ReadInt32() }); m_Streams[s].offset = a_Stream.ReadInt32(); m_Streams[s].stride = a_Stream.ReadByte(); m_Streams[s].dividerOp = a_Stream.ReadByte(); m_Streams[s].frequency = a_Stream.ReadUInt16(); } } } #endregion //actual Vertex Buffer byte[] m_DataSize = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_DataSize, 0, m_DataSize.Length); if (version[0] >= 5) //create streams { m_Streams = new StreamInfo[streamCount]; for (int s = 0; s < streamCount; s++) { m_Streams[s] = new StreamInfo(); m_Streams[s].channelMask = new BitArray(new int[1] { 0 }); m_Streams[s].offset = 0; m_Streams[s].stride = 0; foreach (var m_Channel in m_Channels) { if (m_Channel.stream == s) { m_Streams[s].stride += m_Channel.dimension * (4 / (int)Math.Pow(2, m_Channel.format)); } } if (s > 0) { m_Streams[s].offset = m_Streams[s - 1].offset + m_Streams[s - 1].stride * m_VertexCount; //sometimes there are 8 bytes between streams //this is NOT an alignment, even if sometimes it may seem so if (streamCount == 2) { m_Streams[s].offset = m_DataSize.Length - m_Streams[s].stride * m_VertexCount; } else { m_VertexCount = 0; return; } /*var absoluteOffset = a_Stream.Position + 4 + m_Streams[s].offset; if ((absoluteOffset % m_Streams[s].stride) != 0) { m_Streams[s].offset += m_Streams[s].stride - (int)(absoluteOffset % m_Streams[s].stride); }*/ } } } #endregion #region compute FvF int componentByteSize = 0; byte[] componentBytes; float[] componentsArray; #region 4.0.0 and later if (m_Channels != null) { //it is better to loop channels instead of streams //because channels are likely to be sorted by vertex property foreach (var m_Channel in m_Channels) { if (m_Channel.dimension > 0) { var m_Stream = m_Streams[m_Channel.stream]; for (int b = 0; b < 8; b++) { //in the future, try to use only m_CurrentChannels if ((version[0] < 5 && m_Stream.channelMask.Get(b)) || (version[0] >= 5 && m_CurrentChannels.Get(b))) { // in Unity 4.x the colors channel has 1 dimension, as in 1 color with 4 components if (b == 2 && m_Channel.format == 2) { m_Channel.dimension = 4; } componentByteSize = 4 / (int)Math.Pow(2, m_Channel.format); /*switch (m_Channel.format) { case 0: //32bit valueBufferSize = 4; break; case 1: //16bit valueBufferSize = 2; break; case 2: //8bit valueBufferSize = 1; m_Channel.dimension = 4;//in older versions this is 1, as in 1 color with 4 components break; }*/ componentBytes = new byte[componentByteSize]; componentsArray = new float[m_VertexCount * m_Channel.dimension]; for (int v = 0; v < m_VertexCount; v++) { int vertexOffset = m_Stream.offset + m_Channel.offset + m_Stream.stride * v; for (int d = 0; d < m_Channel.dimension; d++) { int componentOffset = vertexOffset + componentByteSize * d; Buffer.BlockCopy(m_DataSize, componentOffset, componentBytes, 0, componentByteSize); componentsArray[v * m_Channel.dimension + d] = bytesToFloat(componentBytes); } } switch (b) { case 0: m_Vertices = componentsArray; break; case 1: m_Normals = componentsArray; break; case 2: m_Colors = componentsArray; break; case 3: m_UV1 = componentsArray; break; case 4: m_UV2 = componentsArray; break; case 5: if (version[0] == 5) { m_UV3 = componentsArray; } else { m_Tangents = componentsArray; } break; case 6: m_UV4 = componentsArray; break; case 7: m_Tangents = componentsArray; break; } m_Stream.channelMask.Set(b, false); m_CurrentChannels.Set(b, false); componentBytes = null; componentsArray = null; break; //go to next channel } } } } } #endregion #region 3.5.0 - 3.5.7 else if (m_Streams != null) { foreach (var m_Stream in m_Streams) { //a stream may have multiple vertex components but without channels there are no offsets, so I assume all vertex properties are in order //Unity 3.5.x only uses floats, and that's probably why channels were introduced in Unity 4 ChannelInfo m_Channel = new ChannelInfo();//create my own channel so I can use the same methods m_Channel.offset = 0; for (int b = 0; b < 6; b++) { if (m_Stream.channelMask.Get(b)) { switch (b) { case 0: case 1: componentByteSize = 4; m_Channel.dimension = 3; break; case 2: componentByteSize = 1; m_Channel.dimension = 4; break; case 3: case 4: componentByteSize = 4; m_Channel.dimension = 2; break; case 5: componentByteSize = 4; m_Channel.dimension = 4; break; } componentBytes = new byte[componentByteSize]; componentsArray = new float[m_VertexCount * m_Channel.dimension]; for (int v = 0; v < m_VertexCount; v++) { int vertexOffset = m_Stream.offset + m_Channel.offset + m_Stream.stride * v; for (int d = 0; d < m_Channel.dimension; d++) { int m_DataSizeOffset = vertexOffset + componentByteSize * d; Buffer.BlockCopy(m_DataSize, m_DataSizeOffset, componentBytes, 0, componentByteSize); componentsArray[v * m_Channel.dimension + d] = bytesToFloat(componentBytes); } } switch (b) { case 0: m_Vertices = componentsArray; break; case 1: m_Normals = componentsArray; break; case 2: m_Colors = componentsArray; break; case 3: m_UV1 = componentsArray; break; case 4: m_UV2 = componentsArray; break; case 5: m_Tangents = componentsArray; break; } m_Channel.offset += (byte)(m_Channel.dimension * componentByteSize); //safe to cast as byte because strides larger than 255 are unlikely m_Stream.channelMask.Set(b, false); componentBytes = null; componentsArray = null; } } } } #endregion #endregion } #endregion #region Compressed Mesh data for 2.6.0 and later - 160 bytes if (version[0] >= 3 || (version[0] == 2 && version[1] >= 6)) { //remember there can be combinations of packed and regular vertex properties #region m_Vertices PackedBitVector m_Vertices_Packed = new PackedBitVector(); m_Vertices_Packed.m_NumItems = a_Stream.ReadInt32(); m_Vertices_Packed.m_Range = a_Stream.ReadSingle(); m_Vertices_Packed.m_Start = a_Stream.ReadSingle(); m_Vertices_Packed.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_Vertices_Packed.m_Data, 0, m_Vertices_Packed.m_Data.Length); a_Stream.AlignStream(4); m_Vertices_Packed.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment if (m_Vertices_Packed.m_NumItems > 0) { m_VertexCount = m_Vertices_Packed.m_NumItems / 3; uint[] m_Vertices_Unpacked = UnpackBitVector(m_Vertices_Packed); int bitmax = 0;//used to convert int value to float for (int b = 0; b < m_Vertices_Packed.m_BitSize; b++) { bitmax |= (1 << b); } m_Vertices = new float[m_Vertices_Packed.m_NumItems]; for (int v = 0; v < m_Vertices_Packed.m_NumItems; v++) { m_Vertices[v] = (float)((double)m_Vertices_Unpacked[v] / bitmax) * m_Vertices_Packed.m_Range + m_Vertices_Packed.m_Start; } } #endregion #region m_UV PackedBitVector m_UV_Packed = new PackedBitVector(); //contains all channels m_UV_Packed.m_NumItems = a_Stream.ReadInt32(); m_UV_Packed.m_Range = a_Stream.ReadSingle(); m_UV_Packed.m_Start = a_Stream.ReadSingle(); m_UV_Packed.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_UV_Packed.m_Data, 0, m_UV_Packed.m_Data.Length); a_Stream.AlignStream(4); m_UV_Packed.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment if (m_UV_Packed.m_NumItems > 0 && (bool)Properties.Settings.Default["exportUVs"]) { uint[] m_UV_Unpacked = UnpackBitVector(m_UV_Packed); int bitmax = 0; for (int b = 0; b < m_UV_Packed.m_BitSize; b++) { bitmax |= (1 << b); } m_UV1 = new float[m_VertexCount * 2]; for (int v = 0; v < m_VertexCount * 2; v++) { m_UV1[v] = (float)((double)m_UV_Unpacked[v] / bitmax) * m_UV_Packed.m_Range + m_UV_Packed.m_Start; } if (m_UV_Packed.m_NumItems >= m_VertexCount * 4) { m_UV2 = new float[m_VertexCount * 2]; for (uint v = 0; v < m_VertexCount * 2; v++) { m_UV2[v] = (float)((double)m_UV_Unpacked[v + m_VertexCount * 2] / bitmax) * m_UV_Packed.m_Range + m_UV_Packed.m_Start; } if (m_UV_Packed.m_NumItems >= m_VertexCount * 6) { m_UV3 = new float[m_VertexCount * 2]; for (uint v = 0; v < m_VertexCount * 2; v++) { m_UV3[v] = (float)((double)m_UV_Unpacked[v + m_VertexCount * 4] / bitmax) * m_UV_Packed.m_Range + m_UV_Packed.m_Start; } if (m_UV_Packed.m_NumItems == m_VertexCount * 8) { m_UV4 = new float[m_VertexCount * 2]; for (uint v = 0; v < m_VertexCount * 2; v++) { m_UV4[v] = (float)((double)m_UV_Unpacked[v + m_VertexCount * 6] / bitmax) * m_UV_Packed.m_Range + m_UV_Packed.m_Start; } } } } } #endregion #region m_BindPose if (version[0] < 5) { PackedBitVector m_BindPoses_Packed = new PackedBitVector(); m_BindPoses_Packed.m_NumItems = a_Stream.ReadInt32(); m_BindPoses_Packed.m_Range = a_Stream.ReadSingle(); m_BindPoses_Packed.m_Start = a_Stream.ReadSingle(); m_BindPoses_Packed.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_BindPoses_Packed.m_Data, 0, m_BindPoses_Packed.m_Data.Length); a_Stream.AlignStream(4); m_BindPoses_Packed.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment if (m_BindPoses_Packed.m_NumItems > 0 && (bool)Properties.Settings.Default["exportDeformers"]) { uint[] m_BindPoses_Unpacked = UnpackBitVector(m_BindPoses_Packed); int bitmax = 0;//used to convert int value to float for (int b = 0; b < m_BindPoses_Packed.m_BitSize; b++) { bitmax |= (1 << b); } m_BindPose = new float[m_BindPoses_Packed.m_NumItems / 16][,]; for (int i = 0; i < m_BindPose.Length; i++) { m_BindPose[i] = new float[4, 4]; for (int j = 0; j < 4; j++) { for (int k = 0; k < 4; k++) { m_BindPose[i][j,k] = (float)((double)m_BindPoses_Unpacked[i * 16 + j * 4 + k] / bitmax) * m_BindPoses_Packed.m_Range + m_BindPoses_Packed.m_Start; } } } } } #endregion PackedBitVector m_Normals_Packed = new PackedBitVector(); m_Normals_Packed.m_NumItems = a_Stream.ReadInt32(); m_Normals_Packed.m_Range = a_Stream.ReadSingle(); m_Normals_Packed.m_Start = a_Stream.ReadSingle(); m_Normals_Packed.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_Normals_Packed.m_Data, 0, m_Normals_Packed.m_Data.Length); a_Stream.AlignStream(4); m_Normals_Packed.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment PackedBitVector m_Tangents_Packed = new PackedBitVector(); m_Tangents_Packed.m_NumItems = a_Stream.ReadInt32(); m_Tangents_Packed.m_Range = a_Stream.ReadSingle(); m_Tangents_Packed.m_Start = a_Stream.ReadSingle(); m_Tangents_Packed.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_Tangents_Packed.m_Data, 0, m_Tangents_Packed.m_Data.Length); a_Stream.AlignStream(4); m_Tangents_Packed.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment PackedBitVector m_Weights = new PackedBitVector(); m_Weights.m_NumItems = a_Stream.ReadInt32(); m_Weights.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_Weights.m_Data, 0, m_Weights.m_Data.Length); a_Stream.AlignStream(4); m_Weights.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment #region m_Normals PackedBitVector m_NormalSigns_packed = new PackedBitVector(); m_NormalSigns_packed.m_NumItems = a_Stream.ReadInt32(); m_NormalSigns_packed.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_NormalSigns_packed.m_Data, 0, m_NormalSigns_packed.m_Data.Length); a_Stream.AlignStream(4); m_NormalSigns_packed.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment if (m_Normals_Packed.m_NumItems > 0 && (bool)Properties.Settings.Default["exportNormals"]) { uint[] m_Normals_Unpacked = UnpackBitVector(m_Normals_Packed); uint[] m_NormalSigns = UnpackBitVector(m_NormalSigns_packed); int bitmax = 0; for (int b = 0; b < m_Normals_Packed.m_BitSize; b++) { bitmax |= (1 << b); } m_Normals = new float[m_Normals_Packed.m_NumItems / 2 * 3]; for (int v = 0; v < m_Normals_Packed.m_NumItems / 2; v++) { m_Normals[v * 3] = (float)((double)m_Normals_Unpacked[v * 2] / bitmax) * m_Normals_Packed.m_Range + m_Normals_Packed.m_Start; m_Normals[v * 3 + 1] = (float)((double)m_Normals_Unpacked[v * 2 + 1] / bitmax) * m_Normals_Packed.m_Range + m_Normals_Packed.m_Start; m_Normals[v * 3 + 2] = (float)Math.Sqrt(1 - m_Normals[v * 3] * m_Normals[v * 3] - m_Normals[v * 3 + 1] * m_Normals[v * 3 + 1]); if (m_NormalSigns[v] == 0) { m_Normals[v * 3 + 2] *= -1; } } } #endregion #region m_Tangents PackedBitVector m_TangentSigns_packed = new PackedBitVector(); m_TangentSigns_packed.m_NumItems = a_Stream.ReadInt32(); m_TangentSigns_packed.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_TangentSigns_packed.m_Data, 0, m_TangentSigns_packed.m_Data.Length); a_Stream.AlignStream(4); m_TangentSigns_packed.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment if (m_Tangents_Packed.m_NumItems > 0 && (bool)Properties.Settings.Default["exportTangents"]) { uint[] m_Tangents_Unpacked = UnpackBitVector(m_Tangents_Packed); uint[] m_TangentSigns = UnpackBitVector(m_TangentSigns_packed); int bitmax = 0; for (int b = 0; b < m_Tangents_Packed.m_BitSize; b++) { bitmax |= (1 << b); } m_Tangents = new float[m_Tangents_Packed.m_NumItems / 2 * 3]; for (int v = 0; v < m_Tangents_Packed.m_NumItems / 2; v++) { m_Tangents[v * 3] = (float)((double)m_Tangents_Unpacked[v * 2] / bitmax) * m_Tangents_Packed.m_Range + m_Tangents_Packed.m_Start; m_Tangents[v * 3 + 1] = (float)((double)m_Tangents_Unpacked[v * 2 + 1] / bitmax) * m_Tangents_Packed.m_Range + m_Tangents_Packed.m_Start; m_Tangents[v * 3 + 2] = (float)Math.Sqrt(1 - m_Tangents[v * 3] * m_Tangents[v * 3] - m_Tangents[v * 3 + 1] * m_Tangents[v * 3 + 1]); if (m_TangentSigns[v] == 0) { m_Tangents[v * 3 + 2] *= -1; } } } #endregion #region m_FloatColors if (version[0] >= 5) { PackedBitVector m_FloatColors = new PackedBitVector(); m_FloatColors.m_NumItems = a_Stream.ReadInt32(); m_FloatColors.m_Range = a_Stream.ReadSingle(); m_FloatColors.m_Start = a_Stream.ReadSingle(); m_FloatColors.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_FloatColors.m_Data, 0, m_FloatColors.m_Data.Length); a_Stream.AlignStream(4); m_FloatColors.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment if (m_FloatColors.m_NumItems > 0 && (bool)Properties.Settings.Default["exportColors"]) { uint[] m_FloatColors_Unpacked = UnpackBitVector(m_FloatColors); int bitmax = 0; for (int b = 0; b < m_FloatColors.m_BitSize; b++) { bitmax |= (1 << b); } m_Colors = new float[m_FloatColors.m_NumItems]; for (int v = 0; v < m_FloatColors.m_NumItems; v++) { m_Colors[v] = (float)m_FloatColors_Unpacked[v] / bitmax * m_FloatColors.m_Range + m_FloatColors.m_Start; } } } #endregion #region m_Skin PackedBitVector m_BoneIndices = new PackedBitVector(); m_BoneIndices.m_NumItems = a_Stream.ReadInt32(); m_BoneIndices.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_BoneIndices.m_Data, 0, m_BoneIndices.m_Data.Length); a_Stream.AlignStream(4); m_BoneIndices.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment //how the hell does this work?? if (m_BoneIndices.m_NumItems > 0 && m_BoneIndices.m_NumItems == m_Weights.m_NumItems && (bool)Properties.Settings.Default["exportDeformers"]) { uint[] m_Weights_Unpacked = UnpackBitVector(m_Weights); int bitmax = 0; for (int b = 0; b < m_Weights.m_BitSize; b++) { bitmax |= (1 << b); } uint[] m_BoneIndices_Unpacked = UnpackBitVector(m_BoneIndices); m_Skin = new List<BoneInfluence>[m_BoneIndices.m_NumItems / 4]; for (int s = 0; s < m_Skin.Length; s++) { m_Skin[s] = new List<BoneInfluence>(); for (int i = 0; i < 4; i++) { m_Skin[s].Add(new BoneInfluence() { weight = (float)((double)m_Weights_Unpacked[s * 4 + i] / bitmax), boneIndex = (int)m_BoneIndices_Unpacked[s * 4 + i] }); } } } #endregion PackedBitVector m_Triangles = new PackedBitVector(); m_Triangles.m_NumItems = a_Stream.ReadInt32(); m_Triangles.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_Triangles.m_Data, 0, m_Triangles.m_Data.Length); a_Stream.AlignStream(4); m_Triangles.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment if (m_Triangles.m_NumItems > 0) { m_IndexBuffer = UnpackBitVector(m_Triangles); } } #endregion #region Colors & Collision triangles for 3.4.2 and earlier if (version[0] <= 2 || (version[0] == 3 && version[1] <= 4)) // { a_Stream.Position += 24; //Axis-Aligned Bounding Box int m_Colors_size = a_Stream.ReadInt32(); m_Colors = new float[m_Colors_size * 4]; for (int v = 0; v < m_Colors_size * 4; v++) { m_Colors[v] = (float)(a_Stream.ReadByte()) / 0xFF; } int m_CollisionTriangles_size = a_Stream.ReadInt32(); a_Stream.Position += m_CollisionTriangles_size * 4; //UInt32 indices int m_CollisionVertexCount = a_Stream.ReadInt32(); } #endregion #region Compressed colors & Local AABB for 3.5.0 to 4.x.x else //vertex colors are either in streams or packed bits { if (version[0] < 5) { PackedBitVector m_Colors_Packed = new PackedBitVector(); m_Colors_Packed.m_NumItems = a_Stream.ReadInt32(); m_Colors_Packed.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_Colors_Packed.m_Data, 0, m_Colors_Packed.m_Data.Length); a_Stream.AlignStream(4); m_Colors_Packed.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment if (m_Colors_Packed.m_NumItems > 0) { if (m_Colors_Packed.m_BitSize == 32) { //4 x 8bit color channels m_Colors = new float[m_Colors_Packed.m_Data.Length]; for (int v = 0; v < m_Colors_Packed.m_Data.Length; v++) { m_Colors[v] = (float)m_Colors_Packed.m_Data[v] / 0xFF; } } else //not tested { uint[] m_Colors_Unpacked = UnpackBitVector(m_Colors_Packed); int bitmax = 0;//used to convert int value to float for (int b = 0; b < m_Colors_Packed.m_BitSize; b++) { bitmax |= (1 << b); } m_Colors = new float[m_Colors_Packed.m_NumItems]; for (int v = 0; v < m_Colors_Packed.m_NumItems; v++) { m_Colors[v] = (float)m_Colors_Unpacked[v] / bitmax; } } } } else { uint m_UVInfo = a_Stream.ReadUInt32(); } a_Stream.Position += 24; //Axis-Aligned Bounding Box } #endregion int m_MeshUsageFlags = a_Stream.ReadInt32(); if (version[0] >= 5) { //int m_BakedConvexCollisionMesh = a_Stream.ReadInt32(); //a_Stream.Position += m_BakedConvexCollisionMesh; //int m_BakedTriangleCollisionMesh = a_Stream.ReadInt32(); //a_Stream.Position += m_BakedConvexCollisionMesh; } #region Build face indices for (int s = 0; s < m_SubMeshes_size; s++) { uint firstIndex = m_SubMeshes[s].firstByte / 2; if (!m_Use16BitIndices) { firstIndex /= 2; } if (m_SubMeshes[s].topology == 0) { for (int i = 0; i < m_SubMeshes[s].indexCount / 3; i++) { m_Indices.Add(m_IndexBuffer[firstIndex + i * 3]); m_Indices.Add(m_IndexBuffer[firstIndex + i * 3 + 1]); m_Indices.Add(m_IndexBuffer[firstIndex + i * 3 + 2]); m_materialIDs.Add(s); } } else { for (int i = 0; i < m_SubMeshes[s].indexCount - 2; i++) { uint fa = m_IndexBuffer[firstIndex + i]; uint fb = m_IndexBuffer[firstIndex + i + 1]; uint fc = m_IndexBuffer[firstIndex + i + 2]; if ((fa!=fb) && (fa!=fc) && (fc!=fb)) { m_Indices.Add(fa); if ((i % 2) == 0) { m_Indices.Add(fb); m_Indices.Add(fc); } else { m_Indices.Add(fc); m_Indices.Add(fb); } m_materialIDs.Add(s); } } } } #endregion }
public Mesh(AssetPreloadData MeshPD) { //Stream = new EndianStream(File.OpenRead(sourceFile.filePath), sourceFile.endianType); //Stream.endian = sourceFile.endianType; var version = MeshPD.sourceFile.version; a_Stream = MeshPD.sourceFile.a_Stream; a_Stream.Position = MeshPD.Offset; bool m_Use16BitIndices = true; //3.5.0 and newer always uses 16bit indices uint m_MeshCompression = 0; if (MeshPD.sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = MeshPD.sourceFile.ReadPPtr(); PPtr m_PrefabInternal = MeshPD.sourceFile.ReadPPtr(); } m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); if (version[0] < 3 || (version[0] == 3 && version[1] < 5)) { m_Use16BitIndices = a_Stream.ReadBoolean(); a_Stream.Position += 3; } #region Index Buffer for 2.5.1 and earlier if (version[0] == 2 && version[1] <= 5) { int m_IndexBuffer_size = a_Stream.ReadInt32(); if (m_Use16BitIndices) { m_IndexBuffer = new uint[m_IndexBuffer_size / 2]; for (int i = 0; i < m_IndexBuffer_size / 2; i++) { m_IndexBuffer[i] = a_Stream.ReadUInt16(); } a_Stream.AlignStream(4); } else { m_IndexBuffer = new uint[m_IndexBuffer_size / 4]; for (int i = 0; i < m_IndexBuffer_size / 4; i++) { m_IndexBuffer[i] = a_Stream.ReadUInt32(); } } } #endregion int m_SubMeshes_size = a_Stream.ReadInt32(); for (int s = 0; s < m_SubMeshes_size; s++) { m_SubMeshes.Add(new SubMesh()); m_SubMeshes[s].firstByte = a_Stream.ReadUInt32(); m_SubMeshes[s].indexCount = a_Stream.ReadUInt32(); //what is this in case of triangle strips? m_SubMeshes[s].topology = a_Stream.ReadInt32(); //isTriStrip if (version[0] < 4) { m_SubMeshes[s].triangleCount = a_Stream.ReadUInt32(); } if (version[0] >= 3) { m_SubMeshes[s].firstVertex = a_Stream.ReadUInt32(); m_SubMeshes[s].vertexCount = a_Stream.ReadUInt32(); a_Stream.Position += 24; //Axis-Aligned Bounding Box } } #region m_Shapes for 4.1.0 and later, excluding 4.1.0 alpha if (version [0] >= 5 || (version[0] == 4 && (version[1] > 1 || (version[1] == 1 && MeshPD.sourceFile.buildType[0] != "a")))) { if (version[0] == 4 && version[1] <= 2) //4.1.0f4 - 4.2.2f1 { int m_Shapes_size = a_Stream.ReadInt32(); if (m_Shapes_size > 0) { bool stop = true; } for (int s = 0; s < m_Shapes_size; s++) //untested { string shape_name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); a_Stream.Position += 36; //uint firstVertex, vertexCount; Vector3f aabbMinDelta, aabbMaxDelta; bool hasNormals, hasTangents } int m_ShapeVertices_size = a_Stream.ReadInt32(); a_Stream.Position += m_ShapeVertices_size * 40; //vertex positions, normals, tangents & uint index } else //4.3.0 and later { int m_ShapeVertices_size = a_Stream.ReadInt32(); a_Stream.Position += m_ShapeVertices_size * 40; //vertex positions, normals, tangents & uint index int shapes_size = a_Stream.ReadInt32(); a_Stream.Position += shapes_size * 12; //uint firstVertex, vertexCount; bool hasNormals, hasTangents int channels_size = a_Stream.ReadInt32(); for (int c = 0; c < channels_size; c++) { string channel_name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); a_Stream.Position += 12; //uint nameHash; int frameIndex, frameCount } int fullWeights_size = a_Stream.ReadInt32(); a_Stream.Position += fullWeights_size * 4; //floats int m_BindPose_size = a_Stream.ReadInt32(); a_Stream.Position += m_BindPose_size * 16 * 4; //matrix 4x4 int m_BoneNameHashes_size = a_Stream.ReadInt32(); a_Stream.Position += m_BoneNameHashes_size * 4; //uints uint m_RootBoneNameHash = a_Stream.ReadUInt32(); } } #endregion #region Index Buffer for 2.6.0 and later if (version[0] >= 3 || (version[0] == 2 && version[1] >= 6)) { m_MeshCompression = a_Stream.ReadByte(); if (version[0] >= 4) { if (version[0] < 5) { uint m_StreamCompression = a_Stream.ReadByte(); } bool m_IsReadable = a_Stream.ReadBoolean(); bool m_KeepVertices = a_Stream.ReadBoolean(); bool m_KeepIndices = a_Stream.ReadBoolean(); } a_Stream.AlignStream(4); int m_IndexBuffer_size = a_Stream.ReadInt32(); if (m_Use16BitIndices) { m_IndexBuffer = new uint[m_IndexBuffer_size / 2]; for (int i = 0; i < m_IndexBuffer_size / 2; i++) { m_IndexBuffer[i] = a_Stream.ReadUInt16(); } a_Stream.AlignStream(4); } else { m_IndexBuffer = new uint[m_IndexBuffer_size / 4]; for (int i = 0; i < m_IndexBuffer_size / 4; i++) { m_IndexBuffer[i] = a_Stream.ReadUInt32(); } //align?? } } #endregion #region Vertex Buffer for 3.4.2 and earlier if (version[0] < 3 || (version[0] == 3 && version[1] < 5)) { m_VertexCount = a_Stream.ReadUInt32(); m_Vertices = new float[m_VertexCount * 3]; for (int v = 0; v < m_VertexCount * 3; v++) { m_Vertices[v] = a_Stream.ReadSingle(); } int m_Skin_size = a_Stream.ReadInt32(); a_Stream.Position += m_Skin_size * 32; //4x float weights & 4x int boneIndices int m_BindPose_size = a_Stream.ReadInt32(); a_Stream.Position += m_BindPose_size * 16 * 4; //matrix 4x4 int m_UV1_size = a_Stream.ReadInt32(); m_UV1 = new float[m_UV1_size * 2]; for (int v = 0; v < m_UV1_size * 2; v++) { m_UV1[v] = a_Stream.ReadSingle(); } int m_UV2_size = a_Stream.ReadInt32(); m_UV2 = new float[m_UV2_size * 2]; for (int v = 0; v < m_UV2_size * 2; v++) { m_UV2[v] = a_Stream.ReadSingle(); } if (version[0] == 2 && version[1] <= 5) { int m_TangentSpace_size = a_Stream.ReadInt32(); m_Normals = new float[m_TangentSpace_size * 3]; for (int v = 0; v < m_TangentSpace_size; v++) { m_Normals[v * 3] = a_Stream.ReadSingle(); m_Normals[v * 3 + 1] = a_Stream.ReadSingle(); m_Normals[v * 3 + 2] = a_Stream.ReadSingle(); a_Stream.Position += 16; //Vector3f tangent & float handedness } } else //2.6.0 and later { int m_Tangents_size = a_Stream.ReadInt32(); a_Stream.Position += m_Tangents_size * 16; //Vector4f int m_Normals_size = a_Stream.ReadInt32(); m_Normals = new float[m_Normals_size * 3]; for (int v = 0; v < m_Normals_size * 3; v++) { m_Normals[v] = a_Stream.ReadSingle(); } } } #endregion #region Vertex Buffer for 3.5.0 and later else { #region read vertex stream int m_Skin_size = a_Stream.ReadInt32(); a_Stream.Position += m_Skin_size * 32; //4x float weights & 4x int boneIndices if (version[0] <= 3 || (version[0] == 4 && version[1] <= 2)) { int m_BindPose_size = a_Stream.ReadInt32(); a_Stream.Position += m_BindPose_size * 16 * 4; //matrix 4x4 } int m_CurrentChannels = a_Stream.ReadInt32();//defined as uint in Unity m_VertexCount = a_Stream.ReadUInt32(); #region 3.5.0 - 3.5.7 if (version[0] < 4) { if (m_MeshCompression != 0 && version[2] == 0) //special case not just on platform 9 { a_Stream.Position += 12; } else { m_Streams = new StreamInfo[4]; for (int s = 0; s < 4; s++) { m_Streams[s] = new StreamInfo(); m_Streams[s].channelMask = new BitArray(new int[1] { a_Stream.ReadInt32() }); m_Streams[s].offset = a_Stream.ReadInt32(); m_Streams[s].stride = a_Stream.ReadInt32(); m_Streams[s].align = a_Stream.ReadUInt32(); } } } #endregion #region 4.0.0 and later else { int singleStreamStride = 0;//used tor unity 5 m_Channels = new ChannelInfo[a_Stream.ReadInt32()]; for (int c = 0; c < m_Channels.Length; c++) { m_Channels[c] = new ChannelInfo(); m_Channels[c].stream = a_Stream.ReadByte(); m_Channels[c].offset = a_Stream.ReadByte(); m_Channels[c].format = a_Stream.ReadByte(); m_Channels[c].dimension = a_Stream.ReadByte(); //calculate stride for Unity 5 singleStreamStride += m_Channels[c].dimension * (m_Channels[c].format % 2 == 0 ? 4 : 2);//fingers crossed! } if (version[0] < 5) { m_Streams = new StreamInfo[a_Stream.ReadInt32()]; for (int s = 0; s < m_Streams.Length; s++) { m_Streams[s] = new StreamInfo(); m_Streams[s].channelMask = new BitArray(new int[1] { a_Stream.ReadInt32() }); m_Streams[s].offset = a_Stream.ReadInt32(); m_Streams[s].stride = a_Stream.ReadByte(); m_Streams[s].dividerOp = a_Stream.ReadByte(); m_Streams[s].frequency = a_Stream.ReadUInt16(); } } else //it's just easier to create my own stream here { m_Streams = new StreamInfo[1]; m_Streams[0] = new StreamInfo(); m_Streams[0].channelMask = new BitArray(new int[1] { m_CurrentChannels }); m_Streams[0].offset = 0; m_Streams[0].stride = singleStreamStride; } } #endregion //actual Vertex Buffer byte[] m_DataSize = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_DataSize, 0, m_DataSize.Length); #endregion #region compute FvF byte valueBufferSize = 0; byte[] valueBuffer; float[] dstArray; if (m_Channels != null) { //it is better to loop channels instead of streams //because channels are likely to be sorted by vertex property #region 4.0.0 and later foreach (var m_Channel in m_Channels) { if (m_Channel.dimension > 0) { var m_Stream = m_Streams[m_Channel.stream]; for (int b = 0; b < 6; b++) { if (m_Stream.channelMask.Get(b)) { switch (m_Channel.format) { case 0: //32bit valueBufferSize = 4; break; case 1: //16bit valueBufferSize = 2; break; case 2: //8bit valueBufferSize = 1; m_Channel.dimension = 4;//these are actually groups of 4 components break; } valueBuffer = new byte[valueBufferSize]; dstArray = new float[m_VertexCount * m_Channel.dimension]; for (int v = 0; v < m_VertexCount; v++) { for (int d = 0; d < m_Channel.dimension; d++) { int m_DataSizeOffset = m_Stream.offset + m_Channel.offset + m_Stream.stride * v + valueBufferSize * d; Buffer.BlockCopy(m_DataSize, m_DataSizeOffset, valueBuffer, 0, valueBufferSize); dstArray[v * m_Channel.dimension + d] = bytesToFloat(valueBuffer); } } switch (b) { case 0://1 m_Vertices = dstArray; break; case 1://2 m_Normals = dstArray; break; case 2://4 m_Colors = dstArray; break; case 3://8 m_UV1 = dstArray; break; case 4://16 m_UV2 = dstArray; break; case 5://32 m_Tangents = dstArray; break; } m_Stream.channelMask.Set(b, false); //is this needed? valueBuffer = null; dstArray = null; break; //go to next channel } } } } } #endregion #region 3.5.0 - 3.5.7 else if (m_Streams != null) { foreach (var m_Stream in m_Streams) { //a stream may have multiple vertex components but without channels there are no offsets, so I assume all vertex properties are in order //Unity 3.5.x only uses floats, and that's probably why channels were introduced in Unity 4 ChannelInfo m_Channel = new ChannelInfo();//create my own channel so I can use the same methods m_Channel.offset = 0; for (int b = 0; b < 6; b++) { if (m_Stream.channelMask.Get(b)) { switch (b) { case 0: case 1: valueBufferSize = 4; m_Channel.dimension = 3; break; case 2: valueBufferSize = 1; m_Channel.dimension = 4; break; case 3: case 4: valueBufferSize = 4; m_Channel.dimension = 2; break; case 5: valueBufferSize = 4; m_Channel.dimension = 4; break; } valueBuffer = new byte[valueBufferSize]; dstArray = new float[m_VertexCount * m_Channel.dimension]; for (int v = 0; v < m_VertexCount; v++) { for (int d = 0; d < m_Channel.dimension; d++) { int m_DataSizeOffset = m_Stream.offset + m_Channel.offset + m_Stream.stride * v + valueBufferSize * d; Buffer.BlockCopy(m_DataSize, m_DataSizeOffset, valueBuffer, 0, valueBufferSize); dstArray[v * m_Channel.dimension + d] = bytesToFloat(valueBuffer); } } switch (b) { case 0: m_Vertices = dstArray; break; case 1: m_Normals = dstArray; break; case 2: m_Colors = dstArray; break; case 3: m_UV1 = dstArray; break; case 4: m_UV2 = dstArray; break; case 5: m_Tangents = dstArray; break; } m_Channel.offset += (byte)(m_Channel.dimension * valueBufferSize); //strides larger than 255 are unlikely m_Stream.channelMask.Set(b, false); //is this needed? valueBuffer = null; dstArray = null; } } } } #endregion #endregion } #endregion #region Compressed Mesh data for 2.6.0 and later - 160 bytes if (version[0] >= 3 || (version[0] == 2 && version[1] >= 6)) { //remember there can be combinations of packed and regular vertex properties PackedBitVector m_Vertices_Packed = new PackedBitVector(); m_Vertices_Packed.m_NumItems = a_Stream.ReadUInt32(); m_Vertices_Packed.m_Range = a_Stream.ReadSingle(); m_Vertices_Packed.m_Start = a_Stream.ReadSingle(); m_Vertices_Packed.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_Vertices_Packed.m_Data, 0, m_Vertices_Packed.m_Data.Length); a_Stream.AlignStream(4); m_Vertices_Packed.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment if (m_Vertices_Packed.m_NumItems > 0) { m_VertexCount = m_Vertices_Packed.m_NumItems / 3; uint[] m_Vertices_Unpacked = UnpackBitVector(m_Vertices_Packed); int bitmax = 0;//used to convert int value to float for (int b = 0; b < m_Vertices_Packed.m_BitSize; b++) { bitmax |= (1 << b); } m_Vertices = new float[m_Vertices_Packed.m_NumItems]; for (int v = 0; v < m_Vertices_Packed.m_NumItems; v++) { m_Vertices[v] = (float)m_Vertices_Unpacked[v] / bitmax * m_Vertices_Packed.m_Range + m_Vertices_Packed.m_Start; } } PackedBitVector m_UV_Packed = new PackedBitVector(); //contains both channels m_UV_Packed.m_NumItems = a_Stream.ReadUInt32(); m_UV_Packed.m_Range = a_Stream.ReadSingle(); m_UV_Packed.m_Start = a_Stream.ReadSingle(); m_UV_Packed.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_UV_Packed.m_Data, 0, m_UV_Packed.m_Data.Length); m_UV_Packed.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment if (m_UV_Packed.m_NumItems > 0) { uint[] m_UV_Unpacked = UnpackBitVector(m_UV_Packed); int bitmax = 0; for (int b = 0; b < m_Vertices_Packed.m_BitSize; b++) { bitmax |= (1 << b); } m_UV1 = new float[m_VertexCount * 2]; for (int v = 0; v < m_VertexCount * 2; v++) { m_UV1[v] = (float)m_UV_Unpacked[v] / bitmax * m_UV_Packed.m_Range + m_UV_Packed.m_Start; } if (m_UV_Packed.m_NumItems == m_VertexCount * 4) { m_UV2 = new float[m_VertexCount * 2]; for (uint v = 0; v < m_VertexCount * 2; v++) { m_UV2[v] = (float)m_UV_Unpacked[v + m_VertexCount * 2] / bitmax * m_UV_Packed.m_Range + m_UV_Packed.m_Start; } } } if (version[0] < 5) { PackedBitVector m_BindPoses_Packed = new PackedBitVector(); m_BindPoses_Packed.m_NumItems = a_Stream.ReadUInt32(); m_BindPoses_Packed.m_Range = a_Stream.ReadSingle(); m_BindPoses_Packed.m_Start = a_Stream.ReadSingle(); m_BindPoses_Packed.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_BindPoses_Packed.m_Data, 0, m_BindPoses_Packed.m_Data.Length); a_Stream.AlignStream(4); m_BindPoses_Packed.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment } PackedBitVector m_Normals_Packed = new PackedBitVector(); m_Normals_Packed.m_NumItems = a_Stream.ReadUInt32(); m_Normals_Packed.m_Range = a_Stream.ReadSingle(); m_Normals_Packed.m_Start = a_Stream.ReadSingle(); m_Normals_Packed.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_Normals_Packed.m_Data, 0, m_Normals_Packed.m_Data.Length); a_Stream.AlignStream(4); m_Normals_Packed.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment PackedBitVector m_Tangents_Packed = new PackedBitVector(); m_Tangents_Packed.m_NumItems = a_Stream.ReadUInt32(); m_Tangents_Packed.m_Range = a_Stream.ReadSingle(); m_Tangents_Packed.m_Start = a_Stream.ReadSingle(); m_Tangents_Packed.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_Tangents_Packed.m_Data, 0, m_Tangents_Packed.m_Data.Length); a_Stream.AlignStream(4); m_Tangents_Packed.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment PackedBitVector m_Weights_Packed = new PackedBitVector(); m_Weights_Packed.m_NumItems = a_Stream.ReadUInt32(); m_Weights_Packed.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_Weights_Packed.m_Data, 0, m_Weights_Packed.m_Data.Length); a_Stream.AlignStream(4); m_Weights_Packed.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment PackedBitVector m_NormalSigns_packed = new PackedBitVector(); m_NormalSigns_packed.m_NumItems = a_Stream.ReadUInt32(); m_NormalSigns_packed.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_NormalSigns_packed.m_Data, 0, m_NormalSigns_packed.m_Data.Length); a_Stream.AlignStream(4); m_NormalSigns_packed.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment if (m_Normals_Packed.m_NumItems > 0) { uint[] m_Normals_Unpacked = UnpackBitVector(m_Normals_Packed); uint[] m_NormalSigns = UnpackBitVector(m_NormalSigns_packed); int bitmax = 0; for (int b = 0; b < m_Normals_Packed.m_BitSize; b++) { bitmax |= (1 << b); } m_Normals = new float[m_Normals_Packed.m_NumItems / 2 * 3]; for (int v = 0; v < m_Normals_Packed.m_NumItems / 2; v++) { m_Normals[v * 3] = (float)((double)m_Normals_Unpacked[v * 2] / bitmax) * m_Normals_Packed.m_Range + m_Normals_Packed.m_Start; m_Normals[v * 3 + 1] = (float)((double)m_Normals_Unpacked[v * 2 + 1] / bitmax) * m_Normals_Packed.m_Range + m_Normals_Packed.m_Start; m_Normals[v * 3 + 2] = (float)Math.Sqrt(1 - m_Normals[v * 3] * m_Normals[v * 3] - m_Normals[v * 3 + 1] * m_Normals[v * 3 + 1]); if (m_NormalSigns[v] == 0) { m_Normals[v * 3 + 2] *= -1; } } } PackedBitVector m_TangentSigns = new PackedBitVector(); m_TangentSigns.m_NumItems = a_Stream.ReadUInt32(); m_TangentSigns.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_TangentSigns.m_Data, 0, m_TangentSigns.m_Data.Length); a_Stream.AlignStream(4); m_TangentSigns.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment if (version[0] >= 5) { PackedBitVector m_FloatColors = new PackedBitVector(); m_FloatColors.m_NumItems = a_Stream.ReadUInt32(); m_FloatColors.m_Range = a_Stream.ReadSingle(); m_FloatColors.m_Start = a_Stream.ReadSingle(); m_FloatColors.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_FloatColors.m_Data, 0, m_FloatColors.m_Data.Length); a_Stream.AlignStream(4); m_FloatColors.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment if (m_FloatColors.m_NumItems > 0) { uint[] m_FloatColors_Unpacked = UnpackBitVector(m_FloatColors); int bitmax = 0; for (int b = 0; b < m_Vertices_Packed.m_BitSize; b++) { bitmax |= (1 << b); } m_Colors = new float[m_FloatColors.m_NumItems]; for (int v = 0; v < m_FloatColors.m_NumItems; v++) { m_Colors[v] = (float)m_FloatColors_Unpacked[v] / bitmax * m_FloatColors.m_Range + m_FloatColors.m_Start; } } } PackedBitVector m_BoneIndices = new PackedBitVector(); m_BoneIndices.m_NumItems = a_Stream.ReadUInt32(); m_BoneIndices.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_BoneIndices.m_Data, 0, m_BoneIndices.m_Data.Length); a_Stream.AlignStream(4); m_BoneIndices.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment PackedBitVector m_Triangles = new PackedBitVector(); m_Triangles.m_NumItems = a_Stream.ReadUInt32(); m_Triangles.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_Triangles.m_Data, 0, m_Triangles.m_Data.Length); a_Stream.AlignStream(4); m_Triangles.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment if (m_Triangles.m_NumItems > 0) { m_IndexBuffer = UnpackBitVector(m_Triangles); } } #endregion #region Colors & Collision triangles for 3.4.2 and earlier if (version[0] <= 2 || (version[0] == 3 && version[1] <= 4)) // { a_Stream.Position += 24; //Axis-Aligned Bounding Box int m_Colors_size = a_Stream.ReadInt32(); m_Colors = new float[m_Colors_size * 4]; for (int v = 0; v < m_Colors_size * 4; v++) { m_Colors[v] = (float)(a_Stream.ReadByte()) / 0xFF; } int m_CollisionTriangles_size = a_Stream.ReadInt32(); a_Stream.Position += m_CollisionTriangles_size * 4; //UInt32 indices int m_CollisionVertexCount = a_Stream.ReadInt32(); } #endregion #region Compressed colors & Local AABB for 3.5.0 to 4.x.x else //vertex colors are either in streams or packed bits { if (version[0] < 5) { PackedBitVector m_Colors_Packed = new PackedBitVector(); m_Colors_Packed.m_NumItems = a_Stream.ReadUInt32(); m_Colors_Packed.m_Data = new byte[a_Stream.ReadInt32()]; a_Stream.Read(m_Colors_Packed.m_Data, 0, m_Colors_Packed.m_Data.Length); a_Stream.AlignStream(4); m_Colors_Packed.m_BitSize = a_Stream.ReadByte(); a_Stream.Position += 3; //4 byte alignment if (m_Colors_Packed.m_NumItems > 0) { if (m_Colors_Packed.m_BitSize == 32) { //4 x 8bit color channels m_Colors = new float[m_Colors_Packed.m_Data.Length]; for (int v = 0; v < m_Colors_Packed.m_Data.Length; v++) { m_Colors[v] = (float)m_Colors_Packed.m_Data[v] / 0xFF; } } else //not tested { uint[] m_Colors_Unpacked = UnpackBitVector(m_Colors_Packed); int bitmax = 0;//used to convert int value to float for (int b = 0; b < m_Colors_Packed.m_BitSize; b++) { bitmax |= (1 << b); } m_Colors = new float[m_Colors_Packed.m_NumItems]; for (int v = 0; v < m_Colors_Packed.m_NumItems; v++) { m_Colors[v] = (float)m_Colors_Unpacked[v] / bitmax; } } } } a_Stream.Position += 24; //Axis-Aligned Bounding Box } #endregion int m_MeshUsageFlags = a_Stream.ReadInt32(); if (version[0] >= 5) { //int m_BakedConvexCollisionMesh = a_Stream.ReadInt32(); //a_Stream.Position += m_BakedConvexCollisionMesh; //int m_BakedTriangleCollisionMesh = a_Stream.ReadInt32(); //a_Stream.Position += m_BakedConvexCollisionMesh; } #region Build face indices for (int s = 0; s < m_SubMeshes_size; s++) { uint firstIndex = m_SubMeshes[s].firstByte / 2; if (!m_Use16BitIndices) { firstIndex /= 2; } if (m_SubMeshes[s].topology == 0) { for (int i = 0; i < m_SubMeshes[s].indexCount / 3; i++) { m_Indices.Add(m_IndexBuffer[firstIndex + i * 3]); m_Indices.Add(m_IndexBuffer[firstIndex + i * 3 + 1]); m_Indices.Add(m_IndexBuffer[firstIndex + i * 3 + 2]); m_materialIDs.Add(s); } } else { for (int i = 0; i < m_SubMeshes[s].indexCount - 2; i++) { uint fa = m_IndexBuffer[firstIndex + i]; uint fb = m_IndexBuffer[firstIndex + i + 1]; uint fc = m_IndexBuffer[firstIndex + i + 2]; if ((fa!=fb) && (fa!=fc) && (fc!=fb)) { m_Indices.Add(fa); if ((i % 2) == 0) { m_Indices.Add(fb); m_Indices.Add(fc); } else { m_Indices.Add(fc); m_Indices.Add(fb); } m_materialIDs.Add(s); } } } } #endregion }
private void selectAsset(object sender, ListViewItemSelectionChangedEventArgs e) { previewPanel.BackgroundImage = global::Unity_Studio.Properties.Resources.preview; previewPanel.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; assetInfoLabel.Visible = false; assetInfoLabel.Text = null; textPreviewBox.Visible = false; fontPreviewBox.Visible = false; FMODpanel.Visible = false; lastLoadedAsset = null; FMOD.RESULT result; if (sound != null) { result = sound.release(); ERRCHECK(result); } sound = null; timer.Stop(); FMODtimerLabel.Text = "0:00.0 / 0:00.0"; FMODstatusLabel.Text = "Stopped"; FMODprogressBar.Value = 0; FMODinfoLabel.Text = ""; lastSelectedItem = (AssetPreloadData)e.Item; if (e.IsSelected) { assetInfoLabel.Text = lastSelectedItem.InfoText; if (displayInfo.Checked && assetInfoLabel.Text != null) { assetInfoLabel.Visible = true; } //only display the label if asset has info text if (enablePreview.Checked) { lastLoadedAsset = lastSelectedItem; PreviewAsset(lastLoadedAsset); } } }
public unityFont(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); int m_AsciiStartOffset = a_Stream.ReadInt32(); if (sourceFile.version[0] <= 3) { int m_FontCountX = a_Stream.ReadInt32(); int m_FontCountY = a_Stream.ReadInt32(); } float m_Kerning = a_Stream.ReadSingle(); float m_LineSpacing = a_Stream.ReadSingle(); if (sourceFile.version[0] <= 3) { int m_PerCharacterKerning_size = a_Stream.ReadInt32(); for (int i = 0; i < m_PerCharacterKerning_size; i++) { int first = a_Stream.ReadInt32(); float second = a_Stream.ReadSingle(); } } else { int m_CharacterSpacing = a_Stream.ReadInt32(); int m_CharacterPadding = a_Stream.ReadInt32(); } int m_ConvertCase = a_Stream.ReadInt32(); PPtr m_DefaultMaterial = sourceFile.ReadPPtr(); int m_CharacterRects_size = a_Stream.ReadInt32(); for (int i = 0; i < m_CharacterRects_size; i++) { int index = a_Stream.ReadInt32(); //Rectf uv float uvx = a_Stream.ReadSingle(); float uvy = a_Stream.ReadSingle(); float uvwidth = a_Stream.ReadSingle(); float uvheight = a_Stream.ReadSingle(); //Rectf vert float vertx = a_Stream.ReadSingle(); float verty = a_Stream.ReadSingle(); float vertwidth = a_Stream.ReadSingle(); float vertheight = a_Stream.ReadSingle(); float width = a_Stream.ReadSingle(); if (sourceFile.version[0] >= 4) { bool flipped = a_Stream.ReadBoolean(); a_Stream.Position += 3; } } PPtr m_Texture = sourceFile.ReadPPtr(); int m_KerningValues_size = a_Stream.ReadInt32(); for (int i = 0; i < m_KerningValues_size; i++) { int pairfirst = a_Stream.ReadInt16(); int pairsecond = a_Stream.ReadInt16(); float second = a_Stream.ReadSingle(); } if (sourceFile.version[0] <= 3) { bool m_GridFont = a_Stream.ReadBoolean(); a_Stream.Position += 3; //4 byte alignment } else { float m_PixelScale = a_Stream.ReadSingle(); } int m_FontData_size = a_Stream.ReadInt32(); if (m_FontData_size > 0) { m_FontData = new byte[m_FontData_size]; a_Stream.Read(m_FontData, 0, m_FontData_size); if (m_FontData[0] == 79 && m_FontData[1] == 84 && m_FontData[2] == 84 && m_FontData[3] == 79) { extension = ".otf"; } else { extension = ".ttf"; } } float m_FontSize = a_Stream.ReadSingle();//problem here in minifootball float m_Ascent = a_Stream.ReadSingle(); uint m_DefaultStyle = a_Stream.ReadUInt32(); int m_FontNames = a_Stream.ReadInt32(); for (int i = 0; i < m_FontNames; i++) { string m_FontName = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); } if (sourceFile.version[0] >= 4) { int m_FallbackFonts = a_Stream.ReadInt32(); for (int i = 0; i < m_FallbackFonts; i++) { PPtr m_FallbackFont = sourceFile.ReadPPtr(); } int m_FontRenderingMode = a_Stream.ReadInt32(); } }
private void enablePreview_Check(object sender, EventArgs e) { if (lastLoadedAsset != null) { switch (lastLoadedAsset.Type2) { case 28: { if (enablePreview.Checked && imageTexture != null) { previewPanel.BackgroundImage = imageTexture; previewPanel.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; } else { previewPanel.BackgroundImage = global::Unity_Studio.Properties.Resources.preview; previewPanel.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; } } break; case 48: case 49: textPreviewBox.Visible = !textPreviewBox.Visible; break; case 128: fontPreviewBox.Visible = !fontPreviewBox.Visible; break; case 83: { FMODpanel.Visible = !FMODpanel.Visible; FMOD.RESULT result; if (channel != null) { bool playing = false; result = channel.isPlaying(ref playing); if ((result != FMOD.RESULT.OK) && (result != FMOD.RESULT.ERR_INVALID_HANDLE)) { ERRCHECK(result); } if (playing) { result = channel.stop(); ERRCHECK(result); //channel = null; timer.Stop(); FMODtimerLabel.Text = "0:00.0 / " + (FMODlenms / 1000 / 60) + ":" + (FMODlenms / 1000 % 60) + "." + (FMODlenms / 10 % 100); ; FMODstatusLabel.Text = "Stopped"; FMODprogressBar.Value = 0; FMODpauseButton.Text = "Pause"; //FMODinfoLabel.Text = ""; } else if (enablePreview.Checked) { result = system.playSound(FMOD.CHANNELINDEX.FREE, sound, false, ref channel); ERRCHECK(result); timer.Start(); FMODstatusLabel.Text = "Playing"; //FMODinfoLabel.Text = FMODfrequency.ToString(); } } break; } } } else if (lastSelectedItem != null && enablePreview.Checked) { lastLoadedAsset = lastSelectedItem; PreviewAsset(lastLoadedAsset); } Properties.Settings.Default["enablePreview"] = enablePreview.Checked; Properties.Settings.Default.Save(); }
public Texture2D(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); m_Width = a_Stream.ReadInt32(); m_Height = a_Stream.ReadInt32(); m_CompleteImageSize = a_Stream.ReadInt32(); m_TextureFormat = a_Stream.ReadInt32(); if (sourceFile.version[0] < 5 || (sourceFile.version[0] == 5 && sourceFile.version[1] < 2)) { m_MipMap = a_Stream.ReadBoolean(); } else { dwFlags += 0x20000; dwMipMapCount = a_Stream.ReadInt32();//is this with or without main image? dwCaps += 0x400008; } m_IsReadable = a_Stream.ReadBoolean(); //2.6.0 and up m_ReadAllowed = a_Stream.ReadBoolean(); //3.0.0 and up a_Stream.AlignStream(4); m_ImageCount = a_Stream.ReadInt32(); m_TextureDimension = a_Stream.ReadInt32(); //m_TextureSettings m_FilterMode = a_Stream.ReadInt32(); m_Aniso = a_Stream.ReadInt32(); m_MipBias = a_Stream.ReadSingle(); m_WrapMode = a_Stream.ReadInt32(); if (sourceFile.version[0] >= 3) { m_LightmapFormat = a_Stream.ReadInt32(); if (sourceFile.version[0] >= 4 || sourceFile.version[1] >= 5) { m_ColorSpace = a_Stream.ReadInt32(); } //3.5.0 and up } image_data_size = a_Stream.ReadInt32(); if (m_MipMap) { dwFlags += 0x20000; dwMipMapCount = Convert.ToInt32(Math.Log(Math.Max(m_Width, m_Height)) / Math.Log(2)); dwCaps += 0x400008; } if (readSwitch) { image_data = new byte[image_data_size]; a_Stream.Read(image_data, 0, image_data_size); switch (m_TextureFormat) { case 1: //Alpha8 { dwFlags2 = 0x2; dwRGBBitCount = 0x8; dwRBitMask = 0x0; dwGBitMask = 0x0; dwBBitMask = 0x0; dwABitMask = 0xFF; break; } case 2: //A4R4G4B4 { if (sourceFile.platform == 11) //swap bytes for Xbox confirmed, PS3 not encountered { for (int i = 0; i < (image_data_size / 2); i++) { byte b0 = image_data[i * 2]; image_data[i * 2] = image_data[i * 2 + 1]; image_data[i * 2 + 1] = b0; } } else if (sourceFile.platform == 13) //swap bits for android { for (int i = 0; i < (image_data_size / 2); i++) { byte[] argb = BitConverter.GetBytes((BitConverter.ToInt32((new byte[4] { image_data[i * 2], image_data[i * 2 + 1], image_data[i * 2], image_data[i * 2 + 1] }), 0)) >> 4); image_data[i * 2] = argb[0]; image_data[i * 2 + 1] = argb[1]; } } dwFlags2 = 0x41; dwRGBBitCount = 0x10; dwRBitMask = 0xF00; dwGBitMask = 0xF0; dwBBitMask = 0xF; dwABitMask = 0xF000; break; } case 3: //B8G8R8 //confirmed on X360, iOS //PS3 unsure { for (int i = 0; i < (image_data_size / 3); i++) { byte b0 = image_data[i * 3]; image_data[i * 3] = image_data[i * 3 + 2]; //image_data[i * 3 + 1] stays the same image_data[i * 3 + 2] = b0; } dwFlags2 = 0x40; dwRGBBitCount = 0x18; dwRBitMask = 0xFF0000; dwGBitMask = 0xFF00; dwBBitMask = 0xFF; dwABitMask = 0x0; break; } case 4: //G8R8A8B8 //confirmed on X360, iOS { for (int i = 0; i < (image_data_size / 4); i++) { byte b0 = image_data[i * 4]; image_data[i * 4] = image_data[i * 4 + 2]; //image_data[i * 4 + 1] stays the same image_data[i * 4 + 2] = b0; //image_data[i * 4 + 3] stays the same } dwFlags2 = 0x41; dwRGBBitCount = 0x20; dwRBitMask = 0xFF0000; dwGBitMask = 0xFF00; dwBBitMask = 0xFF; dwABitMask = -16777216; break; } case 5: //B8G8R8A8 //confirmed on X360, PS3, Web, iOS { for (int i = 0; i < (image_data_size / 4); i++) { byte b0 = image_data[i * 4]; byte b1 = image_data[i * 4 + 1]; image_data[i * 4] = image_data[i * 4 + 3]; image_data[i * 4 + 1] = image_data[i * 4 + 2]; image_data[i * 4 + 2] = b1; image_data[i * 4 + 3] = b0; } dwFlags2 = 0x41; dwRGBBitCount = 0x20; dwRBitMask = 0xFF0000; dwGBitMask = 0xFF00; dwBBitMask = 0xFF; dwABitMask = -16777216; break; } case 7: //R5G6B5 //confirmed switched on X360; confirmed on iOS { if (sourceFile.platform == 11) { for (int i = 0; i < (image_data_size / 2); i++) { byte b0 = image_data[i * 2]; image_data[i * 2] = image_data[i * 2 + 1]; image_data[i * 2 + 1] = b0; } } dwFlags2 = 0x40; dwRGBBitCount = 0x10; dwRBitMask = 0xF800; dwGBitMask = 0x7E0; dwBBitMask = 0x1F; dwABitMask = 0x0; break; } case 10: //DXT1 { if (sourceFile.platform == 11) //X360 only, PS3 not { for (int i = 0; i < (image_data_size / 2); i++) { byte b0 = image_data[i * 2]; image_data[i * 2] = image_data[i * 2 + 1]; image_data[i * 2 + 1] = b0; } } if (m_MipMap) { dwPitchOrLinearSize = m_Height * m_Width / 2; } dwFlags2 = 0x4; dwFourCC = 0x31545844; dwRGBBitCount = 0x0; dwRBitMask = 0x0; dwGBitMask = 0x0; dwBBitMask = 0x0; dwABitMask = 0x0; break; } case 12: //DXT5 { if (sourceFile.platform == 11) //X360, PS3 not { for (int i = 0; i < (image_data_size / 2); i++) { byte b0 = image_data[i * 2]; image_data[i * 2] = image_data[i * 2 + 1]; image_data[i * 2 + 1] = b0; } } if (m_MipMap) { dwPitchOrLinearSize = m_Height * m_Width / 2; } dwFlags2 = 0x4; dwFourCC = 0x35545844; dwRGBBitCount = 0x0; dwRBitMask = 0x0; dwGBitMask = 0x0; dwBBitMask = 0x0; dwABitMask = 0x0; break; } case 13: //R4G4B4A4, iOS (only?) { for (int i = 0; i < (image_data_size / 2); i++) { byte[] argb = BitConverter.GetBytes((BitConverter.ToInt32((new byte[4] { image_data[i * 2], image_data[i * 2 + 1], image_data[i * 2], image_data[i * 2 + 1] }), 0)) >> 4); image_data[i * 2] = argb[0]; image_data[i * 2 + 1] = argb[1]; } dwFlags2 = 0x41; dwRGBBitCount = 0x10; dwRBitMask = 0xF00; dwGBitMask = 0xF0; dwBBitMask = 0xF; dwABitMask = 0xF000; break; } case 28: //DXT1 Crunched case 29: //DXT1 Crunched break; case 30: //PVRTC_RGB2 { pvrPixelFormat = 0x0; break; } case 31: //PVRTC_RGBA2 { pvrPixelFormat = 0x1; break; } case 32: //PVRTC_RGB4 { pvrPixelFormat = 0x2; break; } case 33: //PVRTC_RGBA4 { pvrPixelFormat = 0x3; break; } case 34: //ETC_RGB4 { pvrPixelFormat = 0x16; break; } } } else { preloadData.InfoText = "Width: " + m_Width.ToString() + "\nHeight: " + m_Height.ToString() + "\nFormat: "; preloadData.exportSize = image_data_size; switch (m_TextureFormat) { case 1: preloadData.InfoText += "Alpha8"; preloadData.extension = ".dds"; preloadData.exportSize += 128; break; case 2: preloadData.InfoText += "ARGB 4.4.4.4"; preloadData.extension = ".dds"; preloadData.exportSize += 128; break; case 3: preloadData.InfoText += "BGR 8.8.8"; preloadData.extension = ".dds"; preloadData.exportSize += 128; break; case 4: preloadData.InfoText += "GRAB 8.8.8.8"; preloadData.extension = ".dds"; preloadData.exportSize += 128; break; case 5: preloadData.InfoText += "BGRA 8.8.8.8"; preloadData.extension = ".dds"; preloadData.exportSize += 128; break; case 7: preloadData.InfoText += "RGB 5.6.5"; preloadData.extension = ".dds"; preloadData.exportSize += 128; break; case 10: preloadData.InfoText += "DXT1"; preloadData.extension = ".dds"; preloadData.exportSize += 128; break; case 12: preloadData.InfoText += "DXT5"; preloadData.extension = ".dds"; preloadData.exportSize += 128; break; case 13: preloadData.InfoText += "RGBA 4.4.4.4"; preloadData.extension = ".dds"; preloadData.exportSize += 128; break; case 28: preloadData.InfoText += "DXT1 Crunched"; preloadData.extension = ".crn"; break; case 29: preloadData.InfoText += "DXT5 Crunched"; preloadData.extension = ".crn"; break; case 30: preloadData.InfoText += "PVRTC_RGB2"; preloadData.extension = ".pvr"; preloadData.exportSize += 52; break; case 31: preloadData.InfoText += "PVRTC_RGBA2"; preloadData.extension = ".pvr"; preloadData.exportSize += 52; break; case 32: preloadData.InfoText += "PVRTC_RGB4"; preloadData.extension = ".pvr"; preloadData.exportSize += 52; break; case 33: preloadData.InfoText += "PVRTC_RGBA4"; preloadData.extension = ".pvr"; preloadData.exportSize += 52; break; case 34: preloadData.InfoText += "ETC_RGB4"; preloadData.extension = ".pvr"; preloadData.exportSize += 52; break; default: preloadData.InfoText += "unknown"; preloadData.extension = ".tex"; break; } switch (m_FilterMode) { case 0: preloadData.InfoText += "\nFilter Mode: Point "; break; case 1: preloadData.InfoText += "\nFilter Mode: Bilinear "; break; case 2: preloadData.InfoText += "\nFilter Mode: Trilinear "; break; } preloadData.InfoText += "\nAnisotropic level: " + m_Aniso.ToString() + "\nMip map bias: " + m_MipBias.ToString(); switch (m_WrapMode) { case 0: preloadData.InfoText += "\nWrap mode: Repeat"; break; case 1: preloadData.InfoText += "\nWrap mode: Clamp"; break; } if (m_Name != "") { preloadData.Text = m_Name; } else { preloadData.Text = preloadData.TypeString + " #" + preloadData.uniqueID; } preloadData.SubItems.AddRange(new string[] { preloadData.TypeString, preloadData.exportSize.ToString() }); } }
public AssetsFile(string fileName, EndianStream fileStream) { //if (memFile != null) { Stream = new EndianStream(memFile, endianType); } //else { Stream = new EndianStream(File.OpenRead(fileName), endianType); } a_Stream = fileStream; filePath = fileName; int tableSize = a_Stream.ReadInt32(); int dataEnd = a_Stream.ReadInt32(); fileGen = a_Stream.ReadInt32(); int dataOffset = a_Stream.ReadInt32(); sharedAssetsList[0].fileName = Path.GetFileName(fileName); //reference itself because sharedFileIDs start from 1 switch (fileGen) { case 6://2.5.0 - 2.6.1 { a_Stream.Position = (dataEnd - tableSize); a_Stream.Position += 1; break; } case 7://3.0.0 beta { a_Stream.Position = (dataEnd - tableSize); a_Stream.Position += 1; m_Version = a_Stream.ReadStringToNull(); break; } case 8://3.0.0 - 3.4.2 { a_Stream.Position = (dataEnd - tableSize); a_Stream.Position += 1; m_Version = a_Stream.ReadStringToNull(); platform = a_Stream.ReadInt32(); break; } case 9://3.5.0 - 4.6.x { a_Stream.Position += 4;//azero m_Version = a_Stream.ReadStringToNull(); platform = a_Stream.ReadInt32(); break; } case 14://5.0.0 beta and final case 15://5.0.1 and up { a_Stream.Position += 4;//azero m_Version = a_Stream.ReadStringToNull(); platform = a_Stream.ReadInt32(); baseDefinitions = a_Stream.ReadBoolean(); break; } default: { //MessageBox.Show("Unsupported Unity version!", "Unity Studio Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } if (platform > 255 || platform < 0) { byte[] b32 = BitConverter.GetBytes(platform); Array.Reverse(b32); platform = BitConverter.ToInt32(b32, 0); //endianType = EndianType.LittleEndian; a_Stream.endian = EndianType.LittleEndian; } switch (platform) { case -2: platformStr = "Unity Package"; break; case 4: platformStr = "OSX"; break; case 5: platformStr = "PC"; break; case 6: platformStr = "Web"; break; case 7: platformStr = "Web streamed"; break; case 9: platformStr = "iOS"; break; case 10: platformStr = "PS3"; break; case 11: platformStr = "Xbox 360"; break; case 13: platformStr = "Android"; break; case 16: platformStr = "Google NaCl"; break; case 21: platformStr = "WP8"; break; case 25: platformStr = "Linux"; break; } int baseCount = a_Stream.ReadInt32(); for (int i = 0; i < baseCount; i++) { if (fileGen < 14) { int classID = a_Stream.ReadInt32(); string baseType = a_Stream.ReadStringToNull(); string baseName = a_Stream.ReadStringToNull(); a_Stream.Position += 20; int memberCount = a_Stream.ReadInt32(); StringBuilder cb = new StringBuilder(); for (int m = 0; m < memberCount; m++) { readBase(cb, 1); } var aClass = new ClassStrStruct() { ID = classID, Text = (baseType + " " + baseName), members = cb.ToString() }; aClass.SubItems.Add(classID.ToString()); ClassStructures.Add(classID, aClass); } else { readBase5(); } } if (fileGen >= 7 && fileGen < 14) {a_Stream.Position += 4;}//azero int assetCount = a_Stream.ReadInt32(); #region asset preload table string assetIDfmt = "D" + assetCount.ToString().Length.ToString(); //format for unique ID for (int i = 0; i < assetCount; i++) { //each table entry is aligned individually, not the whole table if (fileGen >= 14) { a_Stream.AlignStream(4); } AssetPreloadData asset = new AssetPreloadData(); if (fileGen < 14) { asset.m_PathID = a_Stream.ReadInt32(); } else { asset.m_PathID = a_Stream.ReadInt64(); } asset.Offset = a_Stream.ReadInt32(); asset.Offset += dataOffset; asset.Size = a_Stream.ReadInt32(); asset.Type1 = a_Stream.ReadInt32(); asset.Type2 = a_Stream.ReadUInt16(); a_Stream.Position += 2; if (fileGen >= 15) { byte unknownByte = a_Stream.ReadByte(); //this is a single byte, not an int32 //the next entry is aligned after this //but not the last! if (unknownByte != 0) { bool investigate = true; } } asset.TypeString = asset.Type2.ToString(); if (UnityClassID.Names[asset.Type2] != null) { asset.TypeString = UnityClassID.Names[asset.Type2]; } asset.uniqueID = i.ToString(assetIDfmt); asset.exportSize = asset.Size; asset.sourceFile = this; preloadTable.Add(asset.m_PathID, asset); #region read BuildSettings to get version for unity 2.x files if (asset.Type2 == 141 && fileGen == 6) { long nextAsset = a_Stream.Position; BuildSettings BSettings = new BuildSettings(asset); m_Version = BSettings.m_Version; a_Stream.Position = nextAsset; } #endregion } #endregion buildType = m_Version.Split(new string[] { ".", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, StringSplitOptions.RemoveEmptyEntries); string[] strver = (m_Version.Split(new string[] { ".", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "\n" }, StringSplitOptions.RemoveEmptyEntries)); version = Array.ConvertAll(strver, int.Parse); if (fileGen >= 14) { //this looks like a list of assets that need to be preloaded in memory before anytihng else int someCount = a_Stream.ReadInt32(); for (int i = 0; i < someCount; i++) { int num1 = a_Stream.ReadInt32(); a_Stream.AlignStream(4); long m_PathID = a_Stream.ReadInt64(); } } int sharedFileCount = a_Stream.ReadInt32(); for (int i = 0; i < sharedFileCount; i++) { UnityShared shared = new UnityShared(); shared.aName = a_Stream.ReadStringToNull(); a_Stream.Position += 20; string sharedFileName = a_Stream.ReadStringToNull(); //relative path shared.fileName = sharedFileName.Replace("/", "\\"); sharedAssetsList.Add(shared); } }
public SkinnedMeshRenderer(AssetPreloadData preloadData) { var sourceFile = preloadData.sourceFile; var version = preloadData.sourceFile.version; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_GameObject = sourceFile.ReadPPtr(); m_Enabled = a_Stream.ReadBoolean(); m_CastShadows = a_Stream.ReadBoolean(); m_ReceiveShadows = a_Stream.ReadBoolean(); if (sourceFile.version[0] < 5) { m_LightmapIndex = a_Stream.ReadByte(); } else { a_Stream.Position += 5; //suspicious alignment, could be 2 alignments between bools m_LightmapIndex = a_Stream.ReadUInt16(); m_LightmapIndexDynamic = a_Stream.ReadUInt16(); } if (version[0] >= 3) { a_Stream.Position += 16; } //m_LightmapTilingOffset vector4d m_Materials = new PPtr[a_Stream.ReadInt32()]; for (int m = 0; m < m_Materials.Length; m++) { m_Materials[m] = sourceFile.ReadPPtr(); } if (version[0] < 3) { a_Stream.Position += 16; } //m_LightmapTilingOffset vector4d else { int m_SubsetIndices_size = a_Stream.ReadInt32(); a_Stream.Position += m_SubsetIndices_size * 4; PPtr m_StaticBatchRoot = sourceFile.ReadPPtr(); if ((version[0] == 3 && version[1] >= 5) || version[0] >= 4) { bool m_UseLightProbes = a_Stream.ReadBoolean(); a_Stream.Position += 3; //alignment if (version[0] == 5) { int m_ReflectionProbeUsage = a_Stream.ReadInt32(); } //did I ever check if the anchor is conditioned by the bool? PPtr m_LightProbeAnchor = sourceFile.ReadPPtr(); } if (version[0] >= 4 && version[1] >= 3) { if (version[1] >= 5) { int m_SortingLayer = a_Stream.ReadInt32(); } else { int m_SortingLayer = a_Stream.ReadInt16(); } int m_SortingOrder = a_Stream.ReadInt16(); a_Stream.AlignStream(4); } } int m_Quality = a_Stream.ReadInt32(); bool m_UpdateWhenOffscreen = a_Stream.ReadBoolean(); bool m_SkinNormals = a_Stream.ReadBoolean(); //3.1.0 and below a_Stream.Position += 2; if (version[0] == 2 && version[1] < 6) { //this would be the only error if mainVersion is not read in time for a unity 2.x game PPtr m_DisableAnimationWhenOffscreen = sourceFile.ReadPPtr(); } m_Mesh = sourceFile.ReadPPtr(); int m_Bones_size = a_Stream.ReadInt32(); for (int b = 0; b < m_Bones_size; b++) { PPtr aBone = sourceFile.ReadPPtr(); } if (version[0] < 3) { int m_BindPose_size = a_Stream.ReadInt32(); a_Stream.Position += m_BindPose_size * 16 * 4;//Matrix4x4f } else if (version[0] >= 3 && version[1] >= 4) { if (version[1] >= 5) { PPtr m_RootBone = sourceFile.ReadPPtr(); } //AABB float[] m_Center = new float[] { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }; float[] m_Extent = new float[] { a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle() }; bool m_DirtyAABB = a_Stream.ReadBoolean(); } }
public AssetsFile(string fileName, EndianStream fileStream) { //if (memFile != null) { Stream = new EndianStream(memFile, endianType); } //else { Stream = new EndianStream(File.OpenRead(fileName), endianType); } a_Stream = fileStream; filePath = fileName; int tableSize = a_Stream.ReadInt32(); int dataEnd = a_Stream.ReadInt32(); fileGen = a_Stream.ReadInt32(); int dataOffset = a_Stream.ReadInt32(); sharedAssetsList[0].fileName = Path.GetFileName(fileName); //reference itself because sharedFileIDs start from 1 switch (fileGen) { case 6: { a_Stream.Position = (dataEnd - tableSize); a_Stream.Position += 1; break; } case 7://beta { a_Stream.Position = (dataEnd - tableSize); a_Stream.Position += 1; m_Version = a_Stream.ReadStringToNull(); break; } case 8: { a_Stream.Position = (dataEnd - tableSize); a_Stream.Position += 1; m_Version = a_Stream.ReadStringToNull(); platform = a_Stream.ReadInt32(); break; } case 9: { a_Stream.Position += 4;//azero m_Version = a_Stream.ReadStringToNull(); platform = a_Stream.ReadInt32(); break; } case 14: case 15://not fully tested!s { a_Stream.Position += 4;//azero m_Version = a_Stream.ReadStringToNull(); platform = a_Stream.ReadInt32(); baseDefinitions = a_Stream.ReadBoolean(); break; } default: { //MessageBox.Show("Unsupported Unity version!", "Unity Studio Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } if (platform > 255 || platform < 0) { byte[] b32 = BitConverter.GetBytes(platform); Array.Reverse(b32); platform = BitConverter.ToInt32(b32, 0); //endianType = EndianType.LittleEndian; a_Stream.endian = EndianType.LittleEndian; } /*Platform list: -2: unitypackage 4: OSX 5: PC 6: Web 7: Web_streamed 9: iOS 10: PS3(big) 11: Xbox360(big) 13: Android 16: Google_NaCl 21: WP8 25: Linux */ int baseCount = a_Stream.ReadInt32(); for (int i = 0; i < baseCount; i++) { if (fileGen < 14) { int baseType = a_Stream.ReadInt32(); readBase(); } else { readBase5(); } } if (fileGen >= 7 && fileGen < 14) {a_Stream.Position += 4;}//azero int assetCount = a_Stream.ReadInt32(); if (fileGen >= 14) { a_Stream.AlignStream(4); } string assetIDfmt = "D" + assetCount.ToString().Length.ToString(); //format for unique ID for (int i = 0; i < assetCount; i++) { AssetPreloadData asset = new AssetPreloadData(); if (fileGen < 14) { asset.m_PathID = a_Stream.ReadInt32(); } else { asset.m_PathID = a_Stream.ReadInt64(); } asset.Offset = a_Stream.ReadInt32(); asset.Offset += dataOffset; asset.Size = a_Stream.ReadInt32(); asset.Type1 = a_Stream.ReadInt32(); asset.Type2 = a_Stream.ReadUInt16(); a_Stream.Position += 2; if (fileGen >= 15) { int azero = a_Stream.ReadInt32(); } asset.TypeString = asset.Type2.ToString(); if (UnityClassID.Names[asset.Type2] != null) { asset.TypeString = UnityClassID.Names[asset.Type2]; } asset.uniqueID = i.ToString(assetIDfmt); asset.exportSize = asset.Size; asset.sourceFile = this; preloadTable.Add(asset.m_PathID, asset); //this should be among the first nodes in mainData and it contains the version - useful for unity 2.x files if (asset.Type2 == 141 && fileGen == 6) { long nextAsset = a_Stream.Position; BuildSettings BSettings = new BuildSettings(asset); m_Version = BSettings.m_Version; a_Stream.Position = nextAsset; } } buildType = m_Version.Split(new string[] { ".", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, StringSplitOptions.RemoveEmptyEntries); string[] strver = (m_Version.Split(new string[] { ".", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "\n" }, StringSplitOptions.RemoveEmptyEntries)); version = Array.ConvertAll(strver, int.Parse); if (fileGen >= 14) { int someCount = a_Stream.ReadInt32(); a_Stream.Position += someCount * 12; } int sharedFileCount = a_Stream.ReadInt32(); for (int i = 0; i < sharedFileCount; i++) { UnityShared shared = new UnityShared(); shared.aName = a_Stream.ReadStringToNull(); a_Stream.Position += 20; string sharedFileName = a_Stream.ReadStringToNull(); //relative path shared.fileName = sharedFileName.Replace("/", "\\"); sharedAssetsList.Add(shared); } }
public AudioClip(AssetPreloadData preloadData, bool readSwitch) { var sourceFile = preloadData.sourceFile; var a_Stream = preloadData.sourceFile.a_Stream; a_Stream.Position = preloadData.Offset; if (sourceFile.platform == -2) { uint m_ObjectHideFlags = a_Stream.ReadUInt32(); PPtr m_PrefabParentObject = sourceFile.ReadPPtr(); PPtr m_PrefabInternal = sourceFile.ReadPPtr(); } m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); if (sourceFile.version[0] < 5) { m_Format = a_Stream.ReadInt32(); //channels? m_Type = a_Stream.ReadInt32(); m_3D = a_Stream.ReadBoolean(); m_UseHardware = a_Stream.ReadBoolean(); a_Stream.Position += 2; //4 byte alignment if (sourceFile.version[0] >= 4 || (sourceFile.version[0] == 3 && sourceFile.version[1] >= 2)) //3.2.0 to 5 { int m_Stream = a_Stream.ReadInt32(); m_Size = a_Stream.ReadInt32(); if (m_Stream > 1) { m_Offset = a_Stream.ReadInt32(); m_Source = sourceFile.filePath + ".resS"; } } else { m_Size = a_Stream.ReadInt32(); } } else { m_LoadType = a_Stream.ReadInt32(); m_Type = m_LoadType; m_Channels = a_Stream.ReadInt32(); m_Frequency = a_Stream.ReadInt32(); m_BitsPerSample = a_Stream.ReadInt32(); m_Length = a_Stream.ReadSingle(); m_IsTrackerFormat = a_Stream.ReadBoolean(); a_Stream.Position += 3; m_SubsoundIndex = a_Stream.ReadInt32(); m_PreloadAudioData = a_Stream.ReadBoolean(); m_LoadInBackground = a_Stream.ReadBoolean(); m_Legacy3D = a_Stream.ReadBoolean(); a_Stream.Position += 1; m_3D = m_Legacy3D; m_Source = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); //m_Source = Path.GetFileName(m_Source); m_Source = Path.Combine(Path.GetDirectoryName(sourceFile.filePath), m_Source.Replace("archive:/","")); m_Offset = a_Stream.ReadInt64(); m_Size = a_Stream.ReadInt64(); m_CompressionFormat = a_Stream.ReadInt32(); } #region Info Text & extension preloadData.InfoText = "Format: " + m_Format + "\nType: "; switch (m_Type) { case 1: extension = ".fsb"; preloadData.InfoText += "FSB"; break; case 13: extension = ".mp3"; preloadData.InfoText += "MP3"; break; case 14: extension = ".ogg"; preloadData.InfoText += "Ogg Vorbis"; break; case 20: extension = ".wav"; preloadData.InfoText += "WAV"; break; case 22: //xbox encoding extension = ".wav"; preloadData.InfoText += "Xbox360 WAV"; break; default: preloadData.InfoText += "Unknown type " + m_Type; break; } preloadData.InfoText += "\n3D: " + m_3D.ToString(); #endregion if (readSwitch) { m_AudioData = new byte[m_Size]; if (m_Source == null) { a_Stream.Read(m_AudioData, 0, (int)m_Size); } else if (File.Exists(m_Source)) { using (BinaryReader reader = new BinaryReader(File.OpenRead(m_Source))) { reader.BaseStream.Position = m_Offset; reader.Read(m_AudioData, 0, (int)m_Size); reader.Close(); } } } }