├── .gitattributes ├── .gitignore ├── Assembly-CSharp.csproj ├── Assets └── Unity2glTF │ ├── RefDLL │ ├── ChnCharInfo.dll │ ├── Ionic.Zip.dll │ └── Newtonsoft.Json.dll │ ├── Scripts │ ├── Binary.cs │ ├── DirectoryHelper.cs │ ├── ExportWindow.cs │ ├── ForceExternalMaterialProcessor.cs │ ├── GlTF_Accessor.cs │ ├── GlTF_AmbientLight.cs │ ├── GlTF_AnimSampler.cs │ ├── GlTF_Animation.cs │ ├── GlTF_Attributes.cs │ ├── GlTF_BufferView.cs │ ├── GlTF_Camera.cs │ ├── GlTF_Channel.cs │ ├── GlTF_ColorOrTexture.cs │ ├── GlTF_ColorRGB.cs │ ├── GlTF_ColorRGBA.cs │ ├── GlTF_DirectionalLight.cs │ ├── GlTF_FloatArray.cs │ ├── GlTF_FloatArray4.cs │ ├── GlTF_Image.cs │ ├── GlTF_Light.cs │ ├── GlTF_Material.cs │ ├── GlTF_MaterialColor.cs │ ├── GlTF_MaterialTexture.cs │ ├── GlTF_Matrix.cs │ ├── GlTF_Mesh.cs │ ├── GlTF_Node.cs │ ├── GlTF_Orthographic.cs │ ├── GlTF_Perspective.cs │ ├── GlTF_PointLight.cs │ ├── GlTF_Primitive.cs │ ├── GlTF_Program.cs │ ├── GlTF_Rotation.cs │ ├── GlTF_Sampler.cs │ ├── GlTF_Scale.cs │ ├── GlTF_Shader.cs │ ├── GlTF_Skin.cs │ ├── GlTF_SpotLight.cs │ ├── GlTF_Target.cs │ ├── GlTF_Technique.cs │ ├── GlTF_Texture.cs │ ├── GlTF_Translation.cs │ ├── GlTF_Vector3.cs │ ├── GlTF_Writer.cs │ ├── JObjectExtensions.cs │ ├── MimeType.cs │ ├── Packer.cs │ ├── PinYinConverter.cs │ ├── Preset.cs │ ├── SceneToGlTFWiz.cs │ ├── SimpleJSON.cs │ ├── StreamExtensions.cs │ ├── Tools.cs │ └── WebServer.cs │ ├── Unity2glTF.unity │ └── Web │ ├── Assets │ ├── BabylonIdentity.svg │ ├── BtnPerf.png │ ├── FlecheDown.png │ ├── IBLicon.svg │ ├── Icon_Dashboard.svg │ ├── Icon_Down.svg │ ├── Icon_EditModel.svg │ ├── Icon_Fullscreen.svg │ ├── Icon_OpenFile.svg │ ├── Icon_Pause.svg │ ├── Icon_Play.svg │ ├── Icon_Up.svg │ ├── LogoSandbox.png │ ├── Logo_Fullscreen.svg │ ├── arrow.png │ ├── arrowUp.png │ ├── circle.png │ ├── down.png │ ├── font.woff │ ├── pause.png │ ├── play.png │ ├── sep.png │ ├── up.png │ └── video.png │ ├── Oimo.jsx │ ├── ammo.jsx │ ├── ammo.wasm.jsx │ ├── ammo.wasm.wasm │ ├── animation.jsx │ ├── babylon.inspector.bundle.jsx │ ├── babylon.jsx │ ├── babylonjs.loaders.min.jsx │ ├── babylonjs.materials.min.jsx │ ├── babylonjs.serializers.min.jsx │ ├── cannon.jsx │ ├── cta4xsb.css │ ├── draco_decoder_gltf.jsx │ ├── draco_decoder_gltf.wasm │ ├── draco_wasm_wrapper_gltf.jsx │ ├── environment.jsx │ ├── environmentSpecular.env │ ├── favicon.ico │ ├── gltf_validator.jsx │ ├── index-media.css │ ├── index.css │ ├── index.html │ ├── index.jsx │ ├── pep.min.jsx │ ├── split.jsx │ └── studio.env ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset └── UnityConnectSettings.asset ├── README.md ├── Unity2glTF.csproj ├── Unity2glTF.png └── Unity2glTF.sln /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | Library 25 | UnityPackageManager 26 | export 27 | 28 | # Visual Studio 2015 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # MSTest test Results 34 | [Tt]est[Rr]esult*/ 35 | [Bb]uild[Ll]og.* 36 | 37 | # NUNIT 38 | *.VisualState.xml 39 | TestResult.xml 40 | 41 | # Build Results of an ATL Project 42 | [Dd]ebugPS/ 43 | [Rr]eleasePS/ 44 | dlldata.c 45 | 46 | # DNX 47 | project.lock.json 48 | project.fragment.lock.json 49 | artifacts/ 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # NCrunch 117 | _NCrunch_* 118 | .*crunch*.local.xml 119 | nCrunchTemp_* 120 | 121 | # MightyMoose 122 | *.mm.* 123 | AutoTest.Net/ 124 | 125 | # Web workbench (sass) 126 | .sass-cache/ 127 | 128 | # Installshield output folder 129 | [Ee]xpress/ 130 | 131 | # DocProject is a documentation generator add-in 132 | DocProject/buildhelp/ 133 | DocProject/Help/*.HxT 134 | DocProject/Help/*.HxC 135 | DocProject/Help/*.hhc 136 | DocProject/Help/*.hhk 137 | DocProject/Help/*.hhp 138 | DocProject/Help/Html2 139 | DocProject/Help/html 140 | 141 | # Click-Once directory 142 | publish/ 143 | 144 | # Publish Web Output 145 | *.[Pp]ublish.xml 146 | *.azurePubxml 147 | # TODO: Comment the next line if you want to checkin your web deploy settings 148 | # but database connection strings (with potential passwords) will be unencrypted 149 | #*.pubxml 150 | *.publishproj 151 | 152 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 153 | # checkin your Azure Web App publish settings, but sensitive information contained 154 | # in these scripts will be unencrypted 155 | PublishScripts/ 156 | 157 | # NuGet Packages 158 | *.nupkg 159 | # The packages folder can be ignored because of Package Restore 160 | **/packages/* 161 | # except build/, which is used as an MSBuild target. 162 | !**/packages/build/ 163 | # Uncomment if necessary however generally it will be regenerated when needed 164 | #!**/packages/repositories.config 165 | # NuGet v3's project.json files produces more ignoreable files 166 | *.nuget.props 167 | *.nuget.targets 168 | 169 | # Microsoft Azure Build Output 170 | csx/ 171 | *.build.csdef 172 | 173 | # Microsoft Azure Emulator 174 | ecf/ 175 | rcf/ 176 | 177 | # Windows Store app package directories and files 178 | AppPackages/ 179 | BundleArtifacts/ 180 | Package.StoreAssociation.xml 181 | _pkginfo.txt 182 | 183 | # Visual Studio cache files 184 | # files ending in .cache can be ignored 185 | *.[Cc]ache 186 | # but keep track of directories ending in .cache 187 | !*.[Cc]ache/ 188 | 189 | # Others 190 | ClientBin/ 191 | ~$* 192 | *~ 193 | *.dbmdl 194 | *.dbproj.schemaview 195 | *.jfm 196 | *.pfx 197 | *.publishsettings 198 | node_modules/ 199 | orleans.codegen.cs 200 | 201 | # Since there are multiple workflows, uncomment next line to ignore bower_components 202 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 203 | #bower_components/ 204 | 205 | # RIA/Silverlight projects 206 | Generated_Code/ 207 | 208 | # Backup & report files from converting an old project file 209 | # to a newer Visual Studio version. Backup files are not needed, 210 | # because we have git ;-) 211 | _UpgradeReport_Files/ 212 | Backup*/ 213 | UpgradeLog*.XML 214 | UpgradeLog*.htm 215 | 216 | # SQL Server files 217 | *.mdf 218 | *.ldf 219 | 220 | # Business Intelligence projects 221 | *.rdl.data 222 | *.bim.layout 223 | *.bim_*.settings 224 | 225 | # Microsoft Fakes 226 | FakesAssemblies/ 227 | 228 | # GhostDoc plugin setting file 229 | *.GhostDoc.xml 230 | 231 | # Node.js Tools for Visual Studio 232 | .ntvs_analysis.dat 233 | 234 | # Visual Studio 6 build log 235 | *.plg 236 | 237 | # Visual Studio 6 workspace options file 238 | *.opt 239 | 240 | # Visual Studio LightSwitch build output 241 | **/*.HTMLClient/GeneratedArtifacts 242 | **/*.DesktopClient/GeneratedArtifacts 243 | **/*.DesktopClient/ModelManifest.xml 244 | **/*.Server/GeneratedArtifacts 245 | **/*.Server/ModelManifest.xml 246 | _Pvt_Extensions 247 | 248 | # Paket dependency manager 249 | .paket/paket.exe 250 | paket-files/ 251 | 252 | # FAKE - F# Make 253 | .fake/ 254 | 255 | # JetBrains Rider 256 | .idea/ 257 | *.sln.iml 258 | 259 | # CodeRush 260 | .cr/ 261 | 262 | # Python Tools for Visual Studio (PTVS) 263 | __pycache__/ 264 | *.pyc -------------------------------------------------------------------------------- /Assets/Unity2glTF/RefDLL/ChnCharInfo.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/RefDLL/ChnCharInfo.dll -------------------------------------------------------------------------------- /Assets/Unity2glTF/RefDLL/Ionic.Zip.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/RefDLL/Ionic.Zip.dll -------------------------------------------------------------------------------- /Assets/Unity2glTF/RefDLL/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/RefDLL/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/Binary.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Uinty2glTF 7 | { 8 | internal class Binary 9 | { 10 | public const uint Magic = 0x46546C67; 11 | public const uint Version = 2; 12 | public const uint HeaderLength = sizeof(uint) + sizeof(uint) + sizeof(int); 13 | public const uint ChunkHeaderLength = sizeof(uint) + sizeof(uint); 14 | public const uint ChunkFormatJson = 0x4E4F534A; 15 | public const uint ChunkFormatBin = 0x004E4942; 16 | } 17 | } -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/DirectoryHelper.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace Uinty2glTF 4 | { 5 | public class DirectoryHelper 6 | { 7 | 8 | /// 9 | /// 删除指定目录下所有内容:方法二--找到所有文件和子文件夹删除 //转载请注明来自 http://www.shang11.com 10 | /// 11 | /// 12 | public static void DeleteFolder2(string dirPath) 13 | { 14 | if (Directory.Exists(dirPath)) 15 | { 16 | foreach (string content in Directory.GetFileSystemEntries(dirPath)) 17 | { 18 | if (Directory.Exists(content)) 19 | { 20 | try 21 | { 22 | Directory.Delete(content, true); 23 | } 24 | catch { } 25 | } 26 | else if (File.Exists(content)) 27 | { 28 | try 29 | { 30 | File.Delete(content); 31 | } 32 | catch { } 33 | } 34 | } 35 | } 36 | } 37 | 38 | 39 | /// 40 | /// 清空指定的文件夹,但不删除文件夹 41 | /// 42 | /// 43 | public static void DeleteFolder(string dir) 44 | { 45 | foreach (string d in Directory.GetFileSystemEntries(dir)) 46 | { 47 | if (File.Exists(d)) 48 | { 49 | try 50 | { 51 | FileInfo fi = new FileInfo(d); 52 | if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1) 53 | fi.Attributes = FileAttributes.Normal; 54 | File.Delete(d);//直接删除其中的文件 55 | } 56 | catch 57 | { 58 | 59 | } 60 | } 61 | else 62 | { 63 | try 64 | { 65 | DirectoryInfo d1 = new DirectoryInfo(d); 66 | if (d1.GetFiles().Length != 0) 67 | { 68 | DeleteFolder(d1.FullName);////递归删除子文件夹 69 | } 70 | Directory.Delete(d); 71 | } 72 | catch 73 | { 74 | 75 | } 76 | } 77 | } 78 | } 79 | /// 80 | /// 删除文件夹及其内容 81 | /// 82 | /// 83 | public static void DeleteFolder1(string dir) 84 | { 85 | foreach (string d in Directory.GetFileSystemEntries(dir)) 86 | { 87 | if (File.Exists(d)) 88 | { 89 | FileInfo fi = new FileInfo(d); 90 | if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1) 91 | fi.Attributes = FileAttributes.Normal; 92 | File.Delete(d);//直接删除其中的文件 93 | } 94 | else 95 | DeleteFolder(d);////递归删除子文件夹 96 | if (Directory.Exists(d)) Directory.Delete(d); 97 | } 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/ExportWindow.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using UnityEngine; 3 | using UnityEditor; 4 | using UnityEngine.SceneManagement; 5 | using UnityEditor.SceneManagement; 6 | using System.Security.Cryptography; 7 | using System.Diagnostics; 8 | 9 | namespace Uinty2glTF 10 | { 11 | public class ExportWindow : EditorWindow 12 | { 13 | [MenuItem("工具/glTF导出工具")] 14 | public static void Init() 15 | { 16 | ExportWindow window = (ExportWindow)EditorWindow.GetWindow(typeof(ExportWindow), true, "glTF导出工具", true); 17 | window.autoRepaintOnSceneChange = true; 18 | window.minSize = new Vector2(300, 420); 19 | window.maxSize = new Vector2(300, 420); 20 | window.maximized = false; 21 | window._selectedCount = Selection.objects.Length; 22 | window.Show(true); 23 | window.Focus(); 24 | } 25 | 26 | private WebServer webServer; 27 | private WebServer exportFileServer; 28 | private const int _spaceSize = 20; 29 | private const string _selectedCountFormat = "选中物体数量:{0}个"; 30 | private int _selectedCount = 0; 31 | private GUIStyle _msgStytle; 32 | private readonly GUILayoutOption _buttonHeight = GUILayout.Height(30); 33 | private readonly string _errMsgFormat = "{0}"; 34 | private string _errMsg = null; 35 | private readonly string _successMsgFormat = "{0}"; 36 | private string _successMsg = null; 37 | private bool _error = false; 38 | private bool _glb = true; 39 | private GameObject _exporterGo; 40 | private SceneToGlTFWiz _exporter; 41 | public void OnEnable() 42 | { 43 | if (webServer == null) 44 | { 45 | string basePath = Directory.GetParent(Application.dataPath).FullName; 46 | webServer = new WebServer(9527, basePath + "/Assets/Unity2glTF/Web/"); 47 | exportFileServer = new WebServer(9528, basePath + "/export/"); 48 | } 49 | if (_exporterGo == null) 50 | { 51 | _exporterGo = new GameObject("Exporter"); 52 | _exporter = _exporterGo.AddComponent(); 53 | _exporterGo.hideFlags = HideFlags.HideAndDontSave; 54 | } 55 | } 56 | 57 | public void OnDisable() 58 | { 59 | if (_exporterGo != null) 60 | { 61 | DestroyImmediate(_exporterGo); 62 | _exporterGo = null; 63 | } 64 | 65 | } 66 | public void OnSelectionChange() 67 | { 68 | _selectedCount = Selection.objects.Length; 69 | _errMsg = null; 70 | _error = false; 71 | _successMsg = null; 72 | Repaint(); 73 | } 74 | public void OnGUI() 75 | { 76 | if (_msgStytle == null) _msgStytle = new GUIStyle(EditorStyles.label) { richText = true }; 77 | 78 | GUILayout.BeginVertical(); 79 | GUILayout.Space(_spaceSize); 80 | GUILayout.Label(string.Format(_selectedCountFormat, _selectedCount)); 81 | GUILayout.Space(_spaceSize); 82 | _glb = GUILayout.Toggle(_glb, "生成.glb文件"); 83 | GUILayout.Space(_spaceSize); 84 | if (GUILayout.Button("导出选中物体", _buttonHeight)) 85 | { 86 | _errMsg = null; 87 | _error = false; 88 | _successMsg = null; 89 | if (_selectedCount == 0) 90 | { 91 | _error = true; 92 | _errMsg = "请在层级列表面板选中一个或多个物体进行导出!"; 93 | return; 94 | } 95 | Export(); 96 | } 97 | GUILayout.Space(_spaceSize * 2); 98 | if (_error) 99 | { 100 | if (_errMsg != null) 101 | { 102 | GUILayout.Label(string.Format(_errMsgFormat, _errMsg), _msgStytle); 103 | } 104 | else 105 | { 106 | GUILayout.Label(""); 107 | } 108 | } 109 | else 110 | { 111 | if (_successMsg != null) 112 | { 113 | GUILayout.Label(string.Format(_successMsgFormat, _successMsg), _msgStytle); 114 | } 115 | else 116 | { 117 | GUILayout.Label(""); 118 | } 119 | } 120 | GUILayout.Space(_spaceSize * 2); 121 | if (GUILayout.Button("清理场景物体", _buttonHeight)) 122 | { 123 | ClearScene(); 124 | } 125 | GUILayout.Space(_spaceSize); 126 | if (GUILayout.Button("清理资源文件", _buttonHeight)) 127 | { 128 | ClearResources(); 129 | } 130 | GUILayout.Space(_spaceSize); 131 | if (GUILayout.Button("打开项目文件夹", _buttonHeight)) 132 | { 133 | OpenProjectDir(); 134 | } 135 | GUILayout.EndVertical(); 136 | } 137 | private void Export() 138 | { 139 | InitExportPath(); 140 | string mExportPath = Directory.GetParent(Application.dataPath).FullName + "/export"; 141 | //RNGCryptoServiceProvider csp = new RNGCryptoServiceProvider(); 142 | //byte[] byteCsp = new byte[4]; 143 | //csp.GetBytes(byteCsp); 144 | //string mParamName = System.BitConverter.ToString(byteCsp).Replace("-", null); 145 | string mParamName = Selection.objects[0].name; 146 | string exportFileName = Path.Combine(mExportPath, mParamName + ".gltf"); 147 | var callBack = new System.Action((bool state, string msg) => 148 | { 149 | _error = !state; 150 | if (state) 151 | { 152 | _successMsg = msg; 153 | string url = string.Format("{0}?assetUrl={1}{2}.glb", webServer.Prefix, exportFileServer.Prefix, Selection.objects[0].name); 154 | Process.Start(url); 155 | } 156 | else _errMsg = msg; 157 | }); 158 | _exporter.ExportCoroutine(exportFileName, null, _glb, true, true, false, callBack); 159 | } 160 | private void InitExportPath() 161 | { 162 | string exprotPath = Directory.GetParent(Application.dataPath).FullName + "/export"; 163 | if (Directory.Exists(exprotPath)) 164 | { 165 | DirectoryHelper.DeleteFolder2(exprotPath); 166 | } 167 | if (!Directory.Exists(exprotPath)) 168 | { 169 | Directory.CreateDirectory(exprotPath); 170 | } 171 | } 172 | private void ClearScene() 173 | { 174 | GameObject[] objs = SceneManager.GetActiveScene().GetRootGameObjects(); 175 | for (int i = 0; i < objs.Length; i++) 176 | { 177 | if (objs[i].name == "Directional light" || objs[i].name == "Camera") continue; 178 | DestroyImmediate(objs[i]); 179 | } 180 | EditorSceneManager.MarkAllScenesDirty(); 181 | EditorSceneManager.SaveOpenScenes(); 182 | AssetDatabase.SaveAssets(); 183 | AssetDatabase.Refresh(); 184 | } 185 | private void OpenProjectDir() 186 | { 187 | string root = Directory.GetParent(Application.dataPath).FullName; 188 | System.Diagnostics.Process.Start(root); 189 | } 190 | private void ClearResources() 191 | { 192 | string scene = SceneManager.GetActiveScene().path; 193 | string[] array = AssetDatabase.GetAllAssetPaths(); 194 | for (int i = 0; i < array.Length; i++) 195 | { 196 | string path = array[i]; 197 | if (!path.StartsWith("Assets") || path.StartsWith("Assets/Unity2glTF") || path == scene || path == "Assets") continue; 198 | AssetDatabase.DeleteAsset(path); 199 | } 200 | AssetDatabase.SaveAssets(); 201 | AssetDatabase.Refresh(); 202 | } 203 | } 204 | } -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/ForceExternalMaterialProcessor.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | // An asset postprocessor that sets the material setting of a model to "Use External Materials (Legacy)". 3 | // 4 | // It only processes an asset if it's a new one, that didn't exist in the project yet. 5 | // Duplicating an asset inside Unity does not count as new asset in this case. 6 | // It counts as new asset if the .meta file is missing. 7 | // 8 | // Save this file as: Assets/Editor/ForceExternalMaterialProcessor.cs 9 | // 10 | // Download latest version at: https://bitbucket.org/snippets/pschraut/Eea64L 11 | // 12 | using UnityEngine; 13 | using UnityEditor; 14 | using System.IO; 15 | using System.Collections.Generic; 16 | 17 | public class ForceExternalMaterialProcessor : AssetPostprocessor 18 | { 19 | //用来保存贴图的路径 20 | static List list = new List(); 21 | void OnPreprocessModel() 22 | { 23 | list.Clear(); 24 | #if UNITY_2018_1_OR_NEWER 25 | var importSettingsMissing = assetImporter.importSettingsMissing; 26 | #else 27 | var importSettingsMissing = !File.Exists(AssetDatabase.GetTextMetaFilePathFromAssetPath(assetPath)); 28 | #endif 29 | if (!importSettingsMissing) 30 | return; // Asset imported already, do not process. 31 | 32 | var modelImporter = assetImporter as ModelImporter; 33 | modelImporter.materialLocation = ModelImporterMaterialLocation.External; 34 | } 35 | void OnPostprocessTexture(Texture2D texture) 36 | { 37 | list.Add(assetPath); 38 | 39 | } 40 | private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) 41 | { 42 | //资源释放顺序Win:贴图-->材质-->物体,Linux:材质-->物体-->贴图 43 | //Linux存在材质无贴图的问题 44 | //以下代码为彻底解决Linux材质无贴图问题。 45 | if (importedAssets.Length > 0) 46 | { 47 | foreach (string texturePath in list) 48 | { 49 | string name = Path.GetFileNameWithoutExtension(texturePath); 50 | string ext = Path.GetExtension(texturePath); 51 | string matPath = texturePath.Replace("/" + name + ext, ""); 52 | int index = matPath.LastIndexOf("/"); 53 | matPath = matPath.Substring(0, index + 1); 54 | matPath += "Materials/" + name + ".mat"; 55 | Material mat = AssetDatabase.LoadAssetAtPath(matPath); 56 | if (mat && !mat.mainTexture) 57 | { 58 | mat.mainTexture = AssetDatabase.LoadAssetAtPath(texturePath); 59 | } 60 | } 61 | } 62 | } 63 | } 64 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_AmbientLight.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_AmbientLight : GlTF_Light 8 | { 9 | public override void Write() 10 | { 11 | color.Write(); 12 | } 13 | } 14 | } 15 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_AnimSampler.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_AnimSampler : GlTF_Writer 8 | { 9 | public int input = -1; // accessor index 10 | public string interpolation = "LINEAR"; // Can also be STEP in glTF 2.0 11 | public int output = -1; // accessor index 12 | 13 | public GlTF_AnimSampler(int i, int o) { input = i; output = o; } 14 | public override void Write() 15 | { 16 | Indent(); jsonWriter.Write("{\n"); 17 | IndentIn(); 18 | Indent(); jsonWriter.Write("\"input\": " + input + ",\n"); 19 | Indent(); jsonWriter.Write("\"interpolation\": \"" + interpolation + "\",\n"); 20 | Indent(); jsonWriter.Write("\"output\": " + output + "\n"); 21 | IndentOut(); 22 | Indent(); jsonWriter.Write("}"); 23 | } 24 | } 25 | } 26 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Animation.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using UnityEditor; 6 | 7 | namespace Uinty2glTF 8 | { 9 | public class GlTF_Animation : GlTF_Writer 10 | { 11 | public List channels = new List(); 12 | public List animSamplers = new List(); 13 | 14 | public enum ROTATION_TYPE 15 | { 16 | UNKNOWN, 17 | QUATERNION, 18 | EULER 19 | }; 20 | 21 | int bakingFramerate = 30; // FPS 22 | 23 | public GlTF_Animation(string n) 24 | { 25 | name = n; 26 | } 27 | 28 | private struct TargetCurveSet 29 | { 30 | public AnimationCurve[] translationCurves; 31 | public AnimationCurve[] rotationCurves; 32 | //Additional curve types 33 | //public AnimationCurve[] localEulerAnglesRaw; 34 | //public AnimationCurve[] m_LocalEuler; 35 | public AnimationCurve[] scaleCurves; 36 | public ROTATION_TYPE rotationType; 37 | public void Init() 38 | { 39 | translationCurves = new AnimationCurve[3]; 40 | rotationCurves = new AnimationCurve[4]; 41 | scaleCurves = new AnimationCurve[3]; 42 | } 43 | } 44 | 45 | public void Populate(AnimationClip clip, Transform tr, bool bake = true) 46 | { 47 | // 1. browse clip, collect all curves and create a TargetCurveSet for each target 48 | Dictionary targetCurvesBinding = new Dictionary(); 49 | collectClipCurves(clip, ref targetCurvesBinding); 50 | 51 | // Baking needs all properties, fill missing curves with transform data in 2 keyframes (start, endTime) 52 | // where endTime is clip duration 53 | generateMissingCurves(clip.length, ref tr, ref targetCurvesBinding); 54 | 55 | if (bake) 56 | { 57 | // Bake animation for all animated nodes 58 | foreach (string target in targetCurvesBinding.Keys) 59 | { 60 | Transform targetTr = target.Length > 0 ? tr.Find(target) : tr; 61 | if (targetTr == null) 62 | continue; 63 | 64 | Transform targetObject = targetTr; 65 | string targetId = GlTF_Node.GetNameFromObject(targetObject); 66 | 67 | // Initialize accessors for current animation 68 | GlTF_Accessor timeAccessor = new GlTF_Accessor(targetId + "_TimeAccessor_" + clip.name, GlTF_Accessor.Type.SCALAR, GlTF_Accessor.ComponentType.FLOAT); 69 | timeAccessor.bufferView = GlTF_Writer.floatBufferView; 70 | int timeAccessorIndex = GlTF_Writer.accessors.Count; 71 | GlTF_Writer.accessors.Add(timeAccessor); 72 | 73 | // Translation 74 | GlTF_Channel chTranslation = new GlTF_Channel("translation", animSamplers.Count); 75 | GlTF_Target targetTranslation = new GlTF_Target(); 76 | targetTranslation.id = targetId; 77 | targetTranslation.path = "translation"; 78 | chTranslation.target = targetTranslation; 79 | channels.Add(chTranslation); 80 | 81 | GlTF_AnimSampler sTranslation = new GlTF_AnimSampler(timeAccessorIndex, GlTF_Writer.accessors.Count); 82 | GlTF_Accessor translationAccessor = new GlTF_Accessor(targetId + "_TranslationAccessor_" + clip.name, GlTF_Accessor.Type.VEC3, GlTF_Accessor.ComponentType.FLOAT); 83 | translationAccessor.bufferView = GlTF_Writer.vec3BufferViewAnim; 84 | GlTF_Writer.accessors.Add(translationAccessor); 85 | animSamplers.Add(sTranslation); 86 | 87 | // Rotation 88 | GlTF_Channel chRotation = new GlTF_Channel("rotation", animSamplers.Count); 89 | GlTF_Target targetRotation = new GlTF_Target(); 90 | targetRotation.id = GlTF_Node.GetNameFromObject(targetObject); 91 | targetRotation.path = "rotation"; 92 | chRotation.target = targetRotation; 93 | channels.Add(chRotation); 94 | 95 | GlTF_AnimSampler sRotation = new GlTF_AnimSampler(timeAccessorIndex, GlTF_Writer.accessors.Count); 96 | GlTF_Accessor rotationAccessor = new GlTF_Accessor(targetId + "_RotationAccessor_" + clip.name, GlTF_Accessor.Type.VEC4, GlTF_Accessor.ComponentType.FLOAT); 97 | rotationAccessor.bufferView = GlTF_Writer.vec4BufferViewAnim; 98 | GlTF_Writer.accessors.Add(rotationAccessor); 99 | animSamplers.Add(sRotation); 100 | 101 | // Scale 102 | GlTF_Channel chScale = new GlTF_Channel("scale", animSamplers.Count); 103 | GlTF_Target targetScale = new GlTF_Target(); 104 | targetScale.id = GlTF_Node.GetNameFromObject(targetObject); 105 | targetScale.path = "scale"; 106 | chScale.target = targetScale; 107 | channels.Add(chScale); 108 | 109 | GlTF_AnimSampler sScale = new GlTF_AnimSampler(timeAccessorIndex, GlTF_Writer.accessors.Count); 110 | GlTF_Accessor scaleAccessor = new GlTF_Accessor(targetId + "_ScaleAccessor_" + clip.name, GlTF_Accessor.Type.VEC3, GlTF_Accessor.ComponentType.FLOAT); 111 | scaleAccessor.bufferView = GlTF_Writer.vec3BufferViewAnim; 112 | GlTF_Writer.accessors.Add(scaleAccessor); 113 | animSamplers.Add(sScale); 114 | 115 | // Bake and populate animation data 116 | float[] times = null; 117 | Vector3[] positions = null; 118 | Vector3[] scales = null; 119 | Vector4[] rotations = null; 120 | bakeCurveSet(targetCurvesBinding[target], clip.length, bakingFramerate, ref times, ref positions, ref rotations, ref scales); 121 | 122 | // Populate accessors 123 | timeAccessor.Populate(times); 124 | translationAccessor.Populate(positions); 125 | rotationAccessor.Populate(rotations, false); 126 | scaleAccessor.Populate(scales, true); 127 | } 128 | } 129 | else 130 | { 131 | Debug.LogError("Only baked animation is supported for now. Skipping animation"); 132 | } 133 | 134 | } 135 | 136 | private void collectClipCurves(AnimationClip clip, ref Dictionary targetCurves) 137 | { 138 | foreach (var binding in AnimationUtility.GetCurveBindings(clip)) 139 | { 140 | AnimationCurve curve = AnimationUtility.GetEditorCurve(clip, binding); 141 | 142 | if (!targetCurves.ContainsKey(binding.path)) 143 | { 144 | TargetCurveSet curveSet = new TargetCurveSet(); 145 | curveSet.Init(); 146 | targetCurves.Add(binding.path, curveSet); 147 | } 148 | 149 | TargetCurveSet current = targetCurves[binding.path]; 150 | if (binding.propertyName.Contains("m_LocalPosition")) 151 | { 152 | if (binding.propertyName.Contains(".x")) 153 | current.translationCurves[0] = curve; 154 | else if (binding.propertyName.Contains(".y")) 155 | current.translationCurves[1] = curve; 156 | else if (binding.propertyName.Contains(".z")) 157 | current.translationCurves[2] = curve; 158 | } 159 | else if (binding.propertyName.Contains("m_LocalScale")) 160 | { 161 | if (binding.propertyName.Contains(".x")) 162 | current.scaleCurves[0] = curve; 163 | else if (binding.propertyName.Contains(".y")) 164 | current.scaleCurves[1] = curve; 165 | else if (binding.propertyName.Contains(".z")) 166 | current.scaleCurves[2] = curve; 167 | } 168 | else if (binding.propertyName.ToLower().Contains("localrotation")) 169 | { 170 | current.rotationType = ROTATION_TYPE.QUATERNION; 171 | if (binding.propertyName.Contains(".x")) 172 | current.rotationCurves[0] = curve; 173 | else if (binding.propertyName.Contains(".y")) 174 | current.rotationCurves[1] = curve; 175 | else if (binding.propertyName.Contains(".z")) 176 | current.rotationCurves[2] = curve; 177 | else if (binding.propertyName.Contains(".w")) 178 | current.rotationCurves[3] = curve; 179 | } 180 | // Takes into account 'localEuler', 'localEulerAnglesBaked' and 'localEulerAnglesRaw' 181 | else if (binding.propertyName.ToLower().Contains("localeuler")) 182 | { 183 | current.rotationType = ROTATION_TYPE.EULER; 184 | if (binding.propertyName.Contains(".x")) 185 | current.rotationCurves[0] = curve; 186 | else if (binding.propertyName.Contains(".y")) 187 | current.rotationCurves[1] = curve; 188 | else if (binding.propertyName.Contains(".z")) 189 | current.rotationCurves[2] = curve; 190 | } 191 | targetCurves[binding.path] = current; 192 | } 193 | } 194 | 195 | private void generateMissingCurves(float endTime, ref Transform tr, ref Dictionary targetCurvesBinding) 196 | { 197 | foreach (string target in targetCurvesBinding.Keys) 198 | { 199 | Transform targetTr = target.Length > 0 ? tr.Find(target) : tr; 200 | if (targetTr == null) 201 | continue; 202 | 203 | TargetCurveSet current = targetCurvesBinding[target]; 204 | if (current.translationCurves[0] == null) 205 | { 206 | current.translationCurves[0] = createConstantCurve(targetTr.localPosition.x, endTime); 207 | current.translationCurves[1] = createConstantCurve(targetTr.localPosition.y, endTime); 208 | current.translationCurves[2] = createConstantCurve(targetTr.localPosition.z, endTime); 209 | } 210 | 211 | if (current.scaleCurves[0] == null) 212 | { 213 | current.scaleCurves[0] = createConstantCurve(targetTr.localScale.x, endTime); 214 | current.scaleCurves[1] = createConstantCurve(targetTr.localScale.y, endTime); 215 | current.scaleCurves[2] = createConstantCurve(targetTr.localScale.z, endTime); 216 | } 217 | 218 | if (current.rotationCurves[0] == null) 219 | { 220 | current.rotationCurves[0] = createConstantCurve(targetTr.localRotation.x, endTime); 221 | current.rotationCurves[1] = createConstantCurve(targetTr.localRotation.y, endTime); 222 | current.rotationCurves[2] = createConstantCurve(targetTr.localRotation.z, endTime); 223 | current.rotationCurves[3] = createConstantCurve(targetTr.localRotation.w, endTime); 224 | } 225 | } 226 | } 227 | 228 | private void bakeCurveSet(TargetCurveSet curveSet, float length, int bakingFramerate, ref float[] times, ref Vector3[] positions, ref Vector4[] rotations, ref Vector3[] scales) 229 | { 230 | int nbSamples = (int)(length * 30); 231 | float deltaTime = length / nbSamples; 232 | 233 | // Initialize Arrays 234 | times = new float[nbSamples]; 235 | positions = new Vector3[nbSamples]; 236 | scales = new Vector3[nbSamples]; 237 | rotations = new Vector4[nbSamples]; 238 | 239 | // Assuming all the curves exist now 240 | for (int i = 0; i < nbSamples; ++i) 241 | { 242 | float currentTime = i * deltaTime; 243 | times[i] = currentTime; 244 | positions[i] = new Vector3(curveSet.translationCurves[0].Evaluate(currentTime), curveSet.translationCurves[1].Evaluate(currentTime), curveSet.translationCurves[2].Evaluate(currentTime)); 245 | scales[i] = new Vector3(curveSet.scaleCurves[0].Evaluate(currentTime), curveSet.scaleCurves[1].Evaluate(currentTime), curveSet.scaleCurves[2].Evaluate(currentTime)); 246 | if (curveSet.rotationType == ROTATION_TYPE.EULER) 247 | { 248 | Quaternion eulerToQuat = Quaternion.Euler(curveSet.rotationCurves[0].Evaluate(currentTime), curveSet.rotationCurves[1].Evaluate(currentTime), curveSet.rotationCurves[2].Evaluate(currentTime)); 249 | rotations[i] = new Vector4(eulerToQuat.x, eulerToQuat.y, eulerToQuat.z, eulerToQuat.w); 250 | } 251 | else 252 | { 253 | rotations[i] = new Vector4(curveSet.rotationCurves[0].Evaluate(currentTime), curveSet.rotationCurves[1].Evaluate(currentTime), curveSet.rotationCurves[2].Evaluate(currentTime), curveSet.rotationCurves[3].Evaluate(currentTime)); 254 | } 255 | } 256 | } 257 | 258 | public AnimationCurve createConstantCurve(float value, float endTime) 259 | { 260 | // No translation curves, adding them 261 | AnimationCurve curve = new AnimationCurve(); 262 | curve.AddKey(0, value); 263 | curve.AddKey(endTime, value); 264 | return curve; 265 | } 266 | 267 | public override void Write() 268 | { 269 | if (channels.Count == 0) 270 | return; 271 | 272 | Indent(); jsonWriter.Write("{\n"); 273 | IndentIn(); 274 | Indent(); jsonWriter.Write("\"name\": \"" + name + "\",\n"); 275 | Indent(); jsonWriter.Write("\"channels\": [\n"); 276 | foreach (GlTF_Channel c in channels) 277 | { 278 | CommaNL(); 279 | c.Write(); 280 | } 281 | jsonWriter.WriteLine(); 282 | Indent(); jsonWriter.Write("],\n"); 283 | 284 | Indent(); jsonWriter.Write("\"samplers\": [\n"); 285 | IndentIn(); 286 | foreach (GlTF_AnimSampler s in animSamplers) 287 | { 288 | CommaNL(); 289 | s.Write(); 290 | } 291 | IndentOut(); 292 | jsonWriter.WriteLine(); 293 | Indent(); jsonWriter.Write("]\n"); 294 | 295 | IndentOut(); 296 | Indent(); jsonWriter.Write("}"); 297 | } 298 | } 299 | } 300 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Attributes.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Attributes : GlTF_Writer 8 | { 9 | public GlTF_Accessor normalAccessor; 10 | public GlTF_Accessor positionAccessor; 11 | public GlTF_Accessor colorAccessor; 12 | public GlTF_Accessor texCoord0Accessor; 13 | public GlTF_Accessor texCoord1Accessor; 14 | public GlTF_Accessor texCoord2Accessor; 15 | public GlTF_Accessor texCoord3Accessor; 16 | public GlTF_Accessor lightmapTexCoordAccessor; 17 | public GlTF_Accessor jointAccessor; 18 | public GlTF_Accessor weightAccessor; 19 | public GlTF_Accessor tangentAccessor; 20 | 21 | private Vector4[] boneWeightToBoneVec4(BoneWeight[] bw) 22 | { 23 | Vector4[] bones = new Vector4[bw.Length]; 24 | for (int i = 0; i < bw.Length; ++i) 25 | { 26 | bones[i] = new Vector4(bw[i].boneIndex0, bw[i].boneIndex1, bw[i].boneIndex2, bw[i].boneIndex3); 27 | } 28 | 29 | return bones; 30 | } 31 | 32 | private Vector4[] boneWeightToWeightVec4(BoneWeight[] bw) 33 | { 34 | Vector4[] weights = new Vector4[bw.Length]; 35 | for (int i = 0; i < bw.Length; ++i) 36 | { 37 | weights[i] = new Vector4(bw[i].weight0, bw[i].weight1, bw[i].weight2, bw[i].weight3); 38 | } 39 | 40 | return weights; 41 | } 42 | 43 | public void Populate(Mesh m) 44 | { 45 | positionAccessor.Populate(m.vertices); 46 | if (colorAccessor != null) 47 | { 48 | colorAccessor.Populate(m.colors); 49 | } 50 | if (normalAccessor != null) 51 | { 52 | //Vector3[] normals = new Vector3[m.normals.Length]; 53 | //System.Array.Copy(m.normals, normals, normals.Length); 54 | //for(int i = 0; i < normals.Length; i++) 55 | //{ 56 | // normals[i].x = -normals[i].x; 57 | // normals[i].y = -normals[i].y; 58 | // normals[i].z = -normals[i].z; 59 | //} 60 | normalAccessor.Populate(m.normals,true); 61 | } 62 | if (texCoord0Accessor != null) 63 | { 64 | texCoord0Accessor.Populate(m.uv, false); 65 | } 66 | if (texCoord1Accessor != null) 67 | { 68 | texCoord1Accessor.Populate(m.uv2, false); 69 | } 70 | if (texCoord2Accessor != null) 71 | { 72 | texCoord2Accessor.Populate(m.uv3, false); 73 | } 74 | if (texCoord3Accessor != null) 75 | { 76 | texCoord3Accessor.Populate(m.uv4, false); 77 | } 78 | if (lightmapTexCoordAccessor != null) 79 | { 80 | lightmapTexCoordAccessor.PopulateWithOffsetScale(m.uv2, false); 81 | } 82 | if (jointAccessor != null) 83 | { 84 | Vector4[] bones = boneWeightToBoneVec4(m.boneWeights); 85 | jointAccessor.PopulateShort(bones); 86 | } 87 | if (weightAccessor != null) 88 | { 89 | Vector4[] weights = boneWeightToWeightVec4(m.boneWeights); 90 | weightAccessor.Populate(weights); 91 | } 92 | if (tangentAccessor != null) 93 | { 94 | tangentAccessor.Populate(m.tangents, false); 95 | } 96 | } 97 | 98 | public override void Write() 99 | { 100 | Indent(); jsonWriter.Write("\"attributes\": {\n"); 101 | IndentIn(); 102 | if (positionAccessor != null) 103 | { 104 | CommaNL(); 105 | Indent(); jsonWriter.Write("\"POSITION\": " + GlTF_Writer.accessors.IndexOf(positionAccessor)); 106 | } 107 | if (normalAccessor != null) 108 | { 109 | CommaNL(); 110 | Indent(); jsonWriter.Write("\"NORMAL\": " + GlTF_Writer.accessors.IndexOf(normalAccessor)); 111 | } 112 | if (colorAccessor != null) 113 | { 114 | CommaNL(); 115 | Indent(); jsonWriter.Write("\"COLOR_0\": " + GlTF_Writer.accessors.IndexOf(colorAccessor)); 116 | } 117 | if (texCoord0Accessor != null) 118 | { 119 | CommaNL(); 120 | Indent(); jsonWriter.Write("\"TEXCOORD_0\": " + GlTF_Writer.accessors.IndexOf(texCoord0Accessor)); 121 | } 122 | if (texCoord1Accessor != null) 123 | { 124 | CommaNL(); 125 | Indent(); jsonWriter.Write("\"TEXCOORD_1\": " + GlTF_Writer.accessors.IndexOf(texCoord1Accessor)); 126 | } 127 | if (texCoord2Accessor != null) 128 | { 129 | CommaNL(); 130 | Indent(); jsonWriter.Write("\"TEXCOORD_2\": " + GlTF_Writer.accessors.IndexOf(texCoord2Accessor)); 131 | } 132 | if (texCoord3Accessor != null) 133 | { 134 | CommaNL(); 135 | Indent(); jsonWriter.Write("\"TEXCOORD_3\": " + GlTF_Writer.accessors.IndexOf(texCoord3Accessor)); 136 | } 137 | if (lightmapTexCoordAccessor != null) 138 | { 139 | CommaNL(); 140 | Indent(); jsonWriter.Write("\"TEXCOORD_4\": " + GlTF_Writer.accessors.IndexOf(lightmapTexCoordAccessor)); 141 | } 142 | if (jointAccessor != null) 143 | { 144 | CommaNL(); 145 | Indent(); jsonWriter.Write("\"JOINTS_0\": " + GlTF_Writer.accessors.IndexOf(jointAccessor)); 146 | } 147 | if (weightAccessor != null) 148 | { 149 | CommaNL(); 150 | Indent(); jsonWriter.Write("\"WEIGHTS_0\": " + GlTF_Writer.accessors.IndexOf(weightAccessor)); 151 | } 152 | if (tangentAccessor != null) 153 | { 154 | CommaNL(); 155 | Indent(); jsonWriter.Write("\"TANGENT\": " + GlTF_Writer.accessors.IndexOf(tangentAccessor)); 156 | } 157 | 158 | jsonWriter.WriteLine(); 159 | IndentOut(); 160 | Indent(); jsonWriter.Write("}"); 161 | } 162 | 163 | } 164 | } 165 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_BufferView.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | using System.IO; 5 | using System; 6 | 7 | namespace Uinty2glTF 8 | { 9 | public class GlTF_BufferView : GlTF_Writer 10 | { 11 | 12 | public enum TARGET 13 | { 14 | ARRAY = 34962, 15 | ELEMENT = 34963 16 | } 17 | 18 | public int bufferIndex = 0;// ": "duck", 19 | public long byteLength;//": 25272, 20 | public long byteOffset;//": 0, 21 | public long byteStride; 22 | public int target = -1; 23 | // public string target = "ARRAY_BUFFER"; 24 | public int currentOffset = 0; 25 | public MemoryStream memoryStream = new MemoryStream(); 26 | public bool bin = false; 27 | 28 | public GlTF_BufferView(string n, int s) { name = n; byteStride = s; } 29 | public GlTF_BufferView(string n, int s, int t) { name = n; byteStride = s; target = t; } 30 | 31 | public void Populate(int[] vs, bool flippedTriangle) 32 | { 33 | if (flippedTriangle) 34 | { 35 | for (int i = 0; i < vs.Length; i += 3) 36 | { 37 | ushort u = (ushort)vs[i]; 38 | memoryStream.Write(BitConverter.GetBytes(u), 0, BitConverter.GetBytes(u).Length); 39 | currentOffset += 2; 40 | 41 | u = (ushort)vs[i + 2]; 42 | memoryStream.Write(BitConverter.GetBytes(u), 0, BitConverter.GetBytes(u).Length); 43 | currentOffset += 2; 44 | 45 | u = (ushort)vs[i + 1]; 46 | memoryStream.Write(BitConverter.GetBytes(u), 0, BitConverter.GetBytes(u).Length); 47 | currentOffset += 2; 48 | } 49 | } 50 | else 51 | { 52 | for (int i = 0; i < vs.Length; i++) 53 | { 54 | ushort u = (ushort)vs[i]; 55 | memoryStream.Write(BitConverter.GetBytes(u), 0, BitConverter.GetBytes(u).Length); 56 | currentOffset += 2; 57 | } 58 | } 59 | byteLength = currentOffset; 60 | } 61 | 62 | public void PopulateShort(ushort vs) 63 | { 64 | ushort u = (ushort)vs; 65 | memoryStream.Write(BitConverter.GetBytes(u), 0, BitConverter.GetBytes(u).Length); 66 | currentOffset += 2; 67 | byteLength += 2; 68 | } 69 | 70 | public void Populate(float[] vs) 71 | { 72 | for (int i = 0; i < vs.Length; i++) 73 | { 74 | // memoryStream.Write (vs[i]); 75 | // memoryStream.Write ((byte[])vs, 0, vs.Length * sizeof(int)); 76 | float f = vs[i]; 77 | memoryStream.Write(BitConverter.GetBytes(f), 0, BitConverter.GetBytes(f).Length); 78 | currentOffset += 4; 79 | } 80 | byteLength = currentOffset; 81 | } 82 | 83 | public void Populate(uint v) 84 | { 85 | memoryStream.Write(BitConverter.GetBytes(v), 0, BitConverter.GetBytes(v).Length); 86 | currentOffset += 4; 87 | byteLength = currentOffset; 88 | } 89 | 90 | public void Populate(float v) 91 | { 92 | memoryStream.Write(BitConverter.GetBytes(v), 0, BitConverter.GetBytes(v).Length); 93 | currentOffset += 4; 94 | byteLength = currentOffset; 95 | } 96 | 97 | public override void Write() 98 | { 99 | /* 100 | "bufferView_4642": { 101 | "buffer": "vc.bin", 102 | "byteLength": 630080, 103 | "byteOffset": 0, 104 | "target": "ARRAY_BUFFER" 105 | }, 106 | */ 107 | Indent(); jsonWriter.Write("{\n"); 108 | IndentIn(); 109 | //var binName = binary ? "binary_glTF" : Path.GetFileNameWithoutExtension(GlTF_Writer.binFileName); 110 | Indent(); jsonWriter.Write("\"buffer\": " + bufferIndex + ",\n"); 111 | Indent(); jsonWriter.Write("\"byteLength\": " + byteLength + ",\n"); 112 | if ((int)target != (int)-1) 113 | { 114 | Indent(); jsonWriter.Write("\"target\": " + target + ",\n"); 115 | } 116 | 117 | if (byteStride >= 4) 118 | { 119 | Indent(); jsonWriter.Write("\"byteStride\": " + byteStride + ",\n"); 120 | } 121 | 122 | Indent(); jsonWriter.Write("\"byteOffset\": " + byteOffset + "\n"); 123 | 124 | IndentOut(); 125 | Indent(); jsonWriter.Write("}"); 126 | } 127 | } 128 | } 129 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Camera.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Camera : GlTF_Writer 8 | { 9 | public string type;// should be enum ": "perspective" 10 | } 11 | } 12 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Channel.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Channel : GlTF_Writer 8 | { 9 | public int samplerIndex = -1; 10 | public GlTF_Target target; 11 | 12 | public GlTF_Channel(string ch, int sIndex) 13 | { 14 | samplerIndex = sIndex; 15 | } 16 | 17 | public override void Write() 18 | { 19 | if (samplerIndex == -1) 20 | { 21 | Debug.LogError("Error when serializing gltf Channel for target: " + target.id); 22 | return; 23 | } 24 | 25 | IndentIn(); 26 | Indent(); jsonWriter.Write("{\n"); 27 | IndentIn(); 28 | Indent(); jsonWriter.Write("\"sampler\": " + samplerIndex + ",\n"); 29 | target.Write(); 30 | jsonWriter.WriteLine(); 31 | IndentOut(); 32 | Indent(); jsonWriter.Write("}"); 33 | IndentOut(); 34 | } 35 | } 36 | } 37 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_ColorOrTexture.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_ColorOrTexture : GlTF_Writer 8 | { 9 | public GlTF_ColorOrTexture() { } 10 | public GlTF_ColorOrTexture(string n) { name = n; } 11 | } 12 | } 13 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_ColorRGB.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_ColorRGB : GlTF_Writer 8 | { 9 | Color color; 10 | public GlTF_ColorRGB(string n) { name = n; } 11 | public GlTF_ColorRGB(Color c) { color = c; } 12 | public GlTF_ColorRGB(string n, Color c) { name = n; color = c; } 13 | public override void Write() 14 | { 15 | Indent(); 16 | if (name.Length > 0) 17 | jsonWriter.Write("\"" + name + "\": "); 18 | else 19 | jsonWriter.Write("\"color\": ["); 20 | jsonWriter.Write(color.r.ToString() + ", " + color.g.ToString() + ", " + color.b.ToString() + "]"); 21 | } 22 | } 23 | } 24 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_ColorRGBA.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_ColorRGBA : GlTF_Writer 8 | { 9 | Color color; 10 | public GlTF_ColorRGBA(string n) { name = n; } 11 | public GlTF_ColorRGBA(Color c) { color = c; } 12 | public GlTF_ColorRGBA(string n, Color c) { name = n; color = c; } 13 | public override void Write() 14 | { 15 | Indent(); 16 | if (name.Length > 0) 17 | jsonWriter.Write("\"" + name + "\": ["); 18 | else 19 | jsonWriter.Write("\"color\": ["); 20 | jsonWriter.Write(color.r.ToString() + ", " + color.g.ToString() + ", " + color.b.ToString() + ", " + color.a.ToString() + "]"); 21 | } 22 | } 23 | } 24 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_DirectionalLight.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_DirectionalLight : GlTF_Light 8 | { 9 | public override void Write() 10 | { 11 | color.Write(); 12 | } 13 | } 14 | } 15 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_FloatArray.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_FloatArray : GlTF_Writer 8 | { 9 | public float[] items; 10 | public int minItems = 0; 11 | public int maxItems = 0; 12 | 13 | public GlTF_FloatArray() { } 14 | public GlTF_FloatArray(string n) { name = n; } 15 | 16 | public override void Write() 17 | { 18 | if (name.Length > 0) 19 | { 20 | Indent(); jsonWriter.Write("\"" + name + "\": ["); 21 | } 22 | WriteVals(); 23 | if (name.Length > 0) 24 | { 25 | jsonWriter.Write("]"); 26 | } 27 | } 28 | 29 | public virtual void WriteVals() 30 | { 31 | for (int i = 0; i < maxItems; i++) 32 | { 33 | if (i > 0) 34 | jsonWriter.Write(", "); 35 | jsonWriter.Write(items[i].ToString()); 36 | } 37 | } 38 | } 39 | } 40 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_FloatArray4.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_FloatArray4 : GlTF_FloatArray 8 | { 9 | public GlTF_FloatArray4() { minItems = 4; maxItems = 4; items = new float[] { 1.0f, 0.0f, 0.0f, 0.0f }; } 10 | /* 11 | public override void Write() 12 | { 13 | Indent(); jsonWriter.Write ("\"rotation\": [ "); 14 | WriteVals(); 15 | jsonWriter.Write ("]"); 16 | } 17 | */ 18 | } 19 | } 20 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Image.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Image : GlTF_Writer 8 | { 9 | public string uri { get; set; } 10 | 11 | public static string GetNameFromObject(Object o) 12 | { 13 | return "image_" + GlTF_Writer.GetNameFromObject(o, true); 14 | } 15 | 16 | public override void Write() 17 | { 18 | Indent(); jsonWriter.Write("{\n"); 19 | IndentIn(); 20 | Indent(); jsonWriter.Write("\"uri\": \"" + uri + "\"\n"); 21 | IndentOut(); 22 | Indent(); jsonWriter.Write("}"); 23 | } 24 | } 25 | } 26 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Light.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Light : GlTF_Writer 8 | { 9 | public GlTF_ColorRGB color; 10 | public string type; 11 | // public override void Write () 12 | // { 13 | // } 14 | } 15 | } 16 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Material.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | 6 | namespace Uinty2glTF 7 | { 8 | public class GlTF_Material : GlTF_Writer 9 | { 10 | 11 | public class Value : GlTF_Writer 12 | { 13 | } 14 | 15 | public class ColorValue : Value 16 | { 17 | public Color color; 18 | public bool isRGB = false; 19 | 20 | public override void Write() 21 | { 22 | jsonWriter.Write("\"" + name + "\": ["); 23 | jsonWriter.Write(color.r.ToString() + ", " + color.g.ToString() + ", " + color.b.ToString() + (isRGB ? "" : ", " + color.a.ToString())); 24 | jsonWriter.Write("]"); 25 | } 26 | } 27 | 28 | public class VectorValue : Value 29 | { 30 | public Vector4 vector; 31 | 32 | public override void Write() 33 | { 34 | jsonWriter.Write("\"" + name + "\": ["); 35 | jsonWriter.Write(vector.x.ToString() + ", " + vector.y.ToString() + ", " + vector.z.ToString() + ", " + vector.w.ToString()); 36 | jsonWriter.Write("]"); 37 | } 38 | } 39 | 40 | public class FloatValue : Value 41 | { 42 | public float value; 43 | 44 | public override void Write() 45 | { 46 | jsonWriter.Write("\"" + name + "\": " + value); 47 | } 48 | } 49 | 50 | public class IntValue : Value 51 | { 52 | public int value; 53 | 54 | public override void Write() 55 | { 56 | jsonWriter.Write("\"" + name + "\": " + value); 57 | } 58 | } 59 | 60 | public class BoolValue : Value 61 | { 62 | public bool value; 63 | 64 | public override void Write() 65 | { 66 | jsonWriter.Write("\"" + name + "\": " + (value ? "true" : "false")); 67 | } 68 | } 69 | 70 | public class StringValue : Value 71 | { 72 | public string value; 73 | 74 | public override void Write() 75 | { 76 | jsonWriter.Write("\"" + name + "\": \"" + value + "\""); 77 | } 78 | } 79 | 80 | public class DictValue : Value 81 | { 82 | public Dictionary intValue; 83 | public Dictionary floatValue; 84 | public Dictionary stringValue; 85 | public DictValue() 86 | { 87 | intValue = new Dictionary(); 88 | floatValue = new Dictionary(); 89 | stringValue = new Dictionary(); 90 | } 91 | public override void Write() 92 | { 93 | jsonWriter.Write("\"" + name + "\" : {\n"); 94 | IndentIn(); 95 | 96 | foreach (string key in intValue.Keys) 97 | { 98 | CommaNL(); 99 | Indent(); jsonWriter.Write("\"" + key + "\" : " + intValue[key]); 100 | } 101 | foreach (string key in floatValue.Keys) 102 | { 103 | CommaNL(); 104 | Indent(); jsonWriter.Write("\"" + key + "\" : " + floatValue[key]); 105 | } 106 | foreach (string key in stringValue.Keys) 107 | { 108 | CommaNL(); 109 | Indent(); jsonWriter.Write("\"" + key + "\" : " + stringValue[key]); 110 | } 111 | jsonWriter.Write("\n"); 112 | IndentOut(); 113 | Indent(); jsonWriter.Write("}"); 114 | } 115 | } 116 | 117 | public int instanceTechniqueIndex; 118 | public bool isMetal = false; 119 | public float shininess; 120 | public List values = new List(); 121 | public List pbrValues = new List(); 122 | 123 | public static string GetNameFromObject(Object o) 124 | { 125 | return "material_" + GlTF_Writer.GetNameFromObject(o, true); 126 | } 127 | 128 | public override void Write() 129 | { 130 | Indent(); jsonWriter.Write("{\n"); 131 | IndentIn(); 132 | writeExtras(); 133 | if (isMetal) 134 | { 135 | Indent(); jsonWriter.Write("\"pbrMetallicRoughness\": {\n"); 136 | } 137 | else 138 | { 139 | Indent(); jsonWriter.Write("\"extensions\": {\n"); 140 | IndentIn(); 141 | 142 | Indent(); jsonWriter.Write("\"KHR_materials_pbrSpecularGlossiness\": {\n"); 143 | } 144 | IndentIn(); 145 | foreach (var v in pbrValues) 146 | { 147 | CommaNL(); 148 | Indent(); v.Write(); 149 | } 150 | if (!isMetal) 151 | { 152 | IndentOut(); 153 | Indent(); jsonWriter.Write("}"); 154 | jsonWriter.Write("\n"); 155 | } 156 | 157 | jsonWriter.Write("\n"); 158 | IndentOut(); 159 | Indent(); jsonWriter.Write("},\n"); 160 | 161 | // write common values 162 | foreach (var v in values) 163 | { 164 | CommaNL(); 165 | Indent(); v.Write(); 166 | } 167 | CommaNL(); 168 | Indent(); jsonWriter.Write("\"name\": \"" + name + "\"\n"); 169 | IndentOut(); 170 | Indent(); jsonWriter.Write("}"); 171 | 172 | } 173 | 174 | } 175 | } 176 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_MaterialColor.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_MaterialColor : GlTF_ColorOrTexture 8 | { 9 | public GlTF_MaterialColor(string n, Color c) { name = n; color = new GlTF_ColorRGBA(name, c); } 10 | public GlTF_ColorRGBA color = new GlTF_ColorRGBA("diffuse"); 11 | public override void Write() 12 | { 13 | // Indent(); jsonWriter.Write ("\"" + name + "\": "); 14 | color.Write(); 15 | } 16 | } 17 | } 18 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_MaterialTexture.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_MaterialTexture : GlTF_ColorOrTexture 8 | { 9 | public GlTF_MaterialTexture(string n, GlTF_Texture t) { name = n; texture = t; } 10 | public GlTF_Texture texture; 11 | public override void Write() 12 | { 13 | Indent(); jsonWriter.Write("\"" + name + "\": \"" + texture.name + "\""); 14 | } 15 | } 16 | } 17 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Matrix.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Matrix : GlTF_FloatArray 8 | { 9 | public GlTF_Matrix() { name = "matrix"; minItems = 16; maxItems = 16; items = new float[] { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; } 10 | public GlTF_Matrix(Matrix4x4 m, bool convertLeftRight = true) 11 | { 12 | name = "matrix"; 13 | minItems = 16; 14 | maxItems = 16; 15 | 16 | // unity: m[row][col] 17 | // gltf: column major 18 | if (convertRightHanded && convertLeftRight) 19 | convertMatrixLeftToRightHandedness(ref m); 20 | 21 | items = new float[] { 22 | m.m00, m.m10, m.m20, m.m30, 23 | m.m01, m.m11, m.m21, m.m31, 24 | m.m02, m.m12, m.m22, m.m32, 25 | m.m03, m.m13, m.m23, m.m33 26 | }; 27 | } 28 | } 29 | } 30 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Mesh.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | 6 | namespace Uinty2glTF 7 | { 8 | public class GlTF_Mesh : GlTF_Writer 9 | { 10 | public List primitives; 11 | 12 | public GlTF_Mesh() { primitives = new List(); } 13 | 14 | public static string GetNameFromObject(Object o) 15 | { 16 | //return "mesh_" + GlTF_Writer.GetNameFromObject(o, true); 17 | return GlTF_Writer.GetNameFromObject(o, true); 18 | } 19 | 20 | public void Populate(Mesh m) 21 | { 22 | if (primitives.Count > 0) 23 | { 24 | // only populate first attributes because the data are shared between primitives 25 | primitives[0].attributes.Populate(m); 26 | } 27 | 28 | foreach (GlTF_Primitive p in primitives) 29 | { 30 | p.Populate(m); 31 | } 32 | } 33 | 34 | public override void Write() 35 | { 36 | Indent(); jsonWriter.Write("{\n"); 37 | IndentIn(); 38 | Indent(); jsonWriter.Write("\"name\": \"" + name + "\",\n"); 39 | Indent(); jsonWriter.Write("\"primitives\": [\n"); 40 | IndentIn(); 41 | foreach (GlTF_Primitive p in primitives) 42 | { 43 | CommaNL(); 44 | Indent(); jsonWriter.Write("{\n"); 45 | p.Write(); 46 | Indent(); jsonWriter.Write("}"); 47 | } 48 | jsonWriter.WriteLine(); 49 | IndentOut(); 50 | Indent(); jsonWriter.Write("]\n"); 51 | IndentOut(); 52 | Indent(); jsonWriter.Write("}"); 53 | } 54 | } 55 | } 56 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Node.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | 6 | namespace Uinty2glTF 7 | { 8 | public class GlTF_Node : GlTF_Writer 9 | { 10 | public string cameraName; 11 | public bool hasParent = false; 12 | public List childrenNames = new List(); 13 | public bool uniqueItems = true; 14 | public string lightName; 15 | public List bufferViewNames = new List(); 16 | public List indexNames = new List(); 17 | public List accessorNames = new List(); 18 | public int meshIndex = -1; 19 | public GlTF_Matrix matrix; 20 | // public GlTF_Mesh mesh; 21 | public GlTF_Rotation rotation; 22 | public GlTF_Scale scale; 23 | public GlTF_Translation translation; 24 | public int skinIndex = -1; 25 | public List skeletons = new List(); 26 | public bool additionalProperties = false; 27 | 28 | public static string GetNameFromObject(Object o) 29 | { 30 | //return "node_" + GlTF_Writer.GetNameFromObject(o, true); 31 | return GlTF_Writer.GetNameFromObject(o, true); 32 | } 33 | 34 | public override void Write() 35 | { 36 | Indent(); 37 | jsonWriter.Write("{\n"); 38 | IndentIn(); 39 | Indent(); 40 | CommaNL(); 41 | jsonWriter.Write("\"name\": \"" + id + "\""); 42 | if (cameraName != null) 43 | { 44 | CommaNL(); 45 | Indent(); 46 | jsonWriter.Write("\"camera\": \"" + cameraName + "\""); 47 | } 48 | else if (lightName != null) 49 | { 50 | CommaNL(); 51 | Indent(); 52 | jsonWriter.Write("\"light\": \"" + lightName + "\""); 53 | } 54 | else if (meshIndex != -1) 55 | { 56 | CommaNL(); 57 | Indent(); 58 | jsonWriter.Write("\"mesh\": " + meshIndex); 59 | } 60 | 61 | if (childrenNames != null && childrenNames.Count > 0) 62 | { 63 | CommaNL(); 64 | Indent(); jsonWriter.Write("\"children\": [\n"); 65 | IndentIn(); 66 | foreach (string ch in childrenNames) 67 | { 68 | CommaNL(); 69 | Indent(); jsonWriter.Write(GlTF_Writer.nodeNames.IndexOf(ch)); 70 | } 71 | jsonWriter.WriteLine(); 72 | IndentOut(); 73 | Indent(); jsonWriter.Write("]"); 74 | } 75 | 76 | if (matrix != null) 77 | { 78 | CommaNL(); 79 | matrix.Write(); 80 | } 81 | else 82 | { 83 | if (translation != null && (translation.items[0] != 0f || translation.items[1] != 0f || translation.items[2] != 0f)) 84 | { 85 | CommaNL(); 86 | translation.Write(); 87 | } 88 | if (scale != null && (scale.items[0] != 1f || scale.items[1] != 1f || scale.items[2] != 1f)) 89 | { 90 | CommaNL(); 91 | scale.Write(); 92 | } 93 | if (rotation != null && (rotation.items[0] != 0f || rotation.items[1] != 0f || rotation.items[2] != 0f || rotation.items[3] != 0f)) 94 | { 95 | CommaNL(); 96 | rotation.Write(); 97 | } 98 | } 99 | jsonWriter.Write("\n"); 100 | 101 | if (skinIndex > -1) 102 | { 103 | CommaNL(); 104 | Indent(); jsonWriter.Write("\"skin\": " + skinIndex + "\n"); 105 | } 106 | 107 | IndentOut(); 108 | Indent(); jsonWriter.Write("}"); 109 | } 110 | } 111 | } 112 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Orthographic.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Orthographic : GlTF_Camera 8 | { 9 | public float xmag; 10 | public float ymag; 11 | public float zfar; 12 | public float znear; 13 | public GlTF_Orthographic() { type = "orthographic"; } 14 | public override void Write() 15 | { 16 | } 17 | } 18 | } 19 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Perspective.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Perspective : GlTF_Camera 8 | { 9 | public float aspect_ratio; 10 | public float yfov;//": 37.8492, 11 | public float zfar;//": 100, 12 | public float znear;//": 0.01 13 | public GlTF_Perspective() { type = "perspective"; } 14 | public override void Write() 15 | { 16 | /* 17 | "camera_0": { 18 | "perspective": { 19 | "yfov": 45, 20 | "zfar": 3162.76, 21 | "znear": 12.651 22 | }, 23 | "type": "perspective" 24 | } 25 | */ 26 | Indent(); jsonWriter.Write("{\n"); 27 | IndentIn(); 28 | Indent(); jsonWriter.Write("\"perspective\": {\n"); 29 | IndentIn(); 30 | Indent(); jsonWriter.Write("\"aspect_ratio\": " + aspect_ratio.ToString() + ",\n"); 31 | Indent(); jsonWriter.Write("\"yfov\": " + yfov.ToString() + ",\n"); 32 | Indent(); jsonWriter.Write("\"zfar\": " + zfar.ToString() + ",\n"); 33 | Indent(); jsonWriter.Write("\"znear\": " + znear.ToString() + ",\n"); 34 | Indent(); jsonWriter.Write("\"name\": \"" + name + "\"\n"); 35 | IndentOut(); 36 | Indent(); jsonWriter.Write("},\n"); 37 | Indent(); jsonWriter.Write("\"type\": \"perspective\"\n"); 38 | IndentOut(); 39 | Indent(); jsonWriter.Write("}"); 40 | } 41 | } 42 | } 43 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_PointLight.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_PointLight : GlTF_Light 8 | { 9 | public float constantAttenuation = 1f; 10 | public float linearAttenuation = 0f; 11 | public float quadraticAttenuation = 0f; 12 | 13 | public GlTF_PointLight() { type = "point"; } 14 | 15 | public override void Write() 16 | { 17 | color.Write(); 18 | Indent(); jsonWriter.Write("\"constantAttentuation\": " + constantAttenuation); 19 | Indent(); jsonWriter.Write("\"linearAttenuation\": " + linearAttenuation); 20 | Indent(); jsonWriter.Write("\"quadraticAttenuation\": " + quadraticAttenuation); 21 | jsonWriter.Write("}"); 22 | } 23 | } 24 | } 25 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Primitive.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Primitive : GlTF_Writer 8 | { 9 | public GlTF_Attributes attributes = new GlTF_Attributes(); 10 | public GlTF_Accessor indices; 11 | public int materialIndex; 12 | public int primitive = 4; 13 | public int semantics = 4; 14 | public int index = 0; 15 | 16 | public static string GetNameFromObject(Object o, int index) 17 | { 18 | return "primitive_" + index + "_" + GlTF_Writer.GetNameFromObject(o, true); 19 | } 20 | 21 | public void Populate(Mesh m) 22 | { 23 | // attributes.Populate (m); 24 | indices.Populate(m.GetTriangles(index), true); 25 | } 26 | 27 | public override void Write() 28 | { 29 | IndentIn(); 30 | CommaNL(); 31 | if (attributes != null) 32 | attributes.Write(); 33 | CommaNL(); 34 | Indent(); jsonWriter.Write("\"indices\": " + GlTF_Writer.accessors.IndexOf(indices) + ",\n"); 35 | Indent(); jsonWriter.Write("\"material\": " + materialIndex + ",\n"); 36 | Indent(); jsonWriter.Write("\"mode\": " + primitive + "\n"); 37 | // semantics 38 | IndentOut(); 39 | } 40 | } 41 | } 42 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Program.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | 6 | namespace Uinty2glTF 7 | { 8 | public class GlTF_Program : GlTF_Writer 9 | { 10 | public List attributes = new List(); 11 | public string vertexShader = ""; 12 | public string fragmentShader = ""; 13 | 14 | public static string GetNameFromObject(Object o) 15 | { 16 | return "program_" + GlTF_Writer.GetNameFromObject(o); 17 | } 18 | 19 | public override void Write() 20 | { 21 | Indent(); jsonWriter.Write("{\n"); 22 | IndentIn(); 23 | Indent(); jsonWriter.Write("\"attributes\": [\n"); 24 | IndentIn(); 25 | foreach (var a in attributes) 26 | { 27 | CommaNL(); 28 | Indent(); jsonWriter.Write("\"" + a + "\""); 29 | } 30 | jsonWriter.Write("\n"); 31 | IndentOut(); 32 | Indent(); jsonWriter.Write("],\n"); 33 | Indent(); jsonWriter.Write("\"vertexShader\": \"" + vertexShader + "\",\n"); 34 | Indent(); jsonWriter.Write("\"fragmentShader\": \"" + fragmentShader + "\"\n"); 35 | IndentOut(); 36 | Indent(); jsonWriter.Write("}"); 37 | } 38 | } 39 | } 40 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Rotation.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Rotation : GlTF_FloatArray4 8 | { 9 | public GlTF_Rotation(Quaternion q) 10 | { 11 | if (convertRightHanded) 12 | convertQuatLeftToRightHandedness(ref q); 13 | 14 | name = "rotation"; 15 | minItems = 4; 16 | maxItems = 4; 17 | items = new float[] { q.x, q.y, q.z, q.w }; 18 | } 19 | /* 20 | public override void Write() 21 | { 22 | Indent(); jsonWriter.Write ("\"rotation\": [ "); 23 | WriteVals(); 24 | jsonWriter.Write ("]"); 25 | } 26 | */ 27 | } 28 | } 29 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Sampler.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Sampler : GlTF_Writer 8 | { 9 | public enum MagFilter 10 | { 11 | NEAREST = 9728, 12 | LINEAR = 9729 13 | } 14 | 15 | public enum MinFilter 16 | { 17 | NEAREST = 9728, 18 | LINEAR = 9729, 19 | NEAREST_MIPMAP_NEAREST = 9984, 20 | LINEAR_MIPMAP_NEAREST = 9985, 21 | NEAREST_MIPMAP_LINEAR = 9986, 22 | LINEAR_MIPMAP_LINEAR = 9987 23 | } 24 | 25 | public enum Wrap 26 | { 27 | CLAMP_TO_EDGE = 33071, 28 | MIRRORED_REPEAT = 33648, 29 | REPEAT = 10497 30 | } 31 | 32 | MagFilter magFilter = MagFilter.LINEAR; 33 | MinFilter minFilter = MinFilter.LINEAR; 34 | Wrap wrap = Wrap.REPEAT; 35 | 36 | public static string GetNameFromObject(Texture tex) 37 | { 38 | int fm = (int)tex.filterMode; 39 | int w = (int)tex.wrapMode; 40 | var n = "sampler_" + fm + "_" + w; 41 | Texture2D t = tex as Texture2D; 42 | if (t != null) 43 | { 44 | if (t.mipmapCount > 0) 45 | { 46 | n += "_m"; 47 | } 48 | } 49 | return n; 50 | } 51 | 52 | public GlTF_Sampler(Texture tex) 53 | { 54 | bool hasMipMap = false; 55 | Texture2D t = tex as Texture2D; 56 | if (t != null) 57 | { 58 | if (t.mipmapCount > 0) 59 | { 60 | hasMipMap = true; 61 | } 62 | } 63 | 64 | switch (tex.filterMode) 65 | { 66 | case FilterMode.Point: 67 | { 68 | magFilter = MagFilter.NEAREST; 69 | if (hasMipMap) 70 | { 71 | minFilter = MinFilter.NEAREST_MIPMAP_NEAREST; 72 | } 73 | else 74 | { 75 | minFilter = MinFilter.NEAREST; 76 | } 77 | } 78 | break; 79 | 80 | case FilterMode.Bilinear: 81 | { 82 | magFilter = MagFilter.LINEAR; 83 | if (hasMipMap) 84 | { 85 | minFilter = MinFilter.LINEAR_MIPMAP_NEAREST; 86 | } 87 | else 88 | { 89 | minFilter = MinFilter.LINEAR; 90 | } 91 | } 92 | break; 93 | 94 | case FilterMode.Trilinear: 95 | { 96 | magFilter = MagFilter.LINEAR; 97 | if (hasMipMap) 98 | { 99 | minFilter = MinFilter.LINEAR; 100 | } 101 | else 102 | { 103 | minFilter = MinFilter.LINEAR_MIPMAP_LINEAR; 104 | } 105 | } 106 | break; 107 | } 108 | 109 | switch (tex.wrapMode) 110 | { 111 | case TextureWrapMode.Clamp: 112 | { 113 | wrap = Wrap.CLAMP_TO_EDGE; 114 | } 115 | break; 116 | 117 | case TextureWrapMode.Repeat: 118 | { 119 | wrap = Wrap.REPEAT; 120 | } 121 | break; 122 | } 123 | } 124 | 125 | public override void Write() 126 | { 127 | Indent(); jsonWriter.Write("{\n"); 128 | IndentIn(); 129 | Indent(); jsonWriter.Write("\"magFilter\": " + (int)magFilter + ",\n"); 130 | Indent(); jsonWriter.Write("\"minFilter\": " + (int)minFilter + ",\n"); 131 | Indent(); jsonWriter.Write("\"wrapS\": " + (int)wrap + ",\n"); 132 | Indent(); jsonWriter.Write("\"wrapT\": " + (int)wrap + "\n"); 133 | IndentOut(); 134 | Indent(); jsonWriter.Write("}"); 135 | } 136 | } 137 | } 138 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Scale.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Scale : GlTF_Vector3 8 | { 9 | public GlTF_Scale() { items = new float[] { 1f, 1f, 1f }; } 10 | public GlTF_Scale(Vector3 v) { items = new float[] { v.x, v.y, v.z }; } 11 | public override void Write() 12 | { 13 | Indent(); jsonWriter.Write("\"scale\": [ "); 14 | WriteVals(); 15 | jsonWriter.Write("]"); 16 | } 17 | } 18 | } 19 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Shader.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Shader : GlTF_Writer 8 | { 9 | public enum Type 10 | { 11 | Vertex, 12 | Fragment 13 | } 14 | 15 | public Type type = Type.Vertex; 16 | public string uri = ""; 17 | 18 | public static string GetNameFromObject(Object o, Type type) 19 | { 20 | var name = GlTF_Writer.GetNameFromObject(o); 21 | var typeName = type == Type.Vertex ? "vertex" : "fragment"; 22 | return typeName + "_" + name; 23 | } 24 | 25 | public override void Write() 26 | { 27 | Indent(); jsonWriter.Write("\"" + name + "\": {\n"); 28 | IndentIn(); 29 | Indent(); jsonWriter.Write("\"type\": " + TypeStr() + ",\n"); 30 | Indent(); jsonWriter.Write("\"uri\": \"" + uri + "\"\n"); 31 | IndentOut(); 32 | Indent(); jsonWriter.Write("}"); 33 | } 34 | 35 | int TypeStr() 36 | { 37 | if (type == Type.Vertex) 38 | { 39 | return 35633; 40 | } 41 | else if (type == Type.Fragment) 42 | { 43 | return 35632; 44 | } 45 | 46 | return 0; 47 | } 48 | } 49 | } 50 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Skin.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | 6 | namespace Uinty2glTF 7 | { 8 | public class GlTF_Skin : GlTF_Writer 9 | { 10 | public int invBindMatricesAccessorIndex; 11 | public List joints; 12 | public Transform mesh; 13 | 14 | public GlTF_Skin() { } 15 | 16 | public static string GetNameFromObject(Object o) 17 | { 18 | //return "skin_" + GlTF_Writer.GetNameFromObject(o, true); 19 | return GlTF_Writer.GetNameFromObject(o, true); 20 | } 21 | 22 | public void Populate(Transform m, ref GlTF_Accessor invBindMatricesAccessor, int invBindAccessorIndex) 23 | { 24 | SkinnedMeshRenderer skinMesh = m.GetComponent(); 25 | if (!skinMesh) 26 | return; 27 | 28 | // Populate bind poses. From https://docs.unity3d.com/ScriptReference/Mesh-bindposes.html: 29 | // The bind pose is bone's inverse transformation matrix 30 | // In this case we also make this matrix relative to the root 31 | // So that we can move the root game object around freely 32 | 33 | joints = new List(); 34 | //Collect all bones from skin object. Order should be kept here since bones are referenced in the mesh 35 | foreach (Transform t in skinMesh.bones) 36 | { 37 | joints.Add(t); 38 | } 39 | 40 | Matrix4x4[] invBindMatrices = new Matrix4x4[joints.Count]; 41 | for (int i = 0; i < skinMesh.bones.Length; ++i) 42 | { 43 | // Generates inverseWorldMatrix in right-handed coordinate system 44 | Matrix4x4 invBind = skinMesh.sharedMesh.bindposes[i]; 45 | convertMatrixLeftToRightHandedness(ref invBind); 46 | invBindMatrices[i] = invBind; 47 | } 48 | 49 | invBindMatricesAccessor.Populate(invBindMatrices, m); 50 | invBindMatricesAccessorIndex = invBindAccessorIndex; 51 | } 52 | 53 | public override void Write() 54 | { 55 | Indent(); jsonWriter.Write("{\n"); 56 | IndentIn(); 57 | 58 | Indent(); jsonWriter.Write("\"inverseBindMatrices\": " + invBindMatricesAccessorIndex + ",\n"); 59 | Indent(); jsonWriter.Write("\"joints\": [\n"); 60 | 61 | IndentIn(); 62 | foreach (Transform j in joints) 63 | { 64 | CommaNL(); 65 | Indent(); jsonWriter.Write("" + GlTF_Writer.nodeNames.IndexOf(GlTF_Node.GetNameFromObject(j))); 66 | } 67 | 68 | IndentOut(); 69 | jsonWriter.WriteLine(); 70 | Indent(); jsonWriter.Write("],\n"); 71 | 72 | Indent(); jsonWriter.Write("\"name\": \"" + name + "\"\n"); 73 | 74 | IndentOut(); 75 | Indent(); jsonWriter.Write("}"); 76 | } 77 | } 78 | } 79 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_SpotLight.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_SpotLight : GlTF_Light 8 | { 9 | public float constantAttenuation = 1f; 10 | public float fallOffAngle = 3.1415927f; 11 | public float fallOffExponent = 0f; 12 | public float linearAttenuation = 0f; 13 | public float quadraticAttenuation = 0f; 14 | 15 | public GlTF_SpotLight() { type = "spot"; } 16 | 17 | public override void Write() 18 | { 19 | color.Write(); 20 | Indent(); jsonWriter.Write("\"constantAttentuation\": " + constantAttenuation); 21 | Indent(); jsonWriter.Write("\"fallOffAngle\": " + fallOffAngle); 22 | Indent(); jsonWriter.Write("\"fallOffExponent\": " + fallOffExponent); 23 | Indent(); jsonWriter.Write("\"linearAttenuation\": " + linearAttenuation); 24 | Indent(); jsonWriter.Write("\"quadraticAttenuation\": " + quadraticAttenuation); 25 | jsonWriter.Write("}"); 26 | } 27 | } 28 | } 29 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Target.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Target : GlTF_Writer 8 | { 9 | public string path; 10 | public override void Write() 11 | { 12 | Indent(); jsonWriter.Write("\"" + "target" + "\": {\n"); 13 | IndentIn(); 14 | Indent(); jsonWriter.Write("\"node\": " + GlTF_Writer.nodeNames.IndexOf(id) + ",\n"); 15 | Indent(); jsonWriter.Write("\"path\": \"" + path + "\"\n"); 16 | IndentOut(); 17 | Indent(); jsonWriter.Write("}"); 18 | } 19 | } 20 | } 21 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Technique.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | 6 | namespace Uinty2glTF 7 | { 8 | public class GlTF_Technique : GlTF_Writer 9 | { 10 | public enum Type 11 | { 12 | FLOAT = 5126, 13 | FLOAT_VEC2 = 35664, 14 | FLOAT_VEC3 = 35665, 15 | FLOAT_VEC4 = 35666, 16 | FLOAT_MAT3 = 35675, 17 | FLOAT_MAT4 = 35676, 18 | SAMPLER_2D = 35678 19 | } 20 | 21 | public enum Semantic 22 | { 23 | UNKNOWN, 24 | POSITION, 25 | NORMAL, 26 | TEXCOORD_0, 27 | TEXCOORD_1, 28 | TEXCOORD_2, 29 | TEXCOORD_3, 30 | MODELVIEW, 31 | PROJECTION, 32 | MODELVIEWINVERSETRANSPOSE 33 | } 34 | 35 | public class Parameter 36 | { 37 | public string name; 38 | public Type type; 39 | public Semantic semantic = Semantic.UNKNOWN; 40 | } 41 | 42 | public class Attribute 43 | { 44 | public string name; 45 | public string param; 46 | } 47 | 48 | public class Uniform 49 | { 50 | public string name; 51 | public string param; 52 | } 53 | 54 | public string program; 55 | public List attributes = new List(); 56 | public List parameters = new List(); 57 | public List uniforms = new List(); 58 | 59 | public static string GetNameFromObject(Object o) 60 | { 61 | return "technique_" + GlTF_Writer.GetNameFromObject(o); 62 | } 63 | 64 | public void AddDefaultUniforms() 65 | { 66 | var tParam = new Parameter(); 67 | tParam.name = "modelViewMatrix"; 68 | tParam.type = Type.FLOAT_MAT4; 69 | tParam.semantic = Semantic.MODELVIEW; 70 | parameters.Add(tParam); 71 | var uni = new Uniform(); 72 | uni.name = "u_modelViewMatrix"; 73 | uni.param = tParam.name; 74 | uniforms.Add(uni); 75 | 76 | tParam = new Parameter(); 77 | tParam.name = "projectionMatrix"; 78 | tParam.type = Type.FLOAT_MAT4; 79 | tParam.semantic = Semantic.PROJECTION; 80 | parameters.Add(tParam); 81 | uni = new Uniform(); 82 | uni.name = "u_projectionMatrix"; 83 | uni.param = tParam.name; 84 | uniforms.Add(uni); 85 | 86 | tParam = new Parameter(); 87 | tParam.name = "normalMatrix"; 88 | tParam.type = Type.FLOAT_MAT3; 89 | tParam.semantic = Semantic.MODELVIEWINVERSETRANSPOSE; 90 | parameters.Add(tParam); 91 | uni = new Uniform(); 92 | uni.name = "u_normalMatrix"; 93 | uni.param = tParam.name; 94 | uniforms.Add(uni); 95 | } 96 | 97 | public override void Write() 98 | { 99 | Indent(); jsonWriter.Write("\"" + name + "\": {\n"); 100 | IndentIn(); 101 | Indent(); jsonWriter.Write("\"program\": \"" + program + "\",\n"); 102 | Indent(); jsonWriter.Write("\"parameters\": {\n"); 103 | IndentIn(); 104 | foreach (var p in parameters) 105 | { 106 | CommaNL(); 107 | Indent(); jsonWriter.Write("\"" + p.name + "\": {\n"); 108 | IndentIn(); 109 | Indent(); jsonWriter.Write("\"type\": " + (int)p.type); 110 | if (p.semantic != Semantic.UNKNOWN) 111 | { 112 | jsonWriter.Write(",\n"); 113 | Indent(); jsonWriter.Write("\"semantic\": \"" + p.semantic + "\"\n"); 114 | } 115 | else 116 | { 117 | jsonWriter.Write("\n"); 118 | } 119 | IndentOut(); 120 | Indent(); jsonWriter.Write("}"); 121 | } 122 | jsonWriter.Write("\n"); 123 | IndentOut(); 124 | Indent(); jsonWriter.Write("},\n"); 125 | 126 | Indent(); jsonWriter.Write("\"attributes\": {\n"); 127 | IndentIn(); 128 | foreach (var a in attributes) 129 | { 130 | CommaNL(); 131 | Indent(); jsonWriter.Write("\"" + a.name + "\": \"" + a.param + "\""); 132 | } 133 | jsonWriter.Write("\n"); 134 | IndentOut(); 135 | Indent(); jsonWriter.Write("},\n"); 136 | 137 | Indent(); jsonWriter.Write("\"uniforms\": {\n"); 138 | IndentIn(); 139 | foreach (var u in uniforms) 140 | { 141 | CommaNL(); 142 | Indent(); jsonWriter.Write("\"" + u.name + "\": \"" + u.param + "\""); 143 | } 144 | jsonWriter.Write("\n"); 145 | IndentOut(); 146 | Indent(); jsonWriter.Write("}\n"); 147 | IndentOut(); 148 | Indent(); jsonWriter.Write("}"); 149 | } 150 | } 151 | } 152 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Texture.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Texture : GlTF_Writer 8 | { 9 | /* 10 | "texture_O21_jpg": { 11 | "format": 6408, 12 | "internalFormat": 6408, 13 | "sampler": "sampler_0", 14 | "source": "O21_jpg", 15 | "target": 3553, 16 | "type": 5121 17 | }, 18 | */ 19 | public int samplerIndex; 20 | public int source; 21 | public bool flipy = true; 22 | 23 | public static string GetNameFromObject(Object o) 24 | { 25 | return "texture_" + GlTF_Writer.GetNameFromObject(o, true); 26 | } 27 | 28 | public override void Write() 29 | { 30 | Indent(); jsonWriter.Write("{\n"); 31 | IndentIn(); 32 | 33 | writeExtras(); 34 | 35 | Indent(); jsonWriter.Write("\"sampler\": " + samplerIndex + ",\n"); 36 | Indent(); jsonWriter.Write("\"source\": " + source + "\n"); 37 | IndentOut(); 38 | Indent(); jsonWriter.Write("}"); 39 | } 40 | } 41 | } 42 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Translation.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Translation : GlTF_Vector3 8 | { 9 | public GlTF_Translation(Vector3 v) 10 | { 11 | if (convertRightHanded) 12 | convertVector3LeftToRightHandedness(ref v); 13 | 14 | items = new float[] { v.x, v.y, v.z }; 15 | } 16 | public override void Write() 17 | { 18 | Indent(); jsonWriter.Write("\"translation\": [ "); 19 | WriteVals(); 20 | jsonWriter.Write("]"); 21 | } 22 | } 23 | } 24 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/GlTF_Vector3.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | namespace Uinty2glTF 6 | { 7 | public class GlTF_Vector3 : GlTF_FloatArray 8 | { 9 | public GlTF_Vector3() { minItems = 3; maxItems = 3; items = new float[] { 0f, 0f, 0f }; } 10 | public GlTF_Vector3(Vector3 v) { minItems = 3; maxItems = 3; items = new float[] { v.x, v.y, v.z }; } 11 | } 12 | } 13 | #endif -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/JObjectExtensions.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace Uinty2glTF 8 | { 9 | internal static class JObjectExtensions 10 | { 11 | public static void SetValue(this JObject obj, string propertyName, T value, T defaultValue) 12 | { 13 | if (value.Equals(defaultValue)) 14 | { 15 | obj.Remove(propertyName); 16 | } 17 | else 18 | { 19 | obj[propertyName] = JToken.FromObject(value); 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/MimeType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace Uinty2glTF 8 | { 9 | internal class MimeType 10 | { 11 | public static string ToFileExtension(string mimeType) 12 | { 13 | switch (mimeType) 14 | { 15 | case "image/png": 16 | return ".png"; 17 | case "image/jpeg": 18 | return ".jpg"; 19 | case "image/vnd-ms.dds": 20 | return ".dds"; 21 | } 22 | 23 | throw new Exception(string.Format("不支持的mime类型: {0}", mimeType)); 24 | } 25 | 26 | public static string FromFileExtension(string fileExtension) 27 | { 28 | switch (fileExtension.ToLower()) 29 | { 30 | case ".png": 31 | return "image/png"; 32 | case ".jpg": 33 | case ".jpeg": 34 | return "image/jpeg"; 35 | case ".dds": 36 | return "image/vnd-ms.dds"; 37 | } 38 | 39 | throw new Exception(string.Format("不支持的文件扩展名:{0}", fileExtension)); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/Packer.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Linq; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Text; 7 | 8 | namespace Uinty2glTF 9 | { 10 | internal class Packer 11 | { 12 | public static void Pack(string inputFilePath, string outputFilePath) 13 | { 14 | var inputDirectoryPath = Path.GetDirectoryName(inputFilePath);//文件根目录 15 | 16 | JObject json; 17 | using (var jsonStream = File.OpenRead(inputFilePath)) 18 | using (var jsonStreamReader = new StreamReader(jsonStream)) 19 | using (var jsonTextReader = new JsonTextReader(jsonStreamReader)) 20 | { 21 | json = (JObject)JToken.ReadFrom(jsonTextReader); 22 | } 23 | 24 | var position = 0; 25 | 26 | List views = new List(); 27 | 28 | var buffers = (JArray)json["buffers"]; 29 | var bufferViews = (JArray)json["bufferViews"]; 30 | var images = (JArray)json["images"]; 31 | 32 | if (buffers != null) 33 | { 34 | for (var index = buffers.Count - 1; index >= 0; index--) 35 | { 36 | var buffer = (JObject)buffers[index]; 37 | var uri = (string)buffer["uri"]; 38 | if (uri != null && !Tools.IsBase64(uri)) 39 | { 40 | foreach (JObject bufferView in bufferViews) 41 | { 42 | var bufferIndex = (int)bufferView["buffer"]; 43 | if (bufferIndex == index) 44 | { 45 | bufferView["buffer"] = -1; 46 | 47 | var byteOffset = (int?)bufferView["byteOffset"] ?? 0; 48 | bufferView.SetValue("byteOffset", position + byteOffset, 0); 49 | } 50 | } 51 | 52 | var filePath = Path.Combine(inputDirectoryPath, uri); 53 | 54 | views.Add(filePath); 55 | var fileLength = Tools.GetFileLength(filePath); 56 | 57 | position += fileLength; 58 | position = Tools.Align(position); 59 | 60 | buffers.RemoveAt(index); 61 | } 62 | } 63 | } 64 | 65 | if (images != null) 66 | { 67 | foreach (JObject image in images) 68 | { 69 | var uri = (string)image["uri"]; 70 | if (uri != null && !Tools.IsBase64(uri)) 71 | { 72 | var filePath = Path.Combine(inputDirectoryPath, uri); 73 | views.Add(filePath); 74 | var fileLength = Tools.GetFileLength(filePath); 75 | 76 | image.Remove("uri"); 77 | image["bufferView"] = bufferViews.Count; 78 | image["mimeType"] = MimeType.FromFileExtension(Path.GetExtension(uri)); 79 | 80 | position = Tools.Align(position); 81 | 82 | JObject bufferView=new JObject(); 83 | bufferView["buffer"]=-1; 84 | bufferView["byteLength"] = fileLength; 85 | bufferView.SetValue("byteOffset", position, 0); 86 | bufferViews.Add(bufferView); 87 | 88 | position += fileLength; 89 | } 90 | } 91 | } 92 | 93 | if (views.Count != 0) 94 | { 95 | if (buffers == null) 96 | { 97 | json["buffers"] = new JArray(); 98 | } 99 | 100 | JObject item = new JObject(); 101 | item["byteLength"] = position; 102 | buffers.Insert(0, item); 103 | 104 | foreach (var bufferView in bufferViews) 105 | { 106 | var bufferIndex = (int)bufferView["buffer"]; 107 | bufferView["buffer"] = bufferIndex + 1; 108 | } 109 | } 110 | 111 | using (var fileStream = File.Create(outputFilePath)) 112 | using (var binaryWriter = new BinaryWriter(fileStream)) 113 | { 114 | binaryWriter.Write(Binary.Magic); 115 | binaryWriter.Write(Binary.Version); 116 | 117 | var chunksPosition = binaryWriter.BaseStream.Position; 118 | 119 | binaryWriter.Write(0U); // length 120 | 121 | var jsonChunkPosition = binaryWriter.BaseStream.Position; 122 | 123 | binaryWriter.Write(0U); // json chunk length 124 | binaryWriter.Write(Binary.ChunkFormatJson); 125 | 126 | var streamWriter = new StreamWriter(binaryWriter.BaseStream, new UTF8Encoding(false, true), 1024); 127 | var jsonTextWriter = new JsonTextWriter(streamWriter); 128 | json.WriteTo(jsonTextWriter); 129 | jsonTextWriter.Flush(); 130 | 131 | binaryWriter.BaseStream.Align(0x20); 132 | var jsonChunkLength = checked((uint)(binaryWriter.BaseStream.Length - jsonChunkPosition)) - Binary.ChunkHeaderLength; 133 | 134 | binaryWriter.BaseStream.Seek(jsonChunkPosition, SeekOrigin.Begin); 135 | binaryWriter.Write(jsonChunkLength); 136 | 137 | if (views.Count != 0) 138 | { 139 | binaryWriter.BaseStream.Seek(0, SeekOrigin.End); 140 | var binChunkPosition = binaryWriter.BaseStream.Position; 141 | 142 | binaryWriter.Write(0); // bin chunk length 143 | binaryWriter.Write(Binary.ChunkFormatBin); 144 | 145 | foreach (var fileName in views) 146 | { 147 | var viewBytes = File.ReadAllBytes(fileName); 148 | binaryWriter.BaseStream.Align(); 149 | binaryWriter.Write(viewBytes); 150 | } 151 | 152 | binaryWriter.BaseStream.Align(0x20); 153 | var binChunkLength = checked((uint)(binaryWriter.BaseStream.Length - binChunkPosition)) - Binary.ChunkHeaderLength; 154 | 155 | binaryWriter.BaseStream.Seek(binChunkPosition, SeekOrigin.Begin); 156 | binaryWriter.Write(binChunkLength); 157 | } 158 | 159 | var length = checked((uint)binaryWriter.BaseStream.Length); 160 | 161 | binaryWriter.BaseStream.Seek(chunksPosition, SeekOrigin.Begin); 162 | binaryWriter.Write(length); 163 | 164 | jsonTextWriter.Close(); 165 | streamWriter.Dispose(); 166 | } 167 | } 168 | } 169 | } -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/PinYinConverter.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | using Microsoft.International.Converters.PinYinConverter; 3 | 4 | namespace Uinty2glTF 5 | { 6 | public static class PinYinConverter 7 | { 8 | public static string GetPinYin(string source) 9 | { 10 | string value = ""; 11 | foreach (char c in source) 12 | { 13 | if (ChineseChar.IsValidChar(c)) 14 | { 15 | ChineseChar chineseChar = new ChineseChar(c); 16 | value += Regex.Replace(chineseChar.Pinyins[0], @"\d", "").ToLower(); 17 | } 18 | else 19 | { 20 | value += c; 21 | } 22 | } 23 | return value; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/Preset.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using SimpleJSON; 6 | 7 | namespace Uinty2glTF 8 | { 9 | public class Preset 10 | { 11 | public class Shader 12 | { 13 | public string vertexShader; 14 | public string fragmentShader; 15 | } 16 | 17 | public Dictionary shaderMap = new Dictionary(); 18 | 19 | const string DEFAULT_VERTEX_SHADER = "DefaultVS.glsl"; 20 | const string DEFAULT_FRAGMENT_SHADER = "DefaultFS.glsl"; 21 | 22 | public string GetVertexShader(string shaderName) 23 | { 24 | if (shaderMap.ContainsKey(shaderName)) 25 | { 26 | var s = shaderMap[shaderName]; 27 | return s.vertexShader; 28 | } 29 | return DEFAULT_VERTEX_SHADER; 30 | } 31 | 32 | public string GetFragmentShader(string shaderName) 33 | { 34 | if (shaderMap.ContainsKey(shaderName)) 35 | { 36 | var s = shaderMap[shaderName]; 37 | return s.fragmentShader; 38 | } 39 | return DEFAULT_FRAGMENT_SHADER; 40 | } 41 | 42 | public void Load(string path) 43 | { 44 | var text = File.ReadAllText(path); 45 | var obj = JSON.Parse(text); 46 | var sm = obj["ShaderMap"]; 47 | 48 | shaderMap.Clear(); 49 | foreach (var smc in sm.AsObject.Dict) 50 | { 51 | Shader shader = new Shader(); 52 | shader.vertexShader = smc.Value["shaders"]["vertexShader"]; 53 | shader.fragmentShader = smc.Value["shaders"]["fragmentShader"]; 54 | shaderMap[smc.Key] = shader; 55 | } 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/StreamExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace Uinty2glTF 8 | { 9 | internal static class StreamExtensions 10 | { 11 | public static void Align(this Stream stream, byte pad = 0) 12 | { 13 | var count = 3 - ((stream.Position - 1) & 3); 14 | while (count != 0) 15 | { 16 | stream.WriteByte(pad); 17 | count--; 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/Tools.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace Uinty2glTF 8 | { 9 | internal static class Tools 10 | { 11 | public static int GetFileLength(string path) 12 | { 13 | return checked((int)new FileInfo(path).Length); 14 | } 15 | 16 | public static int Align(int value) 17 | { 18 | return value + 3 - ((value - 1) & 3); 19 | } 20 | 21 | public static bool IsBase64(string uri) 22 | { 23 | return uri.StartsWith("data:"); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Assets/Unity2glTF/Scripts/WebServer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Net; 4 | using System.Text; 5 | using System.Web; 6 | using System.Collections.Generic; 7 | 8 | namespace Uinty2glTF 9 | { 10 | public class WebServer 11 | { 12 | private static Dictionary mimeTypes = new Dictionary(); 13 | static WebServer() 14 | { 15 | mimeTypes.Add(".html", "text/html"); 16 | mimeTypes.Add(".htm", "text/html"); 17 | mimeTypes.Add(".ico", "image/vnd.microsoft.icon"); 18 | mimeTypes.Add(".js", "text/javascript"); 19 | mimeTypes.Add(".jsx", "text/javascript"); 20 | mimeTypes.Add(".png", "image/png"); 21 | mimeTypes.Add(".svg", "image/svg+xml"); 22 | mimeTypes.Add(".woff", "font/woff"); 23 | mimeTypes.Add(".css", "text/css"); 24 | } 25 | private static string GetMime(string ext) 26 | { 27 | if (mimeTypes.ContainsKey(ext)) return mimeTypes[ext]; 28 | return "application/octet-stream"; 29 | } 30 | 31 | private HttpListener listener; 32 | public int Port { get; set; } 33 | public string Folder { get; set; } 34 | public string Prefix 35 | { 36 | get { return string.Format("http://localhost:{0}/", Port); } 37 | } 38 | public WebServer(int port, string folder) 39 | { 40 | Port = port; 41 | Folder = folder; 42 | try 43 | { 44 | listener = new HttpListener(); 45 | listener.Prefixes.Add(Prefix); 46 | listener.Start(); 47 | listener.BeginGetContext(onRequest, null); 48 | } 49 | catch { } 50 | } 51 | private void onRequest(IAsyncResult ar) 52 | { 53 | //继续监听 54 | listener.BeginGetContext(onRequest, null); 55 | 56 | HttpListenerContext context = listener.EndGetContext(ar); 57 | context.Response.AddHeader("Cache-Control", "no-cache"); 58 | context.Response.AppendHeader("Access-Control-Allow-Origin", "*");//支持跨域访问 59 | try 60 | { 61 | var path = Path.Combine(Folder, UrlDecode(context.Request.Url.PathAndQuery.Substring(1))); 62 | var questionMarkIndex = path.IndexOf("?"); 63 | if (questionMarkIndex != -1) 64 | { 65 | path = path.Substring(0, questionMarkIndex); 66 | } 67 | //var hashIndex = path.IndexOf("#"); 68 | //if (hashIndex != -1) 69 | //{ 70 | // path = path.Substring(0, hashIndex); 71 | //} 72 | string ext = Path.GetExtension(path).ToLower(); 73 | if (string.IsNullOrEmpty(ext)) 74 | { 75 | ext = ".html"; 76 | path += "index.html"; 77 | } 78 | context.Response.ContentType = GetMime(ext); 79 | byte[] buffer = File.ReadAllBytes(path); 80 | context.Response.ContentLength64 = buffer.Length; 81 | context.Response.OutputStream.Write(buffer, 0, buffer.Length); 82 | context.Response.OutputStream.Close(); 83 | } 84 | catch 85 | { 86 | context.Response.StatusCode = 404; 87 | context.Response.Close(); 88 | } 89 | } 90 | private string UrlDecode(string value) 91 | { 92 | byte[] bytes = Encoding.UTF8.GetBytes(value); 93 | int count = bytes.Length; 94 | int decodedBytesCount = 0; 95 | byte[] decodedBytes = new byte[count]; 96 | 97 | for (int i = 0; i < count; i++) 98 | { 99 | int pos = i; 100 | byte b = bytes[pos]; 101 | 102 | if (b == '+') 103 | { 104 | b = (byte)' '; 105 | } 106 | else if (b == '%' && i < count - 2) 107 | { 108 | int h1 = HexToInt((char)bytes[pos + 1]); 109 | int h2 = HexToInt((char)bytes[pos + 2]); 110 | 111 | if (h1 >= 0 && h2 >= 0) 112 | { // valid 2 hex chars 113 | b = (byte)((h1 << 4) | h2); 114 | i += 2; 115 | } 116 | } 117 | 118 | decodedBytes[decodedBytesCount++] = b; 119 | } 120 | 121 | if (decodedBytesCount < decodedBytes.Length) 122 | { 123 | byte[] newDecodedBytes = new byte[decodedBytesCount]; 124 | Array.Copy(decodedBytes, newDecodedBytes, decodedBytesCount); 125 | decodedBytes = newDecodedBytes; 126 | } 127 | 128 | return Encoding.UTF8.GetString(decodedBytes); 129 | } 130 | private int HexToInt(char h) 131 | { 132 | return (h >= '0' && h <= '9') ? h - '0' : 133 | (h >= 'a' && h <= 'f') ? h - 'a' + 10 : 134 | (h >= 'A' && h <= 'F') ? h - 'A' + 10 : 135 | -1; 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /Assets/Unity2glTF/Unity2glTF.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 8 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0.44657844, g: 0.49641222, b: 0.57481694, a: 1} 42 | --- !u!157 &3 43 | LightmapSettings: 44 | m_ObjectHideFlags: 0 45 | serializedVersion: 11 46 | m_GIWorkflowMode: 0 47 | m_GISettings: 48 | serializedVersion: 2 49 | m_BounceScale: 1 50 | m_IndirectOutputScale: 1 51 | m_AlbedoBoost: 1 52 | m_TemporalCoherenceThreshold: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 1 56 | m_LightmapEditorSettings: 57 | serializedVersion: 9 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_TextureWidth: 1024 61 | m_TextureHeight: 1024 62 | m_AO: 0 63 | m_AOMaxDistance: 1 64 | m_CompAOExponent: 1 65 | m_CompAOExponentDirect: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 500 79 | m_PVRBounces: 2 80 | m_PVRFilterTypeDirect: 0 81 | m_PVRFilterTypeIndirect: 0 82 | m_PVRFilterTypeAO: 0 83 | m_PVRFilteringMode: 2 84 | m_PVRCulling: 1 85 | m_PVRFilteringGaussRadiusDirect: 1 86 | m_PVRFilteringGaussRadiusIndirect: 5 87 | m_PVRFilteringGaussRadiusAO: 2 88 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 89 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 90 | m_PVRFilteringAtrousPositionSigmaAO: 1 91 | m_ShowResolutionOverlay: 1 92 | m_LightingDataAsset: {fileID: 0} 93 | m_UseShadowmask: 1 94 | --- !u!196 &4 95 | NavMeshSettings: 96 | serializedVersion: 2 97 | m_ObjectHideFlags: 0 98 | m_BuildSettings: 99 | serializedVersion: 2 100 | agentTypeID: 0 101 | agentRadius: 0.5 102 | agentHeight: 2 103 | agentSlope: 45 104 | agentClimb: 0.4 105 | ledgeDropHeight: 0 106 | maxJumpAcrossDistance: 0 107 | minRegionArea: 2 108 | manualCellSize: 0 109 | cellSize: 0.16666667 110 | manualTileSize: 0 111 | tileSize: 256 112 | accuratePlacement: 0 113 | debug: 114 | m_Flags: 0 115 | m_NavMeshData: {fileID: 0} 116 | --- !u!1 &27967229 117 | GameObject: 118 | m_ObjectHideFlags: 0 119 | m_PrefabParentObject: {fileID: 0} 120 | m_PrefabInternal: {fileID: 0} 121 | serializedVersion: 5 122 | m_Component: 123 | - component: {fileID: 27967233} 124 | - component: {fileID: 27967232} 125 | - component: {fileID: 27967231} 126 | - component: {fileID: 27967230} 127 | m_Layer: 0 128 | m_Name: Camera 129 | m_TagString: Untagged 130 | m_Icon: {fileID: 0} 131 | m_NavMeshLayer: 0 132 | m_StaticEditorFlags: 0 133 | m_IsActive: 1 134 | --- !u!81 &27967230 135 | AudioListener: 136 | m_ObjectHideFlags: 0 137 | m_PrefabParentObject: {fileID: 0} 138 | m_PrefabInternal: {fileID: 0} 139 | m_GameObject: {fileID: 27967229} 140 | m_Enabled: 1 141 | --- !u!124 &27967231 142 | Behaviour: 143 | m_ObjectHideFlags: 0 144 | m_PrefabParentObject: {fileID: 0} 145 | m_PrefabInternal: {fileID: 0} 146 | m_GameObject: {fileID: 27967229} 147 | m_Enabled: 1 148 | --- !u!20 &27967232 149 | Camera: 150 | m_ObjectHideFlags: 0 151 | m_PrefabParentObject: {fileID: 0} 152 | m_PrefabInternal: {fileID: 0} 153 | m_GameObject: {fileID: 27967229} 154 | m_Enabled: 1 155 | serializedVersion: 2 156 | m_ClearFlags: 1 157 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 158 | m_NormalizedViewPortRect: 159 | serializedVersion: 2 160 | x: 0 161 | y: 0 162 | width: 1 163 | height: 1 164 | near clip plane: 0.3 165 | far clip plane: 1000 166 | field of view: 60 167 | orthographic: 0 168 | orthographic size: 5 169 | m_Depth: 0 170 | m_CullingMask: 171 | serializedVersion: 2 172 | m_Bits: 4294967295 173 | m_RenderingPath: -1 174 | m_TargetTexture: {fileID: 0} 175 | m_TargetDisplay: 0 176 | m_TargetEye: 3 177 | m_HDR: 1 178 | m_AllowMSAA: 1 179 | m_AllowDynamicResolution: 0 180 | m_ForceIntoRT: 0 181 | m_OcclusionCulling: 1 182 | m_StereoConvergence: 10 183 | m_StereoSeparation: 0.022 184 | --- !u!4 &27967233 185 | Transform: 186 | m_ObjectHideFlags: 0 187 | m_PrefabParentObject: {fileID: 0} 188 | m_PrefabInternal: {fileID: 0} 189 | m_GameObject: {fileID: 27967229} 190 | m_LocalRotation: {x: -0.013593858, y: 0.973839, z: -0.21859877, w: -0.06055976} 191 | m_LocalPosition: {x: 3.1549091, y: 2.8884313, z: 7.480246} 192 | m_LocalScale: {x: 1, y: 1, z: 1} 193 | m_Children: [] 194 | m_Father: {fileID: 0} 195 | m_RootOrder: 1 196 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 197 | --- !u!1 &574006908 198 | GameObject: 199 | m_ObjectHideFlags: 0 200 | m_PrefabParentObject: {fileID: 0} 201 | m_PrefabInternal: {fileID: 0} 202 | serializedVersion: 5 203 | m_Component: 204 | - component: {fileID: 574006910} 205 | - component: {fileID: 574006909} 206 | m_Layer: 0 207 | m_Name: Directional light 208 | m_TagString: Untagged 209 | m_Icon: {fileID: 0} 210 | m_NavMeshLayer: 0 211 | m_StaticEditorFlags: 0 212 | m_IsActive: 1 213 | --- !u!108 &574006909 214 | Light: 215 | m_ObjectHideFlags: 0 216 | m_PrefabParentObject: {fileID: 0} 217 | m_PrefabInternal: {fileID: 0} 218 | m_GameObject: {fileID: 574006908} 219 | m_Enabled: 1 220 | serializedVersion: 8 221 | m_Type: 1 222 | m_Color: {r: 1, g: 1, b: 1, a: 1} 223 | m_Intensity: 1 224 | m_Range: 10 225 | m_SpotAngle: 30 226 | m_CookieSize: 10 227 | m_Shadows: 228 | m_Type: 0 229 | m_Resolution: -1 230 | m_CustomResolution: -1 231 | m_Strength: 1 232 | m_Bias: 0.05 233 | m_NormalBias: 0.4 234 | m_NearPlane: 0.2 235 | m_Cookie: {fileID: 0} 236 | m_DrawHalo: 0 237 | m_Flare: {fileID: 0} 238 | m_RenderMode: 0 239 | m_CullingMask: 240 | serializedVersion: 2 241 | m_Bits: 4294967295 242 | m_Lightmapping: 4 243 | m_AreaSize: {x: 1, y: 1} 244 | m_BounceIntensity: 1 245 | m_ColorTemperature: 6570 246 | m_UseColorTemperature: 0 247 | m_ShadowRadius: 0 248 | m_ShadowAngle: 0 249 | --- !u!4 &574006910 250 | Transform: 251 | m_ObjectHideFlags: 0 252 | m_PrefabParentObject: {fileID: 0} 253 | m_PrefabInternal: {fileID: 0} 254 | m_GameObject: {fileID: 574006908} 255 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 256 | m_LocalPosition: {x: 1000, y: 0, z: 0} 257 | m_LocalScale: {x: 1, y: 1, z: 1} 258 | m_Children: [] 259 | m_Father: {fileID: 0} 260 | m_RootOrder: 0 261 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 262 | -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/BabylonIdentity.svg: -------------------------------------------------------------------------------- 1 | BabylonIdentity -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/BtnPerf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/Assets/BtnPerf.png -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/FlecheDown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/Assets/FlecheDown.png -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/IBLicon.svg: -------------------------------------------------------------------------------- 1 | EnvironmentIcon -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/Icon_Dashboard.svg: -------------------------------------------------------------------------------- 1 | Icon_Dashboard -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/Icon_Down.svg: -------------------------------------------------------------------------------- 1 | DownArrowIcon -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/Icon_EditModel.svg: -------------------------------------------------------------------------------- 1 | EditIcon -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/Icon_Fullscreen.svg: -------------------------------------------------------------------------------- 1 | Icon_Fullscreen -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/Icon_OpenFile.svg: -------------------------------------------------------------------------------- 1 | Asset 11 -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/Icon_Pause.svg: -------------------------------------------------------------------------------- 1 | PauseIcon -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/Icon_Play.svg: -------------------------------------------------------------------------------- 1 | PlayIcon -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/Icon_Up.svg: -------------------------------------------------------------------------------- 1 | UpArrowIcon -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/LogoSandbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/Assets/LogoSandbox.png -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/Logo_Fullscreen.svg: -------------------------------------------------------------------------------- 1 | BabylonLogo -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/Assets/arrow.png -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/arrowUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/Assets/arrowUp.png -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/Assets/circle.png -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/Assets/down.png -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/font.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/Assets/font.woff -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/Assets/pause.png -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/Assets/play.png -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/sep.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/Assets/sep.png -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/Assets/up.png -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/Assets/video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/Assets/video.png -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/ammo.wasm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/ammo.wasm.wasm -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/animation.jsx: -------------------------------------------------------------------------------- 1 | // Animations 2 | var animationBar = document.getElementById("animationBar"); 3 | var dropdownBtn = document.getElementById("dropdownBtn"); 4 | var chevronUp = document.getElementById("chevronUp"); 5 | var chevronDown = document.getElementById("chevronDown"); 6 | var dropdownLabel = document.getElementById("dropdownLabel"); 7 | var dropdownContent = document.getElementById("dropdownContent"); 8 | var playBtn = document.getElementById("playBtn"); 9 | var slider = document.getElementById("slider"); 10 | var clickInterceptor = document.getElementById("click-interceptor"); 11 | 12 | clickInterceptor.addEventListener("mousedown", function() { 13 | displayDropdownContent(false); 14 | displayDropdownContentEnv(false); 15 | }); 16 | 17 | // event on the dropdown 18 | function formatId(name) { 19 | return "data-" + name.replace(/\s/g, ''); 20 | } 21 | 22 | function displayDropdownContent(display) { 23 | if (display) { 24 | dropdownContent.style.display = "block"; 25 | chevronDown.style.display = "inline"; 26 | chevronUp.style.display = "none"; 27 | dropdownBtn.classList.add("open"); 28 | clickInterceptor.classList.remove("hidden"); 29 | } 30 | else { 31 | dropdownContent.style.display = "none"; 32 | chevronDown.style.display = "none"; 33 | chevronUp.style.display = "inline"; 34 | dropdownBtn.classList.remove("open"); 35 | clickInterceptor.classList.add("hidden"); 36 | } 37 | } 38 | dropdownBtn.addEventListener("click", function() { 39 | if (dropdownContent.style.display === "block") { 40 | displayDropdownContent(false); 41 | } 42 | else { 43 | displayDropdownContent(true); 44 | } 45 | }); 46 | 47 | function selectCurrentGroup(group, index, animation) { 48 | if (currentGroupIndex !== undefined) { 49 | document.getElementById(formatId(currentGroup.name + "-" + currentGroupIndex)).classList.remove("active"); 50 | } 51 | playBtn.classList.remove("play"); 52 | playBtn.classList.add("pause"); 53 | 54 | // start the new animation group 55 | currentGroup = group; 56 | currentGroupIndex = index; 57 | animation.classList.add("active"); 58 | dropdownLabel.innerHTML = currentGroup.name; 59 | dropdownLabel.title = currentGroup.name; 60 | 61 | // set the slider 62 | slider.setAttribute("min", currentGroup.from); 63 | slider.setAttribute("max", currentGroup.to); 64 | currentSliderValue = currentGroup.from; 65 | slider.value = currentGroup.from; 66 | } 67 | 68 | function createDropdownLink(group, index) { 69 | var animation = document.createElement("a"); 70 | animation.innerHTML = group.name; 71 | animation.title = group.name; 72 | animation.setAttribute("id", formatId(group.name + "-" + index)); 73 | animation.addEventListener("click", function() { 74 | // stop the current animation group 75 | currentGroup.reset(); 76 | currentGroup.stop(); 77 | 78 | group.play(true); 79 | 80 | // hide the content of the dropdown 81 | displayDropdownContent(false); 82 | }); 83 | dropdownContent.appendChild(animation); 84 | 85 | group.onAnimationGroupPlayObservable.add(function(grp) { 86 | selectCurrentGroup(grp, index, animation); 87 | }); 88 | 89 | group.onAnimationGroupPauseObservable.add(function(grp) { 90 | playBtn.classList.add("play"); 91 | playBtn.classList.remove("pause"); 92 | }); 93 | } 94 | 95 | // event on the play/pause button 96 | playBtn.addEventListener("click", function() { 97 | // click on the button to run the animation 98 | if (this.classList.contains("play")) { 99 | currentGroup.play(true); 100 | } 101 | // click on the button to pause the animation 102 | else { 103 | currentGroup.pause(); 104 | } 105 | }); 106 | 107 | // event on the slider 108 | slider.addEventListener("input", function() { 109 | var value = parseFloat(this.value); 110 | 111 | if (playBtn.classList.contains("play")) { 112 | currentGroup.play(true); 113 | currentGroup.goToFrame(value); 114 | currentGroup.pause(); 115 | } else { 116 | currentGroup.goToFrame(value); 117 | } 118 | }); 119 | 120 | var sliderPause = false; 121 | slider.addEventListener("mousedown", function() { 122 | if (playBtn.classList.contains("pause")) { 123 | sliderPause = true; 124 | playBtn.click(); 125 | } 126 | }); 127 | 128 | slider.addEventListener("mouseup", function() { 129 | if (sliderPause) { 130 | sliderPause = false; 131 | playBtn.click(); 132 | } 133 | }); -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/draco_decoder_gltf.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/draco_decoder_gltf.wasm -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/environment.jsx: -------------------------------------------------------------------------------- 1 | 2 | // Environments 3 | var dropdownContentEnv = document.getElementById("dropdownContent-env"); 4 | var btnEnvironment = document.getElementById("btnEnvironment"); 5 | 6 | var skyboxes = [ 7 | "environmentSpecular.env", 8 | "studio.env", 9 | ]; 10 | 11 | var skyboxesNames = [ 12 | "Default", 13 | "Studio", 14 | ]; 15 | 16 | var readLocaStorageValue = function(key, defautlValue) { 17 | if (typeof (Storage) !== "undefined" && localStorage.getItem(key) !== null) { 18 | return parseInt(localStorage.getItem(key)); 19 | } 20 | 21 | return defautlValue; 22 | } 23 | 24 | var defaultSkyboxIndex = readLocaStorageValue("defaultSkyboxId", 0); 25 | 26 | function displayDropdownContentEnv(display) { 27 | if (display) { 28 | dropdownContentEnv.classList.remove("hidden"); 29 | btnEnvironment.classList.add("open"); 30 | clickInterceptor.classList.remove("hidden"); 31 | } 32 | else { 33 | dropdownContentEnv.classList.add("hidden"); 34 | btnEnvironment.classList.remove("open"); 35 | clickInterceptor.classList.add("hidden"); 36 | } 37 | } 38 | 39 | btnEnvironment.addEventListener('click', function() { 40 | displayDropdownContentEnv(dropdownContentEnv.classList.contains("hidden")); 41 | }, false); 42 | 43 | addEnvironmentLoader = function(index) { 44 | var env = document.createElement("div"); 45 | env.innerHTML = skyboxesNames[index]; 46 | env.title = skyboxesNames[index]; 47 | env.addEventListener("click", function() { 48 | // hide the content of the dropdown 49 | displayDropdownContentEnv(false); 50 | if (typeof (Storage) !== "undefined") { 51 | localStorage.setItem("defaultSkyboxId", index); 52 | } 53 | defaultSkyboxIndex = index; 54 | skyboxPath = skyboxes[defaultSkyboxIndex]; 55 | if (filesInput) { 56 | filesInput.reload(); 57 | } 58 | else { 59 | var currentScene = BABYLON.Engine.LastCreatedScene; 60 | currentScene.environmentTexture = BABYLON.CubeTexture.CreateFromPrefilteredData(skyboxPath, currentScene); 61 | for (var i = 0; i < currentScene.materials.length; i++) { 62 | var material = currentScene.materials[i]; 63 | if (material.name === "skyBox") { 64 | var reflectionTexture = material.reflectionTexture; 65 | if (reflectionTexture && reflectionTexture.coordinatesMode === BABYLON.Texture.SKYBOX_MODE) { 66 | material.reflectionTexture = currentScene.environmentTexture.clone(); 67 | if (material.reflectionTexture) { 68 | material.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE; 69 | } 70 | } 71 | } 72 | } 73 | } 74 | }); 75 | 76 | return env; 77 | } 78 | 79 | for (var index = 0; index < skyboxes.length; index++) { 80 | var env = addEnvironmentLoader(index); 81 | dropdownContentEnv.appendChild(env); 82 | } -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/environmentSpecular.env: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/environmentSpecular.env -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kekeqy/Unity2glTF/e08c160b5677cacddf49906ed2a4bbf71ab45b44/Assets/Unity2glTF/Web/favicon.ico -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/index-media.css: -------------------------------------------------------------------------------- 1 | 2 | @media (max-width: 768px) { 3 | html { 4 | --footer-height: 50px; 5 | --font-size: 16px; 6 | } 7 | 8 | .footer { 9 | grid-template-columns: 0px 1fr 150px 10 | } 11 | 12 | .dropdown { 13 | width: 100px; 14 | } 15 | 16 | #dropdownBtn { 17 | width: 100px; 18 | } 19 | } -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/index.css: -------------------------------------------------------------------------------- 1 | html { 2 | --background: #2A2342; 3 | --footer-background: #201936; 4 | --footer-height: 70px; 5 | --button-hover-color: #BB464B; 6 | --button-hover-hover: #e0684b; 7 | --button-hover-background: #162D3A; 8 | --font-size: 20px; 9 | } 10 | 11 | html, body, #root { 12 | width: 100%; 13 | height: 100%; 14 | padding: 0; 15 | margin: 0; 16 | overflow: hidden; 17 | font-size: var(--font-size); 18 | background: var(--background); 19 | font-family: "acumin-pro-condensed"; 20 | font-weight: normal; 21 | } 22 | 23 | .hidden { 24 | display: none !important; 25 | } 26 | 27 | #click-interceptor { 28 | position: absolute; 29 | width: 100%; 30 | height: 100%; 31 | z-index: 99; 32 | top:0; 33 | left:0; 34 | } 35 | 36 | #canvasZone { 37 | display: block; 38 | padding: 0; 39 | margin: 0; 40 | overflow: hidden; 41 | width: 100%; 42 | height: calc(100% - var(--footer-height)); 43 | } 44 | 45 | #renderCanvas { 46 | position: relative; 47 | overflow: hidden; 48 | width: 100%; 49 | height: 100%; 50 | margin: 0; 51 | padding: 0; 52 | touch-action: none; 53 | -ms-touch-action: none; 54 | display: block; 55 | } 56 | 57 | a { 58 | color: white; 59 | } 60 | 61 | a:visited { 62 | color: white; 63 | } 64 | 65 | .footer { 66 | position: relative; 67 | width: 100%; 68 | height: var(--footer-height); 69 | margin: 0; 70 | padding: 0; 71 | background-color:var(--footer-background); 72 | font-size: 0; 73 | display: grid; 74 | grid-template-rows: 100%; 75 | grid-template-columns: 201px 1fr 210px 76 | } 77 | 78 | #logoImg { 79 | height: var(--footer-height); 80 | width: 161px; 81 | } 82 | 83 | .footerLeft { 84 | display: grid; 85 | grid-column: 1; 86 | grid-row: 1; 87 | padding-left: 40px; 88 | align-content: center; 89 | overflow: hidden; 90 | } 91 | 92 | .footerRight { 93 | display: flex; 94 | flex-direction: row-reverse; 95 | grid-column: 3; 96 | grid-row: 1; 97 | } 98 | 99 | .footerRight a { 100 | float: left; /* Float links side by side */ 101 | width: var(--footer-height); 102 | height: var(--footer-height); 103 | margin: 0px; 104 | padding: 0; 105 | transition: all 0.3s ease; /* Add transition for hover effects */ 106 | display: grid; 107 | align-content: center; 108 | justify-content: center; 109 | cursor: pointer; 110 | } 111 | 112 | .footerRight a img { 113 | width: var(--footer-height); 114 | height: var(--footer-height); 115 | } 116 | 117 | .footerRight a:hover { 118 | background-color: var(--button-hover-color); 119 | } 120 | 121 | .footerRight a:active { 122 | background-color: var(--button-hover-background); 123 | } 124 | 125 | .custom-upload { 126 | position: relative; 127 | background:url(./Assets/Icon_OpenFile.svg) center right no-repeat; 128 | width: var(--footer-height); 129 | height: var(--footer-height); 130 | } 131 | 132 | .custom-upload input[type=file] 133 | { 134 | outline:none; 135 | position: relative; 136 | text-align: right; 137 | -moz-opacity:0 ; 138 | opacity: 0; 139 | z-index: 2; 140 | width:100%; 141 | height:100%; 142 | filter:alpha(opacity=0); 143 | } 144 | 145 | #logoContainer { 146 | position: absolute; 147 | top:0; 148 | left:0; 149 | width: 100%; 150 | height: calc(100% - 70px); 151 | pointer-events: none; 152 | } 153 | 154 | #logo { 155 | position: absolute; 156 | width: 20%; 157 | height: 20%; 158 | top: 40%; 159 | left: 40%; 160 | pointer-events: none; 161 | } 162 | 163 | #droptext { 164 | position: absolute; 165 | text-align: center; 166 | color: #fff; 167 | height: 50px; 168 | width: 100%; 169 | bottom: 50px; 170 | } 171 | #btnDownArrow { 172 | position: absolute; 173 | bottom: 35px; 174 | right: 30px; 175 | } 176 | 177 | #loadingText { 178 | width: 100%; 179 | height: 60px; 180 | position: absolute; 181 | top: 50%; 182 | left: 0; 183 | margin-top: -30px; 184 | color: white; 185 | text-align: center; 186 | padding-top: 10px; 187 | font-size: 30px; 188 | transition: transform 0.25s ease-in-out; 189 | -webkit-transition: -webkit-transform 0.25s ease-in-out; 190 | z-index: 3; 191 | cursor: default; 192 | background-color: var(--footer-background); 193 | } 194 | 195 | .loadingText { 196 | transform: translateX(120%); 197 | -webkit-transform: translateX(120%); 198 | } 199 | 200 | #errorZone { 201 | display:none; 202 | position: absolute; 203 | width: 50%; 204 | left: 25%; 205 | bottom: 80px; 206 | background-color: #C73228; 207 | padding:20px; 208 | border-radius: 5px; 209 | color:white; 210 | font-family: 'Inconsolata'; 211 | } 212 | #errorZone button { 213 | position: absolute; 214 | top: 3px; 215 | right: 10px; 216 | padding: 0; 217 | cursor: pointer; 218 | background: transparent; 219 | border: 0; 220 | -webkit-appearance: none; 221 | color: #000; 222 | text-shadow: 0 1px 0 #fff; 223 | opacity: .4; 224 | font-size: 1.8em; 225 | } 226 | 227 | 228 | /* animation bar */ 229 | #animationBar { 230 | margin-left: 10px; 231 | display: none; 232 | align-items: center; 233 | color: white; 234 | min-height: 30px; 235 | height: var(--footer-height); 236 | background-color: var(--footer-background); 237 | grid-column: 2; 238 | grid-row: 1; 239 | } 240 | 241 | .row { 242 | display: flex; 243 | flex-direction: row; 244 | justify-content: center; 245 | flex-grow: 10; 246 | align-items: center 247 | } 248 | 249 | #animationBar * { 250 | padding: 0px; 251 | margin: 0px; 252 | } 253 | 254 | #playBtn img { 255 | width: var(--footer-height); 256 | height: var(--footer-height); 257 | } 258 | 259 | .dropdown { 260 | position: relative; 261 | display: inline-block; 262 | width: 200px; 263 | } 264 | 265 | #playBtn { 266 | display: flex; 267 | align-items: center; 268 | height: var(--footer-height); 269 | width: var(--footer-height); 270 | } 271 | 272 | #dropdownBtn { 273 | display: flex; 274 | height: var(--footer-height); 275 | width: 200px; 276 | font-size: var(--font-size); 277 | } 278 | 279 | #playBtn { 280 | border: none; 281 | background-color: inherit; 282 | } 283 | 284 | #playBtn:hover { 285 | background-color: var(--button-hover-color); 286 | } 287 | 288 | #playBtn:active { 289 | background-color: var(--button-hover-background); 290 | } 291 | 292 | #playBtn:focus { 293 | outline: none !important; 294 | border: none; 295 | } 296 | 297 | #dropdownContent-env { 298 | position: absolute; 299 | bottom: var(--footer-height); 300 | right: 0px; 301 | z-index: 100; 302 | } 303 | 304 | #dropdownContent-env div { 305 | background-color: var(--button-hover-color); 306 | overflow: hidden; 307 | text-overflow: ellipsis; 308 | white-space: nowrap; 309 | font-size: var(--font-size); 310 | width: calc(2 * var(--footer-height)); 311 | color: white; 312 | cursor: pointer; 313 | height: 40px; 314 | box-sizing: border-box; 315 | padding: 0; 316 | margin: 0; 317 | display: grid; 318 | align-content: center; 319 | justify-content: center; 320 | } 321 | 322 | #dropdownContent-env div:hover { 323 | background-color: var(--button-hover-hover); 324 | transition: all 0.3s ease; 325 | } 326 | #dropdownContent-env div:active { 327 | background-color: var(--button-hover-background); 328 | transition: all 0.3s ease; 329 | } 330 | 331 | #btnEnvironment.open { 332 | background-color:var(--button-hover-color); 333 | } 334 | 335 | #dropdownLabel { 336 | align-self: center; 337 | justify-self: center; 338 | overflow: hidden; 339 | text-overflow: ellipsis; 340 | white-space: nowrap; 341 | } 342 | 343 | #dropdownContent a { 344 | overflow: hidden; 345 | text-overflow: ellipsis; 346 | white-space: nowrap; 347 | padding: 10px 15px 10px 46px; 348 | } 349 | 350 | #dropdownBtn:hover { 351 | cursor: pointer; 352 | background-color:var(--button-hover-color); 353 | transition: all 0.3s ease; 354 | } 355 | 356 | #dropdownBtn.open { 357 | background-color:var(--button-hover-color); 358 | } 359 | 360 | #dropdownContent a { 361 | max-width: 1000px; 362 | transition: color 0.5s; 363 | height: 40px; 364 | font-size: var(--font-size); 365 | box-sizing: border-box; 366 | padding: 0; 367 | margin: 0; 368 | display: grid; 369 | align-content: center; 370 | justify-content: center; 371 | } 372 | #dropdownContent a:hover { 373 | background-color: var(--button-hover-hover); 374 | transition: all 0.3s ease; 375 | } 376 | #dropdownContent a:active { 377 | background-color: var(--button-hover-background); 378 | transition: all 0.3s ease; 379 | } 380 | 381 | #dropdownContent { 382 | background-color: var(--button-hover-color); 383 | display: none; 384 | position: absolute; 385 | z-index: 100; 386 | bottom: var(--footer-height); 387 | min-width: 135px; 388 | width: 200px; 389 | max-height: 50vh; 390 | overflow-y: auto; 391 | flex-direction: column; 392 | transition: all 0.3s ease; /* Add transition for hover effects */ 393 | } 394 | 395 | #dropdownContent a, 396 | #playBtn { 397 | cursor: pointer; 398 | } 399 | 400 | #chevronUp { 401 | margin-right: 0px; 402 | margin-left: 0px; 403 | height: var(--footer-height); 404 | width: var(--footer-height); 405 | } 406 | #chevronDown { 407 | display: none; 408 | margin-right: 0px; 409 | margin-left: 0px; 410 | height: var(--footer-height); 411 | width: var(--footer-height); 412 | } 413 | 414 | #dropdownLabel { 415 | cursor: pointer; 416 | width: 200px; 417 | padding: 0px 15px 2px 5px; 418 | } 419 | 420 | 421 | #playBtn.play #pauseImg, 422 | #playBtn.pause #playImg{ 423 | display: none; 424 | } 425 | 426 | #slider { 427 | -webkit-appearance: none; 428 | cursor: pointer; 429 | width: 100%; 430 | max-width: 820px; 431 | height: var(--footer-height); 432 | outline: none; 433 | margin-left: 20px; 434 | margin-right: 10px; 435 | background-color: transparent; 436 | } 437 | 438 | /*Chrome -webkit */ 439 | #slider::-webkit-slider-thumb { 440 | -webkit-appearance: none; 441 | width: 20px; 442 | height: 20px; 443 | border: 2px solid white; 444 | border-radius: 50%; 445 | background: var(--footer-background); 446 | margin-top: -10px; 447 | } 448 | #slider::-webkit-slider-runnable-track { 449 | height: 2px; 450 | -webkit-appearance: none; 451 | background-color: white; 452 | } 453 | 454 | 455 | /** FireFox -moz */ 456 | #slider::-moz-range-progress { 457 | background-color: white; 458 | height: 2px; 459 | } 460 | #slider::-moz-range-thumb{ 461 | width: 20px; 462 | height: 20px; 463 | border: 2px solid white; 464 | border-radius: 50%; 465 | background: var(--footer-background); 466 | } 467 | #slider::-moz-range-track { 468 | background: white; 469 | height: 2px; 470 | } 471 | 472 | /** IE -ms */ 473 | #slider::-ms-track { 474 | height: 2px; 475 | 476 | /*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */ 477 | background: transparent; 478 | 479 | /*leave room for the larger thumb to overflow with a transparent border */ 480 | border-color: transparent; 481 | border-width: 10px 0; 482 | 483 | /*remove default tick marks*/ 484 | color: transparent; 485 | } 486 | #slider::-ms-fill-lower { 487 | background: white; 488 | border-radius: 5px; 489 | } 490 | #slider::-ms-fill-upper { 491 | background: white; 492 | border-radius: 5px; 493 | } 494 | #slider::-ms-thumb { 495 | width: 16px; 496 | height: 16px; 497 | border: 2px solid white; 498 | border-radius: 50%; 499 | background: var(--footer-background); 500 | margin-top: 0px; 501 | } 502 | -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Babylon.js Sandbox - View glTF, glb, obj and babylon files 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 |

