Merge With Lilys (#11)

* Correct Type-o

fix: incorrect spelling for Greasemonkey

* Update CODE_OF_CONDUCT.md

* Create CONTRIBUTING.md

* Update issue templates

* Apply morphs (#3)

Fix: fromBufferAttribute wasn't working with morphtargets so we set them manually
Fix: update tempVector to use morphVector is needed

* Minor adjustments

* task: make parity with my version

* task: @allanmaral did a great job on styling
fix: incorrect naming for OBJ files
fix: save item needs to be available - need to find a way to hide it
after it changes

* fix: check for non-zero vale of skinIndexNames
task: remove herosaver.js

* task: rewind face vertices when mirrored

* Merge With Lilys

* Update README.md
This commit is contained in:
Lucas 2019-10-17 10:33:48 +01:00 committed by GitHub
parent 81b6c04aeb
commit c881d994b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 699 additions and 16 deletions

4
.gitignore vendored
View File

@ -1,2 +1,2 @@
.vs/slnx.sqlite
.DS_Store
node_modules

View File

@ -30,7 +30,7 @@
function runinsert(){
// run the Herosaver Script
var xhr=new XMLHttpRequest;xhr.open("get","https://raw.githubusercontent.com/TeaWithLucas/Herosaver/master/herosaver.js",true);xhr.onreadystatechange=function(){if(xhr.readyState==4){var script=document.createElement("script");script.type="text/javascript";script.text=xhr.responseText;document.body.appendChild(script)}};xhr.send(null);
var xhr=new XMLHttpRequest;xhr.open("get","https://raw.githubusercontent.com/TeaWithLucas/Herosaver/master/dist/saver.min.js",true);xhr.onreadystatechange=function(){if(xhr.readyState==4){var script=document.createElement("script");script.type="text/javascript";script.text=xhr.responseText;document.body.appendChild(script)}};xhr.send(null);
};

View File

@ -9,9 +9,9 @@ Please **Always** think about the **developers** of such websites and try to **s
1. Go to the intended website
2. Open the Javascript Console [F12], then click on Console
3. Paste the following
```
var xhr=new XMLHttpRequest;xhr.open("get","https://raw.githubusercontent.com/TeaWithLucas/Herosaver/master/herosaver.js",true);xhr.onreadystatechange=function(){if(xhr.readyState==4){var script=document.createElement("script");script.type="text/javascript";script.text=xhr.responseText;document.body.appendChild(script)}};xhr.send(null);
var xhr=new XMLHttpRequest;xhr.open("get","https://raw.githubusercontent.com/TeaWithLucas/Herosaver/master/dist/saver.min.js",true);xhr.onreadystatechange=function(){if(xhr.readyState==4){var script=document.createElement("script");script.type="text/javascript";script.text=xhr.responseText;document.body.appendChild(script)}};xhr.send(null);
```
### Loading via Greecemonkey or other script loader
@ -23,29 +23,29 @@ This method should automatically load the script on page load. Current it doesn'
4. Save
## Buttons
* Export Model (STL) - Exports the current model and downloads a STL of it.
* Export (JSON) - Exports the current model settings in a JSON format.
* Import (JSON) - Imports a previously exported JSON file with model settings.
* Enlarge - Increases the size and rotates the model to match STL output for standard printing ```size:[10,10,10], rotation:[90,0,0]```
* Reset Scale - Resets the model and refreshes it, bug: refresh twice to reset some incorrect models.
* STL - Exports the current model and downloads a STL of it.
* OBJ - Exports the current model and downloads a OBJ of it.
* Subdivision Passes - Number of loop subdivision passes for the model.
* Save - Exports the current model settings in a JSON format.
* Load - Imports a previously exported JSON file with model settings.
## Bugs
Current bugs, open to solutions/suggestions
* Reset Scale Button doesnt work first press, need a second refresh to work.
* Autoloader.js doesnt work when page is reloaded, only on first page load.
* Some Geometry like facial experessions are not implemented, need to work on the THREE.js section.
* ~~Reset Scale Button doesnt work first press, need a second refresh to work.~~
* ~~Autoloader.js doesnt work when page is reloaded, only on first page load.~~
* ~~Some Geometry like facial experessions are not implemented, need to work on the THREE.js section.~~
* Shaders are not included, causing a more _'blocky'_ output, work on the THREE.js section is needed for this.
## Future work
Current things to work on, open to solutions/suggestions
* Rotation is off by 90 degrees, simple fix
* The buttons for enlarge and reset scale are a quick and ugly method, needs reworking to not affect the scale in brower if possible, if not, automatically change scale when downloading and resetting scale when downloaded. My lack of THREE.js experience means I am unsure how to do the latter.
* ~~Rotation is off by 90 degrees, simple fix~~
* ~~The buttons for enlarge and reset scale are a quick and ugly method, needs reworking to not affect the scale in brower if possible, if not, automatically change scale when downloading and resetting scale when downloaded. My lack of THREE.js experience means I am unsure how to do the latter.~~
## Limitations
Currently this is a compliled selection of various bits of code, so the output is not 100% great. If you want higher quality exports, consider purchasing the stl files or help work on the code :)
Currently this is a compiled selection of various bits of code, so the output is not 100% great. If you want higher quality exports, consider purchasing the stl files or help work on the code :)

