├── .github ├── FUNDING.yml └── workflows │ ├── native_build.yml │ ├── npm_publish.yml │ └── wasm_build.yml ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE.md ├── README.md ├── assimpjs ├── example │ └── main.cpp └── src │ ├── assimpjs.cpp │ ├── assimpjs.hpp │ ├── fileio.cpp │ ├── fileio.hpp │ ├── filelist.cpp │ ├── filelist.hpp │ ├── result.cpp │ └── result.hpp ├── commands_deb.txt ├── commands_win.txt ├── dist ├── assimpjs.js ├── assimpjs.wasm ├── license.assimp.txt └── license.assimpjs.txt ├── docs ├── dist │ ├── assimpjs.js │ ├── assimpjs.wasm │ ├── license.assimp.txt │ └── license.assimpjs.txt ├── images │ ├── assimpjs_logo.png │ ├── assimpjs_logo.svg │ └── assimpjs_logo_small.png ├── index.html ├── json-formatter │ ├── LICENSE.txt │ ├── json-formatter.cjs.js │ ├── json-formatter.css │ ├── json-formatter.esm.js │ └── json-formatter.umd.js └── source │ ├── demo.css │ └── demo.js ├── examples ├── browser_download_test.html ├── browser_dragdrop_test.html ├── node_local_delay_load_test.js ├── node_local_load_test.js └── testfiles │ ├── cube_texture.png │ ├── cube_with_materials.3ds │ ├── cube_with_materials.mtl │ ├── cube_with_materials.obj │ ├── texture.png │ └── wrong.3ds ├── execute_tests.bat ├── execute_tests.sh ├── package.json ├── start_server.bat ├── start_server.sh ├── test └── test.js └── tools ├── build_wasm_deb.sh ├── build_wasm_win.bat ├── build_wasm_win_dist.bat ├── build_wasm_win_release.bat ├── setup_emscripten_deb.sh └── setup_emscripten_win.bat /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [kovacsv] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.github/workflows/native_build.yml: -------------------------------------------------------------------------------- 1 | name: Native Build 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ${{matrix.os-type}} 13 | 14 | strategy: 15 | matrix: 16 | os-type: [windows-latest] 17 | configuration: [Debug, Release] 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | with: 22 | submodules: true 23 | - name: Configure 24 | run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.configuration}} -DCMAKE_BUILD_TYPE=%2 -DASSIMP_BUILD_TESTS=0 -DBUILD_SHARED_LIBS=0 25 | - name: Build 26 | run: cmake --build ${{github.workspace}}/build --config ${{matrix.configuration}} 27 | -------------------------------------------------------------------------------- /.github/workflows/npm_publish.yml: -------------------------------------------------------------------------------- 1 | name: NPM Publish 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | 8 | jobs: 9 | build: 10 | runs-on: windows-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - uses: actions/setup-node@v2 14 | with: 15 | node-version: '16.x' 16 | registry-url: 'https://registry.npmjs.org' 17 | - run: npm install 18 | - run: npm publish 19 | env: 20 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} 21 | -------------------------------------------------------------------------------- /.github/workflows/wasm_build.yml: -------------------------------------------------------------------------------- 1 | name: WASM Build 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ${{matrix.os-type}} 13 | 14 | strategy: 15 | matrix: 16 | os-type: [windows-latest] 17 | configuration: [Debug, Release] 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | with: 22 | submodules: true 23 | - name: Setup node.js 16.x 24 | uses: actions/setup-node@v2 25 | with: 26 | node-version: 16.x 27 | - name: Get Emscripten 28 | run: ./tools/setup_emscripten_win.bat 29 | - name: Build WASM 30 | run: ./tools/build_wasm_win.bat ${{matrix.configuration}} 31 | - name: Update Package 32 | if: ${{ matrix.configuration == 'Release' }} 33 | run: | 34 | npm install 35 | - name: Run Test 36 | if: ${{ matrix.configuration == 'Release' }} 37 | run: | 38 | $env:TEST_CONFIG="${{matrix.configuration}}" 39 | npm run test 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | emsdk 2 | node_modules 3 | build 4 | build_wasm 5 | package-lock.json 6 | __pycache__ 7 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "assimp"] 2 | path = assimp 3 | url = https://github.com/assimp/assimp.git 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.6) 2 | 3 | set_property (GLOBAL PROPERTY USE_FOLDERS ON) 4 | 5 | set (CMAKE_SUPPRESS_REGENERATION 1) 6 | set (CMAKE_CONFIGURATION_TYPES Debug;Release;RelWithDebInfo;MinSizeRel) 7 | 8 | add_definitions (-DUNICODE -D_UNICODE) 9 | 10 | project (AssimpJS) 11 | 12 | # Assimp 13 | 14 | set (BUILD_SHARED_LIBS OFF CACHE BOOL "") 15 | set (ASSIMP_BUILD_TESTS OFF CACHE BOOL "") 16 | set (ASSIMP_BUILD_ASSIMP_TOOLS OFF CACHE BOOL "") 17 | set (ASSIMP_BUILD_ALL_EXPORTERS_BY_DEFAULT OFF CACHE BOOL "") 18 | set (ASSIMP_BUILD_ASSJSON_EXPORTER ON CACHE BOOL "") 19 | set (ASSIMP_BUILD_GLTF_EXPORTER ON CACHE BOOL "") 20 | 21 | # undefined behaviour because of alignment issues, crashes and memory leaks 22 | # https://github.com/assimp/assimp/pull/4044 23 | set (ASSIMP_BUILD_M3D_IMPORTER OFF CACHE BOOL "") 24 | 25 | # assertion failed because of a memory error 26 | set (ASSIMP_BUILD_RAW_IMPORTER OFF CACHE BOOL "") 27 | 28 | # removed from assimp, so doesn't need to compile at all 29 | # https://github.com/assimp/assimp/issues/3647 30 | set (ASSIMP_BUILD_X3D_IMPORTER OFF CACHE BOOL "") 31 | 32 | # doesn't work because of xml parsing error 33 | set (ASSIMP_BUILD_IRR_IMPORTER OFF CACHE BOOL "") 34 | set (ASSIMP_BUILD_IRRMESH_IMPORTER OFF CACHE BOOL "") 35 | 36 | # doesn't work 37 | set (ASSIMP_BUILD_TERRAGEN_IMPORTER OFF CACHE BOOL "") 38 | 39 | # this dramatically decreases the wasm file size 40 | set (ASSIMP_BUILD_IFC_IMPORTER OFF CACHE BOOL "") 41 | 42 | add_subdirectory (assimp) 43 | 44 | if (${EMSCRIPTEN}) 45 | target_compile_options (assimp PUBLIC -fexceptions -Wno-unused-but-set-variable) 46 | endif () 47 | 48 | # AssimpJS 49 | 50 | set (AssimpJSSourcesFolder assimpjs/src) 51 | file (GLOB 52 | AssimpJSSourceFiles 53 | ${AssimpJSSourcesFolder}/*.hpp 54 | ${AssimpJSSourcesFolder}/*.cpp 55 | ) 56 | source_group ("Sources" FILES ${AssimpJSSourceFiles}) 57 | 58 | if (${EMSCRIPTEN}) 59 | add_executable (AssimpJS ${AssimpJSSourceFiles}) 60 | target_compile_options (AssimpJS PUBLIC "$<$:-gsource-map>") 61 | target_compile_options (AssimpJS PUBLIC -fexceptions) 62 | 63 | target_link_options (AssimpJS PUBLIC -sMODULARIZE=1) 64 | target_link_options (AssimpJS PUBLIC -sEXPORT_NAME=assimpjs) 65 | target_link_options (AssimpJS PUBLIC -sALLOW_MEMORY_GROWTH=1 --no-heap-copy) 66 | target_link_options (AssimpJS PUBLIC -sNO_DISABLE_EXCEPTION_CATCHING) 67 | 68 | # to check for memory errors 69 | #target_link_options (AssimpJS PUBLIC -sASSERTIONS=1 -sSAFE_HEAP=1 -sWARN_UNALIGNED=1) 70 | 71 | target_link_options (AssimpJS PUBLIC --bind) 72 | else () 73 | add_library (AssimpJS ${AssimpJSSourceFiles}) 74 | endif () 75 | 76 | target_link_libraries (AssimpJS assimp) 77 | set_target_properties(AssimpJS PROPERTIES OUTPUT_NAME assimpjs) 78 | set_target_properties (AssimpJS PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}") 79 | 80 | # AssimpJSTest 81 | 82 | if (${EMSCRIPTEN}) 83 | else () 84 | set (AssimpJSExampleSourcesFolder assimpjs/example) 85 | file (GLOB 86 | AssimpJSExampleSourceFiles 87 | ${AssimpJSExampleSourcesFolder}/*.hpp 88 | ${AssimpJSExampleSourcesFolder}/*.cpp 89 | ) 90 | source_group ("Sources" FILES ${AssimpJSExampleSourceFiles}) 91 | add_executable (AssimpJSExample ${AssimpJSExampleSourceFiles}) 92 | target_include_directories (AssimpJSExample PUBLIC ${AssimpJSSourcesFolder}) 93 | target_link_libraries (AssimpJSExample AssimpJS) 94 | set_target_properties (AssimpJSExample PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}") 95 | endif () 96 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Viktor Kovacs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | [Check out the live demo here!](http://kovacsv.github.io/assimpjs) 6 | 7 | [![npm version](https://badge.fury.io/js/assimpjs.svg)](https://badge.fury.io/js/assimpjs) 8 | [![Native Build](https://github.com/kovacsv/assimpjs/actions/workflows/native_build.yml/badge.svg)](https://github.com/kovacsv/assimpjs/actions/workflows/native_build.yml) 9 | [![WASM Build](https://github.com/kovacsv/assimpjs/actions/workflows/wasm_build.yml/badge.svg)](https://github.com/kovacsv/assimpjs/actions/workflows/wasm_build.yml) 10 | 11 |
12 | 13 | # assimpjs 14 | 15 | The [emscripten](https://emscripten.org) interface for the [assimp](https://github.com/assimp/assimp) library. It runs entirely in the browser, and allows you to import 40+ 3D file formats and access the result in JSON or glTF format. This is not a full port of assimp, but an easy to use interface to access it's functionality. 16 | 17 | ## How to install? 18 | 19 | You can get assimpjs from [npm](https://www.npmjs.com/package/assimpjs): 20 | 21 | ``` 22 | npm install assimpjs 23 | ``` 24 | 25 | ## How to use? 26 | 27 | The library runs in the browser and as a node.js module as well. 28 | 29 | You will need two files from the `dist` folder: `assimpjs.js` and `assimpjs.wasm`. The wasm file is loaded runtime by the js file. 30 | 31 | Given that browsers don't access the file system, you should provide all the files needed for import. Some 3D formats are coming in multiple files, so you should list all of them to import the model properly. 32 | 33 | You should provide two things for every file: 34 | - **name:** The name of the file. It's used if files are referring to each other. 35 | - **content:** The content of the file as an `Uint8Array` object. 36 | 37 | The supported target formats are: `assjson`, `gltf`, `gltf2`, `glb`, and `glb2`. The number of result files depends on the format. 38 | 39 | ### Use from the browser 40 | 41 | First, include the `assimpjs.js` file in your website. 42 | 43 | ```html 44 | 45 | ``` 46 | 47 | After that, download the model files, and pass them to assimpjs. 48 | 49 | ```js 50 | assimpjs ().then (function (ajs) { 51 | // fetch the files to import 52 | let files = [ 53 | 'testfiles/cube_with_materials.obj', 54 | 'testfiles/cube_with_materials.mtl' 55 | ]; 56 | Promise.all (files.map ((file) => fetch (file))).then ((responses) => { 57 | return Promise.all (responses.map ((res) => res.arrayBuffer ())); 58 | }).then ((arrayBuffers) => { 59 | // create new file list object, and add the files 60 | let fileList = new ajs.FileList (); 61 | for (let i = 0; i < files.length; i++) { 62 | fileList.AddFile (files[i], new Uint8Array (arrayBuffers[i])); 63 | } 64 | 65 | // convert file list to assimp json 66 | let result = ajs.ConvertFileList (fileList, 'assjson'); 67 | 68 | // check if the conversion succeeded 69 | if (!result.IsSuccess () || result.FileCount () == 0) { 70 | resultDiv.innerHTML = result.GetErrorCode (); 71 | return; 72 | } 73 | 74 | // get the result file, and convert to string 75 | let resultFile = result.GetFile (0); 76 | let jsonContent = new TextDecoder ().decode (resultFile.GetContent ()); 77 | 78 | // parse the result json 79 | let resultJson = JSON.parse (jsonContent); 80 | 81 | resultDiv.innerHTML = JSON.stringify (resultJson, null, 4); 82 | }); 83 | }); 84 | ``` 85 | 86 | ### Use as a node.js module 87 | 88 | You should require the `assimpjs` module in your script. In node.js you can use the file system module to get the buffer of each file. 89 | 90 | ```js 91 | let fs = require ('fs'); 92 | const assimpjs = require ('assimpjs')(); 93 | 94 | assimpjs.then ((ajs) => { 95 | // create new file list object 96 | let fileList = new ajs.FileList (); 97 | 98 | // add model files 99 | fileList.AddFile ( 100 | 'cube_with_materials.obj', 101 | fs.readFileSync ('testfiles/cube_with_materials.obj') 102 | ); 103 | fileList.AddFile ( 104 | 'cube_with_materials.mtl', 105 | fs.readFileSync ('testfiles/cube_with_materials.mtl') 106 | ); 107 | 108 | // convert file list to assimp json 109 | let result = ajs.ConvertFileList (fileList, 'assjson'); 110 | 111 | // check if the conversion succeeded 112 | if (!result.IsSuccess () || result.FileCount () == 0) { 113 | console.log (result.GetErrorCode ()); 114 | return; 115 | } 116 | 117 | // get the result file, and convert to string 118 | let resultFile = result.GetFile (0); 119 | let jsonContent = new TextDecoder ().decode (resultFile.GetContent ()); 120 | 121 | // parse the result json 122 | let resultJson = JSON.parse (jsonContent); 123 | }); 124 | ``` 125 | 126 | It's also possible to delay load the required files so they have to be loaded only when the importer needs them. In this case you have to provide only the name and content of the main file, and implement callbacks to provide additional files. 127 | 128 | ```js 129 | let fs = require ('fs'); 130 | const assimpjs = require ('assimpjs')(); 131 | 132 | assimpjs.then ((ajs) => { 133 | // convert model 134 | let result = ajs.ConvertFile ( 135 | // file name 136 | 'cube_with_materials.obj', 137 | // file format 138 | 'assjson', 139 | // file content as arraybuffer 140 | fs.readFileSync ('testfiles/cube_with_materials.obj'), 141 | // check if file exists by name 142 | function (fileName) { 143 | return fs.existsSync ('testfiles/' + fileName); 144 | }, 145 | // get file content as arraybuffer by name 146 | function (fileName) { 147 | return fs.readFileSync ('testfiles/' + fileName); 148 | } 149 | ); 150 | 151 | // check if the conversion succeeded 152 | if (!result.IsSuccess () || result.FileCount () == 0) { 153 | console.log (result.GetErrorCode ()); 154 | return; 155 | } 156 | 157 | // get the result file, and convert to string 158 | let resultFile = result.GetFile (0); 159 | let jsonContent = new TextDecoder ().decode (resultFile.GetContent ()); 160 | 161 | // parse the result json 162 | let resultJson = JSON.parse (jsonContent); 163 | }); 164 | ``` 165 | 166 | ## How to build on Windows? 167 | 168 | A set of batch scripts are prepared for building on Windows. 169 | 170 | ### 1. Install Prerequisites 171 | 172 | Install [CMake](https://cmake.org) (3.6 minimum version is needed). Make sure that the cmake executable is in the PATH. 173 | 174 | ### 2. Install Emscripten SDK 175 | 176 | Run the Emscripten setup script. 177 | 178 | ``` 179 | tools\setup_emscripten_win.bat 180 | ``` 181 | 182 | ### 3. Compile the WASM library 183 | 184 | Run the release build script. 185 | 186 | ``` 187 | tools\build_wasm_win_release.bat 188 | ``` 189 | 190 | ### 4. Build the native project (optional) 191 | 192 | If you want to debug the code, it's useful to build a native project. To do that, just use cmake to generate the project of your choice. 193 | 194 | ## How to run locally? 195 | 196 | To run the demo and the examples locally, you have to start a web server. Run `npm install` from the root directory, then run `npm start` and visit `http://localhost:8080`. 197 | -------------------------------------------------------------------------------- /assimpjs/example/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "assimpjs.hpp" 5 | 6 | static File GetFile (const std::string& filePath) 7 | { 8 | Assimp::DefaultIOSystem system; 9 | Assimp::IOStream* stream = system.Open (filePath.c_str (), "rb"); 10 | if (stream == nullptr) { 11 | return File (); 12 | } 13 | size_t fileSize = stream->FileSize (); 14 | Buffer content (fileSize); 15 | stream->Read (&content[0], 1, fileSize); 16 | return File (filePath, content); 17 | } 18 | 19 | int main (int argc, const char* argv[]) 20 | { 21 | std::string folderPath = argv[0]; 22 | size_t lastSeparator = folderPath.find_last_of ('\\'); 23 | if (lastSeparator != std::string::npos) { 24 | folderPath = folderPath.substr (0, lastSeparator); 25 | } 26 | 27 | if (argc < 2) { 28 | return 1; 29 | } 30 | 31 | FileList fileList; 32 | for (size_t i = 1; i < argc; i++) { 33 | File file = GetFile (argv[i]); 34 | fileList.AddFile (file.path, file.content); 35 | } 36 | 37 | ConvertFileList (fileList, "gltf2"); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /assimpjs/src/assimpjs.cpp: -------------------------------------------------------------------------------- 1 | #include "assimpjs.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | static const aiScene* ImportFileListByMainFile (Assimp::Importer& importer, const File& file) 12 | { 13 | try { 14 | const aiScene* scene = importer.ReadFile (file.path, 15 | aiProcess_Triangulate | 16 | aiProcess_GenUVCoords | 17 | aiProcess_JoinIdenticalVertices | 18 | aiProcess_SortByPType); 19 | return scene; 20 | } catch (...) { 21 | return nullptr; 22 | } 23 | return nullptr; 24 | } 25 | 26 | static std::string GetFileNameFromFormat (const std::string& format) 27 | { 28 | std::string fileName = "result"; 29 | if (format == "assjson") { 30 | fileName += ".json"; 31 | } else if (format == "gltf" || format == "gltf2") { 32 | fileName += ".gltf"; 33 | } else if (format == "glb" || format == "glb2") { 34 | fileName += ".glb"; 35 | } 36 | return fileName; 37 | } 38 | 39 | static bool ExportScene (const aiScene* scene, const std::string& format, Result& result) 40 | { 41 | if (scene == nullptr) { 42 | result.errorCode = ErrorCode::ImportError; 43 | return false; 44 | } 45 | 46 | Assimp::Exporter exporter; 47 | FileListIOSystemWriteAdapter* exportIOSystem = new FileListIOSystemWriteAdapter (result.fileList); 48 | exporter.SetIOHandler (exportIOSystem); 49 | 50 | Assimp::ExportProperties exportProperties; 51 | exportProperties.SetPropertyBool ("JSON_SKIP_WHITESPACES", true); 52 | std::string fileName = GetFileNameFromFormat (format); 53 | aiReturn exportResult = exporter.Export (scene, format.c_str (), fileName.c_str (), 0u, &exportProperties); 54 | if (exportResult != aiReturn_SUCCESS) { 55 | result.errorCode = ErrorCode::ExportError; 56 | return false; 57 | } 58 | 59 | result.errorCode = ErrorCode::NoError; 60 | return true; 61 | } 62 | 63 | Result ConvertFile (const File& file, const std::string& format, const FileLoader& loader) 64 | { 65 | Assimp::Importer importer; 66 | importer.SetIOHandler (new DelayLoadedIOSystemReadAdapter (file, loader)); 67 | const aiScene* scene = ImportFileListByMainFile (importer, file); 68 | 69 | Result result; 70 | ExportScene (scene, format, result); 71 | return result; 72 | } 73 | 74 | Result ConvertFileList (const FileList& fileList, const std::string& format) 75 | { 76 | if (fileList.FileCount () == 0) { 77 | return Result (ErrorCode::NoFilesFound); 78 | } 79 | 80 | Assimp::Importer importer; 81 | importer.SetIOHandler (new FileListIOSystemReadAdapter (fileList)); 82 | 83 | const aiScene* scene = nullptr; 84 | for (size_t fileIndex = 0; fileIndex < fileList.FileCount (); fileIndex++) { 85 | const File& file = fileList.GetFile (fileIndex); 86 | scene = ImportFileListByMainFile (importer, file); 87 | if (scene != nullptr) { 88 | break; 89 | } 90 | } 91 | 92 | Result result; 93 | ExportScene (scene, format, result); 94 | return result; 95 | } 96 | 97 | #ifdef EMSCRIPTEN 98 | 99 | Result ConvertFileEmscripten ( 100 | const std::string& name, 101 | const std::string& format, 102 | const emscripten::val& content, 103 | const emscripten::val& existsFunc, 104 | const emscripten::val& loadFunc) 105 | { 106 | class FileLoaderEmscripten : public FileLoader 107 | { 108 | public: 109 | FileLoaderEmscripten (const emscripten::val& existsFunc, const emscripten::val& loadFunc) : 110 | existsFunc (existsFunc), 111 | loadFunc (loadFunc) 112 | { 113 | } 114 | 115 | virtual bool Exists (const char* pFile) const override 116 | { 117 | if (existsFunc.isUndefined () || existsFunc.isNull ()) { 118 | return false; 119 | } 120 | std::string fileName = GetFileName (pFile); 121 | emscripten::val exists = existsFunc (fileName); 122 | return exists.as (); 123 | } 124 | 125 | virtual Buffer Load (const char* pFile) const override 126 | { 127 | if (loadFunc.isUndefined () || loadFunc.isNull ()) { 128 | return {}; 129 | } 130 | std::string fileName = GetFileName (pFile); 131 | emscripten::val fileBuffer = loadFunc (fileName); 132 | return emscripten::vecFromJSArray (fileBuffer); 133 | } 134 | 135 | private: 136 | const emscripten::val& existsFunc; 137 | const emscripten::val& loadFunc; 138 | }; 139 | 140 | Buffer buffer = emscripten::vecFromJSArray (content); 141 | File file (name, buffer); 142 | FileLoaderEmscripten loader (existsFunc, loadFunc); 143 | return ConvertFile (file, format, loader); 144 | } 145 | 146 | EMSCRIPTEN_BINDINGS (assimpjs) 147 | { 148 | emscripten::class_ ("File") 149 | .constructor<> () 150 | .function ("GetPath", &File::GetPath) 151 | .function ("GetContent", &File::GetContentEmscripten) 152 | ; 153 | 154 | emscripten::class_ ("FileList") 155 | .constructor<> () 156 | .function ("AddFile", &FileList::AddFileEmscripten) 157 | ; 158 | 159 | emscripten::class_ ("Result") 160 | .constructor<> () 161 | .function ("IsSuccess", &Result::IsSuccess) 162 | .function ("GetErrorCode", &Result::GetErrorCode) 163 | .function ("FileCount", &Result::FileCount) 164 | .function ("GetFile", &Result::GetFile) 165 | ; 166 | 167 | emscripten::function ("ConvertFile", &ConvertFileEmscripten); 168 | emscripten::function ("ConvertFileList", &ConvertFileList); 169 | } 170 | 171 | #endif 172 | -------------------------------------------------------------------------------- /assimpjs/src/assimpjs.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ASSIMPJS_HPP 2 | #define ASSIMPJS_HPP 3 | 4 | #ifdef EMSCRIPTEN 5 | #include 6 | #endif 7 | 8 | #include "filelist.hpp" 9 | #include "fileio.hpp" 10 | #include "result.hpp" 11 | 12 | #include 13 | #include 14 | 15 | Result ConvertFile (const File& file, const std::string& format, const FileLoader& loader); 16 | Result ConvertFileList (const FileList& fileList, const std::string& format); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /assimpjs/src/fileio.cpp: -------------------------------------------------------------------------------- 1 | #include "fileio.hpp" 2 | 3 | #include 4 | 5 | static char GetOsSeparator () 6 | { 7 | #ifndef _WIN32 8 | return '/'; 9 | #else 10 | return '\\'; 11 | #endif 12 | } 13 | 14 | static size_t ReadFromBuffer (const Buffer* buffer, size_t& position, void* pvBuffer, size_t pSize, size_t pCount) 15 | { 16 | size_t remainingElemCount = (size_t) (std::floor ((buffer->size () - position) / pSize)); 17 | size_t readableElemCount = std::min (remainingElemCount, pCount); 18 | if (readableElemCount == 0) { 19 | return 0; 20 | } 21 | memcpy (pvBuffer, buffer->data () + position, readableElemCount * pSize); 22 | position += readableElemCount * pSize; 23 | return readableElemCount; 24 | } 25 | 26 | static size_t WriteToBuffer (Buffer* buffer, size_t& position, const void* pvBuffer, size_t pSize, size_t pCount) 27 | { 28 | size_t memSize = pSize * pCount; 29 | size_t newBufferSize = std::max (buffer->size (), position + memSize); 30 | if (newBufferSize > buffer->size ()) { 31 | buffer->resize (newBufferSize); 32 | } 33 | memcpy (buffer->data () + position, pvBuffer, memSize); 34 | position += memSize; 35 | return pCount; 36 | } 37 | 38 | static aiReturn SeekInBuffer (const Buffer* buffer, size_t& position, size_t pOffset, aiOrigin pOrigin) 39 | { 40 | switch (pOrigin) { 41 | case aiOrigin_SET: 42 | position = pOffset; 43 | break; 44 | case aiOrigin_CUR: 45 | position += pOffset; 46 | break; 47 | case aiOrigin_END: 48 | position = buffer->size () - pOffset; 49 | break; 50 | default: 51 | break; 52 | } 53 | return aiReturn::aiReturn_SUCCESS; 54 | } 55 | 56 | FileLoader::FileLoader () 57 | { 58 | 59 | } 60 | 61 | FileLoader::~FileLoader () 62 | { 63 | 64 | } 65 | 66 | BufferIOStreamReadAdapter::BufferIOStreamReadAdapter (const Buffer* buffer) : 67 | buffer (buffer), 68 | position (0) 69 | { 70 | } 71 | 72 | BufferIOStreamReadAdapter::~BufferIOStreamReadAdapter () 73 | { 74 | 75 | } 76 | 77 | size_t BufferIOStreamReadAdapter::Read (void* pvBuffer, size_t pSize, size_t pCount) 78 | { 79 | return ReadFromBuffer (buffer, position, pvBuffer, pSize, pCount); 80 | } 81 | 82 | size_t BufferIOStreamReadAdapter::Write (const void* pvBuffer, size_t pSize, size_t pCount) 83 | { 84 | throw std::logic_error ("not implemented"); 85 | } 86 | 87 | aiReturn BufferIOStreamReadAdapter::Seek (size_t pOffset, aiOrigin pOrigin) 88 | { 89 | return SeekInBuffer (buffer, position, pOffset, pOrigin); 90 | } 91 | 92 | size_t BufferIOStreamReadAdapter::Tell () const 93 | { 94 | return position; 95 | } 96 | 97 | size_t BufferIOStreamReadAdapter::FileSize () const 98 | { 99 | return buffer->size (); 100 | } 101 | 102 | void BufferIOStreamReadAdapter::Flush () 103 | { 104 | 105 | } 106 | 107 | BufferIOStreamWriteAdapter::BufferIOStreamWriteAdapter (Buffer* buffer) : 108 | buffer (buffer), 109 | position (0) 110 | { 111 | } 112 | 113 | BufferIOStreamWriteAdapter::~BufferIOStreamWriteAdapter () 114 | { 115 | 116 | } 117 | 118 | size_t BufferIOStreamWriteAdapter::Read (void* pvBuffer, size_t pSize, size_t pCount) 119 | { 120 | return ReadFromBuffer (buffer, position, pvBuffer, pSize, pCount); 121 | } 122 | 123 | size_t BufferIOStreamWriteAdapter::Write (const void* pvBuffer, size_t pSize, size_t pCount) 124 | { 125 | return WriteToBuffer (buffer, position, pvBuffer, pSize, pCount); 126 | } 127 | 128 | aiReturn BufferIOStreamWriteAdapter::Seek (size_t pOffset, aiOrigin pOrigin) 129 | { 130 | return SeekInBuffer (buffer, position, pOffset, pOrigin); 131 | } 132 | 133 | size_t BufferIOStreamWriteAdapter::Tell () const 134 | { 135 | return position; 136 | } 137 | 138 | size_t BufferIOStreamWriteAdapter::FileSize () const 139 | { 140 | return buffer->size (); 141 | } 142 | 143 | void BufferIOStreamWriteAdapter::Flush () 144 | { 145 | 146 | } 147 | 148 | OwnerBufferIOStreamReadAdapter::OwnerBufferIOStreamReadAdapter (const Buffer* buffer) : 149 | BufferIOStreamReadAdapter (buffer) 150 | { 151 | } 152 | 153 | OwnerBufferIOStreamReadAdapter::~OwnerBufferIOStreamReadAdapter () 154 | { 155 | delete buffer; 156 | } 157 | 158 | DelayLoadedIOSystemReadAdapter::DelayLoadedIOSystemReadAdapter (const File& file, const FileLoader& loader) : 159 | file (file), 160 | loader (loader) 161 | { 162 | } 163 | 164 | DelayLoadedIOSystemReadAdapter::~DelayLoadedIOSystemReadAdapter () 165 | { 166 | 167 | } 168 | 169 | bool DelayLoadedIOSystemReadAdapter::Exists (const char* pFile) const 170 | { 171 | if (GetFileName (file.path) == GetFileName (pFile)) { 172 | return true; 173 | } 174 | return loader.Exists (pFile); 175 | } 176 | 177 | Assimp::IOStream* DelayLoadedIOSystemReadAdapter::Open (const char* pFile, const char* pMode) 178 | { 179 | if (GetFileName (file.path) == GetFileName (pFile)) { 180 | return new BufferIOStreamReadAdapter (&file.content); 181 | } 182 | if (!loader.Exists (pFile)) { 183 | return nullptr; 184 | } 185 | Buffer buffer = loader.Load (pFile); 186 | Buffer* bufferPtr = new Buffer (buffer); 187 | return new OwnerBufferIOStreamReadAdapter (bufferPtr); 188 | } 189 | 190 | void DelayLoadedIOSystemReadAdapter::Close (Assimp::IOStream* pFile) 191 | { 192 | delete pFile; 193 | } 194 | 195 | char DelayLoadedIOSystemReadAdapter::getOsSeparator () const 196 | { 197 | return GetOsSeparator (); 198 | } 199 | 200 | FileListIOSystemReadAdapter::FileListIOSystemReadAdapter (const FileList& fileList) : 201 | fileList (fileList) 202 | { 203 | } 204 | 205 | FileListIOSystemReadAdapter::~FileListIOSystemReadAdapter () 206 | { 207 | 208 | } 209 | 210 | bool FileListIOSystemReadAdapter::Exists (const char* pFile) const 211 | { 212 | return fileList.GetFile (pFile) != nullptr; 213 | } 214 | 215 | Assimp::IOStream* FileListIOSystemReadAdapter::Open (const char* pFile, const char* pMode) 216 | { 217 | const File* foundFile = fileList.GetFile (pFile); 218 | if (foundFile == nullptr) { 219 | return nullptr; 220 | } 221 | return new BufferIOStreamReadAdapter (&foundFile->content); 222 | } 223 | 224 | void FileListIOSystemReadAdapter::Close (Assimp::IOStream* pFile) 225 | { 226 | delete pFile; 227 | } 228 | 229 | char FileListIOSystemReadAdapter::getOsSeparator () const 230 | { 231 | return GetOsSeparator (); 232 | } 233 | 234 | FileListIOSystemWriteAdapter::FileListIOSystemWriteAdapter (FileList& fileList) : 235 | fileList (fileList) 236 | { 237 | } 238 | 239 | FileListIOSystemWriteAdapter::~FileListIOSystemWriteAdapter () 240 | { 241 | 242 | } 243 | 244 | bool FileListIOSystemWriteAdapter::Exists (const char* pFile) const 245 | { 246 | return fileList.GetFile (pFile) != nullptr; 247 | } 248 | 249 | Assimp::IOStream* FileListIOSystemWriteAdapter::Open (const char* pFile, const char* pMode) 250 | { 251 | File* foundFile = fileList.GetFile (pFile); 252 | if (foundFile != nullptr) { 253 | return new BufferIOStreamWriteAdapter (&foundFile->content); 254 | } 255 | 256 | fileList.AddFile (pFile, {}); 257 | File* newFile = fileList.GetFile (pFile); 258 | if (newFile != nullptr) { 259 | return new BufferIOStreamWriteAdapter (&newFile->content); 260 | } 261 | 262 | return nullptr; 263 | } 264 | 265 | void FileListIOSystemWriteAdapter::Close (Assimp::IOStream* pFile) 266 | { 267 | delete pFile; 268 | } 269 | 270 | char FileListIOSystemWriteAdapter::getOsSeparator () const 271 | { 272 | return GetOsSeparator (); 273 | } 274 | -------------------------------------------------------------------------------- /assimpjs/src/fileio.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FILEIO_HPP 2 | #define FILEIO_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include "filelist.hpp" 8 | 9 | class FileLoader 10 | { 11 | public: 12 | FileLoader (); 13 | virtual ~FileLoader (); 14 | 15 | virtual bool Exists (const char* pFile) const = 0; 16 | virtual Buffer Load (const char* pFile) const = 0; 17 | }; 18 | 19 | class BufferIOStreamReadAdapter : public Assimp::IOStream 20 | { 21 | public: 22 | BufferIOStreamReadAdapter (const Buffer* buffer); 23 | virtual ~BufferIOStreamReadAdapter (); 24 | 25 | virtual size_t Read (void* pvBuffer, size_t pSize, size_t pCount) override; 26 | virtual size_t Write (const void* pvBuffer, size_t pSize, size_t pCount) override; 27 | 28 | virtual aiReturn Seek (size_t pOffset, aiOrigin pOrigin) override; 29 | virtual size_t Tell () const override; 30 | 31 | virtual size_t FileSize () const override; 32 | virtual void Flush () override; 33 | 34 | protected: 35 | const Buffer* buffer; 36 | size_t position; 37 | }; 38 | 39 | class BufferIOStreamWriteAdapter : public Assimp::IOStream 40 | { 41 | public: 42 | BufferIOStreamWriteAdapter (Buffer* buffer); 43 | virtual ~BufferIOStreamWriteAdapter (); 44 | 45 | virtual size_t Read (void* pvBuffer, size_t pSize, size_t pCount) override; 46 | virtual size_t Write (const void* pvBuffer, size_t pSize, size_t pCount) override; 47 | 48 | virtual aiReturn Seek (size_t pOffset, aiOrigin pOrigin) override; 49 | virtual size_t Tell () const override; 50 | 51 | virtual size_t FileSize () const override; 52 | virtual void Flush () override; 53 | 54 | protected: 55 | Buffer* buffer; 56 | size_t position; 57 | }; 58 | 59 | class OwnerBufferIOStreamReadAdapter : public BufferIOStreamReadAdapter 60 | { 61 | public: 62 | OwnerBufferIOStreamReadAdapter (const Buffer* buffer); 63 | virtual ~OwnerBufferIOStreamReadAdapter (); 64 | }; 65 | 66 | class DelayLoadedIOSystemReadAdapter : public Assimp::IOSystem 67 | { 68 | public: 69 | DelayLoadedIOSystemReadAdapter (const File& file, const FileLoader& loader); 70 | virtual ~DelayLoadedIOSystemReadAdapter (); 71 | 72 | virtual bool Exists (const char* pFile) const override; 73 | virtual Assimp::IOStream* Open (const char* pFile, const char* pMode) override; 74 | virtual void Close (Assimp::IOStream* pFile) override; 75 | 76 | virtual char getOsSeparator () const override; 77 | 78 | private: 79 | const File& file; 80 | const FileLoader& loader; 81 | }; 82 | 83 | class FileListIOSystemReadAdapter : public Assimp::IOSystem 84 | { 85 | public: 86 | FileListIOSystemReadAdapter (const FileList& fileList); 87 | virtual ~FileListIOSystemReadAdapter (); 88 | 89 | virtual bool Exists (const char* pFile) const override; 90 | virtual Assimp::IOStream* Open (const char* pFile, const char* pMode) override; 91 | virtual void Close (Assimp::IOStream* pFile) override; 92 | 93 | virtual char getOsSeparator () const override; 94 | 95 | private: 96 | const FileList& fileList; 97 | }; 98 | 99 | class FileListIOSystemWriteAdapter : public Assimp::IOSystem 100 | { 101 | public: 102 | FileListIOSystemWriteAdapter (FileList& fileList); 103 | virtual ~FileListIOSystemWriteAdapter (); 104 | 105 | virtual bool Exists (const char* pFile) const override; 106 | virtual Assimp::IOStream* Open (const char* pFile, const char* pMode) override; 107 | virtual void Close (Assimp::IOStream* pFile) override; 108 | 109 | virtual char getOsSeparator () const override; 110 | 111 | private: 112 | FileList& fileList; 113 | }; 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /assimpjs/src/filelist.cpp: -------------------------------------------------------------------------------- 1 | #include "filelist.hpp" 2 | 3 | static std::string ToLowercase (const std::string& str) 4 | { 5 | std::string res = str; 6 | for (char& c : res) { 7 | c = std::tolower (c); 8 | } 9 | return res; 10 | } 11 | 12 | File::File () : 13 | path (), 14 | content () 15 | { 16 | } 17 | 18 | File::File (const std::string& path, const Buffer& content) : 19 | path (path), 20 | content (content) 21 | { 22 | } 23 | 24 | const std::string& File::GetPath () const 25 | { 26 | return path; 27 | } 28 | 29 | #ifdef EMSCRIPTEN 30 | 31 | emscripten::val File::GetContentEmscripten () const 32 | { 33 | emscripten::val Uint8Array = emscripten::val::global ("Uint8Array"); 34 | return Uint8Array.new_ (emscripten::typed_memory_view (content.size (), content.data ())); 35 | } 36 | 37 | #endif 38 | 39 | FileList::FileList () : 40 | files () 41 | { 42 | } 43 | 44 | void FileList::AddFile (const std::string& path, const Buffer& content) 45 | { 46 | files.push_back (File (path, content)); 47 | } 48 | 49 | size_t FileList::FileCount () const 50 | { 51 | return files.size (); 52 | } 53 | 54 | File& FileList::GetFile (size_t index) 55 | { 56 | return files[index]; 57 | } 58 | 59 | File* FileList::GetFile (const std::string& path) 60 | { 61 | std::string fileName = GetFileName (path); 62 | for (File& file : files) { 63 | std::string currFileName = GetFileName (file.path); 64 | if (currFileName == fileName) { 65 | return &file; 66 | } 67 | } 68 | return nullptr; 69 | } 70 | 71 | const File& FileList::GetFile (size_t index) const 72 | { 73 | return const_cast (this)->GetFile (index); 74 | } 75 | 76 | const File* FileList::GetFile (const std::string& path) const 77 | { 78 | return const_cast (this)->GetFile (path); 79 | } 80 | 81 | #ifdef EMSCRIPTEN 82 | 83 | void FileList::AddFileEmscripten (const std::string& path, const emscripten::val& content) 84 | { 85 | Buffer contentArr = emscripten::vecFromJSArray (content); 86 | AddFile (path, contentArr); 87 | } 88 | 89 | #endif 90 | 91 | std::string GetFileName (const std::string& path) 92 | { 93 | size_t lastSeparator = path.find_last_of ('/'); 94 | if (lastSeparator == std::wstring::npos) { 95 | lastSeparator = path.find_last_of ('\\'); 96 | } 97 | if (lastSeparator == std::wstring::npos) { 98 | return ToLowercase (path); 99 | } 100 | std::string fileName = path.substr (lastSeparator + 1, path.length () - lastSeparator - 1); 101 | return ToLowercase (fileName); 102 | } 103 | -------------------------------------------------------------------------------- /assimpjs/src/filelist.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FILELIST_HPP 2 | #define FILELIST_HPP 3 | 4 | #ifdef EMSCRIPTEN 5 | #include 6 | #endif 7 | 8 | #include 9 | #include 10 | 11 | using Buffer = std::vector; 12 | 13 | class File 14 | { 15 | public: 16 | File (); 17 | File (const std::string& path, const Buffer& content); 18 | 19 | const std::string& GetPath () const; 20 | 21 | #ifdef EMSCRIPTEN 22 | emscripten::val GetContentEmscripten () const; 23 | #endif 24 | 25 | std::string path; 26 | Buffer content; 27 | }; 28 | 29 | class FileList 30 | { 31 | public: 32 | FileList (); 33 | 34 | void AddFile (const std::string& path, const Buffer& content); 35 | 36 | size_t FileCount () const; 37 | File& GetFile (size_t index); 38 | File* GetFile (const std::string& path); 39 | const File& GetFile (size_t index) const; 40 | const File* GetFile (const std::string& path) const; 41 | 42 | #ifdef EMSCRIPTEN 43 | void AddFileEmscripten (const std::string& path, const emscripten::val& content); 44 | #endif 45 | 46 | private: 47 | std::vector files; 48 | }; 49 | 50 | std::string GetFileName (const std::string& path); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /assimpjs/src/result.cpp: -------------------------------------------------------------------------------- 1 | #include "result.hpp" 2 | 3 | Result::Result () : 4 | Result (ErrorCode::UnknownError) 5 | { 6 | } 7 | 8 | Result::Result (ErrorCode error) : 9 | errorCode (error), 10 | fileList () 11 | { 12 | } 13 | 14 | bool Result::IsSuccess () const 15 | { 16 | return errorCode == ErrorCode::NoError; 17 | } 18 | 19 | std::string Result::GetErrorCode () const 20 | { 21 | switch (errorCode) { 22 | case ErrorCode::NoError: 23 | return "no_error"; 24 | case ErrorCode::NoFilesFound: 25 | return "no_files_found"; 26 | case ErrorCode::ImportError: 27 | return "import_error"; 28 | case ErrorCode::ExportError: 29 | return "export_error"; 30 | case ErrorCode::UnknownError: 31 | return "unknown_error"; 32 | } 33 | 34 | return "unknown_error"; 35 | } 36 | 37 | size_t Result::FileCount () const 38 | { 39 | return fileList.FileCount (); 40 | } 41 | 42 | const File& Result::GetFile (size_t index) const 43 | { 44 | return fileList.GetFile (index); 45 | } 46 | -------------------------------------------------------------------------------- /assimpjs/src/result.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RESULT_HPP 2 | #define RESULT_HPP 3 | 4 | #include "filelist.hpp" 5 | 6 | enum class ErrorCode : int 7 | { 8 | NoError = 0, 9 | NoFilesFound = 1, 10 | ImportError = 2, 11 | ExportError = 3, 12 | UnknownError = 4 13 | }; 14 | 15 | class Result 16 | { 17 | public: 18 | Result (); 19 | Result (ErrorCode error); 20 | 21 | bool IsSuccess () const; 22 | std::string GetErrorCode () const; 23 | 24 | size_t FileCount () const; 25 | const File& GetFile (size_t index) const; 26 | 27 | ErrorCode errorCode; 28 | FileList fileList; 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /commands_deb.txt: -------------------------------------------------------------------------------- 1 | --- Commands for debian systems --- 2 | 3 | # First command --- setup emscripten 4 | ./tools/setup_emscripten_deb.sh 5 | 6 | # Second command --- build the project 7 | ./tools/build_wasm_deb.sh 8 | -------------------------------------------------------------------------------- /commands_win.txt: -------------------------------------------------------------------------------- 1 | --- Commands for windows systems --- 2 | 3 | # First command --- setup emscripten 4 | ./tools/setup_emscripten_win.bat 5 | 6 | # Second command --- build the project 7 | ./tools/build_wasm_win.bat 8 | -------------------------------------------------------------------------------- /dist/assimpjs.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kovacsv/assimpjs/733a2c6c251bc31aa6e407087d63a68994836f1d/dist/assimpjs.wasm -------------------------------------------------------------------------------- /dist/license.assimp.txt: -------------------------------------------------------------------------------- 1 | Open Asset Import Library (assimp) 2 | 3 | Copyright (c) 2006-2021, assimp team 4 | All rights reserved. 5 | 6 | Redistribution and use of this software in source and binary forms, 7 | with or without modification, are permitted provided that the 8 | following conditions are met: 9 | 10 | * Redistributions of source code must retain the above 11 | copyright notice, this list of conditions and the 12 | following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above 15 | copyright notice, this list of conditions and the 16 | following disclaimer in the documentation and/or other 17 | materials provided with the distribution. 18 | 19 | * Neither the name of the assimp team, nor the names of its 20 | contributors may be used to endorse or promote products 21 | derived from this software without specific prior 22 | written permission of the assimp team. 23 | 24 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | 37 | 38 | ****************************************************************************** 39 | 40 | AN EXCEPTION applies to all files in the ./test/models-nonbsd folder. 41 | These are 3d models for testing purposes, from various free sources 42 | on the internet. They are - unless otherwise stated - copyright of 43 | their respective creators, which may impose additional requirements 44 | on the use of their work. For any of these models, see 45 | .source.txt for more legal information. Contact us if you 46 | are a copyright holder and believe that we credited you inproperly or 47 | if you don't want your files to appear in the repository. 48 | 49 | 50 | ****************************************************************************** 51 | 52 | Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors 53 | http://code.google.com/p/poly2tri/ 54 | 55 | All rights reserved. 56 | Redistribution and use in source and binary forms, with or without modification, 57 | are permitted provided that the following conditions are met: 58 | 59 | * Redistributions of source code must retain the above copyright notice, 60 | this list of conditions and the following disclaimer. 61 | * Redistributions in binary form must reproduce the above copyright notice, 62 | this list of conditions and the following disclaimer in the documentation 63 | and/or other materials provided with the distribution. 64 | * Neither the name of Poly2Tri nor the names of its contributors may be 65 | used to endorse or promote products derived from this software without specific 66 | prior written permission. 67 | 68 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 69 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 70 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 71 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 72 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 73 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 74 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 75 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 76 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 77 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 78 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 79 | -------------------------------------------------------------------------------- /dist/license.assimpjs.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Viktor Kovacs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/dist/assimpjs.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kovacsv/assimpjs/733a2c6c251bc31aa6e407087d63a68994836f1d/docs/dist/assimpjs.wasm -------------------------------------------------------------------------------- /docs/dist/license.assimp.txt: -------------------------------------------------------------------------------- 1 | Open Asset Import Library (assimp) 2 | 3 | Copyright (c) 2006-2021, assimp team 4 | All rights reserved. 5 | 6 | Redistribution and use of this software in source and binary forms, 7 | with or without modification, are permitted provided that the 8 | following conditions are met: 9 | 10 | * Redistributions of source code must retain the above 11 | copyright notice, this list of conditions and the 12 | following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above 15 | copyright notice, this list of conditions and the 16 | following disclaimer in the documentation and/or other 17 | materials provided with the distribution. 18 | 19 | * Neither the name of the assimp team, nor the names of its 20 | contributors may be used to endorse or promote products 21 | derived from this software without specific prior 22 | written permission of the assimp team. 23 | 24 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | 37 | 38 | ****************************************************************************** 39 | 40 | AN EXCEPTION applies to all files in the ./test/models-nonbsd folder. 41 | These are 3d models for testing purposes, from various free sources 42 | on the internet. They are - unless otherwise stated - copyright of 43 | their respective creators, which may impose additional requirements 44 | on the use of their work. For any of these models, see 45 | .source.txt for more legal information. Contact us if you 46 | are a copyright holder and believe that we credited you inproperly or 47 | if you don't want your files to appear in the repository. 48 | 49 | 50 | ****************************************************************************** 51 | 52 | Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors 53 | http://code.google.com/p/poly2tri/ 54 | 55 | All rights reserved. 56 | Redistribution and use in source and binary forms, with or without modification, 57 | are permitted provided that the following conditions are met: 58 | 59 | * Redistributions of source code must retain the above copyright notice, 60 | this list of conditions and the following disclaimer. 61 | * Redistributions in binary form must reproduce the above copyright notice, 62 | this list of conditions and the following disclaimer in the documentation 63 | and/or other materials provided with the distribution. 64 | * Neither the name of Poly2Tri nor the names of its contributors may be 65 | used to endorse or promote products derived from this software without specific 66 | prior written permission. 67 | 68 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 69 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 70 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 71 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 72 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 73 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 74 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 75 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 76 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 77 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 78 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 79 | -------------------------------------------------------------------------------- /docs/dist/license.assimpjs.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Viktor Kovacs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/images/assimpjs_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kovacsv/assimpjs/733a2c6c251bc31aa6e407087d63a68994836f1d/docs/images/assimpjs_logo.png -------------------------------------------------------------------------------- /docs/images/assimpjs_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 115 | -------------------------------------------------------------------------------- /docs/images/assimpjs_logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kovacsv/assimpjs/733a2c6c251bc31aa6e407087d63a68994836f1d/docs/images/assimpjs_logo_small.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | AssimpJS Demo 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 |
22 | This site is a demonstration of assimpjs, the emscripten interface for the assimp library. You can try it out just by simply dragging and dropping a 3D model in this browser window. The result is the json representation of the model provided by assimp. 23 |
24 |
25 |
26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /docs/json-formatter/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Mohsen Azimi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /docs/json-formatter/json-formatter.cjs.js: -------------------------------------------------------------------------------- 1 | "use strict";function __$styleInject(e){if(e&&"undefined"!=typeof window){var t=document.createElement("style");return t.setAttribute("media","screen"),t.innerHTML=e,document.head.appendChild(t),e}}function escapeString(e){return e.replace(/"/g,'\\"')}function getType(e){return null===e?"null":typeof e}function isObject(e){return!!e&&"object"==typeof e}function getObjectName(e){if(void 0===e)return"";if(null===e)return"Object";if("object"==typeof e&&!e.constructor)return"Object";var t=/function ([^(]*)/.exec(e.constructor.toString());return t&&t.length>1?t[1]:""}function getValuePreview(e,t,r){return"null"===e||"undefined"===e?e:("string"!==e&&"stringifiable"!==e||(r='"'+escapeString(r)+'"'),"function"===e?t.toString().replace(/[\r\n]/g,"").replace(/\{.*\}/,"")+"{…}":r)}function getPreview(e){var t="";return isObject(e)?(t=getObjectName(e),Array.isArray(e)&&(t+="["+e.length+"]")):t=getValuePreview(getType(e),e,e),t}function cssClass(e){return"json-formatter-"+e}function createElement(e,t,r){var n=document.createElement(e);return t&&n.classList.add(cssClass(t)),void 0!==r&&(r instanceof Node?n.appendChild(r):n.appendChild(document.createTextNode(String(r)))),n}__$styleInject('.json-formatter-row {\n font-family: monospace;\n}\n.json-formatter-row,\n.json-formatter-row a,\n.json-formatter-row a:hover {\n color: black;\n text-decoration: none;\n}\n.json-formatter-row .json-formatter-row {\n margin-left: 1rem;\n}\n.json-formatter-row .json-formatter-children.json-formatter-empty {\n opacity: 0.5;\n margin-left: 1rem;\n}\n.json-formatter-row .json-formatter-children.json-formatter-empty:after {\n display: none;\n}\n.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-object:after {\n content: "No properties";\n}\n.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-array:after {\n content: "[]";\n}\n.json-formatter-row .json-formatter-string,\n.json-formatter-row .json-formatter-stringifiable {\n color: green;\n white-space: pre;\n word-wrap: break-word;\n}\n.json-formatter-row .json-formatter-number {\n color: blue;\n}\n.json-formatter-row .json-formatter-boolean {\n color: red;\n}\n.json-formatter-row .json-formatter-null {\n color: #855A00;\n}\n.json-formatter-row .json-formatter-undefined {\n color: #ca0b69;\n}\n.json-formatter-row .json-formatter-function {\n color: #FF20ED;\n}\n.json-formatter-row .json-formatter-date {\n background-color: rgba(0, 0, 0, 0.05);\n}\n.json-formatter-row .json-formatter-url {\n text-decoration: underline;\n color: blue;\n cursor: pointer;\n}\n.json-formatter-row .json-formatter-bracket {\n color: blue;\n}\n.json-formatter-row .json-formatter-key {\n color: #00008B;\n padding-right: 0.2rem;\n}\n.json-formatter-row .json-formatter-toggler-link {\n cursor: pointer;\n}\n.json-formatter-row .json-formatter-toggler {\n line-height: 1.2rem;\n font-size: 0.7rem;\n vertical-align: middle;\n opacity: 0.6;\n cursor: pointer;\n padding-right: 0.2rem;\n}\n.json-formatter-row .json-formatter-toggler:after {\n display: inline-block;\n transition: transform 100ms ease-in;\n content: "►";\n}\n.json-formatter-row > a > .json-formatter-preview-text {\n opacity: 0;\n transition: opacity 0.15s ease-in;\n font-style: italic;\n}\n.json-formatter-row:hover > a > .json-formatter-preview-text {\n opacity: 0.6;\n}\n.json-formatter-row.json-formatter-open > .json-formatter-toggler-link .json-formatter-toggler:after {\n transform: rotate(90deg);\n}\n.json-formatter-row.json-formatter-open > .json-formatter-children:after {\n display: inline-block;\n}\n.json-formatter-row.json-formatter-open > a > .json-formatter-preview-text {\n display: none;\n}\n.json-formatter-row.json-formatter-open.json-formatter-empty:after {\n display: block;\n}\n.json-formatter-dark.json-formatter-row {\n font-family: monospace;\n}\n.json-formatter-dark.json-formatter-row,\n.json-formatter-dark.json-formatter-row a,\n.json-formatter-dark.json-formatter-row a:hover {\n color: white;\n text-decoration: none;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-row {\n margin-left: 1rem;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty {\n opacity: 0.5;\n margin-left: 1rem;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty:after {\n display: none;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-object:after {\n content: "No properties";\n}\n.json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-array:after {\n content: "[]";\n}\n.json-formatter-dark.json-formatter-row .json-formatter-string,\n.json-formatter-dark.json-formatter-row .json-formatter-stringifiable {\n color: #31F031;\n white-space: pre;\n word-wrap: break-word;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-number {\n color: #66C2FF;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-boolean {\n color: #EC4242;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-null {\n color: #EEC97D;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-undefined {\n color: #ef8fbe;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-function {\n color: #FD48CB;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-date {\n background-color: rgba(255, 255, 255, 0.05);\n}\n.json-formatter-dark.json-formatter-row .json-formatter-url {\n text-decoration: underline;\n color: #027BFF;\n cursor: pointer;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-bracket {\n color: #9494FF;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-key {\n color: #23A0DB;\n padding-right: 0.2rem;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-toggler-link {\n cursor: pointer;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-toggler {\n line-height: 1.2rem;\n font-size: 0.7rem;\n vertical-align: middle;\n opacity: 0.6;\n cursor: pointer;\n padding-right: 0.2rem;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-toggler:after {\n display: inline-block;\n transition: transform 100ms ease-in;\n content: "►";\n}\n.json-formatter-dark.json-formatter-row > a > .json-formatter-preview-text {\n opacity: 0;\n transition: opacity 0.15s ease-in;\n font-style: italic;\n}\n.json-formatter-dark.json-formatter-row:hover > a > .json-formatter-preview-text {\n opacity: 0.6;\n}\n.json-formatter-dark.json-formatter-row.json-formatter-open > .json-formatter-toggler-link .json-formatter-toggler:after {\n transform: rotate(90deg);\n}\n.json-formatter-dark.json-formatter-row.json-formatter-open > .json-formatter-children:after {\n display: inline-block;\n}\n.json-formatter-dark.json-formatter-row.json-formatter-open > a > .json-formatter-preview-text {\n display: none;\n}\n.json-formatter-dark.json-formatter-row.json-formatter-open.json-formatter-empty:after {\n display: block;\n}\n');var DATE_STRING_REGEX=/(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/,PARTIAL_DATE_REGEX=/\d{2}:\d{2}:\d{2} GMT-\d{4}/,JSON_DATE_REGEX=/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/,MAX_ANIMATED_TOGGLE_ITEMS=10,requestAnimationFrame=window.requestAnimationFrame||function(e){return e(),0},_defaultConfig={hoverPreviewEnabled:!1,hoverPreviewArrayCount:100,hoverPreviewFieldCount:5,animateOpen:!0,animateClose:!0,theme:null,useToJSON:!0,sortPropertiesBy:null},JSONFormatter=function(){function e(e,t,r,n){void 0===t&&(t=1),void 0===r&&(r=_defaultConfig),this.json=e,this.open=t,this.config=r,this.key=n,this._isOpen=null,void 0===this.config.hoverPreviewEnabled&&(this.config.hoverPreviewEnabled=_defaultConfig.hoverPreviewEnabled),void 0===this.config.hoverPreviewArrayCount&&(this.config.hoverPreviewArrayCount=_defaultConfig.hoverPreviewArrayCount),void 0===this.config.hoverPreviewFieldCount&&(this.config.hoverPreviewFieldCount=_defaultConfig.hoverPreviewFieldCount),void 0===this.config.useToJSON&&(this.config.useToJSON=_defaultConfig.useToJSON),""===this.key&&(this.key='""')}return Object.defineProperty(e.prototype,"isOpen",{get:function(){return null!==this._isOpen?this._isOpen:this.open>0},set:function(e){this._isOpen=e},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"isDate",{get:function(){return this.json instanceof Date||"string"===this.type&&(DATE_STRING_REGEX.test(this.json)||JSON_DATE_REGEX.test(this.json)||PARTIAL_DATE_REGEX.test(this.json))},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"isUrl",{get:function(){return"string"===this.type&&0===this.json.indexOf("http")},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"isArray",{get:function(){return Array.isArray(this.json)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"isObject",{get:function(){return isObject(this.json)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"isEmptyObject",{get:function(){return!this.keys.length&&!this.isArray},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"isEmpty",{get:function(){return this.isEmptyObject||this.keys&&!this.keys.length&&this.isArray},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"useToJSON",{get:function(){return this.config.useToJSON&&"stringifiable"===this.type},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"hasKey",{get:function(){return void 0!==this.key},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"constructorName",{get:function(){return getObjectName(this.json)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"type",{get:function(){return this.config.useToJSON&&this.json&&this.json.toJSON?"stringifiable":getType(this.json)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"keys",{get:function(){if(this.isObject){var e=Object.keys(this.json);return!this.isArray&&this.config.sortPropertiesBy?e.sort(this.config.sortPropertiesBy):e}return[]},enumerable:!0,configurable:!0}),e.prototype.toggleOpen=function(){this.isOpen=!this.isOpen,this.element&&(this.isOpen?this.appendChildren(this.config.animateOpen):this.removeChildren(this.config.animateClose),this.element.classList.toggle(cssClass("open")))},e.prototype.openAtDepth=function(e){void 0===e&&(e=1),e<0||(this.open=e,this.isOpen=0!==e,this.element&&(this.removeChildren(!1),0===e?this.element.classList.remove(cssClass("open")):(this.appendChildren(this.config.animateOpen),this.element.classList.add(cssClass("open")))))},e.prototype.getInlinepreview=function(){var e=this;if(this.isArray)return this.json.length>this.config.hoverPreviewArrayCount?"Array["+this.json.length+"]":"["+this.json.map(getPreview).join(", ")+"]";var t=this.keys,r=t.slice(0,this.config.hoverPreviewFieldCount).map((function(t){return t+":"+getPreview(e.json[t])})),n=t.length>=this.config.hoverPreviewFieldCount?"…":"";return"{"+r.join(", ")+n+"}"},e.prototype.render=function(){this.element=createElement("div","row");var e=this.isObject?createElement("a","toggler-link"):createElement("span");if(this.isObject&&!this.useToJSON&&e.appendChild(createElement("span","toggler")),this.hasKey&&e.appendChild(createElement("span","key",this.key+":")),this.isObject&&!this.useToJSON){var t=createElement("span","value"),r=createElement("span"),n=createElement("span","constructor-name",this.constructorName);if(r.appendChild(n),this.isArray){var o=createElement("span");o.appendChild(createElement("span","bracket","[")),o.appendChild(createElement("span","number",this.json.length)),o.appendChild(createElement("span","bracket","]")),r.appendChild(o)}t.appendChild(r),e.appendChild(t)}else{(t=this.isUrl?createElement("a"):createElement("span")).classList.add(cssClass(this.type)),this.isDate&&t.classList.add(cssClass("date")),this.isUrl&&(t.classList.add(cssClass("url")),t.setAttribute("href",this.json));var s=getValuePreview(this.type,this.json,this.useToJSON?this.json.toJSON():this.json);t.appendChild(document.createTextNode(s)),e.appendChild(t)}if(this.isObject&&this.config.hoverPreviewEnabled){var i=createElement("span","preview-text");i.appendChild(document.createTextNode(this.getInlinepreview())),e.appendChild(i)}var a=createElement("div","children");return this.isObject&&a.classList.add(cssClass("object")),this.isArray&&a.classList.add(cssClass("array")),this.isEmpty&&a.classList.add(cssClass("empty")),this.config&&this.config.theme&&this.element.classList.add(cssClass(this.config.theme)),this.isOpen&&this.element.classList.add(cssClass("open")),this.element.appendChild(e),this.element.appendChild(a),this.isObject&&this.isOpen&&this.appendChildren(),this.isObject&&!this.useToJSON&&e.addEventListener("click",this.toggleOpen.bind(this)),this.element},e.prototype.appendChildren=function(t){var r=this;void 0===t&&(t=!1);var n=this.element.querySelector("div."+cssClass("children"));if(n&&!this.isEmpty)if(t){var o=0,s=function(){var t=r.keys[o],i=new e(r.json[t],r.open-1,r.config,t);n.appendChild(i.render()),(o+=1)MAX_ANIMATED_TOGGLE_ITEMS?s():requestAnimationFrame(s))};requestAnimationFrame(s)}else this.keys.forEach((function(t){var o=new e(r.json[t],r.open-1,r.config,t);n.appendChild(o.render())}))},e.prototype.removeChildren=function(e){void 0===e&&(e=!1);var t=this.element.querySelector("div."+cssClass("children"));if(e){var r=0,n=function(){t&&t.children.length&&(t.removeChild(t.children[0]),(r+=1)>MAX_ANIMATED_TOGGLE_ITEMS?n():requestAnimationFrame(n))};requestAnimationFrame(n)}else t&&(t.innerHTML="")},e}();module.exports=JSONFormatter; 2 | -------------------------------------------------------------------------------- /docs/json-formatter/json-formatter.css: -------------------------------------------------------------------------------- 1 | .json-formatter-row { 2 | font-family: monospace; 3 | } 4 | .json-formatter-row, 5 | .json-formatter-row a, 6 | .json-formatter-row a:hover { 7 | color: black; 8 | text-decoration: none; 9 | } 10 | .json-formatter-row .json-formatter-row { 11 | margin-left: 1rem; 12 | } 13 | .json-formatter-row .json-formatter-children.json-formatter-empty { 14 | opacity: 0.5; 15 | margin-left: 1rem; 16 | } 17 | .json-formatter-row .json-formatter-children.json-formatter-empty:after { 18 | display: none; 19 | } 20 | .json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-object:after { 21 | content: "No properties"; 22 | } 23 | .json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-array:after { 24 | content: "[]"; 25 | } 26 | .json-formatter-row .json-formatter-string, 27 | .json-formatter-row .json-formatter-stringifiable { 28 | color: green; 29 | white-space: pre; 30 | word-wrap: break-word; 31 | } 32 | .json-formatter-row .json-formatter-number { 33 | color: blue; 34 | } 35 | .json-formatter-row .json-formatter-boolean { 36 | color: red; 37 | } 38 | .json-formatter-row .json-formatter-null { 39 | color: #855A00; 40 | } 41 | .json-formatter-row .json-formatter-undefined { 42 | color: #ca0b69; 43 | } 44 | .json-formatter-row .json-formatter-function { 45 | color: #FF20ED; 46 | } 47 | .json-formatter-row .json-formatter-date { 48 | background-color: rgba(0, 0, 0, 0.05); 49 | } 50 | .json-formatter-row .json-formatter-url { 51 | text-decoration: underline; 52 | color: blue; 53 | cursor: pointer; 54 | } 55 | .json-formatter-row .json-formatter-bracket { 56 | color: blue; 57 | } 58 | .json-formatter-row .json-formatter-key { 59 | color: #00008B; 60 | padding-right: 0.2rem; 61 | } 62 | .json-formatter-row .json-formatter-toggler-link { 63 | cursor: pointer; 64 | } 65 | .json-formatter-row .json-formatter-toggler { 66 | line-height: 1.2rem; 67 | font-size: 0.7rem; 68 | vertical-align: middle; 69 | opacity: 0.6; 70 | cursor: pointer; 71 | padding-right: 0.2rem; 72 | } 73 | .json-formatter-row .json-formatter-toggler:after { 74 | display: inline-block; 75 | transition: transform 100ms ease-in; 76 | content: "►"; 77 | } 78 | .json-formatter-row > a > .json-formatter-preview-text { 79 | opacity: 0; 80 | transition: opacity 0.15s ease-in; 81 | font-style: italic; 82 | } 83 | .json-formatter-row:hover > a > .json-formatter-preview-text { 84 | opacity: 0.6; 85 | } 86 | .json-formatter-row.json-formatter-open > .json-formatter-toggler-link .json-formatter-toggler:after { 87 | transform: rotate(90deg); 88 | } 89 | .json-formatter-row.json-formatter-open > .json-formatter-children:after { 90 | display: inline-block; 91 | } 92 | .json-formatter-row.json-formatter-open > a > .json-formatter-preview-text { 93 | display: none; 94 | } 95 | .json-formatter-row.json-formatter-open.json-formatter-empty:after { 96 | display: block; 97 | } 98 | .json-formatter-dark.json-formatter-row { 99 | font-family: monospace; 100 | } 101 | .json-formatter-dark.json-formatter-row, 102 | .json-formatter-dark.json-formatter-row a, 103 | .json-formatter-dark.json-formatter-row a:hover { 104 | color: white; 105 | text-decoration: none; 106 | } 107 | .json-formatter-dark.json-formatter-row .json-formatter-row { 108 | margin-left: 1rem; 109 | } 110 | .json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty { 111 | opacity: 0.5; 112 | margin-left: 1rem; 113 | } 114 | .json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty:after { 115 | display: none; 116 | } 117 | .json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-object:after { 118 | content: "No properties"; 119 | } 120 | .json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-array:after { 121 | content: "[]"; 122 | } 123 | .json-formatter-dark.json-formatter-row .json-formatter-string, 124 | .json-formatter-dark.json-formatter-row .json-formatter-stringifiable { 125 | color: #31F031; 126 | white-space: pre; 127 | word-wrap: break-word; 128 | } 129 | .json-formatter-dark.json-formatter-row .json-formatter-number { 130 | color: #66C2FF; 131 | } 132 | .json-formatter-dark.json-formatter-row .json-formatter-boolean { 133 | color: #EC4242; 134 | } 135 | .json-formatter-dark.json-formatter-row .json-formatter-null { 136 | color: #EEC97D; 137 | } 138 | .json-formatter-dark.json-formatter-row .json-formatter-undefined { 139 | color: #ef8fbe; 140 | } 141 | .json-formatter-dark.json-formatter-row .json-formatter-function { 142 | color: #FD48CB; 143 | } 144 | .json-formatter-dark.json-formatter-row .json-formatter-date { 145 | background-color: rgba(255, 255, 255, 0.05); 146 | } 147 | .json-formatter-dark.json-formatter-row .json-formatter-url { 148 | text-decoration: underline; 149 | color: #027BFF; 150 | cursor: pointer; 151 | } 152 | .json-formatter-dark.json-formatter-row .json-formatter-bracket { 153 | color: #9494FF; 154 | } 155 | .json-formatter-dark.json-formatter-row .json-formatter-key { 156 | color: #23A0DB; 157 | padding-right: 0.2rem; 158 | } 159 | .json-formatter-dark.json-formatter-row .json-formatter-toggler-link { 160 | cursor: pointer; 161 | } 162 | .json-formatter-dark.json-formatter-row .json-formatter-toggler { 163 | line-height: 1.2rem; 164 | font-size: 0.7rem; 165 | vertical-align: middle; 166 | opacity: 0.6; 167 | cursor: pointer; 168 | padding-right: 0.2rem; 169 | } 170 | .json-formatter-dark.json-formatter-row .json-formatter-toggler:after { 171 | display: inline-block; 172 | transition: transform 100ms ease-in; 173 | content: "►"; 174 | } 175 | .json-formatter-dark.json-formatter-row > a > .json-formatter-preview-text { 176 | opacity: 0; 177 | transition: opacity 0.15s ease-in; 178 | font-style: italic; 179 | } 180 | .json-formatter-dark.json-formatter-row:hover > a > .json-formatter-preview-text { 181 | opacity: 0.6; 182 | } 183 | .json-formatter-dark.json-formatter-row.json-formatter-open > .json-formatter-toggler-link .json-formatter-toggler:after { 184 | transform: rotate(90deg); 185 | } 186 | .json-formatter-dark.json-formatter-row.json-formatter-open > .json-formatter-children:after { 187 | display: inline-block; 188 | } 189 | .json-formatter-dark.json-formatter-row.json-formatter-open > a > .json-formatter-preview-text { 190 | display: none; 191 | } 192 | .json-formatter-dark.json-formatter-row.json-formatter-open.json-formatter-empty:after { 193 | display: block; 194 | } 195 | -------------------------------------------------------------------------------- /docs/json-formatter/json-formatter.esm.js: -------------------------------------------------------------------------------- 1 | function t(t){return null===t?"null":typeof t}function e(t){return!!t&&"object"==typeof t}function r(t){if(void 0===t)return"";if(null===t)return"Object";if("object"==typeof t&&!t.constructor)return"Object";var e=/function ([^(]*)/.exec(t.constructor.toString());return e&&e.length>1?e[1]:""}function n(t,e,r){return"null"===t||"undefined"===t?t:("string"!==t&&"stringifiable"!==t||(r='"'+r.replace(/"/g,'\\"')+'"'),"function"===t?e.toString().replace(/[\r\n]/g,"").replace(/\{.*\}/,"")+"{…}":r)}function o(o){var i="";return e(o)?(i=r(o),Array.isArray(o)&&(i+="["+o.length+"]")):i=n(t(o),o,o),i}function i(t){return"json-formatter-"+t}function s(t,e,r){var n=document.createElement(t);return e&&n.classList.add(i(e)),void 0!==r&&(r instanceof Node?n.appendChild(r):n.appendChild(document.createTextNode(String(r)))),n}!function(t){if(t&&"undefined"!=typeof window){var e=document.createElement("style");e.setAttribute("media","screen"),e.innerHTML=t,document.head.appendChild(e)}}('.json-formatter-row {\n font-family: monospace;\n}\n.json-formatter-row,\n.json-formatter-row a,\n.json-formatter-row a:hover {\n color: black;\n text-decoration: none;\n}\n.json-formatter-row .json-formatter-row {\n margin-left: 1rem;\n}\n.json-formatter-row .json-formatter-children.json-formatter-empty {\n opacity: 0.5;\n margin-left: 1rem;\n}\n.json-formatter-row .json-formatter-children.json-formatter-empty:after {\n display: none;\n}\n.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-object:after {\n content: "No properties";\n}\n.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-array:after {\n content: "[]";\n}\n.json-formatter-row .json-formatter-string,\n.json-formatter-row .json-formatter-stringifiable {\n color: green;\n white-space: pre;\n word-wrap: break-word;\n}\n.json-formatter-row .json-formatter-number {\n color: blue;\n}\n.json-formatter-row .json-formatter-boolean {\n color: red;\n}\n.json-formatter-row .json-formatter-null {\n color: #855A00;\n}\n.json-formatter-row .json-formatter-undefined {\n color: #ca0b69;\n}\n.json-formatter-row .json-formatter-function {\n color: #FF20ED;\n}\n.json-formatter-row .json-formatter-date {\n background-color: rgba(0, 0, 0, 0.05);\n}\n.json-formatter-row .json-formatter-url {\n text-decoration: underline;\n color: blue;\n cursor: pointer;\n}\n.json-formatter-row .json-formatter-bracket {\n color: blue;\n}\n.json-formatter-row .json-formatter-key {\n color: #00008B;\n padding-right: 0.2rem;\n}\n.json-formatter-row .json-formatter-toggler-link {\n cursor: pointer;\n}\n.json-formatter-row .json-formatter-toggler {\n line-height: 1.2rem;\n font-size: 0.7rem;\n vertical-align: middle;\n opacity: 0.6;\n cursor: pointer;\n padding-right: 0.2rem;\n}\n.json-formatter-row .json-formatter-toggler:after {\n display: inline-block;\n transition: transform 100ms ease-in;\n content: "►";\n}\n.json-formatter-row > a > .json-formatter-preview-text {\n opacity: 0;\n transition: opacity 0.15s ease-in;\n font-style: italic;\n}\n.json-formatter-row:hover > a > .json-formatter-preview-text {\n opacity: 0.6;\n}\n.json-formatter-row.json-formatter-open > .json-formatter-toggler-link .json-formatter-toggler:after {\n transform: rotate(90deg);\n}\n.json-formatter-row.json-formatter-open > .json-formatter-children:after {\n display: inline-block;\n}\n.json-formatter-row.json-formatter-open > a > .json-formatter-preview-text {\n display: none;\n}\n.json-formatter-row.json-formatter-open.json-formatter-empty:after {\n display: block;\n}\n.json-formatter-dark.json-formatter-row {\n font-family: monospace;\n}\n.json-formatter-dark.json-formatter-row,\n.json-formatter-dark.json-formatter-row a,\n.json-formatter-dark.json-formatter-row a:hover {\n color: white;\n text-decoration: none;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-row {\n margin-left: 1rem;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty {\n opacity: 0.5;\n margin-left: 1rem;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty:after {\n display: none;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-object:after {\n content: "No properties";\n}\n.json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-array:after {\n content: "[]";\n}\n.json-formatter-dark.json-formatter-row .json-formatter-string,\n.json-formatter-dark.json-formatter-row .json-formatter-stringifiable {\n color: #31F031;\n white-space: pre;\n word-wrap: break-word;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-number {\n color: #66C2FF;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-boolean {\n color: #EC4242;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-null {\n color: #EEC97D;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-undefined {\n color: #ef8fbe;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-function {\n color: #FD48CB;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-date {\n background-color: rgba(255, 255, 255, 0.05);\n}\n.json-formatter-dark.json-formatter-row .json-formatter-url {\n text-decoration: underline;\n color: #027BFF;\n cursor: pointer;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-bracket {\n color: #9494FF;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-key {\n color: #23A0DB;\n padding-right: 0.2rem;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-toggler-link {\n cursor: pointer;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-toggler {\n line-height: 1.2rem;\n font-size: 0.7rem;\n vertical-align: middle;\n opacity: 0.6;\n cursor: pointer;\n padding-right: 0.2rem;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-toggler:after {\n display: inline-block;\n transition: transform 100ms ease-in;\n content: "►";\n}\n.json-formatter-dark.json-formatter-row > a > .json-formatter-preview-text {\n opacity: 0;\n transition: opacity 0.15s ease-in;\n font-style: italic;\n}\n.json-formatter-dark.json-formatter-row:hover > a > .json-formatter-preview-text {\n opacity: 0.6;\n}\n.json-formatter-dark.json-formatter-row.json-formatter-open > .json-formatter-toggler-link .json-formatter-toggler:after {\n transform: rotate(90deg);\n}\n.json-formatter-dark.json-formatter-row.json-formatter-open > .json-formatter-children:after {\n display: inline-block;\n}\n.json-formatter-dark.json-formatter-row.json-formatter-open > a > .json-formatter-preview-text {\n display: none;\n}\n.json-formatter-dark.json-formatter-row.json-formatter-open.json-formatter-empty:after {\n display: block;\n}\n');var a=/(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/,f=/\d{2}:\d{2}:\d{2} GMT-\d{4}/,m=/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/,l=window.requestAnimationFrame||function(t){return t(),0},d={hoverPreviewEnabled:!1,hoverPreviewArrayCount:100,hoverPreviewFieldCount:5,animateOpen:!0,animateClose:!0,theme:null,useToJSON:!0,sortPropertiesBy:null},c=function(){function c(t,e,r,n){void 0===e&&(e=1),void 0===r&&(r=d),this.json=t,this.open=e,this.config=r,this.key=n,this._isOpen=null,void 0===this.config.hoverPreviewEnabled&&(this.config.hoverPreviewEnabled=d.hoverPreviewEnabled),void 0===this.config.hoverPreviewArrayCount&&(this.config.hoverPreviewArrayCount=d.hoverPreviewArrayCount),void 0===this.config.hoverPreviewFieldCount&&(this.config.hoverPreviewFieldCount=d.hoverPreviewFieldCount),void 0===this.config.useToJSON&&(this.config.useToJSON=d.useToJSON),""===this.key&&(this.key='""')}return Object.defineProperty(c.prototype,"isOpen",{get:function(){return null!==this._isOpen?this._isOpen:this.open>0},set:function(t){this._isOpen=t},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"isDate",{get:function(){return this.json instanceof Date||"string"===this.type&&(a.test(this.json)||m.test(this.json)||f.test(this.json))},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"isUrl",{get:function(){return"string"===this.type&&0===this.json.indexOf("http")},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"isArray",{get:function(){return Array.isArray(this.json)},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"isObject",{get:function(){return e(this.json)},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"isEmptyObject",{get:function(){return!this.keys.length&&!this.isArray},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"isEmpty",{get:function(){return this.isEmptyObject||this.keys&&!this.keys.length&&this.isArray},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"useToJSON",{get:function(){return this.config.useToJSON&&"stringifiable"===this.type},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"hasKey",{get:function(){return void 0!==this.key},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"constructorName",{get:function(){return r(this.json)},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"type",{get:function(){return this.config.useToJSON&&this.json&&this.json.toJSON?"stringifiable":t(this.json)},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"keys",{get:function(){if(this.isObject){var t=Object.keys(this.json);return!this.isArray&&this.config.sortPropertiesBy?t.sort(this.config.sortPropertiesBy):t}return[]},enumerable:!0,configurable:!0}),c.prototype.toggleOpen=function(){this.isOpen=!this.isOpen,this.element&&(this.isOpen?this.appendChildren(this.config.animateOpen):this.removeChildren(this.config.animateClose),this.element.classList.toggle(i("open")))},c.prototype.openAtDepth=function(t){void 0===t&&(t=1),t<0||(this.open=t,this.isOpen=0!==t,this.element&&(this.removeChildren(!1),0===t?this.element.classList.remove(i("open")):(this.appendChildren(this.config.animateOpen),this.element.classList.add(i("open")))))},c.prototype.getInlinepreview=function(){var t=this;if(this.isArray)return this.json.length>this.config.hoverPreviewArrayCount?"Array["+this.json.length+"]":"["+this.json.map(o).join(", ")+"]";var e=this.keys,r=e.slice(0,this.config.hoverPreviewFieldCount).map((function(e){return e+":"+o(t.json[e])})),n=e.length>=this.config.hoverPreviewFieldCount?"…":"";return"{"+r.join(", ")+n+"}"},c.prototype.render=function(){this.element=s("div","row");var t=this.isObject?s("a","toggler-link"):s("span");if(this.isObject&&!this.useToJSON&&t.appendChild(s("span","toggler")),this.hasKey&&t.appendChild(s("span","key",this.key+":")),this.isObject&&!this.useToJSON){var e=s("span","value"),r=s("span"),o=s("span","constructor-name",this.constructorName);if(r.appendChild(o),this.isArray){var a=s("span");a.appendChild(s("span","bracket","[")),a.appendChild(s("span","number",this.json.length)),a.appendChild(s("span","bracket","]")),r.appendChild(a)}e.appendChild(r),t.appendChild(e)}else{(e=this.isUrl?s("a"):s("span")).classList.add(i(this.type)),this.isDate&&e.classList.add(i("date")),this.isUrl&&(e.classList.add(i("url")),e.setAttribute("href",this.json));var f=n(this.type,this.json,this.useToJSON?this.json.toJSON():this.json);e.appendChild(document.createTextNode(f)),t.appendChild(e)}if(this.isObject&&this.config.hoverPreviewEnabled){var m=s("span","preview-text");m.appendChild(document.createTextNode(this.getInlinepreview())),t.appendChild(m)}var l=s("div","children");return this.isObject&&l.classList.add(i("object")),this.isArray&&l.classList.add(i("array")),this.isEmpty&&l.classList.add(i("empty")),this.config&&this.config.theme&&this.element.classList.add(i(this.config.theme)),this.isOpen&&this.element.classList.add(i("open")),this.element.appendChild(t),this.element.appendChild(l),this.isObject&&this.isOpen&&this.appendChildren(),this.isObject&&!this.useToJSON&&t.addEventListener("click",this.toggleOpen.bind(this)),this.element},c.prototype.appendChildren=function(t){var e=this;void 0===t&&(t=!1);var r=this.element.querySelector("div."+i("children"));if(r&&!this.isEmpty)if(t){var n=0,o=function(){var t=e.keys[n],i=new c(e.json[t],e.open-1,e.config,t);r.appendChild(i.render()),(n+=1)10?o():l(o))};l(o)}else this.keys.forEach((function(t){var n=new c(e.json[t],e.open-1,e.config,t);r.appendChild(n.render())}))},c.prototype.removeChildren=function(t){void 0===t&&(t=!1);var e=this.element.querySelector("div."+i("children"));if(t){var r=0,n=function(){e&&e.children.length&&(e.removeChild(e.children[0]),(r+=1)>10?n():l(n))};l(n)}else e&&(e.innerHTML="")},c}();export default c; 2 | -------------------------------------------------------------------------------- /docs/json-formatter/json-formatter.umd.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).JSONFormatter=e()}(this,(function(){"use strict";function t(t){return null===t?"null":typeof t}function e(t){return!!t&&"object"==typeof t}function r(t){if(void 0===t)return"";if(null===t)return"Object";if("object"==typeof t&&!t.constructor)return"Object";var e=/function ([^(]*)/.exec(t.constructor.toString());return e&&e.length>1?e[1]:""}function n(t,e,r){return"null"===t||"undefined"===t?t:("string"!==t&&"stringifiable"!==t||(r='"'+r.replace(/"/g,'\\"')+'"'),"function"===t?e.toString().replace(/[\r\n]/g,"").replace(/\{.*\}/,"")+"{…}":r)}function o(o){var i="";return e(o)?(i=r(o),Array.isArray(o)&&(i+="["+o.length+"]")):i=n(t(o),o,o),i}function i(t){return"json-formatter-"+t}function s(t,e,r){var n=document.createElement(t);return e&&n.classList.add(i(e)),void 0!==r&&(r instanceof Node?n.appendChild(r):n.appendChild(document.createTextNode(String(r)))),n}!function(t){if(t&&"undefined"!=typeof window){var e=document.createElement("style");e.setAttribute("media","screen"),e.innerHTML=t,document.head.appendChild(e)}}('.json-formatter-row {\n font-family: monospace;\n}\n.json-formatter-row,\n.json-formatter-row a,\n.json-formatter-row a:hover {\n color: black;\n text-decoration: none;\n}\n.json-formatter-row .json-formatter-row {\n margin-left: 1rem;\n}\n.json-formatter-row .json-formatter-children.json-formatter-empty {\n opacity: 0.5;\n margin-left: 1rem;\n}\n.json-formatter-row .json-formatter-children.json-formatter-empty:after {\n display: none;\n}\n.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-object:after {\n content: "No properties";\n}\n.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-array:after {\n content: "[]";\n}\n.json-formatter-row .json-formatter-string,\n.json-formatter-row .json-formatter-stringifiable {\n color: green;\n white-space: pre;\n word-wrap: break-word;\n}\n.json-formatter-row .json-formatter-number {\n color: blue;\n}\n.json-formatter-row .json-formatter-boolean {\n color: red;\n}\n.json-formatter-row .json-formatter-null {\n color: #855A00;\n}\n.json-formatter-row .json-formatter-undefined {\n color: #ca0b69;\n}\n.json-formatter-row .json-formatter-function {\n color: #FF20ED;\n}\n.json-formatter-row .json-formatter-date {\n background-color: rgba(0, 0, 0, 0.05);\n}\n.json-formatter-row .json-formatter-url {\n text-decoration: underline;\n color: blue;\n cursor: pointer;\n}\n.json-formatter-row .json-formatter-bracket {\n color: blue;\n}\n.json-formatter-row .json-formatter-key {\n color: #00008B;\n padding-right: 0.2rem;\n}\n.json-formatter-row .json-formatter-toggler-link {\n cursor: pointer;\n}\n.json-formatter-row .json-formatter-toggler {\n line-height: 1.2rem;\n font-size: 0.7rem;\n vertical-align: middle;\n opacity: 0.6;\n cursor: pointer;\n padding-right: 0.2rem;\n}\n.json-formatter-row .json-formatter-toggler:after {\n display: inline-block;\n transition: transform 100ms ease-in;\n content: "►";\n}\n.json-formatter-row > a > .json-formatter-preview-text {\n opacity: 0;\n transition: opacity 0.15s ease-in;\n font-style: italic;\n}\n.json-formatter-row:hover > a > .json-formatter-preview-text {\n opacity: 0.6;\n}\n.json-formatter-row.json-formatter-open > .json-formatter-toggler-link .json-formatter-toggler:after {\n transform: rotate(90deg);\n}\n.json-formatter-row.json-formatter-open > .json-formatter-children:after {\n display: inline-block;\n}\n.json-formatter-row.json-formatter-open > a > .json-formatter-preview-text {\n display: none;\n}\n.json-formatter-row.json-formatter-open.json-formatter-empty:after {\n display: block;\n}\n.json-formatter-dark.json-formatter-row {\n font-family: monospace;\n}\n.json-formatter-dark.json-formatter-row,\n.json-formatter-dark.json-formatter-row a,\n.json-formatter-dark.json-formatter-row a:hover {\n color: white;\n text-decoration: none;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-row {\n margin-left: 1rem;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty {\n opacity: 0.5;\n margin-left: 1rem;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty:after {\n display: none;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-object:after {\n content: "No properties";\n}\n.json-formatter-dark.json-formatter-row .json-formatter-children.json-formatter-empty.json-formatter-array:after {\n content: "[]";\n}\n.json-formatter-dark.json-formatter-row .json-formatter-string,\n.json-formatter-dark.json-formatter-row .json-formatter-stringifiable {\n color: #31F031;\n white-space: pre;\n word-wrap: break-word;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-number {\n color: #66C2FF;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-boolean {\n color: #EC4242;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-null {\n color: #EEC97D;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-undefined {\n color: #ef8fbe;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-function {\n color: #FD48CB;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-date {\n background-color: rgba(255, 255, 255, 0.05);\n}\n.json-formatter-dark.json-formatter-row .json-formatter-url {\n text-decoration: underline;\n color: #027BFF;\n cursor: pointer;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-bracket {\n color: #9494FF;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-key {\n color: #23A0DB;\n padding-right: 0.2rem;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-toggler-link {\n cursor: pointer;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-toggler {\n line-height: 1.2rem;\n font-size: 0.7rem;\n vertical-align: middle;\n opacity: 0.6;\n cursor: pointer;\n padding-right: 0.2rem;\n}\n.json-formatter-dark.json-formatter-row .json-formatter-toggler:after {\n display: inline-block;\n transition: transform 100ms ease-in;\n content: "►";\n}\n.json-formatter-dark.json-formatter-row > a > .json-formatter-preview-text {\n opacity: 0;\n transition: opacity 0.15s ease-in;\n font-style: italic;\n}\n.json-formatter-dark.json-formatter-row:hover > a > .json-formatter-preview-text {\n opacity: 0.6;\n}\n.json-formatter-dark.json-formatter-row.json-formatter-open > .json-formatter-toggler-link .json-formatter-toggler:after {\n transform: rotate(90deg);\n}\n.json-formatter-dark.json-formatter-row.json-formatter-open > .json-formatter-children:after {\n display: inline-block;\n}\n.json-formatter-dark.json-formatter-row.json-formatter-open > a > .json-formatter-preview-text {\n display: none;\n}\n.json-formatter-dark.json-formatter-row.json-formatter-open.json-formatter-empty:after {\n display: block;\n}\n');var a=/(^\d{1,4}[\.|\\/|-]\d{1,2}[\.|\\/|-]\d{1,4})(\s*(?:0?[1-9]:[0-5]|1(?=[012])\d:[0-5])\d\s*[ap]m)?$/,f=/\d{2}:\d{2}:\d{2} GMT-\d{4}/,m=/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/,l=window.requestAnimationFrame||function(t){return t(),0},d={hoverPreviewEnabled:!1,hoverPreviewArrayCount:100,hoverPreviewFieldCount:5,animateOpen:!0,animateClose:!0,theme:null,useToJSON:!0,sortPropertiesBy:null};return function(){function c(t,e,r,n){void 0===e&&(e=1),void 0===r&&(r=d),this.json=t,this.open=e,this.config=r,this.key=n,this._isOpen=null,void 0===this.config.hoverPreviewEnabled&&(this.config.hoverPreviewEnabled=d.hoverPreviewEnabled),void 0===this.config.hoverPreviewArrayCount&&(this.config.hoverPreviewArrayCount=d.hoverPreviewArrayCount),void 0===this.config.hoverPreviewFieldCount&&(this.config.hoverPreviewFieldCount=d.hoverPreviewFieldCount),void 0===this.config.useToJSON&&(this.config.useToJSON=d.useToJSON),""===this.key&&(this.key='""')}return Object.defineProperty(c.prototype,"isOpen",{get:function(){return null!==this._isOpen?this._isOpen:this.open>0},set:function(t){this._isOpen=t},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"isDate",{get:function(){return this.json instanceof Date||"string"===this.type&&(a.test(this.json)||m.test(this.json)||f.test(this.json))},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"isUrl",{get:function(){return"string"===this.type&&0===this.json.indexOf("http")},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"isArray",{get:function(){return Array.isArray(this.json)},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"isObject",{get:function(){return e(this.json)},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"isEmptyObject",{get:function(){return!this.keys.length&&!this.isArray},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"isEmpty",{get:function(){return this.isEmptyObject||this.keys&&!this.keys.length&&this.isArray},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"useToJSON",{get:function(){return this.config.useToJSON&&"stringifiable"===this.type},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"hasKey",{get:function(){return void 0!==this.key},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"constructorName",{get:function(){return r(this.json)},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"type",{get:function(){return this.config.useToJSON&&this.json&&this.json.toJSON?"stringifiable":t(this.json)},enumerable:!0,configurable:!0}),Object.defineProperty(c.prototype,"keys",{get:function(){if(this.isObject){var t=Object.keys(this.json);return!this.isArray&&this.config.sortPropertiesBy?t.sort(this.config.sortPropertiesBy):t}return[]},enumerable:!0,configurable:!0}),c.prototype.toggleOpen=function(){this.isOpen=!this.isOpen,this.element&&(this.isOpen?this.appendChildren(this.config.animateOpen):this.removeChildren(this.config.animateClose),this.element.classList.toggle(i("open")))},c.prototype.openAtDepth=function(t){void 0===t&&(t=1),t<0||(this.open=t,this.isOpen=0!==t,this.element&&(this.removeChildren(!1),0===t?this.element.classList.remove(i("open")):(this.appendChildren(this.config.animateOpen),this.element.classList.add(i("open")))))},c.prototype.getInlinepreview=function(){var t=this;if(this.isArray)return this.json.length>this.config.hoverPreviewArrayCount?"Array["+this.json.length+"]":"["+this.json.map(o).join(", ")+"]";var e=this.keys,r=e.slice(0,this.config.hoverPreviewFieldCount).map((function(e){return e+":"+o(t.json[e])})),n=e.length>=this.config.hoverPreviewFieldCount?"…":"";return"{"+r.join(", ")+n+"}"},c.prototype.render=function(){this.element=s("div","row");var t=this.isObject?s("a","toggler-link"):s("span");if(this.isObject&&!this.useToJSON&&t.appendChild(s("span","toggler")),this.hasKey&&t.appendChild(s("span","key",this.key+":")),this.isObject&&!this.useToJSON){var e=s("span","value"),r=s("span"),o=s("span","constructor-name",this.constructorName);if(r.appendChild(o),this.isArray){var a=s("span");a.appendChild(s("span","bracket","[")),a.appendChild(s("span","number",this.json.length)),a.appendChild(s("span","bracket","]")),r.appendChild(a)}e.appendChild(r),t.appendChild(e)}else{(e=this.isUrl?s("a"):s("span")).classList.add(i(this.type)),this.isDate&&e.classList.add(i("date")),this.isUrl&&(e.classList.add(i("url")),e.setAttribute("href",this.json));var f=n(this.type,this.json,this.useToJSON?this.json.toJSON():this.json);e.appendChild(document.createTextNode(f)),t.appendChild(e)}if(this.isObject&&this.config.hoverPreviewEnabled){var m=s("span","preview-text");m.appendChild(document.createTextNode(this.getInlinepreview())),t.appendChild(m)}var l=s("div","children");return this.isObject&&l.classList.add(i("object")),this.isArray&&l.classList.add(i("array")),this.isEmpty&&l.classList.add(i("empty")),this.config&&this.config.theme&&this.element.classList.add(i(this.config.theme)),this.isOpen&&this.element.classList.add(i("open")),this.element.appendChild(t),this.element.appendChild(l),this.isObject&&this.isOpen&&this.appendChildren(),this.isObject&&!this.useToJSON&&t.addEventListener("click",this.toggleOpen.bind(this)),this.element},c.prototype.appendChildren=function(t){var e=this;void 0===t&&(t=!1);var r=this.element.querySelector("div."+i("children"));if(r&&!this.isEmpty)if(t){var n=0,o=function(){var t=e.keys[n],i=new c(e.json[t],e.open-1,e.config,t);r.appendChild(i.render()),(n+=1)10?o():l(o))};l(o)}else this.keys.forEach((function(t){var n=new c(e.json[t],e.open-1,e.config,t);r.appendChild(n.render())}))},c.prototype.removeChildren=function(t){void 0===t&&(t=!1);var e=this.element.querySelector("div."+i("children"));if(t){var r=0,n=function(){e&&e.children.length&&(e.removeChild(e.children[0]),(r+=1)>10?n():l(n))};l(n)}else e&&(e.innerHTML="")},c}()})); 2 | -------------------------------------------------------------------------------- /docs/source/demo.css: -------------------------------------------------------------------------------- 1 | html, body 2 | { 3 | color: #fafafa; 4 | background: #222222; 5 | font-family: Arial; 6 | } 7 | 8 | a 9 | { 10 | color: #008ab8; 11 | text-decoration: none; 12 | } 13 | 14 | a:hover 15 | { 16 | text-decoration: underline; 17 | } 18 | 19 | #main 20 | { 21 | width: 920px; 22 | margin: 1.0em auto; 23 | } 24 | 25 | #dragdrop 26 | { 27 | color: inherit; 28 | background: #282828; 29 | font-size: 1.6em; 30 | text-align: center; 31 | padding: 1.0em; 32 | border: 1px solid #444444; 33 | border-radius: 0.2em; 34 | } 35 | 36 | #info 37 | { 38 | color: #dddddd; 39 | line-height: 1.4em; 40 | margin: 1.0em 0.0em; 41 | } 42 | 43 | #result 44 | { 45 | padding: 1.0em; 46 | border: 1px solid #444444; 47 | border-radius: 0.2em; 48 | } 49 | 50 | @media only screen and (max-width: 920px) 51 | { 52 | 53 | #main 54 | { 55 | width: 90%; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /docs/source/demo.js: -------------------------------------------------------------------------------- 1 | function GetFileBuffer (file) 2 | { 3 | return new Promise ((resolve, reject) => { 4 | let reader = new FileReader (); 5 | reader.onloadend = function (event) { 6 | if (event.target.readyState === FileReader.DONE) { 7 | resolve (event.target.result); 8 | } 9 | }; 10 | reader.onerror = function () { 11 | reject (); 12 | }; 13 | reader.readAsArrayBuffer (file); 14 | }); 15 | } 16 | 17 | function LoadModel (ajs, files, onLoad) 18 | { 19 | let downloadFiles = []; 20 | for (let i = 0; i < files.length; i++) { 21 | downloadFiles.push (GetFileBuffer (files[i])); 22 | } 23 | Promise.all (downloadFiles).then ((arrayBuffers) => { 24 | let fileList = new ajs.FileList (); 25 | for (let i = 0; i < arrayBuffers.length; i++) { 26 | fileList.AddFile (files[i].name, new Uint8Array (arrayBuffers[i])); 27 | } 28 | let result = ajs.ConvertFileList (fileList, 'assjson'); 29 | if (!result.IsSuccess () || result.FileCount () == 0) { 30 | onLoad ({ 31 | error: result.GetErrorCode () 32 | }); 33 | } else { 34 | let resultFile = result.GetFile (0); 35 | let jsonContent = new TextDecoder ().decode (resultFile.GetContent ()); 36 | let resultJson = JSON.parse (jsonContent); 37 | onLoad (resultJson); 38 | } 39 | }).catch (() => { 40 | onLoad ({ 41 | error: 'failed_to_load_file' 42 | }); 43 | }); 44 | } 45 | 46 | window.onload = function () { 47 | let dragDropDiv = document.getElementById ('dragdrop'); 48 | let resultDiv = document.getElementById ('result'); 49 | resultDiv.style.display = 'none'; 50 | let texts = { 51 | loadingAssimpJS : 'LOADING ASSIMPJS...', 52 | loadingModel : 'LOADING MODEL...', 53 | dragDrop : 'DRAG & DROP YOUR FILES' 54 | }; 55 | dragDropDiv.innerHTML = texts.loadingAssimpJS; 56 | assimpjs ().then (function (ajs) { 57 | dragDropDiv.innerHTML = texts.dragDrop; 58 | window.addEventListener ('dragstart', (ev) => { 59 | ev.preventDefault (); 60 | }, false); 61 | window.addEventListener ('dragover', (ev) => { 62 | ev.stopPropagation (); 63 | ev.preventDefault (); 64 | ev.dataTransfer.dropEffect = 'copy'; 65 | }, false); 66 | window.addEventListener ('drop', (ev) => { 67 | ev.stopPropagation (); 68 | ev.preventDefault (); 69 | let files = ev.dataTransfer.files; 70 | if (files.length > 0) { 71 | dragDropDiv.innerHTML = texts.loadingModel; 72 | resultDiv.style.display = 'none'; 73 | resultDiv.innerHTML = ''; 74 | setTimeout (() => { 75 | LoadModel (ajs, files, (result) => { 76 | dragDropDiv.innerHTML = texts.dragDrop; 77 | let formatter = new JSONFormatter (result, 2, { 78 | 'theme' : 'dark' 79 | }); 80 | resultDiv.style.display = 'block'; 81 | resultDiv.appendChild (formatter.render ()); 82 | }); 83 | }, 10); 84 | } 85 | }, false); 86 | }); 87 | }; 88 | -------------------------------------------------------------------------------- /examples/browser_download_test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | AssimpJS Demo 9 | 10 | 11 | 52 | 53 | 54 | 55 |

56 | 
57 | 
58 | 
59 | 


--------------------------------------------------------------------------------
/examples/browser_dragdrop_test.html:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | 
 4 | 
 5 |     
 6 |     
 7 | 
 8 |     AssimpJS Demo
 9 |     
10 |     
11 |     
87 | 
88 | 
89 | 
90 | 	

91 | 
92 | 
93 | 
94 | 


--------------------------------------------------------------------------------
/examples/node_local_delay_load_test.js:
--------------------------------------------------------------------------------
 1 | let fs = require ('fs');
 2 | const assimpjs = require ('../dist/assimpjs.js')();
 3 | 
 4 | assimpjs.then ((ajs) => {
 5 |     // convert model
 6 |     let result = ajs.ConvertFile (
 7 |         // file name
 8 |         'cube_with_materials.obj',
 9 |         // file format
10 |         'assjson',
11 |         // file content as arraybuffer
12 |         fs.readFileSync ('testfiles/cube_with_materials.obj'),
13 |         // check if file exists by name
14 |         function (fileName) {
15 |             return fs.existsSync ('testfiles/' + fileName);
16 |         },
17 |         // get file content as arraybuffer by name
18 |         function (fileName) {
19 |             return fs.readFileSync ('testfiles/' + fileName);
20 |         }
21 |     );
22 |     
23 |     // check if the conversion succeeded
24 |     if (!result.IsSuccess () || result.FileCount () == 0) {
25 |         console.log (result.GetErrorCode ());
26 |         return;
27 |     }
28 | 
29 |     // get the result file, and convert to string
30 |     let resultFile = result.GetFile (0);
31 |     let jsonContent = new TextDecoder ().decode (resultFile.GetContent ());
32 | 
33 |     // parse the result json
34 |     let resultJson = JSON.parse (jsonContent);
35 | 
36 |     console.log (resultJson);
37 | });
38 | 


--------------------------------------------------------------------------------
/examples/node_local_load_test.js:
--------------------------------------------------------------------------------
 1 | let fs = require ('fs');
 2 | const assimpjs = require ('../dist/assimpjs.js')();
 3 | 
 4 | assimpjs.then ((ajs) => {
 5 |     // create new file list object
 6 |     let fileList = new ajs.FileList ();
 7 |     
 8 |     // add model files
 9 |     fileList.AddFile (
10 |         'cube_with_materials.obj',
11 |         fs.readFileSync ('testfiles/cube_with_materials.obj')
12 |     );
13 |     fileList.AddFile (
14 |         'cube_with_materials.mtl',
15 |         fs.readFileSync ('testfiles/cube_with_materials.mtl')
16 |     );
17 |     
18 |     // convert file list to assimp json
19 |     let result = ajs.ConvertFileList (fileList, 'assjson');
20 | 
21 |     // check if the conversion succeeded
22 |     if (!result.IsSuccess () || result.FileCount () == 0) {
23 |         console.log (result.GetErrorCode ());
24 |         return;
25 |     }
26 | 
27 |     // get the result file, and convert to string
28 |     let resultFile = result.GetFile (0);
29 |     let jsonContent = new TextDecoder ().decode (resultFile.GetContent ());
30 | 
31 |     // parse the result json
32 |     let resultJson = JSON.parse (jsonContent);
33 |     
34 |     console.log (resultJson);
35 | });
36 | 


--------------------------------------------------------------------------------
/examples/testfiles/cube_texture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kovacsv/assimpjs/733a2c6c251bc31aa6e407087d63a68994836f1d/examples/testfiles/cube_texture.png


--------------------------------------------------------------------------------
/examples/testfiles/cube_with_materials.3ds:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kovacsv/assimpjs/733a2c6c251bc31aa6e407087d63a68994836f1d/examples/testfiles/cube_with_materials.3ds


--------------------------------------------------------------------------------
/examples/testfiles/cube_with_materials.mtl:
--------------------------------------------------------------------------------
 1 | newmtl Red
 2 | Ka 0.000000 0.000000 0.000000
 3 | Kd 0.800000 0.000000 0.000000
 4 | Ks 0.500000 0.500000 0.500000
 5 | 
 6 | newmtl Green
 7 | Ka 0.000000 0.000000 0.000000
 8 | Kd 0.000000 0.800000 0.000000
 9 | Ks 0.500000 0.500000 0.500000
10 | 
11 | newmtl Blue
12 | Ka 0.000000 0.000000 0.000000
13 | Kd 0.000000 0.000000 0.800000
14 | Ks 0.500000 0.500000 0.500000
15 | 
16 | newmtl White
17 | Ka 0.000000 0.000000 0.000000
18 | Kd 0.800000 0.800000 0.800000
19 | Ks 0.500000 0.500000 0.500000
20 | 
21 | newmtl Texture
22 | Ka 0.000000 0.000000 0.000000
23 | Kd 0.800000 0.800000 0.800000
24 | Ks 0.500000 0.500000 0.500000
25 | map_Kd cube_texture.png
26 | 


--------------------------------------------------------------------------------
/examples/testfiles/cube_with_materials.obj:
--------------------------------------------------------------------------------
 1 | # Cube with Materials
 2 | 
 3 | mtllib cube_with_materials.mtl
 4 | 
 5 | g Cube
 6 | 
 7 | v 0.0 0.0 0.0
 8 | v 1.0 0.0 0.0
 9 | v 1.0 1.0 0.0
10 | v 0.0 1.0 0.0
11 | v 0.0 0.0 1.0
12 | v 1.0 0.0 1.0
13 | v 1.0 1.0 1.0
14 | v 0.0 1.0 1.0
15 | 
16 | vn 1.0 0.0 0.0
17 | vn -1.0 0.0 0.0
18 | vn 0.0 1.0 0.0
19 | vn 0.0 -1.0 0.0
20 | vn 0.0 0.0 1.0
21 | vn 0.0 0.0 -1.0
22 | 
23 | vt 0.0 0.0
24 | vt 1.0 0.0
25 | vt 1.0 1.0
26 | vt 0.0 1.0
27 | 
28 | usemtl Red
29 | f 1/1/4 2/2/4 6/3/4 5/4/4
30 | usemtl Green
31 | f 2/1/1 3/2/1 7/3/1 6/4/1
32 | usemtl Blue
33 | f 3/1/3 4/2/3 8/3/3 7/4/3
34 | usemtl Texture
35 | f 4/1/2 1/2/2 5/3/2 8/4/2
36 | usemtl White
37 | f 1/1/6 4/2/6 3/3/6 2/4/6
38 | f 5/1/5 6/2/5 7/3/5 8/4/5
39 | 


--------------------------------------------------------------------------------
/examples/testfiles/texture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kovacsv/assimpjs/733a2c6c251bc31aa6e407087d63a68994836f1d/examples/testfiles/texture.png


--------------------------------------------------------------------------------
/examples/testfiles/wrong.3ds:
--------------------------------------------------------------------------------
1 | invalid 3ds file
2 | 


--------------------------------------------------------------------------------
/execute_tests.bat:
--------------------------------------------------------------------------------
1 | npm test
2 | 


--------------------------------------------------------------------------------
/execute_tests.sh:
--------------------------------------------------------------------------------
1 | npm test
2 | 


--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 | 	"name": "assimpjs",
 3 | 	"version": "0.0.11",
 4 | 	"description": "Javascript interface for the assimp library.",
 5 | 	"license": "MIT",
 6 | 	"main": "./dist/assimpjs.js",
 7 | 	"repository": "github:kovacsv/assimpjs",
 8 | 	"keywords": [
 9 | 		"assimp",
10 | 		"3d",
11 | 		"model",
12 | 		"converter"
13 | 	],
14 | 	"devDependencies": {
15 | 		"http-server": "^0.12.3",
16 | 		"mocha": "^8.3.2"
17 | 	},
18 | 	"scripts": {
19 | 		"start": "http-server",
20 | 		"test": "mocha test --timeout 30000"
21 | 	},
22 | 	"dependencies": {}
23 | }
24 | 


--------------------------------------------------------------------------------
/start_server.bat:
--------------------------------------------------------------------------------
1 | npm start
2 | 


--------------------------------------------------------------------------------
/start_server.sh:
--------------------------------------------------------------------------------
1 | npm start
2 | 


--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
  1 | var fs = require ('fs');
  2 | var path = require ('path');
  3 | var assert = require ('assert');
  4 | 
  5 | var config = 'Release'
  6 | if (process.env.TEST_CONFIG !== undefined) {
  7 | 	config = process.env.TEST_CONFIG;
  8 | }
  9 | var assimpjs = require ('../build_wasm/' + config + '/assimpjs.js')();
 10 | 
 11 | var ajs = null;
 12 | before (async function () {
 13 | 	if (ajs !== null) {
 14 | 		return;
 15 | 	}
 16 | 	ajs = await assimpjs;
 17 | });
 18 | 
 19 | function GetTestFileLocation (fileName)
 20 | {
 21 | 	return path.join (__dirname, '../assimp/test/models/' + fileName);
 22 | }
 23 | 
 24 | function LoadModel (files)
 25 | {
 26 | 	let fileList = new ajs.FileList ();
 27 | 	for (let i = 0; i < files.length; i++) {
 28 | 		let filePath = GetTestFileLocation (files[i]);
 29 | 		fileList.AddFile (filePath, fs.readFileSync (filePath))
 30 | 	}
 31 | 	return ajs.ConvertFileList (fileList, 'assjson');
 32 | }
 33 | 
 34 | function IsError (files)
 35 | {
 36 | 	let result = LoadModel (files);
 37 | 	return !result.IsSuccess ();
 38 | }
 39 | 
 40 | function IsSuccess (files)
 41 | {
 42 | 	let result = LoadModel (files);
 43 | 	return result.IsSuccess ();
 44 | }
 45 | 
 46 | describe ('Importer', function () {
 47 | 
 48 | it ('Empty file list', function () {
 49 | 	assert (IsError ([]));
 50 | });
 51 | 
 52 | it ('Not importable file', function () {
 53 | 	assert (IsError (['3DS/test.png']));
 54 | });
 55 | 
 56 | it ('Independent order', function () {
 57 | 	assert (IsSuccess (['OBJ/cube_usemtl.obj', 'OBJ/cube_usemtl.mtl']));
 58 | 	assert (IsSuccess (['OBJ/cube_usemtl.mtl', 'OBJ/cube_usemtl.obj']));
 59 | });
 60 | 
 61 | it ('Delay load', function () {
 62 | 	let result = ajs.ConvertFile (
 63 | 		'OBJ/cube_usemtl.obj',
 64 | 		'assjson',
 65 | 		fs.readFileSync (GetTestFileLocation ('OBJ/cube_usemtl.obj')),
 66 | 		function (fileName) {
 67 | 			return fs.existsSync (GetTestFileLocation ('OBJ/' + fileName));
 68 | 		},
 69 | 		function (fileName) {
 70 | 			return fs.readFileSync (GetTestFileLocation ('OBJ/' + fileName));
 71 | 		}
 72 | 	);
 73 | 	assert (result.IsSuccess ());
 74 | 	assert (result.FileCount () == 1);
 75 | 	let jsonFile = result.GetFile (0);
 76 | 	let jsonString = new TextDecoder ().decode (jsonFile.GetContent ());
 77 | 	let scene = JSON.parse (jsonString);
 78 | 	assert.deepStrictEqual (scene.materials[1].properties[4].value, [1, 1, 1]);
 79 | });
 80 | 
 81 | it ('glTF export', function () {
 82 | 	let files = ['OBJ/cube_usemtl.obj', 'OBJ/cube_usemtl.mtl'];
 83 | 	let fileList = new ajs.FileList ();
 84 | 	for (let i = 0; i < files.length; i++) {
 85 | 		let filePath = GetTestFileLocation (files[i]);
 86 | 		fileList.AddFile (filePath, fs.readFileSync (filePath))
 87 | 	}
 88 | 	{
 89 | 		let result = ajs.ConvertFileList (fileList, 'gltf2');
 90 | 		assert (result.IsSuccess ());
 91 | 		assert.equal (result.FileCount (), 2);
 92 | 		assert.equal (result.GetFile (0).GetPath (), 'result.gltf');
 93 | 		assert.equal (result.GetFile (1).GetPath (), 'result.bin');
 94 | 	}
 95 | 	{
 96 | 		let result = ajs.ConvertFileList (fileList, 'glb2');
 97 | 		assert (result.IsSuccess ());
 98 | 		assert.equal (result.FileCount (), 1);
 99 | 		assert.equal (result.GetFile (0).GetPath (), 'result.glb');
100 | 	}
101 | });
102 | 
103 | it ('3D', function () {
104 | 	assert (IsSuccess (['3D/box.uc', '3D/box_a.3d', '3D/box_d.3d']));
105 | });
106 | 
107 | it ('3DS', function () {
108 | 	assert (IsSuccess (['3DS/test1.3ds']));
109 | 	assert (IsSuccess (['3DS/fels.3ds']));
110 | 	assert (IsSuccess (['3DS/cubes_with_alpha.3DS']));
111 | 	assert (IsSuccess (['3DS/cube_with_specular_texture.3DS']));
112 | 	assert (IsSuccess (['3DS/cube_with_diffuse_texture.3DS']));
113 | 	assert (IsSuccess (['3DS/RotatingCube.3DS']));
114 | });
115 | 
116 | it ('3MF', function () {
117 | 	assert (IsSuccess (['3MF/box.3mf']));
118 | });
119 | 
120 | it ('AC', function () {
121 | 	assert (IsSuccess (['AC/SphereWithLight.ac']));
122 | 	assert (IsSuccess (['AC/SphereWithLight_UTF8BOM.ac']));
123 | });
124 | 
125 | it ('AMF', function () {
126 | 	assert (IsSuccess (['AMF/test_with_mat.amf']));
127 | 	assert (IsSuccess (['AMF/test1.amf']));
128 | 	assert (IsSuccess (['AMF/test2.amf']));
129 | 	assert (IsSuccess (['AMF/test3.amf']));
130 | 	assert (IsSuccess (['AMF/test4.amf']));
131 | 	assert (IsSuccess (['AMF/test5.amf']));
132 | 	assert (IsSuccess (['AMF/test6.amf']));
133 | 	assert (IsSuccess (['AMF/test7.amf']));
134 | 	assert (IsSuccess (['AMF/test8.amf']));
135 | 	assert (IsSuccess (['AMF/test9.amf']));
136 | });
137 | 
138 | it ('ASE', function () {
139 | 	assert (IsSuccess (['ASE/ThreeCubesGreen.ASE']));
140 | 	assert (IsSuccess (['ASE/RotatingCube.ASE']));
141 | 	assert (IsSuccess (['ASE/CameraRollAnim.ase']));
142 | 	assert (IsSuccess (['ASE/CameraRollAnimWithChildObject.ase']));
143 | });
144 | 
145 | it ('B3D', function () {
146 | 	assert (IsSuccess (['B3D/WusonBlitz.b3d']));
147 | });
148 | 
149 | it ('BLEND', function () {
150 | 	assert (IsSuccess (['BLEND/box.blend']));
151 | 	assert (IsSuccess (['BLEND/AreaLight_269.blend']));
152 | });
153 | 
154 | it ('BVH', function () {
155 | 	assert (IsSuccess (['BVH/Boxing_Toes.bvh']));
156 | });
157 | 
158 | it ('COB', function () {
159 | 	assert (IsSuccess (['COB/molecule.cob']));
160 | 	assert (IsSuccess (['COB/dwarf.cob']));
161 | });
162 | 
163 | it ('COLLADA', function () {
164 | 	assert (IsSuccess (['Collada/duck.dae']));
165 | 	assert (IsSuccess (['Collada/duck.zae']));
166 | 	assert (IsSuccess (['Collada/COLLADA.dae']));
167 | 	assert (IsSuccess (['Collada/COLLADA_triangulate.dae']));
168 | 	assert (IsSuccess (['Collada/ConcavePolygon.dae']));
169 | 	assert (IsSuccess (['Collada/cube_tristrips.dae']));
170 | 	assert (IsSuccess (['Collada/cube_emptyTags.dae']));
171 | 	assert (IsSuccess (['Collada/cube_triangulate.dae']));
172 | 	assert (IsSuccess (['Collada/earthCylindrical.DAE']));
173 | 	assert (IsSuccess (['Collada/human.zae']));
174 | 	assert (IsSuccess (['Collada/lights.dae']));
175 | 	assert (IsSuccess (['Collada/sphere.dae']));
176 | 	assert (IsSuccess (['Collada/sphere_triangulate.dae']));
177 | 	assert (IsSuccess (['Collada/teapot_instancenodes.DAE']));
178 | 	assert (IsSuccess (['Collada/teapots.DAE']));
179 | });
180 | 
181 | it ('CSM', function () {
182 | 	assert (IsSuccess (['CSM/ThomasFechten.csm']));
183 | });
184 | 
185 | it ('DXF', function () {
186 | 	assert (IsSuccess (['DXF/PinkEggFromLW.dxf']));
187 | 	assert (IsSuccess (['DXF/wuson.dxf']));
188 | });
189 | 
190 | it ('FBX', function () {
191 | 	assert (IsSuccess (['FBX/box.fbx']));
192 | 	assert (IsSuccess (['FBX/cubes_nonames.fbx']));
193 | 	assert (IsSuccess (['FBX/cubes_with_names.fbx']));
194 | 	assert (IsSuccess (['FBX/global_settings.fbx']));
195 | 	assert (IsSuccess (['FBX/spider.fbx']));
196 | 	assert (IsSuccess (['FBX/phong_cube.fbx']));
197 | 	assert (IsSuccess (['FBX/embedded_ascii/box.FBX']));
198 | 	assert (IsSuccess (['FBX/embedded_ascii/box_embedded_texture_fragmented.fbx']));
199 | });
200 | 
201 | it ('glTF', function () {
202 | 	assert (IsSuccess (['glTF/BoxTextured-glTF/BoxTextured.gltf', 'glTF/BoxTextured-glTF/BoxTextured.bin']));
203 | 	assert (IsSuccess (['glTF/BoxTextured-glTF-Embedded/BoxTextured.gltf']));
204 | 	assert (IsSuccess (['glTF/CesiumMilkTruck/CesiumMilkTruck.gltf', 'glTF/CesiumMilkTruck/CesiumMilkTruck.bin']));
205 | });
206 | 
207 | it ('glTF2', function () {
208 | 	assert (IsSuccess (['glTF2/BoxTextured-glTF/BoxTextured.gltf', 'glTF2/BoxTextured-glTF/BoxTextured0.bin']));
209 | 	assert (IsSuccess (['glTF2/BoxTextured-glTF-Binary/BoxTextured.glb']));
210 | 	assert (IsSuccess (['glTF2/2CylinderEngine-glTF-Binary/2CylinderEngine.glb']));
211 | });
212 | 
213 | it ('HMP', function () {
214 | 	assert (IsSuccess (['HMP/terrain.hmp']));
215 | });
216 | 
217 | it ('IFC', function () {
218 | 	// IFC importer is disabled
219 | 	assert (IsError (['IFC/AC14-FZK-Haus.ifc']));
220 | });
221 | 
222 | it ('IRR', function () {
223 | 	// IRR importer is disabled
224 | 	assert (IsError (['IRR/box.irr']));
225 | });
226 | 
227 | it ('IRRMesh', function () {
228 | 	// IRRMESH importer is disabled
229 | 	assert (IsError (['IRRMesh/spider.irrmesh']));
230 | });
231 | 
232 | it ('LWO', function () {
233 | 	assert (IsSuccess (['LWO/LWO2/hierarchy.lwo']));
234 | 	assert (IsSuccess (['LWO/LWO2/nonplanar_polygon.lwo']));
235 | 	assert (IsSuccess (['LWO/LWO2/sphere_with_gradient.lwo']));
236 | 	assert (IsSuccess (['LWO/LWO2/sphere_with_mat_gloss_10pc.lwo']));
237 | 	assert (IsSuccess (['LWO/LWO2/transparency.lwo']));
238 | 	assert (IsSuccess (['LWO/LWO2/uvtest.lwo']));
239 | 	assert (IsSuccess (['LWO/LXOB_Modo/sphereWithVertMap.lxo']));
240 | 	assert (IsSuccess (['LWO/LWOB/sphere_with_mat_gloss_10pc.lwo']));
241 | });
242 | 
243 | it ('LWS', function () {
244 | 	assert (IsSuccess (['LWS/move_x.lws']));
245 | 	assert (IsSuccess (['LWS/simple_cube.lwo']));
246 | });
247 | 
248 | it ('M3D', function () {
249 | 	// M3D importer is disabled
250 | 	assert (IsError (['M3D/cube_usemtl.m3d']));
251 | });
252 | 
253 | it ('MD2', function () {
254 | 	assert (IsSuccess (['MD2/faerie.md2']));
255 | 	assert (IsSuccess (['MD2/sydney.md2']));
256 | });
257 | 
258 | it ('MD5', function () {
259 | 	assert (IsSuccess (['MD5/SimpleCube.md5mesh']));
260 | });
261 | 
262 | it ('MDC', function () {
263 | 	assert (IsSuccess (['MDC/spider.mdc']));
264 | });
265 | 
266 | it ('MDL (HL1)', function () {
267 | 	assert (IsSuccess (['MDL/MDL (HL1)/chrome_sphere.mdl']));
268 | });
269 | 
270 | it ('MDL3', function () {
271 | 	assert (IsSuccess (['MDL/MDL3 (3DGS A4)/minigun.MDL']));
272 | });
273 | 
274 | it ('MDL5', function () {
275 | 	assert (IsSuccess (['MDL/MDL5 (3DGS A5)/minigun_mdl5.mdl']));
276 | });
277 | 
278 | it ('MDL7', function () {
279 | 	assert (IsSuccess (['MDL/MDL7 (3DGS A7)/Sphere_DiffPinkBlueSpec_Alpha90.mdl']));
280 | });
281 | 
282 | it ('MS3D', function () {
283 | 	assert (IsSuccess (['MS3D/twospheres.ms3d']));
284 | 	assert (IsSuccess (['MS3D/twospheres_withmats.ms3d']));
285 | 	assert (IsSuccess (['MS3D/Wuson.ms3d']));
286 | });
287 | 
288 | it ('NFF', function () {
289 | 	assert (IsSuccess (['NFF/NFF/cylinder.nff']));
290 | 	assert (IsSuccess (['NFF/NFF/hexahedron.nff']));
291 | 	assert (IsSuccess (['NFF/NFF/spheres.nff']));
292 | });
293 | 
294 | it ('OBJ', function () {
295 | 	assert (IsSuccess (['OBJ/box.obj']));
296 | 	assert (IsSuccess (['OBJ/box_longline.obj']));
297 | 	assert (IsSuccess (['OBJ/box_mat_with_spaces.obj']));
298 | 	assert (IsSuccess (['OBJ/spider.obj']));
299 | 	assert (IsSuccess (['OBJ/cube_usemtl.obj']));
300 | 	assert (IsSuccess (['OBJ/cube_usemtl.obj', 'OBJ/cube_usemtl.mtl']));
301 | });
302 | 
303 | it ('OFF', function () {
304 | 	assert (IsSuccess (['OFF/Cube.off']));
305 | 	assert (IsSuccess (['OFF/Wuson.off']));
306 | });
307 | 
308 | it ('Ogre', function () {
309 | 	assert (IsSuccess (['Ogre/TheThing/Mesh.mesh.xml', 'Ogre/TheThing/BlockMat.material']));
310 | });
311 | 
312 | it ('OpenGEX', function () {
313 | 	assert (IsSuccess (['OpenGEX/Example.ogex']));
314 | 	assert (IsSuccess (['OpenGEX/camera.ogex']));
315 | });
316 | 
317 | it ('PLY', function () {
318 | 	assert (IsSuccess (['PLY/cube.ply']));
319 | 	assert (IsSuccess (['PLY/cube_binary.ply']));
320 | 	assert (IsSuccess (['PLY/cube_uv.ply']));
321 | 	assert (IsSuccess (['PLY/Wuson.ply']));
322 | });
323 | 
324 | it ('Q3D', function () {
325 | 	assert (IsSuccess (['Q3D/earth.q3o']));
326 | 	assert (IsSuccess (['Q3D/E-AT-AT.q3o']));
327 | 	assert (IsSuccess (['Q3D/WusonOrange.q3o']));
328 | 	assert (IsSuccess (['Q3D/WusonOrange.q3s']));
329 | });
330 | 
331 | it ('RAW', function () {
332 | 	// RAW importer is disabled
333 | 	assert (IsError (['RAW/WithColor.raw']));
334 | });
335 | 
336 | it ('SIB', function () {
337 | 	assert (IsSuccess (['SIB/heffalump.sib']));
338 | });
339 | 
340 | it ('SMD', function () {
341 | 	assert (IsSuccess (['SMD/triangle.smd']));
342 | 	assert (IsSuccess (['SMD/holy_grailref.smd']));
343 | 	assert (IsSuccess (['SMD/WusonSMD.smd']));
344 | });
345 | 
346 | it ('STL', function () {
347 | 	assert (IsSuccess (['STL/Spider_ascii.stl']));
348 | 	assert (IsSuccess (['STL/Spider_binary.stl']));
349 | 	assert (IsSuccess (['STL/sphereWithHole.stl']));
350 | 	assert (IsSuccess (['STL/3DSMaxExport.STL']));
351 | 	assert (IsSuccess (['STL/Wuson.stl']));
352 | });
353 | 
354 | it ('TER', function () {
355 | 	// TER importer is disabled
356 | 	assert (IsError (['TER/RealisticTerrain.ter']));
357 | });
358 | 
359 | it ('X', function () {
360 | 	assert (IsSuccess (['X/test_cube_text.x']));
361 | 	assert (IsSuccess (['X/test_cube_compressed.x']));
362 | 	assert (IsSuccess (['X/test_cube_binary.x']));
363 | });
364 | 
365 | it ('X3D', function () {
366 | 	// X3D importer is disabled
367 | 	assert (IsError (['X3D/ComputerKeyboard.x3d']));
368 | });
369 | 
370 | it ('XGL', function () {
371 | 	assert (IsSuccess (['XGL/cubes_with_alpha.zgl']));
372 | 	assert (IsSuccess (['XGL/sample_official.xgl']));
373 | 	assert (IsSuccess (['XGL/Wuson.zgl']));
374 | });
375 | 
376 | });
377 | 


--------------------------------------------------------------------------------
/tools/build_wasm_deb.sh:
--------------------------------------------------------------------------------
1 | # activate the path for the terminal session
2 | eval source ./emsdk_env.sh
3 | #cd "emsdk"
4 | eval emcmake cmake -B ./build_wasm -DEMSCRIPTEN=1 -DCMAKE_BUILD_TYPE=Release
5 | #cd "./build_wasm"
6 | eval emmake make -C build_wasm -j 12
7 | # message for user
8 | echo "Build Succeeded."
9 | 


--------------------------------------------------------------------------------
/tools/build_wasm_win.bat:
--------------------------------------------------------------------------------
 1 | pushd %~dp0\..
 2 | 
 3 | call emsdk\emsdk_env.bat
 4 | call emcmake cmake -B build_wasm -G "Unix Makefiles" -DEMSCRIPTEN=1 -DCMAKE_MAKE_PROGRAM=mingw32-make -DCMAKE_BUILD_TYPE=%1 . || goto :error
 5 | call emmake mingw32-make -C build_wasm || goto :error
 6 | popd
 7 | echo Build Succeeded.
 8 | 
 9 | popd
10 | exit /b 0
11 | 
12 | :error
13 | echo Build Failed with Error %errorlevel%.
14 | popd
15 | popd
16 | exit /b 1
17 | 


--------------------------------------------------------------------------------
/tools/build_wasm_win_dist.bat:
--------------------------------------------------------------------------------
 1 | pushd %~dp0\..
 2 | 
 3 | call tools\build_wasm_win_release.bat || goto :error
 4 | echo Build Succeeded.
 5 | 
 6 | call set TEST_CONFIG=Release
 7 | call npm run test || goto :error
 8 | 
 9 | mkdir dist
10 | copy build_wasm\Release\assimpjs.js dist\assimpjs.js || goto :error
11 | copy build_wasm\Release\assimpjs.wasm dist\assimpjs.wasm || goto :error
12 | copy assimp\LICENSE dist\license.assimp.txt || goto :error
13 | copy LICENSE.md dist\license.assimpjs.txt || goto :error
14 | xcopy dist\*.* docs\dist\*.* /K /D /H /Y
15 | 
16 | popd
17 | echo Distribution Succeeded.
18 | 
19 | exit /b 0
20 | 
21 | :error
22 | echo Distribution Failed with Error %errorlevel%.
23 | popd
24 | popd
25 | exit /b 1
26 | 


--------------------------------------------------------------------------------
/tools/build_wasm_win_release.bat:
--------------------------------------------------------------------------------
1 | pushd %~dp0\..
2 | call tools\build_wasm_win.bat Release
3 | popd
4 | 


--------------------------------------------------------------------------------
/tools/setup_emscripten_deb.sh:
--------------------------------------------------------------------------------
 1 | # check if emsdk path is there
 2 | if [ ! -d "emsdk" ]; then
 3 |   # clone if path is missing
 4 |   eval git clone --recursive https://github.com/emscripten-core/emsdk.git
 5 |   # enter emsdk path
 6 |   cd "emsdk"
 7 |   # install the version 3.1.56
 8 |   eval ./emsdk install 3.1.56
 9 |   # activate the version 3.1.56
10 |   eval ./emsdk activate 3.1.56
11 |   # activate the path for the terminal session
12 |   eval source ./emsdk_env.sh
13 | else
14 |   echo "Emscripten already set up!"
15 |   # enter emsdk path
16 |   cd "emsdk"
17 |   # activate the path for the terminal session
18 |   eval source ./emsdk_env.sh
19 | fi
20 | 


--------------------------------------------------------------------------------
/tools/setup_emscripten_win.bat:
--------------------------------------------------------------------------------
 1 | pushd %~dp0\..
 2 | 
 3 | call git clone https://github.com/emscripten-core/emsdk.git
 4 | call cd emsdk
 5 | call emsdk install 3.1.56
 6 | call emsdk activate 3.1.56
 7 | call emsdk install mingw-7.1.0-64bit
 8 | call emsdk activate mingw-7.1.0-64bit
 9 | call cd ..
10 | 
11 | popd
12 | 


--------------------------------------------------------------------------------