Drag and drop gltf, glb, obj or babylon files to view them

33 |
34 | 35 |
36 | 38 | 76 |
77 | 78 |
79 |
80 |
81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/index.jsx: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | var assetUrl; 4 | var cameraPosition; 5 | var kiosk; 6 | var currentGroup; // animation group 7 | var currentGroupIndex; 8 | var currentScene; 9 | 10 | // html tags 11 | var footer = document.getElementById("footer"); 12 | var canvas = document.getElementById("renderCanvas"); 13 | var canvasZone = document.getElementById("canvasZone"); 14 | 15 | // Check URL 16 | var indexOf = location.href.indexOf("?"); 17 | if (indexOf !== -1) { 18 | var params = location.href.substr(indexOf + 1).split("&"); 19 | for (var index = 0; index < params.length; index++) { 20 | var param = params[index].split("="); 21 | var name = param[0]; 22 | var value = param[1]; 23 | switch (name) { 24 | case "assetUrl": { 25 | assetUrl = value; 26 | break; 27 | } 28 | case "cameraPosition": { 29 | cameraPosition = BABYLON.Vector3.FromArray(value.split(",").map(function(component) { return +component; })); 30 | break; 31 | } 32 | case "kiosk": { 33 | kiosk = value === "true" ? true : false; 34 | break; 35 | } 36 | } 37 | } 38 | } 39 | 40 | if (kiosk) { 41 | footer.style.display = "none"; 42 | canvasZone.style.height = "100%"; 43 | } 44 | 45 | if (BABYLON.Engine.isSupported()) { 46 | var engine = new BABYLON.Engine(canvas, true, { premultipliedAlpha: false, preserveDrawingBuffer: true }); 47 | var htmlInput = document.getElementById("files"); 48 | var btnInspector = document.getElementById("btnInspector"); 49 | var errorZone = document.getElementById("errorZone"); 50 | var filesInput; 51 | var currentScene; 52 | var currentSkybox; 53 | var currentPluginName; 54 | var skyboxPath = skyboxes[defaultSkyboxIndex]; 55 | var debugLayerEnabled = false; 56 | 57 | engine.loadingUIBackgroundColor = "#2A2342"; 58 | 59 | btnInspector.classList.add("hidden"); 60 | btnEnvironment.classList.add("hidden"); 61 | 62 | canvas.addEventListener("contextmenu", function(evt) { 63 | evt.preventDefault(); 64 | }, false); 65 | 66 | BABYLON.Engine.ShadersRepository = "/src/Shaders/"; 67 | 68 | // This is really important to tell Babylon.js to use decomposeLerp and matrix interpolation 69 | BABYLON.Animation.AllowMatricesInterpolation = true; 70 | 71 | // Setting up some GLTF values 72 | BABYLON.GLTFFileLoader.IncrementalLoading = false; 73 | BABYLON.SceneLoader.OnPluginActivatedObservable.add(function(plugin) { 74 | currentPluginName = plugin.name; 75 | if (currentPluginName === "gltf") { 76 | plugin.onValidatedObservable.add(function(results) { 77 | if (results.issues.numErrors > 0) { 78 | debugLayerEnabled = true; 79 | } 80 | }); 81 | } 82 | }); 83 | 84 | // Resize 85 | window.addEventListener("resize", function() { 86 | engine.resize(); 87 | }); 88 | 89 | var sceneLoaded = function(sceneFile, babylonScene) { 90 | engine.clearInternalTexturesCache();console.log(babylonScene); 91 | 92 | // Clear dropdown that contains animation names 93 | dropdownContent.innerHTML = ""; 94 | animationBar.style.display = "none"; 95 | currentGroup = null; 96 | 97 | if (babylonScene.animationGroups.length > 0) { 98 | animationBar.style.display = "flex"; 99 | for (var index = 0; index < babylonScene.animationGroups.length; index++) { 100 | var group = babylonScene.animationGroups[index]; 101 | createDropdownLink(group, index); 102 | } 103 | currentGroup = babylonScene.animationGroups[0]; 104 | currentGroupIndex = 0; 105 | currentGroup.play(true); 106 | } 107 | 108 | // Sync the slider with the current frame 109 | babylonScene.registerBeforeRender(function() { 110 | if (currentGroup) { 111 | var targetedAnimations = currentGroup.targetedAnimations; 112 | if (targetedAnimations.length > 0) { 113 | var runtimeAnimations = currentGroup.targetedAnimations[0].animation.runtimeAnimations; 114 | if (runtimeAnimations.length > 0) { 115 | slider.value = runtimeAnimations[0].currentFrame; 116 | } 117 | } 118 | } 119 | }); 120 | 121 | // Clear the error 122 | errorZone.style.display = 'none'; 123 | 124 | btnInspector.classList.remove("hidden"); 125 | btnEnvironment.classList.remove("hidden"); 126 | 127 | currentScene = babylonScene; 128 | document.title = "Babylon.js - " + sceneFile.name; 129 | // Fix for IE, otherwise it will change the default filter for files selection after first use 130 | htmlInput.value = ""; 131 | 132 | // Attach camera to canvas inputs 133 | if (!currentScene.activeCamera || currentScene.lights.length === 0) { 134 | currentScene.createDefaultCamera(true); 135 | 136 | if (cameraPosition) { 137 | currentScene.activeCamera.setPosition(cameraPosition); 138 | } 139 | else { 140 | if (currentPluginName === "gltf") { 141 | // glTF assets use a +Z forward convention while the default camera faces +Z. Rotate the camera to look at the front of the asset. 142 | currentScene.activeCamera.alpha += Math.PI; 143 | } 144 | 145 | // Enable camera's behaviors 146 | currentScene.activeCamera.useFramingBehavior = true; 147 | 148 | var framingBehavior = currentScene.activeCamera.getBehaviorByName("Framing"); 149 | framingBehavior.framingTime = 0; 150 | framingBehavior.elevationReturnTime = -1; 151 | 152 | if (currentScene.meshes.length) { 153 | var worldExtends = currentScene.getWorldExtends(); 154 | currentScene.activeCamera.lowerRadiusLimit = null; 155 | framingBehavior.zoomOnBoundingInfo(worldExtends.min, worldExtends.max); 156 | } 157 | } 158 | 159 | currentScene.activeCamera.pinchPrecision = 200 / currentScene.activeCamera.radius; 160 | currentScene.activeCamera.upperRadiusLimit = 5 * currentScene.activeCamera.radius; 161 | 162 | currentScene.activeCamera.wheelDeltaPercentage = 0.01; 163 | currentScene.activeCamera.pinchDeltaPercentage = 0.01; 164 | } 165 | 166 | currentScene.activeCamera.attachControl(canvas); 167 | 168 | // Lighting 169 | if (currentPluginName === "gltf") { 170 | if (!currentScene.environmentTexture) { 171 | currentScene.environmentTexture = BABYLON.CubeTexture.CreateFromPrefilteredData(skyboxPath, currentScene); 172 | } 173 | 174 | currentSkybox = currentScene.createDefaultSkybox(currentScene.environmentTexture, true, (currentScene.activeCamera.maxZ - currentScene.activeCamera.minZ) / 2, 0.3, false); 175 | } 176 | else { 177 | var pbrPresent = false; 178 | for (var i = 0; i < currentScene.materials.length; i++) { 179 | if (currentScene.materials[i]._transparencyMode !== undefined) { 180 | pbrPresent = true; 181 | break; 182 | } 183 | } 184 | 185 | if (pbrPresent) { 186 | if (!currentScene.environmentTexture) { 187 | currentScene.environmentTexture = BABYLON.CubeTexture.CreateFromPrefilteredData(skyboxPath, currentScene); 188 | } 189 | } 190 | else { 191 | currentScene.createDefaultLight(); 192 | } 193 | } 194 | 195 | // In case of error during loading, meshes will be empty and clearColor is set to red 196 | if (currentScene.meshes.length === 0 && currentScene.clearColor.r === 1 && currentScene.clearColor.g === 0 && currentScene.clearColor.b === 0) { 197 | document.getElementById("logo").className = ""; 198 | canvas.style.opacity = 0; 199 | debugLayerEnabled = true; 200 | } 201 | else { 202 | if (BABYLON.Tools.errorsCount > 0) { 203 | debugLayerEnabled = true; 204 | } 205 | document.getElementById("logo").className = "hidden"; 206 | document.getElementById("droptext").className = "hidden"; 207 | canvas.style.opacity = 1; 208 | if (currentScene.activeCamera.keysUp) { 209 | currentScene.activeCamera.keysUp.push(90); // Z 210 | currentScene.activeCamera.keysUp.push(87); // W 211 | currentScene.activeCamera.keysDown.push(83); // S 212 | currentScene.activeCamera.keysLeft.push(65); // A 213 | currentScene.activeCamera.keysLeft.push(81); // Q 214 | currentScene.activeCamera.keysRight.push(69); // E 215 | currentScene.activeCamera.keysRight.push(68); // D 216 | } 217 | } 218 | 219 | if (debugLayerEnabled) { 220 | currentScene.debugLayer.show(); 221 | } 222 | }; 223 | 224 | var sceneError = function(sceneFile, babylonScene, message) { 225 | document.title = "Babylon.js - " + sceneFile.name; 226 | document.getElementById("logo").className = ""; 227 | canvas.style.opacity = 0; 228 | 229 | var errorContent = '
' + message.replace("file:[object File]", "'" + sceneFile.name + "'") + '
'; 230 | 231 | errorZone.style.display = 'block'; 232 | errorZone.innerHTML = errorContent; 233 | 234 | // Close button error 235 | errorZone.querySelector('.close').addEventListener('click', function() { 236 | errorZone.style.display = 'none'; 237 | }); 238 | }; 239 | 240 | var loadFromAssetUrl = function() { 241 | var rootUrl = BABYLON.Tools.GetFolderPath(assetUrl); 242 | var fileName = BABYLON.Tools.GetFilename(assetUrl); 243 | BABYLON.SceneLoader.LoadAsync(rootUrl, fileName, engine).then(function(scene) { 244 | if (currentScene) { 245 | currentScene.dispose(); 246 | } 247 | 248 | sceneLoaded({ name: fileName }, scene); 249 | 250 | scene.whenReadyAsync().then(function() { 251 | engine.runRenderLoop(function() { 252 | scene.render(); 253 | }); 254 | }); 255 | }).catch(function(reason) { 256 | sceneError({ name: fileName }, null, reason.message || reason); 257 | }); 258 | }; 259 | 260 | if (assetUrl) { 261 | loadFromAssetUrl(); 262 | } 263 | else { 264 | var startProcessingFiles = function() { 265 | BABYLON.Tools.ClearLogCache(); 266 | }; 267 | 268 | filesInput = new BABYLON.FilesInput(engine, null, sceneLoaded, null, null, null, startProcessingFiles, null, sceneError); 269 | filesInput.onProcessFileCallback = (function(file, name, extension) { 270 | if (filesInput._filesToLoad && filesInput._filesToLoad.length === 1 && extension) { 271 | if (extension.toLowerCase() === "dds" || extension.toLowerCase() === "env") { 272 | BABYLON.FilesInput.FilesToLoad[name] = file; 273 | skyboxPath = "file:" + file.correctName; 274 | return false; 275 | } 276 | } 277 | return true; 278 | }).bind(this); 279 | filesInput.monitorElementForDragNDrop(canvas); 280 | 281 | htmlInput.addEventListener('change', function(event) { 282 | // Handling data transfer via drag'n'drop 283 | if (event && event.dataTransfer && event.dataTransfer.files) { 284 | filesToLoad = event.dataTransfer.files; 285 | } 286 | // Handling files from input files 287 | if (event && event.target && event.target.files) { 288 | filesToLoad = event.target.files; 289 | } 290 | filesInput.loadFiles(event); 291 | }, false); 292 | } 293 | 294 | window.addEventListener("keydown", function(event) { 295 | // Press R to reload 296 | if (event.keyCode === 82 && event.target.nodeName !== "INPUT" && currentScene) { 297 | if (assetUrl) { 298 | loadFromAssetUrl(); 299 | } 300 | else { 301 | filesInput.reload(); 302 | } 303 | } 304 | }); 305 | 306 | btnInspector.addEventListener('click', function() { 307 | if (currentScene) { 308 | if (currentScene.debugLayer.isVisible()) { 309 | debugLayerEnabled = false; 310 | currentScene.debugLayer.hide(); 311 | } 312 | else { 313 | currentScene.debugLayer.show(); 314 | debugLayerEnabled = true; 315 | } 316 | } 317 | }, false); 318 | 319 | window.addEventListener("keydown", function(event) { 320 | // Press space to toggle footer 321 | if (event.keyCode === 32 && event.target.nodeName !== "INPUT") { 322 | if (footer.style.display === "none") { 323 | footer.style.display = "block"; 324 | canvasZone.style.height = "calc(100% - 56px)"; 325 | if (debugLayerEnabled) { 326 | currentScene.debugLayer.show(); 327 | } 328 | engine.resize(); 329 | } 330 | else { 331 | footer.style.display = "none"; 332 | canvasZone.style.height = "100%"; 333 | errorZone.style.display = "none"; 334 | engine.resize(); 335 | if (currentScene.debugLayer.isVisible()) { 336 | currentScene.debugLayer.hide(); 337 | } 338 | } 339 | } 340 | }); 341 | 342 | sizeScene(); 343 | 344 | window.onresize = function() { 345 | sizeScene(); 346 | } 347 | } 348 | 349 | function sizeScene() { 350 | let divInspWrapper = document.getElementsByClassName('insp-wrapper')[0]; 351 | if (divInspWrapper) { 352 | let divFooter = document.getElementsByClassName('footer')[0]; 353 | divInspWrapper.style.height = (document.body.clientHeight - divFooter.clientHeight) + "px"; 354 | divInspWrapper.style['max-width'] = document.body.clientWidth + "px"; 355 | } 356 | } 357 | 358 | -------------------------------------------------------------------------------- /Assets/Unity2glTF/Web/split.jsx: -------------------------------------------------------------------------------- 1 | /*! Split.js - v1.5.9 */ 2 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Split=t()}(this,function(){"use strict";var B=window,L=B.document,T="addEventListener",N="removeEventListener",R="getBoundingClientRect",q="horizontal",H=function(){return!1},I=B.attachEvent&&!B[T],i=["","-webkit-","-moz-","-o-"].filter(function(e){var t=L.createElement("div");return t.style.cssText="width:"+e+"calc(9px)",!!t.style.length}).shift()+"calc",s=function(e){return"string"==typeof e||e instanceof String},W=function(e){if(s(e)){var t=L.querySelector(e);if(!t)throw new Error("Selector "+e+" did not match a DOM element");return t}return e},X=function(e,t,n){var r=e[t];return void 0!==r?r:n},Y=function(e,t,n,r){if(t){if("end"===r)return 0;if("center"===r)return e/2}else if(n){if("start"===r)return 0;if("center"===r)return e/2}return e},G=function(e,t){var n=L.createElement("div");return n.className="gutter gutter-"+t,n},J=function(e,t,n){var r={};return s(t)?r[e]=t:r[e]=I?t+"%":i+"("+t+"% - "+n+"px)",r},K=function(e,t){var n;return(n={})[e]=t+"px",n};return function(e,i){void 0===i&&(i={});var u,t,s,o,r,a,l=e;Array.from&&(l=Array.from(l));var c=W(l[0]).parentNode,f=getComputedStyle?getComputedStyle(c).flexDirection:null,m=X(i,"sizes")||l.map(function(){return 100/l.length}),n=X(i,"minSize",100),h=Array.isArray(n)?n:l.map(function(){return n}),d=X(i,"expandToMin",!1),g=X(i,"gutterSize",10),v=X(i,"gutterAlign","center"),p=X(i,"snapOffset",30),y=X(i,"dragInterval",1),z=X(i,"direction",q),S=X(i,"cursor",z===q?"col-resize":"row-resize"),b=X(i,"gutter",G),_=X(i,"elementStyle",J),E=X(i,"gutterStyle",K);function w(t,e,n,r){var i=_(u,e,n,r);Object.keys(i).forEach(function(e){t.style[e]=i[e]})}function k(){return a.map(function(e){return e.size})}function x(e){return"touches"in e?e.touches[0][t]:e[t]}function M(e){var t=a[this.a],n=a[this.b],r=t.size+n.size;t.size=e/this.size*r,n.size=r-e/this.size*r,w(t.element,t.size,this._b,t.i),w(n.element,n.size,this._c,n.i)}function U(){var e=a[this.a].element,t=a[this.b].element,n=e[R](),r=t[R]();this.size=n[u]+r[u]+this._b+this._c,this.start=n[s],this.end=n[o]}function O(s){var o=function(e){if(!getComputedStyle)return null;var t=getComputedStyle(e),n=e[r];return 0===n?null:n-=z===q?parseFloat(t.paddingLeft)+parseFloat(t.paddingRight):parseFloat(t.paddingTop)+parseFloat(t.paddingBottom)}(c);if(null===o)return s;var a=0,u=[],e=s.map(function(e,t){var n=o*e/100,r=Y(g,0===t,t===s.length-1,v),i=h[t]+r;return n=this.size-(r.minSize+p+this._c)&&(t=this.size-(r.minSize+this._c)),M.call(this,t),X(i,"onDrag",H)())}.bind(t),t.stop=function(){var e=this,t=a[e.a].element,n=a[e.b].element;e.dragging&&X(i,"onDragEnd",H)(k()),e.dragging=!1,B[N]("mouseup",e.stop),B[N]("touchend",e.stop),B[N]("touchcancel",e.stop),B[N]("mousemove",e.move),B[N]("touchmove",e.move),e.stop=null,e.move=null,t[N]("selectstart",H),t[N]("dragstart",H),n[N]("selectstart",H),n[N]("dragstart",H),t.style.userSelect="",t.style.webkitUserSelect="",t.style.MozUserSelect="",t.style.pointerEvents="",n.style.userSelect="",n.style.webkitUserSelect="",n.style.MozUserSelect="",n.style.pointerEvents="",e.gutter.style.cursor="",e.parent.style.cursor="",L.body.style.cursor=""}.bind(t),B[T]("mouseup",t.stop),B[T]("touchend",t.stop),B[T]("touchcancel",t.stop),B[T]("mousemove",t.move),B[T]("touchmove",t.move),n[T]("selectstart",H),n[T]("dragstart",H),r[T]("selectstart",H),r[T]("dragstart",H),n.style.userSelect="none",n.style.webkitUserSelect="none",n.style.MozUserSelect="none",n.style.pointerEvents="none",r.style.userSelect="none",r.style.webkitUserSelect="none",r.style.MozUserSelect="none",r.style.pointerEvents="none",t.gutter.style.cursor=S,t.parent.style.cursor=S,L.body.style.cursor=S,U.call(t),t.dragOffset=x(e)-t.end}}z===q?(u="width",t="clientX",s="left",o="right",r="clientWidth"):"vertical"===z&&(u="height",t="clientY",s="top",o="bottom",r="clientHeight"),m=O(m);var D=[];function A(e){var t=e.i===D.length,n=t?D[e.i-1]:D[e.i];U.call(n);var r=t?n.size-e.minSize-n._c:e.minSize+n._b;M.call(n,r)}function j(e){var s=O(e);s.forEach(function(e,t){if(0