1
dist/saver.min.js vendored Normal file

File diff suppressed because one or more lines are too long

341
package-lock.json generated Normal file
View File

@ -0,0 +1,341 @@
{
"name": "rollup-starter-lib",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@babel/code-frame": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
"integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
"dev": true,
"requires": {
"@babel/highlight": "^7.0.0"
}
},
"@babel/highlight": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
"integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"@types/estree": {
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
"dev": true
},
"@types/node": {
"version": "12.7.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.4.tgz",
"integrity": "sha512-W0+n1Y+gK/8G2P/piTkBBN38Qc5Q1ZSO6B5H3QmPCUewaiXOo2GCAWZ4ElZCcNhjJuBSUSLGFUJnmlCn5+nxOQ==",
"dev": true
},
"@types/resolve": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
"integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"acorn": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz",
"integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==",
"dev": true
},
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
},
"arrive": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/arrive/-/arrive-2.4.1.tgz",
"integrity": "sha1-VkyH8gvAm4DeeBEk2UMWlQBLgCA="
},
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
"dev": true
},
"builtin-modules": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz",
"integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==",
"dev": true
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
"commander": {
"version": "2.20.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
"integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
"dev": true
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"estree-walker": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
"integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
"dev": true
},
"esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true
},
"file-saver": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.2.tgz",
"integrity": "sha512-Wz3c3XQ5xroCxd1G8b7yL0Ehkf0TC9oYC6buPFkNnU9EnaPlifeAFCyCh+iewXTyFRcg0a6j3J7FmJsIhlhBdw=="
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"is-module": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
"integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
"dev": true
},
"is-reference": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.3.tgz",
"integrity": "sha512-W1iHHv/oyBb2pPxkBxtaewxa1BC58Pn5J0hogyCdefwUIvb6R+TGbAcIa4qPNYLqLhb3EnOgUf2MQkkF76BcKw==",
"dev": true,
"requires": {
"@types/estree": "0.0.39"
}
},
"jest-worker": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz",
"integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==",
"dev": true,
"requires": {
"merge-stream": "^2.0.0",
"supports-color": "^6.1.0"
},
"dependencies": {
"supports-color": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
"integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
"jquery": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz",
"integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw=="
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
},
"magic-string": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.2.tgz",
"integrity": "sha512-iLs9mPjh9IuTtRsqqhNGYcZXGei0Nh/A4xirrsqW7c+QhKVFL2vm7U09ru6cHRD22azaP/wMDgI+HCqbETMTtg==",
"dev": true,
"requires": {
"sourcemap-codec": "^1.4.4"
}
},
"merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
"dev": true
},
"path-parse": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
"dev": true
},
"resolve": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz",
"integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==",
"dev": true,
"requires": {
"path-parse": "^1.0.6"
}
},
"rollup": {
"version": "1.20.3",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-1.20.3.tgz",
"integrity": "sha512-/OMCkY0c6E8tleeVm4vQVDz24CkVgvueK3r8zTYu2AQNpjrcaPwO9hE+pWj5LTFrvvkaxt4MYIp2zha4y0lRvg==",
"dev": true,
"requires": {
"@types/estree": "0.0.39",
"@types/node": "^12.7.2",
"acorn": "^7.0.0"
}
},
"rollup-plugin-commonjs": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz",
"integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==",
"dev": true,
"requires": {
"estree-walker": "^0.6.1",
"is-reference": "^1.1.2",
"magic-string": "^0.25.2",
"resolve": "^1.11.0",
"rollup-pluginutils": "^2.8.1"
}
},
"rollup-plugin-node-resolve": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz",
"integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==",
"dev": true,
"requires": {
"@types/resolve": "0.0.8",
"builtin-modules": "^3.1.0",
"is-module": "^1.0.0",
"resolve": "^1.11.1",
"rollup-pluginutils": "^2.8.1"
}
},
"rollup-plugin-replace": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-replace/-/rollup-plugin-replace-2.2.0.tgz",
"integrity": "sha512-/5bxtUPkDHyBJAKketb4NfaeZjL5yLZdeUihSfbF2PQMz+rSTEb8ARKoOl3UBT4m7/X+QOXJo3sLTcq+yMMYTA==",
"dev": true,
"requires": {
"magic-string": "^0.25.2",
"rollup-pluginutils": "^2.6.0"
}
},
"rollup-plugin-terser": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.1.1.tgz",
"integrity": "sha512-McIMCDEY8EU6Y839C09UopeRR56wXHGdvKKjlfiZG/GrP6wvZQ62u2ko/Xh1MNH2M9WDL+obAAHySljIZYCuPQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"jest-worker": "^24.6.0",
"rollup-pluginutils": "^2.8.1",
"serialize-javascript": "^1.7.0",
"terser": "^4.1.0"
}
},
"rollup-pluginutils": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.1.tgz",
"integrity": "sha512-J5oAoysWar6GuZo0s+3bZ6sVZAC0pfqKz68De7ZgDi5z63jOVZn1uJL/+z1jeKHNbGII8kAyHF5q8LnxSX5lQg==",
"dev": true,
"requires": {
"estree-walker": "^0.6.1"
}
},
"serialize-javascript": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.8.0.tgz",
"integrity": "sha512-3tHgtF4OzDmeKYj6V9nSyceRS0UJ3C7VqyD2Yj28vC/z2j6jG5FmFGahOKMD9CrglxTm3tETr87jEypaYV8DUg==",
"dev": true
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
},
"source-map-support": {
"version": "0.5.13",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
"integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
"dev": true,
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"sourcemap-codec": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz",
"integrity": "sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg==",
"dev": true
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
},
"terser": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.2.0.tgz",
"integrity": "sha512-6lPt7lZdZ/13icQJp8XasFOwZjFJkxFFIb/N1fhYEQNoNI3Ilo3KABZ9OocZvZoB39r6SiIk/0+v/bt8nZoSeA==",
"dev": true,
"requires": {
"commander": "^2.20.0",
"source-map": "~0.6.1",
"source-map-support": "~0.5.12"
}
},
"three": {
"version": "0.109.0",
"resolved": "https://registry.npmjs.org/three/-/three-0.109.0.tgz",
"integrity": "sha512-XT99T3Hvgh2CEvwPdHYEunNE+clLK6KiT1U8En7YOgIqTUw4MrLeIc8zxQAJ6wbP8hhJaY5+Cff3jwBPpBa0gA=="
}
}
}

