123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447 |
- using System;
- using System.IO;
- using System.Linq;
- using System.Web;
- using Newtonsoft.Json;
- using Newtonsoft.Json.Linq;
- using System.Collections.Generic;
- using System.Net;
- namespace ConvertToBinary
- {
- public enum DataType { Int32, Float };
- class Program
- {
- static void Main(string[] args)
- {
- if (args.Length < 1)
- {
- DisplayUsage();
- return;
- }
- // Parsing arguments
- string srcFilename = "";
- string dstPath = "";
- foreach (var arg in args)
- {
- var order = arg.Substring(0, 3);
- switch (order)
- {
- case "/i:":
- srcFilename = arg.Substring(3);
- break;
- case "/o:":
- dstPath = arg.Substring(3);
- break;
- default:
- DisplayUsage();
- return;
- }
- }
- if (string.IsNullOrEmpty(srcFilename) || string.IsNullOrEmpty(dstPath))
- {
- DisplayUsage();
- return;
- }
- ProcessSourceFile(srcFilename, dstPath);
- }
- static void ProcessSourceFile(string srcFilename, string dstPath)
- {
- try
- {
- if (!Directory.Exists(dstPath))
- Directory.CreateDirectory(dstPath);
- string srcPath = Path.GetDirectoryName(srcFilename);
- string dstFilename = Path.Combine(dstPath, Path.GetFileNameWithoutExtension(srcFilename) + ".binary.babylon");
- dynamic scene;
- // Loading
- Console.ForegroundColor = ConsoleColor.Green;
- Console.WriteLine("Loading " + srcFilename);
- Console.WriteLine();
- Console.ResetColor();
- using (var streamReader = new StreamReader(srcFilename))
- {
- using (var reader = new JsonTextReader(streamReader))
- {
- scene = JObject.Load(reader);
- }
- }
- // Marking scene
- string objName = scene.name;
- if(string.IsNullOrEmpty(objName))
- objName = Path.GetFileNameWithoutExtension(srcFilename);
- int atDot = objName.IndexOf(".incremental");
- if(atDot > 0)
- objName = objName.Substring(0, atDot);
- scene["autoClear"] = true;
- scene["useDelayedTextureLoading"] = true;
- var doNotDelayLoadingForGeometries = new List<string>();
- // Parsing meshes
- bool isMesh = true;
- var meshes = (JArray)scene.meshes;
- foreach (dynamic mesh in meshes)
- {
- if (mesh.checkCollisions.Value) // Do not delay load collisions object
- {
- if (mesh.geometryId != null)
- doNotDelayLoadingForGeometries.Add(mesh.geometryId.Value);
- continue;
- }
- isMesh = true;
- Extract(srcPath, dstPath, objName, mesh, isMesh);
- }
- // Parsing vertexData
- var geometries = scene.geometries;
- if (geometries != null)
- {
- var vertexData = (JArray)geometries.vertexData;
- foreach (dynamic geometry in vertexData)
- {
- var id = geometry.id.Value;
- if (doNotDelayLoadingForGeometries.Any(g => g == id))
- continue;
- isMesh = false;
- Extract(srcPath, dstPath, objName, geometry, isMesh);
- }
- }
- // Saving
- Console.ForegroundColor = ConsoleColor.Green;
- Console.WriteLine("Saving " + dstFilename);
- string json = scene.ToString(Formatting.Indented);
- using (var writer = new StreamWriter(WebUtility.UrlDecode(dstFilename)))
- {
- writer.Write(json);
- }
- Console.WriteLine();
- Console.ResetColor();
- }
- catch (Exception ex)
- {
- Console.ForegroundColor = ConsoleColor.Red;
- Console.WriteLine("Fatal error encountered:");
- Console.WriteLine(ex.Message);
- Console.ResetColor();
- }
- }
-
- static void Extract(string srcPath, string dstPath, string objName, dynamic meshObj, bool isMesh)
- {
- try
- {
- string dstFilename = meshObj.delayLoadingFile;
- string dstExt = (isMesh ? ".babylonbinarymeshdata" : ".babylonbinarygeometrydata");
-
- if(!string.IsNullOrEmpty(dstFilename))
- {
- string filename = WebUtility.UrlDecode(Path.Combine(srcPath, (string)meshObj.delayLoadingFile));
- using (var streamReader = new StreamReader(filename))
- {
- using (var reader = new JsonTextReader(streamReader))
- {
- var meshData = JObject.Load(reader);
- meshObj.positions = meshData["positions"];
- meshObj.normals = meshData["normals"];
- meshObj.indices = meshData["indices"];
- meshObj.uvs = meshData["uvs"];
- meshObj.uvs2 = meshData["uvs2"];
- meshObj.colors = meshData["colors"];
- meshObj.matricesIndices = meshData["matricesIndices"];
- meshObj.matricesWeights = meshData["matricesWeights"];
- meshObj.subMeshes = meshData["subMeshes"];
- }
- }
- }
- if (meshObj.positions == null || meshObj.normals == null || meshObj.indices == null)
- return;
- Console.WriteLine("Extracting " + (isMesh ? meshObj.name : meshObj.id));
- ComputeBoundingBox(meshObj);
- string meshName = meshObj.name.ToString();
- meshName = meshName.Trim();
- if (meshName.Length > 40)
- meshName = meshName.Substring(0, 40);
- if (isMesh && !string.IsNullOrEmpty(meshName))
- dstFilename = objName + "." + meshName + "." + meshObj.id.ToString() + dstExt;
- else
- dstFilename = objName + meshObj.id.ToString() + dstExt;
- dstFilename = dstFilename.Replace("+", "_").Replace(" ", "_").Replace("/", "_").Replace("\\", "_");
- meshObj.delayLoadingFile = WebUtility.UrlEncode(dstFilename);
- Console.WriteLine("Creating delayLoadingFile: " + meshObj.delayLoadingFile);
- var binaryInfo = new JObject();
- using (var stream = File.Open(WebUtility.UrlDecode(Path.Combine(dstPath, dstFilename)), FileMode.Create))
- {
- BinaryWriter writer = new BinaryWriter(stream);
- if (meshObj.positions != null && meshObj.positions.Count > 0)
- {
- var attrData = new JObject();
- attrData["count"] = meshObj.positions.Count;
- attrData["stride"] = 3;
- attrData["offset"] = stream.Length;
- attrData["dataType"] = (int)DataType.Float;
- binaryInfo["positionsAttrDesc"] = attrData;
- for (int x = 0; x < meshObj.positions.Count; x++)
- writer.Write((float)meshObj.positions[x]);
- meshObj.positions = null;
- }
- if (meshObj.colors != null && meshObj.colors.Count > 0)
- {
- var attrData = new JObject();
- attrData["count"] = meshObj.colors.Count;
- attrData["stride"] = 3;
- attrData["offset"] = stream.Length;
- attrData["dataType"] = (int)DataType.Float;
- binaryInfo["colorsAttrDesc"] = attrData;
- for (int x = 0; x < meshObj.colors.Count; x++)
- writer.Write((float)meshObj.colors[x]);
- meshObj["hasColors"] = true;
- meshObj.colors = null;
- }
- if (meshObj.normals != null && meshObj.normals.Count > 0)
- {
- var attrData = new JObject();
- attrData["count"] = meshObj.normals.Count;
- attrData["stride"] = 3;
- attrData["offset"] = stream.Length;
- attrData["dataType"] = (int)DataType.Float;
- binaryInfo["normalsAttrDesc"] = attrData;
- for (int x = 0; x < meshObj.normals.Count; x++)
- writer.Write((float)meshObj.normals[x]);
- meshObj.normals = null;
- }
- if (meshObj.uvs != null && meshObj.uvs.Count > 0)
- {
- var attrData = new JObject();
- attrData["count"] = meshObj.uvs.Count;
- attrData["stride"] = 2;
- attrData["offset"] = stream.Length;
- attrData["dataType"] = (int)DataType.Float;
- binaryInfo["uvsAttrDesc"] = attrData;
- for (int x = 0; x < meshObj.uvs.Count; x++)
- writer.Write((float)meshObj.uvs[x]);
- meshObj["hasUVs"] = true;
- meshObj.uvs = null;
- }
- if (meshObj.uvs2 != null && meshObj.uvs2.Count > 0)
- {
- var attrData = new JObject();
- attrData["count"] = meshObj.uvs2.Count;
- attrData["stride"] = 2;
- attrData["offset"] = stream.Length;
- attrData["dataType"] = (int)DataType.Float;
- binaryInfo["uvs2AttrDesc"] = attrData;
- for (int x = 0; x < meshObj.uvs2.Count; x++)
- writer.Write((float)meshObj.uvs2[x]);
- meshObj["hasUVs2"] = true;
- meshObj.uvs2 = null;
- }
- if (meshObj.indices != null && meshObj.indices.Count > 0)
- {
- var attrData = new JObject();
- attrData["count"] = meshObj.indices.Count;
- attrData["stride"] = 1;
- attrData["offset"] = stream.Length;
- attrData["dataType"] = (int)DataType.Int32;
- binaryInfo["indicesAttrDesc"] = attrData;
- for (int x = 0; x < meshObj.indices.Count; x++)
- writer.Write((int)meshObj.indices[x]);
- meshObj.indices = null;
- }
- if (meshObj.matricesIndices != null && meshObj.matricesIndices.Count > 0)
- {
- var attrData = new JObject();
- attrData["count"] = meshObj.matricesIndices.Count;
- attrData["stride"] = 1;
- attrData["offset"] = stream.Length;
- attrData["dataType"] = (int)DataType.Int32;
- binaryInfo["matricesIndicesAttrDesc"] = attrData;
- for (int x = 0; x < meshObj.matricesIndices.Count; x++)
- writer.Write((int)meshObj.matricesIndices[x]);
- meshObj["hasMatricesIndices"] = true;
- meshObj.matricesIndices = null;
- }
- if (meshObj.matricesWeights != null && meshObj.matricesWeights.Count > 0)
- {
- var attrData = new JObject();
- attrData["count"] = meshObj.matricesWeights.Count;
- attrData["stride"] = 2;
- attrData["offset"] = stream.Length;
- attrData["dataType"] = (int)DataType.Float;
- binaryInfo["matricesWeightsAttrDesc"] = attrData;
- for (int x = 0; x < meshObj.matricesWeights.Count; x++)
- writer.Write((float)meshObj.matricesWeights[x]);
- meshObj["hasMatricesWeights"] = true;
- meshObj.matricesWeights = null;
- }
- if (isMesh && meshObj.subMeshes != null && meshObj.subMeshes.Count > 0)
- {
- var attrData = new JObject();
- attrData["count"] = meshObj.subMeshes.Count;
- attrData["stride"] = 5;
- attrData["offset"] = stream.Length;
- attrData["dataType"] = (int)DataType.Int32;
- binaryInfo["subMeshesAttrDesc"] = attrData;
- int[] smData = new int[5];
- for (int x = 0; x < meshObj.subMeshes.Count; x++)
- {
- smData[0] = meshObj.subMeshes[x].materialIndex;
- smData[1] = meshObj.subMeshes[x].verticesStart;
- smData[2] = meshObj.subMeshes[x].verticesCount;
- smData[3] = meshObj.subMeshes[x].indexStart;
- smData[4] = meshObj.subMeshes[x].indexCount;
- for (int y = 0; y < smData.Length; y++)
- writer.Write((int)smData[y]);
- }
- meshObj.subMeshes = null;
- }
- }
- meshObj["_binaryInfo"] = binaryInfo;
- }
- catch (Exception ex)
- {
- Console.ForegroundColor = ConsoleColor.Red;
- Console.WriteLine();
- Console.WriteLine(ex.Message);
- Console.ForegroundColor = ConsoleColor.DarkCyan;
- Console.WriteLine(ex);
- Console.ResetColor();
- }
- }
-
-
- static void ComputeBoundingBox(dynamic meshOrGeometry)
- {
- // Compute bounding boxes
- var positions = ((JArray)meshOrGeometry.positions).Select(v => v.Value<float>()).ToArray();
- var minimum = new[] { float.MaxValue, float.MaxValue, float.MaxValue };
- var maximum = new[] { float.MinValue, float.MinValue, float.MinValue };
- for (var index = 0; index < positions.Length; index += 3)
- {
- var x = positions[index];
- var y = positions[index + 1];
- var z = positions[index + 2];
- if (x < minimum[0])
- {
- minimum[0] = x;
- }
- if (x > maximum[0])
- {
- maximum[0] = x;
- }
- if (y < minimum[1])
- {
- minimum[1] = y;
- }
- if (y > maximum[1])
- {
- maximum[1] = y;
- }
- if (z < minimum[2])
- {
- minimum[2] = z;
- }
- if (z > maximum[2])
- {
- maximum[2] = z;
- }
- }
- meshOrGeometry["boundingBoxMinimum"] = new JArray(minimum);
- meshOrGeometry["boundingBoxMaximum"] = new JArray(maximum);
- }
- static void DisplayUsage()
- {
- Console.WriteLine("ConvertToBinary usage: ConvertToBinary.exe /i:\"sourceFilename\" /o:\"dstinationFolder\"");
- }
- }
- }
|