From c111537382013cc957a634899ce12116fd98d67c Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Wed, 26 Aug 2015 22:14:40 +0530 Subject: [PATCH 1/3] Unity 5 upgrade (backwards compatible); Add support for TGA textures; Performance improvements in parsing; Fix edge case bug for continuing usemtl across groups --- .DS_Store | Bin 0 -> 6148 bytes OBJ.meta | 9 +++ OBJ/.DS_Store | Bin 0 -> 6148 bytes OBJ/src.meta | 9 +++ OBJ/src/.DS_Store | Bin 0 -> 6148 bytes OBJ/src/FaceIndices.cs.meta | 12 +++ OBJ/src/GeometryBuffer.cs | 51 ++++-------- OBJ/src/GeometryBuffer.cs.meta | 12 +++ OBJ/src/OBJ.cs | 140 ++++++++++++++++++++++----------- OBJ/src/OBJ.cs.meta | 12 +++ OBJ/src/TGALoader.cs | 79 +++++++++++++++++++ OBJ/src/TGALoader.cs.meta | 12 +++ README | 6 +- README.meta | 8 ++ objDemo.unity | Bin 14245 -> 15876 bytes objDemo.unity.meta | 8 ++ 16 files changed, 276 insertions(+), 82 deletions(-) create mode 100644 .DS_Store create mode 100644 OBJ.meta create mode 100644 OBJ/.DS_Store create mode 100644 OBJ/src.meta create mode 100644 OBJ/src/.DS_Store create mode 100644 OBJ/src/FaceIndices.cs.meta create mode 100644 OBJ/src/GeometryBuffer.cs.meta create mode 100644 OBJ/src/OBJ.cs.meta create mode 100644 OBJ/src/TGALoader.cs create mode 100644 OBJ/src/TGALoader.cs.meta create mode 100644 README.meta create mode 100644 objDemo.unity.meta diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ff7a7b302f3e57a73729fdd6fb98ea1c407a7af8 GIT binary patch literal 6148 zcmeHK&59F25U$RjGZA$J59@7idI*xN3-RVSCW4A6JK`Q(S!bMJW*MiKWMYsQn4`b% zA$s*Od;kx=ORVZH7vk!1g_SC({;I31y6LZn?kNCJ;VkU|cmUv_64qR7{vb3?dPHjM zX(B3`LqAJ$onViq6FCVC(Am}DK7?@RcD{Cgw{YY#YIC(R8{w#AK0V-5{*fHy*|h9- zzpGlk(QKV^+;-b-pFP)p5{>mdD&ulC4dcmU>OF|dal-aPt@A@WP99~W`JQ*-rY_1j zD@GHOoTVcS+1<&CRL?^_E7Iw1WSu)%T8_=6>~LJyareB9#iF;_@A%iYmK}f5>-M)g zet)yOTzX$!=i;TS*Y76!^_#cv-hcS`>9g4rDEw}XoM-$6U(nzkzlLeTgn{E_ zfbTx%^zkkuvkL>lzzJl4?gt;0Fkq}KnyUjFQvx71&}{^5^Yf4BlLIketSq7jMcGtD zo2t0PP+U7Gn~viF$5$3@Iw-R;&ciD!u22-09?Cc2paP513IoExIsfgc5Zz4z*g*m#aVR(6=pl!sR0=n&P>@hBm5k`2Ma8ZoV#)GWu|p0al8=1; z4^*!GF+KFZlsCJRN>$+qQqYVv`^K{~YwufYcSk9uN3(38RG^gdpoA?S&2NPINpDDt zJ#C<-G0bsVm=sSmoX9#bKx@}lm71#KSH-pUdx@S+sJ^_k6XB?IUY+nNU!*5RUe*2n zxo)*Pw{G9@{BGCp-n-v@8&AwUu9JFJjgsjBJ?$m+BxU=xF~yagq;K-^{3v+%+>~{a zm*c5T&a*K>4)^miGxL#|m05KdJLi6$)e}1?J3Qa_{G(uFu^4O(d*RdVWiMO|`oryB zINa(lm%*9uJ$n4)*=}k+e)|07>$mSePVJnO#(!(&0pkjO!r&Qyh^J*?%J=ZBqE}IZ z!hkR!46G*uyqkG<*Yoq`tAzn!;4d;j`$GsNj2Ih-cI!Z6O8{U8ZY!|ud7~h^3==18N2S XkPKkN*f@j-A{PNmgEYdxKV{$-m?>Q4 literal 0 HcmV?d00001 diff --git a/OBJ/src.meta b/OBJ/src.meta new file mode 100644 index 0000000..e9c469d --- /dev/null +++ b/OBJ/src.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6e9b587a311264351bdb3323fd4f0f7b +folderAsset: yes +timeCreated: 1439563994 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/OBJ/src/.DS_Store b/OBJ/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..09f890c003eac5b14cc480b5e133b58c6e3e901f GIT binary patch literal 6148 zcmeHKOG*Pl5PhXV0*b_)%UNb6c!P0>k%%Cu2QWWDhz=ODa5o3^0Ny6Ps%piF?N&sp zLe=X}eR>|GKLDg!&5nT{fG$;0w2=`V&Q5J5=MGUU#|V#@;T}`WGl~AIwanq#?CWmGznyIKUadwZ;SOGoJ8*3M<_4H)k)G;gwPSwTWfe z!6jqPbG~x5;k$<$);qxkD~`$Z4>ja%BhCti2?m0JU?3O>28;oo*(%*#$FRXbFc1uU zGNAiIK~*dhHjcJ+(AX1zsMlx{w)L8i#KSpWB)>9Y 0; } } public static int MAX_VERTICES_LIMIT_FOR_A_MESH = 64999; - + public void PopulateMeshes(GameObject[] gs, Dictionary mats) { if(gs.Length != numObjects) return; // Should not happen unless obj file is corrupt... Debug.Log("PopulateMeshes GameObjects count:"+gs.Length); @@ -140,7 +146,7 @@ public void PopulateMeshes(GameObject[] gs, Dictionary mats) { Vector3[] tvertices = new Vector3[od.allFaces.Count]; Vector2[] tuvs = new Vector2[od.allFaces.Count]; Vector3[] tnormals = new Vector3[od.allFaces.Count]; - + int k = 0; foreach(FaceIndices fi in od.allFaces) { if (k >= MAX_VERTICES_LIMIT_FOR_A_MESH) { @@ -152,18 +158,18 @@ public void PopulateMeshes(GameObject[] gs, Dictionary mats) { if(hasNormals && fi.vn >= 0) tnormals[k] = normals[fi.vn]; k++; } - + Mesh m = (gs[i].GetComponent(typeof(MeshFilter)) as MeshFilter).mesh; m.vertices = tvertices; if(hasUVs) m.uv = tuvs; if(objectHasNormals) m.normals = tnormals; - + if(od.groups.Count == 1) { Debug.Log("PopulateMeshes only one group: "+od.groups[0].name); GroupData gd = od.groups[0]; string matName = (gd.materialName != null) ? gd.materialName : "default"; // MAYBE: "default" may not enough. if (mats.ContainsKey(matName)) { - gs[i].renderer.material = mats[matName]; + gs[i].GetComponent().material = mats[matName]; Debug.Log("PopulateMeshes mat:"+matName+" set."); } else { @@ -173,7 +179,7 @@ public void PopulateMeshes(GameObject[] gs, Dictionary mats) { for(int j = 0; j < triangles.Length; j++) triangles[j] = j; m.triangles = triangles; - + } else { int gl = od.groups.Count; Material[] materials = new Material[gl]; @@ -198,38 +204,11 @@ public void PopulateMeshes(GameObject[] gs, Dictionary mats) { m.SetTriangles(triangles, j); } - gs[i].renderer.materials = materials; + gs[i].GetComponent().materials = materials; } if (!objectHasNormals) { m.RecalculateNormals(); } } } -} - - - - - - - - - - - - - - - - - - - - - - - - - - - +} \ No newline at end of file diff --git a/OBJ/src/GeometryBuffer.cs.meta b/OBJ/src/GeometryBuffer.cs.meta new file mode 100644 index 0000000..f4fd300 --- /dev/null +++ b/OBJ/src/GeometryBuffer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: efd18f63dfb50486299fa8890b408c18 +timeCreated: 1440397990 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/OBJ/src/OBJ.cs b/OBJ/src/OBJ.cs index 84a17bc..0e8842d 100644 --- a/OBJ/src/OBJ.cs +++ b/OBJ/src/OBJ.cs @@ -9,7 +9,12 @@ public class OBJ : MonoBehaviour { public string objPath; - +#if UNITY_5 + public bool useLegacyShaders = false; // compatibility option for previous users of OBJ.cs using Unity5 +#else + private bool useLegacyShaders = true; +#endif + /* OBJ file tags */ private const string O = "o"; private const string G = "g"; @@ -35,7 +40,31 @@ public class OBJ : MonoBehaviour { private const string MAP_KE = "map_Ke"; // Emissive texture private const string MAP_BUMP = "map_bump"; // Bump map texture private const string BUMP = "bump"; // Bump map texture + + /* Material shaders */ +#if UNITY_5 + private const string DIFFUSE_SHADER = "Standard"; + private const string SPECULAR_SHADER = "Standard (Specular setup)"; + private const string BUMPED_DIFFUSE_SHADER = "Standard"; + private const string BUMPED_SPECULAR_SHADER = "Standard (Specular setup)"; + private const string LEGACY_DIFFUSE_SHADER = "Legacy Shaders/Diffuse"; + private const string LEGACY_SPECULAR_SHADER = "Legacy Shaders/Specular"; + private const string LEGACY_BUMPED_DIFFUSE_SHADER = "Legacy Shaders/Bumped Diffuse"; + private const string LEGACY_BUMPED_SPECULAR_SHADER = "Legacy Shaders/Bumped Specular"; +#else + private const string DIFFUSE_SHADER = "Diffuse"; + private const string SPECULAR_SHADER = "Specular"; + private const string BUMPED_DIFFUSE_SHADER = "Bumped Diffuse"; + private const string BUMPED_SPECULAR_SHADER = "Bumped Specular"; + + private const string LEGACY_DIFFUSE_SHADER = DIFFUSE_SHADER; + private const string LEGACY_SPECULAR_SHADER = SPECULAR_SHADER; + private const string LEGACY_BUMPED_DIFFUSE_SHADER = BUMPED_DIFFUSE_SHADER; + private const string LEGACY_BUMPED_SPECULAR_SHADER = BUMPED_SPECULAR_SHADER; +#endif + + private string basepath; private string mtllib; private GeometryBuffer buffer; @@ -43,65 +72,73 @@ public class OBJ : MonoBehaviour { void Start () { buffer = new GeometryBuffer (); + StartCoroutine (Load (objPath)); } public IEnumerator Load(string path) { + yield return 0; // play nice by not hogging the main thread + basepath = (path.IndexOf("/") == -1) ? "" : path.Substring(0, path.LastIndexOf("/") + 1); - + WWW loader = new WWW(path); yield return loader; - SetGeometryData(loader.text); + yield return StartCoroutine(SetGeometryData(loader.text)); if(hasMaterials) { - loader = new WWW(basepath + mtllib); Debug.Log("base path = "+basepath); Debug.Log("MTL path = "+(basepath + mtllib)); + string mtlPath = basepath + mtllib; + loader = new WWW (mtlPath); yield return loader; + if (loader.error != null) { Debug.LogError(loader.error); } else { SetMaterialData(loader.text); } - - foreach(MaterialData m in materialData) { - if(m.diffuseTexPath != null) { - WWW texloader = GetTextureLoader(m, m.diffuseTexPath); - yield return texloader; - if (texloader.error != null) { - Debug.LogError(texloader.error); - } else { - m.diffuseTex = texloader.texture; + + if (materialData != null) { + foreach(MaterialData m in materialData) { + if(m.diffuseTexPath != null) { + string texpath = basepath + m.diffuseTexPath; + loader = new WWW(texpath); + yield return loader; + + if (loader.error != null) { + Debug.LogError(loader.error); + } else { + m.diffuseTex = GetTexture(loader); + } } - } - if(m.bumpTexPath != null) { - WWW texloader = GetTextureLoader(m, m.bumpTexPath); - yield return texloader; - if (texloader.error != null) { - Debug.LogError(texloader.error); - } else { - m.bumpTex = texloader.texture; + + if(m.bumpTexPath != null) { + string texpath = basepath + m.bumpTexPath; + loader = new WWW(texpath); + yield return loader; + + if (loader.error != null) { + Debug.LogError(loader.error); + } else { + m.bumpTex = GetTexture(loader); + } } } } } - - Build(); + Build(); } - - private WWW GetTextureLoader(MaterialData m, string texpath) { - char[] separators = {'/', '\\'}; - string[] components = texpath.Split(separators); - string filename = components[components.Length-1]; - string ext = Path.GetExtension(filename).ToLower(); - if (ext != ".png" && ext != ".jpg") { + + private Texture2D GetTexture(WWW loader) { + string ext = Path.GetExtension(loader.url).ToLower(); + if (ext != ".png" && ext != ".jpg" && ext != ".tga") { Debug.LogWarning("maybe unsupported texture format:"+ext); } - WWW texloader = new WWW(basepath + filename); - Debug.Log("texture path for material("+m.name+") = "+(basepath + filename)); - return texloader; + + return (ext == ".tga" ? TGALoader.LoadTGA (new MemoryStream(loader.bytes)) : loader.texture); + // refactor this method to add support for more formats } private void GetFaceIndicesByOneFaceLine(FaceIndices[] faces, string[] p, bool isFaceIndexPlus) { @@ -155,18 +192,22 @@ private void GetFaceIndicesByOneFaceLine(FaceIndices[] faces, string[] p, bool i } } - private void SetGeometryData(string data) { + private IEnumerator SetGeometryData(string data) { + yield return 0; // play nice by not hogging the main thread + string[] lines = data.Split("\n".ToCharArray()); - Regex regexWhitespaces = new Regex(@"\s+"); + bool isFirstInGroup = true; bool isFaceIndexPlus = true; + for(int i = 0; i < lines.Length; i++) { string l = lines[i].Trim(); - - if(l.IndexOf("#") != -1) { // comment line + + if(l.Length > 0 && l[0] == '#') { // comment line continue; } - string[] p = regexWhitespaces.Split(l); + string[] p = l.Replace(" ", " ").Split(' '); + switch(p[0]) { case O: buffer.PushObject(p[1].Trim()); @@ -221,8 +262,8 @@ private void SetGeometryData(string data) { buffer.PushMaterialName(p[1].Trim()); break; } + if (i % 7000 == 0) yield return 0; // play nice with main thread while parsing large objs } - // buffer.Trace(); } @@ -231,7 +272,7 @@ private float cf(string v) { return float.Parse(v); } catch(Exception e) { - print(e); + Debug.LogError("Error parsing: " + v + ": " + e); return 0; } } @@ -241,7 +282,7 @@ private int ci(string v) { return int.Parse(v); } catch(Exception e) { - print(e); + Debug.LogError(e); return 0; } } @@ -274,7 +315,7 @@ private void SetMaterialData(string data) { materialData = new List(); MaterialData current = new MaterialData(); Regex regexWhitespaces = new Regex(@"\s+"); - + for(int i = 0; i < lines.Length; i++) { string l = lines[i].Trim(); @@ -318,19 +359,28 @@ private void SetMaterialData(string data) { Debug.Log("this line was not processed :" +l ); break; } - } + } } private Material GetMaterial(MaterialData md) { Material m; + string shaderName; if(md.illumType == 2) { - string shaderName = (md.bumpTex != null)? "Bumped Specular" : "Specular"; + if (useLegacyShaders) { + shaderName = (md.bumpTex != null)? LEGACY_BUMPED_SPECULAR_SHADER : LEGACY_SPECULAR_SHADER; + } else { + shaderName = (md.bumpTex != null)? BUMPED_SPECULAR_SHADER : SPECULAR_SHADER; + } m = new Material(Shader.Find(shaderName)); m.SetColor("_SpecColor", md.specular); m.SetFloat("_Shininess", md.shininess); } else { - string shaderName = (md.bumpTex != null)? "Bumped Diffuse" : "Diffuse"; + if (useLegacyShaders) { + shaderName = (md.bumpTex != null)? LEGACY_BUMPED_DIFFUSE_SHADER : LEGACY_DIFFUSE_SHADER; + } else { + shaderName = (md.bumpTex != null)? BUMPED_DIFFUSE_SHADER : DIFFUSE_SHADER; + } m = new Material(Shader.Find(shaderName)); } diff --git a/OBJ/src/OBJ.cs.meta b/OBJ/src/OBJ.cs.meta new file mode 100644 index 0000000..83e19c2 --- /dev/null +++ b/OBJ/src/OBJ.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a239a1833de95428bb67c4b9cf609940 +timeCreated: 1440397987 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/OBJ/src/TGALoader.cs b/OBJ/src/TGALoader.cs new file mode 100644 index 0000000..535e957 --- /dev/null +++ b/OBJ/src/TGALoader.cs @@ -0,0 +1,79 @@ +// This was made by aaro4130 on the Unity forums. Thanks boss! +// It's been optimized and slimmed down for the purpose of loading Quake 3 TGA textures from memory streams. + +using System; +using System.IO; +using UnityEngine; + +public static class TGALoader +{ + + /*public static Texture2D LoadTGA(string fileName) + { + using (var imageFile = File.OpenRead(fileName)) + { + return LoadTGA(imageFile); + } + }*/ + + public static Texture2D LoadTGA(Stream TGAStream) + { + + using (BinaryReader r = new BinaryReader(TGAStream)) + { + // Skip some header info we don't care about. + // Even if we did care, we have to move the stream seek point to the beginning, + // as the previous method in the workflow left it at the end. + r.BaseStream.Seek(12, SeekOrigin.Begin); + + short width = r.ReadInt16(); + short height = r.ReadInt16(); + int bitDepth = r.ReadByte(); + + // Skip a byte of header information we don't care about. + r.BaseStream.Seek(1, SeekOrigin.Current); + + Texture2D tex = new Texture2D(width, height); + Color32[] pulledColors = new Color32[width * height]; + int length = width * height; + + if (bitDepth == 32) + { + for (int row = 1; row <= height; row++) + { + for (int col = 0; col < width; col++) + { + byte red = r.ReadByte(); + byte green = r.ReadByte(); + byte blue = r.ReadByte(); + byte alpha = r.ReadByte(); + + // pulledColors [i] = new Color32(blue, green, red, alpha); + pulledColors [length - (row * width) + col] = new Color32(blue, green, red, alpha); + } + } + } else if (bitDepth == 24) + { + for (int row = 1; row <= height; row++) + { + for (int col = 0; col < width; col++) + { + byte red = r.ReadByte(); + byte green = r.ReadByte(); + byte blue = r.ReadByte(); + + pulledColors [length - (row * width) + col] = new Color32(blue, green, red, 1); + } + } + } else + { + throw new Exception("TGA texture had non 32/24 bit depth."); + } + + tex.SetPixels32(pulledColors); + tex.Apply(); + return tex; + + } + } +} \ No newline at end of file diff --git a/OBJ/src/TGALoader.cs.meta b/OBJ/src/TGALoader.cs.meta new file mode 100644 index 0000000..fd5aa9d --- /dev/null +++ b/OBJ/src/TGALoader.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 68a55205098494e878b701f227d86044 +timeCreated: 1440599977 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/README b/README index fb770d5..050d3fe 100644 --- a/README +++ b/README @@ -7,10 +7,14 @@ http://www.everyday3d.com/blog/index.php/2010/05/24/loading-3d-models-runtime-un Many thanks to the original author, Bartek Drozdz for publishing the code under MIT license. +- Upgraded to work with Unity 5 Shaders, while also supporting Unity 4 users. +- Supports loading from local file system (file:// prefix url) as well as remotely over WWW. +- Supports PNG/JPG/TGA textures. + License: MIT Notes: - please put all texture files on the same directory of . obj file. - please use use this form of URL for local files. ex) file:///Users/someone/somepath/model.obj - Bump map is not correctly working. TODO: convert hight map to normal map, make tangent data. - + - Arbitrary polygons is not supported yet, only triangles. See https://github.com/mtschoen/unity-obj-loader/ for quad support. diff --git a/README.meta b/README.meta new file mode 100644 index 0000000..7d69f5e --- /dev/null +++ b/README.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: aa83a0a7f225843948e6935268f91b59 +timeCreated: 1440397986 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/objDemo.unity b/objDemo.unity index c1fe27ce37271be17c7fa29434114bb769ca951e..e3663dcd5ffb61b34db9dc48715acc7a5e70bc88 100644 GIT binary patch literal 15876 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 literal 14245 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 pw;!c{z4oaSkM_DJ!bcu@QpZX{tfPxz8?Sp diff --git a/objDemo.unity.meta b/objDemo.unity.meta new file mode 100644 index 0000000..85d62c3 --- /dev/null +++ b/objDemo.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4fc59539ba6e544deb7cf8c6f5a9f6bf +timeCreated: 1440397986 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: From 1037bb8717d69ab9644b98e5eafe50bf9ebe14cc Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Wed, 26 Aug 2015 22:14:40 +0530 Subject: [PATCH 2/3] Unity 5 upgrade (backwards compatible); Add support for TGA textures; Performance improvements in parsing; Fix edge case bug for continuing usemtl across groups --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..82925af --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +.meta From 99872527be55b14e831023d39640fe6cbbaa2583 Mon Sep 17 00:00:00 2001 From: cmdr2 Date: Wed, 26 Aug 2015 22:29:23 +0530 Subject: [PATCH 3/3] Remove dummy files --- .DS_Store | Bin 6148 -> 0 bytes OBJ.meta | 9 --------- OBJ/.DS_Store | Bin 6148 -> 0 bytes OBJ/src.meta | 9 --------- OBJ/src/.DS_Store | Bin 6148 -> 0 bytes OBJ/src/FaceIndices.cs.meta | 12 ------------ OBJ/src/GeometryBuffer.cs.meta | 12 ------------ OBJ/src/OBJ.cs.meta | 12 ------------ OBJ/src/TGALoader.cs.meta | 12 ------------ README.meta | 8 -------- objDemo.unity.meta | 8 -------- 11 files changed, 82 deletions(-) delete mode 100644 .DS_Store delete mode 100644 OBJ.meta delete mode 100644 OBJ/.DS_Store delete mode 100644 OBJ/src.meta delete mode 100644 OBJ/src/.DS_Store delete mode 100644 OBJ/src/FaceIndices.cs.meta delete mode 100644 OBJ/src/GeometryBuffer.cs.meta delete mode 100644 OBJ/src/OBJ.cs.meta delete mode 100644 OBJ/src/TGALoader.cs.meta delete mode 100644 README.meta delete mode 100644 objDemo.unity.meta diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index ff7a7b302f3e57a73729fdd6fb98ea1c407a7af8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK&59F25U$RjGZA$J59@7idI*xN3-RVSCW4A6JK`Q(S!bMJW*MiKWMYsQn4`b% zA$s*Od;kx=ORVZH7vk!1g_SC({;I31y6LZn?kNCJ;VkU|cmUv_64qR7{vb3?dPHjM zX(B3`LqAJ$onViq6FCVC(Am}DK7?@RcD{Cgw{YY#YIC(R8{w#AK0V-5{*fHy*|h9- zzpGlk(QKV^+;-b-pFP)p5{>mdD&ulC4dcmU>OF|dal-aPt@A@WP99~W`JQ*-rY_1j zD@GHOoTVcS+1<&CRL?^_E7Iw1WSu)%T8_=6>~LJyareB9#iF;_@A%iYmK}f5>-M)g zet)yOTzX$!=i;TS*Y76!^_#cv-hcS`>9g4rDEw}XoM-$6U(nzkzlLeTgn{E_ zfbTx%^zkkuvkL>lzzJl4?gt;0Fkq}KnyUjFQvx71&}{^5^Yf4BlLIketSq7jMcGtD zo2t0PP+U7Gn~viF$5$3@Iw-R;&ciD!u22-09?Cc2paP513IoExIsfgc5Zz4z*g*m#aVR(6=pl!sR0=n&P>@hBm5k`2Ma8ZoV#)GWu|p0al8=1; z4^*!GF+KFZlsCJRN>$+qQqYVv`^K{~YwufYcSk9uN3(38RG^gdpoA?S&2NPINpDDt zJ#C<-G0bsVm=sSmoX9#bKx@}lm71#KSH-pUdx@S+sJ^_k6XB?IUY+nNU!*5RUe*2n zxo)*Pw{G9@{BGCp-n-v@8&AwUu9JFJjgsjBJ?$m+BxU=xF~yagq;K-^{3v+%+>~{a zm*c5T&a*K>4)^miGxL#|m05KdJLi6$)e}1?J3Qa_{G(uFu^4O(d*RdVWiMO|`oryB zINa(lm%*9uJ$n4)*=}k+e)|07>$mSePVJnO#(!(&0pkjO!r&Qyh^J*?%J=ZBqE}IZ z!hkR!46G*uyqkG<*Yoq`tAzn!;4d;j`$GsNj2Ih-cI!Z6O8{U8ZY!|ud7~h^3==18N2S XkPKkN*f@j-A{PNmgEYdxKV{$-m?>Q4 diff --git a/OBJ/src.meta b/OBJ/src.meta deleted file mode 100644 index e9c469d..0000000 --- a/OBJ/src.meta +++ /dev/null @@ -1,9 +0,0 @@ -fileFormatVersion: 2 -guid: 6e9b587a311264351bdb3323fd4f0f7b -folderAsset: yes -timeCreated: 1439563994 -licenseType: Free -DefaultImporter: - userData: - assetBundleName: - assetBundleVariant: diff --git a/OBJ/src/.DS_Store b/OBJ/src/.DS_Store deleted file mode 100644 index 09f890c003eac5b14cc480b5e133b58c6e3e901f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKOG*Pl5PhXV0*b_)%UNb6c!P0>k%%Cu2QWWDhz=ODa5o3^0Ny6Ps%piF?N&sp zLe=X}eR>|GKLDg!&5nT{fG$;0w2=`V&Q5J5=MGUU#|V#@;T}`WGl~AIwanq#?CWmGznyIKUadwZ;SOGoJ8*3M<_4H)k)G;gwPSwTWfe z!6jqPbG~x5;k$<$);qxkD~`$Z4>ja%BhCti2?m0JU?3O>28;oo*(%*#$FRXbFc1uU zGNAiIK~*dhHjcJ+(AX1zsMlx{w)L8i#KSpWB)>9Y