26
package.json Normal file
View File

@ -0,0 +1,26 @@
{
"name": "rollup-starter-lib",
"version": "1.0.0",
"browser": "dist/saver.min.js",
"dependencies": {
"arrive": "^2.4.1",
"file-saver": "^2.0.2",
"jquery": "^3.4.1",
"three": "^0.109.0"
},
"devDependencies": {
"rollup": "^1.20.3",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-terser": "^5.1.1"
},
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"pretest": "npm run build"
},
"files": [
"dist"
]
}

46
rollup.config.js Normal file
View File

@ -0,0 +1,46 @@
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import replace from 'rollup-plugin-replace';
import { terser } from 'rollup-plugin-terser';
import pkg from './package.json';
export default [
{
input: 'src/saver.js',
output: {
name: 'saver',
file: pkg.browser,
format: 'umd'
},
plugins: [
resolve(),
commonjs({
namedExports: {
'file-saver': ['saveAs'],
}
}),
replace({
' instanceof BufferGeometry': '.isBufferGeometry',
' instanceof Geometry': '.isGeometry'
}),
terser({
compress: {
arguments: true,
booleans_as_integers: true,
drop_console: true,
hoist_funs: true,
hoist_vars: true,
keep_fargs: false,
toplevel: true,
unsafe: true,
unsafe_Function: true,
passes: 2
},
mangle: {
eval: true,
toplevel: true,
}
})
]
}
];

117
src/finalizeMesh.js Normal file
View File

@ -0,0 +1,117 @@
import { Matrix4, Vector3, Vector4 } from "three";
var finalizeMesh = function() {};
finalizeMesh.prototype = {
constructor: finalizeMesh,
parse: function (mesh) {
if (!mesh.isMesh) {
console.warn('Mesh type unsupported', mesh);
return;
}
var vertex = new Vector3();
var i, l = [];
var nbVertex = 0;
var geometry = mesh.geometry;
var mrot = new Matrix4().makeRotationX(90 * Math.PI / 180);
var msca = new Matrix4().makeScale(10, 10, 10);
if (geometry.isBufferGeometry) {
var newGeometry = geometry.clone(geometry);
var vertices = geometry.getAttribute('position');
// vertices
if (vertices !== undefined) {
for (i = 0, l = vertices.count; i < l; i++ , nbVertex++) {
vertex.x = vertices.getX(i);
vertex.y = vertices.getY(i);
vertex.z = vertices.getZ(i);
if (geometry.skinIndexNames == undefined
|| geometry.skinIndexNames == 0) {
vertex.applyMatrix4(mesh.matrixWorld).applyMatrix4(mrot).applyMatrix4(msca);
newGeometry.attributes.position.setXYZ(i, vertex.x, vertex.y, vertex.z);
} else {
var finalVector = new Vector4();
if (geometry.morphTargetInfluences !== undefined) {
var morphVector = new Vector4(vertex.x, vertex.y, vertex.z);
var tempMorph = new Vector4();
for (var mt = 0; mt < geometry.morphAttributes.position.length; mt++) {
if (geometry.morphTargetInfluences[mt] == 0) continue;
if (geometry.morphTargetDictionary.hide == mt) continue;
var morph = new Vector4(
geometry.morphAttributes.position[mt].getX(i),
geometry.morphAttributes.position[mt].getY(i),
geometry.morphAttributes.position[mt].getZ(i));
tempMorph.addScaledVector(morph.sub(morphVector), geometry.morphTargetInfluences[mt]);
}
morphVector.add(tempMorph);
}
for (var si = 0; si < geometry.skinIndexNames.length; si++) {
var skinIndices = geometry.getAttribute([geometry.skinIndexNames[si]])
var weights = geometry.getAttribute([geometry.skinWeightNames[si]])
var skinIndex = [];
skinIndex[0] = skinIndices.getX(i);
skinIndex[1] = skinIndices.getY(i);
skinIndex[2] = skinIndices.getZ(i);
skinIndex[3] = skinIndices.getW(i);
var skinWeight = [];
skinWeight[0] = weights.getX(i);
skinWeight[1] = weights.getY(i);
skinWeight[2] = weights.getZ(i);
skinWeight[3] = weights.getW(i);
var inverses = [];
inverses[0] = mesh.skeleton.boneInverses[skinIndex[0]];
inverses[1] = mesh.skeleton.boneInverses[skinIndex[1]];
inverses[2] = mesh.skeleton.boneInverses[skinIndex[2]];
inverses[3] = mesh.skeleton.boneInverses[skinIndex[3]];
var skinMatrices = [];
skinMatrices[0] = mesh.skeleton.bones[skinIndex[0]].matrixWorld;
skinMatrices[1] = mesh.skeleton.bones[skinIndex[1]].matrixWorld;
skinMatrices[2] = mesh.skeleton.bones[skinIndex[2]].matrixWorld;
skinMatrices[3] = mesh.skeleton.bones[skinIndex[3]].matrixWorld;
for (var k = 0; k < 4; k++) {
if (geometry.morphTargetInfluences !== undefined) {
var tempVector = new Vector4(morphVector.x, morphVector.y, morphVector.z);
} else {
var tempVector = new Vector4(vertex.x, vertex.y, vertex.z);
}
tempVector.multiplyScalar(skinWeight[k]);
//the inverse takes the vector into local bone space
//which is then transformed to the appropriate world space
tempVector.applyMatrix4(inverses[k])
.applyMatrix4(skinMatrices[k])
.applyMatrix4(mrot).applyMatrix4(msca);
finalVector.add(tempVector);
}
}
newGeometry.attributes.position.setXYZ(i, finalVector.x, finalVector.y, finalVector.z);
}
}
}
} else {
console.warn( 'Geometry type unsupported', geometry );
}
return newGeometry;
}
};
export { finalizeMesh };

152
src/saver.js Executable file
View File

@ -0,0 +1,152 @@
import { MeshBasicMaterial, Group, Mesh } from 'three';
import { STLExporter } from 'three/examples/jsm/exporters/STLExporter.js';
import { OBJExporter } from 'three/examples/jsm/exporters/OBJExporter.js';
import { SubdivisionModifier } from 'three/examples/jsm/modifiers/SubdivisionModifier.js';
import { saveAs } from 'file-saver';
import jQuery from 'jquery';
import { arrive } from 'arrive';
import { finalizeMesh } from './finalizeMesh.js';
function save_stl() {
var smooth = jQuery('#subdivideSLT').val() > 0 ? jQuery('#subdivideSLT').val() : undefined;
var mirroredPose = CK.character.data.mirroredPose;
var group = process(CK.character, smooth, mirroredPose);
var exporter = new STLExporter();
var fileString = exporter.parse(group);
var name = get_name();
var blob = new Blob([fileString], { type: "application/sla;charset=utf-8" });
saveAs(blob, name + ((smooth) ? '-smooth' : '') + '.stl');
};
function save_obj() {
var smooth = jQuery('#subdivideSLT').val() > 0 ? jQuery('#subdivideSLT').val() : undefined;
var mirroredPose = CK.character.data.mirroredPose;
var group = process(CK.character, smooth, mirroredPose);
var exporter = new OBJExporter();
var fileString = exporter.parse(group);
var name = get_name();
var blob = new Blob([fileString], { type: "text/plain;charset=utf-8" });
saveAs(blob, name + ((smooth) ? '-smooth' : '') + '.obj');
};
function save_json(){
var name = get_name();
var blob = new Blob([JSON.stringify(CK.data.getJson())], {type: "text/plain;charset=utf-8"});
saveAs(blob, name + ".json");
};
function load_json (e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
e.preventDefault();
CK.change(JSON.parse(e.target.result));
};
})(file);
if (file != undefined) reader.readAsText(file);
};
function get_name() {
var getName = CK.character.data.meta.character_name;
return getName === "" ? "Hero" : getName;
};
function subdivide(geometry, subdivisions) {
var modifier = new SubdivisionModifier( subdivisions );
var smoothGeometry = modifier.modify( geometry );
return smoothGeometry;
};
function mirror(geometry) {
const tempXYZ = [0, 0, 0];
if (geometry.index) geometry.copy(geometry.toNonIndexed());
for (let i = 0; i < geometry.attributes.position.array.length / 9; i++) {
tempXYZ[0] = geometry.attributes.position.array[i * 9];
tempXYZ[1] = geometry.attributes.position.array[i * 9 + 1];
tempXYZ[2] = geometry.attributes.position.array[i * 9 + 2];
geometry.attributes.position.array[i * 9] = geometry.attributes.position.array[i * 9 + 6];
geometry.attributes.position.array[i * 9 + 1] = geometry.attributes.position.array[i * 9 + 7];
geometry.attributes.position.array[i * 9 + 2] = geometry.attributes.position.array[i * 9 + 8];
geometry.attributes.position.array[i * 9 + 6] = tempXYZ[0];
geometry.attributes.position.array[i * 9 + 7] = tempXYZ[1];
geometry.attributes.position.array[i * 9 + 8] = tempXYZ[2];
}
return geometry;
}
function process(object3d, smooth, mirroredPose) {
var material = new MeshBasicMaterial();
var group = new Group();
object3d.traverseVisible(function (object) {
if (object.isMesh) {
var exporter = new finalizeMesh();
var geometry = exporter.parse(object);
if (mirroredPose == true) {
geometry = mirror(geometry)
}
if (smooth
&& object.name != 'baseRim'
&& object.name != 'base') {
geometry = subdivide(geometry, smooth);
}
var mesh = new Mesh(geometry, material);
group.add(mesh);
}
});
return group;
};
document.body.arrive(".footer", { onceOnly: true, existing: true }, function () {
jQuery('.headerMenu:last').remove();
jQuery('a:contains(Log In)').remove();
jQuery(".headerMenu-nav-item:contains(Save)").hide();
jQuery(".headerMenu-nav-item:contains(Share)").remove();
jQuery(".headerMenu-nav-item:contains(Heroes)").remove();
jQuery(".editorFooter").empty();
jQuery("li.tab-Material").remove();
jQuery(".footer").empty();
var character_area = jQuery(".headerMenu-container").first();
character_area.css({ "display": "flex", "justify-content": "center", "align-content": "center", "align-items": "center" });
var style = { "margin-left": "10px", "width": "50px" };
character_area
.append(jQuery("<a />", { css: style, class: "jss7 jss9 jss10", text: "STL" }).on("click", save_stl))
.append(jQuery("<a />", { css: style, class: "jss7 jss9 jss10", text: "OBJ" }).on("click", save_obj))
.append(jQuery('<label />', { css: { "margin-left": "20px" }, for: 'subdivideSLT', text: 'Subdivision Passes' }))
.append(
jQuery('<select />', { css: { "margin-left": "5px" }, id: 'subdivideSLT' })
.append(new Option("0", 0))
.append(new Option("1", 1))
.append(new Option("2", 2))
);
jQuery(".headerMenu-nav-scroll:first").append([
jQuery('<a class="headerMenu-nav-item" href="#" target="_self"><div class="headerMenu-nav-item-img"><img src="/static/svg/character-menu/save.svg" width="20"></div><div class="headerMenu-nav-item-text">Save</div></a>').on("click", save_json),
jQuery('<label for="load"><span class="headerMenu-nav-item" href="#" target="_self"><input type="file" id="load" name="load" style="display: none;"/><div class="headerMenu-nav-item-img"><img src="/static/svg/character-menu/folder.svg" width="20"></div><div class="headerMenu-nav-item-text">Load</div></span></label>').on("change", load_json)
]);
});